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