LF: VS1010D example code for timer & GPIO interrupts

Designing hardware and software for systems that use the VS1010 MP3 Audio DSP Microcontroller.
Post Reply
kenc
User
Posts: 11
Joined: Tue 2021-02-09 3:41
Location: Ontario, Canada

LF: VS1010D example code for timer & GPIO interrupts

Post by kenc » Fri 2021-02-12 16:33

Hello,

Does anyone have working sample code for timer and GPIO interrupts for the VS1010D?

I've been trying to get the solutions from "VSOS_360_RootAndLibrariesSourceCode" running (for example, the GpioDemo solution), but am not having any success.

EDIT: To give some context, I'm using a VS1010 Minidemo Board and am trying to catch the SW1 button press on GPI1_3 in an interrupt handler. I'm using the GpioDemo solution, and have changed every instance of gpio0 to gpio1 everywhere, changed to GpioSetAsInput(0x13), etc.

EDIT 2: I did read through this thread: viewtopic.php?f=15&t=2148 but for my application I need to be able to do precise and consistent timing calculations between two input pulses (which will be connected to an infrared sensor measuring the rotational frequency of a motor shaft). So I think I need to use the hardware interrupts here. I don't think using the playercallback method will give me the necessary resolution, as I need to catch sub-millisecond differences between pulses.

Thanks!
Ken C.

User avatar
Panu
VSDSP Expert
Posts: 2803
Joined: Tue 2010-06-22 13:43

Re: LF: VS1010D example code for timer & GPIO interrupts

Post by Panu » Mon 2021-02-15 9:22

Hi!

I'll take a look, but you do realize that it's the chip select of the SPI flash, don't you? So if you use the flash, horrible things will happen.

-Panu
Info: Line In and Line Out, VS1000 User interface, Overlay howto, Latest VSIDE, MCU Howto, Youtube
Panu-Kristian Poiksalo, VLSI Solution Oy

kenc
User
Posts: 11
Joined: Tue 2021-02-09 3:41
Location: Ontario, Canada

Re: LF: VS1010D example code for timer & GPIO interrupts

Post by kenc » Mon 2021-02-15 15:15

Panu,

Yes, this is just to show a working proof of concept before I design a PCB.

I’m not using the SPI flash on the minidemo board.

Thanks!
Ken

User avatar
Panu
VSDSP Expert
Posts: 2803
Joined: Tue 2010-06-22 13:43

Re: LF: VS1010D example code for timer & GPIO interrupts

Post by Panu » Tue 2021-02-16 7:44

Hi!

Here's the first part of the answer - the timer part without interrupts. It's easier to concentrate first on the timer before tackling the interrupts.

The first version of the program sets up timer 1 and then goes into a loop waiting for the button to be pressed. At each press, it prints out the number of crystal cycles between each button press. Without using interrupts this is imprecise, but it allows us to check that the values read from the timer are good.

I started the program and pressed the button at roughly one second intervals, but as the first cup of coffee this morning has not fully kicked in yet, I was a little bit slow:
VS1010>gpioint
Interval: 13304843 xtali cycles, 1082.7509 milliseconds
Interval: 15300445 xtali cycles, 1245.1534 milliseconds
Interval: 14256926 xtali cycles, 1160.2316 milliseconds
Interval: 14688962 xtali cycles, 1195.3908 milliseconds

VS1010>
Here's the source code, demonstrating different aspecs of the timer operation.

Code: Select all

u_int32 GetTimer1Value() {
	u_int16 th_first = PERIP(TIMER_T1CNTH);
	u_int16 tl = PERIP(TIMER_T1CNTL);
	u_int16 th = PERIP(TIMER_T1CNTH);
	if (th != th_first) {
		tl = 0xffffu; //MSW changed during read, adjust tl to be correct
	}
	return ((u_int32)th << 16) | tl;
}

void Timer1Reset() {
	// VS1010 should let master timer clock divider remain at zero - don't write to TIMER_CF_CLKDIV
	// Set timer cycle start value - VSDSP timers always count downwards towards next timer interrupt
	PERIP(TIMER_T1CNTL) = 0xffffu; //low word first to avoid overflow
	PERIP(TIMER_T1CNTH) = 0xffffu; 
	// Enable timer 1
	PERIP(TIMER_ENA) |= TIMER_ENA_T1;
}
	
u_int32 CalculateInterval(register u_int32 timerValue) {
	static u_int32 previousValue;
	u_int32 result = previousValue - timerValue;
	previousValue = timerValue;
	return result;
}

ioresult main (char *params) {
	
	Timer1Reset();
	GpioSetAsInput(0x13);

	while (lastReceivedCharUart0 != 27) { // Loop until ESC key is pressed
		if (!GpioReadPin(0x13)) {
			u_int32 interval = CalculateInterval(GetTimer1Value());
			double ms = (double)interval / 12288.0;
			printf("Interval: %ld xtali cycles, %1.4f milliseconds\n",interval,ms);
			while(!GpioReadPin(0x13)) {
				// Wait until button not pressed
			}
		}
	}		
			
	return S_OK;
}
Timers are 32-bit and they calculate downwards. So the timer value registers specify the timer reset interval and the timer count registers tell how much time there is left until the count reaches zero and starts again. So to measure time, set the interval to 0xffffffff and subtract from that to get the number of cycles.
Attachments
arch-gpioint-2021-02-16-07-55-TimerOnly.zip
Source code, VSIDE solution
(20.94 KiB) Downloaded 6 times
Info: Line In and Line Out, VS1000 User interface, Overlay howto, Latest VSIDE, MCU Howto, Youtube
Panu-Kristian Poiksalo, VLSI Solution Oy

User avatar
Panu
VSDSP Expert
Posts: 2803
Joined: Tue 2010-06-22 13:43

Re: LF: VS1010D example code for timer & GPIO interrupts

Post by Panu » Tue 2021-02-16 8:18

Here's the interrupt version of the above program. It sets up GPIO1 controller to fire an interrupt from the falling edge of bit 3 and the interrupt handler.

Code: Select all

volatile u_int32 lastInterval;
volatile int interruptOccurred;

#pragma interrupt y 0x28 
void MyGpio1InterruptHandler(void) {
	lastInterval = CalculateInterval(GetTimer1Value());
	interruptOccurred = 1;
}

ioresult main (char *params) {
	Timer1Reset();
	GpioSetAsInput(0x13);

	PERIP(GPIO1_INT_FALL) |= (1<<3);
	PERIP(INT_ENABLE0_HP) |= INTF_GPIO1; //Enable GPIO1 controller interrupt

	while (lastReceivedCharUart0 != 27) {
		if (interruptOccurred) {
			u_int32 interval = lastInterval;
			double ms = (double)interval / 12288.0;
			interruptOccurred = 0;
			printf("Interval: %ld xtali cycles, %1.4f milliseconds\n",interval,ms);
		}
	}		
			
	return S_OK;
}
Note the fini() function that is called before the program is unloaded - you must disable the interrupt there to make sure that no interrupts are vectored to the handler after the program has been unloaded fom the memory.

Code: Select all

void fini(void) {
	PERIP(INT_ENABLE0_HP) &= ~INTF_GPIO1; //Disable GPIO1 controller interrupt (high priority)
	PERIP(INT_ENABLE0_LP) &= ~INTF_GPIO1; //Disable GPIO1 controller interrupt (low priority)
	printf("Interrupt disabled.\n");
}
Example run:
VS1010>gpioint
Interval: 42415880 xtali cycles, 3451.8131 milliseconds
Interval: 14203871 xtali cycles, 1155.9140 milliseconds
Interval: 12017553 xtali cycles, 977.9910 milliseconds
Interval: 11591817 xtali cycles, 943.3445 milliseconds
Interval: 7417149 xtali cycles, 603.6091 milliseconds
Interval: 3281329 xtali cycles, 267.0352 milliseconds
Interval: 2471084 xtali cycles, 201.0973 milliseconds
Interval: 2058631 xtali cycles, 167.5318 milliseconds
Interval: 1850698 xtali cycles, 150.6102 milliseconds
Interval: 1812321 xtali cycles, 147.4871 milliseconds
Interrupt disabled.

VS1010>
Good luck!
-Panu
Attachments
arch-gpioint-2021-02-16-08-17-WithInterrupts.zip
Source code, VSIDE Solution
(22.48 KiB) Downloaded 6 times
Info: Line In and Line Out, VS1000 User interface, Overlay howto, Latest VSIDE, MCU Howto, Youtube
Panu-Kristian Poiksalo, VLSI Solution Oy

kenc
User
Posts: 11
Joined: Tue 2021-02-09 3:41
Location: Ontario, Canada

Re: LF: VS1010D example code for timer & GPIO interrupts

Post by kenc » Tue 2021-02-16 15:41

Panu,

Thank you very much, especially for taking the time to make both versions. And you went above and beyond by including the Delta-Time code :)

I've built and run both versions, everything works great!

Please let me know how I can buy you a coffee from Canada (it may be some time before I'm in Finland ;)

Best,
Ken C

User avatar
Panu
VSDSP Expert
Posts: 2803
Joined: Tue 2010-06-22 13:43

Re: LF: VS1010D example code for timer & GPIO interrupts

Post by Panu » Fri 2021-02-19 6:48

Thank you for your kind words, glad that it works!

Good luck!

-Panu
Info: Line In and Line Out, VS1000 User interface, Overlay howto, Latest VSIDE, MCU Howto, Youtube
Panu-Kristian Poiksalo, VLSI Solution Oy

Post Reply