CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

A question about disable_interrupts()

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
allenhuffman



Joined: 17 Jun 2019
Posts: 552
Location: Des Moines, Iowa, USA

View user's profile Send private message Visit poster's website

A question about disable_interrupts()
PostPosted: Wed Dec 09, 2020 10:39 am     Reply with quote

As I continue to work through some I2C bus lockup issues, I found some routines that do global interrupt masking like this:

Code:

disable_interrupts(GLOBAL);

// Do something here...

enable_interrupts(GLOBAL);


Would this cause an I2C interrupt to be MISSED if the Master wrote at the moment the code was masked? Or would be interrupt be pending and be handled as soon as interrupts are re-enabled?

Some test code I wrote looks like it just drops the interrupts, rather than leave them pending.
_________________
Allen C. Huffman, Sub-Etha Software (est. 1990) http://www.subethasoftware.com
Embedded C, Arduino, MSP430, ESP8266/32, BASIC Stamp and PIC24 programmer.
http://www.whywouldyouwanttodothat.com ?
jeremiah



Joined: 20 Jul 2010
Posts: 1348

View user's profile Send private message

PostPosted: Wed Dec 09, 2020 11:35 am     Reply with quote

In all my tests on my PIC24 chips, the interrupt is waiting for me when I get back with enable interrupts. Specifically I have a blurb in my code like:

Code:

while(TRUE){
   handle_interrupts();
   main_processing();

   // Disable all interrupts to they don't get serviced right before going to sleep
   disable_interrupts(GLOBAL);
   
   // make sure no interrupts happened between the last call to
   // handle_interrupts() and the upcoming sleep() call
   if (all_interrupts_handled()){
   
      sleep();
      delay_cycles(1);  // one NOP after waking

   }
   
   enable_interrupts(GLOBAL);

}



even with interrupt handling disabled, external interrupts still fire while asleep and wake me from sleep and when I enable interrupts I see the ISR fire right after (I used some inserted I/O line toggling and delays to verify the timing)
bkamen



Joined: 07 Jan 2004
Posts: 1615
Location: Central Illinois, USA

View user's profile Send private message

PostPosted: Wed Dec 09, 2020 11:57 am     Reply with quote

Right -

The disable_interrupts(GLOBAL) (IIRC) only flips the GLOBAL interrupt bit and not the interrupt flags for individual peripherals.
_________________
Dazed and confused? I don't think so. Just "plain lost" will do. :D
allenhuffman



Joined: 17 Jun 2019
Posts: 552
Location: Des Moines, Iowa, USA

View user's profile Send private message Visit poster's website

PostPosted: Wed Dec 09, 2020 12:30 pm     Reply with quote

bkamen wrote:
The disable_interrupts(GLOBAL) (IIRC) only flips the GLOBAL interrupt bit and not the interrupt flags for individual peripherals.


Question about this... I thought GLOBAL meant "all" interrupts?

If I understand -- as long as I don't have interrupts masked to long (longer than 2 bytes of I2C data coming in), I should not miss a Master write.

But when I see this in our code:

Code:

disable_interrupts (GLOBAL);
// Loop
// Write flash
enable_interrupts (GLOBAL);


...that could be long enough that multiple bytes could have been written to this Slave PIC by the Master. When interrupts are re-enabled, would the:

i2c_isr_state()

...be returning the initial Master Write value (0x00) or, if that byte had passed, would it be coming back with 0x01, etc. indicating which byte it is receiving?
_________________
Allen C. Huffman, Sub-Etha Software (est. 1990) http://www.subethasoftware.com
Embedded C, Arduino, MSP430, ESP8266/32, BASIC Stamp and PIC24 programmer.
http://www.whywouldyouwanttodothat.com ?
jeremiah



Joined: 20 Jul 2010
Posts: 1348

View user's profile Send private message

PostPosted: Wed Dec 09, 2020 2:26 pm     Reply with quote

Disabling global means none of the normal interrupts can fire an ISR (ISRs for things like Address Errors, divide by zero, etc. can still fire), the interrupts still are seen (meaning all the individual IF flags will get set, chip will still wake from sleep, etc.) but just none of your interrupt code will work until they are re-enabled and if the IF flag was set, then the ISR will then fire (the order is platform specific and settings specific if you use priorities).

For the case of the same interrupt firing more than once, then yes, you'll miss out on running the ISR for some of them and will only get one I2C isr at the enable, so that will cause you problems.

In general you'll have to address this using your internal message protocol. the other side will need to know you cannot receive data yet until you tell it you are ready or you need a separate small micro to handle your I2C separately from your other code (or a chip with two cores potentially).
allenhuffman



Joined: 17 Jun 2019
Posts: 552
Location: Des Moines, Iowa, USA

View user's profile Send private message Visit poster's website

PostPosted: Wed Dec 09, 2020 2:31 pm     Reply with quote

jeremiah wrote:
In general you'll have to address this using your internal message protocol. the other side will need to know you cannot receive data yet until you tell it you are ready or you need a separate small micro to handle your I2C separately from your other code (or a chip with two cores potentially).


Thanks. I should be on the same page now.

I'm wondering if I even need to mask around write_program_memory() -- or if that was added to work around some issue where IRQs were expected to cause them.

Actually, looking at the code, if there was concern over interrupting the actual write, it looks like I could reduce the time things are masked by disabling/enabled around that call itself inside the loop, rather than at the start and end of the function. More stuff on the TO DO list!
_________________
Allen C. Huffman, Sub-Etha Software (est. 1990) http://www.subethasoftware.com
Embedded C, Arduino, MSP430, ESP8266/32, BASIC Stamp and PIC24 programmer.
http://www.whywouldyouwanttodothat.com ?
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group