added prescaler for 16 bit pwm in LPC1347 target

Fork of mbed-dev by mbed official

Committer:
mbed_official
Date:
Wed Nov 04 16:30:11 2015 +0000
Revision:
15:a81a8d6c1dfe
Child:
64:41a834223ea3
Synchronized with git revision 46af745ef4405614c3fa49abbd9a706a362ea514

Full URL: https://github.com/mbedmicro/mbed/commit/46af745ef4405614c3fa49abbd9a706a362ea514/

Renamed TARGET_SAM_CortexM0+ to TARGET_SAM_CortexM0P for compatiblity with online compiler

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