📄 main.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 : Boot_loader main file//* Object ://* Translator ://* 1.0 19/03/01 HI : Creation//* 1.1 02/10/02 FB : Add on Svc DataFlash//*--------------------------------------------------------------------------------------#include "services/obj_romboot.h"#include "usb_enum.h"#include "appli/includes/main.h"#include "appli/includes/download.h"#include "appli/includes/lib_main.h"#include "eeprom.h"/* ================================================================ *//* ====================== External const ====================== *//* ================================================================ */// Defined in constant.cextern const USBDfuModeDesc USB_DFU_DESC;extern const char USART_HEADER[];extern const int PLLB_SETUP[][2];/* ================================================================ *//* ====================== Variables ====================== *//* ================================================================ */AT91S_RomBoot const *pAT91;AT91S_SBuffer sUdpBuffer;AT91S_SBuffer sXmBuffer;AT91S_SvcUdp svcUdp;AT91S_SvcXmodem svcXmodem;AT91S_Pipe udpPipe;AT91S_Pipe xmodemPipe;AT91S_UsbDesc usbDesc;AT91S_DfuDesc dfuDesc;AT91S_CtlTempo ctlTempo;AT91S_UsbSetup dfuSetup;AT91S_SvcDataFlash svcDataFlash;AT91S_Dataflash DataFlashDevice;int SizeToDownload;volatile unsigned int StTick; //* system timer tick count for timeout int SizeUpload;/* ================================================================ *//* ====================== Local functions ====================== *//* ================================================================ */void UdpClockInit(void);/*Static functions */static void ResetRegisters(void);void usb_c_handler(void);void irq1_c_handler(void); //* irq handler for system timer and dbguvoid spi_c_handler(void);/* ================================================================ *//* ====================== External functions =================== *//* ================================================================ *//* assembly function */extern void Remap(void);extern void Init_BSS(void);extern void Enable_IRQ(void);/* assembly handlers */extern void usb_asm_handler(void);extern void irq1_asm_handler(void);extern void AT91F_spi_asm_handler(void);//*--------------------------------------------------------------------------------------//* Function Name : UdpClockInit//* Object : Set the PLLB for Master clock and USB clock//* Input Parameters ://* Output Parameters ://*--------------------------------------------------------------------------------------void UdpClockInit(void){/*****!!!! : The PLLB output is 96 MHZ before the divider by 2 ==> UDP clock == 96/2 MHz To set the master clock to 48 MHz, set CSS and PRES for the master clock in APMC_MCKR register CSS = 0x03 ==> clock from PLLB is selected for master clock PRES = 0x01 ==> the selected clock is divided by 2 Master clock value is 48 Mhz ******/ AT91PS_APMC pApmc = APMC_BASE; volatile int tmp = 0; volatile int freq = 0; //* Determine the main clock frequency while(!(pApmc->APMC_MCFR & APMC_FREQ_END) && (tmp++ < DELAY_MAIN_FREQ)); if (tmp >= DELAY_MAIN_FREQ) return; freq = (pApmc->APMC_MCFR & 0x0000FFFF)*2048; // main clock freq = Number of main clock cycles in 16 slow clock cycles 2048 = 32768/16 /* find the crystal frequency and the PLLB setup in the crystal_freq table */ tmp = 0; while( (PLLB_SETUP[tmp][0] != 0) && (freq - 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 ((freq - PLLB_SETUP[tmp-1][0]) < (PLLB_SETUP[tmp][0] - freq)) tmp --; /* if the crystal value doesn't match */ if (PLLB_SETUP[tmp][0] == 0) return;#ifdef THUNDER /* setup the PLLB register */ pApmc->APMC_PLLBR = (PLLB_SETUP[tmp][1] | APMC_CLK_RANGE_80_TO_160MHZ | 0x3E << 8 );#else //* BOOSTER_LIGHT pApmc->APMC_PLLBR = (PLLB_SETUP[tmp][1] | APMC_CLK_RANGE_70_TO_100MHZ | 0x3E << 8 );#endif /* wait for PLLB stabilization */ tmp = 0; while( (tmp++ < DELAY_PLLA) && !(pApmc->APMC_SR & APMC_LOCKB) ) ; /* Set the divider by 2 for the USB PLL */ pApmc->APMC_PLLBR |= APMC_USB_96M; // the divider by 2 must be set first to avoid a freq too important on the peripheral's clock //* First set the DIV by 2 prescaler and wait for MCK_RDY flag ==> pApmc->APMC_MCKR = APMC_DIVMCK_DIV2; /* wait until the main clock is established */ tmp = 0; while(!(pApmc->APMC_SR & APMC_MCK_RDY) && (tmp++ < DELAY_MAIN_FREQ)); //* Switch main clock on PLLB output (96 MHZ) ==> main clock = 48 Mhz pApmc->APMC_MCKR |= APMC_MCKS_PLLB; /* wait until the main clock is established */ tmp = 0; while(!(pApmc->APMC_SR & APMC_MCK_RDY) && (tmp++ < DELAY_MAIN_FREQ)); /* Enables the 48M USB clock */ pApmc->APMC_SCER = APMC_UDP; pApmc->APMC_PCER = (1 << UDP_ID); }//*--------------------------------------------------------------------------------------//* Function Name : ResetRegisters()//* Object : Set all the registers used to their reset value and disable interrupts//* Input Parameters ://* Output Parameters ://*--------------------------------------------------------------------------------------static void ResetRegisters(void){ volatile int i = 0; //* set the PIOs in input PIOA_BASE->PIO_ODR = 0xFFFFFFFF; /* Disables all the output pins */ PIOA_BASE->PIO_PER = 0xFFFFFFFF; /* Enables the PIO to control all the pins */ //* Close the system peripheral Interrupt at91_irq_close (AIC_BASE, SYS_ID) ; //* Close the USB Interrupt at91_irq_close (AIC_BASE, UDP_ID) ; /* close all peripheral clocks */ APMC_BASE->APMC_PCDR = 0xFFFFFFFC; //* Disable core interrupts and set supervisor mode __asm { MSR CPSR_c, #0xDF //* ARM_MODE_SYS(0x1F) | I_BIT(0x80) | F_BIT(0x40) } //* Clear all the interrupts AIC_BASE->AIC_ICCR = 0xffffffff; /* read the AIC_IVR and AIC_FVR */ i = AIC_BASE->AIC_IVR; i = AIC_BASE->AIC_FVR; /* write the end of interrupt control register */ AIC_BASE->AIC_EOICR = 0;}//*--------------------------------------------------------------------------------------//* Function Name : BranchAppli()//* Object : Perform the remap and jump to appli in RAM//* Input Parameters ://* Output Parameters ://*--------------------------------------------------------------------------------------void BranchAppli(){ //* Reset registers ResetRegisters(); Remap(); while(1);}//*--------------------------------------------------------------------------------------//* Function Name : AT91_XmodemComplete()//* Object : Perform the remap and jump to appli in RAM//* Input Parameters ://* Output Parameters ://*--------------------------------------------------------------------------------------void AT91_XmodemComplete(AT91S_PipeStatus status, void *pVoid){ // stop the Xmodem tempo svcXmodem.tempo.Stop(&(svcXmodem.tempo)); SizeUpload = (int)((svcXmodem.pData) - BASE_LOAD_ADDRESS); // upload complete dfuDesc.dfuStatus.bState = AT91C_DFU_dfuMANIFEST_WAIT_RESET;}/* ================================================================ *//* ====================== XMODEM dispatcher ====================== *//* ================================================================ *///* This is the first XMODEM packet received which says if this is the full//* RAM contents or the first Setup packet in the DFU protocol.//* If this is the RAM contents then the transfer is achieved immediately,//* else, DFUDispatch class request is invoked. Then each time a new packet//* is sent by the host if it does not belong to the previous DFU transaction,//* it is considered as a new DFU setup packet by the ISR.void XmodemProtocol(AT91S_PipeStatus status, void *pVoid){ AT91PS_SBuffer pSBuffer = (AT91PS_SBuffer) xmodemPipe.pBuffer->pChild; AT91PS_UsbSetup pSetup = (AT91PS_UsbSetup) pVoid; AT91PS_USART2 pUsart = svcXmodem.pUsart; if (pSBuffer->szRdBuffer != 8) { // Force to exit the buffer has been sent in the first packet // Start a tempo to wait the Xmodem protocol complete svcXmodem.tempo.Start(&(svcXmodem.tempo), 10, 0, AT91_XmodemComplete, pUsart); } else { // We have received a setup packet through USART XMODEM... dfuDesc.pPipe = &xmodemPipe; dfuDesc.DispatchClassRequest(pSetup, &dfuDesc); }}void XmodemHandleRequest(AT91S_PipeStatus status, void *pVoid){ AT91PS_UsbSetup pSetup = (AT91PS_UsbSetup) pVoid; dfuDesc.DispatchClassRequest(pSetup, &dfuDesc);}//*--------------------------------------------------------------------------------------//* Function Name : GetTickCount()//* Object : Return the number of systimer tick //* Input Parameters ://* Output Parameters ://*--------------------------------------------------------------------------------------unsigned int GetTickCount(void){ return StTick;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -