Skip to content

Commit 4f451c8

Browse files
authored
Merge pull request arduino#46 from bcmi-labs/can-h33-rebased
Implement CAN FD support for Portenta H33 arduino#2 Former-commit-id: 6f20171
2 parents 6eb9e42 + 9e64a3f commit 4f451c8

38 files changed

+992
-652
lines changed

cores/arduino/IRQManager.cpp

+82-12
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#define TIMER_PRIORITY 12
3232
#define ADC_PRIORITY 12
3333
#define CAN_PRIORITY 12
34+
#define CANFD_PRIORITY 12
3435
#define FIRST_INT_SLOT_FREE 0
3536

3637
IRQManager::IRQManager() : last_interrupt_index{0} {
@@ -868,19 +869,7 @@ bool IRQManager::addPeripheral(Peripheral_t p, void *cfg) {
868869
********************************************************************** */
869870
else if(p == IRQ_CAN && cfg != NULL) {
870871
if ((last_interrupt_index + CAN_REQ_NUM) < PROG_IRQ_NUM ) {
871-
# if IS_CAN_FD
872-
canfd_instance_ctrl_t * p_ctrl = reinterpret_cast<CanIrqReq_t *>(cfg)->ctrl;
873-
#define can_error_isr canfd_error_isr
874-
#define can_rx_isr canfd_rx_fifo_isr
875-
#define can_tx_isr canfd_channel_tx_isr
876-
// TODO: ATTENTION:
877-
// this is just a workaround, CANFD interrupts are different and somehow
878-
// more specialized
879-
// This is not expected to work until set_can_error_link_event and similar functions
880-
// are ported
881-
# else
882872
can_instance_ctrl_t * p_ctrl = reinterpret_cast<CanIrqReq_t *>(cfg)->ctrl;
883-
# endif
884873
can_cfg_t * p_cfg = reinterpret_cast<CanIrqReq_t *>(cfg)->cfg;
885874
p_cfg->ipl = CAN_PRIORITY; /* All interrupts share the same priority. */
886875

@@ -908,6 +897,7 @@ bool IRQManager::addPeripheral(Peripheral_t p, void *cfg) {
908897
}
909898
#endif /* CAN_HOWMANY > 0 */
910899

900+
911901
#if ETHERNET_HOWMANY > 0
912902
/* **********************************************************************
913903
ETHERNET
@@ -926,6 +916,41 @@ bool IRQManager::addPeripheral(Peripheral_t p, void *cfg) {
926916
}
927917
}
928918
#endif
919+
920+
#if CANFD_HOWMANY > 0
921+
/* **********************************************************************
922+
CANFD
923+
********************************************************************** */
924+
else if(p == IRQ_CANFD && cfg != NULL) {
925+
if ((last_interrupt_index + CAN_REQ_NUM) < PROG_IRQ_NUM ) {
926+
canfd_instance_ctrl_t * p_ctrl = reinterpret_cast<CanFdIrqReq_t *>(cfg)->ctrl;
927+
can_cfg_t * p_cfg = reinterpret_cast<CanFdIrqReq_t *>(cfg)->cfg;
928+
p_cfg->ipl = CAN_PRIORITY; /* All interrupts share the same priority. */
929+
930+
/* Error interrupt */
931+
p_cfg->error_irq = (IRQn_Type)last_interrupt_index;
932+
*(irq_ptr + last_interrupt_index) = (uint32_t)canfd_error_isr;
933+
set_canfd_error_link_event(last_interrupt_index, p_cfg->channel);
934+
R_BSP_IrqCfgEnable(p_cfg->error_irq, p_cfg->ipl, p_ctrl);
935+
last_interrupt_index++;
936+
937+
/* Receive interrupt */
938+
p_cfg->rx_irq = (IRQn_Type)last_interrupt_index;
939+
*(irq_ptr + last_interrupt_index) = (uint32_t)canfd_rx_fifo_isr;
940+
set_canfd_rx_link_event(last_interrupt_index, p_cfg->channel);
941+
R_BSP_IrqCfgEnable(p_cfg->rx_irq, p_cfg->ipl, p_ctrl);
942+
last_interrupt_index++;
943+
944+
/* Transmit interrupt */
945+
p_cfg->tx_irq = (IRQn_Type)last_interrupt_index;
946+
*(irq_ptr + last_interrupt_index) = (uint32_t)canfd_channel_tx_isr;
947+
set_canfd_tx_link_event(last_interrupt_index, p_cfg->channel);
948+
R_BSP_IrqCfgEnable(p_cfg->tx_irq, p_cfg->ipl, p_ctrl);
949+
last_interrupt_index++;
950+
}
951+
}
952+
#endif /* CANFD_HOWMANY > 0 */
953+
929954
else {
930955
rv = false;
931956
}
@@ -1666,6 +1691,51 @@ void IRQManager::set_can_tx_link_event(int li, int ch)
16661691
#endif
16671692
}
16681693

1694+
void IRQManager::set_canfd_error_link_event(int li, int ch)
1695+
{
1696+
if (0) {}
1697+
#ifdef ELC_EVENT_CAN0_CHERR
1698+
else if(ch == 0) {
1699+
R_ICU->IELSR[li] = BSP_PRV_IELS_ENUM(EVENT_CAN0_CHERR);
1700+
}
1701+
#endif
1702+
#ifdef ELC_EVENT_CAN1_CHERR
1703+
else if(ch == 1) {
1704+
R_ICU->IELSR[li] = BSP_PRV_IELS_ENUM(EVENT_CAN1_CHERR);
1705+
}
1706+
#endif
1707+
}
1708+
1709+
void IRQManager::set_canfd_rx_link_event(int li, int ch)
1710+
{
1711+
if (0) {}
1712+
#ifdef ELC_EVENT_CAN0_COMFRX
1713+
else if(ch == 0) {
1714+
R_ICU->IELSR[li] = BSP_PRV_IELS_ENUM(EVENT_CAN0_COMFRX);
1715+
}
1716+
#endif
1717+
#ifdef ELC_EVENT_CAN1_COMFRX
1718+
else if(ch == 1) {
1719+
R_ICU->IELSR[li] = BSP_PRV_IELS_ENUM(EVENT_CAN1_COMFRX);
1720+
}
1721+
#endif
1722+
}
1723+
1724+
void IRQManager::set_canfd_tx_link_event(int li, int ch)
1725+
{
1726+
if (0) {}
1727+
#ifdef ELC_EVENT_CAN0_TX
1728+
else if(ch == 0) {
1729+
R_ICU->IELSR[li] = BSP_PRV_IELS_ENUM(EVENT_CAN0_TX);
1730+
}
1731+
#endif
1732+
#ifdef ELC_EVENT_CAN1_TX
1733+
else if(ch == 1) {
1734+
R_ICU->IELSR[li] = BSP_PRV_IELS_ENUM(EVENT_CAN1_TX);
1735+
}
1736+
#endif
1737+
}
1738+
16691739
bool IRQManager::set_dma_link_event(int li, int ch) {
16701740
bool rv = false;
16711741
if (0) {}

cores/arduino/IRQManager.h

+18-11
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ typedef enum {
4141
IRQ_SPI_MASTER,
4242
IRQ_SCI_SPI_MASTER,
4343
IRQ_CAN,
44-
IRQ_ETHERNET
44+
IRQ_ETHERNET,
45+
IRQ_CANFD,
4546
} Peripheral_t;
4647

4748
#if RTC_HOWMANY > 0
@@ -99,22 +100,21 @@ typedef struct sci_spi_master_irq {
99100
#endif
100101

101102
#if CAN_HOWMANY > 0
102-
# if IS_CAN_FD
103-
# include "r_canfd.h"
104-
# else
105-
# include "r_can.h"
106-
# endif
107-
103+
# include "r_can.h"
108104
typedef struct can_irq {
109-
#if IS_CAN_FD
110-
canfd_instance_ctrl_t * ctrl;
111-
#else
112105
can_instance_ctrl_t * ctrl;
113-
#endif
114106
can_cfg_t * cfg;
115107
} CanIrqReq_t;
116108
#endif /* CAN_HOWMANY > 0 */
117109

110+
#if CANFD_HOWMANY > 0
111+
# include "r_canfd.h"
112+
typedef struct canfd_irq {
113+
canfd_instance_ctrl_t * ctrl;
114+
can_cfg_t * cfg;
115+
} CanFdIrqReq_t;
116+
#endif /* CANFD_HOWMANY > 0 */
117+
118118
typedef struct usb {
119119
uint32_t num_of_irqs_required;
120120
uint32_t address_of_handler;
@@ -177,6 +177,9 @@ void can_error_isr(void);
177177
void can_rx_isr(void);
178178
void can_tx_isr(void);
179179
void ether_eint_isr (void);
180+
void canfd_error_isr(void);
181+
void canfd_rx_fifo_isr(void);
182+
void canfd_channel_tx_isr(void);
180183
#ifdef __cplusplus
181184
}
182185
#endif
@@ -244,6 +247,10 @@ class IRQManager {
244247
void set_can_rx_link_event(int li, int ch);
245248
void set_can_tx_link_event(int li, int ch);
246249

250+
void set_canfd_error_link_event(int li, int ch);
251+
void set_canfd_rx_link_event(int li, int ch);
252+
void set_canfd_tx_link_event(int li, int ch);
253+
247254
bool set_dma_link_event(int li, int ch);
248255
IRQManager();
249256
};

cores/arduino/Interrupts.cpp

+3-4
Original file line numberDiff line numberDiff line change
@@ -80,15 +80,14 @@ static int pin2IrqChannel(int pin) {
8080
return -1;
8181
}
8282
/* getting configuration from table */
83-
const uint16_t *cfg = g_pin_cfg[pin].list;
84-
uint16_t cfg_irq = getPinCfg(cfg, PIN_CFG_REQ_INTERRUPT,false);
83+
auto cfg_irq = getPinCfgs(pin, PIN_CFG_REQ_INTERRUPT);
8584

8685
/* verify configuration are good */
87-
if(cfg_irq == 0) {
86+
if(cfg_irq[0] == 0) {
8887
return -1;
8988
}
9089

91-
return GET_CHANNEL(cfg_irq);
90+
return GET_CHANNEL(cfg_irq[0]);
9291
}
9392

9493
/* -------------------------------------------------------------------------- */

cores/arduino/Serial.cpp

+20-8
Original file line numberDiff line numberDiff line change
@@ -147,18 +147,30 @@ bool UART::cfg_pins(int max_index) {
147147
return false;
148148
}
149149
/* getting configuration from table */
150-
const uint16_t *cfg = g_pin_cfg[tx_pin].list;
151-
uint16_t cfg_tx = getPinCfg(cfg, PIN_CFG_REQ_UART_TX, true);
152-
cfg = g_pin_cfg[rx_pin].list;
153-
uint16_t cfg_rx = getPinCfg(cfg, PIN_CFG_REQ_UART_RX, true);
150+
auto cfgs_tx = getPinCfgs(tx_pin, PIN_CFG_REQ_UART_TX);
151+
auto cfgs_rx = getPinCfgs(rx_pin, PIN_CFG_REQ_UART_RX);
152+
153+
uint16_t cfg_tx = 0;
154+
uint16_t cfg_rx = 0;
155+
156+
/* Find the best combination */
157+
for (size_t i = 0; i < cfgs_tx.size(); i++) {
158+
for (size_t j = 0; j < cfgs_rx.size(); j++) {
159+
if (cfgs_tx[i] && cfgs_rx[i] && GET_CHANNEL(cfgs_tx[i]) == GET_CHANNEL(cfgs_rx[j])) {
160+
cfg_tx = cfgs_tx[i];
161+
cfg_rx = cfgs_rx[j];
162+
channel = GET_CHANNEL(cfg_tx);
163+
goto done;
164+
}
165+
}
166+
}
167+
168+
done:
154169
/* verify configuration are good */
155170
if(cfg_tx == 0 || cfg_rx == 0 ) {
156171
return false;
157172
}
158-
/* verify channel are the same for both pins */
159-
if(GET_CHANNEL(cfg_tx) != GET_CHANNEL(cfg_rx) ) {
160-
return false;
161-
}
173+
162174
/* verify channel does not exceed max possible uart channels */
163175
if(channel >= MAX_UARTS) {
164176
return false;

cores/arduino/analog.cpp

+4-42
Original file line numberDiff line numberDiff line change
@@ -139,20 +139,16 @@ static void ADC_irq_cbk(adc_callback_args_t * cb_data) {
139139
static ADC_Container *get_ADC_container_ptr(int32_t pin, uint16_t &cfg) {
140140
/* -------------------------------------------------------------------------- */
141141
ADC_Container *rv = nullptr;
142-
uint16_t cfg_adc = 0;
143-
if(pin >= 0) {
144-
const uint16_t *cfg = g_pin_cfg[pin].list;
145-
cfg_adc = getPinCfg(cfg, PIN_CFG_REQ_ADC);
146-
}
147-
if(cfg_adc > 0 ) {
148-
if(IS_ADC1(cfg_adc)) {
142+
auto cfg_adc = getPinCfgs(pin, PIN_CFG_REQ_ADC);
143+
if(cfg_adc[0] > 0 ) {
144+
if(IS_ADC1(cfg_adc[0])) {
149145
rv = &adc1;
150146
}
151147
else {
152148
rv = &adc;
153149
}
154150
}
155-
cfg = cfg_adc;
151+
cfg = cfg_adc[0];
156152
return rv;
157153

158154
}
@@ -348,40 +344,6 @@ bool attachScanEndBIrq(ADCIrqCbk_f cbk, adc_mode_t mode /*= ADC_MODE_GROUP_SCAN*
348344

349345
#endif
350346

351-
int getStoredAnalogValue(bsp_io_port_pin_t pin) {
352-
int rv = -1;
353-
int32_t index = getPinIndex(pin);
354-
uint16_t cfg_adc = 0;
355-
356-
if(index >= 0) {
357-
const uint16_t *cfg = g_pin_cfg[index].list;
358-
cfg_adc = getPinCfg(cfg, PIN_CFG_REQ_ADC);
359-
}
360-
if(cfg_adc > 0 ) {
361-
rv = analog_values_by_channels[GET_CHANNEL(cfg_adc)];
362-
rv = map(rv, 0, (1 << _privateGetHwAnalogResolution()), 0, (1 << _analogRequestedReadResolution));
363-
}
364-
return rv;
365-
}
366-
367-
int getStoredAnalogValue(pin_size_t pinNumber) {
368-
int rv = -1;
369-
int32_t index = digitalPinToAnalogPin(pinNumber);
370-
uint16_t cfg_adc = 0;
371-
if(index >= 0) {
372-
const uint16_t *cfg = g_pin_cfg[index].list;
373-
cfg_adc = getPinCfg(cfg, PIN_CFG_REQ_ADC);
374-
}
375-
if(cfg_adc > 0 ) {
376-
rv = analog_values_by_channels[GET_CHANNEL(cfg_adc)];
377-
rv = map(rv, 0, (1 << _privateGetHwAnalogResolution()), 0, (1 << _analogRequestedReadResolution));
378-
}
379-
return rv;
380-
}
381-
382-
383-
384-
385347
bool analogAttachIrqCompareA(uint16_t low_th, uint16_t high_th, bool enable_window, ADCIrqCbk_f cbk, adc_mode_t mode /*= ADC_MODE_GROUP_SCAN*/, uint8_t priority /* = 12 */){
386348
bool rv = true;
387349
if(adc.channel_cfg.p_window_cfg != nullptr) {

cores/arduino/analog.h

-2
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,6 @@ bool analogAttachIrqCompareB(bsp_io_port_pin_t pinNumber, bool lower_or_outside_
5656
bool analogAttachIrqCompareB(pin_size_t pinNumber, bool lower_or_outside_wnd, uint16_t low_th, uint16_t high_th, bool enable_window, ADCIrqCbk_f cbk, adc_mode_t mode = ADC_MODE_CONTINUOUS_SCAN, uint8_t priority = 12);
5757
bool analogAddPinToCompare(bsp_io_port_pin_t pin, bool lower_or_outside_wnd) ;
5858
bool analogAddPinToCompare(pin_size_t pinNumber, bool lower_or_outside_wnd);
59-
int getStoredAnalogValue(bsp_io_port_pin_t pinNumber);
60-
int getStoredAnalogValue(pin_size_t pinNumber);
6159

6260
int analogRead(bsp_io_port_pin_t pinNumber);
6361

cores/arduino/pwm.cpp

+5-6
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,18 @@ bool PwmOut::cfg_pin(int max_index) {
2121
return false;
2222
}
2323
/* getting configuration from table */
24-
const uint16_t *cfg = g_pin_cfg[_pin].list;
25-
uint16_t pin_cgf = getPinCfg(cfg, PIN_CFG_REQ_PWM,false);
24+
auto pin_cgf = getPinCfgs(_pin, PIN_CFG_REQ_PWM);
2625

2726
/* verify configuration are good */
28-
if(pin_cgf == 0) {
27+
if(pin_cgf[0] == 0) {
2928
return false;
3029
}
3130

32-
timer_channel = GET_CHANNEL(pin_cgf);
31+
timer_channel = GET_CHANNEL(pin_cgf[0]);
3332

34-
_is_agt = IS_PIN_AGT_PWM(pin_cgf);
33+
_is_agt = IS_PIN_AGT_PWM(pin_cgf[0]);
3534

36-
_pwm_channel = IS_PWM_ON_A(pin_cgf) ? CHANNEL_A : CHANNEL_B;
35+
_pwm_channel = IS_PWM_ON_A(pin_cgf[0]) ? CHANNEL_A : CHANNEL_B;
3736

3837
/* actually configuring PIN function */
3938
R_IOPORT_PinCfg(&g_ioport_ctrl, g_pin_cfg[_pin].pin, (uint32_t) (IOPORT_CFG_PERIPHERAL_PIN | (_is_agt ? IOPORT_PERIPHERAL_AGT : IOPORT_PERIPHERAL_GPT1)));

cores/arduino/variant.h

+2-4
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,9 @@ typedef enum {
2626
} PinCfgReq_t;
2727

2828
int32_t getPinIndex(bsp_io_port_pin_t p);
29-
uint16_t getPinCfg(const uint16_t *cfg, PinCfgReq_t req, bool prefer_sci);
3029
#ifdef __cplusplus
31-
static inline uint16_t getPinCfg(const uint16_t *cfg, PinCfgReq_t req) {
32-
return getPinCfg(cfg, req, false);
33-
}
30+
#include <array>
31+
std::array<uint16_t, 3> getPinCfgs(const pin_size_t pin, PinCfgReq_t req);
3432
#endif
3533

3634
#define SCI_CHANNEL 0x1

extras/e2studioProjects/Santiago/fsp_to_arduino.sh

+9
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,15 @@ else
1313
echo "already commented!"
1414
fi
1515

16+
mkdir -p fsp_patched
17+
cd fsp_patched
18+
ln -s ../../../tinyusb/hw/mcu/renesas/fsp/ra/ .
19+
cd ..
20+
21+
set +e
22+
find ra -type f | xargs -I{} cp fsp_patched/{} {}
23+
set -e
24+
1625
cd Debug
1726
make clean
1827
make -j$(nproc)

0 commit comments

Comments
 (0)