jmann
Joined: 27 Dec 2004 Posts: 21
|
I think I'm missing an I2C interrupt (slave)*** Locked - Dup |
Posted: Tue Apr 02, 2013 7:41 am |
|
|
In a previous thread, I asked about the proper form of the I2C slave
++++++++++++++++++++++++++
Locked.
Reason: Duplicate thread on same i2c slave topic.
No posting of new thread every day on same thing !!!! No dups !
Add new comments to original thread:
http://www.ccsinfo.com/forum/viewtopic.php?t=50124
- Forum Moderator
++++++++++++++++++++++++++
interrupt and how to also identify a STOP condition. I was going to process a command I put in the buffer when I got the stop (so it was all there). In the conclusion of that thread, I posted the framework for the code I am using to do that. It turns on start/stop interrupts and then turns them off again. ( http://www.ccsinfo.com/forum/viewtopic.php?t=50124 )
In the process, I found that I was getting one less interrupt than I expected. Everything else works with that code. So this is a different question.
Here is our sample code to explain the question:
Code: |
//test part is a PIC16F887
#INT_SSP
void ssp_interupt ()
{
BYTE state;
static int8 i2cRegAddress;
state = i2c_isr_state();
if(state ==0) // address byte
{
i2C_read( ); // Empty read buffer or we'll have a problem ( we do nothing )
}
else if (state == 1) // First received byte is register address
{
i2cRegAddress = i2c_read();
}
else if (state<0x80) // If we get a write, we
{
Buffer[(i2cRegAddress++) ]= i2c_read();
}
else if (state >= 0x80) // Second or more received byte is data we write to the buffer
{
if (state == 0x80)
i2c_read(); // empty the read buffer (do nothing)
i2c_write(Buffer[(i2cRegAddress++)]);
}
printf("State: %02x\n",state); // this is our debug output to identify when we get interrupts
} |
Like I said in the conclusion to the previous thread, I noticed that we don't get an interrupt on the address I2C write byte. Here is our example:
(our slave address is 0x10)
[start][write 0x10][write regaddress][start][write 0x11][read data1][read data2][stop]
intterrpts are triggered on the [write 0x10], [write regaddress],[ read data1], and [read data2]. We do not get an itterrupt on [write 0x11]
If I send each part of the I2C frame one-at-a-time, the command and the debugging output that follows would look like this
[start]
[write 0x10] "State: 00"
[write regaddr] "State: 01"
[start]
[write 0x11] (no interrupt)
[read data1] "State: 80"
[read data2] "State: 81"
[stop]
I though I was supposed to be pre-loading the write buffer on the preceding interrupt so that the byte is already there waiting to be sent. For Example, I though I was supposed to get an interrupt on the [write 0x11] where I put data1 in the write buffer so the next read takes it out and interrupts me when the buffer is empty again.
Is this an incorrect understanding or does CCS do something behind the scenes that results in hiding that interrupt so all the read interrupts are delayed one byte? The effective result is that the hardware I2C controller's write buffer is always empty and it always attempts to stretch the clock until the interrupt puts something in it. |
|