123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297 |
- #include "include.h"
- #if I2C_SW_EN
- //AT(.text.bsp.i2c)
- //static void bsp_i2c_delay(void)
- //{
- // u8 delay = 60;
- // while (delay--) {
- // asm("nop");
- // }
- //}
- #define bsp_i2c_delay() delay_us(5)
- //ACK: The transmitter releases the SDA line (HIGH->LOW) during the acknowledge clock pulse
- AT(.text.bsp.i2c)
- void bsp_i2c_tx_ack(void)
- {
- I2C_SDA_OUT();
- I2C_SDA_L();
- bsp_i2c_delay();
- I2C_SCL_H();
- bsp_i2c_delay();
- I2C_SCL_L();
- }
- AT(.text.bsp.i2c)
- bool bsp_i2c_rx_ack(void)
- {
- bool ret = false;
- I2C_SDA_IN();
- bsp_i2c_delay();
- I2C_SCL_H();
- bsp_i2c_delay();
- if (!I2C_SDA_IS_H()) {
- ret = true;
- }
- I2C_SCL_L();
- return ret;
- }
- //NACK: The transmitter holds the SDA line (keep HIGH) during the acknowledge clock pulse
- AT(.text.bsp.i2c)
- void bsp_i2c_tx_nack(void)
- {
- I2C_SDA_OUT();
- I2C_SDA_H();
- bsp_i2c_delay();
- I2C_SCL_H();
- bsp_i2c_delay();
- I2C_SCL_L();
- }
- //START: A HIGH to LOW transition on the SDA line while SCL is HIGH is one such unique case.
- AT(.text.bsp.i2c)
- void bsp_i2c_start(void)
- {
- #if I2C_MUX_SD_EN
- if (sdcard_detect_is_busy()) {
- return;
- }
- if (FUNCMCON0 & 0x0f) {
- FUNCMCON0 = 0x0f;
- delay_us(5);
- }
- #endif // I2C_MUX_SD_EN
- I2C_SDA_SCL_OUT();
- I2C_SDA_SCL_H();
- bsp_i2c_delay();
- I2C_SDA_L();
- bsp_i2c_delay();
- I2C_SCL_L();
- }
- //STOP: A LOW to HIGH transition on the SDA line while SCL is HIGH
- AT(.text.bsp.i2c)
- void bsp_i2c_stop(void)
- {
- I2C_SDA_OUT();
- I2C_SDA_L();
- bsp_i2c_delay();
- I2C_SCL_H();
- bsp_i2c_delay();
- I2C_SDA_H();
- }
- //tx 1byte
- AT(.text.bsp.i2c)
- void bsp_i2c_tx_byte(uint8_t dat)
- {
- u8 i;
- I2C_SDA_OUT();
- for (i=0; i<8; i++) {
- if (dat & BIT(7)) {
- I2C_SDA_H();
- } else {
- I2C_SDA_L();
- }
- bsp_i2c_delay();
- I2C_SCL_H();
- bsp_i2c_delay();
- I2C_SCL_L();
- dat <<= 1;
- }
- }
- //rx 1byte
- AT(.text.bsp.i2c)
- uint8_t bsp_i2c_rx_byte(void)
- {
- u8 i, dat = 0;
- I2C_SDA_IN();
- for (i=0; i<8; i++) {
- bsp_i2c_delay();
- I2C_SCL_H();
- bsp_i2c_delay();
- dat <<= 1;
- if (I2C_SDA_IS_H()) {
- dat |= BIT(0);
- }
- I2C_SCL_L();
- }
- return dat;
- }
- AT(.text.bsp.i2c)
- void bsp_i2c_init(void)
- {
- I2C_SDA_SCL_OUT();
- I2C_SDA_H();
- delay_5ms(2);
- }
- #endif
- #if I2C_HW_EN
- //AT(.com_rodata.i2c)
- //const char str[] = "i2c read data:%x\n";
- //AT(.com_rodata.i2c)
- //const char str1[] = "i2c send\n";
- volatile uint8_t i2c_tx_done_flag;
- volatile uint8_t i2c_rx_done_flag;
- AT(.com_text.i2c) WEAK
- void bsp_i2c_isr(void)
- {
- if (IICCON0 & BIT(31)) {
- IICCON0 |= BIT(29);
- if (IICCON1 & RDATA) { //read data done
- // printf(str, IICDATA);
- i2c_rx_done_flag = 1;
- }
- if (IICCON1 & WDATA) { //send data done
- // printf(str1);
- }
- i2c_tx_done_flag = 1;
- }
- }
- static u32 bsp_i2c_config(u32 i2c_cfg, u16 dev_addr, u16 reg_addr, u32 dat)
- {
- u16 timeout = 1000;
- while (!i2c_tx_done_flag && timeout--) {
- delay_us(1);
- }
- i2c_tx_done_flag = 0;
- IICCMDA = (u8)dev_addr | ((u32)(dev_addr >> 8)) << 24 |
- (u32)((u8)reg_addr) << 8 | (u32)((u8)(reg_addr >> 8)) << 16;
- IICCON1 = DATA_CNT_1B | i2c_cfg;
- IICDATA = dat;
- IICCON0 |= BIT(28); // kick
- if (i2c_cfg & RDATA) {
- timeout = 1000;
- while (!i2c_rx_done_flag && timeout--) {
- delay_us(1);
- }
- i2c_rx_done_flag = 0;
- return IICDATA;
- } else {
- return 0;
- }
- }
- void bsp_i2c_tx_byte(u16 dev_addr, u16 reg_addr, u32 data)
- {
- bsp_i2c_config(START_FLAG0 | DEV_ADDR0 | REG_ADDR_0 | WDATA | STOP_FLAG, dev_addr, reg_addr, data);
- }
- void bsp_i2c_rx_buf(u16 dev_addr, u16 reg_addr, u8 *buf, u16 len)
- {
- int i;
- u32 cfg;
- if (buf == NULL || len == 0) {
- return;
- }
- for (i = 0; i < len; i++) {
- cfg = RDATA;
- if (i == 0) { //ÊÕµÚ1byte
- cfg |= START_FLAG0 | DEV_ADDR0 | REG_ADDR_0 | START_FLAG1 | DEV_ADDR1;
- }
- if (i == (len - 1)) { //ÊÕ×îºó1byte
- cfg |= STOP_FLAG | NACK;
- }
- buf[i] = bsp_i2c_config(cfg, dev_addr, reg_addr, 0);
- }
- }
- void bsp_i2c_init(void)
- {
- CLKCON1 = (CLKCON1 & ~(1 << 27)) | (0 << 27); //I2C clk select, 0:rc2m_clk, 1:x26m_clkdiv8
- CLKGAT0 |= BIT(11); //I2C clk enable
- RSTCON0 |= BIT(3); //I2C release reset, enable model function
- RTCCON3 &= ~BIT(6);
- FUNCMCON2 = 0xf << 24;
- #if (I2C_MAPPING == I2CMAP_PA7PA6)
- GPIOADE |= BIT(7) | BIT(6);
- GPIOADIR |= BIT(7) | BIT(6);
- GPIOAPU |= BIT(7) | BIT(6);
- GPIOAFEN |= BIT(7) | BIT(6);
- FUNCMCON2 = I2CMAP_PA7PA6;
- #elif (I2C_MAPPING == I2CMAP_PA5PA6)
- GPIOADE |= BIT(5) | BIT(6);
- GPIOADIR |= BIT(5) | BIT(6);
- GPIOAPU |= BIT(5) | BIT(6);
- GPIOAFEN |= BIT(5) | BIT(6);
- FUNCMCON2 = I2CMAP_PA5PA6;
- #elif (I2C_MAPPING == I2CMAP_PB2PB1)
- GPIOBDE |= BIT(2) | BIT(1);
- GPIOBDIR |= BIT(2) | BIT(1);
- GPIOBPU |= BIT(2) | BIT(1);
- GPIOBFEN |= BIT(2) | BIT(1);
- FUNCMCON2 = I2CMAP_PB2PB1;
- #elif (I2C_MAPPING == I2CMAP_PB0PB1)
- GPIOBDE |= BIT(0) | BIT(1);
- GPIOBDIR |= BIT(0) | BIT(1);
- GPIOBPU |= BIT(0) | BIT(1);
- GPIOBFEN |= BIT(0) | BIT(1);
- FUNCMCON2 = I2CMAP_PB0PB1;
- #elif (I2C_MAPPING == I2CMAP_PE7PE6)
- GPIOEDE |= BIT(7) | BIT(6);
- GPIOEDIR |= BIT(7) | BIT(6);
- GPIOEPU |= BIT(7) | BIT(6);
- GPIOEFEN |= BIT(7) | BIT(6);
- FUNCMCON2 = I2CMAP_PE7PE6;
- #elif (I2C_MAPPING == I2CMAP_PE5PE6)
- GPIOEDE |= BIT(5) | BIT(6);
- GPIOEDIR |= BIT(5) | BIT(6);
- GPIOEPU |= BIT(5) | BIT(6);
- GPIOEFEN |= BIT(5) | BIT(6);
- FUNCMCON2 = I2CMAP_PE5PE6;
- #elif (I2C_MAPPING == I2CMAP_PB4PB3)
- GPIOBDE |= BIT(4) | BIT(3);
- GPIOBDIR |= BIT(4) | BIT(3);
- GPIOBPU |= BIT(4) | BIT(3);
- GPIOBFEN |= BIT(4) | BIT(3);
- FUNCMCON2 = I2CMAP_PB4PB3;
- #elif (I2C_MAPPING == I2CMAP_PF1PF0)
- GPIOFDE |= BIT(0) | BIT(1);
- GPIOFDIR |= BIT(0) | BIT(1);
- GPIOFPU |= BIT(0) | BIT(1);
- GPIOFFEN |= BIT(0) | BIT(1);
- FUNCMCON2 = I2CMAP_PF1PF0;
- #endif
- i2c_tx_done_flag = 1;
- i2c_rx_done_flag = 0;
- // IICCON1 = 1 << 0 | // data cnt
- // 1 << 3 | // start0 en
- // 1 << 4 | // ctl0 en
- // 1 << 5 | // adr0 en
- // 0 << 6 | // adr1 en
- // 0 << 7 | // start1 en
- // 0 << 8 | // ctl1 en
- // 0 << 9 | // rdat en
- // 1 << 10| // wdat en
- // 1 << 11| // stop en
- // 0 << 12; // txnaken
- IICCON0 = 1 << 0 | // iicen
- 1 << 1 | // iic int
- 1 << 2 | // hold cnt[3:2]
- 9 << 4 ; // pos div [9:4]
- }
- #else
- AT(.com_text.i2c) WEAK
- void bsp_i2c_isr(void)
- {
- }
- #endif
|