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

SPI Prbolem , Clock dosen't work

Why the SPI clk doesn't work, i checked using an oscilloscope :/ I also don't get any SPI interrupt and no data change in the RX buffer although I have wired MISO and MOSI

void vSensor_eInitSensor_Exe()
{
   /*Config SPI PINs*/
	  nrf_gpio_pin_set(SCLK_PIN); /*Initial state of CLK is High*/

      NRF_GPIO->PIN_CNF[SCLK_PIN] =
    (GPIO_PIN_CNF_DIR_Output        << GPIO_PIN_CNF_DIR_Pos)
  | (GPIO_PIN_CNF_INPUT_Connect     << GPIO_PIN_CNF_INPUT_Pos)
  | (GPIO_PIN_CNF_PULL_Disabled     << GPIO_PIN_CNF_PULL_Pos)
  | (GPIO_PIN_CNF_DRIVE_S0S1        << GPIO_PIN_CNF_DRIVE_Pos)
  | (GPIO_PIN_CNF_SENSE_Disabled    << GPIO_PIN_CNF_SENSE_Pos);
  // - MOSI (optional) - output with initial value 0,
      nrf_gpio_pin_clear(MOSI_PIN);
    nrf_gpio_cfg_output(MOSI_PIN);
  /* - MISO (mandatory) - input*/
  nrf_gpio_cfg_input(MISO_PIN, NRF_GPIO_PIN_NOPULL);
  /*Init SPI*/
  nrf_spim_pins_set(&stSPI_iNRF_SPI_Type,(uint32_t )SCLK_PIN, MOSI_PIN,(uint32_t )MISO_PIN);
  nrf_spim_frequency_set(&stSPI_iNRF_SPI_Type,NRF_SPIM_FREQ_125K);
  nrf_spim_configure(&stSPI_iNRF_SPI_Type,NRF_SPIM_MODE_0,CstSPI_iNrfSpiBitOrder);
  nrf_spim_rx_buffer_set(&stSPI_iNRF_SPI_Type,ui8RxBuffer,SPI_RX_BYTES_NB);
  nrf_spim_tx_buffer_set(&stSPI_iNRF_SPI_Type,ui8TxBuffer/*NULL*/,SPI_RX_BYTES_NB);
  nrf_spim_int_enable(&stSPI_iNRF_SPI_Type,NRF_SPIM_INT_STOPPED_MASK|NRF_SPIM_INT_ENDRX_MASK|NRF_SPIM_INT_STARTED_MASK); /*get events when RX done*/
  nrf_spim_enable(&stSPI_iNRF_SPI_Type);
  nrf_drv_common_irq_enable(SPIM_IRQ ,SPIM_CONFIG_IRQ_PRIORITY); /*enable SPI0 interrupt */
	stSPI_iNRF_SPI_Type.POWER=1;
 /*Create Periodic task for reading*/ 
  vSensor_iCreateReadingTask_Exe();
}

Here is the periodic task of reading

static void vSensor_iPeriodicReadHandler_Exe(void * p_context)
{
	 if(false==nrf_drv_gpiote_in_is_set(MISO_PIN))
	 { 
		 /*Clear interrupt flags & Lunch read transaction*/
		 nrf_spim_event_clear(&stSPI_iNRF_SPI_Type,NRF_SPIM_EVENT_ENDRX);
		 nrf_spim_task_trigger(&stSPI_iNRF_SPI_Type,NRF_SPIM_TASK_START);
		 app_timer_start(m_conversion_read_timer_id, PERIODIC_READING_INTERVAL, NULL);
	 }
	 else
	 {
		 /*empty else*/
	 }
	 
}
  • Does it work if you comment out the int enable line?:

    //nrf_spim_int_enable(&stSPI_iNRF_SPI_Type, ...);
    

    In that case have you written the SPIM irq handler or do you use the one in the SDK? Using the one in the SDK will probably cause troubles.

  • Look waht I did : I am using the ble_app_hrs and I want to integrate SPI part. I took it from the project SPI in the examples. I just did my driver layer,, what I attached in the question it dosen't work. Now I used the driver elaborated by Nordic but dosen't work and I discovered that is related to bsp_btn config. I deleted this function and it works :

    //    bsp_btn_ble_on_ble_evt(p_ble_evt);
    

    Now after i discovered the source of the problem , I take back my driver layer,, which is the code i attached in the question and it dosen't work :/

  • yeah I defined my intrrupt handler, and it dosen(t work, as there is no CLK working already, so no interrupt.

    #define SPIM_IRQ                    SPI0_TWI0_IRQn
    #define SPI0_TWI0_IRQHandler        vSensor_iSPI0_TWI0_IRQHandler_Exe
    #define SPIM_CONFIG_IRQ_PRIORITY    APP_IRQ_PRIORITY_LOW
    
        void vSensor_iSPI0_TWI0_IRQHandler_Exe(void) 
    {
    	 ui8RXCounter++;
    	 /*Cehck End sending Flag*/
    	 if(true==nrf_spim_event_check(&stSPI_iNRF_SPI_Type,NRF_SPIM_EVENT_ENDRX))
    	 {
    		 ui8RXCounter++;
    	 }
    	 
    	 else
    	 {
    		 /*empty else*/
    	 }
    	 
    	 if(3==ui8RXCounter)
    	 {
    		 /*3 bytes are read*/
    		 //ui8RXCounter=0;
    		 /*Extarct data & check status bytes*/
    		 if(0x01==((ui8RxBuffer[SPI_RX_BYTES_NB-1]&AD7780_STAT_PAT0)|(ui8RxBuffer[SPI_RX_BYTES_NB-1]&AD7780_STAT_PAT1)))
    		 {
    			  /*Serial transfer was correctly performed ==> push in the FIFO*/
    		 
    					uint8_t tmpPtr = 0;
    				  tmpPtr = ucPushPtr + 1;
    					if(tmpPtr >= DfMaxBufferSize) tmpPtr = 0;
    					if(tmpPtr != ucPopPtr)
    						{
    							fMeasureVlaues[ucPushPtr] = (uint32_t )(fSensor_iConvertToVolatage_Exe(ulSensor_iAdcMeasure_Get(ui8RxBuffer))) ;
    							ucPushPtr = tmpPtr;
    						}
    		 }
    		 else
    		 {
    			 /*empty else*/
    		 }
    	 }
    	 else
    	 {
    		  /*empty else*/
    	 }
    }
    

    the content of the handler not really done well,, i am still fixing it, but it never enter to it already,,i am doing that counter ui8RXCounter and it is also 0

  • I commented the line : //nrf_spim_int_enable(&stSPI_iNRF_SPI_Type, ...); it dosen't work :/

  • I tested your code and got it to work when I commented out //nrf_spim_int_enable(&stSPI_iNRF_SPI_Type, ...);. I used the SPI example in the SDK as a base (with the interrupt handler from the SPI driver). You should try to only run the SPI code to see if it works without the BLE stuff.

    Also, in the interrupt handler you have to clear the event that triggered the interrupt:

    if (nrf_spim_event_check(p_spim, NRF_SPIM_EVENT_END))
    {
        nrf_spim_event_clear(p_spim, NRF_SPIM_EVENT_END);
    }
    

    Or else you will not get any more interrupts.

Related