Contiki-Inga 3.x
i2cmaster.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010, Swedish Institute of Computer Science.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the Institute nor the names of its contributors
14  * may be used to endorse or promote products derived from this software
15  * without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  * This file is part of the Contiki operating system.
30  *
31  */
32 
33 /**
34  * \file
35  * I2C communication device drivers for Zolertia Z1 sensor node.
36  * \author
37  * Enric M. Calvo, Zolertia <ecalvo@zolertia.com>
38  * Marcus Lundén, SICS <mlunden@sics.se>
39  */
40 
41 #include "i2cmaster.h"
42 #include "isr_compat.h"
43 
44 signed char tx_byte_ctr, rx_byte_ctr;
45 unsigned char rx_buf[2];
46 unsigned char* tx_buf_ptr;
47 unsigned char* rx_buf_ptr;
48 unsigned char receive_data;
49 unsigned char transmit_data1;
50 unsigned char transmit_data2;
51 volatile unsigned int i; // volatile to prevent optimization
52 
53 //------------------------------------------------------------------------------
54 // void i2c_receiveinit(unsigned char slave_address,
55 // unsigned char prescale)
56 //
57 // This function initializes the USCI module for master-receive operation.
58 //
59 // IN: unsigned char slave_address => Slave Address
60 // unsigned char prescale => SCL clock adjustment
61 //-----------------------------------------------------------------------------
62 void
63 i2c_receiveinit(uint8_t slave_address) {
64  UCB1CTL1 = UCSWRST; // Enable SW reset
65  UCB1CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode
66  UCB1CTL1 = UCSSEL_2 | UCSWRST; // Use SMCLK, keep SW reset
67  UCB1BR0 = I2C_PRESC_400KHZ_LSB; // prescaler for 400 kHz data rate
68  UCB1BR1 = I2C_PRESC_400KHZ_MSB;
69  UCB1I2CSA = slave_address; // set slave address
70 
71  UCB1CTL1 &= ~UCTR; // I2C Receiver
72 
73  UCB1CTL1 &= ~UCSWRST; // Clear SW reset, resume operation
74  UCB1I2CIE = UCNACKIE;
75 #if I2C_RX_WITH_INTERRUPT
76  UC1IE = UCB1RXIE; // Enable RX interrupt if desired
77 #endif
78 }
79 
80 //------------------------------------------------------------------------------
81 // void i2c_transmitinit(unsigned char slave_address,
82 // unsigned char prescale)
83 //
84 // Initializes USCI for master-transmit operation.
85 //
86 // IN: unsigned char slave_address => Slave Address
87 // unsigned char prescale => SCL clock adjustment
88 //------------------------------------------------------------------------------
89 void
90 i2c_transmitinit(uint8_t slave_address) {
91  UCB1CTL1 |= UCSWRST; // Enable SW reset
92  UCB1CTL0 |= (UCMST | UCMODE_3 | UCSYNC); // I2C Master, synchronous mode
93  UCB1CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset
94  UCB1BR0 = I2C_PRESC_400KHZ_LSB; // prescaler for 400 kHz data rate
95  UCB1BR1 = I2C_PRESC_400KHZ_MSB;
96  UCB1I2CSA = slave_address; // Set slave address
97 
98  UCB1CTL1 &= ~UCSWRST; // Clear SW reset, resume operation
99  UCB1I2CIE = UCNACKIE;
100  UC1IE = UCB1TXIE; // Enable TX ready interrupt
101 }
102 
103 //------------------------------------------------------------------------------
104 // void i2c_receive_n(unsigned char byte_ctr, unsigned char * rx_buf)
105 // This function is used to start an I2C communication in master-receiver mode WITHOUT INTERRUPTS
106 // for more than 1 byte
107 // IN: unsigned char byte_ctr => number of bytes to be read
108 // OUT: unsigned char rx_buf => receive data buffer
109 // OUT: int n_received => number of bytes read
110 //------------------------------------------------------------------------------
111 static volatile uint8_t rx_byte_tot = 0;
112 uint8_t
113 i2c_receive_n(uint8_t byte_ctr, uint8_t *rx_buf) {
114 
115  rx_byte_tot = byte_ctr;
116  rx_byte_ctr = byte_ctr;
117  rx_buf_ptr = rx_buf;
118 
119  while ((UCB1CTL1 & UCTXSTT) || (UCB1STAT & UCNACKIFG)) // Slave acks address or not?
120  PRINTFDEBUG ("____ UCTXSTT not clear OR NACK received\n");
121 
122 #if I2C_RX_WITH_INTERRUPT
123  PRINTFDEBUG(" RX Interrupts: YES \n");
124 
125  // SPECIAL-CASE: Stop condition must be sent while receiving the 1st byte for 1-byte only read operations
126  if(rx_byte_tot == 1){ // See page 537 of slau144e.pdf
127  dint();
128  UCB1CTL1 |= UCTXSTT; // I2C start condition
129  while(UCB1CTL1 & UCTXSTT) // Waiting for Start bit to clear
130  PRINTFDEBUG ("____ STT clear wait\n");
131  UCB1CTL1 |= UCTXSTP; // I2C stop condition
132  eint();
133  }
134  else{ // all other cases
135  UCB1CTL1 |= UCTXSTT; // I2C start condition
136  }
137  return 0;
138 
139 #else
140  uint8_t n_received = 0;
141 
142  PRINTFDEBUG(" RX Interrupts: NO \n");
143 
144  UCB1CTL1 |= UCTXSTT; // I2C start condition
145 
146  while (rx_byte_ctr > 0){
147  if (UC1IFG & UCB1RXIFG) { // Waiting for Data
148  rx_buf[rx_byte_tot - rx_byte_ctr] = UCB1RXBUF;
149  rx_byte_ctr--;
150  UC1IFG &= ~UCB1RXIFG; // Clear USCI_B1 RX int flag
151  n_received++;
152  }
153  }
154  UCB1CTL1 |= UCTXSTP; // I2C stop condition
155  return n_received;
156 #endif
157 }
158 
159 
160 //------------------------------------------------------------------------------
161 // uint8_t i2c_busy()
162 //
163 // This function is used to check if there is communication in progress.
164 //
165 // OUT: unsigned char => 0: I2C bus is idle,
166 // 1: communication is in progress
167 //------------------------------------------------------------------------------
168 uint8_t
169 i2c_busy(void) {
170  return (UCB1STAT & UCBBUSY);
171 }
172 
173 /*----------------------------------------------------------------------------*/
174 /* Setup ports and pins for I2C use. */
175 
176 void
177 i2c_enable(void) {
178  I2C_PxSEL |= (I2C_SDA | I2C_SCL); // Secondary function (USCI) selected
179  I2C_PxSEL2 |= (I2C_SDA | I2C_SCL); // Secondary function (USCI) selected
180  I2C_PxDIR |= I2C_SCL; // SCL is output (not needed?)
181  I2C_PxDIR &= ~I2C_SDA; // SDA is input (not needed?)
182  I2C_PxREN |= (I2C_SDA | I2C_SCL); // Activate internal pull-up/-down resistors
183  I2C_PxOUT |= (I2C_SDA | I2C_SCL); // Select pull-up resistors
184 }
185 
186 void
187 i2c_disable(void) {
188  I2C_PxSEL &= ~(I2C_SDA | I2C_SCL); // GPIO function selected
189  I2C_PxSEL2 &= ~(I2C_SDA | I2C_SCL); // GPIO function selected
190  I2C_PxREN &= ~(I2C_SDA | I2C_SCL); // Deactivate internal pull-up/-down resistors
191  I2C_PxOUT &= ~(I2C_SDA | I2C_SCL); // Select pull-up resistors
192 }
193 
194 /*----------------------------------------------------------------------------*/
195 //------------------------------------------------------------------------------
196 // void i2c_transmit_n(unsigned char byte_ctr, unsigned char *field)
197 //
198 // This function is used to start an I2C communication in master-transmit mode.
199 //
200 // IN: unsigned char byte_ctr => number of bytes to be transmitted
201 // unsigned char *tx_buf => Content to transmit. Read and transmitted from [0] to [byte_ctr]
202 //------------------------------------------------------------------------------
203 static volatile uint8_t tx_byte_tot = 0;
204 void
205 i2c_transmit_n(uint8_t byte_ctr, uint8_t *tx_buf) {
206  tx_byte_tot = byte_ctr;
207  tx_byte_ctr = byte_ctr;
208  tx_buf_ptr = tx_buf;
209  UCB1CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition
210 }
211 
212 /*----------------------------------------------------------------------------*/
213 ISR(USCIAB1TX, i2c_tx_interrupt)
214 {
215  // TX Part
216  if (UC1IFG & UCB1TXIFG) { // TX int. condition
217  if (tx_byte_ctr == 0) {
218  UCB1CTL1 |= UCTXSTP; // I2C stop condition
219  UC1IFG &= ~UCB1TXIFG; // Clear USCI_B1 TX int flag
220  }
221  else {
222  UCB1TXBUF = tx_buf_ptr[tx_byte_tot - tx_byte_ctr];
223  tx_byte_ctr--;
224  }
225  }
226  // RX Part
227 #if I2C_RX_WITH_INTERRUPT
228  else if (UC1IFG & UCB1RXIFG){ // RX int. condition
229  rx_buf_ptr[rx_byte_tot - rx_byte_ctr] = UCB1RXBUF;
230  rx_byte_ctr--;
231  if (rx_byte_ctr == 1){ //stop condition should be set before receiving last byte
232  // Only for 1-byte transmissions, STOP is handled in receive_n_int
233  if (rx_byte_tot != 1)
234  UCB1CTL1 |= UCTXSTP; // I2C stop condition
235  UC1IFG &= ~UCB1RXIFG; // Clear USCI_B1 RX int flag. XXX Just in case, check if necessary
236  }
237  }
238 #endif
239 }
240 
241 ISR(USCIAB1RX, i2c_rx_interrupt)
242 {
243  if(UCB1STAT & UCNACKIFG) {
244  PRINTFDEBUG("!!! NACK received in RX\n");
245  UCB1CTL1 |= UCTXSTP;
246  UCB1STAT &= ~UCNACKIFG;
247  }
248 }