Contiki 2.6

i2c.c

00001 /*
00002  * Copyright (c) 2011, Hedde Bosman <heddebosman@incas3.eu>
00003  *
00004  * I2C communication device drivers for mc1322x
00005  *
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions
00008  * are met:
00009  * 1. Redistributions of source code must retain the above copyright
00010  *    notice, this list of conditions and the following disclaimer.
00011  * 2. Redistributions in binary form must reproduce the above copyright
00012  *    notice, this list of conditions and the following disclaimer in the
00013  *    documentation and/or other materials provided with the distribution.
00014  * 3. Neither the name of the Institute nor the names of its contributors
00015  *    may be used to endorse or promote products derived from this software
00016  *    without specific prior written permission.
00017  *
00018  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
00019  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00020  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00021  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
00022  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00023  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00024  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00025  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00026  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00027  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00028  * SUCH DAMAGE.
00029  *
00030  * $Id$
00031  */
00032 
00033 #include "i2c.h"
00034 
00035 #include <stdio.h>
00036 
00037 static int8_t tx_byte_ctr;
00038 static int8_t rx_byte_ctr;
00039 
00040 static uint8_t* tx_buf_ptr;
00041 static uint8_t* rx_buf_ptr;
00042 
00043 
00044 volatile unsigned int i;        // volatile to prevent optimization
00045 
00046 static inline void i2c_send_byte(void) {
00047         *I2CDR = *(tx_buf_ptr++); // set new byte, MCF is automatically cleared
00048         tx_byte_ctr--;
00049 }
00050 static inline void i2c_recv_byte(void) {
00051         *(rx_buf_ptr++) = *I2CDR;
00052         rx_byte_ctr--;
00053 }
00054 
00055 //------------------------------------------------------------------------------
00056 // void i2c_receiveinit(uint8_t slave_address, 
00057 //                              uint8_t prescale)
00058 //
00059 // This function initializes the USCI module for master-receive operation. 
00060 //
00061 // IN:   uint8_t slave_address   =>  Slave Address
00062 //       uint8_t prescale        =>  SCL clock adjustment 
00063 //-----------------------------------------------------------------------------
00064 //static volatile uint8_t rx_byte_tot = 0;
00065 void i2c_receiveinit(uint8_t slave_address, uint8_t byte_ctr, uint8_t *rx_buf) {
00066         // wait for bus to be free before setting MSTA (assuming we're in a multi-master environment or still sending something else)
00067         while(i2c_busy()) /* wait */;
00068 
00069         // assert: rx_byte_ctr <= 0
00070         // assert: tx_byte_ctr <= 0
00071         tx_buf_ptr = 0;
00072         tx_byte_ctr = 0; // indicate that nothing is to be received
00073         rx_byte_ctr = byte_ctr;
00074         rx_buf_ptr  = rx_buf;
00075 
00076         // clockdiv
00077         //*I2CFDR = 0x20; // 150 khz for redbee econotag
00078         
00079         // assume being master, thus no addres has to be set
00080         *I2CCR = I2C_MEN |
00081 #ifdef I2C_NON_BLOCKING
00082                 I2C_MIEN | 
00083 #endif
00084                 I2C_MSTA | I2C_MTX | I2C_RXAK; // start condition is triggered
00085         
00086         // write out address of slave
00087         *I2CDR = (slave_address & 0x7f) <<1 | 0x01;
00088 
00089 #ifndef I2C_NON_BLOCKING
00090         i2c_receive();
00091 #endif  
00092 }
00093 
00094 //------------------------------------------------------------------------------
00095 // void i2c_transmitinit(uint8_t slave_address, 
00096 //                               uint8_t prescale)
00097 //
00098 // Initializes USCI for master-transmit operation. 
00099 //
00100 // IN:   uint8_t slave_address   =>  Slave Address
00101 //       uint8_t prescale        =>  SCL clock adjustment 
00102 //------------------------------------------------------------------------------
00103 //static volatile uint8_t tx_byte_tot = 0;
00104 void i2c_transmitinit(uint8_t slave_address, uint8_t byte_ctr, uint8_t *tx_buf) {
00105         // wait for bus to be free before setting MSTA (assuming we're in a multi-master environment or still sending something else)
00106         while(i2c_busy()) /* wait */;
00107 
00108         // assert: rx_byte_ctr <= 0
00109         // assert: tx_byte_ctr <= 0
00110         rx_buf_ptr = 0;
00111         rx_byte_ctr = 0; // indicate that nothing is to be received
00112         tx_byte_ctr = byte_ctr;
00113         tx_buf_ptr  = tx_buf;
00114 
00115         // clockdiv
00116         //*I2CFDR = 0x20; // 150 khz for redbee econotag
00117         
00118         // assume being master, thus no addres has to be set
00119         *I2CCR = I2C_MEN | 
00120 #ifdef I2C_NON_BLOCKING
00121                 I2C_MIEN | 
00122 #endif
00123                 I2C_MSTA | I2C_MTX ; // start condition is triggered
00124 
00125         // write out address of slave
00126         *I2CDR = (slave_address & 0x7f) <<1;
00127 
00128 #ifndef I2C_NON_BLOCKING
00129         i2c_transmit();
00130 #endif  
00131 }
00132 
00133 /*----------------------------------------------------------------------------*/
00134 /*- blocking counterparts of interrupt hanlder function  ---------------------*/
00135 /*----------------------------------------------------------------------------*/
00136 #ifndef I2C_NON_BLOCKING
00137 /*----------------------------------------------------------------------------*/
00138 uint8_t i2c_receive() {
00139         while(rx_byte_ctr > 0) {
00140                 // busy wait
00141                 while(!(*I2CSR & I2C_MCF) || !(*I2CSR & I2C_MIF)) /*wait*/;
00142 
00143                 if (rx_byte_ctr == 1) { // receiving next-to-last byte, thus turn off auto-ack for stop condition
00144                         *I2CCR |= I2C_TXAK;
00145                 }
00146                 
00147                 if (*I2CSR & I2C_MCF) {
00148                         i2c_recv_byte(); // read new byte
00149                 }
00150 
00151                 if (*I2CSR & I2C_MAL) {
00152                         *I2CSR &= ~I2C_MAL; // should be cleared in software
00153                         printf("*** ERROR I2C: Arbitration lost\n");
00154                         // Arbitration lost; ERROR?
00155                 }
00156         }
00157 
00158         while(!(*I2CSR & I2C_MCF) || !(*I2CSR & I2C_MIF)) /*wait*/;
00159         if (*I2CSR & I2C_RXAK) {
00160                 // NO acknoledge byte received
00161                 printf("*** ERROR I2C: No ack received\n");
00162         }
00163         if (*I2CSR & I2C_MAL) {
00164                 *I2CSR &= ~I2C_MAL; // should be cleared in software
00165                 printf("*** ERROR I2C: Arbitration lost\n");
00166                 // Arbitration lost; ERROR?
00167         }
00168 
00169         *I2CCR &= ~I2C_MSTA; // stop condition
00170 }
00171 /*----------------------------------------------------------------------------*/
00172 void    i2c_transmit() {
00173         while(tx_byte_ctr > 0) {
00174                 // busy wait
00175                 while(!(*I2CSR & I2C_MCF) || !(*I2CSR & I2C_MIF)) /*wait*/;
00176 
00177                 if (*I2CSR & I2C_RXAK) {
00178                         // NO acknoledge byte received
00179                         printf("*** ERROR I2C: No ack received\n");
00180                 }
00181                 
00182                 if (*I2CSR & I2C_MCF) {
00183                         i2c_send_byte();
00184                 }
00185                 
00186                 if (*I2CSR & I2C_MAL) {
00187                         *I2CSR &= ~I2C_MAL; // should be cleared in software
00188                         printf("*** ERROR I2C: Arbitration lost\n");
00189                         // Arbitration lost; ERROR?
00190                 }
00191                 
00192                 // clear MIF
00193                 *I2CSR &= ~I2C_MIF;
00194         }
00195         
00196         while(!(*I2CSR & I2C_MCF) || !(*I2CSR & I2C_MIF)) /*wait*/;
00197         if (*I2CSR & I2C_RXAK) {
00198                 // NO acknoledge byte received
00199                 printf("*** ERROR I2C: No ack received\n");
00200         }
00201         if (*I2CSR & I2C_MAL) {
00202                 *I2CSR &= ~I2C_MAL; // should be cleared in software
00203                 printf("*** ERROR I2C: Arbitration lost\n");
00204                 // Arbitration lost; ERROR?
00205         }
00206         
00207         *I2CCR &= ~I2C_MSTA; // stop condition
00208 }
00209 #endif
00210 /*----------------------------------------------------------------------------*/
00211 
00212 
00213 /*----------------------------------------------------------------------------*/
00214 /* force SCL to become bus master when sda is still low (can occur after sys reset */
00215 /*----------------------------------------------------------------------------*/
00216 void i2c_force_reset(void) {
00217         uint8_t tmp;
00218         *I2CCR = 0x20;
00219         *I2CCR = 0xA0;
00220         tmp = *I2CDR;
00221         // return to module state Master?
00222 }
00223 
00224 
00225 /*----------------------------------------------------------------------------*/
00226 /*-  check if we're still in the process of sending something  ----------------*/
00227 /*----------------------------------------------------------------------------*/
00228 uint8_t i2c_transferred(void) {
00229         return (!i2c_busy() && rx_byte_ctr == 0 && tx_byte_ctr == 0);
00230 }
00231 
00232 
00233 /*----------------------------------------------------------------------------*/
00234 /* check if there is communication in progress on the i2c bus.                */
00235 /*----------------------------------------------------------------------------*/
00236 uint8_t i2c_busy(void) {
00237   return ((*I2CSR & I2C_MBB) > 0); // bit 5 high = busy
00238 }
00239 
00240 
00241 /*----------------------------------------------------------------------------*/
00242 /* Setup ports and pins for I2C use. */
00243 /*----------------------------------------------------------------------------*/
00244 void i2c_enable(void) {
00245         // enable clock signal to i2c module
00246         *I2CCKER = I2C_CKEN; // enable
00247 
00248         enable_irq(I2C);
00249 
00250         *I2CFDR = 0x20; // clockdiv: 150 khz for redbee econotag
00251         *I2CADR = 0x01; // our slave address (not used; we're master)
00252         // then enable i2c module
00253         *I2CCR |= I2C_MEN | // module-enable, auto-ack = on
00254 #ifdef I2C_NON_BLOCKING
00255                 I2C_MIEN | //module-interrupt-enable
00256 #endif
00257                 0;
00258 
00259         // then switch gpio pins to i2c
00260         *GPIO_FUNC_SEL0         |= (0x01 << (I2C_SCL*2)) | (0x01 << (I2C_SDA*2)); // GPIO 12, 13 to i2c
00261         // and enable pull-up resistors
00262         *GPIO_PAD_PU_EN0        |= (0x01 << I2C_SCL) | (0x01 << I2C_SDA); // Activate internal pull-up/-down resistors
00263         *GPIO_PAD_PU_SEL0       |= (0x01 << I2C_SCL) | (0x01 << I2C_SDA); // select pull-up resistors for ports
00264 }
00265 
00266 /*----------------------------------------------------------------------------*/
00267 /* Reset ports and pins for GPIO use. */
00268 /*----------------------------------------------------------------------------*/
00269 void i2c_disable(void) {
00270         // all control values are set off
00271         *I2CCR = 0;
00272         // clock is turned off
00273         *I2CCKER = ~I2C_CKEN;
00274 
00275         // then switch gpio pins to gpio
00276         *GPIO_FUNC_SEL0         &= ~(0x01 << (I2C_SCL*2)) | (0x01 << (I2C_SDA*2)); // GPIO 12, 13 to i2c
00277         // and disable resistors
00278         *GPIO_PAD_PU_EN0        &= ~(0x01 << I2C_SCL) | (0x01 << I2C_SDA); // Deactivate internal pull-up/-down resistors
00279 
00280         disable_irq(I2C);
00281 }
00282 
00283 
00284 /*----------------------------------------------------------------------------*/
00285 /*-  i2c interrupt handler  --------------------------------------------------*/
00286 /*----------------------------------------------------------------------------*/
00287 #ifdef I2C_NON_BLOCKING
00288 void i2c_isr (void) {
00289         uint8_t dummy;
00290         if (*I2CSR & I2C_MIF) { // interrupt is from i2c
00291                 if (*I2CSR & I2C_MCF) { // one byte transferred/received. will be cleared automatically when I2CDR is written or I2CSR read
00292                         if (tx_buf_ptr != 0) { // we're sending
00293                                 if (*I2CSR & I2C_RXAK) {
00294                                         // NO acknoledge byte received
00295                                         printf("*** ERROR I2C: No ack received\n");
00296                                 }
00297 
00298                                 if (tx_byte_ctr > 0) { // tx
00299                                         i2c_send_byte(); // set new byte, MCF is automatically cleared
00300                                 } else {
00301                                         *I2CCR &= ~I2C_MSTA; // generate stop condition
00302                                 }
00303                         } else { //if (rx_buf_ptr != 0) { // receive
00304                                 if (rx_byte_ctr == 1) { // receiving next-to-last byte, thus turn off auto-ack for stop condition
00305                                         *I2CCR |= I2C_TXAK;
00306                                 }
00307                                 if (*I2CCR & I2C_MTX) { // address byte was just sent
00308                                         *I2CCR &= ~I2C_MTX; // switch to receive mode
00309                                         dummy = *I2CDR; // dummy read to throw away the address from register
00310                                         
00311                                 } else if (rx_byte_ctr > 0) {
00312                                         i2c_recv_byte(); // read new byte
00313                                 } else {
00314                                         *I2CCR &= ~I2C_MSTA; // generate stop condition
00315                                 }
00316                                 
00317                         }
00318                 }
00319                 if (*I2CSR & I2C_MAL) {
00320                         *I2CSR &= ~I2C_MAL; // should be cleared in software
00321                         printf("*** ERROR I2C: Arbitration lost\n");
00322                         // Arbitration lost; reset..
00323                         rx_byte_ctr = tx_byte_ctr = 0;
00324                         *I2CCR &= ~I2C_MSTA; // generate stop condition
00325                 }
00326                 
00327                 // clear MIF
00328                 *I2CSR &= ~I2C_MIF;
00329         }
00330 }
00331 #endif