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

Spi interface problem

Hi,

I am using customized nrf52 board with softdevice s132

I am trying to interface External Flash (MX25L64) using spi.so when ever i am trying to send any command /data to external flash i am getting only zero in the receiving buffer or else other values.

I have interfaced the same application code for writing/reading/sending command to External Flash  with STM32 board and it worked fine because i wanted to check is there any hardware issue with my external Flash or not.But when i am trying with nordic it is showing some different behavior.

The complete code is same only the difference is transferring call for Stm32 and nordic

i have used their call for 1 byte transferring and our spi transferring call in my case i.e

err_code = nrf_drv_spi_transfer(&spi, &Byte, 2, pData, 2);
    APP_ERROR_CHECK(err_code);

here it returned err_code as Zero every time when it comes to this call,which means it returned NRF_SUCCESS.

instead of sending and receiving two bytes,if i go with 1 byte it is giving showing different behavior.

i don't understand where i am making mistake.so please help me regarding this issue as soon as possible.

i am sending u the log statements and my code,so that problem can be easily found.

thank you.

code:

#define SPI_INSTANCE  2
static const nrf_drv_spi_t spi = NRF_DRV_SPI_INSTANCE(SPI_INSTANCE);  /**< SPI instance. */
static volatile bool spi_xfer_done; 
uint8_t  Rxbuff[100];




void Mx25L64_Init()
{
	printf("Spi...Init....\r\n");
	Spi_Init();

	FLASH_IO_CS_High();
}


uint32_t Mx25L64_ReadID()
{

	uint32_t  Temp = 0, Temp0 = 0, Temp1 = 0, Temp2 = 0;
	
	/* Select the FLASH: Chip Select low */
	FLASH_IO_CS_Low();
	/* Send "RDID " instruction */
	Temp=FLASH_IO_WriteByte(0x9F);
	
	/* Read a byte from the FLASH */
	Temp0 = FLASH_IO_WriteByte(0);
	
	/* Read a byte from the FLASH */
	Temp1 = FLASH_IO_WriteByte(0);
	
	/* Read a byte from the FLASH */
	Temp2 = FLASH_IO_WriteByte(0);
	
	printf("Temp = %d Temp0 = %d Temp1 =%d Temp2 = %d\r\n",Temp,Temp0,Temp1,Temp2);
	/* Deselect the FLASH: Chip Select high */
	FLASH_IO_CS_High();
	
	Temp = (Temp0 << 16) | (Temp1 << 8) | Temp2;
	
	return Temp;	
}	
	
/*==================================================================
Write 1 byte to flash memory
WARNING: you can only write to previously erased memory locations (see datasheet)
         use the block erase commands to first clear memory (write 0xFFs)
==================================================================*/

void Mx25L64_BYTE_Write( uint8_t  byt,uint32_t addr)   
{	
	printf("\n\rbyte write done beginning \r\n");
	FLASH_IO_CS_Low();
	FLASH_IO_WriteByte(SPIFLASH_WRITEENABLE);
	FLASH_IO_CS_High();

//	while(Mx25L64_readStatus()!=0x02)
//	{
//		nrf_delay_ms(1000);
//		printf("\n\rNot in write enable Wait\r\n");
//	}
		
	FLASH_IO_CS_Low();
	FLASH_IO_WriteByte(SPIFLASH_BYTEPAGEPROGRAM);
	FLASH_IO_WriteByte(addr>>16);
	FLASH_IO_WriteByte(addr>>8);
	FLASH_IO_WriteByte(addr);
	FLASH_IO_WriteByte(byt);
	FLASH_IO_CS_High();
	printf("\n\rbyte write done end\r\n");
	
	}
/*==================================================================
// read 1 byte from flash memory
==================================================================*/
uint8_t Mx25L64_BYTE_Read(uint32_t addr) 
{
	
	uint8_t *RxBuffer;
	FLASH_IO_CS_Low();
	FLASH_IO_WriteByte(SPIFLASH_READ);
	FLASH_IO_WriteByte(addr>>16);
	FLASH_IO_WriteByte(addr>>8);
	FLASH_IO_WriteByte(addr);
	RxBuffer=FLASH_IO_WriteReadByte(0,1);
	uint8_t result=RxBuffer[0];
	printf("\n\r%x%x%x%x\r\n",RxBuffer[0],RxBuffer[1],RxBuffer[2],RxBuffer[3]);
	FLASH_IO_CS_High();
	return result;
}


/**
 * @brief SPI user event handler.
 * @param event
 */
void spi_event_handler(nrf_drv_spi_evt_t const * p_event,
                       void *                    p_context)
{
    spi_xfer_done = true;

}


void Spi_Init(void)
{
	 ret_code_t err_code;
	  nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG;
    spi_config.ss_pin   = SPI_SS_PIN;
    spi_config.miso_pin = SPI_MISO_PIN;
    spi_config.mosi_pin = SPI_MOSI_PIN;
    spi_config.sck_pin  = SPI_SCK_PIN;
    err_code = nrf_drv_spi_init(&spi, &spi_config, spi_event_handler, NULL);
    APP_ERROR_CHECK(err_code);
    printf("\n\rSPI example started.  = %d \n",err_code);
	
}

/**
  * @brief  Sends a Byte through the SPI interface & CHECK RESPONSE
  * @param  Byte : Byte send.
  */
uint8_t SPIx_WriteRead(const nrf_drv_spi_t spi,uint8_t Byte)
{   
	  ret_code_t err_code;
	  uint8_t pData[4];
    spi_xfer_done = false;
    /* Send a Byte through the SPI peripheral */
	/* Read byte from the SPI bus */
    err_code = nrf_drv_spi_transfer(&spi, &Byte, 2, pData, 2);
    APP_ERROR_CHECK(err_code);
	
	      while(!spi_xfer_done)
        {
            __WFE();
        }
	  printf("\n\rByte = %d and SPI_WRITE_READ  = %d == %d === %d ==== %d err_code = %d\r\n",Byte,pData[0],pData[1],pData[2],pData[3],err_code);
	    
	return pData[2];

}


/**
  * @brief SPI Flash CS High
  * @param 
  * @retval
  */
void FLASH_IO_CS_High()
{
	nrf_gpio_pin_set(SPI_SS_PIN);
}


/**
  * @brief SPI Flash CS low
  * @param 
  * @retval 
  */
void FLASH_IO_CS_Low()
{
  nrf_gpio_pin_clear(SPI_SS_PIN);
	
}


/**
  * @brief write data to flash 
  * @param TxData: Data to transfer
  * @retval Retur data
  */
uint8_t FLASH_IO_WriteByte(uint8_t TxData)
{
	return SPIx_WriteRead(spi ,TxData);
}


/**
  * @brief write data to flash 
  * @param TxData: Data to transfer
  * @retval Retur data
  */

uint8_t* FLASH_IO_WriteReadByte(uint8_t data,uint8_t len)
{
    ret_code_t err_code;
    err_code = nrf_drv_spi_transfer(&spi, &data, len, Rxbuff, len);
    APP_ERROR_CHECK(err_code);
	  return Rxbuff;
}


int main(void)
{
	/* timer initialisation */
	timer_init();
	/* all ble profiles init */
	aqua_all_fun_init();
	/* uart init */
	uart_init();
	/* 7 seg Display init */
	display_init();
	/* transmitter power set to +4db and role set to conn */
	sd_ble_gap_tx_power_set(2,1,+4);

	
	/* 7 segment display current firware ver */
	display_int(farmware_ver,0);
	nrf_delay_ms(5000);
	display_int(0,0); 
	
	initialize_motor_app();		
	nrf_gpio_pin_set(LED_1);
	nrf_gpio_pin_set(LED_2);
	nrf_gpio_pin_set(LED_3);
	nrf_gpio_cfg_output(SPI_SS_PIN);
   
     Mx25L64_Init();
	 uint32_t Id = Mx25L64_ReadID();
	 printf("Id = %d \r\n",Id);
	 Mx25L64_BYTE_Write(5,1);
	 Id = Mx25L64_BYTE_Read(1);
	 printf("Mx25L64_BYTE_Read = %d \r\n",Id);

	/* Enter main loop. */
	for (;;)
	{


	}
}

/* i have send u the function calls and the operations inside those functions */

log statements by using nordic spi interface :

Spi...Init....

SPI example started.  = 0 

Byte = 159 and SPI_WRITE_READ  = 0 == 194 === 0 ==== 0 err_code = 0

Byte = 0 and SPI_WRITE_READ  = 0 == 0 === 0 ==== 0 err_code = 0

Byte = 0 and SPI_WRITE_READ  = 0 == 0 === 0 ==== 0 err_code = 0

Byte = 0 and SPI_WRITE_READ  = 0 == 0 === 0 ==== 0 err_code = 0
Temp = 0 Temp0 = 0 Temp1 =0 Temp2 = 0
Id = 0 

byte write done beginning 

Byte = 6 and SPI_WRITE_READ  = 0 == 0 === 2 ==== 0 err_code = 0

Byte = 2 and SPI_WRITE_READ  = 0 == 0 === 2 ==== 0 err_code = 0

Byte = 0 and SPI_WRITE_READ  = 0 == 0 === 2 ==== 0 err_code = 0

Byte = 0 and SPI_WRITE_READ  = 0 == 0 === 2 ==== 0 err_code = 0

Byte = 1 and SPI_WRITE_READ  = 0 == 0 === 2 ==== 0 err_code = 0

Byte = 5 and SPI_WRITE_READ  = 0 == 0 === 2 ==== 0 err_code = 0

byte write done end

Byte = 3 and SPI_WRITE_READ  = 0 == 0 === 0 ==== 0 err_code = 0

Byte = 0 and SPI_WRITE_READ  = 0 == 0 === 0 ==== 0 err_code = 0

Byte = 0 and SPI_WRITE_READ  = 0 == 0 === 0 ==== 0 err_code = 0

Byte = 1 and SPI_WRITE_READ  = 0 == 0 === 0 ==== 0 err_code = 0

0000
Mx25L64_BYTE_Read = 0

and i am also sending u the log statements of stm32 spi interface:

***spi initilization***
Byte  = 159   and pData = 255  = 0  = 0  = 0
Byte  = 0   and pData = 194    = 0  = 0  = 0
Byte  = 0   and pData = 32     = 0  = 0  = 0
Byte  = 0   and pData = 23     = 0  = 0  = 0
Id = 12722199 
Byte  = 6   and pData = 255    = 0  = 0  = 0
Byte  = 5   and pData = 255    = 0  = 0  = 0
Byte  = 0   and pData = 2      = 0  = 0  = 0
Byte  = 0   and pData = 2      = 0  = 0  = 0
Byte  = 0   and pData = 2      = 0  = 0  = 0
Byte  = 2   and pData = 255    = 0  = 0  = 0
Byte  = 0   and pData = 255    = 0  = 0  = 0
Byte  = 0   and pData = 255    = 0  = 0  = 0
Byte  = 1   and pData = 255    = 0  = 0  = 0
Byte  = 4   and pData = 255    = 0  = 0  = 0
Byte  = 3   and pData = 255    = 0  = 0  = 0
Byte  = 0   and pData = 255    = 0  = 0  = 0
Byte  = 0   and pData = 255    = 0  = 0  = 0
Byte  = 1   and pData = 255    = 0  = 0  = 0

4000
Mx25L64_BYTE_Read = 4 

  • Manually controlling the CS pin requires that you change .ss_pin to stop the Nordic library code also controlling the pin from this

    spi_config.ss_pin   = SPI_SS_PIN;
    

    to this:

    spi_config.ss_pin = NRF_DRV_SPI_PIN_NOT_USED;

    There is also a bug here, as if more than 1 byte is transmitted a pointer to an array of bytes must be used, not the address of a single byte

    err_code = nrf_drv_spi_transfer(&spi, &Byte, 2, pData, 2);
    // if only 1 byte change to this:
    err_code = nrf_drv_spi_transfer(&spi, &Byte, 1, pData, 2);

    Same problem here and in other places, spi_transfer requires a pointer to an array or the address of a byte if only sending 1 byte

    uint8_t* FLASH_IO_WriteReadByte(uint8_t data,uint8_t len)
    {
        ret_code_t err_code;
        err_code = nrf_drv_spi_transfer(&spi, &data, len, Rxbuff, len);
        APP_ERROR_CHECK(err_code);
    	  return Rxbuff;
    }
    
    change to something like this:
    
    uint8_t* FLASH_IO_WriteReadByte(uint8_t * p_data,uint8_t len)
    {
        ret_code_t err_code;
        err_code = nrf_drv_spi_transfer(&spi, p_data, len, Rxbuff, len);
        APP_ERROR_CHECK(err_code);
    	  return Rxbuff;
    }

    That's all I can help with, too busy fixing my own projects ..

  • Hi,i have tried what u said ,but still i got the same problem.

    i have commented

        FLASH_IO_CS_High();

        FLASH_IO_CS_low();

    and checked it

    i will send the log  statements

    Spi...Init....
    
    SPI example started.  = 0 
    
    Byte = 159 and SPI_WRITE_READ  = 0 == 194 === 0 ==== 0 err_code = 0
    
    Byte = 0 and SPI_WRITE_READ  = 0 == 0 === 0 ==== 0 err_code = 0
    
    Byte = 0 and SPI_WRITE_READ  = 0 == 0 === 0 ==== 0 err_code = 0
    
    Byte = 0 and SPI_WRITE_READ  = 0 == 0 === 0 ==== 0 err_code = 0
    Temp = 0 Temp0 = 0 Temp1 =0 Temp2 = 0
    Id = 0 
    
    byte write done beginning 
    
    Byte = 6 and SPI_WRITE_READ  = 0 == 0 === 3 ==== 0 err_code = 0
    
    Byte = 2 and SPI_WRITE_READ  = 0 == 0 === 3 ==== 0 err_code = 0
    
    Byte = 0 and SPI_WRITE_READ  = 0 == 0 === 3 ==== 0 err_code = 0
    
    Byte = 0 and SPI_WRITE_READ  = 0 == 0 === 3 ==== 0 err_code = 0
    
    Byte = 1 and SPI_WRITE_READ  = 0 == 0 === 3 ==== 0 err_code = 0
    
    Byte = 5 and SPI_WRITE_READ  = 0 == 0 === 3 ==== 0 err_code = 0
    
    byte write done end
    
    Byte = 3 and SPI_WRITE_READ  = 0 == 0 === 0 ==== 0 err_code = 0
    
    Byte = 0 and SPI_WRITE_READ  = 0 == 0 === 0 ==== 0 err_code = 0
    
    Byte = 0 and SPI_WRITE_READ  = 0 == 0 === 0 ==== 0 err_code = 0
    
    Byte = 1 and SPI_WRITE_READ  = 0 == 0 === 0 ==== 0 err_code = 0
    
     0 4 0 32
    Mx25L64_BYTE_Read = 0 
    
    /*here i am getting some different values in the receiving  buffer while reading*/

  • Hi

    Did you implement the bug fixes suggested? Have you remembered to set the correct frequency, etc. according to the MX25L64? Do you have a logic analyzer available so you can check that you're sending the correct info to the external memory?

    Best regards,

    Simon

Related