#ifndef _IIC_HW_V2_H_ #define _IIC_HW_V2_H_ #include "typedef.h" #include "gpio.h" #define MAX_HW_IIC_NUM 1 enum { HW_IIC_0, // HW_IIC_1, }; #define IIC_WHILE_TIMEOUT_CNT_ 736000 //lsb17M约:500ms #define IPC_SPIN_LOCK_HW_IIC_EN 1//iic多核锁使能 // #define IIC_PORT_GROUP_NUM 4 #define iic_init_prepare(reg) (reg->CON = 1) #define iic_enable(reg) (reg->CON |= BIT(0)) #define iic_disable(reg) (reg->CON &= ~BIT(0)) #define is_iic_enable(reg) ((reg->CON & 0x03)==0x03) #define iic_rst_rst(reg) (reg->CON &= ~BIT(1)) #define iic_rst_release(reg) (reg->CON |= BIT(1)) #define iic_role_host(reg) (reg->CON &= ~BIT(2)) #define iic_role_slave(reg) (reg->CON |= BIT(2)) #define iic_flt_sel(reg,x) SFR(reg->CON, 3, 2, x)//0:close; 1:<1*Tiic_baud_clk, 2:<2*Tiic_baud_clk, 3:<3*Tiic_baud_clk #define iic_stretch_en(reg) (reg->CON &= ~BIT(5)) #define iic_stretch_dis(reg) (reg->CON |= BIT(5)) #define iic_ignore_nack_dis(reg) (reg->CON &= ~BIT(6)) #define iic_ignore_nack_en(reg) (reg->CON |= BIT(6)) #define iic_addr_resp_manu(reg) (reg->CON &= ~BIT(7)) #define iic_addr_resp_auto(reg) (reg->CON |= BIT(7)) #define iic_slv_rx_manu(reg) (reg->CON &= ~BIT(8)) #define iic_slv_rx_auto(reg) (reg->CON |= BIT(8)) #define iic_slv_tx_manu(reg) (reg->CON &= ~BIT(9)) #define iic_slv_tx_auto(reg) (reg->CON |= BIT(9)) #define iic_baddr_resp_dis(reg) (reg->CON &= ~BIT(10)) #define iic_baddr_resp_en(reg) (reg->CON |= BIT(10)) typedef enum { I2C_TASK_SEND_RESET = 0x0, I2C_TASK_SEND_ADDR = 0x1, I2C_TASK_SEND_DATA = 0x2, I2C_TASK_SEND_ACK = 0x3, I2C_TASK_SEND_NACK = 0x4, I2C_TASK_SEND_STOP = 0x5, I2C_TASK_SEND_NACK_STOP = 0x6, I2C_TASK_RECV_DATA = 0x7, I2C_TASK_RECV_DATA_ACK = 0x8, I2C_TASK_RECV_DATA_NACK = 0x9, } i2c_task_typedef; #define iic_task_sel(reg,x) SFR(reg->TASK, 0, 4, x)//i2c_task_typedef typedef enum { I2C_PND_TASK_DONE = BIT(20), I2C_PND_START = BIT(21), I2C_PND_STOP = BIT(22), I2C_PND_RXACK = BIT(23), I2C_PND_RXNACK = BIT(24), I2C_PND_ADR_MATCH = BIT(25), I2C_PND_RXDATA_DONE = BIT(26), I2C_PND_TXTASK_LOAD = BIT(27), I2C_PND_RXTASK_LOAD = BIT(28), } i2c_pnd_typedef; #define iic_set_task_ie(reg) (reg->PND |= BIT(0)) #define iic_clr_task_ie(reg) (reg->PND &= ~BIT(0)) #define iic_task_pnd(reg) (reg->PND & BIT(20)) #define iic_task_pnd_clr(reg) (reg->PND |= BIT(10)) #define iic_set_start_ie(reg) (reg->PND |= BIT(1)) #define iic_clr_start_ie(reg) (reg->PND &= ~BIT(1)) #define iic_start_pnd(reg) (reg->PND & BIT(21)) #define iic_start_pnd_clr(reg) (reg->PND |= BIT(11)) #define iic_set_stop_ie(reg) (reg->PND |= BIT(2)) #define iic_clr_stop_ie(reg) (reg->PND &= ~BIT(2)) #define iic_stop_pnd(reg) (reg->PND & BIT(22)) #define iic_stop_pnd_clr(reg) (reg->PND |= BIT(12)) #define iic_set_rxack_ie(reg) (reg->PND |= BIT(3)) #define iic_clr_rxack_ie(reg) (reg->PND &= ~BIT(3)) #define iic_rxack_pnd(reg) (reg->PND & BIT(23)) #define iic_rxack_pnd_clr(reg) (reg->PND |= BIT(13)) #define iic_set_rxnack_ie(reg) (reg->PND |= BIT(4)) #define iic_clr_rxnack_ie(reg) (reg->PND &= ~BIT(4)) #define iic_rxnack_pnd(reg) (reg->PND & BIT(24)) #define iic_rxnack_pnd_clr(reg) (reg->PND |= BIT(14)) #define iic_set_adr_match_ie(reg) (reg->PND |= BIT(5)) #define iic_clr_adr_match_ie(reg) (reg->PND &= ~BIT(5)) #define iic_adr_match_pnd(reg) (reg->PND & BIT(25)) #define iic_adr_match_pnd_clr(reg) (reg->PND |= BIT(15)) #define iic_set_rxdata_done_ie(reg) (reg->PND |= BIT(6)) #define iic_clr_rxdata_done_ie(reg) (reg->PND &= ~BIT(6)) #define iic_rxdata_done_pnd(reg) (reg->PND & BIT(26)) #define iic_rxdata_done_pnd_clr(reg) (reg->PND |= BIT(16)) #define iic_set_txtask_load_ie(reg) (reg->PND |= BIT(7)) #define iic_clr_txtask_load_ie(reg) (reg->PND &= ~BIT(7)) #define iic_txtask_load_pnd(reg) (reg->PND & BIT(27)) #define iic_txtask_load_pnd_clr(reg) (reg->PND |= BIT(17)) #define iic_set_rxtask_load_ie(reg) (reg->PND |= BIT(8)) #define iic_clr_rxtask_load_ie(reg) (reg->PND &= ~BIT(8)) #define iic_rxtask_load_pnd(reg) (reg->PND & BIT(28)) #define iic_rxtask_load_pnd_clr(reg) (reg->PND |= BIT(18)) #define iic_reset_pnd(reg) (reg->PND = 0x1ff << 10) #define iic_png_reg(reg) (reg->PND) #define iic_tx_buf_reg(reg) (reg->TX_BUF) #define iic_rx_buf_reg(reg) (reg->RX_BUF)//8bit only read #define iic_addr_reg(reg) (reg->ADDR)//bit0:r/w #define iic_baud_reg(reg) (reg->BAUD)//12bit BAUD_CNT > (SETUP_CNT+HOLD_CNT)>0 #define iic_tsu_reg(reg) (reg->TSU)//7bit(0~6) sda信号保持时间 #define iic_thd_reg(reg) (reg->THD)//7bit(0~6) sda信号建立时间 #define iic_dbg_reg(reg) (reg->DBG)//32bit only read typedef const int hw_iic_dev; #define HW_IIC_MASTER_ISR_EN 0 #include "iic_api.h" struct hw_iic_slave_config { struct iic_master_config config; void (*iic_slave_irq_func)(void); u8 slave_addr;//bit7~bit1 }; struct iic_master_config *get_hw_iic_config(hw_iic_dev iic); enum iic_state_enum hw_iic_init(hw_iic_dev iic, struct iic_master_config *i2c_config); enum iic_state_enum hw_iic_deinit(hw_iic_dev iic); enum iic_state_enum hw_iic_resume(hw_iic_dev iic); enum iic_state_enum hw_iic_suspend(hw_iic_dev iic); enum iic_state_enum hw_iic_check_busy(hw_iic_dev iic); enum iic_state_enum hw_iic_start(hw_iic_dev iic); void hw_iic_stop(hw_iic_dev iic); void hw_iic_reset(hw_iic_dev iic); void hw_iic_err_reset(hw_iic_dev iic); u8 hw_iic_tx_byte(hw_iic_dev iic, u8 byte); u8 hw_iic_rx_byte(hw_iic_dev iic, u8 ack, s8 *err);//err:错误返回 int hw_iic_read_buf(hw_iic_dev iic, void *buf, int len); int hw_iic_write_buf(hw_iic_dev iic, const void *buf, int len); int hw_iic_set_baud(hw_iic_dev iic, u32 baud); void hw_iic_set_ack(hw_iic_dev iic, u8 ack_en); void hw_iic_set_ie(hw_iic_dev iic, i2c_pnd_typedef png, u8 en); u8 hw_iic_get_pnd(hw_iic_dev iic, i2c_pnd_typedef png); void hw_iic_clr_pnd(hw_iic_dev iic, i2c_pnd_typedef png); void hw_iic_clr_all_pnd(hw_iic_dev iic); #if HW_IIC_MASTER_ISR_EN //iic主机中断接口 struct hw_iic_master_isr_transmit { u8 *data_buf;//收发数据buf u8 *reg_buf;//寄存器buf OS_SEM sem; u16 tx_len;//要发送的长tx_len,rx_len不能同时赋值 u16 rx_len;//要接收的长tx_len,rx_len不能同时赋值 u16 xfer_postion;//=0,返回通信数据长 enum iic_state_enum result;//通信结果。0:ok,<0:error u8 reg_len; u8 dev_addr;//从机设备地址 u8 restart_flag;//是否有restart.1:发送restart,0不发 }; //支持协议: //tx: start,addr write,data0,data1,,,,,,stop //rx:start,addr read,data0,data1,,,,,nack,stop //tx: start,addr write,regx,data0,data1,,,,,,stop //rx:start,addr write,regx,start,addr read,data0,data1,,,,,nack,stop //tx/rx:start,addr,regx write/read,data0,data1,,,,,nack,stop //会修改结构体值,每次调用需初始化结构体 //timeout:byte间隔等待时间。0:一直等, >0:*10ms(超时未通信完直接stop), <0:不等待(需确保结构体参数在通信结束前有效) //不可在低优先级中断等 enum iic_state_enum hw_iic_master_isr_transmit_cfg(hw_iic_dev iic, struct hw_iic_master_isr_transmit *info, int timeout); //非阻塞获取iic主机中断传输状态 enum iic_state_enum hw_iic_master_isr_get_status(hw_iic_dev iic); #endif #define MASTER_IIC_WRITE_MODE_FAST_RESP 0 #define MASTER_IIC_READ_MODE_FAST_RESP 0//接收移位,客户根据协议修改 #define SLAVE_NO_STRETCH_AUTO_TASK 0 // 1+PULL_IIC_BUS=0:图3(no stretch) //从机接口: enum iic_slave_rx_state { IIC_SLAVE_RX_PREPARE_TIMEOUT = -1, IIC_SLAVE_RX_PREPARE_OK = 0, IIC_SLAVE_RX_PREPARE_END_OK = 1, IIC_SLAVE_RX_ADDR_NO_MATCH = -2, IIC_SLAVE_RX_ADDR_TX = 2, IIC_SLAVE_RX_ADDR_RX = 3, IIC_SLAVE_RX_DATA = 4, }; enum iic_state_enum hw_iic_slave_init(hw_iic_dev iic, struct hw_iic_slave_config *i2c_config); void hw_iic_slave_set_addr(hw_iic_dev iic, u8 addr, u8 addr_ack); void hw_iic_slave_set_isr_func(hw_iic_dev iic, void (*iic_slave_irq_func)(void)); u8 hw_iic_slave_get_addr(hw_iic_dev iic); enum iic_slave_rx_state hw_iic_slave_rx_prepare(hw_iic_dev iic, u8 ack, u32 wait_time);//轮询, 准备收 //判断地址,返回数据类型, 不检查结束位 enum iic_slave_rx_state hw_iic_slave_rx_byte(hw_iic_dev iic, u8 *rx_byte); int hw_iic_slave_rx_nbyte(hw_iic_dev iic, u8 *rx_buf);//轮询,含结束位 u8 hw_iic_slave_tx_check_ack(hw_iic_dev iic);//return:1:ack; 0:no ack void hw_iic_slave_tx_byte(hw_iic_dev iic, u8 byte);//准备发 int hw_iic_slave_tx_nbyte(hw_iic_dev iic, u8 *tx_buf);//轮询,含结束位 #endif