Esempio n. 1
0
/*
** Main Function.
*/
int main(void)
{
    unsigned char choice = 0;

    /* Enable the clocks for McSPI0 module.*/
    McSPI0ModuleClkConfig();

    /* Perform Pin-Muxing for SPI0 Instance.*/
    McSPIPinMuxSetup(0);

    /* Perform Pin-Muxing for CS0 of SPI0 Instance.*/
    McSPI0CSPinMuxSetup(MCSPI_CH_NUM);

    /* Initialize the UART utility functions.*/
    UARTStdioInit();

    /* Enable IRQ in CPSR.*/
    IntMasterIRQEnable();

    UARTPuts("Here the McSPI controller on the SOC communicates with ",-1);
    UARTPuts("the McSPI Flash.\r\n\r\n",-1);

    /* Initialize the EDMA3 instance.*/
    EDMA3Initialize();

    /* Request EDMA3CC for Tx and Rx channels for SPI0. */
    RequestEDMA3Channels();

    /* Set up the McSPI instance.*/
    McSPISetUp();

    /* Enable the SPI Flash for writing to it. */
    WriteEnable();

    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))
    {
        /* Erasing the specified sector of SPI Flash. */
        FlashSectorErase();
    }

    /* Enable the SPI Flash for writing to it. */
    WriteEnable();

    /* Write data of 1 page size into a page of Flash.*/
    FlashPageProgram();

    /* Read data of 1 page size from a page of flash.*/
    ReadFromFlash();

    /* Verify the data written to and read from Flash are same or not.*/
    VerifyData();

    while(1);
}
Esempio n. 2
0
/**
 * Set the time of the alarm in HH:MM:SS.
 *
 * @param alarm pointer to RTCTime object that contains the alarm time
 */
void ISL12026::EnableAlarm(const RTCTime *alarm)
{
    uint8_t data[20];

    // Set the time register values.
    WriteEnable();

    I2C0::GetInstance()->Start(WriteCCR);

    data[0] = 0x00;
    data[1] = 0x00;

    // Seconds.
    data[2] = 0x80 | ConvertDecimalToBCD(alarm->seconds);

    // Minutes.
    data[3] =  0x80 | ConvertDecimalToBCD(alarm->minutes);

    // Hours.
    data[4] = 0x80 | ConvertDecimalToBCD(alarm->hours);

    data[5] = 0x00;
    data[6] = 0x00;
    data[7] = 0x00;
    data[8] = 0x00;
    data[9] = 0x00;
    data[10] = 0x00;

    I2C0::GetInstance()->Write(data, 5);
    I2C0::GetInstance()->Stop();

    WriteDisable();


    // Set the alarm and interrupt enable bits.
    WriteEnable();

    I2C0::GetInstance()->Start(WriteCCR);

    data[0] = 0x00;
    data[1] = ControlRegister;
    data[2] = ControlRegisterAlarm1 | ControlRegisterInterruptMode;

    I2C0::GetInstance()->Write(data, 3);
    I2C0::GetInstance()->Stop();

    WriteDisable();
}
Esempio n. 3
0
void FlashDev::WriteStatusReg (StatDataReg &data)
{
	WriteEnable ();
	u16 *d = (u16 *)((void*)&data);
	*d |= 0x0100L;
	spi.Read (d, 1,d, 1, Spi::Flash);
}
/******************************************************************************
  函数(模块)名称:void SectorErase(unsigned int SectorAddr)
  功能:	FLASH块擦除函数
  输入参数:FLASH块地址,从0开始         	              		
  输出参数: 无         	 		   		 
  其它说明: 
*******************************************************************************/
void BlockErase_SST25(unsigned int BlockAddr)
{
    unsigned char Addr0,Addr1,Addr2;
    unsigned long WritedAddr;
    WritedAddr = (unsigned long)BlockAddr;
    WritedAddr=WritedAddr<<15;
    
    Addr0=(unsigned char)WritedAddr;
    WritedAddr=WritedAddr>>8;
    
    Addr1=(unsigned char)WritedAddr;
    WritedAddr=WritedAddr>>8;
    
    Addr2=(unsigned char)WritedAddr;
    
    WriteEnable();
    SPI_CE_L;
    SPI_Send_Byte(BlorkErase_Command);//发送命令
    SPI_Send_Byte(Addr2);              //发送地址
    SPI_Send_Byte(Addr1);
    SPI_Send_Byte(Addr0);
    SPI_CE_H;
    WriteDisable();
    while(ReadStatus()&Busy_BIT);
}
Esempio n. 5
0
uint32_t SPIFlash::EraseChip (void)
{
  // Wait until the device is ready or a timeout occurs
  if (WaitForReady())
    return 0;

  // Make sure the chip is write enabled
  WriteEnable (1);

  // Make sure the write enable latch is actually set
  uint8_t status;
  status = readstatus();
  if (!(status & SPIFLASH_STAT_WRTEN))
  {
    // Throw a write protection error (write enable latch not set)
    return 0;
  }

  // Send the erase chip command
  digitalWrite(_ss, LOW);
  spiwrite(W25Q16BV_CMD_CHIPERASE); 
  digitalWrite(_ss, HIGH);

  // Wait until the busy bit is cleared before exiting
  // This can take up to 10 seconds according to the datasheet!
  while (readstatus() & SPIFLASH_STAT_BUSY);

  return 1;
}
/******************************************************************************
*
*
* This function writes to the  serial FLASH connected to the SPI interface.
*
* @param	InstancePtr is a pointer to the XIsf component to use.
* @param	Address contains the address to write data to in the FLASH.
* @param	ByteCount contains the number of bytes to write.
* @param	Command is the command used to write data to the flash.
*
* @return	None.
*
* @note		None.
*
******************************************************************************/
int FlashWrite(XIsf *InstancePtr, u32 Address, u32 ByteCount, u8 Command)
{
	XIsf_WriteParam WriteParam;

	int Status;

	WriteEnable(InstancePtr);

	WriteParam.Address = Address;
	WriteParam.NumBytes = ByteCount;
	WriteParam.WritePtr = WriteBuffer;

	/*
	 * Perform the Write operation.
	 */
	Status = XIsf_Write(&Isf, Command, (void*) &WriteParam);
	if(Status != XST_SUCCESS) {
		return XST_FAILURE;
	}

	/*
	 * Wait till the Flash is not Busy.
	 */
	Status = IsfWaitForFlashNotBusy();
	if(Status != XST_SUCCESS) {
		return XST_FAILURE;
	}
	return XST_SUCCESS;
}
/******************************************************************************
  函数(模块)名称:void MultiByteWrite(unsigned long WriteAddr,unsigned char *WriteData,unsigned int WriteLent)
  功能:	FLASH字节写函数
  输入参数:写地址,写数据         	              		
  输出参数: 无         	 		   		 
  其它说明: 
*******************************************************************************/
void MultiByteWrite_SST25(unsigned long WriteAddr,unsigned char *WriteData,unsigned int WriteLent)
{
    unsigned char Addr0,Addr1,Addr2;
    Addr0=(unsigned char)WriteAddr;
    WriteAddr=WriteAddr>>8;
    
    Addr1=(unsigned char)WriteAddr;
    WriteAddr=WriteAddr>>8;
    
    Addr2=(unsigned char)WriteAddr;
    
    WriteEnable();
    SPI_CE_L;
    SPI_Send_Byte(AAIProgram_Command);  //发送命令
    SPI_Send_Byte(Addr2);               //发送地址
    SPI_Send_Byte(Addr1);
    SPI_Send_Byte(Addr0);
    SPI_Send_Byte(*WriteData++);        //发送数据
    SPI_CE_H;
    //__delay_cycles(50);                 // Delay;
    while(ReadStatus()&Busy_BIT);
    for(unsigned int i=0;i<WriteLent-1;i++)
    {
        SPI_CE_L;
        SPI_Send_Byte(AAIProgram_Command);    //发送命令
        SPI_Send_Byte(*WriteData++);          //发送数据
        SPI_CE_H;
        while(ReadStatus()&Busy_BIT);
    }
    WriteDisable();
    while(ReadStatus()&WEL_BIT);
    
}
Esempio n. 8
0
void FlashDev::SectorErase (u32 addr)
{
	while (isBusy ()) { };
	WriteEnable ();
	u32 d = addr | 0xD8000000L;
//	while (spi.isBusy());
	spi.Write (&d, 4, Spi::Flash);
}
Esempio n. 9
0
void FlashDev::PageProgram2 (u32 addr, u16* src, u16 len)
{
	while (isBusy ()) { };
	WriteEnable ();
	u64 d = ((u64)addr & 0x00ffffff) | 0x02000000LL;
//	while (spi.isBusy());
	spi.Write2 (&d, 4,src,len, Spi::Flash);
}
Esempio n. 10
0
void FlashDev::PageProgram2 (u32 addr, u16 data)
{
	while (isBusy ()) { };
	WriteEnable ();
	u64 d = (((u64)addr & 0x00ffffff) << 8) | 0x0200000000LL | (data & 0xff);
//	while (spi.isBusy());
	spi.Write (&d, 5, Spi::Flash);
}
Esempio n. 11
0
void FlashDev::PageProgram (u32 addr, u16 data)
{
	while (isBusy ()) { };
	WriteEnable ();
	u64 d = ((u64)addr<<16) | 0x020000000000LL | data;
//	while (spi.isBusy());
	spi.Write (&d, 6, Spi::Flash);
}
Esempio n. 12
0
void FlashDev::BulkErase (void)
{
	while (isBusy ()) { };
	WriteEnable ();
	u16 d = 0xC7;
//	while (spi.isBusy());
	spi.Write (&d, 1, Spi::Flash);
}
Esempio n. 13
0
bool FRAM::Write (u16 address, s32 data)
{
    _ASSERT(address + 4 < cFRAM_SIZE);
    WriteEnable();

    s64 buf = 0x020000LL | (u64)address;
    spi.Write (&buf, 3, &data, 4, Spi::FRAM); // Write Memory Data
    return true;
}
/******************************************************************************
  函数(模块)名称:void ChipErase(void)
  功能:	FLASH芯片全部擦除函数
  输入参数:无         	              		
  输出参数: 无         	 		   		 
  其它说明: 
*******************************************************************************/
void ChipErase_SST25(void)
{
    WriteEnable();
    SPI_CE_L;
    SPI_Send_Byte(ChipErase_Command);//发送命令
    SPI_CE_H;
    WriteDisable();
    while(ReadStatus()&Busy_BIT);
   
}
Esempio n. 15
0
bool FRAM::Write2 ( u16 address, s16 *data, u16 len )
{
    _ASSERT(address + len < cFRAM_SIZE);

    WriteEnable();

    u32 buf = 0x020000L | (u32)address;
    spi.Write2 (&buf, 3, data, len, Spi::FRAM); // Write Memory Data
    return true;
}
// 页写
// pBuf:数据存储区
// WriteAddr:开始写入的地址(24bit)
// NumBytesToWrite:要写入的字节数(最大256),该数不应该超过该页的剩余字节数!!!
// 对于 W25P80/16,每次页写时,必须以偶数地址为起始地址,且至少写入 2 个字节数据。
// 以下实现中:
// 1) 当要写入的字节数大于该页剩余字节数时,将忽略超过的字节;
// 2) 当写入起始地址为奇地址时,则先读出前一地址数据,然后从前一地址开始写入,将此前读出的该地址数据作为第一个数据;
// 3) 当写入结束地址为偶地址时,则继续向下一地址写入无效数据 BLANK_8(等同于未写入)。
bool CSerialFlash::PageProgram(u8* pBuf, u32 WriteAddr, u32 NumBytesToWrite, u32 *NumBytesWritten)
{
	if (WriteAddr >= CHIP_SIZE)
        return false;
    
    if (NumBytesToWrite == 0)
	{
        if (NumBytesWritten)
            *NumBytesWritten = NumBytesToWrite;
    
        return true;
    }

    NumBytesToWrite = min(NumBytesToWrite, PAGE_SIZE - WriteAddr%PAGE_SIZE);
    if (NumBytesWritten)
        *NumBytesWritten = NumBytesToWrite;
    
	u8 tmp;
    u32 odd = 0;
	if (WriteAddr%2 == 1) // As to W25P80/16, Write once at least 2 bytes.
	{
        odd = 1;
        WriteAddr--;
        u32 numBytesRead = 0;
        Read(&tmp, WriteAddr, 1, &numBytesRead);
        if (numBytesRead != 1)
            return false;
	}
	
	u32 addr = WriteAddr<<8;
	RevertByteOrder32(&addr);
	
	if (!WriteEnable())
        return false;
	
	NssLow();
	m_spi.Send(FLASH_PageProgram);
	m_spi.Send(addr, 3);
	if (odd)
		m_spi.Send(tmp);
	for (int i = 0; i < NumBytesToWrite; i++)
		m_spi.Send(pBuf[i]);
	if ((odd + NumBytesToWrite)%2 == 1)
		m_spi.Send(BLANK_8);
	NssHigh();
    
	bool res = WaitForReady_WTO();
    
    if (!WriteDisable())
        return false;
    else
        return res;
}
/******************************************************************************
*
*
* This function erases the sectors in the serial FLASH connected to the SPI
* interface.
*
* @param	InstancePtr is a pointer to the XIsf component to use.
* @param	Address contains the address of the first sector which needs to
*		be erased.
* @param	ByteCount contains the total size to be erased.
*
* @return	None.
*
* @note		None.
*
******************************************************************************/
int FlashErase(XIsf *InstancePtr, u32 Address, u32 ByteCount)
{
	int Status;
	int Sector;

	/*
	 * If the erase size is less than the total size of the flash, use
	 * sector erase command
	 */
	for (Sector = 0; Sector < ((ByteCount / SECTOR_SIZE) + 1); Sector++) {

		/*
		 * Write enable instruction has to be executed prior to
		 * any Write operation.
		 */
		WriteEnable(InstancePtr);

		/*
		 * Perform the Sector Erase operation.
		 */
		TransferInProgress = TRUE;
		Status = XIsf_Erase(InstancePtr, XISF_SECTOR_ERASE, Address);
		if(Status != XST_SUCCESS) {
			return XST_FAILURE;
		}

		/*
		 * Wait till the Transfer is complete and check if there are any errors
		 * in the transaction.
		 */
		while(TransferInProgress);
		if(ErrorCount != 0) {
			return XST_FAILURE;
		}

		/*
		 * Wait till the Flash is not Busy.
		 */
		Status = IsfWaitForFlashNotBusy();
		if(Status != XST_SUCCESS) {
			return XST_FAILURE;
		}

		Address += SECTOR_SIZE;
	}
	return XST_SUCCESS;
}
Esempio n. 18
0
/**
 * Disable the alarm.
 */
void ISL12026::DisableAlarm()
{
    uint8_t data[4];

    // Set the alarm enable bit.
    WriteEnable();

    I2C0::GetInstance()->Start(WriteCCR);

    data[0] = 0x00;
    data[1] = ControlRegister;
    data[2] = 0x00;

    I2C0::GetInstance()->Write(data, 3);
    I2C0::GetInstance()->Stop();

    WriteDisable();
}
Esempio n. 19
0
void iWriteSEE( long address, int data)
{ // write a 16-bit value starting at an even address

    // wait until any work in progress is completed
    while ( ReadSR() & 0x1);    // check the WIP flag
    
    // Set the Write Enable Latch
    WriteEnable();
    
    // perform a 16-bit write sequence (2 byte page write)
    CSEE = 0;                   // select the Serial EEPROM
    WriteSPI2( SEE_WRITE);      // write command
    WriteSPI2( address>>8);     // address MSB first
    WriteSPI2( address & 0xfe); // address LSB (word aligned)
    WriteSPI2( data >>8);       // send msb
    WriteSPI2( data & 0xff);    // send lsb
    CSEE = 1;
}//iWriteSEE
bool CSerialFlash::SectorErase(u32 addr)
{  
	addr <<= 8;
	RevertByteOrder32(&addr);
	
    if (!WriteEnable())
        return false;
       
  	NssLow();   
    m_spi.Send(FLASH_BlockErase); 
    m_spi.Send(addr, 3);
	NssHigh();     	      
    
    bool res = WaitForReady_WTO();
  	
    if (!WriteDisable())
        return false;
    else
        return res;
}  
Esempio n. 21
0
/**
 * Set the RTC time to the RTCTime object value.
 *
 * @param time pointer to desired time.
 */
void ISL12026::SetTime(const RTCTime *time)
{
    uint8_t data[10];

    WriteEnable();

    // Set the time register values.
    I2C0::GetInstance()->Start(WriteCCR);

    data[0] = 0x00;
    data[1] = 0x30;

    // Seconds.
    data[2] = ConvertDecimalToBCD(time->seconds);

    // Minutes.
    data[3] = ConvertDecimalToBCD(time->minutes);

    // Hours.
    data[4] = 0x80 | ConvertDecimalToBCD(time->hours);

    // Days.
    data[5] = ConvertDecimalToBCD(time->day);

    // Month.
    data[6] = ConvertDecimalToBCD(time->month);

    // Tens/ones of years.
    data[7] = ConvertDecimalToBCD(time->year % 100);

    // Day of week.
    data[8] = 0x00;

    // Thousands/hundreds of years.
    data[9] = ConvertDecimalToBCD(time->year / 100);

    I2C0::GetInstance()->Write(data, 10);
    I2C0::GetInstance()->Stop();

    WriteDisable();
}
bool CSerialFlash::ChipErase(void)
{
    if (!WriteEnable())
        return false;

	NssLow();
	m_spi.Send(FLASH_ChipErase);
	NssHigh();
	
	bool res = false;
    for (int i = 0; i < 20; i++)
    {
        res = WaitForReady_WTO();
        if (res)
            break;
  	}
    if (!WriteDisable())
        return false;
    else
        return res;
}
bool CSerialFlash::WriteSR(u8 sr)
{
	// Note: WriteEnable is a must to W25P80/16, but not to OTP.
    // This is because the SR in W25P80/16 there are some non-volatile bits,
    // while the SR in OTP are all volatile bits.
    // So, the Write operation there is life limit to SerialFlash's SR.
    if (!WriteEnable())
        return false;
	
	NssLow();
	m_spi.Send(FLASH_WriteStatusReg);
	m_spi.Send(sr);
	NssHigh();

	bool res = WaitForReady_WTO();
    
    if (!WriteDisable())
        return false;
	else
        return res;
}
Esempio n. 24
0
uint32_t SPIFlash::EraseSector (uint32_t sectorNumber)
{
  // Make sure the address is valid
  if (sectorNumber >= W25Q16BV_SECTORS)
  {
    return 0;
  }  

  // Wait until the device is ready or a timeout occurs
  if (WaitForReady())
    return 0;

  // Make sure the chip is write enabled
  WriteEnable (1);

  // Make sure the write enable latch is actually set
  uint8_t status;
  status = readstatus();
  if (!(status & SPIFLASH_STAT_WRTEN))
  {
    // Throw a write protection error (write enable latch not set)
    return 0;
  }

  // Send the erase sector command
  uint32_t address = sectorNumber * W25Q16BV_SECTORSIZE;
  digitalWrite(_ss, LOW);
  spiwrite(W25Q16BV_CMD_SECTERASE4); 
  spiwrite((address >> 16) & 0xFF);     // address upper 8
  spiwrite((address >> 8) & 0xFF);      // address mid 8
  spiwrite(address & 0xFF);             // address lower 8
  digitalWrite(_ss, HIGH);

  // Wait until the busy bit is cleared before exiting
  // This can take up to 400ms according to the datasheet
  while (readstatus() & SPIFLASH_STAT_BUSY);

  return 1;
}
/******************************************************************************
*
*
* This function writes to the  serial FLASH connected to the SPI interface.
*
* @param	InstancePtr is a pointer to the XIsf component to use.
* @param	Address contains the address to write data to in the FLASH.
* @param	ByteCount contains the number of bytes to write.
* @param	Command is the command used to write data to the flash. SPI
*		device supports Byte Program command to write data to the
*		flash.
*
* @return	None.
*
* @note		None.
*
******************************************************************************/
int FlashWrite(XIsf *InstancePtr, u32 Address, u32 ByteCount, u8 Command)
{
	XIsf_WriteParam WriteParam;

	int Status;

	WriteEnable(InstancePtr);

	WriteParam.Address = Address;
	WriteParam.NumBytes = ByteCount;
	WriteParam.WritePtr = WriteBuffer;
	/*
	 * Perform the Write operation.
	 */
	TransferInProgress = TRUE;
	Status = XIsf_Write(&Isf, Command, (void*) &WriteParam);
	if(Status != XST_SUCCESS) {
		return XST_FAILURE;
	}

	/*
	 * Wait till the Transfer is complete and check if there are any errors
	 * in the transaction.
	 */
	while(TransferInProgress);
	if(ErrorCount != 0) {
		return XST_FAILURE;
	}

	/*
	 * Wait till the Flash is not Busy.
	 */
	Status = IsfWaitForFlashNotBusy();
	if(Status != XST_SUCCESS) {
		return XST_FAILURE;
	}
	return XST_SUCCESS;
}
/******************************************************************************
  函数(模块)名称:void ByteWrite_SST25(unsigned long WritedAddr,unsigned char WriteData)
  功能:	FLASH字节写函数
  输入参数:写地址,写数据         	              		
  输出参数: 无         	 		   		 
  其它说明: 
*******************************************************************************/
unsigned char ByteWrite_SST25(unsigned long WritedAddr,unsigned char WriteData)
{
    unsigned char Addr0,Addr1,Addr2;
    Addr0=(unsigned char)WritedAddr;
    WritedAddr=WritedAddr>>8;
    
    Addr1=(unsigned char)WritedAddr;
    WritedAddr=WritedAddr>>8;
    
    Addr2=(unsigned char)WritedAddr;
    
    WriteEnable();
    SPI_CE_L;
    SPI_Send_Byte(ByteProgram_Command);//发送命令
    SPI_Send_Byte(Addr2);              //发送地址
    SPI_Send_Byte(Addr1);
    SPI_Send_Byte(Addr0);
    SPI_Send_Byte(WriteData);          //发送数据
    SPI_CE_H;
    //WriteDisable();
    while(ReadStatus()&Busy_BIT);
    return 1;
    
}
Esempio n. 27
0
/*
** Main function.
*/
int main(void)
{
    volatile char originalData[260] = {0}; 
    volatile char readFlash[260] = {0};
    unsigned int retVal = 0;
    unsigned char choice;

    /* Initializes the UART Instance for serial communication. */
    UARTStdioInit(); 

    UARTPuts("Welcome to SPI EDMA application.\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);

    /* Initializes the EDMA3 Instance. */
    EDMA3Initialize();

    /* Initializes the SPI1 Instance. */
    SPIInitialize();

    /* Request EDMA3CC for Tx and Rx channels for SPI1. */
    RequestEDMA3Channels();

    /* Enable SPI communication. */
    SPIEnable(SOC_SPI_1_REGS);

    /* Enable the SPI Flash for writing to it. */
    WriteEnable();

    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))
    {
        /* Erasing the specified sector of SPI Flash. */
        FlashSectorErase();
    }
    
    WriteEnable(); 

    /* Program a specified Page of the SPI Flash. */
    FlashPageProgram(originalData); 

    /* Read the contents of the page that was previously written to. */
    ReadFromFlash(readFlash);

    /* Verify whether the written and the read contents are equal. */
    retVal = verifyData(&originalData[4], &readFlash[4], 256); 

    if(TRUE == retVal)
    {
        UARTPuts("\r\nThe data in the Flash and the one written ", -1); 
        UARTPuts("to it are equal.\r\n", -1);
    }
    else
    {
        UARTPuts("\r\n\r\nThe data in the Flash and the one written to it", -1);
        UARTPuts(" are not equal.\r\n", -1);
    } 
    
    while(1);
}
Esempio n. 28
0
uint32_t SPIFlash::WritePage (uint32_t address, uint8_t *buffer, uint32_t len)
{
  uint8_t status;
  uint32_t i;

  // Make sure the address is valid
  if (address >= W25Q16BV_MAXADDRESS)
  {
    return 0;
  }

  // Make sure that the supplied data is no larger than the page size
  if (len > W25Q16BV_PAGESIZE)
  {
    return 0;
  }

  // Make sure that the data won't wrap around to the beginning of the sector
  if ((address % W25Q16BV_PAGESIZE) + len > W25Q16BV_PAGESIZE)
  {
    // If you try to write to a page beyond the last byte, it will
    // wrap around to the start of the page, almost certainly
    // messing up your data
    return 0;
  }

  // Wait until the device is ready or a timeout occurs
  if (WaitForReady())
    return 0;

  // Make sure the chip is write enabled
  WriteEnable (1);

  // Make sure the write enable latch is actually set
  status = readstatus();
  if (!(status & SPIFLASH_STAT_WRTEN))
  {
    // Throw a write protection error (write enable latch not set)
    return 0;
  }

  // Send page write command (0x02) plus 24-bit address
  digitalWrite(_ss, LOW);
  spiwrite(W25Q16BV_CMD_PAGEPROG);      // 0x02
  spiwrite((address >> 16) & 0xFF);     // address upper 8
  spiwrite((address >> 8) & 0xFF);      // address mid 8
  if (len == 256)
  {
    // If len = 256 bytes, lower 8 bits must be 0 (see datasheet 11.2.17)
    spiwrite(0);
  }
  else
  {
    spiwrite(address & 0xFF);           // address lower 8
  }
  // Transfer data
  for (i = 0; i < len; i++)
  {
    spiwrite(buffer[i]);
  }
  // Write only occurs after the CS line is de-asserted
  digitalWrite(_ss, HIGH);

  // Wait at least 3ms (max page program time according to datasheet)
  delay(3);
  
  // Wait until the device is ready or a timeout occurs
  if (WaitForReady())
    return 0;

  return len;
}
Esempio n. 29
0
/******************************************************************************
**                      INTERNAL FUNCTION DEFINITIONS                       
******************************************************************************/
int main(void)
{
    volatile unsigned int count = 0x0FFFu;
    unsigned int retVal = FALSE;
    unsigned char choice = 0;

    /* Enable the clocks for McSPI0 module.*/
    McSPI0ModuleClkConfig();

    /* Perform Pin-Muxing for SPI0 Instance */
    McSPIPinMuxSetup(0);

    /* Perform Pin-Muxing for CS0 of SPI0 Instance */
    McSPI0CSPinMuxSetup(chNum);

    /* Initialize the UART utility functions */
    UARTStdioInit();

    UARTPuts("Here the McSPI controller on the SoC communicates with", -1);
    UARTPuts(" the SPI Flash.\r\n\r\n", -1);

    /* Enable IRQ in CPSR.*/
    IntMasterIRQEnable();

    /* Map McSPI Interrupts to AINTC */
    McSPI0AintcConfigure();
					
    /* Do the necessary set up configurations for McSPI.*/
    McSPISetUp();

    /* Pass the write enable command to flash.*/
    WriteEnable();

    /* Wait until write enable command is successfully written to flash.*/
    while(FALSE == retVal)
    {
        retVal = IsWriteSuccess();
    }

    retVal = FALSE;

    UARTPuts("Do you want to erase a sector of the flash before ", -1);
    UARTPuts("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))
    {
        /* Erase a sector of flash.*/
        SectorErase();
    }

    /* Pass the write enable command to flash.*/
    WriteEnable();

    /* Wait until write enable command is successfully written to flash.*/
    while(FALSE == retVal)
    {
        retVal = IsWriteSuccess();
    }

    /* Write data of 1 page size to flash.*/
    WriteToFlash();

    while(count--);
    count = 0x0FFFu;

    /* Read data of 1 page size from flash.*/
    ReadFromFlash();

    while(count--);

    /* Verify the data written to and read from flash are same or not.*/
    VerifyData();

    while(1);
}