From a311b041ed1d169eb5e08d7a22b8b2a9c7231bbd Mon Sep 17 00:00:00 2001 From: cfif Date: Fri, 24 Jan 2025 13:22:32 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9F=D0=B5=D1=80=D0=B5=D0=BD=D0=BE=D1=81=20?= =?UTF-8?q?=D0=BD=D0=B0=20=D0=BD=D0=BE=D0=B2=D1=83=D1=8E=20=D0=BE=D1=80?= =?UTF-8?q?=D0=B3=D0=B0=D0=BD=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D1=8E=20GONEC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- i2c_application.c | 2210 +++++++++++++++++++++++++++++++++++++++++++++ i2c_application.h | 181 ++++ i2c_smbus.c | 208 +++++ i2c_smbus.h | 10 + modular.json | 10 + 5 files changed, 2619 insertions(+) create mode 100644 i2c_application.c create mode 100644 i2c_application.h create mode 100644 i2c_smbus.c create mode 100644 i2c_smbus.h create mode 100644 modular.json diff --git a/i2c_application.c b/i2c_application.c new file mode 100644 index 0000000..8e080af --- /dev/null +++ b/i2c_application.c @@ -0,0 +1,2210 @@ +/** + ************************************************************************** + * @file i2c_application.c + * @version v2.0.4 + * @date 2021-12-31 + * @brief the driver library of the i2c peripheral + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +#include "i2c_application.h" + +/** + * @brief get the dma transfer direction flag through the channel + */ +#define DMA_GET_REQUEST(DMA_CHANNEL) \ +(((uint32_t)(DMA_CHANNEL) == ((uint32_t)hi2c->dma_tx_channel)) ? I2C_DMA_REQUEST_TX : I2C_DMA_REQUEST_RX) + +/** + * @brief get the dma transfer complete flag through the channel + */ +#define DMA_GET_TC_FLAG(DMA_CHANNEL) \ +(((uint32_t)(DMA_CHANNEL) == ((uint32_t)DMA1_CHANNEL1))? DMA1_FDT1_FLAG : \ + ((uint32_t)(DMA_CHANNEL) == ((uint32_t)DMA1_CHANNEL2))? DMA1_FDT2_FLAG : \ + ((uint32_t)(DMA_CHANNEL) == ((uint32_t)DMA1_CHANNEL3))? DMA1_FDT3_FLAG : \ + ((uint32_t)(DMA_CHANNEL) == ((uint32_t)DMA1_CHANNEL4))? DMA1_FDT4_FLAG : \ + ((uint32_t)(DMA_CHANNEL) == ((uint32_t)DMA1_CHANNEL5))? DMA1_FDT5_FLAG : \ + ((uint32_t)(DMA_CHANNEL) == ((uint32_t)DMA1_CHANNEL6))? DMA1_FDT6_FLAG : \ + ((uint32_t)(DMA_CHANNEL) == ((uint32_t)DMA1_CHANNEL7))? DMA1_FDT7_FLAG : \ + ((uint32_t)(DMA_CHANNEL) == ((uint32_t)DMA2_CHANNEL1))? DMA2_FDT1_FLAG : \ + ((uint32_t)(DMA_CHANNEL) == ((uint32_t)DMA2_CHANNEL2))? DMA2_FDT2_FLAG : \ + ((uint32_t)(DMA_CHANNEL) == ((uint32_t)DMA2_CHANNEL3))? DMA2_FDT3_FLAG : \ + ((uint32_t)(DMA_CHANNEL) == ((uint32_t)DMA2_CHANNEL4))? DMA2_FDT4_FLAG : \ + ((uint32_t)(DMA_CHANNEL) == ((uint32_t)DMA2_CHANNEL5))? DMA2_FDT5_FLAG : \ + ((uint32_t)(DMA_CHANNEL) == ((uint32_t)DMA2_CHANNEL6))? DMA2_FDT6_FLAG : \ + DMA2_FDT7_FLAG) + +/** + * @brief get the dma half transfer flag through the channel + */ +#define DMA_GET_HT_FLAG(DMA_CHANNEL) \ +(((uint32_t)(DMA_CHANNEL) == ((uint32_t)DMA1_CHANNEL1))? DMA1_HDT1_FLAG : \ + ((uint32_t)(DMA_CHANNEL) == ((uint32_t)DMA1_CHANNEL2))? DMA1_HDT2_FLAG : \ + ((uint32_t)(DMA_CHANNEL) == ((uint32_t)DMA1_CHANNEL3))? DMA1_HDT3_FLAG : \ + ((uint32_t)(DMA_CHANNEL) == ((uint32_t)DMA1_CHANNEL4))? DMA1_HDT4_FLAG : \ + ((uint32_t)(DMA_CHANNEL) == ((uint32_t)DMA1_CHANNEL5))? DMA1_HDT5_FLAG : \ + ((uint32_t)(DMA_CHANNEL) == ((uint32_t)DMA1_CHANNEL6))? DMA1_HDT6_FLAG : \ + ((uint32_t)(DMA_CHANNEL) == ((uint32_t)DMA1_CHANNEL7))? DMA1_HDT7_FLAG : \ + ((uint32_t)(DMA_CHANNEL) == ((uint32_t)DMA2_CHANNEL1))? DMA2_HDT1_FLAG : \ + ((uint32_t)(DMA_CHANNEL) == ((uint32_t)DMA2_CHANNEL2))? DMA2_HDT2_FLAG : \ + ((uint32_t)(DMA_CHANNEL) == ((uint32_t)DMA2_CHANNEL3))? DMA2_HDT3_FLAG : \ + ((uint32_t)(DMA_CHANNEL) == ((uint32_t)DMA2_CHANNEL4))? DMA2_HDT4_FLAG : \ + ((uint32_t)(DMA_CHANNEL) == ((uint32_t)DMA2_CHANNEL5))? DMA2_HDT5_FLAG : \ + ((uint32_t)(DMA_CHANNEL) == ((uint32_t)DMA2_CHANNEL6))? DMA2_HDT6_FLAG : \ + DMA2_HDT7_FLAG) + +/** + * @brief get the dma transfer error flag through the channel + */ +#define DMA_GET_TERR_FLAG(DMA_CHANNEL) \ +(((uint32_t)(DMA_CHANNEL) == ((uint32_t)DMA1_CHANNEL1))? DMA1_DTERR1_FLAG : \ + ((uint32_t)(DMA_CHANNEL) == ((uint32_t)DMA1_CHANNEL2))? DMA1_DTERR2_FLAG : \ + ((uint32_t)(DMA_CHANNEL) == ((uint32_t)DMA1_CHANNEL3))? DMA1_DTERR3_FLAG : \ + ((uint32_t)(DMA_CHANNEL) == ((uint32_t)DMA1_CHANNEL4))? DMA1_DTERR4_FLAG : \ + ((uint32_t)(DMA_CHANNEL) == ((uint32_t)DMA1_CHANNEL5))? DMA1_DTERR5_FLAG : \ + ((uint32_t)(DMA_CHANNEL) == ((uint32_t)DMA1_CHANNEL6))? DMA1_DTERR6_FLAG : \ + ((uint32_t)(DMA_CHANNEL) == ((uint32_t)DMA1_CHANNEL7))? DMA1_DTERR7_FLAG : \ + ((uint32_t)(DMA_CHANNEL) == ((uint32_t)DMA2_CHANNEL1))? DMA2_DTERR1_FLAG : \ + ((uint32_t)(DMA_CHANNEL) == ((uint32_t)DMA2_CHANNEL2))? DMA2_DTERR2_FLAG : \ + ((uint32_t)(DMA_CHANNEL) == ((uint32_t)DMA2_CHANNEL3))? DMA2_DTERR3_FLAG : \ + ((uint32_t)(DMA_CHANNEL) == ((uint32_t)DMA2_CHANNEL4))? DMA2_DTERR4_FLAG : \ + ((uint32_t)(DMA_CHANNEL) == ((uint32_t)DMA2_CHANNEL5))? DMA2_DTERR5_FLAG : \ + ((uint32_t)(DMA_CHANNEL) == ((uint32_t)DMA2_CHANNEL6))? DMA2_DTERR6_FLAG : \ + DMA2_DTERR7_FLAG) + +/** + * @brief i2c transmission status + */ +#define I2C_START 0 +#define I2C_END 1 + +/** + * @brief i2c peripheral initialization. + * @param hi2c: the handle points to the operation information. + * @retval none. + */ +void i2c_config(i2c_handle_type* hi2c) +{ + /* reset i2c peripheral */ + i2c_reset(hi2c->i2cx); + + /* i2c peripheral initialization */ + i2c_lowlevel_init(hi2c); + + /* i2c peripheral enable */ + i2c_enable(hi2c->i2cx, TRUE); +} + +/** + * @brief refresh i2c register. + * @param hi2c: the handle points to the operation information. + * @retval none. + */ +void i2c_refresh_txdt_register(i2c_handle_type* hi2c) +{ + /* clear tdis flag */ + if (i2c_flag_get(hi2c->i2cx, I2C_TDIS_FLAG) != RESET) + { + hi2c->i2cx->txdt = 0x00; + } + + /* refresh txdt register*/ + if (i2c_flag_get(hi2c->i2cx, I2C_TDBE_FLAG) == RESET) + { + hi2c->i2cx->sts_bit.tdbe = 1; + } +} + +/** + * @brief reset ctrl2 register. + * @param hi2c: the handle points to the operation information. + * @retval none. + */ +void i2c_reset_ctrl2_register(i2c_handle_type* hi2c) +{ + hi2c->i2cx->ctrl2_bit.saddr = 0; + hi2c->i2cx->ctrl2_bit.readh10 = 0; + hi2c->i2cx->ctrl2_bit.cnt = 0; + hi2c->i2cx->ctrl2_bit.rlden = 0; + hi2c->i2cx->ctrl2_bit.dir = 0; +} + +/** + * @brief wait for the transfer to end. + * @param hi2c: the handle points to the operation information. + * @param timeout: maximum waiting time. + * @retval i2c status. + */ +i2c_status_type i2c_wait_end(i2c_handle_type* hi2c, uint32_t timeout) +{ + while(hi2c->status != I2C_END) + { + /* check timeout */ + if((timeout--) == 0) + { + return I2C_ERR_TIMEOUT; + } + } + + if(hi2c->error_code != I2C_OK) + { + return hi2c->error_code; + } + + return I2C_OK; +} + +/** + * @brief wait for the flag. + * @param hi2c: the handle points to the operation information. + * @param flag: flag to wait. + * @param status: status to wait. + * @param event_check: flag to check while waiting for the flag. + * parameter as following values: + * - I2C_EVENT_CHECK_NONE + * - I2C_EVENT_CHECK_ACKFAIL + * - I2C_EVENT_CHECK_STOP + * @param timeout: maximum waiting time. + * @retval i2c status. + */ +i2c_status_type i2c_wait_flag(i2c_handle_type* hi2c, uint32_t Flag, flag_status Status, uint32_t event_check, uint32_t timeout) +{ + while(i2c_flag_get(hi2c->i2cx, Flag) == Status) + { + /* check the ack fail flag */ + if(event_check & I2C_EVENT_CHECK_ACKFAIL) + { + if(hi2c->i2cx->sts & I2C_ACKFAIL_FLAG) + { + /* clear ack fail flag */ + i2c_flag_clear(hi2c->i2cx, I2C_ACKFAIL_FLAG); + + hi2c->error_code = I2C_ERR_ACKFAIL; + + return I2C_ERR_ACKFAIL; + } + } + + /* check the stop flag */ + if(event_check & I2C_EVENT_CHECK_STOP) + { + if(hi2c->i2cx->sts & I2C_STOPF_FLAG) + { + /* clear stop flag */ + i2c_flag_clear(hi2c->i2cx, I2C_STOPF_FLAG); + + i2c_reset_ctrl2_register(hi2c); + + hi2c->error_code = I2C_ERR_STOP; + + return I2C_ERR_STOP; + } + } + + /* check timeout */ + if((timeout--) == 0) + { + hi2c->error_code = I2C_ERR_TIMEOUT; + + return I2C_ERR_TIMEOUT; + } + } + + return I2C_OK; +} + +/** + * @brief dma transfer cofiguration. + * @param hi2c: the handle points to the operation information. + * @param dma_channelx: dma channel to be cofigured. + * @param pdata: data buffer. + * @param size: data size. + * @retval none. + */ +void i2c_dma_config(i2c_handle_type* hi2c, dma_channel_type* dma_channel, uint8_t* pdata, uint16_t size) +{ + /* disable the dma channel */ + dma_channel_enable(dma_channel, FALSE); + + /* disable the transfer complete interrupt */ + dma_interrupt_enable(dma_channel, DMA_FDT_INT, FALSE); + + /* configure the dma channel with the buffer address and the buffer size */ + hi2c->dma_init_struct.memory_base_addr = (uint32_t)pdata; + hi2c->dma_init_struct.direction = (dma_channel == hi2c->dma_tx_channel) ? DMA_DIR_MEMORY_TO_PERIPHERAL : DMA_DIR_PERIPHERAL_TO_MEMORY; + hi2c->dma_init_struct.peripheral_base_addr = (dma_channel == hi2c->dma_tx_channel) ? (uint32_t)&hi2c->i2cx->txdt : (uint32_t)&hi2c->i2cx->rxdt; + hi2c->dma_init_struct.buffer_size = (uint32_t)size; + dma_init(dma_channel, &hi2c->dma_init_struct); + + /* enable the transfer complete interrupt */ + dma_interrupt_enable(dma_channel, DMA_FDT_INT, TRUE); + + /* enable the dma channel */ + dma_channel_enable(dma_channel, TRUE); +} + +/** + * @brief start transfer in poll mode or interrupt mode. + * @param hi2c: the handle points to the operation information. + * @param address: slave address. + * @param start_stop: config gen start condition mode. + * parameter as following values: + * - I2C_WITHOUT_START: transfer data without start condition. + * - I2C_GEN_START_READ: read data and generate start. + * - I2C_GEN_START_WRITE: send data and generate start. + * @retval i2c status. + */ +void i2c_start_transfer(i2c_handle_type* hi2c, uint16_t address, i2c_start_stop_mode_type start_stop) +{ + if (hi2c->pcount > MAX_TRANSFER_CNT) + { + hi2c->psize = MAX_TRANSFER_CNT; + + i2c_transmit_set(hi2c->i2cx, address, hi2c->psize, I2C_RELOAD_MODE, start_stop); + } + else + { + hi2c->psize = hi2c->pcount; + + i2c_transmit_set(hi2c->i2cx, address, hi2c->psize, I2C_AUTO_STOP_MODE, start_stop); + } +} + +/** + * @brief start transfer in dma mode. + * @param hi2c: the handle points to the operation information. + * @param address: slave address. + * @param start_stop: config gen start condition mode. + * parameter as following values: + * - I2C_WITHOUT_START: transfer data without start condition. + * - I2C_GEN_START_READ: read data and generate start. + * - I2C_GEN_START_WRITE: send data and generate start. + * @retval i2c status. + */ +void i2c_start_transfer_dma(i2c_handle_type* hi2c, dma_channel_type* dma_channelx, uint16_t address, i2c_start_stop_mode_type start_stop) +{ + if (hi2c->pcount > MAX_TRANSFER_CNT) + { + hi2c->psize = MAX_TRANSFER_CNT; + + /* config dma */ + i2c_dma_config(hi2c, dma_channelx, hi2c->pbuff, hi2c->psize); + + i2c_transmit_set(hi2c->i2cx, address, hi2c->psize, I2C_RELOAD_MODE, start_stop); + } + else + { + hi2c->psize = hi2c->pcount; + + /* config dma */ + i2c_dma_config(hi2c, dma_channelx, hi2c->pbuff, hi2c->psize); + + i2c_transmit_set(hi2c->i2cx, address, hi2c->psize, I2C_AUTO_STOP_MODE, start_stop); + } +} + +/** + * @brief the master transmits data through polling mode. + * @param hi2c: the handle points to the operation information. + * @param address: slave address. + * @param pdata: data buffer. + * @param size: data size. + * @param timeout: maximum waiting time. + * @retval i2c status. + */ +i2c_status_type i2c_master_transmit(i2c_handle_type* hi2c, uint16_t address, uint8_t* pdata, uint16_t size, uint32_t timeout) +{ + /* initialization parameters */ + hi2c->pbuff = pdata; + hi2c->pcount = size; + + hi2c->error_code = I2C_OK; + + /* wait for the busy falg to be reset */ + if (i2c_wait_flag(hi2c, I2C_BUSYF_FLAG, SET, I2C_EVENT_CHECK_NONE, timeout) != I2C_OK) + { + return I2C_ERR_STEP_1; + } + + /* start transfer */ + i2c_start_transfer(hi2c, address, I2C_GEN_START_WRITE); + + while (hi2c->pcount > 0) + { + /* wait for the tdis falg to be set */ + if(i2c_wait_flag(hi2c, I2C_TDIS_FLAG, RESET, I2C_EVENT_CHECK_ACKFAIL, timeout) != I2C_OK) + { + return I2C_ERR_STEP_2; + } + + /* send data */ + i2c_data_send(hi2c->i2cx, *hi2c->pbuff++); + hi2c->psize--; + hi2c->pcount--; + + if ((hi2c->psize == 0) && (hi2c->pcount != 0)) + { + /* wait for the tcrld falg to be set */ + if (i2c_wait_flag(hi2c, I2C_TCRLD_FLAG, RESET, I2C_EVENT_CHECK_ACKFAIL, timeout) != I2C_OK) + { + return I2C_ERR_STEP_3; + } + + /* continue transfer */ + i2c_start_transfer(hi2c, address, I2C_WITHOUT_START); + } + } + + /* wait for the stop falg to be set */ + if(i2c_wait_flag(hi2c, I2C_STOPF_FLAG, RESET, I2C_EVENT_CHECK_ACKFAIL, timeout) != I2C_OK) + { + return I2C_ERR_STEP_4; + } + + /* clear stop flag */ + i2c_flag_clear(hi2c->i2cx, I2C_STOPF_FLAG); + + /* reset ctrl2 register */ + i2c_reset_ctrl2_register(hi2c); + + return I2C_OK; +} + +/** + * @brief the slave receive data through polling mode. + * @param hi2c: the handle points to the operation information. + * @param pdata: data buffer. + * @param size: data size. + * @param timeout: maximum waiting time. + * @retval i2c status. + */ +i2c_status_type i2c_slave_receive(i2c_handle_type* hi2c, uint8_t* pdata, uint16_t size, uint32_t timeout) +{ + /* initialization parameters */ + hi2c->pbuff = pdata; + hi2c->pcount = size; + + hi2c->error_code = I2C_OK; + + /* wait for the busy falg to be reset */ + if(i2c_wait_flag(hi2c, I2C_BUSYF_FLAG, SET, I2C_EVENT_CHECK_NONE, timeout) != I2C_OK) + { + return I2C_ERR_STEP_1; + } + + /* enable acknowledge */ + i2c_ack_enable(hi2c->i2cx, TRUE); + + /* wait for the addr falg to be set */ + if (i2c_wait_flag(hi2c, I2C_ADDRF_FLAG, RESET, I2C_EVENT_CHECK_NONE, timeout) != I2C_OK) + { + return I2C_ERR_STEP_2; + } + + /* clear addr flag */ + i2c_flag_clear(hi2c->i2cx, I2C_ADDRF_FLAG); + + /* wait for the dir falg to be reset */ + if (i2c_wait_flag(hi2c, I2C_SDIR_FLAG, SET, I2C_EVENT_CHECK_NONE, timeout) != I2C_OK) + { + /* disable acknowledge */ + i2c_ack_enable(hi2c->i2cx, FALSE); + + return I2C_ERR_STEP_3; + } + + while (hi2c->pcount > 0) + { + /* wait for the rdbf falg to be set */ + if(i2c_wait_flag(hi2c, I2C_RDBF_FLAG, RESET, I2C_EVENT_CHECK_STOP, timeout) != I2C_OK) + { + /* disable acknowledge */ + i2c_ack_enable(hi2c->i2cx, FALSE); + + /* if data is received, read data */ + if (i2c_flag_get(hi2c->i2cx, I2C_RDBF_FLAG) == SET) + { + /* read data */ + (*hi2c->pbuff++) = i2c_data_receive(hi2c->i2cx); + hi2c->pcount--; + } + + return I2C_ERR_STEP_4; + } + + /* read data */ + (*hi2c->pbuff++) = i2c_data_receive(hi2c->i2cx); + hi2c->pcount--; + } + + /* wait for the stop falg to be set */ + if(i2c_wait_flag(hi2c, I2C_STOPF_FLAG, RESET, I2C_EVENT_CHECK_NONE, timeout) != I2C_OK) + { + /* disable acknowledge */ + i2c_ack_enable(hi2c->i2cx, FALSE); + + return I2C_ERR_STEP_5; + } + + /* clear stop flag */ + i2c_flag_clear(hi2c->i2cx, I2C_STOPF_FLAG); + + /* wait for the busy falg to be reset */ + if (i2c_wait_flag(hi2c, I2C_BUSYF_FLAG, SET, I2C_EVENT_CHECK_NONE, timeout) != I2C_OK) + { + /* disable acknowledge */ + i2c_ack_enable(hi2c->i2cx, FALSE); + + return I2C_ERR_STEP_6; + } + + return I2C_OK; +} + +/** + * @brief the master receive data through polling mode. + * @param hi2c: the handle points to the operation information. + * @param address: slave address. + * @param pdata: data buffer. + * @param size: data size. + * @param timeout: maximum waiting time. + * @retval i2c status. + */ +i2c_status_type i2c_master_receive(i2c_handle_type* hi2c, uint16_t address, uint8_t* pdata, uint16_t size, uint32_t timeout) +{ + /* initialization parameters */ + hi2c->pbuff = pdata; + hi2c->pcount = size; + + hi2c->error_code = I2C_OK; + + /* wait for the busy falg to be reset */ + if (i2c_wait_flag(hi2c, I2C_BUSYF_FLAG, SET, I2C_EVENT_CHECK_NONE, timeout) != I2C_OK) + { + return I2C_ERR_STEP_1; + } + + /* start transfer */ + i2c_start_transfer(hi2c, address, I2C_GEN_START_READ); + + while (hi2c->pcount > 0) + { + /* wait for the rdbf falg to be set */ + if(i2c_wait_flag(hi2c, I2C_RDBF_FLAG, RESET, I2C_EVENT_CHECK_ACKFAIL, timeout) != I2C_OK) + { + return I2C_ERR_STEP_2; + } + + /* read data */ + (*hi2c->pbuff++) = i2c_data_receive(hi2c->i2cx); + hi2c->pcount--; + hi2c->psize--; + + if ((hi2c->psize == 0) && (hi2c->pcount != 0)) + { + /* wait for the tcrld falg to be set */ + if (i2c_wait_flag(hi2c, I2C_TCRLD_FLAG, RESET, I2C_EVENT_CHECK_NONE, timeout) != I2C_OK) + { + return I2C_ERR_STEP_3; + } + + /* continue transfer */ + i2c_start_transfer(hi2c, address, I2C_WITHOUT_START); + } + } + + /* wait for the stop falg to be set */ + if(i2c_wait_flag(hi2c, I2C_STOPF_FLAG, RESET, I2C_EVENT_CHECK_ACKFAIL, timeout) != I2C_OK) + { + return I2C_ERR_STEP_4; + } + + /* clear stop flag */ + i2c_flag_clear(hi2c->i2cx, I2C_STOPF_FLAG); + + /* reset ctrl2 register */ + i2c_reset_ctrl2_register(hi2c); + + return I2C_OK; +} + +/** + * @brief the slave transmits data through polling mode. + * @param hi2c: the handle points to the operation information. + * @param pdata: data buffer. + * @param size: data size. + * @param timeout: maximum waiting time. + * @retval i2c status. + */ +i2c_status_type i2c_slave_transmit(i2c_handle_type* hi2c, uint8_t* pdata, uint16_t size, uint32_t timeout) +{ + /* initialization parameters */ + hi2c->pbuff = pdata; + hi2c->pcount = size; + + hi2c->error_code = I2C_OK; + + /* wait for the busy falg to be reset */ + if(i2c_wait_flag(hi2c, I2C_BUSYF_FLAG, SET, I2C_EVENT_CHECK_NONE, timeout) != I2C_OK) + { + return I2C_ERR_STEP_1; + } + + /* enable acknowledge */ + i2c_ack_enable(hi2c->i2cx, TRUE); + + /* wait for the addr falg to be set */ + if (i2c_wait_flag(hi2c, I2C_ADDRF_FLAG, RESET, I2C_EVENT_CHECK_NONE, timeout) != I2C_OK) + { + /* disable acknowledge */ + i2c_ack_enable(hi2c->i2cx, FALSE); + return I2C_ERR_STEP_2; + } + + /* clear addr flag */ + i2c_flag_clear(hi2c->i2cx, I2C_ADDRF_FLAG); + + /* if 10-bit address mode is used */ + if (hi2c->i2cx->ctrl2_bit.addr10 != RESET) + { + /* wait for the addr falg to be set */ + if (i2c_wait_flag(hi2c, I2C_ADDRF_FLAG, RESET, I2C_EVENT_CHECK_NONE, timeout) != I2C_OK) + { + /* disable acknowledge */ + i2c_ack_enable(hi2c->i2cx, FALSE); + + return I2C_ERR_STEP_3; + } + + /* clear addr flag */ + i2c_flag_clear(hi2c->i2cx, I2C_ADDRF_FLAG); + } + + /* wait for the dir falg to be set */ + if (i2c_wait_flag(hi2c, I2C_SDIR_FLAG, RESET, I2C_EVENT_CHECK_NONE, timeout) != I2C_OK) + { + /* disable acknowledge */ + i2c_ack_enable(hi2c->i2cx, FALSE); + + return I2C_ERR_STEP_4; + } + + while (hi2c->pcount > 0) + { + /* wait for the tdis falg to be set */ + if(i2c_wait_flag(hi2c, I2C_TDIS_FLAG, RESET, I2C_EVENT_CHECK_ACKFAIL, timeout) != I2C_OK) + { + /* disable acknowledge */ + i2c_ack_enable(hi2c->i2cx, FALSE); + + return I2C_ERR_STEP_5; + } + + /* send data */ + i2c_data_send(hi2c->i2cx, *hi2c->pbuff++); + hi2c->pcount--; + } + + /* wait for the ackfail falg to be set */ + if(i2c_wait_flag(hi2c, I2C_ACKFAIL_FLAG, RESET, I2C_EVENT_CHECK_NONE, timeout) != I2C_OK) + { + return I2C_ERR_STEP_6; + } + + /* clear ack fail flag */ + i2c_flag_clear(hi2c->i2cx, I2C_ACKFAIL_FLAG); + + /* wait for the stop falg to be set */ + if(i2c_wait_flag(hi2c, I2C_STOPF_FLAG, RESET, I2C_EVENT_CHECK_NONE, timeout) != I2C_OK) + { + /* disable acknowledge */ + i2c_ack_enable(hi2c->i2cx, FALSE); + + return I2C_ERR_STEP_7; + } + + /* clear stop flag */ + i2c_flag_clear(hi2c->i2cx, I2C_STOPF_FLAG); + + /* wait for the busy falg to be reset */ + if (i2c_wait_flag(hi2c, I2C_BUSYF_FLAG, SET, I2C_EVENT_CHECK_NONE, timeout) != I2C_OK) + { + /* disable acknowledge */ + i2c_ack_enable(hi2c->i2cx, FALSE); + + return I2C_ERR_STEP_8; + } + + /* refresh tx dt register */ + i2c_refresh_txdt_register(hi2c); + + return I2C_OK; +} + +/** + * @brief the master transmits data through interrupt mode. + * @param hi2c: the handle points to the operation information. + * @param address: slave address. + * @param pdata: data buffer. + * @param size: data size. + * @param timeout: maximum waiting time. + * @retval i2c status. + */ +i2c_status_type i2c_master_transmit_int(i2c_handle_type* hi2c, uint16_t address, uint8_t* pdata, uint16_t size, uint32_t timeout) +{ + /* initialization parameters */ + hi2c->mode = I2C_INT_MA_TX; + hi2c->status = I2C_START; + + hi2c->pbuff = pdata; + hi2c->pcount = size; + + hi2c->error_code = I2C_OK; + + /* wait for the busy falg to be reset */ + if (i2c_wait_flag(hi2c, I2C_BUSYF_FLAG, SET, I2C_EVENT_CHECK_NONE, timeout) != I2C_OK) + { + return I2C_ERR_STEP_1; + } + + /* start transfer */ + i2c_start_transfer(hi2c, address, I2C_GEN_START_WRITE); + + /* enable interrupt */ + i2c_interrupt_enable(hi2c->i2cx, I2C_ERR_INT | I2C_TDC_INT | I2C_STOP_INT | I2C_ACKFIAL_INT | I2C_TD_INT, TRUE); + + return I2C_OK; +} + +/** + * @brief the slave receive data through interrupt mode. + * @param hi2c: the handle points to the operation information. + * @param pdata: data buffer. + * @param size: data size. + * @param timeout: maximum waiting time. + * @retval i2c status. + */ +i2c_status_type i2c_slave_receive_int(i2c_handle_type* hi2c, uint8_t* pdata, uint16_t size, uint32_t timeout) +{ + /* initialization parameters */ + hi2c->mode = I2C_INT_SLA_RX; + hi2c->status = I2C_START; + + hi2c->pbuff = pdata; + hi2c->pcount = size; + + hi2c->error_code = I2C_OK; + + /* wait for the busy falg to be reset */ + if (i2c_wait_flag(hi2c, I2C_BUSYF_FLAG, SET, I2C_EVENT_CHECK_NONE, timeout) != I2C_OK) + { + return I2C_ERR_STEP_1; + } + + /* enable acknowledge */ + i2c_ack_enable(hi2c->i2cx, TRUE); + + /* enable interrupt */ + i2c_interrupt_enable(hi2c->i2cx, I2C_ERR_INT | I2C_TDC_INT | I2C_STOP_INT | I2C_ACKFIAL_INT | I2C_ADDR_INT | I2C_RD_INT, TRUE); + + return I2C_OK; +} + +/** + * @brief the master receive data through interrupt mode. + * @param hi2c: the handle points to the operation information. + * @param address: slave address. + * @param pdata: data buffer. + * @param size: data size. + * @param timeout: maximum waiting time. + * @retval i2c status. + */ +i2c_status_type i2c_master_receive_int(i2c_handle_type* hi2c, uint16_t address, uint8_t* pdata, uint16_t size, uint32_t timeout) +{ + /* initialization parameters */ + hi2c->mode = I2C_INT_MA_RX; + hi2c->status = I2C_START; + + hi2c->pbuff = pdata; + hi2c->pcount = size; + + hi2c->error_code = I2C_OK; + + /* wait for the busy falg to be reset */ + if (i2c_wait_flag(hi2c, I2C_BUSYF_FLAG, SET, I2C_EVENT_CHECK_NONE, timeout) != I2C_OK) + { + return I2C_ERR_STEP_1; + } + + /* start transfer */ + i2c_start_transfer(hi2c, address, I2C_GEN_START_READ); + + /* enable interrupt */ + i2c_interrupt_enable(hi2c->i2cx, I2C_ERR_INT | I2C_TDC_INT | I2C_STOP_INT | I2C_ACKFIAL_INT | I2C_RD_INT, TRUE); + + return I2C_OK; +} + +/** + * @brief the slave transmits data through interrupt mode. + * @param hi2c: the handle points to the operation information. + * @param pdata: data buffer. + * @param size: data size. + * @param timeout: maximum waiting time. + * @retval i2c status. + */ +i2c_status_type i2c_slave_transmit_int(i2c_handle_type* hi2c, uint8_t* pdata, uint16_t size, uint32_t timeout) +{ + /* initialization parameters */ + hi2c->mode = I2C_INT_SLA_TX; + hi2c->status = I2C_START; + + hi2c->pbuff = pdata; + hi2c->pcount = size; + + hi2c->error_code = I2C_OK; + + /* wait for the busy falg to be reset */ + if (i2c_wait_flag(hi2c, I2C_BUSYF_FLAG, SET, I2C_EVENT_CHECK_NONE, timeout) != I2C_OK) + { + return I2C_ERR_STEP_1; + } + + /* enable acknowledge */ + i2c_ack_enable(hi2c->i2cx, TRUE); + + /* enable interrupt */ + i2c_interrupt_enable(hi2c->i2cx, I2C_ERR_INT | I2C_TDC_INT | I2C_STOP_INT | I2C_ACKFIAL_INT | I2C_ADDR_INT | I2C_TD_INT, TRUE); + + i2c_refresh_txdt_register(hi2c); + + return I2C_OK; +} + +/** + * @brief the master transmits data through dma mode. + * @param hi2c: the handle points to the operation information. + * @param address: slave address. + * @param pdata: data buffer. + * @param size: data size. + * @param timeout: maximum waiting time. + * @retval i2c status. + */ +i2c_status_type i2c_master_transmit_dma(i2c_handle_type* hi2c, uint16_t address, uint8_t* pdata, uint16_t size, uint32_t timeout) +{ + /* initialization parameters */ + hi2c->mode = I2C_DMA_MA_TX; + hi2c->status = I2C_START; + + hi2c->pbuff = pdata; + hi2c->pcount = size; + + hi2c->error_code = I2C_OK; + + /* wait for the busy falg to be reset */ + if(i2c_wait_flag(hi2c, I2C_BUSYF_FLAG, SET, I2C_EVENT_CHECK_NONE, timeout) != I2C_OK) + { + return I2C_ERR_STEP_1; + } + + /* disable dma request */ + i2c_dma_enable(hi2c->i2cx, I2C_DMA_REQUEST_TX, FALSE); + + /* start transfer */ + i2c_start_transfer_dma(hi2c, hi2c->dma_tx_channel, address, I2C_GEN_START_WRITE); + + /* enable i2c interrupt */ + i2c_interrupt_enable(hi2c->i2cx, I2C_ERR_INT | I2C_ACKFIAL_INT, TRUE); + + /* enable dma request */ + i2c_dma_enable(hi2c->i2cx, I2C_DMA_REQUEST_TX, TRUE); + + return I2C_OK; +} + +/** + * @brief the slave receive data through dma mode. + * @param hi2c: the handle points to the operation information. + * @param pdata: data buffer. + * @param size: data size. + * @param timeout: maximum waiting time. + * @retval i2c status. + */ +i2c_status_type i2c_slave_receive_dma(i2c_handle_type* hi2c, uint8_t* pdata, uint16_t size, uint32_t timeout) +{ + /* initialization parameters */ + hi2c->mode = I2C_DMA_SLA_RX; + hi2c->status = I2C_START; + + hi2c->pbuff = pdata; + hi2c->pcount = size; + + hi2c->error_code = I2C_OK; + + /* wait for the busy falg to be reset */ + if(i2c_wait_flag(hi2c, I2C_BUSYF_FLAG, SET, I2C_EVENT_CHECK_NONE, timeout) != I2C_OK) + { + return I2C_ERR_STEP_1; + } + + /* disable dma request */ + i2c_dma_enable(hi2c->i2cx, I2C_DMA_REQUEST_RX, FALSE); + + /* config dma */ + i2c_dma_config(hi2c, hi2c->dma_rx_channel, hi2c->pbuff, size); + + /* enable acknowledge */ + i2c_ack_enable(hi2c->i2cx, TRUE); + + /* enable i2c interrupt */ + i2c_interrupt_enable(hi2c->i2cx, I2C_ADDR_INT | I2C_STOP_INT | I2C_ACKFIAL_INT | I2C_ERR_INT, TRUE); + + /* enable dma request */ + i2c_dma_enable(hi2c->i2cx, I2C_DMA_REQUEST_RX, TRUE); + + return I2C_OK; +} + +/** + * @brief the master receive data through dma mode. + * @param hi2c: the handle points to the operation information. + * @param address: slave address. + * @param pdata: data buffer. + * @param size: data size. + * @param timeout: maximum waiting time. + * @retval i2c status. + */ +i2c_status_type i2c_master_receive_dma(i2c_handle_type* hi2c, uint16_t address, uint8_t* pdata, uint16_t size, uint32_t timeout) +{ + /* initialization parameters */ + hi2c->mode = I2C_DMA_MA_RX; + hi2c->status = I2C_START; + + hi2c->pbuff = pdata; + hi2c->pcount = size; + + hi2c->error_code = I2C_OK; + + /* wait for the busy falg to be reset */ + if(i2c_wait_flag(hi2c, I2C_BUSYF_FLAG, SET, I2C_EVENT_CHECK_NONE, timeout) != I2C_OK) + { + return I2C_ERR_STEP_1; + } + + /* disable dma request */ + i2c_dma_enable(hi2c->i2cx, I2C_DMA_REQUEST_RX, FALSE); + + /* start transfer */ + i2c_start_transfer_dma(hi2c, hi2c->dma_rx_channel, address, I2C_GEN_START_READ); + + /* enable i2c interrupt */ + i2c_interrupt_enable(hi2c->i2cx, I2C_ERR_INT | I2C_ACKFIAL_INT, TRUE); + + /* enable dma request */ + i2c_dma_enable(hi2c->i2cx, I2C_DMA_REQUEST_RX, TRUE); + + return I2C_OK; +} + +/** + * @brief the slave transmits data through dma mode. + * @param hi2c: the handle points to the operation information. + * @param pdata: data buffer. + * @param size: data size. + * @param timeout: maximum waiting time. + * @retval i2c status. + */ +i2c_status_type i2c_slave_transmit_dma(i2c_handle_type* hi2c, uint8_t* pdata, uint16_t size, uint32_t timeout) +{ + /* initialization parameters */ + hi2c->mode = I2C_DMA_SLA_TX; + hi2c->status = I2C_START; + + hi2c->pbuff = pdata; + hi2c->pcount = size; + + hi2c->error_code = I2C_OK; + + /* wait for the busy falg to be reset */ + if(i2c_wait_flag(hi2c, I2C_BUSYF_FLAG, SET, I2C_EVENT_CHECK_NONE, timeout) != I2C_OK) + { + return I2C_ERR_STEP_1; + } + + /* disable dma request */ + i2c_dma_enable(hi2c->i2cx, I2C_DMA_REQUEST_TX, FALSE); + + /* config dma */ + i2c_dma_config(hi2c, hi2c->dma_tx_channel, hi2c->pbuff, size); + + /* enable acknowledge */ + i2c_ack_enable(hi2c->i2cx, TRUE); + + /* enable i2c interrupt */ + i2c_interrupt_enable(hi2c->i2cx, I2C_ADDR_INT | I2C_STOP_INT | I2C_ACKFIAL_INT | I2C_ERR_INT, TRUE); + + /* enable dma request */ + i2c_dma_enable(hi2c->i2cx, I2C_DMA_REQUEST_TX, TRUE); + + return I2C_OK; +} + +/** + * @brief write data to the memory device through polling mode. + * @param hi2c: the handle points to the operation information. + * @param address: memory device address. + * @param memaddress: memory address. + * @param pdata: data buffer. + * @param size: data size. + * @param timeout: maximum waiting time. + * @retval i2c status. + */ +i2c_status_type i2c_memory_write(i2c_handle_type* hi2c, uint16_t address, uint16_t memaddress, uint8_t* pdata, uint16_t size, uint32_t timeout) +{ + /* initialization parameters */ + hi2c->pbuff = pdata; + hi2c->pcount = size + 1; + + hi2c->error_code = I2C_OK; + + /* wait for the busy falg to be reset */ + if (i2c_wait_flag(hi2c, I2C_BUSYF_FLAG, SET, I2C_EVENT_CHECK_NONE, timeout) != I2C_OK) + { + return I2C_ERR_STEP_1; + } + + /* start transfer */ + i2c_start_transfer(hi2c, address, I2C_GEN_START_WRITE); + + /* wait for the tdis falg to be set */ + if(i2c_wait_flag(hi2c, I2C_TDIS_FLAG, RESET, I2C_EVENT_CHECK_ACKFAIL, timeout) != I2C_OK) + { + return I2C_ERR_STEP_2; + } + + /* send memory address */ + i2c_data_send(hi2c->i2cx, memaddress); + + hi2c->psize--; + hi2c->pcount--; + + while (hi2c->pcount > 0) + { + /* wait for the tdis falg to be set */ + if(i2c_wait_flag(hi2c, I2C_TDIS_FLAG, RESET, I2C_EVENT_CHECK_ACKFAIL, timeout) != I2C_OK) + { + return I2C_ERR_STEP_3; + } + + /* send data */ + i2c_data_send(hi2c->i2cx, *hi2c->pbuff++); + hi2c->psize--; + hi2c->pcount--; + + if ((hi2c->psize == 0) && (hi2c->pcount != 0)) + { + /* wait for the tcrld falg to be set */ + if (i2c_wait_flag(hi2c, I2C_TCRLD_FLAG, RESET, I2C_EVENT_CHECK_ACKFAIL, timeout) != I2C_OK) + { + return I2C_ERR_STEP_4; + } + + /* continue transfer */ + i2c_start_transfer(hi2c, address, I2C_WITHOUT_START); + } + } + + /* wait for the stop falg to be set */ + if(i2c_wait_flag(hi2c, I2C_STOPF_FLAG, RESET, I2C_EVENT_CHECK_ACKFAIL, timeout) != I2C_OK) + { + return I2C_ERR_STEP_5; + } + + /* clear stop flag */ + i2c_flag_clear(hi2c->i2cx, I2C_STOPF_FLAG); + + /* reset ctrl2 register */ + i2c_reset_ctrl2_register(hi2c); + + return I2C_OK; +} + +/** + * @brief read data from memory device through polling mode. + * @param hi2c: the handle points to the operation information. + * @param address: memory device address. + * @param memaddress: memory address. + * @param pdata: data buffer. + * @param size: data size. + * @param timeout: maximum waiting time. + * @retval i2c status. + */ +i2c_status_type i2c_memory_read(i2c_handle_type* hi2c, uint16_t address, uint16_t memaddress, uint8_t* pdata, uint16_t size, uint32_t timeout) +{ + /* initialization parameters */ + hi2c->pbuff = pdata; + hi2c->pcount = size; + + hi2c->error_code = I2C_OK; + + /* wait for the busy falg to be reset */ + if(i2c_wait_flag(hi2c, I2C_BUSYF_FLAG, SET, I2C_EVENT_CHECK_NONE, timeout) != I2C_OK) + { + return I2C_ERR_STEP_1; + } + + /* start transfer */ + i2c_transmit_set(hi2c->i2cx, address, 1, I2C_SOFT_STOP_MODE, I2C_GEN_START_WRITE); + + /* wait for the tdis falg to be set */ + if(i2c_wait_flag(hi2c, I2C_TDIS_FLAG, RESET, I2C_EVENT_CHECK_ACKFAIL, timeout) != I2C_OK) + { + return I2C_ERR_STEP_2; + } + + /* send memory address */ + i2c_data_send(hi2c->i2cx, memaddress); + + /* wait for the tdc falg to be set */ + if (i2c_wait_flag(hi2c, I2C_TDC_FLAG, RESET, I2C_EVENT_CHECK_NONE, timeout) != I2C_OK) + { + return I2C_ERR_STEP_3; + } + + /* start transfer */ + i2c_start_transfer(hi2c, address, I2C_GEN_START_READ); + + while (hi2c->pcount > 0) + { + /* wait for the rdbf falg to be set */ + if (i2c_wait_flag(hi2c, I2C_RDBF_FLAG, RESET, I2C_EVENT_CHECK_ACKFAIL, timeout) != I2C_OK) + { + return I2C_ERR_STEP_4; + } + + /* read data */ + (*hi2c->pbuff++) = i2c_data_receive(hi2c->i2cx); + hi2c->pcount--; + hi2c->psize--; + + if ((hi2c->psize == 0) && (hi2c->pcount != 0)) + { + /* wait for the tcrld falg to be set */ + if (i2c_wait_flag(hi2c, I2C_TCRLD_FLAG, RESET, I2C_EVENT_CHECK_NONE, timeout) != I2C_OK) + { + return I2C_ERR_STEP_5; + } + + /* continue transfer */ + i2c_start_transfer(hi2c, address, I2C_WITHOUT_START); + } + } + + /* wait for the stop falg to be set */ + if (i2c_wait_flag(hi2c, I2C_STOPF_FLAG, RESET, I2C_EVENT_CHECK_ACKFAIL, timeout) != I2C_OK) + { + return I2C_ERR_STEP_6; + } + + /* clear stop flag */ + i2c_flag_clear(hi2c->i2cx, I2C_STOPF_FLAG); + + /* reset ctrl2 register */ + i2c_reset_ctrl2_register(hi2c); + + return I2C_OK; +} + +/** + * @brief write data to the memory device through interrupt mode. + * @param hi2c: the handle points to the operation information. + * @param address: memory device address. + * @param memaddress: memory address. + * @param pdata: data buffer. + * @param size: data size. + * @param timeout: maximum waiting time. + * @retval i2c status. + */ +i2c_status_type i2c_memory_write_int(i2c_handle_type* hi2c, uint16_t address, uint16_t memaddress, uint8_t* pdata, uint16_t size, uint32_t timeout) +{ + /* initialization parameters */ + hi2c->mode = I2C_INT_MA_TX; + hi2c->status = I2C_START; + + hi2c->pbuff = pdata; + hi2c->pcount = size + 1; + + hi2c->error_code = I2C_OK; + + /* wait for the busy falg to be reset */ + if (i2c_wait_flag(hi2c, I2C_BUSYF_FLAG, SET, I2C_EVENT_CHECK_NONE, timeout) != I2C_OK) + { + return I2C_ERR_STEP_1; + } + + /* start transfer */ + i2c_start_transfer(hi2c, address, I2C_GEN_START_WRITE); + + /* wait for the tdis falg to be set */ + if(i2c_wait_flag(hi2c, I2C_TDIS_FLAG, RESET, I2C_EVENT_CHECK_ACKFAIL, timeout) != I2C_OK) + { + return I2C_ERR_STEP_2; + } + + /* send memory address */ + i2c_data_send(hi2c->i2cx, memaddress); + hi2c->psize--; + hi2c->pcount--; + + /* enable interrupt */ + i2c_interrupt_enable(hi2c->i2cx, I2C_ERR_INT | I2C_TDC_INT | I2C_STOP_INT | I2C_ACKFIAL_INT | I2C_TD_INT, TRUE); + + return I2C_OK; +} + +/** + * @brief read data from memory device through interrupt mode. + * @param hi2c: the handle points to the operation information. + * @param address: memory device address. + * @param memaddress: memory address. + * @param pdata: data buffer. + * @param size: data size. + * @param timeout: maximum waiting time. + * @retval i2c status. + */ +i2c_status_type i2c_memory_read_int(i2c_handle_type* hi2c, uint16_t address, uint16_t memaddress, uint8_t* pdata, uint16_t size, uint32_t timeout) +{ + /* initialization parameters */ + hi2c->mode = I2C_INT_MA_RX; + hi2c->status = I2C_START; + + hi2c->pbuff = pdata; + hi2c->pcount = size; + + hi2c->error_code = I2C_OK; + + /* wait for the busy falg to be reset */ + if(i2c_wait_flag(hi2c, I2C_BUSYF_FLAG, SET, I2C_EVENT_CHECK_NONE, timeout) != I2C_OK) + { + return I2C_ERR_STEP_1; + } + + /* start transfer */ + i2c_transmit_set(hi2c->i2cx, address, 1, I2C_SOFT_STOP_MODE, I2C_GEN_START_WRITE); + + /* wait for the tdis falg to be set */ + if(i2c_wait_flag(hi2c, I2C_TDIS_FLAG, RESET, I2C_EVENT_CHECK_ACKFAIL, timeout) != I2C_OK) + { + return I2C_ERR_STEP_2; + } + + /* send memory address */ + i2c_data_send(hi2c->i2cx, memaddress); + + /* wait for the tdc falg to be set */ + if (i2c_wait_flag(hi2c, I2C_TDC_FLAG, RESET, I2C_EVENT_CHECK_NONE, timeout) != I2C_OK) + { + return I2C_ERR_STEP_3; + } + + /* start transfer */ + i2c_start_transfer(hi2c, address, I2C_GEN_START_READ); + + /* enable i2c interrupt */ + i2c_interrupt_enable(hi2c->i2cx, I2C_ERR_INT | I2C_TDC_INT | I2C_STOP_INT | I2C_ACKFIAL_INT | I2C_RD_INT, TRUE); + + return I2C_OK; +} + +/** + * @brief write data to the memory device through dma mode. + * @param hi2c: the handle points to the operation information. + * @param address: memory device address. + * @param memaddress: memory address. + * @param pdata: data buffer. + * @param size: data size. + * @param timeout: maximum waiting time. + * @retval i2c status. + */ +i2c_status_type i2c_memory_write_dma(i2c_handle_type* hi2c, uint16_t address, uint16_t memaddress, uint8_t* pdata, uint16_t size, uint32_t timeout) +{ + /* initialization parameters */ + hi2c->mode = I2C_DMA_MA_TX; + hi2c->status = I2C_START; + + hi2c->pbuff = pdata; + hi2c->pcount = size; + + hi2c->error_code = I2C_OK; + + /* disable dma request */ + i2c_dma_enable(hi2c->i2cx, I2C_DMA_REQUEST_TX, FALSE); + + /* wait for the busy falg to be reset */ + if(i2c_wait_flag(hi2c, I2C_BUSYF_FLAG, SET, I2C_EVENT_CHECK_NONE, timeout) != I2C_OK) + { + return I2C_ERR_STEP_1; + } + + /* transfer config */ + i2c_transmit_set(hi2c->i2cx, address, 1, I2C_RELOAD_MODE, I2C_GEN_START_WRITE); + + /* wait for the tdis falg to be set */ + if(i2c_wait_flag(hi2c, I2C_TDIS_FLAG, RESET, I2C_EVENT_CHECK_ACKFAIL, timeout) != I2C_OK) + { + return I2C_ERR_STEP_2; + } + + /* send memory address */ + i2c_data_send(hi2c->i2cx, memaddress); + + /* wait for the tcrld falg to be set */ + if (i2c_wait_flag(hi2c, I2C_TCRLD_FLAG, RESET, I2C_EVENT_CHECK_NONE, timeout) != I2C_OK) + { + return I2C_ERR_STEP_3; + } + + /* start transfer */ + i2c_start_transfer_dma(hi2c, hi2c->dma_tx_channel, address, I2C_WITHOUT_START); + + /* enable i2c interrupt */ + i2c_interrupt_enable(hi2c->i2cx, I2C_ERR_INT | I2C_ACKFIAL_INT, TRUE); + + /* enable dma request */ + i2c_dma_enable(hi2c->i2cx, I2C_DMA_REQUEST_TX, TRUE); + + return I2C_OK; +} + +/** + * @brief read data from memory device through polling mode. + * @param hi2c: the handle points to the operation information. + * @param address: memory device address. + * @param memaddress: memory address. + * @param pdata: data buffer. + * @param size: data size. + * @param timeout: maximum waiting time. + * @retval i2c status. + */ +i2c_status_type i2c_memory_read_dma(i2c_handle_type* hi2c, uint16_t address, uint16_t memaddress, uint8_t* pdata, uint16_t size, uint32_t timeout) +{ + /* initialization parameters */ + hi2c->mode = I2C_DMA_MA_RX; + hi2c->status = I2C_START; + + hi2c->pbuff = pdata; + hi2c->pcount = size; + + hi2c->error_code = I2C_OK; + + /* wait for the busy falg to be reset */ + if(i2c_wait_flag(hi2c, I2C_BUSYF_FLAG, SET, I2C_EVENT_CHECK_NONE, timeout) != I2C_OK) + { + return I2C_ERR_STEP_1; + } + + /* start transfer */ + i2c_transmit_set(hi2c->i2cx, address, 1, I2C_SOFT_STOP_MODE, I2C_GEN_START_WRITE); + + /* wait for the tdis falg to be set */ + if(i2c_wait_flag(hi2c, I2C_TDIS_FLAG, RESET, I2C_EVENT_CHECK_ACKFAIL, timeout) != I2C_OK) + { + return I2C_ERR_STEP_2; + } + + /* send memory address */ + i2c_data_send(hi2c->i2cx, memaddress); + + /* wait for the tdc falg to be set */ + if (i2c_wait_flag(hi2c, I2C_TDC_FLAG, RESET, I2C_EVENT_CHECK_NONE, timeout) != I2C_OK) + { + return I2C_ERR_STEP_3; + } + + /* disable dma request */ + i2c_dma_enable(hi2c->i2cx, I2C_DMA_REQUEST_RX, FALSE); + + /* start transfer */ + i2c_start_transfer_dma(hi2c, hi2c->dma_rx_channel, address, I2C_GEN_START_READ); + + /* enable i2c interrupt */ + i2c_interrupt_enable(hi2c->i2cx, I2C_ERR_INT | I2C_ACKFIAL_INT, TRUE); + + /* enable dma request */ + i2c_dma_enable(hi2c->i2cx, I2C_DMA_REQUEST_RX, TRUE); + + return I2C_OK; +} + +/** + * @brief the master transmits data through SMBus mode. + * @param hi2c: the handle points to the operation information. + * @param address: slave address. + * @param pdata: data buffer. + * @param size: data size. + * @param timeout: maximum waiting time. + * @retval i2c status. + */ +i2c_status_type i2c_smbus_master_transmit(i2c_handle_type* hi2c, uint16_t address, uint8_t* pdata, uint16_t size, uint32_t timeout) +{ + /* initialization parameters */ + hi2c->pbuff = pdata; + hi2c->pcount = size; + + hi2c->error_code = I2C_OK; + + /* wait for the busy falg to be reset */ + if (i2c_wait_flag(hi2c, I2C_BUSYF_FLAG, SET, I2C_EVENT_CHECK_NONE, timeout) != I2C_OK) + { + return I2C_ERR_STEP_1; + } + + /* enable pec calculation */ + i2c_pec_calculate_enable(hi2c->i2cx, TRUE); + + /* enable pec transmit request */ + i2c_pec_transmit_enable(hi2c->i2cx, TRUE); + + /* start transfer */ + i2c_start_transfer(hi2c, address, I2C_GEN_START_WRITE); + + hi2c->pcount--; + + while (hi2c->pcount > 0) + { + /* wait for the tdis falg to be set */ + if(i2c_wait_flag(hi2c, I2C_TDIS_FLAG, RESET, I2C_EVENT_CHECK_ACKFAIL, timeout) != I2C_OK) + { + return I2C_ERR_STEP_2; + } + + /* send data */ + i2c_data_send(hi2c->i2cx, *hi2c->pbuff++); + hi2c->psize--; + hi2c->pcount--; + + if ((hi2c->psize == 0) && (hi2c->pcount != 0)) + { + /* wait for the tcrld falg to be set */ + if (i2c_wait_flag(hi2c, I2C_TCRLD_FLAG, RESET, I2C_EVENT_CHECK_ACKFAIL, timeout) != I2C_OK) + { + return I2C_ERR_STEP_3; + } + + /* continue transfer */ + i2c_start_transfer(hi2c, address, I2C_WITHOUT_START); + } + } + + /* wait for the stop falg to be set */ + if(i2c_wait_flag(hi2c, I2C_STOPF_FLAG, RESET, I2C_EVENT_CHECK_ACKFAIL, timeout) != I2C_OK) + { + return I2C_ERR_STEP_4; + } + + /* clear stop flag */ + i2c_flag_clear(hi2c->i2cx, I2C_STOPF_FLAG); + + /* reset ctrl2 register */ + i2c_reset_ctrl2_register(hi2c); + + return I2C_OK; +} + +/** + * @brief the slave receive data through SMBus mode. + * @param hi2c: the handle points to the operation information. + * @param pdata: data buffer. + * @param size: data size. + * @param timeout: maximum waiting time. + * @retval i2c status. + */ +i2c_status_type i2c_smbus_slave_receive(i2c_handle_type* hi2c, uint8_t* pdata, uint16_t size, uint32_t timeout) +{ + /* initialization parameters */ + hi2c->pbuff = pdata; + hi2c->pcount = size; + + hi2c->error_code = I2C_OK; + + /* enable pec calculation */ + i2c_pec_calculate_enable(hi2c->i2cx, TRUE); + + /* enable slave data control mode */ + i2c_slave_data_ctrl_enable(hi2c->i2cx, TRUE); + + /* enable acknowledge */ + i2c_ack_enable(hi2c->i2cx, TRUE); + + /* wait for the addr falg to be set */ + if (i2c_wait_flag(hi2c, I2C_ADDRF_FLAG, RESET, I2C_EVENT_CHECK_NONE, timeout) != I2C_OK) + { + return I2C_ERR_STEP_1; + } + + /* enable pec transmit request */ + i2c_pec_transmit_enable(hi2c->i2cx, TRUE); + + /* configure the number of bytes to be transmitted */ + i2c_cnt_set(hi2c->i2cx, hi2c->pcount); + + /* clear addr flag */ + i2c_flag_clear(hi2c->i2cx, I2C_ADDRF_FLAG); + + /* wait for the dir falg to be reset */ + if (i2c_wait_flag(hi2c, I2C_SDIR_FLAG, SET, I2C_EVENT_CHECK_NONE, timeout) != I2C_OK) + { + /* disable acknowledge */ + i2c_ack_enable(hi2c->i2cx, FALSE); + + return I2C_ERR_STEP_2; + } + + while (hi2c->pcount > 0) + { + /* wait for the rdbf falg to be set */ + if(i2c_wait_flag(hi2c, I2C_RDBF_FLAG, RESET, I2C_EVENT_CHECK_STOP, timeout) != I2C_OK) + { + /* disable acknowledge */ + i2c_ack_enable(hi2c->i2cx, FALSE); + + /* if data is received, read data */ + if (i2c_flag_get(hi2c->i2cx, I2C_RDBF_FLAG) == SET) + { + /* read data */ + (*hi2c->pbuff++) = i2c_data_receive(hi2c->i2cx); + hi2c->pcount--; + } + + return I2C_ERR_STEP_3; + } + + /* read data */ + (*hi2c->pbuff++) = i2c_data_receive(hi2c->i2cx); + hi2c->pcount--; + } + + /* wait for the stop falg to be set */ + if(i2c_wait_flag(hi2c, I2C_STOPF_FLAG, RESET, I2C_EVENT_CHECK_NONE, timeout) != I2C_OK) + { + /* disable acknowledge */ + i2c_ack_enable(hi2c->i2cx, FALSE); + + return I2C_ERR_STEP_4; + } + + /* clear stop flag */ + i2c_flag_clear(hi2c->i2cx, I2C_STOPF_FLAG); + + /* wait for the busy falg to be reset */ + if (i2c_wait_flag(hi2c, I2C_BUSYF_FLAG, SET, I2C_EVENT_CHECK_NONE, timeout) != I2C_OK) + { + /* disable acknowledge */ + i2c_ack_enable(hi2c->i2cx, FALSE); + + return I2C_ERR_STEP_5; + } + + /* disable slave data control mode */ + i2c_slave_data_ctrl_enable(hi2c->i2cx, FALSE); + + return I2C_OK; +} + +/** + * @brief the master receive data through SMBus mode. + * @param hi2c: the handle points to the operation information. + * @param address: slave address. + * @param pdata: data buffer. + * @param size: data size. + * @param timeout: maximum waiting time. + * @retval i2c status. + */ +i2c_status_type i2c_smbus_master_receive(i2c_handle_type* hi2c, uint16_t address, uint8_t* pdata, uint16_t size, uint32_t timeout) +{ + /* initialization parameters */ + hi2c->pbuff = pdata; + hi2c->pcount = size; + + hi2c->error_code = I2C_OK; + + /* wait for the busy falg to be reset */ + if (i2c_wait_flag(hi2c, I2C_BUSYF_FLAG, SET, I2C_EVENT_CHECK_NONE, timeout) != I2C_OK) + { + return I2C_ERR_STEP_1; + } + + /* enable pec calculation */ + i2c_pec_calculate_enable(hi2c->i2cx, TRUE); + + /* enable pec transmit request */ + i2c_pec_transmit_enable(hi2c->i2cx, TRUE); + + /* start transfer */ + i2c_start_transfer(hi2c, address, I2C_GEN_START_READ); + + while (hi2c->pcount > 0) + { + /* wait for the rdbf falg to be set */ + if(i2c_wait_flag(hi2c, I2C_RDBF_FLAG, RESET, I2C_EVENT_CHECK_ACKFAIL, timeout) != I2C_OK) + { + return I2C_ERR_STEP_2; + } + + /* read data */ + (*hi2c->pbuff++) = i2c_data_receive(hi2c->i2cx); + hi2c->pcount--; + hi2c->psize--; + + if ((hi2c->psize == 0) && (hi2c->pcount != 0)) + { + /* wait for the tcrld falg to be set */ + if (i2c_wait_flag(hi2c, I2C_TCRLD_FLAG, RESET, I2C_EVENT_CHECK_NONE, timeout) != I2C_OK) + { + return I2C_ERR_STEP_3; + } + + /* continue transfer */ + i2c_start_transfer(hi2c, address, I2C_WITHOUT_START); + } + } + + /* wait for the stop falg to be set */ + if(i2c_wait_flag(hi2c, I2C_STOPF_FLAG, RESET, I2C_EVENT_CHECK_ACKFAIL, timeout) != I2C_OK) + { + return I2C_ERR_STEP_4; + } + + /* clear stop flag */ + i2c_flag_clear(hi2c->i2cx, I2C_STOPF_FLAG); + + /* reset ctrl2 register */ + i2c_reset_ctrl2_register(hi2c); + + return I2C_OK; +} + +/** + * @brief the slave transmits data through SMBus mode. + * @param hi2c: the handle points to the operation information. + * @param pdata: data buffer. + * @param size: data size. + * @param timeout: maximum waiting time. + * @retval i2c status. + */ +i2c_status_type i2c_smbus_slave_transmit(i2c_handle_type* hi2c, uint8_t* pdata, uint16_t size, uint32_t timeout) +{ + /* initialization parameters */ + hi2c->pbuff = pdata; + hi2c->pcount = size; + + hi2c->error_code = I2C_OK; + + /* enable pec calculation */ + i2c_pec_calculate_enable(hi2c->i2cx, TRUE); + + /* enable slave data control mode */ + i2c_slave_data_ctrl_enable(hi2c->i2cx, TRUE); + + /* enable acknowledge */ + i2c_ack_enable(hi2c->i2cx, TRUE); + + /* wait for the addr falg to be set */ + if (i2c_wait_flag(hi2c, I2C_ADDRF_FLAG, RESET, I2C_EVENT_CHECK_NONE, timeout) != I2C_OK) + { + /* disable acknowledge */ + i2c_ack_enable(hi2c->i2cx, FALSE); + return I2C_ERR_STEP_1; + } + + /* if 7-bit address mode is selected */ + if (hi2c->i2cx->ctrl2_bit.addr10 == 0) + { + /* enable pec transmit request */ + i2c_pec_transmit_enable(hi2c->i2cx, TRUE); + + /* configure the number of bytes to be transmitted */ + i2c_cnt_set(hi2c->i2cx, hi2c->pcount); + } + + /* clear addr flag */ + i2c_flag_clear(hi2c->i2cx, I2C_ADDRF_FLAG); + + /* if 10-bit address mode is used */ + if (hi2c->i2cx->ctrl2_bit.addr10 != RESET) + { + /* wait for the addr falg to be set */ + if (i2c_wait_flag(hi2c, I2C_ADDRF_FLAG, RESET, I2C_EVENT_CHECK_NONE, timeout) != I2C_OK) + { + /* disable acknowledge */ + i2c_ack_enable(hi2c->i2cx, FALSE); + + return I2C_ERR_STEP_2; + } + + /* enable pec transmit request */ + i2c_pec_transmit_enable(hi2c->i2cx, TRUE); + + /* configure the number of bytes to be transmitted */ + i2c_cnt_set(hi2c->i2cx, hi2c->pcount); + + /* clear addr flag */ + i2c_flag_clear(hi2c->i2cx, I2C_ADDRF_FLAG); + } + + /* wait for the dir falg to be set */ + if (i2c_wait_flag(hi2c, I2C_SDIR_FLAG, RESET, I2C_EVENT_CHECK_NONE, timeout) != I2C_OK) + { + /* disable acknowledge */ + i2c_ack_enable(hi2c->i2cx, FALSE); + + return I2C_ERR_STEP_3; + } + + hi2c->pcount--; + + while (hi2c->pcount > 0) + { + /* wait for the tdis falg to be set */ + if(i2c_wait_flag(hi2c, I2C_TDIS_FLAG, RESET, I2C_EVENT_CHECK_ACKFAIL, timeout) != I2C_OK) + { + /* disable acknowledge */ + i2c_ack_enable(hi2c->i2cx, FALSE); + + return I2C_ERR_STEP_4; + } + + /* send data */ + i2c_data_send(hi2c->i2cx, *hi2c->pbuff++); + hi2c->pcount--; + } + + /* wait for the ackfail falg to be set */ + if(i2c_wait_flag(hi2c, I2C_ACKFAIL_FLAG, RESET, I2C_EVENT_CHECK_NONE, timeout) != I2C_OK) + { + return I2C_ERR_STEP_5; + } + + /* clear ack fail flag */ + i2c_flag_clear(hi2c->i2cx, I2C_ACKFAIL_FLAG); + + /* wait for the stop falg to be set */ + if(i2c_wait_flag(hi2c, I2C_STOPF_FLAG, RESET, I2C_EVENT_CHECK_NONE, timeout) != I2C_OK) + { + /* disable acknowledge */ + i2c_ack_enable(hi2c->i2cx, FALSE); + + return I2C_ERR_STEP_6; + } + + /* clear stop flag */ + i2c_flag_clear(hi2c->i2cx, I2C_STOPF_FLAG); + + /* wait for the busy falg to be reset */ + if (i2c_wait_flag(hi2c, I2C_BUSYF_FLAG, SET, I2C_EVENT_CHECK_NONE, timeout) != I2C_OK) + { + /* disable acknowledge */ + i2c_ack_enable(hi2c->i2cx, FALSE); + + return I2C_ERR_STEP_7; + } + + /* reset ctrl2 register */ + i2c_reset_ctrl2_register(hi2c); + + /* refresh tx dt register */ + i2c_refresh_txdt_register(hi2c); + + /* disable slave data control mode */ + i2c_slave_data_ctrl_enable(hi2c->i2cx, FALSE); + + return I2C_OK; +} + +/** + * @brief master interrupt processing function in interrupt mode. + * @param hi2c: the handle points to the operation information. + * @retval i2c status. + */ +i2c_status_type i2c_master_irq_handler_int(i2c_handle_type* hi2c) +{ + if (i2c_flag_get(hi2c->i2cx, I2C_ACKFAIL_FLAG) != RESET) + { + /* clear ackfail flag */ + i2c_flag_clear(hi2c->i2cx, I2C_ACKFAIL_FLAG); + + /* refresh tx register */ + i2c_refresh_txdt_register(hi2c); + + if(hi2c->pcount != 0) + { + hi2c->error_code = I2C_ERR_ACKFAIL; + } + } + else if (i2c_flag_get(hi2c->i2cx, I2C_TDIS_FLAG) != RESET) + { + /* send data */ + i2c_data_send(hi2c->i2cx, *hi2c->pbuff++); + hi2c->pcount--; + hi2c->psize--; + } + else if (i2c_flag_get(hi2c->i2cx, I2C_TCRLD_FLAG) != RESET) + { + if ((hi2c->psize == 0) && (hi2c->pcount != 0)) + { + /* continue transfer */ + i2c_start_transfer(hi2c, i2c_transfer_addr_get(hi2c->i2cx), I2C_WITHOUT_START); + } + else + { + return I2C_ERR_TCRLD; + } + } + else if (i2c_flag_get(hi2c->i2cx, I2C_RDBF_FLAG) != RESET) + { + /* read data */ + (*hi2c->pbuff++) = i2c_data_receive(hi2c->i2cx); + hi2c->pcount--; + hi2c->psize--; + } + else if (i2c_flag_get(hi2c->i2cx, I2C_TDC_FLAG) != RESET) + { + if (hi2c->pcount == 0) + { + if (hi2c->i2cx->ctrl2_bit.astopen == 0) + { + /* generate stop condtion */ + i2c_stop_generate(hi2c->i2cx); + } + } + else + { + return I2C_ERR_TDC; + } + } + else if (i2c_flag_get(hi2c->i2cx, I2C_STOPF_FLAG) != RESET) + { + /* clear stop flag */ + i2c_flag_clear(hi2c->i2cx, I2C_STOPF_FLAG); + + /* reset ctrl2 register */ + i2c_reset_ctrl2_register(hi2c); + + if (i2c_flag_get(hi2c->i2cx, I2C_ACKFAIL_FLAG) != RESET) + { + /* clear ackfail flag */ + i2c_flag_clear(hi2c->i2cx, I2C_ACKFAIL_FLAG); + } + + /* refresh tx dt register */ + i2c_refresh_txdt_register(hi2c); + + /* disable interrupts */ + i2c_interrupt_enable(hi2c->i2cx, I2C_ERR_INT | I2C_TDC_INT | I2C_STOP_INT | I2C_ACKFIAL_INT | I2C_TD_INT | I2C_RD_INT, FALSE); + + /* transfer complete */ + hi2c->status = I2C_END; + } + + return I2C_OK; +} + +/** + * @brief slave interrupt processing function in interrupt mode. + * @param hi2c: the handle points to the operation information. + * @retval i2c status. + */ +i2c_status_type i2c_slave_irq_handler_int(i2c_handle_type* hi2c) +{ + if (i2c_flag_get(hi2c->i2cx, I2C_ACKFAIL_FLAG) != RESET) + { + /* transfer complete */ + if (hi2c->pcount == 0) + { + i2c_refresh_txdt_register(hi2c); + + /* clear ackfail flag */ + i2c_flag_clear(hi2c->i2cx, I2C_ACKFAIL_FLAG); + } + /* the transfer has not been completed */ + else + { + /* clear ackfail flag */ + i2c_flag_clear(hi2c->i2cx, I2C_ACKFAIL_FLAG); + } + } + else if (i2c_flag_get(hi2c->i2cx, I2C_ADDRF_FLAG) != RESET) + { + /* clear addr flag */ + i2c_flag_clear(hi2c->i2cx, I2C_ADDRF_FLAG); + } + else if (i2c_flag_get(hi2c->i2cx, I2C_TDIS_FLAG) != RESET) + { + if (hi2c->pcount > 0) + { + /* send data */ + hi2c->i2cx->txdt = (*(hi2c->pbuff++)); + hi2c->psize--; + hi2c->pcount--; + } + } + else if (i2c_flag_get(hi2c->i2cx, I2C_RDBF_FLAG) != RESET) + { + if (hi2c->pcount > 0) + { + /* read data */ + (*hi2c->pbuff++) = i2c_data_receive(hi2c->i2cx); + hi2c->pcount--; + hi2c->psize--; + } + } + else if (i2c_flag_get(hi2c->i2cx, I2C_STOPF_FLAG) != RESET) + { + /* clear stop flag */ + i2c_flag_clear(hi2c->i2cx, I2C_STOPF_FLAG); + + /* disable interrupts */ + i2c_interrupt_enable(hi2c->i2cx, I2C_ADDR_INT | I2C_STOP_INT | I2C_ACKFIAL_INT | I2C_ERR_INT | I2C_TDC_INT | I2C_TD_INT | I2C_RD_INT, FALSE); + + /* reset ctrl2 register */ + i2c_reset_ctrl2_register(hi2c); + + /* refresh tx dt register */ + i2c_refresh_txdt_register(hi2c); + + /* if data is received, read data */ + if (i2c_flag_get(hi2c->i2cx, I2C_RDBF_FLAG) != RESET) + { + /* read data */ + (*hi2c->pbuff++) = i2c_data_receive(hi2c->i2cx); + + if ((hi2c->psize > 0)) + { + hi2c->pcount--; + hi2c->psize--; + } + } + + /* transfer complete */ + hi2c->status = I2C_END; + } + + return I2C_OK; +} + +/** + * @brief master interrupt processing function in dma mode. + * @param hi2c: the handle points to the operation information. + * @retval i2c status. + */ +i2c_status_type i2c_master_irq_handler_dma(i2c_handle_type* hi2c) +{ + if (i2c_flag_get(hi2c->i2cx, I2C_ACKFAIL_FLAG) != RESET) + { + /* clear ackfail flag */ + i2c_flag_clear(hi2c->i2cx, I2C_ACKFAIL_FLAG); + + /* enable stop interrupt to wait for stop generate stop */ + i2c_interrupt_enable(hi2c->i2cx, I2C_STOP_INT, TRUE); + + /* refresh tx dt register */ + i2c_refresh_txdt_register(hi2c); + + if(hi2c->pcount != 0) + { + hi2c->error_code = I2C_ERR_ACKFAIL; + } + } + else if (i2c_flag_get(hi2c->i2cx, I2C_TCRLD_FLAG) != RESET) + { + /* disable tdc interrupt */ + i2c_interrupt_enable(hi2c->i2cx, I2C_TDC_INT, FALSE); + + if (hi2c->pcount != 0) + { + /* continue transfer */ + i2c_start_transfer(hi2c, i2c_transfer_addr_get(hi2c->i2cx), I2C_WITHOUT_START); + + /* enable dma request */ + if (hi2c->dma_init_struct.direction == DMA_DIR_MEMORY_TO_PERIPHERAL) + { + i2c_dma_enable(hi2c->i2cx, I2C_DMA_REQUEST_TX, TRUE); + } + else + { + i2c_dma_enable(hi2c->i2cx, I2C_DMA_REQUEST_RX, TRUE); + } + } + else + { + return I2C_ERR_TCRLD; + } + } + else if (i2c_flag_get(hi2c->i2cx, I2C_STOPF_FLAG) != RESET) + { + /* clear stop flag */ + i2c_flag_clear(hi2c->i2cx, I2C_STOPF_FLAG); + + /* reset ctrl2 register */ + i2c_reset_ctrl2_register(hi2c); + + if (i2c_flag_get(hi2c->i2cx, I2C_ACKFAIL_FLAG) != RESET) + { + /* clear ackfail flag */ + i2c_flag_clear(hi2c->i2cx, I2C_ACKFAIL_FLAG); + } + + /* refresh tx dt register */ + i2c_refresh_txdt_register(hi2c); + + /* disable interrupts */ + i2c_interrupt_enable(hi2c->i2cx, I2C_ERR_INT | I2C_TDC_INT | I2C_STOP_INT | I2C_ACKFIAL_INT | I2C_TD_INT | I2C_RD_INT, FALSE); + + /* transfer complete */ + hi2c->status = I2C_END; + } + + return I2C_OK; +} + +/** + * @brief slave interrupt processing function in dma mode. + * @param hi2c: the handle points to the operation information. + * @retval i2c status. + */ +i2c_status_type i2c_slave_irq_handler_dma(i2c_handle_type* hi2c) +{ + if (i2c_flag_get(hi2c->i2cx, I2C_ACKFAIL_FLAG) != RESET) + { + /* clear ackfail flag */ + i2c_flag_clear(hi2c->i2cx, I2C_ACKFAIL_FLAG); + } + else if (i2c_flag_get(hi2c->i2cx, I2C_ADDRF_FLAG) != RESET) + { + /* clear addr flag */ + i2c_flag_clear(hi2c->i2cx, I2C_ADDRF_FLAG); + } + else if (i2c_flag_get(hi2c->i2cx, I2C_STOPF_FLAG) != RESET) + { + /* clear stop flag */ + i2c_flag_clear(hi2c->i2cx, I2C_STOPF_FLAG); + + /* disable interrupts */ + i2c_interrupt_enable(hi2c->i2cx, I2C_ADDR_INT | I2C_STOP_INT | I2C_ACKFIAL_INT | I2C_ERR_INT | I2C_TDC_INT | I2C_TD_INT | I2C_RD_INT, FALSE); + + /* reset ctrl2 register */ + i2c_reset_ctrl2_register(hi2c); + + /* refresh tx dt register */ + i2c_refresh_txdt_register(hi2c); + + /* if data is received, read data */ + if (i2c_flag_get(hi2c->i2cx, I2C_RDBF_FLAG) != RESET) + { + /* read data */ + (*hi2c->pbuff++) = i2c_data_receive(hi2c->i2cx); + + if ((hi2c->psize > 0)) + { + hi2c->pcount--; + hi2c->psize--; + } + } + + /* transfer complete */ + hi2c->status = I2C_END; + } + + return I2C_OK; +} + +/** + * @brief dma processing function. + * @param hi2c: the handle points to the operation information. + * @retval none. + */ +void i2c_dma_tx_rx_irq_handler(i2c_handle_type* hi2c, dma_channel_type* dma_channel) +{ + /* transfer complete */ + if (dma_flag_get(DMA_GET_TC_FLAG(dma_channel)) != RESET) + { + /* disable the transfer complete interrupt */ + dma_interrupt_enable(dma_channel, DMA_FDT_INT, FALSE); + + /* clear the transfer complete flag */ + dma_flag_clear(DMA_GET_TC_FLAG(dma_channel)); + + /* disable dma request */ + i2c_dma_enable(hi2c->i2cx, DMA_GET_REQUEST(dma_channel), FALSE); + + /* disable dma channel */ + dma_channel_enable(dma_channel, FALSE); + + switch(hi2c->mode) + { + case I2C_DMA_MA_TX: + case I2C_DMA_MA_RX: + { + /* update the number of transfers */ + hi2c->pcount -= hi2c->psize; + + /* transfer complete */ + if (hi2c->pcount == 0) + { + /* enable stop interrupt */ + i2c_interrupt_enable(hi2c->i2cx, I2C_STOP_INT, TRUE); + } + /* the transfer has not been completed */ + else + { + /* update the buffer pointer of transfers */ + hi2c->pbuff += hi2c->psize; + + /* set the number to be transferred */ + if (hi2c->pcount > MAX_TRANSFER_CNT) + { + hi2c->psize = MAX_TRANSFER_CNT; + } + else + { + hi2c->psize = hi2c->pcount; + } + + /* config dma channel, continue to transfer data */ + i2c_dma_config(hi2c, dma_channel, hi2c->pbuff, hi2c->psize); + + /* enable tdc interrupt */ + i2c_interrupt_enable(hi2c->i2cx, I2C_TDC_INT, TRUE); + } + }break; + case I2C_DMA_SLA_TX: + case I2C_DMA_SLA_RX: + { + + }break; + + default:break; + } + } +} + +/** + * @brief dma transmission complete interrupt function. + * @param hi2c: the handle points to the operation information. + * @retval none. + */ +void i2c_dma_tx_irq_handler(i2c_handle_type* hi2c) +{ + i2c_dma_tx_rx_irq_handler(hi2c, hi2c->dma_tx_channel); +} + +/** + * @brief dma reveive complete interrupt function. + * @param hi2c: the handle points to the operation information. + * @retval none. + */ +void i2c_dma_rx_irq_handler(i2c_handle_type* hi2c) +{ + i2c_dma_tx_rx_irq_handler(hi2c, hi2c->dma_rx_channel); +} + +/** + * @brief interrupt procession function. + * @param hi2c: the handle points to the operation information. + * @retval none. + */ +void i2c_evt_irq_handler(i2c_handle_type* hi2c) +{ + switch(hi2c->mode) + { + case I2C_INT_MA_TX: + case I2C_INT_MA_RX: + { + i2c_master_irq_handler_int(hi2c); + }break; + case I2C_INT_SLA_TX: + case I2C_INT_SLA_RX: + { + i2c_slave_irq_handler_int(hi2c); + }break; + case I2C_DMA_MA_TX: + case I2C_DMA_MA_RX: + { + i2c_master_irq_handler_dma(hi2c); + }break; + case I2C_DMA_SLA_TX: + case I2C_DMA_SLA_RX: + { + i2c_slave_irq_handler_dma(hi2c); + }break; + + default:break; + } +} + +/** + * @brief dma reveive complete interrupt function. + * @param hi2c: the handle points to the operation information. + * @retval none. + */ +void i2c_err_irq_handler(i2c_handle_type* hi2c) +{ + hi2c->error_code = I2C_ERR_INTERRUPT; + + /* buserr */ + if (i2c_flag_get(hi2c->i2cx, I2C_BUSERR_FLAG) != RESET) + { + i2c_flag_clear(hi2c->i2cx, I2C_BUSERR_FLAG); + } + + /* arlost */ + if (i2c_flag_get(hi2c->i2cx, I2C_ARLOST_FLAG) != RESET) + { + i2c_flag_clear(hi2c->i2cx, I2C_ARLOST_FLAG); + } + + /* ouf */ + if (i2c_flag_get(hi2c->i2cx, I2C_OUF_FLAG) != RESET) + { + i2c_flag_clear(hi2c->i2cx, I2C_OUF_FLAG); + } + + /* pecerr */ + if (i2c_flag_get(hi2c->i2cx, I2C_PECERR_FLAG) != RESET) + { + i2c_flag_clear(hi2c->i2cx, I2C_PECERR_FLAG); + } + + /* timeout */ + if (i2c_flag_get(hi2c->i2cx, I2C_TMOUT_FLAG) != RESET) + { + i2c_flag_clear(hi2c->i2cx, I2C_TMOUT_FLAG); + } + + /* alertf */ + if (i2c_flag_get(hi2c->i2cx, I2C_ALERTF_FLAG) != RESET) + { + i2c_flag_clear(hi2c->i2cx, I2C_ALERTF_FLAG); + } + + /* disable interrupts */ + i2c_interrupt_enable(hi2c->i2cx, I2C_ERR_INT, FALSE); +} + diff --git a/i2c_application.h b/i2c_application.h new file mode 100644 index 0000000..90c2626 --- /dev/null +++ b/i2c_application.h @@ -0,0 +1,181 @@ +/** + ************************************************************************** + * @file i2c_application.h + * @version v2.0.4 + * @date 2021-12-31 + * @brief i2c application libray header file + ************************************************************************** + * Copyright notice & Disclaimer + * + * The software Board Support Package (BSP) that is made available to + * download from Artery official website is the copyrighted work of Artery. + * Artery authorizes customers to use, copy, and distribute the BSP + * software and its related documentation for the purpose of design and + * development in conjunction with Artery microcontrollers. Use of the + * software is governed by this copyright notice and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, + * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, + * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR + * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, + * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. + * + ************************************************************************** + */ + +/*!< define to prevent recursive inclusion -------------------------------------*/ +#ifndef __I2C_APPLICATION_H +#define __I2C_APPLICATION_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* includes ------------------------------------------------------------------*/ +#include "at32f435_437.h" + +/** @addtogroup AT32F435_437_middlewares_i2c_application_library + * @{ + */ + + +/** @defgroup I2C_library_event_check_flag + * @{ + */ + +#define I2C_EVENT_CHECK_NONE ((uint32_t)0x00000000) /*!< check flag none */ +#define I2C_EVENT_CHECK_ACKFAIL ((uint32_t)0x00000001) /*!< check flag ackfail */ +#define I2C_EVENT_CHECK_STOP ((uint32_t)0x00000002) /*!< check flag stop */ + +/** + * @} + */ + +/** @defgroup I2C_library_transmission_mode + * @{ + */ + +typedef enum +{ + I2C_INT_MA_TX = 0, + I2C_INT_MA_RX, + I2C_INT_SLA_TX, + I2C_INT_SLA_RX, + I2C_DMA_MA_TX, + I2C_DMA_MA_RX, + I2C_DMA_SLA_TX, + I2C_DMA_SLA_RX, +} i2c_mode_type; + +/** + * @} + */ + +/** @defgroup I2C_library_status_code + * @{ + */ + +typedef enum +{ + I2C_OK = 0, /*!< no error */ + I2C_ERR_STEP_1, /*!< step 1 error */ + I2C_ERR_STEP_2, /*!< step 2 error */ + I2C_ERR_STEP_3, /*!< step 3 error */ + I2C_ERR_STEP_4, /*!< step 4 error */ + I2C_ERR_STEP_5, /*!< step 5 error */ + I2C_ERR_STEP_6, /*!< step 6 error */ + I2C_ERR_STEP_7, /*!< step 7 error */ + I2C_ERR_STEP_8, /*!< step 8 error */ + I2C_ERR_STEP_9, /*!< step 9 error */ + I2C_ERR_STEP_10, /*!< step 10 error */ + I2C_ERR_STEP_11, /*!< step 11 error */ + I2C_ERR_STEP_12, /*!< step 12 error */ + I2C_ERR_TCRLD, /*!< tcrld error */ + I2C_ERR_TDC, /*!< tdc error */ + I2C_ERR_ADDR, /*!< addr error */ + I2C_ERR_STOP, /*!< stop error */ + I2C_ERR_ACKFAIL, /*!< ackfail error */ + I2C_ERR_TIMEOUT, /*!< timeout error */ + I2C_ERR_INTERRUPT, /*!< interrupt error */ +} i2c_status_type; + +/** + * @} + */ + +/** @defgroup I2C_library_handler + * @{ + */ + +typedef struct +{ + i2c_type *i2cx; /*!< i2c registers base address */ + uint8_t *pbuff; /*!< pointer to i2c transfer buffer */ + __IO uint16_t psize; /*!< i2c transfer size */ + __IO uint16_t pcount; /*!< i2c transfer counter */ + __IO uint32_t mode; /*!< i2c communication mode */ + __IO uint32_t status; /*!< i2c communication status */ + __IO i2c_status_type error_code; /*!< i2c error code */ + dma_channel_type *dma_tx_channel; /*!< dma transmit channel */ + dma_channel_type *dma_rx_channel; /*!< dma receive channel */ + dma_init_type dma_init_struct; /*!< dma init parameters */ +} i2c_handle_type; + +/** + * @} + */ + +/** @defgroup I2C_library_exported_functions + * @{ + */ + +void i2c_config (i2c_handle_type* hi2c); +void i2c_lowlevel_init (i2c_handle_type* hi2c); +i2c_status_type i2c_wait_end (i2c_handle_type* hi2c, uint32_t timeout); + +i2c_status_type i2c_master_transmit (i2c_handle_type* hi2c, uint16_t address, uint8_t* pdata, uint16_t size, uint32_t timeout); +i2c_status_type i2c_master_receive (i2c_handle_type* hi2c, uint16_t address, uint8_t* pdata, uint16_t size, uint32_t timeout); +i2c_status_type i2c_slave_transmit (i2c_handle_type* hi2c, uint8_t* pdata, uint16_t size, uint32_t timeout); +i2c_status_type i2c_slave_receive (i2c_handle_type* hi2c, uint8_t* pdata, uint16_t size, uint32_t timeout); + +i2c_status_type i2c_master_transmit_int (i2c_handle_type* hi2c, uint16_t address, uint8_t* pdata, uint16_t size, uint32_t timeout); +i2c_status_type i2c_master_receive_int (i2c_handle_type* hi2c, uint16_t address, uint8_t* pdata, uint16_t size, uint32_t timeout); +i2c_status_type i2c_slave_transmit_int (i2c_handle_type* hi2c, uint8_t* pdata, uint16_t size, uint32_t timeout); +i2c_status_type i2c_slave_receive_int (i2c_handle_type* hi2c, uint8_t* pdata, uint16_t size, uint32_t timeout); + +i2c_status_type i2c_master_transmit_dma (i2c_handle_type* hi2c, uint16_t address, uint8_t* pdata, uint16_t size, uint32_t timeout); +i2c_status_type i2c_master_receive_dma (i2c_handle_type* hi2c, uint16_t address, uint8_t* pdata, uint16_t size, uint32_t timeout); +i2c_status_type i2c_slave_transmit_dma (i2c_handle_type* hi2c, uint8_t* pdata, uint16_t size, uint32_t timeout); +i2c_status_type i2c_slave_receive_dma (i2c_handle_type* hi2c, uint8_t* pdata, uint16_t size, uint32_t timeout); + +i2c_status_type i2c_smbus_master_transmit (i2c_handle_type* hi2c, uint16_t address, uint8_t* pdata, uint16_t size, uint32_t timeout); +i2c_status_type i2c_smbus_master_receive (i2c_handle_type* hi2c, uint16_t address, uint8_t* pdata, uint16_t size, uint32_t timeout); +i2c_status_type i2c_smbus_slave_transmit (i2c_handle_type* hi2c, uint8_t* pdata, uint16_t size, uint32_t timeout); +i2c_status_type i2c_smbus_slave_receive (i2c_handle_type* hi2c, uint8_t* pdata, uint16_t size, uint32_t timeout); + +i2c_status_type i2c_memory_write (i2c_handle_type* hi2c, uint16_t address, uint16_t memaddress, uint8_t* pdata, uint16_t size, uint32_t timeout); +i2c_status_type i2c_memory_write_int (i2c_handle_type* hi2c, uint16_t address, uint16_t memaddress, uint8_t* pdata, uint16_t size, uint32_t timeout); +i2c_status_type i2c_memory_write_dma (i2c_handle_type* hi2c, uint16_t address, uint16_t memaddress, uint8_t* pdata, uint16_t size, uint32_t timeout); +i2c_status_type i2c_memory_read (i2c_handle_type* hi2c, uint16_t address, uint16_t memaddress, uint8_t* pdata, uint16_t size, uint32_t timeout); +i2c_status_type i2c_memory_read_int (i2c_handle_type* hi2c, uint16_t address, uint16_t memaddress, uint8_t* pdata, uint16_t size, uint32_t timeout); +i2c_status_type i2c_memory_read_dma (i2c_handle_type* hi2c, uint16_t address, uint16_t memaddress, uint8_t* pdata, uint16_t size, uint32_t timeout); + +void i2c_evt_irq_handler (i2c_handle_type* hi2c); +void i2c_err_irq_handler (i2c_handle_type* hi2c); +void i2c_dma_tx_irq_handler (i2c_handle_type* hi2c); +void i2c_dma_rx_irq_handler (i2c_handle_type* hi2c); + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/i2c_smbus.c b/i2c_smbus.c new file mode 100644 index 0000000..d87bdb2 --- /dev/null +++ b/i2c_smbus.c @@ -0,0 +1,208 @@ +// +// Created by cfif on 11.02.23. +// + +#include "i2c_application.h" +#include "delay_sec.h" +#include "stdbool.h" + +/** @addtogroup AT32F437_periph_examples + * @{ + */ + +/** @addtogroup 437_I2C_communication_smbus I2C_communication_smbus + * @{ + */ + +#define I2C_TIMEOUT 0xFFFF + +//#define I2Cx_CLKCTRL 0xB170FFFF //10K +//#define I2Cx_CLKCTRL 0xC0E06969 //50K +#define I2Cx_CLKCTRL 0x80504C4E //100K +//#define I2Cx_CLKCTRL 0x30F03C6B //200K + +//0x6A +#define I2Cx_ADDRESS (0x60 << 1) + +#define I2Cx_PORT I2C3 +#define I2Cx_CLK CRM_I2C3_PERIPH_CLOCK +#define I2Cx_DMA DMA1 +#define I2Cx_DMA_CLK CRM_DMA1_PERIPH_CLOCK + +#define I2Cx_SCL_GPIO_CLK CRM_GPIOF_PERIPH_CLOCK +#define I2Cx_SCL_GPIO_PIN GPIO_PINS_14 +#define I2Cx_SCL_GPIO_PinsSource GPIO_PINS_SOURCE14 +#define I2Cx_SCL_GPIO_PORT GPIOF +#define I2Cx_SCL_GPIO_MUX GPIO_MUX_4 + +#define I2Cx_SDA_GPIO_CLK CRM_GPIOF_PERIPH_CLOCK +#define I2Cx_SDA_GPIO_PIN GPIO_PINS_15 +#define I2Cx_SDA_GPIO_PinsSource GPIO_PINS_SOURCE15 +#define I2Cx_SDA_GPIO_PORT GPIOF +#define I2Cx_SDA_GPIO_MUX GPIO_MUX_4 + + +i2c_handle_type hi2cx; + + +void i2c_lowlevel_init(i2c_handle_type *hi2c) { + gpio_init_type gpio_init_structure; + + if (hi2c->i2cx == I2Cx_PORT) { + /* i2c periph clock enable */ + crm_periph_clock_enable(I2Cx_CLK, TRUE); + crm_periph_clock_enable(I2Cx_SCL_GPIO_CLK, TRUE); + crm_periph_clock_enable(I2Cx_SDA_GPIO_CLK, TRUE); + + /* gpio configuration */ + gpio_pin_mux_config(I2Cx_SCL_GPIO_PORT, I2Cx_SCL_GPIO_PinsSource, I2Cx_SCL_GPIO_MUX); + + gpio_pin_mux_config(I2Cx_SDA_GPIO_PORT, I2Cx_SDA_GPIO_PinsSource, I2Cx_SDA_GPIO_MUX); + + /* configure i2c pins: scl */ + gpio_init_structure.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER; + gpio_init_structure.gpio_mode = GPIO_MODE_MUX; + gpio_init_structure.gpio_out_type = GPIO_OUTPUT_OPEN_DRAIN; + gpio_init_structure.gpio_pull = GPIO_PULL_UP; + + gpio_init_structure.gpio_pins = I2Cx_SCL_GPIO_PIN; + gpio_init(I2Cx_SCL_GPIO_PORT, &gpio_init_structure); + + /* configure i2c pins: sda */ + gpio_init_structure.gpio_pins = I2Cx_SDA_GPIO_PIN; + gpio_init(I2Cx_SDA_GPIO_PORT, &gpio_init_structure); + + /* config i2c */ + i2c_init(hi2c->i2cx, 0, I2Cx_CLKCTRL); + + i2c_own_address1_set(hi2c->i2cx, I2C_ADDRESS_MODE_7BIT, I2Cx_ADDRESS); + } +} + +const uint16_t V = 1700; + +uint8_t reg0[2] = {0x0, V & 7}; +uint8_t reg1[2] = {0x1, V >> 3}; +uint8_t reg2[2] = {0x2, 0x1}; +uint8_t reg3[2] = {0x3, 70}; +uint8_t reg_read; + +bool sendI2c() { + i2c_status_type i2c_status; + + hi2cx.i2cx = I2Cx_PORT; + + // i2c config + i2c_config(&hi2cx); + + uint8_t adr = 1; + + // 0 - запись + // 1 - чтение + + // Reg0 - Напряжение + if ((i2c_status = i2c_master_transmit(&hi2cx, I2Cx_ADDRESS | 0, reg0, 2, I2C_TIMEOUT)) != I2C_OK) { + return false; + } + if ((i2c_status = i2c_master_transmit(&hi2cx, I2Cx_ADDRESS | 0, reg0, 1, I2C_TIMEOUT)) != I2C_OK) { + return false; + } + if ((i2c_status = i2c_master_receive(&hi2cx, I2Cx_ADDRESS | 1, ®_read, 1, I2C_TIMEOUT)) != I2C_OK) { + return false; + } + + // Reg1 - Напряжение + if ((i2c_status = i2c_master_transmit(&hi2cx, I2Cx_ADDRESS | 0, reg1, 2, I2C_TIMEOUT)) != I2C_OK) { + return false; + } + if ((i2c_status = i2c_master_transmit(&hi2cx, I2Cx_ADDRESS | 0, reg1, 1, I2C_TIMEOUT)) != I2C_OK) { + return false; + } + if ((i2c_status = i2c_master_receive(&hi2cx, I2Cx_ADDRESS | 1, ®_read, 1, I2C_TIMEOUT)) != I2C_OK) { + return false; + } + + + // Reg3 - Ток + if ((i2c_status = i2c_master_transmit(&hi2cx, I2Cx_ADDRESS | 0, reg3, 2, I2C_TIMEOUT)) != I2C_OK) { + return false; + } + if ((i2c_status = i2c_master_transmit(&hi2cx, I2Cx_ADDRESS | 0, reg3, 1, I2C_TIMEOUT)) != I2C_OK) { + return false; + } + if ((i2c_status = i2c_master_receive(&hi2cx, I2Cx_ADDRESS | 1, ®_read, 1, I2C_TIMEOUT)) != I2C_OK) { + return false; + } + + + + + // Reg2 - Запуск + if ((i2c_status = i2c_master_transmit(&hi2cx, I2Cx_ADDRESS | 0, reg2, 2, I2C_TIMEOUT)) != I2C_OK) { + return false; + } + if ((i2c_status = i2c_master_transmit(&hi2cx, I2Cx_ADDRESS | 0, reg2, 1, I2C_TIMEOUT)) != I2C_OK) { + return false; + } + if ((i2c_status = i2c_master_receive(&hi2cx, I2Cx_ADDRESS | 1, ®_read, 1, I2C_TIMEOUT)) != I2C_OK) { + return false; + } + +// delay_ms(20); + + // Reg2 + if ((i2c_status = i2c_master_transmit(&hi2cx, I2Cx_ADDRESS | 0, reg2, 1, I2C_TIMEOUT)) != I2C_OK) { + return false; + } + if ((i2c_status = i2c_master_receive(&hi2cx, I2Cx_ADDRESS | 1, ®_read, 1, I2C_TIMEOUT)) != I2C_OK) { + return false; + } + + + int a = 0; +// // start the request reception process +// if((i2c_status = i2c_master_transmit(&hi2cx, I2Cx_ADDRESS | 0, tx_buf, 1, I2C_TIMEOUT)) != I2C_OK) +// { +// return false; +// } +// +// // start the request reception process +// if((i2c_status = i2c_master_receive(&hi2cx, I2Cx_ADDRESS | 1, rx_buf, 1, I2C_TIMEOUT)) != I2C_OK) +// { +// return false; +// } + +// // start the request reception process +// if((i2c_status = i2c_master_transmit(&hi2cx, I2Cx_ADDRESS | 0, tx_buf, 2, I2C_TIMEOUT)) != I2C_OK) +// { +// return false; +// } +// // start the request reception process +// if((i2c_status = i2c_master_transmit(&hi2cx, I2Cx_ADDRESS | 0, tx_buf, 1, I2C_TIMEOUT)) != I2C_OK) +// { +// return false; +// } +// +// // start the request reception process +// if((i2c_status = i2c_master_receive(&hi2cx, I2Cx_ADDRESS | 1, rx_buf, 1, I2C_TIMEOUT)) != I2C_OK) +// { +// return false; +// } + + + /* + // start the request reception process + if((i2c_status = i2c_smbus_master_transmit(&hi2cx, I2Cx_ADDRESS | 1, tx_buf, BUF_SIZE, I2C_TIMEOUT)) != I2C_OK) + { + return false; + } + + // start the request reception process + if((i2c_status = i2c_smbus_master_receive(&hi2cx, I2Cx_ADDRESS | 1, rx_buf, BUF_SIZE, I2C_TIMEOUT)) != I2C_OK) + { + return false; + } + */ + + return true; +} \ No newline at end of file diff --git a/i2c_smbus.h b/i2c_smbus.h new file mode 100644 index 0000000..112fca1 --- /dev/null +++ b/i2c_smbus.h @@ -0,0 +1,10 @@ +// +// Created by cfif on 11.02.23. +// + +#ifndef GONEC_GSM_I2C_SMBUS_H +#define GONEC_GSM_I2C_SMBUS_H + +bool sendI2c(); + +#endif //GONEC_GSM_I2C_SMBUS_H diff --git a/modular.json b/modular.json new file mode 100644 index 0000000..0f78556 --- /dev/null +++ b/modular.json @@ -0,0 +1,10 @@ +{ + "cmake": { + "inc_dirs": [ + "./" + ], + "srcs": [ + "*.c" + ] + } +} \ No newline at end of file