View previous topic :: View next topic |
Author |
Message |
bdeb
Joined: 05 Nov 2010 Posts: 42 Location: Sweden
|
I2C master and slave on 18F25K22 |
Posted: Mon Dec 25, 2017 12:49 pm |
|
|
Chips 18F25K22, 18LF25K22
Compiler 5.075
Dear gurus,
Please note that my approach is working - just want second opinion if code is "kosher", or if it will come back and bite me in my lazy behind on newer compiler versions..
Using I2C2 as slave and I2C1 as master - therefore I need to use "stream" at least on one of them.
Since I have a lot of I2C drivers NOT using stream, I defined the slave (with stream) first, since manual says last "#use" directive will work with commands without stream.
Code: |
#use i2c(SLAVE, I2C2, FORCE_HW, ADDRESS=0x42, STREAM=I2CS)
#use i2c(MASTER, I2C1, FORCE_HW, FAST=100000)
|
Merry Xmas & Happy New!
/Björn |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Dec 25, 2017 9:20 pm |
|
|
I can't get it to work unless I specify a stream for the Master.
It won't compile code for I2C1 at all. It uses I2C2. I can see this
by looking at the .LST file. I tested this with vs. 5.075.
If I specify a stream for both and use them, then it works.
Test program:
Code: |
#include <18F25K22.h>
#fuses INTRC_IO, NOWDT, BROWNOUT, PUT, NOPBADEN
#use delay(clock=4M)
#use rs232(baud=9600, UART1, ERRORS)
#use i2c(SLAVE, I2C2, FORCE_HW, ADDRESS=0x42, STREAM=I2CS)
#use i2c(MASTER, I2C1, FORCE_HW, FAST=100000) // , stream=Master)
unsigned int8 address, buffer[16];
#int_ssp2
void ssp2_interrupt(void)
{
unsigned int8 incoming, state;
state = i2c_isr_state(I2CS);
if(state <= 0x80) //Master is sending data
{
if(state == 0x80)
incoming = i2c_read(I2CS, 2); //Passing 2 as parameter, causes the function to read the SSPBUF without releasing the clock
else
incoming = i2c_read(I2CS);
if(state == 1) //First received byte is address
address = incoming;
else if(state >= 2 && state != 0x80) //Received byte is data
buffer[address++] = incoming;
}
if(state >= 0x80) //Master is requesting data
{
i2c_write(I2CS, buffer[address++]);
}
}
//======================================
void main()
{
int8 temp;
i2c_write(0x55);
temp = i2c_read();
//i2c_write(Master, 0x55);
// temp = i2c_read(Master);
while(TRUE);
}
|
|
|
|
bdeb
Joined: 05 Nov 2010 Posts: 42 Location: Sweden
|
|
Posted: Tue Dec 26, 2017 1:23 am |
|
|
Thanks PCM programmer,
My SSP2-interrupt looks exactly like yours - only thing I spot is your main() is missing normal sending of start and stop conditions.
Can this make the compiler think I2C1 is "unused"?
All the best:
/Björn |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19545
|
|
Posted: Tue Dec 26, 2017 3:24 am |
|
|
Honestly if you have a lot of stuff not using stream, this is what 'search & replace' is for. You can simply search for all the I2C calls in the file containing these, and replace with the same function, with the stream name added. About 1 seconds work, and no need to try to rely on things that may not work. |
|
|
bdeb
Joined: 05 Nov 2010 Posts: 42 Location: Sweden
|
|
Posted: Tue Dec 26, 2017 5:19 am |
|
|
Thanks Ttelmah,
Sound advice and probably how I'll end up doing it.
My worries are that "search&replace" in 4 computers 150 miles apart, each having 200+ code files, may end up making some other small boo-boo, that I will discover a year from now..
Had it affected only current project, I would not have bothered you guys.
Happy holidays:
/Björn |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9245 Location: Greensville,Ontario
|
|
Posted: Tue Dec 26, 2017 9:05 am |
|
|
re:
small boo-boo, that I will discover a year from now..
just a year ? That'd be nice ! It took me THREE years to finally find the culprit on one of my remote energy controller boards, 25 years ago. One of those very random, odd problems....turned out to be I hadn't soldered the wiper of a preset pot. The friction fit of the pin into the plated through hole made it work OK but high humidity or vibration would cause it to open, causing a problem. just ONE missed handsoldered joint out of 367(yeah I counted them...) caused this pain.
Jay |
|
|
bdeb
Joined: 05 Nov 2010 Posts: 42 Location: Sweden
|
|
Posted: Tue Dec 26, 2017 10:02 am |
|
|
Thanks temtronic,
You are so right, but what can i say?
Maybe "I reject reality and substitute my own", to quote Mythbusters..
All the best:
/Björn |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19545
|
|
Posted: Tue Dec 26, 2017 11:07 am |
|
|
I honestly think that trying to rely on mixing using streams and not, is far more likely to lead to a 'boo boo', than doing the changes.
Honestly if code is stored in so many places your code inventory system needs to be looked at... |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Dec 26, 2017 12:09 pm |
|
|
bdeb wrote: |
My SSP2-interrupt looks exactly like yours - only thing I spot is your main() is missing normal sending of start and stop conditions.
Can this make the compiler think I2C1 is "unused"?
|
No. It doesn't work that way.
The rule I have always followed is, if one #use i2c() statement uses
streams, all #use i2c() must use streams. That works. |
|
|
bdeb
Joined: 05 Nov 2010 Posts: 42 Location: Sweden
|
|
Posted: Tue Dec 26, 2017 4:08 pm |
|
|
Thank you all!
Just the advice I was seeking - will use streams on all I2C.
/Björn |
|
|
|