mbed library sources. Supersedes mbed-src.

Fork of mbed-dev by mbed official

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

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

Renamed TARGET_SAM_CortexM0+ to TARGET_SAM_CortexM0P for compatiblity with online compiler

Who changed what in which revision?

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