mbed library sources. Supersedes mbed-src.

Dependents:   Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more

Committer:
AnnaBridge
Date:
Wed Feb 20 22:31:08 2019 +0000
Revision:
189:f392fc9709a3
Parent:
171:89b338f31ef1
mbed library release version 165

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 15:a81a8d6c1dfe 1 /* mbed Microcontroller Library
mbed_official 15:a81a8d6c1dfe 2 * Copyright (c) 2006-2015 ARM Limited
mbed_official 15:a81a8d6c1dfe 3 *
mbed_official 15:a81a8d6c1dfe 4 * Licensed under the Apache License, Version 2.0 (the "License");
mbed_official 15:a81a8d6c1dfe 5 * you may not use this file except in compliance with the License.
mbed_official 15:a81a8d6c1dfe 6 * You may obtain a copy of the License at
mbed_official 15:a81a8d6c1dfe 7 *
mbed_official 15:a81a8d6c1dfe 8 * http://www.apache.org/licenses/LICENSE-2.0
mbed_official 15:a81a8d6c1dfe 9 *
mbed_official 15:a81a8d6c1dfe 10 * Unless required by applicable law or agreed to in writing, software
mbed_official 15:a81a8d6c1dfe 11 * distributed under the License is distributed on an "AS IS" BASIS,
mbed_official 15:a81a8d6c1dfe 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
mbed_official 15:a81a8d6c1dfe 13 * See the License for the specific language governing permissions and
mbed_official 15:a81a8d6c1dfe 14 * limitations under the License.
mbed_official 15:a81a8d6c1dfe 15 */
mbed_official 15:a81a8d6c1dfe 16 #include "mbed_assert.h"
mbed_official 15:a81a8d6c1dfe 17 #include "i2c_api.h"
mbed_official 15:a81a8d6c1dfe 18
mbed_official 15:a81a8d6c1dfe 19 #include <math.h>
mbed_official 15:a81a8d6c1dfe 20
mbed_official 15:a81a8d6c1dfe 21 #include "cmsis.h"
mbed_official 15:a81a8d6c1dfe 22 #include "pinmap.h"
mbed_official 15:a81a8d6c1dfe 23 #include "sercom.h"
mbed_official 15:a81a8d6c1dfe 24 #include "i2c_master.h"
mbed_official 15:a81a8d6c1dfe 25 #include "i2c_slave.h"
mbed_official 15:a81a8d6c1dfe 26
mbed_official 15:a81a8d6c1dfe 27 #include "pinmap_function.h"
mbed_official 15:a81a8d6c1dfe 28
mbed_official 15:a81a8d6c1dfe 29 #if DEVICE_I2C_ASYNCH
mbed_official 15:a81a8d6c1dfe 30 #include "i2c_master_interrupt.h"
mbed_official 15:a81a8d6c1dfe 31 #endif
mbed_official 15:a81a8d6c1dfe 32
mbed_official 15:a81a8d6c1dfe 33
mbed_official 15:a81a8d6c1dfe 34 #if DEVICE_I2C_ASYNCH
mbed_official 15:a81a8d6c1dfe 35 #define pI2C_S(obj) (&obj->i2c)
mbed_official 15:a81a8d6c1dfe 36 #else
mbed_official 15:a81a8d6c1dfe 37 #define pI2C_S(obj) obj
mbed_official 15:a81a8d6c1dfe 38 #endif
mbed_official 15:a81a8d6c1dfe 39
mbed_official 15:a81a8d6c1dfe 40 #define I2C_MASTER_DEFAULT_BAUD 100000
mbed_official 15:a81a8d6c1dfe 41
mbed_official 15:a81a8d6c1dfe 42 /**
mbed_official 15:a81a8d6c1dfe 43 * \brief I2C modes enum
mbed_official 15:a81a8d6c1dfe 44 *
mbed_official 15:a81a8d6c1dfe 45 * I2C mode selection.
mbed_official 15:a81a8d6c1dfe 46 */
mbed_official 15:a81a8d6c1dfe 47 enum i2c_mode {
mbed_official 15:a81a8d6c1dfe 48 /** Master mode. */
mbed_official 15:a81a8d6c1dfe 49 I2C_MODE_MASTER = 0x5,
mbed_official 15:a81a8d6c1dfe 50 /** Slave mode. */
mbed_official 15:a81a8d6c1dfe 51 I2C_MODE_SLAVE = 0x4,
mbed_official 15:a81a8d6c1dfe 52 };
mbed_official 15:a81a8d6c1dfe 53
mbed_official 15:a81a8d6c1dfe 54 /* Extern Variables */
mbed_official 15:a81a8d6c1dfe 55 extern uint8_t g_sys_init;
mbed_official 15:a81a8d6c1dfe 56
mbed_official 15:a81a8d6c1dfe 57 typedef void (*I2CHandler)(void);
mbed_official 15:a81a8d6c1dfe 58
mbed_official 15:a81a8d6c1dfe 59 #if DEVICE_I2C_ASYNCH
mbed_official 15:a81a8d6c1dfe 60 #define _SERCOM_INTERRUPT_HANDLERS(n, unused) (uint32_t)SERCOM##n##_Handler,
mbed_official 15:a81a8d6c1dfe 61
mbed_official 15:a81a8d6c1dfe 62 /* To save the i2c objects */
mbed_official 15:a81a8d6c1dfe 63 static uint32_t i2c_instances[SERCOM_INST_NUM] = {0};
mbed_official 15:a81a8d6c1dfe 64 const uint32_t sercom_irq_handlers[SERCOM_INST_NUM] = {
mbed_official 15:a81a8d6c1dfe 65 MREPEAT(SERCOM_INST_NUM, _SERCOM_INTERRUPT_HANDLERS, ~)
mbed_official 15:a81a8d6c1dfe 66 };
mbed_official 64:41a834223ea3 67
mbed_official 15:a81a8d6c1dfe 68 #endif
mbed_official 15:a81a8d6c1dfe 69
mbed_official 15:a81a8d6c1dfe 70 /* Forward declaration */
mbed_official 15:a81a8d6c1dfe 71 enum status_code _i2c_master_wait_for_bus(
mbed_official 15:a81a8d6c1dfe 72 struct i2c_master_module *const module);
mbed_official 15:a81a8d6c1dfe 73
mbed_official 15:a81a8d6c1dfe 74 enum status_code _i2c_master_address_response(
mbed_official 15:a81a8d6c1dfe 75 struct i2c_master_module *const module);
mbed_official 15:a81a8d6c1dfe 76
mbed_official 15:a81a8d6c1dfe 77 enum status_code _i2c_master_send_hs_master_code(
mbed_official 15:a81a8d6c1dfe 78 struct i2c_master_module *const module,
mbed_official 15:a81a8d6c1dfe 79 uint8_t hs_master_code);
mbed_official 15:a81a8d6c1dfe 80
mbed_official 15:a81a8d6c1dfe 81 /* Adding function from ASF for compatibility */
mbed_official 15:a81a8d6c1dfe 82 static enum status_code _i2c_slave_wait_for_bus(
mbed_official 15:a81a8d6c1dfe 83 struct i2c_slave_module *const module)
mbed_official 15:a81a8d6c1dfe 84 {
mbed_official 15:a81a8d6c1dfe 85 /* Sanity check arguments. */
mbed_official 15:a81a8d6c1dfe 86 MBED_ASSERT(module);
mbed_official 15:a81a8d6c1dfe 87 MBED_ASSERT(module->hw);
mbed_official 15:a81a8d6c1dfe 88
mbed_official 15:a81a8d6c1dfe 89 SercomI2cs *const i2c_hw = &(module->hw->I2CS);
mbed_official 15:a81a8d6c1dfe 90
mbed_official 15:a81a8d6c1dfe 91 /* Wait for reply. */
mbed_official 15:a81a8d6c1dfe 92 uint16_t timeout_counter = 0;
mbed_official 15:a81a8d6c1dfe 93 while ((!(i2c_hw->INTFLAG.reg & SERCOM_I2CS_INTFLAG_DRDY)) &&
mbed_official 15:a81a8d6c1dfe 94 (!(i2c_hw->INTFLAG.reg & SERCOM_I2CS_INTFLAG_PREC)) &&
mbed_official 15:a81a8d6c1dfe 95 (!(i2c_hw->INTFLAG.reg & SERCOM_I2CS_INTFLAG_AMATCH))) {
mbed_official 15:a81a8d6c1dfe 96
mbed_official 15:a81a8d6c1dfe 97 /* Check timeout condition. */
mbed_official 15:a81a8d6c1dfe 98 if (++timeout_counter >= module->buffer_timeout) {
mbed_official 15:a81a8d6c1dfe 99 return STATUS_ERR_TIMEOUT;
mbed_official 15:a81a8d6c1dfe 100 }
mbed_official 15:a81a8d6c1dfe 101 }
mbed_official 15:a81a8d6c1dfe 102 return STATUS_OK;
mbed_official 15:a81a8d6c1dfe 103 }
mbed_official 15:a81a8d6c1dfe 104
mbed_official 15:a81a8d6c1dfe 105 /** Initialize the I2C peripheral
mbed_official 15:a81a8d6c1dfe 106 *
mbed_official 15:a81a8d6c1dfe 107 * Configures the pins used by I2C, sets a default format and frequency, and enables the peripheral
mbed_official 15:a81a8d6c1dfe 108 * @param[out] obj The I2C object to initialize
mbed_official 15:a81a8d6c1dfe 109 * @param[in] sda The pin to use for SDA
mbed_official 15:a81a8d6c1dfe 110 * @param[in] scl The pin to use for SCL
mbed_official 15:a81a8d6c1dfe 111 * @return void
mbed_official 15:a81a8d6c1dfe 112 */
mbed_official 15:a81a8d6c1dfe 113 void i2c_init(i2c_t *obj, PinName sda, PinName scl)
mbed_official 15:a81a8d6c1dfe 114 {
mbed_official 15:a81a8d6c1dfe 115 Sercom* hw;
mbed_official 15:a81a8d6c1dfe 116 uint32_t mux_func;
mbed_official 15:a81a8d6c1dfe 117 struct i2c_master_config config_i2c_master;
mbed_official 15:a81a8d6c1dfe 118
mbed_official 15:a81a8d6c1dfe 119 /* Sanity check arguments */
mbed_official 15:a81a8d6c1dfe 120 MBED_ASSERT(obj);
mbed_official 15:a81a8d6c1dfe 121 MBED_ASSERT(sda != NC);
mbed_official 15:a81a8d6c1dfe 122 MBED_ASSERT(scl != NC);
mbed_official 15:a81a8d6c1dfe 123
mbed_official 15:a81a8d6c1dfe 124 if (g_sys_init == 0) {
mbed_official 15:a81a8d6c1dfe 125 system_init();
mbed_official 15:a81a8d6c1dfe 126 g_sys_init = 1;
mbed_official 15:a81a8d6c1dfe 127 }
mbed_official 15:a81a8d6c1dfe 128
mbed_official 15:a81a8d6c1dfe 129 pI2C_S(obj)->pins[0] = sda;
mbed_official 15:a81a8d6c1dfe 130 pI2C_S(obj)->pins[1] = scl;
mbed_official 15:a81a8d6c1dfe 131
mbed_official 15:a81a8d6c1dfe 132 /* Calculate SERCOM instance from pins */
mbed_official 15:a81a8d6c1dfe 133 uint32_t sercom_index = pinmap_merge_sercom(sda, scl);
mbed_official 15:a81a8d6c1dfe 134 if (sercom_index == (uint32_t)NC) {
mbed_official 15:a81a8d6c1dfe 135 return;
mbed_official 15:a81a8d6c1dfe 136 }
mbed_official 15:a81a8d6c1dfe 137 hw = (Sercom*)pinmap_peripheral_sercom(NC, sercom_index);
mbed_official 15:a81a8d6c1dfe 138
mbed_official 15:a81a8d6c1dfe 139 i2c_master_get_config_defaults(&config_i2c_master);
mbed_official 15:a81a8d6c1dfe 140
mbed_official 15:a81a8d6c1dfe 141 /* SERCOM PAD0 - SDA */
mbed_official 15:a81a8d6c1dfe 142 mux_func = pinmap_function_sercom(sda, sercom_index);
mbed_official 15:a81a8d6c1dfe 143 if (mux_func == (uint32_t)NC) return;
mbed_official 15:a81a8d6c1dfe 144 config_i2c_master.pinmux_pad0 = (sda << 16) | (mux_func & 0xFFFF);
mbed_official 15:a81a8d6c1dfe 145
mbed_official 15:a81a8d6c1dfe 146 /* SERCOM PAD1 - SCL */
mbed_official 15:a81a8d6c1dfe 147 mux_func = pinmap_function_sercom(scl, sercom_index);
mbed_official 15:a81a8d6c1dfe 148 if (mux_func == (uint32_t)NC) return;
mbed_official 15:a81a8d6c1dfe 149 config_i2c_master.pinmux_pad1 = (scl << 16) | (mux_func & 0xFFFF);
mbed_official 15:a81a8d6c1dfe 150
mbed_official 15:a81a8d6c1dfe 151 /* Default baud rate is set to 100kHz */
mbed_official 15:a81a8d6c1dfe 152 pI2C_S(obj)->baud_rate = I2C_MASTER_DEFAULT_BAUD;
mbed_official 15:a81a8d6c1dfe 153 config_i2c_master.baud_rate = pI2C_S(obj)->baud_rate / 1000;
mbed_official 15:a81a8d6c1dfe 154
mbed_official 15:a81a8d6c1dfe 155 while(i2c_master_init(&pI2C_S(obj)->master, hw, &config_i2c_master) != STATUS_OK);
mbed_official 15:a81a8d6c1dfe 156 pI2C_S(obj)->mode = I2C_MODE_MASTER;
mbed_official 15:a81a8d6c1dfe 157
mbed_official 15:a81a8d6c1dfe 158 #if DEVICE_I2C_ASYNCH
mbed_official 15:a81a8d6c1dfe 159 /* Save the i2c object */
mbed_official 15:a81a8d6c1dfe 160 i2c_instances[sercom_index] = (uint32_t)obj;
mbed_official 15:a81a8d6c1dfe 161 #endif
mbed_official 15:a81a8d6c1dfe 162
mbed_official 15:a81a8d6c1dfe 163 i2c_master_enable(&pI2C_S(obj)->master);
mbed_official 15:a81a8d6c1dfe 164 }
mbed_official 15:a81a8d6c1dfe 165
mbed_official 15:a81a8d6c1dfe 166 /** Configure the I2C frequency.
mbed_official 15:a81a8d6c1dfe 167 * @param obj The i2c object
mbed_official 15:a81a8d6c1dfe 168 * @param hz Frequency in Hz
mbed_official 15:a81a8d6c1dfe 169 */
mbed_official 15:a81a8d6c1dfe 170 void i2c_frequency(i2c_t *obj, int hz)
mbed_official 15:a81a8d6c1dfe 171 {
mbed_official 15:a81a8d6c1dfe 172 /* Temporary variables. */
mbed_official 15:a81a8d6c1dfe 173 int32_t baud_rate;
mbed_official 15:a81a8d6c1dfe 174 int32_t tmp_baud;
mbed_official 15:a81a8d6c1dfe 175 int32_t tmp_baud_hs;
AnnaBridge 171:89b338f31ef1 176 enum status_code tmp_status_code = STATUS_OK;
mbed_official 15:a81a8d6c1dfe 177
mbed_official 15:a81a8d6c1dfe 178 /* Sanity check arguments */
mbed_official 15:a81a8d6c1dfe 179 MBED_ASSERT(obj);
mbed_official 15:a81a8d6c1dfe 180 MBED_ASSERT(pI2C_S(obj)->master.hw);
mbed_official 15:a81a8d6c1dfe 181
mbed_official 15:a81a8d6c1dfe 182 /* Return if in Slave mode, slave do not have any baud to set */
mbed_official 15:a81a8d6c1dfe 183 if (pI2C_S(obj)->mode != I2C_MODE_MASTER) return;
mbed_official 15:a81a8d6c1dfe 184
mbed_official 15:a81a8d6c1dfe 185 SercomI2cm *const i2c_module = &(pI2C_S(obj)->master.hw->I2CM);
mbed_official 15:a81a8d6c1dfe 186
mbed_official 15:a81a8d6c1dfe 187 /* Disable I2C Module */
mbed_official 15:a81a8d6c1dfe 188 i2c_master_disable(&pI2C_S(obj)->master);
mbed_official 15:a81a8d6c1dfe 189
mbed_official 15:a81a8d6c1dfe 190 baud_rate = hz / 1000; /* To kHz */
mbed_official 15:a81a8d6c1dfe 191
mbed_official 15:a81a8d6c1dfe 192 /* Give a dummy supported value */
mbed_official 15:a81a8d6c1dfe 193 pI2C_S(obj)->baud_rate_high_speed = I2C_MASTER_BAUD_RATE_3400KHZ;
mbed_official 15:a81a8d6c1dfe 194
mbed_official 15:a81a8d6c1dfe 195 uint32_t sercom_index = _sercom_get_sercom_inst_index(pI2C_S(obj)->master.hw);
mbed_official 15:a81a8d6c1dfe 196
mbed_official 15:a81a8d6c1dfe 197 /* Find and set baudrate. */
mbed_official 15:a81a8d6c1dfe 198 tmp_baud = (int32_t)(div_ceil(
mbed_official 15:a81a8d6c1dfe 199 system_gclk_chan_get_hz(SERCOM0_GCLK_ID_CORE + sercom_index), (2000*(baud_rate))) - 5);
mbed_official 15:a81a8d6c1dfe 200
mbed_official 15:a81a8d6c1dfe 201 /* Check that baudrate is supported at current speed. */
mbed_official 15:a81a8d6c1dfe 202 if (tmp_baud > 255 || tmp_baud < 0) {
mbed_official 15:a81a8d6c1dfe 203 /* Baud rate not supported. */
mbed_official 15:a81a8d6c1dfe 204 tmp_status_code = STATUS_ERR_BAUDRATE_UNAVAILABLE;
mbed_official 15:a81a8d6c1dfe 205 } else {
mbed_official 15:a81a8d6c1dfe 206 /* Find baudrate for high speed */
mbed_official 15:a81a8d6c1dfe 207 tmp_baud_hs = (int32_t)(div_ceil(
mbed_official 15:a81a8d6c1dfe 208 system_gclk_chan_get_hz(SERCOM0_GCLK_ID_CORE + sercom_index),
mbed_official 15:a81a8d6c1dfe 209 (2000*(pI2C_S(obj)->baud_rate_high_speed))) - 1);
mbed_official 15:a81a8d6c1dfe 210
mbed_official 15:a81a8d6c1dfe 211 /* Check that baudrate is supported at current speed. */
mbed_official 15:a81a8d6c1dfe 212 if (tmp_baud_hs > 255 || tmp_baud_hs < 0) {
mbed_official 15:a81a8d6c1dfe 213 /* Baud rate not supported. */
mbed_official 15:a81a8d6c1dfe 214 tmp_status_code = STATUS_ERR_BAUDRATE_UNAVAILABLE;
mbed_official 15:a81a8d6c1dfe 215 }
mbed_official 15:a81a8d6c1dfe 216 }
mbed_official 15:a81a8d6c1dfe 217 if (tmp_status_code != STATUS_ERR_BAUDRATE_UNAVAILABLE) {
mbed_official 15:a81a8d6c1dfe 218 /* Baud rate acceptable. */
mbed_official 15:a81a8d6c1dfe 219 i2c_module->BAUD.reg = SERCOM_I2CM_BAUD_BAUD(tmp_baud) | SERCOM_I2CM_BAUD_HSBAUD(tmp_baud_hs);
mbed_official 15:a81a8d6c1dfe 220 pI2C_S(obj)->baud_rate = hz;
mbed_official 15:a81a8d6c1dfe 221 }
mbed_official 15:a81a8d6c1dfe 222
mbed_official 15:a81a8d6c1dfe 223 /* Enable back the I2C Module */
mbed_official 15:a81a8d6c1dfe 224 i2c_master_enable(&pI2C_S(obj)->master);
mbed_official 15:a81a8d6c1dfe 225 }
mbed_official 15:a81a8d6c1dfe 226
mbed_official 15:a81a8d6c1dfe 227 /** Send START command.
mbed_official 15:a81a8d6c1dfe 228 * @param obj The i2c object
mbed_official 15:a81a8d6c1dfe 229 */
mbed_official 15:a81a8d6c1dfe 230 int i2c_start(i2c_t *obj)
mbed_official 15:a81a8d6c1dfe 231 {
mbed_official 15:a81a8d6c1dfe 232 /* Sanity check arguments */
mbed_official 15:a81a8d6c1dfe 233 MBED_ASSERT(obj);
mbed_official 15:a81a8d6c1dfe 234
mbed_official 15:a81a8d6c1dfe 235 if (pI2C_S(obj)->mode == I2C_MODE_MASTER) {
mbed_official 15:a81a8d6c1dfe 236 pI2C_S(obj)->start_pending = 1;
mbed_official 15:a81a8d6c1dfe 237 }
mbed_official 15:a81a8d6c1dfe 238 return 0;
mbed_official 15:a81a8d6c1dfe 239 }
mbed_official 15:a81a8d6c1dfe 240
mbed_official 15:a81a8d6c1dfe 241 /** Send STOP command.
mbed_official 15:a81a8d6c1dfe 242 * @param obj The i2c object
mbed_official 15:a81a8d6c1dfe 243 */
mbed_official 15:a81a8d6c1dfe 244 int i2c_stop(i2c_t *obj)
mbed_official 15:a81a8d6c1dfe 245 {
mbed_official 15:a81a8d6c1dfe 246 /* Sanity check arguments */
mbed_official 15:a81a8d6c1dfe 247 MBED_ASSERT(obj);
mbed_official 15:a81a8d6c1dfe 248
mbed_official 15:a81a8d6c1dfe 249 if (pI2C_S(obj)->mode == I2C_MODE_MASTER) {
mbed_official 15:a81a8d6c1dfe 250 /* Send STOP command */
mbed_official 15:a81a8d6c1dfe 251 i2c_master_send_stop(&pI2C_S(obj)->master);
mbed_official 15:a81a8d6c1dfe 252 } else {
mbed_official 15:a81a8d6c1dfe 253 SercomI2cs *const i2c_hw = &(pI2C_S(obj)->slave.hw->I2CS);
mbed_official 15:a81a8d6c1dfe 254 /* Release line and wait for next start condition */
mbed_official 15:a81a8d6c1dfe 255 i2c_hw->CTRLB.reg |= SERCOM_I2CS_CTRLB_CMD(0x2);
mbed_official 15:a81a8d6c1dfe 256 }
mbed_official 15:a81a8d6c1dfe 257
mbed_official 15:a81a8d6c1dfe 258 pI2C_S(obj)->start_pending = 0;
mbed_official 15:a81a8d6c1dfe 259
mbed_official 15:a81a8d6c1dfe 260 /* TODO: Wait till STOP is send */
mbed_official 15:a81a8d6c1dfe 261 return 0;
mbed_official 15:a81a8d6c1dfe 262 }
mbed_official 15:a81a8d6c1dfe 263
mbed_official 15:a81a8d6c1dfe 264 /** Blocking reading data.
mbed_official 15:a81a8d6c1dfe 265 * @param obj The i2c object
mbed_official 15:a81a8d6c1dfe 266 * @param address 7-bit address (last bit is 1)
mbed_official 15:a81a8d6c1dfe 267 * @param data The buffer for receiving
mbed_official 15:a81a8d6c1dfe 268 * @param length Number of bytes to read
mbed_official 15:a81a8d6c1dfe 269 * @param stop Stop to be generated after the transfer is done
mbed_official 15:a81a8d6c1dfe 270 * @return Number of read bytes
mbed_official 15:a81a8d6c1dfe 271 */
mbed_official 15:a81a8d6c1dfe 272 int i2c_read(i2c_t *obj, int address, char *data, int length, int stop)
mbed_official 15:a81a8d6c1dfe 273 {
mbed_official 15:a81a8d6c1dfe 274 /* Sanity check arguments */
mbed_official 15:a81a8d6c1dfe 275 MBED_ASSERT(obj);
mbed_official 15:a81a8d6c1dfe 276 MBED_ASSERT(pI2C_S(obj)->master.hw);
mbed_official 15:a81a8d6c1dfe 277
mbed_official 15:a81a8d6c1dfe 278 enum status_code tmp_status;
mbed_official 15:a81a8d6c1dfe 279
mbed_official 15:a81a8d6c1dfe 280 #if DEVICE_I2C_ASYNCH
mbed_official 15:a81a8d6c1dfe 281 if (i2c_active(obj)) {
mbed_official 15:a81a8d6c1dfe 282 /* I2C is busy with a job */
mbed_official 15:a81a8d6c1dfe 283 return 0;
mbed_official 15:a81a8d6c1dfe 284 }
mbed_official 15:a81a8d6c1dfe 285 #endif
mbed_official 15:a81a8d6c1dfe 286
mbed_official 15:a81a8d6c1dfe 287 struct i2c_master_packet packet;
mbed_official 15:a81a8d6c1dfe 288 packet.address = (address & 0xFF) >> 1;
mbed_official 15:a81a8d6c1dfe 289 packet.data_length = length;
mbed_official 15:a81a8d6c1dfe 290 packet.data = (uint8_t*)data;
mbed_official 15:a81a8d6c1dfe 291 packet.ten_bit_address = false;
mbed_official 15:a81a8d6c1dfe 292 packet.high_speed = false;
mbed_official 15:a81a8d6c1dfe 293
mbed_official 15:a81a8d6c1dfe 294 if (stop) {
mbed_official 15:a81a8d6c1dfe 295 tmp_status = i2c_master_read_packet_wait(&pI2C_S(obj)->master, &packet);
mbed_official 15:a81a8d6c1dfe 296 } else {
mbed_official 15:a81a8d6c1dfe 297 tmp_status = i2c_master_read_packet_wait_no_stop(&pI2C_S(obj)->master, &packet);
mbed_official 15:a81a8d6c1dfe 298 }
mbed_official 15:a81a8d6c1dfe 299
mbed_official 15:a81a8d6c1dfe 300 if (tmp_status == STATUS_OK) {
mbed_official 15:a81a8d6c1dfe 301 return length;
mbed_official 15:a81a8d6c1dfe 302 } else {
mbed_official 15:a81a8d6c1dfe 303 /* Currently, no way to track no of bytes received, so return 0 if fail */
mbed_official 15:a81a8d6c1dfe 304 return 0;
mbed_official 15:a81a8d6c1dfe 305 }
mbed_official 15:a81a8d6c1dfe 306 }
mbed_official 15:a81a8d6c1dfe 307
mbed_official 15:a81a8d6c1dfe 308 /** Blocking sending data.
mbed_official 15:a81a8d6c1dfe 309 * @param obj The i2c object
mbed_official 15:a81a8d6c1dfe 310 * @param address 7-bit address (last bit is 0)
mbed_official 15:a81a8d6c1dfe 311 * @param data The buffer for sending
mbed_official 15:a81a8d6c1dfe 312 * @param length Number of bytes to write
mbed_official 15:a81a8d6c1dfe 313 * @param stop Stop to be generated after the transfer is done
mbed_official 15:a81a8d6c1dfe 314 * @return Number of written bytes
mbed_official 15:a81a8d6c1dfe 315 */
mbed_official 15:a81a8d6c1dfe 316 int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop)
mbed_official 15:a81a8d6c1dfe 317 {
mbed_official 15:a81a8d6c1dfe 318 /* Sanity check arguments */
mbed_official 15:a81a8d6c1dfe 319 MBED_ASSERT(obj);
mbed_official 15:a81a8d6c1dfe 320 MBED_ASSERT(pI2C_S(obj)->master.hw);
mbed_official 15:a81a8d6c1dfe 321
mbed_official 15:a81a8d6c1dfe 322 enum status_code tmp_status;
mbed_official 15:a81a8d6c1dfe 323
mbed_official 15:a81a8d6c1dfe 324 #if DEVICE_I2C_ASYNCH
mbed_official 15:a81a8d6c1dfe 325 if (i2c_active(obj)) {
mbed_official 15:a81a8d6c1dfe 326 /* I2C is busy with a job */
mbed_official 15:a81a8d6c1dfe 327 return 0;
mbed_official 15:a81a8d6c1dfe 328 }
mbed_official 15:a81a8d6c1dfe 329 #endif
mbed_official 15:a81a8d6c1dfe 330
mbed_official 15:a81a8d6c1dfe 331 struct i2c_master_packet packet;
mbed_official 15:a81a8d6c1dfe 332 packet.address = (address & 0xFF) >> 1;
mbed_official 15:a81a8d6c1dfe 333 packet.data_length = length;
mbed_official 64:41a834223ea3 334 packet.data = (uint8_t *)data;
mbed_official 15:a81a8d6c1dfe 335 packet.ten_bit_address = false;
mbed_official 15:a81a8d6c1dfe 336 packet.high_speed = false;
mbed_official 15:a81a8d6c1dfe 337
mbed_official 15:a81a8d6c1dfe 338 if (stop) {
mbed_official 15:a81a8d6c1dfe 339 tmp_status = i2c_master_write_packet_wait(&pI2C_S(obj)->master, &packet);
mbed_official 15:a81a8d6c1dfe 340 } else {
mbed_official 15:a81a8d6c1dfe 341 tmp_status = i2c_master_write_packet_wait_no_stop(&pI2C_S(obj)->master, &packet);
mbed_official 15:a81a8d6c1dfe 342 }
mbed_official 15:a81a8d6c1dfe 343
mbed_official 15:a81a8d6c1dfe 344 if (tmp_status == STATUS_OK) {
mbed_official 15:a81a8d6c1dfe 345 return length;
mbed_official 15:a81a8d6c1dfe 346 } else {
mbed_official 15:a81a8d6c1dfe 347 /* Currently, no way to track no of bytes transmitted, so return 0 if fail */
mbed_official 15:a81a8d6c1dfe 348 return 0;
mbed_official 15:a81a8d6c1dfe 349 }
mbed_official 15:a81a8d6c1dfe 350 }
mbed_official 15:a81a8d6c1dfe 351
mbed_official 15:a81a8d6c1dfe 352 /** Reset I2C peripheral.
mbed_official 15:a81a8d6c1dfe 353 * @param obj The i2c object
mbed_official 15:a81a8d6c1dfe 354 */
mbed_official 15:a81a8d6c1dfe 355 void i2c_reset(i2c_t *obj)
mbed_official 15:a81a8d6c1dfe 356 {
mbed_official 15:a81a8d6c1dfe 357 /* Sanity check arguments */
mbed_official 15:a81a8d6c1dfe 358 MBED_ASSERT(obj);
mbed_official 15:a81a8d6c1dfe 359
mbed_official 15:a81a8d6c1dfe 360 /* Send STOP */
mbed_official 15:a81a8d6c1dfe 361 i2c_stop(obj);
mbed_official 15:a81a8d6c1dfe 362
mbed_official 15:a81a8d6c1dfe 363 pI2C_S(obj)->start_pending = 0;
mbed_official 15:a81a8d6c1dfe 364 }
mbed_official 15:a81a8d6c1dfe 365
mbed_official 15:a81a8d6c1dfe 366 /** Write address preceded by START condition.
mbed_official 15:a81a8d6c1dfe 367 * @param obj The i2c object
mbed_official 15:a81a8d6c1dfe 368 * @param address Address to be placed
mbed_official 15:a81a8d6c1dfe 369 * @param rw_flag read or write flag
mbed_official 15:a81a8d6c1dfe 370 * @return 1 if NAK was received, 0 if ACK was received, 2 for timeout.
mbed_official 15:a81a8d6c1dfe 371 */
mbed_official 15:a81a8d6c1dfe 372 int i2c_write_address(i2c_t *obj, int address, int rw_flag)
mbed_official 15:a81a8d6c1dfe 373 {
mbed_official 15:a81a8d6c1dfe 374 /* Sanity check arguments */
mbed_official 15:a81a8d6c1dfe 375 MBED_ASSERT(obj);
mbed_official 15:a81a8d6c1dfe 376 MBED_ASSERT(pI2C_S(obj)->master.hw);
mbed_official 15:a81a8d6c1dfe 377
mbed_official 15:a81a8d6c1dfe 378 enum status_code tmp_status;
mbed_official 15:a81a8d6c1dfe 379 SercomI2cm *const i2c_module = &(pI2C_S(obj)->master.hw->I2CM);
mbed_official 15:a81a8d6c1dfe 380
mbed_official 15:a81a8d6c1dfe 381 _i2c_master_wait_for_sync(&pI2C_S(obj)->master);
mbed_official 15:a81a8d6c1dfe 382
mbed_official 15:a81a8d6c1dfe 383 /* Set action to ACK. */
mbed_official 15:a81a8d6c1dfe 384 i2c_module->CTRLB.reg &= ~SERCOM_I2CM_CTRLB_ACKACT;
mbed_official 15:a81a8d6c1dfe 385
mbed_official 15:a81a8d6c1dfe 386 /* Write 7-bit address + read/write flag */
mbed_official 15:a81a8d6c1dfe 387 i2c_module->ADDR.reg = ((address & 0x7F) << 1) | (rw_flag & 0x01) | (0 << SERCOM_I2CM_ADDR_HS_Pos);
mbed_official 15:a81a8d6c1dfe 388
mbed_official 15:a81a8d6c1dfe 389 /* Wait for response on bus. */
mbed_official 15:a81a8d6c1dfe 390 tmp_status = _i2c_master_wait_for_bus(&pI2C_S(obj)->master);
mbed_official 15:a81a8d6c1dfe 391 /* Check for error. */
mbed_official 15:a81a8d6c1dfe 392 if (tmp_status != STATUS_OK) {
mbed_official 15:a81a8d6c1dfe 393 return I2C_ERROR_BUS_BUSY;
mbed_official 15:a81a8d6c1dfe 394 }
mbed_official 15:a81a8d6c1dfe 395 /* Check for address response error unless previous error is detected. */
mbed_official 15:a81a8d6c1dfe 396 tmp_status = _i2c_master_address_response(&pI2C_S(obj)->master);
mbed_official 15:a81a8d6c1dfe 397 if (tmp_status != STATUS_OK) {
mbed_official 15:a81a8d6c1dfe 398 return I2C_ERROR_NO_SLAVE;
mbed_official 15:a81a8d6c1dfe 399 }
mbed_official 15:a81a8d6c1dfe 400
mbed_official 15:a81a8d6c1dfe 401 return 0;
mbed_official 15:a81a8d6c1dfe 402 }
mbed_official 15:a81a8d6c1dfe 403
mbed_official 15:a81a8d6c1dfe 404 /** Read one byte.
mbed_official 15:a81a8d6c1dfe 405 * @param obj The i2c object
mbed_official 15:a81a8d6c1dfe 406 * @param last Acknowledge
mbed_official 15:a81a8d6c1dfe 407 * @return The read byte
mbed_official 15:a81a8d6c1dfe 408 */
mbed_official 15:a81a8d6c1dfe 409 int i2c_byte_read(i2c_t *obj, int last)
mbed_official 15:a81a8d6c1dfe 410 {
mbed_official 15:a81a8d6c1dfe 411 int data = -1;
mbed_official 15:a81a8d6c1dfe 412 /* Sanity check arguments */
mbed_official 15:a81a8d6c1dfe 413 MBED_ASSERT(obj);
mbed_official 15:a81a8d6c1dfe 414 MBED_ASSERT(pI2C_S(obj)->master.hw);
mbed_official 15:a81a8d6c1dfe 415
mbed_official 15:a81a8d6c1dfe 416 enum status_code tmp_status;
mbed_official 15:a81a8d6c1dfe 417
mbed_official 15:a81a8d6c1dfe 418 if (pI2C_S(obj)->mode == I2C_MODE_MASTER) {
mbed_official 15:a81a8d6c1dfe 419 SercomI2cm *const i2c_module = &(pI2C_S(obj)->master.hw->I2CM);
mbed_official 15:a81a8d6c1dfe 420
mbed_official 15:a81a8d6c1dfe 421 if (last) {
mbed_official 15:a81a8d6c1dfe 422 /* Set action to nack. */
mbed_official 15:a81a8d6c1dfe 423 i2c_module->CTRLB.reg |= SERCOM_I2CM_CTRLB_ACKACT;
mbed_official 15:a81a8d6c1dfe 424 } else {
mbed_official 15:a81a8d6c1dfe 425 /* Set action to ack. */
mbed_official 15:a81a8d6c1dfe 426 i2c_module->CTRLB.reg &= ~SERCOM_I2CM_CTRLB_ACKACT;
mbed_official 15:a81a8d6c1dfe 427 }
mbed_official 15:a81a8d6c1dfe 428
mbed_official 15:a81a8d6c1dfe 429 /* Check that bus ownership is not lost. */
mbed_official 15:a81a8d6c1dfe 430 if (!(i2c_module->STATUS.reg & SERCOM_I2CM_STATUS_BUSSTATE(2))) {
mbed_official 15:a81a8d6c1dfe 431 return -1; /* Return invalid data*/
mbed_official 15:a81a8d6c1dfe 432 }
mbed_official 15:a81a8d6c1dfe 433
mbed_official 15:a81a8d6c1dfe 434 /* Save data to buffer. */
mbed_official 15:a81a8d6c1dfe 435 _i2c_master_wait_for_sync(&pI2C_S(obj)->master);
mbed_official 15:a81a8d6c1dfe 436 data = i2c_module->DATA.reg;
mbed_official 15:a81a8d6c1dfe 437 /* Wait for response. */
mbed_official 15:a81a8d6c1dfe 438 tmp_status = _i2c_master_wait_for_bus(&pI2C_S(obj)->master);
mbed_official 15:a81a8d6c1dfe 439
mbed_official 15:a81a8d6c1dfe 440 /* Check for error. */
mbed_official 15:a81a8d6c1dfe 441 if (tmp_status != STATUS_OK) {
mbed_official 15:a81a8d6c1dfe 442 return -1; /* Return invalid data*/
mbed_official 15:a81a8d6c1dfe 443 }
mbed_official 15:a81a8d6c1dfe 444
mbed_official 15:a81a8d6c1dfe 445 } else {
mbed_official 15:a81a8d6c1dfe 446 #if DEVICE_I2CSLAVE
mbed_official 15:a81a8d6c1dfe 447 SercomI2cs *const i2c_hw = &(pI2C_S(obj)->slave.hw->I2CS);
mbed_official 15:a81a8d6c1dfe 448
mbed_official 15:a81a8d6c1dfe 449 /* Check direction */
mbed_official 15:a81a8d6c1dfe 450 if (i2c_hw->STATUS.reg & SERCOM_I2CS_STATUS_DIR) {
mbed_official 15:a81a8d6c1dfe 451 /* Write request from master, send NACK and return */
mbed_official 15:a81a8d6c1dfe 452 i2c_hw->CTRLB.reg |= SERCOM_I2CS_CTRLB_ACKACT;
mbed_official 15:a81a8d6c1dfe 453 i2c_hw->CTRLB.reg |= SERCOM_I2CS_CTRLB_CMD(0x3);
mbed_official 15:a81a8d6c1dfe 454 return -1; /* Return invalid data*/
mbed_official 15:a81a8d6c1dfe 455 }
mbed_official 15:a81a8d6c1dfe 456
mbed_official 15:a81a8d6c1dfe 457 if (i2c_hw->INTFLAG.reg & SERCOM_I2CS_INTFLAG_AMATCH) {
mbed_official 15:a81a8d6c1dfe 458 /* Request from master, Address not yet acknowledged */
mbed_official 15:a81a8d6c1dfe 459 i2c_hw->CTRLB.reg &= ~SERCOM_I2CS_CTRLB_ACKACT;
mbed_official 15:a81a8d6c1dfe 460 i2c_hw->CTRLB.reg |= SERCOM_I2CS_CTRLB_CMD(0x3);
mbed_official 15:a81a8d6c1dfe 461 i2c_hw->INTFLAG.reg = SERCOM_I2CS_INTFLAG_AMATCH;
mbed_official 15:a81a8d6c1dfe 462 }
mbed_official 15:a81a8d6c1dfe 463 if (last) {
mbed_official 15:a81a8d6c1dfe 464 /* Set action to nack. */
mbed_official 15:a81a8d6c1dfe 465 i2c_hw->CTRLB.reg |= SERCOM_I2CM_CTRLB_ACKACT;
mbed_official 15:a81a8d6c1dfe 466 } else {
mbed_official 15:a81a8d6c1dfe 467 /* Set action to ack. */
mbed_official 15:a81a8d6c1dfe 468 i2c_hw->CTRLB.reg &= ~SERCOM_I2CM_CTRLB_ACKACT;
mbed_official 15:a81a8d6c1dfe 469 }
mbed_official 15:a81a8d6c1dfe 470
mbed_official 15:a81a8d6c1dfe 471 /* Wait for next byte or stop condition */
mbed_official 15:a81a8d6c1dfe 472 tmp_status = _i2c_slave_wait_for_bus(&pI2C_S(obj)->slave);
mbed_official 15:a81a8d6c1dfe 473 if (tmp_status != STATUS_OK) {
mbed_official 15:a81a8d6c1dfe 474 /* Timeout, return */
mbed_official 15:a81a8d6c1dfe 475 return -1;
mbed_official 15:a81a8d6c1dfe 476 }
mbed_official 15:a81a8d6c1dfe 477
mbed_official 15:a81a8d6c1dfe 478 if (i2c_hw->INTFLAG.reg & SERCOM_I2CS_INTFLAG_PREC) {
mbed_official 15:a81a8d6c1dfe 479 /* Master sent stop condition, or repeated start, read done */
mbed_official 15:a81a8d6c1dfe 480 /* Clear stop flag */
mbed_official 15:a81a8d6c1dfe 481 i2c_hw->INTFLAG.reg = SERCOM_I2CS_INTFLAG_PREC;
mbed_official 15:a81a8d6c1dfe 482 return -1;
mbed_official 15:a81a8d6c1dfe 483 }
mbed_official 15:a81a8d6c1dfe 484
mbed_official 15:a81a8d6c1dfe 485 /* Read data */
mbed_official 15:a81a8d6c1dfe 486 _i2c_slave_wait_for_sync(&pI2C_S(obj)->slave);
mbed_official 15:a81a8d6c1dfe 487 data = i2c_hw->DATA.reg;
mbed_official 15:a81a8d6c1dfe 488 #endif
mbed_official 15:a81a8d6c1dfe 489 }
mbed_official 15:a81a8d6c1dfe 490
mbed_official 15:a81a8d6c1dfe 491 return data;
mbed_official 15:a81a8d6c1dfe 492 }
mbed_official 15:a81a8d6c1dfe 493
mbed_official 15:a81a8d6c1dfe 494 /** Write one byte.
mbed_official 15:a81a8d6c1dfe 495 * @param obj The i2c object
mbed_official 15:a81a8d6c1dfe 496 * @param data Byte to be written
mbed_official 15:a81a8d6c1dfe 497 * @return 1 if NAK was received, 0 if ACK was received, 2 for timeout.
mbed_official 15:a81a8d6c1dfe 498 */
mbed_official 15:a81a8d6c1dfe 499 int i2c_byte_write(i2c_t *obj, int data)
mbed_official 15:a81a8d6c1dfe 500 {
mbed_official 15:a81a8d6c1dfe 501 /* Sanity check arguments */
mbed_official 15:a81a8d6c1dfe 502 MBED_ASSERT(obj);
mbed_official 15:a81a8d6c1dfe 503 MBED_ASSERT(pI2C_S(obj)->master.hw);
mbed_official 15:a81a8d6c1dfe 504
mbed_official 15:a81a8d6c1dfe 505 enum status_code tmp_status;
mbed_official 15:a81a8d6c1dfe 506
mbed_official 15:a81a8d6c1dfe 507 data = data & 0xFF;
mbed_official 15:a81a8d6c1dfe 508
mbed_official 15:a81a8d6c1dfe 509 if (pI2C_S(obj)->mode == I2C_MODE_MASTER) {
mbed_official 15:a81a8d6c1dfe 510 SercomI2cm *const i2c_module = &(pI2C_S(obj)->master.hw->I2CM);
mbed_official 15:a81a8d6c1dfe 511
mbed_official 15:a81a8d6c1dfe 512 if (pI2C_S(obj)->start_pending) {
mbed_official 15:a81a8d6c1dfe 513 pI2C_S(obj)->start_pending = 0;
mbed_official 15:a81a8d6c1dfe 514 /* Write address */
mbed_official 15:a81a8d6c1dfe 515 return i2c_write_address(obj, (data >> 1), (data & 0x01));
mbed_official 15:a81a8d6c1dfe 516 } else {
mbed_official 15:a81a8d6c1dfe 517 /* Write data */
mbed_official 15:a81a8d6c1dfe 518 /* Check that bus ownership is not lost. */
mbed_official 15:a81a8d6c1dfe 519 if (!(i2c_module->STATUS.reg & SERCOM_I2CM_STATUS_BUSSTATE(2))) {
mbed_official 15:a81a8d6c1dfe 520 return I2C_ERROR_NO_SLAVE;
mbed_official 15:a81a8d6c1dfe 521 }
mbed_official 15:a81a8d6c1dfe 522
mbed_official 15:a81a8d6c1dfe 523 /* Write byte to slave. */
mbed_official 15:a81a8d6c1dfe 524 _i2c_master_wait_for_sync(&pI2C_S(obj)->master);
mbed_official 15:a81a8d6c1dfe 525 i2c_module->DATA.reg = data;
mbed_official 15:a81a8d6c1dfe 526
mbed_official 15:a81a8d6c1dfe 527 /* Wait for response. */
mbed_official 15:a81a8d6c1dfe 528 tmp_status = _i2c_master_wait_for_bus(&pI2C_S(obj)->master);
mbed_official 15:a81a8d6c1dfe 529 /* Check for error. */
mbed_official 15:a81a8d6c1dfe 530 if (tmp_status != STATUS_OK) {
mbed_official 15:a81a8d6c1dfe 531 return I2C_ERROR_BUS_BUSY;
mbed_official 15:a81a8d6c1dfe 532 }
mbed_official 15:a81a8d6c1dfe 533
mbed_official 15:a81a8d6c1dfe 534 /* Check for NACK from slave. */
mbed_official 15:a81a8d6c1dfe 535 if (i2c_module->STATUS.reg & SERCOM_I2CM_STATUS_RXNACK) {
mbed_official 15:a81a8d6c1dfe 536 /* Return bad data value. */
mbed_official 15:a81a8d6c1dfe 537 return I2C_ERROR_NO_SLAVE;
mbed_official 15:a81a8d6c1dfe 538 }
mbed_official 15:a81a8d6c1dfe 539 }
mbed_official 15:a81a8d6c1dfe 540 } else {
mbed_official 15:a81a8d6c1dfe 541 #if DEVICE_I2CSLAVE
mbed_official 15:a81a8d6c1dfe 542 SercomI2cs *const i2c_hw = &(pI2C_S(obj)->slave.hw->I2CS);
mbed_official 15:a81a8d6c1dfe 543
mbed_official 15:a81a8d6c1dfe 544 if (i2c_hw->INTFLAG.reg & SERCOM_I2CS_INTFLAG_AMATCH) {
mbed_official 15:a81a8d6c1dfe 545 /* Read request from master, Address not yet acknowledged */
mbed_official 15:a81a8d6c1dfe 546 i2c_hw->CTRLB.reg &= ~SERCOM_I2CS_CTRLB_ACKACT;
mbed_official 15:a81a8d6c1dfe 547 i2c_hw->CTRLB.reg |= SERCOM_I2CS_CTRLB_CMD(0x3);
mbed_official 15:a81a8d6c1dfe 548 i2c_hw->INTFLAG.reg = SERCOM_I2CS_INTFLAG_AMATCH;
mbed_official 15:a81a8d6c1dfe 549 }
mbed_official 15:a81a8d6c1dfe 550
mbed_official 15:a81a8d6c1dfe 551 /* Write data */
mbed_official 15:a81a8d6c1dfe 552 _i2c_slave_wait_for_sync(&pI2C_S(obj)->slave);
mbed_official 15:a81a8d6c1dfe 553 i2c_hw->DATA.reg = data;
mbed_official 15:a81a8d6c1dfe 554
mbed_official 15:a81a8d6c1dfe 555 /* Wait for response from master */
mbed_official 15:a81a8d6c1dfe 556 tmp_status = _i2c_slave_wait_for_bus(&pI2C_S(obj)->slave);
mbed_official 15:a81a8d6c1dfe 557
mbed_official 15:a81a8d6c1dfe 558 if (tmp_status != STATUS_OK) {
mbed_official 15:a81a8d6c1dfe 559 /* Timeout, return */
mbed_official 15:a81a8d6c1dfe 560 return I2C_ERROR_BUS_BUSY;
mbed_official 15:a81a8d6c1dfe 561 }
mbed_official 15:a81a8d6c1dfe 562
mbed_official 15:a81a8d6c1dfe 563 if (i2c_hw->STATUS.reg & SERCOM_I2CS_STATUS_RXNACK) {
mbed_official 15:a81a8d6c1dfe 564 /* NACK from master, abort */
mbed_official 15:a81a8d6c1dfe 565 /* Release line */
mbed_official 15:a81a8d6c1dfe 566 i2c_hw->CTRLB.reg |= SERCOM_I2CS_CTRLB_CMD(0x02);
mbed_official 15:a81a8d6c1dfe 567
mbed_official 15:a81a8d6c1dfe 568 return I2C_ERROR_NO_SLAVE;
mbed_official 15:a81a8d6c1dfe 569 }
mbed_official 15:a81a8d6c1dfe 570 #endif
mbed_official 15:a81a8d6c1dfe 571 }
mbed_official 15:a81a8d6c1dfe 572
mbed_official 15:a81a8d6c1dfe 573 return 0;
mbed_official 15:a81a8d6c1dfe 574 }
mbed_official 15:a81a8d6c1dfe 575
mbed_official 15:a81a8d6c1dfe 576
mbed_official 15:a81a8d6c1dfe 577 #if DEVICE_I2CSLAVE
mbed_official 15:a81a8d6c1dfe 578
mbed_official 15:a81a8d6c1dfe 579 /**
mbed_official 15:a81a8d6c1dfe 580 * \defgroup SynchI2C Synchronous I2C Hardware Abstraction Layer for slave
mbed_official 15:a81a8d6c1dfe 581 * @{
mbed_official 15:a81a8d6c1dfe 582 */
mbed_official 15:a81a8d6c1dfe 583
mbed_official 15:a81a8d6c1dfe 584 /** Configure I2C as slave or master.
mbed_official 15:a81a8d6c1dfe 585 * @param obj The I2C object
mbed_official 15:a81a8d6c1dfe 586 * @param enable_slave configure I2C in slave mode or not
mbed_official 15:a81a8d6c1dfe 587 * @return void
mbed_official 15:a81a8d6c1dfe 588 */
mbed_official 15:a81a8d6c1dfe 589 void i2c_slave_mode(i2c_t *obj, int enable_slave)
mbed_official 15:a81a8d6c1dfe 590 {
mbed_official 15:a81a8d6c1dfe 591 int i;
mbed_official 15:a81a8d6c1dfe 592 /* Sanity check arguments */
mbed_official 15:a81a8d6c1dfe 593 MBED_ASSERT(obj);
mbed_official 15:a81a8d6c1dfe 594 MBED_ASSERT(pI2C_S(obj)->master.hw);
mbed_official 15:a81a8d6c1dfe 595
mbed_official 15:a81a8d6c1dfe 596 uint32_t mux_func[2];
mbed_official 15:a81a8d6c1dfe 597 uint32_t sercom_index = _sercom_get_sercom_inst_index(pI2C_S(obj)->master.hw);
mbed_official 15:a81a8d6c1dfe 598 for (i=0; i<2; i++) {
mbed_official 15:a81a8d6c1dfe 599 mux_func[i] = pinmap_function_sercom(pI2C_S(obj)->pins[0], sercom_index);
mbed_official 64:41a834223ea3 600 if (mux_func[i] == (uint32_t)NC) return;
mbed_official 15:a81a8d6c1dfe 601 }
mbed_official 15:a81a8d6c1dfe 602
mbed_official 15:a81a8d6c1dfe 603 if (enable_slave) {
mbed_official 15:a81a8d6c1dfe 604 /* Disable I2C Master module if active */
mbed_official 15:a81a8d6c1dfe 605 i2c_master_disable(&pI2C_S(obj)->master);
mbed_official 15:a81a8d6c1dfe 606
mbed_official 15:a81a8d6c1dfe 607 struct i2c_slave_config config_i2c_slave;
mbed_official 15:a81a8d6c1dfe 608 i2c_slave_get_config_defaults(&config_i2c_slave);
mbed_official 15:a81a8d6c1dfe 609
mbed_official 15:a81a8d6c1dfe 610 /* SERCOM PAD0 - SDA */
mbed_official 15:a81a8d6c1dfe 611 config_i2c_slave.pinmux_pad0 = (pI2C_S(obj)->pins[0] << 16) | (mux_func[0] & 0xFFFF);
mbed_official 15:a81a8d6c1dfe 612 /* SERCOM PAD1 - SCL */
mbed_official 15:a81a8d6c1dfe 613 config_i2c_slave.pinmux_pad1 = (pI2C_S(obj)->pins[1] << 16) | (mux_func[1] & 0xFFFF);
mbed_official 15:a81a8d6c1dfe 614
mbed_official 15:a81a8d6c1dfe 615 i2c_slave_init(&pI2C_S(obj)->slave, pI2C_S(obj)->master.hw, &config_i2c_slave);
mbed_official 15:a81a8d6c1dfe 616
mbed_official 15:a81a8d6c1dfe 617 pI2C_S(obj)->mode = I2C_MODE_SLAVE;
mbed_official 15:a81a8d6c1dfe 618
mbed_official 15:a81a8d6c1dfe 619 i2c_slave_enable(&pI2C_S(obj)->slave);
mbed_official 15:a81a8d6c1dfe 620 } else {
mbed_official 15:a81a8d6c1dfe 621 if ((pI2C_S(obj)->master.hw) && (pI2C_S(obj)->mode == I2C_MODE_MASTER)) {
mbed_official 15:a81a8d6c1dfe 622 /* Already configured, enable and return */
mbed_official 15:a81a8d6c1dfe 623 i2c_master_enable(&pI2C_S(obj)->master);
mbed_official 15:a81a8d6c1dfe 624 return;
mbed_official 15:a81a8d6c1dfe 625 } else if ((pI2C_S(obj)->slave.hw) && (pI2C_S(obj)->mode == I2C_MODE_SLAVE)) {
mbed_official 15:a81a8d6c1dfe 626 /* Disable slave */
mbed_official 15:a81a8d6c1dfe 627 i2c_slave_disable(&pI2C_S(obj)->slave);
mbed_official 15:a81a8d6c1dfe 628 }
mbed_official 15:a81a8d6c1dfe 629
mbed_official 15:a81a8d6c1dfe 630 struct i2c_master_config config_i2c_master;
mbed_official 15:a81a8d6c1dfe 631 /* SERCOM PAD0 - SDA */
mbed_official 15:a81a8d6c1dfe 632 config_i2c_master.pinmux_pad0 = (pI2C_S(obj)->pins[0] << 16) | (mux_func[0] & 0xFFFF);
mbed_official 15:a81a8d6c1dfe 633 /* SERCOM PAD1 - SCL */
mbed_official 15:a81a8d6c1dfe 634 config_i2c_master.pinmux_pad1 = (pI2C_S(obj)->pins[1] << 16) | (mux_func[1] & 0xFFFF);
mbed_official 15:a81a8d6c1dfe 635 /* Baud rate */
mbed_official 15:a81a8d6c1dfe 636 config_i2c_master.baud_rate = pI2C_S(obj)->baud_rate / 1000;
mbed_official 15:a81a8d6c1dfe 637
mbed_official 15:a81a8d6c1dfe 638 while(i2c_master_init(&pI2C_S(obj)->master, pI2C_S(obj)->master.hw, &config_i2c_master) != STATUS_OK);
mbed_official 15:a81a8d6c1dfe 639 pI2C_S(obj)->mode = I2C_MODE_MASTER;
mbed_official 15:a81a8d6c1dfe 640
mbed_official 15:a81a8d6c1dfe 641 i2c_master_enable(&pI2C_S(obj)->master);
mbed_official 15:a81a8d6c1dfe 642 }
mbed_official 15:a81a8d6c1dfe 643 }
mbed_official 15:a81a8d6c1dfe 644
mbed_official 15:a81a8d6c1dfe 645 /** Check to see if the I2C slave has been addressed.
mbed_official 15:a81a8d6c1dfe 646 * @param obj The I2C object
mbed_official 15:a81a8d6c1dfe 647 * @return The status - 1 - read addresses, 2 - write to all slaves,
mbed_official 15:a81a8d6c1dfe 648 * 3 write addressed, 0 - the slave has not been addressed
mbed_official 15:a81a8d6c1dfe 649 */
mbed_official 15:a81a8d6c1dfe 650 int i2c_slave_receive(i2c_t *obj)
mbed_official 15:a81a8d6c1dfe 651 {
mbed_official 15:a81a8d6c1dfe 652 /* Sanity check arguments */
mbed_official 15:a81a8d6c1dfe 653 MBED_ASSERT(obj);
mbed_official 15:a81a8d6c1dfe 654 MBED_ASSERT(pI2C_S(obj)->slave.hw);
mbed_official 15:a81a8d6c1dfe 655
mbed_official 15:a81a8d6c1dfe 656 SercomI2cs *const i2c_module = &(pI2C_S(obj)->slave.hw->I2CS);
mbed_official 15:a81a8d6c1dfe 657
mbed_official 15:a81a8d6c1dfe 658 if (i2c_module->INTFLAG.reg & SERCOM_I2CS_INTFLAG_AMATCH) {
mbed_official 15:a81a8d6c1dfe 659 if (i2c_module->STATUS.reg & SERCOM_I2CS_STATUS_DIR) {
mbed_official 15:a81a8d6c1dfe 660 /* Slave is read addressed */
mbed_official 15:a81a8d6c1dfe 661 return 1;
mbed_official 15:a81a8d6c1dfe 662 } else {
mbed_official 15:a81a8d6c1dfe 663 if (!(i2c_module->DATA.reg & 0xFF)) {
mbed_official 15:a81a8d6c1dfe 664 /* General call address detected */
mbed_official 15:a81a8d6c1dfe 665 return 2;
mbed_official 15:a81a8d6c1dfe 666 } else {
mbed_official 15:a81a8d6c1dfe 667 /* Slave is write addressed */
mbed_official 15:a81a8d6c1dfe 668 return 3;
mbed_official 15:a81a8d6c1dfe 669 }
mbed_official 15:a81a8d6c1dfe 670 }
mbed_official 15:a81a8d6c1dfe 671 }
mbed_official 15:a81a8d6c1dfe 672
mbed_official 15:a81a8d6c1dfe 673 return 0;
mbed_official 15:a81a8d6c1dfe 674 }
mbed_official 15:a81a8d6c1dfe 675
mbed_official 15:a81a8d6c1dfe 676 /** Blocking reading data.
mbed_official 15:a81a8d6c1dfe 677 * @param obj The i2c slave object
mbed_official 15:a81a8d6c1dfe 678 * @param data The buffer for receiving
mbed_official 15:a81a8d6c1dfe 679 * @param length Number of bytes to read
mbed_official 15:a81a8d6c1dfe 680 * @return Number of read bytes
mbed_official 15:a81a8d6c1dfe 681 */
mbed_official 15:a81a8d6c1dfe 682 int i2c_slave_read(i2c_t *obj, char *data, int length)
mbed_official 15:a81a8d6c1dfe 683 {
mbed_official 15:a81a8d6c1dfe 684 /* Sanity check arguments */
mbed_official 15:a81a8d6c1dfe 685 MBED_ASSERT(obj);
mbed_official 15:a81a8d6c1dfe 686 MBED_ASSERT(pI2C_S(obj)->slave.hw);
mbed_official 15:a81a8d6c1dfe 687
mbed_official 15:a81a8d6c1dfe 688 if (!data || !length) return 0;
mbed_official 15:a81a8d6c1dfe 689
mbed_official 15:a81a8d6c1dfe 690 enum status_code tmp_status;
mbed_official 15:a81a8d6c1dfe 691
mbed_official 15:a81a8d6c1dfe 692 struct i2c_slave_packet packet;
mbed_official 15:a81a8d6c1dfe 693 packet.data_length = length;
mbed_official 15:a81a8d6c1dfe 694 packet.data = (uint8_t*)data;
mbed_official 15:a81a8d6c1dfe 695
mbed_official 15:a81a8d6c1dfe 696 tmp_status = i2c_slave_read_packet_wait(&pI2C_S(obj)->slave, &packet);
mbed_official 15:a81a8d6c1dfe 697
mbed_official 15:a81a8d6c1dfe 698 if (tmp_status == STATUS_OK) {
mbed_official 15:a81a8d6c1dfe 699 return length;
mbed_official 15:a81a8d6c1dfe 700 } else {
mbed_official 15:a81a8d6c1dfe 701 /* Currently, no way to track no of bytes transmitted, so return 0 */
mbed_official 15:a81a8d6c1dfe 702 return 0;
mbed_official 15:a81a8d6c1dfe 703 }
mbed_official 15:a81a8d6c1dfe 704
mbed_official 15:a81a8d6c1dfe 705 }
mbed_official 15:a81a8d6c1dfe 706
mbed_official 15:a81a8d6c1dfe 707 /** Blocking writing data.
mbed_official 15:a81a8d6c1dfe 708 * @param obj The i2c slave object
mbed_official 15:a81a8d6c1dfe 709 * @param data The buffer for transmitting
mbed_official 15:a81a8d6c1dfe 710 * @param length Number of bytes to write
mbed_official 15:a81a8d6c1dfe 711 * @return Number of bytes written
mbed_official 15:a81a8d6c1dfe 712 */
mbed_official 15:a81a8d6c1dfe 713 int i2c_slave_write(i2c_t *obj, const char *data, int length)
mbed_official 15:a81a8d6c1dfe 714 {
mbed_official 15:a81a8d6c1dfe 715 /* Sanity check arguments */
mbed_official 15:a81a8d6c1dfe 716 MBED_ASSERT(obj);
mbed_official 15:a81a8d6c1dfe 717 MBED_ASSERT(pI2C_S(obj)->slave.hw);
mbed_official 15:a81a8d6c1dfe 718
mbed_official 15:a81a8d6c1dfe 719 if (!data || !length) return 0;
mbed_official 15:a81a8d6c1dfe 720
mbed_official 15:a81a8d6c1dfe 721 enum status_code tmp_status;
mbed_official 15:a81a8d6c1dfe 722
mbed_official 15:a81a8d6c1dfe 723 struct i2c_slave_packet packet;
mbed_official 15:a81a8d6c1dfe 724 packet.data_length = length;
mbed_official 64:41a834223ea3 725 packet.data = (uint8_t *)data;
mbed_official 15:a81a8d6c1dfe 726
mbed_official 15:a81a8d6c1dfe 727 tmp_status = i2c_slave_write_packet_wait(&pI2C_S(obj)->slave, &packet);
mbed_official 15:a81a8d6c1dfe 728
mbed_official 15:a81a8d6c1dfe 729 if (tmp_status == STATUS_OK) {
mbed_official 15:a81a8d6c1dfe 730 return length;
mbed_official 15:a81a8d6c1dfe 731 } else {
mbed_official 15:a81a8d6c1dfe 732 /* Currently, no way to track no of bytes transmitted, so return 0 */
mbed_official 15:a81a8d6c1dfe 733 return 0;
mbed_official 15:a81a8d6c1dfe 734 }
mbed_official 64:41a834223ea3 735
mbed_official 15:a81a8d6c1dfe 736 }
mbed_official 15:a81a8d6c1dfe 737
mbed_official 15:a81a8d6c1dfe 738 /** Configure I2C slave address.
mbed_official 15:a81a8d6c1dfe 739 * @param obj The I2C object
mbed_official 15:a81a8d6c1dfe 740 * @param idx Currently not used
mbed_official 15:a81a8d6c1dfe 741 * @param address The address to be set
mbed_official 15:a81a8d6c1dfe 742 * @param mask Currently not used
mbed_official 15:a81a8d6c1dfe 743 */
mbed_official 15:a81a8d6c1dfe 744 void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask)
mbed_official 15:a81a8d6c1dfe 745 {
mbed_official 15:a81a8d6c1dfe 746 /* Sanity check arguments */
mbed_official 15:a81a8d6c1dfe 747 MBED_ASSERT(obj);
mbed_official 15:a81a8d6c1dfe 748 MBED_ASSERT(pI2C_S(obj)->slave.hw);
mbed_official 15:a81a8d6c1dfe 749
mbed_official 15:a81a8d6c1dfe 750 /* Disable I2C Module */
mbed_official 15:a81a8d6c1dfe 751 i2c_slave_disable(&pI2C_S(obj)->slave);
mbed_official 15:a81a8d6c1dfe 752
mbed_official 15:a81a8d6c1dfe 753 SercomI2cs *const i2c_hw = &(pI2C_S(obj)->slave.hw->I2CS);
mbed_official 15:a81a8d6c1dfe 754
mbed_official 15:a81a8d6c1dfe 755 address = (address & 0xFF) >> 1;
mbed_official 15:a81a8d6c1dfe 756 if (!mask) {
mbed_official 15:a81a8d6c1dfe 757 mask = (0xFE >> 1);
mbed_official 15:a81a8d6c1dfe 758 }
mbed_official 15:a81a8d6c1dfe 759 /* Set the address and address mask */
mbed_official 15:a81a8d6c1dfe 760 i2c_hw->ADDR.reg = (address << SERCOM_I2CS_ADDR_ADDR_Pos) |
mbed_official 15:a81a8d6c1dfe 761 (mask << SERCOM_I2CS_ADDR_ADDRMASK_Pos) |
mbed_official 15:a81a8d6c1dfe 762 (0 << SERCOM_I2CS_ADDR_TENBITEN_Pos) |
mbed_official 15:a81a8d6c1dfe 763 (1 << SERCOM_I2CS_ADDR_GENCEN_Pos);
mbed_official 15:a81a8d6c1dfe 764
mbed_official 15:a81a8d6c1dfe 765 /* Enable I2C Module */
mbed_official 15:a81a8d6c1dfe 766 i2c_slave_enable(&pI2C_S(obj)->slave);
mbed_official 15:a81a8d6c1dfe 767 }
mbed_official 15:a81a8d6c1dfe 768
mbed_official 15:a81a8d6c1dfe 769 #endif /* DEVICE_I2CSLAVE */
mbed_official 15:a81a8d6c1dfe 770
mbed_official 15:a81a8d6c1dfe 771 /**@}*/
mbed_official 15:a81a8d6c1dfe 772
mbed_official 15:a81a8d6c1dfe 773 #if DEVICE_I2C_ASYNCH
mbed_official 15:a81a8d6c1dfe 774
mbed_official 15:a81a8d6c1dfe 775 /**
mbed_official 15:a81a8d6c1dfe 776 * \defgroup AsynchI2C Asynchronous I2C Hardware Abstraction Layer
mbed_official 15:a81a8d6c1dfe 777 * @{
mbed_official 15:a81a8d6c1dfe 778 */
mbed_official 15:a81a8d6c1dfe 779
mbed_official 15:a81a8d6c1dfe 780 /**
mbed_official 15:a81a8d6c1dfe 781 * \internal
mbed_official 15:a81a8d6c1dfe 782 * Callback for transfer finish.
mbed_official 15:a81a8d6c1dfe 783 *
mbed_official 15:a81a8d6c1dfe 784 * \param[in,out] module Pointer to SPI software instance struct
mbed_official 15:a81a8d6c1dfe 785 */
mbed_official 15:a81a8d6c1dfe 786 void i2c_transfer_complete_callback(struct i2c_master_module *const module)
mbed_official 15:a81a8d6c1dfe 787 {
mbed_official 15:a81a8d6c1dfe 788 uint32_t sercom_index = _sercom_get_sercom_inst_index(module->hw);
mbed_official 15:a81a8d6c1dfe 789
mbed_official 15:a81a8d6c1dfe 790 if (sercom_index >= SERCOM_INST_NUM) {
mbed_official 15:a81a8d6c1dfe 791 /* TODO: Abort operation */
mbed_official 15:a81a8d6c1dfe 792 return;
mbed_official 15:a81a8d6c1dfe 793 }
mbed_official 15:a81a8d6c1dfe 794
mbed_official 15:a81a8d6c1dfe 795 i2c_t *obj = (i2c_t*)i2c_instances[sercom_index];
mbed_official 15:a81a8d6c1dfe 796
mbed_official 15:a81a8d6c1dfe 797 i2c_master_disable_callback(&pI2C_S(obj)->master, I2C_MASTER_CALLBACK_WRITE_COMPLETE);
mbed_official 15:a81a8d6c1dfe 798 i2c_master_disable_callback(&pI2C_S(obj)->master, I2C_MASTER_CALLBACK_READ_COMPLETE);
mbed_official 15:a81a8d6c1dfe 799 i2c_master_disable_callback(&pI2C_S(obj)->master, I2C_MASTER_CALLBACK_ERROR);
mbed_official 15:a81a8d6c1dfe 800
mbed_official 15:a81a8d6c1dfe 801 /* Call the handler function */
mbed_official 15:a81a8d6c1dfe 802 if (pI2C_S(obj)->handler) {
mbed_official 15:a81a8d6c1dfe 803 ((I2CHandler)pI2C_S(obj)->handler)();
mbed_official 15:a81a8d6c1dfe 804 }
mbed_official 15:a81a8d6c1dfe 805 }
mbed_official 15:a81a8d6c1dfe 806
mbed_official 15:a81a8d6c1dfe 807 /**
mbed_official 15:a81a8d6c1dfe 808 * \internal
mbed_official 15:a81a8d6c1dfe 809 * Callback for write complete. Initiate read from here.
mbed_official 15:a81a8d6c1dfe 810 *
mbed_official 15:a81a8d6c1dfe 811 * \param[in,out] module Pointer to SPI software instance struct
mbed_official 15:a81a8d6c1dfe 812 */
mbed_official 15:a81a8d6c1dfe 813 void i2c_write_complete_callback(struct i2c_master_module *const module)
mbed_official 15:a81a8d6c1dfe 814 {
mbed_official 15:a81a8d6c1dfe 815 uint32_t sercom_index = _sercom_get_sercom_inst_index(module->hw);
mbed_official 15:a81a8d6c1dfe 816
mbed_official 15:a81a8d6c1dfe 817 if (sercom_index >= SERCOM_INST_NUM) {
mbed_official 15:a81a8d6c1dfe 818 /* TODO: Abort operation */
mbed_official 15:a81a8d6c1dfe 819 return;
mbed_official 15:a81a8d6c1dfe 820 }
mbed_official 15:a81a8d6c1dfe 821
mbed_official 15:a81a8d6c1dfe 822 i2c_t *obj = (i2c_t*)i2c_instances[sercom_index];
mbed_official 15:a81a8d6c1dfe 823
mbed_official 15:a81a8d6c1dfe 824 if (!(pI2C_S(obj)->rd_packet.data) || (pI2C_S(obj)->rd_packet.data_length == 0)) {
mbed_official 15:a81a8d6c1dfe 825 /* Call the handler function */
mbed_official 15:a81a8d6c1dfe 826 i2c_transfer_complete_callback(module);
mbed_official 15:a81a8d6c1dfe 827 } else {
mbed_official 15:a81a8d6c1dfe 828 i2c_master_disable_callback(&pI2C_S(obj)->master, I2C_MASTER_CALLBACK_WRITE_COMPLETE);
mbed_official 15:a81a8d6c1dfe 829
mbed_official 15:a81a8d6c1dfe 830 /* Register read complete callback */
mbed_official 15:a81a8d6c1dfe 831 i2c_master_register_callback(&pI2C_S(obj)->master, i2c_transfer_complete_callback, I2C_MASTER_CALLBACK_READ_COMPLETE);
mbed_official 15:a81a8d6c1dfe 832 i2c_master_enable_callback(&pI2C_S(obj)->master, I2C_MASTER_CALLBACK_READ_COMPLETE);
mbed_official 15:a81a8d6c1dfe 833
mbed_official 15:a81a8d6c1dfe 834 /* Initiate read operation */
mbed_official 15:a81a8d6c1dfe 835 if (pI2C_S(obj)->master.send_stop) {
mbed_official 15:a81a8d6c1dfe 836 i2c_master_read_packet_job(&pI2C_S(obj)->master,&pI2C_S(obj)->rd_packet);
mbed_official 15:a81a8d6c1dfe 837 } else {
mbed_official 15:a81a8d6c1dfe 838 i2c_master_read_packet_job_no_stop(&pI2C_S(obj)->master, &pI2C_S(obj)->rd_packet);
mbed_official 15:a81a8d6c1dfe 839 }
mbed_official 15:a81a8d6c1dfe 840 }
mbed_official 15:a81a8d6c1dfe 841 }
mbed_official 15:a81a8d6c1dfe 842
mbed_official 15:a81a8d6c1dfe 843 /** Start i2c asynchronous transfer.
mbed_official 15:a81a8d6c1dfe 844 * @param obj The I2C object
mbed_official 15:a81a8d6c1dfe 845 * @param tx The buffer to send
mbed_official 15:a81a8d6c1dfe 846 * @param tx_length The number of words to transmit
mbed_official 15:a81a8d6c1dfe 847 * @param rx The buffer to receive
mbed_official 15:a81a8d6c1dfe 848 * @param rx_length The number of words to receive
mbed_official 15:a81a8d6c1dfe 849 * @param address The address to be set - 7bit or 9 bit
mbed_official 15:a81a8d6c1dfe 850 * @param stop If true, stop will be generated after the transfer is done
mbed_official 15:a81a8d6c1dfe 851 * @param handler The I2C IRQ handler to be set
mbed_official 15:a81a8d6c1dfe 852 * @param hint DMA hint usage
mbed_official 15:a81a8d6c1dfe 853 */
mbed_official 15:a81a8d6c1dfe 854 void i2c_transfer_asynch(i2c_t *obj, const void *tx, size_t tx_length, void *rx, size_t rx_length, uint32_t address, uint32_t stop, uint32_t handler, uint32_t event, DMAUsage hint)
mbed_official 15:a81a8d6c1dfe 855 {
mbed_official 15:a81a8d6c1dfe 856 /* Sanity check arguments */
mbed_official 15:a81a8d6c1dfe 857 MBED_ASSERT(obj);
mbed_official 15:a81a8d6c1dfe 858 MBED_ASSERT(pI2C_S(obj)->master.hw);
mbed_official 15:a81a8d6c1dfe 859
mbed_official 15:a81a8d6c1dfe 860 /* Return if in Slave mode */
mbed_official 15:a81a8d6c1dfe 861 if (pI2C_S(obj)->mode != I2C_MODE_MASTER) return;
mbed_official 15:a81a8d6c1dfe 862
mbed_official 15:a81a8d6c1dfe 863 uint32_t sercom_index = _sercom_get_sercom_inst_index(pI2C_S(obj)->master.hw);
mbed_official 15:a81a8d6c1dfe 864
mbed_official 15:a81a8d6c1dfe 865 /* Init i2c packet. */
mbed_official 15:a81a8d6c1dfe 866 pI2C_S(obj)->wr_packet.address = address >> 1;
mbed_official 15:a81a8d6c1dfe 867 pI2C_S(obj)->wr_packet.data_length = tx_length;
mbed_official 64:41a834223ea3 868 pI2C_S(obj)->wr_packet.data = (uint8_t *)tx;
mbed_official 15:a81a8d6c1dfe 869
mbed_official 15:a81a8d6c1dfe 870 pI2C_S(obj)->rd_packet.address = address >> 1;
mbed_official 15:a81a8d6c1dfe 871 pI2C_S(obj)->rd_packet.data_length = rx_length;
mbed_official 15:a81a8d6c1dfe 872 pI2C_S(obj)->rd_packet.data = rx;
mbed_official 15:a81a8d6c1dfe 873
mbed_official 15:a81a8d6c1dfe 874 /* Save event mask and handler function pointer */
mbed_official 15:a81a8d6c1dfe 875 pI2C_S(obj)->events = event;
mbed_official 15:a81a8d6c1dfe 876 pI2C_S(obj)->handler = handler;
mbed_official 15:a81a8d6c1dfe 877
mbed_official 15:a81a8d6c1dfe 878 /* TODO: Current implementation is interrupt based only */
mbed_official 15:a81a8d6c1dfe 879
mbed_official 15:a81a8d6c1dfe 880 /* Set interrupt handler to default handler of ASF */
mbed_official 15:a81a8d6c1dfe 881 /* Enable interrupt */
mbed_official 64:41a834223ea3 882 NVIC_SetVector((IRQn_Type)((uint32_t)SERCOM0_IRQn + sercom_index), sercom_irq_handlers[sercom_index]);
mbed_official 64:41a834223ea3 883 NVIC_EnableIRQ((IRQn_Type)((uint32_t)SERCOM0_IRQn + sercom_index));
mbed_official 15:a81a8d6c1dfe 884
mbed_official 15:a81a8d6c1dfe 885 /* Register callbacks */
mbed_official 15:a81a8d6c1dfe 886 i2c_master_register_callback(&pI2C_S(obj)->master, i2c_transfer_complete_callback, I2C_MASTER_CALLBACK_ERROR);
mbed_official 15:a81a8d6c1dfe 887 i2c_master_enable_callback(&pI2C_S(obj)->master, I2C_MASTER_CALLBACK_ERROR);
mbed_official 15:a81a8d6c1dfe 888 if (tx && tx_length) {
mbed_official 15:a81a8d6c1dfe 889 i2c_master_register_callback(&pI2C_S(obj)->master, i2c_write_complete_callback, I2C_MASTER_CALLBACK_WRITE_COMPLETE);
mbed_official 15:a81a8d6c1dfe 890 i2c_master_enable_callback(&pI2C_S(obj)->master, I2C_MASTER_CALLBACK_WRITE_COMPLETE);
mbed_official 15:a81a8d6c1dfe 891
mbed_official 15:a81a8d6c1dfe 892 /* Start I2C write */
mbed_official 15:a81a8d6c1dfe 893 if (stop) {
mbed_official 15:a81a8d6c1dfe 894 i2c_master_write_packet_job(&pI2C_S(obj)->master, &pI2C_S(obj)->wr_packet);
mbed_official 15:a81a8d6c1dfe 895 } else {
mbed_official 15:a81a8d6c1dfe 896 i2c_master_write_packet_job_no_stop(&pI2C_S(obj)->master, &pI2C_S(obj)->wr_packet);
mbed_official 15:a81a8d6c1dfe 897 }
mbed_official 15:a81a8d6c1dfe 898 } else if (rx && rx_length) {
mbed_official 15:a81a8d6c1dfe 899 i2c_master_register_callback(&pI2C_S(obj)->master, i2c_transfer_complete_callback, I2C_MASTER_CALLBACK_READ_COMPLETE);
mbed_official 15:a81a8d6c1dfe 900 i2c_master_enable_callback(&pI2C_S(obj)->master, I2C_MASTER_CALLBACK_READ_COMPLETE);
mbed_official 15:a81a8d6c1dfe 901
mbed_official 15:a81a8d6c1dfe 902 /* Start I2C read */
mbed_official 15:a81a8d6c1dfe 903 if (stop) {
mbed_official 15:a81a8d6c1dfe 904 i2c_master_read_packet_job(&pI2C_S(obj)->master,&pI2C_S(obj)->rd_packet);
mbed_official 15:a81a8d6c1dfe 905 } else {
mbed_official 15:a81a8d6c1dfe 906 i2c_master_read_packet_job_no_stop(&pI2C_S(obj)->master, &pI2C_S(obj)->rd_packet);
mbed_official 15:a81a8d6c1dfe 907 }
mbed_official 15:a81a8d6c1dfe 908 } else {
mbed_official 15:a81a8d6c1dfe 909 /* Nothing to transfer, invoke callback */
mbed_official 15:a81a8d6c1dfe 910 i2c_transfer_complete_callback(&pI2C_S(obj)->master);
mbed_official 15:a81a8d6c1dfe 911 }
mbed_official 15:a81a8d6c1dfe 912 }
mbed_official 15:a81a8d6c1dfe 913
mbed_official 15:a81a8d6c1dfe 914 /** The asynchronous IRQ handler
mbed_official 15:a81a8d6c1dfe 915 * @param obj The I2C object which holds the transfer information
mbed_official 15:a81a8d6c1dfe 916 * @return event flags if a transfer termination condition was met or 0 otherwise.
mbed_official 15:a81a8d6c1dfe 917 */
mbed_official 15:a81a8d6c1dfe 918 uint32_t i2c_irq_handler_asynch(i2c_t *obj)
mbed_official 15:a81a8d6c1dfe 919 {
mbed_official 15:a81a8d6c1dfe 920 /* Sanity check arguments */
mbed_official 15:a81a8d6c1dfe 921 MBED_ASSERT(obj);
mbed_official 15:a81a8d6c1dfe 922 MBED_ASSERT(pI2C_S(obj)->master.hw);
mbed_official 15:a81a8d6c1dfe 923
mbed_official 15:a81a8d6c1dfe 924 uint32_t event_mask = pI2C_S(obj)->events;
mbed_official 15:a81a8d6c1dfe 925
mbed_official 15:a81a8d6c1dfe 926 /* TODO: Current implementation is interrupt based only */
mbed_official 15:a81a8d6c1dfe 927
mbed_official 15:a81a8d6c1dfe 928 switch (pI2C_S(obj)->master.status) {
mbed_official 15:a81a8d6c1dfe 929 case STATUS_OK:
mbed_official 15:a81a8d6c1dfe 930 /* Transfer is complete */
mbed_official 15:a81a8d6c1dfe 931 return (I2C_EVENT_TRANSFER_COMPLETE & event_mask);
mbed_official 64:41a834223ea3 932
mbed_official 15:a81a8d6c1dfe 933 case STATUS_ERR_BAD_ADDRESS:
mbed_official 15:a81a8d6c1dfe 934 /* Received a NACK */
mbed_official 15:a81a8d6c1dfe 935 return (I2C_EVENT_ERROR_NO_SLAVE & event_mask);
mbed_official 64:41a834223ea3 936
mbed_official 15:a81a8d6c1dfe 937 case STATUS_ERR_PACKET_COLLISION:
mbed_official 15:a81a8d6c1dfe 938 /* An error occurred in between transfer */
mbed_official 15:a81a8d6c1dfe 939 return (I2C_EVENT_ERROR & event_mask);
mbed_official 64:41a834223ea3 940
mbed_official 15:a81a8d6c1dfe 941 default:
mbed_official 15:a81a8d6c1dfe 942 return 0;
mbed_official 15:a81a8d6c1dfe 943 }
mbed_official 15:a81a8d6c1dfe 944
mbed_official 64:41a834223ea3 945 //return 0;
mbed_official 15:a81a8d6c1dfe 946 }
mbed_official 15:a81a8d6c1dfe 947
mbed_official 15:a81a8d6c1dfe 948 /** Attempts to determine if I2C peripheral is already in use.
mbed_official 15:a81a8d6c1dfe 949 * @param obj The I2C object
mbed_official 15:a81a8d6c1dfe 950 * @return non-zero if the I2C module is active or zero if it is not
mbed_official 15:a81a8d6c1dfe 951 */
mbed_official 15:a81a8d6c1dfe 952 uint8_t i2c_active(i2c_t *obj)
mbed_official 15:a81a8d6c1dfe 953 {
mbed_official 15:a81a8d6c1dfe 954 /* Sanity check arguments */
mbed_official 15:a81a8d6c1dfe 955 MBED_ASSERT(obj);
mbed_official 15:a81a8d6c1dfe 956 MBED_ASSERT(pI2C_S(obj)->master.hw);
mbed_official 15:a81a8d6c1dfe 957
mbed_official 15:a81a8d6c1dfe 958 return (pI2C_S(obj)->master.status == STATUS_BUSY);
mbed_official 15:a81a8d6c1dfe 959 }
mbed_official 15:a81a8d6c1dfe 960
mbed_official 15:a81a8d6c1dfe 961 /** Abort ongoing asynchronous transaction.
mbed_official 15:a81a8d6c1dfe 962 * @param obj The I2C object
mbed_official 15:a81a8d6c1dfe 963 */
mbed_official 15:a81a8d6c1dfe 964 void i2c_abort_asynch(i2c_t *obj)
mbed_official 15:a81a8d6c1dfe 965 {
mbed_official 15:a81a8d6c1dfe 966 /* Sanity check arguments */
mbed_official 15:a81a8d6c1dfe 967 MBED_ASSERT(obj);
mbed_official 15:a81a8d6c1dfe 968 MBED_ASSERT(pI2C_S(obj)->master.hw);
mbed_official 15:a81a8d6c1dfe 969
mbed_official 15:a81a8d6c1dfe 970 /* Pointer to the hardware module instance */
mbed_official 15:a81a8d6c1dfe 971 SercomI2cm *const i2c_module = &(pI2C_S(obj)->master.hw->I2CM);
mbed_official 15:a81a8d6c1dfe 972
mbed_official 15:a81a8d6c1dfe 973 /* Abort ongoing job */
mbed_official 15:a81a8d6c1dfe 974
mbed_official 15:a81a8d6c1dfe 975 /* Stop packet operation */
mbed_official 15:a81a8d6c1dfe 976 i2c_module->INTENCLR.reg = SERCOM_I2CM_INTENCLR_MB | SERCOM_I2CM_INTENCLR_SB;
mbed_official 15:a81a8d6c1dfe 977
mbed_official 15:a81a8d6c1dfe 978 pI2C_S(obj)->master.buffer_length = 0;
mbed_official 15:a81a8d6c1dfe 979 pI2C_S(obj)->master.buffer_remaining = 0;
mbed_official 15:a81a8d6c1dfe 980
mbed_official 15:a81a8d6c1dfe 981 /* Send nack and stop command unless arbitration is lost */
mbed_official 15:a81a8d6c1dfe 982 if ((pI2C_S(obj)->master.status != STATUS_ERR_PACKET_COLLISION) && pI2C_S(obj)->master.send_stop) {
mbed_official 15:a81a8d6c1dfe 983 _i2c_master_wait_for_sync(&pI2C_S(obj)->master);
mbed_official 15:a81a8d6c1dfe 984 i2c_module->CTRLB.reg |= SERCOM_I2CM_CTRLB_ACKACT | SERCOM_I2CM_CTRLB_CMD(3);
mbed_official 15:a81a8d6c1dfe 985 }
mbed_official 15:a81a8d6c1dfe 986
mbed_official 15:a81a8d6c1dfe 987 /* Disable any registered callback */
mbed_official 15:a81a8d6c1dfe 988 i2c_master_disable_callback(&pI2C_S(obj)->master, I2C_MASTER_CALLBACK_WRITE_COMPLETE);
mbed_official 15:a81a8d6c1dfe 989 i2c_master_disable_callback(&pI2C_S(obj)->master, I2C_MASTER_CALLBACK_READ_COMPLETE);
mbed_official 15:a81a8d6c1dfe 990 i2c_master_disable_callback(&pI2C_S(obj)->master, I2C_MASTER_CALLBACK_ERROR);
mbed_official 15:a81a8d6c1dfe 991
mbed_official 15:a81a8d6c1dfe 992 pI2C_S(obj)->master.status = STATUS_ABORTED;
mbed_official 15:a81a8d6c1dfe 993 }
mbed_official 15:a81a8d6c1dfe 994
mbed_official 15:a81a8d6c1dfe 995 #endif