Contiki 2.6

i2cmaster.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2010, Swedish Institute of Computer Science.
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  * 1. Redistributions of source code must retain the above copyright
00009  *    notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright
00011  *    notice, this list of conditions and the following disclaimer in the
00012  *    documentation and/or other materials provided with the distribution.
00013  * 3. Neither the name of the Institute nor the names of its contributors
00014  *    may be used to endorse or promote products derived from this software
00015  *    without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
00018  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
00021  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00022  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00023  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00024  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00025  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00026  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00027  * SUCH DAMAGE.
00028  *
00029  * This file is part of the Contiki operating system.
00030  *
00031  */
00032 
00033 /**
00034  * \file
00035  *         I2C communication device drivers for Zolertia Z1 sensor node.
00036  * \author
00037  *         Enric M. Calvo, Zolertia <ecalvo@zolertia.com>
00038  *         Marcus Lundén, SICS <mlunden@sics.se>
00039  */
00040 
00041 #include "i2cmaster.h"
00042 #include "isr_compat.h"
00043 
00044 signed   char tx_byte_ctr, rx_byte_ctr;
00045 unsigned char rx_buf[2];
00046 unsigned char* tx_buf_ptr;
00047 unsigned char* rx_buf_ptr;
00048 unsigned char receive_data;
00049 unsigned char transmit_data1;
00050 unsigned char transmit_data2;
00051 volatile unsigned int i;        // volatile to prevent optimization
00052 
00053 //------------------------------------------------------------------------------
00054 // void i2c_receiveinit(unsigned char slave_address, 
00055 //                              unsigned char prescale)
00056 //
00057 // This function initializes the USCI module for master-receive operation. 
00058 //
00059 // IN:   unsigned char slave_address   =>  Slave Address
00060 //       unsigned char prescale        =>  SCL clock adjustment 
00061 //-----------------------------------------------------------------------------
00062 void
00063 i2c_receiveinit(uint8_t slave_address) {
00064   UCB1CTL1 = UCSWRST;                    // Enable SW reset
00065   UCB1CTL0 = UCMST + UCMODE_3 + UCSYNC;  // I2C Master, synchronous mode
00066   UCB1CTL1 = UCSSEL_2 | UCSWRST;         // Use SMCLK, keep SW reset
00067   UCB1BR0  = I2C_PRESC_400KHZ_LSB;       // prescaler for 400 kHz data rate
00068   UCB1BR1  = I2C_PRESC_400KHZ_MSB;
00069   UCB1I2CSA = slave_address;             // set slave address
00070 
00071   UCB1CTL1 &= ~UCTR;                     // I2C Receiver 
00072 
00073   UCB1CTL1 &= ~UCSWRST;                  // Clear SW reset, resume operation
00074   UCB1I2CIE = UCNACKIE;
00075 #if I2C_RX_WITH_INTERRUPT
00076   UC1IE = UCB1RXIE;                      // Enable RX interrupt if desired
00077 #endif
00078 }
00079 
00080 //------------------------------------------------------------------------------
00081 // void i2c_transmitinit(unsigned char slave_address, 
00082 //                               unsigned char prescale)
00083 //
00084 // Initializes USCI for master-transmit operation. 
00085 //
00086 // IN:   unsigned char slave_address   =>  Slave Address
00087 //       unsigned char prescale        =>  SCL clock adjustment 
00088 //------------------------------------------------------------------------------
00089 void
00090 i2c_transmitinit(uint8_t slave_address) {
00091   UCB1CTL1 |= UCSWRST;                     // Enable SW reset
00092   UCB1CTL0 |= (UCMST | UCMODE_3 | UCSYNC); // I2C Master, synchronous mode
00093   UCB1CTL1  = UCSSEL_2 + UCSWRST;          // Use SMCLK, keep SW reset
00094   UCB1BR0   = I2C_PRESC_400KHZ_LSB;        // prescaler for 400 kHz data rate
00095   UCB1BR1   = I2C_PRESC_400KHZ_MSB;
00096   UCB1I2CSA = slave_address;               // Set slave address
00097 
00098   UCB1CTL1 &= ~UCSWRST;                    // Clear SW reset, resume operation
00099   UCB1I2CIE = UCNACKIE;
00100   UC1IE = UCB1TXIE;                        // Enable TX ready interrupt
00101 }
00102 
00103 //------------------------------------------------------------------------------
00104 // void i2c_receive_n(unsigned char byte_ctr, unsigned char * rx_buf)
00105 // This function is used to start an I2C communication in master-receiver mode WITHOUT INTERRUPTS
00106 // for more than 1 byte
00107 // IN:   unsigned char byte_ctr   =>  number of bytes to be read
00108 // OUT:  unsigned char rx_buf     =>  receive data buffer
00109 // OUT:  int n_received           =>  number of bytes read
00110 //------------------------------------------------------------------------------
00111 static volatile uint8_t rx_byte_tot = 0;
00112 uint8_t
00113 i2c_receive_n(uint8_t byte_ctr, uint8_t *rx_buf) {
00114 
00115   rx_byte_tot = byte_ctr;
00116   rx_byte_ctr = byte_ctr;
00117   rx_buf_ptr  = rx_buf;
00118 
00119   while ((UCB1CTL1 & UCTXSTT) || (UCB1STAT & UCNACKIFG))        // Slave acks address or not?
00120     PRINTFDEBUG ("____ UCTXSTT not clear OR NACK received\n");
00121 
00122 #if I2C_RX_WITH_INTERRUPT
00123   PRINTFDEBUG(" RX Interrupts: YES \n");
00124 
00125   // SPECIAL-CASE: Stop condition must be sent while receiving the 1st byte for 1-byte only read operations
00126   if(rx_byte_tot == 1){                 // See page 537 of slau144e.pdf
00127     dint();
00128     UCB1CTL1 |= UCTXSTT;                // I2C start condition
00129     while(UCB1CTL1 & UCTXSTT)           // Waiting for Start bit to clear
00130       PRINTFDEBUG ("____ STT clear wait\n");
00131     UCB1CTL1 |= UCTXSTP;                // I2C stop condition
00132     eint();
00133   }
00134   else{                                 // all other cases
00135     UCB1CTL1 |= UCTXSTT;                // I2C start condition
00136   }
00137   return 0;
00138 
00139 #else
00140   uint8_t n_received = 0;
00141 
00142   PRINTFDEBUG(" RX Interrupts: NO \n");
00143 
00144   UCB1CTL1 |= UCTXSTT;          // I2C start condition
00145 
00146   while (rx_byte_ctr > 0){
00147     if (UC1IFG & UCB1RXIFG) {   // Waiting for Data
00148       rx_buf[rx_byte_tot - rx_byte_ctr] = UCB1RXBUF;
00149       rx_byte_ctr--;
00150       UC1IFG &= ~UCB1RXIFG;     // Clear USCI_B1 RX int flag      
00151       n_received++;
00152     }
00153   }
00154   UCB1CTL1 |= UCTXSTP;          // I2C stop condition
00155   return n_received;
00156 #endif
00157 }
00158 
00159 
00160 //------------------------------------------------------------------------------
00161 // uint8_t i2c_busy()
00162 //
00163 // This function is used to check if there is communication in progress. 
00164 //
00165 // OUT:  unsigned char  =>  0: I2C bus is idle, 
00166 //                          1: communication is in progress
00167 //------------------------------------------------------------------------------
00168 uint8_t
00169 i2c_busy(void) {
00170   return (UCB1STAT & UCBBUSY);
00171 }
00172 
00173 /*----------------------------------------------------------------------------*/
00174 /* Setup ports and pins for I2C use. */
00175 
00176 void
00177 i2c_enable(void) {
00178   I2C_PxSEL |= (I2C_SDA | I2C_SCL);    // Secondary function (USCI) selected
00179   I2C_PxSEL2 |= (I2C_SDA | I2C_SCL);   // Secondary function (USCI) selected
00180   I2C_PxDIR |= I2C_SCL;                // SCL is output (not needed?)
00181   I2C_PxDIR &= ~I2C_SDA;               // SDA is input (not needed?)
00182   I2C_PxREN |= (I2C_SDA | I2C_SCL);    // Activate internal pull-up/-down resistors
00183   I2C_PxOUT |= (I2C_SDA | I2C_SCL);    // Select pull-up resistors
00184 }
00185 
00186 void
00187 i2c_disable(void) {
00188   I2C_PxSEL &= ~(I2C_SDA | I2C_SCL);    // GPIO function selected
00189   I2C_PxSEL2 &= ~(I2C_SDA | I2C_SCL);   // GPIO function selected
00190   I2C_PxREN &= ~(I2C_SDA | I2C_SCL);    // Deactivate internal pull-up/-down resistors
00191   I2C_PxOUT &= ~(I2C_SDA | I2C_SCL);    // Select pull-up resistors
00192 }
00193 
00194 /*----------------------------------------------------------------------------*/
00195 //------------------------------------------------------------------------------
00196 // void i2c_transmit_n(unsigned char byte_ctr, unsigned char *field)
00197 //
00198 // This function is used to start an I2C communication in master-transmit mode. 
00199 //
00200 // IN:   unsigned char byte_ctr   =>  number of bytes to be transmitted
00201 //       unsigned char *tx_buf    =>  Content to transmit. Read and transmitted from [0] to [byte_ctr]
00202 //------------------------------------------------------------------------------
00203 static volatile uint8_t tx_byte_tot = 0;
00204 void
00205 i2c_transmit_n(uint8_t byte_ctr, uint8_t *tx_buf) {
00206   tx_byte_tot = byte_ctr;
00207   tx_byte_ctr = byte_ctr;
00208   tx_buf_ptr  = tx_buf;
00209   UCB1CTL1 |= UCTR + UCTXSTT;      // I2C TX, start condition
00210 }
00211 
00212 /*----------------------------------------------------------------------------*/
00213 ISR(USCIAB1TX, i2c_tx_interrupt)
00214 {
00215   // TX Part
00216   if (UC1IFG & UCB1TXIFG) {        // TX int. condition
00217     if (tx_byte_ctr == 0) {
00218       UCB1CTL1 |= UCTXSTP;         // I2C stop condition
00219       UC1IFG &= ~UCB1TXIFG;        // Clear USCI_B1 TX int flag
00220     }
00221     else {
00222       UCB1TXBUF = tx_buf_ptr[tx_byte_tot - tx_byte_ctr];
00223       tx_byte_ctr--;
00224     }
00225   }
00226   // RX Part
00227 #if I2C_RX_WITH_INTERRUPT
00228   else if (UC1IFG & UCB1RXIFG){    // RX int. condition
00229     if (rx_byte_ctr == 0){
00230       // Only for 1-byte transmissions, STOP is handled in receive_n_int
00231       if (rx_byte_tot != 1) 
00232         UCB1CTL1 |= UCTXSTP;       // I2C stop condition
00233 
00234       UC1IFG &= ~UCB1RXIFG;        // Clear USCI_B1 RX int flag. XXX Just in case, check if necessary
00235     }
00236     else {
00237       rx_buf_ptr[rx_byte_tot - rx_byte_ctr] = UCB1RXBUF;
00238       rx_byte_ctr--;
00239     }
00240   }
00241 #endif
00242 }
00243 
00244 ISR(USCIAB1RX, i2c_rx_interrupt)
00245 {
00246   if(UCB1STAT & UCNACKIFG) {
00247     PRINTFDEBUG("!!! NACK received in RX\n");
00248     UCB1CTL1 |= UCTXSTP;
00249     UCB1STAT &= ~UCNACKIFG;
00250   }
00251 }