THB2/bthome_phy6222/source/dev_i2c.c
2024-11-22 14:56:19 +03:00

234 lines
5.7 KiB
C
Raw Permalink 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 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);
}