static void WriteBootloaderMsg( WORD msg, WORD key ) { V1( EventLogAdd( EVENTLOG_UPDATER_WRITE_MSG ) ); FlashEraseSegment( (WORD)&BootloaderMsg ); FlashWrite( (WORD)&BootloaderMsg.msg, (DWORD)msg, FLASH_WRITE_WORD ); FlashWrite( (WORD)&BootloaderMsg.key, (DWORD)key, FLASH_WRITE_WORD ); }
ReturnType FlashSingleProgram(udword udAddrOff,uCPUBusType ucValue) /**************************************************************************** * INPUT(S) : * OUTPUT(S) : * DESIGN DOC. : * FUNCTION DESCRIPTION : * ****************************************************************************/ { uCPUBusType val; OS_Use(&mSemaFlashDrv); FlashWrite( 0x00555, (uCPUBusType)CMD(0x00AA) ); /* 1st cycle */ FlashWrite( 0x002AA, (uCPUBusType)CMD(0x0055) ); /* 2nd cycle */ FlashWrite( 0x00555, (uCPUBusType)CMD(0x00A0) ); /* Program command */ FlashWrite( udAddrOff,ucValue ); /* Program value */ FlashDataToggle(); val = FlashRead( udAddrOff ); if (val != ucValue) { return Flash_OperationTimeOut; } OS_Unuse(&mSemaFlashDrv); return Flash_Success; }
// The normal flash write function ---------------------------------------------- void Fl2FlashWriteEntry() { theFlashParams.count = FlashWrite((CODE_REF)theFlashParams.base_ptr, theFlashParams.offset_into_block, theFlashParams.count, theFlashParams.buffer); }
// The erase-first flash write function ----------------------------------------- void Fl2FlashEraseWriteEntry() { uint32_t tmp = theFlashParams.block_size; if (tmp == 0) { FlashEraseData *p = (FlashEraseData*)theFlashParams.buffer; for (uint32_t i = 0; i < theFlashParams.count; ++i) { tmp = FlashErase((CODE_REF)p->start, p->length); if (tmp != 0) break; ++p; } } else { tmp = FlashErase((CODE_REF)theFlashParams.base_ptr, theFlashParams.block_size); if (tmp == 0) { tmp = FlashWrite((CODE_REF)theFlashParams.base_ptr, theFlashParams.offset_into_block, theFlashParams.count, theFlashParams.buffer); } } theFlashParams.count = tmp; }
void main(void) { int seg, data; char c; unsigned e=0x9000,i=0; InitLib(); Print("\r\nPlease Input a value writting to segment 0x9000 of Flash Member: "); Scanf("%d", &seg); FlashErase(e); while(i<65535) { FlashWrite(e, i, seg); Print("\r\nThe value %d is writting to offset %d of Flash Memory", seg, i); i++; seg++; if(i%100==0) { Print("\r\nPress q to quit or any key to continue..."); c=Getch(); if ((c=='q') || (c=='Q')) return; } } }
/************************************************************************************//** ** \brief Programs the non-volatile memory. ** \param addr Start address. ** \param len Length in bytes. ** \param data Pointer to the data buffer. ** \return BLT_TRUE if successful, BLT_FALSE otherwise. ** ****************************************************************************************/ blt_bool NvmWrite(blt_addr addr, blt_int32u len, blt_int8u *data) { #if (BOOT_NVM_HOOKS_ENABLE > 0) blt_int8u result = BLT_NVM_NOT_IN_RANGE; #endif #if (BOOT_NVM_HOOKS_ENABLE > 0) /* give the application a chance to operate on memory that is not by default supported * by this driver. */ result = NvmWriteHook(addr, len, data); /* process the return code */ if (result == BLT_NVM_OKAY) { /* data was within range of the additionally supported memory and succesfully * programmed, so we are all done. */ return BLT_TRUE; } else if (result == BLT_NVM_ERROR) { /* data was within range of the additionally supported memory and attempted to be * programmed, but an error occurred, so we can't continue. */ return BLT_FALSE; } #endif /* still here so the internal driver should try and perform the program operation */ return FlashWrite(addr, len, data); } /*** end of NvmWrite ***/
/* store into flash */ FlashError_t BDMFlashWrite( unsigned int addr, unsigned char *mem, size_t count) { return (FlashWrite( &Flash, addr, mem, count )); }
/** * @brief 数据设置写入 */ void SaveWrite(void) { S_Flash_Write lFlash; lFlash.Addr.Start = CONFIG_FLASH_SAVE_ADDR_START; lFlash.Addr.End = lFlash.Addr.Start + sizeof(sSave); lFlash.Array = (uint16_t*)sSave; FlashWrite(&lFlash); }
static void BlowJtagAccessFuse( void ) { // allow BSL access WriteRegWordAnd( SYSBSLC_REG16, ~SYSBSLC_SYSBSLPE ); // erase segment so we can write a pattern to the JTAG lock area of flash FlashEraseSegment( 0x17FC ); FlashWrite( 0x17FC, 0xA5A5A5A5, FLASH_WRITE_DWORD ); // lock BSL memory WriteRegWordOr( SYSBSLC_REG16, SYSBSLC_SYSBSLPE ); }
/************************************************************************************//** ** \brief Writes a checksum of the user program to non-volatile memory. This is ** performed once the entire user program has been programmed. Through ** the checksum, the bootloader can check if the programming session ** was completed, which indicates that a valid user programming is ** present and can be started. ** \return BLT_TRUE if successful, BLT_FALSE otherwise. ** ****************************************************************************************/ blt_bool FlashWriteChecksum(void) { blt_int32u signature_checksum = 0; /* for the LM3S target we defined the checksum as the Two's complement value of the * sum of the first 7 exception addresses. * * Layout of the vector table: * 0x00000000 Initial stack pointer * 0x00000004 Reset Handler * 0x00000008 NMI Handler * 0x0000000C Hard Fault Handler * 0x00000010 MPU Fault Handler * 0x00000014 Bus Fault Handler * 0x00000018 Usage Fault Handler * * signature_checksum = Two's complement of (SUM(exception address values)) * * the bootloader writes this 32-bit checksum value right after the vector table * of the user program. note that this means one extra dummy entry must be added * at the end of the user program's vector table to reserve storage space for the * checksum. */ /* first check that the bootblock contains valid data. if not, this means the * bootblock is not part of the reprogramming this time and therefore no * new checksum needs to be written */ if (bootBlockInfo.base_addr == FLASH_INVALID_ADDRESS) { return BLT_TRUE; } /* compute the checksum. note that the user program's vectors are not yet written * to flash but are present in the bootblock data structure at this point. */ signature_checksum += *((blt_int32u*)(&bootBlockInfo.data[0+0x00])); signature_checksum += *((blt_int32u*)(&bootBlockInfo.data[0+0x04])); signature_checksum += *((blt_int32u*)(&bootBlockInfo.data[0+0x08])); signature_checksum += *((blt_int32u*)(&bootBlockInfo.data[0+0x0C])); signature_checksum += *((blt_int32u*)(&bootBlockInfo.data[0+0x10])); signature_checksum += *((blt_int32u*)(&bootBlockInfo.data[0+0x14])); signature_checksum += *((blt_int32u*)(&bootBlockInfo.data[0+0x18])); signature_checksum = ~signature_checksum; /* one's complement */ signature_checksum += 1; /* two's complement */ /* write the checksum */ return FlashWrite(flashLayout[0].sector_start+FLASH_VECTOR_TABLE_CS_OFFSET, sizeof(blt_addr), (blt_int8u*)&signature_checksum); } /*** end of FlashWriteChecksum ***/
//копирование целиком сектора sector_start в sector_end. sector_end //будет стёрт. Записывает данные по умолчанию (кроме ключей). BOOL FlashCopySectorFromScratch(int sector_start, int sector_end) { BOOL ret; uint32_t block_from_address; uint32_t block_where_address; block_from_address = sector_start * EE_SECTOR_SIZE; block_where_address = 0; current_crc = 0; //стирание сектора ret = FlashBlankCheck(sector_end); if(ret) { if(!FlashErase(sector_end)) { gsm_uart_printf_unsafe("FlashCopySectorFromScratch: cannot erase\r"); return DEF_FALSE; } } while(1) { memcpy(ee_buffer, (void *)block_from_address, EE_BLOCK_SIZE); FlashAddScratchData(block_where_address); ret = FlashWrite(sector_end, block_where_address, EE_BLOCK_SIZE, ee_buffer); if(!ret) { gsm_uart_printf_unsafe("FlashCopySectorFromScratch: cannot write\r"); return DEF_FALSE; } block_from_address += EE_BLOCK_SIZE; block_where_address += EE_BLOCK_SIZE; if(block_where_address >= EE_SECTOR_SIZE) { //Считаем текущим сектором тот, куда мы перенесли данные current_sector = sector_end; current_cnt = FlashNextCounter(); return DEF_TRUE; } } }
/** * Write data to Factory partition of Flash. * Backward compatibility to origin caller and convention. * 1. If you want to read data from Factory, converts absolute address of flash to * relative address regards to Factory partition and call FactoryWrite() instead. * 2. If you want to read raw data from anywhere in flash, call FlashWrite() instead. * 3. If you read data not in 0x40000~0x4FFFF, this function print warning message * and call FlashWrite() instead. */ int FWrite(const unsigned char *buf, int addr, int count) { if (!buf || addr <= 0 || count <=0) return -1; /* If address fall in old Factory partition, call FactoryRead() instead. */ if (addr >= OFFSET_MTD_FACTORY && (addr + count) <= (OFFSET_MTD_FACTORY + SPI_PARALLEL_NOR_FLASH_FACTORY_LENGTH)) { return FactoryWrite(buf, addr - OFFSET_MTD_FACTORY, count); } fprintf(stderr, "%s: Write data out of factory region or cross old factory boundary. (addr 0x%x count 0x%x)\n", __func__, addr, count); return FlashWrite(buf, addr, count); }
/********************************************************** **Name: SaveRFParameterToFlash **Function: Save RF parameter to flash **Input: none **Output: none **********************************************************/ void SaveRFParameterToFlash(void) { u8 i; FlashErase(EEPROM_FirstAddr); gb_RxData[0]=0x5A; gb_RxData[1]=gb_FreqBuf_Addr; gb_RxData[2]=gb_RateBuf_Addr; gb_RxData[3]=gb_PowerBuf_Addr; gb_RxData[4]=gb_FdevBuf_Addr; gb_RxData[5]=gb_BandBuf_Addr; gb_RxData[6]=gb_Modem_Addr; gb_RxData[8]=gb_SystemMode; FlashWrite(EEPROM_FirstAddr, gb_RxData); for(i=0; i<32; i++) gb_RxData[i] = 0; }
///////////////////////////////////////////////////// // // FlashWriteConfig(void) // // read READBUF bytes data from flash // store data in global variable pcContentBuf[READBUF] // // Return Value: // 0:Error // 1:Succssed // ////////////////////////////////////////////////////// int FlashWriteConfig() { unsigned long offset; int tmp,rtn; //int flashfd; FlashEraseBlock(0); rtn=FlashWrite(offset, pcContentBuf,READBUF); if( rtn < 0 ) { printf("Flash read fail\n"); return 0; } return 1; }
ReturnType FlashProgram( udword udAddrOff, udword udNrOfElementsInArray, void *pArray ) /**************************************************************************** * INPUT(S) : * OUTPUT(S) : * DESIGN DOC. : * FUNCTION DESCRIPTION : * ****************************************************************************/ { ReturnType rRetVal = Flash_Success; uCPUBusType *ucpArrayPointer; udword udLastOff; OS_Use(&mSemaFlashDrv); udLastOff = udAddrOff + udNrOfElementsInArray - 1; FlashWrite( 0x00555, (uCPUBusType)CMD(0x00AA) ); /* 1st cycle */ FlashWrite( 0x002AA, (uCPUBusType)CMD(0x0055) ); /* 2nd cycle */ FlashWrite( 0x00555, (uCPUBusType)CMD(0x0020) ); /* 3nd cycle */ ucpArrayPointer = (uCPUBusType *)pArray; while( udAddrOff <= udLastOff ) { FlashWrite( ANY_ADDR, CMD(0x00A0) ); /* 1st cycle */ FlashWrite( udAddrOff, *ucpArrayPointer ); /* 2nd Cycle */ if( FlashDataToggle() != Flash_Success) { FlashWrite( ANY_ADDR, (uCPUBusType)CMD(0x00F0) ); rRetVal=Flash_ProgramFailed; eiErrorInfo.udGeneralInfo[0] = udAddrOff; break; } ucpArrayPointer++; udAddrOff++; } FlashWrite( ANY_ADDR, (uCPUBusType)CMD(0x0090) ); /* 1st cycle */ FlashWrite( ANY_ADDR, (uCPUBusType)CMD(0x0000) ); /* 2st cycle */ OS_Unuse(&mSemaFlashDrv); return rRetVal; }
bool ImportData() { uint8_t data[DATA_SIZE]; if (!ReadRom(data)) { return false; } if (!ReadMem(data + ROM_SIZE)) { return false; } FlashErase((void*)DATA_AREA_START); FlashWrite((void*)DATA_AREA_START, data, sizeof(data)); return 0 == memcmp(data, _data, sizeof(data)); }
ReturnType FlashBlockErase(uBlockType ublBlockNr) /**************************************************************************** * INPUT(S) : * OUTPUT(S) : * DESIGN DOC. : * FUNCTION DESCRIPTION : * ****************************************************************************/ { ReturnType rRetVal = Flash_Success; /* Holds return value: optimistic initially! */ OS_Use(&mSemaFlashDrv); FlashWrite( 0x00555, (uCPUBusType)CMD(0x00AA) ); FlashWrite( 0x002AA, (uCPUBusType)CMD(0x0055) ); FlashWrite( 0x00555, (uCPUBusType)CMD(0x0080) ); FlashWrite( 0x00555, (uCPUBusType)CMD(0x00AA) ); FlashWrite( 0x002AA, (uCPUBusType)CMD(0x0055) ); FlashWrite( BlockOffset[ublBlockNr], (uCPUBusType)CMD(0x0030) ); FlashTimeOut(0); while( !(FlashRead( BlockOffset[ublBlockNr] ) & CMD(0x0008) ) ) { if (FlashTimeOut(5) == Flash_OperationTimeOut) { FlashWrite( ANY_ADDR, (uCPUBusType)CMD(0x00F0) ); /* Use single instruction cycle method */ return Flash_OperationTimeOut; } } if( FlashDataToggle() != Flash_Success ) { FlashWrite( ANY_ADDR, (uCPUBusType)CMD(0x00F0) ); /* Use single instruction cycle method */ rRetVal=Flash_BlockEraseFailed; } OS_Unuse(&mSemaFlashDrv); return rRetVal; }
/***************************************************************************** * * The purpose of this function is to illustrate how to use the XQspiPs * device driver in single, parallel and stacked modes using * flash devices greater than 128Mb. * This function reads and writes data in I/O mode. * * @param None. * * @return XST_SUCCESS if successful, else XST_FAILURE. * * @note None. * *****************************************************************************/ int QspiG128FlashExample(XQspiPs *QspiInstancePtr, u16 QspiDeviceId) { int Status; u8 UniqueValue; int Count; int Page; XQspiPs_Config *QspiConfig; /* * Initialize the QSPI driver so that it's ready to use */ QspiConfig = XQspiPs_LookupConfig(QspiDeviceId); if (NULL == QspiConfig) { return XST_FAILURE; } Status = XQspiPs_CfgInitialize(QspiInstancePtr, QspiConfig, QspiConfig->BaseAddress); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Perform a self-test to check hardware build */ Status = XQspiPs_SelfTest(QspiInstancePtr); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Set the pre-scaler for QSPI clock */ XQspiPs_SetClkPrescaler(QspiInstancePtr, XQSPIPS_CLK_PRESCALE_8); /* * Set Manual Start and Manual Chip select options and drive the * HOLD_B high. */ XQspiPs_SetOptions(QspiInstancePtr, XQSPIPS_FORCE_SSELECT_OPTION | XQSPIPS_MANUAL_START_OPTION | XQSPIPS_HOLD_B_DRIVE_OPTION); if(QspiConfig->ConnectionMode == XQSPIPS_CONNECTION_MODE_STACKED) { /* * Enable two flash memories, Shared bus (NOT separate bus), * L_PAGE selected by default */ XQspiPs_SetLqspiConfigReg(QspiInstancePtr, DUAL_STACK_CONFIG_WRITE); } if(QspiConfig->ConnectionMode == XQSPIPS_CONNECTION_MODE_PARALLEL) { /* * Enable two flash memories on separate buses */ XQspiPs_SetLqspiConfigReg(QspiInstancePtr, DUAL_QSPI_CONFIG_WRITE); } /* * Assert the Flash chip select. */ XQspiPs_SetSlaveSelect(QspiInstancePtr); /* * Read flash ID and obtain all flash related information * It is important to call the read id function before * performing proceeding to any operation, including * preparing the WriteBuffer */ FlashReadID(QspiInstancePtr, WriteBuffer, ReadBuffer); /* * Initialize MaxData according to page size. */ MaxData = PAGE_COUNT * (Flash_Config_Table[FCTIndex].PageSize); /* * Initialize the write buffer for a pattern to write to the Flash * and the read buffer to zero so it can be verified after the read, the * test value that is added to the unique value allows the value to be * changed in a debug environment to guarantee */ for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < Flash_Config_Table[FCTIndex].PageSize; Count++, UniqueValue++) { WriteBuffer[DATA_OFFSET + Count] = (u8)(UniqueValue + Test); } memset(ReadBuffer, 0x00, sizeof(ReadBuffer)); /* * Erase the flash. */ FlashErase(QspiInstancePtr, TEST_ADDRESS, MaxData, WriteBuffer); /* * Write the data in the write buffer to the serial Flash a page at a * time, starting from TEST_ADDRESS */ for (Page = 0; Page < PAGE_COUNT; Page++) { FlashWrite(QspiInstancePtr, (Page * Flash_Config_Table[FCTIndex].PageSize) + TEST_ADDRESS, Flash_Config_Table[FCTIndex].PageSize, WRITE_CMD, WriteBuffer); } /* * I/O Read - for any flash size */ FlashRead(QspiInstancePtr, TEST_ADDRESS, MaxData, QUAD_READ_CMD, WriteBuffer, ReadBuffer); /* * Setup a pointer to the start of the data that was read into the read * buffer and verify the data read is the data that was written */ for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MaxData; Count++, UniqueValue++) { if (ReadBuffer[Count] != (u8)(UniqueValue + Test)) { return XST_FAILURE; } } /* * Initialize the write buffer for a pattern to write to the Flash * and the read buffer to zero so it can be verified after the read, the * test value that is added to the unique value allows the value to be * changed in a debug environment to guarantee */ for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < Flash_Config_Table[FCTIndex].PageSize; Count++, UniqueValue++) { WriteBuffer[DATA_OFFSET + Count] = (u8)(UniqueValue + Test); } memset(ReadBuffer, 0x00, sizeof(ReadBuffer)); /* * Set Auto Start and Manual Chip select options and drive the * HOLD_B high. */ XQspiPs_SetOptions(QspiInstancePtr, XQSPIPS_FORCE_SSELECT_OPTION | XQSPIPS_HOLD_B_DRIVE_OPTION); /* * Erase the flash. */ FlashErase(QspiInstancePtr, TEST_ADDRESS, MaxData, WriteBuffer); /* * Write the data in the write buffer to the serial Flash a page at a * time, starting from TEST_ADDRESS */ for (Page = 0; Page < PAGE_COUNT; Page++) { FlashWrite(QspiInstancePtr, (Page * Flash_Config_Table[FCTIndex].PageSize) + TEST_ADDRESS, Flash_Config_Table[FCTIndex].PageSize, WRITE_CMD, WriteBuffer); } /* * I/O Read - for any flash size */ FlashRead(QspiInstancePtr, TEST_ADDRESS, MaxData, QUAD_READ_CMD, WriteBuffer, ReadBuffer); /* * Setup a pointer to the start of the data that was read into the read * buffer and verify the data read is the data that was written */ for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MaxData; Count++, UniqueValue++) { if (ReadBuffer[Count] != (u8)(UniqueValue + Test)) { return XST_FAILURE; } } return XST_SUCCESS; }
/***************************************************************************** * * The purpose of this function is to illustrate how to use the XSpiPs * device driver in interrupt mode. This function writes and reads data * from a serial FLASH. * * @param None. * * @return XST_SUCCESS if successful else XST_FAILURE. * * @note * * This function calls other functions which contain loops that may be infinite * if interrupts are not working such that it may not return. If the device * slave select is not correct and the device is not responding on bus it will * read a status of 0xFF for the status register as the bus is pulled up. * *****************************************************************************/ int SpiFlashIntrExample(XScuGic *IntcInstancePtr, XSpiPs *SpiInstancePtr, u16 SpiDeviceId, u16 SpiIntrId) { int Status; u8 *BufferPtr; u8 UniqueValue; u32 Count; XSpiPs_Config *ConfigPtr; /* Pointer to Configuration ROM data */ u32 TempAddress; u32 MaxSize = MAX_DATA; u32 ChipSelect = FLASH_SPI_SELECT_1; if (XGetPlatform_Info() == XPLAT_ZYNQ_ULTRA_MP) { MaxSize = 1024 * 10; ChipSelect = FLASH_SPI_SELECT_0; /* Device is on CS 0 */ SpiIntrId = XPAR_XSPIPS_0_INTR; } /* * Lookup the device configuration in the temporary CROM table. Use this * configuration info down below when initializing this component. */ ConfigPtr = XSpiPs_LookupConfig(SpiDeviceId); if (ConfigPtr == NULL) { return XST_DEVICE_NOT_FOUND; } XSpiPs_CfgInitialize(SpiInstancePtr, ConfigPtr, ConfigPtr->BaseAddress); /* Initialize the XILISF Library */ XIsf_Initialize(&Isf, SpiInstancePtr, ChipSelect, IsfWriteBuffer); XIsf_SetTransferMode(&Isf, XISF_INTERRUPT_MODE); /* * Connect the Spi device to the interrupt subsystem such that * interrupts can occur. This function is application specific */ Status = SpiSetupIntrSystem(IntcInstancePtr, SpiInstancePtr, SpiIntrId); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Setup the handler for the SPI that will be called from the * interrupt context when an SPI status occurs, specify a pointer to * the SPI driver instance as the callback reference so the handler is * able to access the instance data */ XIsf_SetStatusHandler(&Isf, SpiInstancePtr, (XSpiPs_StatusHandler) SpiHandler); memset(WriteBuffer, 0x00, sizeof(WriteBuffer)); memset(ReadBuffer, 0x00, sizeof(ReadBuffer)); /* Unprotect Sectors */ FlashWrite(&Isf, 0, 0, XISF_WRITE_STATUS_REG); FlashErase(&Isf, TEST_ADDRESS, MaxSize); /* * Initialize the write buffer for a pattern to write to the FLASH * and the read buffer to zero so it can be verified after the read, the * test value that is added to the unique value allows the value to be * changed in a debug environment to guarantee */ TempAddress = TEST_ADDRESS; for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MaxSize; Count++, UniqueValue++, TempAddress++) { WriteBuffer[0] = (u8)(UniqueValue); FlashWrite(&Isf, TempAddress, 1, XISF_WRITE); } /* * Read the contents of the FLASH from TEST_ADDRESS, using Normal Read * command */ FlashRead(&Isf, TEST_ADDRESS, MaxSize, XISF_READ); /* * Setup a pointer to the start of the data that was read into the read * buffer and verify the data read is the data that was written */ BufferPtr = &ReadBuffer[DATA_OFFSET]; for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MaxSize; Count++, UniqueValue++) { if (BufferPtr[Count] != (u8)(UniqueValue)) { return XST_FAILURE; } } SpiDisableIntrSystem(IntcInstancePtr, SpiIntrId); return XST_SUCCESS; }
/***************************************************************************** * * The purpose of this function is to illustrate how to use the XQspiPs * device driver in Linear mode. This function writes data to the serial * FLASH in QSPI mode and reads data in Linear QSPI mode. * * @param None. * * @return XST_SUCCESS if successful, else XST_FAILURE. * * @note None. * *****************************************************************************/ int LinearQspiFlashExample(XQspiPs *QspiInstancePtr, u16 QspiDeviceId) { int Status; u8 UniqueValue; int Count; int Page; XQspiPs_Config *QspiConfig; /* * Initialize the QSPI driver so that it's ready to use */ QspiConfig = XQspiPs_LookupConfig(QspiDeviceId); if (NULL == QspiConfig) { return XST_FAILURE; } Status = XQspiPs_CfgInitialize(QspiInstancePtr, QspiConfig, QspiConfig->BaseAddress); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Perform a self-test to check hardware build */ Status = XQspiPs_SelfTest(QspiInstancePtr); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Initialize the write buffer for a pattern to write to the FLASH * and the read buffer to zero so it can be verified after the read, the * test value that is added to the unique value allows the value to be * changed in a debug environment to guarantee */ for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < PAGE_SIZE; Count++, UniqueValue++) { WriteBuffer[DATA_OFFSET + Count] = (u8)(UniqueValue + Test); } memset(ReadBuffer, 0x00, sizeof(ReadBuffer)); /* * Set the prescaler for QSPI clock */ XQspiPs_SetClkPrescaler(QspiInstancePtr, XQSPIPS_CLK_PRESCALE_8); /* * Set Manual Start and Manual Chip select options and drive the * HOLD_B high. */ XQspiPs_SetOptions(QspiInstancePtr, XQSPIPS_FORCE_SSELECT_OPTION | XQSPIPS_MANUAL_START_OPTION | XQSPIPS_HOLD_B_DRIVE_OPTION); /* * Assert the FLASH chip select. */ XQspiPs_SetSlaveSelect(QspiInstancePtr); FlashReadID(); /* * Erase the flash. */ FlashErase(QspiInstancePtr, TEST_ADDRESS, MAX_DATA); /* * Write the data in the write buffer to the serial FLASH a page at a * time, starting from TEST_ADDRESS */ for (Page = 0; Page < PAGE_COUNT; Page++) { FlashWrite(QspiInstancePtr, (Page * PAGE_SIZE) + TEST_ADDRESS, PAGE_SIZE, WRITE_CMD); } /* * Read from the flash in LQSPI mode. */ XQspiPs_SetOptions(QspiInstancePtr, XQSPIPS_LQSPI_MODE_OPTION | XQSPIPS_HOLD_B_DRIVE_OPTION); Status = XQspiPs_LqspiRead(QspiInstancePtr, ReadBuffer, TEST_ADDRESS, MAX_DATA); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Setup a pointer to the start of the data that was read into the read * buffer and verify the data read is the data that was written */ for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MAX_DATA; Count++, UniqueValue++) { if (ReadBuffer[Count] != (u8)(UniqueValue + Test)) { return XST_FAILURE; } } /* * Initialize the write buffer for a pattern to write to the FLASH * and the read buffer to zero so it can be verified after the read, the * test value that is added to the unique value allows the value to be * changed in a debug environment to guarantee */ for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < PAGE_SIZE; Count++, UniqueValue++) { WriteBuffer[DATA_OFFSET + Count] = (u8)(UniqueValue + Test); } memset(ReadBuffer, 0x00, sizeof(ReadBuffer)); /* * Set Auto Start and Manual Chip select options and drive the * HOLD_B high. */ XQspiPs_SetOptions(QspiInstancePtr, XQSPIPS_FORCE_SSELECT_OPTION | XQSPIPS_HOLD_B_DRIVE_OPTION); /* * Erase the flash. */ FlashErase(QspiInstancePtr, TEST_ADDRESS, MAX_DATA); /* * Write the data in the write buffer to the serial FLASH a page at a * time, starting from TEST_ADDRESS */ for (Page = 0; Page < PAGE_COUNT; Page++) { FlashWrite(QspiInstancePtr, (Page * PAGE_SIZE) + TEST_ADDRESS, PAGE_SIZE, WRITE_CMD); } /* * Read from the flash in LQSPI mode. */ XQspiPs_SetOptions(QspiInstancePtr, XQSPIPS_LQSPI_MODE_OPTION | XQSPIPS_HOLD_B_DRIVE_OPTION); Status = XQspiPs_LqspiRead(QspiInstancePtr, ReadBuffer, TEST_ADDRESS, MAX_DATA); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Setup a pointer to the start of the data that was read into the read * buffer and verify the data read is the data that was written */ for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MAX_DATA; Count++, UniqueValue++) { if (ReadBuffer[Count] != (u8)(UniqueValue + Test)) { return XST_FAILURE; } } return XST_SUCCESS; }
int SpiFlashPolledExample(XSpiPs *SpiInstancePtr, u16 SpiDeviceId) { u8 *BufferPtr; u8 UniqueValue; u32 Count; XSpiPs_Config *ConfigPtr; /* Pointer to Configuration ROM data */ u32 TempAddress; /* * Lookup the device configuration in the temporary CROM table. Use this * configuration info down below when initializing this component. */ ConfigPtr = XSpiPs_LookupConfig(SpiDeviceId); if (ConfigPtr == NULL) { return XST_DEVICE_NOT_FOUND; } XSpiPs_CfgInitialize(SpiInstancePtr, ConfigPtr, ConfigPtr->BaseAddress); /* Initialize the XILISF Library */ XIsf_Initialize(&Isf, SpiInstancePtr, FLASH_SPI_SELECT, IsfWriteBuffer); memset(WriteBuffer, 0x00, sizeof(WriteBuffer)); memset(ReadBuffer, 0x00, sizeof(ReadBuffer)); /* Unprotect Sectors */ FlashWrite(&Isf, 0, 0, XISF_WRITE_STATUS_REG); FlashErase(&Isf, TEST_ADDRESS, MAX_DATA); /* * Initialize the write buffer for a pattern to write to the FLASH * and the read buffer to zero so it can be verified after the read, the * test value that is added to the unique value allows the value to be * changed in a debug environment to guarantee */ TempAddress = TEST_ADDRESS; for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MAX_DATA; Count++, UniqueValue++, TempAddress++) { WriteBuffer[0] = (u8)(UniqueValue); FlashWrite(&Isf, TempAddress, 1, XISF_WRITE); } /* * Read the contents of the FLASH from TEST_ADDRESS, using Normal Read * command */ FlashRead(&Isf, TEST_ADDRESS, MAX_DATA, XISF_READ); /* * Setup a pointer to the start of the data that was read into the read * buffer and verify the data read is the data that was written */ BufferPtr = &ReadBuffer[DATA_OFFSET]; for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MAX_DATA; Count++, UniqueValue++) { if (BufferPtr[Count] != (u8)(UniqueValue)) { return XST_FAILURE; } } return XST_SUCCESS; }
/***************************************************************************** * * The purpose of this function is to illustrate how to use the XQspiPs * device driver in Linear mode. This function writes data to the serial * FLASH in QSPI mode and reads data in Linear QSPI mode. * * @param None. * * @return XST_SUCCESS if successful, else XST_FAILURE. * * @note None. * *****************************************************************************/ int LinearQspiFlashExample(XQspiPs *QspiInstancePtr, u16 QspiDeviceId) { int Status; u8 UniqueValue; int Count; int Page; XQspiPs_Config *QspiConfig; /* * Initialize the QSPI driver so that it's ready to use */ QspiConfig = XQspiPs_LookupConfig(QspiDeviceId); if (NULL == QspiConfig) { return XST_FAILURE; } Status = XQspiPs_CfgInitialize(QspiInstancePtr, QspiConfig, QspiConfig->BaseAddress); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Perform a self-test to check hardware build */ Status = XQspiPs_SelfTest(QspiInstancePtr); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Enable two flash memories on seperate buses */ XQspiPs_SetLqspiConfigReg(QspiInstancePtr, DUAL_QSPI_CONFIG_WRITE); /* * Set the QSPI device as a master and enable manual CS, manual start * and flash interface mode options and drive HOLD_B pin high. */ XQspiPs_SetOptions(QspiInstancePtr, XQSPIPS_FORCE_SSELECT_OPTION | XQSPIPS_MANUAL_START_OPTION | XQSPIPS_HOLD_B_DRIVE_OPTION); XQspiPs_SetClkPrescaler(QspiInstancePtr, XQSPIPS_CLK_PRESCALE_8); /* * Initialize the write buffer for a pattern to write to the FLASH * and the read buffer to zero so it can be verified after the read, the * test value that is added to the unique value allows the value to be * changed in a debug environment to guarantee */ for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < PAGE_SIZE; Count++, UniqueValue++) { WriteBuffer[DATA_OFFSET + Count] = (u8)(UniqueValue + Test); } memset(ReadBuffer, 0x00, sizeof(ReadBuffer)); /* * Assert the FLASH chip select. */ XQspiPs_SetSlaveSelect(QspiInstancePtr); /* * Erase the flash sectors */ FlashErase(QspiInstancePtr, TEST_ADDRESS, MAX_DATA); /* * Write data to the two flash memories on seperate buses, starting from * TEST_ADDRESS. This is same as writing to a single flash memory. The * LQSPI controller takes care of splitting the data words and writing * them to the two flash memories. The user needs to take care of the * address translation */ for (Page = 0; Page < PAGE_COUNT; Page++) { FlashWrite(QspiInstancePtr, ((Page * PAGE_SIZE) + TEST_ADDRESS) / 2, PAGE_SIZE, WRITE_CMD); } /* * Read from the two flash memories on seperate buses in LQSPI mode. */ XQspiPs_SetOptions(QspiInstancePtr, XQSPIPS_LQSPI_MODE_OPTION | XQSPIPS_HOLD_B_DRIVE_OPTION); XQspiPs_SetLqspiConfigReg(QspiInstancePtr, DUAL_QSPI_CONFIG_QUAD_READ); Status = XQspiPs_LqspiRead(QspiInstancePtr, ReadBuffer, TEST_ADDRESS, MAX_DATA); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Setup a pointer to the start of the data that was read into the read * buffer and verify the data read is the data that was written */ for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MAX_DATA; Count++, UniqueValue++) { if (ReadBuffer[Count] != WriteBuffer[DATA_OFFSET + (Count % PAGE_SIZE)]) { return XST_FAILURE; } } /* * Set the QSPI device as a master and enable manual CS, manual start * and flash interface mode options and drive HOLD_B pin high. */ XQspiPs_SetOptions(QspiInstancePtr, XQSPIPS_FORCE_SSELECT_OPTION | XQSPIPS_HOLD_B_DRIVE_OPTION); /* * Initialize the write buffer for a pattern to write to the FLASH * and the read buffer to zero so it can be verified after the read, the * test value that is added to the unique value allows the value to be * changed in a debug environment to guarantee */ for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < PAGE_SIZE; Count++, UniqueValue++) { WriteBuffer[DATA_OFFSET + Count] = (u8)(UniqueValue + Test); } memset(ReadBuffer, 0x00, sizeof(ReadBuffer)); /* * Erase the flash sectors */ FlashErase(QspiInstancePtr, TEST_ADDRESS, MAX_DATA); /* * Write data to the two flash memories on seperate buses, starting from * TEST_ADDRESS. This is same as writing to a single flash memory. The * LQSPI controller takes care of splitting the data words and writing * them to the two flash memories. The user needs to take care of the * address translation */ for (Page = 0; Page < PAGE_COUNT; Page++) { FlashWrite(QspiInstancePtr, ((Page * PAGE_SIZE) + TEST_ADDRESS) / 2, PAGE_SIZE, WRITE_CMD); } /* * Read from the two flash memories on seperate buses in LQSPI mode. */ XQspiPs_SetOptions(QspiInstancePtr, XQSPIPS_LQSPI_MODE_OPTION | XQSPIPS_HOLD_B_DRIVE_OPTION); XQspiPs_SetLqspiConfigReg(QspiInstancePtr, DUAL_QSPI_CONFIG_QUAD_READ); Status = XQspiPs_LqspiRead(QspiInstancePtr, ReadBuffer, TEST_ADDRESS, MAX_DATA); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Setup a pointer to the start of the data that was read into the read * buffer and verify the data read is the data that was written */ for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MAX_DATA; Count++, UniqueValue++) { if (ReadBuffer[Count] != WriteBuffer[DATA_OFFSET + (Count % PAGE_SIZE)]) { return XST_FAILURE; } } return XST_SUCCESS; }
/***************************************************************************** * * The purpose of this function is to illustrate how to use the XSpiPs * device driver in interrupt mode. This function writes and reads data * from a serial flash. * * @param IntcInstancePtr is a pointer to Interrupt Controller instance. * * @param SpiInstancePtr is a pointer to the SPI driver instance to use. * * @param SpiDeviceId is the Instance Id of SPI in the system. * * @param SpiIntrId is the Interrupt Id for SPI in the system. * * @param None. * * @return * - XST_SUCCESS if successful * - XST_FAILURE if not successful * * @note * * This function calls other functions which contain loops that may be infinite * if interrupts are not working such that it may not return. If the device * slave select is not correct and the device is not responding on bus it will * read a status of 0xFF for the status register as the bus is pulled up. * *****************************************************************************/ int SpiPsFlashIntrExample(XScuGic *IntcInstancePtr, XSpiPs *SpiInstancePtr, u16 SpiDeviceId, u16 SpiIntrId) { int Status; u8 *BufferPtr; u8 UniqueValue; u32 Count; u32 MaxSize = MAX_DATA; u32 ChipSelect = FLASH_SPI_SELECT_1; XSpiPs_Config *SpiConfig; if (XGetPlatform_Info() == XPLAT_ZYNQ_ULTRA_MP) { MaxSize = 1024 * 10; ChipSelect = FLASH_SPI_SELECT_0; /* Device is on CS 0 */ SpiIntrId = XPAR_XSPIPS_0_INTR; } /* * Initialize the SPI driver so that it's ready to use */ SpiConfig = XSpiPs_LookupConfig(SpiDeviceId); if (NULL == SpiConfig) { return XST_FAILURE; } Status = XSpiPs_CfgInitialize(SpiInstancePtr, SpiConfig, SpiConfig->BaseAddress); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Perform a self-test to check hardware build */ Status = XSpiPs_SelfTest(SpiInstancePtr); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Connect the Spi device to the interrupt subsystem such that * interrupts can occur. This function is application specific */ Status = SpiPsSetupIntrSystem(IntcInstancePtr, SpiInstancePtr, SpiIntrId); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Setup the handler for the SPI that will be called from the * interrupt context when an SPI status occurs, specify a pointer to * the SPI driver instance as the callback reference so the handler is * able to access the instance data */ XSpiPs_SetStatusHandler(SpiInstancePtr, SpiInstancePtr, (XSpiPs_StatusHandler) SpiPsHandler); /* * Set the SPI device as a master with manual start and manual * chip select mode options */ XSpiPs_SetOptions(SpiInstancePtr, XSPIPS_MANUAL_START_OPTION | \ XSPIPS_MASTER_OPTION | XSPIPS_FORCE_SSELECT_OPTION); /* * Set the SPI device pre-scalar to divide by 8 */ XSpiPs_SetClkPrescaler(SpiInstancePtr, XSPIPS_CLK_PRESCALE_8); memset(WriteBuffer, 0x00, sizeof(WriteBuffer)); memset(ReadBuffer, 0x00, sizeof(ReadBuffer)); /* * Initialize the write buffer for a pattern to write to the flash * and the read buffer to zero so it can be verified after the read, the * test value that is added to the unique value allows the value to be * changed in a debug environment to guarantee */ for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MaxSize; Count++, UniqueValue++) { WriteBuffer[DATA_OFFSET + Count] = (u8)(UniqueValue); } /* * Assert the flash chip select */ XSpiPs_SetSlaveSelect(SpiInstancePtr, ChipSelect); /* * Read the flash ID */ Status = FlashReadID(SpiInstancePtr); if (Status != XST_SUCCESS) { xil_printf("SPI FLASH Interrupt Example Read ID Failed\r\n"); return XST_FAILURE; } /* * Erase the flash */ FlashErase(SpiInstancePtr); /* * Write the data in the write buffer to TestAddress in serial flash */ FlashWrite(SpiInstancePtr, TestAddress, MaxSize, WRITE_CMD); /* * Read the contents of the flash from TestAddress of size MAX_DATA * using Normal Read command */ FlashRead(SpiInstancePtr, TestAddress, MaxSize, READ_CMD); /* * Setup a pointer to the start of the data that was read into the read * buffer and verify the data read is the data that was written */ BufferPtr = &ReadBuffer[DATA_OFFSET]; for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MaxSize; Count++, UniqueValue++) { if (BufferPtr[Count] != (u8)(UniqueValue)) { return XST_FAILURE; } } /* * Set the SPI device as a master with auto start and manual * chip select mode options */ XSpiPs_SetOptions(SpiInstancePtr, XSPIPS_MASTER_OPTION | \ XSPIPS_FORCE_SSELECT_OPTION); memset(WriteBuffer, 0x00, sizeof(WriteBuffer)); memset(ReadBuffer, 0x00, sizeof(ReadBuffer)); /* * Initialize the write buffer for a pattern to write to the flash * and the read buffer to zero so it can be verified after the read, the * test value that is added to the unique value allows the value to be * changed in a debug environment to guarantee */ for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MaxSize; Count++, UniqueValue++) { WriteBuffer[DATA_OFFSET + Count] = (u8)(UniqueValue); } /* * Erase the flash */ FlashErase(SpiInstancePtr); /* * Write the data in the write buffer to TestAddress in serial flash */ FlashWrite(SpiInstancePtr, TestAddress, MaxSize, WRITE_CMD); /* * Read the contents of the flash from TestAddress of size MAX_DATA * using Normal Read command */ FlashRead(SpiInstancePtr, TestAddress, MaxSize, READ_CMD); /* * Setup a pointer to the start of the data that was read into the read * buffer and verify the data read is the data that was written */ BufferPtr = &ReadBuffer[DATA_OFFSET]; for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MaxSize; Count++, UniqueValue++) { if (BufferPtr[Count] != (u8)(UniqueValue)) { return XST_FAILURE; } } SpiPsDisableIntrSystem(IntcInstancePtr, SpiIntrId); return XST_SUCCESS; }
int main(int argc,char **argv) { int index ; /* used in argument processing */ int erase = FALSE ; /* perform erase on FlashEPROM */ int verify = FALSE ; /* verify file against FlashEPROM (do not program) */ char *infile = NULL ; /* input filename */ word filesize ; /* input file size in bytes */ char *buffer ; /* image file buffer */ FILE *ihand ; /* input FILE handle */ /* verify FlashEPROM presence */ if (!FlashCheck()) { fprintf(stderr,"%s: FlashEPROM not found\n",whoami) ; exit(9) ; } for (index=1; (index < argc); index++) { if (argv[index][0] == '-') { switch (argv[index][1]) { case 'h' : /* help */ usage() ; case 'e' : /* erase */ erase = TRUE ; break ; case 'v' : /* verify */ verify = TRUE ; break ; } } else { /* default input file */ if (infile == NULL) { infile = argv[index] ; if (!checkimage(infile,&filesize)) { fprintf(stderr,"%s: \"%s\" not found\n",whoami,infile) ; exit(2) ; } if (filesize > flash_size) { fprintf(stderr,"%s: specified file bigger than &%08X bytes\n",whoami,flash_size) ; exit(3) ; } } else { fprintf(stderr,"%s: unrecognised arg \"%s\"\n",whoami,argv[index]) ; exit(4) ; } } } if (erase && verify) { fprintf(stderr,"%s: -e and -v are mutually exclusive\n",whoami) ; exit(5) ; } if ((infile == NULL) && !erase) { fprintf(stderr,"%s: Image file not specified\n",whoami) ; exit(5) ; } /* Erase the FlashEPROM is the user desires */ if (erase) { if ((index = FlashErase()) != -1) { fprintf(stderr,"%s: FlashEPROM erase failed at index &%08X\n",whoami,index) ; exit(10) ; } } if (infile != NULL) { if ((buffer = (char *)malloc(filesize)) == NULL) { fprintf(stderr,"%s: unable to allocate image buffer memory\n",whoami) ; exit(6) ; } if ((ihand = fopen(infile,"r")) == NULL) { fprintf(stderr,"%s: unable to open file \"%s\"\n",whoami,infile) ; exit(7) ; } if (fread(buffer,filesize,1,ihand) != 1) { fprintf(stderr,"%s: unable to read data from file \"%s\"\n",whoami,infile); exit(8) ; } fclose(ihand) ; if (verify) { if ((index = FlashVerify(buffer,filesize)) != -1) { fprintf(stderr,"%s: verify failed at index &%08X\n",whoami,index) ; exit(10) ; } } else { if ((index = FlashWrite(buffer,filesize)) != -1) { fprintf(stderr,"%s: write failed at index &%08X\n",whoami,index) ; exit(10) ; } } } return(0) ; }
//--------------------------------------------------- //用户使用按键设定的参数 //退出设定时保存参数 //------------------------------------------------ void SaveParameters(unsigned char *pTable) { FlashPageErase(0x6A00,SELECT_64K); FlashWrite(0x6A00,pTable,15,SELECT_64K); WDog_Feed(); }
int main(int argc, char *argv[]) { int opt; char options[] = "r:w:f:l:o:c:?"; int fd, method; unsigned char buffer[FLASH_MAX_RW_SIZE]; int i=0; unsigned int *src; unsigned int *dst; unsigned int value; unsigned int bytes; unsigned int start_addr; unsigned int end_addr; if (argc < 3) { show_usage(); return 0; } while ((opt = getopt (argc, argv, options)) != -1) { switch (opt) { case 'r': dst = (unsigned int *)buffer; src = (unsigned int *)strtol(optarg, NULL, 16); method = FLASH_IOCTL_READ; break; case 'w': dst = (unsigned int *)strtol(optarg, NULL, 16); method = FLASH_IOCTL_WRITE; break; case 'f': start_addr=strtol(optarg, NULL, 16); method = FLASH_IOCTL_ERASE; break; case 'l': end_addr=strtol(optarg, NULL, 16); method = FLASH_IOCTL_ERASE; break; case 'c': bytes=strtol(optarg,NULL,10); if(bytes > FLASH_MAX_RW_SIZE) { printf("Too many bytes - %d > %d bytes\n", bytes, FLASH_MAX_RW_SIZE); return 0; } break; case 'o': value=strtol(optarg, NULL, 16); break; case '?': show_usage(); } } switch(method) { case FLASH_IOCTL_READ: if(FlashRead(dst,src, bytes)<0) { printf("READ: Out of scope\n"); } else { for(i=0; i<bytes; i++) { printf("%X: %X\n", ((unsigned int)src)+i, buffer[i]); } } break; case FLASH_IOCTL_WRITE: if(FlashWrite(&value, dst, 1)<0) { printf("WRITE: Out of scope\n"); } else { printf("Write %0X to %0X\n", value, dst); } break; case FLASH_IOCTL_ERASE: if(end_addr<start_addr) { printf("ERASE: End addr MUST bigger than Start addr\n"); break; } if(FlashErase(start_addr, end_addr)<0) { printf("ERASE: Out of scope\n"); } else { printf("Erase Addr From %0X To %0X\n",start_addr, end_addr); } break; } return 0; }
/** * The purpose of this function is to illustrate how to use the XQspiPs * device driver in interrupt mode. This function writes and reads data * from a serial FLASH. * * @return XST_SUCCESS if successful else XST_FAILURE. * * @note * * This function calls other functions which contain loops that may be infinite * if interrupts are not working such that it may not return. If the device * slave select is not correct and the device is not responding on bus it will * read a status of 0xFF for the status register as the bus is pulled up. * *****************************************************************************/ int QspiFlashPollExample(XScuGic *IntcInstancePtr, XQspiPs *QspiInstancePtr, u16 QspiDeviceId, u16 QspiIntrId) { u8 *BufferPtr; u8 UniqueValue; int Count; int Page; int Status; u32 Options; /* * Lookup the device configuration in the temporary CROM table. Use this * configuration info down below when initializing this component. */ ConfigPtr = XQspiPs_LookupConfig(QspiDeviceId); if (ConfigPtr == NULL) { return XST_DEVICE_NOT_FOUND; } Status = XQspiPs_CfgInitialize(QspiInstancePtr, ConfigPtr, ConfigPtr->BaseAddress); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Set the QSPI options */ Options = XQSPIPS_FORCE_SSELECT_OPTION | XQSPIPS_MANUAL_START_OPTION | XQSPIPS_HOLD_B_DRIVE_OPTION; XIsf_SetSpiConfiguration(&Isf, QspiInstancePtr, Options, XISF_SPI_PRESCALER); if(ConfigPtr->ConnectionMode == XQSPIPS_CONNECTION_MODE_STACKED) { /* * Enable two flash memories, Shared bus * (NOT separate bus), L_PAGE selected by default */ XQspiPs_SetLqspiConfigReg(QspiInstancePtr, DUAL_STACK_CONFIG_WRITE); } if(ConfigPtr->ConnectionMode == XQSPIPS_CONNECTION_MODE_PARALLEL) { /* * Enable two flash memories on separate buses */ XQspiPs_SetLqspiConfigReg(QspiInstancePtr, DUAL_QSPI_CONFIG_WRITE); } /* Initialize the XILISF Library */ XIsf_Initialize(&Isf, QspiInstancePtr, FLASH_QSPI_SELECT, IsfWriteBuffer); /* * Initialize the write buffer for a pattern to write to the FLASH * and the read buffer to zero so it can be verified after the read, * the test value that is added to the unique value allows the value * to be changed in a debug environment to guarantee */ for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < PAGE_SIZE; Count++, UniqueValue++) { WriteBuffer[Count] = (u8)(UniqueValue + Test_Polled); } memset(ReadBuffer, 0x00, sizeof(ReadBuffer)); Status = FlashErase(&Isf, TEST_ADDRESS, MAX_DATA); if(Status != XST_SUCCESS){ return XST_FAILURE; } /* * Write the data in the write buffer to the serial FLASH a page at a * time, starting from TEST_ADDRESS */ for (Page = 0; Page < PAGE_COUNT; Page++) { Status = FlashWrite(&Isf, (Page * PAGE_SIZE) + TEST_ADDRESS, PAGE_SIZE, XISF_QUAD_IP_PAGE_WRITE); if(Status != XST_SUCCESS){ return XST_FAILURE; } } /****************************************************** **********************NORMAL READ********************* ******************************************************/ /* * Read the contents of the FLASH from TEST_ADDRESS, using Normal Read * command */ Status = FlashRead(&Isf, TEST_ADDRESS, MAX_DATA, XISF_READ); if(Status != XST_SUCCESS){ return XST_FAILURE; } /* * Setup a pointer to the start of the data that was read into the read * buffer and verify the data read is the data that was written */ BufferPtr = ReadBuffer; for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MAX_DATA; Count++, UniqueValue++) { if (BufferPtr[Count] != (u8)(UniqueValue + Test_Polled)) { return XST_FAILURE; } } /****************************************************** **********************FAST READ*********************** ******************************************************/ /* * Read the contents of the FLASH from TEST_ADDRESS, using Fast Read * command */ Status = FlashRead(&Isf, TEST_ADDRESS, MAX_DATA, XISF_FAST_READ); if(Status != XST_SUCCESS){ return XST_FAILURE; } /* * Setup a pointer to the start of the data that was read into the read * buffer and verify the data read is the data that was written */ BufferPtr = ReadBuffer; for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MAX_DATA; Count++, UniqueValue++) { if (BufferPtr[Count] != (u8)(UniqueValue + Test_Polled)) { return XST_FAILURE; } } /****************************************************** ******************DUAL OP FAST READ******************* ******************************************************/ /* * Read the contents of the FLASH from TEST_ADDRESS, using DUAL OP * Fast Read command */ Status = FlashRead(&Isf, TEST_ADDRESS, MAX_DATA, XISF_DUAL_OP_FAST_READ); if(Status != XST_SUCCESS){ return XST_FAILURE; } /* * Setup a pointer to the start of the data that was read into the read * buffer and verify the data read is the data that was written */ BufferPtr = ReadBuffer; for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MAX_DATA; Count++, UniqueValue++) { if (BufferPtr[Count] != (u8)(UniqueValue + Test_Polled)) { return XST_FAILURE; } } /****************************************************** ******************QUAD IO FAST READ******************* ******************************************************/ /* * Read the contents of the FLASH from TEST_ADDRESS, using QUAD IO * Fast Read command */ Status = FlashRead(&Isf, TEST_ADDRESS, MAX_DATA, XISF_QUAD_OP_FAST_READ); if(Status != XST_SUCCESS){ return XST_FAILURE; } /* * Setup a pointer to the start of the data that was read into the read * buffer and verify the data read is the data that was written */ BufferPtr = ReadBuffer; for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MAX_DATA; Count++, UniqueValue++) { if (BufferPtr[Count] != (u8)(UniqueValue + Test_Polled)) { return XST_FAILURE; } } return XST_SUCCESS; }
/***************************************************************************** * * The purpose of this function is to illustrate how to use the XQspiPs * device driver in interrupt mode. This function writes and reads data * from a serial FLASH. * * @param None. * * @return XST_SUCCESS if successful else XST_FAILURE. * * @note * * This function calls other functions which contain loops that may be infinite * if interrupts are not working such that it may not return. If the device * slave select is not correct and the device is not responding on bus it will * read a status of 0xFF for the status register as the bus is pulled up. * *****************************************************************************/ int QspiFlashIntrExample(XScuGic *IntcInstancePtr, XQspiPs *QspiInstancePtr, u16 QspiDeviceId, u16 QspiIntrId) { int Status; u8 *BufferPtr; u8 UniqueValue; int Count; int Page; XQspiPs_Config *QspiConfig; /* * Initialize the QSPI driver so that it's ready to use */ QspiConfig = XQspiPs_LookupConfig(QspiDeviceId); if (NULL == QspiConfig) { return XST_FAILURE; } Status = XQspiPs_CfgInitialize(QspiInstancePtr, QspiConfig, QspiConfig->BaseAddress); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Perform a self-test to check hardware build */ Status = XQspiPs_SelfTest(QspiInstancePtr); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Connect the Qspi device to the interrupt subsystem such that * interrupts can occur. This function is application specific */ Status = QspiSetupIntrSystem(IntcInstancePtr, QspiInstancePtr, QspiIntrId); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Setup the handler for the QSPI that will be called from the * interrupt context when an QSPI status occurs, specify a pointer to * the QSPI driver instance as the callback reference so the handler is * able to access the instance data */ XQspiPs_SetStatusHandler(QspiInstancePtr, QspiInstancePtr, (XQspiPs_StatusHandler) QspiHandler); /* * Set Manual Start and Manual Chip select options and drive the * HOLD_B high. */ XQspiPs_SetOptions(QspiInstancePtr, XQSPIPS_FORCE_SSELECT_OPTION | XQSPIPS_MANUAL_START_OPTION | XQSPIPS_HOLD_B_DRIVE_OPTION); /* * Set the operating clock frequency using the clock divider */ XQspiPs_SetClkPrescaler(QspiInstancePtr, XQSPIPS_CLK_PRESCALE_8); /* * Assert the FLASH chip select */ XQspiPs_SetSlaveSelect(QspiInstancePtr); /* * Initialize the write buffer for a pattern to write to the FLASH * and the read buffer to zero so it can be verified after the read, the * test value that is added to the unique value allows the value to be * changed in a debug environment to guarantee */ for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < PAGE_SIZE; Count++, UniqueValue++) { WriteBuffer[DATA_OFFSET + Count] = (u8)(UniqueValue + Test); } memset(ReadBuffer, 0x00, sizeof(ReadBuffer)); FlashReadID(); /* * Erase the flash. */ FlashErase(QspiInstancePtr, TEST_ADDRESS, MAX_DATA); /* * Write the data in the write buffer to the serial FLASH a page at a * time, starting from TEST_ADDRESS */ for (Page = 0; Page < PAGE_COUNT; Page++) { FlashWrite(QspiInstancePtr, (Page * PAGE_SIZE) + TEST_ADDRESS, PAGE_SIZE, WRITE_CMD); } /* * Read the contents of the FLASH from TEST_ADDRESS, using Normal Read * command. */ FlashRead(QspiInstancePtr, TEST_ADDRESS, MAX_DATA, READ_CMD); /* * Setup a pointer to the start of the data that was read into the read * buffer and verify the data read is the data that was written */ BufferPtr = &ReadBuffer[DATA_OFFSET]; for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MAX_DATA; Count++, UniqueValue++) { if (BufferPtr[Count] != (u8)(UniqueValue + Test)) { return XST_FAILURE; } } /* * Read the contents of the FLASH from TEST_ADDRESS, using Fast Read * command */ memset(ReadBuffer, 0x00, sizeof(ReadBuffer)); FlashRead(QspiInstancePtr, TEST_ADDRESS, MAX_DATA, FAST_READ_CMD); /* * Setup a pointer to the start of the data that was read into the read * buffer and verify the data read is the data that was written */ BufferPtr = &ReadBuffer[DATA_OFFSET + DUMMY_SIZE]; for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MAX_DATA; Count++, UniqueValue++) { if (BufferPtr[Count] != (u8)(UniqueValue + Test)) { return XST_FAILURE; } } /* * Read the contents of the FLASH from TEST_ADDRESS, using Dual Read * command */ memset(ReadBuffer, 0x00, sizeof(ReadBuffer)); FlashRead(QspiInstancePtr, TEST_ADDRESS, MAX_DATA, DUAL_READ_CMD); /* * Setup a pointer to the start of the data that was read into the read * buffer and verify the data read is the data that was written */ BufferPtr = &ReadBuffer[DATA_OFFSET + DUMMY_SIZE]; for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MAX_DATA; Count++, UniqueValue++) { if (BufferPtr[Count] != (u8)(UniqueValue + Test)) { return XST_FAILURE; } } /* * Read the contents of the FLASH from TEST_ADDRESS, using Quad Read * command */ memset(ReadBuffer, 0x00, sizeof(ReadBuffer)); FlashRead(QspiInstancePtr, TEST_ADDRESS, MAX_DATA, QUAD_READ_CMD); /* * Setup a pointer to the start of the data that was read into the read * buffer and verify the data read is the data that was written */ BufferPtr = &ReadBuffer[DATA_OFFSET + DUMMY_SIZE]; for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MAX_DATA; Count++, UniqueValue++) { if (BufferPtr[Count] != (u8)(UniqueValue + Test)) { return XST_FAILURE; } } /* * Set Auto Start and Manual Chip select options and drive the * HOLD_B high. */ XQspiPs_SetOptions(QspiInstancePtr, XQSPIPS_FORCE_SSELECT_OPTION | XQSPIPS_HOLD_B_DRIVE_OPTION); /* * Initialize the write buffer for a pattern to write to the FLASH * and the read buffer to zero so it can be verified after the read, the * test value that is added to the unique value allows the value to be * changed in a debug environment to guarantee */ for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < PAGE_SIZE; Count++, UniqueValue++) { WriteBuffer[DATA_OFFSET + Count] = (u8)(UniqueValue + Test); } memset(ReadBuffer, 0x00, sizeof(ReadBuffer)); /* * Erase the flash. */ FlashErase(QspiInstancePtr, TEST_ADDRESS, MAX_DATA); /* * Write the data in the write buffer to the serial FLASH a page at a * time, starting from TEST_ADDRESS */ for (Page = 0; Page < PAGE_COUNT; Page++) { FlashWrite(QspiInstancePtr, (Page * PAGE_SIZE) + TEST_ADDRESS, PAGE_SIZE, WRITE_CMD); } /* * Read the contents of the FLASH from TEST_ADDRESS, using Normal Read * command. */ FlashRead(QspiInstancePtr, TEST_ADDRESS, MAX_DATA, READ_CMD); /* * Setup a pointer to the start of the data that was read into the read * buffer and verify the data read is the data that was written */ BufferPtr = &ReadBuffer[DATA_OFFSET]; for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MAX_DATA; Count++, UniqueValue++) { if (BufferPtr[Count] != (u8)(UniqueValue + Test)) { return XST_FAILURE; } } /* * Read the contents of the FLASH from TEST_ADDRESS, using Fast Read * command */ memset(ReadBuffer, 0x00, sizeof(ReadBuffer)); FlashRead(QspiInstancePtr, TEST_ADDRESS, MAX_DATA, FAST_READ_CMD); /* * Setup a pointer to the start of the data that was read into the read * buffer and verify the data read is the data that was written */ BufferPtr = &ReadBuffer[DATA_OFFSET + DUMMY_SIZE]; for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MAX_DATA; Count++, UniqueValue++) { if (BufferPtr[Count] != (u8)(UniqueValue + Test)) { return XST_FAILURE; } } /* * Read the contents of the FLASH from TEST_ADDRESS, using Dual Read * command */ memset(ReadBuffer, 0x00, sizeof(ReadBuffer)); FlashRead(QspiInstancePtr, TEST_ADDRESS, MAX_DATA, DUAL_READ_CMD); /* * Setup a pointer to the start of the data that was read into the read * buffer and verify the data read is the data that was written */ BufferPtr = &ReadBuffer[DATA_OFFSET + DUMMY_SIZE]; for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MAX_DATA; Count++, UniqueValue++) { if (BufferPtr[Count] != (u8)(UniqueValue + Test)) { return XST_FAILURE; } } /* * Read the contents of the FLASH from TEST_ADDRESS, using Quad Read * command */ memset(ReadBuffer, 0x00, sizeof(ReadBuffer)); FlashRead(QspiInstancePtr, TEST_ADDRESS, MAX_DATA, QUAD_READ_CMD); /* * Setup a pointer to the start of the data that was read into the read * buffer and verify the data read is the data that was written */ BufferPtr = &ReadBuffer[DATA_OFFSET + DUMMY_SIZE]; for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MAX_DATA; Count++, UniqueValue++) { if (BufferPtr[Count] != (u8)(UniqueValue + Test)) { return XST_FAILURE; } } QspiDisableIntrSystem(IntcInstancePtr, QspiIntrId); return XST_SUCCESS; }
/***************************************************************************** * * The purpose of this function is to illustrate how to use the XSpiPs * device driver in polled mode. This function writes and reads data * from a serial flash. * * @param SpiPtr is a pointer to the SPI driver instance to use. * * @param SpiDeviceId is the Instance Id of SPI in the system. * * @return * - XST_SUCCESS if successful * - XST_FAILURE if not successful * * @note * * If the device slave select is not correct and the device is not responding * on bus it will read a status of 0xFF for the status register as the bus * is pulled up. * *****************************************************************************/ int SpiPsFlashPolledExample(XSpiPs *SpiInstancePtr, u16 SpiDeviceId) { int Status; u8 *BufferPtr; u8 UniqueValue; u32 Count; XSpiPs_Config *SpiConfig; /* * Initialize the SPI driver so that it's ready to use */ SpiConfig = XSpiPs_LookupConfig(SpiDeviceId); if (NULL == SpiConfig) { return XST_FAILURE; } Status = XSpiPs_CfgInitialize(SpiInstancePtr, SpiConfig, SpiConfig->BaseAddress); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Perform a self-test to check hardware build */ Status = XSpiPs_SelfTest(SpiInstancePtr); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Set the SPI device as a master with manual start and manual * chip select mode options */ XSpiPs_SetOptions(SpiInstancePtr, XSPIPS_MANUAL_START_OPTION | \ XSPIPS_MASTER_OPTION | XSPIPS_FORCE_SSELECT_OPTION); /* * Set the SPI device pre-scalar to divide by 8 */ XSpiPs_SetClkPrescaler(SpiInstancePtr, XSPIPS_CLK_PRESCALE_8); memset(WriteBuffer, 0x00, sizeof(WriteBuffer)); memset(ReadBuffer, 0x00, sizeof(ReadBuffer)); /* * Initialize the write buffer for a pattern to write to the Flash * and the read buffer to zero so it can be verified after the read, the * test value that is added to the unique value allows the value to be * changed in a debug environment to guarantee */ for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MAX_DATA; Count++, UniqueValue++) { WriteBuffer[DATA_OFFSET + Count] = (u8)(UniqueValue); } /* * Set the flash chip select */ XSpiPs_SetSlaveSelect(SpiInstancePtr, FLASH_SPI_SELECT); /* * Read the flash Id */ Status = FlashReadID(); if (Status != XST_SUCCESS) { xil_printf("SPI Flash Polled Example Read ID Failed\r\n"); return XST_FAILURE; } /* * Erase the flash */ FlashErase(SpiInstancePtr); TestAddress = 0x0; /* * Write the data in the write buffer to TestAddress in serial flash */ FlashWrite(SpiInstancePtr, TestAddress, MAX_DATA, WRITE_CMD); /* * Read the contents of the flash from TestAddress of size MAX_DATA * using Normal Read command */ FlashRead(SpiInstancePtr, TestAddress, MAX_DATA, READ_CMD); /* * Setup a pointer to the start of the data that was read into the read * buffer and verify the data read is the data that was written */ BufferPtr = &ReadBuffer[DATA_OFFSET]; for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MAX_DATA; Count++, UniqueValue++) { if (BufferPtr[Count] != (u8)(UniqueValue)) { return XST_FAILURE; } } memset(WriteBuffer, 0x00, sizeof(WriteBuffer)); memset(ReadBuffer, 0x00, sizeof(ReadBuffer)); /* * Initialize the write buffer for a pattern to write to the Flash * and the read buffer to zero so it can be verified after the read, the * test value that is added to the unique value allows the value to be * changed in a debug environment to guarantee */ for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MAX_DATA; Count++, UniqueValue++) { WriteBuffer[DATA_OFFSET + Count] = (u8)(UniqueValue); } /* * Set the SPI device as a master with auto start and manual * chip select mode options */ XSpiPs_SetOptions(SpiInstancePtr, XSPIPS_MASTER_OPTION | \ XSPIPS_FORCE_SSELECT_OPTION); /* * Erase the flash */ FlashErase(SpiInstancePtr); TestAddress = 0x0; /* * Write the data in the write buffer to TestAddress in serial flash */ FlashWrite(SpiInstancePtr, TestAddress, MAX_DATA, WRITE_CMD); /* * Read the contents of the flash from TestAddress of size MAX_DATA * using Normal Read command */ FlashRead(SpiInstancePtr, TestAddress, MAX_DATA, READ_CMD); /* * Setup a pointer to the start of the data that was read into the read * buffer and verify the data read is the data that was written */ BufferPtr = &ReadBuffer[DATA_OFFSET]; for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MAX_DATA; Count++, UniqueValue++) { if (BufferPtr[Count] != (u8)(UniqueValue)) { return XST_FAILURE; } } return XST_SUCCESS; }
//копирует сектор из block_start в block_end, заменяя данные, начиная с адреса where_to_replace данными data //записывая data_size байт BOOL FlashCopySectorAndReplaceData(int sector_start, int sector_end, int where_to_replace, unsigned char *data, int data_size) { BOOL ret; int i; uint32_t block_from_address; uint32_t block_where_address; block_from_address = sector_start * EE_SECTOR_SIZE; block_where_address = 0; current_crc = 0; //стирание сектора ret = FlashBlankCheck(sector_end); if(ret) { if(!FlashErase(sector_end)) { gsm_uart_printf_unsafe("FlashCopySectorAndReplaceData: cannot erase\r"); return DEF_FALSE; } } while(1) { memcpy(ee_buffer, (void *)block_from_address, EE_BLOCK_SIZE); //если следующий блок начинается с адреса после адреса where_to_replace, то нужно //заменять данные уже в этом блоке if(((block_where_address + EE_BLOCK_SIZE) > where_to_replace) && (block_where_address <= where_to_replace) && data_size) { i = (where_to_replace - block_where_address) % EE_BLOCK_SIZE; while((i < EE_BLOCK_SIZE) && data_size) { ee_buffer[i] = *data; data_size--; data++; where_to_replace++; i++; } } FlashAddEepromData(block_where_address); ret = FlashWrite(sector_end, block_where_address, EE_BLOCK_SIZE, ee_buffer); if(!ret) { gsm_uart_printf_unsafe("FlashCopySectorAndReplaceData: cannot write\r"); return DEF_FALSE; } block_from_address += EE_BLOCK_SIZE; block_where_address += EE_BLOCK_SIZE; if(block_where_address >= EE_SECTOR_SIZE) { //Считаем текущим сектором тот, куда мы перенесли данные current_sector = sector_end; current_cnt = FlashNextCounter(); return DEF_TRUE; } } }