mbed library sources

Fork of mbed-src by mbed official

Committer:
mbed_official
Date:
Fri Jul 17 09:15:10 2015 +0100
Revision:
592:a274ee790e56
Parent:
579:53297373a894
Synchronized with git revision e7144f83a8d75df80c4877936b6ffe552b0be9e6

Full URL: https://github.com/mbedmicro/mbed/commit/e7144f83a8d75df80c4877936b6ffe552b0be9e6/

More API implementation for SAMR21

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 579:53297373a894 1 #include "i2c_master.h"
mbed_official 579:53297373a894 2
mbed_official 579:53297373a894 3 #if I2C_MASTER_CALLBACK_MODE == true
mbed_official 579:53297373a894 4 # include "i2c_master_interrupt.h"
mbed_official 579:53297373a894 5 #endif
mbed_official 579:53297373a894 6
mbed_official 579:53297373a894 7 /* Forward declaration */
mbed_official 579:53297373a894 8 enum status_code _i2c_master_wait_for_bus(
mbed_official 579:53297373a894 9 struct i2c_master_module *const module);
mbed_official 579:53297373a894 10
mbed_official 579:53297373a894 11 enum status_code _i2c_master_address_response(
mbed_official 579:53297373a894 12 struct i2c_master_module *const module);
mbed_official 579:53297373a894 13
mbed_official 579:53297373a894 14 enum status_code _i2c_master_send_hs_master_code(
mbed_official 579:53297373a894 15 struct i2c_master_module *const module,
mbed_official 579:53297373a894 16 uint8_t hs_master_code);
mbed_official 579:53297373a894 17
mbed_official 579:53297373a894 18 #if !defined(__DOXYGEN__)
mbed_official 579:53297373a894 19
mbed_official 579:53297373a894 20 /**
mbed_official 579:53297373a894 21 * \internal Sets configurations to module
mbed_official 579:53297373a894 22 *
mbed_official 579:53297373a894 23 * \param[out] module Pointer to software module structure
mbed_official 579:53297373a894 24 * \param[in] config Configuration structure with configurations to set
mbed_official 579:53297373a894 25 *
mbed_official 579:53297373a894 26 * \return Status of setting configuration.
mbed_official 579:53297373a894 27 * \retval STATUS_OK If module was configured correctly
mbed_official 579:53297373a894 28 * \retval STATUS_ERR_ALREADY_INITIALIZED If setting other GCLK generator than
mbed_official 579:53297373a894 29 * previously set
mbed_official 579:53297373a894 30 * \retval STATUS_ERR_BAUDRATE_UNAVAILABLE If given baudrate is not compatible
mbed_official 579:53297373a894 31 * with set GCLK frequency
mbed_official 579:53297373a894 32 */
mbed_official 579:53297373a894 33 static enum status_code _i2c_master_set_config(
mbed_official 579:53297373a894 34 struct i2c_master_module *const module,
mbed_official 579:53297373a894 35 const struct i2c_master_config *const config)
mbed_official 579:53297373a894 36 {
mbed_official 579:53297373a894 37 /* Sanity check arguments. */
mbed_official 579:53297373a894 38 Assert(module);
mbed_official 579:53297373a894 39 Assert(module->hw);
mbed_official 579:53297373a894 40 Assert(config);
mbed_official 579:53297373a894 41
mbed_official 579:53297373a894 42 /* Temporary variables. */
mbed_official 579:53297373a894 43 uint32_t tmp_ctrla;
mbed_official 579:53297373a894 44 int32_t tmp_baud;
mbed_official 579:53297373a894 45 int32_t tmp_baud_hs;
mbed_official 579:53297373a894 46 enum status_code tmp_status_code = STATUS_OK;
mbed_official 579:53297373a894 47
mbed_official 579:53297373a894 48 SercomI2cm *const i2c_module = &(module->hw->I2CM);
mbed_official 579:53297373a894 49 Sercom *const sercom_hw = module->hw;
mbed_official 579:53297373a894 50
mbed_official 579:53297373a894 51 uint8_t sercom_index = _sercom_get_sercom_inst_index(sercom_hw);
mbed_official 579:53297373a894 52
mbed_official 579:53297373a894 53 /* Pin configuration */
mbed_official 579:53297373a894 54 struct system_pinmux_config pin_conf;
mbed_official 579:53297373a894 55 system_pinmux_get_config_defaults(&pin_conf);
mbed_official 579:53297373a894 56
mbed_official 579:53297373a894 57 uint32_t pad0 = config->pinmux_pad0;
mbed_official 579:53297373a894 58 uint32_t pad1 = config->pinmux_pad1;
mbed_official 579:53297373a894 59
mbed_official 579:53297373a894 60 /* SERCOM PAD0 - SDA */
mbed_official 579:53297373a894 61 if (pad0 == PINMUX_DEFAULT) {
mbed_official 579:53297373a894 62 pad0 = _sercom_get_default_pad(sercom_hw, 0);
mbed_official 579:53297373a894 63 }
mbed_official 579:53297373a894 64 pin_conf.mux_position = pad0 & 0xFFFF;
mbed_official 579:53297373a894 65 pin_conf.direction = SYSTEM_PINMUX_PIN_DIR_OUTPUT_WITH_READBACK;
mbed_official 579:53297373a894 66 system_pinmux_pin_set_config(pad0 >> 16, &pin_conf);
mbed_official 579:53297373a894 67
mbed_official 579:53297373a894 68 /* SERCOM PAD1 - SCL */
mbed_official 579:53297373a894 69 if (pad1 == PINMUX_DEFAULT) {
mbed_official 579:53297373a894 70 pad1 = _sercom_get_default_pad(sercom_hw, 1);
mbed_official 579:53297373a894 71 }
mbed_official 579:53297373a894 72 pin_conf.mux_position = pad1 & 0xFFFF;
mbed_official 579:53297373a894 73 pin_conf.direction = SYSTEM_PINMUX_PIN_DIR_OUTPUT_WITH_READBACK;
mbed_official 579:53297373a894 74 system_pinmux_pin_set_config(pad1 >> 16, &pin_conf);
mbed_official 579:53297373a894 75
mbed_official 579:53297373a894 76 /* Save timeout on unknown bus state in software module. */
mbed_official 579:53297373a894 77 module->unknown_bus_state_timeout = config->unknown_bus_state_timeout;
mbed_official 579:53297373a894 78
mbed_official 579:53297373a894 79 /* Save timeout on buffer write. */
mbed_official 579:53297373a894 80 module->buffer_timeout = config->buffer_timeout;
mbed_official 579:53297373a894 81
mbed_official 579:53297373a894 82 /* Set whether module should run in standby. */
mbed_official 579:53297373a894 83 if (config->run_in_standby || system_is_debugger_present()) {
mbed_official 579:53297373a894 84 tmp_ctrla = SERCOM_I2CM_CTRLA_RUNSTDBY;
mbed_official 579:53297373a894 85 } else {
mbed_official 579:53297373a894 86 tmp_ctrla = 0;
mbed_official 579:53297373a894 87 }
mbed_official 579:53297373a894 88
mbed_official 579:53297373a894 89 /* Check and set start data hold timeout. */
mbed_official 579:53297373a894 90 if (config->start_hold_time != I2C_MASTER_START_HOLD_TIME_DISABLED) {
mbed_official 579:53297373a894 91 tmp_ctrla |= config->start_hold_time;
mbed_official 579:53297373a894 92 }
mbed_official 579:53297373a894 93
mbed_official 579:53297373a894 94 /* Check and set transfer speed */
mbed_official 579:53297373a894 95 tmp_ctrla |= config->transfer_speed;
mbed_official 579:53297373a894 96
mbed_official 579:53297373a894 97 /* Check and set SCL low timeout. */
mbed_official 579:53297373a894 98 if (config->scl_low_timeout) {
mbed_official 579:53297373a894 99 tmp_ctrla |= SERCOM_I2CM_CTRLA_LOWTOUTEN;
mbed_official 579:53297373a894 100 }
mbed_official 579:53297373a894 101
mbed_official 579:53297373a894 102 /* Check and set inactive bus timeout. */
mbed_official 579:53297373a894 103 if (config->inactive_timeout != I2C_MASTER_INACTIVE_TIMEOUT_DISABLED) {
mbed_official 579:53297373a894 104 tmp_ctrla |= config->inactive_timeout;
mbed_official 579:53297373a894 105 }
mbed_official 579:53297373a894 106
mbed_official 579:53297373a894 107 /* Check and set SCL clock stretch mode. */
mbed_official 579:53297373a894 108 if (config->scl_stretch_only_after_ack_bit) {
mbed_official 579:53297373a894 109 tmp_ctrla |= SERCOM_I2CM_CTRLA_SCLSM;
mbed_official 579:53297373a894 110 }
mbed_official 579:53297373a894 111
mbed_official 579:53297373a894 112 /* Check and set slave SCL low extend timeout. */
mbed_official 579:53297373a894 113 if (config->slave_scl_low_extend_timeout) {
mbed_official 579:53297373a894 114 tmp_ctrla |= SERCOM_I2CM_CTRLA_SEXTTOEN;
mbed_official 579:53297373a894 115 }
mbed_official 579:53297373a894 116
mbed_official 579:53297373a894 117 /* Check and set master SCL low extend timeout. */
mbed_official 579:53297373a894 118 if (config->master_scl_low_extend_timeout) {
mbed_official 579:53297373a894 119 tmp_ctrla |= SERCOM_I2CM_CTRLA_MEXTTOEN;
mbed_official 579:53297373a894 120 }
mbed_official 579:53297373a894 121
mbed_official 579:53297373a894 122 /* Write config to register CTRLA. */
mbed_official 579:53297373a894 123 i2c_module->CTRLA.reg |= tmp_ctrla;
mbed_official 579:53297373a894 124
mbed_official 579:53297373a894 125 /* Set configurations in CTRLB. */
mbed_official 579:53297373a894 126 i2c_module->CTRLB.reg = SERCOM_I2CM_CTRLB_SMEN;
mbed_official 579:53297373a894 127
mbed_official 579:53297373a894 128 /* Find and set baudrate. */
mbed_official 579:53297373a894 129 tmp_baud = (int32_t)(div_ceil(
mbed_official 579:53297373a894 130 system_gclk_chan_get_hz(SERCOM0_GCLK_ID_CORE + sercom_index),
mbed_official 579:53297373a894 131 (2000*(config->baud_rate))) - 5);
mbed_official 579:53297373a894 132
mbed_official 579:53297373a894 133 /* Check that baudrate is supported at current speed. */
mbed_official 579:53297373a894 134 if (tmp_baud > 255 || tmp_baud < 0) {
mbed_official 579:53297373a894 135 /* Baud rate not supported. */
mbed_official 579:53297373a894 136 tmp_status_code = STATUS_ERR_BAUDRATE_UNAVAILABLE;
mbed_official 579:53297373a894 137 } else {
mbed_official 579:53297373a894 138 /* Find baudrate for high speed */
mbed_official 579:53297373a894 139 tmp_baud_hs = (int32_t)(div_ceil(
mbed_official 579:53297373a894 140 system_gclk_chan_get_hz(SERCOM0_GCLK_ID_CORE + sercom_index),
mbed_official 579:53297373a894 141 (2000*(config->baud_rate_high_speed))) - 1);
mbed_official 579:53297373a894 142
mbed_official 579:53297373a894 143 /* Check that baudrate is supported at current speed. */
mbed_official 579:53297373a894 144 if (tmp_baud_hs > 255 || tmp_baud_hs < 0) {
mbed_official 579:53297373a894 145 /* Baud rate not supported. */
mbed_official 579:53297373a894 146 tmp_status_code = STATUS_ERR_BAUDRATE_UNAVAILABLE;
mbed_official 579:53297373a894 147 }
mbed_official 579:53297373a894 148 }
mbed_official 579:53297373a894 149 if (tmp_status_code != STATUS_ERR_BAUDRATE_UNAVAILABLE) {
mbed_official 579:53297373a894 150 /* Baud rate acceptable. */
mbed_official 579:53297373a894 151 i2c_module->BAUD.reg = SERCOM_I2CM_BAUD_BAUD(tmp_baud) |
mbed_official 579:53297373a894 152 SERCOM_I2CM_BAUD_HSBAUD(tmp_baud_hs);
mbed_official 579:53297373a894 153 }
mbed_official 579:53297373a894 154
mbed_official 579:53297373a894 155 return tmp_status_code;
mbed_official 579:53297373a894 156 }
mbed_official 579:53297373a894 157 #endif /* __DOXYGEN__ */
mbed_official 579:53297373a894 158
mbed_official 579:53297373a894 159 /**
mbed_official 579:53297373a894 160 * \brief Initializes the requested I<SUP>2</SUP>C hardware module
mbed_official 579:53297373a894 161 *
mbed_official 579:53297373a894 162 * Initializes the SERCOM I<SUP>2</SUP>C master device requested and sets the provided
mbed_official 579:53297373a894 163 * software module struct. Run this function before any further use of
mbed_official 579:53297373a894 164 * the driver.
mbed_official 579:53297373a894 165 *
mbed_official 579:53297373a894 166 * \param[out] module Pointer to software module struct
mbed_official 579:53297373a894 167 * \param[in] hw Pointer to the hardware instance
mbed_official 579:53297373a894 168 * \param[in] config Pointer to the configuration struct
mbed_official 579:53297373a894 169 *
mbed_official 579:53297373a894 170 * \return Status of initialization.
mbed_official 579:53297373a894 171 * \retval STATUS_OK Module initiated correctly
mbed_official 579:53297373a894 172 * \retval STATUS_ERR_DENIED If module is enabled
mbed_official 579:53297373a894 173 * \retval STATUS_BUSY If module is busy resetting
mbed_official 579:53297373a894 174 * \retval STATUS_ERR_ALREADY_INITIALIZED If setting other GCLK generator than
mbed_official 579:53297373a894 175 * previously set
mbed_official 579:53297373a894 176 * \retval STATUS_ERR_BAUDRATE_UNAVAILABLE If given baudrate is not compatible
mbed_official 579:53297373a894 177 * with set GCLK frequency
mbed_official 579:53297373a894 178 *
mbed_official 579:53297373a894 179 */
mbed_official 579:53297373a894 180 enum status_code i2c_master_init(
mbed_official 579:53297373a894 181 struct i2c_master_module *const module,
mbed_official 579:53297373a894 182 Sercom *const hw,
mbed_official 579:53297373a894 183 const struct i2c_master_config *const config)
mbed_official 579:53297373a894 184 {
mbed_official 579:53297373a894 185 /* Sanity check arguments. */
mbed_official 579:53297373a894 186 Assert(module);
mbed_official 579:53297373a894 187 Assert(hw);
mbed_official 579:53297373a894 188 Assert(config);
mbed_official 579:53297373a894 189
mbed_official 579:53297373a894 190 /* Initialize software module */
mbed_official 579:53297373a894 191 module->hw = hw;
mbed_official 579:53297373a894 192
mbed_official 579:53297373a894 193 SercomI2cm *const i2c_module = &(module->hw->I2CM);
mbed_official 579:53297373a894 194
mbed_official 579:53297373a894 195 uint32_t sercom_index = _sercom_get_sercom_inst_index(module->hw);
mbed_official 579:53297373a894 196 #if (SAML21)
mbed_official 579:53297373a894 197 uint32_t pm_index = sercom_index + MCLK_APBCMASK_SERCOM0_Pos;
mbed_official 579:53297373a894 198 #else
mbed_official 579:53297373a894 199 uint32_t pm_index = sercom_index + PM_APBCMASK_SERCOM0_Pos;
mbed_official 579:53297373a894 200 #endif
mbed_official 579:53297373a894 201 uint32_t gclk_index = sercom_index + SERCOM0_GCLK_ID_CORE;
mbed_official 579:53297373a894 202
mbed_official 579:53297373a894 203 /* Turn on module in PM */
mbed_official 579:53297373a894 204 system_apb_clock_set_mask(SYSTEM_CLOCK_APB_APBC, 1 << pm_index);
mbed_official 579:53297373a894 205
mbed_official 579:53297373a894 206 /* Set up the GCLK for the module */
mbed_official 579:53297373a894 207 struct system_gclk_chan_config gclk_chan_conf;
mbed_official 579:53297373a894 208 system_gclk_chan_get_config_defaults(&gclk_chan_conf);
mbed_official 579:53297373a894 209 gclk_chan_conf.source_generator = config->generator_source;
mbed_official 579:53297373a894 210 system_gclk_chan_set_config(gclk_index, &gclk_chan_conf);
mbed_official 579:53297373a894 211 system_gclk_chan_enable(gclk_index);
mbed_official 579:53297373a894 212 sercom_set_gclk_generator(config->generator_source, false);
mbed_official 579:53297373a894 213
mbed_official 579:53297373a894 214 /* Check if module is enabled. */
mbed_official 579:53297373a894 215 if (i2c_module->CTRLA.reg & SERCOM_I2CM_CTRLA_ENABLE) {
mbed_official 579:53297373a894 216 return STATUS_ERR_DENIED;
mbed_official 579:53297373a894 217 }
mbed_official 579:53297373a894 218
mbed_official 579:53297373a894 219 /* Check if reset is in progress. */
mbed_official 579:53297373a894 220 if (i2c_module->CTRLA.reg & SERCOM_I2CM_CTRLA_SWRST) {
mbed_official 579:53297373a894 221 return STATUS_BUSY;
mbed_official 579:53297373a894 222 }
mbed_official 579:53297373a894 223
mbed_official 579:53297373a894 224 #if I2C_MASTER_CALLBACK_MODE == true
mbed_official 579:53297373a894 225 /* Get sercom instance index and register callback. */
mbed_official 579:53297373a894 226 uint8_t instance_index = _sercom_get_sercom_inst_index(module->hw);
mbed_official 579:53297373a894 227 _sercom_set_handler(instance_index, _i2c_master_interrupt_handler);
mbed_official 579:53297373a894 228 _sercom_instances[instance_index] = module;
mbed_official 579:53297373a894 229
mbed_official 579:53297373a894 230 /* Initialize values in module. */
mbed_official 579:53297373a894 231 module->registered_callback = 0;
mbed_official 579:53297373a894 232 module->enabled_callback = 0;
mbed_official 579:53297373a894 233 module->buffer_length = 0;
mbed_official 579:53297373a894 234 module->buffer_remaining = 0;
mbed_official 579:53297373a894 235
mbed_official 579:53297373a894 236 module->status = STATUS_OK;
mbed_official 579:53297373a894 237 module->buffer = NULL;
mbed_official 579:53297373a894 238 #endif
mbed_official 579:53297373a894 239
mbed_official 579:53297373a894 240 /* Set sercom module to operate in I2C master mode. */
mbed_official 579:53297373a894 241 i2c_module->CTRLA.reg = SERCOM_I2CM_CTRLA_MODE(0x5);
mbed_official 579:53297373a894 242
mbed_official 579:53297373a894 243 /* Set config and return status. */
mbed_official 579:53297373a894 244 return _i2c_master_set_config(module, config);
mbed_official 579:53297373a894 245 }
mbed_official 579:53297373a894 246
mbed_official 579:53297373a894 247 /**
mbed_official 579:53297373a894 248 * \brief Resets the hardware module
mbed_official 579:53297373a894 249 *
mbed_official 579:53297373a894 250 * Reset the module to hardware defaults.
mbed_official 579:53297373a894 251 *
mbed_official 579:53297373a894 252 * \param[in,out] module Pointer to software module structure
mbed_official 579:53297373a894 253 */
mbed_official 579:53297373a894 254 void i2c_master_reset(struct i2c_master_module *const module)
mbed_official 579:53297373a894 255 {
mbed_official 579:53297373a894 256 /* Sanity check arguments */
mbed_official 579:53297373a894 257 Assert(module);
mbed_official 579:53297373a894 258 Assert(module->hw);
mbed_official 579:53297373a894 259
mbed_official 579:53297373a894 260 SercomI2cm *const i2c_module = &(module->hw->I2CM);
mbed_official 579:53297373a894 261
mbed_official 579:53297373a894 262 /* Wait for sync */
mbed_official 579:53297373a894 263 _i2c_master_wait_for_sync(module);
mbed_official 579:53297373a894 264
mbed_official 579:53297373a894 265 /* Disable module */
mbed_official 579:53297373a894 266 i2c_master_disable(module);
mbed_official 579:53297373a894 267
mbed_official 579:53297373a894 268 #if I2C_MASTER_CALLBACK_MODE == true
mbed_official 579:53297373a894 269 /* Clear all pending interrupts */
mbed_official 579:53297373a894 270 system_interrupt_enter_critical_section();
mbed_official 579:53297373a894 271 system_interrupt_clear_pending(_sercom_get_interrupt_vector(module->hw));
mbed_official 579:53297373a894 272 system_interrupt_leave_critical_section();
mbed_official 579:53297373a894 273 #endif
mbed_official 579:53297373a894 274
mbed_official 579:53297373a894 275 /* Wait for sync */
mbed_official 579:53297373a894 276 _i2c_master_wait_for_sync(module);
mbed_official 579:53297373a894 277
mbed_official 579:53297373a894 278 /* Reset module */
mbed_official 579:53297373a894 279 i2c_module->CTRLA.reg = SERCOM_I2CM_CTRLA_SWRST;
mbed_official 579:53297373a894 280 }
mbed_official 579:53297373a894 281
mbed_official 579:53297373a894 282 #if !defined(__DOXYGEN__)
mbed_official 579:53297373a894 283 /**
mbed_official 579:53297373a894 284 * \internal
mbed_official 579:53297373a894 285 * Address response. Called when address is answered or timed out.
mbed_official 579:53297373a894 286 *
mbed_official 579:53297373a894 287 * \param[in,out] module Pointer to software module structure
mbed_official 579:53297373a894 288 *
mbed_official 579:53297373a894 289 * \return Status of address response.
mbed_official 579:53297373a894 290 * \retval STATUS_OK No error has occurred
mbed_official 579:53297373a894 291 * \retval STATUS_ERR_DENIED If error on bus
mbed_official 579:53297373a894 292 * \retval STATUS_ERR_PACKET_COLLISION If arbitration is lost
mbed_official 579:53297373a894 293 * \retval STATUS_ERR_BAD_ADDRESS If slave is busy, or no slave
mbed_official 579:53297373a894 294 * acknowledged the address
mbed_official 579:53297373a894 295 */
mbed_official 579:53297373a894 296 enum status_code _i2c_master_address_response(
mbed_official 579:53297373a894 297 struct i2c_master_module *const module)
mbed_official 579:53297373a894 298 {
mbed_official 579:53297373a894 299 /* Sanity check arguments */
mbed_official 579:53297373a894 300 Assert(module);
mbed_official 579:53297373a894 301 Assert(module->hw);
mbed_official 579:53297373a894 302
mbed_official 579:53297373a894 303 SercomI2cm *const i2c_module = &(module->hw->I2CM);
mbed_official 579:53297373a894 304
mbed_official 579:53297373a894 305 /* Check for error and ignore bus-error; workaround for BUSSTATE stuck in
mbed_official 579:53297373a894 306 * BUSY */
mbed_official 579:53297373a894 307 if (i2c_module->INTFLAG.reg & SERCOM_I2CM_INTFLAG_SB) {
mbed_official 579:53297373a894 308
mbed_official 579:53297373a894 309 /* Clear write interrupt flag */
mbed_official 579:53297373a894 310 i2c_module->INTFLAG.reg = SERCOM_I2CM_INTFLAG_SB;
mbed_official 579:53297373a894 311
mbed_official 579:53297373a894 312 /* Check arbitration. */
mbed_official 579:53297373a894 313 if (i2c_module->STATUS.reg & SERCOM_I2CM_STATUS_ARBLOST) {
mbed_official 579:53297373a894 314 /* Return packet collision. */
mbed_official 579:53297373a894 315 return STATUS_ERR_PACKET_COLLISION;
mbed_official 579:53297373a894 316 }
mbed_official 579:53297373a894 317 /* Check that slave responded with ack. */
mbed_official 579:53297373a894 318 } else if (i2c_module->STATUS.reg & SERCOM_I2CM_STATUS_RXNACK) {
mbed_official 579:53297373a894 319 /* Slave busy. Issue ack and stop command. */
mbed_official 579:53297373a894 320 i2c_module->CTRLB.reg |= SERCOM_I2CM_CTRLB_CMD(3);
mbed_official 579:53297373a894 321
mbed_official 579:53297373a894 322 /* Return bad address value. */
mbed_official 579:53297373a894 323 return STATUS_ERR_BAD_ADDRESS;
mbed_official 579:53297373a894 324 }
mbed_official 579:53297373a894 325
mbed_official 579:53297373a894 326 return STATUS_OK;
mbed_official 579:53297373a894 327 }
mbed_official 579:53297373a894 328
mbed_official 579:53297373a894 329 /**
mbed_official 579:53297373a894 330 * \internal
mbed_official 579:53297373a894 331 * Waits for answer on bus.
mbed_official 579:53297373a894 332 *
mbed_official 579:53297373a894 333 * \param[in,out] module Pointer to software module structure
mbed_official 579:53297373a894 334 *
mbed_official 579:53297373a894 335 * \return Status of bus.
mbed_official 579:53297373a894 336 * \retval STATUS_OK If given response from slave device
mbed_official 579:53297373a894 337 * \retval STATUS_ERR_TIMEOUT If no response was given within specified timeout
mbed_official 579:53297373a894 338 * period
mbed_official 579:53297373a894 339 */
mbed_official 579:53297373a894 340 enum status_code _i2c_master_wait_for_bus(
mbed_official 579:53297373a894 341 struct i2c_master_module *const module)
mbed_official 579:53297373a894 342 {
mbed_official 579:53297373a894 343 /* Sanity check arguments */
mbed_official 579:53297373a894 344 Assert(module);
mbed_official 579:53297373a894 345 Assert(module->hw);
mbed_official 579:53297373a894 346
mbed_official 579:53297373a894 347 SercomI2cm *const i2c_module = &(module->hw->I2CM);
mbed_official 579:53297373a894 348
mbed_official 579:53297373a894 349 /* Wait for reply. */
mbed_official 579:53297373a894 350 uint16_t timeout_counter = 0;
mbed_official 579:53297373a894 351 while (!(i2c_module->INTFLAG.reg & SERCOM_I2CM_INTFLAG_MB) &&
mbed_official 579:53297373a894 352 !(i2c_module->INTFLAG.reg & SERCOM_I2CM_INTFLAG_SB)) {
mbed_official 579:53297373a894 353
mbed_official 579:53297373a894 354 /* Check timeout condition. */
mbed_official 579:53297373a894 355 if (++timeout_counter >= module->buffer_timeout) {
mbed_official 579:53297373a894 356 return STATUS_ERR_TIMEOUT;
mbed_official 579:53297373a894 357 }
mbed_official 579:53297373a894 358 }
mbed_official 579:53297373a894 359 return STATUS_OK;
mbed_official 579:53297373a894 360 }
mbed_official 579:53297373a894 361 #endif /* __DOXYGEN__ */
mbed_official 579:53297373a894 362
mbed_official 579:53297373a894 363 /**
mbed_official 579:53297373a894 364 * \internal
mbed_official 579:53297373a894 365 * Send master code for high speed transfer.
mbed_official 579:53297373a894 366 *
mbed_official 579:53297373a894 367 * \param[in,out] module Pointer to software module structure
mbed_official 579:53297373a894 368 * \param[in] hs_master_code 8-bit master code (0000 1XXX)
mbed_official 579:53297373a894 369 *
mbed_official 579:53297373a894 370 * \return Status of bus.
mbed_official 579:53297373a894 371 * \retval STATUS_OK No error happen
mbed_official 579:53297373a894 372 */
mbed_official 579:53297373a894 373 enum status_code _i2c_master_send_hs_master_code(
mbed_official 579:53297373a894 374 struct i2c_master_module *const module,
mbed_official 579:53297373a894 375 uint8_t hs_master_code)
mbed_official 579:53297373a894 376 {
mbed_official 579:53297373a894 377 SercomI2cm *const i2c_module = &(module->hw->I2CM);
mbed_official 579:53297373a894 378 /* Return value. */
mbed_official 579:53297373a894 379 enum status_code tmp_status;
mbed_official 579:53297373a894 380
mbed_official 579:53297373a894 381 /* Set NACK for high speed code */
mbed_official 579:53297373a894 382 i2c_module->CTRLB.reg |= SERCOM_I2CM_CTRLB_ACKACT;
mbed_official 579:53297373a894 383 /* Send high speed code */
mbed_official 579:53297373a894 384 i2c_module->ADDR.reg = hs_master_code;
mbed_official 579:53297373a894 385 /* Wait for response on bus. */
mbed_official 579:53297373a894 386 tmp_status = _i2c_master_wait_for_bus(module);
mbed_official 579:53297373a894 387 /* Clear write interrupt flag */
mbed_official 579:53297373a894 388 i2c_module->INTFLAG.reg = SERCOM_I2CM_INTENCLR_MB;
mbed_official 579:53297373a894 389
mbed_official 579:53297373a894 390 return tmp_status;
mbed_official 579:53297373a894 391 }
mbed_official 579:53297373a894 392
mbed_official 579:53297373a894 393
mbed_official 579:53297373a894 394 /**
mbed_official 579:53297373a894 395 * \internal
mbed_official 579:53297373a894 396 * Starts blocking read operation.
mbed_official 579:53297373a894 397 *
mbed_official 579:53297373a894 398 * \param[in,out] module Pointer to software module struct
mbed_official 579:53297373a894 399 * \param[in,out] packet Pointer to I<SUP>2</SUP>C packet to transfer
mbed_official 579:53297373a894 400 *
mbed_official 579:53297373a894 401 * \return Status of reading packet.
mbed_official 579:53297373a894 402 * \retval STATUS_OK The packet was read successfully
mbed_official 579:53297373a894 403 * \retval STATUS_ERR_TIMEOUT If no response was given within
mbed_official 579:53297373a894 404 * specified timeout period
mbed_official 579:53297373a894 405 * \retval STATUS_ERR_DENIED If error on bus
mbed_official 579:53297373a894 406 * \retval STATUS_ERR_PACKET_COLLISION If arbitration is lost
mbed_official 579:53297373a894 407 * \retval STATUS_ERR_BAD_ADDRESS If slave is busy, or no slave
mbed_official 579:53297373a894 408 * acknowledged the address
mbed_official 579:53297373a894 409 *
mbed_official 579:53297373a894 410 */
mbed_official 579:53297373a894 411 static enum status_code _i2c_master_read_packet(
mbed_official 579:53297373a894 412 struct i2c_master_module *const module,
mbed_official 579:53297373a894 413 struct i2c_master_packet *const packet)
mbed_official 579:53297373a894 414 {
mbed_official 579:53297373a894 415 /* Sanity check arguments */
mbed_official 579:53297373a894 416 Assert(module);
mbed_official 579:53297373a894 417 Assert(module->hw);
mbed_official 579:53297373a894 418 Assert(packet);
mbed_official 579:53297373a894 419
mbed_official 579:53297373a894 420 SercomI2cm *const i2c_module = &(module->hw->I2CM);
mbed_official 579:53297373a894 421
mbed_official 579:53297373a894 422 /* Return value. */
mbed_official 579:53297373a894 423 enum status_code tmp_status;
mbed_official 579:53297373a894 424 uint16_t tmp_data_length = packet->data_length;
mbed_official 579:53297373a894 425
mbed_official 579:53297373a894 426 /* Written buffer counter. */
mbed_official 579:53297373a894 427 uint16_t counter = 0;
mbed_official 579:53297373a894 428
mbed_official 579:53297373a894 429 bool sclsm_flag = i2c_module->CTRLA.bit.SCLSM;
mbed_official 579:53297373a894 430
mbed_official 579:53297373a894 431 /* Switch to high speed mode */
mbed_official 579:53297373a894 432 if (packet->high_speed) {
mbed_official 579:53297373a894 433 _i2c_master_send_hs_master_code(module, packet->hs_master_code);
mbed_official 579:53297373a894 434 }
mbed_official 579:53297373a894 435
mbed_official 579:53297373a894 436 /* Set action to ACK. */
mbed_official 579:53297373a894 437 i2c_module->CTRLB.reg &= ~SERCOM_I2CM_CTRLB_ACKACT;
mbed_official 579:53297373a894 438
mbed_official 579:53297373a894 439 /* Set address and direction bit. Will send start command on bus. */
mbed_official 579:53297373a894 440 if (packet->ten_bit_address) {
mbed_official 579:53297373a894 441 /*
mbed_official 579:53297373a894 442 * Write ADDR.ADDR[10:1] with the 10-bit address. ADDR.TENBITEN must
mbed_official 579:53297373a894 443 * be set and read/write bit (ADDR.ADDR[0]) equal to 0.
mbed_official 579:53297373a894 444 */
mbed_official 579:53297373a894 445 i2c_module->ADDR.reg = (packet->address << 1) |
mbed_official 579:53297373a894 446 (packet->high_speed << SERCOM_I2CM_ADDR_HS_Pos) |
mbed_official 579:53297373a894 447 SERCOM_I2CM_ADDR_TENBITEN;
mbed_official 579:53297373a894 448
mbed_official 579:53297373a894 449 /* Wait for response on bus. */
mbed_official 579:53297373a894 450 tmp_status = _i2c_master_wait_for_bus(module);
mbed_official 579:53297373a894 451
mbed_official 579:53297373a894 452 /* Set action to ack. */
mbed_official 579:53297373a894 453 i2c_module->CTRLB.reg &= ~SERCOM_I2CM_CTRLB_ACKACT;
mbed_official 579:53297373a894 454
mbed_official 579:53297373a894 455 /* Check for address response error unless previous error is
mbed_official 579:53297373a894 456 * detected. */
mbed_official 579:53297373a894 457 if (tmp_status == STATUS_OK) {
mbed_official 579:53297373a894 458 tmp_status = _i2c_master_address_response(module);
mbed_official 579:53297373a894 459 }
mbed_official 579:53297373a894 460
mbed_official 579:53297373a894 461 if (tmp_status == STATUS_OK) {
mbed_official 579:53297373a894 462 /*
mbed_official 579:53297373a894 463 * Write ADDR[7:0] register to 鈥10 address[9:8] 1鈥
mbed_official 579:53297373a894 464 * ADDR.TENBITEN must be cleared
mbed_official 579:53297373a894 465 */
mbed_official 579:53297373a894 466 i2c_module->ADDR.reg = (((packet->address >> 8) | 0x78) << 1) |
mbed_official 579:53297373a894 467 (packet->high_speed << SERCOM_I2CM_ADDR_HS_Pos) |
mbed_official 579:53297373a894 468 I2C_TRANSFER_READ;
mbed_official 579:53297373a894 469 } else {
mbed_official 579:53297373a894 470 return tmp_status;
mbed_official 579:53297373a894 471 }
mbed_official 579:53297373a894 472 } else {
mbed_official 579:53297373a894 473 i2c_module->ADDR.reg = (packet->address << 1) | I2C_TRANSFER_READ |
mbed_official 579:53297373a894 474 (packet->high_speed << SERCOM_I2CM_ADDR_HS_Pos);
mbed_official 579:53297373a894 475 }
mbed_official 579:53297373a894 476
mbed_official 579:53297373a894 477 /* Wait for response on bus. */
mbed_official 579:53297373a894 478 tmp_status = _i2c_master_wait_for_bus(module);
mbed_official 579:53297373a894 479
mbed_official 579:53297373a894 480 /* Set action to ack. */
mbed_official 579:53297373a894 481 i2c_module->CTRLB.reg &= ~SERCOM_I2CM_CTRLB_ACKACT;
mbed_official 579:53297373a894 482
mbed_official 579:53297373a894 483 /* Check for address response error unless previous error is
mbed_official 579:53297373a894 484 * detected. */
mbed_official 579:53297373a894 485 if (tmp_status == STATUS_OK) {
mbed_official 579:53297373a894 486 tmp_status = _i2c_master_address_response(module);
mbed_official 579:53297373a894 487 }
mbed_official 579:53297373a894 488
mbed_official 579:53297373a894 489 /* Check that no error has occurred. */
mbed_official 579:53297373a894 490 if (tmp_status == STATUS_OK) {
mbed_official 579:53297373a894 491 /* Read data buffer. */
mbed_official 579:53297373a894 492 while (tmp_data_length--) {
mbed_official 579:53297373a894 493 /* Check that bus ownership is not lost. */
mbed_official 579:53297373a894 494 if (!(i2c_module->STATUS.reg & SERCOM_I2CM_STATUS_BUSSTATE(2))) {
mbed_official 579:53297373a894 495 return STATUS_ERR_PACKET_COLLISION;
mbed_official 579:53297373a894 496 }
mbed_official 579:53297373a894 497
mbed_official 579:53297373a894 498 if (((!sclsm_flag) && (tmp_data_length == 0)) ||
mbed_official 579:53297373a894 499 ((sclsm_flag) && (tmp_data_length == 1))) {
mbed_official 579:53297373a894 500 /* Set action to NACK */
mbed_official 579:53297373a894 501 i2c_module->CTRLB.reg |= SERCOM_I2CM_CTRLB_ACKACT;
mbed_official 579:53297373a894 502 } else {
mbed_official 579:53297373a894 503 /* Save data to buffer. */
mbed_official 579:53297373a894 504 _i2c_master_wait_for_sync(module);
mbed_official 579:53297373a894 505 packet->data[counter++] = i2c_module->DATA.reg;
mbed_official 579:53297373a894 506 /* Wait for response. */
mbed_official 579:53297373a894 507 tmp_status = _i2c_master_wait_for_bus(module);
mbed_official 579:53297373a894 508 }
mbed_official 579:53297373a894 509
mbed_official 579:53297373a894 510 /* Check for error. */
mbed_official 579:53297373a894 511 if (tmp_status != STATUS_OK) {
mbed_official 579:53297373a894 512 break;
mbed_official 579:53297373a894 513 }
mbed_official 579:53297373a894 514 }
mbed_official 579:53297373a894 515
mbed_official 579:53297373a894 516 if (module->send_stop) {
mbed_official 579:53297373a894 517 /* Send stop command unless arbitration is lost. */
mbed_official 579:53297373a894 518 _i2c_master_wait_for_sync(module);
mbed_official 579:53297373a894 519 i2c_module->CTRLB.reg |= SERCOM_I2CM_CTRLB_CMD(3);
mbed_official 579:53297373a894 520 }
mbed_official 579:53297373a894 521
mbed_official 579:53297373a894 522 /* Save last data to buffer. */
mbed_official 579:53297373a894 523 _i2c_master_wait_for_sync(module);
mbed_official 579:53297373a894 524 packet->data[counter] = i2c_module->DATA.reg;
mbed_official 579:53297373a894 525 }
mbed_official 579:53297373a894 526
mbed_official 579:53297373a894 527 return tmp_status;
mbed_official 579:53297373a894 528 }
mbed_official 579:53297373a894 529
mbed_official 579:53297373a894 530 /**
mbed_official 579:53297373a894 531 * \brief Reads data packet from slave
mbed_official 579:53297373a894 532 *
mbed_official 579:53297373a894 533 * Reads a data packet from the specified slave address on the I<SUP>2</SUP>C
mbed_official 579:53297373a894 534 * bus and sends a stop condition when finished.
mbed_official 579:53297373a894 535 *
mbed_official 579:53297373a894 536 * \note This will stall the device from any other operation. For
mbed_official 579:53297373a894 537 * interrupt-driven operation, see \ref i2c_master_read_packet_job.
mbed_official 579:53297373a894 538 *
mbed_official 579:53297373a894 539 * \param[in,out] module Pointer to software module struct
mbed_official 579:53297373a894 540 * \param[in,out] packet Pointer to I<SUP>2</SUP>C packet to transfer
mbed_official 579:53297373a894 541 *
mbed_official 579:53297373a894 542 * \return Status of reading packet.
mbed_official 579:53297373a894 543 * \retval STATUS_OK The packet was read successfully
mbed_official 579:53297373a894 544 * \retval STATUS_ERR_TIMEOUT If no response was given within
mbed_official 579:53297373a894 545 * specified timeout period
mbed_official 579:53297373a894 546 * \retval STATUS_ERR_DENIED If error on bus
mbed_official 579:53297373a894 547 * \retval STATUS_ERR_PACKET_COLLISION If arbitration is lost
mbed_official 579:53297373a894 548 * \retval STATUS_ERR_BAD_ADDRESS If slave is busy, or no slave
mbed_official 579:53297373a894 549 * acknowledged the address
mbed_official 579:53297373a894 550 */
mbed_official 579:53297373a894 551 enum status_code i2c_master_read_packet_wait(
mbed_official 579:53297373a894 552 struct i2c_master_module *const module,
mbed_official 579:53297373a894 553 struct i2c_master_packet *const packet)
mbed_official 579:53297373a894 554 {
mbed_official 579:53297373a894 555 /* Sanity check */
mbed_official 579:53297373a894 556 Assert(module);
mbed_official 579:53297373a894 557 Assert(module->hw);
mbed_official 579:53297373a894 558 Assert(packet);
mbed_official 579:53297373a894 559
mbed_official 579:53297373a894 560 #if I2C_MASTER_CALLBACK_MODE == true
mbed_official 579:53297373a894 561 /* Check if the I2C module is busy with a job. */
mbed_official 579:53297373a894 562 if (module->buffer_remaining > 0) {
mbed_official 579:53297373a894 563 return STATUS_BUSY;
mbed_official 579:53297373a894 564 }
mbed_official 579:53297373a894 565 #endif
mbed_official 579:53297373a894 566
mbed_official 579:53297373a894 567 module->send_stop = true;
mbed_official 579:53297373a894 568
mbed_official 579:53297373a894 569 return _i2c_master_read_packet(module, packet);
mbed_official 579:53297373a894 570 }
mbed_official 579:53297373a894 571
mbed_official 579:53297373a894 572 /**
mbed_official 579:53297373a894 573 * \brief Reads data packet from slave without sending a stop condition when done
mbed_official 579:53297373a894 574 *
mbed_official 579:53297373a894 575 * Reads a data packet from the specified slave address on the I<SUP>2</SUP>C
mbed_official 579:53297373a894 576 * bus without sending a stop condition when done, thus retaining ownership of
mbed_official 579:53297373a894 577 * the bus when done. To end the transaction, a
mbed_official 579:53297373a894 578 * \ref i2c_master_read_packet_wait "read" or
mbed_official 579:53297373a894 579 * \ref i2c_master_write_packet_wait "write" with stop condition must be
mbed_official 579:53297373a894 580 * performed.
mbed_official 579:53297373a894 581 *
mbed_official 579:53297373a894 582 * \note This will stall the device from any other operation. For
mbed_official 579:53297373a894 583 * interrupt-driven operation, see \ref i2c_master_read_packet_job.
mbed_official 579:53297373a894 584 *
mbed_official 579:53297373a894 585 * \param[in,out] module Pointer to software module struct
mbed_official 579:53297373a894 586 * \param[in,out] packet Pointer to I<SUP>2</SUP>C packet to transfer
mbed_official 579:53297373a894 587 *
mbed_official 579:53297373a894 588 * \return Status of reading packet.
mbed_official 579:53297373a894 589 * \retval STATUS_OK The packet was read successfully
mbed_official 579:53297373a894 590 * \retval STATUS_ERR_TIMEOUT If no response was given within
mbed_official 579:53297373a894 591 * specified timeout period
mbed_official 579:53297373a894 592 * \retval STATUS_ERR_DENIED If error on bus
mbed_official 579:53297373a894 593 * \retval STATUS_ERR_PACKET_COLLISION If arbitration is lost
mbed_official 579:53297373a894 594 * \retval STATUS_ERR_BAD_ADDRESS If slave is busy, or no slave
mbed_official 579:53297373a894 595 * acknowledged the address
mbed_official 579:53297373a894 596 */
mbed_official 579:53297373a894 597 enum status_code i2c_master_read_packet_wait_no_stop(
mbed_official 579:53297373a894 598 struct i2c_master_module *const module,
mbed_official 579:53297373a894 599 struct i2c_master_packet *const packet)
mbed_official 579:53297373a894 600 {
mbed_official 579:53297373a894 601 /* Sanity check */
mbed_official 579:53297373a894 602 Assert(module);
mbed_official 579:53297373a894 603 Assert(module->hw);
mbed_official 579:53297373a894 604 Assert(packet);
mbed_official 579:53297373a894 605
mbed_official 579:53297373a894 606 #if I2C_MASTER_CALLBACK_MODE == true
mbed_official 579:53297373a894 607 /* Check if the I2C module is busy with a job. */
mbed_official 579:53297373a894 608 if (module->buffer_remaining > 0) {
mbed_official 579:53297373a894 609 return STATUS_BUSY;
mbed_official 579:53297373a894 610 }
mbed_official 579:53297373a894 611 #endif
mbed_official 579:53297373a894 612
mbed_official 579:53297373a894 613 module->send_stop = false;
mbed_official 579:53297373a894 614
mbed_official 579:53297373a894 615 return _i2c_master_read_packet(module, packet);
mbed_official 579:53297373a894 616 }
mbed_official 579:53297373a894 617
mbed_official 579:53297373a894 618 /**
mbed_official 579:53297373a894 619 * \internal
mbed_official 579:53297373a894 620 * Starts blocking write operation.
mbed_official 579:53297373a894 621 *
mbed_official 579:53297373a894 622 * \param[in,out] module Pointer to software module struct
mbed_official 579:53297373a894 623 * \param[in,out] packet Pointer to I<SUP>2</SUP>C packet to transfer
mbed_official 579:53297373a894 624 *
mbed_official 579:53297373a894 625 * \return Status of reading packet.
mbed_official 579:53297373a894 626 * \retval STATUS_OK The packet was read successfully
mbed_official 579:53297373a894 627 * \retval STATUS_ERR_TIMEOUT If no response was given within
mbed_official 579:53297373a894 628 * specified timeout period
mbed_official 579:53297373a894 629 * \retval STATUS_ERR_DENIED If error on bus
mbed_official 579:53297373a894 630 * \retval STATUS_ERR_PACKET_COLLISION If arbitration is lost
mbed_official 579:53297373a894 631 * \retval STATUS_ERR_BAD_ADDRESS If slave is busy, or no slave
mbed_official 579:53297373a894 632 * acknowledged the address
mbed_official 579:53297373a894 633 */
mbed_official 579:53297373a894 634 static enum status_code _i2c_master_write_packet(
mbed_official 579:53297373a894 635 struct i2c_master_module *const module,
mbed_official 579:53297373a894 636 struct i2c_master_packet *const packet)
mbed_official 579:53297373a894 637 {
mbed_official 579:53297373a894 638 SercomI2cm *const i2c_module = &(module->hw->I2CM);
mbed_official 579:53297373a894 639
mbed_official 579:53297373a894 640 /* Return value. */
mbed_official 579:53297373a894 641 enum status_code tmp_status;
mbed_official 579:53297373a894 642 uint16_t tmp_data_length = packet->data_length;
mbed_official 579:53297373a894 643
mbed_official 579:53297373a894 644 _i2c_master_wait_for_sync(module);
mbed_official 579:53297373a894 645
mbed_official 579:53297373a894 646 /* Switch to high speed mode */
mbed_official 579:53297373a894 647 if (packet->high_speed) {
mbed_official 579:53297373a894 648 _i2c_master_send_hs_master_code(module, packet->hs_master_code);
mbed_official 579:53297373a894 649 }
mbed_official 579:53297373a894 650
mbed_official 579:53297373a894 651 /* Set action to ACK. */
mbed_official 579:53297373a894 652 i2c_module->CTRLB.reg &= ~SERCOM_I2CM_CTRLB_ACKACT;
mbed_official 579:53297373a894 653
mbed_official 579:53297373a894 654 /* Set address and direction bit. Will send start command on bus. */
mbed_official 579:53297373a894 655 if (packet->ten_bit_address) {
mbed_official 579:53297373a894 656 i2c_module->ADDR.reg = (packet->address << 1) | I2C_TRANSFER_WRITE |
mbed_official 579:53297373a894 657 (packet->high_speed << SERCOM_I2CM_ADDR_HS_Pos) |
mbed_official 579:53297373a894 658 SERCOM_I2CM_ADDR_TENBITEN;
mbed_official 579:53297373a894 659 } else {
mbed_official 579:53297373a894 660 i2c_module->ADDR.reg = (packet->address << 1) | I2C_TRANSFER_WRITE |
mbed_official 579:53297373a894 661 (packet->high_speed << SERCOM_I2CM_ADDR_HS_Pos);
mbed_official 579:53297373a894 662 }
mbed_official 579:53297373a894 663 /* Wait for response on bus. */
mbed_official 579:53297373a894 664 tmp_status = _i2c_master_wait_for_bus(module);
mbed_official 579:53297373a894 665
mbed_official 579:53297373a894 666 /* Check for address response error unless previous error is
mbed_official 579:53297373a894 667 * detected. */
mbed_official 579:53297373a894 668 if (tmp_status == STATUS_OK) {
mbed_official 579:53297373a894 669 tmp_status = _i2c_master_address_response(module);
mbed_official 579:53297373a894 670 }
mbed_official 579:53297373a894 671
mbed_official 579:53297373a894 672 /* Check that no error has occurred. */
mbed_official 579:53297373a894 673 if (tmp_status == STATUS_OK) {
mbed_official 579:53297373a894 674 /* Buffer counter. */
mbed_official 579:53297373a894 675 uint16_t buffer_counter = 0;
mbed_official 579:53297373a894 676
mbed_official 579:53297373a894 677 /* Write data buffer. */
mbed_official 579:53297373a894 678 while (tmp_data_length--) {
mbed_official 579:53297373a894 679 /* Check that bus ownership is not lost. */
mbed_official 579:53297373a894 680 if (!(i2c_module->STATUS.reg & SERCOM_I2CM_STATUS_BUSSTATE(2))) {
mbed_official 579:53297373a894 681 return STATUS_ERR_PACKET_COLLISION;
mbed_official 579:53297373a894 682 }
mbed_official 579:53297373a894 683
mbed_official 579:53297373a894 684 /* Write byte to slave. */
mbed_official 579:53297373a894 685 _i2c_master_wait_for_sync(module);
mbed_official 579:53297373a894 686 i2c_module->DATA.reg = packet->data[buffer_counter++];
mbed_official 579:53297373a894 687
mbed_official 579:53297373a894 688 /* Wait for response. */
mbed_official 579:53297373a894 689 tmp_status = _i2c_master_wait_for_bus(module);
mbed_official 579:53297373a894 690
mbed_official 579:53297373a894 691 /* Check for error. */
mbed_official 579:53297373a894 692 if (tmp_status != STATUS_OK) {
mbed_official 579:53297373a894 693 break;
mbed_official 579:53297373a894 694 }
mbed_official 579:53297373a894 695
mbed_official 579:53297373a894 696 /* Check for NACK from slave. */
mbed_official 579:53297373a894 697 if (i2c_module->STATUS.reg & SERCOM_I2CM_STATUS_RXNACK) {
mbed_official 579:53297373a894 698 /* Return bad data value. */
mbed_official 579:53297373a894 699 tmp_status = STATUS_ERR_OVERFLOW;
mbed_official 579:53297373a894 700 break;
mbed_official 579:53297373a894 701 }
mbed_official 579:53297373a894 702 }
mbed_official 579:53297373a894 703
mbed_official 579:53297373a894 704 if (module->send_stop) {
mbed_official 579:53297373a894 705 /* Stop command */
mbed_official 579:53297373a894 706 _i2c_master_wait_for_sync(module);
mbed_official 579:53297373a894 707 i2c_module->CTRLB.reg |= SERCOM_I2CM_CTRLB_CMD(3);
mbed_official 579:53297373a894 708 }
mbed_official 579:53297373a894 709 }
mbed_official 579:53297373a894 710
mbed_official 579:53297373a894 711 return tmp_status;
mbed_official 579:53297373a894 712 }
mbed_official 579:53297373a894 713
mbed_official 579:53297373a894 714 /**
mbed_official 579:53297373a894 715 * \brief Writes data packet to slave
mbed_official 579:53297373a894 716 *
mbed_official 579:53297373a894 717 * Writes a data packet to the specified slave address on the I<SUP>2</SUP>C bus
mbed_official 579:53297373a894 718 * and sends a stop condition when finished.
mbed_official 579:53297373a894 719 *
mbed_official 579:53297373a894 720 * \note This will stall the device from any other operation. For
mbed_official 579:53297373a894 721 * interrupt-driven operation, see \ref i2c_master_read_packet_job.
mbed_official 579:53297373a894 722 *
mbed_official 579:53297373a894 723 * \param[in,out] module Pointer to software module struct
mbed_official 579:53297373a894 724 * \param[in,out] packet Pointer to I<SUP>2</SUP>C packet to transfer
mbed_official 579:53297373a894 725 *
mbed_official 579:53297373a894 726 * \return Status of reading packet.
mbed_official 579:53297373a894 727 * \retval STATUS_OK If packet was read
mbed_official 579:53297373a894 728 * \retval STATUS_BUSY If master module is busy with a job
mbed_official 579:53297373a894 729 * \retval STATUS_ERR_DENIED If error on bus
mbed_official 579:53297373a894 730 * \retval STATUS_ERR_PACKET_COLLISION If arbitration is lost
mbed_official 579:53297373a894 731 * \retval STATUS_ERR_BAD_ADDRESS If slave is busy, or no slave
mbed_official 579:53297373a894 732 * acknowledged the address
mbed_official 579:53297373a894 733 * \retval STATUS_ERR_TIMEOUT If timeout occurred
mbed_official 579:53297373a894 734 * \retval STATUS_ERR_OVERFLOW If slave did not acknowledge last sent
mbed_official 579:53297373a894 735 * data, indicating that slave does not
mbed_official 579:53297373a894 736 * want more data and was not able to read
mbed_official 579:53297373a894 737 * last data sent
mbed_official 579:53297373a894 738 */
mbed_official 579:53297373a894 739 enum status_code i2c_master_write_packet_wait(
mbed_official 579:53297373a894 740 struct i2c_master_module *const module,
mbed_official 579:53297373a894 741 struct i2c_master_packet *const packet)
mbed_official 579:53297373a894 742 {
mbed_official 579:53297373a894 743 /* Sanity check */
mbed_official 579:53297373a894 744 Assert(module);
mbed_official 579:53297373a894 745 Assert(module->hw);
mbed_official 579:53297373a894 746 Assert(packet);
mbed_official 579:53297373a894 747
mbed_official 579:53297373a894 748 #if I2C_MASTER_CALLBACK_MODE == true
mbed_official 579:53297373a894 749 /* Check if the I2C module is busy with a job */
mbed_official 579:53297373a894 750 if (module->buffer_remaining > 0) {
mbed_official 579:53297373a894 751 return STATUS_BUSY;
mbed_official 579:53297373a894 752 }
mbed_official 579:53297373a894 753 #endif
mbed_official 579:53297373a894 754
mbed_official 579:53297373a894 755 module->send_stop = true;
mbed_official 579:53297373a894 756
mbed_official 579:53297373a894 757 return _i2c_master_write_packet(module, packet);
mbed_official 579:53297373a894 758 }
mbed_official 579:53297373a894 759
mbed_official 579:53297373a894 760 /**
mbed_official 579:53297373a894 761 * \brief Writes data packet to slave without sending a stop condition when done
mbed_official 579:53297373a894 762 *
mbed_official 579:53297373a894 763 * Writes a data packet to the specified slave address on the I<SUP>2</SUP>C bus
mbed_official 579:53297373a894 764 * without sending a stop condition, thus retaining ownership of the bus when
mbed_official 579:53297373a894 765 * done. To end the transaction, a \ref i2c_master_read_packet_wait "read" or
mbed_official 579:53297373a894 766 * \ref i2c_master_write_packet_wait "write" with stop condition or sending a
mbed_official 579:53297373a894 767 * stop with the \ref i2c_master_send_stop function must be performed.
mbed_official 579:53297373a894 768 *
mbed_official 579:53297373a894 769 * \note This will stall the device from any other operation. For
mbed_official 579:53297373a894 770 * interrupt-driven operation, see \ref i2c_master_read_packet_job.
mbed_official 579:53297373a894 771 *
mbed_official 579:53297373a894 772 * \param[in,out] module Pointer to software module struct
mbed_official 579:53297373a894 773 * \param[in,out] packet Pointer to I<SUP>2</SUP>C packet to transfer
mbed_official 579:53297373a894 774 *
mbed_official 579:53297373a894 775 * \return Status of reading packet.
mbed_official 579:53297373a894 776 * \retval STATUS_OK If packet was read
mbed_official 579:53297373a894 777 * \retval STATUS_BUSY If master module is busy
mbed_official 579:53297373a894 778 * \retval STATUS_ERR_DENIED If error on bus
mbed_official 579:53297373a894 779 * \retval STATUS_ERR_PACKET_COLLISION If arbitration is lost
mbed_official 579:53297373a894 780 * \retval STATUS_ERR_BAD_ADDRESS If slave is busy, or no slave
mbed_official 579:53297373a894 781 * acknowledged the address
mbed_official 579:53297373a894 782 * \retval STATUS_ERR_TIMEOUT If timeout occurred
mbed_official 579:53297373a894 783 * \retval STATUS_ERR_OVERFLOW If slave did not acknowledge last sent
mbed_official 579:53297373a894 784 * data, indicating that slave do not want
mbed_official 579:53297373a894 785 * more data
mbed_official 579:53297373a894 786 */
mbed_official 579:53297373a894 787 enum status_code i2c_master_write_packet_wait_no_stop(
mbed_official 579:53297373a894 788 struct i2c_master_module *const module,
mbed_official 579:53297373a894 789 struct i2c_master_packet *const packet)
mbed_official 579:53297373a894 790 {
mbed_official 579:53297373a894 791 /* Sanity check */
mbed_official 579:53297373a894 792 Assert(module);
mbed_official 579:53297373a894 793 Assert(module->hw);
mbed_official 579:53297373a894 794 Assert(packet);
mbed_official 579:53297373a894 795
mbed_official 579:53297373a894 796 #if I2C_MASTER_CALLBACK_MODE == true
mbed_official 579:53297373a894 797 /* Check if the I2C module is busy with a job */
mbed_official 579:53297373a894 798 if (module->buffer_remaining > 0) {
mbed_official 579:53297373a894 799 return STATUS_BUSY;
mbed_official 579:53297373a894 800 }
mbed_official 579:53297373a894 801 #endif
mbed_official 579:53297373a894 802
mbed_official 579:53297373a894 803 module->send_stop = false;
mbed_official 579:53297373a894 804
mbed_official 579:53297373a894 805 return _i2c_master_write_packet(module, packet);
mbed_official 579:53297373a894 806 }
mbed_official 579:53297373a894 807
mbed_official 579:53297373a894 808 /**
mbed_official 579:53297373a894 809 * \brief Sends stop condition on bus
mbed_official 579:53297373a894 810 *
mbed_official 579:53297373a894 811 * Sends a stop condition on bus.
mbed_official 579:53297373a894 812 *
mbed_official 579:53297373a894 813 * \note This function can only be used after the
mbed_official 579:53297373a894 814 * \ref i2c_master_write_packet_wait_no_stop function. If a stop condition
mbed_official 579:53297373a894 815 * is to be sent after a read, the \ref i2c_master_read_packet_wait
mbed_official 579:53297373a894 816 * function must be used.
mbed_official 579:53297373a894 817 *
mbed_official 579:53297373a894 818 * \param[in] module Pointer to the software instance struct
mbed_official 579:53297373a894 819 */
mbed_official 579:53297373a894 820 void i2c_master_send_stop(struct i2c_master_module *const module)
mbed_official 579:53297373a894 821 {
mbed_official 579:53297373a894 822 /* Sanity check */
mbed_official 579:53297373a894 823 Assert(module);
mbed_official 579:53297373a894 824 Assert(module->hw);
mbed_official 579:53297373a894 825
mbed_official 579:53297373a894 826 SercomI2cm *const i2c_module = &(module->hw->I2CM);
mbed_official 579:53297373a894 827
mbed_official 579:53297373a894 828 /* Send stop command */
mbed_official 579:53297373a894 829 _i2c_master_wait_for_sync(module);
mbed_official 579:53297373a894 830 i2c_module->CTRLB.reg |= SERCOM_I2CM_CTRLB_CMD(3);
mbed_official 579:53297373a894 831 }