pic24_i2c.c

00001 /*
00002  * "Copyright (c) 2008 Robert B. Reese, Bryan A. Jones, J. W. Bruce ("AUTHORS")"
00003  * All rights reserved.
00004  * (R. Reese, reese_AT_ece.msstate.edu, Mississippi State University)
00005  * (B. A. Jones, bjones_AT_ece.msstate.edu, Mississippi State University)
00006  * (J. W. Bruce, jwbruce_AT_ece.msstate.edu, Mississippi State University)
00007  *
00008  * Permission to use, copy, modify, and distribute this software and its
00009  * documentation for any purpose, without fee, and without written agreement is
00010  * hereby granted, provided that the above copyright notice, the following
00011  * two paragraphs and the authors appear in all copies of this software.
00012  *
00013  * IN NO EVENT SHALL THE "AUTHORS" BE LIABLE TO ANY PARTY FOR
00014  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
00015  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE "AUTHORS"
00016  * HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00017  *
00018  * THE "AUTHORS" SPECIFICALLY DISCLAIMS ANY WARRANTIES,
00019  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
00020  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
00021  * ON AN "AS IS" BASIS, AND THE "AUTHORS" HAS NO OBLIGATION TO
00022  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
00023  *
00024  * Please maintain this header in its entirety when copying/modifying
00025  * these files.
00026  *
00027  *
00028  */
00029 
00030 #include "pic24_all.h"
00031 #include <stdio.h>   //for NULL definition
00032 
00033 // Only include if this UART exists.
00034 #if (NUM_I2C_MODS >= 1)
00035 
00036 // Documentation for this file. If the \file tag is not present,
00037 // this file will not be documented.
00038 // Note: place this comment below the #if NUM_I2C_MODS so Doxygen
00039 // will only see it once.
00049 void configI2C1(uint16 u16_FkHZ) {
00050   uint32 u32_temp;
00051 
00052   u32_temp = (FCY/1000L)/((uint32) u16_FkHZ);
00053   u32_temp = u32_temp - FCY/10000000L - 1;
00054   I2C1BRG = u32_temp;
00055   I2C1CONbits.I2CEN = 1;
00056 }
00057 
00061 void startI2C1(void) {
00062   uint8 u8_wdtState;
00063 
00064   sz_lastTimeoutError = "I2C1 Start";
00065   u8_wdtState = _SWDTEN;  //save WDT state
00066   _SWDTEN = 1; //enable WDT
00067   I2C1CONbits.SEN = 1;   // initiate start
00068   // wait until start finished
00069   while (I2C1CONbits.SEN);
00070   _SWDTEN = u8_wdtState;  //restore WDT
00071   sz_lastTimeoutError = NULL;
00072 }
00073 
00077 void rstartI2C1(void) {// repeated start
00078   uint8 u8_wdtState;
00079 
00080   sz_lastTimeoutError = "I2C1 RStart";
00081   u8_wdtState = _SWDTEN;  //save WDT state
00082   _SWDTEN = 1;  //enable WDT
00083   I2C1CONbits.RSEN = 1;   // initiate start
00084   // wait until start finished
00085   while (I2C1CONbits.RSEN);
00086   _SWDTEN = u8_wdtState;  //restore WDT
00087   sz_lastTimeoutError = NULL;
00088 }
00089 
00093 void stopI2C1(void) {
00094   uint8 u8_wdtState;
00095 
00096   sz_lastTimeoutError = "I2C1 Stop";
00097   u8_wdtState = _SWDTEN;  //save WDT state
00098   _SWDTEN = 1;  //enable WDT
00099   I2C1CONbits.PEN=1;     // initiate stop, PEN=1
00100   //wait until stop finished
00101   while (I2C1CONbits.PEN);
00102   _SWDTEN = u8_wdtState;  //restore WDT
00103   sz_lastTimeoutError = NULL;
00104 }
00105 
00110 void putI2C1(uint8 u8_val) {
00111   uint8 u8_wdtState;
00112 
00113   sz_lastTimeoutError = "I2C1 Put";
00114   u8_wdtState = _SWDTEN;  //save WDT state
00115   _SWDTEN = 1;       //enable WDT
00116   I2C1TRN = u8_val;    // write byte
00117   while (I2C1STATbits.TRSTAT);   // wait for 8bits+ ack bit to finish
00118   _SWDTEN = u8_wdtState;  //restore WDT
00119   sz_lastTimeoutError = NULL;
00120   if (I2C1STATbits.ACKSTAT != I2C_ACK) {
00121     //NAK returned
00122     reportError("I2CPUT1, NAK returned.");
00123   }
00124 }
00125 
00132 uint8 putNoAckCheckI2C1(uint8 u8_val) {
00133   uint8 u8_wdtState;
00134 
00135   sz_lastTimeoutError = "I2C1 Put";
00136   u8_wdtState = _SWDTEN;  //save WDT state
00137   _SWDTEN = 1;       //enable WDT
00138   I2C1TRN = u8_val;    // write byte
00139   while (I2C1STATbits.TRSTAT);   // wait for 8bits+ ack bit to finish
00140   _SWDTEN = u8_wdtState;  //restore WDT
00141   sz_lastTimeoutError = NULL;
00142   return(I2C1STATbits.ACKSTAT);
00143 }
00144 
00150 uint8 getI2C1(uint8 u8_ack2Send) {
00151   uint8 u8_wdtState;
00152   uint8 u8_inByte;
00153 
00154   sz_lastTimeoutError = "I2C1 Get";
00155   u8_wdtState = _SWDTEN;              //save WDT state
00156   _SWDTEN = 1;                        //enable WDT
00157   while (I2C1CON & 0x1F);           //wait for idle condition
00158   I2C1CONbits.RCEN = 1;             //enable receive
00159   while (!I2C1STATbits.RBF);        //wait for receive byte
00160   CLRWDT();
00161   u8_inByte = I2C1RCV;              //read byte;
00162   //wait for idle condition before attempting ACK
00163   while (I2C1CON & 0x1F);           //lower 5 bits must be 0
00164   I2C1CONbits.ACKDT = u8_ack2Send;  //ACK bit to send back on receive
00165   I2C1CONbits.ACKEN = 1;            //enable ACKbit transmittion
00166   while (I2C1CONbits.ACKEN);        //wait for completion
00167   _SWDTEN = u8_wdtState;              //restore WDT
00168   sz_lastTimeoutError = NULL;
00169   return(u8_inByte);                  //return the value
00170 }
00176 void write1I2C1(uint8 u8_addr,uint8 u8_d1) {
00177   startI2C1();
00178   putI2C1(I2C_WADDR(u8_addr));
00179   putI2C1(u8_d1);
00180   stopI2C1();
00181 }
00188 void write2I2C1(uint8 u8_addr,uint8 u8_d1, uint8 u8_d2) {
00189   startI2C1();
00190   putI2C1(I2C_WADDR(u8_addr));
00191   putI2C1(u8_d1);
00192   putI2C1(u8_d2);
00193   stopI2C1();
00194 }
00195 
00202 void writeNI2C1(uint8 u8_addr,uint8* pu8_data, uint16 u16_cnt) {
00203   uint16 u16_i;
00204   startI2C1();
00205   putI2C1(I2C_WADDR(u8_addr));
00206   for (u16_i=0; u16_i < u16_cnt; u16_i++) {
00207     putI2C1(*pu8_data);
00208     pu8_data++;
00209   }
00210   stopI2C1();
00211 }
00218 void read1I2C1 (uint8 u8_addr,uint8* pu8_d1) {
00219   startI2C1();
00220   putI2C1(I2C_RADDR(u8_addr));
00221   *pu8_d1 = getI2C1(I2C_NAK); //last ack bit from master to slave during read must be a NAK
00222   stopI2C1();
00223 }
00231 void read2I2C1 (uint8 u8_addr,uint8* pu8_d1, uint8* pu8_d2) {
00232   startI2C1();
00233   putI2C1(I2C_RADDR(u8_addr));
00234   *pu8_d1 = getI2C1(I2C_ACK);
00235   *pu8_d2 = getI2C1(I2C_NAK);
00236   stopI2C1();
00237 }
00245 void readNI2C1 (uint8 u8_addr,uint8* pu8_data, uint16 u16_cnt) {
00246   uint16 u16_i;
00247   startI2C1();
00248   putI2C1(I2C_RADDR(u8_addr));
00249   for (u16_i=0; u16_i < u16_cnt; u16_i++) {
00250     if (u16_i != u16_cnt-1) *pu8_data = getI2C1(I2C_ACK);
00251     else *pu8_data = getI2C1(I2C_NAK);
00252     pu8_data++;
00253   }
00254   stopI2C1();
00255 }
00256 
00257 #endif // #if (NUM_I2C_MODS >= 1)
00258 
00259 
00260 
00261 
00262 
00263 
00264 
00265 
00266 
00267 
00268 
00269 
00270 /*
00271  * "Copyright (c) 2008 Robert B. Reese, Bryan A. Jones, J. W. Bruce ("AUTHORS")"
00272  * All rights reserved.
00273  * (R. Reese, reese_AT_ece.msstate.edu, Mississippi State University)
00274  * (B. A. Jones, bjones_AT_ece.msstate.edu, Mississippi State University)
00275  * (J. W. Bruce, jwbruce_AT_ece.msstate.edu, Mississippi State University)
00276  *
00277  * Permission to use, copy, modify, and distribute this software and its
00278  * documentation for any purpose, without fee, and without written agreement is
00279  * hereby granted, provided that the above copyright notice, the following
00280  * two paragraphs and the authors appear in all copies of this software.
00281  *
00282  * IN NO EVENT SHALL THE "AUTHORS" BE LIABLE TO ANY PARTY FOR
00283  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
00284  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE "AUTHORS"
00285  * HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00286  *
00287  * THE "AUTHORS" SPECIFICALLY DISCLAIMS ANY WARRANTIES,
00288  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
00289  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
00290  * ON AN "AS IS" BASIS, AND THE "AUTHORS" HAS NO OBLIGATION TO
00291  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
00292  *
00293  * Please maintain this header in its entirety when copying/modifying
00294  * these files.
00295  *
00296  *
00297  */
00298 
00299 #include "pic24_all.h"
00300 #include <stdio.h>   //for NULL definition
00301 
00302 // Only include if this UART exists.
00303 #if (NUM_I2C_MODS >= 2)
00304 
00305 // Documentation for this file. If the \file tag is not present,
00306 // this file will not be documented.
00307 // Note: place this comment below the #if NUM_I2C_MODS so Doxygen
00308 // will only see it once.
00318 void configI2C2(uint16 u16_FkHZ) {
00319   uint32 u32_temp;
00320 
00321   u32_temp = (FCY/1000L)/((uint32) u16_FkHZ);
00322   u32_temp = u32_temp - FCY/10000000L - 1;
00323   I2C2BRG = u32_temp;
00324   I2C2CONbits.I2CEN = 1;
00325 }
00326 
00330 void startI2C2(void) {
00331   uint8 u8_wdtState;
00332 
00333   sz_lastTimeoutError = "I2C2 Start";
00334   u8_wdtState = _SWDTEN;  //save WDT state
00335   _SWDTEN = 1; //enable WDT
00336   I2C2CONbits.SEN = 1;   // initiate start
00337   // wait until start finished
00338   while (I2C2CONbits.SEN);
00339   _SWDTEN = u8_wdtState;  //restore WDT
00340   sz_lastTimeoutError = NULL;
00341 }
00342 
00346 void rstartI2C2(void) {// repeated start
00347   uint8 u8_wdtState;
00348 
00349   sz_lastTimeoutError = "I2C2 RStart";
00350   u8_wdtState = _SWDTEN;  //save WDT state
00351   _SWDTEN = 1;  //enable WDT
00352   I2C2CONbits.RSEN = 1;   // initiate start
00353   // wait until start finished
00354   while (I2C2CONbits.RSEN);
00355   _SWDTEN = u8_wdtState;  //restore WDT
00356   sz_lastTimeoutError = NULL;
00357 }
00358 
00362 void stopI2C2(void) {
00363   uint8 u8_wdtState;
00364 
00365   sz_lastTimeoutError = "I2C2 Stop";
00366   u8_wdtState = _SWDTEN;  //save WDT state
00367   _SWDTEN = 1;  //enable WDT
00368   I2C2CONbits.PEN=1;     // initiate stop, PEN=1
00369   //wait until stop finished
00370   while (I2C2CONbits.PEN);
00371   _SWDTEN = u8_wdtState;  //restore WDT
00372   sz_lastTimeoutError = NULL;
00373 }
00374 
00379 void putI2C2(uint8 u8_val) {
00380   uint8 u8_wdtState;
00381 
00382   sz_lastTimeoutError = "I2C2 Put";
00383   u8_wdtState = _SWDTEN;  //save WDT state
00384   _SWDTEN = 1;       //enable WDT
00385   I2C2TRN = u8_val;    // write byte
00386   while (I2C2STATbits.TRSTAT);   // wait for 8bits+ ack bit to finish
00387   _SWDTEN = u8_wdtState;  //restore WDT
00388   sz_lastTimeoutError = NULL;
00389   if (I2C2STATbits.ACKSTAT != I2C_ACK) {
00390     //NAK returned
00391     reportError("I2CPUT2, NAK returned.");
00392   }
00393 }
00394 
00401 uint8 putNoAckCheckI2C2(uint8 u8_val) {
00402   uint8 u8_wdtState;
00403 
00404   sz_lastTimeoutError = "I2C2 Put";
00405   u8_wdtState = _SWDTEN;  //save WDT state
00406   _SWDTEN = 1;       //enable WDT
00407   I2C2TRN = u8_val;    // write byte
00408   while (I2C2STATbits.TRSTAT);   // wait for 8bits+ ack bit to finish
00409   _SWDTEN = u8_wdtState;  //restore WDT
00410   sz_lastTimeoutError = NULL;
00411   return(I2C2STATbits.ACKSTAT);
00412 }
00413 
00419 uint8 getI2C2(uint8 u8_ack2Send) {
00420   uint8 u8_wdtState;
00421   uint8 u8_inByte;
00422 
00423   sz_lastTimeoutError = "I2C2 Get";
00424   u8_wdtState = _SWDTEN;              //save WDT state
00425   _SWDTEN = 1;                        //enable WDT
00426   while (I2C2CON & 0x1F);           //wait for idle condition
00427   I2C2CONbits.RCEN = 1;             //enable receive
00428   while (!I2C2STATbits.RBF);        //wait for receive byte
00429   CLRWDT();
00430   u8_inByte = I2C2RCV;              //read byte;
00431   //wait for idle condition before attempting ACK
00432   while (I2C2CON & 0x1F);           //lower 5 bits must be 0
00433   I2C2CONbits.ACKDT = u8_ack2Send;  //ACK bit to send back on receive
00434   I2C2CONbits.ACKEN = 1;            //enable ACKbit transmittion
00435   while (I2C2CONbits.ACKEN);        //wait for completion
00436   _SWDTEN = u8_wdtState;              //restore WDT
00437   sz_lastTimeoutError = NULL;
00438   return(u8_inByte);                  //return the value
00439 }
00445 void write1I2C2(uint8 u8_addr,uint8 u8_d1) {
00446   startI2C2();
00447   putI2C2(I2C_WADDR(u8_addr));
00448   putI2C2(u8_d1);
00449   stopI2C2();
00450 }
00457 void write2I2C2(uint8 u8_addr,uint8 u8_d1, uint8 u8_d2) {
00458   startI2C2();
00459   putI2C2(I2C_WADDR(u8_addr));
00460   putI2C2(u8_d1);
00461   putI2C2(u8_d2);
00462   stopI2C2();
00463 }
00464 
00471 void writeNI2C2(uint8 u8_addr,uint8* pu8_data, uint16 u16_cnt) {
00472   uint16 u16_i;
00473   startI2C2();
00474   putI2C2(I2C_WADDR(u8_addr));
00475   for (u16_i=0; u16_i < u16_cnt; u16_i++) {
00476     putI2C2(*pu8_data);
00477     pu8_data++;
00478   }
00479   stopI2C2();
00480 }
00487 void read1I2C2 (uint8 u8_addr,uint8* pu8_d1) {
00488   startI2C2();
00489   putI2C2(I2C_RADDR(u8_addr));
00490   *pu8_d1 = getI2C2(I2C_NAK); //last ack bit from master to slave during read must be a NAK
00491   stopI2C2();
00492 }
00500 void read2I2C2 (uint8 u8_addr,uint8* pu8_d1, uint8* pu8_d2) {
00501   startI2C2();
00502   putI2C2(I2C_RADDR(u8_addr));
00503   *pu8_d1 = getI2C2(I2C_ACK);
00504   *pu8_d2 = getI2C2(I2C_NAK);
00505   stopI2C2();
00506 }
00514 void readNI2C2 (uint8 u8_addr,uint8* pu8_data, uint16 u16_cnt) {
00515   uint16 u16_i;
00516   startI2C2();
00517   putI2C2(I2C_RADDR(u8_addr));
00518   for (u16_i=0; u16_i < u16_cnt; u16_i++) {
00519     if (u16_i != u16_cnt-1) *pu8_data = getI2C2(I2C_ACK);
00520     else *pu8_data = getI2C2(I2C_NAK);
00521     pu8_data++;
00522   }
00523   stopI2C2();
00524 }
00525 
00526 #endif // #if (NUM_I2C_MODS >= 2)
00527 
00528 
00529 
00530 
00531 
00532 
00533 
00534 
00535 
00536 
00537 
00538 

Generated on Mon Oct 18 07:40:46 2010 for Python-on-a-chip by  doxygen 1.5.9