/* * Copyright (c) 2022-2023, ArtInChip Technology Co., Ltd * * SPDX-License-Identifier: Apache-2.0 */ #include #include #include #include #include #include #include #include #include #include #include #define I2C_HELP \ "i2c write data\n" \ "i2c read \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");