THB2/bthome_phy6222/source/dev_i2c.c
2024-01-26 00:18:00 +03:00

202 lines
4.9 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* dev_i2c.c
*
* Created on: 25 янв. 2024 г.
* Author: pvvx
*/
#include "config.h"
#include "OSAL.h"
#include "gpio.h"
#include "rom_sym_def.h"
#include "i2c.h"
#include "dev_i2c.h"
#define I2C_WAIT_ms 1
void init_i2c(bool speed400khz) {
hal_gpio_fmux_set(I2C_SCL, FMUX_IIC0_SCL);
hal_gpio_fmux_set(I2C_SDA, FMUX_IIC0_SDA);
//hal_i2c_init(I2C_0, I2C_CLOCK_400K):
int pclk = clk_get_pclk();
AP_I2C_TypeDef* pi2cdev = AP_I2C0;
hal_clk_gate_enable(MOD_I2C0);
pi2cdev->IC_ENABLE = 0;
pi2cdev->IC_CON = 0x61;
if(speed400khz) {
// SET_I2C_SPEED 400 kHz
pi2cdev->IC_CON = ((pi2cdev->IC_CON) & 0xfffffff9) | (0x02 << 1); // SPEED_FAST
if (pclk == 16000000) {
pi2cdev->IC_FS_SCL_HCNT = 10;
pi2cdev->IC_FS_SCL_LCNT = 17;
} else if (pclk == 32000000) {
pi2cdev->IC_FS_SCL_HCNT = 30;
pi2cdev->IC_FS_SCL_LCNT = 35;
} else if (pclk == 48000000) {
pi2cdev->IC_FS_SCL_HCNT = 48;
pi2cdev->IC_FS_SCL_LCNT = 54;
} else if (pclk == 64000000) {
pi2cdev->IC_FS_SCL_HCNT = 67;
pi2cdev->IC_FS_SCL_LCNT = 75;
} else if (pclk == 96000000) {
pi2cdev->IC_FS_SCL_HCNT = 105;
pi2cdev->IC_FS_SCL_LCNT = 113;
}
} else {
// SET_I2C_SPEED 100 kHz
pi2cdev->IC_CON = ((pi2cdev->IC_CON) & 0xfffffff9) | (0x01 << 1); // SPEED_STANDARD
if (pclk == 16000000) {
pi2cdev->IC_SS_SCL_HCNT = 70; //16
pi2cdev->IC_SS_SCL_LCNT = 76; //32)
} else if (pclk == 32000000) {
pi2cdev->IC_SS_SCL_HCNT = 148; //16
pi2cdev->IC_SS_SCL_LCNT = 154; //32)
} else if (pclk == 48000000) {
pi2cdev->IC_SS_SCL_HCNT = 230; //16
pi2cdev->IC_SS_SCL_LCNT = 236; //32)
} else if (pclk == 64000000) {
pi2cdev->IC_SS_SCL_HCNT = 307; //16
pi2cdev->IC_SS_SCL_LCNT = 320; //32)
} else if (pclk == 96000000) {
pi2cdev->IC_SS_SCL_HCNT = 460; //16
pi2cdev->IC_SS_SCL_LCNT = 470; //32)
}
}
// pi2cdev->IC_TAR = I2C_MASTER_ADDR_DEF;
pi2cdev->IC_INTR_MASK = 0;
pi2cdev->IC_RX_TL = 0x0;
pi2cdev->IC_TX_TL = 0x1;
// pi2cdev->IC_ENABLE = 1;
}
void deinit_i2c(void) {
AP_I2C_TypeDef * pi2cdev = AP_I2C0;
pi2cdev->IC_ENABLE = 0;
hal_clk_gate_disable(MOD_I2C0);
hal_gpio_pin_init(I2C_SCL, IE);
hal_gpio_pin_init(I2C_SDA, IE);
}
extern volatile uint32 osal_sys_tick;
/* size max = 7 ! */
int read_i2c_bytes(uint8 addr, uint8 reg, uint8 * data, uint8 size) {
int i = size;
AP_I2C_TypeDef * pi2cdev = AP_I2C0;
pi2cdev->IC_ENABLE = 0;
pi2cdev->IC_TAR = addr;
HAL_ENTER_CRITICAL_SECTION();
pi2cdev->IC_ENABLE = 1;
pi2cdev->IC_DATA_CMD = reg;
//while(!(pi2cdev->IC_RAW_INTR_STAT & 0x10));
while(i--)
pi2cdev->IC_DATA_CMD = 0x100;
HAL_EXIT_CRITICAL_SECTION();
uint32 to = osal_sys_tick;
i = size;
while(i) {
if(pi2cdev->IC_STATUS & 0x08) { // fifo not empty
*data = pi2cdev->IC_DATA_CMD & 0xff;
data++;
i--;
}
if(osal_sys_tick - to > I2C_WAIT_ms)
return 1;
}
return 0;
}
int read_i2c_nabuf(uint8 addr, uint8 * data, uint8 size) {
int i = size;
AP_I2C_TypeDef * pi2cdev = AP_I2C0;
pi2cdev->IC_ENABLE = 0;
pi2cdev->IC_TAR = addr;
HAL_ENTER_CRITICAL_SECTION();
pi2cdev->IC_ENABLE = 1;
while(i--)
pi2cdev->IC_DATA_CMD = 0x100;
HAL_EXIT_CRITICAL_SECTION();
uint32 to = osal_sys_tick;
i = size;
while(i) {
if(pi2cdev->IC_STATUS & 0x08) { // fifo not empty
*data = pi2cdev->IC_DATA_CMD & 0xff;
data++;
i--;
}
if(osal_sys_tick - to > I2C_WAIT_ms)
return 1;
}
return 0;
}
int send_i2c_byte(uint8 addr, uint8 data) {
AP_I2C_TypeDef * pi2cdev = AP_I2C0;
pi2cdev->IC_ENABLE = 0;
pi2cdev->IC_TAR = addr;
HAL_ENTER_CRITICAL_SECTION();
pi2cdev->IC_ENABLE = 1;
pi2cdev->IC_DATA_CMD = data;
// while(!(pi2cdev->IC_RAW_INTR_STAT & 0x10));
HAL_EXIT_CRITICAL_SECTION();
uint32 to = osal_sys_tick;
while(1) {
if(pi2cdev->IC_RAW_INTR_STAT & 0x200)// check tx empty
break;
if(osal_sys_tick - to > I2C_WAIT_ms)
return 1;
}
return 0;
}
int send_i2c_wreg(uint8 addr, uint8 reg, uint16 data) {
AP_I2C_TypeDef * pi2cdev = AP_I2C0;
pi2cdev->IC_ENABLE = 0;
pi2cdev->IC_TAR = addr;
HAL_ENTER_CRITICAL_SECTION();
pi2cdev->IC_ENABLE = 1;
pi2cdev->IC_DATA_CMD = reg;
while(!(pi2cdev->IC_RAW_INTR_STAT & 0x10));
pi2cdev->IC_DATA_CMD = (data >> 8) & 0xff;
while(!(pi2cdev->IC_RAW_INTR_STAT & 0x10));
pi2cdev->IC_DATA_CMD = data & 0xff;
HAL_EXIT_CRITICAL_SECTION();
uint32 to = osal_sys_tick;
while(1) {
if(pi2cdev->IC_RAW_INTR_STAT & 0x200)// check tx empty
break;
if(osal_sys_tick - to > I2C_WAIT_ms)
return 1;
}
return 0;
}
int send_i2c_buf(uint8 addr, uint8 * pdata, int len) {
AP_I2C_TypeDef * pi2cdev = AP_I2C0;
pi2cdev->IC_ENABLE = 0;
pi2cdev->IC_TAR = addr;
HAL_ENTER_CRITICAL_SECTION();
pi2cdev->IC_ENABLE = 1;
while(len--) {
pi2cdev->IC_DATA_CMD = *pdata++;
while(!(pi2cdev->IC_RAW_INTR_STAT & 0x10));
}
HAL_EXIT_CRITICAL_SECTION();
uint32 to = osal_sys_tick;
while(1) {
if(pi2cdev->IC_RAW_INTR_STAT & 0x200)// check tx empty
break;
if(osal_sys_tick - to > I2C_WAIT_ms)
return 1;
}
return 0;
}