1 /***************************************************************************//** 2 * \file cyhal_ezi2c.h 3 * 4 * \brief 5 * Provides a high level interface for interacting with the Infineon EZI2C. 6 * This interface abstracts out the chip specific details. If any chip specific 7 * functionality is necessary, or performance is critical the low level functions 8 * can be used directly. 9 * 10 ******************************************************************************** 11 * \copyright 12 * Copyright 2018-2022 Cypress Semiconductor Corporation (an Infineon company) or 13 * an affiliate of Cypress Semiconductor Corporation 14 * 15 * SPDX-License-Identifier: Apache-2.0 16 * 17 * Licensed under the Apache License, Version 2.0 (the "License"); 18 * you may not use this file except in compliance with the License. 19 * You may obtain a copy of the License at 20 * 21 * http://www.apache.org/licenses/LICENSE-2.0 22 * 23 * Unless required by applicable law or agreed to in writing, software 24 * distributed under the License is distributed on an "AS IS" BASIS, 25 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 26 * See the License for the specific language governing permissions and 27 * limitations under the License. 28 *******************************************************************************/ 29 30 /** 31 * \addtogroup group_hal_ezi2c EZI2C (Inter-Integrated Circuit) 32 * \ingroup group_hal 33 * \{ 34 * High level interface for interacting with the Cypress EZ Inter-Integrated Circuit (EZI2C). 35 * The EZI2C driver implements an I2C slave device that emulates a common I2C EEPROM interface between 36 * the external master and your application code. EZI2C Slave buffers can be set up as any variable, array, 37 * or structure in your code without worrying about the I2C protocol. I2C related transactions and processing 38 * of data from the I2C master are handled by the driver through internal interrupt routine, reducing application 39 * involvement to maintain the I2C buffer. 40 * 41 * \section subsection_ezi2c_features Features 42 * * EZI2C Slave functionality 43 * * Configurable standard data rates of 100/400/1000 kbps - \ref cyhal_ezi2c_data_rate_t 44 * * Supports one or two addresses with independent memory buffers - \ref cyhal_ezi2c_cfg_t 45 * * Memory buffers provide configurable read/write and read only regions - \ref cyhal_ezi2c_cfg_t 46 * * 8 or 16-bit sub-addressing - \ref cyhal_ezi2c_sub_addr_size_t 47 * * Configurable interrupt and callback assignment from EZI2C events - \ref cyhal_ezi2c_event_t 48 * 49 * \section section_ezi2c_quickstart Quick Start 50 * Initialize EZI2C by using \ref cyhal_ezi2c_init and selecting the <b>sda</b> and <b>scl</b> pins. 51 * Setup one or two memory buffers and read/write boundaries using the EZI2C configuration 52 * structure \ref cyhal_ezi2c_cfg_t. 53 * See \ref subsection_ezi2c_snippet_1 54 * \note The clock parameter <b>clk</b> is optional and can be set to NULL to generate and use an 55 * available clock resource. 56 * 57 * \section section_ezi2c_snippets Code snippets 58 * 59 * \subsection subsection_ezi2c_snippet_1 Snippet 1: EZI2C Initialization and Configuration 60 * The following snippet shows how to initialize and configure an EZI2C and assign the pins to the <b>sda</b> and <b>scl</b> lines. 61 * The <b>clk</b> need not be provided (NULL), in which case a clock resource is assigned. 62 * 63 * \snippet hal_ezi2c.c snippet_cyhal_ezi2c_init 64 * 65 * \subsection subsection_ezi2c_snippet_2 Snippet 2: Register Callback function 66 * The following snippet shows how to use the \ref cyhal_ezi2c_register_callback function. The <b>callback</b> parameter 67 * refers to the handler which will be invoked when an event triggers. 68 * 69 * \snippet hal_ezi2c.c snippet_cyhal_ezi2c_handler 70 */ 71 72 #pragma once 73 74 #include <stdint.h> 75 #include <stdbool.h> 76 #include "cy_result.h" 77 #include "cyhal_hw_types.h" 78 79 #if defined(__cplusplus) 80 extern "C" { 81 #endif 82 83 /** \addtogroup group_hal_results_ezi2c EZI2C HAL Results 84 * EZI2C specific return codes 85 * \ingroup group_hal_results 86 * \{ *//** 87 */ 88 89 /** The requested resource type is invalid */ 90 #define CYHAL_EZI2C_RSLT_ERR_INVALID_PIN \ 91 (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_EZI2C, 0)) 92 /** Can not reach desired data rate */ 93 #define CYHAL_EZI2C_RSLT_ERR_CAN_NOT_REACH_DR \ 94 (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_EZI2C, 1)) 95 /** Number of addresses is not valid */ 96 #define CYHAL_EZI2C_RSLT_ERR_NUM_ADDR_NOT_VALID \ 97 (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_EZI2C, 2)) 98 /** Number of addresses is not valid */ 99 #define CYHAL_EZI2C_RSLT_ERR_CHECK_USER_CONFIG \ 100 (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_EZI2C, 3)) 101 102 /** 103 * \} 104 */ 105 106 /** CYHAL_EZI2C_EVENT_NONE event is deprecated and that CYHAL_EZI2C_STATUS_OK should be used instead */ 107 #define CYHAL_EZI2C_EVENT_NONE CYHAL_EZI2C_STATUS_OK 108 109 /** Size of Sub-Address */ 110 typedef enum 111 { 112 CYHAL_EZI2C_SUB_ADDR8_BITS, /**< Sub-address is 8 bits */ 113 CYHAL_EZI2C_SUB_ADDR16_BITS /**< Sub-address is 16 bits */ 114 } cyhal_ezi2c_sub_addr_size_t; 115 116 /** Data rate of the slave */ 117 typedef enum 118 { 119 CYHAL_EZI2C_DATA_RATE_100KHZ = 100000, 120 CYHAL_EZI2C_DATA_RATE_400KHZ = 400000, 121 CYHAL_EZI2C_DATA_RATE_1MHZ = 1000000 122 } cyhal_ezi2c_data_rate_t; 123 124 /** Return codes of ezi2c */ 125 typedef enum 126 { 127 /** Each EZI2C slave status is encoded in a separate bit, therefore multiple bits may be set to indicate the current status */ 128 CYHAL_EZI2C_STATUS_OK = 0x1UL, /**< Operation completed successfully */ 129 CYHAL_EZI2C_STATUS_READ1 = 0x2UL, /**< The Read transfer intended for the primary slave address is complete */ 130 CYHAL_EZI2C_STATUS_WRITE1 = 0x4UL, /**< The Write transfer intended for the primary slave address is complete */ 131 CYHAL_EZI2C_STATUS_READ2 = 0x8UL, /**< The Read transfer intended for the secondary slave address is complete */ 132 CYHAL_EZI2C_STATUS_WRITE2 = 0x10UL, /**< The Write transfer intended for the secondary slave address is complete */ 133 CYHAL_EZI2C_STATUS_BUSY = 0x20UL, /**< A transfer intended for the primary address or secondary address is in progress */ 134 CYHAL_EZI2C_STATUS_ERR = 0x40UL /**< An error occurred during a transfer intended for the primary or secondary slave address */ 135 136 } cyhal_ezi2c_status_t; 137 138 /** This type is deprecated and that cyhal_ezi2c_status_t should be used instead */ 139 typedef cyhal_ezi2c_status_t cyhal_ezi2c_event_t; 140 141 /** Handler for I2C events */ 142 typedef void (*cyhal_ezi2c_event_callback_t)(void *callback_arg, cyhal_ezi2c_status_t event); 143 144 /** Initial EZI2C sub configuration */ 145 typedef struct 146 { 147 /** The 7-bit right justified primary slave address */ 148 uint8_t slave_address; 149 /** A pointer to the data buffer for the primary/secondary slave address */ 150 uint8_t *buf; 151 /** The size of the buffer assigned to the primary/secondary slave address */ 152 uint32_t buf_size; 153 /** The Read/Write boundary within the buffer assigned to the primary/secondary slave address. 154 * This specifies the number of data bytes from the beginning of the buffer with 155 * read and write access for the master. Data bytes at this value or greater are read 156 * only by the master */ 157 uint32_t buf_rw_boundary; 158 } cyhal_ezi2c_slave_cfg_t; 159 160 /** Initial EZI2C configuration */ 161 typedef struct 162 { 163 /** Number of addresses (one or two). If set "true" - use two addresses otherwise ("false") one */ 164 bool two_addresses; 165 /** When set, the slave will wake the device from Deep Sleep on an address match */ 166 bool enable_wake_from_sleep; 167 /** Maximum frequency that the I2C Slave bus runs at. Supports standard data rates of 100/400/1000 kbps */ 168 cyhal_ezi2c_data_rate_t data_rate; 169 /** Refer to cyhal_ezi2c_slave_cfg_t for details. This config structure is mandatory. */ 170 cyhal_ezi2c_slave_cfg_t slave1_cfg; 171 /** Refer to cyhal_ezi2c_slave_cfg_t for details. This config structure is optional. */ 172 /** Set it if user want to use dual-port addressing otherwise leave blank */ 173 cyhal_ezi2c_slave_cfg_t slave2_cfg; 174 /** The size of the sub-address, can either be 8 or 16 bits */ 175 cyhal_ezi2c_sub_addr_size_t sub_address_size; 176 } cyhal_ezi2c_cfg_t; 177 178 179 /** Initialize the EZI2C (slave), and configures its specified pins and clock. 180 * See \ref subsection_ezi2c_snippet_1 181 * 182 * @param[out] obj Pointer to an EZI2C object. The caller must allocate the memory 183 * for this object but the init function will initialize its contents. 184 * @param[in] sda The sda pin 185 * @param[in] scl The scl pin 186 * @param[in] clk The clock to use can be shared, if NULL a new clock will be allocated 187 * @param[in] cfg The ezi2c configuration (refer to cyhal_ezi2c_cfg_t for details) 188 * @return The status of the init request 189 */ 190 cy_rslt_t cyhal_ezi2c_init(cyhal_ezi2c_t *obj, cyhal_gpio_t sda, cyhal_gpio_t scl, const cyhal_clock_t *clk, const cyhal_ezi2c_cfg_t *cfg); 191 192 /** Deinitialize the ezi2c object 193 * 194 * @param[in,out] obj The ezi2c object 195 */ 196 void cyhal_ezi2c_free(cyhal_ezi2c_t *obj); 197 198 /** 199 * EZI2C slave get activity status 200 * This function returns a non-zero value ( \ref cyhal_ezi2c_status_t) if an I2C Read or Write 201 * cycle has occurred since the last time this function was called. 202 * See \ref subsection_ezi2c_snippet_2 203 * 204 * @param[in] obj The EZI2C object 205 * 206 * @return The status of the EZI2C (see cyhal_ezi2c_status_t for details) 207 */ 208 cyhal_ezi2c_status_t cyhal_ezi2c_get_activity_status(cyhal_ezi2c_t *obj); 209 210 /** Register a EZI2C event callback handler 211 * 212 * See \ref subsection_ezi2c_snippet_2 213 * 214 * @param[in] obj The EZI2C object 215 * @param[in] callback The callback handler which will be invoked when an event triggers 216 * @param[in] callback_arg Generic argument that will be provided to the callback when called 217 */ 218 void cyhal_ezi2c_register_callback(cyhal_ezi2c_t *obj, cyhal_ezi2c_event_callback_t callback, void *callback_arg); 219 220 /** Configure and Enable or Disable EZI2C Interrupt. 221 * 222 * @param[in] obj The EZI2C object 223 * @param[in] event The EZI2C event type 224 * @param[in] intr_priority The priority for NVIC interrupt events 225 * @param[in] enable True to turn on interrupts, False to turn off 226 */ 227 void cyhal_ezi2c_enable_event(cyhal_ezi2c_t *obj, cyhal_ezi2c_status_t event, uint8_t intr_priority, bool enable); 228 229 /** Initialize the EZI2C peripheral using a configurator generated configuration struct and set up slave address(es) data. 230 * 231 * @param[in] obj The EZI2C peripheral to configure 232 * @param[in] cfg Configuration structure generated by a configurator. 233 * @param[in] slave1_cfg Primary slave address configuration 234 * @param[in] slave2_cfg Secondary slave address configuration (can be NULL) 235 * @return The status of the operation 236 */ 237 cy_rslt_t cyhal_ezi2c_init_cfg(cyhal_ezi2c_t *obj, const cyhal_ezi2c_configurator_t *cfg, const cyhal_ezi2c_slave_cfg_t *slave1_cfg, const cyhal_ezi2c_slave_cfg_t *slave2_cfg); 238 239 #if defined(__cplusplus) 240 } 241 #endif 242 243 /** \} group_hal_ezi2c */ 244