Wireless Core Porting Article¶
The Wireless Core needs access to some MCU peripherals for it to function. This article provides a detailed description of all the hooks required for the BSP development of a new hardware platform.
- The Wireless Core needs control over the following MCU peripherals & features:
SPI
DMA
GPIOs
Timers
MCU Exception Callbacks
Enter/Exit Critical Section
Step 1. Populate the swc_hal_t
Structure¶
The code block below represents one of the functions of the BSP Interface which aims to populate the structure swc_hal_t
with BSP functions of the EVK1.4 board. The user needs to create the same functions while using their new BSP implementation instead.
void iface_swc_hal_init(swc_hal_t *hal)
{
hal->radio_hal[0].set_shutdown_pin = evk_radio_set_shutdown_pin;
hal->radio_hal[0].reset_shutdown_pin = evk_radio_reset_shutdown_pin;
hal->radio_hal[0].set_reset_pin = evk_radio_set_reset_pin;
hal->radio_hal[0].reset_reset_pin = evk_radio_reset_reset_pin;
hal->radio_hal[0].read_irq_pin = evk_radio_read_irq_pin;
hal->radio_hal[0].set_cs = evk_radio_spi_set_cs;
hal->radio_hal[0].reset_cs = evk_radio_spi_reset_cs;
hal->radio_hal[0].delay_ms = evk_timer_delay_ms;
hal->radio_hal[0].transfer_full_duplex_blocking = evk_radio_spi_transfer_full_duplex_blocking;
hal->radio_hal[0].transfer_full_duplex_non_blocking = evk_radio_spi_transfer_full_duplex_non_blocking;
hal->radio_hal[0].is_spi_busy = evk_radio_is_spi_busy;
hal->radio_hal[0].context_switch = evk_radio_context_switch;
hal->radio_hal[0].disable_radio_irq = evk_radio_disable_irq_it;
hal->radio_hal[0].enable_radio_irq = evk_radio_enable_irq_it;
hal->radio_hal[0].disable_radio_dma_irq = evk_radio_disable_dma_irq_it;
hal->radio_hal[0].enable_radio_dma_irq = evk_radio_enable_dma_irq_it;
hal->context_switch = evk_radio_callback_context_switch;
hal->get_tick_quarter_ms = evk_timer_get_free_running_tick_ms;
}
Note
The pulsar name is a placeholder name since the EVK1.4 does not support the dual radio.
void iface_swc_hal_init(swc_hal_t *hal)
{
hal->radio_hal[0].set_shutdown_pin = pulsar_radio_1_set_shutdown_pin;
hal->radio_hal[0].reset_shutdown_pin = pulsar_radio_1_reset_shutdown_pin;
hal->radio_hal[0].set_reset_pin = pulsar_radio_1_set_reset_pin;
hal->radio_hal[0].reset_reset_pin = pulsar_radio_1_reset_reset_pin;
hal->radio_hal[0].read_irq_pin = pulsar_radio_1_read_irq_pin;
hal->radio_hal[0].set_cs = pulsar_radio_1_spi_set_cs;
hal->radio_hal[0].reset_cs = pulsar_radio_1_spi_reset_cs;
hal->radio_hal[0].delay_ms = pulsar_timer_delay_ms;
hal->radio_hal[0].transfer_full_duplex_blocking = pulsar_radio_1_spi_transfer_full_duplex_blocking;
hal->radio_hal[0].transfer_full_duplex_non_blocking = pulsar_radio_1_spi_transfer_full_duplex_non_blocking;
hal->radio_hal[0].is_spi_busy = pulsar_radio_1_is_spi_busy;
hal->radio_hal[0].context_switch = pulsar_radio_1_context_switch;
hal->radio_hal[0].disable_radio_irq = pulsar_radio_1_disable_irq_it;
hal->radio_hal[0].enable_radio_irq = pulsar_radio_1_enable_irq_it;
hal->radio_hal[0].disable_radio_dma_irq = pulsar_radio_1_disable_dma_irq_it;
hal->radio_hal[0].enable_radio_dma_irq = pulsar_radio_1_enable_dma_irq_it;
hal->context_switch = pulsar_radio_1_callback_context_switch;
hal->get_tick_quarter_ms = pulsar_timer_get_free_running_tick_ms;
#if (WPS_RADIO_COUNT == 2)
hal->radio_hal[1].set_shutdown_pin = pulsar_radio_2_set_shutdown_pin;
hal->radio_hal[1].reset_shutdown_pin = pulsar_radio_2_reset_shutdown_pin;
hal->radio_hal[1].set_reset_pin = pulsar_radio_2_set_reset_pin;
hal->radio_hal[1].reset_reset_pin = pulsar_radio_2_reset_reset_pin;
hal->radio_hal[1].read_irq_pin = pulsar_radio_2_read_irq_pin;
hal->radio_hal[1].set_cs = pulsar_radio_2_spi_set_cs;
hal->radio_hal[1].reset_cs = pulsar_radio_2_spi_reset_cs;
hal->radio_hal[1].delay_ms = pulsar_timer_delay_ms;
hal->radio_hal[1].transfer_full_duplex_blocking = pulsar_radio_2_spi_transfer_full_duplex_blocking;
hal->radio_hal[1].transfer_full_duplex_non_blocking = pulsar_radio_2_spi_transfer_full_duplex_non_blocking;
hal->radio_hal[1].is_spi_busy = pulsar_radio_2_is_spi_busy;
hal->radio_hal[1].context_switch = pulsar_radio_2_context_switch;
hal->radio_hal[1].disable_radio_irq = pulsar_radio_2_disable_irq_it;
hal->radio_hal[1].enable_radio_irq = pulsar_radio_2_enable_irq_it;
hal->radio_hal[1].disable_radio_dma_irq = pulsar_radio_2_disable_dma_irq_it;
hal->radio_hal[1].enable_radio_dma_irq = pulsar_radio_2_enable_dma_irq_it;
hal->timer_start = pulsar_timer_multi_radio_timer_start;
hal->timer_stop = pulsar_timer_multi_radio_timer_stop;
hal->timer_set_period = pulsar_timer_multi_radio_timer_set_period;
hal->disable_timer_irq = pulsar_timer_multi_radio_timer_disable_irq;
hal->enable_timer_irq = pulsar_timer_multi_radio_timer_enable_irq;
#endif
}
The HAL is pointing to the EVK1.4 hardware BSP which is a great starting point to look into the dependencies and implementation.
The code block below shows the swc_hal_t
structure and its elements that need to be populated by the user.
typedef struct swc_hal {
swc_radio_hal_t radio_hal[WPS_RADIO_COUNT]; /*!< Radio HAL */
void (*context_switch)(void); /*!< Context switch function pointer */
uint64_t (*get_tick_quarter_ms)(void); /*!< Get tick quarter ms function pointer */
#if (WPS_RADIO_COUNT == 2)
void (*timer_start)(void); /*!< Radio timer start interface. */
void (*timer_stop)(void); /*!< Radio timer stop interface. */
void (*timer_set_period)(uint16_t period); /*!< Radio timer set period interface. */
void (*disable_timer_irq)(void); /*!< Disable Multi radio interrupt source */
void (*enable_timer_irq)(void); /*!< Enable Multi radio interrupt source */
#endif
} swc_hal_t;
See child elements in details
Step 2. Provide Callback Function Setters¶
Additionally to the swc_hal_t structure, the user must provide callback setters to run some part of the Wireless Core code when specific IRQ events are triggered. The user needs to create the same functions and adapt them to the user hardware BSP.
Step 3. Provide Enter/Exit Critical Section Functions¶
The Wireless Core uses the lib/spark/queue library which has some dependencies that need to be satisfied. This queue library needs a mean to enter and exit critical sections.