spim task does not work on nrf5340 dk using nrfx spim driver

Hi everyone,

I'm trying to interface the nrf5340 with the intan chip rhd2132, that allows to record signals. I can read successfuly the registers, but when I try the recording task, It does not work. I'm using the PPI module to handle the spim. 

void ppi_configuration()
{
	nrfx_err_t err_code;
	uint8_t ppi_channel1,ppi_channel2; // ppi_channel3;

	err_code = nrfx_gppi_channel_alloc(&ppi_channel1);
    if (err_code != NRFX_SUCCESS)
    {
        printk("PPI channel allocation error for channel 1");
    }

    err_code = nrfx_gppi_channel_alloc(&ppi_channel2);
    if (err_code != NRFX_SUCCESS)
    {
        //printk("PPI channel allocation error for channel 2");
    }

   	// err_code = nrfx_gppi_channel_alloc(&ppi_channel3);
    // if (err_code != NRFX_SUCCESS)
    // {
    //     printk("PPI channel allocation error for channel 3");
    // }
	
    uint32_t timer_event_addr = nrfx_timer_compare_event_address_get(&timer, NRF_TIMER_CC_CHANNEL0);
    spim_start_task_addr = nrf_spim_task_address_get(spim_inst.p_reg, NRF_SPIM_TASK_START);

	nrfx_gppi_channel_endpoints_setup(ppi_channel1, timer_event_addr, spim_start_task_addr);

	spim_end_event_addr = nrf_spim_event_address_get(spim_inst.p_reg, NRF_SPIM_EVENT_END);
	uint32_t counter_task_addr = nrfx_timer_task_address_get(&counter, NRF_TIMER_TASK_COUNT);

	nrfx_gppi_fork_endpoint_setup(ppi_channel1, counter_task_addr);

	uint32_t counter_event_addr = nrfx_timer_compare_event_address_get(&counter, NRF_TIMER_CC_CHANNEL4);
	uint32_t counter_seq_task_addr = nrfx_timer_task_address_get(&counter_seq, NRF_TIMER_TASK_COUNT);

	nrfx_gppi_channel_endpoints_setup(ppi_channel2, counter_event_addr, counter_seq_task_addr);

	nrfx_gppi_channels_enable(1 << ppi_channel1 | 1 << ppi_channel2); // | 1 << ppi_channel3); AL MOMENTO IL CANALE 3 non è abilitato
}
This is the spim initialization
void spim_initialization(void)  
{	
	nrfx_spim_config_t spim_config = NRFX_SPIM_DEFAULT_CONFIG(SCK_PIN,
								  MOSI_PIN,
								  MISO_PIN,
								  CS1_PIN);
	spim_config.ss_active_high = false,                                                                     
    spim_config.irq_priority   = 0,                                     
    spim_config.orc            = 0xFF,                                                                      
    spim_config.frequency      = NRFX_MHZ_TO_HZ(16),                                                         
    spim_config.mode           = NRF_SPIM_MODE_0,                                                           
    spim_config.bit_order      = NRF_SPIM_BIT_ORDER_MSB_FIRST,                                              
    spim_config.miso_pull      = NRF_GPIO_PIN_NOPULL,    
	NRFX_COND_CODE_1(NRFX_SPIM_EXTENDED_ENABLED, (spim_config.use_hw_ss = true; spim_config.ss_duration = 0x04;), ()); //prova con 0x00

	nrfx_err_t status = nrfx_spim_init(&spim_inst, &spim_config, NULL, NULL);
	//nrfx_err_t status = nrfx_spim_init(&spim_inst, &spim_config, spim_event_handler, NULL);
	if (status != NRFX_SUCCESS) 
	{
		//printk("SPI initialization failed with error code: %d\n", status);
		//return 0;
	}
	else
	{
		//return 1;
	}
}
This part handles the spim through the nrfx spim flags:
void spim_convert_trx_setup()    // NEW VERSION 
{
	spim_inst.p_reg->TXD.PTR = (uint32_t)convert_commands[0];
	spim_inst.p_reg->RXD.PTR = (uint32_t)spim_trx_result_conv[0];
	spim_inst.p_reg->TXD.LIST = 1;
	spim_inst.p_reg->RXD.LIST = 1;
	spim_inst.p_reg->TXD.MAXCNT = 2;  // we want to transfer 2 bytes for each trx
	spim_inst.p_reg->RXD.MAXCNT = 2; // we want to receive 2 bytes for each trx

	nrfx_spim_xfer_desc_t xfer_desc = NRFX_SPIM_XFER_TRX(convert_commands[0], 2, spim_trx_result_conv[0], 2);
	uint32_t spim_flags = NRFX_SPIM_FLAG_TX_POSTINC | NRFX_SPIM_FLAG_RX_POSTINC | NRFX_SPIM_FLAG_NO_XFER_EVT_HANDLER | NRFX_SPIM_FLAG_REPEATED_XFER | NRFX_SPIM_FLAG_HOLD_XFER;
	nrfx_spim_xfer(&spim_inst, &xfer_desc, spim_flags);
	

	//printk("spim_convert_trx_setup.\n");
}
Do you have any suggestion? Thanks

Parents
  • Hi,

    Can you elaborate more about in what way it does not work and what you have found from testing/debugging?

  • My aim is to send CONVERT commands in this way:

    1. Each time the timer expires, one CONVERT command is sent (from the array uint8_t convert_commands[N][2]) and the first counter is incremented.

    2. When the first counter reaches N, this happens: 

    void counter_handler(nrf_timer_event_t event_type, void *p_context)
    {
    	spim_inst.p_reg->TXD.PTR = (uint32_t)convert_commands[0];  // si sposta l'indice dell'array dei convert commands a 0
    
    	k_sem_give(&file_write_sem);
    }
    and I read the responses of the convert command (uint8_t spim_trx_result_conv[2N][2]) via UART (I read half buffer). Here the second counter is incremented.

    3. When the second counter reaches M: 

    void counter_seq_handler(nrf_timer_event_t event_type, void *p_context)
    {
    	spim_inst.p_reg->RXD.PTR = (uint32_t)spim_trx_result_conv[0];  // si sposta l'indice dell'array dei risultati dei convert commands a 0
    
    }
    The idea is to send one CONVERT command each time the timer expires and counter++, since we are doing spim trx, we are filling spim_trx_result_conv and once we reache counter==N, half buffer will be filled and transferred via UART. In the meantime the timer keeps expiring, the CONVERT commands are sent but this time the second half of spim_trx_result_conv will be filled and then sent via UART. 

    I have checked convert_commands and it is ok, it contains what I want, but spim_trx_result_conv contains always 0. 

    Chip select is handles via hardware, I'm using spim4.

    Thanks in advance

Reply
  • My aim is to send CONVERT commands in this way:

    1. Each time the timer expires, one CONVERT command is sent (from the array uint8_t convert_commands[N][2]) and the first counter is incremented.

    2. When the first counter reaches N, this happens: 

    void counter_handler(nrf_timer_event_t event_type, void *p_context)
    {
    	spim_inst.p_reg->TXD.PTR = (uint32_t)convert_commands[0];  // si sposta l'indice dell'array dei convert commands a 0
    
    	k_sem_give(&file_write_sem);
    }
    and I read the responses of the convert command (uint8_t spim_trx_result_conv[2N][2]) via UART (I read half buffer). Here the second counter is incremented.

    3. When the second counter reaches M: 

    void counter_seq_handler(nrf_timer_event_t event_type, void *p_context)
    {
    	spim_inst.p_reg->RXD.PTR = (uint32_t)spim_trx_result_conv[0];  // si sposta l'indice dell'array dei risultati dei convert commands a 0
    
    }
    The idea is to send one CONVERT command each time the timer expires and counter++, since we are doing spim trx, we are filling spim_trx_result_conv and once we reache counter==N, half buffer will be filled and transferred via UART. In the meantime the timer keeps expiring, the CONVERT commands are sent but this time the second half of spim_trx_result_conv will be filled and then sent via UART. 

    I have checked convert_commands and it is ok, it contains what I want, but spim_trx_result_conv contains always 0. 

    Chip select is handles via hardware, I'm using spim4.

    Thanks in advance

Children
  • Hi,

    I notice a few things. Firstly her:

    	spim_inst.p_reg->TXD.PTR = (uint32_t)convert_commands[0];
    	spim_inst.p_reg->RXD.PTR = (uint32_t)spim_trx_result_conv[0];

    Does convert_commands and spim_trx_result_conv contain pointers to buffers and you want the buffers pointed to in index 0? Or is it normal one dimensional buffers? If so, you must remove the "[0]" part.

    I also see that there is no error handling, and all return values are returned. I would make sure to always check all return codes in case some errors are detected but you do not notice. This can typically save a lot of time debugging.

    Lastly, it is a bit difficult for me to follow what is going on. I suggest adding some logging which will hopefully make things clearer.

Related