diff --git a/.github/workflows/compile-examples.yml b/.github/workflows/compile-examples.yml index bffbffe9f..3340e3c46 100644 --- a/.github/workflows/compile-examples.yml +++ b/.github/workflows/compile-examples.yml @@ -87,11 +87,13 @@ jobs: - board: fqbn: "arduino:renesas_uno:unor4wifi" additional-sketch-paths: | + - libraries/Arduino_LED_Matrix - libraries/WiFiS3 - libraries/OTAUpdate - board: fqbn: "arduino-git:renesas:unor4wifi" additional-sketch-paths: | + - libraries/Arduino_LED_Matrix - libraries/WiFiS3 - libraries/OTAUpdate - libraries/OPAMP @@ -157,6 +159,7 @@ jobs: - name: ArduinoDMX - name: ArduinoRS485 - name: ArduinoIoTCloud + - name: ArduinoGraphics platforms: | # Use Board Manager to install the latest release of Arduino Renesas Boards to get the toolchain - name: "arduino:renesas_uno" diff --git a/cores/arduino/IRQManager.cpp b/cores/arduino/IRQManager.cpp index 4d9e6e1e8..fffd8cf15 100644 --- a/cores/arduino/IRQManager.cpp +++ b/cores/arduino/IRQManager.cpp @@ -23,6 +23,7 @@ #define ADC_PRIORITY 12 #define CAN_PRIORITY 12 #define CANFD_PRIORITY 12 +#define I2S_PRIORITY 12 #define FIRST_INT_SLOT_FREE 0 IRQManager::IRQManager() : last_interrupt_index{0} { @@ -38,6 +39,28 @@ IRQManager& IRQManager::getInstance() { return instance; } +bool IRQManager::addGenericInterrupt(GenericIrqCfg_t &cfg, Irq_f fnc /*= nullptr*/){ + /* getting the address of the current location of the irq vector table */ + volatile uint32_t *irq_ptr = (volatile uint32_t *)SCB->VTOR; + /* set the displacement to the "programmable" part of the table */ + irq_ptr += FIXED_IRQ_NUM; + bool rv = false; + + if((cfg.irq == FSP_INVALID_VECTOR) && (last_interrupt_index < PROG_IRQ_NUM)) { + if(fnc != nullptr){ + R_ICU->IELSR[last_interrupt_index] = cfg.event; + *(irq_ptr + last_interrupt_index) = (uint32_t)fnc; + R_BSP_IrqDisable((IRQn_Type)last_interrupt_index); + R_BSP_IrqStatusClear((IRQn_Type)last_interrupt_index); + NVIC_SetPriority((IRQn_Type)last_interrupt_index, cfg.ipl); + R_BSP_IrqEnable ((IRQn_Type)last_interrupt_index); + cfg.irq = (IRQn_Type)last_interrupt_index; + last_interrupt_index++; + rv = true; + } + } + return rv; +} bool IRQManager::addADCScanEnd(ADC_Container *adc, Irq_f fnc /*= nullptr*/) { /* getting the address of the current location of the irq vector table */ @@ -45,8 +68,10 @@ bool IRQManager::addADCScanEnd(ADC_Container *adc, Irq_f fnc /*= nullptr*/) { /* set the displacement to the "programmable" part of the table */ irq_ptr += FIXED_IRQ_NUM; bool rv = true; - - if (adc->cfg.scan_end_irq == FSP_INVALID_VECTOR) { + if (last_interrupt_index >= PROG_IRQ_NUM){ + rv = false; + } + else if (adc->cfg.scan_end_irq == FSP_INVALID_VECTOR) { if(set_adc_end_link_event(last_interrupt_index, adc->cfg.unit)) { adc->cfg.scan_end_ipl = TIMER_PRIORITY; adc->cfg.scan_end_irq = (IRQn_Type)last_interrupt_index; @@ -79,8 +104,10 @@ bool IRQManager::addADCScanEndB(ADC_Container *adc, Irq_f fnc /*= nullptr*/) { /* set the displacement to the "programmable" part of the table */ irq_ptr += FIXED_IRQ_NUM; bool rv = true; - - if (adc->cfg.scan_end_b_irq == FSP_INVALID_VECTOR) { + if (last_interrupt_index >= PROG_IRQ_NUM){ + rv = false; + } + else if (adc->cfg.scan_end_b_irq == FSP_INVALID_VECTOR) { if(set_adc_end_b_link_event(last_interrupt_index, adc->cfg.unit)) { adc->cfg.scan_end_b_ipl = TIMER_PRIORITY; adc->cfg.scan_end_b_irq = (IRQn_Type)last_interrupt_index; @@ -103,8 +130,10 @@ bool IRQManager::addADCWinCmpA(ADC_Container *adc, Irq_f fnc /*= nullptr*/) { /* set the displacement to the "programmable" part of the table */ irq_ptr += FIXED_IRQ_NUM; bool rv = true; - - if( ((adc_extended_cfg_t *)(adc->cfg.p_extend))->window_a_irq == FSP_INVALID_VECTOR) { + if (last_interrupt_index >= PROG_IRQ_NUM){ + rv = false; + } + else if( ((adc_extended_cfg_t *)(adc->cfg.p_extend))->window_a_irq == FSP_INVALID_VECTOR) { if(set_adc_win_a_link_event(last_interrupt_index, adc->cfg.unit)) { ((adc_extended_cfg_t *)(adc->cfg.p_extend))->window_a_ipl = TIMER_PRIORITY; ((adc_extended_cfg_t *)(adc->cfg.p_extend))->window_a_irq = (IRQn_Type)last_interrupt_index; @@ -128,8 +157,10 @@ bool IRQManager::addADCWinCmpB(ADC_Container *adc, Irq_f fnc /*= nullptr*/) { /* set the displacement to the "programmable" part of the table */ irq_ptr += FIXED_IRQ_NUM; bool rv = true; - - if (((adc_extended_cfg_t *)(adc->cfg.p_extend))->window_b_irq == FSP_INVALID_VECTOR) { + if (last_interrupt_index >= PROG_IRQ_NUM){ + rv = false; + } + else if (((adc_extended_cfg_t *)(adc->cfg.p_extend))->window_b_irq == FSP_INVALID_VECTOR) { if(set_adc_win_b_link_event(last_interrupt_index, adc->cfg.unit)) { ((adc_extended_cfg_t *)(adc->cfg.p_extend))->window_b_ipl = TIMER_PRIORITY; ((adc_extended_cfg_t *)(adc->cfg.p_extend))->window_b_irq = (IRQn_Type)last_interrupt_index; @@ -155,8 +186,10 @@ bool IRQManager::addTimerOverflow(TimerIrqCfg_t &cfg, Irq_f fnc /* = nullptr */) /* set the displacement to the "programmable" part of the table */ irq_ptr += FIXED_IRQ_NUM; bool rv = true; - - if (cfg.base_cfg->cycle_end_irq == FSP_INVALID_VECTOR) { + if (last_interrupt_index >= PROG_IRQ_NUM){ + rv = false; + } + else if (cfg.base_cfg->cycle_end_irq == FSP_INVALID_VECTOR) { if(cfg.gpt_ext_cfg != nullptr) { if(set_gpt_over_link_event(last_interrupt_index, cfg.base_cfg->channel)) { cfg.base_cfg->cycle_end_ipl = TIMER_PRIORITY; @@ -202,7 +235,7 @@ bool IRQManager::addTimerUnderflow(TimerIrqCfg_t &cfg, Irq_f fnc /*= nullptr*/) irq_ptr += FIXED_IRQ_NUM; bool rv = true; - if(cfg.agt_ext_cfg != nullptr) { + if((cfg.agt_ext_cfg != nullptr) || (last_interrupt_index >= PROG_IRQ_NUM)) { /* not supported for AGT */ rv = false; } @@ -236,7 +269,7 @@ bool IRQManager::addTimerCompareCaptureA(TimerIrqCfg_t &cfg, Irq_f fnc /*= nullp irq_ptr += FIXED_IRQ_NUM; bool rv = true; - if(cfg.agt_ext_cfg != nullptr) { + if((cfg.agt_ext_cfg != nullptr) || (last_interrupt_index >= PROG_IRQ_NUM)) { /* not supported for AGT */ rv = false; } @@ -270,7 +303,7 @@ bool IRQManager::addTimerCompareCaptureB(TimerIrqCfg_t &cfg, Irq_f fnc /*= nullp irq_ptr += FIXED_IRQ_NUM; bool rv = true; - if(cfg.agt_ext_cfg != nullptr) { + if((cfg.agt_ext_cfg != nullptr) || (last_interrupt_index >= PROG_IRQ_NUM)) { /* not supported for AGT */ rv = false; } @@ -304,8 +337,10 @@ bool IRQManager::addDMA(dmac_extended_cfg_t &cfg, Irq_f fnc /* = nullptr */) { /* set the displacement to the "programmable" part of the table */ irq_ptr += FIXED_IRQ_NUM; bool rv = true; - - if (cfg.irq == FSP_INVALID_VECTOR) { + if (last_interrupt_index >= PROG_IRQ_NUM){ + rv = false; + } + else if (cfg.irq == FSP_INVALID_VECTOR) { /* to check correctness of the channel */ if(set_dma_link_event(last_interrupt_index, cfg.channel)) { cfg.ipl = DMA_PRIORITY; @@ -335,6 +370,11 @@ bool IRQManager::addPeripheral(Peripheral_t p, void *cfg) { irq_ptr += FIXED_IRQ_NUM; bool rv = true; + if(last_interrupt_index >= PROG_IRQ_NUM){ + rv = false; + goto end_config; + } + __disable_irq(); /* ********************************************************************** USB @@ -471,7 +511,12 @@ bool IRQManager::addPeripheral(Peripheral_t p, void *cfg) { ********************************************************************** */ else if(p == IRQ_SCI_UART && cfg != NULL) { uart_cfg_t *p_cfg = (uart_cfg_t *)cfg; + if (p_cfg->txi_irq == FSP_INVALID_VECTOR) { + if (last_interrupt_index + UART_INTERRUPT_COUNT > PROG_IRQ_NUM){ + rv = false; + goto end_config; + } /* TX interrupt */ p_cfg->txi_ipl = UART_SCI_PRIORITY; p_cfg->txi_irq = (IRQn_Type)last_interrupt_index; @@ -557,13 +602,18 @@ bool IRQManager::addPeripheral(Peripheral_t p, void *cfg) { #if WIRE_HOWMANY > 0 /* I2C true NOT SCI */ - else if(p == IRQ_I2C_MASTER && cfg != NULL) { + else if(p == IRQ_I2C_MASTER && cfg != NULL) { + 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) { + if (last_interrupt_index + WIRE_MASTER_INTERRUPT_COUNT > PROG_IRQ_NUM){ + rv = false; + goto end_config; + } /* TX interrupt */ mcfg->txi_irq = (IRQn_Type)last_interrupt_index; scfg->txi_irq = (IRQn_Type)last_interrupt_index; @@ -604,11 +654,15 @@ bool IRQManager::addPeripheral(Peripheral_t p, void *cfg) { R_BSP_IrqEnable (mcfg->eri_irq); } /* I2C SCI MASTER (only) */ - else if(p == IRQ_SCI_I2C_MASTER && cfg != NULL) { + else if(p == IRQ_SCI_I2C_MASTER && cfg != NULL) { 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) { + if (mcfg->txi_irq == FSP_INVALID_VECTOR) { + if (last_interrupt_index + WIRE_SCI_MASTER_INTERRUPT_COUNT > PROG_IRQ_NUM) { + rv = false; + goto end_config; + } /* TX interrupt */ mcfg->txi_irq = (IRQn_Type)last_interrupt_index; *(irq_ptr + last_interrupt_index) = (uint32_t)sci_i2c_txi_isr; @@ -652,8 +706,12 @@ bool IRQManager::addPeripheral(Peripheral_t p, void *cfg) { 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) { + + if (scfg->txi_irq == FSP_INVALID_VECTOR) { + if (last_interrupt_index + WIRE_SLAVE_INTERRUPT_COUNT > PROG_IRQ_NUM) { + rv = false; + goto end_config; + } /* TX interrupt */ mcfg->txi_irq = (IRQn_Type)last_interrupt_index; scfg->txi_irq = (IRQn_Type)last_interrupt_index; @@ -710,12 +768,16 @@ bool IRQManager::addPeripheral(Peripheral_t p, void *cfg) { /* ********************************************************************** SPI MASTER ********************************************************************** */ - else if(p == IRQ_SPI_MASTER && cfg != NULL) { + else if(p == IRQ_SPI_MASTER && cfg != NULL) { spi_instance_ctrl_t * p_ctrl = reinterpret_cast(cfg)->ctrl; spi_cfg_t * p_cfg = reinterpret_cast(cfg)->cfg; uint8_t const hw_channel = reinterpret_cast(cfg)->hw_channel; if (p_cfg->txi_irq == FSP_INVALID_VECTOR) { + if (last_interrupt_index + SPI_INTERRUPT_COUNT > PROG_IRQ_NUM) { + rv = false; + goto end_config; + } /* TX interrupt */ p_cfg->txi_irq = (IRQn_Type)last_interrupt_index; p_cfg->txi_ipl = SPI_MASTER_PRIORITY; @@ -758,12 +820,16 @@ bool IRQManager::addPeripheral(Peripheral_t p, void *cfg) { /* ********************************************************************** SCI SPI MASTER ********************************************************************** */ - else if(p == IRQ_SCI_SPI_MASTER && cfg != NULL) { + else if(p == IRQ_SCI_SPI_MASTER && cfg != NULL) { sci_spi_instance_ctrl_t * p_ctrl = reinterpret_cast(cfg)->ctrl; spi_cfg_t * p_cfg = reinterpret_cast(cfg)->cfg; uint8_t const hw_channel = reinterpret_cast(cfg)->hw_channel; if (p_cfg->txi_irq == FSP_INVALID_VECTOR) { + if (last_interrupt_index + SPI_INTERRUPT_COUNT > PROG_IRQ_NUM) { + rv = false; + goto end_config; + } /* TX interrupt */ p_cfg->txi_irq = (IRQn_Type)last_interrupt_index; p_cfg->txi_ipl = SPI_MASTER_PRIORITY; @@ -807,12 +873,16 @@ bool IRQManager::addPeripheral(Peripheral_t p, void *cfg) { /* ********************************************************************** CAN ********************************************************************** */ - else if(p == IRQ_CAN && cfg != NULL) { + else if(p == IRQ_CAN && cfg != NULL) { can_instance_ctrl_t * p_ctrl = reinterpret_cast(cfg)->ctrl; can_cfg_t * p_cfg = reinterpret_cast(cfg)->cfg; p_cfg->ipl = CAN_PRIORITY; /* All interrupts share the same priority. */ if (p_cfg->error_irq == FSP_INVALID_VECTOR) { + if (last_interrupt_index + CAN_INTERRUPT_COUNT > PROG_IRQ_NUM) { + rv = false; + goto end_config; + } /* Error interrupt */ p_cfg->error_irq = (IRQn_Type)last_interrupt_index; *(irq_ptr + last_interrupt_index) = (uint32_t)can_error_isr; @@ -867,6 +937,10 @@ bool IRQManager::addPeripheral(Peripheral_t p, void *cfg) { p_cfg->ipl = CAN_PRIORITY; /* All interrupts share the same priority. */ if (p_cfg->error_irq == FSP_INVALID_VECTOR) { + if (last_interrupt_index + CANFD_INTERRUPT_COUNT > PROG_IRQ_NUM) { + rv = false; + goto end_config; + } /* Error interrupt */ p_cfg->error_irq = (IRQn_Type)last_interrupt_index; *(irq_ptr + last_interrupt_index) = (uint32_t)canfd_error_isr; @@ -902,7 +976,10 @@ bool IRQManager::addPeripheral(Peripheral_t p, void *cfg) { sdmmc_cfg_t *sd_cfg = (sdmmc_cfg_t *)cfg; /* SDCARD_ACCESS */ if(sd_cfg->access_irq == FSP_INVALID_VECTOR) { - + if (last_interrupt_index + SD_INTERRUPT_COUNT > PROG_IRQ_NUM){ + rv = false; + goto end_config; + } sd_cfg->access_irq = (IRQn_Type)last_interrupt_index; sd_cfg->access_ipl = SDCARD_ACCESS_PRIORITY; *(irq_ptr + last_interrupt_index) = (uint32_t)sdhimmc_accs_isr; @@ -930,6 +1007,41 @@ bool IRQManager::addPeripheral(Peripheral_t p, void *cfg) { } } #endif + +#if I2S_HOWMANY > 0 + /* ********************************************************************** + I2S + ********************************************************************** */ + else if(p == IRQ_I2S && cfg != NULL) { + i2s_cfg_t *i2s_cfg = (i2s_cfg_t *)cfg; + + if(i2s_cfg->txi_irq == FSP_INVALID_VECTOR) { + i2s_cfg->txi_irq = (IRQn_Type)last_interrupt_index; + i2s_cfg->txi_ipl = I2S_PRIORITY; + *(irq_ptr + last_interrupt_index) = (uint32_t)ssi_txi_isr; + R_ICU->IELSR[last_interrupt_index] = BSP_PRV_IELS_ENUM(EVENT_SSI0_TXI); + R_FSP_IsrContextSet(i2s_cfg->txi_irq, (void*)i2s_cfg->p_context); + last_interrupt_index++; + } + if(i2s_cfg->rxi_irq == FSP_INVALID_VECTOR) { + i2s_cfg->rxi_irq = (IRQn_Type)last_interrupt_index; + i2s_cfg->rxi_ipl = I2S_PRIORITY; + *(irq_ptr + last_interrupt_index) = (uint32_t)ssi_rxi_isr; + R_ICU->IELSR[last_interrupt_index] = BSP_PRV_IELS_ENUM(EVENT_SSI0_RXI); + R_FSP_IsrContextSet(i2s_cfg->rxi_irq, (void*)i2s_cfg->p_context); + last_interrupt_index++; + } + if(i2s_cfg->int_irq == FSP_INVALID_VECTOR) { + i2s_cfg->int_irq = (IRQn_Type)last_interrupt_index; + i2s_cfg->idle_err_ipl = I2S_PRIORITY; + *(irq_ptr + last_interrupt_index) = (uint32_t)ssi_int_isr; + R_ICU->IELSR[last_interrupt_index] = BSP_PRV_IELS_ENUM(EVENT_SSI0_INT); + R_FSP_IsrContextSet(i2s_cfg->int_irq, (void*)i2s_cfg->p_context); + last_interrupt_index++; + } + } +#endif + else { rv = false; } diff --git a/cores/arduino/IRQManager.h b/cores/arduino/IRQManager.h index 2f9e093cc..24cbf54ff 100644 --- a/cores/arduino/IRQManager.h +++ b/cores/arduino/IRQManager.h @@ -12,12 +12,22 @@ #if SERIAL_HOWMANY > 0 #include "r_uart_api.h" +#define UART_INTERRUPT_COUNT 4 #endif #if EXT_INTERRUPTS_HOWMANY > 0 #include "r_external_irq_api.h" #endif +#if I2S_HOWMANY > 0 +#include "r_ssi.h" +extern "C" { +void ssi_txi_isr(void); +void ssi_rxi_isr(void); +void ssi_int_isr(void); +} +#endif + #include "r_timer_api.h" #ifdef ELC_EVENT_DMAC0_INT @@ -43,7 +53,8 @@ typedef enum { IRQ_CAN, IRQ_ETHERNET, IRQ_CANFD, - IRQ_SDCARD + IRQ_SDCARD, + IRQ_I2S } Peripheral_t; #if SDCARD_HOWMANY > 0 @@ -78,6 +89,9 @@ typedef struct i2c_irq_req { i2c_master_cfg_t *mcfg; i2c_slave_cfg_t *scfg; } I2CIrqReq_t; +#define WIRE_MASTER_INTERRUPT_COUNT 4 +#define WIRE_SLAVE_INTERRUPT_COUNT 4 +#define WIRE_SCI_MASTER_INTERRUPT_COUNT 3 #endif #if SPI_HOWMANY > 0 @@ -95,6 +109,7 @@ typedef struct sci_spi_master_irq { spi_cfg_t * cfg; uint8_t hw_channel; } SciSpiMasterIrqReq_t; +#define SPI_INTERRUPT_COUNT 4 #endif #if CAN_HOWMANY > 0 @@ -103,6 +118,7 @@ typedef struct can_irq { can_instance_ctrl_t * ctrl; can_cfg_t * cfg; } CanIrqReq_t; +#define CAN_INTERRUPT_COUNT 3 #endif /* CAN_HOWMANY > 0 */ #if CANFD_HOWMANY > 0 @@ -111,8 +127,11 @@ typedef struct canfd_irq { canfd_instance_ctrl_t * ctrl; can_cfg_t * cfg; } CanFdIrqReq_t; +#define CANFD_INTERRUPT_COUNT 3 #endif /* CANFD_HOWMANY > 0 */ +#define SD_INTERRUPT_COUNT 2 + typedef struct usb { uint32_t num_of_irqs_required; uint32_t address_of_handler; @@ -125,6 +144,11 @@ typedef struct timer { agt_extended_cfg_t *agt_ext_cfg; } TimerIrqCfg_t; +typedef struct genericIrq { + IRQn_Type irq; + uint8_t ipl; + elc_event_t event; +} GenericIrqCfg_t; #ifdef __cplusplus @@ -199,7 +223,8 @@ class IRQManager { it returns true if the interrupt is correctly added */ bool addDMA(dmac_extended_cfg_t &cfg, Irq_f fnc = nullptr); #endif - + + bool addGenericInterrupt(GenericIrqCfg_t &cfg, Irq_f fnc = nullptr); bool addTimerOverflow(TimerIrqCfg_t &cfg, Irq_f fnc = nullptr); bool addTimerUnderflow(TimerIrqCfg_t &cfg, Irq_f fnc = nullptr); bool addTimerCompareCaptureA(TimerIrqCfg_t &cfg, Irq_f fnc = nullptr); diff --git a/cores/arduino/cm_backtrace/fault_handler/gcc/cmb_fault.S b/cores/arduino/cm_backtrace/fault_handler/gcc/cmb_fault.S index 9491663f2..ca305c6d3 100644 --- a/cores/arduino/cm_backtrace/fault_handler/gcc/cmb_fault.S +++ b/cores/arduino/cm_backtrace/fault_handler/gcc/cmb_fault.S @@ -26,6 +26,8 @@ * Created on: 2016-12-16 */ +#ifdef BACKTRACE_SUPPORT + .syntax unified .thumb .text @@ -41,3 +43,5 @@ HardFault_Handler: Fault_Loop: BL Fault_Loop /* while(1) */ + +#endif \ No newline at end of file diff --git a/extras/fsp b/extras/fsp index 8ec537bc8..5d13f916c 160000 --- a/extras/fsp +++ b/extras/fsp @@ -1 +1 @@ -Subproject commit 8ec537bc86b1b71203d72d0cbb28e6e75b353ebd +Subproject commit 5d13f916c72f9d1471864361dfaf8f492cab5979 diff --git a/libraries/Arduino_CAN/src/CanUtil.cpp b/libraries/Arduino_CAN/src/CanUtil.cpp index d3250ae48..9861e15e8 100644 --- a/libraries/Arduino_CAN/src/CanUtil.cpp +++ b/libraries/Arduino_CAN/src/CanUtil.cpp @@ -28,7 +28,7 @@ namespace util **************************************************************************************/ std::tuple - calc_can_bit_timing(CanBitRate const can_bitrate, + calc_can_bit_timing(uint32_t const can_bitrate, uint32_t const can_clock_Hz, uint32_t const tq_min, uint32_t const tq_max, diff --git a/libraries/Arduino_CAN/src/CanUtil.h b/libraries/Arduino_CAN/src/CanUtil.h index ec5a89ae5..ae1a488a1 100644 --- a/libraries/Arduino_CAN/src/CanUtil.h +++ b/libraries/Arduino_CAN/src/CanUtil.h @@ -36,7 +36,7 @@ std::tuple /* time_segment_2 */ -calc_can_bit_timing(CanBitRate const can_bitrate, uint32_t const can_clock_Hz, uint32_t const tq_min, uint32_t const tq_max, +calc_can_bit_timing(uint32_t const can_bitrate, uint32_t const can_clock_Hz, uint32_t const tq_min, uint32_t const tq_max, uint32_t const tseg1_min, uint32_t const tseg1_max, uint32_t const tseg2_min, uint32_t const tseg2_max); /************************************************************************************** diff --git a/libraries/Arduino_CAN/src/R7FA4M1_CAN.cpp b/libraries/Arduino_CAN/src/R7FA4M1_CAN.cpp index 95938e80e..c53f44942 100644 --- a/libraries/Arduino_CAN/src/R7FA4M1_CAN.cpp +++ b/libraries/Arduino_CAN/src/R7FA4M1_CAN.cpp @@ -137,6 +137,11 @@ R7FA4M1_CAN::R7FA4M1_CAN(int const can_tx_pin, int const can_rx_pin) **************************************************************************************/ bool R7FA4M1_CAN::begin(CanBitRate const can_bitrate) +{ + return begin(static_cast(can_bitrate)); +} + +bool R7FA4M1_CAN::begin(uint32_t const can_bitrate) { bool init_ok = true; diff --git a/libraries/Arduino_CAN/src/R7FA4M1_CAN.h b/libraries/Arduino_CAN/src/R7FA4M1_CAN.h index f60252f61..235df871f 100644 --- a/libraries/Arduino_CAN/src/R7FA4M1_CAN.h +++ b/libraries/Arduino_CAN/src/R7FA4M1_CAN.h @@ -52,6 +52,7 @@ class R7FA4M1_CAN final : public HardwareCAN bool begin(CanBitRate const can_bitrate) override; + bool begin(uint32_t const can_bitrate); void end() override; void setFilterMask_Standard(uint32_t const mask); diff --git a/libraries/Arduino_CAN/src/R7FA6M5_CAN.cpp b/libraries/Arduino_CAN/src/R7FA6M5_CAN.cpp index 9995a4072..ae2bb8ccf 100644 --- a/libraries/Arduino_CAN/src/R7FA6M5_CAN.cpp +++ b/libraries/Arduino_CAN/src/R7FA6M5_CAN.cpp @@ -100,6 +100,11 @@ R7FA6M5_CAN::R7FA6M5_CAN(int const can_tx_pin, int const can_rx_pin) **************************************************************************************/ bool R7FA6M5_CAN::begin(CanBitRate const can_bitrate) +{ + return begin(static_cast(can_bitrate)); +} + +bool R7FA6M5_CAN::begin(uint32_t const can_bitrate) { bool init_ok = true; diff --git a/libraries/Arduino_CAN/src/R7FA6M5_CAN.h b/libraries/Arduino_CAN/src/R7FA6M5_CAN.h index 79a5d4c4a..12d81d143 100644 --- a/libraries/Arduino_CAN/src/R7FA6M5_CAN.h +++ b/libraries/Arduino_CAN/src/R7FA6M5_CAN.h @@ -54,6 +54,7 @@ class R7FA6M5_CAN final : public HardwareCAN bool begin(CanBitRate const can_bitrate) override; + bool begin(uint32_t const can_bitrate); void end() override; diff --git a/libraries/Arduino_FreeRTOS/src/Arduino_FreeRTOS.h b/libraries/Arduino_FreeRTOS/src/Arduino_FreeRTOS.h index 6ffd5b098..8e58deddd 100644 --- a/libraries/Arduino_FreeRTOS/src/Arduino_FreeRTOS.h +++ b/libraries/Arduino_FreeRTOS/src/Arduino_FreeRTOS.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2022 by Alexander Entinger - * CAN library for Arduino. + * FreeRTOS library for Arduino. * * This file is free software; you can redistribute it and/or modify * it under the terms of either the GNU General Public License version 2 diff --git a/libraries/Arduino_LED_Matrix/examples/DisplaySingleFrame/DisplaySingleFrame.ino b/libraries/Arduino_LED_Matrix/examples/DisplaySingleFrame/DisplaySingleFrame.ino index a6ba766ae..49b3f0294 100644 --- a/libraries/Arduino_LED_Matrix/examples/DisplaySingleFrame/DisplaySingleFrame.ino +++ b/libraries/Arduino_LED_Matrix/examples/DisplaySingleFrame/DisplaySingleFrame.ino @@ -34,6 +34,10 @@ void loop() { matrix.loadFrame(LEDMATRIX_HEART_BIG); delay(500); + // Turn off the display + matrix.clear(); + delay(1000); + // Print the current value of millis() to the serial monitor Serial.println(millis()); } diff --git a/libraries/Arduino_LED_Matrix/src/Arduino_LED_Matrix.h b/libraries/Arduino_LED_Matrix/src/Arduino_LED_Matrix.h index 6cd4a26c9..1dacbdd92 100644 --- a/libraries/Arduino_LED_Matrix/src/Arduino_LED_Matrix.h +++ b/libraries/Arduino_LED_Matrix/src/Arduino_LED_Matrix.h @@ -170,13 +170,18 @@ class ArduinoLEDMatrix turnLed(pin, false); } int begin() { + bool rv = true; uint8_t type; - uint8_t ch = FspTimer::get_available_timer(type); + int8_t ch = FspTimer::get_available_timer(type); + if(ch == -1) { + return false; + } // TODO: avoid passing "this" argument to remove autoscroll - _ledTimer.begin(TIMER_MODE_PERIODIC, type, ch, 10000.0, 50.0, turnOnLedISR, this); - _ledTimer.setup_overflow_irq(); - _ledTimer.open(); - _ledTimer.start(); + rv &= _ledTimer.begin(TIMER_MODE_PERIODIC, type, ch, 10000.0, 50.0, turnOnLedISR, this); + rv &= _ledTimer.setup_overflow_irq(); + rv &= _ledTimer.open(); + rv &= _ledTimer.start(); + return rv; } void next() { uint32_t frame[3]; @@ -248,6 +253,16 @@ class ArduinoLEDMatrix _callBack = callBack; } + void clear() { + const uint32_t fullOff[] = { + 0x00000000, + 0x00000000, + 0x00000000 + }; + loadFrame(fullOff); + } + + #ifdef MATRIX_WITH_ARDUINOGRAPHICS virtual void set(int x, int y, uint8_t r, uint8_t g, uint8_t b) { if (y >= canvasHeight || x >= canvasWidth || y < 0 || x < 0) { diff --git a/libraries/Arduino_LED_Matrix/src/gallery.h b/libraries/Arduino_LED_Matrix/src/gallery.h index 81a9a3e9d..628b640fa 100644 --- a/libraries/Arduino_LED_Matrix/src/gallery.h +++ b/libraries/Arduino_LED_Matrix/src/gallery.h @@ -572,3 +572,26 @@ constexpr uint32_t LEDMATRIX_ANIMATION_WIFI_SEARCH[][4] = { { 0x0, 0x1f02084, 0xe4110040, 500 }, { 0x3f840, 0x49f22084, 0xe4110040, 500 } }; +constexpr uint32_t LEDMATRIX_ANIMATION_HOURGLASS[][4] = { + { 0xe07f99fe, 0x1fc1fc1f, 0xe1f99e07, 50 }, + { 0xe07f99fe, 0x1ff1fc1f, 0xe1f99e07, 50 }, + { 0xe07f99fe, 0x1ffdfc1f, 0xe1f99e07, 50 }, + { 0xe07f99fe, 0x1ffffc1f, 0xe1f99e07, 50 }, + { 0xe07f99fe, 0x1ffffc3f, 0xe1f99e07, 50 }, + { 0xe07f99fe, 0x1bfffc3f, 0xe1f99e07, 50 }, + { 0xe07f99fe, 0x3bffbc3f, 0xe1f99e07, 50 }, + { 0xe07f9bfe, 0x3bffbc3b, 0xe1f99e07, 50 }, + { 0xe07f9bfe, 0x3bffbc3b, 0xe3f99e07, 50 }, + { 0xe07f9bbe, 0x3bffbc3b, 0xe3f9be07, 50 }, + { 0xe07b9bbe, 0x3bffbc7b, 0xe3f9be07, 50 }, + { 0xe07b9bbe, 0x3bffbc7b, 0xe7b9be07, 50 }, + { 0xe07b9bbe, 0x39ffbc7b, 0xe7b9be07, 50 }, + { 0xe07b9bbe, 0x79ff9c7b, 0xe7b9be07, 50 }, + { 0xe07b9bbe, 0x79ff9c79, 0xe7b9fe07, 50 }, + { 0xe07b9f9e, 0x79ff9c79, 0xe7b9fe07, 50 }, + { 0xe07b9f9e, 0x78ff9cf9, 0xe7b9fe07, 50 }, + { 0xe0799f9e, 0xf8ff8cf9, 0xe799fe07, 50 }, + { 0xe0799f8e, 0xf8ff8cf8, 0xef99fe07, 50 }, + { 0xe0799f87, 0xf87f87f8, 0x7f99fe07, 50 }, + { 0xe0799f87, 0xf83f83f8, 0x7f99fe07, 300 } +}; diff --git a/libraries/BlockDevices/HeapBlockDevice.cpp b/libraries/BlockDevices/HeapBlockDevice.cpp index a3306d151..12b2363f9 100644 --- a/libraries/BlockDevices/HeapBlockDevice.cpp +++ b/libraries/BlockDevices/HeapBlockDevice.cpp @@ -105,7 +105,7 @@ bd_size_t HeapBlockDevice::get_erase_size() const return _erase_size; } -bd_size_t HeapBlockDevice::get_erase_size(bd_addr_t addr) const +bd_size_t HeapBlockDevice::get_erase_size(__attribute__((unused)) bd_addr_t addr) const { return _erase_size; } diff --git a/libraries/BlockDevices/ReadOnlyBlockDevice.cpp b/libraries/BlockDevices/ReadOnlyBlockDevice.cpp index 15b59252c..86c256eb0 100644 --- a/libraries/BlockDevices/ReadOnlyBlockDevice.cpp +++ b/libraries/BlockDevices/ReadOnlyBlockDevice.cpp @@ -24,7 +24,10 @@ int ReadOnlyBlockDevice::open() { return BLOCK_DEVICE_OK; } int ReadOnlyBlockDevice::close() { return BLOCK_DEVICE_OK; } -int ReadOnlyBlockDevice::write(const void *buffer, bd_addr_t addr, bd_size_t size) {return BLOCK_DEVICE_OK;} +int ReadOnlyBlockDevice::write(__attribute__((unused)) const void *buffer, __attribute__((unused)) bd_addr_t addr, __attribute__((unused)) bd_size_t size) +{ + return BLOCK_DEVICE_OK; +} ReadOnlyBlockDevice::ReadOnlyBlockDevice(BlockDevice *bd) : _bd(bd) @@ -57,12 +60,12 @@ int ReadOnlyBlockDevice::read(void *buffer, bd_addr_t addr, bd_size_t size) return _bd->read(buffer, addr, size); } -int ReadOnlyBlockDevice::program(const void *buffer, bd_addr_t addr, bd_size_t size) +int ReadOnlyBlockDevice::program(__attribute__((unused)) const void *buffer, __attribute__((unused)) bd_addr_t addr, __attribute__((unused)) bd_size_t size) { return BD_ERROR_WRITE_PROTECTED; } -int ReadOnlyBlockDevice::erase(bd_addr_t addr, bd_size_t size) +int ReadOnlyBlockDevice::erase(__attribute__((unused)) bd_addr_t addr, __attribute__((unused)) bd_size_t size) { return BD_ERROR_WRITE_PROTECTED; } diff --git a/libraries/Ethernet/src/Ethernet.cpp b/libraries/Ethernet/src/Ethernet.cpp index 22c90ff62..c63635096 100644 --- a/libraries/Ethernet/src/Ethernet.cpp +++ b/libraries/Ethernet/src/Ethernet.cpp @@ -1,5 +1,5 @@ #include - +#include /* * The old implementation of the begin set a default mac address: * this does not make any sense. @@ -12,10 +12,15 @@ /* -------------------------------------------------------------------------- */ int CEthernet::begin(unsigned long timeout, unsigned long responseTimeout) { /* -------------------------------------------------------------------------- */ + + ethernetTimer = new EthernetClock(); + ethernetTimer->start(); + delay(2); (void)responseTimeout; int rv = 0; + ni = CLwipIf::getInstance().get(NI_ETHERNET); if(ni != nullptr) { ni->DhcpSetTimeout(timeout); @@ -56,9 +61,17 @@ int CEthernet::begin(IPAddress local_ip, IPAddress dns_server, IPAddress gateway int CEthernet::begin(IPAddress local_ip, IPAddress dns_server, IPAddress gateway, IPAddress subnet) { /* -------------------------------------------------------------------------- */ - ni = CLwipIf::getInstance().get(NI_ETHERNET, local_ip, gateway, subnet); - if(ni == nullptr) { - return 0; + ethernetTimer = new EthernetClock(); + ethernetTimer->start(); + delay(2); + + if (ni != nullptr) { + ni->config(local_ip, gateway, subnet); + } else { + ni = CLwipIf::getInstance().get(NI_ETHERNET, local_ip, gateway, subnet); + if (ni == nullptr) { + return 0; + } } /* If there is a local DHCP informs it of our manual IP configuration to prevent IP conflict */ @@ -132,6 +145,9 @@ EthernetHardwareStatus CEthernet::hardwareStatus() { /* -------------------------------------------------------------------------- */ int CEthernet::disconnect() { /* -------------------------------------------------------------------------- */ + ethernetTimer->stop(); + delete(ethernetTimer); + ethernetTimer = NULL; return 1; } diff --git a/libraries/Ethernet/src/EthernetC33.h b/libraries/Ethernet/src/EthernetC33.h index 97fa54511..5c684fe63 100644 --- a/libraries/Ethernet/src/EthernetC33.h +++ b/libraries/Ethernet/src/EthernetC33.h @@ -13,6 +13,7 @@ #include "EthernetClient.h" #include "EthernetServer.h" +#include "EthernetClock.h" #include "CNetIf.h" #include "lwipMem.h" @@ -68,8 +69,11 @@ class CEthernet { IPAddress gatewayIP(); IPAddress dnsServerIP(); + friend class EthernetClient; friend class EthernetServer; + private: + EthernetClock * ethernetTimer; }; extern CEthernet Ethernet; diff --git a/libraries/Ethernet/src/EthernetClock.cpp b/libraries/Ethernet/src/EthernetClock.cpp new file mode 100644 index 000000000..a38fbe5ea --- /dev/null +++ b/libraries/Ethernet/src/EthernetClock.cpp @@ -0,0 +1,78 @@ +#include "EthernetClock.h" +#include "pins_arduino.h" + +#if defined(ETHERNET_CLK_PIN) + +EthernetClock::EthernetClock() { + pinPeripheral(ETHERNET_CLK_PIN, (uint32_t) (IOPORT_CFG_PERIPHERAL_PIN | IOPORT_PERIPHERAL_AGT)); + + this->TIMER_ETHERNET_extend.count_source = AGT_CLOCK_PCLKB; + this->TIMER_ETHERNET_extend.agto = AGT_PIN_CFG_START_LEVEL_LOW; + this->TIMER_ETHERNET_extend.agtoab_settings_b.agtoa = AGT_PIN_CFG_DISABLED; + this->TIMER_ETHERNET_extend.agtoab_settings_b.agtob = AGT_PIN_CFG_DISABLED; + this->TIMER_ETHERNET_extend.measurement_mode = AGT_MEASURE_DISABLED; + this->TIMER_ETHERNET_extend.agtio_filter = AGT_AGTIO_FILTER_NONE; + this->TIMER_ETHERNET_extend.enable_pin = AGT_ENABLE_PIN_NOT_USED; + this->TIMER_ETHERNET_extend.trigger_edge = AGT_TRIGGER_EDGE_RISING; + + this->TIMER_ETHERNET_cfg.mode = TIMER_MODE_PERIODIC; + this->TIMER_ETHERNET_cfg.period_counts = (uint32_t) 0x1; + this->TIMER_ETHERNET_cfg.duty_cycle_counts = 0x00; + this->TIMER_ETHERNET_cfg.source_div = (timer_source_div_t) 0; + this->TIMER_ETHERNET_cfg.channel = ETHERNET_AGT_TIMER_CHANNEL; + this->TIMER_ETHERNET_cfg.p_callback = NULL; + this->TIMER_ETHERNET_cfg.p_context = NULL; + this->TIMER_ETHERNET_cfg.p_extend = &TIMER_ETHERNET_extend; + this->TIMER_ETHERNET_cfg.cycle_end_ipl = (BSP_IRQ_DISABLED); + this->TIMER_ETHERNET_cfg.cycle_end_irq = FSP_INVALID_VECTOR; +} + +fsp_err_t EthernetClock::start() { + fsp_err_t err = R_AGT_Open(&this->TIMER_ETHERNET_ctrl,&this->TIMER_ETHERNET_cfg); + if (err != FSP_SUCCESS) { + return err; + } + err = R_AGT_Enable(&this->TIMER_ETHERNET_ctrl); + if (err != FSP_SUCCESS) { + return err; + } + err = R_AGT_Start(&this->TIMER_ETHERNET_ctrl); + if (err != FSP_SUCCESS) { + return err; + } + + FspTimer::set_timer_is_used(AGT_TIMER, ETHERNET_AGT_TIMER_CHANNEL); + return err; +} + +fsp_err_t EthernetClock::stop() { + fsp_err_t err = R_AGT_Stop(&this->TIMER_ETHERNET_ctrl); + if (err != FSP_SUCCESS) { + return err; + } else { + err = R_AGT_Close(&this->TIMER_ETHERNET_ctrl); + if (err != FSP_SUCCESS) { + return err; + } else { + err = R_AGT_Disable(&this->TIMER_ETHERNET_ctrl); + if (err != FSP_SUCCESS) { + return err; + } + } + } +} + +#else + +EthernetClock::EthernetClock() { +} + +fsp_err_t EthernetClock::start() { + return FSP_SUCCESS; +} + +fsp_err_t EthernetClock::stop() { + return FSP_SUCCESS; +} + +#endif \ No newline at end of file diff --git a/libraries/Ethernet/src/EthernetClock.h b/libraries/Ethernet/src/EthernetClock.h new file mode 100644 index 000000000..0e3940f91 --- /dev/null +++ b/libraries/Ethernet/src/EthernetClock.h @@ -0,0 +1,19 @@ + +#ifndef ETHERNET_CLOCK_H +#define ETHERNET_CLOCK_H + +#include "FspTimer.h" + +class EthernetClock { + public: + EthernetClock(); + fsp_err_t start(); + fsp_err_t stop(); + + private: + agt_instance_ctrl_t TIMER_ETHERNET_ctrl; + agt_extended_cfg_t TIMER_ETHERNET_extend; + timer_cfg_t TIMER_ETHERNET_cfg; +}; + +#endif diff --git a/libraries/I2S/I2S.cpp b/libraries/I2S/I2S.cpp new file mode 100644 index 000000000..b17232a28 --- /dev/null +++ b/libraries/I2S/I2S.cpp @@ -0,0 +1,184 @@ +/* + This file is part of the Arduino_AdvancedAnalog library. + Copyright (c) 2024 Arduino SA. All rights reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "I2S.h" + +I2SClass I2S; + +extern "C" i2s_cfg_t g_i2s0_cfg; +extern "C" ssi_instance_ctrl_t g_i2s0_ctrl; +extern "C" void i2s_callback(i2s_callback_args_t *p_args); + +int I2SClass::start_transfer() { + if (!rx_buf && (i2s_mode & I2S_MODE_IN)) { + rx_buf = rx_pool->alloc(DMA_BUFFER_WRITE); + } + + if (!tx_buf && (i2s_mode & I2S_MODE_OUT)) { + tx_buf = tx_pool->alloc(DMA_BUFFER_READ); + } + + // Start I2S DMA. + if (i2s_mode == I2S_MODE_IN) { + if (R_SSI_Read(&g_i2s0_ctrl, (void*) rx_buf->data(), rx_buf->bytes()) != FSP_SUCCESS) { + return 0; + } + } else if (i2s_mode == I2S_MODE_OUT) { + if (R_SSI_Write(&g_i2s0_ctrl, (void*) tx_buf->data(), tx_buf->bytes()) != FSP_SUCCESS) { + return 0; + } + } else { + if (R_SSI_WriteRead(&g_i2s0_ctrl, (void*) tx_buf->data(), + (void*) rx_buf->data(), tx_buf->bytes()) != FSP_SUCCESS) { + return 0; + } + } + return 1; +} + +int I2SClass::begin(uint32_t i2s_mode, uint32_t sample_rate, size_t n_samples, size_t n_buffers) { + this->i2s_mode = i2s_mode; + + IRQManager::getInstance().addPeripheral(IRQ_I2S, &g_i2s0_cfg); + if (R_SSI_Open(&g_i2s0_ctrl, &g_i2s0_cfg) != FSP_SUCCESS) { + return false; + } + + if (R_SSI_CallbackSet(&g_i2s0_ctrl, i2s_callback, this, NULL) != FSP_SUCCESS) { + return false; + } + + // Internal AUDIO_CLK from GPT channel. + // Need to find the timer connected to GPT_TIMER 2A for internal clock + auto pwm = new PwmOut(64); + pwm->begin(50, 25, true); + + // Configure I/Os. + pinPeripheral(BSP_IO_PORT_01_PIN_12, (uint32_t) (IOPORT_CFG_PERIPHERAL_PIN | IOPORT_PERIPHERAL_SSI)); + pinPeripheral(BSP_IO_PORT_01_PIN_13, (uint32_t) (IOPORT_CFG_PERIPHERAL_PIN | IOPORT_PERIPHERAL_SSI)); + pinPeripheral(BSP_IO_PORT_01_PIN_14, (uint32_t) (IOPORT_CFG_PERIPHERAL_PIN | IOPORT_PERIPHERAL_SSI)); + pinPeripheral(BSP_IO_PORT_01_PIN_15, (uint32_t) (IOPORT_CFG_PERIPHERAL_PIN | IOPORT_PERIPHERAL_SSI)); + + if (i2s_mode & I2S_MODE_IN) { + // Allocate RX buffer pool. + if (!(rx_pool = new DMAPool(n_samples, 2, n_buffers))) { + return 0; + } + } + + if (i2s_mode & I2S_MODE_OUT) { + // Allocate TX buffer pool. + if (!(tx_pool = new DMAPool(n_samples, 2, n_buffers))) { + return 0; + } + } + + if (i2s_mode == I2S_MODE_IN) { + return start_transfer(); + } + + if (i2s_mode == I2S_MODE_INOUT) { + // The transmit pool has to be primed with a few buffers first, + // before the transfer can be started in full-duplex mode. + for (int i=0; i<3; i++) { + SampleBuffer outbuf = dequeue(); + memset(outbuf.data(), 0, outbuf.bytes()); + write(outbuf); + } + } + + return 1; +} + +bool I2SClass::available() { + if (rx_pool && i2s_mode == I2S_MODE_IN) { + return rx_pool->readable(); + } else if (tx_pool && i2s_mode == I2S_MODE_OUT) { + return tx_pool->writable(); + } else if (tx_pool && rx_pool) { + return rx_pool->readable() && tx_pool->writable(); + } + return false; +} + +SampleBuffer I2SClass::read() { + while (!rx_pool->readable()) { + __WFI(); + } + return *rx_pool->alloc(DMA_BUFFER_READ); +} + +SampleBuffer I2SClass::dequeue() { + while (!tx_pool->writable()) { + __WFI(); + } + return *tx_pool->alloc(DMA_BUFFER_WRITE); +} + +void I2SClass::write(SampleBuffer buf) { + static uint32_t buf_count = 0; + if (tx_pool == nullptr) { + return; + } + + buf.flush(); + buf.release(); + + if (tx_buf == nullptr && (++buf_count % 3) == 0) { + start_transfer(); + } +} + +extern "C" void i2s_callback(i2s_callback_args_t *p_args) { + if (p_args == NULL) { + return; + } + + i2s_event_t i2s_event = p_args->event; + I2SClass *i2s = (I2SClass *) p_args->p_context; + + if (i2s_event == I2S_EVENT_TX_EMPTY) { + // Release the current buffer and get the next one. + if (i2s->tx_pool->readable()) { + i2s->tx_buf->release(); + i2s->tx_buf = i2s->tx_pool->alloc(DMA_BUFFER_READ); + } else { + // TODO stop/restart + } + R_SSI_Write(&g_i2s0_ctrl, (void*) i2s->tx_buf->data(), i2s->tx_buf->bytes()); + } + + if (i2s_event == I2S_EVENT_RX_FULL) { + // Update the buffer's timestamp. + //i2s->rx_buf->timestamp(us_ticker_read()); + if (i2s->rx_pool->writable()) { + // Move current DMA buffer to ready queue. + i2s->rx_buf->release(); + // Allocate a new free buffer. + i2s->rx_buf = i2s->rx_pool->alloc(DMA_BUFFER_WRITE); + // Currently, all multi-channel buffers are interleaved. + if (i2s->rx_buf->channels() > 1) { + i2s->rx_buf->set_flags(DMA_BUFFER_INTRLVD); + } + } else { + i2s->rx_buf->set_flags(DMA_BUFFER_DISCONT); + } + R_SSI_Read(&g_i2s0_ctrl, (void*) i2s->rx_buf->data(), i2s->rx_buf->bytes()); + } +} diff --git a/libraries/I2S/I2S.h b/libraries/I2S/I2S.h new file mode 100644 index 000000000..b30293566 --- /dev/null +++ b/libraries/I2S/I2S.h @@ -0,0 +1,58 @@ +/* + This file is part of the Arduino_AdvancedAnalog library. + Copyright (c) 2024 Arduino SA. All rights reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ +#ifndef __I2S_H__ +#define __I2S_H__ + +#include "r_i2s_api.h" +#include "r_ssi.h" +#include "pwm.h" +#include "api/DMAPool.h" + +typedef uint16_t Sample; +typedef DMABuffer &SampleBuffer; + +enum { + I2S_MODE_IN = (1U << 0U), + I2S_MODE_OUT = (1U << 1U), + I2S_MODE_INOUT = (I2S_MODE_IN | I2S_MODE_OUT), +}; + +class I2SClass { + private: + uint32_t i2s_mode; + int start_transfer(); + + public: + DMABuffer *tx_buf; + DMABuffer *rx_buf; + DMAPool *tx_pool; + DMAPool *rx_pool; + + I2SClass(): tx_buf(nullptr), rx_buf(nullptr), tx_pool(nullptr), rx_pool(nullptr) { + } + bool available(); + SampleBuffer read(); + SampleBuffer dequeue(); + void write(SampleBuffer buf); + int begin(uint32_t i2s_mode, uint32_t sample_rate, size_t n_samples, size_t n_buffers); + int stop(); +}; + +extern I2SClass I2S; +#endif // __I2S_H__ diff --git a/libraries/I2S/config.c b/libraries/I2S/config.c new file mode 100644 index 000000000..4d7a6b31f --- /dev/null +++ b/libraries/I2S/config.c @@ -0,0 +1,69 @@ +#include "r_i2s_api.h" +#include "r_ssi.h" +#include "r_dtc.h" +dtc_instance_ctrl_t g_transfer0_ctrl; + +transfer_info_t g_transfer0_info = { + .transfer_settings_word_b.dest_addr_mode = TRANSFER_ADDR_MODE_FIXED, + .transfer_settings_word_b.repeat_area = TRANSFER_REPEAT_AREA_SOURCE, + .transfer_settings_word_b.irq = TRANSFER_IRQ_END, + .transfer_settings_word_b.chain_mode = TRANSFER_CHAIN_MODE_DISABLED, + .transfer_settings_word_b.src_addr_mode = TRANSFER_ADDR_MODE_INCREMENTED, + .transfer_settings_word_b.size = TRANSFER_SIZE_4_BYTE, + .transfer_settings_word_b.mode = TRANSFER_MODE_BLOCK, + .p_dest = (void*) NULL, + .p_src = (void const*) NULL, + .num_blocks = 0, + .length = 0, +}; + +const dtc_extended_cfg_t g_transfer0_cfg_extend ={ + .activation_source = VECTOR_NUMBER_SSI0_TXI, +}; + +const transfer_cfg_t g_transfer0_cfg = { + .p_info = &g_transfer0_info, + .p_extend = &g_transfer0_cfg_extend +}; + +/* Instance structure to use this module. */ +const transfer_instance_t g_transfer0 = { + .p_ctrl = &g_transfer0_ctrl, + .p_cfg = &g_transfer0_cfg, + .p_api = &g_transfer_on_dtc +}; +ssi_instance_ctrl_t g_i2s0_ctrl; + +/** SSI instance configuration */ +const ssi_extended_cfg_t g_i2s0_cfg_extend = { + .audio_clock = SSI_AUDIO_CLOCK_INTERNAL, + .bit_clock_div = SSI_CLOCK_DIV_1 +}; + +/** I2S interface configuration */ +const i2s_cfg_t g_i2s0_cfg = { + .channel = 0, + .pcm_width = I2S_PCM_WIDTH_16_BITS, + //.pcm_width = I2S_PCM_WIDTH_32_BITS, + .operating_mode = I2S_MODE_MASTER, + .word_length = I2S_WORD_LENGTH_32_BITS, + .ws_continue = I2S_WS_CONTINUE_ON, + .p_callback = NULL, + .p_context = NULL, + .p_extend = &g_i2s0_cfg_extend, + .txi_irq = FSP_INVALID_VECTOR, + .rxi_irq = FSP_INVALID_VECTOR, + .int_irq = FSP_INVALID_VECTOR, + .txi_ipl = (2), + .rxi_ipl = (2), + .idle_err_ipl = (2), + .p_transfer_tx = NULL, // MAY be null + .p_transfer_rx = NULL, +}; + +/* Instance structure to use this module. */ +const i2s_instance_t g_i2s0 = { + .p_ctrl = &g_i2s0_ctrl, + .p_cfg = &g_i2s0_cfg, + .p_api = &g_i2s_on_ssi +}; diff --git a/libraries/I2S/examples/RecordAndStream/RecordAndStream.ino b/libraries/I2S/examples/RecordAndStream/RecordAndStream.ino new file mode 100644 index 000000000..8ed3b2a72 --- /dev/null +++ b/libraries/I2S/examples/RecordAndStream/RecordAndStream.ino @@ -0,0 +1,26 @@ +#include + +void setup() { + Serial.begin(9600); + while (!Serial) { + + } + + // Resolution, sample rate, number of samples per channel, queue depth. + if (!I2S.begin(I2S_MODE_INOUT, 32000, 256, 8)) { + Serial.println("Failed to start I2S"); + while (1); + } +} + +void loop() { + if (I2S.available()) { + SampleBuffer rxbuf = I2S.read(); + SampleBuffer txbuf = I2S.dequeue(); + for (size_t i=0; isetAlarmCallback(nullptr, t, m); +} + bool RTClock::isRunning() { return isRtcRunning(); } diff --git a/libraries/RTC/src/RTC.h b/libraries/RTC/src/RTC.h index 1010fdbbf..92df943d4 100644 --- a/libraries/RTC/src/RTC.h +++ b/libraries/RTC/src/RTC.h @@ -181,6 +181,8 @@ class RTClock { bool setPeriodicCallback(rtc_cbk_t fnc, Period p); bool setAlarmCallback(rtc_cbk_t fnc, RTCTime &t, AlarmMatch &m); + bool setAlarm(RTCTime &t, AlarmMatch &m); + bool isRunning(); bool setTime(RTCTime &t); bool setTimeIfNotRunning(RTCTime &t); diff --git a/libraries/SE05X/src/lib/platform/arduino/sm_port.cpp b/libraries/SE05X/src/lib/platform/arduino/sm_port.cpp index 3e3f529c9..364c4f78e 100644 --- a/libraries/SE05X/src/lib/platform/arduino/sm_port.cpp +++ b/libraries/SE05X/src/lib/platform/arduino/sm_port.cpp @@ -23,7 +23,7 @@ void smlog_print(const char *format, ...) { char debug_buf[1024]; va_list argptr; va_start(argptr, format); - vsprintf(debug_buf, format, argptr); + vsnprintf(debug_buf, sizeof(debug_buf), format, argptr); va_end(argptr); Serial.print(debug_buf); } diff --git a/libraries/SSLClient/src/ssl_debug.cpp b/libraries/SSLClient/src/ssl_debug.cpp index 151abc7d5..e22ef0429 100644 --- a/libraries/SSLClient/src/ssl_debug.cpp +++ b/libraries/SSLClient/src/ssl_debug.cpp @@ -23,7 +23,7 @@ void ssl_debug_print(const char *format, ...) { char debug_buf[1024]; va_list argptr; va_start(argptr, format); - vsprintf(debug_buf, format, argptr); + vsnprintf(debug_buf, sizeof(debug_buf), format, argptr); va_end(argptr); Serial.print(debug_buf); } @@ -32,7 +32,7 @@ void ssl_debug_println(const char *format, ...) { char debug_buf[1024]; va_list argptr; va_start(argptr, format); - vsprintf(debug_buf, format, argptr); + vsnprintf(debug_buf, sizeof(debug_buf), format, argptr); va_end(argptr); Serial.println(debug_buf); } diff --git a/libraries/SoftwareSerial/src/SoftwareSerial.h b/libraries/SoftwareSerial/src/SoftwareSerial.h index 77c1292b5..e62cac7e1 100644 --- a/libraries/SoftwareSerial/src/SoftwareSerial.h +++ b/libraries/SoftwareSerial/src/SoftwareSerial.h @@ -57,7 +57,7 @@ template struct ss_descr_t { fsp_dma_t dma; fsp_pin_t pin; int irq_chan; - ::RingBuffer ringbuf; + ::RingBuffer ringbuf; uint32_t dmabuf[N][SS_MAX_FRAME_SIZE] __attribute__((aligned(4))); ss_descr_t(size_t bufsize): irq_chan(-1), ringbuf(bufsize) { } diff --git a/libraries/WiFi/src/WiFi.cpp b/libraries/WiFi/src/WiFi.cpp index 59e742a0f..bb1750fc3 100644 --- a/libraries/WiFi/src/WiFi.cpp +++ b/libraries/WiFi/src/WiFi.cpp @@ -89,6 +89,7 @@ void CWifi::config(IPAddress local_ip) { _gw[3] = 1; _config(local_ip, _gw, _nm); + setDNS(_gw); } extern uint8_t *IpAddress2uint8(IPAddress a); @@ -98,11 +99,7 @@ void CWifi::_config(IPAddress local_ip, IPAddress gateway, IPAddress subnet) { /* -------------------------------------------------------------------------- */ _useStaticIp = local_ip != INADDR_NONE; if(ni != nullptr) { - ni->DhcpStop(); - ni->DhcpNotUsed(); - IP_ADDR4(&ni->ip, local_ip[0], local_ip[1], local_ip[2], local_ip[3]); - IP_ADDR4(&ni->gw, gateway[0], gateway[1], gateway[2], gateway[3]); - IP_ADDR4(&ni->nm, subnet[0], subnet[1], subnet[2], subnet[3]); + ni->config(local_ip, gateway, subnet); } else { CNetIf::default_ip = local_ip; diff --git a/libraries/WiFiS3/examples/WiFiWebClientSSL/WiFiWebClientSSL.ino b/libraries/WiFiS3/examples/WiFiWebClientSSL/WiFiWebClientSSL.ino index 4efdb3ee6..ee7afc531 100644 --- a/libraries/WiFiS3/examples/WiFiWebClientSSL/WiFiWebClientSSL.ino +++ b/libraries/WiFiS3/examples/WiFiWebClientSSL/WiFiWebClientSSL.ino @@ -1,8 +1,8 @@ /* TLS WiFi Web client - Remember to update the CA certificates using CertificateUploader sketch - before using this sketch. + Board CA Root certificate bundle is embedded inside WiFi firmware: + https://github.com/arduino/uno-r4-wifi-usb-bridge/blob/main/certificates/cacrt_all.pem Find the full UNO R4 WiFi Network documentation here: https://docs.arduino.cc/tutorials/uno-r4-wifi/wifi-examples#wi-fi-web-client-ssl @@ -12,7 +12,7 @@ #include "WiFiSSLClient.h" #include "IPAddress.h" -#include "arduino_secrets.h" +#include "arduino_secrets.h" ///////please enter your sensitive data in the Secret tab/arduino_secrets.h char ssid[] = SECRET_SSID; // your network SSID (name) @@ -31,41 +31,41 @@ WiFiSSLClient client; /* -------------------------------------------------------------------------- */ void setup() { -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ //Initialize serial and wait for port to open: Serial.begin(115200); while (!Serial) { ; // wait for serial port to connect. Needed for native USB port only } - + // check for the WiFi module: if (WiFi.status() == WL_NO_MODULE) { Serial.println("Communication with WiFi module failed!"); // don't continue while (true); } - + String fv = WiFi.firmwareVersion(); if (fv < WIFI_FIRMWARE_LATEST_VERSION) { Serial.println("Please upgrade the firmware"); } - + // attempt to connect to WiFi network: while (status != WL_CONNECTED) { Serial.print("Attempting to connect to SSID: "); Serial.println(ssid); // Connect to WPA/WPA2 network. status = WiFi.begin(ssid, pass); - + // wait 10 seconds for connection: delay(10000); } - + printWifiStatus(); - + Serial.println("\nStarting connection to server..."); // if you get a connection, report back via serial: - + if (client.connect(server, 443)) { Serial.println("connected to server"); // Make a HTTP request: @@ -79,7 +79,7 @@ void setup() { /* just wrap the received data up to 80 columns in the serial print*/ /* -------------------------------------------------------------------------- */ void read_response() { -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ uint32_t received_data_num = 0; while (client.available()) { /* actual data reception */ @@ -88,15 +88,15 @@ void read_response() { Serial.print(c); /* wrap data to 80 columns*/ received_data_num++; - if(received_data_num % 80 == 0) { + if(received_data_num % 80 == 0) { Serial.println(); } - } + } } /* -------------------------------------------------------------------------- */ void loop() { -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ read_response(); // if the server's disconnected, stop the client: @@ -112,7 +112,7 @@ void loop() { /* -------------------------------------------------------------------------- */ void printWifiStatus() { -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ // print the SSID of the network you're attached to: Serial.print("SSID: "); Serial.println(WiFi.SSID()); diff --git a/libraries/WiFiS3/src/Modem.cpp b/libraries/WiFiS3/src/Modem.cpp index 3ae38f335..884ae688b 100644 --- a/libraries/WiFiS3/src/Modem.cpp +++ b/libraries/WiFiS3/src/Modem.cpp @@ -86,12 +86,11 @@ bool ModemClass::passthrough(const uint8_t *data, size_t size) { } /* -------------------------------------------------------------------------- */ -void ModemClass::write_nowait(const string &cmd, string &str, char * fmt, ...) { +void ModemClass::write_nowait(const string &cmd, string &str, const char * fmt, ...) { /* -------------------------------------------------------------------------- */ - memset(tx_buff,0x00,MAX_BUFF_SIZE); va_list va; va_start (va, fmt); - vsprintf ((char *)tx_buff, fmt, va); + vsnprintf((char *)tx_buff, MAX_BUFF_SIZE, fmt, va); va_end (va); if(_serial_debug && _debug_level >= 2) { @@ -106,13 +105,12 @@ void ModemClass::write_nowait(const string &cmd, string &str, char * fmt, ...) { /* -------------------------------------------------------------------------- */ -bool ModemClass::write(const string &prompt, string &data_res, char * fmt, ...){ +bool ModemClass::write(const string &prompt, string &data_res, const char * fmt, ...){ /* -------------------------------------------------------------------------- */ data_res.clear(); - memset(tx_buff,0x00,MAX_BUFF_SIZE); va_list va; va_start (va, fmt); - vsprintf ((char *)tx_buff, fmt, va); + vsnprintf((char *)tx_buff, MAX_BUFF_SIZE, fmt, va); va_end (va); if(_serial_debug) { diff --git a/libraries/WiFiS3/src/Modem.h b/libraries/WiFiS3/src/Modem.h index 3d8aee5b5..78539e7e3 100644 --- a/libraries/WiFiS3/src/Modem.h +++ b/libraries/WiFiS3/src/Modem.h @@ -24,8 +24,8 @@ class ModemClass { void begin(int badurate = 115200); void end(); - bool write(const std::string &cmd, std::string &str, char * fmt, ...); - void write_nowait(const std::string &cmd, std::string &str, char * fmt, ...); + bool write(const std::string &cmd, std::string &str, const char * fmt, ...); + void write_nowait(const std::string &cmd, std::string &str, const char * fmt, ...); bool passthrough(const uint8_t *data, size_t size); void avoid_trim_results() { diff --git a/libraries/WiFiS3/src/WiFiClient.cpp b/libraries/WiFiS3/src/WiFiClient.cpp index adb020053..143f92dae 100644 --- a/libraries/WiFiS3/src/WiFiClient.cpp +++ b/libraries/WiFiS3/src/WiFiClient.cpp @@ -3,11 +3,11 @@ using namespace std; /* -------------------------------------------------------------------------- */ -WiFiClient::WiFiClient() : _sock(-1), destroy_at_distructor(true), rx_buffer(nullptr) { +WiFiClient::WiFiClient() : _sock(-1), destroy_at_distructor(true), rx_buffer(nullptr) { rx_buffer = std::shared_ptr>(new FifoBuffer()); } /* -------------------------------------------------------------------------- */ - + /* -------------------------------------------------------------------------- */ WiFiClient::WiFiClient(int s) : _sock(s), destroy_at_distructor(false), rx_buffer(nullptr) { rx_buffer = std::shared_ptr>(new FifoBuffer()); @@ -18,9 +18,9 @@ WiFiClient::WiFiClient(int s) : _sock(s), destroy_at_distructor(false), rx_buffe WiFiClient::~WiFiClient() { } /* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ WiFiClient::WiFiClient(const WiFiClient& c) { -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ _sock = c._sock; rx_buffer = c.rx_buffer; } @@ -28,13 +28,19 @@ WiFiClient::WiFiClient(const WiFiClient& c) { /* -------------------------------------------------------------------------- */ void WiFiClient::getSocket() { /* -------------------------------------------------------------------------- */ + if(_sock >= 0 && !connected()) { + // if sock >= 0 -> it means we were connected, but something happened and we need + // to reset this socket in order to be able to connect again + stop(); + } + if(_sock == -1) { string res = ""; modem.begin(); if(modem.write(string(PROMPT(_BEGINCLIENT)),res, "%s" , CMD(_BEGINCLIENT))) { _sock = atoi(res.c_str()); } - } + } } /* -------------------------------------------------------------------------- */ @@ -45,7 +51,7 @@ int WiFiClient::connect(IPAddress ip, uint16_t port){ /* -------------------------------------------------------------------------- */ int WiFiClient::connect(const char *host, uint16_t port){ -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ getSocket(); if(_sock >= 0) { string res = ""; @@ -55,17 +61,18 @@ int WiFiClient::connect(const char *host, uint16_t port){ return 1; } } else { - if(modem.write(string(PROMPT(_CLIENTCONNECTNAME)),res, "%s%d,%s,%d\r\n" , CMD_WRITE(_CLIENTCONNECTNAME), _sock, host,port)) { - return 1; - } + if(modem.write(string(PROMPT(_CLIENTCONNECTNAME)),res, "%s%d,%s,%d\r\n" , CMD_WRITE(_CLIENTCONNECTNAME), _sock, host,port)) { + return 1; + } } } + return 0; } /* -------------------------------------------------------------------------- */ size_t WiFiClient::write(uint8_t b){ -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ return write(&b, 1); } @@ -79,7 +86,6 @@ size_t WiFiClient::write(const uint8_t *buf, size_t size){ if(modem.passthrough(buf,size)) { return size; } - } return 0; @@ -87,7 +93,7 @@ size_t WiFiClient::write(const uint8_t *buf, size_t size){ /* -------------------------------------------------------------------------- */ int WiFiClient::available() { -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ int rv = 0; if(_sock >= 0 && rx_buffer != nullptr) { if(rx_buffer->available() > 0) { @@ -109,17 +115,17 @@ int WiFiClient::available() { /* -------------------------------------------------------------------------- */ int WiFiClient::_read() { -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ int rv = -1; if(_sock >= 0 && rx_buffer != nullptr) { string res = ""; uint32_t size = rx_buffer->freePositions() - 1; modem.begin(); - + /* important - it works one shot */ modem.avoid_trim_results(); modem.read_using_size(); - + if(modem.write(string(PROMPT(_CLIENTRECEIVE)),res, "%s%d,%d\r\n" , CMD_WRITE(_CLIENTRECEIVE), _sock, size)) { if(res.size() > 0) { for(int i = 0, rv = 0; i < size && i < res.size(); i++) { @@ -133,11 +139,11 @@ int WiFiClient::_read() { } } return rv; -} +} /* -------------------------------------------------------------------------- */ void WiFiClient::read_if_needed(size_t s) { -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ if(rx_buffer != nullptr) { if((size_t)rx_buffer->available() < s) { _read(); @@ -147,12 +153,12 @@ void WiFiClient::read_if_needed(size_t s) { /* -------------------------------------------------------------------------- */ int WiFiClient::read() { -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ uint8_t b; if(read(&b, 1) == 1) { return b; } - return -1; + return -1; } /* -------------------------------------------------------------------------- */ @@ -173,19 +179,19 @@ int WiFiClient::read(uint8_t *buf, size_t size) { } } } - return rv; + return rv; } /* -------------------------------------------------------------------------- */ int WiFiClient::peek() { -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ int rv = -1; if(_sock >= 0) { string res = ""; modem.begin(); if(modem.write(string(PROMPT(_PEEK)),res, "%s%d\r\n" , CMD_WRITE(_PEEK), _sock)) { rv = atoi(res.c_str()); - } + } } return rv; } @@ -193,7 +199,7 @@ int WiFiClient::peek() { /* -------------------------------------------------------------------------- */ void WiFiClient::flush() { -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ if(_sock >= 0) { string res = ""; modem.begin(); @@ -203,18 +209,20 @@ void WiFiClient::flush() { /* -------------------------------------------------------------------------- */ void WiFiClient::stop() { -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ if(_sock >= 0) { string res = ""; modem.begin(); modem.write(string(PROMPT(_CLIENTCLOSE)),res, "%s%d\r\n" , CMD_WRITE(_CLIENTCLOSE), _sock); _sock = -1; } + + rx_buffer->clear(); } /* -------------------------------------------------------------------------- */ uint8_t WiFiClient::connected() { -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ uint8_t rv = 0; if(this->available() > 0) { return 1; @@ -224,16 +232,16 @@ uint8_t WiFiClient::connected() { modem.begin(); if(modem.write(string(PROMPT(_CLIENTCONNECTED)),res, "%s%d\r\n" , CMD_WRITE(_CLIENTCONNECTED), _sock)) { rv = atoi(res.c_str()); - } + } } + return rv; } /* -------------------------------------------------------------------------- */ -bool WiFiClient::operator==(const WiFiClient& whs) -{ - /* -------------------------------------------------------------------------- */ - return _sock == whs._sock; +bool WiFiClient::operator==(const WiFiClient& whs) { +/* -------------------------------------------------------------------------- */ + return _sock == whs._sock; } /* -------------------------------------------------------------------------- */ @@ -246,14 +254,14 @@ IPAddress WiFiClient::remoteIP() { if(modem.write(string(PROMPT(_REMOTEIP)),res, "%s%d\r\n" , CMD_WRITE(_REMOTEIP), _sock)) { ip.fromString(res.c_str()); return ip; - } + } } return IPAddress(0,0,0,0); } /* -------------------------------------------------------------------------- */ uint16_t WiFiClient::remotePort(){ -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ uint16_t rv = 0; if(_sock >= 0) { string res = ""; @@ -261,7 +269,7 @@ uint16_t WiFiClient::remotePort(){ if(modem.write(string(PROMPT(_REMOTEPORT)),res, "%s%d\r\n" , CMD_WRITE(_REMOTEPORT), _sock)) { rv = atoi(res.c_str()); return rv; - } + } } - return rv; + return rv; } diff --git a/libraries/WiFiS3/src/WiFiClient.h b/libraries/WiFiS3/src/WiFiClient.h index 972b98b8a..81f5afae6 100644 --- a/libraries/WiFiS3/src/WiFiClient.h +++ b/libraries/WiFiS3/src/WiFiClient.h @@ -30,8 +30,6 @@ #include "FifoBuffer.h" #include -#define RX_BUFFER_DIM 1024 - class WiFiClient : public Client { public: @@ -67,17 +65,17 @@ class WiFiClient : public Client { } friend class WiFiServer; - + using Print::write; protected: int _sock; int _connectionTimeout = 0; void getSocket(); + static constexpr uint32_t RX_BUFFER_DIM = 1024; std::shared_ptr> rx_buffer; int _read(); void read_if_needed(size_t s); - void clear_buffer(); bool destroy_at_distructor; diff --git a/libraries/WiFiS3/src/WiFiSSLClient.cpp b/libraries/WiFiS3/src/WiFiSSLClient.cpp index f67c30896..91b6951e5 100644 --- a/libraries/WiFiS3/src/WiFiSSLClient.cpp +++ b/libraries/WiFiS3/src/WiFiSSLClient.cpp @@ -3,9 +3,8 @@ using namespace std; /* -------------------------------------------------------------------------- */ -WiFiSSLClient::WiFiSSLClient() : _sock(-1) { +WiFiSSLClient::WiFiSSLClient() { /* -------------------------------------------------------------------------- */ - rx_buffer = std::shared_ptr>(new FifoBuffer()); } /* -------------------------------------------------------------------------- */ @@ -17,13 +16,19 @@ WiFiSSLClient::~WiFiSSLClient() { /* -------------------------------------------------------------------------- */ void WiFiSSLClient::getSocket() { /* -------------------------------------------------------------------------- */ + if(_sock >= 0 && !connected()) { + // if sock >= 0 -> it means we were connected, but something happened and we need + // to reset this socket in order to be able to connect again + stop(); + } + if(_sock == -1) { string res = ""; modem.begin(); if(modem.write(string(PROMPT(_SSLBEGINCLIENT)),res, "%s" , CMD(_SSLBEGINCLIENT))) { _sock = atoi(res.c_str()); } - } + } } /* -------------------------------------------------------------------------- */ @@ -87,7 +92,7 @@ void WiFiSSLClient::setEccSlot(int ecc508KeySlot, const byte cert[], int certLen /* -------------------------------------------------------------------------- */ size_t WiFiSSLClient::write(uint8_t b){ -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ return write(&b, 1); } @@ -101,7 +106,7 @@ size_t WiFiSSLClient::write(const uint8_t *buf, size_t size){ if(modem.passthrough(buf,size)) { return size; } - + } return 0; @@ -109,7 +114,7 @@ size_t WiFiSSLClient::write(const uint8_t *buf, size_t size){ /* -------------------------------------------------------------------------- */ int WiFiSSLClient::available(){ -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ int rv = 0; if(_sock >= 0 && rx_buffer != nullptr) { if(rx_buffer->available() > 0) { @@ -123,7 +128,7 @@ int WiFiSSLClient::available(){ if (rv < 0) { return 0; } - } + } } } return rv; @@ -131,13 +136,13 @@ int WiFiSSLClient::available(){ /* -------------------------------------------------------------------------- */ int WiFiSSLClient::_read() { -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ int rv = -1; - if(_sock >= 0) { + if(_sock >= 0 && rx_buffer != nullptr) { string res = ""; uint32_t size = rx_buffer->freePositions() - 1; modem.begin(); - + /* important - it works one shot */ modem.avoid_trim_results(); modem.read_using_size(); @@ -154,11 +159,11 @@ int WiFiSSLClient::_read() { } } return rv; -} +} /* -------------------------------------------------------------------------- */ void WiFiSSLClient::read_if_needed(size_t s) { -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ if((size_t)rx_buffer->available() < s) { _read(); } @@ -166,12 +171,12 @@ void WiFiSSLClient::read_if_needed(size_t s) { /* -------------------------------------------------------------------------- */ int WiFiSSLClient::read() { -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ uint8_t b; if(read(&b, 1) == 1) { return b; } - return -1; + return -1; } /* -------------------------------------------------------------------------- */ @@ -190,19 +195,19 @@ int WiFiSSLClient::read(uint8_t *buf, size_t size) { go_on = false; } } - return rv; + return rv; } /* -------------------------------------------------------------------------- */ int WiFiSSLClient::peek() { -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ int rv = -1; if(_sock >= 0) { string res = ""; modem.begin(); if(modem.write(string(PROMPT(_SSLPEEK)),res, "%s%d\r\n" , CMD_WRITE(_SSLPEEK), _sock)) { rv = atoi(res.c_str()); - } + } } return rv; } @@ -210,7 +215,7 @@ int WiFiSSLClient::peek() { /* -------------------------------------------------------------------------- */ void WiFiSSLClient::flush() { -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ if(_sock >= 0) { string res = ""; modem.begin(); @@ -220,31 +225,33 @@ void WiFiSSLClient::flush() { /* -------------------------------------------------------------------------- */ void WiFiSSLClient::stop() { -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ if(_sock >= 0) { string res = ""; modem.begin(); modem.write(string(PROMPT(_SSLCLIENTCLOSE)),res, "%s%d\r\n" , CMD_WRITE(_SSLCLIENTCLOSE), _sock); _sock = -1; } + + rx_buffer->clear(); } /* -------------------------------------------------------------------------- */ uint8_t WiFiSSLClient::connected() { -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ uint8_t rv = 0; if(_sock >= 0) { string res = ""; modem.begin(); if(modem.write(string(PROMPT(_SSLCLIENTCONNECTED)),res, "%s%d\r\n" , CMD_WRITE(_SSLCLIENTCONNECTED), _sock)) { rv = atoi(res.c_str()); - } + } } return rv; } -bool WiFiSSLClient::operator==(const WiFiSSLClient& whs) -{ - return _sock == whs._sock; + +bool WiFiSSLClient::operator==(const WiFiSSLClient& whs) { + return _sock == whs._sock; } /* -------------------------------------------------------------------------- */ @@ -257,14 +264,14 @@ IPAddress WiFiSSLClient::remoteIP() { if(modem.write(string(PROMPT(_SSLREMOTEIP)),res, "%s%d\r\n" , CMD_WRITE(_SSLREMOTEIP), _sock)) { ip.fromString(res.c_str()); return ip; - } + } } return IPAddress(0,0,0,0); } /* -------------------------------------------------------------------------- */ uint16_t WiFiSSLClient::remotePort(){ -/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ uint16_t rv = 0; if(_sock >= 0) { string res = ""; @@ -272,7 +279,7 @@ uint16_t WiFiSSLClient::remotePort(){ if(modem.write(string(PROMPT(_SSLREMOTEPORT)),res, "%s%d\r\n" , CMD_WRITE(_SSLREMOTEPORT), _sock)) { rv = atoi(res.c_str()); return rv; - } + } } - return rv; + return rv; } \ No newline at end of file diff --git a/libraries/WiFiS3/src/WiFiSSLClient.h b/libraries/WiFiS3/src/WiFiSSLClient.h index c021a0a16..6bdbf9687 100644 --- a/libraries/WiFiS3/src/WiFiSSLClient.h +++ b/libraries/WiFiS3/src/WiFiSSLClient.h @@ -45,7 +45,7 @@ class WiFiSSLClient : public WiFiClient { virtual void stop(); virtual uint8_t connected(); virtual operator bool() { - return _sock != -1; + return _sock != -1; } virtual bool operator==(const WiFiSSLClient&); virtual bool operator!=(const WiFiSSLClient& whs) @@ -60,7 +60,6 @@ class WiFiSSLClient : public WiFiClient { using Print::write; private: - int _sock; void getSocket(); int _read(); void read_if_needed(size_t s); diff --git a/libraries/WiFiS3/src/WiFiUdp.h b/libraries/WiFiS3/src/WiFiUdp.h index 8eda0ca65..a6d7c6026 100644 --- a/libraries/WiFiS3/src/WiFiUdp.h +++ b/libraries/WiFiS3/src/WiFiUdp.h @@ -30,11 +30,10 @@ #include "Modem.h" #include "FifoBuffer.h" -#define RX_BUFFER_DIM 1461 - class WiFiUDP : public UDP { private: int _sock; + static constexpr uint32_t RX_BUFFER_DIM = 1461; FifoBuffer rx_buffer; protected: diff --git a/libraries/Wire/Wire.cpp b/libraries/Wire/Wire.cpp index 00233ab4d..4fdffa032 100644 --- a/libraries/Wire/Wire.cpp +++ b/libraries/Wire/Wire.cpp @@ -30,8 +30,8 @@ extern "C" { #include "Wire.h" -TwoWire *TwoWire::g_SCIWires[TWOWIRE_MAX_I2C_CHANNELS] = {nullptr}; -TwoWire *TwoWire::g_I2CWires[TWOWIRE_MAX_SCI_CHANNELS] = {nullptr}; +TwoWire *TwoWire::g_SCIWires[TWOWIRE_MAX_SCI_CHANNELS] = {nullptr}; +TwoWire *TwoWire::g_I2CWires[TWOWIRE_MAX_I2C_CHANNELS] = {nullptr}; /* -------------------------------------------------------------------------- */ void TwoWire::setBusStatus(WireStatus_t ws) { @@ -437,25 +437,28 @@ void TwoWire::end(void) { 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); - + m_close(&m_i2c_ctrl); } } 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); + s_close(&s_i2c_ctrl); } } } + /* fix for slave that create a sort of lock on the I2C bus when end is called and the master + is not more able to get the I2C buse working */ + R_IOPORT_PinCfg(NULL, g_pin_cfg[sda_pin].pin, IOPORT_CFG_PORT_DIRECTION_INPUT | IOPORT_CFG_PULLUP_ENABLE); + R_IOPORT_PinCfg(NULL, g_pin_cfg[scl_pin].pin, IOPORT_CFG_PORT_DIRECTION_INPUT | IOPORT_CFG_PULLUP_ENABLE); init_ok = false; } @@ -486,6 +489,10 @@ uint8_t TwoWire::read_from(uint8_t address, uint8_t* data, uint8_t length, unsig if(bus_status == WIRE_STATUS_RX_COMPLETED) { return length; } + + if(bus_status == WIRE_STATUS_UNSET) { + m_abort(&m_i2c_ctrl); + } return 0; /* ???????? return value ??????? */ } @@ -518,6 +525,7 @@ uint8_t TwoWire::write_to(uint8_t address, uint8_t* data, uint8_t length, unsign } else if(bus_status == WIRE_STATUS_UNSET) { rv = END_TX_TIMEOUT; + m_abort(&m_i2c_ctrl); } /* as far as I know is impossible to distinguish between NACK on ADDRESS and NACK on DATA */ diff --git a/libraries/Wire/Wire.h b/libraries/Wire/Wire.h index 5a78660b1..88ff8d652 100644 --- a/libraries/Wire/Wire.h +++ b/libraries/Wire/Wire.h @@ -152,8 +152,8 @@ class TwoWire : public arduino::HardwareI2C { private: - static TwoWire *g_SCIWires[TWOWIRE_MAX_I2C_CHANNELS]; - static TwoWire *g_I2CWires[TWOWIRE_MAX_SCI_CHANNELS]; + static TwoWire *g_SCIWires[TWOWIRE_MAX_SCI_CHANNELS]; + static TwoWire *g_I2CWires[TWOWIRE_MAX_I2C_CHANNELS]; static void WireSCIMasterCallback(i2c_master_callback_args_t *); static void WireMasterCallback(i2c_master_callback_args_t *); diff --git a/libraries/lwIpWrapper/src/CNetIf.cpp b/libraries/lwIpWrapper/src/CNetIf.cpp index 53f01dd78..3cc07c924 100644 --- a/libraries/lwIpWrapper/src/CNetIf.cpp +++ b/libraries/lwIpWrapper/src/CNetIf.cpp @@ -1271,6 +1271,24 @@ void CNetIf::setLinkDown() netif_set_down(&ni); } +/* -------------------------------------------------------------------------- */ +void CNetIf::config(IPAddress _ip, IPAddress _gw, IPAddress _nm) +{ + DhcpStop(); + DhcpNotUsed(); + + IP_ADDR4(&ip, _ip[0], _ip[1], _ip[2], _ip[3]); + IP_ADDR4(&nm, _nm[0], _nm[1], _nm[2], _nm[3]); + IP_ADDR4(&gw, _gw[0], _gw[1], _gw[2], _gw[3]); + + netif_set_addr(&ni, &ip, &nm, &gw); + + if (netif_is_link_up(&ni)) { + netif_set_down(&ni); + netif_set_up(&ni); + } +} + /* ########################################################################## */ /* ETHERNET NETWORK INTERFACE CLASS */ /* ########################################################################## */ @@ -1549,10 +1567,9 @@ char b_dbg[512]; extern "C" void printDbg(const char* fmt, ...) { - memset(b_dbg, 0x00, 256); va_list va; va_start(va, fmt); - vsprintf(b_dbg, fmt, va); + vsnprintf(b_dbg, sizeof(b_dbg), fmt, va); va_end(va); Serial.println(b_dbg); diff --git a/libraries/lwIpWrapper/src/CNetIf.h b/libraries/lwIpWrapper/src/CNetIf.h index 0b805d202..2fa090bba 100644 --- a/libraries/lwIpWrapper/src/CNetIf.h +++ b/libraries/lwIpWrapper/src/CNetIf.h @@ -189,6 +189,8 @@ class CNetIf { uint32_t getNmAdd() { return ip4_addr_get_u32(&(ni.netmask)); } uint32_t getGwAdd() { return ip4_addr_get_u32(&(ni.gw)); } + void config(IPAddress _ip, IPAddress _gw, IPAddress _nm); + void setHostname(const char* name) { memset(hostname, 0x00, MAX_HOSTNAME_DIM); diff --git a/platform.txt b/platform.txt index 557f5a3df..c18a49197 100644 --- a/platform.txt +++ b/platform.txt @@ -3,7 +3,7 @@ # https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5---3rd-party-Hardware-specification name=Arduino Renesas fsp Boards -version=1.1.0 +version=1.2.0 # Compile variables # ------------------------ @@ -68,19 +68,19 @@ build.usb_flags= # ----------------------- ## Compile c files -recipe.c.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.c.flags} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} -DARDUINO_ARCH_RENESAS -DARDUINO_FSP -D_XOPEN_SOURCE=700 {compiler.fsp.cflags} {compiler.tinyusb.cflags} {build.extra_flags} {tinyusb.includes} "-I{build.core.path}/api/deprecated" "-I{build.core.path}/api/deprecated-avr-comp" {includes} "-iprefix{runtime.platform.path}" "@{compiler.fsp.includes}" -o "{object_file}" "{source_file}" +recipe.c.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.c.flags} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} -DARDUINO_ARCH_RENESAS -DARDUINO_FSP -D_XOPEN_SOURCE=700 {compiler.fsp.cflags} {compiler.tinyusb.cflags} {compiler.c.extra_flags} {build.extra_flags} {tinyusb.includes} "-I{build.core.path}/api/deprecated" "-I{build.core.path}/api/deprecated-avr-comp" {includes} "-iprefix{runtime.platform.path}" "@{compiler.fsp.includes}" -o "{object_file}" "{source_file}" ## Compile c++ files -recipe.cpp.o.pattern="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} -DARDUINO={runtime.ide.version} "-DPROJECT_NAME="{build.path}/{build.project_name}"" -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} -DARDUINO_ARCH_RENESAS -DARDUINO_FSP -D_XOPEN_SOURCE=700 {compiler.fsp.cxxflags} {compiler.tinyusb.cxxflags} {build.extra_flags} {tinyusb.includes} "-I{build.core.path}/api/deprecated" "-I{build.core.path}/api/deprecated-avr-comp" {includes} "-iprefix{runtime.platform.path}" "@{compiler.fsp.includes}" "{source_file}" -o "{object_file}" +recipe.cpp.o.pattern="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} -DARDUINO={runtime.ide.version} "-DPROJECT_NAME="{build.path}/{build.project_name}"" -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} -DARDUINO_ARCH_RENESAS -DARDUINO_FSP -D_XOPEN_SOURCE=700 {compiler.fsp.cxxflags} {compiler.tinyusb.cxxflags} {compiler.cpp.extra_flags} {build.extra_flags} {tinyusb.includes} "-I{build.core.path}/api/deprecated" "-I{build.core.path}/api/deprecated-avr-comp" {includes} "-iprefix{runtime.platform.path}" "@{compiler.fsp.includes}" "{source_file}" -o "{object_file}" ## Compile asm files -recipe.S.o.pattern="{compiler.path}{compiler.S.cmd}" {compiler.S.flags} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} -DARDUINO_ARCH_RENESAS -DARDUINO_FSP -D_XOPEN_SOURCE=700 {includes} {build.extra_flags} {build.extra_ldflags} {compiler.cpp.extra_flags} "-I{build.core.path}/api/deprecated" "-I{build.core.path}/api/deprecated-avr-comp" {includes} "-iprefix{runtime.platform.path}" "@{compiler.fsp.includes}" "{source_file}" -o "{object_file}" +recipe.S.o.pattern="{compiler.path}{compiler.S.cmd}" {compiler.S.flags} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} -DARDUINO_ARCH_RENESAS -DARDUINO_FSP -D_XOPEN_SOURCE=700 {includes} {build.extra_flags} {build.extra_ldflags} {compiler.S.extra_flags} "-I{build.core.path}/api/deprecated" "-I{build.core.path}/api/deprecated-avr-comp" {includes} "-iprefix{runtime.platform.path}" "@{compiler.fsp.includes}" "{source_file}" -o "{object_file}" ## Create archives recipe.ar.pattern="{compiler.path}{compiler.ar.cmd}" {compiler.ar.flags} {compiler.ar.extra_flags} "{archive_file_path}" "{object_file}" ## Combine gc-sections, archives, and objects -recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.c.elf.flags} {build.extra_flags} -o "{build.path}/{build.project_name}.elf" "-L{build.path}" "-L{build.variant.path}" "-T{build.variant.path}/fsp.ld" {object_files} -Wl,--whole-archive -Wl,--start-group {compiler.fsp} "{build.path}/{archive_file}" -Wl,--no-whole-archive {compiler.fsp.extra_ldflags} {compiler.libraries.ldflags} -Wl,--end-group "-Wl,-Map,{build.path}/{build.project_name}.map" +recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.c.elf.flags} {compiler.c.elf.extra_flags} {build.extra_flags} -o "{build.path}/{build.project_name}.elf" "-L{build.path}" "-L{build.variant.path}" "-T{build.variant.path}/fsp.ld" {object_files} -Wl,--whole-archive -Wl,--start-group {compiler.fsp} "{build.path}/{archive_file}" -Wl,--no-whole-archive {compiler.fsp.extra_ldflags} {compiler.libraries.ldflags} -Wl,--end-group "-Wl,-Map,{build.path}/{build.project_name}.map" ## Create output (bin file) recipe.objcopy.bin.pattern="{compiler.path}{compiler.elf2hex.cmd}" {compiler.elf2hex.bin.flags} {compiler.elf2hex.extra_flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.bin" @@ -144,4 +144,4 @@ debug.cortex-debug.custom.postAttachCommands.3=c debug.cortex-debug.custom.overrideRestartCommands.0=monitor reset halt debug.cortex-debug.custom.overrideRestartCommands.1=monitor gdb_sync debug.cortex-debug.custom.overrideRestartCommands.2=c -debug.cortex-debug.custom.request=attach \ No newline at end of file +debug.cortex-debug.custom.request=attach diff --git a/svd/R7FA4M1AB.svd b/svd/R7FA4M1AB.svd index 3fffa3672..67a6ba02f 100644 --- a/svd/R7FA4M1AB.svd +++ b/svd/R7FA4M1AB.svd @@ -16080,39 +16080,665 @@ These bits select the peripheral function. For individual pin functions, see the 0x00 0xFD - - 8 + + P100PFS + P100 Pin Function Control Register + 0x040 + 32 + read-write + 0x00000000 + 0xFFFFFFFD + + + Reserved + These bits are read as 000. The write value should be 000. + 29 + 31 + read-write + + + PSEL + Port Function Select +These bits select the peripheral function. For individual pin functions, see the MPC table + 24 + 28 + read-write + + + Reserved + These bits are read as 0000000. The write value should be 0000000. + 17 + 23 + read-write + + + PMR + Port Mode Control + 16 + 16 + read-write + + + 0 + Uses the pin as a general I/O pin. + #0 + + + 1 + Uses the pin as an I/O port for peripheral functions. + #1 + + + + + ASEL + Analog Input enable + 15 + 15 + read-write + + + 0 + Used other than as analog pin + #0 + + + 1 + Used as analog pin + #1 + + + + + ISEL + IRQ input enable + 14 + 14 + read-write + + + 0 + Not used as IRQn input pin + #0 + + + 1 + Used as IRQn input pin + #1 + + + + + EOF + Event on Falling + 13 + 13 + read-write + + + 0 + Do not care + #0 + + + 1 + Detect falling edge + #1 + + + + + EOR + Event on Rising + 12 + 12 + read-write + + + 0 + Do not care + #0 + + + 1 + Detect rising edge + #1 + + + + + Reserved + These bits are read as 000. The write value should be 000. + 11 + 11 + read-write + + + DSCR + Port Drive Capability + 10 + 10 + read-write + + + 0 + Low drive + #0 + + + 1 + Middle drive. + #1 + + + + + Reserved + These bits are read as 000. The write value should be 000. + 7 + 9 + read-write + + + NCODR + N-Channel Open Drain Control + 6 + 6 + read-write + + + 0 + CMOS output + #0 + + + 1 + NMOS open-drain output + #1 + + + + + Reserved + This bit is read as 0. The write value should be 0. + 5 + 5 + read-write + + + PCR + Pull-up Control + 4 + 4 + read-write + + + 0 + Disables an input pull-up. + #0 + + + 1 + Enables an input pull-up. + #1 + + + + + Reserved + This bit is read as 0. The write value should be 0. + 3 + 3 + read-write + + + PDR + Port Direction + 2 + 2 + read-write + + + 0 + Input (Functions as an input pin.) + #0 + + + 1 + Output (Functions as an output pin.) + #1 + + + + + PIDR + Port Input Data + 1 + 1 + read-only + + + 0 + Low input + #0 + + + 1 + High input + #1 + + + + + PODR + Port Output Data + 0 + 0 + read-write + + + 0 + Low output + #0 + + + 1 + High output + #1 + + + + + + + P100PFS_HA + P100 Pin Function Control Register + 0x042 + 16 + read-write + 0x0000 + 0xFFFD + + + ASEL + Analog Input enable + 15 + 15 + read-write + + + 0 + Used other than as analog pin + #0 + + + 1 + Used as analog pin + #1 + + + + + ISEL + IRQ input enable + 14 + 14 + read-write + + + 0 + Not used as IRQn input pin + #0 + + + 1 + Used as IRQn input pin + #1 + + + + + EOF + Event on Falling + 13 + 13 + read-write + + + 0 + Do not care + #0 + + + 1 + Detect falling edge + #1 + + + + + EOR + Event on Rising + 12 + 12 + read-write + + + 0 + Do not care + #0 + + + 1 + Detect rising edge + #1 + + + + + Reserved + These bits are read as 000. The write value should be 000. + 11 + 11 + read-write + + + DSCR + Port Drive Capability + 10 + 10 + read-write + + + 0 + Low drive + #0 + + + 1 + Middle drive. + #1 + + + + + Reserved + These bits are read as 000. The write value should be 000. + 7 + 9 + read-write + + + NCODR + N-Channel Open Drain Control + 6 + 6 + read-write + + + 0 + CMOS output + #0 + + + 1 + NMOS open-drain output + #1 + + + + + Reserved + This bit is read as 0. The write value should be 0. + 5 + 5 + read-write + + + PCR + Pull-up Control + 4 + 4 + read-write + + + 0 + Disables an input pull-up. + #0 + + + 1 + Enables an input pull-up. + #1 + + + + + Reserved + This bit is read as 0. The write value should be 0. + 3 + 3 + read-write + + + PDR + Port Direction + 2 + 2 + read-write + + + 0 + Input (Functions as an input pin.) + #0 + + + 1 + Output (Functions as an output pin.) + #1 + + + + + PIDR + Port Input Data + 1 + 1 + read-only + + + 0 + Low input + #0 + + + 1 + High input + #1 + + + + + PODR + Port Output Data + 0 + 0 + read-write + + + 0 + Low output + #0 + + + 1 + High output + #1 + + + + + + + P100PFS_BY + P100 Pin Function Control Register + 0x043 + 8 + read-write + 0x00 + 0xFD + + + Reserved + These bits are read as 000. The write value should be 000. + 7 + 7 + read-write + + + NCODR + N-Channel Open Drain Control + 6 + 6 + read-write + + + 0 + CMOS output + #0 + + + 1 + NMOS open-drain output + #1 + + + + + Reserved + This bit is read as 0. The write value should be 0. + 5 + 5 + read-write + + + PCR + Pull-up Control + 4 + 4 + read-write + + + 0 + Disables an input pull-up. + #0 + + + 1 + Enables an input pull-up. + #1 + + + + + Reserved + This bit is read as 0. The write value should be 0. + 3 + 3 + read-write + + + PDR + Port Direction + 2 + 2 + read-write + + + 0 + Input (Functions as an input pin.) + #0 + + + 1 + Output (Functions as an output pin.) + #1 + + + + + PIDR + Port Input Data + 1 + 1 + read-only + + + 0 + Low input + #0 + + + 1 + High input + #1 + + + + + PODR + Port Output Data + 0 + 0 + read-write + + + 0 + Low output + #0 + + + 1 + High output + #1 + + + + + + + 7 0x4 - 0-7 + 1-7 P10%sPFS P10%s Pin Function Control Register - 0x040 + 0x044 32 read-write 0x00000000 0xFFFFFFFD - - 8 + + 7 0x4 - 0-7 + 1-7 P10%sPFS_HA P10%s Pin Function Control Register P10%sPFS - 0x042 + 0x046 16 read-write 0x0000 0xFFFD - - 8 + + 7 0x4 - 0-7 + 1-7 P10%sPFS_BY P10%s Pin Function Control Register P10%sPFS - 0x043 + 0x047 8 read-write 0x00 @@ -17403,7 +18029,7 @@ These bits select the peripheral function. For individual pin functions, see the 0x10 0xFD - + 5 0x4 11-15 @@ -17415,7 +18041,7 @@ These bits select the peripheral function. For individual pin functions, see the 0x00000000 0xFFFFFFFD - + 5 0x4 11-15 @@ -17428,7 +18054,7 @@ These bits select the peripheral function. For individual pin functions, see the 0x0000 0xFFFD - + 5 0x4 11-15 @@ -17441,7 +18067,7 @@ These bits select the peripheral function. For individual pin functions, see the 0x00 0xFD - + P200PFS P200 Pin Function Control Register 0x080 @@ -17450,7 +18076,7 @@ These bits select the peripheral function. For individual pin functions, see the 0x00000000 0xFFFFFFFD - + P200PFS_HA P200 Pin Function Control Register P200PFS @@ -17460,7 +18086,7 @@ These bits select the peripheral function. For individual pin functions, see the 0x0000 0xFFFD - + P200PFS_BY P200 Pin Function Control Register P200PFS @@ -17617,7 +18243,7 @@ These bits select the peripheral function. For individual pin functions, see the 1 - High drive + Middle drive #1 @@ -17847,7 +18473,7 @@ These bits select the peripheral function. For individual pin functions, see the 1 - High drive + Middle drive #1 @@ -18931,7 +19557,7 @@ These bits select the peripheral function. For individual pin functions, see the - + P409PFS P409 Pin Function Control Register 0x124 @@ -18940,7 +19566,7 @@ These bits select the peripheral function. For individual pin functions, see the 0x00000000 0xFFFFFFFD - + P409PFS_HA P409 Pin Function Control Register P409PFS @@ -18950,7 +19576,7 @@ These bits select the peripheral function. For individual pin functions, see the 0x0000 0xFFFD - + P409PFS_BY P409 Pin Function Control Register P409PFS @@ -18960,7 +19586,7 @@ These bits select the peripheral function. For individual pin functions, see the 0x00 0xFD - + 6 0x4 10-15 @@ -18972,7 +19598,7 @@ These bits select the peripheral function. For individual pin functions, see the 0x00000000 0xFFFFFFFD - + 6 0x4 10-15 @@ -18985,7 +19611,7 @@ These bits select the peripheral function. For individual pin functions, see the 0x0000 0xFFFD - + 6 0x4 10-15 diff --git a/variants/MINIMA/libs/libfsp.a b/variants/MINIMA/libs/libfsp.a index a962eb912..62a9a8436 100644 Binary files a/variants/MINIMA/libs/libfsp.a and b/variants/MINIMA/libs/libfsp.a differ diff --git a/variants/MINIMA/pins_arduino.h b/variants/MINIMA/pins_arduino.h index be936298a..2786bc95a 100644 --- a/variants/MINIMA/pins_arduino.h +++ b/variants/MINIMA/pins_arduino.h @@ -90,6 +90,7 @@ static const uint8_t D13 = PIN_D13; static const uint8_t D14 = PIN_D14; static const uint8_t D15 = PIN_D15; +#define digitalPinHasPWM(p) (IS_PIN_PWM(getPinCfgs(p, PIN_CFG_REQ_PWM)[0])) // LEDs // ---- #define PIN_LED (13u) diff --git a/variants/PORTENTA_C33/libs/libfsp.a b/variants/PORTENTA_C33/libs/libfsp.a index abb6f7d10..0c447a2cf 100644 Binary files a/variants/PORTENTA_C33/libs/libfsp.a and b/variants/PORTENTA_C33/libs/libfsp.a differ diff --git a/variants/PORTENTA_C33/pins_arduino.h b/variants/PORTENTA_C33/pins_arduino.h index 898a1940d..1cd256bfc 100644 --- a/variants/PORTENTA_C33/pins_arduino.h +++ b/variants/PORTENTA_C33/pins_arduino.h @@ -161,6 +161,7 @@ static const uint8_t SS = PIN_SPI_CS; /****** SDCARD CORE DEFINES *******/ #define SDCARD_HOWMANY 1 +#define I2S_HOWMANY 1 #define EXT_INTERRUPTS_HOWMANY 8 @@ -208,4 +209,7 @@ static const uint8_t SS = PIN_SPI_CS; #define RTC_CLOCK_SOURCE RTC_CLOCK_SOURCE_SUBCLK -#define AR_INTERNAL_VOLTAGE 1.18f \ No newline at end of file +#define AR_INTERNAL_VOLTAGE 1.18f + +#define ETHERNET_AGT_TIMER_CHANNEL 3 +#define ETHERNET_CLK_PIN BSP_IO_PORT_06_PIN_00 diff --git a/variants/PORTENTA_C33/variant.cpp b/variants/PORTENTA_C33/variant.cpp index 3dd128d2a..ce4409b84 100644 --- a/variants/PORTENTA_C33/variant.cpp +++ b/variants/PORTENTA_C33/variant.cpp @@ -216,58 +216,8 @@ int32_t getPinIndex(bsp_io_port_pin_t p) { return rv; } -#include "FspTimer.h" - -#define AGT_TIMER_CHANNEL 3 -#define ETHERNET_CLK_PIN BSP_IO_PORT_06_PIN_00 - -agt_instance_ctrl_t TIMER_ETHERNET_ctrl; -agt_extended_cfg_t TIMER_ETHERNET_extend; -timer_cfg_t TIMER_ETHERNET_cfg; - - -fsp_err_t startETHClock() { - pinPeripheral(ETHERNET_CLK_PIN, (uint32_t) (IOPORT_CFG_PERIPHERAL_PIN | IOPORT_PERIPHERAL_AGT)); - - TIMER_ETHERNET_extend.count_source = AGT_CLOCK_PCLKB; - TIMER_ETHERNET_extend.agto = AGT_PIN_CFG_START_LEVEL_LOW; - TIMER_ETHERNET_extend.agtoab_settings_b.agtoa = AGT_PIN_CFG_DISABLED; - TIMER_ETHERNET_extend.agtoab_settings_b.agtob = AGT_PIN_CFG_DISABLED; - TIMER_ETHERNET_extend.measurement_mode = AGT_MEASURE_DISABLED; - TIMER_ETHERNET_extend.agtio_filter = AGT_AGTIO_FILTER_NONE; - TIMER_ETHERNET_extend.enable_pin = AGT_ENABLE_PIN_NOT_USED; - TIMER_ETHERNET_extend.trigger_edge = AGT_TRIGGER_EDGE_RISING; - - TIMER_ETHERNET_cfg.mode = TIMER_MODE_PERIODIC; - TIMER_ETHERNET_cfg.period_counts = (uint32_t) 0x1; - TIMER_ETHERNET_cfg.duty_cycle_counts = 0x00; - TIMER_ETHERNET_cfg.source_div = (timer_source_div_t) 0; - TIMER_ETHERNET_cfg.channel = AGT_TIMER_CHANNEL; - TIMER_ETHERNET_cfg.p_callback = NULL; - TIMER_ETHERNET_cfg.p_context = NULL; - TIMER_ETHERNET_cfg.p_extend = &TIMER_ETHERNET_extend; - TIMER_ETHERNET_cfg.cycle_end_ipl = (BSP_IRQ_DISABLED); - TIMER_ETHERNET_cfg.cycle_end_irq = FSP_INVALID_VECTOR; - - fsp_err_t err = R_AGT_Open(&TIMER_ETHERNET_ctrl,&TIMER_ETHERNET_cfg); - if (err != FSP_SUCCESS) { - return err; - } - err = R_AGT_Enable(&TIMER_ETHERNET_ctrl); - if (err != FSP_SUCCESS) { - return err; - } - err = R_AGT_Start(&TIMER_ETHERNET_ctrl); - if (err != FSP_SUCCESS) { - return err; - } - - FspTimer::set_timer_is_used(AGT_TIMER, AGT_TIMER_CHANNEL); - return err; -} - void initVariant() { - startETHClock(); + // bootloader configures LED_BUILTIN as PWM output, deconfigure it to avoid spurious signals pinMode(LED_BUILTIN, INPUT); } diff --git a/variants/UNOWIFIR4/libs/libfsp.a b/variants/UNOWIFIR4/libs/libfsp.a index a962eb912..62a9a8436 100644 Binary files a/variants/UNOWIFIR4/libs/libfsp.a and b/variants/UNOWIFIR4/libs/libfsp.a differ diff --git a/variants/UNOWIFIR4/pins_arduino.h b/variants/UNOWIFIR4/pins_arduino.h index 4f0ebb897..b16d73fd3 100644 --- a/variants/UNOWIFIR4/pins_arduino.h +++ b/variants/UNOWIFIR4/pins_arduino.h @@ -90,6 +90,8 @@ static const uint8_t D13 = PIN_D13; static const uint8_t D14 = PIN_D14; static const uint8_t D15 = PIN_D15; +#define digitalPinHasPWM(p) (IS_PIN_PWM(getPinCfgs(p, PIN_CFG_REQ_PWM)[0])) + // LEDs // ---- #define PIN_LED (13u)