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

📄 init_sam9.c

📁 AT91BootSAM9261.zip,atmelsam9261微处理器启动初始化源代码
💻 C
字号:
//*----------------------------------------------------------------------------
//*         ATMEL Microcontroller Software Support  -  ROUSSET  -
//*----------------------------------------------------------------------------
//* The software is delivered "AS IS" without warranty or condition of any
//* kind, either express, implied or statutory. This includes without
//* limitation any warranty or condition with respect to merchantability or
//* fitness for any particular purpose, or against the infringements of
//* intellectual property rights of others.
//*----------------------------------------------------------------------------
//* File Name           : init.c
//* Object              : Low level initializations written in C
//* Creation            : ODi   06/26/2002
//*
//*----------------------------------------------------------------------------

#include "main.h"
#include "dataflash.h"

extern struct _AT91S_CDC 	pCDC;
extern AT91S_XMODEM 		xModem;
extern AT91PS_XMODEM 		AT91F_XMODEM_Open(AT91PS_XMODEM);

/////////////////////////////////////////////////////////////////////////////////////////////////////
// Constants defined for PLL
/////////////////////////////////////////////////////////////////////////////////////////////////////
//	Array to determine the PLLB setup for 48MHz USB clock
//	PLLB_OUTPUT = FREQ * (MUL+1)/DIV = 96 MHz
//	USB_CLOCK = PLLB_OUTPUT/2;
/////////////////////////////////////////////////////////////////////////////////////////////////////
const int PLLB_SETUP[][2] =
{
//		Freq   DIV	   MUL
	{ 3000000, 	1  + ((32 -1) << 16) },
	{ 3276800, 	3  + ((88 -1) << 16) },
	{ 3686400, 	1  + ((26 -1) << 16) },
	{ 3840000, 	1  + ((25 -1) << 16) },
	{ 4000000, 	1  + ((24 -1) << 16) },
	{ 4433619, 	3  + ((65 -1) << 16) },
	{ 4608000, 	5  + ((104 -1) << 16) },
	{ 4915200, 	2  + ((39 -1) << 16) },
	{ 5000000, 	5  + ((96 -1) << 16) },
	{ 5242880, 	3  + ((55 -1) << 16) },
	{ 6000000, 	1  + ((16 -1) << 16) },
	{ 6144000, 	5  + ((78 -1) << 16) },
	{ 6400000, 	1  + ((15 -1) << 16) },
	{ 6553600, 	3  + ((44 -1) << 16) },
	{ 7159090, 	5  + ((67 -1) << 16) },
	{ 7372800, 	1  + ((13 -1) << 16) },
	{ 7864320, 	5  + ((61 -1) << 16) },
	{ 8000000, 	1  + ((12 -1) << 16) },
	{ 9830400, 	9  + ((88 -1) << 16) },
	{ 10000000, 5  + ((48 -1) << 16) },
	{ 11059200, 3  + ((26 -1) << 16) },
	{ 12000000, 1  + (( 8 -1) << 16) },
	{ 12288000,	11 + ((86 -1) << 16) },
	{ 13000000, 13 + ((96 -1) << 16) },
	{ 13560000,	13 + ((92 -1) << 16) },
	{ 14318180, 10 + ((67 -1) << 16) },
	{ 14745600, 2  + ((13 -1) << 16) },
	{ 16000000, 1  + (( 6 -1) << 16) },
	{ 16367667, 15 + ((88 -1) << 16) },
	{ 17734470, 17 + ((92 -1) << 16) },
	{ 18432000, 14 + ((73 -1) << 16) },
	{ 20000000, 5  + ((24 -1) << 16) },
	{ 24000000, 1  + (( 4 -1) << 16) },
	{ 25000000, 25 + ((96 -1) << 16) },
	{ 26000000, 13 + ((48 -1) << 16) },
	{ 28224000, 5  + ((17 -1) << 16) },
	{ 32000000, 1  + (( 3 -1) << 16) },
	{ 33000000, 11 + ((32 -1) << 16) },
	{ 40000000, 10 + ((24 -1) << 16) },
	{ 0		  , 0				     },
};

//*----------------------------------------------------------------------------
//* \fn    AT91F_US_Baudrate
//* \brief Calculate baud_value according to the main clock and the baud rate
//*----------------------------------------------------------------------------
unsigned int AT91F_GetBaudrate (
	const unsigned int main_clock, // \arg peripheral clock
	const unsigned int baud_rate)  // \arg UART baudrate
{
	unsigned int baud_value = ((main_clock*10)/(baud_rate * 16));
	if ((baud_value % 10) >= 5)
		baud_value = (baud_value / 10) + 1;
	else
		baud_value /= 10;
	return baud_value;
}

//*----------------------------------------------------------------------------
//* \fn    AT91F_EndOfCalibration
//* \brief Autobaudrate State Machine
//*----------------------------------------------------------------------------
unsigned int AT91F_EndOfCalibration(void)
{
	if (AT91C_BASE_DBGU->DBGU_CSR & AT91C_US_RXRDY)
		return AT91C_FINAL;
	else
		return AT91C_INIT;
}


//*----------------------------------------------------------------------------
//* \fn    AT91F_LowLevelInit
//* \brief This function performs very low level HW initialization
//*----------------------------------------------------------------------------
void AT91F_LowLevelInit()
{
	unsigned int	tmp	= 0;
	int 			MainClock = 0;
	const char* 	pBuffer = "RomBOOT\n\r>";

/////////////////////////////////////////////////////////////////////////////////////////////////////
// PMC Init Step 3.
// Check the Main Oscillator Frequency and Find Corresponding Quartz
/////////////////////////////////////////////////////////////////////////////////////////////////////

	// Wait for MAINRDY flag in PMC_MCFR
	tmp = 0;
	while(!(AT91C_BASE_CKGR->CKGR_MCFR & AT91C_CKGR_MAINRDY) && (tmp++ < DELAY) );

	// Compute MAINCK <=> nb of main clock cycles in 16 slow clock cycles (SLCK = 32768 kHz)
	MainClock = (AT91C_BASE_CKGR->CKGR_MCFR  & AT91C_CKGR_MAINF) * (32768/16);

	// Find the crystal frequency and the PLLB setup in the crystal_freq table (in Hz)
	tmp = 0;
	while( (PLLB_SETUP[tmp][0] != 0) && (MainClock - PLLB_SETUP[tmp][0] > 0))
		tmp++;

	// if the crystal frequency doesn't match with the table content
	if(PLLB_SETUP[tmp][0] == 0)
		return;

	// find the correct entry in the table
	if ((MainClock - PLLB_SETUP[tmp-1][0]) < (PLLB_SETUP[tmp][0] - MainClock))
		tmp --;

	// if the crystal value doesn't match
	if (PLLB_SETUP[tmp][0] == 0)
		return;

/////////////////////////////////////////////////////////////////////////////////////////////////////
// PMC Init Step 4.
// Setting PLL and Divider
/////////////////////////////////////////////////////////////////////////////////////////////////////

#ifdef AT91C340
	AT91C_BASE_CKGR->CKGR_PLLBR = AT91C_CKGR_USBDIV_1 | AT91C_CKGR_OUTB_1 | AT91C_CKGR_PLLBCOUNT |\
								PLLB_SETUP[tmp][1];
#else
	AT91C_BASE_CKGR->CKGR_PLLBR = AT91C_CKGR_USBDIV_1 | AT91C_CKGR_OUTB_0 | AT91C_CKGR_PLLBCOUNT |\
								PLLB_SETUP[tmp][1];
#endif


	// Wait for PLL stabilization LOCKB bit in PMC_SR
	tmp = 0;
	while( !(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_LOCKB) && (tmp++ < DELAY) );

/////////////////////////////////////////////////////////////////////////////////////////////////////
// PMC Init Step 5.
// Selection of Master Clock MCK (Processor Clock PCK/2)
/////////////////////////////////////////////////////////////////////////////////////////////////////

	// MCK=PCK/2=PLL/2
	AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_CSS_PLLB_CLK|AT91C_PMC_PRES_CLK|AT91C_PMC_MDIV_2;

	// Wait until the master clock is established
	tmp = 0;
	while( !(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY) && (tmp++ < DELAY) );

/////////////////////////////////////////////////////////////////////////////////////////////////////
// DBGU Initialisation
/////////////////////////////////////////////////////////////////////////////////////////////////////

	// Open PIO for DBGU
	AT91f_OpenDbguPIO();

    // Disable interrupts
    AT91C_BASE_DBGU->DBGU_IDR = (unsigned int) -1;

    // Reset receiver and transmitter
    AT91C_BASE_DBGU->DBGU_CR = AT91C_US_RSTRX | AT91C_US_RSTTX | AT91C_US_RXDIS | AT91C_US_TXDIS ;

	// Define the baud rate divisor register
	AT91C_BASE_DBGU->DBGU_BRGR = AT91F_GetBaudrate(AT91C_MASTER_CLOCK, AT91C_BAUDRATE_115200);

    // Define the USART mode
    AT91C_BASE_DBGU->DBGU_MR = AT91C_DBGU_ASYNC_MODE;

	// Enable Transmitter and Receiver
    AT91C_BASE_DBGU->DBGU_CR = AT91C_US_TXEN | AT91C_US_RXEN;

	// Print Init Buffer
	while(*pBuffer != '\0')
	{
		while (!(AT91C_BASE_DBGU->DBGU_CSR & AT91C_US_TXRDY));
		AT91C_BASE_DBGU->DBGU_THR = (*pBuffer++ & 0x1FF);
	}
	while ( !((AT91C_BASE_DBGU->DBGU_CSR) & AT91C_US_TXEMPTY) );

/////////////////////////////////////////////////////////////////////////////////////////////////////
// SYSC: User Reset Init
/////////////////////////////////////////////////////////////////////////////////////////////////////

	// Enable User Reset and set its assertion min to 960 us
	AT91C_BASE_RSTC->RSTC_RMR = AT91C_RSTC_URSTEN | (0x4<<8) | (0xA5<<24);

/////////////////////////////////////////////////////////////////////////////////////////////////////
// Xmodem + CDC Open
/////////////////////////////////////////////////////////////////////////////////////////////////////
 	AT91F_XMODEM_Open(&xModem);
	AT91F_CDC_Open(&pCDC, AT91C_BASE_UDP);

}

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

	// Close all peripheral clocks used
	AT91C_BASE_PMC->PMC_PCDR = (1 << AT91C_ID_SPI0);


#if defined (AT91SAM9260) || defined (AT91SAM9262)

	// Close Smart Media, disable the address range of CS3 in HMATRIX user interface
	AT91C_BASE_MATRIX->MATRIX_EBI0 &= ~AT91C_MATRIX_CS3A_SM;

	// Close PIOA Clock
#ifdef AT91SAM9260
	AT91C_BASE_PMC->PMC_PCDR = ((unsigned int) 1 << AT91C_ID_PIOB);
#else
	AT91C_BASE_PMC->PMC_PCDR = ((unsigned int) 1 << AT91C_ID_PIOA);
#endif

	AT91f_CloseNandFlashPIO();

#endif

}

//*----------------------------------------------------------------------------
//* \fn    AT91F_SpiInit
//* \brief
//*----------------------------------------------------------------------------
void AT91F_SpiInit(void)
{
	// Open PIO for SPI0
	AT91f_OpenSpiPIO();

	// Enables the SPI0 Clock
	AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_SPI0);

	// Reset SPI0
	AT91C_BASE_SPI0->SPI_CR = AT91C_SPI_SWRST;

    // Configure SPI0 in Master Mode with No CS selected
	AT91C_BASE_SPI0->SPI_MR = AT91C_SPI_MSTR | AT91C_SPI_MODFDIS | AT91C_SPI_PCS;

	// Configure CS0 (SPI Mode 3)
	*(AT91C_SPI0_CSR + 0) = AT91C_SPI_CPOL | (AT91C_SPI_DLYBS & DATAFLASH_TCSS) | (AT91C_SPI_DLYBCT & DATAFLASH_TCHS) | ((AT91C_MASTER_CLOCK / AT91C_SPI_CLK) << 8);

	// Choose CS0
	AT91C_BASE_SPI0->SPI_MR &= 0xFFF0FFFF;
	AT91C_BASE_SPI0->SPI_MR |= ((AT91C_SPI_PCS0_DATAFLASH<<16) & AT91C_SPI_PCS);

	// SPI_Enable
	AT91C_BASE_SPI0->SPI_CR = AT91C_SPI_SPIEN;
}

//*----------------------------------------------------------------------------
//* \fn    AT91F_InitUSB
//* \brief
//*----------------------------------------------------------------------------
void AT91F_InitUSB(void)
{
	// Enables the 48MHz USB clock UDPCK
	AT91C_BASE_PMC->PMC_SCER = AT91C_PMC_UDP;

	// Enables the USB Clock
	AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_UDP);

	// Enable the pull-up
#ifndef AT91SAM9261
	AT91C_BASE_UDP->UDP_TXVC = (AT91C_UDP_PUON); // Set PUON and Clear TXVDIS
#else
	AT91C_BASE_MATRIX->MATRIX_USBPCR = AT91C_MATRIX_USBPCR_PUON;
#endif
}

⌨️ 快捷键说明

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