Announcements

Help us improve the Power & Sensing Selection Guide. Share feedback

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
yaga_3967241
Level 3
Level 3
50 sign-ins 25 sign-ins 10 replies posted

Hi,

We are using PSoC LP5. In our design, we have a I2C slave component. In the ISR_ExitCallback(), we copy write buffer to a queue, and the queue is processed in main loop.

My questions are:

1. At what timing the I2C ISR routine (ISR_ExitCallback()) can be called? is the I2C ISR routine called at any time(as long as I2C transaction happens) while the main thread is looping?

2. How to synchronize the I2C ISR routine and main loop? Is it ok to disable I2C interrupt in the main loop so when main loop reads data from the queue, I2C ISR routing won't modify the queue at the same time?

Regards,

Winston

0 Likes
1 Solution
Len_CONSULTRON
Level 9
Level 9
Beta tester 500 solutions authored 1000 replies posted

Winston,

One common practice used by seasoned firmware designers synchronize the ISR and main() loop processing is to use double or multiple buffering.

By using multiple buffers, you can load one buffer from the ISR while the main() loop is processing the previous buffer.  

It is also a common practice for a SW semaphore to be used as communication between the ISR and main().

If you're using a RTOS like FreeRTOS, then you allocate the buffer memory you need then place it on a single-linked list structure to point to the next buffer used by the ISR.

Note:  One of the design considerations you need to account for is that the main() loop processing of the queue of data should not be SLOWER than adding the next buffer to the queue with the ISR.

If you don't design for the above concern, you will eventually run out of memory for buffers to add to the queue.

Len
"Engineering is an Art. The Art of Compromise."

View solution in original post

4 Replies
Len_CONSULTRON
Level 9
Level 9
Beta tester 500 solutions authored 1000 replies posted

Winston,

One common practice used by seasoned firmware designers synchronize the ISR and main() loop processing is to use double or multiple buffering.

By using multiple buffers, you can load one buffer from the ISR while the main() loop is processing the previous buffer.  

It is also a common practice for a SW semaphore to be used as communication between the ISR and main().

If you're using a RTOS like FreeRTOS, then you allocate the buffer memory you need then place it on a single-linked list structure to point to the next buffer used by the ISR.

Note:  One of the design considerations you need to account for is that the main() loop processing of the queue of data should not be SLOWER than adding the next buffer to the queue with the ISR.

If you don't design for the above concern, you will eventually run out of memory for buffers to add to the queue.

Len
"Engineering is an Art. The Art of Compromise."
odissey1
Level 9
Level 9
First comment on KBA 1000 replies posted 750 replies posted

yaga,

1 Yes. When isr is fired, the main loop freezes and all processing shifts to isr code. Try to keep is as short as possible, just read the I2C buffer, set the flag and exit isr.

In the main loop check for the flag and process received data. Of course, the isr rate should be low enough to have sufficient time for processing.

2. Situation complicates considerably if isr rate is too high or some other  tasks flooding CPU. Best way is to temporary store the incoming data into a ring buffer, as Len_CONSULTRON described above. 

Unfortunately, i have no I2C examples of the ring buffer. But you may take a look on a similar UART Rx examples using a ring buffer

https://community.infineon.com/t5/PSoC-5-3-1/PSOC5-LP-SIM800A-GSM-module-Interfacing-to-read-Time-an...

 

3. If some I2C data allowed to be lost, you can disable isr inside the isr code as soos as it enters isr routine. Then enable isr back in main code once the data processing is done. Don't forget to call myISR_ClearPending() to clean up the pile of unprocessed interrupts before enabling the isr back. 

yaga_3967241
Level 3
Level 3
50 sign-ins 25 sign-ins 10 replies posted

Thanks for quick reply.

The problem now is that when two processes send I2C read/write about the same time repeatedly (I think this is the case ISR rate is too high), the read process got the wrong results.

I know the theory for Linux kernel, but for PSoC, it seems there is no synchronization mechanism like spin lock, mutex. We do store I2C WriteBuffer to a ring buffer from inside ISR, and process it in main loop. I tried to disable ISR at the beginning of processing and enable ISR at the ending of processing in main loop, but it does not help - I don't know why.

 

0 Likes

I recommend to draft a small demo code and post it here for review. 

0 Likes