mbed library sources

Dependents:   Encrypted my_mbed lklk CyaSSL_DTLS_Cellular ... more

Superseded

This library was superseded by mbed-dev - https://os.mbed.com/users/mbed_official/code/mbed-dev/.

Development branch of the mbed library sources. This library is kept in synch with the latest changes from the mbed SDK and it is not guaranteed to work.

If you are looking for a stable and tested release, please import one of the official mbed library releases:

Import librarymbed

The official Mbed 2 C/C++ SDK provides the software platform and libraries to build your applications.

Committer:
mbed_official
Date:
Wed Jul 01 09:45:11 2015 +0100
Revision:
579:53297373a894
Child:
592:a274ee790e56
Synchronized with git revision d5b4d2ab9c47edb4dc5776e7177b0c2263459081

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

Initial version of drivers for SAMR21

Who changed what in which revision?

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