From dd216a81175b64c9df60a071935830b3533d4a0d Mon Sep 17 00:00:00 2001 From: IOsetting Date: Sun, 3 Jul 2022 18:00:23 +0800 Subject: [PATCH] feat: i2c support for 16-bit address --- include/fw_i2c.h | 6 ++++-- src/fw_i2c.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 2 deletions(-) diff --git a/include/fw_i2c.h b/include/fw_i2c.h index 6591fe4..cd9ba99 100644 --- a/include/fw_i2c.h +++ b/include/fw_i2c.h @@ -34,7 +34,7 @@ typedef enum save the received bit to MSACKI(I2CMSST.1) */ I2C_MasterCmd_Recv = 0x04, // Recive data I2C_MasterCmd_TxAck = 0x05, /* Send Ack. This command will generate 1 clock on SCL, and - write the value of MSACKO(I2CMSST.0) to SDA */ + write the bit value of MSACKO(I2CMSST.0) to SDA */ I2C_MasterCmd_Stop = 0x06, // STOP. This command will send STOP signal, and reset MSBUSY flag I2C_MasterCmd_StartSendRxAck = 0x09, // START + Send data + RxAck I2C_MasterCmd_SendRxAck = 0x0A, // Send data + RxAck @@ -55,7 +55,7 @@ typedef enum #define I2C_SetWorkMode(__MODE__) SFRX_ASSIGN(I2CCFG, 6, __MODE__) /** - * I2C bus clock = SYSCLK / 2 / (__DIV__ * 2 + 4) + * I2C bus clock = FOSC / 2 / (__DIV__ * 2 + 4) * __DIV__ values range [0, 63] */ #define I2C_SetClockPrescaler(__DIV__) do { \ @@ -106,5 +106,7 @@ typedef enum uint8_t I2C_Write(uint8_t devAddr, uint8_t memAddr, uint8_t *dat, uint16_t size); uint8_t I2C_Read(uint8_t devAddr, uint8_t memAddr, uint8_t *buf, uint16_t size); +uint8_t I2C_Write16BitAddr(uint8_t devAddr, uint16_t memAddr, uint8_t *dat, uint16_t size); +uint8_t I2C_Read16BitAddr(uint8_t devAddr, uint16_t memAddr, uint8_t *buf, uint16_t size); #endif diff --git a/src/fw_i2c.c b/src/fw_i2c.c index 4431682..abc1e8e 100644 --- a/src/fw_i2c.c +++ b/src/fw_i2c.c @@ -61,3 +61,54 @@ uint8_t I2C_Read(uint8_t devAddr, uint8_t memAddr, uint8_t *buf, uint16_t size) SFRX_OFF(); return HAL_OK; } + +uint8_t I2C_Write16BitAddr(uint8_t devAddr, uint16_t memAddr, uint8_t *dat, uint16_t size) +{ + SFRX_ON(); + I2C_MasterStart(); + I2C_MasterSendData(devAddr & 0xFE); + I2C_MasterRxAck(); + I2C_MasterSendData(memAddr >> 8); + I2C_MasterRxAck(); + I2C_MasterSendData(memAddr & 0xFF); + I2C_MasterRxAck(); + while(size--) + { + I2C_MasterSendData(*dat++); + I2C_MasterRxAck(); + } + I2C_MasterStop(); + SFRX_OFF(); + return HAL_OK; +} + +uint8_t I2C_Read16BitAddr(uint8_t devAddr, uint16_t memAddr, uint8_t *buf, uint16_t size) +{ + SFRX_ON(); + I2C_MasterStart(); + I2C_MasterSendData(devAddr & 0xFE); + I2C_MasterRxAck(); + I2C_MasterSendData(memAddr >> 8); + I2C_MasterRxAck(); + I2C_MasterSendData(memAddr & 0xFF); + I2C_MasterRxAck(); + I2C_MasterStart(); + I2C_MasterSendData(devAddr | 0x01); + I2C_MasterRxAck(); + while(size--) + { + I2C_SendMasterCmd(I2C_MasterCmd_Recv); + *buf++ = I2CRXD; + if (size == 0) + { + I2C_MasterNAck(); + } + else + { + I2C_MasterAck(); + } + } + I2C_MasterStop(); + SFRX_OFF(); + return HAL_OK; +} \ No newline at end of file