From 25ea7bc2d8a6ad38f2f2a7ecf8688a1561bea89a Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Wed, 12 Jul 2023 11:58:46 +0200 Subject: [PATCH 1/2] Wire: fix setClock clock source is fixed for RA4M1, so the rates will be wrong for C33. This will be fixed in the next commit --- libraries/Wire/Wire.cpp | 82 ++++++++++++++++++++--------------------- libraries/Wire/Wire.h | 10 +---- 2 files changed, 41 insertions(+), 51 deletions(-) diff --git a/libraries/Wire/Wire.cpp b/libraries/Wire/Wire.cpp index d663fcdf4..7e70aaed9 100644 --- a/libraries/Wire/Wire.cpp +++ b/libraries/Wire/Wire.cpp @@ -184,13 +184,12 @@ void TwoWire::WireSlaveCallback(i2c_slave_callback_args_t *arg) { /* -------------------------------------------------------------------------- */ -TwoWire::TwoWire(int scl, int sda, WireSpeed_t wp /*= SPEED_STANDARD*/, WireAddressMode_t am /*= ADDRESS_MODE_7_BITS*/, bool prefer_sci /*= false*/) : +TwoWire::TwoWire(int scl, int sda, WireAddressMode_t am /*= ADDRESS_MODE_7_BITS*/, bool prefer_sci /*= false*/) : scl_pin(scl), sda_pin(sda), init_ok(false), is_master(true), is_sci(false), - speed_mode(wp), address_mode(am), timeout(1000), transmission_begun(false), @@ -281,11 +280,14 @@ void TwoWire::begin(void) { init_ok &= cfg_pins(max_index); if(init_ok) { - + /* ----------------------------------- ->>>>> MASTER initialization * ----------------------------------- */ if(is_master) { + + setClock(I2C_MASTER_RATE_STANDARD); + if(is_sci) { TwoWire::g_SCIWires[channel] = this; @@ -317,29 +319,8 @@ void TwoWire::begin(void) { m_i2c_cfg.p_callback = WireMasterCallback; } - m_sci_i2c_extend.clock_settings.clk_divisor_value = 0; - m_sci_i2c_extend.clock_settings.brr_value = 14; - m_sci_i2c_extend.clock_settings.mddr_value = 255; - m_sci_i2c_extend.clock_settings.bitrate_modulation = false; - m_sci_i2c_extend.clock_settings.cycles_value = 15; - m_sci_i2c_extend.clock_settings.snfr_value = (1); - - - /* Actual calculated bitrate: 99272. Actual calculated duty cycle: 49%. */ - m_i2c_extend.timeout_mode = IIC_MASTER_TIMEOUT_MODE_SHORT; - m_i2c_extend.timeout_scl_low = IIC_MASTER_TIMEOUT_SCL_LOW_DISABLED; - m_i2c_extend.clock_settings.brl_value = 27; - m_i2c_extend.clock_settings.brh_value = 26; - m_i2c_extend.clock_settings.cks_value = 2; - m_i2c_cfg.channel = channel; m_i2c_cfg.rate = I2C_MASTER_RATE_STANDARD; - if(speed_mode == SPEED_FAST) { - m_i2c_cfg.rate = I2C_MASTER_RATE_FAST; - } - else if(speed_mode == SPEED_VERY_FAST) { - m_i2c_cfg.rate = I2C_MASTER_RATE_FASTPLUS; - } m_i2c_cfg.slave = 0x00; m_i2c_cfg.addr_mode = (address_mode == ADDRESS_MODE_7_BITS) ? I2C_MASTER_ADDR_MODE_7BIT : I2C_MASTER_ADDR_MODE_10BIT; m_i2c_cfg.p_transfer_tx = NULL; @@ -347,8 +328,7 @@ void TwoWire::begin(void) { m_i2c_cfg.p_context = &m_i2c_cfg; m_i2c_cfg.ipl = (12); - - + } // if(is_master) { /* ----------------------------------- ->>>>> SLAVE initialization @@ -369,12 +349,6 @@ void TwoWire::begin(void) { s_i2c_cfg.channel = channel; s_i2c_cfg.rate = I2C_SLAVE_RATE_STANDARD; - if(speed_mode == SPEED_FAST) { - s_i2c_cfg.rate = I2C_SLAVE_RATE_FAST; - } - else if(speed_mode == SPEED_VERY_FAST) { - s_i2c_cfg.rate = I2C_SLAVE_RATE_FASTPLUS; - } s_i2c_cfg.slave = slave_address; s_i2c_cfg.addr_mode = (address_mode == ADDRESS_MODE_7_BITS) ? I2C_SLAVE_ADDR_MODE_7BIT : I2C_SLAVE_ADDR_MODE_10BIT; s_i2c_cfg.general_call_enable = false; @@ -544,7 +518,7 @@ uint8_t TwoWire::write_to(uint8_t address, uint8_t* data, uint8_t length, unsign } /* -------------------------------------------------------------------------- */ -void TwoWire::setClock(uint32_t ws) { +void TwoWire::setClock(uint32_t freq) { /* -------------------------------------------------------------------------- */ if(init_ok && is_master) { if(m_close != nullptr) { @@ -553,16 +527,40 @@ void TwoWire::setClock(uint32_t ws) { } if(is_master) { - if((WireSpeed_t)ws == SPEED_STANDARD) { - m_i2c_cfg.rate = I2C_MASTER_RATE_STANDARD; - } - else if((WireSpeed_t)ws == SPEED_FAST) { - m_i2c_cfg.rate = I2C_MASTER_RATE_FAST; - } - else if((WireSpeed_t)ws == SPEED_VERY_FAST) { - m_i2c_cfg.rate = I2C_MASTER_RATE_FASTPLUS; + m_i2c_cfg.rate = (i2c_master_rate_t)freq; + + if (is_sci) { + switch (m_i2c_cfg.rate) { + case I2C_MASTER_RATE_STANDARD: + m_sci_i2c_extend.clock_settings.brr_value = 14; + m_sci_i2c_extend.clock_settings.mddr_value = 255; + m_sci_i2c_extend.clock_settings.bitrate_modulation = false; + break; + case I2C_MASTER_RATE_FAST: + m_sci_i2c_extend.clock_settings.brr_value = 2; + m_sci_i2c_extend.clock_settings.mddr_value = 204; + m_sci_i2c_extend.clock_settings.bitrate_modulation = true; + break; + } + } else { + switch (m_i2c_cfg.rate) { + case I2C_MASTER_RATE_STANDARD: + m_i2c_extend.clock_settings.brl_value = 27; + m_i2c_extend.clock_settings.brh_value = 26; + m_i2c_extend.clock_settings.cks_value = 2; + break; + case I2C_MASTER_RATE_FAST: + m_i2c_extend.clock_settings.brl_value = 24; + m_i2c_extend.clock_settings.brh_value = 23; + m_i2c_extend.clock_settings.cks_value = 0; + break; + case I2C_MASTER_RATE_FASTPLUS: + m_i2c_extend.clock_settings.brl_value = 6; + m_i2c_extend.clock_settings.brh_value = 5; + m_i2c_extend.clock_settings.cks_value = 0; + break; + } } - } if(init_ok) { diff --git a/libraries/Wire/Wire.h b/libraries/Wire/Wire.h index 2e09c58e4..6b4eb5624 100644 --- a/libraries/Wire/Wire.h +++ b/libraries/Wire/Wire.h @@ -83,13 +83,6 @@ typedef enum { ADDRESS_MODE_10_BITS } WireAddressMode_t; -typedef enum { - SPEED_STANDARD = 0, //100 kHz - SPEED_FAST, //400 kHz - SPEED_VERY_FAST //1 Mhz -} WireSpeed_t; - - typedef enum { WIRE_STATUS_UNSET, WIRE_STATUS_RX_COMPLETED, @@ -103,7 +96,7 @@ typedef enum { class TwoWire : public arduino::HardwareI2C { public: - TwoWire(int scl_pin, int sda_pin, WireSpeed_t wp = SPEED_STANDARD, WireAddressMode_t am = ADDRESS_MODE_7_BITS, bool prefer_sci = false); + TwoWire(int scl_pin, int sda_pin, WireAddressMode_t am = ADDRESS_MODE_7_BITS, bool prefer_sci = false); void begin(); void begin(uint8_t); void begin(uint16_t); @@ -172,7 +165,6 @@ class TwoWire : public arduino::HardwareI2C { bool is_master; int channel; bool is_sci; - WireSpeed_t speed_mode; WireAddressMode_t address_mode; unsigned int timeout; From 3c4642661cb3a0d1f9046ca80b6a26b9c475b969 Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Fri, 4 Aug 2023 14:46:05 +0200 Subject: [PATCH 2/2] Wire: adapt clocks to C33 and fix useless extra delay --- libraries/Wire/Wire.cpp | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/libraries/Wire/Wire.cpp b/libraries/Wire/Wire.cpp index 7e70aaed9..b8704318e 100644 --- a/libraries/Wire/Wire.cpp +++ b/libraries/Wire/Wire.cpp @@ -317,6 +317,9 @@ void TwoWire::begin(void) { m_i2c_cfg.p_extend = &m_i2c_extend; m_i2c_cfg.p_callback = WireMasterCallback; + + m_i2c_extend.timeout_mode = IIC_MASTER_TIMEOUT_MODE_SHORT; + m_i2c_extend.timeout_scl_low = IIC_MASTER_TIMEOUT_SCL_LOW_DISABLED; } m_i2c_cfg.channel = channel; @@ -325,7 +328,7 @@ void TwoWire::begin(void) { m_i2c_cfg.addr_mode = (address_mode == ADDRESS_MODE_7_BITS) ? I2C_MASTER_ADDR_MODE_7BIT : I2C_MASTER_ADDR_MODE_10BIT; m_i2c_cfg.p_transfer_tx = NULL; m_i2c_cfg.p_transfer_rx = NULL; - + m_i2c_cfg.p_context = &m_i2c_cfg; m_i2c_cfg.ipl = (12); @@ -457,13 +460,13 @@ uint8_t TwoWire::read_from(uint8_t address, uint8_t* data, uint8_t length, unsig } if(err == FSP_SUCCESS) { if(m_read != nullptr) { + bus_status = WIRE_STATUS_UNSET; err = m_read(&m_i2c_ctrl,data,length,!sendStop); } } - bus_status = WIRE_STATUS_UNSET; - while(timeout_ms > 0 && bus_status == WIRE_STATUS_UNSET) { - timeout_ms--; - delay(1); + timeout_ms = millis() + timeout_ms; + while(millis() < timeout_ms && bus_status == WIRE_STATUS_UNSET && err == FSP_SUCCESS) { + } } @@ -485,13 +488,13 @@ uint8_t TwoWire::write_to(uint8_t address, uint8_t* data, uint8_t length, unsign } if(err == FSP_SUCCESS) { if(m_write != nullptr) { + bus_status = WIRE_STATUS_UNSET; err = m_write(&m_i2c_ctrl,data,length,!sendStop); } } - bus_status = WIRE_STATUS_UNSET; - while(err == FSP_SUCCESS && timeout_ms > 0 && bus_status == WIRE_STATUS_UNSET) { - timeout_ms--; - delay(1); + timeout_ms = millis() + timeout_ms; + while(millis() < timeout_ms && bus_status == WIRE_STATUS_UNSET && err == FSP_SUCCESS) { + } if(err != FSP_SUCCESS) { @@ -529,7 +532,12 @@ void TwoWire::setClock(uint32_t freq) { if(is_master) { m_i2c_cfg.rate = (i2c_master_rate_t)freq; + int clock_divisor = (R_FSP_SystemClockHzGet(BSP_FEATURE_SCI_CLOCK) / 48000000u) - 1; + if (is_sci) { + m_sci_i2c_extend.clock_settings.clk_divisor_value = 0; + m_sci_i2c_extend.clock_settings.cycles_value = 15; + m_sci_i2c_extend.clock_settings.snfr_value = (1); switch (m_i2c_cfg.rate) { case I2C_MASTER_RATE_STANDARD: m_sci_i2c_extend.clock_settings.brr_value = 14; @@ -537,6 +545,7 @@ void TwoWire::setClock(uint32_t freq) { m_sci_i2c_extend.clock_settings.bitrate_modulation = false; break; case I2C_MASTER_RATE_FAST: + default: m_sci_i2c_extend.clock_settings.brr_value = 2; m_sci_i2c_extend.clock_settings.mddr_value = 204; m_sci_i2c_extend.clock_settings.bitrate_modulation = true; @@ -547,18 +556,20 @@ void TwoWire::setClock(uint32_t freq) { case I2C_MASTER_RATE_STANDARD: m_i2c_extend.clock_settings.brl_value = 27; m_i2c_extend.clock_settings.brh_value = 26; - m_i2c_extend.clock_settings.cks_value = 2; + m_i2c_extend.clock_settings.cks_value = 2 + clock_divisor; break; case I2C_MASTER_RATE_FAST: - m_i2c_extend.clock_settings.brl_value = 24; - m_i2c_extend.clock_settings.brh_value = 23; - m_i2c_extend.clock_settings.cks_value = 0; + m_i2c_extend.clock_settings.brl_value = 16; + m_i2c_extend.clock_settings.brh_value = 15; + m_i2c_extend.clock_settings.cks_value = 0 + clock_divisor; break; +#if BSP_FEATURE_IIC_FAST_MODE_PLUS case I2C_MASTER_RATE_FASTPLUS: m_i2c_extend.clock_settings.brl_value = 6; m_i2c_extend.clock_settings.brh_value = 5; m_i2c_extend.clock_settings.cks_value = 0; break; +#endif } } }