⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dataflash.c

📁 AT91BootSAM9261.zip,atmelsam9261微处理器启动初始化源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
		if (AT91F_DataFlashContinuousRead (pDataFlash, addr, (unsigned char *)buffer, SizeToRead) != AT91C_DATAFLASH_OK)
			return FALSE;

		size -= SizeToRead;
		addr += SizeToRead;
		buffer += SizeToRead;
	}

   	return AT91C_DATAFLASH_OK;
}

//*----------------------------------------------------------------------
//* \fn    AT91F_DownloadFromDataflash
//* \brief load the content of the dataflash to SRAM at BASE_LOAD_ADDRESS
//*----------------------------------------------------------------------
int AT91F_DownloadFromDataflash(void)
{
	// read bytes in the dataflash
	if (AT91F_DataFlashRead(&CurrentDataFlash,0,(unsigned char *)AT91C_BASE_LOAD_ADDRESS,SizeToDownload) != AT91C_DATAFLASH_OK)
			return FALSE;

	// wait the dataflash ready status
	if(AT91F_DataFlashWaitReady( &(CurrentDataFlash.DataFlashDesc) ,AT91C_DATAFLASH_TIMEOUT) != AT91C_DATAFLASH_OK)
			return FALSE;

    return TRUE;
}

//*--------------------------------------------------------------------------------------
//* \fn    IsBootValid
//* \brief Check that the first bytes of the buffer are valid ARM vectors
//*--------------------------------------------------------------------------------------
unsigned int IsBootValid(unsigned char *buffer)
{
    int i = 3;

    SizeToDownload = 0;

 	// Verify if the 28 first bytes of the sram correspond to ARM vectors
	// The sixth ARM vector contain the size of the code
    while(i < 28)
    {
		if (i != 23)
		{
			if ((buffer[i] != 0xEA) && (buffer[i] != 0xE5) )
				return FALSE;
		}
		i+=4;
    }

	// Compute the size of code to download in SRAM
    SizeToDownload = ( ((unsigned int)buffer[20]) | (buffer[21]<<8) | (buffer[22] << 16) | (buffer[23] << 24) );
	if (SizeToDownload > AT91C_MEMORY_SIZE)
		return FALSE;

    return TRUE;
}

//*----------------------------------------------------------------------------
//* \fn    AT91F_DataflashProbe
//* \brief
//*----------------------------------------------------------------------------
int AT91F_DataflashProbe(AT91PS_DataflashDesc pDesc)
{

   	if(AT91F_DataFlashGetStatus(pDesc) == AT91C_DATAFLASH_OK)
 	  	return ((pDesc->command[1] == 0xFF)? FALSE: (pDesc->command[1] & 0x3C));
 	else
 		return FALSE;
}

//*------------------------------------------------------------------------------
//* Function Name       : AT91F_DataflashInit
//* \brief
//*------------------------------------------------------------------------------
int AT91F_DataflashInit (void)
{
	int dfcode = 0;
	int Nb_device = 0;

	CurrentDataFlash.Device.pages_number = 0;
	CurrentDataFlash.Device.pages_size = 0;
	CurrentDataFlash.Device.page_offset = 0;
	CurrentDataFlash.DataFlashDesc.DataFlash_state = IDLE;
	CurrentDataFlash.id = 0;

	dfcode = AT91F_DataflashProbe ( &(CurrentDataFlash.DataFlashDesc) );

	switch (dfcode)
	{
		case AT45DB011B:
			CurrentDataFlash.Device.pages_number = 512;
			CurrentDataFlash.Device.pages_size = 264;
			CurrentDataFlash.Device.page_offset = 9;
			CurrentDataFlash.DataFlashDesc.DataFlash_state = IDLE;
			CurrentDataFlash.id = dfcode;
			Nb_device++;
			break;

		case AT45DB021B:
			CurrentDataFlash.Device.pages_number = 1024;
			CurrentDataFlash.Device.pages_size = 264;
			CurrentDataFlash.Device.page_offset = 9;
			CurrentDataFlash.DataFlashDesc.DataFlash_state = IDLE;
			CurrentDataFlash.id = dfcode;
			Nb_device++;
			break;

		case AT45DB041B:
			CurrentDataFlash.Device.pages_number = 2048;
			CurrentDataFlash.Device.pages_size = 264;
			CurrentDataFlash.Device.page_offset = 9;
			CurrentDataFlash.DataFlashDesc.DataFlash_state = IDLE;
			CurrentDataFlash.id = dfcode;
			Nb_device++;
			break;

		case AT45DB081B:
			CurrentDataFlash.Device.pages_number = 4096;
			CurrentDataFlash.Device.pages_size = 264;
			CurrentDataFlash.Device.page_offset = 9;
			CurrentDataFlash.DataFlashDesc.DataFlash_state = IDLE;
			CurrentDataFlash.id = dfcode;
			Nb_device++;
			break;

		case AT45DB161B:
			CurrentDataFlash.Device.pages_number = 4096;
			CurrentDataFlash.Device.pages_size = 528;
			CurrentDataFlash.Device.page_offset = 10;
			CurrentDataFlash.DataFlashDesc.DataFlash_state = IDLE;
			CurrentDataFlash.id = dfcode;
			Nb_device++;
			break;

		case AT45DB321B:
			CurrentDataFlash.Device.pages_number = 8192;
			CurrentDataFlash.Device.pages_size = 528;
			CurrentDataFlash.Device.page_offset = 10;
			CurrentDataFlash.DataFlashDesc.DataFlash_state = IDLE;
			CurrentDataFlash.id = dfcode;
			Nb_device++;
			break;

		case AT45DB642:
			CurrentDataFlash.Device.pages_number = 8192;
			CurrentDataFlash.Device.pages_size = 1056;
			CurrentDataFlash.Device.page_offset = 11;
			CurrentDataFlash.DataFlashDesc.DataFlash_state = IDLE;
			CurrentDataFlash.id = dfcode;
			Nb_device++;
			break;

		case AT45DB1282:
			CurrentDataFlash.Device.pages_number = 16384;
			CurrentDataFlash.Device.pages_size = 1056;
			CurrentDataFlash.Device.page_offset = 11;
			CurrentDataFlash.DataFlashDesc.DataFlash_state = IDLE;
			CurrentDataFlash.id = dfcode;
			Nb_device++;
			break;

		case AT45DB2562:
			CurrentDataFlash.Device.pages_number = 16384;
			CurrentDataFlash.Device.pages_size = 2112;
			CurrentDataFlash.Device.page_offset = 12;
			CurrentDataFlash.DataFlashDesc.DataFlash_state = IDLE;
			CurrentDataFlash.id = dfcode;
			Nb_device++;
			break;

		case AT45DB5122:
			CurrentDataFlash.Device.pages_number = 32768;
			CurrentDataFlash.Device.pages_size = 2112;
			CurrentDataFlash.Device.page_offset = 12;
			CurrentDataFlash.DataFlashDesc.DataFlash_state = IDLE;
			CurrentDataFlash.id = dfcode;
			Nb_device++;
			break;

		default:
			break;
	}

return (Nb_device);
}

//*--------------------------------------------------------------------------------------
//* \fn    AT91F_DataFlashReset_Registers()
//* \brief Set all the registers used to their reset value
//*--------------------------------------------------------------------------------------
void AT91F_DataFlashReset_Registers(void)
{
	// Open PIO for SPI0
	AT91f_CloseSpiPIO();
	// Open PIO for SPI0
	AT91f_CloseDbguPIO();

	// Disables the 48MHz USB clock UDPCK
	AT91C_BASE_PMC->PMC_SCDR = AT91C_PMC_UDP;
	// Close all peripheral clocks used
	AT91C_BASE_PMC->PMC_PCDR = (1 << AT91C_ID_UDP) | (1 << AT91C_ID_SPI0);
}

//*----------------------------------------------------------------------------
//* \fn    AT91F_DataFlashBoot
//* \brief This function performs very low level HW initialization
//*----------------------------------------------------------------------------
void AT91F_DataFlashBoot(unsigned int uPCS)
{
	unsigned char dataflashboot = 0;
	unsigned char rxBuffer[128];

	AT91F_SpiInit(uPCS);

	dataflashboot = AT91F_DataflashInit();

	if (dataflashboot != TRUE)
		return;

	if (AT91F_DataFlashContinuousRead(&CurrentDataFlash,0, rxBuffer, 32) != AT91C_DATAFLASH_OK)
		return;

	// Wait the dataflash ready status
	if(AT91F_DataFlashWaitReady( &(CurrentDataFlash.DataFlashDesc) ,AT91C_DATAFLASH_TIMEOUT) != AT91C_DATAFLASH_OK)
		return;

	if (!IsBootValid(rxBuffer))
		return;

	if(AT91F_DownloadFromDataflash())
	{
		// Reset registers
		AT91F_DataFlashReset_Registers();
		Remap();

	    while(1);
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -