XilinxProcessorIPLib/drivers/qspips/examples/xqspips_g128_flash_example.c
void FlashErase(XQspiPs *QspiPtr, u32 Address, u32 ByteCount, u8 *WriteBfrPtr)
{
	u8 WriteEnableCmd = { WRITE_ENABLE_CMD };
	u8 ReadStatusCmd[] = { READ_STATUS_CMD, 0 };  /* Must send 2 bytes */
	u8 FlashStatus[2];
	int Sector;
	u32 RealAddr;
	u32 LqspiCr;
	u32 NumSect;
	u32 BankSel;
	u8 BankInitFlag = 1;
	u8 ReadFlagSRCmd[] = { READ_FLAG_STATUS_CMD, 0 };
	u8 FlagStatus[2];

	/*
	 * If erase size is same as the total size of the flash, use bulk erase
	 * command or die erase command multiple times as required
	 */
	if (ByteCount == ((Flash_Config_Table[FCTIndex]).NumSect *
			(Flash_Config_Table[FCTIndex]).SectSize) ) {

		if(QspiPtr->Config.ConnectionMode == XQSPIPS_CONNECTION_MODE_STACKED){

			/*
			 * Get the current LQSPI configuration register value
			 */
			LqspiCr = XQspiPs_GetLqspiConfigReg(QspiPtr);
			/*
			 * Set selection to L_PAGE
			 */
			XQspiPs_SetLqspiConfigReg(QspiPtr,
					LqspiCr & (~XQSPIPS_LQSPI_CR_U_PAGE_MASK));

			/*
			 * Assert the Flash chip select.
			 */
			XQspiPs_SetSlaveSelect(QspiPtr);
		}

		if(Flash_Config_Table[FCTIndex].NumDie == 1) {
			/*
			 * Call Bulk erase
			 */
			BulkErase(QspiPtr, WriteBfrPtr);
		}

		if(Flash_Config_Table[FCTIndex].NumDie > 1) {
			/*
			 * Call Die erase
			 */
			DieErase(QspiPtr, WriteBfrPtr);
		}
		/*
		 * If stacked mode, bulk erase second flash
		 */
		if(QspiPtr->Config.ConnectionMode == XQSPIPS_CONNECTION_MODE_STACKED){

			/*
			 * Get the current LQSPI configuration register value
			 */
			LqspiCr = XQspiPs_GetLqspiConfigReg(QspiPtr);
			/*
			 * Set selection to U_PAGE
			 */
			XQspiPs_SetLqspiConfigReg(QspiPtr,
					LqspiCr | XQSPIPS_LQSPI_CR_U_PAGE_MASK);

			/*
			 * Assert the Flash chip select.
			 */
			XQspiPs_SetSlaveSelect(QspiPtr);

			if(Flash_Config_Table[FCTIndex].NumDie == 1) {
				/*
				 * Call Bulk erase
				 */
				BulkErase(QspiPtr, WriteBfrPtr);
			}

			if(Flash_Config_Table[FCTIndex].NumDie > 1) {
				/*
				 * Call Die erase
				 */
				DieErase(QspiPtr, WriteBfrPtr);
			}
		}

		return;
	}

	/*
	 * If the erase size is less than the total size of the flash, use
	 * sector erase command
	 */

	/*
	 * Calculate no. of sectors to erase based on byte count
	 */
	NumSect = ByteCount/(Flash_Config_Table[FCTIndex].SectSize) + 1;

	/*
	 * If ByteCount to k sectors,
	 * but the address range spans from N to N+k+1 sectors, then
	 * increment no. of sectors to be erased
	 */

	if( ((Address + ByteCount) & Flash_Config_Table[FCTIndex].SectMask) ==
			((Address + (NumSect * Flash_Config_Table[FCTIndex].SectSize)) &
					Flash_Config_Table[FCTIndex].SectMask) ) {
		NumSect++;
	}

	for (Sector = 0; Sector < NumSect; Sector++) {

		/*
		 * Translate address based on type of connection
		 * If stacked assert the slave select based on address
		 */
		RealAddr = GetRealAddr(QspiPtr, Address);

		/*
		 * Initial bank selection
		 */
		if((BankInitFlag) &&
				(Flash_Config_Table[FCTIndex].FlashDeviceSize > SIXTEENMB)) {
			/*
			 * Reset initial bank select flag
			 */
			BankInitFlag = 0;
			/*
			 * Calculate initial bank
			 */
			BankSel = RealAddr/SIXTEENMB;
			/*
			 * Select bank
			 */
			SendBankSelect(QspiPtr, WriteBfrPtr, BankSel);
		}
		/*
		 * Check bank and send bank select if new bank
		 */
		if((BankSel != RealAddr/SIXTEENMB) &&
				(Flash_Config_Table[FCTIndex].FlashDeviceSize > SIXTEENMB)) {
			/*
			 * Calculate initial bank
			 */
			BankSel = RealAddr/SIXTEENMB;
			/*
			 * Select bank
			 */
			SendBankSelect(QspiPtr, WriteBfrPtr, BankSel);
		}

		/*
		 * Send the write enable command to the SEEPOM so that it can be
		 * written to, this needs to be sent as a separate transfer
		 * before the write
		 */
		XQspiPs_PolledTransfer(QspiPtr, &WriteEnableCmd, NULL,
				  sizeof(WriteEnableCmd));

		/*
		 * Setup the write command with the specified address and data
		 * for the Flash
		 */
		/*
		 * This ensures 3B address is sent to flash even with address
		 * greater than 128Mb.
		 */
		WriteBfrPtr[COMMAND_OFFSET]   = SEC_ERASE_CMD;
		WriteBfrPtr[ADDRESS_1_OFFSET] = (u8)(RealAddr >> 16);
		WriteBfrPtr[ADDRESS_2_OFFSET] = (u8)(RealAddr >> 8);
		WriteBfrPtr[ADDRESS_3_OFFSET] = (u8)(RealAddr & 0xFF);

		/*
		 * Send the sector erase command and address; no receive buffer
		 * is specified since there is nothing to receive
		 */
		XQspiPs_PolledTransfer(QspiPtr, WriteBfrPtr, NULL,
					SEC_ERASE_SIZE);

		if((Flash_Config_Table[FCTIndex].NumDie > 1) &&
				(FlashMake == MICRON_ID_BYTE0)) {
			XQspiPs_PolledTransfer(QspiPtr, ReadFlagSRCmd, FlagStatus,
						sizeof(ReadFlagSRCmd));
		}
		/*
		 * Wait for the sector erase command to the Flash to be completed
		 */
		while (1) {
			/*
			 * Poll the status register of the device to determine
			 * when it completes, by sending a read status command
			 * and receiving the status byte
			 */
			XQspiPs_PolledTransfer(QspiPtr, ReadStatusCmd,
						FlashStatus,
						sizeof(ReadStatusCmd));

			/*
			 * If the status indicates the write is done, then stop
			 * waiting, if a value of 0xFF in the status byte is
			 * read from the device and this loop never exits, the
			 * device slave select is possibly incorrect such that
			 * the device status is not being read
			 */
			if ((FlashStatus[1] & 0x01) == 0) {
				break;
			}
		}

		if((Flash_Config_Table[FCTIndex].NumDie > 1) &&
				(FlashMake == MICRON_ID_BYTE0)) {
			XQspiPs_PolledTransfer(QspiPtr, ReadFlagSRCmd, FlagStatus,
						sizeof(ReadFlagSRCmd));
		}

		Address += Flash_Config_Table[FCTIndex].SectSize;

	}
}
/*****************************************************************************/
/**
*
*
* This function erases the sectors in the  serial Flash connected to the
* QSPI interface.
*
* @param	QspiPtr is a pointer to the QSPI driver component to use.
* @param	Address contains the address of the first sector which needs to
*		be erased.
* @param	ByteCount contains the total size to be erased.
* @param	WriteBfrPtr is Pointer to the write buffer
*		(which is to be transmitted)
*
* @return	None.
*
* @note		None.
*
******************************************************************************/
This function erases the sectors in the  serial Flash connected to the
QSPI interface.
This function erases the sectors in the serial Flash connected to the QSPI interface .
void FlashErase(XQspiPs *QspiPtr, u32 Address, u32 ByteCount, u8 *WriteBfrPtr)
{
	u8 WriteEnableCmd = { WRITE_ENABLE_CMD };
	u8 ReadStatusCmd[] = { READ_STATUS_CMD, 0 };  
	u8 FlashStatus[2];
	int Sector;
	u32 RealAddr;
	u32 LqspiCr;
	u32 NumSect;
	u32 BankSel;
	u8 BankInitFlag = 1;
	u8 ReadFlagSRCmd[] = { READ_FLAG_STATUS_CMD, 0 };
	u8 FlagStatus[2];
	if (ByteCount == ((Flash_Config_Table[FCTIndex]).NumSect *
			(Flash_Config_Table[FCTIndex]).SectSize) ) {
		if(QspiPtr->Config.ConnectionMode == XQSPIPS_CONNECTION_MODE_STACKED){
			LqspiCr = XQspiPs_GetLqspiConfigReg(QspiPtr);
			XQspiPs_SetLqspiConfigReg(QspiPtr,
					LqspiCr & (~XQSPIPS_LQSPI_CR_U_PAGE_MASK));
			XQspiPs_SetSlaveSelect(QspiPtr);
		}
		if(Flash_Config_Table[FCTIndex].NumDie == 1) {
			BulkErase(QspiPtr, WriteBfrPtr);
		}
		if(Flash_Config_Table[FCTIndex].NumDie > 1) {
			DieErase(QspiPtr, WriteBfrPtr);
		}
		if(QspiPtr->Config.ConnectionMode == XQSPIPS_CONNECTION_MODE_STACKED){
			LqspiCr = XQspiPs_GetLqspiConfigReg(QspiPtr);
			XQspiPs_SetLqspiConfigReg(QspiPtr,
					LqspiCr | XQSPIPS_LQSPI_CR_U_PAGE_MASK);
			XQspiPs_SetSlaveSelect(QspiPtr);
			if(Flash_Config_Table[FCTIndex].NumDie == 1) {
				BulkErase(QspiPtr, WriteBfrPtr);
			}
			if(Flash_Config_Table[FCTIndex].NumDie > 1) {
				DieErase(QspiPtr, WriteBfrPtr);
			}
		}
		return;
	}
	NumSect = ByteCount/(Flash_Config_Table[FCTIndex].SectSize) + 1;
	if( ((Address + ByteCount) & Flash_Config_Table[FCTIndex].SectMask) ==
			((Address + (NumSect * Flash_Config_Table[FCTIndex].SectSize)) &
					Flash_Config_Table[FCTIndex].SectMask) ) {
		NumSect++;
	}
	for (Sector = 0; Sector < NumSect; Sector++) {
		RealAddr = GetRealAddr(QspiPtr, Address);
		if((BankInitFlag) &&
				(Flash_Config_Table[FCTIndex].FlashDeviceSize > SIXTEENMB)) {
			BankInitFlag = 0;
			BankSel = RealAddr/SIXTEENMB;
			SendBankSelect(QspiPtr, WriteBfrPtr, BankSel);
		}
		if((BankSel != RealAddr/SIXTEENMB) &&
				(Flash_Config_Table[FCTIndex].FlashDeviceSize > SIXTEENMB)) {
			BankSel = RealAddr/SIXTEENMB;
			SendBankSelect(QspiPtr, WriteBfrPtr, BankSel);
		}
		XQspiPs_PolledTransfer(QspiPtr, &WriteEnableCmd, NULL,
				  sizeof(WriteEnableCmd));
		WriteBfrPtr[COMMAND_OFFSET]   = SEC_ERASE_CMD;
		WriteBfrPtr[ADDRESS_1_OFFSET] = (u8)(RealAddr >> 16);
		WriteBfrPtr[ADDRESS_2_OFFSET] = (u8)(RealAddr >> 8);
		WriteBfrPtr[ADDRESS_3_OFFSET] = (u8)(RealAddr & 0xFF);
		XQspiPs_PolledTransfer(QspiPtr, WriteBfrPtr, NULL,
					SEC_ERASE_SIZE);
		if((Flash_Config_Table[FCTIndex].NumDie > 1) &&
				(FlashMake == MICRON_ID_BYTE0)) {
			XQspiPs_PolledTransfer(QspiPtr, ReadFlagSRCmd, FlagStatus,
						sizeof(ReadFlagSRCmd));
		}
		while (1) {
			XQspiPs_PolledTransfer(QspiPtr, ReadStatusCmd,
						FlashStatus,
						sizeof(ReadStatusCmd));
			if ((FlashStatus[1] & 0x01) == 0) {
				break;
			}
		}
		if((Flash_Config_Table[FCTIndex].NumDie > 1) &&
				(FlashMake == MICRON_ID_BYTE0)) {
			XQspiPs_PolledTransfer(QspiPtr, ReadFlagSRCmd, FlagStatus,
						sizeof(ReadFlagSRCmd));
		}
		Address += Flash_Config_Table[FCTIndex].SectSize;
	}
}
void FlashErase ( XQspiPs * QspiPtr , u32 Address , u32 ByteCount , u8 * WriteBfrPtr ) { u8 WriteEnableCmd = { WRITE_ENABLE_CMD } ; u8 ReadStatusCmd [ ] = { READ_STATUS_CMD , 0 } ; u8 FlashStatus [ 2 ] ; int Sector ; u32 RealAddr ; u32 LqspiCr ; u32 NumSect ; u32 BankSel ; u8 BankInitFlag = 1 ; u8 ReadFlagSRCmd [ ] = { READ_FLAG_STATUS_CMD , 0 } ; u8 FlagStatus [ 2 ] ; if ( ByteCount == ( ( Flash_Config_Table [ FCTIndex ] ) . NumSect * ( Flash_Config_Table [ FCTIndex ] ) . SectSize ) ) { if ( QspiPtr -> Config . ConnectionMode == XQSPIPS_CONNECTION_MODE_STACKED ) { LqspiCr = XQspiPs_GetLqspiConfigReg ( QspiPtr ) ; XQspiPs_SetLqspiConfigReg ( QspiPtr , LqspiCr & ( ~ XQSPIPS_LQSPI_CR_U_PAGE_MASK ) ) ; XQspiPs_SetSlaveSelect ( QspiPtr ) ; } if ( Flash_Config_Table [ FCTIndex ] . NumDie == 1 ) { BulkErase ( QspiPtr , WriteBfrPtr ) ; } if ( Flash_Config_Table [ FCTIndex ] . NumDie > 1 ) { DieErase ( QspiPtr , WriteBfrPtr ) ; } if ( QspiPtr -> Config . ConnectionMode == XQSPIPS_CONNECTION_MODE_STACKED ) { LqspiCr = XQspiPs_GetLqspiConfigReg ( QspiPtr ) ; XQspiPs_SetLqspiConfigReg ( QspiPtr , LqspiCr | XQSPIPS_LQSPI_CR_U_PAGE_MASK ) ; XQspiPs_SetSlaveSelect ( QspiPtr ) ; if ( Flash_Config_Table [ FCTIndex ] . NumDie == 1 ) { BulkErase ( QspiPtr , WriteBfrPtr ) ; } if ( Flash_Config_Table [ FCTIndex ] . NumDie > 1 ) { DieErase ( QspiPtr , WriteBfrPtr ) ; } } return ; } NumSect = ByteCount / ( Flash_Config_Table [ FCTIndex ] . SectSize ) + 1 ; if ( ( ( Address + ByteCount ) & Flash_Config_Table [ FCTIndex ] . SectMask ) == ( ( Address + ( NumSect * Flash_Config_Table [ FCTIndex ] . SectSize ) ) & Flash_Config_Table [ FCTIndex ] . SectMask ) ) { NumSect ++ ; } for ( Sector = 0 ; Sector < NumSect ; Sector ++ ) { RealAddr = GetRealAddr ( QspiPtr , Address ) ; if ( ( BankInitFlag ) && ( Flash_Config_Table [ FCTIndex ] . FlashDeviceSize > SIXTEENMB ) ) { BankInitFlag = 0 ; BankSel = RealAddr / SIXTEENMB ; SendBankSelect ( QspiPtr , WriteBfrPtr , BankSel ) ; } if ( ( BankSel != RealAddr / SIXTEENMB ) && ( Flash_Config_Table [ FCTIndex ] . FlashDeviceSize > SIXTEENMB ) ) { BankSel = RealAddr / SIXTEENMB ; SendBankSelect ( QspiPtr , WriteBfrPtr , BankSel ) ; } XQspiPs_PolledTransfer ( QspiPtr , & WriteEnableCmd , NULL , sizeof ( WriteEnableCmd ) ) ; WriteBfrPtr [ COMMAND_OFFSET ] = SEC_ERASE_CMD ; WriteBfrPtr [ ADDRESS_1_OFFSET ] = ( u8 ) ( RealAddr >> 16 ) ; WriteBfrPtr [ ADDRESS_2_OFFSET ] = ( u8 ) ( RealAddr >> 8 ) ; WriteBfrPtr [ ADDRESS_3_OFFSET ] = ( u8 ) ( RealAddr & 0xFF ) ; XQspiPs_PolledTransfer ( QspiPtr , WriteBfrPtr , NULL , SEC_ERASE_SIZE ) ; if ( ( Flash_Config_Table [ FCTIndex ] . NumDie > 1 ) && ( FlashMake == MICRON_ID_BYTE0 ) ) { XQspiPs_PolledTransfer ( QspiPtr , ReadFlagSRCmd , FlagStatus , sizeof ( ReadFlagSRCmd ) ) ; } while ( 1 ) { XQspiPs_PolledTransfer ( QspiPtr , ReadStatusCmd , FlashStatus , sizeof ( ReadStatusCmd ) ) ; if ( ( FlashStatus [ 1 ] & 0x01 ) == 0 ) { break ; } } if ( ( Flash_Config_Table [ FCTIndex ] . NumDie > 1 ) && ( FlashMake == MICRON_ID_BYTE0 ) ) { XQspiPs_PolledTransfer ( QspiPtr , ReadFlagSRCmd , FlagStatus , sizeof ( ReadFlagSRCmd ) ) ; } Address += Flash_Config_Table [ FCTIndex ] . SectSize ; } }
This function erases the sectors in the  serial Flash connected to the
QSPI interface.
This function erases the sectors in the serial Flash connected to the QSPI interface .
/* Must send 2 bytes */ /*
	 * If erase size is same as the total size of the flash, use bulk erase
	 * command or die erase command multiple times as required
	 */ /*
			 * Get the current LQSPI configuration register value
			 */ /*
			 * Set selection to L_PAGE
			 */ /*
			 * Assert the Flash chip select.
			 */ /*
			 * Call Bulk erase
			 */ /*
			 * Call Die erase
			 */ /*
		 * If stacked mode, bulk erase second flash
		 */ /*
			 * Get the current LQSPI configuration register value
			 */ /*
			 * Set selection to U_PAGE
			 */ /*
			 * Assert the Flash chip select.
			 */ /*
				 * Call Bulk erase
				 */ /*
				 * Call Die erase
				 */ /*
	 * If the erase size is less than the total size of the flash, use
	 * sector erase command
	 */ /*
	 * Calculate no. of sectors to erase based on byte count
	 */ /*
	 * If ByteCount to k sectors,
	 * but the address range spans from N to N+k+1 sectors, then
	 * increment no. of sectors to be erased
	 */ /*
		 * Translate address based on type of connection
		 * If stacked assert the slave select based on address
		 */ /*
		 * Initial bank selection
		 */ /*
			 * Reset initial bank select flag
			 */ /*
			 * Calculate initial bank
			 */ /*
			 * Select bank
			 */ /*
		 * Check bank and send bank select if new bank
		 */ /*
			 * Calculate initial bank
			 */ /*
			 * Select bank
			 */ /*
		 * Send the write enable command to the SEEPOM so that it can be
		 * written to, this needs to be sent as a separate transfer
		 * before the write
		 */ /*
		 * Setup the write command with the specified address and data
		 * for the Flash
		 */ /*
		 * This ensures 3B address is sent to flash even with address
		 * greater than 128Mb.
		 */ /*
		 * Send the sector erase command and address; no receive buffer
		 * is specified since there is nothing to receive
		 */ /*
		 * Wait for the sector erase command to the Flash to be completed
		 */ /*
			 * Poll the status register of the device to determine
			 * when it completes, by sending a read status command
			 * and receiving the status byte
			 */ /*
			 * If the status indicates the write is done, then stop
			 * waiting, if a value of 0xFF in the status byte is
			 * read from the device and this loop never exits, the
			 * device slave select is possibly incorrect such that
			 * the device status is not being read
			 */