Contiki 2.6
|
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