Hi Tom,
Thanks for the update. I will be replying to the queries along with some more clarfications that will be marked in red font. I am really looking forward to the queries asked below which is needed for better understanding of the Slice Timers Interrupt generation.
First, you haven't programmed those timers for a 5ms interrupt period. They will interrupt 5ms after the PREVIOUS interrupt has been acked. If you actually need a real 5ms period, then you need the "RUN" bit set as well. But "5ms plus a random bit" might be what you actually want.
I understand that the RUN bit will automatically load the counter and starts counting down which will generate the interrupt exactly at 5 msecs everytime upon counter expiration. But without RUN bit, the interrupt will be generated but the counter will be loaded only after the ST bit is status register is cleared (writing '1' to it). Software does clear the ST bit inside the ISR routine and I believe there will be little bit latency in generating the next 5 msecs interrupt, but shouldn't stop generating the interrupt every 5 msecs + latency.
Once the interrupt triggers, the interrupt service routine has to reliably write a one to the "ST" bit in SSR0. This clears the interrupt and starts the timer running again.Are you doing this with a direct write or a read-modify-write?
I am doing the direct write in my software to clear the interrupt inside the ISR routine and that will resume the countdown.
The latter is unnecessary and slow. Are you sure the memory regions are set up properly to make sure the cache isn't interfering?
Yes the memory regions are set up properly to make sure the cache isn't referring
Check the Interrupt Controller to make sure it is still properly programmed for this interrupt. Something may have turned it off there. Check the IPRH and IPRL Registers to see if the request is pending there. Check the IMRH and IMRL registers to make sure the interrupt is enabled.
Yes the registers are setup in my software as below
The register values for slice timer are validated as:
SLT Terminal Count Register (STCNTn) => 0x0008BD36 (5 msecs count)
SLT Control Register (SCRn) => 0x03000000 (IEN = 1, TEN = 1)
SLT Timer Count Register (SCNTn) => 0x00000000 (Timer expired)
SLT Status Register (SSRn) => 0x01000000 (ST = 1)
Are you sure the background isn't accidentally changing the CPU IPL Level? It might be running at a high IPL and blocking the slice timer interrupt. Your background loop should check the IPL every time through and throw an error if it ever isn't zero.
The background is not changing the CPU Level. The background function is run in a while(1) loop and does not depend on IPL to block the slice timer interrupt. Also verified the registers for correctness when the interrupt is not generated and everything looks fine.
The next thing that EVERYONE gets wrong the first time is that they miss the bit in the Reference Manual that says:
That's really hard to do if the interrupts are set up "all over the place", so each driver sets its own interrupt. You need to have a common set of definitions for every interrupt in the system so that code (or a fixed table) can ensure that you never have two interrupts with the same level and priority. "Undefined behavior" can mean anything from failing immediately to failing once a week (or once every 3 hours).
The next thing everyone gets wrong is messing with any interrupt control registers while CPU interrupts are enabled. If you are enabling and disabling interrupts "on the fly" by changing bits in IMRL or IMRH then it is essential to set the CPU IPL to 7 around all those accesses. The same applies to any interrupt enables in peripheral registers. The worst thing is to be doing this in the mainline code and in interrupt service routines as then you've got a classic "shared data interrupt hazard" situation.
The interrupt Control Registers are set below for different priorities with Interrupt Level 7
MCF_INTC_ICR29 = MCF_INTC_ICRn_IP(7) | MCF_INTC_ICRn_IL(7) ; /* DSPI */
MCF_INTC_ICR40 = MCF_INTC_ICRn_IP(6) | MCF_INTC_ICRn_IL(7) ; /* I2C */
MCF_INTC_ICR53 = MCF_INTC_ICRn_IP(5) | MCF_INTC_ICRn_IL(7) ; /* ST1 */
MCF_INTC_ICR54 = MCF_INTC_ICRn_IP(4) | MCF_INTC_ICRn_IL(7) ; /* ST0 */
MCF_INTC_ICR35 = MCF_INTC_ICRn_IP(1) | MCF_INTC_ICRn_IL(7) ; /* PSC0 */
/* The interrupt will not be masked if the bit is set to 0 */
MCF_INTC_IMRL &= ~( MCF_INTC_IMRL_INT_MASK29 ); /* DSPI TCF */
MCF_INTC_IMRH &= ~( MCF_INTC_IMRH_INT_MASK35 | /* PSC0 */
MCF_INTC_IMRH_INT_MASK40 | /* I2C Bus */
MCF_INTC_IMRH_INT_MASK53 | /* Slice Timer 1 */
MCF_INTC_IMRH_INT_MASK54 ); /* Slice Timer 0 */
Slice Timer 0 is not intialized as part of system initialization becasue it is not required for our software, only Slice Timer 1 is used to generate 5msec interrupt.
So next is I have two queries for my understanding w.r.t manual as listed below:
- First one is a scenario. I setup all the control registers and mask registers, SLT Terminal Count Register for 5 msec ,Slicer Timer SLT Control Register with only the timer enabled(TEN bit),then run a for loop for more than 5 msec (for eg:1 sec), the status register is set to 1 in the for loop and the timer will be expired before the for loop exists. Next, I will enable the interrupt bit in SLT Control Register, so my query here is whether the interrupt will be generated in this scenario?
Code Snippet:
//All the Interrupt related registers are configured before this.
SLT1_SCR->TEN = 1;
for(i=0i<500000;i++); // Approximately 1 secs (>5msec)
SLT1_SCR->IEN = 1; //whether the interrupt will be generated ?
- Whether the interrupt will be generated for timer counter expiry or status bit getting set?