156 lines
3.6 KiB
C
156 lines
3.6 KiB
C
/*************
|
|
i2c_s.c
|
|
SDK_LICENSE
|
|
***************/
|
|
|
|
#include "bus_dev.h"
|
|
#include "gpio.h"
|
|
#include "clock.h"
|
|
#include "i2c_s.h"
|
|
#include "i2c.h"
|
|
#include "error.h"
|
|
#include "log.h"
|
|
|
|
typedef struct
|
|
{
|
|
uint8_t id; //0: uninit, 1: i2c0, 2:i2c1
|
|
uint8_t mode; //(1)I2CS_MODE_REG_8BIT, (2)I2CS_MODE_REG_16BIT,(3)I2CS_MODE_RAW
|
|
uint8_t saddr;
|
|
gpio_pin_e cs; //cs pin, used to wakeup or release
|
|
gpio_pin_e sda;
|
|
gpio_pin_e scl;
|
|
AP_I2C_TypeDef* dev;
|
|
i2cs_hdl_t evt_handler;
|
|
uint8_t rxoffset;
|
|
uint8_t rxbuf[I2CS_RX_MAX_SIZE];
|
|
uint8_t txoffset;
|
|
uint8_t txbuf[I2CS_TX_MAX_SIZE];
|
|
} i2cs_ctx_t;
|
|
|
|
static volatile uint8_t s_i2cs_state = I2CSST_IDLE;
|
|
|
|
static i2cs_ctx_t s_i2cs_ctx;
|
|
|
|
static void i2cs_irq_rx_handler(AP_I2C_TypeDef* pdev)
|
|
{
|
|
uint32_t val;
|
|
|
|
while(1)
|
|
{
|
|
if((pdev->IC_STATUS & BV(3)) == 0)
|
|
break;
|
|
|
|
val = pdev->IC_DATA_CMD;
|
|
LOG("Rx %x\n",val);
|
|
}
|
|
}
|
|
static uint32_t tx_dummy = 0;
|
|
static void i2cs_irq_tx_handler(AP_I2C_TypeDef* pdev)
|
|
{
|
|
pdev->IC_DATA_CMD = tx_dummy &0xff;
|
|
tx_dummy ++;
|
|
pdev->IC_DATA_CMD = tx_dummy &0xff;
|
|
tx_dummy ++;
|
|
//LOG("Tx\n");
|
|
}
|
|
static void i2cs_irq_handler(AP_I2C_TypeDef* pdev)
|
|
{
|
|
uint32_t int_status = pdev->IC_INTR_STAT;
|
|
uint32_t clr = pdev->IC_CLR_INTR;
|
|
|
|
//LOG("i2cs_irq_handler %x\n",int_status);
|
|
if(int_status & I2C_MASK_START_DET)
|
|
{
|
|
}
|
|
|
|
if(int_status & I2C_MASK_RX_FULL)
|
|
{
|
|
i2cs_irq_rx_handler(pdev);
|
|
}
|
|
|
|
if(int_status & I2C_MASK_RD_REQ)
|
|
{
|
|
i2cs_irq_tx_handler(pdev);
|
|
}
|
|
}
|
|
|
|
void __attribute__((used)) hal_I2C0_IRQHandler(void)
|
|
{
|
|
i2cs_ctx_t* pctx = &s_i2cs_ctx;
|
|
|
|
if(pctx->id == I2CS_0)
|
|
i2cs_irq_handler(AP_I2C0);
|
|
}
|
|
void __attribute__((used)) hal_I2C1_IRQHandler(void)
|
|
{
|
|
i2cs_ctx_t* pctx = &s_i2cs_ctx;
|
|
|
|
if(pctx->id == I2CS_1)
|
|
i2cs_irq_handler(AP_I2C1);
|
|
}
|
|
|
|
|
|
|
|
int i2cs_init(
|
|
i2cs_channel_t ch_id,
|
|
i2cs_mode_t mode,
|
|
uint8_t saddr, //slave address
|
|
gpio_pin_e cs, //if need not cs, choose GPIO_DUMMY_PIN
|
|
gpio_pin_e sda,
|
|
gpio_pin_e scl,
|
|
i2cs_hdl_t evt_handler)
|
|
{
|
|
i2cs_ctx_t* pctx = &s_i2cs_ctx;
|
|
Fmux_Type_e fmux;
|
|
MODULE_e module;
|
|
AP_I2C_TypeDef* pdev = NULL;
|
|
int irqid;
|
|
|
|
if(pctx->id)
|
|
{
|
|
return PPlus_ERR_IO_CONFILCT;
|
|
}
|
|
|
|
//parameter validate check
|
|
//set device
|
|
irqid = (ch_id == I2CS_0) ? I2C0_IRQ : I2C1_IRQ;
|
|
module = (ch_id == I2CS_0) ? MOD_I2C0 : MOD_I2C1;
|
|
hal_clk_gate_enable(module);
|
|
pdev = (ch_id == I2CS_0) ? AP_I2C0 : AP_I2C1;
|
|
pctx->id = ch_id;
|
|
pctx->dev = pdev;
|
|
pctx->saddr = saddr;
|
|
pctx->cs = cs;
|
|
pctx->scl = scl;
|
|
pctx->sda = sda;
|
|
pctx->evt_handler = evt_handler;
|
|
fmux = (ch_id == I2CS_0) ? IIC0_SCL : IIC1_SCL;
|
|
hal_gpio_fmux_set(scl, fmux);
|
|
fmux = (ch_id == I2CS_0) ? IIC0_SDA : IIC1_SDA;
|
|
hal_gpio_fmux_set(sda, fmux);
|
|
hal_gpio_pull_set(scl, STRONG_PULL_UP);
|
|
hal_gpio_pull_set(sda, STRONG_PULL_UP);
|
|
pdev->IC_ENABLE = 0; //disable
|
|
pdev->IC_CON = (SPEED_FAST) << 1;
|
|
pdev->IC_SAR = saddr;
|
|
pdev->IC_RX_TL = 1;
|
|
pdev->IC_TX_TL = 1;
|
|
pdev->IC_INTR_MASK = 0xfef;//(I2C_MASK_TX_ABRT | I2C_MASK_RD_REQ | I2C_MASK_RX_FULL | I2C_MASK_RX_DONE);
|
|
pdev->IC_ENABLE = 1; //disable
|
|
NVIC_EnableIRQ((IRQn_Type)irqid);
|
|
NVIC_SetPriority((IRQn_Type)irqid, IRQ_PRIO_HAL);
|
|
return PPlus_SUCCESS;
|
|
}
|
|
|
|
|
|
int i2cs_deinit(void)
|
|
{
|
|
i2cs_ctx_t* pctx = &s_i2cs_ctx;
|
|
|
|
if(pctx->id == 0)
|
|
return PPlus_ERR_IO_FAIL;
|
|
|
|
//release io
|
|
return PPlus_SUCCESS;
|
|
}
|
|
|