/* * 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 3 void init_i2c(pdev_i2c_t pi2c_dev) { AP_I2C_TypeDef* pi2cdev = AP_I2C0; if(pi2c_dev->i2c_num) pi2cdev = AP_I2C1; pi2c_dev->pi2cdev = pi2cdev; hal_gpio_fmux_set(pi2c_dev->scl, FMUX_IIC0_SCL + (pi2c_dev->i2c_num<<1)); // FMUX_IIC1_SCL hal_gpio_fmux_set(pi2c_dev->sda, FMUX_IIC0_SDA + (pi2c_dev->i2c_num<<1)); // FMUX_IIC1_SDA // int pclk = clk_get_pclk(); hal_clk_gate_enable(MOD_I2C0 + pi2c_dev->i2c_num); // MOD_I2C1 pi2cdev->IC_ENABLE = 0; pi2cdev->IC_CON = 0x61; if(pi2c_dev->speed) { // SET_I2C_SPEED 400 kHz pi2cdev->IC_CON = ((pi2cdev->IC_CON) & 0xfffffff9) | (0x02 << 1); // SPEED_FAST #if 0 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 pi2cdev->IC_FS_SCL_HCNT = 10; pi2cdev->IC_FS_SCL_LCNT = 17; #endif } else { // SET_I2C_SPEED 100 kHz pi2cdev->IC_CON = ((pi2cdev->IC_CON) & 0xfffffff9) | (0x01 << 1); // SPEED_STANDARD #if 0 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) } #else pi2cdev->IC_SS_SCL_HCNT = 70; //16 pi2cdev->IC_SS_SCL_LCNT = 76; //32) #endif } // 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(pdev_i2c_t pi2c_dev) { AP_I2C_TypeDef* pi2cdev = pi2c_dev->pi2cdev; pi2cdev->IC_ENABLE = 0; hal_clk_gate_disable(MOD_I2C0 + pi2c_dev->i2c_num); // MOD_I2C1 hal_gpio_pin_init(pi2c_dev->scl, IE); hal_gpio_pin_init(pi2c_dev->sda, IE); } extern volatile uint32 osal_sys_tick; /* size max = 7 ! */ int read_i2c_bytes(pdev_i2c_t pi2c_dev, uint8 addr, uint8 reg, uint8 * data, uint8 size) { AP_I2C_TypeDef* pi2cdev = pi2c_dev->pi2cdev; int i = size; 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; } /* size max = 7 ! */ int read_i2c_nabuf(pdev_i2c_t pi2c_dev, uint8 addr, uint8 * data, uint8 size) { AP_I2C_TypeDef* pi2cdev = pi2c_dev->pi2cdev; int i = size; 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; } static int i2c_wait_send(AP_I2C_TypeDef* pi2cdev) { 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_byte(pdev_i2c_t pi2c_dev, uint8 addr, uint8 data) { AP_I2C_TypeDef* pi2cdev = pi2c_dev->pi2cdev; 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(); return i2c_wait_send(pi2cdev); } int send_i2c_wreg(pdev_i2c_t pi2c_dev, uint8 addr, uint8 reg, uint16 data) { AP_I2C_TypeDef* pi2cdev = pi2c_dev->pi2cdev; 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(); return i2c_wait_send(pi2cdev); } int send_i2c_wcmd(pdev_i2c_t pi2c_dev, uint8 addr, uint16 cmd) { AP_I2C_TypeDef* pi2cdev = pi2c_dev->pi2cdev; pi2cdev->IC_ENABLE = 0; pi2cdev->IC_TAR = addr; HAL_ENTER_CRITICAL_SECTION(); pi2cdev->IC_ENABLE = 1; pi2cdev->IC_DATA_CMD = (cmd >> 8) & 0xff; while(!(pi2cdev->IC_RAW_INTR_STAT & 0x10)); pi2cdev->IC_DATA_CMD = cmd & 0xff; HAL_EXIT_CRITICAL_SECTION(); return i2c_wait_send(pi2cdev); } int send_i2c_buf(pdev_i2c_t pi2c_dev, uint8 addr, uint8 * pdata, int len) { AP_I2C_TypeDef* pi2cdev = pi2c_dev->pi2cdev; 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(); return i2c_wait_send(pi2cdev); }