Пример #1
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;
}
Пример #2
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;
        }
    }
}
Пример #3
0
void FlashWrite(unsigned int addr, char *data)
{
    int i;

    FlashErase(addr);		// must erase flash before writing

    TBLPTR = addr;

    // load the table latch with data
    for (i = 0; i < 64; i++)
    {
	TABLAT = data[i];	// copy data from buffer
	_asm
	    TBLWTPOSTINC	// increment the table latch
	_endasm
    }

    TBLPTR = addr;

    EECON1bits.EEPGD = 1;	// select program memory
    EECON1bits.CFGS = 0;	// enable program memory access
    EECON1bits.WREN = 1;	// enable write access

    INTCONbits.GIE = 0;		// disable interrupts

    // write sequence
    EECON2 = 0x55;
    EECON2 = 0xAA;
    EECON1bits.WR = 1;

    INTCONbits.GIE = 1;		// enable interrupts

}
Пример #4
0
Файл: nvm.c Проект: x893/OpenBLT
/************************************************************************************//**
** \brief     Erases the non-volatile memory.
** \param     addr Start address.
** \param     len  Length in bytes.
** \return    BLT_TRUE if successful, BLT_FALSE otherwise.
**
****************************************************************************************/
blt_bool NvmErase(blt_addr addr, blt_int32u len)
{
#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 = NvmEraseHook(addr, len);
  
  /* process the return code */
  if (result == BLT_NVM_OKAY)
  {
    /* address was within range of the additionally supported memory and succesfully
     * erased, so we are all done. 
     */
    return BLT_TRUE;
  }
  else if (result == BLT_NVM_ERROR)
  {
    /* address was within range of the additionally supported memory and attempted to be
     * erased, but an error occurred, so we can't continue.
     */
    return BLT_FALSE;
  }
#endif

  /* still here so the internal driver should try and perform the erase operation */
  return FlashErase(addr, len);
} /*** end of NvmErase ***/
Пример #5
0
/*
 * @brief Edit the bootloader state words (subnet and bootloader state)
 * @param state The value of the bootloader state
 * @return void
 */
void writeBootloaderState(unsigned long state) {
	uint32 tempBootloaderSubnet = bootloaderSubnet;
	// address of the last word (4 bytes) of state flash = 0x0003FFFC
	// address of last 1kb block = 0x0003FC00
	FlashErase(BL_STATE_BLOCK_ADDRESS);
	FlashProgram(&state, BL_STATE_WORD_ADDRESS, sizeof(uint32));
	// address of the second to the last word in state flash
	FlashProgram(&tempBootloaderSubnet, BL_STATE_SUBNET_ADDRESS, sizeof(uint32));
}
unsigned long massStorageWrite(void * drive,unsigned char *data,unsigned long blockNumber,unsigned long numberOfBlocks)
{
	
	//FlashProgram((unsigned long*)data,USER_PROGRAM_START+counter,BLOCK_SIZE*numberOfBlocks);
	//counter+=BLOCK_SIZE*numberOfBlocks;
	
#ifdef DEBUG
	UARTprintf("Write block: %d, no. of blocks: %d\n",blockNumber,numberOfBlocks);
	
	int i,j;
	
	for (j=0;j<BLOCK_SIZE*numberOfBlocks;j+=16){
		for (i=0;i<16;i++)
			UARTprintf("%x ",data[j+i]);
		UARTprintf("\n");
	}
		
#endif	 
	
	if (blockNumber==0){
		memcpy(bootSector,data,BOOT_LEN);
	}
	else if (blockNumber==1||blockNumber==2){
		memcpy(fat,data,FAT_LEN);
		firmware_start_cluster=directory[58];//sometimes the system will move the firmware to a different cluster
		
	}
	else if (blockNumber==3){
		memcpy(directory,data,DIRECTORY_LEN);
		
			
	}
	
	//new firmware is being uploaded
    else if (blockNumber>=FIRMWARE_START_SECTOR&&blockNumber<FIRMWARE_START_SECTOR+USER_PROGRAM_LENGTH/BLOCK_SIZE){
		unsigned long address=(blockNumber-FIRMWARE_START_SECTOR)*BLOCK_SIZE+USER_PROGRAM_START;
				
		if (blockNumber==FIRMWARE_START_SECTOR){
			for (counter=0;counter<239;counter++)
		FlashErase(USER_PROGRAM_START+counter*1024);
		}
		
		FlashProgram((unsigned long*)data,address,BLOCK_SIZE*numberOfBlocks);
		
		return BLOCK_SIZE*numberOfBlocks;
	}
	
	
	return BLOCK_SIZE*numberOfBlocks;
}
Пример #7
0
int					HexrecSign(int a) {
int 				i,crc;
						RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_CRC, ENABLE);
						i=FlashErase(_SIGN_PAGE);
						CRC_ResetDR();
						crc=CRC_CalcBlockCRC((uint32_t *)a,0x8000);
						i |= FlashProgram32((int)_FW_CRC,crc);																// vpisi !!!
						i |= FlashProgram32((int)_FW_SIZE,0x8000);
						i |= FlashProgram32((int)_FW_START,a);
						CRC_ResetDR();
						crc=CRC_CalcBlockCRC((uint32_t *)_FW_SIZE,3);
						i |= FlashProgram32((int)_SIGN_CRC,crc);						
						return i;
}
Пример #8
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;
    }
  }
}
Пример #9
0
/**
 * Erases the indicated flash memory
 
 *  \param startAddress Start location of flash memory that is to be erased
 *  	it must land on a 1KB boundry
 *  \param eraseLength Length of data to erase in flash memory
 *  	it must land on a 1KB boundry, set to 0x0 to skip erasure
 **/
int32_t twe_eraseFlashRange(uint32_t startAddress, uint32_t eraseLength) {
	int32_t status = 0;
	uint32_t modCheck;
	uint32_t block;
	modCheck = startAddress - startAddress/0x400;
	modCheck = modCheck + eraseLength/0x400;
	ASSERT(modCheck == 0);
	if(eraseLength > 0x0) {
		for(block = 0; block < (eraseLength/0x400); block++) {
			status = FlashErase(startAddress + 0x400 * block) // Erases each 1KB block
			ASSERT(status == 0);
		}
	}
	return status;
}
Пример #10
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;
}
Пример #11
0
//*****************************************************************************
//
//! Erases an EEPROM page. 
//!
//! This function is called to erase an EEPROM page.  It verifies that the page
//! has been erased by reading the status words of the page and confirming that
//! they read as 0xFFFFFFFF.
//!
//! \param pucPageAddr is the beginning address of the EEPROM page to erase.
//!
//! \return A value of 0 indicates that the erase was successful.  A non-zero
//! value indicates a failure.
//
//*****************************************************************************
static long
PageErase(unsigned char* pucPageAddr)
{
    unsigned char* pucAddr;

    //
    // Loop through the Flash pages within the specified EEPROM page.
    //
    for(pucAddr = pucPageAddr; pucAddr < (pucPageAddr + g_ulEEPROMPgSize);
        pucAddr += FLASH_ERASE_SIZE)
    {
        //
        // Erase the page.
        //
        if(FlashErase((unsigned long)pucAddr))
        {
            //
            // The erase failed.
            //
            return(-1);
        }
    }

    //
    // Verify that the EEPROM page is indeed erased by checking that the
    // status words are 0xFFFFFFFF (much faster than reading the entire
    // page).  It is assumed that if there was an error erasing the data
    // portion of the page, then it will be detected when verifying the
    // subsequent data writes in SoftEEPROMWrite().
    //
    if(((*(unsigned long*)pucPageAddr) != ERASED_WORD) ||
    ((*(unsigned long*)(pucPageAddr + 4)) != ERASED_WORD))
    {
        //
        // The erase-verify failed.
        //
        return(-1);
    }

    //
    // The erase and erase-verify were successful, so return 0.
    //
    return(0);
}
Пример #12
0
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));
}
Пример #13
0
/******************************************************************
*  Function: TopMenu
*
*  Purpose: Generates the top level menu.
* 
******************************************************************/
static int TopMenu( void )
{
  char ch;

  /* Print the top-level menu to stdout */
  while (1)
  {
    MenuBegin("      Memory Test Main Menu");
    MenuItem( 'a', "Test RAM" );
    MenuItem( 'b', "Test Flash");
    ch = MenuEnd( 'a', 'b' );

    switch(ch)
    {
      MenuCase('a',TestRam());
      MenuCase('b',TestFlash(TEST));
      MenuCase('e',FlashErase());       /* hidden option */
      MenuCase('m',TestFlash(SHOWMAP)); /* hidden option */
    }
    if (ch == 'q')
      break;
  }
  return (ch);
}
Пример #14
0
//*****************************************************************************
//
// Erase the data storage area of flash.
//
//*****************************************************************************
void
FlashStoreErase(void)
{
    unsigned long ulAddr;

    //
    // Inform user we are erasing
    //
    SetStatusText("ERASE", 0, "ERASING", 0);

    //
    // Loop through entire storage area and erase each page.
    //
    for(ulAddr = FLASH_STORE_START_ADDR; ulAddr < FLASH_STORE_END_ADDR;
        ulAddr += 0x400)
    {
        FlashErase(ulAddr);
    }

    //
    // Inform user the erase is done.
    //
    SetStatusText("SAVE", "ERASE", "COMPLETE", "PRESS <");
}
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;
}
Пример #16
0
void Persistent::pageInit(uint8_t* address, uint32_t sequence) {
	FlashErase((uint32_t) address);
	FlashProgram(&sequence, (uint32_t) address, 4);
}
Пример #17
0
void Persistent::pageErase(uint8_t* address) {
	FlashErase((uint32_t) address);
}
Пример #18
0
int32_t FlashWrite(uint16_t *source, uint16_t *destination, uint32_t numBytes)
{
    uint16_t first_sector;
    uint16_t last_sector;
    uint32_t sector_size;
    uint32_t sector_base;
    uint32_t sector_num;
    uint8_t  *buffer;
    uint8_t  *src;
    uint8_t  *dst;

    uint32_t len=0;

    if((uint32_t)destination > max_flash_size) {
	printk("%s: %08X out of scope \n",__FUNCTION__, (uint32_t)destination);
	return -1;
    }

    src=(uint8_t *)source;
    dst=(uint8_t *)(logic2phy((uint32_t)destination));

    /* get covered sector range */
    first_sector = FlashSectNum((uint32_t)dst);
    last_sector =  FlashSectNum((uint32_t)dst+numBytes -1);
    buffer=kmalloc(FLASH_MAX_RW_SIZE, GFP_KERNEL);
    
    for(sector_num=first_sector; sector_num<= last_sector; sector_num++ ) {

	/* each sector has different size and base address */
	sector_size=FlashSectSize(sector_num);
	sector_base=FlashSectAddr(sector_num);

	/* prepare new sector contents */
	memcpy((char *)buffer, (char *)sector_base, sector_size);
	if((uint32_t)dst+numBytes < sector_base+sector_size) {
	    memcpy(&buffer[(uint32_t)dst-sector_base], src, numBytes);
	}else {
	    len=sector_base+sector_size-(uint32_t)dst;
	    memcpy(&buffer[sector_size-len], src, len);
	    src+=len;
	    dst+=len;
	    numBytes-=len;
	}

	/* burn new sector contents */
	FlashErase(sector_num, sector_num);
#ifdef CONFIG_FLASH_SST39VF320X
	if(isSST) {
		__SSTFlashWrite((uint16_t *)buffer, (uint16_t *)sector_base, sector_size);
	} else {
		__FlashWrite((uint16_t *)buffer, (uint16_t *)sector_base, sector_size);
	}
#else
	__FlashWrite((uint16_t *)buffer, (uint16_t *)sector_base, sector_size);
#endif
	
    }
    
    kfree(buffer);
    return 0;
}
/*****************************************************************************
*
* 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;
}
/*****************************************************************************
*
* 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;
}
Пример #21
0
/*-----------------------------------------------------------------------------
*  Verarbeitung der Bustelegramme
*/
static void ProcessBus(UINT8 ret) {
   
   TBusMsgType   msgType;    
   UINT16        *pData;
   UINT16        wordAddr;
   BOOL          rc;
   BOOL          msgForMe = FALSE;

   if (ret == BUS_MSG_OK) {
      msgType = spRxBusMsg->type; 
      switch (msgType) {  
         case eBusDevReqReboot:
         case eBusDevReqUpdEnter:
         case eBusDevReqUpdData:
         case eBusDevReqUpdTerm:
            if (spRxBusMsg->msg.devBus.receiverAddr == MY_ADDR) {
               msgForMe = TRUE;
            }
         default:
            break;
      }
      if (msgForMe == FALSE) {
         return;
      }

    
      if (msgType == eBusDevReqReboot) {
         /* Über Watchdog Reset auslösen */    
         /* Watchdogtimeout auf kurzeste Zeit (14 ms) stellen */                     
         cli();
         wdt_enable(WDTO_15MS);
         /* warten auf Reset */
         while (1);
      } else {
         switch (sFwuState) {
            case WAIT_FOR_UPD_ENTER_TIMEOUT:
            case WAIT_FOR_UPD_ENTER:
               if (msgType == eBusDevReqUpdEnter) {
                  /* Applicationbereich des Flash löschen */  
                  FlashErase();
                  /* Antwort senden */
                  SetMsg(eBusDevRespUpdEnter, spRxBusMsg->senderAddr);
                  BusSend(&sTxBusMsg);
                  sFwuState = WAIT_FOR_UPD_DATA;     
               }           
               break;
            case WAIT_FOR_UPD_DATA:
               if (msgType == eBusDevReqUpdData) {
                  wordAddr = spRxBusMsg->msg.devBus.x.devReq.updData.wordAddr;
                  pData = spRxBusMsg->msg.devBus.x.devReq.updData.data;
                  /* Flash programmieren */
                  rc = FlashProgram(wordAddr, pData, sizeof(spRxBusMsg->msg.devBus.x.devReq.updData.data) / 2);
                  /* Antwort senden */
                  SetMsg(eBusDevRespUpdData, spRxBusMsg->senderAddr);
                  if (rc == TRUE) {
                     /* Falls Programmierung des Block OK: empfangene wordAddr zurücksenden */
                     sTxBusMsg.msg.devBus.x.devResp.updData.wordAddr = wordAddr;
                  } else {
                     /* Problem bei Programmierung: -1 als wordAddr zurücksenden */
                     sTxBusMsg.msg.devBus.x.devResp.updData.wordAddr = -1;
                  }
                  BusSend(&sTxBusMsg);  
               } else if (msgType == eBusDevReqUpdTerm) {
                  /* programmiervorgang im Flash abschließen (falls erforderlich) */
                  rc = FlashProgramTerminate();
                  /* Antwort senden */
                  SetMsg(eBusDevRespUpdTerm, spRxBusMsg->senderAddr);
                  if (rc == TRUE) {
                     /* Falls Programmierung OK: success auf 1 setzen */
                     sTxBusMsg.msg.devBus.x.devResp.updTerm.success = 1;
                  } else {
                     /* Problem bei Programmierung: -1 als wordAddr zurücksenden */
                     sTxBusMsg.msg.devBus.x.devResp.updTerm.success = 0;
                  }
                  BusSend(&sTxBusMsg);
               }
               break;
            default:
               break;
         }
      }
   }
}
/*****************************************************************************
*
* 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;
}
/*****************************************************************************
*
* 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;
}
Пример #25
0
//*****************************************************************************
//
// This is the main application entry function.
//
//*****************************************************************************
int
main(void)
{
    uint32_t ui32TxCount;
    uint32_t ui32RxCount;
    //uint32_t ui32Loop;

    //
    // Enable lazy stacking for interrupt handlers.  This allows floating-point
    // instructions to be used within interrupt handlers, but at the expense of
    // extra stack usage.
    //
    ROM_FPULazyStackingEnable();

    //
    // Set the clocking to run from the PLL at 50MHz
    //
#if 1
    ROM_SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN |
                       SYSCTL_XTAL_16MHZ);

    //
    // Configure the required pins for USB operation.
    //
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
    ROM_GPIOPinTypeUSBAnalog(GPIO_PORTD_BASE, GPIO_PIN_5 | GPIO_PIN_4);
       //ROM_SysTickPeriodSet(ROM_SysCtlClockGet() / 100);

    /* This code taken from: http://e2e.ti.com/support/microcontrollers/tiva_arm/f/908/t/311237.aspx
    */
#else       
#include "hw_nvic.h"
       FlashErase(0x00000000);
       ROM_IntMasterDisable();
       ROM_SysTickIntDisable();
       ROM_SysTickDisable();
       uint32_t ui32SysClock;
       ROM_SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);
       ui32SysClock = ROM_SysCtlClockGet();
       ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
       ROM_GPIOPinTypeUSBAnalog(GPIO_PORTD_BASE, GPIO_PIN_4 | GPIO_PIN_5);
       ROM_SysTickPeriodSet(ROM_SysCtlClockGet() / 100);
       HWREG(NVIC_DIS0) = 0xffffffff;
       HWREG(NVIC_DIS1) = 0xffffffff;
       HWREG(NVIC_DIS2) = 0xffffffff;
       HWREG(NVIC_DIS3) = 0xffffffff;
       HWREG(NVIC_DIS4) = 0xffffffff;
       int ui32Addr;
       for(ui32Addr = NVIC_PRI0; ui32Addr <= NVIC_PRI34; ui32Addr+=4)
       {
          HWREG(ui32Addr) = 0;
       }
       HWREG(NVIC_SYS_PRI1) = 0;
       HWREG(NVIC_SYS_PRI2) = 0;
       HWREG(NVIC_SYS_PRI3) = 0;
       ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_USB0);
       ROM_SysCtlPeripheralReset(SYSCTL_PERIPH_USB0);
       ROM_SysCtlUSBPLLEnable();
       ROM_SysCtlDelay(ui32SysClock*2 / 3);
       ROM_IntMasterEnable();
       ROM_UpdateUSB(0);
       while(1)
           {
           }
#endif
#define BOOTLOADER_TEST 0
#if BOOTLOADER_TEST
#include "hw_nvic.h"
    
    //ROM_UpdateUART();
    // May need to do the following here:
    //  0. See if this will cause bootloader to start
    //ROM_FlashErase(0); 
    //ROM_UpdateUSB(0);
    
#define SYSTICKS_PER_SECOND 100
    uint32_t ui32SysClock = ROM_SysCtlClockGet();
    ROM_SysTickPeriodSet(ROM_SysCtlClockGet() / SYSTICKS_PER_SECOND);
    ROM_SysTickIntEnable();
    ROM_SysTickEnable();
    
    //USBDCDTerm(0);
    
    // Disable all interrupts
    ROM_IntMasterDisable();
    ROM_SysTickIntDisable();
    ROM_SysTickDisable();
    HWREG(NVIC_DIS0) = 0xffffffff;
    HWREG(NVIC_DIS1) = 0xffffffff;
    HWREG(NVIC_DIS2) = 0xffffffff;
    HWREG(NVIC_DIS3) = 0xffffffff;
    HWREG(NVIC_DIS4) = 0xffffffff;
       int ui32Addr;
       for(ui32Addr = NVIC_PRI0; ui32Addr <= NVIC_PRI34; ui32Addr+=4)
       {
          HWREG(ui32Addr) = 0;
       }
       HWREG(NVIC_SYS_PRI1) = 0;
       HWREG(NVIC_SYS_PRI2) = 0;
       HWREG(NVIC_SYS_PRI3) = 0;
    
    //  1. Enable USB PLL
    //ROM_SysCtlUSBPLLEnable();
    //  2. Enable USB controller
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_USB0);
    ROM_SysCtlPeripheralReset(SYSCTL_PERIPH_USB0);
    //USBClockEnable(USB0_BASE, 8, USB_CLOCK_INTERNAL);
    //HWREG(USB0_BASE + USB_O_CC) = (8 - 1) | USB_CLOCK_INTERNAL;

    ROM_SysCtlUSBPLLEnable();
    
    //  3. Enable USB D+ D- pins

    //  4. Activate USB DFU
    ROM_SysCtlDelay(ui32SysClock * 2 / 3);
    ROM_IntMasterEnable();  // Re-enable interrupts at NVIC level
    ROM_UpdateUSB(0);
    //  5. Should never get here since update is in progress
#endif // BOOTLOADER_TEST

    //
    // Enable the GPIO port that is used for the on-board LED.
    //
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);    // gjs Our board uses GPIOB for LEDs
    // gjs original ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);

    //
    // Enable the GPIO pins for the LED (PF2 & PF3).
    //
    ROM_GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE, GPIO_PIN_0|GPIO_PIN_1);
    // gjs original ROM_GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_3|GPIO_PIN_2);

    //
    // Not configured initially.
    //
    g_bUSBConfigured = false;

    //
    // Enable the UART that we will be redirecting.
    //
    ROM_SysCtlPeripheralEnable(USB_UART_PERIPH);

    //
    // Enable and configure the UART RX and TX pins
    //
    ROM_SysCtlPeripheralEnable(TX_GPIO_PERIPH);
    ROM_SysCtlPeripheralEnable(RX_GPIO_PERIPH);
    ROM_GPIOPinTypeUART(TX_GPIO_BASE, TX_GPIO_PIN);
    ROM_GPIOPinTypeUART(RX_GPIO_BASE, RX_GPIO_PIN);

    //
    // TODO: Add code to configure handshake GPIOs if required.
    //

    //
    // Set the default UART configuration.
    //
    ROM_UARTConfigSetExpClk(USB_UART_BASE, ROM_SysCtlClockGet(),
                            DEFAULT_BIT_RATE, DEFAULT_UART_CONFIG);
    ROM_UARTFIFOLevelSet(USB_UART_BASE, UART_FIFO_TX4_8, UART_FIFO_RX4_8);

    //
    // Configure and enable UART interrupts.
    //
    ROM_UARTIntClear(USB_UART_BASE, ROM_UARTIntStatus(USB_UART_BASE, false));
    ROM_UARTIntEnable(USB_UART_BASE, (UART_INT_OE | UART_INT_BE | UART_INT_PE |
                      UART_INT_FE | UART_INT_RT | UART_INT_TX | UART_INT_RX));

    //
    // Enable the system tick.
    //
#if 0    
    ROM_SysTickPeriodSet(ROM_SysCtlClockGet() / SYSTICKS_PER_SECOND);
    ROM_SysTickIntEnable();
    ROM_SysTickEnable();
#endif
    //
    // Initialize the transmit and receive buffers.
    //
    USBBufferInit(&g_sTxBuffer);
    USBBufferInit(&g_sRxBuffer);

    //
    // Set the USB stack mode to Device mode with VBUS monitoring.
    //
    USBStackModeSet(0, eUSBModeDevice, 0);

    //
    // Pass our device information to the USB library and place the device
    // on the bus.
    //
    USBDCDCInit(0, &g_sCDCDevice);

    //
    // Clear our local byte counters.
    //
    ui32RxCount = 0;
    ui32TxCount = 0;

    //
    // Enable interrupts now that the application is ready to start.
    //
    ROM_IntEnable(USB_UART_INT);

    // Enable FreeRTOS
    mainA(); // FreeRTOS. Will not return
    
#if 0    
    //
    // Main application loop.
    //
    while(1)
    {
        //
        // Have we been asked to update the status display?
        //
        if(g_ui32Flags & COMMAND_STATUS_UPDATE)
        {
            //
            // Clear the command flag
            //
            ROM_IntMasterDisable();
            g_ui32Flags &= ~COMMAND_STATUS_UPDATE;
            ROM_IntMasterEnable();
        }

        //
        // Has there been any transmit traffic since we last checked?
        //
        if(ui32TxCount != g_ui32UARTTxCount)
        {
            //
            // Turn on the Green LED.
            //
            // gjs ROM_UARTCharPutNonBlocking(USB_UART_BASE, 'b');

#if 1
            if (ui32TxCount & 1) {
                GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_0, GPIO_PIN_0);
            } else {
                GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_0, 0);
            }
#else            
            if (1 || g_ui32UARTTxCount & 0x01) {
                GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_3, GPIO_PIN_3);
            } else {
                //GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_3, 0);
            }

            //
            // Delay for a bit.
            //
            for(uint32_t ui32Loop = 0; ui32Loop < 150000; ui32Loop++)
            {
            }

            //
            // Turn off the Green LED.
            //
            GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_3, 0);
#endif            

            //
            // Take a snapshot of the latest transmit count.
            //
            ui32TxCount = g_ui32UARTTxCount;
        }

        //
        // Has there been any receive traffic since we last checked?
        //
        if(ui32RxCount != g_ui32UARTRxCount)
        {
            //
            // Turn on the Blue LED.
            //
#if 1
            if (ui32RxCount & 1) {
                GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_1, GPIO_PIN_1);
            } else {
                GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_1, 0);
            }
#else            
            GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, GPIO_PIN_2);

            //
            // Delay for a bit.
            //
            for(uint32_t ui32Loop = 0; ui32Loop < 150000; ui32Loop++)
            {
            }

            //
            // Turn off the Blue LED.
            //
            GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, 0);
#endif
            //
            // Take a snapshot of the latest receive count.
            //
            ui32RxCount = g_ui32UARTRxCount;

        }
    }
#endif    
}
/*****************************************************************************
*
* 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;
}
Пример #27
0
//*****************************************************************************
//
//! Writes a new parameter block to flash.
//!
//! \param pucBuffer is the address of the parameter block to be written to
//! flash.
//!
//! This function will write a parameter block to flash.  Saving the new
//! parameter blocks involves three steps:
//!
//! - Setting the sequence number such that it is one greater than the sequence
//!   number of the latest parameter block in flash.
//! - Computing the checksum of the parameter block.
//! - Writing the parameter block into the storage immediately following the
//!   latest parameter block in flash; if that storage is at the start of an
//!   erase block, that block is erased first.
//!
//! By this process, there is always a valid parameter block in flash.  If
//! power is lost while writing a new parameter block, the checksum will not
//! match and the partially written parameter block will be ignored.  This is
//! what makes this fault-tolerant.
//!
//! Another benefit of this scheme is that it provides wear leveling on the
//! flash.  Since multiple parameter blocks fit into each erase block of flash,
//! and multiple erase blocks are used for parameter block storage, it takes
//! quite a few parameter block saves before flash is re-written.
//!
//! \return None.
//
//*****************************************************************************
void
FlashPBSave(unsigned char *pucBuffer)
{
    unsigned char *pucNew;
    unsigned long ulIdx, ulSum;

    //
    // Check the arguments.
    //
    ASSERT(pucBuffer != (void *)0);

    //
    // See if there is a valid parameter block in flash.
    //
    if(g_pucFlashPBCurrent)
    {
        //
        // Set the sequence number to one greater than the most recent
        // parameter block.
        //
        pucBuffer[0] = g_pucFlashPBCurrent[0] + 1;

        //
        // Try to write the new parameter block immediately after the most
        // recent parameter block.
        //
        pucNew = g_pucFlashPBCurrent + g_ulFlashPBSize;
        if(pucNew == g_pucFlashPBEnd)
        {
            pucNew = g_pucFlashPBStart;
        }
    }
    else
    {
        //
        // There is not a valid parameter block in flash, so set the sequence
        // number of this parameter block to zero.
        //
        pucBuffer[0] = 0;

        //
        // Try to write the new parameter block at the beginning of the flash
        // space for parameter blocks.
        //
        pucNew = g_pucFlashPBStart;
    }

    //
    // Compute the checksum of the parameter block to be written.
    //
    for(ulIdx = 0, ulSum = 0; ulIdx < g_ulFlashPBSize; ulIdx++)
    {
        ulSum -= pucBuffer[ulIdx];
    }

    //
    // Store the checksum into the parameter block.
    //
    pucBuffer[1] += ulSum;

    //
    // Look for a location to store this parameter block.  This infinite loop
    // will be explicitly broken out of when a valid location is found.
    //
    while(1)
    {
        //
        // See if this location is at the start of an erase block.
        //
        if(((unsigned long)pucNew & 1023) == 0)
        {
            //
            // Erase this block of the flash.  This does not assume that the
            // erase succeeded in case this block of the flash has become bad
            // through too much use.  Given the extremely low frequency that
            // the parameter blocks are written, this will likely never fail.
            // But, that assumption is not made in order to be safe.
            //
            FlashErase((unsigned long)pucNew);
        }

        //
        // Loop through this portion of flash to see if is all ones (i.e. it
        // is an erased portion of flash).
        //
        for(ulIdx = 0; ulIdx < g_ulFlashPBSize; ulIdx++)
        {
            if(pucNew[ulIdx] != 0xff)
            {
                break;
            }
        }

        //
        // If all bytes in this portion of flash are ones, then break out of
        // the loop since this is a good location for storing the parameter
        // block.
        //
        if(ulIdx == g_ulFlashPBSize)
        {
            break;
        }

        //
        // Increment to the next parameter block location.
        //
        pucNew += g_ulFlashPBSize;
        if(pucNew == g_pucFlashPBEnd)
        {
            pucNew = g_pucFlashPBStart;
        }

        //
        // If every possible location has been checked and none are valid, then
        // it will not be possible to write this parameter block.  Simply
        // return without writing it.
        //
        if((g_pucFlashPBCurrent && (pucNew == g_pucFlashPBCurrent)) ||
           (!g_pucFlashPBCurrent && (pucNew == g_pucFlashPBStart)))
        {
            return;
        }
    }

    //
    // Write this parameter block to flash.
    //
    FlashProgram((unsigned long *)pucBuffer, (unsigned long)pucNew,
                 g_ulFlashPBSize);

    //
    // Compare the parameter block data to the data that should now be in
    // flash.  Return if any of the data does not compare, leaving the previous
    // parameter block in flash as the most recent (since the current parameter
    // block failed to properly program).
    //
    for(ulIdx = 0; ulIdx < g_ulFlashPBSize; ulIdx++)
    {
        if(pucNew[ulIdx] != pucBuffer[ulIdx])
        {
            return;
        }
    }

    //
    // The new parameter block becomes the most recent parameter block.
    //
    g_pucFlashPBCurrent = pucNew;
}
Пример #28
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;
    }
  }
}
/*****************************************************************************
*
* 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;
}
Пример #30
0
/* erase flash */
FlashError_t
BDMFlashErase( void )
{
    return (FlashErase( &Flash ));
}