ferenczdr wrote on Thursday, November 14, 2019:
Hi
I’m trying to develop a PWM signal using the TTC1 timer interrupts. My development board is an ultra96 with Xilinx’s MPSoC and I’m building on top of the Xilinx’s freeRTOS Hello World example.
I have two really simple tasks that are running for testing - one initializes the timer and interrupt and prints with a delay, and the other one just prints with a delay.
void servoTask(){
ttcInitialize();
const TickType_t xDelay = 200 / portTICK_PERIOD_MS;
xil_printf("Servo task\r\n");
for(;;) {
vTaskDelay( xDelay );
xil_printf("Servo print\r\n");
}
}
void dummyTask(){
xil_printf("Dummy task\r\n");
const TickType_t xDelay = 2000 / portTICK_PERIOD_MS;
for(;;) {
vTaskDelay( xDelay );
xil_printf("dummy print\r\n");
}
}
I have followed the demo for Cortex R5 and initialized my timer and interrupt using the
FreeRTOS XScuGic xInterruptController
/* Initialize TTC1 */
XTtcPs ttc1Inst; /* Driver instance */
XTtcPs_Config* ttc1Conf; /* TTC configuration */
TimerSetup timerSetup;
int Status;
extern XScuGic xInterruptController;
/* Lookup configuration */
ttc1Conf = XTtcPs_LookupConfig(TTC_TICK_DEVICE_ID);
/* Initialize TTC */
Status = XTtcPs_CfgInitialize(&ttc1Inst, ttc1Conf, ttc1Conf->BaseAddress);
if (Status != XST_SUCCESS){
return XST_FAILURE;
}
/* Set options */
timerSetup.OutputHz = 1; /* 50Hz to accomplish the 20ms period */
timerSetup.Options = (XTTCPS_OPTION_INTERVAL_MODE | XTTCPS_OPTION_WAVE_DISABLE);
XTtcPs_SetOptions(&ttc1Inst, timerSetup.Options);
/* Calculate and set the interval and prescaler automatically */
XTtcPs_CalcIntervalFromFreq(&ttc1Inst,
timerSetup.OutputHz,
&(timerSetup.Interval),
&(timerSetup.Prescaler)); /* TODO: PSC is calculated as disabled... why? Does not make sense to have such a fast clock */
XTtcPs_SetInterval(&ttc1Inst, timerSetup.Interval); /* Set interval */
XTtcPs_SetPrescaler(&ttc1Inst, timerSetup.Prescaler); /* Set prescaler */
XScuGic_SetPriorityTriggerType( &xInterruptController, XPAR_XTTCPS_3_INTR, configMAX_API_CALL_INTERRUPT_PRIORITY << portPRIORITY_SHIFT, 3 );
Status = XScuGic_Connect(&xInterruptController, XPAR_XTTCPS_3_INTR,
(Xil_ExceptionHandler)IntCallback,
&ttc1Inst);
configASSERT( Status == XST_SUCCESS);
XScuGic_Enable(&xInterruptController, XPAR_XTTCPS_3_INTR);
/* Enable TTC and interrupt */
XTtcPs_EnableInterrupts(&ttc1Inst, XTTCPS_IXR_INTERVAL_MASK); /* Enable interrupt */
/* Start timer*/
XTtcPs_Start(&ttc1Inst); /* Start timer */
return XST_SUCCESS;
The 2 tasks are working correctly and printing with the delays given. However, the timer interrupt handler runs only once and then it stops being called again… In theory the handler should be called every one second, which does at the beginning, but then it is not called again. This is my handler
void IntCallback(void *CallBackRef){
u32 StatusEvent = 0;
XTtcPs* ttc1Inst = (XTtcPs*)CallBackRef;
StatusEvent = XTtcPs_GetInterruptStatus(ttc1Inst); /* Read and reset interrupt */
XTtcPs_ClearInterruptStatus(ttc1Inst, StatusEvent);
configASSERT( ( XTTCPS_IXR_INTERVAL_MASK & StatusEvent ) != 0 );
xil_printf("Callback\r\n");
}
I thing the freeRTOS is disabling interrupts after the first run, maybe I’m not clearing the interrupt correctly?
Any thoughts about what could be causing this?
Thanks