i2c_master.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. /*********************************************************************
  2. *
  3. * i2c master library for Fraise pic18f device
  4. *********************************************************************
  5. * Author Date Comment
  6. *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  7. * Antoine Rousseau october 2013 adapted from Vangelis Rokas's sdcc i2c lib.
  8. ********************************************************************/
  9. /*
  10. # This program is free software; you can redistribute it and/or
  11. # modify it under the terms of the GNU General Public License
  12. # as published by the Free Software Foundation; either version 2
  13. # of the License, or (at your option) any later version.
  14. #
  15. # This program is distributed in the hope that it will be useful,
  16. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. # GNU General Public License for more details.
  19. # You should have received a copy of the GNU General Public License
  20. # along with this program; if not, write to the Free Software
  21. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  22. # MA 02110-1301, USA.
  23. */
  24. #include <core.h>
  25. #include <i2c_master.h>
  26. #ifndef I2CMASTER_PORT
  27. #define I2CMASTER_PORT 1
  28. #endif
  29. #if I2CMASTER_PORT==1
  30. #define SSPxBUF SSPBUF
  31. #define SSPxCON1 SSPCON1
  32. #define SSPxCON1bits SSPCON1bits
  33. #define SSPxCON2 SSPCON2
  34. #define SSPxCON2bits SSPCON2bits
  35. #define SSPxCON3 SSPCON3
  36. #define SSPxCON3bits SSPCON3bits
  37. #define SSPxSTAT SSPSTAT
  38. #define SSPxSTATbits SSPSTATbits
  39. #define SSPxMSK SSPMSK
  40. #define SSPxMSKbits SSPMSKbits
  41. #define SSPxADD SSPADD
  42. #define SSPxADDbits SSPADDbits
  43. #define SSPxIF PIR1bits.SSPIF
  44. #define SSPxIE PIE1bits.SSPIE
  45. #define SSPxIP PIR1bits.SSPIP
  46. #define BCLxIF PIR2bits.BCLIF
  47. /*#define SSPxBUF SSP1BUF
  48. #define SSPxCON1 SSP1CON1
  49. #define SSPxCON1bits SSP1CON1bits
  50. #define SSPxCON2 SSP1CON2
  51. #define SSPxCON2bits SSP1CON2bits
  52. #define SSPxCON3 SSP1CON3
  53. #define SSPxCON3bits SSP1CON3bits
  54. #define SSPxSTAT SSP1STAT
  55. #define SSPxSTATbits SSP1STATbits
  56. #define SSPxMSK SSP1MSK
  57. #define SSPxMSKbits SSP1MSKbits
  58. #define SSPxADD SSP1ADD
  59. #define SSPxADDbits SSP1ADDbits
  60. #define SSPxIF PIR1bits.SSP1IF
  61. #define SSPxIE PIE1bits.SSP1IE
  62. #define SSPxIP PIR1bits.SSP1IP
  63. #define BCLxIF PIR2bits.BCL1IF*/
  64. #else
  65. #define SSPxBUF SSP2BUF
  66. #define SSPxCON1 SSP2CON1
  67. #define SSPxCON1bits SSP2CON1bits
  68. #define SSPxCON2 SSP2CON2
  69. #define SSPxCON2bits SSP2CON2bits
  70. #define SSPxCON3 SSP2CON3
  71. #define SSPxCON3bits SSP2CON3bits
  72. #define SSPxSTAT SSP2STAT
  73. #define SSPxSTATbits SSP2STATbits
  74. #define SSPxMSK SSP2MSK
  75. #define SSPxMSKbits SSP2MSKbits
  76. #define SSPxADD SSP2ADD
  77. #define SSPxADDbits SSP2ADDbits
  78. #define SSPxIF PIR3bits.SSP2IF
  79. #define SSPxIE PIE3bits.SSP2IE
  80. #define SSPxIP PIR3bits.SSP2IP
  81. #define BCLxIF PIR3bits.BCL2IF
  82. #endif
  83. /*#ifndef SSP1CON1
  84. #define SSPxBUF SSPBUF
  85. #define SSPxCON1 SSPCON1
  86. #define SSPxCON1bits SSPCON1bits
  87. #define SSPxCON2 SSPCON2
  88. #define SSPxCON2bits SSPCON2bits
  89. #define SSPxCON3 SSPCON3
  90. #define SSPxCON3bits SSPCON3bits
  91. #define SSPxSTAT SSPSTAT
  92. #define SSPxSTATbits SSPSTATbits
  93. #define SSPxMSK SSPMSK
  94. #define SSPxMSKbits SSPMSKbits
  95. #define SSPxADD SSPADD
  96. #define SSPxADDbits SSPADDbits
  97. #define SSPxIF PIR1bits.SSPIF
  98. #define SSPxIE PIE1bits.SSPIE
  99. #define SSPxIP PIR1bits.SSPIP
  100. #define BCLxIF PIR2bits.BCLIF
  101. #endif*/
  102. void i2cm_init(unsigned char mode, unsigned char slew, unsigned char addr_brd)
  103. {
  104. SSPxSTAT &= 0x3f;
  105. SSPxCON1 = 0;
  106. SSPxCON2 = 0;
  107. SSPxCON1 |= mode;
  108. SSPxSTAT |= slew;
  109. #if I2CMASTER_PORT==1
  110. SetPinDigiIn(I2C1SDA);
  111. SetPinDigiIn(I2C1SCL);
  112. SetPinAnsel(I2C1SDA,0);
  113. SetPinAnsel(I2C1SCL,0);
  114. #else
  115. SetPinDigiIn(I2C2SDA);
  116. SetPinDigiIn(I2C2SCL);
  117. SetPinAnsel(I2C2SDA,0);
  118. SetPinAnsel(I2C2SCL,0);
  119. #endif
  120. SSPxADD = addr_brd;
  121. SSPxCON1 |= 0x20; // enable SSP
  122. SSPxIF = 0; // MSSP Interrupt Flag
  123. BCLxIF = 0; // Bus Collision Interrupt Flag
  124. }
  125. void i2cm_close(void)
  126. {
  127. SSPxCON1 &= 0xdf;
  128. }
  129. /*--------------------------------------*/
  130. unsigned char i2cm_drdy(void)
  131. {
  132. if(SSPxSTATbits.BF) return (+1);
  133. else return (0);
  134. }
  135. void i2cm_idle(void)
  136. {
  137. while((SSPxCON2 & 0x1f) | (SSPxSTATbits.R_W));
  138. }
  139. void i2cm_start(void)
  140. {
  141. i2cm_idle();
  142. SSPxCON2bits.SEN = 1;
  143. while (SSPxCON2bits.SEN);
  144. }
  145. void i2cm_restart(void)
  146. {
  147. i2cm_idle();
  148. SSPxCON2bits.RSEN = 1;
  149. while (SSPxCON2bits.RSEN);
  150. }
  151. void i2cm_stop(void)
  152. {
  153. i2cm_idle();
  154. SSPxCON2bits.PEN = 1;
  155. while (SSPxCON2bits.PEN);
  156. }
  157. void i2cm_ack(void)
  158. {
  159. i2cm_idle();
  160. SSPxIF = 0;
  161. SSPxCON2bits.ACKDT = 0;
  162. SSPxCON2bits.ACKEN = 1;
  163. while (!SSPxIF);
  164. }
  165. void i2cm_nack(void)
  166. {
  167. i2cm_idle();
  168. SSPxIF = 0;
  169. SSPxCON2bits.ACKDT = 1;
  170. SSPxCON2bits.ACKEN = 1;
  171. while (!SSPxIF);
  172. }
  173. /*--------------------------------------*/
  174. unsigned char i2cm_readchar(void)
  175. {
  176. i2cm_idle();
  177. SSPxCON2bits.RCEN = 1;
  178. while( !i2cm_drdy() );
  179. return ( SSPxBUF );
  180. }
  181. char i2cm_readstr(_I2CPARAM_SPEC unsigned char *ptr, unsigned char len)
  182. {
  183. unsigned char count=0;
  184. while( len-- ) {
  185. *ptr++ = i2cm_readchar();
  186. while(SSPxCON2bits.RCEN) {
  187. if(BCLxIF)return (-1);
  188. count++;
  189. if(len) {
  190. i2cm_ack();
  191. while(SSPxCON2bits.ACKEN);
  192. }
  193. }
  194. }
  195. return count;
  196. }
  197. char i2cm_writechar(unsigned char dat)
  198. {
  199. SSPxCON1bits.WCOL = 0;
  200. SSPxBUF = dat;
  201. if( SSPxCON1bits.WCOL ) {
  202. return -1;
  203. } else {
  204. i2cm_idle();
  205. return 0;
  206. }
  207. }
  208. char i2cm_writestr(unsigned char *ptr)
  209. {
  210. while( *ptr ) {
  211. if( SSPxCON1bits.SSPM3 ) {
  212. if(i2cm_writechar( *ptr )) {
  213. return (-3);
  214. }
  215. i2cm_idle();
  216. if( SSPxCON2bits.ACKSTAT ) {
  217. return (-2);
  218. }
  219. } else {
  220. SSPxIF = 0;
  221. SSPxBUF = *ptr;
  222. SSPxCON1bits.CKP = 1;
  223. while( !SSPxIF );
  224. if((!SSPxSTATbits.R_W) && ( !SSPxSTATbits.BF )) {
  225. return (-2);
  226. }
  227. }
  228. ptr++;
  229. }
  230. return 0;
  231. }
  232. /*--------------------------------------*/
  233. void i2cm_begin(unsigned char address, unsigned char doread)
  234. {
  235. i2cm_start();
  236. i2cm_writechar( (address<<1) | (doread != 0) );
  237. }