How to change HW_TIMER interrupt priority

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

How to change HW_TIMER interrupt priority

726 Views
michaelschwager
Contributor III

I'm using K60 and MQX 4.1.something.

I have a HWTIMER firing every 2.5ms and also a Processor Expert SPI slave device which is receiving data from elsewhere.

With some random regularity, the HWTIMER fires during a SPI transaction, and the SPI slave loses a byte, thus screwing up the sync between SPI master and slave.

The PE SPI slave routine fires an interrupt with every byte that comes in, and after th expected number of bytes calls a callback which posts an MQX semaphore.  The interrupt must be an MQX-handled interrupt for the semaphore to work.  Except sometimes when the HWTIMER is in the user-provided callback, which is already in the interrupt frame, it prevents the SPI handler from executing.  So the SPI slave peripheral, not having been updated by the ISR, places the previous byte in the shift register and the SPI master therefore reads double of a given byte.  In my particular case the SPI transaction is about 140 bytes, so the actual byte that is screwed up is kind of random within that sequence.  The SPI slave afterwards doesn't realize that all 140 bytes have been sent (it thinks there are only 139 bytes sent), so things get screwed up from there.

I've tried everything, from _int_disable() in the timer callback, to EnterCritical() in the SPI ISR, to trying to use kernel interrupts for SPI which set a flag which is picked up by another task which posts the semaphore, etc.  it's taken me a long time to track it down to this one issue.  The one thing that seems to work is to disable the HWTIMER when the SPI slave expects a transaction (there is a GPIO line which is asserted telling the SPI master to come read stuff out).  But it means that in heavy SPI traffic, or if the SPI master is slow to respond to the GPIO, the HWTIMER is disabled much more than I'd like.

Is there any way to tweak the interrupt priorities of HWTIMER so it never clobbers the PE SPI slave ISR, but still can fire, say, while a SPI byte is transferring, but not during the actual ISR for said SPI byte?

Ie I need a way to mask out HWTIMER interrupt during SPI slave interrupt.  I could not do it with _int_disable(0 or EnterCritical().

thanks

Michael

0 Kudos
4 Replies

397 Views
soledad
NXP Employee
NXP Employee

Hi Michael,

Did you try using hwtimer_callback_block()???

Please check more information in the the MQXIOUG document page 291.

Regards

Sol

0 Kudos

397 Views
michaelschwager
Contributor III

Thanks I didn’t try that. Does this actually stop the MQX hwtimer interrupt from occurring? Or just prevent the callback from running? I need the actual interrupt to stop, which is why I just called hwtimer_stop().

One minor issue with this however, is that the timer starts again at zero. Is there a way to start the timer again where it left off?

thanks

0 Kudos

397 Views
DavidS
NXP Employee
NXP Employee

Hi Michael,

It looks like just the callback is prevented from running.

The SPI and HWTIMER interrupt level is set in the twrk60d100m.h header.

The default setting of each is:

#define BSP_DSPI_INT_LEVEL              (4)          <--SPI interrupt level

#define BSP_DEFAULT_MQX_HARDWARE_INTERRUPT_LEVEL_MAX      (2L)     <--HWTIMER interrupt level (in the code that initializes the HWTIMER isr it adds "1" so actually HWTIME isr priority level is "3".

You could try and swap them like following:

#define BSP_DSPI_INT_LEVEL              (2)          <--SPI interrupt level

#define BSP_DEFAULT_MQX_HARDWARE_INTERRUPT_LEVEL_MAX      (4L)     <--HWTIMER

Regards,

David

0 Kudos

397 Views
michaelschwager
Contributor III

Thanks David.

Actually the SPI interrupt that is interfering with HWTimer is not the from the MQX DSPI driver. The SPI interrupt is from the Processor Expert module which I added in later, and which I installed manually with intinstall_isr(…) and bspint_init(…) during initialization. I tried setting the PE-SPI interrupt to 2 (maximum priority), but it still didn’t nest into the existing HWTimer interrupt, so that’s very strange, now that you mention the HWTimer interrupt is 3.

I’ll try recompiling the MQX with a different HWTimer interrupt and see if that works. It’s not a big deal to disable the HWTimer when I expect SPI traffic, but it’ll be nice to know the timer counter doesn’t reset the next time I start it. I’m working on other stuff now so it’ll probably be a while before I revisit this issue; as I said just disabling the HWTimer is a reasonable workaround for now, so I’m dealing with other priorities. Kinda like an RTOS.

It would be great to see a unified DSPI MQX driver that does DMA-based SPI slave transactions. The reason I’m using the PE driver is because it does SPI slave, albeit not with DMA, so it gets an interrupt with each and every single byte, which can easily interfere with a HWTimer that is ticking frequently.

Thanks for the recommendation.

Michael

0 Kudos