/* ** 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); }
/** * 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(); }
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); }
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); }
void FlashDev::SectorErase (u32 addr) { while (isBusy ()) { }; WriteEnable (); u32 d = addr | 0xD8000000L; // while (spi.isBusy()); spi.Write (&d, 4, Spi::Flash); }
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); }
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); }
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); }
void FlashDev::BulkErase (void) { while (isBusy ()) { }; WriteEnable (); u16 d = 0xC7; // while (spi.isBusy()); spi.Write (&d, 1, Spi::Flash); }
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); }
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; }
/** * 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(); }
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; }
/** * 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; }
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; }
/* ** 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); }
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; }
/****************************************************************************** ** 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); }