1 /* mbed Microcontroller Library
2 * Copyright (c) 2013 Nordic Semiconductor
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 #include "mbed_assert.h"
20 #include "mbed_error.h"
22 // nRF51822's I2C_0 and SPI_0 (I2C_1, SPI_1 and SPIS1) share the same address.
23 // They can't be used at the same time. So we use two global variable to track the usage.
24 // See nRF51822 address information at nRF51822_PS v2.0.pdf - Table 15 Peripheral instance reference
25 volatile i2c_spi_peripheral_t i2c0_spi0_peripheral = {0, 0, 0, 0};
26 volatile i2c_spi_peripheral_t i2c1_spi1_peripheral = {0, 0, 0, 0};
28 void i2c_interface_enable(i2c_t *obj)
30 obj->i2c->ENABLE = (TWI_ENABLE_ENABLE_Enabled << TWI_ENABLE_ENABLE_Pos);
33 void twi_master_init(i2c_t *obj, PinName sda, PinName scl, int frequency)
35 NRF_GPIO->PIN_CNF[scl] = ((GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos) |
36 (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) |
37 (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos) |
38 (GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos) |
39 (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos));
41 NRF_GPIO->PIN_CNF[sda] = ((GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos) |
42 (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) |
43 (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos) |
44 (GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos) |
45 (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos));
47 obj->i2c->PSELSCL = scl;
48 obj->i2c->PSELSDA = sda;
49 // set default frequency at 100k
50 i2c_frequency(obj, frequency);
51 i2c_interface_enable(obj);
54 void i2c_init(i2c_t *obj, PinName sda, PinName scl)
58 if (i2c0_spi0_peripheral.usage == I2C_SPI_PERIPHERAL_FOR_I2C &&
59 i2c0_spi0_peripheral.sda_mosi == (uint8_t)sda &&
60 i2c0_spi0_peripheral.scl_miso == (uint8_t)scl) {
61 // The I2C with the same pins is already initialized
62 i2c = (NRF_TWI_Type *)I2C_0;
63 obj->peripheral = 0x1;
64 } else if (i2c1_spi1_peripheral.usage == I2C_SPI_PERIPHERAL_FOR_I2C &&
65 i2c1_spi1_peripheral.sda_mosi == (uint8_t)sda &&
66 i2c1_spi1_peripheral.scl_miso == (uint8_t)scl) {
67 // The I2C with the same pins is already initialized
68 i2c = (NRF_TWI_Type *)I2C_1;
69 obj->peripheral = 0x2;
70 } else if (i2c0_spi0_peripheral.usage == 0) {
71 i2c0_spi0_peripheral.usage = I2C_SPI_PERIPHERAL_FOR_I2C;
72 i2c0_spi0_peripheral.sda_mosi = (uint8_t)sda;
73 i2c0_spi0_peripheral.scl_miso = (uint8_t)scl;
75 i2c = (NRF_TWI_Type *)I2C_0;
76 obj->peripheral = 0x1;
77 } else if (i2c1_spi1_peripheral.usage == 0) {
78 i2c1_spi1_peripheral.usage = I2C_SPI_PERIPHERAL_FOR_I2C;
79 i2c1_spi1_peripheral.sda_mosi = (uint8_t)sda;
80 i2c1_spi1_peripheral.scl_miso = (uint8_t)scl;
82 i2c = (NRF_TWI_Type *)I2C_1;
83 obj->peripheral = 0x2;
85 // No available peripheral
86 error("No available I2C");
92 obj->i2c->EVENTS_ERROR = 0;
93 obj->i2c->ENABLE = TWI_ENABLE_ENABLE_Disabled << TWI_ENABLE_ENABLE_Pos;
96 for (int i = 0; i<100; i++) {
100 twi_master_init(obj, sda, scl, 100000);
103 void i2c_reset(i2c_t *obj)
105 obj->i2c->EVENTS_ERROR = 0;
106 obj->i2c->ENABLE = TWI_ENABLE_ENABLE_Disabled << TWI_ENABLE_ENABLE_Pos;
108 for (int i = 0; i<100; i++) {
112 twi_master_init(obj, obj->sda, obj->scl, obj->freq);
115 int i2c_start(i2c_t *obj)
119 obj->address_set = 0;
123 int i2c_stop(i2c_t *obj)
125 int timeOut = 100000;
126 obj->i2c->EVENTS_STOPPED = 0;
127 // write the stop bit
128 obj->i2c->TASKS_STOP = 1;
129 while (!obj->i2c->EVENTS_STOPPED) {
135 obj->address_set = 0;
140 int i2c_do_write(i2c_t *obj, int value)
142 int timeOut = 100000;
143 obj->i2c->TXD = value;
144 while (!obj->i2c->EVENTS_TXDSENT) {
150 obj->i2c->EVENTS_TXDSENT = 0;
154 int i2c_do_read(i2c_t *obj, char *data, int last)
156 int timeOut = 100000;
159 // To trigger stop task when a byte is received,
160 // must be set before resume task.
161 obj->i2c->SHORTS = 2;
164 obj->i2c->TASKS_RESUME = 1;
166 while (!obj->i2c->EVENTS_RXDREADY) {
172 obj->i2c->EVENTS_RXDREADY = 0;
173 *data = obj->i2c->RXD;
178 void i2c_frequency(i2c_t *obj, int hz)
182 obj->i2c->FREQUENCY = (TWI_FREQUENCY_FREQUENCY_K100 << TWI_FREQUENCY_FREQUENCY_Pos);
183 } else if (hz<400000) {
185 obj->i2c->FREQUENCY = (TWI_FREQUENCY_FREQUENCY_K250 << TWI_FREQUENCY_FREQUENCY_Pos);
188 obj->i2c->FREQUENCY = (TWI_FREQUENCY_FREQUENCY_K400 << TWI_FREQUENCY_FREQUENCY_Pos);
192 int checkError(i2c_t *obj)
194 if (obj->i2c->EVENTS_ERROR == 1) {
195 if (obj->i2c->ERRORSRC & TWI_ERRORSRC_ANACK_Msk) {
196 obj->i2c->EVENTS_ERROR = 0;
197 obj->i2c->TASKS_STOP = 1;
198 return I2C_ERROR_BUS_BUSY;
201 obj->i2c->EVENTS_ERROR = 0;
202 obj->i2c->TASKS_STOP = 1;
203 return I2C_ERROR_NO_SLAVE;
208 int i2c_read(i2c_t *obj, int address, char *data, int length, int stop)
210 int status, count, errorResult;
211 obj->i2c->ADDRESS = (address >> 1);
212 obj->i2c->SHORTS = 1; // to trigger suspend task when a byte is received
213 obj->i2c->EVENTS_RXDREADY = 0;
214 obj->i2c->TASKS_STARTRX = 1;
216 // Read in all except last byte
217 for (count = 0; count < (length - 1); count++) {
218 status = i2c_do_read(obj, &data[count], 0);
220 errorResult = checkError(obj);
230 status = i2c_do_read(obj, &data[length - 1], 1);
235 // If not repeated start, send stop.
237 while (!obj->i2c->EVENTS_STOPPED) {
239 obj->i2c->EVENTS_STOPPED = 0;
244 int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop)
246 int status, errorResult;
247 obj->i2c->ADDRESS = (address >> 1);
248 obj->i2c->SHORTS = 0;
249 obj->i2c->TASKS_STARTTX = 1;
251 for (int i = 0; i<length; i++) {
252 status = i2c_do_write(obj, data[i]);
255 errorResult = checkError(obj);
263 // If not repeated start, send stop.
266 return I2C_ERROR_NO_SLAVE;
272 int i2c_byte_read(i2c_t *obj, int last)
277 status = i2c_do_read(obj, &data, last);
284 int i2c_byte_write(i2c_t *obj, int data)
287 if (!obj->address_set) {
288 obj->address_set = 1;
289 obj->i2c->ADDRESS = (data >> 1);
292 obj->i2c->EVENTS_RXDREADY = 0;
293 obj->i2c->SHORTS = 1;
294 obj->i2c->TASKS_STARTRX = 1;
296 obj->i2c->SHORTS = 0;
297 obj->i2c->TASKS_STARTTX = 1;
300 status = i2c_do_write(obj, data);