From 359f7a89f20aeae0d1c35836cb90ed5ced1bea68 Mon Sep 17 00:00:00 2001 From: Mikael Johansson Date: Sat, 10 Oct 2020 16:48:14 +0200 Subject: [PATCH 1/5] Fixed return value bug in TwoWire::write --- libraries/Wire/src/Wire.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libraries/Wire/src/Wire.cpp b/libraries/Wire/src/Wire.cpp index de489cd..86b0684 100644 --- a/libraries/Wire/src/Wire.cpp +++ b/libraries/Wire/src/Wire.cpp @@ -279,8 +279,9 @@ TwoWire::requestFrom(uint16_t address, uint8_t size, bool sendStop) //请求数 size_t TwoWire::write(uint8_t data) //写到txbuff { - if(transmitting) { + if(transmitting && !i2c_tx_buff->isFull()) { i2c_tx_buff->store_char(data); + return 1; } return 0; } @@ -288,7 +289,7 @@ TwoWire::write(uint8_t data) //写到txbuff size_t TwoWire::write(const uint8_t *data, int quantity) { - for(size_t i = 0; i < quantity; ++i) { + for(size_t i = 0; i < quantity; i++) { if(!write(data[i])) { return i; } From 9b077cb47007f0195fb3b5631e23d535f5229b44 Mon Sep 17 00:00:00 2001 From: Mikael Johansson Date: Sat, 10 Oct 2020 16:48:49 +0200 Subject: [PATCH 2/5] Set default I2C frequency to 400kHz, same as Arduino boards use --- libraries/Wire/src/Wire.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/Wire/src/Wire.h b/libraries/Wire/src/Wire.h index fc9fb06..c13f0c7 100644 --- a/libraries/Wire/src/Wire.h +++ b/libraries/Wire/src/Wire.h @@ -24,7 +24,7 @@ public: TwoWire(i2c_device_number_t i2c_device); ~TwoWire(); - void begin(uint8_t sda = SDA, uint8_t scl = SCL, uint32_t frequency = 500000); + void begin(uint8_t sda = SDA, uint8_t scl = SCL, uint32_t frequency = 400000); void begin(uint16_t slave_address, uint8_t sda = SDA, uint8_t scl = SCL); void setClock(uint32_t frequency); From 7c7ec509acdb7cab734ff061cd8030e59a8a97bb Mon Sep 17 00:00:00 2001 From: Mikael Johansson Date: Sun, 11 Oct 2020 12:10:38 +0200 Subject: [PATCH 3/5] Return number of received bytes from TwoWire::requestFrom(), like Arduino documentation specifies Nl --- libraries/Wire/src/Wire.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/Wire/src/Wire.cpp b/libraries/Wire/src/Wire.cpp index 86b0684..507ed18 100644 --- a/libraries/Wire/src/Wire.cpp +++ b/libraries/Wire/src/Wire.cpp @@ -267,13 +267,13 @@ TwoWire::requestFrom(uint16_t address, uint8_t size, bool sendStop) //请求数 uint8_t rx_data[RING_BUFFER_SIZE]; state = readTransmission(address, rx_data, size, sendStop); if(0 == state){ - while(size) + while(index < size) { i2c_rx_buff->store_char(rx_data[index++]); - size--; } + return size; } - return i2c_rx_buff->available(); + return 0; } size_t From 763c23d13c26972e31cd6ae58de3c43a9cb854f6 Mon Sep 17 00:00:00 2001 From: Mikael Johansson Date: Sun, 11 Oct 2020 14:59:18 +0200 Subject: [PATCH 4/5] Refacted TwoWire::begin() to reduce duplicated code with TwoWire::setClock() --- libraries/Wire/src/Wire.cpp | 45 +++++++++++++------------------------ 1 file changed, 15 insertions(+), 30 deletions(-) diff --git a/libraries/Wire/src/Wire.cpp b/libraries/Wire/src/Wire.cpp index 507ed18..991f354 100644 --- a/libraries/Wire/src/Wire.cpp +++ b/libraries/Wire/src/Wire.cpp @@ -9,6 +9,9 @@ static int maix_i2c_slave_irq(void *userdata); TwoWire::TwoWire(i2c_device_number_t i2c_device) { + i2c_tx_buff = 0; + i2c_rx_buff = 0; + _i2c_num = i2c_device; switch(i2c_device) { @@ -38,44 +41,26 @@ TwoWire::~TwoWire() void TwoWire::begin(uint8_t sda, uint8_t scl, uint32_t frequency) { - i2c_clk = frequency; fpioa_set_function(sda, sda_func); fpioa_set_function(scl, scl_func); - volatile i2c_t *i2c_adapter = i2c[_i2c_num]; - uint8_t speed_mode = I2C_CON_SPEED_STANDARD; - //i2c_clk_init + sysctl_clock_enable((sysctl_clock_t)(SYSCTL_CLOCK_I2C0 + _i2c_num)); sysctl_clock_set_threshold((sysctl_threshold_t)(SYSCTL_THRESHOLD_I2C0 + _i2c_num), 3); - uint32_t v_i2c_freq = sysctl_clock_get_freq((sysctl_clock_t)(SYSCTL_CLOCK_I2C0 + _i2c_num)); - uint16_t v_period_clk_cnt = floor( (v_i2c_freq*1.0 / i2c_clk / 2) + 0.5 ); - - - if(v_period_clk_cnt <= 6) - v_period_clk_cnt = 6; - if(v_period_clk_cnt >= 65525)//65535-10 - v_period_clk_cnt = 65525; - if((i2c_clk>100000) && (i2c_clk<=1000000)) - speed_mode = I2C_CON_SPEED_FAST; - else - speed_mode = I2C_CON_SPEED_HIGH; + volatile i2c_t *i2c_adapter = i2c[_i2c_num]; i2c_adapter->enable = 0; - i2c_adapter->con = I2C_CON_MASTER_MODE | I2C_CON_SLAVE_DISABLE | I2C_CON_RESTART_EN | - (address_width == 10 ? I2C_CON_10BITADDR_SLAVE : 0) | I2C_CON_SPEED(speed_mode); - i2c_adapter->ss_scl_hcnt = I2C_SS_SCL_HCNT_COUNT(v_period_clk_cnt); - i2c_adapter->ss_scl_lcnt = I2C_SS_SCL_LCNT_COUNT(v_period_clk_cnt); - i2c_adapter->intr_mask = 0; i2c_adapter->dma_cr = 0x3; i2c_adapter->dma_rdlr = 0; i2c_adapter->dma_tdlr = 4; - i2c_adapter->enable = I2C_ENABLE_ENABLE; + is_master_mode = true; + delete i2c_tx_buff, i2c_rx_buff; i2c_tx_buff = new RingBuffer(); i2c_rx_buff = new RingBuffer(); - + setClock(frequency); } void @@ -83,12 +68,11 @@ TwoWire::begin(uint16_t slave_address, uint8_t sda, uint8_t scl) { fpioa_set_function(sda, sda_func); fpioa_set_function(scl, scl_func); - - volatile i2c_t *i2c_adapter = i2c[_i2c_num]; sysctl_clock_enable((sysctl_clock_t)(SYSCTL_CLOCK_I2C0 + _i2c_num)); sysctl_clock_set_threshold((sysctl_threshold_t)(SYSCTL_THRESHOLD_I2C0 + _i2c_num), 3); + volatile i2c_t *i2c_adapter = i2c[_i2c_num]; i2c_adapter->enable = 0; i2c_adapter->con = I2C_CON_SPEED(1) | I2C_CON_STOP_DET_IFADDRESSED; i2c_adapter->ss_scl_hcnt = I2C_SS_SCL_HCNT_COUNT(37); @@ -98,17 +82,19 @@ TwoWire::begin(uint16_t slave_address, uint8_t sda, uint8_t scl) i2c_adapter->tx_tl = I2C_TX_TL_VALUE(0); i2c_adapter->intr_mask = I2C_INTR_MASK_RX_FULL | I2C_INTR_MASK_START_DET | I2C_INTR_MASK_STOP_DET | I2C_INTR_MASK_RD_REQ; + is_master_mode = false; + plic_set_priority((plic_irq_t)(IRQN_I2C0_INTERRUPT + _i2c_num), 1); plic_irq_register((plic_irq_t)(IRQN_I2C0_INTERRUPT + _i2c_num), maix_i2c_slave_irq, this); plic_irq_enable((plic_irq_t)(IRQN_I2C0_INTERRUPT + _i2c_num)); - i2c_adapter->enable = I2C_ENABLE_ENABLE; - is_master_mode = false; - + delete i2c_tx_buff, i2c_rx_buff; i2c_tx_buff = new RingBuffer(); i2c_rx_buff = new RingBuffer(); -} + i2c_adapter->enable = I2C_ENABLE_ENABLE; +} + void TwoWire::setTimeOut(uint16_t timeOutMillis) { @@ -145,7 +131,6 @@ TwoWire::setClock(uint32_t frequency) i2c_adapter->ss_scl_hcnt = I2C_SS_SCL_HCNT_COUNT(v_period_clk_cnt); i2c_adapter->ss_scl_lcnt = I2C_SS_SCL_LCNT_COUNT(v_period_clk_cnt); i2c_adapter->enable = I2C_ENABLE_ENABLE; - } uint32_t From 78f7bb18c569f861e0fe10160a257263d7996d7e Mon Sep 17 00:00:00 2001 From: Mikael Johansson Date: Sun, 11 Oct 2020 14:59:54 +0200 Subject: [PATCH 5/5] Flush buffers on every I2C transaction, in case the user hasn't consumed all bytes F --- libraries/Wire/src/Wire.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libraries/Wire/src/Wire.cpp b/libraries/Wire/src/Wire.cpp index 991f354..26e984c 100644 --- a/libraries/Wire/src/Wire.cpp +++ b/libraries/Wire/src/Wire.cpp @@ -221,6 +221,9 @@ TwoWire::readTransmission(uint16_t address, uint8_t* receive_buf, size_t receive void TwoWire::beginTransmission(uint16_t address) { + // Clear buffers when new transation/packet starts + flush(); + transmitting = 1; txAddress = address; } @@ -248,6 +251,9 @@ TwoWire::endTransmission(bool sendStop) //结束时从rxbuff发送数据? uint8_t TwoWire::requestFrom(uint16_t address, uint8_t size, bool sendStop) //请求数据,存入rxbuff,供read读 { + // Clear buffers when new transation/packet starts + flush(); + int state,index = 0; uint8_t rx_data[RING_BUFFER_SIZE]; state = readTransmission(address, rx_data, size, sendStop);