/* * i2c_drv.c * * Created on: 02/05/2017. * Author: pvvx */ #include "driver/i2c_drv.h" #include "rtl_lib.h" #if CONFIG_I2C_EN #include "pinmap.h" typedef struct { unsigned char sda; unsigned char scl; unsigned char sel; unsigned char id; } PinMapI2C; #define I2C_SEL(idx, ps) ((idx<<4) | ps) static const PinMapI2C PinMap_I2C[] = { // sda, scl, sel, id // I2C0 {PD_4, PD_5, I2C_SEL(0, S0), I2C0}, {PH_1, PH_0, I2C_SEL(0, S1), I2C0}, {PC_8, PC_9, I2C_SEL(0, S2), I2C0}, {PE_7, PE_6, I2C_SEL(0, S3), I2C0}, // I2C1 {PC_4, PC_5, I2C_SEL(1, S0), I2C1}, {PH_3, PH_2, I2C_SEL(1, S1), I2C1}, {PD_7, PD_6, I2C_SEL(1, S2), I2C1}, // I2C2 {PB_7, PB_6, I2C_SEL(2, S0), I2C2}, {PE_1, PE_0, I2C_SEL(2, S1), I2C2}, {PC_7, PC_6, I2C_SEL(2, S2), I2C2}, // I2C3 {PB_3, PB_2, I2C_SEL(3, S0), I2C3}, {PE_3, PE_2, I2C_SEL(3, S1), I2C3}, {PE_5, PE_4, I2C_SEL(3, S2), I2C3}, {PD_9, PD_8, I2C_SEL(3, S3), I2C3}, {0xff, 0xff, 0, 0} }; static void * i2c_base_reg[4] = { (void *)I2C0_REG_BASE, (void *)I2C1_REG_BASE, (void *)I2C2_REG_BASE, (void *)I2C3_REG_BASE }; #if 1 #define test_printf(...) #define i2c_dump_regs(p) #else #define test_printf rtl_printf static int i2c_dump_regs(i2c_drv_t *pi2c) { uint32 *ptr = pi2c->base_regs; test_printf("%s:", __func__); for(int i = 0; i < (0xA0>>2); i++) { if(!(i%4)) { test_printf("\n%08x:", &ptr[i]); } test_printf("\t%08x", ptr[i]); } test_printf("\n"); } #endif #define i2c_reg(r) *((volatile uint32 *)(pi2c->base_regs + r)) // flg =0 write, =1 Read static int i2c_ready(i2c_drv_t *pi2c, unsigned char flg) { test_printf("%s:\n", __func__); // Test enable i2c if(!(i2c_reg(REG_DW_I2C_IC_ENABLE) & BIT_IC_ENABLE)) { error_printf("I2C%d disable!\n", pi2c->idx); pi2c->status = DRV_I2C_IC_OFF; return DRV_I2C_IC_OFF; } // Wait Receive FIFO is empty & Transmit FIFO Completely Empty int poll_count = DRV_I2C_POOL_TIMEOUT; do { if(i2c_reg(REG_DW_I2C_IC_RAW_INTR_STAT) & BIT_IC_RAW_INTR_STAT_TX_ABRT) { error_printf("I2C%d Abort!\n", pi2c->idx); // Clear abort status. (volatile uint32)i2c_reg(REG_DW_I2C_IC_CLR_TX_ABRT); // Be sure that all interrupts flag are cleared. // i2c_reg(REG_DW_I2C_IC_CLR_INTR); pi2c->status = DRV_I2C_ABORT; return DRV_I2C_ABORT; } if(flg) { // Receive FIFO ready ? if(i2c_reg(REG_DW_I2C_IC_STATUS) & (BIT_IC_STATUS_RFNE | BIT_IC_STATUS_RFF)) { // pi2c->status = DRV_I2C_IC_ENABLE; return DRV_I2C_OK; } } else { // Transmit FIFO is not full ? if(i2c_reg(REG_DW_I2C_IC_STATUS) & BIT_IC_STATUS_TFNF) { // pi2c->status = DRV_I2C_IC_ENABLE; return DRV_I2C_OK; } } } while(poll_count--); error_printf("I2C%d Timeout!\n", pi2c->idx); pi2c->status = DRV_I2C_TIMEOUT; return DRV_I2C_TIMEOUT; } int _i2c_break(i2c_drv_t *pi2c) { test_printf("%s\n", __func__); // i2c_reg(REG_DW_I2C_IC_CLR_INTR); // ABORT operation int poll_count = DRV_I2C_POOL_TIMEOUT; i2c_reg(REG_DW_I2C_IC_ENABLE) |= 2; // Wait until controller is disabled. while(i2c_reg(REG_DW_I2C_IC_ENABLE) & 2) { if(poll_count-- <= 0) { error_printf("Error abort i2c%d\n", pi2c->idx); pi2c->status = DRV_I2C_TIMEOUT; return DRV_I2C_TIMEOUT; }; }; pi2c->status = DRV_I2C_OFF; // All interrupts flag are cleared. (volatile uint32)i2c_reg(REG_DW_I2C_IC_CLR_INTR); return DRV_I2C_OK; } /* (!) вызывать после _i2c_init */ int _i2c_set_speed(i2c_drv_t *pi2c, uint32 clk_hz) { test_printf("%s:\n", __func__); if(clk_hz < 10000 || clk_hz > HalGetCpuClk()/16) { error_printf("I2C%d Error clk!\n", pi2c->idx); return DRV_I2C_ERR; } uint32 tmp; uint32 CpuClkTmp = HalGetCpuClk()/clk_hz; switch(pi2c->mode) { case I2C_SS_MODE: // Standard Speed Clock SCL High Count tmp = (CpuClkTmp * I2C_SS_MIN_SCL_HTIME)/(I2C_SS_MIN_SCL_HTIME + I2C_SS_MIN_SCL_LTIME); i2c_reg(REG_DW_I2C_IC_SS_SCL_HCNT) = BIT_CTRL_IC_SS_SCL_HCNT(tmp); // Standard Speed Clock SCL Low Count tmp = (CpuClkTmp * I2C_SS_MIN_SCL_LTIME)/(I2C_SS_MIN_SCL_HTIME + I2C_SS_MIN_SCL_LTIME); i2c_reg(REG_DW_I2C_IC_SS_SCL_LCNT) = BIT_CTRL_IC_SS_SCL_LCNT(tmp); break; case I2C_HS_MODE: // Standard Speed Clock SCL High Count i2c_reg(REG_DW_I2C_IC_SS_SCL_HCNT) = BIT_CTRL_IC_SS_SCL_HCNT(400); // Standard Speed Clock SCL Low Count i2c_reg(REG_DW_I2C_IC_SS_SCL_LCNT) = BIT_CTRL_IC_SS_SCL_LCNT(470); // Fast Speed Clock SCL High Count i2c_reg(REG_DW_I2C_IC_FS_SCL_HCNT) = BIT_CTRL_IC_FS_SCL_HCNT(85); // Fast Speed I2C Clock SCL Low Count i2c_reg(REG_DW_I2C_IC_FS_SCL_LCNT) = BIT_CTRL_IC_FS_SCL_LCNT(105); // High Speed I2C Clock SCL High Count tmp = (CpuClkTmp * I2C_HS_MIN_SCL_HTIME_100)/(I2C_HS_MIN_SCL_HTIME_100 + I2C_HS_MIN_SCL_LTIME_100); if (tmp > 8) tmp -= 3; i2c_reg(REG_DW_I2C_IC_HS_SCL_HCNT) = BIT_CTRL_IC_HS_SCL_HCNT(tmp); // High Speed I2C Clock SCL Low Count tmp = (CpuClkTmp * I2C_HS_MIN_SCL_LTIME_100)/(I2C_HS_MIN_SCL_HTIME_100 + I2C_HS_MIN_SCL_LTIME_100); if (tmp > 6) tmp -= 6; i2c_reg(REG_DW_I2C_IC_HS_SCL_LCNT) = BIT_CTRL_IC_FS_SCL_LCNT(tmp); break; // case I2C_FS_MODE: default: pi2c->mode = I2C_FS_MODE; // Fast Speed Clock SCL High Count tmp = (CpuClkTmp * I2C_FS_MIN_SCL_HTIME)/(I2C_FS_MIN_SCL_HTIME + I2C_FS_MIN_SCL_LTIME); if (tmp > 4) tmp -= 4;// this part is according to the fine-tune result i2c_reg(REG_DW_I2C_IC_FS_SCL_HCNT) = BIT_CTRL_IC_FS_SCL_HCNT(tmp); // Fast Speed I2C Clock SCL Low Count tmp = (CpuClkTmp * I2C_FS_MIN_SCL_LTIME)/(I2C_FS_MIN_SCL_HTIME + I2C_FS_MIN_SCL_LTIME); if (tmp > 3) tmp -= 3; // this part is according to the fine-tune result i2c_reg(REG_DW_I2C_IC_FS_SCL_LCNT) = BIT_CTRL_IC_FS_SCL_LCNT(tmp); } return DRV_I2C_OK; } static int i2c_disable(i2c_drv_t *pi2c) { test_printf("%s:\n", __func__); pi2c->status = DRV_I2C_IC_OFF; if(i2c_reg(REG_DW_I2C_IC_ENABLE_STATUS) & BIT_IC_ENABLE_STATUS_IC_EN) { test_printf("I2C%d Already disable!\n", pi2c->idx); return DRV_I2C_OK; } // Disable controller. int poll_count = DRV_I2C_POOL_TIMEOUT; i2c_reg(REG_DW_I2C_IC_ENABLE) &= ~BIT_IC_ENABLE; // Wait until controller is disabled. while(i2c_reg(REG_DW_I2C_IC_ENABLE_STATUS) & BIT_IC_ENABLE_STATUS_IC_EN) { if(poll_count-- <= 0) { error_printf("I2C%d Error disable!\n", pi2c->idx); pi2c->status = DRV_I2C_TIMEOUT; return DRV_I2C_TIMEOUT; }; }; return DRV_I2C_OK; } static int i2c_enable(i2c_drv_t *pi2c) { test_printf("%s:\n", __func__); int poll_count = DRV_I2C_POOL_TIMEOUT; if(!(i2c_reg(REG_DW_I2C_IC_ENABLE_STATUS) & BIT_IC_ENABLE_STATUS_IC_EN)) { // Enable controller. i2c_reg(REG_DW_I2C_IC_ENABLE) = BIT_IC_ENABLE; // Wait until controller is enabled while(!(i2c_reg(REG_DW_I2C_IC_ENABLE_STATUS) & BIT_IC_ENABLE_STATUS_IC_EN)) { if(poll_count-- <= 0) { error_printf("I2C%d Error enable\n", pi2c->idx); pi2c->status = DRV_I2C_TIMEOUT; return DRV_I2C_TIMEOUT; }; }; }; // Be sure that all interrupts flag are cleared. (volatile uint32)i2c_reg(REG_DW_I2C_IC_CLR_INTR); pi2c->status = DRV_I2C_IC_ENABLE; return DRV_I2C_OK; } // IC On & Enable CLK static void _i2c_ic_on(i2c_drv_t *pi2c) { test_printf("%s:\n", __func__); uint32 tmp = 1 << (pi2c->idx << 1); HAL_PERI_ON_WRITE32(REG_PESOC_PERI_CLK_CTRL1, HAL_PERI_ON_READ32(REG_PESOC_PERI_CLK_CTRL1) | tmp); HAL_PERI_ON_WRITE32(REG_PESOC_PERI_CLK_CTRL1, HAL_PERI_ON_READ32(REG_PESOC_PERI_CLK_CTRL1) | (tmp << 1)); tmp = BIT_PERI_I2C0_EN << pi2c->idx; HAL_PERI_ON_WRITE32(REG_SOC_PERI_FUNC0_EN, HAL_PERI_ON_READ32(REG_SOC_PERI_FUNC0_EN) & (~tmp)); HAL_PERI_ON_WRITE32(REG_SOC_PERI_FUNC0_EN, HAL_PERI_ON_READ32(REG_SOC_PERI_FUNC0_EN) | tmp); tmp = HAL_READ32(PERI_ON_BASE, REG_PESOC_CLK_SEL); tmp &= (~(BIT_PESOC_PERI_SCLK_SEL(3))); HAL_WRITE32(PERI_ON_BASE, REG_PESOC_CLK_SEL, tmp); HalPinCtrlRtl8195A(I2C0 + pi2c->idx, pi2c->io_sel, 1); } // IC Off & Disable CLK void _i2c_ic_off(i2c_drv_t *pi2c) { test_printf("%s:\n", __func__); if(pi2c->status) { // mask all interrupts i2c_reg(REG_DW_I2C_IC_INTR_MASK) = 0; // Disable (Abort I2C Controller) _i2c_break(pi2c); i2c_disable(pi2c); uint32 mask = BIT_PERI_I2C0_EN << pi2c->idx; HAL_PERI_ON_WRITE32(REG_SOC_PERI_FUNC0_EN, HAL_PERI_ON_READ32(REG_SOC_PERI_FUNC0_EN) & (~mask)); HalPinCtrlRtl8195A(I2C0 + pi2c->idx, pi2c->io_sel, 0); #ifdef CONFIG_SOC_PS_MODULE REG_POWER_STATE i2cPwrState; // To register a new peripheral device power state i2cPwrState.FuncIdx = I2C0 + pi2c->idx; i2cPwrState.PwrState = INACT; RegPowerState(i2cPwrState); #endif pi2c->status = DRV_I2C_OFF; } } /* (!) вызывать до _i2c_init, если параметрв драйвера не заданы в i2c_drv_t */ int _i2c_setup(i2c_drv_t *pi2c, PinName sda, PinName scl, unsigned char mode) { test_printf("%s:\n", __func__); if(mode < DRV_I2C_SS_MODE || mode > DRV_I2C_HS_MODE) { error_printf("I2C Error mode!\n"); return DRV_I2C_ERR; } // Pins -> index PinMapI2C *p = (PinMapI2C *)PinMap_I2C; while(p->sda != 0xFF) { if(p->sda == sda && p->scl == scl) { pi2c->io_sel = RTL_GET_PERI_SEL(p->sel); pi2c->idx = RTL_GET_PERI_IDX(p->sel); pi2c->mode = mode; return DRV_I2C_OK; } p++; } error_printf("I2C Error pins!\n"); return DRV_I2C_ERR; } /* (!) Использует заполненную структуру i2c_drv_t */ int _i2c_init(i2c_drv_t *pi2c) { test_printf("%s:\n", __func__); // Set base address regs i2c pi2c->base_regs = i2c_base_reg[pi2c->idx]; // IC On & Enable CLK if(pi2c->status == DRV_I2C_OFF) _i2c_ic_on(pi2c); // mask all interrupts i2c_reg(REG_DW_I2C_IC_INTR_MASK) = 0; // disable i2c if(i2c_disable(pi2c)) return pi2c->status; // Set Control Register: // bit0: master enabled, // bit1..2: fast mode (400 kbit/s), ... // bit2: Slave Addressing Mode 7-bit // bit4: Master Addressing Mode 7-bit // bit5: Restart disable // bit6: Slave Mode Disable // bit7: STOP_DET_IFADDRESSED // bit8: TX_EMPTY_CTRL // bit9: RX_FIFO_FULL_HLD_CTRL // Set MASTER_MODE i2c_reg(REG_DW_I2C_IC_CON) = BIT_CTRL_IC_CON_MASTER_MODE(1) | BIT_IC_CON_SPEED(pi2c->mode) | BIT_CTRL_IC_CON_IC_10BITADDR_SLAVE(0) | BIT_CTRL_IC_CON_IC_10BITADDR_MASTER(0) | BIT_CTRL_IC_CON_IC_RESTART_EN(1) | BIT_CTRL_IC_CON_IC_SLAVE_DISABLE(1); // Master Target Address // i2c_reg(REG_DW_I2C_IC_TAR) = 0x40; // Slave Address // i2c_reg(REG_DW_I2C_IC_SAR) = 0x55; // High Speed Master ID (00001xxx) bit0..2 // i2c_reg(REG_DW_I2C_IC_HS_MADDR) = BIT_CTRL_IC_HS_MADDR(0x4); // Standard Speed Clock SCL High Count (100kHz) i2c_reg(REG_DW_I2C_IC_SS_SCL_HCNT) = BIT_CTRL_IC_SS_SCL_HCNT(400); // Standard Speed Clock SCL Low Count (100kHz) i2c_reg(REG_DW_I2C_IC_SS_SCL_LCNT) = BIT_CTRL_IC_SS_SCL_LCNT(470); // Fast Speed Clock SCL High Count (400kHz) i2c_reg(REG_DW_I2C_IC_FS_SCL_HCNT) = BIT_CTRL_IC_FS_SCL_HCNT(80); // Fast Speed I2C Clock SCL Low Count (400kHz) i2c_reg(REG_DW_I2C_IC_FS_SCL_LCNT) = BIT_CTRL_IC_FS_SCL_LCNT(100); // High Speed I2C Clock SCL High Count (1MHz) i2c_reg(REG_DW_I2C_IC_HS_SCL_HCNT) = BIT_CTRL_IC_HS_SCL_HCNT(30); // High Speed I2C Clock SCL Low Count (1MHz) i2c_reg(REG_DW_I2C_IC_HS_SCL_LCNT) = BIT_CTRL_IC_FS_SCL_LCNT(40); // SDA Hold (IC_CLK period, when I2C controller acts as a transmitter/receiver) i2c_reg(REG_DW_I2C_IC_SDA_HOLD) = BIT_CTRL_IC_SDA_HOLD(10); // General Call Ack i2c_reg(REG_DW_I2C_IC_ACK_GENERAL_CALL) = BIT_CTRL_IC_ACK_GENERAL_CALL(1); // Receive FIFO Threshold Level // i2c_reg(REG_DW_I2C_IC_RX_TL) = 0x0; // Transmit FIFO Threshold Level // i2c_reg(REG_DW_I2C_IC_TX_TL) = 0x0; // Transmit Abort Source // i2c_reg(REG_DW_I2C_IC_TX_ABRT_SOURCE) = 0x0; // DMA Transmit Data Level Register // i2c_reg(REG_DW_I2C_IC_DMA_TDLR) = 0x09; #ifdef CONFIG_SOC_PS_MODULE REG_POWER_STATE i2cPwrState; // To register a new peripheral device power state i2cPwrState.FuncIdx = I2C0 + pi2c->idx; i2cPwrState.PwrState = ACT; RegPowerState(i2cPwrState); #endif i2c_dump_regs(pi2c); // pi2c->status = DRV_I2C_IC_OFF; return DRV_I2C_OK; } int _i2c_write(i2c_drv_t *pi2c, uint32 address, const char *data, int length, int stop) { test_printf("%s: [%d]%d\n", __func__, length, stop); uint8_t *d = (uint8_t *)data; // Write slave address to TAR. // bit12: = 1 - 10-bit addressing mode when acting as a master // bit11: = 1 - Special Command Enable // bit10: = 1 - Special Command Type START BYTE i2c_reg(REG_DW_I2C_IC_TAR) = address; // Enable controller if(i2c_enable(pi2c)) return pi2c->status; while (length--) { // Transmit FIFO is not full if(i2c_ready(pi2c, 0)) return pi2c->status; // BIT_IC_STATUS_TFNF // Fill IC_DATA_CMD[7:0] with the data. // Send stop after last byte ? if(length == 0 && stop) i2c_reg(REG_DW_I2C_IC_DATA_CMD) = *d | BIT_IC_DATA_CMD_STOP; else i2c_reg(REG_DW_I2C_IC_DATA_CMD) = *d; d++; } // Disable controller. if(stop) { if(i2c_disable(pi2c)) return pi2c->status; } return DRV_I2C_OK; } int _i2c_read(i2c_drv_t *pi2c, uint32 address, const char *data, int length, int stop) { test_printf("%s: [%d]%d\n", __func__, length, stop); uint8_t *d = (uint8_t *)data; int len = length; // Write slave address to TAR. // bit12: = 1 - 10-bit addressing mode when acting as a master // bit11: = 1 - Special Command Enable // bit10: = 1 - Special Command Type START BYTE i2c_reg(REG_DW_I2C_IC_TAR) = address; // Enable controller. if(i2c_enable(pi2c)) return pi2c->status; while (len--) { // Transmit FIFO is not full if(i2c_ready(pi2c, 0)) return pi2c->status; // BIT_IC_STATUS_TFE // Send stop after last byte ? if (len == 0 && stop) { // bit10: = 1 - Restart Bit Control // bit9: = 1 - Stop Bit Control // bit8: = 1 - Command read / = 0 Command write i2c_reg(REG_DW_I2C_IC_DATA_CMD) = BIT_IC_DATA_CMD_CMD | BIT_IC_DATA_CMD_STOP; } else { // Read command -IC_DATA_CMD[8] = 1. i2c_reg(REG_DW_I2C_IC_DATA_CMD) = BIT_IC_DATA_CMD_CMD; } // Receive FIFO ready? if(i2c_reg(REG_DW_I2C_IC_STATUS) & (BIT_IC_STATUS_RFNE | BIT_IC_STATUS_RFF)) { // IC_DATA_CMD[7:0] contains received data. if(length) { *d++ = i2c_reg(REG_DW_I2C_IC_DATA_CMD); length--; } else (volatile uint32)i2c_reg(REG_DW_I2C_IC_DATA_CMD); }; } while(length) { // Receive FIFO ready? if(i2c_ready(pi2c, 1)) return pi2c->status; // BIT_IC_STATUS_TFE // IC_DATA_CMD[7:0] contains received data. *d++ = i2c_reg(REG_DW_I2C_IC_DATA_CMD); length--; }; // Disable controller. if(stop) { if(i2c_disable(pi2c)) return pi2c->status; } return DRV_I2C_OK; } #if defined(USE_I2C_CONSOLE) && USE_I2C_CONSOLE //extern void dump_bytes(uint32 addr, int size); extern int print_hex_dump(uint8_t *buf, int len, unsigned char k); extern uint32 hextoul(uint8 *s); i2c_drv_t ti2c; /* I2C Init: * ati2c i [sda_pin [scl_pin [mode [speed]]]] * I2C Deinit: * ati2c d * I2C Write: * iati2c W address data1 [data2 ... [data8]...] * I2C write + stop: * iati2c w address data1 [data2 ... [data8]...] * I2C Read: * ati2c R address count * I2C read + stop: * ati2c r address count */ static void fATI2C(int argc, char *argv[]) { i2c_drv_t *pi2c = &ti2c; uint8 buf[32]; if(argc > 1) { if(argv[1][0] == 'i') { // if(!pi2c->status) { uint8 sda = 0; uint8 scl = 0; uint8 mode = 0; uint32 speed = 0; if(argc > 2) sda = hextoul(argv[2]); else if(argc > 3) scl = hextoul(argv[3]); else if(argc > 4) mode = hextoul(argv[4]); else if(argc > 5) speed = hextoul(argv[5]); if(!sda) sda = PC_4; if(!scl) scl = PC_5; if(!mode) mode = DRV_I2C_FS_MODE; if(!speed) speed = 50000; if(_i2c_setup(pi2c, sda, scl, mode) == DRV_I2C_OK && _i2c_init(pi2c) == DRV_I2C_OK && _i2c_set_speed(pi2c, speed) == DRV_I2C_OK) { rtl_printf("I2C%d Init: %02x %02x %02x %08x\n", pi2c->idx, sda, scl, mode, speed); }; } else { rtl_printf("Already init!\n"); return; }; } else if(argv[1][0] == '?') { rtl_printf("I2C Init:\n\tati2c i [sda_pin [scl_pin [mode [speed]]]]\n"); rtl_printf("I2C Deinit:\n\tati2c d\n"); rtl_printf("I2C Write:\n\tati2c W address data1 [data2 ... [data8]...]\n"); rtl_printf("I2C write + stop:\n\tati2c w address data1 [data2 ... [data8]...]\n"); rtl_printf("I2C Read:\n\tati2c R address count\n"); rtl_printf("I2C read + stop:\n\tati2c r address count\n"); rtl_printf("I2C get:\n\tati2c g address wrcount wrdata1 [..wrdata6] rdcount\n"); } else { if(pi2c->status) { if(argv[1][0] == 'd') { _i2c_ic_off(pi2c); rtl_printf("I2C%d DeInit\n", pi2c->idx); return; }; int i; for(i = 0; i + 2 < argc; i++) { buf[i] = hextoul(argv[i+2]); }; if(i) { if(argv[1][0] == 'w' || argv[1][0] == 'W') { // >ati2c w 40 2 // I2C1 write[1]: 40 02 00 // I2C1 drvStatus = 1 _i2c_write(pi2c, buf[0], &buf[1], i-1, argv[1][0] == 'w'); rtl_printf("I2C%d write[%d]: ", pi2c->idx, i-1); print_hex_dump(buf, i, ' '); rtl_printf("\n"); } else if(argv[1][0] == 'r' || argv[1][0] == 'R') { // >ati2c r 40 2 // I2C1 read[2]: 40 07 d8 // I2C1 drvStatus = 1 i = buf[1]; if(i > sizeof(buf) - 1) i = sizeof(buf) - 1; _i2c_read(pi2c, buf[0], &buf[1], i, argv[1][0] == 'r'); rtl_printf("I2C%d read[%d]: ", pi2c->idx, i); print_hex_dump(buf, i+1, ' '); rtl_printf("\n"); } else if(argv[1][0] == 'g') { // >ati2c g 5a 1 6 3 // I2C1 get[3]: 5a 5e 3a 6c // I2C1 drvStatus = 1 if (argc < 5 || buf[1] == 0 || buf[1] > sizeof(buf) - 2) { rtl_printf("Error command string!\n"); return; } if(_i2c_write(pi2c, buf[0], &buf[2], buf[1], 0) >= 0) { i = buf[buf[1] + 2]; // кол-во байт чтения if(i == 0 || i > sizeof(buf) - 1) i = sizeof(buf) - 1; _i2c_read(pi2c, buf[0], &buf[1], i, 1); rtl_printf("I2C%d get[%d]: ", pi2c->idx, i); print_hex_dump(buf, i+1, ' '); } rtl_printf("\n"); }; }; }; }; }; rtl_printf("I2C%d Status = %d\n", pi2c->idx, pi2c->status); return; } MON_RAM_TAB_SECTION COMMAND_TABLE console_commands_i2c[] = { {"ATI2C", 0, fATI2C, ": Test I2C, nit, einit, rite, ead"}, }; #endif // USE_I2C_CONSOLE #endif // CONFIG_I2C_EN