Files
luban-lite-t3e-pro/bsp/examples_bare/test-i2c/test_eeprom.c
刘可亮 3b4064f334 v1.0.2
2023-11-30 19:48:02 +08:00

166 lines
5.0 KiB
C

/*
* Copyright (c) 2022-2023, ArtInChip Technology Co., Ltd
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <console.h>
#include <aic_common.h>
#include <aic_errno.h>
#include <aic_core.h>
#include <unistd.h>
#include <hal_i2c.h>
#include <aic_soc.h>
#define I2C_HELP \
"i2c write <I2C BUS ID> <slave addr> <reg_addr> data\n" \
"i2c read <I2C BUS ID> <slave addr> <reg_addr>\n" \
"This program is used to test master read&write eeprom function of i2c\n " \
"Example:\n" \
"write one byte: i2c write 0 0x50 0x0000 0x11\n" \
"read one byte: i2c read 0 0x50 0x0000 \n" \
"tips: slave addr is 16bit such as : 0x1234\n" \
" if use se_i2c please input bus_id write 5\n"
#define I2C_BASE_OFFSET 0x1000
#define SE_BUS_ID (CLK_I2C0 - CLK_SE_I2C)
#ifdef SE_I2C_BASE
#define I2C_REG_BASE(x) (SE_I2C_BASE)
#else
#define I2C_REG_BASE(x) (I2C0_BASE + (x * I2C_BASE_OFFSET))
#endif
void i2c_usage(void)
{
puts(I2C_HELP);
}
struct aic_i2c_msg *i2c_msg;
void read_eeprom(unsigned long reg_base, struct aic_i2c_msg *msg)
{
uint8_t *receive_data = msg->buf;
unsigned long reg_data;
aic_i2c_module_disable(reg_base);
aic_i2c_target_addr(reg_base, msg->addr);
aic_i2c_module_enable(reg_base);
aic_i2c_transmit_data(reg_base, receive_data[0]); //write high_address
aic_i2c_transmit_data(reg_base, receive_data[1]); //write low_address
aic_i2c_transmit_data(reg_base, I2C_INTR_ACTIVITY | I2C_INTR_STOP_DET); //read signal
while ((aic_i2c_get_raw_interrupt_state(reg_base) & I2C_INTR_STOP_DET) == 0) {;};
reg_data = aic_i2c_get_receive_data(reg_base);
printf("read_data = 0x%lx\n", reg_data);
}
void write_eeprom(unsigned long reg_base, struct aic_i2c_msg *msg)
{
uint8_t *send_data = msg->buf;
aic_i2c_module_disable(reg_base);
aic_i2c_target_addr(reg_base, msg->addr);
aic_i2c_module_enable(reg_base);
aic_i2c_transmit_data(reg_base, send_data[0]); //write high_address
aic_i2c_transmit_data(reg_base, send_data[1]); //write low_address
aic_i2c_transmit_data(reg_base, send_data[2] | I2C_INTR_STOP_DET); //write data
while ((aic_i2c_get_raw_interrupt_state(reg_base) & I2C_INTR_STOP_DET) == 0) {;};
aic_i2c_module_disable(reg_base);
}
static int test_i2c_example(int argc, char *argv[])
{
int bus_id = 0;
struct aic_i2c_msg *msgs = NULL;
msgs = aicos_malloc(MEM_CMA, sizeof(struct aic_i2c_msg));
if (!msgs) {
hal_log_err("msgs malloc fail\n");
goto __exit;
}
memset(msgs, 0, sizeof(struct aic_i2c_msg));
uint16_t buf_size = 10;
msgs->buf = aicos_malloc(MEM_CMA, buf_size);
if (!msgs->buf) {
hal_log_err("buf malloc fail\n");
goto __exit;
}
if (argc < 5) {
i2c_usage();
goto __exit;
}
bus_id = atoi(argv[2]);
if (bus_id < 0 || bus_id > 5) {
hal_log_err("bus id param error,pleaseinput range 0-5\n");
goto __exit;
}
uint16_t slave_addr = strtol((argv[3]), NULL, 16);
msgs->addr = slave_addr;
/* get reg high addr&low addr */
uint16_t data = strtol((argv[4]), NULL, 16);
uint8_t high_addr = data >> 8;
uint8_t low_addr = data & 0xff;
memcpy(&msgs->buf[0], &high_addr, 1);
memcpy(&msgs->buf[1], &low_addr, 1);
if (argc == 6) {
uint16_t write_data = strtol(argv[5], NULL, 16);
memcpy(&msgs->buf[2], &write_data, 1);
printf("write_data = 0x%x\n", write_data);
}
int ret = -1;
#ifdef SE_I2C_BASE
ret = aic_i2c_init(SE_BUS_ID);
#else
ret = aic_i2c_init(bus_id);
#endif
if (ret) {
hal_log_err("init error\n");
goto __exit;
}
ret = aic_i2c_set_master_slave_mode(I2C_REG_BASE(bus_id), true);
if (ret) {
hal_log_err("mode set error\n");
goto __exit;
}
hal_i2c_set_hold(I2C_REG_BASE(bus_id), 10);
aic_i2c_master_10bit_addr(I2C_REG_BASE(bus_id), false);
aic_i2c_slave_10bit_addr(I2C_REG_BASE(bus_id), false);
aic_i2c_master_enable_transmit_irq(I2C_REG_BASE(bus_id));
aic_i2c_master_enable_receive_irq(I2C_REG_BASE(bus_id));
aic_i2c_speed_mode_select(I2C_REG_BASE(bus_id), I2C_DEFALT_CLOCK, true);
aic_i2c_module_enable(I2C_REG_BASE(bus_id));
if (!strcmp(argv[1], "write")) {
write_eeprom(I2C_REG_BASE(bus_id), msgs);
} else if (!strcmp(argv[1], "read")) {
read_eeprom(I2C_REG_BASE(bus_id), msgs);
}
__exit:
if (msgs != NULL) {
if (msgs->buf != NULL) {
aicos_free(MEM_CMA, msgs->buf);
}
aicos_free(MEM_CMA, msgs);
}
return 0;
}
CONSOLE_CMD(i2c, test_i2c_example, "i2c-tools");