1 /** 2 * \file 3 * 4 * \brief I2C Slave Driver for SAMB 5 * 6 * Copyright (c) 2015-2016 Atmel Corporation. All rights reserved. 7 * 8 * \asf_license_start 9 * 10 * \page License 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions are met: 14 * 15 * 1. Redistributions of source code must retain the above copyright notice, 16 * this list of conditions and the following disclaimer. 17 * 18 * 2. Redistributions in binary form must reproduce the above copyright notice, 19 * this list of conditions and the following disclaimer in the documentation 20 * and/or other materials provided with the distribution. 21 * 22 * 3. The name of Atmel may not be used to endorse or promote products derived 23 * from this software without specific prior written permission. 24 * 25 * 4. This software may only be redistributed and used in connection with an 26 * Atmel microcontroller product. 27 * 28 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED 29 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 30 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE 31 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR 32 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 36 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 37 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 38 * POSSIBILITY OF SUCH DAMAGE. 39 * 40 * \asf_license_stop 41 * 42 */ 43 /* 44 * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a> 45 */ 46 47 #ifndef I2C_SLAVE_H_INCLUDED 48 #define I2C_SLAVE_H_INCLUDED 49 50 #include "i2c_common.h" 51 52 #ifdef __cplusplus 53 extern "C" { 54 #endif 55 56 /** 57 * \addtogroup asfdoc_samb_i2c_group 58 * 59 * @{ 60 * 61 */ 62 63 /** 64 * \brief I<SUP>2</SUP>C slave packet for read/write 65 * 66 * Structure to be used when transferring I<SUP>2</SUP>C slave packets. 67 */ 68 struct i2c_slave_packet { 69 /** Length of data array */ 70 uint16_t data_length; 71 /** Data array containing all data to be transferred */ 72 uint8_t *data; 73 }; 74 75 #if I2C_SLAVE_CALLBACK_MODE == true 76 /** 77 * \brief Callback types 78 * 79 * The available callback types for the I<SUP>2</SUP>C slave. 80 */ 81 enum i2c_slave_callback { 82 /** Callback for packet write complete */ 83 I2C_SLAVE_CALLBACK_WRITE_COMPLETE, 84 /** Callback for packet read complete */ 85 I2C_SLAVE_CALLBACK_READ_COMPLETE, 86 /** 87 * Callback for read request from master - can be used to 88 * issue a write 89 */ 90 I2C_SLAVE_CALLBACK_READ_REQUEST, 91 /** 92 * Callback for write request from master - can be used to issue a read 93 */ 94 I2C_SLAVE_CALLBACK_WRITE_REQUEST, 95 /** Callback for error */ 96 I2C_SLAVE_CALLBACK_ERROR, 97 # if !defined(__DOXYGEN__) 98 /** Total number of callbacks */ 99 _I2C_SLAVE_CALLBACK_N, 100 # endif 101 }; 102 103 # if !defined(__DOXYGEN__) 104 /** Software module prototype. */ 105 struct i2c_slave_module; 106 107 /** Callback type. */ 108 typedef void (*i2c_slave_callback_t)( 109 struct i2c_slave_module *const module); 110 # endif 111 #endif 112 113 /** 114 * \brief Enum for the direction of a request 115 * 116 * Enum for the direction of a request. 117 */ 118 enum i2c_slave_direction { 119 /** Read */ 120 I2C_SLAVE_DIRECTION_READ, 121 /** Write */ 122 I2C_SLAVE_DIRECTION_WRITE, 123 /** No direction */ 124 I2C_SLAVE_DIRECTION_NONE, 125 }; 126 127 /** 128 * \brief I<SUP>2</SUP>C Slave driver software device instance structure. 129 * 130 * I<SUP>2</SUP>C Slave driver software instance structure, used to 131 * retain software state information of an associated hardware module instance. 132 * 133 * \note The fields of this structure should not be altered by the user 134 * application; they are reserved for module-internal use only. 135 */ 136 struct i2c_slave_module { 137 #if !defined(__DOXYGEN__) 138 /** Hardware instance initialized for the struct */ 139 I2c *hw; 140 /** Module lock */ 141 volatile bool locked; 142 /** Timeout value for polled functions */ 143 uint16_t buffer_timeout; 144 # if I2C_SLAVE_CALLBACK_MODE == true 145 /** Pointers to callback functions */ 146 volatile i2c_slave_callback_t callbacks[_I2C_SLAVE_CALLBACK_N]; 147 /** Mask for registered callbacks */ 148 volatile uint8_t registered_callback; 149 /** Mask for enabled callbacks */ 150 volatile uint8_t enabled_callback; 151 /** The total number of bytes to transfer */ 152 volatile uint16_t buffer_length; 153 /** 154 * Counter used for bytes left to send in write and to count number of 155 * obtained bytes in read 156 */ 157 uint16_t buffer_remaining; 158 /** Data buffer for packet write and read */ 159 volatile uint8_t *buffer; 160 /** Save direction of request from master. 1 = read, 0 = write. */ 161 volatile enum i2c_transfer_direction transfer_direction; 162 /** Status for status read back in error callback */ 163 volatile enum status_code status; 164 # endif 165 #endif 166 }; 167 168 /** 169 * \brief Configuration structure for the I<SUP>2</SUP>C Slave device 170 * 171 * This is the configuration structure for the I<SUP>2</SUP>C Slave device. It is used 172 * as an argument for \ref i2c_slave_init to provide the desired 173 * configurations for the module. The structure should be initialized using the 174 * \ref i2c_slave_get_config_defaults. 175 */ 176 struct i2c_slave_config { 177 /** Timeout to wait for master in polled functions */ 178 uint16_t buffer_timeout; 179 /** Address or upper limit of address range */ 180 uint16_t address; 181 /** CLOCK INPUT to use as clock source */ 182 enum i2c_clock_input clock_source; 183 /** Divide ratio used to generate the sck clock */ 184 uint16_t clock_divider; 185 /** PAD0 (SDA) pin number */ 186 uint32_t pin_number_pad0; 187 /** PAD0 (SDA) pinmux selection */ 188 uint32_t pinmux_sel_pad0; 189 /** PAD1 (SCL) pin numer */ 190 uint32_t pin_number_pad1; 191 /** PAD1 (SCL) pinmux selection */ 192 uint32_t pinmux_sel_pad1; 193 }; 194 195 /** 196 * \name Configuration and Initialization 197 * @{ 198 */ 199 200 void i2c_slave_get_config_defaults( 201 struct i2c_slave_config *const config); 202 enum status_code i2c_slave_init(struct i2c_slave_module *const module, 203 I2c *const hw, 204 const struct i2c_slave_config *const config); 205 enum status_code i2c_slave_write_packet_wait( 206 struct i2c_slave_module *const module, 207 struct i2c_slave_packet *const packet); 208 enum status_code i2c_slave_read_packet_wait( 209 struct i2c_slave_module *const module, 210 struct i2c_slave_packet *const packet); 211 212 /** @} */ 213 214 /** 215 * \name Status Management 216 * @{ 217 */ 218 uint32_t i2c_slave_get_status( 219 struct i2c_slave_module *const module); 220 void i2c_slave_clear_status( 221 struct i2c_slave_module *const module, 222 uint32_t status_flags); 223 /** @} */ 224 225 /** @} */ 226 227 #ifdef __cplusplus 228 } 229 #endif 230 231 #endif /* I2C_SLAVE_H_INCLUDED */ 232