199 lines
4.4 KiB
C
199 lines
4.4 KiB
C
|
/**
|
||
|
****************************************************************************************
|
||
|
*
|
||
|
* @file i2c_test.c
|
||
|
*
|
||
|
* @brief Demo of I2C Master/Slave Usage.
|
||
|
*
|
||
|
****************************************************************************************
|
||
|
*/
|
||
|
|
||
|
#include "string.h"
|
||
|
#include "b6x.h"
|
||
|
#include "drvs.h"
|
||
|
#include "dbg.h"
|
||
|
|
||
|
|
||
|
/*
|
||
|
* DEFINES
|
||
|
****************************************************************************************
|
||
|
*/
|
||
|
|
||
|
#define PIN_I2C_SCL PA11
|
||
|
#define PIN_I2C_SDA PA12
|
||
|
#define GPIO_I2C_TEST GPIO02
|
||
|
|
||
|
#define I2C_SLV_ADDR 0x57 // AT24C64 Eeprom
|
||
|
#define I2C_SLV_WRITE ((I2C_SLV_ADDR << 1) | 0x0)
|
||
|
#define I2C_SLV_READ ((I2C_SLV_ADDR << 1) | 0x1)
|
||
|
|
||
|
#define AT24C64_EEP ((I2C_SLV_ADDR << 1))
|
||
|
|
||
|
#define AT24C64_DATA_ADDR 0x20
|
||
|
|
||
|
#define DATA_BUFF_LEN 16
|
||
|
|
||
|
|
||
|
/*
|
||
|
* FUNCTIONS
|
||
|
****************************************************************************************
|
||
|
*/
|
||
|
|
||
|
#if (I2C_ROLE_SLAVE)
|
||
|
|
||
|
#define MEM_ADDR_BASE 0x20008000
|
||
|
|
||
|
uint8_t dataBuff[258] = {0};
|
||
|
uint16_t buff_pos = 0;
|
||
|
uint32_t mem_addr = 0;
|
||
|
|
||
|
static void i2c_isr(void)
|
||
|
{
|
||
|
if (I2C_IFLG_GET() == 0)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
debug("I2C status:0x%02X\r\n", I2C_STAT_GET());
|
||
|
|
||
|
switch (I2C_STAT_GET())
|
||
|
{
|
||
|
case I2C_SS_RECV_ADDR_W:
|
||
|
{
|
||
|
|
||
|
} break;
|
||
|
|
||
|
case I2C_SS_RECV_DAT_ACK:
|
||
|
{
|
||
|
I2C_DATA_GET(dataBuff[buff_pos++]);
|
||
|
} break;
|
||
|
|
||
|
case I2C_SS_RECV_STOP_OR_RESTART:
|
||
|
{
|
||
|
mem_addr = (MEM_ADDR_BASE + (dataBuff[0]<<8|dataBuff[1]));
|
||
|
|
||
|
if (buff_pos > 2)
|
||
|
{
|
||
|
memcpy((uint8_t *)(mem_addr), &dataBuff[2], buff_pos-2);
|
||
|
}
|
||
|
buff_pos = 0;
|
||
|
} break;
|
||
|
|
||
|
case I2C_SS_RECV_ADDR_R_ACK:
|
||
|
case I2C_SS_SEND_DAT_ACK:
|
||
|
{
|
||
|
I2C_DATA_PUT(*(uint8_t *)(mem_addr++));
|
||
|
} break;
|
||
|
}
|
||
|
|
||
|
I2C_IFLG_CLR();
|
||
|
|
||
|
NVIC_ClearPendingIRQ(I2C_IRQn);
|
||
|
NVIC_EnableIRQ(I2C_IRQn);
|
||
|
}
|
||
|
|
||
|
void I2C_IRQHandler(void)
|
||
|
{
|
||
|
NVIC_DisableIRQ(I2C_IRQn);
|
||
|
|
||
|
//i2c_isr();
|
||
|
}
|
||
|
|
||
|
static void i2cProc(void)
|
||
|
{
|
||
|
while (1)
|
||
|
{
|
||
|
i2c_isr(); // polling
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#else // (I2C_ROLE_MASTER)
|
||
|
|
||
|
static void i2cProc(void)
|
||
|
{
|
||
|
uint16_t cnt;
|
||
|
uint8_t buff_tx[DATA_BUFF_LEN];
|
||
|
uint8_t buff_rx[DATA_BUFF_LEN];
|
||
|
|
||
|
// I2C access as eeprom
|
||
|
debug("** I2C Master RD(0x%02X)/WR(0x%02X) 1B \r\n", I2C_SLV_READ, I2C_SLV_WRITE);
|
||
|
|
||
|
buff_tx[0] = (AT24C64_DATA_ADDR >> 8) & 0xFF;
|
||
|
buff_tx[1] = AT24C64_DATA_ADDR & 0xFF; // data addr MSB
|
||
|
buff_tx[2] = 0x5A; // 1B data
|
||
|
|
||
|
i2c_write(I2C_SLV_WRITE, 3, buff_tx); // write 1byte (3len-2addr)
|
||
|
debug("I2C WR_E2(ByteVal=0x5A)...\r\n");
|
||
|
bootDelayMs(60);
|
||
|
|
||
|
i2c_write(I2C_SLV_WRITE, 2, buff_tx); // data addr MSB
|
||
|
cnt = i2c_read(I2C_SLV_READ, 1, buff_rx);
|
||
|
debug("I2C RD_E2(len=%d, ByteVal=0x%02X) -> %s\r\n", cnt, buff_rx[0], (buff_rx[0]==0x5A)?"OK":"FAIL");
|
||
|
|
||
|
// Eeprom Test
|
||
|
debug("** Eeprom(0x%02X) RD/WR at_0x%04X \r\n", AT24C64_EEP, AT24C64_DATA_ADDR);
|
||
|
|
||
|
cnt = eeprom_read(AT24C64_EEP, AT24C64_DATA_ADDR, DATA_BUFF_LEN, buff_rx);
|
||
|
debug("Read(len=%d) before:\r\n", cnt);
|
||
|
debugHex(buff_rx, cnt);
|
||
|
|
||
|
for (uint16_t i = 0; i < DATA_BUFF_LEN; i++)
|
||
|
{
|
||
|
buff_tx[i] = buff_rx[i] + 2; // autoInc
|
||
|
}
|
||
|
|
||
|
cnt = eeprom_write(AT24C64_EEP, AT24C64_DATA_ADDR, DATA_BUFF_LEN, buff_tx);
|
||
|
debug("Write(len=%d), autoInc 2...\r\n", cnt);
|
||
|
bootDelayMs(60); // delay 10ms, wait write complete
|
||
|
|
||
|
cnt = eeprom_read(AT24C64_EEP, AT24C64_DATA_ADDR, DATA_BUFF_LEN, buff_rx);
|
||
|
debug("Read(len=%d) after:\r\n", cnt);
|
||
|
debugHex(buff_rx, cnt);
|
||
|
|
||
|
if ((cnt == DATA_BUFF_LEN) && (memcmp(buff_tx, buff_rx, DATA_BUFF_LEN) == 0))
|
||
|
{
|
||
|
debug("** I2C-Master Test End -> OK\r\n\r\n");
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
debug("** I2C-Master Test End -> FAIL\r\n\r\n");
|
||
|
}
|
||
|
|
||
|
while (1)
|
||
|
{
|
||
|
// empty
|
||
|
};
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
static void i2cInit(void)
|
||
|
{
|
||
|
i2c_init(PIN_I2C_SCL, PIN_I2C_SDA, SCLK_100K);
|
||
|
|
||
|
#if (I2C_ROLE_SLAVE)
|
||
|
I2C_SET_ACK();
|
||
|
I2C_SLV_ADR(0x57);
|
||
|
|
||
|
// Enable interrupt
|
||
|
I2C_INT_EN();
|
||
|
|
||
|
NVIC_ClearPendingIRQ(I2C_IRQn);
|
||
|
NVIC_EnableIRQ(I2C_IRQn);
|
||
|
__enable_irq();
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
void i2cTest(void)
|
||
|
{
|
||
|
#if (FPGA_TEST)
|
||
|
// FPGA 48M need use 24M 20221119 --whl
|
||
|
RCC->APB1CLK_DIV = 1;
|
||
|
#endif
|
||
|
|
||
|
debug("i2cTest Start...\r\n");
|
||
|
|
||
|
i2cInit();
|
||
|
|
||
|
i2cProc();
|
||
|
}
|