Hi,
I'm trying to make the softdevice controller work on NuttX RTOS. I followed the SDK example code to reproduce initialization. All calls are returning 0 (no error). However, once I send the first HCI command (a controller RESET) I don't receive SWI interrupt which would lead to signaling for available HCI EVT. If I call sdc_hci_evt_get() on my own, it returns 0 (indicating available EVT), so I think the SWI signaling is not working. I'm also not receiving any other interrupts configured (for RTC, TIMER, RADIO, etc). If I monitor peripheral registers after initialization calls, I also don't see any registers related to peripheral interrupt change. I also verified that if I manually pend the chosen SWI line I get to the appropriate ISR. I'm not sure if I should be doing something else besides these initialization calls (do I need to enable events for each peripheral?). The relevant code is as follows:
int nrf52_sdc_initialize(void)
{
int ret;
int32_t required_memory;
sdc_cfg_t cfg;
/* Initialize device data */
memset(&g_sdc_dev, 0, sizeof(g_sdc_dev));
nxsem_init(&g_sdc_dev.exclsem, 0, 1);
/* Register interrupt handler for normal-priority events */
irq_attach(NRF52_IRQ_SWI5_EGU5, swi_isr, NULL);
irq_attach(NRF52_IRQ_POWER_CLOCK, power_clock_isr, NULL);
irq_attach(NRF52_IRQ_RNG, rng_isr, NULL);
up_enable_irq(NRF52_IRQ_SWI5_EGU5);
up_enable_irq(NRF52_IRQ_POWER_CLOCK);
up_enable_irq(NRF52_IRQ_RNG);
up_prioritize_irq(NRF52_IRQ_SWI5_EGU5, NVIC_SYSH_PRIORITY_DEFAULT);
up_prioritize_irq(NRF52_IRQ_POWER_CLOCK, NVIC_SYSH_PRIORITY_DEFAULT);
up_prioritize_irq(NRF52_IRQ_RNG, NVIC_SYSH_PRIORITY_DEFAULT);
// TODO: RNG handler should be called with normal priority but without
// added processing, is it OK to use NuttX forwarding then?
// Otherwise, is it OK to do as below but use normal priority?
/* TODO: how do WFI again after high priority interrupt wakes MCU up? */
/* Register high-priority interrupts for specific peripherals */
arm_ramvec_attach(NRF52_IRQ_RTC0, rtc0_handler);
arm_ramvec_attach(NRF52_IRQ_TIMER0, timer0_handler);
arm_ramvec_attach(NRF52_IRQ_RADIO, radio_handler);
up_prioritize_irq(NRF52_IRQ_RTC0, MPSL_HIGH_IRQ_PRIORITY);
up_prioritize_irq(NRF52_IRQ_TIMER0, MPSL_HIGH_IRQ_PRIORITY);
up_prioritize_irq(NRF52_IRQ_RADIO, MPSL_HIGH_IRQ_PRIORITY);
up_enable_irq(NRF52_IRQ_RTC0);
up_enable_irq(NRF52_IRQ_TIMER0);
up_enable_irq(NRF52_IRQ_RADIO);
/* Initialize MPSL */
ret = mpsl_init(&g_clock_config, SWI5_EGU5_IRQn, &mpsl_assert_handler);
if (ret < 0)
{
wlerr("mpsl init failed: %d\n", ret);
return ret;
}
/* Initialize SDC */
ret = sdc_init(&sdc_fault_handler);
if (ret < 0)
{
wlerr("mpsl init failed: %d\n", ret);
return ret;
}
cfg.master_count.count = SDC_MASTER_COUNT;
ret = sdc_cfg_set(SDC_DEFAULT_RESOURCE_CFG_TAG,
SDC_CFG_TYPE_MASTER_COUNT, &cfg);
if (ret < 0)
{
wlerr("Failed to set master role count: %d\n", ret);
return ret;
}
cfg.slave_count.count = CONFIG_NRF52_SDC_SLAVE_COUNT;
ret = sdc_cfg_set(SDC_DEFAULT_RESOURCE_CFG_TAG,
SDC_CFG_TYPE_SLAVE_COUNT, &cfg);
if (ret < 0)
{
wlerr("Failed to set slave role count: %d\n", ret);
return ret;
}
cfg.buffer_cfg.rx_packet_size = SDC_DEFAULT_RX_PACKET_SIZE;
cfg.buffer_cfg.tx_packet_size = SDC_DEFAULT_TX_PACKET_SIZE;
cfg.buffer_cfg.rx_packet_count = SDC_DEFAULT_RX_PACKET_COUNT;
cfg.buffer_cfg.tx_packet_count = SDC_DEFAULT_TX_PACKET_COUNT;
required_memory =
sdc_cfg_set(SDC_DEFAULT_RESOURCE_CFG_TAG,
SDC_CFG_TYPE_BUFFER_CFG, &cfg);
if (required_memory < 0)
{
wlerr("Failed to set packet size/count: %ld\n", required_memory);
return ret;
}
ASSERT(required_memory <= sizeof(g_sdc_dev.mempool));
/* Turn on specific features */
#ifdef CONFIG_NRF52_SDC_ADVERTISING
ret = sdc_support_adv();
if (ret < 0)
{
wlerr("Could not enable advertising feature: %d\n", ret);
return ret;
}
#endif
#ifdef CONFIG_NRF52_SDC_SCANNING
ret = sdc_support_scan();
if (ret < 0)
{
wlerr("Could not enable scanning feature: %d\n", ret);
return ret;
}
#endif
#ifdef CONFIG_NRF52_SDC_CONNECTION
ret = sdc_support_master();
if (ret < 0)
{
wlerr("Could not enable master feature: %d\n", ret);
return ret;
}
#endif
#if CONFIG_NRF52_SDC_SLAVE_COUNT > 0
ret = sdc_support_slave();
if (ret < 0)
{
wlerr("Could not enable slave feature: %d\n", ret);
return ret;
}
#endif
ret = sdc_enable(sdc_hci_signal, g_sdc_dev.mempool);
if (ret < 0)
{
wlerr("SoftDevice controller enable failed: %d\n", ret);
return ret;
}
/* Register network device */
ret = bt_netdev_register(&g_bt_driver);
return ret;
}
Thank you,
Matias