Question

Platform - ARM9

I have a third party device connected via I2C to the ARM9. My problem is the I2C read/write is getting in a twist. It appears the IRQ line is asserted but never de-asserted when there is data to read. The read fails as the third-party device NACKs the address packet. So any subsequent write fails.

I am wondering if my interrupt handling in ok. In the ISR that services the IRQ, I disable interrupts, unregister the interrupt handler and then signal to the task to go read from the I2C bus. Finally, I re-enable the interrupts.

When the task services the signal posted above, I attempt to read data from the I2C bus but this fails. Finally, I always reregister the ISR after ever read attempt. There is no interrupt disabling/enabling that takes place during handling of the read signal.

My question is do I need to disable interrupts when reading/writing to the I2C bus?

Programming language of choice is c using propriety RTOS.

Was it helpful?

Solution

An important thing is whether your RTOS/system is ready to support nested exceptions. Unless there is a good reason to do so, things are simpler if you avoid nested exceptions and disable all interrupts when entering an ISR and re-enabling when leaving.

If you want to allow other higher-priority interrupts to occur while you are serving the I2C interrupt, then disable only the I2C interrupt. It is rather unusual to unregister an interrupt handler when entering an ISR. This may lead to unexpected behaviour, when there is no registered handler, the interrupt itself is enabled and an interrupt occurs. So instead of unregistering the handler, simple disable the I2C interrupt (Perhaps you are already doing so, but as I see it, registering a handler and enabling an interrupt are two different things).

A good strategy to solve your problem will be to try to communicate with the device without interrupts. Try to read/write from it in a serial fashion, doesn't matter if everything blocks - it is just testing. This is much easier to debug and after you are successful you can move to the interrupts version.

OTHER TIPS

Most interrupts need to be acknowledged or cleared. You mention enabling/disabling, registering/unregistering and handling the interrupt. Just check that the interrupt is being acknowledged and/or cleared/reset. Often this involves writing the interrupt number or bit back to the interrupt pending register. Check the specific ARM manual or your RTOS manual.

Whether you need to enable/disable interrupts for your target platform is dependant on your specific hardware/RTOS implementation. Unfortunately, every ARM microcontroller vendor (STMicro, Freescale, Oki, etc) has the ability implement their I2C hardware differently and may have different requirements in how to clear the IRQ.

I'd recommend you find a copy of the hardware datasheet (and/or post the specific hardware part-number here so we can help pour over the vendor documentation, with you).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top