View previous topic :: View next topic |
Author |
Message |
Guest Guest
|
I2C Slave without INT_SSP? |
Posted: Fri Jan 13, 2006 3:52 pm |
|
|
I'm trying to modify a bootloader to use I2C instead of serial. In order to avoid getting into using interrupts in the bootloader, I'd like to service the SSP in a tight loop. So far, I've not had success. I think there's a step I'm missing sine the i2c_write() command doesn't work. I have successfully recieved the first couple of bytes, the restart, second address send, but my code won't send using i2c_write().
Are there any docs available that show a full transaction step-by-step with what registers need to be set/reset for each byte? |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Jan 13, 2006 4:25 pm |
|
|
I assume you're polling the SSPIF bit, in order to emulate an interrupt.
Are you clearing the bit after you handle the "interrupt" ? That's what
the compiler does. |
|
![](templates/subSilver/images/spacer.gif) |
Guest Guest
|
|
Posted: Fri Jan 13, 2006 6:47 pm |
|
|
Here's basically what I'm doing (in pseudo code):
Code: |
if (SSPSTAT.0) { // byte is ready in SSPBUF
incoming = i2c_read(); // Get the byte
state = i2c_isr_state(); // Get the state
if (state < 80) { // Master is sending
if (state == 1) {
address = incoming; // first byte is the address
} else {
buffer[address + (state - 2)] = incoming; // Store the data
}
} else { // Master wants data
if(state > 80) {
i2c_write(buffer[address + (state - 81)]); // send byte
}
}
SSPIF = 0;
}
|
I don't use the i2c_isr_state routine. I use equivalent code instead.
At first, I didn't have the SSPIF = 0 line and nothing was happening. After adding it, the slave gets the first address, command, restart and second address. But, i2c_write doesn't run. I confirmed with the o-scope. I'm not sure where exactly it stops running, but a byte isn't sent back ot the master and no further data is sent or received, so the processor must be locking up.
Does anything else have to be reset or set before calling i2c_write? I keep going over the LST file from a project that uses the interrupt, but I can't see anything else going on. |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Jan 13, 2006 6:49 pm |
|
|
1. Where's the tight loop where you're testing if SSPIF goes high ?
2. Have you configured the SSP module as an i2c slave, by using
the #use i2c() statement ? |
|
![](templates/subSilver/images/spacer.gif) |
Guest Guest
|
|
Posted: Fri Jan 13, 2006 8:13 pm |
|
|
The above code is wrapped in a while(index < xx) {} loop. And, currently, I'm not testing for SSPIF. Just SSPSTAT.0 or BF (Buffer Full). I'll change it to check for SSPIF instead and see if that works.
Yes, I have the use i2c line in there with force_hw.
I got working code from another project (the one I want to load wih the bootloader) and copied the ISR_SSP code into a while loop. Then, I changed the i2c_isr_state command to equivalent code. I wasn't sure if it would work outside of an isr. |
|
![](templates/subSilver/images/spacer.gif) |
Guest Guest
|
|
Posted: Wed Jan 18, 2006 10:57 am |
|
|
Tried checking for SSPIF instead of Buffer Full and still no-go. The PIC was getting stuck in clock stretching mode.
I finally got it to work, though. I'm using all the default commands (i2c_isr_state, i2c_write and i2c_read) instead of my own routines, but what finally got it to work was putting in: SSPIF = 0; at the end of my code. I guess the BCF F9E.3 that is in the i2c_write command isn't enough. You have to reset it again at the end of your isr.
Thanks for your help! |
|
![](templates/subSilver/images/spacer.gif) |
|