This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

nRF52840 USB HID with simultaneous SPIM transfer

Hello,

I use SDK15.2, SES4.12 and custom board with nRF52840.

I have a strip of ws2812b LED's connected to my device. I've made a simple RGB animation, each frame of which is transferred via SPIM. It works fine.

Now I need to add some USB HID functionality. I have simple custom descriptor with one output report. And it works fine too, if there is no SPIM transfer.

When I try to run both SPIM and USB, my code breaks somewhere with no call stack available. If I manually break the execution, it breaks on line 72 in ses_startup_nrf52840.s file, here is a snippet from there:

  .thumb_func
  .weak   HardFault_Handler
HardFault_Handler:
  b     .

Here is my main

int main(void)
{ 
    nrf_gpio_cfg_output( LOGO );
    
	Logo_Initialize(LOGO);

	init_hid();
    
	RGB_Refresh();

    while (true)
    {
		while (app_usbd_event_queue_process())
        {
            /* Nothing to do */
        }
        /* Sleep CPU only if there was no interrupt since last loop processing */
        __WFE();
    }
}

SPIM part:

void spim_event_handler(nrfx_spim_evt_t const * p_event, void * p_context)
{
    NRF_LOG_INFO("Transfer completed.");
	
	nrf_delay_ms(10);
	RGB_Refresh();  
}

void Logo_Initialize(uint8_t logo_pin)
{
	uint8_t m_rx_buf[DATA_LENGTH];
	
	nrfx_spim_xfer_desc_t xfer_desc = NRFX_SPIM_XFER_TRX(m_tx_buf, DATA_LENGTH, m_rx_buf, DATA_LENGTH);

    nrfx_spim_config_t spi_config = NRFX_SPIM_DEFAULT_CONFIG;
    spi_config.frequency = NRF_SPIM_FREQ_4M;
    spi_config.mosi_pin = logo_pin;
    spi_config.use_hw_ss = true;
    spi_config.ss_active_high = false;
    APP_ERROR_CHECK(nrfx_spim_init(&spi, &spi_config, spim_event_handler, NULL));

	transfer_descriptor = &xfer_desc;

    NRF_LOG_INFO("NRFX SPIM example started.");

    bitmanio_init_array8(&bio_arr, m_tx_buf, CODED_BYTES_PER_RGB_BYTE);

//animation array initialization here
}

void RGB_Refresh()
{
//get next frame here

	APP_ERROR_CHECK(nrfx_spim_xfer_dcx(&spi, transfer_descriptor, 0, 15));
}

Basically now I can have either RGB_Refresh() call or app_usbd_event_queue_process() call in my main function, but not both.

Parents Reply Children
Related