Other Parts Discussed in Thread: SYSBIOS
I am new to SYS/BIOS, mostly worked on bare-metal in the past. I am seeing an issue related to zero/low-latency interrupt ISR call for XINT1. On bare-metal I have add code to allow interrupt nesting thereby getting a very low latency (~24 cycles)XINT1 ISR call. I want to create similar effect in SYS/BIOS but here I am seeing latency in the range of 2-5 us which is too long for my application. Below are more details on the ask and issues.
Ask:
PWM generation that needs to be synchronous to an external asynchronous pulse with a very strict timing requirement down 20-30 ns accuracy. The scenario is explained below,
- Receive an external asynchronous pulse on a GPIO input.
- Trigger external Interrupt (XINT1) on rising edge of the pulse from the receiving GPIO.
- In the XINT1 ISR, reload the PWM compare register, and reset the PWM1 counter to zero.
Issue:
Conceptually it is a simple logic to implement, and I have successfully tested it in bare-metal, meeting all the timing requirements. In sysBios OSAL2 however, the challenge I am facing is the interrupt latency jitter associated with XINT ISR call.
From the point when the input pulse is received to the moment the PWM registers are modified in XINT ISR I am seeing ISR latency jitter of up to 5 µs.
So, to counter this high ISR latency, I tried to make use of ti_sysbios_family_c28_Hwi.zeroLatencyIERMask. (Does this setting allows interrupt nesting in SYS/BIOS for the flagged interrupt group?)
When I set the ti_sysbios_family_c28_Hwi.zeroLatencyIERMask in app.cfg, I don't see the XINT1 ISR callback function called.
In main I am added the code before BIOS_start() ,
main()
{
//... user tasks
// PWM and other tasks initialized in OSAL2
....
...
// Plug in the zero-latency interrupt */
Hwi_plug(35, xint1_isr);
XintInitBareMetal();
Hwi_enableIER(0x0001);
BIOS_start();
}
bool XintInitBareMetal(void)
{
// Initialize GPIO
EALLOW;
GpioCtrlRegs.GPAMUX1.bit.GPIO13 = 0; // GPIO
GpioCtrlRegs.GPADIR.bit.GPIO13 = 0; // input
GpioCtrlRegs.GPAQSEL1.bit.GPIO13 = 0; // XINT1 Synch to SYSCLKOUT only
GpioIntRegs.GPIOXINT1SEL.bit.GPIOSEL = 13; // XINT1 is GPIO0
EDIS;
XIntruptRegs.XINT1CR.bit.POLARITY = 1; // Rising edge interrupt
XIntruptRegs.XINT1CR.bit.ENABLE = 1; // Enable XINT1
PieCtrlRegs.PIEIER1.bit.INTx4 = 0u; // 2) disable XINTx in PIE group
asm(" RPT #4 || NOP "); // 3) wait 5 cycles
IFR &= ~0x0001u; // 4) clear IFR bit for this PIE group
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; // 5) Must acknowledge the PIE group
PieCtrlRegs.PIEIER1.bit.INTx4 = 1u; // Enable XINT1 intrrupt
return true;
}
#pragma CODE_SECTION(xint1_isr, "ramfuncs")
__interrupt void xint1_isr(void)
{
EPwm1Regs.TBCTR = 0x0000;
EPwm1Regs.TBCTL.bit.CTRMODE=0; //pwmdrv_CM_COUNT_UP;
GpioDataRegs.GPATOGGLE.bit.GPIO21 = 1;
// Acknowledge this interrupt to get more from group 1
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}
Attached are the videos for reference. Please advise how to make the code in sysbios perform like bare-metal.