News:

Attention: For security reasons,please choose a user name *different* from your login name.
Also make sure to choose a secure password and change it regularly.

Main Menu

SPI Flash Unlock

Started by Oleksandr Kiyenko, February 21, 2013, 02:13:21 PM

Previous topic - Next topic

Oleksandr Kiyenko

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;
}