Example #1
0
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 );
}
Example #2
0
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;
}
Example #3
0
// The normal flash write function ----------------------------------------------
void Fl2FlashWriteEntry()
{
  theFlashParams.count = FlashWrite((CODE_REF)theFlashParams.base_ptr,
                                    theFlashParams.offset_into_block,
                                    theFlashParams.count,
                                    theFlashParams.buffer);
}
Example #4
0
// 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;
}
Example #5
0
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;
        }
    }
}
Example #6
0
File: nvm.c Project: x893/OpenBLT
/************************************************************************************//**
** \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 ***/
Example #7
0
/* store into flash */
FlashError_t
BDMFlashWrite( unsigned int addr, unsigned char *mem, size_t count)
{
    return (FlashWrite( &Flash,
                        addr,
                        mem,
                        count ));
}
Example #8
0
/**
 * @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);
}
Example #9
0
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 );
}
Example #10
0
File: flash.c Project: x893/OpenBLT
/************************************************************************************//**
** \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 ***/
Example #11
0
//копирование целиком сектора 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;
    }
  }
}
Example #12
0
/**
 * 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);
}
Example #13
0
/**********************************************************
**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;
}
Example #14
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;
	
}
Example #15
0
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;
}
Example #16
0
File: data.cpp Project: HclX/MSP430
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));
}
Example #17
0
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;
}
Example #24
0
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) ;
}
Example #25
0
//---------------------------------------------------
//用户使用按键设定的参数
//退出设定时保存参数
//------------------------------------------------
void SaveParameters(unsigned char *pTable)
{
    FlashPageErase(0x6A00,SELECT_64K);
    FlashWrite(0x6A00,pTable,15,SELECT_64K);
    WDog_Feed();
}
Example #26
0
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;
}
Example #30
0
//копирует сектор из 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;
    }
  }
}