Trenz Electronic GmbH Support Forum

Archived Boards and Threads => Archived Boards => FAQ Trenz Electronic FPGA Modules => Topic started by: Oleksandr Kiyenko on February 21, 2013, 02:13:21 PM

Title: SPI Flash Unlock
Post by: Oleksandr Kiyenko on February 21, 2013, 02:13:21 PM
While working with SPI Flash, especially using own flash write/read library possible situation that protection bits can be set.  As result some sectors or whole flash become "read only" and all "write" or "erase" attempts from firmware or by iMPACT fails.

To fix that protection bits should be cleared. Below simple code to do that.

/* File      : flash_ulock.c
* Company   : Trenz Electronics
* Author   : Oleksandr Kiyenko
*/

#include "xparameters.h"
#include "xspi.h"
#include "xspi_l.h"

#define SPI_WREN            0x06
#define   SPI_WRSR            0x01
#define SPI_RDSR1            0x05
#define RDSR1_BYTES            2
#define WREN_BYTES            1
#define WRSR_BYTES            2

#define SPI_SELECT            0x01
#define BUSY_MASK            0x01

int main(void){
   XSpi Spi;
   u8 WriteBuffer[4];
   u8 ReadBuffer[4];
   int Status;

   XSpi_Config *ConfigPtr;
   ConfigPtr = XSpi_LookupConfig(XPAR_SPI_0_DEVICE_ID);
   if (ConfigPtr == NULL)
      return XST_DEVICE_NOT_FOUND;

   Status = XSpi_CfgInitialize(&Spi, ConfigPtr, ConfigPtr->BaseAddress);
   if (Status != XST_SUCCESS)
      return XST_FAILURE;

   Status = XSpi_SetOptions(&Spi, XSP_MASTER_OPTION |
         XSP_MANUAL_SSELECT_OPTION);
   if(Status != XST_SUCCESS)
      return XST_FAILURE;

   Status = XSpi_SetSlaveSelect(&Spi, SPI_SELECT);
   if(Status != XST_SUCCESS)
      return XST_FAILURE;

   XSpi_Start(&Spi);            // Start
   XSpi_IntrGlobalDisable(&Spi);   // Pooled mode

   // Wait till ready

   WriteBuffer[0] = SPI_RDSR1;
   do{
      XSpi_Transfer(&Spi, WriteBuffer, ReadBuffer, RDSR1_BYTES);
   }
   while((ReadBuffer[1] & BUSY_MASK)==BUSY_MASK);

   // Send Write Enable
   WriteBuffer[0] = SPI_WREN;   // Write enable
   XSpi_Transfer(&Spi, WriteBuffer, NULL, WREN_BYTES);
   // Write 0 to Status Register
   WriteBuffer[0] = SPI_WRSR;   // Write Status Register
   WriteBuffer[1] = 0x00;      // Clear all bits
   XSpi_Transfer(&Spi, WriteBuffer, NULL, WRSR_BYTES);

   return 0;
}