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

spi fails after removing print statements

So i am utilizing SPI and i got it to work, however for some absurd reason after removing the segger_print statement below from before the while loop the spi would stop functioning. otherwise it works perfectly fine. Any idea why a print statement would cause this? do i need to add a delay? Although i would expect the while loop to handle any delay necessary.

uint32_t LCD_SPI_Write_Command (uint8_t command)
{
	spi_lcd_xfer_done = false;
	LCD_CSX_LOW(); //	set CSX to low to activate LCD listening
	LCD_DCX_LOW(); // indicate command
	uint32_t err_code = nrf_drv_spi_transfer(&m_spi_LCD, &command, 1, NULL, 0);
	if (err_code != NRF_SUCCESS) {
		SEGGER_RTT_printf(0, "[ERROR] on command transfer :%d \n", err_code);
	}
		SEGGER_RTT_printf(0,"Im writing a command! \n");

	while (!spi_lcd_xfer_done)
	  {
	  }
	return err_code;
}
Parents Reply Children
  • it is set in true as follows, but not volatile just to be clear everything is working in code above. however it stops working when the the SEGGER_RTT line which prints "Im writing a command" is commented out/deleted

    static bool spi_lcd_xfer_done = false;
    
    /**
     * @brief SPI user event handler.
     * @param event
     */
    void spi_lcd_event_handler(nrf_drv_spi_evt_t const * p_event)
    {
    	spi_lcd_xfer_done = true;
    	switch(p_event->type)
    		{
    		case NRF_DRV_SPI_EVENT_DONE:
    		    printf(" Transfer completed.\r\n");
    			break;
    		default:
    			break;
    		}
    }
    
  • Okay, but it looks like compiler placed code in other registers/memory. Try to change:

    static bool spi_lcd_xfer_done = false;
    

    to:

    static volatile bool spi_lcd_xfer_done = false;
    

    It should prevent compiler from code optimization with this variable so its address and access should be now the same in every place in code.

    You can also try to implement state machine to send data to the LCD to prevent creating additional variable and putting while loop. Unfortunately while loop is not energy efficient.

    Try to do it this way:

    send command (from main thread/context) and wait to irq -> in irq set data and start sending -> wait until next irq -> in next irq send next data but remember that access from many context requires mutexes/critical section and other similar things.

    greetings!

Related