Discussion:
[Sdcc-user] Example or tutorial for I2C usage with PIC
Laurent FAILLIE
2010-07-07 13:30:41 UTC
Permalink
Hello,

I googled but w/o success ... can someone point me out a tutorial or at least an example of I2C slave programming with SDcc on PIC (I'm using 16F88) ?

Thanks a lot.

Laurent

PS: As I didn't received any confirmation of my inscription to this ML, I'll try also on the forum.

---
The misspelling master is on the Web.
_________ 100 % Dictionnary Free !
/ /(
/ Dico / / Pleins d'autres fautes sur
/________/ /
(#######( / http://destroyedlolo.homeunix.org
Quoi, des fautes d'orthographe! Pas possible ;-D.

A voir aussi : http://sillingy.clubphotos.fr , le site du
photo club de ... Sillingy.
Sébastien Lorquet
2010-07-07 16:07:51 UTC
Permalink
Hi,

Your message made it to the list :)

I'm searching the same information for PIC18.

Sebastien
Post by Laurent FAILLIE
Hello,
I googled but w/o success ... can someone point me out a tutorial or at
least an example of I2C slave programming with SDcc on PIC (I'm using 16F88)
?
Thanks a lot.
Laurent
PS: As I didn't received any confirmation of my inscription to this ML,
I'll try also on the forum.
---
The misspelling master is on the Web.
_________ 100 % Dictionnary Free !
/ /(
/ Dico / / Pleins d'autres fautes sur
/________/ /
(#######( / http://destroyedlolo.homeunix.org
Quoi, des fautes d'orthographe! Pas possible ;-D.
A voir aussi : http://sillingy.clubphotos.fr , le site du
photo club de ... Sillingy.
------------------------------------------------------------------------------
This SF.net email is sponsored by Sprint
What will you do first with EVO, the first 4G phone?
Visit sprint.com/first -- http://p.sf.net/sfu/sprint-com-first
_______________________________________________
Sdcc-user mailing list
https://lists.sourceforge.net/lists/listinfo/sdcc-user
lementec fabien
2010-07-07 17:14:01 UTC
Permalink
hope it helps:
http://github.com/texane/pic18f_i2c
Post by Sébastien Lorquet
Hi,
Your message made it to the list :)
I'm searching the same information for PIC18.
Sebastien
Post by Laurent FAILLIE
Hello,
I googled but w/o success ... can someone point me out a tutorial or at
least an example of I2C slave programming with SDcc on PIC (I'm using 16F88)
?
Thanks a lot.
Laurent
PS: As I didn't received any confirmation of my inscription to this ML,
I'll try also on the forum.
---
The misspelling master is on the Web.
  _________    100 % Dictionnary Free !
 /        /(
 /  Dico  / /   Pleins d'autres fautes sur
/________/ /
(#######( /     http://destroyedlolo.homeunix.org
Quoi, des fautes d'orthographe! Pas possible ;-D.
A voir aussi : http://sillingy.clubphotos.fr , le site du
photo club de ... Sillingy.
------------------------------------------------------------------------------
This SF.net email is sponsored by Sprint
What will you do first with EVO, the first 4G phone?
Visit sprint.com/first -- http://p.sf.net/sfu/sprint-com-first
_______________________________________________
Sdcc-user mailing list
https://lists.sourceforge.net/lists/listinfo/sdcc-user
------------------------------------------------------------------------------
This SF.net email is sponsored by Sprint
What will you do first with EVO, the first 4G phone?
Visit sprint.com/first -- http://p.sf.net/sfu/sprint-com-first
_______________________________________________
Sdcc-user mailing list
https://lists.sourceforge.net/lists/listinfo/sdcc-user
Sébastien Lorquet
2010-07-07 19:57:59 UTC
Permalink
Thanks, nice.

For PIC16, I just found that:
http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1824&appnote=en011798

Regards
Sebastien
Post by lementec fabien
http://github.com/texane/pic18f_i2c
Post by Sébastien Lorquet
Hi,
Your message made it to the list :)
I'm searching the same information for PIC18.
Sebastien
Post by Laurent FAILLIE
Hello,
I googled but w/o success ... can someone point me out a tutorial or at
least an example of I2C slave programming with SDcc on PIC (I'm using
16F88)
Post by Sébastien Lorquet
Post by Laurent FAILLIE
?
Thanks a lot.
Laurent
PS: As I didn't received any confirmation of my inscription to this ML,
I'll try also on the forum.
---
The misspelling master is on the Web.
_________ 100 % Dictionnary Free !
/ /(
/ Dico / / Pleins d'autres fautes sur
/________/ /
(#######( / http://destroyedlolo.homeunix.org
Quoi, des fautes d'orthographe! Pas possible ;-D.
A voir aussi : http://sillingy.clubphotos.fr , le site du
photo club de ... Sillingy.
------------------------------------------------------------------------------
Post by Sébastien Lorquet
Post by Laurent FAILLIE
This SF.net email is sponsored by Sprint
What will you do first with EVO, the first 4G phone?
Visit sprint.com/first -- http://p.sf.net/sfu/sprint-com-first
_______________________________________________
Sdcc-user mailing list
https://lists.sourceforge.net/lists/listinfo/sdcc-user
------------------------------------------------------------------------------
Post by Sébastien Lorquet
This SF.net email is sponsored by Sprint
What will you do first with EVO, the first 4G phone?
Visit sprint.com/first -- http://p.sf.net/sfu/sprint-com-first
_______________________________________________
Sdcc-user mailing list
https://lists.sourceforge.net/lists/listinfo/sdcc-user
------------------------------------------------------------------------------
This SF.net email is sponsored by Sprint
What will you do first with EVO, the first 4G phone?
Visit sprint.com/first -- http://p.sf.net/sfu/sprint-com-first
_______________________________________________
Sdcc-user mailing list
https://lists.sourceforge.net/lists/listinfo/sdcc-user
Sébastien Lorquet
2010-07-07 22:41:23 UTC
Permalink
And reading the app note (AN734) reveals the modifications required for
PIC18.

Sebastien
Post by Sébastien Lorquet
Thanks, nice.
http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1824&appnote=en011798
Regards
Sebastien
Post by lementec fabien
http://github.com/texane/pic18f_i2c
Post by Sébastien Lorquet
Hi,
Your message made it to the list :)
I'm searching the same information for PIC18.
Sebastien
Post by Laurent FAILLIE
Hello,
I googled but w/o success ... can someone point me out a tutorial or at
least an example of I2C slave programming with SDcc on PIC (I'm using
16F88)
Post by Sébastien Lorquet
Post by Laurent FAILLIE
?
Thanks a lot.
Laurent
PS: As I didn't received any confirmation of my inscription to this ML,
I'll try also on the forum.
---
The misspelling master is on the Web.
_________ 100 % Dictionnary Free !
/ /(
/ Dico / / Pleins d'autres fautes sur
/________/ /
(#######( / http://destroyedlolo.homeunix.org
Quoi, des fautes d'orthographe! Pas possible ;-D.
A voir aussi : http://sillingy.clubphotos.fr , le site du
photo club de ... Sillingy.
------------------------------------------------------------------------------
Post by Sébastien Lorquet
Post by Laurent FAILLIE
This SF.net email is sponsored by Sprint
What will you do first with EVO, the first 4G phone?
Visit sprint.com/first -- http://p.sf.net/sfu/sprint-com-first
_______________________________________________
Sdcc-user mailing list
https://lists.sourceforge.net/lists/listinfo/sdcc-user
------------------------------------------------------------------------------
Post by Sébastien Lorquet
This SF.net email is sponsored by Sprint
What will you do first with EVO, the first 4G phone?
Visit sprint.com/first -- http://p.sf.net/sfu/sprint-com-first
_______________________________________________
Sdcc-user mailing list
https://lists.sourceforge.net/lists/listinfo/sdcc-user
------------------------------------------------------------------------------
This SF.net email is sponsored by Sprint
What will you do first with EVO, the first 4G phone?
Visit sprint.com/first -- http://p.sf.net/sfu/sprint-com-first
_______________________________________________
Sdcc-user mailing list
https://lists.sourceforge.net/lists/listinfo/sdcc-user
lementec fabien
2010-07-07 17:13:04 UTC
Permalink
hope it helps:
http://github.com/texane/pic18f_i2c
Post by Sébastien Lorquet
Hi,
Your message made it to the list :)
I'm searching the same information for PIC18.
Sebastien
Post by Laurent FAILLIE
Hello,
I googled but w/o success ... can someone point me out a tutorial or at
least an example of I2C slave programming with SDcc on PIC (I'm using 16F88)
?
Thanks a lot.
Laurent
PS: As I didn't received any confirmation of my inscription to this ML,
I'll try also on the forum.
---
The misspelling master is on the Web.
  _________    100 % Dictionnary Free !
 /        /(
 /  Dico  / /   Pleins d'autres fautes sur
/________/ /
(#######( /     http://destroyedlolo.homeunix.org
Quoi, des fautes d'orthographe! Pas possible ;-D.
A voir aussi : http://sillingy.clubphotos.fr , le site du
photo club de ... Sillingy.
------------------------------------------------------------------------------
This SF.net email is sponsored by Sprint
What will you do first with EVO, the first 4G phone?
Visit sprint.com/first -- http://p.sf.net/sfu/sprint-com-first
_______________________________________________
Sdcc-user mailing list
https://lists.sourceforge.net/lists/listinfo/sdcc-user
------------------------------------------------------------------------------
This SF.net email is sponsored by Sprint
What will you do first with EVO, the first 4G phone?
Visit sprint.com/first -- http://p.sf.net/sfu/sprint-com-first
_______________________________________________
Sdcc-user mailing list
https://lists.sourceforge.net/lists/listinfo/sdcc-user
--
Donald Gillies, a student at Princeton, created an assembler to do the
work. Von Neumann was angry, claiming “It is a waste of a valuable
scientific computing instrument to use it to do clerical work”.
Michelle Konzack
2010-07-08 09:49:47 UTC
Permalink
Bonjour Laurent FAILLIE,
Post by Laurent FAILLIE
Hello,
I googled but w/o success ... can someone point me out a tutorial or
at least an example of I2C slave programming with SDcc on PIC (I'm
using 16F88) ?
Why not use the sample sources provided by Microchip?

Thanks, Greetings and nice Day/Evening
Michelle Konzack
--
##################### Debian GNU/Linux Consultant ######################
Development of Intranet and Embedded Systems with Debian GNU/Linux

***@tdnet France EURL ***@tdnet UG (limited liability)
Owner Michelle Konzack Owner Michelle Konzack

Apt. 917 (homeoffice)
50, rue de Soultz Kinzigstraße 17
67100 Strasbourg/France 77694 Kehl/Germany
Tel: +33-6-61925193 mobil Tel: +49-177-9351947 mobil
Tel: +33-9-52705884 fix

<http://www.itsystems.tamay-dogan.net/> <http://www.flexray4linux.org/>
<http://www.debian.tamay-dogan.net/> <http://www.can4linux.org/>

Jabber ***@jabber.ccc.de
ICQ #328449886

Linux-User #280138 with the Linux Counter, http://counter.li.org/
Laurent FAILLIE
2010-07-08 11:06:38 UTC
Permalink
Bonjour Michelle,
Post by Michelle Konzack
Why not use the sample sources provided by Microchip?
Are they compatible w/ SDcc ? Because I found in libio several functions related to I2C and I tought they are SDcc specifics.

Bye

Laurent

---
The misspelling master is on the Web.
_________ 100 % Dictionnary Free !
/ /(
/ Dico / / Pleins d'autres fautes sur
/________/ /
(#######( / http://destroyedlolo.homeunix.org
Quoi, des fautes d'orthographe! Pas possible ;-D.

A voir aussi : http://sillingy.clubphotos.fr , le site du
photo club de ... Sillingy.
Sébastien Lorquet
2010-07-08 11:56:02 UTC
Permalink
sdcc uses gpasm as backend, if gpasm is compatible with mplab then you're done.

Or you can just translate the microchip AN register accesses into sdcc c code.

Regards
Sebastien
Post by Laurent FAILLIE
Bonjour Michelle,
Post by Michelle Konzack
Why not use the sample sources provided by Microchip?
Are they compatible w/ SDcc ? Because I found in libio several functions related to I2C and I tought they are SDcc specifics.
Bye
Laurent
---
The misspelling master is on the Web.
  _________    100 % Dictionnary Free !
 /        /(
 /  Dico  / /   Pleins d'autres fautes sur
/________/ /
(#######( /     http://destroyedlolo.homeunix.org
Quoi, des fautes d'orthographe! Pas possible ;-D.
A voir aussi : http://sillingy.clubphotos.fr , le site du
photo club de ... Sillingy.
------------------------------------------------------------------------------
This SF.net email is sponsored by Sprint
What will you do first with EVO, the first 4G phone?
Visit sprint.com/first -- http://p.sf.net/sfu/sprint-com-first
_______________________________________________
Sdcc-user mailing list
https://lists.sourceforge.net/lists/listinfo/sdcc-user
r***@penti.org
2010-07-08 00:47:05 UTC
Permalink
Post by Laurent FAILLIE
Hello,
I googled but w/o success ... can someone point me out a tutorial or
at least an example of I2C slave programming with SDcc on PIC (I'm
using 16F88) ?
I don't know if the 16F88 has a hardware I2C circuit, but if it has,
I've used this (just the relevant functions here):


// Send an I2C start sequence
void I2Cstart()
{
SEN=1;
while(SEN) {
}
SSPIF=0;
}


// Send an I2C STOP sequence
void I2Cstop()
{
PEN=1;
while(PEN) {
}
SSPIF=0;
}

// Send a repeated START
void I2Crestart()
{
RSEN=1;
while(RSEN) {
}
SSPIF=0;
}


These were the control signals, next is what I used for the data,
after calling relevant previous functions (never mind my comments, I
assume an RTC won't complain about any data errors):

// Shift one byte of data to the bus.
// As of this version, no error checing is done. The function
// assumes the receiver sends an "Acknowledged".
void I2Cwrite(unsigned char c)
{
SSPBUF=c;
while(!SSPIF);
SSPIF=0;
}





// Shift in one byte from the bus and then sends and "Acknowledge"
unsigned char I2Cread(unsigned char ack)
{
unsigned char c;
RCEN=1;
while(!BF);
c=SSPBUF;
if(ack) {
ACKDT=0;
}
else {
ACKDT=1;
}
ACKEN=1;
return(c);
}




************************************
Then, the bit-banged version, if you don't have proper I2C hardware.
This is on a 16F690, mapping like this:
SDA=PORTB4
SCL=PORTB6

(You can try without the delays, for me it was just for being on the
safe side)



void I2Cstart(void)
{
SCL=0;
I2Cdelay();
SDA=1;
I2Cdelay();
SCL=1;
I2Cdelay();
SDA=0;
I2Cdelay();
}


void I2Cstop(void)
{
SDA=0;
I2Cdelay();
SCL=1;
I2Cdelay();
SDA=1;
I2Cdelay();
}



void I2Cwrite(unsigned char c)
{
signed char i;
SCL=0;
I2Cdelay();
for(i=7 ; i>=0 ; i--) {
SDA=((c>>i)&0x01);
I2Cdelay();
SCL=1;
I2Cdelay();
while(SCL_RD==0) { // Ensure the clock has been released by the slave
}
SCL=0;
I2Cdelay();
}
I2Cdelay();
while(SDA_RD) { // wait for ack
}
SCL=1;
I2Cdelay();
I2Cdelay();
I2Cdelay();

}




unsigned char I2Cread(unsigned char ack)
{
unsigned char i,byte;
byte=0x00;
SCL=0;
for(i=0;i<8;i++) {
I2Cdelay();
SDA=1;
SCL=1;
while(SCL_RD==0) { // Clock stretch
}
I2Cdelay();
byte=byte << 1;
byte |= (SDA_RD & 0x01);
I2Cdelay();
SCL=0;
}
I2Cdelay();
if(ack==0) {
SDA=1;
I2Cdelay();
SCL=1;
I2Cdelay();
SCL=0;
I2Cdelay();
}
else {
SDA=0;
I2Cdelay();
SCL=1;
I2Cdelay();
SCL=0;
}
return(byte);

}


Note: I haven't bothered with error checking or things like that, you
may want to add some later on...

I hope this helps at all.

Regards, Robert
Sébastien Lorquet
2010-07-08 21:24:24 UTC
Permalink
Hi, this is code for a master I2C device.

We're talking about slaves here. Make the PIC behave as an I2C device
like an EEPROM or something like that.
Yes that's a bit trickier, even with hardware support :)

Sebastien
Post by r***@penti.org
Post by Laurent FAILLIE
Hello,
I googled but w/o success ... can someone point me out a tutorial or
at least an example of I2C slave programming with SDcc on PIC (I'm
using 16F88) ?
I don't know if the 16F88 has a hardware I2C circuit, but if it has,
// Send an I2C start sequence
void I2Cstart()
{
  SEN=1;
  while(SEN) {
  }
  SSPIF=0;
}
// Send an I2C STOP sequence
void I2Cstop()
{
  PEN=1;
  while(PEN) {
  }
  SSPIF=0;
}
// Send a repeated START
void I2Crestart()
{
  RSEN=1;
  while(RSEN) {
  }
  SSPIF=0;
}
These were the control signals, next is what I used for the data,
after calling relevant previous functions (never mind my comments, I
// Shift one byte of data to the bus.
// As of this version, no error checing is done. The function
// assumes the receiver sends an "Acknowledged".
void I2Cwrite(unsigned char c)
{
  SSPBUF=c;
  while(!SSPIF);
  SSPIF=0;
}
// Shift in one byte from the bus and then sends and "Acknowledge"
unsigned char I2Cread(unsigned char ack)
{
  unsigned char c;
  RCEN=1;
  while(!BF);
  c=SSPBUF;
  if(ack) {
    ACKDT=0;
  }
  else {
    ACKDT=1;
  }
  ACKEN=1;
  return(c);
}
************************************
Then, the bit-banged version, if you don't have proper I2C hardware.
SDA=PORTB4
SCL=PORTB6
(You can try without the delays, for me it was just for being on the
safe side)
void I2Cstart(void)
{
  SCL=0;
  I2Cdelay();
  SDA=1;
  I2Cdelay();
  SCL=1;
  I2Cdelay();
  SDA=0;
  I2Cdelay();
}
void I2Cstop(void)
{
  SDA=0;
  I2Cdelay();
  SCL=1;
  I2Cdelay();
  SDA=1;
  I2Cdelay();
}
void I2Cwrite(unsigned char c)
{
  signed char i;
  SCL=0;
  I2Cdelay();
  for(i=7 ; i>=0 ; i--) {
    SDA=((c>>i)&0x01);
    I2Cdelay();
    SCL=1;
    I2Cdelay();
    while(SCL_RD==0) {  // Ensure the clock has been released by the slave
    }
    SCL=0;
    I2Cdelay();
  }
  I2Cdelay();
  while(SDA_RD) {       // wait for ack
  }
  SCL=1;
  I2Cdelay();
  I2Cdelay();
  I2Cdelay();
}
unsigned char I2Cread(unsigned char ack)
{
  unsigned char i,byte;
  byte=0x00;
  SCL=0;
  for(i=0;i<8;i++) {
    I2Cdelay();
    SDA=1;
    SCL=1;
    while(SCL_RD==0) {  // Clock stretch
    }
    I2Cdelay();
    byte=byte << 1;
    byte |= (SDA_RD & 0x01);
    I2Cdelay();
    SCL=0;
  }
  I2Cdelay();
  if(ack==0) {
    SDA=1;
    I2Cdelay();
    SCL=1;
    I2Cdelay();
    SCL=0;
    I2Cdelay();
  }
  else {
    SDA=0;
    I2Cdelay();
    SCL=1;
    I2Cdelay();
    SCL=0;
  }
  return(byte);
}
Note: I haven't bothered with error checking or things like that, you
may want to add some later on...
I hope this helps at all.
Regards, Robert
------------------------------------------------------------------------------
This SF.net email is sponsored by Sprint
What will you do first with EVO, the first 4G phone?
Visit sprint.com/first -- http://p.sf.net/sfu/sprint-com-first
_______________________________________________
Sdcc-user mailing list
https://lists.sourceforge.net/lists/listinfo/sdcc-user
Laurent FAILLIE
2010-07-09 07:42:48 UTC
Permalink
Thanks Robert for your mail : I'll certainly use you code for my PICs haven't I2C hardware.

Pic 16F88 have the needed hardware and I did notice those function in libio lib.
But my question is more having a full example, from 0 to a workable tiny application :
- initialization to do,
- choregraphy
- checks

Thanks

Laurent

---
The misspelling master is on the Web.
_________ 100 % Dictionnary Free !
/ /(
/ Dico / / Pleins d'autres fautes sur
/________/ /
(#######( / http://destroyedlolo.homeunix.org
Quoi, des fautes d'orthographe! Pas possible ;-D.

A voir aussi : http://sillingy.clubphotos.fr , le site du
photo club de ... Sillingy.
Objet: Re: [Sdcc-user] Example or tutorial for I2C usage with PIC
Date: Jeudi 8 juillet 2010, 2h47
Post by Laurent FAILLIE
Hello,
I googled but w/o success ... can someone point me out
a tutorial or 
Post by Laurent FAILLIE
at least an example of I2C slave programming with SDcc
on PIC (I'm 
Post by Laurent FAILLIE
using 16F88) ?
I don't know if the 16F88 has a hardware I2C circuit, but
if it has, 
// Send an I2C start sequence
void I2Cstart()
{
   SEN=1;
   while(SEN) {
   }
   SSPIF=0;
}
// Send an I2C STOP sequence
void I2Cstop()
{
   PEN=1;
   while(PEN) {
   }
   SSPIF=0;
}
// Send a repeated START
void I2Crestart()
{
   RSEN=1;
   while(RSEN) {
   }
   SSPIF=0;
}
These were the control signals, next is what I used for the
data, 
after calling relevant previous functions (never mind my
comments, I 
// Shift one byte of data to the bus.
// As of this version, no error checing is done. The
function
// assumes the receiver sends an "Acknowledged".
void I2Cwrite(unsigned char c)
{
   SSPBUF=c;
   while(!SSPIF);
   SSPIF=0;
}
// Shift in one byte from the bus and then sends and
"Acknowledge"
unsigned char I2Cread(unsigned char ack)
{
   unsigned char c;
   RCEN=1;
   while(!BF);
   c=SSPBUF;
   if(ack) {
     ACKDT=0;
   }
   else {
     ACKDT=1;
   }
   ACKEN=1;
   return(c);
}
************************************
Then, the bit-banged version, if you don't have proper I2C
hardware. 
SDA=PORTB4
SCL=PORTB6
(You can try without the delays, for me it was just for
being on the 
safe side)
void I2Cstart(void)
{
   SCL=0;
   I2Cdelay();
   SDA=1;
   I2Cdelay();
   SCL=1;
   I2Cdelay();
   SDA=0;
   I2Cdelay();
}
void I2Cstop(void)
{
   SDA=0;
   I2Cdelay();
   SCL=1;
   I2Cdelay();
   SDA=1;
   I2Cdelay();
}
void I2Cwrite(unsigned char c)
{
   signed char i;
   SCL=0;
   I2Cdelay();
   for(i=7 ; i>=0 ; i--) {
     SDA=((c>>i)&0x01);
     I2Cdelay();
     SCL=1;
     I2Cdelay();
     while(SCL_RD==0) {  // Ensure
the clock has been released by the slave
     }
     SCL=0;
     I2Cdelay();
   }
   I2Cdelay();
   while(SDA_RD) {   
   // wait for ack
   }
   SCL=1;
   I2Cdelay();
   I2Cdelay();
   I2Cdelay();
}
unsigned char I2Cread(unsigned char ack)
{
   unsigned char i,byte;
   byte=0x00;
   SCL=0;
   for(i=0;i<8;i++) {
     I2Cdelay();
     SDA=1;
     SCL=1;
     while(SCL_RD==0) {  // Clock
stretch
     }
     I2Cdelay();
     byte=byte << 1;
     byte |= (SDA_RD & 0x01);
     I2Cdelay();
     SCL=0;
   }
   I2Cdelay();
   if(ack==0) {
     SDA=1;
     I2Cdelay();
     SCL=1;
     I2Cdelay();
     SCL=0;
     I2Cdelay();
   }
   else {
     SDA=0;
     I2Cdelay();
     SCL=1;
     I2Cdelay();
     SCL=0;
   }
   return(byte);
}
Note: I haven't bothered with error checking or things like
that, you 
may want to add some later on...
I hope this helps at all.
Regards, Robert
------------------------------------------------------------------------------
This SF.net email is sponsored by Sprint
What will you do first with EVO, the first 4G phone?
Visit sprint.com/first -- http://p.sf.net/sfu/sprint-com-first
_______________________________________________
Sdcc-user mailing list
https://lists.sourceforge.net/lists/listinfo/sdcc-user
Robert Bergfors
2010-07-09 12:19:24 UTC
Permalink
Post by Laurent FAILLIE
Thanks Robert for your mail : I'll certainly use you code for my PICs haven't I2C hardware.
Pic 16F88 have the needed hardware and I did notice those function in libio lib.
- initialization to do,
- choregraphy
- checks
Thanks
Laurent
Hello Laurent,

It's a long long time since I programmed all of this, but the
I2C-specific initialation that I used (for running a PIC16F886 as I2C
master) looks like this, some of it may be unnecessary, but I added
them to be on the safe side. I now regret not commenting the code more
thorougly... I do not, however, have any experience with the 16F88,
but as I understand it, it should be almost the same as 16F88X
series...? At least the registers seem to have the same names.

{
TRISC3=1;
TRISC4=1;
SMP=1;
WCOL=0;
SSPOV=0;
SSPEN=1;
CKP=1;
SSPCON=SSPCON&0xf0;
SSPCON=SSPCON|0x08;
GCEN=0;
ACKSTAT=0;
ACKDT=0;
ACKEN=0;
RCEN=0;
PEN=0;
RSEN=0;
SEN=0;
SSPADD=15;
}


Basicly what I did was just read the PIC datasheet really carefylly
and set all the relevant registers I could find, I never used any
library functions for anything.
For the 16F886:
SSPSTAT contains the various flags to check.
SSPCON contains the registers to set, and most stuff that follows
SSPCON in the above code are part of the SSPCON2 register.


Then I just sit and wait for an external interrupt that makes the
program read out one byte from the slave, in this case a 1Hz square
wave output from the RTC DS1337 which triggers the PIC to read out the
clocktime from the RTC.

void RTCputc(unsigned char addr, unsigned char c_data)

{
unsigned char c;
c=(RTC_ADDR<<1)&0xfe;; // recalculate the I2C address & write bit
I2Cstart();
I2Cwrite(c); // send the RTC address to the bus
I2Cwrite(addr); // send the RTC internal memory location
I2Cwrite(c_data); // send the data to that location
I2Cstop();
}


unsigned char RTCgetc(unsigned char addr)
{
unsigned char c;
c=(RTC_ADDR<<1)&0xfe; // recalculate the I2C address & write bit
I2Cstart();
I2Cwrite(c); // Send the RTC's I2C address
I2Cwrite(addr); // RTC internal memory location to be read
I2Crestart();
c=c|0x01; // swap the Read/write bit
I2Cwrite(c); // resend the address
c=I2Cread(0); // read one byte, passing the ACK/NAK bit
I2Cstop();
return(c);
}

I hope I answered the right question this time :o)
If you want, I could send the entire project as a .tar.gz, it's a
school project and contains no secrets, only perhaps bad ideas :o)

Best Regards, Robert
Laurent FAILLIE
2010-07-09 13:25:56 UTC
Permalink
Thanks Robert :)
I'll keep also this mail which help me for my server coding (on a PC under Linux).

But my concern is using this PIC as a slave. Any code for that ?

Thanks

Laurent

PS: when it's working, I'll put some workable example code on my own site because I don't think I'm the only one with such question ;D

---
The misspelling master is on the Web.
_________ 100 % Dictionnary Free !
/ /(
/ Dico / / Pleins d'autres fautes sur
/________/ /
(#######( / http://destroyedlolo.homeunix.org
Quoi, des fautes d'orthographe! Pas possible ;-D.

A voir aussi : http://sillingy.clubphotos.fr , le site du
photo club de ... Sillingy.
Objet: Re: [Sdcc-user] Example or tutorial for I2C usage with PIC
Date: Vendredi 9 juillet 2010, 14h19
Post by Laurent FAILLIE
Thanks Robert for your mail : I'll certainly use you
code for my 
Post by Laurent FAILLIE
PICs haven't I2C hardware.
Pic 16F88 have the needed hardware and I did notice
those function 
Post by Laurent FAILLIE
in libio lib.
But my question is more having a full example, from 0
to a workable 
Post by Laurent FAILLIE
- initialization to do,
- choregraphy
- checks
Thanks
Laurent
Hello Laurent,
It's a long long time since I programmed all of this, but
the 
I2C-specific initialation that I used (for running a
PIC16F886 as I2C 
master) looks like this, some of it may be unnecessary, but
I added 
them to be on the safe side. I now regret not commenting
the code more 
thorougly... I do not, however, have any experience with
the 16F88, 
but as I understand it, it should be almost the same as
16F88X 
series...? At least the registers seem to have the same
names.
{
   TRISC3=1;
   TRISC4=1;
   SMP=1;
   WCOL=0;
   SSPOV=0;
   SSPEN=1;
   CKP=1;
   SSPCON=SSPCON&0xf0;
   SSPCON=SSPCON|0x08;
   GCEN=0;
   ACKSTAT=0;
   ACKDT=0;
   ACKEN=0;
   RCEN=0;
   PEN=0;
   RSEN=0;
   SEN=0;
   SSPADD=15;
}
Basicly what I did was just read the PIC datasheet really
carefylly 
and set all the relevant registers I could find, I never
used any 
library functions for anything.
SSPSTAT contains the various flags to check.
SSPCON contains the registers to set, and most stuff that
follows 
SSPCON in the above code are part of the SSPCON2 register.
Then I just sit and wait for an external interrupt that
makes the 
program read out one byte from the slave, in this case a
1Hz square 
wave output from the RTC DS1337 which triggers the PIC to
read out the 
clocktime from the RTC.
void RTCputc(unsigned char addr, unsigned char c_data)
{
   unsigned char c;
   c=(RTC_ADDR<<1)&0xfe;;  //
recalculate the I2C address & write bit
   I2Cstart();
   I2Cwrite(c);      // send
the RTC address to the bus
   I2Cwrite(addr);   // send
the RTC internal memory location
   I2Cwrite(c_data); // send the data to
that location
   I2Cstop();
}
unsigned char RTCgetc(unsigned char addr)
{
   unsigned char c;
   c=(RTC_ADDR<<1)&0xfe; //
recalculate the I2C address & write bit
   I2Cstart();
   I2Cwrite(c);       
// Send the RTC's I2C address
   I2Cwrite(addr); 
   // RTC internal memory location to be
read
   I2Crestart();
   c=c|0x01;       
   // swap the Read/write bit
   I2Cwrite(c);       
// resend the address
   c=I2Cread(0);   
   // read one byte, passing the ACK/NAK bit
   I2Cstop();
   return(c);
}
I hope I answered the right question this time :o)
If you want, I could send the entire project as a .tar.gz,
it's a 
school project and contains no secrets, only perhaps bad
ideas :o)
Best Regards, Robert
------------------------------------------------------------------------------
This SF.net email is sponsored by Sprint
What will you do first with EVO, the first 4G phone?
Visit sprint.com/first -- http://p.sf.net/sfu/sprint-com-first
_______________________________________________
Sdcc-user mailing list
https://lists.sourceforge.net/lists/listinfo/sdcc-user
Sébastien Lorquet
2010-07-09 13:37:58 UTC
Permalink
Post by Laurent FAILLIE
Thanks Robert :)
I'll keep also this mail which help me for my server coding (on a PC under Linux).
But my concern is using this PIC as a slave. Any code for that ?
Nothing new since http://github.com/texane/pic18f_i2c from fabien lementec.
There's always the Microchip AN 734 document for the moment.
http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1824&appnote=en011798
Does not look rocket science.
Post by Laurent FAILLIE
Thanks
Laurent
PS: when it's working, I'll put some workable example code on my own site
because I don't think I'm the only one with such question ;D
Totally agreed. I coded an I2C master yesterday evening. I'll start coding
the slave for PIC18 in the following days and post the related code.
My device will emulate a 7 bit slave with some registers accessed like this:

write(adr,reg) : START <DEVICE_ADDR_W> <adr> <dat> STOP
read(adr): START <DEVICE_ADDR_W> <adr> RESTART <DEVICE_ADDR_R> <dat> STOP

Regards
Sebastien
Laurent FAILLIE
2010-07-12 07:26:06 UTC
Permalink
Thanks a lot.

I'll go thru the provided links :)

Bye

Laurent

--- En date de : Ven 9.7.10, Sébastien Lorquet <***@gmail.com> a écrit :

De: Sébastien Lorquet <***@gmail.com>
Objet: Re: [Sdcc-user] Example or tutorial for I2C usage with PIC
À: "sdcc-user" <sdcc-***@lists.sourceforge.net>
Date: Vendredi 9 juillet 2010, 15h37



On Fri, Jul 9, 2010 at 3:25 PM, Laurent FAILLIE <***@yahoo.com> wrote:

Thanks Robert :)

I'll keep also this mail which help me for my server coding (on a PC under Linux).



But my concern is using this PIC as a slave. Any code for that ?
 Nothing new since http://github.com/texane/pic18f_i2c from fabien lementec.

There's always the Microchip AN 734 document for the moment.
http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1824&appnote=en011798

Does not look rocket science.




Thanks



Laurent



PS: when it's working, I'll put some workable example code on my own site because I don't think I'm the only one with such question ;D

Totally agreed. I coded an I2C master yesterday evening. I'll start coding the slave for PIC18 in the following days and post the related code.

My device will emulate a 7 bit slave with some registers accessed like this:

write(adr,reg) : START <DEVICE_ADDR_W> <adr> <dat> STOP
 read(adr): START <DEVICE_ADDR_W> <adr> RESTART <DEVICE_ADDR_R> <dat> STOP


Regards
Sebastien



-----La pièce jointe associée suit-----
Sébastien Lorquet
2010-07-15 22:20:43 UTC
Permalink
hi,

Here is the picture of the PIC that will be a I2C slave. The encoding wheel
defines the slave address' LSbits.

http://www.mirari.fr/vF00

the console will help with debugging :)

coupled with the DAC this will make a configurable AFSK modulator.

I'm now working on the firmware, using SDCC in mplab.

Sebastien
Sébastien Lorquet
2010-07-19 14:26:18 UTC
Permalink
Hi,

appnote 736 has additional information about I2C slave inner workings,
including flow charts.

http://ww1.microchip.com/downloads/en/AppNotes/00736a.pdf

Sebastien
Sébastien Lorquet
2010-07-25 13:03:26 UTC
Permalink
Hi,

I got the i2c slave working, based on the explanations from the application
note AN734.
My code emulates a 128 bytes RAM.

You can read and write registers.
To write, use:

START ADDR+W REG_ADDRESS_BASE DATA DATA DATA... STOP
ADDR+W is the slave address with the LSB cleared (write)
REG_ADDR_BASE is the address of the first register you want to write
DATA are the bytes you want to write from this address.

Read is a bit longer. You have to start a write transaction with no data
(just the reg addr), then restart and go to read mode.
START ADDR+W REG_ADDRESS_BASE STOP
START ADDR+R <data+ACK>....<data+NACK> STOP

=================
ALL THE CODE THAT FOLLOWS IS PUBLIC DOMAIN.
=================

I defined the following useful constants

// DA S RW BF
#define I2C_SLAVE_STATE_MASK 0x2D // - - X - X X - X
#define I2C_SLAVE_STATE_1 0x09 // - - 0 - 1 0 - 1 DA=0 S=1 RW=0 BF=1
#define I2C_SLAVE_STATE_2 0x29 // - - 1 - 1 0 - 1 DA=1 S=1 RW=0 BF=1
#define I2C_SLAVE_STATE_3_MASK 0x2C // - - X - X X - - da,s,rw
#define I2C_SLAVE_STATE_3 0x0C // - - 0 - 1 1 - - DA=0 S=1 RW=1
#define I2C_SLAVE_STATE_4 0x2C // - - 1 - 1 1 - 0 DA=1 S=1 RW=1 BF=0 CKP=0
#define I2C_SLAVE_STATE_5_MASK 0x28 // - - X - X - - - da,s
#define I2C_SLAVE_STATE_5 0x28 // - - 1 - 1 0 - 0 DA=1 S=1 CKP=1

I used the following variables

#define I2C_REG_SIZE 128
static unsigned char i2c_regs[I2C_REG_SIZE]; //actual memory storage
static unsigned char i2c_reg_addr; //current memory address, where the
operation will take place
static unsigned char i2c_first_data; //true when we are about to get the
first data byte, ie register address
static unsigned char i2c_status; //masked SSPSTAT value
static unsigned char i2c_data; //temporary storage for data
#ifdef I2C_DEBUG
static unsigned char flag;
#endif


The initialization code defines the MSSP macrocell configuration. The slave
address is defined here.
the code from fabien lementec initializes the slave with 0x26 instead of
0x36, which I don't like. I prefer initializing CKP to 1 to be sure the
clock line is released. Apart from that, the initialization is very similar.

//-------------------------------------------------------------------------------------------
//Setup the pic peripheral
void i2c_slave_setup(unsigned char addr)
{
TRISCbits.TRISC3 = 1;
TRISCbits.TRISC4 = 1;
SSPCON1 = 0x36; //7-bit I2C slave, no IRQ on start/stop
//SSPCON2bits.SEN = 1; //enable clock stretching
SSPADD = (addr<<1);
PIE1bits.SSPIE = 1;
PIR1bits.SSPIF = 0;
//init vars
i2c_reg_addr = 0;
i2c_first_data = 0;
}

The slave is interrupt driven.

Algorithm:

There are 5 states, defined by the value in the SSPSTAT register

State 1 is triggered when the slave receives the address byte with the RW
flag cleared, ie we start a write transaction.
State 2 is triggered when more bytes are sent by the master. Here, we want
to discriminate the first one which is the register address, but a PCF8574
is even simpler than that
State 3 is triggered when we just got an address byte with the RW flag set,
ie when we are READY to send the first byte of the read transaction. Now you
understand that we must first write the register address byte before reading
anything.
State 4 is triggered when we are READY to send the next bytes.
State 5 is triggered after the master sent a NACK in a read transaction.

There are two MSSP macrocells in PIC devices: PIC16 and devices listed in
AN734 page 17 have the OLD state machine, all other PIC18 have the NEW state
machine.
With the NEW machine, in state 3, we MUST read SSPBUF or the read operation
will fail. This is what prevented me from posting this code earlier! There
is no need to read SSPBUF in state 4.

So with new PICs, you have to
#define I2C_SLAVE_NEW

This does not follow the state machine from fabien, I didn't try his code,
but I guess mine is more straightforward, with less if() statements.

Here is the code:

//-------------------------------------------------------------------------------------------
//Manage I2C slave events
SIGHANDLER(i2c_slave_isr)
{
//no local variables here for faster response times
i2c_status = SSPSTAT & I2C_SLAVE_STATE_MASK; //Mask useless bits
#ifdef I2C_DEBUG
ser_putchar('[');
ser_puthb(i2c_status);
ser_putchar(']');
#endif

//--------------------
// state 1: just got an address byte for a write transaction.
//--------------------
if(i2c_status == I2C_SLAVE_STATE_1) {
i2c_first_data = 1; //next byte will be the register address
//dummy read the buffer to clear BF
i2c_data = SSPBUF;
#ifdef I2C_DEBUG
ser_putchar('1');
#endif
goto i2c_slave_exit;
}
//--------------------
// state 2: just got a data byte in a write transaction.
//--------------------
if(i2c_status == I2C_SLAVE_STATE_2) {
i2c_data = SSPBUF; //read data to clear BF
if(i2c_first_data) { //this is the first data byte, store into the register
address
i2c_first_data = 0;
i2c_reg_addr = i2c_data;
#ifdef I2C_DEBUG
flag=0;
#endif
} else { //next bytes are really data
if(i2c_reg_addr<I2C_REG_SIZE) {
i2c_regs[i2c_reg_addr] = i2c_data;
i2c_reg_addr++; //next write will go to next register
#ifdef I2C_DEBUG
flag=1;
#endif
}
}
#ifdef I2C_DEBUG
ser_putchar('2');
ser_putchar('<');
if(flag==0) {
ser_putchar('@');
ser_puthb(i2c_reg_addr);
}else {
ser_puthb(i2c_reg_addr-1);
ser_putchar(':');
ser_puthb(i2c_data);
}
ser_putchar('>');
#endif
goto i2c_slave_exit;
}
//--------------------
// state 3: just got an address byte for a read transaction. ready to fill
buffer for next read.
//--------------------
if( (i2c_status & I2C_SLAVE_STATE_3_MASK) == I2C_SLAVE_STATE_3) {
#ifdef I2C_SLAVE_NEW
//SSPBUF must be read
i2c_data = SSPBUF;
#endif
if(i2c_reg_addr<I2C_REG_SIZE) {
i2c_data = i2c_regs[i2c_reg_addr];
i2c_reg_addr++;
} else {
i2c_data = 0xFF;
}
while(SSPSTATbits.BF==1); //wait for previous byte to be read
SSPCON1bits.WCOL=0;
redowrite3:
SSPBUF = i2c_data;
if(SSPCON1bits.WCOL) goto redowrite3;
//Release clock
SSPCON1bits.CKP = 1;

#ifdef I2C_DEBUG
ser_putchar('3');
ser_putchar('<');
ser_puthb(i2c_reg_addr-1);
ser_putchar(':');
ser_puthb(i2c_data);
ser_putchar('>');
#endif
goto i2c_slave_exit;
}
//--------------------
//state 4: a byte has just been read by the master. ready to fill buffer for
next read.
//--------------------
if(i2c_status == I2C_SLAVE_STATE_4) {
if(SSPCON1bits.CKP) {
//CKP=1 means state 5!
#ifdef I2C_DEBUG
ser_putchar('!');
#endif
goto i2c_slave_state_5;
}
if(i2c_reg_addr<I2C_REG_SIZE) {
i2c_data = i2c_regs[i2c_reg_addr];
i2c_reg_addr++;
} else {
i2c_data = 0xFF;
}
while(SSPSTATbits.BF==1); //wait for previous byte to be read
SSPCON1bits.WCOL=0;
redowrite4:
SSPBUF = i2c_data;
if(SSPCON1bits.WCOL) goto redowrite4;

//Release clock
SSPCON1bits.CKP = 1;

#ifdef I2C_DEBUG
ser_putchar('4');
ser_putchar('<');
ser_puthb(i2c_reg_addr-1);
ser_putchar(':');
ser_puthb(i2c_data);
ser_putchar('>');
#endif
goto i2c_slave_exit;
}
//--------------------
//state 5: just got a NACK from the master, this is the end of a read
transaction
//--------------------
i2c_slave_state_5:
if( (i2c_status & I2C_SLAVE_STATE_5_MASK) == I2C_SLAVE_STATE_5) {
#ifdef I2C_DEBUG
ser_putchar('5');
#endif
goto i2c_slave_exit;
}

//error... just reset!
#ifdef I2C_DEBUG
ser_putchar('X');
#endif
Reset();
i2c_slave_exit:
PIR1bits.SSPIF = 0; //ACK interrupt or the next one will to be triggered!
}



Here is a sample of state sequences with SSPSTAT values for a write
transaction:

I did not trigger any interruption on start/stop bit.

When I send START ADDRW 00 50 51 52 STOP, I get:
[09]1
[29]2<@00>
[29]2<00:50>
[29]2<01:51>
[29]2<02:52>

For a read transaction:
START ADDRW 00 RESTART READACK READACK READACK READNACK STOP

[09]1
[29]2<@00>
[0D]3<00:50>
[2C]4<01:51>
[2C]4<02:52>
[2C]4<03:00>
[2C]!5

A read transaction for a single byte at register address 0 with no ack
gives:

[09]1
[29]2<@00>
[0D]3<00:50>
[2C]!5


I release this code with the purpose of helping anyone who need an i2c
slave. There is no restriction on it.
Enjoy and report problems you found!
Please ask questions!

Sebastien
Laurent FAILLIE
2010-07-25 19:23:59 UTC
Permalink
Thanks a lot :)

I'll cross datasheet and you code to build my own one :)

Bye

Laurent
Laurent FAILLIE
2010-07-30 13:22:49 UTC
Permalink
Salut Sebastien,

est-ce que tu pourrai m'envoyer ton code complet.
Je suis aussi béotien avec l'USART et donc cette partie du code m'interesse aussi :).

Merci

Laurent

---
The misspelling master is on the Web.

_________ 100 % Dictionnary Free !
/ /(
/ Dico / / Pleins d'autres fautes sur
/________/ /
(#######( / http://destroyedlolo.homeunix.org

Quoi, des fautes d'orthographe! Pas possible ;-D.

A voir aussi : http://sillingy.clubphotos.fr , le site du
photo club de ... Sillingy.
Sébastien Lorquet
2010-07-30 14:51:31 UTC
Permalink
The code I gave was quite complete.
here is some uart code; for ease of use it is not interrupt driven.
This is FAR more simpler than an i2c slave.

a few more LOC are needed for a main() that calls initialization methods,
set pin directions, and globally enable interrupts
you also need a DEFINE_INT..... as described in sdcc documentation.

Sebastien.

//-------------------------------------------------------------------------------------------
//initialize the serial port
void ser_setup()
{
//configure the serial port
TXSTAbits.SYNC = 0; //asynchronous mode
RCSTAbits.SPEN = 1; //enable serial port
RCSTAbits.CREN = 1; //enable receiver
TRISCbits.TRISC6 = 0; //set txd as output
TRISCbits.TRISC7 = 1; //set rxd as input

TXSTAbits.BRGH = 1; //baud = fosc/(16(X+1)) X=(fosc/(16bauds))-1
SPBRG = ...;
}

//-------------------------------------------------------------------------------------------
//Transmit a byte.
void ser_putchar(char car)
{
TXREG = car;
TXSTAbits.TXEN=1; //enable transmission
//Wait for completion
while(TXSTAbits.TRMT==0);
}

//-------------------------------------------------------------------------------------------
//read a byte
char ser_getchar()
{
//wait until something is received
while(PIR1bits.RCIF==0);
return RCREG;
}

tested to work perfectly on pic18f452 and pic18f2620, will also probably
work for other.

You just have to calculate proper BRGH value to get the correct baud rate

Sebastien
Laurent FAILLIE
2010-07-30 15:24:33 UTC
Permalink
Thanks again :)
Sébastien Lorquet
2010-08-01 11:25:33 UTC
Permalink
Additional note: for a PIC18 with an EUSART, like the pic18f4455 or 18f4685,
you need to ensure that the BRG16 bit in BAUDCON is cleared.

I just solved a problem related to that.

Sebastien
Post by Laurent FAILLIE
Thanks again :)
------------------------------------------------------------------------------
The Palm PDK Hot Apps Program offers developers who use the
Plug-In Development Kit to bring their C/C++ apps to Palm for a share
http://p.sf.net/sfu/dev2dev-palm
_______________________________________________
Sdcc-user mailing list
https://lists.sourceforge.net/lists/listinfo/sdcc-user
Continue reading on narkive:
Loading...