This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

SPI interface in AM1808

Other Parts Discussed in Thread: AM1808, SYSBIOS, OMAPL138

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 *********************************/

  • This question is not about an MSP430, so I moved this from the MSP430 forum to the TI-RTOS forum since you mentioned SYSBIOS. You may also want to try posting in the forum for the AM1808:

  • Hi,

    Can you post your cfg file? Have you verified the Hwi is being executed when data is received? Are there any error messages you are receiving?

    Regards,
    -- Emmanuel
  • hi thanks for your reply...Hwi is executed when data is received..but when erase flash ...get busying state ,the data is error ...

    the log of received data with hwi and without hwi is below ' you can see there is different between the two conditions.
    but oscilloscope show the received datas are both correct . so i think the hwi mode i make something wrong
    hwi:
    [ARM9_0] SF: Read Winbond ID is 4016h
    [ARM9_0] Flash ID read SUCCESS
    [ARM9_0] first check busy or not
    [ARM9_0] rx_data[0]= ff rx_data[1]=0
    [ARM9_0] begin erase address 0 for test
    [ARM9_0] rx_data[0]= ff rx_data[1]=ff
    [ARM9_0] rx_data[0]= 3 rx_data[1]=ff
    [ARM9_0] rx_data[0]= 3 rx_data[1]=ff
    [ARM9_0] rx_data[0]= 3 rx_data[1]=ff
    [ARM9_0] rx_data[0]= 0 rx_data[1]=ff /*because rx_data[1] is ff so it's always notify the flash is busying*/

    no hwi
    [ARM9_0] SF: Read Winbond ID is 4016h
    [ARM9_0] Flash ID read SUCCESS
    [ARM9_0] first check busy or not
    [ARM9_0] rx_data[0]= ff rx_data[1]=0
    [ARM9_0] begin erase address 0 for test
    [ARM9_0] rx_data[0]= ff rx_data[1]=3
    [ARM9_0] rx_data[0]= ff rx_data[1]=3
    [ARM9_0] rx_data[0]= ff rx_data[1]=3
    [ARM9_0] rx_data[0]= ff rx_data[1]=0
    [ARM9_0] erase Address 0 ok
  • cfg file

    var Defaults = xdc.useModule('xdc.runtime.Defaults');
    var Diags = xdc.useModule('xdc.runtime.Diags');
    var Error = xdc.useModule('xdc.runtime.Error');
    var Log = xdc.useModule('xdc.runtime.Log');
    var LoggerBuf = xdc.useModule('xdc.runtime.LoggerBuf');
    var Main = xdc.useModule('xdc.runtime.Main');
    var SysMin = xdc.useModule('xdc.runtime.SysMin');
    var System = xdc.useModule('xdc.runtime.System');

    var BIOS = xdc.useModule('ti.sysbios.BIOS');
    var Swi = xdc.useModule('ti.sysbios.knl.Swi');
    var Task = xdc.useModule('ti.sysbios.knl.Task');
    var Semaphore = xdc.useModule('ti.sysbios.knl.Semaphore');
    var Hwi = xdc.useModule('ti.sysbios.hal.Hwi');
    /* set the Timer frequency to 20MHz */
    var Timer = xdc.useModule('ti.sysbios.timers.timer64.Timer');


    var Cache = xdc.useModule('ti.sysbios.family.arm.arm9.Cache');
    var Mmu = xdc.useModule('ti.sysbios.family.arm.arm9.Mmu');
    var Clock = xdc.useModule('ti.sysbios.knl.Clock');
    var HeapMem = xdc.useModule('ti.sysbios.heaps.HeapMem');
    var Memory = xdc.useModule('xdc.runtime.Memory');
    var HeapStd = xdc.useModule('xdc.runtime.HeapStd');
    var HeapMin = xdc.useModule('xdc.runtime.HeapMin');
    var HeapBuf = xdc.useModule('ti.sysbios.heaps.HeapBuf');
    var HeapMultiBuf = xdc.useModule('ti.sysbios.heaps.HeapMultiBuf');
    var HeapNull = xdc.useModule('ti.sysbios.heaps.HeapNull');
    var ti_sysbios_hal_Timer = xdc.useModule('ti.sysbios.hal.Timer');
    //var Global = xdc.useModule('ti.ndk.config.Global');
    //var Telnet = xdc.useModule('ti.ndk.config.Telnet');
    //var DhcpClient = xdc.useModule('ti.ndk.config.DhcpClient');
    //var Emac = xdc.useModule('ti.ndk.config.Emac');
    //var Ip = xdc.useModule('ti.ndk.config.Ip');
    //var Icmp = xdc.useModule('ti.ndk.config.Icmp');
    //var Tcp = xdc.useModule('ti.ndk.config.Tcp');
    //var Udp = xdc.useModule('ti.ndk.config.Udp');
    //var Http = xdc.useModule('ti.ndk.config.Http');
    //var ti_drv_omapl138_Emac = xdc.useModule('ti.drv.omapl138.Emac');
    //var Timer = xdc.useModule('ti.sysbios.hal.Timer');
    Timer.intFreqs[0].lo=24000000;

    // Enable the cache
    Cache.enableCache = true;

    // Enable the MMU (Required for L1 data caching)
    Mmu.enableMMU = true;

    // Force peripheral section to be NON cacheable
    var PeripheralAttrs = {
    type : Mmu.FirstLevelDesc_SECTION, // SECTION descriptor
    bufferable : false, // bufferable
    cacheable : false, // cacheable
    };

    var DDRAttrs = {
    type : Mmu.FirstLevelDesc_SECTION, // SECTION descriptor
    bufferable : true, // bufferable
    cacheable : true, // cacheable
    };
    // Define the base address of the 1 Meg page
    // the peripheral resides in.

    // Configure the corresponding MMU page descriptor accordingly
    for (var i=0x01000000; i < 0x02000000; i = i + 0x00100000) {
    Mmu.setFirstLevelDescMeta(i, i, PeripheralAttrs);
    }
    for (var i=0xC2000000; i < 0xC4000000; i = i + 0x00100000) {
    Mmu.setFirstLevelDescMeta(i, i, DDRAttrs);
    }


    /*
    * Program.argSize sets the size of the .args section.
    * The examples don't use command line args so argSize is set to 0.
    */
    Program.argSize = 0x0;

    /*
    * Uncomment this line to globally disable Asserts.
    * All modules inherit the default from the 'Defaults' module. You
    * can override these defaults on a per-module basis using Module.common$.
    * Disabling Asserts will save code space and improve runtime performance.
    Defaults.common$.diags_ASSERT = Diags.ALWAYS_OFF;
    */

    /*
    * Uncomment this line to keep module names from being loaded on the target.
    * The module name strings are placed in the .const section. Setting this
    * parameter to false will save space in the .const section. Error and
    * Assert messages will contain an "unknown module" prefix instead
    * of the actual module name.
    Defaults.common$.namedModule = false;
    */

    /*
    * Minimize exit handler array in System. The System module includes
    * an array of functions that are registered with System_atexit() to be
    * called by System_exit().
    */
    System.maxAtexitHandlers = 4;

    /*
    * Uncomment this line to disable the Error print function.
    * We lose error information when this is disabled since the errors are
    * not printed. Disabling the raiseHook will save some code space if
    * your app is not using System_printf() since the Error_print() function
    * calls System_printf().
    Error.raiseHook = null;
    */

    /*
    * Uncomment this line to keep Error, Assert, and Log strings from being
    * loaded on the target. These strings are placed in the .const section.
    * Setting this parameter to false will save space in the .const section.
    * Error, Assert and Log message will print raw ids and args instead of
    * a formatted message.
    Text.isLoaded = false;
    */

    /*
    * Uncomment this line to disable the output of characters by SysMin
    * when the program exits. SysMin writes characters to a circular buffer.
    * This buffer can be viewed using the SysMin Output view in ROV.
    SysMin.flushAtExit = false;
    */

    /*
    * The BIOS module will create the default heap for the system.
    * Specify the size of this default heap.
    */
    BIOS.heapSize = 0xA00000;

    /* System stack size (used by ISRs and Swis) */
    Program.stack = 0x200000;

    /* Circular buffer size for System_printf() */
    SysMin.bufSize = 0x200;

    /*
    * Create and install logger for the whole system
    */
    var loggerBufParams = new LoggerBuf.Params();
    loggerBufParams.numEntries = 16;
    var logger0 = LoggerBuf.create(loggerBufParams);
    Defaults.common$.logger = logger0;
    Main.common$.diags_INFO = Diags.ALWAYS_ON;

    System.SupportProxy = SysMin;
    var TSK_MainCtrlParams = new Task.Params();
    TSK_MainCtrlParams.instance.name = "MainCtrlTask";
    TSK_MainCtrlParams.priority = 7;
    TSK_MainCtrlParams.stackSize = 81920;
    Program.global.MainCtrlTask = Task.create("&MainCtrlTaskProc", TSK_MainCtrlParams);
    Mmu.cachePlatformMemory = false;
    Clock.timerId = 0;
    Task.common$.namedInstance = false;
    BIOS.libType = BIOS.LibType_Instrumented;
    BIOS.clockEnabled = true;
    BIOS.assertsEnabled = true;
    BIOS.logsEnabled = true;
    BIOS.cpuFreq.lo = 450000000;
    Clock.tickSource = Clock.TickSource_TIMER;
    var heapmemInstance0 = xdc.lookup('ti.sysbios.heaps.HeapMem.Instance#0');
    Memory.defaultHeapSize = 10485760;
    Semaphore.supportsEvents = false;

    var Load = xdc.useModule('ti.sysbios.utils.Load');
    Main.common$.diags_ASSERT = Diags.RUNTIME_ON;
    //Ip.domainName = "CronusArm";
    //Emac.device = Emac.EVMOMAPL138;
    //Ip.enableFiltering = false;
    //Ip.autoIp = false;
    //Ip.address = "192.168.1.106";
    //Ip.mask = "255.255.255.0";
    //Ip.gatewayIpAddr = "192.168.1.1";
    //Global.debugAbortLevel = Global.DBG_INFO;
    //Global.stackLibType = Global.MIN;