i use AM1808_StarterWare_1_00_03_03 SPI example can communicate with SPI FLASH such as read flash ID erase Flash write Flash read flash are all ok.
when I put the example in SYSBIOS using HWI there is a error when erasing Flash, the spi data read is not corrected . but oscilloscope show the shape is correct data,but spi read isn't . but read flash ID is always correct. is there anything wrong ?
/**
* \file spiFlashBurn.c
*
* \brief This is a sample application file which invokes some APIs
* from the SPI device abstraction layer to perform configuration,
* transmission and reception operations.
*
*/
/*
* Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
//#define _USE_BIOS /*sysbios use or not*/
#include <string.h>
#include "soc_AM1808.h"
#include "hw_psc_AM1808.h"
#include "evmAM1808.h"
#include "uart.h"
#include "spi.h"
#include "psc.h"
#include "interrupt.h"
#include "uartStdio.h"
#ifdef _USE_BIOS
#include "OsalInclude.h"
#include "HwInterrupt.h"
#endif
/******************************************************************************
** INTERNAL MACRO DEFINITIONS
*******************************************************************************/
/* value to configure SMIO,SOMI,CLK and CS pin as functional pin */
#define SIMO_SOMI_CLK_CS 0x00000E01 /* cs_0 = 1 */
//#define SIMO_SOMI_CLK_CS 0x00000E04 /* cs_2 = 1 */
#define CHAR_LENGTH 0x8
#define SPI_CS 0x01 /* cs_0 = 1 */
/* flash address where data will be written and read */
#define SPI_FLASH_ADDR_MSB1 0x0A
#define SPI_FLASH_ADDR_MSB0 0x00
#define SPI_FLASH_ADDR_LSB 0x00
/* sector erase command */
#define SPI_FLASH_SECTOR_ERASE_4KB 0x20
#define SPI_FLASH_BLOCK_ERASE_32KB 0x52
#define SPI_FLASH_BLOCK_ERASE_64KB 0xD8
#define SPI_FLASH_CHIP_ERASE 0xC7
/* page program command */
#define SPI_FLASH_PAGE_WRITE 0x02
/* status register read command */
#define SPI_FLASH_STATUS_RX 0x05
/* write enable command */
#define SPI_FLASH_WRITE_EN 0x06
#define SPI_FLASH_WRITE_DIS 0x04
/* flash data read command */
#define SPI_FLASH_READ 0x03
/* flash ID read command */
#define SPI_FLASH_ID_READ 0x9f
/* flash data read */
#define WRITE_IN_PROGRESS 0x01
/******************************************************************************
** FLASH INFORMATION
*******************************************************************************/
#define WINBOND_ID_W25X16 0x3015
#define WINBOND_ID_W25X32 0x3016
#define WINBOND_ID_W25X64 0x3017
#define WINBOND_ID_W25Q32 0x4016
#define WINBOND_ID_M25P16 0x2015
#define WINBOND_ID_M25P40 0x2013
struct spi_flash_params {
unsigned short idcode;
unsigned short page_size;
unsigned short pages_per_sector;
unsigned short nr_sectors;
const char *name;
};
const struct spi_flash_params *params;
static const struct spi_flash_params winbond_spi_flash_table[] = {
{
WINBOND_ID_W25X32,
256,
16,
1024,
"W25X32",
},
{
WINBOND_ID_W25X16,
256,
16,
512,
"W25X16",
},
{
WINBOND_ID_W25X64,
256,
16,
2048,
"W25X64",
},
{
WINBOND_ID_W25Q32,
256,
16,
1024,
"W25Q32",
},
{
WINBOND_ID_M25P16,
256,
16,
1024,
"M25p16",
},
{
WINBOND_ID_M25P40,
256,
16,
1024,
"M25p40",
},
};
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
/******************************************************************************
* Global constants *
******************************************************************************/
#define FLASH_ERROR_NONE ( 0)
#define FLASH_ERROR_NODEVICE (-1)
#define FLASH_ERROR_ERASE_TO (-2)
#define FLASH_ERROR_WRITE_TO (-3)
#define FLASH_ERROR_NOMEMORY (-4)
#define FLASH_ERROR_DEV_UNSUPPORTED (-5)
#define FLASH_ERROR_DEV_LOCKED (-6)
#define FLASH_ERROR_OVERFLOW (-7)
/******************************************************************************
** INTERNAL FUNCTION PROTOTYPES
*******************************************************************************/
static void SPIConfigDataFmtReg(unsigned long dataFormat);
static void WriteEnable(void);
static void WriteDisable(void);
static void ReadFlashID(void);
static void ReadFromFlash(unsigned addr, unsigned char *data, unsigned length);
int WritetoFlash(unsigned addr, unsigned char *data, unsigned length);
static void IsFlashBusy(void);
static void SpiTransfer(void);
static void VerifyData(void);
static void StatusGet(void);
static void SetUpInt(void);
static void SetUpSPI(void);
void SPIIsr(void);
static void SectorErase(int addr);
static void BlockErase(int addr);
int WinbondSectorEraseChoose(int num);
int WinbondBlockEraseChoose(int num);
void WinbondChipEraseChoose(void);
unsigned int convert(char *hexChar);
static void Delay(volatile unsigned int delay);
/******************************************************************************
** INTERNAL VARIABLE DEFINITIONS
*******************************************************************************/
volatile unsigned int flag = 1;
unsigned int len;
char vrf_data[0x1020];
char tx_data[0x1020];
char rx_data[0x1020];
char *p_tx;
char *p_rx;
FILE *aisIn = NULL;
char *Filename = "C:\\Users\\jhoe\\Desktop\\xx\\gpio_reset_ais.bin";
char AisStream[256];
int iFileSize = 0;
unsigned int uiBlockNum = 0;
unsigned int aisStreamCount;
unsigned int readCount;
unsigned int seekCount;
char value[20];
char dummy[64];
unsigned char readBack = 0x00;
unsigned char readBackVerify[0x1000];
int error, errorCnt;
int offset;
int wrtPageCnt;
#ifdef _USE_BIOS
/*******************************************************************************
* Function Name : MainCtrlTaskProc
* Description :
* Input :
* Return :
* Attention :
*******************************************************************************/
void MainCtrlTaskProc(void)
{
//MyTackCreate(NetWorkServiceTaskProc, "NwSvr",2,4096);
while(1)
{
Task_sleep(1000);
printf("----------\n");
}
}
#endif
/******************************************************************************
** INTERNAL FUNCTION DEFINITIONS
*******************************************************************************/
void main(void)
{
//unsigned char choice = 0;
#ifdef _USE_BIOS
/*先关闭中断*/
HwICtrlInit();
HwICtrlRelease();
#endif
/* Waking up the SPI1 instance. */
PSCModuleControl(SOC_PSC_0_REGS, HW_PSC_SPI0, PSC_POWERDOMAIN_ALWAYS_ON,
PSC_MDCTL_NEXT_ENABLE);
/* Initializing the UART instance for serial communication. */
//UARTStdioInit();
//UARTPuts("StarterWare AM1808 SPI application.\r\n\r\n", -1);
//UARTPuts("Here the SPI controller on the SoC communicates with", -1);
//UARTPuts(" the SPI Flash present on the SoM.\r\n\r\n", -1);
/* Performing the Pin Multiplexing for SPI0. */
SPIPinMuxSetup(0);
/*
** Using the Chip Select(CS) 2 pin of SPI0 to communicate with SPI Flash.
** AM1808 EVM mandates us to do so.
*/
SPI0CSPinMuxSetup(0);
#ifdef _USE_BIOS
HwiCreate(SYS_INT_SPINT0,2, SPIIsr);
#else
SetUpInt();
#endif
/* Configuring and enabling the SPI1 instance. */
SetUpSPI();
#ifdef _USE_BIOS
HwICtrlEnable();
#endif
/* Reads the flash ID and verify */
ReadFlashID();
printf("first check busy or not\n");
IsFlashBusy();
WriteEnable();
printf("begin erase address 0 for test \n");
SectorErase( 0);
printf("erase Address 0 ok \n");
/* Preparing the Flash for a Write. */
//WriteEnable();
/*---------------------------------------------------------------*/
/* Read File, Erase Flash and Write Flash */
/*---------------------------------------------------------------*/
aisIn = fopen(Filename, "rb");
if(NULL == aisIn)
{
printf ("Couldn't open file:\n %s\n",Filename);
return ;
}
iFileSize = 0;
fseek(aisIn, 0, SEEK_END);/*将文件指针定位到文件结尾偏移为0处*/
iFileSize = ftell(aisIn);
if(0 == iFileSize)
{
printf("\nERROR: File read failed.\n");
fclose(aisIn);
return ;
}
aisStreamCount = 0;
readCount = 0;
seekCount = 0;
offset = 0;
errorCnt = 0;
error = 0;
wrtPageCnt = 0;
printf ("Opened AIS file:\n %s\n\n", Filename);
printf("Data Length : %d\n", iFileSize);
// FLASH Sector erase
error = WinbondSectorEraseChoose(80);
if(error != FLASH_ERROR_NONE)
{
printf ("Error erase to FLASH, error code = %d\n", error);
fclose(aisIn);
return;
}
// Start write FLASH
printf ("Start write FLASH...\n");
fseek(aisIn, 0, SEEK_SET);/*将文件指针定位到文件开头偏移为0处*/
while (((readCount = fread(dummy, 1, 64, aisIn)) == 64) && (errorCnt == 0)) {
//AisStream[aisStreamCount] = convert(dummy);
//fseek(aisIn, seekCount, SEEK_SET);
memcpy((void *)&AisStream[aisStreamCount], dummy, readCount);
aisStreamCount += readCount;
seekCount += readCount;
if (aisStreamCount >= 256) {
printf (" Writing Page of FLASH\n");
WriteEnable();
error = WritetoFlash( offset, (unsigned char *)&AisStream[0], aisStreamCount );
if (!error) {
ReadFromFlash( offset, (unsigned char *)&readBack, 1 );
if (readBack != AisStream[0]) {
errorCnt++;
}
} else {
errorCnt++;
}
wrtPageCnt++;
offset += aisStreamCount;
aisStreamCount = 0;
}
}
if (readCount !=0 ) {
//fseek(aisIn, seekCount, SEEK_SET);
memcpy((void *)&AisStream[aisStreamCount], dummy, readCount);
aisStreamCount += readCount;
printf (" Writing Last Segment to FLASH, AisStream[0] = 0x%08X, aisStreamCount = 0x%08X\n",AisStream[0], aisStreamCount);
WriteEnable();
error = WritetoFlash( offset, (unsigned char *)&AisStream[0], aisStreamCount );
if (!error) {
ReadFromFlash( offset, (unsigned char *)&readBack, 1 );
if (readBack != AisStream[0]) {
errorCnt++;
}
} else {
errorCnt++;
}
}
if (errorCnt == 0) {
printf ("Writing Flash space %dbytes = 256bytes × %d + %d .\n", (256*wrtPageCnt+aisStreamCount), wrtPageCnt, aisStreamCount);
printf ("FLASH Programming Complete.\n");
} else {
printf ("Error writing to FLASH, error code = %d.\n", error);
}
//UARTPuts("Do you want to erase a sector of the flash before writing to it ?.", -1);
//UARTPuts("\r\nInput y(Y)/n(N) to proceed.\r\n", -1);
//choice = UARTGetc();
//UARTPutc(choice);
//if(('y' == choice) || ('Y' == choice))
//SectorErase();
//WriteEnable();
/* Programming the necessary data to Flash. */
//WritetoFlash();
/* Reading from the required location from Flash. */
//ReadFromFlash();
/* Comparing the written and read data. */
//VerifyData();
fclose(aisIn);
/*---------------------------------------------------------------*/
/* If Flash burn finish, blink the light */
/*---------------------------------------------------------------*/
#ifdef _USE_BIOS
BIOS_start();
#else
while(1);
#endif
}
/*
** Reads the status register of m25p80 flash
**
*/
static void StatusGet(void)
{
tx_data[0] = SPI_FLASH_STATUS_RX;
len = 2;
SPIDat1Config(SOC_SPI_0_REGS, (SPI_CSHOLD | SPI_DATA_FORMAT0), SPI_CS);
SpiTransfer();
}
/*
** Enables write to m25p80 flash
**
*/
static void WriteEnable(void)
{
tx_data[0] = SPI_FLASH_WRITE_EN;
len = 1;
SPIDat1Config(SOC_SPI_0_REGS, (SPI_CSHOLD | SPI_DATA_FORMAT0), SPI_CS);
SpiTransfer();
}
/*
** Disables write to m25p80 flash
**
*/
static void WriteDisable(void)
{
tx_data[0] = SPI_FLASH_WRITE_DIS;
len = 1;
SPIDat1Config(SOC_SPI_0_REGS, (SPI_CSHOLD | SPI_DATA_FORMAT0), SPI_CS);
SpiTransfer();
}
/*
** It polls for write in progress bit(wip)in status register of m25p80 flash
**
*/
static void IsFlashBusy(void)
{
do{
StatusGet();
printf("rx_data[0]= %x rx_data[1]=%x \n",rx_data[0],rx_data[1]);
}while(rx_data[1] & WRITE_IN_PROGRESS);
}
/*
** Writes 256 bytes of data to desired memory address
**
*/
int WritetoFlash(unsigned addr, unsigned char *data, unsigned length)
{
unsigned int index;
tx_data[0] = SPI_FLASH_PAGE_WRITE;
tx_data[1] = (addr&0xFF0000) >> 16;
tx_data[2] = (addr&0x00FF00) >> 8;
tx_data[3] = (addr&0x0000FF);
/* Populate the data to be written to the flash */
for (index = 4; index < (length + 4); index++)
{
tx_data[index] = data[index-4];
vrf_data[index] = data[index-4];
}
len = index;
SPIDat1Config(SOC_SPI_0_REGS, (SPI_CSHOLD | SPI_DATA_FORMAT0), SPI_CS);
SpiTransfer();
IsFlashBusy();
return 0;
}
/*
** Reads the data from addressed memory of flash
**
*/
static void ReadFromFlash(unsigned addr, unsigned char *data, unsigned length)
{
unsigned int i, index;
tx_data[0] = SPI_FLASH_READ;
tx_data[1] = (addr&0xFF0000) >> 16;
tx_data[2] = (addr&0x00FF00) >> 8;
tx_data[3] = (addr&0x0000FF);
/* Reset the data in the tx buffer */
for (index = 4; index < (length + 4); index++)
{
tx_data[index] = 0;
}
len = index;
SPIDat1Config(SOC_SPI_0_REGS, (SPI_CSHOLD | SPI_DATA_FORMAT0), SPI_CS);
SpiTransfer();
for(i = 0; i < length; i++){
data[i]=rx_data[4+i];
}
}
/*
** Reads the ID from flash
**
*/
static void ReadFlashID(void)
{
unsigned int index;
unsigned int idmatch;
tx_data[0] = SPI_FLASH_ID_READ;
/* Reset the data in the tx buffer */
for (index = 1; index < 4; index++)
{
tx_data[index] = 0;
}
len = index;
SPIDat1Config(SOC_SPI_0_REGS, (SPI_CSHOLD | SPI_DATA_FORMAT0), SPI_CS);
SpiTransfer();
/* match the present FLASH ID */
idmatch = ((rx_data[2] << 8) | rx_data[3]);
printf("SF: Read Winbond ID is %02xh\n", idmatch);
for (index = 0; index < ARRAY_SIZE(winbond_spi_flash_table); index++)
{
params = &winbond_spi_flash_table[index];
if (params->idcode == idmatch)
{
printf("Flash ID read SUCCESS \n");
break;
}
}
if (index == ARRAY_SIZE(winbond_spi_flash_table))
{
printf("SF: Unsupported Winbond ID %02xh\n", idmatch);
}
}
/*
** Verfies the data written to flash and read from the flash of same address
**
*/
static void VerifyData(void)
{
unsigned int index;
for(index = 4; index < 260; index++)
{
if(vrf_data[index] != rx_data[index])
{
//printf("\r\n", -1);
printf("VerifyData: Comparing the data written to and read", -1);
printf(" from Flash.\r\nThe two data blocks are unequal.", -1);
printf(" Mismatch found at index ", -1);
//UARTPutNum((int)index - 3);
//printf("\r\n", -1);
break;
}
}
if (index == 260)
{
//UARTPuts("\r\nThe data in the Flash and the one written ", -1);
//UARTPuts("to it are equal.\r\n", -1);
printf("The data in the Flash and the one written to it are equal.\n");
}
}
/*
** Configures ARM interrupt controller to generate SPI interrupt
**
*/
static void SetUpInt(void)
{
/* Initialize the ARM Interrupt Controller.*/
IntAINTCInit();
/* Register the ISR in the Interrupt Vector Table.*/
IntRegister(SYS_INT_SPINT0, SPIIsr);
/* Set the channnel number 2 of AINTC for system interrupt 56.
* Channel 2 is mapped to IRQ interrupt of ARM9.
*/
IntChannelSet(SYS_INT_SPINT0, 2);
/* Enable the System Interrupts for AINTC.*/
IntSystemEnable(SYS_INT_SPINT0);
/* Enable IRQ in CPSR.*/
IntMasterIRQEnable();
/* Enable the interrupts in GER of AINTC.*/
IntGlobalEnable();
/* Enable the interrupts in HIER of AINTC.*/
IntIRQEnable();
}
/*
** Configures SPI Controller
**
*/
static void SetUpSPI(void)
{
unsigned char cs = SPI_CS;
unsigned char dcs = SPI_CS;
unsigned int val = SIMO_SOMI_CLK_CS;
SPIReset(SOC_SPI_0_REGS);
SPIOutOfReset(SOC_SPI_0_REGS);
SPIModeConfigure(SOC_SPI_0_REGS, SPI_MASTER_MODE);
SPIClkConfigure(SOC_SPI_0_REGS, 150000000, 20000000, SPI_DATA_FORMAT0);
SPIPinControl(SOC_SPI_0_REGS, 0, 0, &val);
SPIDefaultCSSet(SOC_SPI_0_REGS, dcs);
/* Configures SPI Data Format Register */
SPIConfigDataFmtReg(SPI_DATA_FORMAT0);
/* Selects the SPI Data format register to used and Sets CSHOLD
* to assert CS pin(line)
*/
SPIDat1Config(SOC_SPI_0_REGS, (SPI_CSHOLD | SPI_DATA_FORMAT0), cs);
/* map interrupts to interrupt line INT1 */
SPIIntLevelSet(SOC_SPI_0_REGS, SPI_RECV_INTLVL | SPI_TRANSMIT_INTLVL);
/* Enable SPI communication */
SPIEnable(SOC_SPI_0_REGS);
}
/*
** Configures Data Format register of SPI
**
*/
static void SPIConfigDataFmtReg(unsigned long dataFormat)
{
/* Configures the polarity and phase of SPI clock */
SPIConfigClkFormat(SOC_SPI_0_REGS,
(SPI_CLK_POL_HIGH | SPI_CLK_INPHASE),
dataFormat);
/* Configures SPI to transmit MSB bit First during data transfer */
SPIShiftMsbFirst(SOC_SPI_0_REGS, dataFormat);
/* Sets the Charcter length */
SPICharLengthSet(SOC_SPI_0_REGS, CHAR_LENGTH, dataFormat);
}
/*
** Enables SPI Transmit and Receive interrupt.
** Deasserts Chip Select line.
*/
static void SpiTransfer(void)
{
p_tx = &tx_data[0];
p_rx = &rx_data[0];
SPIIntEnable(SOC_SPI_0_REGS, (SPI_RECV_INT | SPI_TRANSMIT_INT));
while(flag);
flag = 1;
/* Deasserts the CS pin(line) */
SPIDat1Config(SOC_SPI_0_REGS, SPI_DATA_FORMAT0, SPI_CS);
}
/*
** Data transmission and receiption SPIIsr
**
*/
void SPIIsr(void)
{
unsigned long intCode = 0;
IntSystemStatusClear(SYS_INT_SPINT0);
intCode = SPIInterruptVectorGet(SOC_SPI_0_REGS);
while (intCode)
{
if(intCode == SPI_TX_BUF_EMPTY)
{
len--;
SPITransmitData1(SOC_SPI_0_REGS, *p_tx);
p_tx++;
if (!len)
{
SPIIntDisable(SOC_SPI_0_REGS, SPI_TRANSMIT_INT);
}
}
if(intCode == SPI_RECV_FULL)
{
*p_rx = (char)SPIDataReceive(SOC_SPI_0_REGS);
p_rx++;
if (!len)
{
flag = 0;
SPIIntDisable(SOC_SPI_0_REGS, SPI_RECV_INT);
}
}
intCode = SPIInterruptVectorGet(SOC_SPI_0_REGS);
}
}
/*
** bin to hex convert
**
*/
unsigned int convert(char *hexChar) {
unsigned short i;
unsigned char ch;
unsigned int value = 0;
char *localPtr;
char localString[16];
// Skip first two chars (0x)
sscanf(hexChar, "%s", &localString);
// printf("localString :%s:\n",localString);
localPtr = &localString[0];
++localPtr;
++localPtr;
for(i = 0; i< 8; ++i) {
ch = *(unsigned char *)localPtr;
if ((ch >= 'A') && (ch <= 'F')) {
value = (value << 4) + 10 + (unsigned int) (ch - 'A');
} else {
value = (value << 4) + (unsigned int) (ch - '0');
}
++localPtr;
}
return value;
}
/*
** \brief This function can be called to generate a delay.
*/
static void Delay(volatile unsigned int delay)
{
while(delay--);
}
/*
** Set the all bits to 1 in chosen sector
**
*/
static void SectorErase(int addr)
{
tx_data[0] = SPI_FLASH_SECTOR_ERASE_4KB;
tx_data[1] = (addr&0xFF0000) >> 16;
tx_data[2] = (addr&0x00FF00) >> 8;
tx_data[3] = (addr&0x0000FF);
len = 4;
SPIDat1Config(SOC_SPI_0_REGS, (SPI_CSHOLD | SPI_DATA_FORMAT0), SPI_CS);
SpiTransfer();
IsFlashBusy();
}
int WinbondSectorEraseChoose(int num)
{
int i,j;
if((num <= 0) || (params->nr_sectors < num)) return FLASH_ERROR_NOMEMORY;
//WriteEnable();
//Delay(0x730);
// Choose FLASH Sector erase
for(i = 0; i < num; i++) // number 4KBytes
{
WriteEnable();
SectorErase(0x0000 + (i*0x1000)); // One 4KBytes
ReadFromFlash( (0x0000 + (i*0x1000)), (unsigned char *)&readBackVerify[0], 2 );
for(j = 0; j < 2; j++){
if (readBackVerify[j] != 0xFF) {
printf(" Erase Flash error.\r\n");
return FLASH_ERROR_ERASE_TO;
}
}
}
WriteDisable();
/*for(i = 0; i < num; i++){
ReadFromFlash( (0x0000 + (i*0x1000)), (unsigned char *)&readBack, 1 );
if (readBack != 0xFF) {
printf(" Erase Flash error.\r\n");
return FLASH_ERROR_ERASE_TO;
}
}*/
return FLASH_ERROR_NONE;
}
/*
** Set the all bits to 1 in chosen block
**
*/
static void BlockErase(int addr)
{
tx_data[0] = SPI_FLASH_BLOCK_ERASE_64KB;
tx_data[1] = (addr&0xFF0000) >> 16;
tx_data[2] = (addr&0x00FF00) >> 8;
tx_data[3] = (addr&0x0000FF);
len = 4;
SPIDat1Config(SOC_SPI_0_REGS, (SPI_CSHOLD | SPI_DATA_FORMAT0), SPI_CS);
SpiTransfer();
IsFlashBusy();
}
int WinbondBlockEraseChoose(int num)
{
int i;
if((num <= 0) || ((params->nr_sectors/params->pages_per_sector) < num)) return FLASH_ERROR_NOMEMORY;
// Choose FLASH Block erase
for(i = 0; i < num; i++) // number 64KBytes
{
BlockErase(0x0000 + (i*0x10000)); // One 64KBytes
}
return FLASH_ERROR_NONE;
}
/*
** Flash Chip Erase
**
*/
void WinbondChipEraseChoose(void)
{
tx_data[0] = SPI_FLASH_CHIP_ERASE;
len = 1;
SPIDat1Config(SOC_SPI_0_REGS, (SPI_CSHOLD | SPI_DATA_FORMAT0), SPI_CS);
SpiTransfer();
IsFlashBusy();
}
/******************************* End of file *********************************/