MAX_CARLINK_A270S/MXC_A27-PCB4.5-270T/ArkmicroFiles/libboard-amt630hv100/source/i2c-slave-eeprom.c

103 lines
1.9 KiB
C
Raw Normal View History

2025-01-21 16:49:37 +08:00
#include "FreeRTOS.h"
#include "board.h"
#include "chip.h"
#ifdef I2C_EEPROM_SLAVE_DEMO
#if !defined(I2C0_SLAVE_MODE) && !defined(I2C1_SLAVE_MODE)
#error "i2c eeprom slave demo needs a slave mode i2c dev"
#endif
#define I2C_EEPROM_24C02_ADDR 0x50
#define I2C_EEPROM_24C02_SIZE 256
struct eeprom_data {
bool first_write;
u8 buffer_idx;
u8 buffer[];
};
static struct eeprom_data *g_eeprom = NULL;
static struct i2c_adapter *g_adap = NULL;
static int i2c_slave_eeprom_slave_cb(struct i2c_adapter *adap,
enum i2c_slave_event event, u8 *val)
{
struct eeprom_data *eeprom = g_eeprom;
switch (event) {
case I2C_SLAVE_WRITE_RECEIVED:
if (eeprom->first_write) {
eeprom->buffer_idx = *val;
eeprom->first_write = false;
} else {
eeprom->buffer[eeprom->buffer_idx++] = *val;
}
break;
case I2C_SLAVE_READ_REQUESTED:
*val = eeprom->buffer[eeprom->buffer_idx++];
/*
* Do not increment buffer_idx here, because we don't know if
* this byte will be actually used. Read Linux I2C slave docs
* for details.
*/
break;
case I2C_SLAVE_STOP:
case I2C_SLAVE_WRITE_REQUESTED:
eeprom->first_write = true;
break;
default:
break;
}
return 0;
}
int i2c_slave_eeprom_init(void)
{
struct eeprom_data *eeprom;
int ret;
unsigned size = I2C_EEPROM_24C02_SIZE;
struct i2c_adapter *adap = NULL;
eeprom = pvPortMalloc(sizeof(struct eeprom_data) + size);
if (!eeprom)
return -ENOMEM;
g_eeprom = eeprom;
eeprom->first_write = true;
#ifdef I2C0_SLAVE_MODE
adap = i2c_open("i2c0");
#else
adap = i2c_open("i2c1");
#endif
if (!adap) {
printf("%s open i2c fail.\n", __func__);
vPortFree(eeprom);
return -1;
}
g_adap = adap;
ret = i2c_slave_register(adap, I2C_EEPROM_24C02_ADDR, i2c_slave_eeprom_slave_cb);
if (ret) {
return ret;
}
return 0;
};
int i2c_slave_eeprom_uninit(void)
{
if (g_adap)
i2c_slave_unregister(g_adap);
if (g_eeprom)
vPortFree(g_eeprom);
return 0;
}
#endif