Skip to content

Commit d0354d4

Browse files
authored
Wire: allow switch from master to slave and vice versa (#191)
1 parent 87dcacb commit d0354d4

File tree

5 files changed

+91
-68
lines changed

5 files changed

+91
-68
lines changed

Diff for: .gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
.idea
2+
compile_commands.json
3+
.clangd
4+
.cache/
25
cores/arduino/mydebug.cpp
36
libraries/Storage/.development
47
cores/arduino/mydebug.cpp.donotuse

Diff for: cores/arduino/IRQManager.cpp

+53-40
Original file line numberDiff line numberDiff line change
@@ -556,79 +556,85 @@ bool IRQManager::addPeripheral(Peripheral_t p, void *cfg) {
556556
#endif
557557

558558
#if WIRE_HOWMANY > 0
559+
/* I2C true NOT SCI */
559560
else if(p == IRQ_I2C_MASTER && cfg != NULL) {
560-
I2CIrqMasterReq_t *p_cfg = (I2CIrqMasterReq_t *)cfg;
561-
//iic_master_instance_ctrl_t *ctrl = (iic_master_instance_ctrl_t *)p_cfg->ctrl;
562-
i2c_master_cfg_t *mcfg = (i2c_master_cfg_t *)p_cfg->cfg;
563-
uint8_t hw_channel = p_cfg->hw_channel;
561+
I2CIrqReq_t *p_cfg = (I2CIrqReq_t *)cfg;
562+
i2c_master_cfg_t *mcfg = (i2c_master_cfg_t *)p_cfg->mcfg;
563+
i2c_slave_cfg_t *scfg = (i2c_slave_cfg_t *)p_cfg->scfg;
564564
mcfg->ipl = I2C_MASTER_PRIORITY;
565+
565566
if (mcfg->txi_irq == FSP_INVALID_VECTOR) {
566567
/* TX interrupt */
567568
mcfg->txi_irq = (IRQn_Type)last_interrupt_index;
568-
*(irq_ptr + last_interrupt_index) = (uint32_t)iic_master_txi_isr;
569-
set_iic_tx_link_event(last_interrupt_index, hw_channel);
569+
scfg->txi_irq = (IRQn_Type)last_interrupt_index;
570+
set_iic_tx_link_event(last_interrupt_index, p_cfg->mcfg->channel);
570571
R_BSP_IrqCfg((IRQn_Type)last_interrupt_index, I2C_MASTER_PRIORITY, mcfg);
571572
last_interrupt_index++;
572573

573574
/* RX interrupt */
574575
mcfg->rxi_irq = (IRQn_Type)last_interrupt_index;
575-
*(irq_ptr + last_interrupt_index) = (uint32_t)iic_master_rxi_isr;
576-
set_iic_rx_link_event(last_interrupt_index, hw_channel);
576+
scfg->rxi_irq = (IRQn_Type)last_interrupt_index;
577+
set_iic_rx_link_event(last_interrupt_index, p_cfg->mcfg->channel);
577578
R_BSP_IrqCfg((IRQn_Type)last_interrupt_index, I2C_MASTER_PRIORITY, mcfg);
578579
last_interrupt_index++;
579580

580581
/* TX ERROR interrupt */
581582
mcfg->tei_irq = (IRQn_Type)last_interrupt_index;
582-
*(irq_ptr + last_interrupt_index) = (uint32_t)iic_master_tei_isr;
583-
set_iic_tei_link_event(last_interrupt_index, hw_channel);
583+
scfg->tei_irq = (IRQn_Type)last_interrupt_index;
584+
set_iic_tei_link_event(last_interrupt_index, p_cfg->mcfg->channel);
584585
R_BSP_IrqCfg((IRQn_Type)last_interrupt_index, I2C_MASTER_PRIORITY, mcfg);
585586
last_interrupt_index++;
586587

587588
/* RX ERROR interrupt */
588589
mcfg->eri_irq = (IRQn_Type)last_interrupt_index;
589-
*(irq_ptr + last_interrupt_index) = (uint32_t)iic_master_eri_isr;
590-
set_iic_eri_link_event(last_interrupt_index, hw_channel);
590+
scfg->eri_irq = (IRQn_Type)last_interrupt_index;
591+
set_iic_eri_link_event(last_interrupt_index, p_cfg->mcfg->channel);
591592
R_BSP_IrqCfg((IRQn_Type)last_interrupt_index, I2C_MASTER_PRIORITY, mcfg);
592593
last_interrupt_index++;
593594
}
595+
596+
*(irq_ptr + mcfg->txi_irq) = (uint32_t)iic_master_txi_isr;
597+
*(irq_ptr + mcfg->rxi_irq) = (uint32_t)iic_master_rxi_isr;
598+
*(irq_ptr + mcfg->tei_irq) = (uint32_t)iic_master_tei_isr;
599+
*(irq_ptr + mcfg->eri_irq) = (uint32_t)iic_master_eri_isr;
600+
594601
R_BSP_IrqEnable (mcfg->txi_irq);
595602
R_BSP_IrqEnable (mcfg->rxi_irq);
596603
R_BSP_IrqEnable (mcfg->tei_irq);
597604
R_BSP_IrqEnable (mcfg->eri_irq);
598605
}
606+
/* I2C SCI MASTER (only) */
599607
else if(p == IRQ_SCI_I2C_MASTER && cfg != NULL) {
600-
I2CIrqMasterReq_t *p_cfg = (I2CIrqMasterReq_t *)cfg;
601-
//iic_master_instance_ctrl_t *ctrl = (iic_master_instance_ctrl_t *)p_cfg->ctrl;
602-
i2c_master_cfg_t *mcfg = (i2c_master_cfg_t *)p_cfg->cfg;
603-
uint8_t hw_channel = p_cfg->hw_channel;
608+
I2CIrqReq_t *p_cfg = (I2CIrqReq_t *)cfg;
609+
i2c_master_cfg_t *mcfg = (i2c_master_cfg_t *)p_cfg->mcfg;
604610
mcfg->ipl = I2C_MASTER_PRIORITY;
605611
if (mcfg->txi_irq == FSP_INVALID_VECTOR) {
606612
/* TX interrupt */
607613
mcfg->txi_irq = (IRQn_Type)last_interrupt_index;
608614
*(irq_ptr + last_interrupt_index) = (uint32_t)sci_i2c_txi_isr;
609-
set_sci_tx_link_event(last_interrupt_index, hw_channel);
615+
set_sci_tx_link_event(last_interrupt_index, p_cfg->mcfg->channel);
610616
R_BSP_IrqCfg((IRQn_Type)last_interrupt_index, I2C_MASTER_PRIORITY, mcfg);
611617
last_interrupt_index++;
612618

613619
/* RX interrupt */
614620
mcfg->rxi_irq = (IRQn_Type)last_interrupt_index;
615621
*(irq_ptr + last_interrupt_index) = (uint32_t)sci_i2c_rxi_isr;
616-
set_sci_rx_link_event(last_interrupt_index, hw_channel);
622+
set_sci_rx_link_event(last_interrupt_index, p_cfg->mcfg->channel);
617623
R_BSP_IrqCfg((IRQn_Type)last_interrupt_index, I2C_MASTER_PRIORITY, mcfg);
618624
last_interrupt_index++;
619625

620626
/* TX ERROR interrupt */
621627
mcfg->tei_irq = (IRQn_Type)last_interrupt_index;
622628
*(irq_ptr + last_interrupt_index) = (uint32_t)sci_i2c_tei_isr;
623-
set_sci_tei_link_event(last_interrupt_index, hw_channel);
629+
set_sci_tei_link_event(last_interrupt_index, p_cfg->mcfg->channel);
624630
R_BSP_IrqCfg((IRQn_Type)last_interrupt_index, I2C_MASTER_PRIORITY, mcfg);
625631
last_interrupt_index++;
626632

627633
/* RX ERROR interrupt */
628634
#if 0
629635
mcfg->eri_irq = (IRQn_Type)last_interrupt_index;
630636
*(irq_ptr + last_interrupt_index) = (uint32_t)sci_i2c_eri_isr;
631-
set_sci_eri_link_event(last_interrupt_index, hw_channel);
637+
set_sci_eri_link_event(last_interrupt_index, p_cfg->mcfg->channel);
632638
R_BSP_IrqCfg((IRQn_Type)last_interrupt_index, I2C_MASTER_PRIORITY, mcfg);
633639
last_interrupt_index++;
634640
#endif
@@ -641,38 +647,45 @@ bool IRQManager::addPeripheral(Peripheral_t p, void *cfg) {
641647
#endif
642648
}
643649
else if(p == IRQ_I2C_SLAVE && cfg != NULL) {
644-
i2c_slave_cfg_t *p_cfg = (i2c_slave_cfg_t *)cfg;
645-
p_cfg->ipl = I2C_SLAVE_PRIORITY;
646-
p_cfg->eri_ipl = I2C_SLAVE_PRIORITY;
647-
if (p_cfg->txi_irq == FSP_INVALID_VECTOR) {
650+
I2CIrqReq_t *p_cfg = (I2CIrqReq_t *)cfg;
651+
i2c_master_cfg_t *mcfg = (i2c_master_cfg_t *)p_cfg->mcfg;
652+
i2c_slave_cfg_t *scfg = (i2c_slave_cfg_t *)p_cfg->scfg;
653+
scfg->ipl = I2C_SLAVE_PRIORITY;
654+
scfg->eri_ipl = I2C_SLAVE_PRIORITY;
655+
656+
if (scfg->txi_irq == FSP_INVALID_VECTOR) {
648657
/* TX interrupt */
649-
p_cfg->txi_irq = (IRQn_Type)last_interrupt_index;
650-
*(irq_ptr + last_interrupt_index) = (uint32_t)iic_slave_txi_isr;
651-
set_iic_tx_link_event(last_interrupt_index, p_cfg->channel);
658+
mcfg->txi_irq = (IRQn_Type)last_interrupt_index;
659+
scfg->txi_irq = (IRQn_Type)last_interrupt_index;
660+
set_iic_tx_link_event(last_interrupt_index, scfg->channel);
652661
last_interrupt_index++;
653662

654663
/* RX interrupt */
655-
p_cfg->rxi_irq = (IRQn_Type)last_interrupt_index;
656-
*(irq_ptr + last_interrupt_index) = (uint32_t)iic_slave_rxi_isr;
657-
set_iic_rx_link_event(last_interrupt_index, p_cfg->channel);
664+
scfg->rxi_irq = (IRQn_Type)last_interrupt_index;
665+
mcfg->rxi_irq = (IRQn_Type)last_interrupt_index;
666+
set_iic_rx_link_event(last_interrupt_index, scfg->channel);
658667
last_interrupt_index++;
659668

660669
/* TEI interrupt */
661-
p_cfg->tei_irq = (IRQn_Type)last_interrupt_index;
662-
*(irq_ptr + last_interrupt_index) = (uint32_t)iic_slave_tei_isr;
663-
set_iic_tei_link_event(last_interrupt_index, p_cfg->channel);
670+
scfg->tei_irq = (IRQn_Type)last_interrupt_index;
671+
mcfg->tei_irq = (IRQn_Type)last_interrupt_index;
672+
set_iic_tei_link_event(last_interrupt_index, scfg->channel);
664673
last_interrupt_index++;
665674

666675
/* ERI interrupt */
667-
p_cfg->eri_irq = (IRQn_Type)last_interrupt_index;
668-
*(irq_ptr + last_interrupt_index) = (uint32_t)iic_slave_eri_isr;
669-
set_iic_eri_link_event(last_interrupt_index, p_cfg->channel);
676+
scfg->eri_irq = (IRQn_Type)last_interrupt_index;
677+
mcfg->eri_irq = (IRQn_Type)last_interrupt_index;
678+
set_iic_eri_link_event(last_interrupt_index, scfg->channel);
670679
last_interrupt_index++;
671680
}
672-
R_BSP_IrqEnable (p_cfg->txi_irq);
673-
R_BSP_IrqEnable (p_cfg->rxi_irq);
674-
R_BSP_IrqEnable (p_cfg->tei_irq);
675-
R_BSP_IrqEnable (p_cfg->eri_irq);
681+
*(irq_ptr + scfg->txi_irq) = (uint32_t)iic_slave_txi_isr;
682+
*(irq_ptr + scfg->rxi_irq) = (uint32_t)iic_slave_rxi_isr;
683+
*(irq_ptr + scfg->tei_irq) = (uint32_t)iic_slave_tei_isr;
684+
*(irq_ptr + scfg->eri_irq) = (uint32_t)iic_slave_eri_isr;
685+
R_BSP_IrqEnable (scfg->txi_irq);
686+
R_BSP_IrqEnable (scfg->rxi_irq);
687+
R_BSP_IrqEnable (scfg->tei_irq);
688+
R_BSP_IrqEnable (scfg->eri_irq);
676689

677690
}
678691
#endif

Diff for: cores/arduino/IRQManager.h

+4-12
Original file line numberDiff line numberDiff line change
@@ -74,18 +74,10 @@ typedef struct rtc_irq {
7474
#include "r_iic_master.h"
7575
#include "r_iic_slave.h"
7676

77-
typedef struct i2c_master_irq {
78-
iic_master_instance_ctrl_t *ctrl;
79-
i2c_master_cfg_t *cfg;
80-
uint8_t hw_channel;
81-
82-
} I2CIrqMasterReq_t;
83-
84-
typedef struct i2c_slave_irq {
85-
iic_slave_instance_ctrl_t *ctrl;
86-
i2c_slave_cfg_t *cfg;
87-
88-
} I2CIrqSlaveReq_t;
77+
typedef struct i2c_irq_req {
78+
i2c_master_cfg_t *mcfg;
79+
i2c_slave_cfg_t *scfg;
80+
} I2CIrqReq_t;
8981
#endif
9082

9183
#if SPI_HOWMANY > 0

Diff for: libraries/Wire/Wire.cpp

+29-16
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,16 @@ bool TwoWire::cfg_pins(int max_index) {
273273

274274
/* -------------------------------------------------------------------------- */
275275
void TwoWire::begin(void) {
276+
/* -------------------------------------------------------------------------- */
277+
end();
278+
is_master = true;
279+
_begin();
280+
281+
}
282+
283+
284+
/* -------------------------------------------------------------------------- */
285+
void TwoWire::_begin(void) {
276286
/* -------------------------------------------------------------------------- */
277287
init_ok = true;
278288
int max_index = PINS_COUNT;
@@ -368,15 +378,11 @@ void TwoWire::begin(void) {
368378
return;
369379
}
370380

371-
if(is_master) {
372-
I2CIrqMasterReq_t irq_req;
373-
irq_req.ctrl = &m_i2c_ctrl;
374-
irq_req.cfg = &m_i2c_cfg;
375-
/* see note in the cfg_pins
376-
the IRQ manager need to know the HW channel that in case of SCI
377-
peripheral is not the one in the cfg structure but the one in
378-
the Wire channel, so copy it in the request */
379-
irq_req.hw_channel = channel;
381+
I2CIrqReq_t irq_req;
382+
irq_req.mcfg = &m_i2c_cfg;
383+
irq_req.scfg = &s_i2c_cfg;
384+
385+
if(is_master) {
380386
if(is_sci) {
381387
init_ok &= IRQManager::getInstance().addPeripheral(IRQ_SCI_I2C_MASTER,&irq_req);
382388
}
@@ -391,7 +397,7 @@ void TwoWire::begin(void) {
391397
}
392398
}
393399
else {
394-
init_ok &= IRQManager::getInstance().addPeripheral(IRQ_I2C_SLAVE,&s_i2c_cfg);
400+
init_ok &= IRQManager::getInstance().addPeripheral(IRQ_I2C_SLAVE,&irq_req);
395401
if(FSP_SUCCESS == s_open(&s_i2c_ctrl,&s_i2c_cfg)) {
396402
init_ok &= true;
397403
}
@@ -404,26 +410,23 @@ void TwoWire::begin(void) {
404410
/* -------------------------------------------------------------------------- */
405411
void TwoWire::begin(uint16_t address) {
406412
/* -------------------------------------------------------------------------- */
413+
end();
407414
is_master = false;
408415
slave_address = address;
409416
/* Address is set inside begin() using slave_address member variable */
410-
begin();
417+
_begin();
411418

412419
}
413420

414421
/* -------------------------------------------------------------------------- */
415422
void TwoWire::begin(int address) {
416423
/* -------------------------------------------------------------------------- */
417-
is_master = false;
418-
slave_address = (uint16_t)address;
419424
begin((uint16_t)address);
420425
}
421426

422427
/* -------------------------------------------------------------------------- */
423428
void TwoWire::begin(uint8_t address) {
424429
/* -------------------------------------------------------------------------- */
425-
is_master = false;
426-
slave_address = (uint16_t)address;
427430
begin((uint16_t)address);
428431
}
429432

@@ -434,12 +437,22 @@ void TwoWire::end(void) {
434437
if(init_ok) {
435438
if(is_master) {
436439
if(m_close != nullptr) {
437-
m_close(&m_i2c_ctrl);
440+
m_close(&m_i2c_ctrl);
441+
R_BSP_IrqDisable (m_i2c_cfg.txi_irq);
442+
R_BSP_IrqDisable (m_i2c_cfg.rxi_irq);
443+
R_BSP_IrqDisable (m_i2c_cfg.tei_irq);
444+
R_BSP_IrqDisable (m_i2c_cfg.eri_irq);
445+
438446
}
439447
}
440448
else {
441449
if(s_close != nullptr) {
442450
s_close(&s_i2c_ctrl);
451+
R_BSP_IrqDisable (s_i2c_cfg.txi_irq);
452+
R_BSP_IrqDisable (s_i2c_cfg.rxi_irq);
453+
R_BSP_IrqDisable (s_i2c_cfg.tei_irq);
454+
R_BSP_IrqDisable (s_i2c_cfg.eri_irq);
455+
443456
}
444457
}
445458
}

Diff for: libraries/Wire/Wire.h

+2
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,8 @@ class TwoWire : public arduino::HardwareI2C {
158158
static void WireSCIMasterCallback(i2c_master_callback_args_t *);
159159
static void WireMasterCallback(i2c_master_callback_args_t *);
160160
static void WireSlaveCallback(i2c_slave_callback_args_t *);
161+
162+
void _begin();
161163

162164
int scl_pin;
163165
int sda_pin;

0 commit comments

Comments
 (0)