diff --git a/.gitignore b/.gitignore index 216b0ba99..bef9554fc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,7 @@ .idea +compile_commands.json +.clangd +.cache/ cores/arduino/mydebug.cpp libraries/Storage/.development cores/arduino/mydebug.cpp.donotuse diff --git a/cores/arduino/IRQManager.cpp b/cores/arduino/IRQManager.cpp index 73036ffe8..9212e78fa 100644 --- a/cores/arduino/IRQManager.cpp +++ b/cores/arduino/IRQManager.cpp @@ -25,8 +25,11 @@ #define CANFD_PRIORITY 12 #define FIRST_INT_SLOT_FREE 0 -IRQManager::IRQManager() : last_interrupt_index{0} { - +IRQManager::IRQManager() : last_interrupt_index{0} , + rcfg_I2C_interrupt_index_txi(-1), + rcfg_I2C_interrupt_index_rxi(-1), + rcfg_I2C_interrupt_index_tei(-1), + rcfg_I2C_interrupt_index_eri(-1) { } IRQManager::~IRQManager() { @@ -562,35 +565,54 @@ bool IRQManager::addPeripheral(Peripheral_t p, void *cfg) { i2c_master_cfg_t *mcfg = (i2c_master_cfg_t *)p_cfg->cfg; uint8_t hw_channel = p_cfg->hw_channel; mcfg->ipl = I2C_MASTER_PRIORITY; - if (mcfg->txi_irq == FSP_INVALID_VECTOR) { + if (rcfg_I2C_interrupt_index_txi == -1) { /* TX interrupt */ mcfg->txi_irq = (IRQn_Type)last_interrupt_index; *(irq_ptr + last_interrupt_index) = (uint32_t)iic_master_txi_isr; set_iic_tx_link_event(last_interrupt_index, hw_channel); R_BSP_IrqCfg((IRQn_Type)last_interrupt_index, I2C_MASTER_PRIORITY, mcfg); + rcfg_I2C_interrupt_index_txi = last_interrupt_index; last_interrupt_index++; + } else { + *(irq_ptr + rcfg_I2C_interrupt_index_txi) = (uint32_t)iic_master_txi_isr; + } + if (rcfg_I2C_interrupt_index_rxi == -1) { /* RX interrupt */ mcfg->rxi_irq = (IRQn_Type)last_interrupt_index; *(irq_ptr + last_interrupt_index) = (uint32_t)iic_master_rxi_isr; set_iic_rx_link_event(last_interrupt_index, hw_channel); R_BSP_IrqCfg((IRQn_Type)last_interrupt_index, I2C_MASTER_PRIORITY, mcfg); + rcfg_I2C_interrupt_index_rxi = last_interrupt_index; last_interrupt_index++; + } else { + *(irq_ptr + rcfg_I2C_interrupt_index_rxi) = (uint32_t)iic_master_rxi_isr; + } + if (rcfg_I2C_interrupt_index_tei == -1) { /* TX ERROR interrupt */ mcfg->tei_irq = (IRQn_Type)last_interrupt_index; *(irq_ptr + last_interrupt_index) = (uint32_t)iic_master_tei_isr; set_iic_tei_link_event(last_interrupt_index, hw_channel); R_BSP_IrqCfg((IRQn_Type)last_interrupt_index, I2C_MASTER_PRIORITY, mcfg); + rcfg_I2C_interrupt_index_tei = last_interrupt_index; last_interrupt_index++; + } else { + *(irq_ptr + rcfg_I2C_interrupt_index_tei) = (uint32_t)iic_master_tei_isr; + } + if (rcfg_I2C_interrupt_index_eri == -1) { /* RX ERROR interrupt */ mcfg->eri_irq = (IRQn_Type)last_interrupt_index; *(irq_ptr + last_interrupt_index) = (uint32_t)iic_master_eri_isr; set_iic_eri_link_event(last_interrupt_index, hw_channel); R_BSP_IrqCfg((IRQn_Type)last_interrupt_index, I2C_MASTER_PRIORITY, mcfg); + rcfg_I2C_interrupt_index_eri = last_interrupt_index; last_interrupt_index++; + } else { + *(irq_ptr + rcfg_I2C_interrupt_index_eri) = (uint32_t)iic_master_eri_isr; } + R_BSP_IrqEnable (mcfg->txi_irq); R_BSP_IrqEnable (mcfg->rxi_irq); R_BSP_IrqEnable (mcfg->tei_irq); @@ -644,31 +666,50 @@ bool IRQManager::addPeripheral(Peripheral_t p, void *cfg) { i2c_slave_cfg_t *p_cfg = (i2c_slave_cfg_t *)cfg; p_cfg->ipl = I2C_SLAVE_PRIORITY; p_cfg->eri_ipl = I2C_SLAVE_PRIORITY; - if (p_cfg->txi_irq == FSP_INVALID_VECTOR) { + if (rcfg_I2C_interrupt_index_txi == -1) { /* TX interrupt */ p_cfg->txi_irq = (IRQn_Type)last_interrupt_index; *(irq_ptr + last_interrupt_index) = (uint32_t)iic_slave_txi_isr; set_iic_tx_link_event(last_interrupt_index, p_cfg->channel); + rcfg_I2C_interrupt_index_txi = last_interrupt_index; last_interrupt_index++; - + } else { + *(irq_ptr + rcfg_I2C_interrupt_index_txi) = (uint32_t)iic_slave_txi_isr; + } + + if (rcfg_I2C_interrupt_index_rxi == -1) { /* RX interrupt */ p_cfg->rxi_irq = (IRQn_Type)last_interrupt_index; *(irq_ptr + last_interrupt_index) = (uint32_t)iic_slave_rxi_isr; set_iic_rx_link_event(last_interrupt_index, p_cfg->channel); + rcfg_I2C_interrupt_index_rxi = last_interrupt_index; last_interrupt_index++; + } else { + *(irq_ptr + rcfg_I2C_interrupt_index_rxi) = (uint32_t)iic_slave_rxi_isr; + } + if (rcfg_I2C_interrupt_index_tei == -1) { /* TEI interrupt */ p_cfg->tei_irq = (IRQn_Type)last_interrupt_index; *(irq_ptr + last_interrupt_index) = (uint32_t)iic_slave_tei_isr; set_iic_tei_link_event(last_interrupt_index, p_cfg->channel); + rcfg_I2C_interrupt_index_tei = last_interrupt_index; last_interrupt_index++; + } else { + *(irq_ptr + rcfg_I2C_interrupt_index_tei) = (uint32_t)iic_slave_tei_isr; + } + if (rcfg_I2C_interrupt_index_eri == -1) { /* ERI interrupt */ p_cfg->eri_irq = (IRQn_Type)last_interrupt_index; *(irq_ptr + last_interrupt_index) = (uint32_t)iic_slave_eri_isr; set_iic_eri_link_event(last_interrupt_index, p_cfg->channel); + rcfg_I2C_interrupt_index_eri = last_interrupt_index; last_interrupt_index++; + } else { + *(irq_ptr + rcfg_I2C_interrupt_index_eri) = (uint32_t)iic_slave_eri_isr; } + R_BSP_IrqEnable (p_cfg->txi_irq); R_BSP_IrqEnable (p_cfg->rxi_irq); R_BSP_IrqEnable (p_cfg->tei_irq); diff --git a/cores/arduino/IRQManager.h b/cores/arduino/IRQManager.h index 6d7dff385..2f0f59255 100644 --- a/cores/arduino/IRQManager.h +++ b/cores/arduino/IRQManager.h @@ -223,6 +223,10 @@ class IRQManager { ~IRQManager(); private: + int rcfg_I2C_interrupt_index_txi; + int rcfg_I2C_interrupt_index_rxi; + int rcfg_I2C_interrupt_index_tei; + int rcfg_I2C_interrupt_index_eri; size_t last_interrupt_index; bool set_adc_end_link_event(int li, int ch); bool set_adc_end_b_link_event(int li, int ch); diff --git a/libraries/Wire/Wire.cpp b/libraries/Wire/Wire.cpp index 778f0a93c..5fd8a84ba 100644 --- a/libraries/Wire/Wire.cpp +++ b/libraries/Wire/Wire.cpp @@ -22,6 +22,7 @@ Version 2022 for Renesas RA4 by Daniele Aimo (d.aimo@arduino.cc) */ +#include "r_iic_slave.h" extern "C" { #include #include @@ -252,8 +253,9 @@ bool TwoWire::cfg_pins(int max_index) { ioport_sda = USE_SCI_EVEN_CFG(cfg_sda) ? IOPORT_PERIPHERAL_SCI0_2_4_6_8 : IOPORT_PERIPHERAL_SCI1_3_5_7_9; ioport_scl = USE_SCI_EVEN_CFG(cfg_scl) ? IOPORT_PERIPHERAL_SCI0_2_4_6_8 : IOPORT_PERIPHERAL_SCI1_3_5_7_9; - R_IOPORT_PinCfg(&g_ioport_ctrl, g_pin_cfg[sda_pin].pin, (uint32_t) (IOPORT_CFG_PULLUP_ENABLE | IOPORT_CFG_PERIPHERAL_PIN | ioport_sda)); - R_IOPORT_PinCfg(&g_ioport_ctrl, g_pin_cfg[scl_pin].pin, (uint32_t) (IOPORT_CFG_PULLUP_ENABLE | IOPORT_CFG_PERIPHERAL_PIN | ioport_scl)); + fsp_err_t err = R_IOPORT_PinCfg(&g_ioport_ctrl, g_pin_cfg[sda_pin].pin, (uint32_t) (IOPORT_CFG_PULLUP_ENABLE | IOPORT_CFG_PERIPHERAL_PIN | ioport_sda)); + + err = R_IOPORT_PinCfg(&g_ioport_ctrl, g_pin_cfg[scl_pin].pin, (uint32_t) (IOPORT_CFG_PULLUP_ENABLE | IOPORT_CFG_PERIPHERAL_PIN | ioport_scl)); } else { @@ -263,7 +265,6 @@ bool TwoWire::cfg_pins(int max_index) { is_sci = false; ioport_sda = IOPORT_PERIPHERAL_IIC; ioport_scl = IOPORT_PERIPHERAL_IIC; - R_IOPORT_PinCfg(&g_ioport_ctrl, g_pin_cfg[sda_pin].pin, (uint32_t) (IOPORT_CFG_PULLUP_ENABLE | IOPORT_CFG_DRIVE_MID | IOPORT_CFG_PERIPHERAL_PIN | ioport_sda)); R_IOPORT_PinCfg(&g_ioport_ctrl, g_pin_cfg[scl_pin].pin, (uint32_t) (IOPORT_CFG_PULLUP_ENABLE | IOPORT_CFG_DRIVE_MID | IOPORT_CFG_PERIPHERAL_PIN | ioport_scl)); } @@ -272,7 +273,17 @@ bool TwoWire::cfg_pins(int max_index) { } /* -------------------------------------------------------------------------- */ -void TwoWire::begin(void) { +void TwoWire::begin() { +/* -------------------------------------------------------------------------- */ + end(); + is_master = true; + _begin(); +} + +/* private version of begin so that it can be called both for slave and master + * initialization */ +/* -------------------------------------------------------------------------- */ +void TwoWire::_begin(void) { /* -------------------------------------------------------------------------- */ init_ok = true; int max_index = PINS_COUNT; @@ -285,7 +296,6 @@ void TwoWire::begin(void) { ->>>>> MASTER initialization * ----------------------------------- */ if(is_master) { - setClock(I2C_MASTER_RATE_STANDARD); if(is_sci) { @@ -342,6 +352,7 @@ void TwoWire::begin(void) { init_ok = false; return; } + TwoWire::g_I2CWires[channel] = this; s_open = R_IIC_SLAVE_Open; @@ -367,53 +378,73 @@ void TwoWire::begin(void) { init_ok = false; return; } - + if(is_master) { - I2CIrqMasterReq_t irq_req; - irq_req.ctrl = &m_i2c_ctrl; - irq_req.cfg = &m_i2c_cfg; - /* see note in the cfg_pins - the IRQ manager need to know the HW channel that in case of SCI - peripheral is not the one in the cfg structure but the one in - the Wire channel, so copy it in the request */ - irq_req.hw_channel = channel; - if(is_sci) { - init_ok &= IRQManager::getInstance().addPeripheral(IRQ_SCI_I2C_MASTER,&irq_req); - } - else { - init_ok &= IRQManager::getInstance().addPeripheral(IRQ_I2C_MASTER,&irq_req); - } - if(FSP_SUCCESS == m_open(&m_i2c_ctrl,&m_i2c_cfg)) { - init_ok &= true; - } - else { - init_ok = false; - } - } - else { - init_ok &= IRQManager::getInstance().addPeripheral(IRQ_I2C_SLAVE,&s_i2c_cfg); - if(FSP_SUCCESS == s_open(&s_i2c_ctrl,&s_i2c_cfg)) { - init_ok &= true; - } - else { - init_ok = false; - } + /* master but IRQ has already been configured as slave */ + if(slave_irq_added) { + m_i2c_cfg.txi_irq = s_i2c_cfg.txi_irq; + m_i2c_cfg.rxi_irq = s_i2c_cfg.rxi_irq; + m_i2c_cfg.tei_irq = s_i2c_cfg.tei_irq; + m_i2c_cfg.eri_irq = s_i2c_cfg.eri_irq; + } + + I2CIrqMasterReq_t irq_req; + irq_req.ctrl = &m_i2c_ctrl; + irq_req.cfg = &m_i2c_cfg; + /* see note in the cfg_pins + the IRQ manager need to know the HW channel that in case of SCI + peripheral is not the one in the cfg structure but the one in + the Wire channel, so copy it in the request */ + irq_req.hw_channel = channel; + if(is_sci) { + init_ok &= IRQManager::getInstance().addPeripheral(IRQ_SCI_I2C_MASTER,&irq_req); + } + else { + init_ok &= IRQManager::getInstance().addPeripheral(IRQ_I2C_MASTER,&irq_req); + } + master_irq_added = true; + + + if(FSP_SUCCESS == m_open(&m_i2c_ctrl,&m_i2c_cfg)) { + init_ok &= true; + } else { + init_ok = false; + } + + } else { + if(master_irq_added) { + s_i2c_cfg.txi_irq = m_i2c_cfg.txi_irq; + s_i2c_cfg.rxi_irq = m_i2c_cfg.rxi_irq; + s_i2c_cfg.tei_irq = m_i2c_cfg.tei_irq; + s_i2c_cfg.eri_irq = m_i2c_cfg.eri_irq; + } + + init_ok &= IRQManager::getInstance().addPeripheral(IRQ_I2C_SLAVE,&s_i2c_cfg); + slave_irq_added = true; + + if(FSP_SUCCESS == s_open(&s_i2c_ctrl,&s_i2c_cfg)) { + init_ok &= true; + } else { + init_ok = false; + } } } /* -------------------------------------------------------------------------- */ void TwoWire::begin(uint16_t address) { -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + end(); is_master = false; slave_address = address; /* Address is set inside begin() using slave_address member variable */ - begin(); + _begin(); } /* -------------------------------------------------------------------------- */ void TwoWire::begin(int address) { -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + end(); is_master = false; slave_address = (uint16_t)address; begin((uint16_t)address); @@ -421,7 +452,8 @@ void TwoWire::begin(int address) { /* -------------------------------------------------------------------------- */ void TwoWire::begin(uint8_t address) { -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + end(); is_master = false; slave_address = (uint16_t)address; begin((uint16_t)address); @@ -429,17 +461,24 @@ void TwoWire::begin(uint8_t address) { /* -------------------------------------------------------------------------- */ void TwoWire::end(void) { -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ - if(init_ok) { - if(is_master) { - if(m_close != nullptr) { - m_close(&m_i2c_ctrl); + if (init_ok) { + if (is_master) { + if (m_close != nullptr) { + m_close(&m_i2c_ctrl); + R_BSP_IrqDisable(m_i2c_cfg.txi_irq); + R_BSP_IrqDisable(m_i2c_cfg.rxi_irq); + R_BSP_IrqDisable(m_i2c_cfg.tei_irq); + R_BSP_IrqDisable(m_i2c_cfg.eri_irq); } - } - else { - if(s_close != nullptr) { + } else { + if (s_close != nullptr) { s_close(&s_i2c_ctrl); + R_BSP_IrqDisable(s_i2c_cfg.txi_irq); + R_BSP_IrqDisable(s_i2c_cfg.rxi_irq); + R_BSP_IrqDisable(s_i2c_cfg.tei_irq); + R_BSP_IrqDisable(s_i2c_cfg.eri_irq); } } } @@ -447,10 +486,9 @@ void TwoWire::end(void) { } - /* -------------------------------------------------------------------------- */ uint8_t TwoWire::read_from(uint8_t address, uint8_t* data, uint8_t length, unsigned int timeout_ms, bool sendStop) { -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ /* ??? does this function make sense only for MASTER ???? */ fsp_err_t err = FSP_ERR_ASSERTION; @@ -477,9 +515,9 @@ uint8_t TwoWire::read_from(uint8_t address, uint8_t* data, uint8_t length, unsig return 0; /* ???????? return value ??????? */ } -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ uint8_t TwoWire::write_to(uint8_t address, uint8_t* data, uint8_t length, unsigned int timeout_ms, bool sendStop) { -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ uint8_t rv = END_TX_OK; fsp_err_t err = FSP_ERR_ASSERTION; if(init_ok) { @@ -520,9 +558,9 @@ uint8_t TwoWire::write_to(uint8_t address, uint8_t* data, uint8_t length, unsign return rv; } -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ void TwoWire::setClock(uint32_t freq) { -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ if(init_ok && is_master) { if(m_close != nullptr) { m_close(&m_i2c_ctrl); @@ -592,7 +630,7 @@ void TwoWire::setClock(uint32_t freq) { /* -------------------------------------------------------------------------- */ void TwoWire::beginTransmission(uint32_t address) { -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ if (init_ok) { data_too_long = false; master_tx_address = address; @@ -609,13 +647,13 @@ void TwoWire::beginTransmission(uint16_t address) { /* -------------------------------------------------------------------------- */ void TwoWire::beginTransmission(uint8_t address){ -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ beginTransmission((uint32_t)address); } /* -------------------------------------------------------------------------- */ void TwoWire::beginTransmission(int address) { -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ beginTransmission((uint32_t)address); } @@ -625,7 +663,7 @@ void TwoWire::beginTransmission(int address) { /* -------------------------------------------------------------------------- */ uint8_t TwoWire::endTransmission(bool sendStop) { -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ uint8_t ret = write_to(master_tx_address, tx_buffer, tx_index, timeout, sendStop); transmission_begun = false; return ret; @@ -633,7 +671,7 @@ uint8_t TwoWire::endTransmission(bool sendStop) { /* -------------------------------------------------------------------------- */ uint8_t TwoWire::endTransmission(void) { -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ return endTransmission(true); } @@ -643,7 +681,7 @@ uint8_t TwoWire::endTransmission(void) { /* -------------------------------------------------------------------------- */ size_t TwoWire::requestFrom(uint8_t address, size_t quantity, uint32_t iaddress, uint8_t isize, uint8_t sendStop) { -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ if(init_ok) { if (isize > 0) { @@ -685,13 +723,13 @@ size_t TwoWire::requestFrom(uint8_t address, size_t quantity, uint32_t iaddress, /* -------------------------------------------------------------------------- */ size_t TwoWire::requestFrom(uint8_t address, size_t quantity, bool sendStop) { -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ return requestFrom((uint8_t)address, quantity, (uint32_t)0, (uint8_t)0, sendStop); } /* -------------------------------------------------------------------------- */ size_t TwoWire::requestFrom(uint8_t address, size_t quantity) { -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ return requestFrom((uint8_t)address, quantity, true); } @@ -704,7 +742,7 @@ size_t TwoWire::requestFrom(uint8_t address, size_t quantity) { // or after beginTransmission(address) /* -------------------------------------------------------------------------- */ size_t TwoWire::write(uint8_t data) { -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ if(init_ok) { if(is_master) { if(transmission_begun) { @@ -733,7 +771,7 @@ size_t TwoWire::write(uint8_t data) { // or after beginTransmission(address) /* -------------------------------------------------------------------------- */ size_t TwoWire::write(const uint8_t *data, size_t quantity) { -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ if(init_ok) { if(is_master) { // in master transmitter mode @@ -757,14 +795,14 @@ size_t TwoWire::write(const uint8_t *data, size_t quantity) { // sets function called on slave write /* -------------------------------------------------------------------------- */ void TwoWire::onReceive( I2C_onRxCallback_f f ) { -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ rx_callback = f; } // sets function called on slave read /* -------------------------------------------------------------------------- */ void TwoWire::onRequest( I2C_onTxCallback_f f ) { -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ tx_callback = f; } @@ -776,7 +814,7 @@ void TwoWire::onRequest( I2C_onTxCallback_f f ) { /* -------------------------------------------------------------------------- */ int TwoWire::available(void) { -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ return rx_index - rx_extract_index; } @@ -785,7 +823,7 @@ int TwoWire::available(void) { // or after requestFrom(address, numBytes) /* -------------------------------------------------------------------------- */ int TwoWire::read(void) { -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ int rv = -1; // get each successive byte on each call @@ -802,7 +840,7 @@ int TwoWire::read(void) { // or after requestFrom(address, numBytes) /* -------------------------------------------------------------------------- */ int TwoWire::peek(void) { -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ int rv = -1; // get each successive byte on each call @@ -815,13 +853,11 @@ int TwoWire::peek(void) { /* -------------------------------------------------------------------------- */ void TwoWire::flush(void) { -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ while(bus_status != WIRE_STATUS_TX_COMPLETED && bus_status != WIRE_STATUS_TRANSACTION_ABORTED) {} } - - #if WIRE_HOWMANY > 0 TwoWire Wire(WIRE_SCL_PIN, WIRE_SDA_PIN); #endif diff --git a/libraries/Wire/Wire.h b/libraries/Wire/Wire.h index 6b4eb5624..be1d8e0c7 100644 --- a/libraries/Wire/Wire.h +++ b/libraries/Wire/Wire.h @@ -151,6 +151,9 @@ class TwoWire : public arduino::HardwareI2C { } private: + bool master_irq_added; + bool slave_irq_added; + void _begin(); static TwoWire *g_SCIWires[TWOWIRE_MAX_I2C_CHANNELS]; static TwoWire *g_I2CWires[TWOWIRE_MAX_SCI_CHANNELS]; @@ -233,4 +236,4 @@ extern TwoWire Wire3; #endif #endif -#endif \ No newline at end of file +#endif