Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow Wire to switch from master to slave and vice versa #191

Merged
merged 3 commits into from
Nov 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
.idea
compile_commands.json
.clangd
.cache/
cores/arduino/mydebug.cpp
libraries/Storage/.development
cores/arduino/mydebug.cpp.donotuse
Expand Down
93 changes: 53 additions & 40 deletions cores/arduino/IRQManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -556,79 +556,85 @@ bool IRQManager::addPeripheral(Peripheral_t p, void *cfg) {
#endif

#if WIRE_HOWMANY > 0
/* I2C true NOT SCI */
else if(p == IRQ_I2C_MASTER && cfg != NULL) {
I2CIrqMasterReq_t *p_cfg = (I2CIrqMasterReq_t *)cfg;
//iic_master_instance_ctrl_t *ctrl = (iic_master_instance_ctrl_t *)p_cfg->ctrl;
i2c_master_cfg_t *mcfg = (i2c_master_cfg_t *)p_cfg->cfg;
uint8_t hw_channel = p_cfg->hw_channel;
I2CIrqReq_t *p_cfg = (I2CIrqReq_t *)cfg;
i2c_master_cfg_t *mcfg = (i2c_master_cfg_t *)p_cfg->mcfg;
i2c_slave_cfg_t *scfg = (i2c_slave_cfg_t *)p_cfg->scfg;
mcfg->ipl = I2C_MASTER_PRIORITY;

if (mcfg->txi_irq == FSP_INVALID_VECTOR) {
/* 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);
scfg->txi_irq = (IRQn_Type)last_interrupt_index;
set_iic_tx_link_event(last_interrupt_index, p_cfg->mcfg->channel);
R_BSP_IrqCfg((IRQn_Type)last_interrupt_index, I2C_MASTER_PRIORITY, mcfg);
last_interrupt_index++;

/* 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);
scfg->rxi_irq = (IRQn_Type)last_interrupt_index;
set_iic_rx_link_event(last_interrupt_index, p_cfg->mcfg->channel);
R_BSP_IrqCfg((IRQn_Type)last_interrupt_index, I2C_MASTER_PRIORITY, mcfg);
last_interrupt_index++;

/* 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);
scfg->tei_irq = (IRQn_Type)last_interrupt_index;
set_iic_tei_link_event(last_interrupt_index, p_cfg->mcfg->channel);
R_BSP_IrqCfg((IRQn_Type)last_interrupt_index, I2C_MASTER_PRIORITY, mcfg);
last_interrupt_index++;

/* 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);
scfg->eri_irq = (IRQn_Type)last_interrupt_index;
set_iic_eri_link_event(last_interrupt_index, p_cfg->mcfg->channel);
R_BSP_IrqCfg((IRQn_Type)last_interrupt_index, I2C_MASTER_PRIORITY, mcfg);
last_interrupt_index++;
}

*(irq_ptr + mcfg->txi_irq) = (uint32_t)iic_master_txi_isr;
*(irq_ptr + mcfg->rxi_irq) = (uint32_t)iic_master_rxi_isr;
*(irq_ptr + mcfg->tei_irq) = (uint32_t)iic_master_tei_isr;
*(irq_ptr + mcfg->eri_irq) = (uint32_t)iic_master_eri_isr;

R_BSP_IrqEnable (mcfg->txi_irq);
R_BSP_IrqEnable (mcfg->rxi_irq);
R_BSP_IrqEnable (mcfg->tei_irq);
R_BSP_IrqEnable (mcfg->eri_irq);
}
/* I2C SCI MASTER (only) */
else if(p == IRQ_SCI_I2C_MASTER && cfg != NULL) {
I2CIrqMasterReq_t *p_cfg = (I2CIrqMasterReq_t *)cfg;
//iic_master_instance_ctrl_t *ctrl = (iic_master_instance_ctrl_t *)p_cfg->ctrl;
i2c_master_cfg_t *mcfg = (i2c_master_cfg_t *)p_cfg->cfg;
uint8_t hw_channel = p_cfg->hw_channel;
I2CIrqReq_t *p_cfg = (I2CIrqReq_t *)cfg;
i2c_master_cfg_t *mcfg = (i2c_master_cfg_t *)p_cfg->mcfg;
mcfg->ipl = I2C_MASTER_PRIORITY;
if (mcfg->txi_irq == FSP_INVALID_VECTOR) {
/* TX interrupt */
mcfg->txi_irq = (IRQn_Type)last_interrupt_index;
*(irq_ptr + last_interrupt_index) = (uint32_t)sci_i2c_txi_isr;
set_sci_tx_link_event(last_interrupt_index, hw_channel);
set_sci_tx_link_event(last_interrupt_index, p_cfg->mcfg->channel);
R_BSP_IrqCfg((IRQn_Type)last_interrupt_index, I2C_MASTER_PRIORITY, mcfg);
last_interrupt_index++;

/* RX interrupt */
mcfg->rxi_irq = (IRQn_Type)last_interrupt_index;
*(irq_ptr + last_interrupt_index) = (uint32_t)sci_i2c_rxi_isr;
set_sci_rx_link_event(last_interrupt_index, hw_channel);
set_sci_rx_link_event(last_interrupt_index, p_cfg->mcfg->channel);
R_BSP_IrqCfg((IRQn_Type)last_interrupt_index, I2C_MASTER_PRIORITY, mcfg);
last_interrupt_index++;

/* TX ERROR interrupt */
mcfg->tei_irq = (IRQn_Type)last_interrupt_index;
*(irq_ptr + last_interrupt_index) = (uint32_t)sci_i2c_tei_isr;
set_sci_tei_link_event(last_interrupt_index, hw_channel);
set_sci_tei_link_event(last_interrupt_index, p_cfg->mcfg->channel);
R_BSP_IrqCfg((IRQn_Type)last_interrupt_index, I2C_MASTER_PRIORITY, mcfg);
last_interrupt_index++;

/* RX ERROR interrupt */
#if 0
mcfg->eri_irq = (IRQn_Type)last_interrupt_index;
*(irq_ptr + last_interrupt_index) = (uint32_t)sci_i2c_eri_isr;
set_sci_eri_link_event(last_interrupt_index, hw_channel);
set_sci_eri_link_event(last_interrupt_index, p_cfg->mcfg->channel);
R_BSP_IrqCfg((IRQn_Type)last_interrupt_index, I2C_MASTER_PRIORITY, mcfg);
last_interrupt_index++;
#endif
Expand All @@ -641,38 +647,45 @@ bool IRQManager::addPeripheral(Peripheral_t p, void *cfg) {
#endif
}
else if(p == IRQ_I2C_SLAVE && cfg != NULL) {
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) {
I2CIrqReq_t *p_cfg = (I2CIrqReq_t *)cfg;
i2c_master_cfg_t *mcfg = (i2c_master_cfg_t *)p_cfg->mcfg;
i2c_slave_cfg_t *scfg = (i2c_slave_cfg_t *)p_cfg->scfg;
scfg->ipl = I2C_SLAVE_PRIORITY;
scfg->eri_ipl = I2C_SLAVE_PRIORITY;

if (scfg->txi_irq == FSP_INVALID_VECTOR) {
/* 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);
mcfg->txi_irq = (IRQn_Type)last_interrupt_index;
scfg->txi_irq = (IRQn_Type)last_interrupt_index;
set_iic_tx_link_event(last_interrupt_index, scfg->channel);
last_interrupt_index++;

/* 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);
scfg->rxi_irq = (IRQn_Type)last_interrupt_index;
mcfg->rxi_irq = (IRQn_Type)last_interrupt_index;
set_iic_rx_link_event(last_interrupt_index, scfg->channel);
last_interrupt_index++;

/* 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);
scfg->tei_irq = (IRQn_Type)last_interrupt_index;
mcfg->tei_irq = (IRQn_Type)last_interrupt_index;
set_iic_tei_link_event(last_interrupt_index, scfg->channel);
last_interrupt_index++;

/* 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);
scfg->eri_irq = (IRQn_Type)last_interrupt_index;
mcfg->eri_irq = (IRQn_Type)last_interrupt_index;
set_iic_eri_link_event(last_interrupt_index, scfg->channel);
last_interrupt_index++;
}
R_BSP_IrqEnable (p_cfg->txi_irq);
R_BSP_IrqEnable (p_cfg->rxi_irq);
R_BSP_IrqEnable (p_cfg->tei_irq);
R_BSP_IrqEnable (p_cfg->eri_irq);
*(irq_ptr + scfg->txi_irq) = (uint32_t)iic_slave_txi_isr;
*(irq_ptr + scfg->rxi_irq) = (uint32_t)iic_slave_rxi_isr;
*(irq_ptr + scfg->tei_irq) = (uint32_t)iic_slave_tei_isr;
*(irq_ptr + scfg->eri_irq) = (uint32_t)iic_slave_eri_isr;
R_BSP_IrqEnable (scfg->txi_irq);
R_BSP_IrqEnable (scfg->rxi_irq);
R_BSP_IrqEnable (scfg->tei_irq);
R_BSP_IrqEnable (scfg->eri_irq);

}
#endif
Expand Down
16 changes: 4 additions & 12 deletions cores/arduino/IRQManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,18 +74,10 @@ typedef struct rtc_irq {
#include "r_iic_master.h"
#include "r_iic_slave.h"

typedef struct i2c_master_irq {
iic_master_instance_ctrl_t *ctrl;
i2c_master_cfg_t *cfg;
uint8_t hw_channel;

} I2CIrqMasterReq_t;

typedef struct i2c_slave_irq {
iic_slave_instance_ctrl_t *ctrl;
i2c_slave_cfg_t *cfg;

} I2CIrqSlaveReq_t;
typedef struct i2c_irq_req {
i2c_master_cfg_t *mcfg;
i2c_slave_cfg_t *scfg;
} I2CIrqReq_t;
#endif

#if SPI_HOWMANY > 0
Expand Down
45 changes: 29 additions & 16 deletions libraries/Wire/Wire.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,16 @@ bool TwoWire::cfg_pins(int max_index) {

/* -------------------------------------------------------------------------- */
void TwoWire::begin(void) {
/* -------------------------------------------------------------------------- */
end();
facchinm marked this conversation as resolved.
Show resolved Hide resolved
is_master = true;
_begin();

}


/* -------------------------------------------------------------------------- */
void TwoWire::_begin(void) {
/* -------------------------------------------------------------------------- */
init_ok = true;
int max_index = PINS_COUNT;
Expand Down Expand Up @@ -368,15 +378,11 @@ void TwoWire::begin(void) {
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;
I2CIrqReq_t irq_req;
irq_req.mcfg = &m_i2c_cfg;
irq_req.scfg = &s_i2c_cfg;

if(is_master) {
if(is_sci) {
init_ok &= IRQManager::getInstance().addPeripheral(IRQ_SCI_I2C_MASTER,&irq_req);
}
Expand All @@ -391,7 +397,7 @@ void TwoWire::begin(void) {
}
}
else {
init_ok &= IRQManager::getInstance().addPeripheral(IRQ_I2C_SLAVE,&s_i2c_cfg);
init_ok &= IRQManager::getInstance().addPeripheral(IRQ_I2C_SLAVE,&irq_req);
if(FSP_SUCCESS == s_open(&s_i2c_ctrl,&s_i2c_cfg)) {
init_ok &= true;
}
Expand All @@ -404,26 +410,23 @@ void TwoWire::begin(void) {
/* -------------------------------------------------------------------------- */
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) {
/* -------------------------------------------------------------------------- */
is_master = false;
facchinm marked this conversation as resolved.
Show resolved Hide resolved
slave_address = (uint16_t)address;
begin((uint16_t)address);
}

/* -------------------------------------------------------------------------- */
void TwoWire::begin(uint8_t address) {
/* -------------------------------------------------------------------------- */
is_master = false;
slave_address = (uint16_t)address;
begin((uint16_t)address);
}

Expand All @@ -434,12 +437,22 @@ void TwoWire::end(void) {
if(init_ok) {
if(is_master) {
if(m_close != nullptr) {
m_close(&m_i2c_ctrl);
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) {
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);

}
}
}
Expand Down
2 changes: 2 additions & 0 deletions libraries/Wire/Wire.h
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,8 @@ class TwoWire : public arduino::HardwareI2C {
static void WireSCIMasterCallback(i2c_master_callback_args_t *);
static void WireMasterCallback(i2c_master_callback_args_t *);
static void WireSlaveCallback(i2c_slave_callback_args_t *);

void _begin();

int scl_pin;
int sda_pin;
Expand Down
Loading