added prescaler for 16 bit pwm in LPC1347 target

Fork of mbed-dev by mbed official

Committer:
JojoS
Date:
Sat Sep 10 15:32:04 2016 +0000
Revision:
147:ba84b7dc41a7
Parent:
64:41a834223ea3
added prescaler for 16 bit timers (solution as in LPC11xx), default prescaler 31 for max 28 ms period time

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;
mbed_official 15:a81a8d6c1dfe 176 enum status_code tmp_status_code;
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