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

Using I2C IRQs from bootloader and application

 
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

Using I2C IRQs from bootloader and application
PostPosted: Thu Nov 07, 2019 11:29 am     Reply with quote

I created a simple proof-of-concept PIC24 bootloader the other day, and now I have started implementing an I2C firmware update capability to it. I ran into a snag, and after reading through some old threads here on similar issues, I think I know what to ask.

Originally, I thought I could use I2C FORCE_SW as a SLAVE (bootloader), but I see that is not supported. I will have to use I2C interrupts.

However, if the bootloader has the I2C interrupt in its main vector table, it won't be able to get to the application routine (which will also use I2C). From ex_pcd_boatloader.c, interrupts are redirected like this:

Code:
#int_default
void isr(void)
{
   jump_to_isr(LOADER_END+5);
}


When I looked at Microchips EZBL bootloader, it looked like they took all the IRQs and then passed them on (using a special API applications use to access timers and such).

Is that the only option?
_________________
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 ?
gaugeguy



Joined: 05 Apr 2011
Posts: 303

View user's profile Send private message

PostPosted: Thu Nov 07, 2019 11:35 am     Reply with quote

For a bootloader you should be able to poll the interrupt flags. This avoids messing with the main application interrupt vectors.
allenhuffman



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

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

PostPosted: Thu Nov 07, 2019 1:42 pm     Reply with quote

gaugeguy wrote:
For a bootloader you should be able to poll the interrupt flags. This avoids messing with the main application interrupt vectors.


I adapted this code which looks like it polls for a Start, then receives until it gets a Stop. The registers (for 24FJ256GA106 in this case, but the code is cross platform):

SLAVE:

Code:
    // IC2C3STAT - sto(P) and (S)tart bits for status.
    #word I2C3STAT = getenv("SFR:I2C3STAT")
    #bit P = I2C3STAT.4                 // bit 4 - stop
    #bit S = I2C3STAT.3                 // bit 3 - start
    #bit RBF = I2C3STAT.1               // bit 1 - RBF receive buffer status bit


...and the code that waits for incoming data:

Code:
    unsigned int    bytesRead;
   
    while (S==0); // Wait for start.

    bytesRead = 0;
   
    while (1) // Read incoming bytes.
    {
        if (RBF == 1) // Read Buffer Full?
        {
            buffer[bytesRead++] = i2c_read(SYSTEM_BUS);
           
            if (bytesRead > size)
            {
                break;
            }
        }
       
        if (P == 1) // Stop?
        {
            break;
        }
    }


I've blasted a few hundred messages of different byte sizes to it, and it's worked fine.

The production code we use at work does all of this inside an ISR, so the next thing I have to add is the way to turn around and send a response back to the Master.
_________________
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 ?
allenhuffman



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

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

PostPosted: Fri Nov 08, 2019 8:43 am     Reply with quote

I bailed on this, since it seems the original author was not using it on a shared bus. The way it checks the receive buffer register makes it respond to all traffic on the line.
_________________
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 ?
allenhuffman



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

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

PostPosted: Fri Nov 08, 2019 9:48 am     Reply with quote

gaugeguy wrote:
For a bootloader you should be able to poll the interrupt flags. This avoids messing with the main application interrupt vectors.


I started looking at this. On my PIC24 board, I am wanting to use I2C3. I find:

Quote:
IFS5 - Interrupt Flag Status Register 5

SI2CSIF - Slave I2C3 Event Interrupt Flag Status Bit


I can see it toggle to 1 when data comes in, via:

Code:
    #word IFS5 = getenv("SFR:IFS5")
    #bit SI2C3IF = IFS5.4               // bit 4 - slave I2C3 IRQ status


The only others I see are:

IEC5 - Interrupt Enable Control Register 5 (SI2C3IE)

and

IPC21 - Interrupt Priority Control Register 21 (SI2C3IP)

Where does the rest of the state come from in i2c_isr_state()? I think the high bit there may be the RW status bit (in or out data?), then the other 7-bits are the incoming byte count... Is that being done by the library?

Thanks!
_________________
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 ?
Ttelmah



Joined: 11 Mar 2010
Posts: 19499

View user's profile Send private message

PostPosted: Fri Nov 08, 2019 10:19 am     Reply with quote

Don't worry. Yes it is done in the library, it is reset when an
address byte is received. You can just use I2C_ISR_state as normal
in your polled code. It doesn't mind at all that your service routine is not
actually in an 'interrupt' as such.

Look at my reply here (why have you got two threads running for the
same question?):

<http://www.ccsinfo.com/forum/viewtopic.php?t=58338>
allenhuffman



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

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

PostPosted: Fri Nov 08, 2019 11:22 am     Reply with quote

Ttelmah wrote:
Look at my reply here (why have you got two threads running for the
same question?):


This thread was for the question of how to have bootloader Vector table end up at the Application's vector table.

jump_to_isr ()

As soon as I have it tested, I'll mark this one as solved.
_________________
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