第1步 低級(jí)初始化由函數(shù) void AT91F_LowLevelInit() 執(zhí)行,定義于init.c. 低級(jí)初始化主要包括初始化高級(jí)中斷控制器,為DEBUG打開并設(shè)置PIO,使能字符傳輸寄存器等。 第1.1步 初始化高級(jí)中斷控制器由lib_AT91RM9200.h中的函數(shù) __inline void AT91F_AIC_Open( AT91PS_AIC pAic, // \arg pointer to the AIC registers void (*IrqHandler) (), // \arg Default IRQ vector exception void (*FiqHandler) (), // \arg Default FIQ vector exception void (*DefaultHandler) (), // \arg Default Handler set in ISR void (*SpuriousHandler) (), // \arg Default Spurious Handler unsigned int protectMode) // \arg Debug Control Register 完成。
首先屏蔽原先攝制的中斷, __inline void AT91F_AIC_DisableIt ( AT91PS_AIC pAic, // \arg pointer to the AIC registers unsigned int irq_id ) // \arg interrupt number to initialize 并重新設(shè)置中斷,將其優(yōu)先級(jí)全部置最低, __inline unsigned int AT91F_AIC_ConfigureIt ( AT91PS_AIC pAic, // \arg pointer to the AIC registers unsigned int irq_id, // \arg interrupt number to initialize unsigned int priority, // \arg priority to give to the interrupt unsigned int src_type, // \arg activation and sense of activation void (*newHandler) (void) ) // \arg address of the interrupt handler 中斷處理函數(shù)設(shè)為未定義 void AT91F_UndefHandler() { AT91F_DBGU_Printk("-F- Undef detected\n\r"); while (1); } 然后設(shè)置外部中斷異常向量和快速中斷異常向量 AT91F_AIC_SetExceptionVector((unsigned int *) 0x18, IrqHandler); AT91F_AIC_SetExceptionVector((unsigned int *) 0x1C, FiqHandler); 最后設(shè)置偽向量寄存器和調(diào)試控制寄存器 pAic->AIC_SPU = (unsigned int) SpuriousHandler; pAic->AIC_DCR = protectMode; 此處SpuriousHandler為函數(shù) void AT91F_SpuriousHandler() { AT91F_DBGU_Printk("-F- Spurious Interrupt detected\n\r"); while (1); } 的地址 此處protectMode值為0,意為The Protection Mode is disabled,and the nIRQ and nFIQ lines are normally controlled by the AIC.(見
AT91RM9200手冊(cè)252頁(yè))
第1.2步 然后Perform 8 End Of Interrupt Command to make sure AIC will not Lock out nIRQ
第1.3步 接著設(shè)置中斷向量表 AT91F_AIC_SetExceptionVector((unsigned int *)0x0C, AT91F_FetchAbort); AT91F_AIC_SetExceptionVector((unsigned int *)0x10, AT91F_DataAbort); AT91F_AIC_SetExceptionVector((unsigned int *)0x4, AT91F_Undef); 其第一個(gè)參數(shù)的含義見AT91RM9200手冊(cè)244頁(yè) 其第一個(gè)參數(shù)的含義見init.c
第1.4步 最后為DBGU打開并配置PIO 由函數(shù)__inline void AT91F_DBGU_CfgPIO (void) 和函數(shù)__inline void AT91F_US_Configure ( AT91PS_USART pUSART, // \arg pointer to a USART controller unsigned int mainClock, // \arg peripheral clock unsigned int mode , // \arg mode Register to be programmed unsigned int baudRate , // \arg baudrate to be programmed unsigned int timeguard ) // \arg timeguard to be programmed 完成(兩個(gè)函數(shù)在lib_AT91RM9200.h中定義) 第1.4.1步 調(diào)用函數(shù) __inline void AT91F_DBGU_CfgPIO (void) { // Configure PIO controllers to periph mode AT91F_PIO_CfgPeriph( AT91C_BASE_PIOA, // PIO controller base address ((unsigned int) AT91C_PA31_DTXD ) | ((unsigned int) AT91C_PA30_DRXD ), // Peripheral A 0); // Peripheral B } AT91C_PA31_DTXD 和 AT91C_PA30_DRXD均定義在AT91RM9200_inc.h,分別表示DBGU模式下的發(fā)送、接收數(shù)據(jù)的字段 該函數(shù)繼續(xù)調(diào)用函數(shù) __inline void AT91F_PIO_CfgPeriph( AT91PS_PIO pPio, // \arg pointer to a PIO controller unsigned int periphAEnable, // \arg PERIPH A to enable unsigned int periphBEnable) // \arg PERIPH B to enable { pPio->PIO_ASR = periphAEnable; pPio->PIO_BSR = periphBEnable; pPio->PIO_PDR = (periphAEnable | periphBEnable); // Set in Periph mode }
第1.4.2步 各參數(shù)如下AT91PS_USART) AT91C_BASE_DBGU, // DBGU base address 60000000, // 48 MHz AT91C_US_ASYNC_MODE, // mode Register to be programmed 115200 , // baudrate to be programmed 0 // timeguard to be programmed
第1.5步 使用函數(shù)void AT91F_DBGU_Printk(char *buffer) // \arg pointer to a string ending by \0 { while(*buffer != '\0') { while (!AT91F_US_TxReady((AT91PS_USART)AT91C_BASE_DBGU)); AT91F_US_PutChar((AT91PS_USART)AT91C_BASE_DBGU, *buffer++); } } 輸出"-I- AT91F_LowLevelInit() done\n\r"表示低級(jí)初始化成功 函數(shù) __inline void AT91F_US_PutChar (AT91PS_USART pUSART,int character ) { pUSART->US_THR = (character & 0x1FF); } 將要輸出的字符寫入U(xiǎn)SART的Transmitter Holding Register,然后由超級(jí)終端接受
以上步驟完成后,回到cstartup_ads.s,繼續(xù)維護(hù)一些堆棧,然后進(jìn)行設(shè)備初始化。
USB Device Port的設(shè)備初始化
第2步 設(shè)備初始化由main.c的函數(shù)void AT91F_InitDrivers()完成, 首先配置電源管理控制器,然后為每個(gè)端點(diǎn)開啟DMA服務(wù),接著配置高級(jí)中斷控制器,使能UDP相應(yīng)的中斷,使能UDP的上拉電阻。 第2.1步 配置電源管理控制器由lib_AT91RM9200.h的函數(shù)__inline void AT91F_UDP_CfgPMC (void)完成 __inline void AT91F_UDP_CfgPMC (void) { AT91F_PMC_EnablePeriphClock( AT91C_BASE_PMC, // PIO controller base address ((unsigned int) 1 << AT91C_ID_UDP)); } 其中AT91C_ID_UDP的定義如下 #define AT91C_ID_UDP ((unsigned int) 11) // USB Device Port 函數(shù)AT91F_UDP_CfgPMC 調(diào)用了下面的函數(shù) __inline void AT91F_PMC_EnablePeriphClock ( AT91PS_PMC pPMC, // \arg pointer to PMC controller unsigned int periphIds) // \arg IDs of peripherals to enable { pPMC->PMC_PCER = periphIds; //Peripheral Clock Enable Register } 其中PMC_PCER是外設(shè)時(shí)鐘使能寄存器 接著通過System Clock Enable Register置位為UDP開啟系統(tǒng)時(shí)鐘,代碼如下: AT91C_BASE_PMC->PMC_SCER |= AT91C_PMC_UDP; // Enable 48 MHz
第2.2步 然后為每個(gè)端點(diǎn)開啟DMA服務(wù) 第2.2.1步 首先為USB的控制端點(diǎn)開啟DMA服務(wù),由AT91_SVC_USBCTL.c中的函數(shù) AT91PS_SVC_USBCTL AT91F_SVC_USBCTL_Open( AT91PS_SVC_USBCTL pSvcUdp, // \arg Pointer to an USBCTL service previously allocated AT91PS_UDP pUdp) // \arg Pointer to UDP registers 完成。其中pUdp的值是AT91C_BASE_UDP,為UDP相關(guān)的寄存器的基地址;pSvcUdp是定義在AT91_SVC_USBCTL.h里的結(jié)構(gòu)體。 函數(shù)AT91F_SVC_USBCTL_Open注冊(cè)了相應(yīng)的服務(wù),Handler,Read,Write;初始化了其他相關(guān)的數(shù)據(jù)。 然后為控制服務(wù)指定了請(qǐng)求分派程序,usb_enumerate.c中的AT91F_USB_DispatchRequest函數(shù)
第2.2.2步 為USB的IN端點(diǎn)開啟DMA服務(wù),由AT91_SVC_USBIN.c中的函數(shù) AT91PS_SVC_USBIN AT91F_SVC_USBIN_Open( AT91PS_SVC_USBIN pSvcUdp, // \arg Pointer to an USBIN service previously allocated AT91PS_UDP pUdp, // \arg Pointer to UDP registers unsigned char epNb, // \arg Endpoint Number unsigned char epSize, // \arg Endpoint Size unsigned char nbBanks) // \arg UDP DPR banks 完成。其中pUdp的值是AT91C_BASE_UDP,為UDP相關(guān)的寄存器的基地址;pSvcUdp是定義在AT91_SVC_USBIN.h里的結(jié)構(gòu)體。 函數(shù)AT91F_SVC_USBCTL_Open注冊(cè)了相應(yīng)的服務(wù),Handler,Write;初始化了其他相關(guān)的數(shù)據(jù),包括緩沖、數(shù)據(jù)塊等。
第2.2.3步 為USB的OUT端點(diǎn)開啟DMA服務(wù),由AT91_SVC_USBCTL.c中的函數(shù) AT91PS_SVC_USBIN AT91F_SVC_USBIN_Open( AT91PS_SVC_USBIN pSvcUdp, // \arg Pointer to an USBIN service previously allocated AT91PS_UDP pUdp, // \arg Pointer to UDP registers unsigned char epNb, // \arg Endpoint Number unsigned char epSize, // \arg Endpoint Size unsigned char nbBanks) // \arg UDP DPR banks 完成。其中pUdp的值是AT91C_BASE_UDP,為UDP相關(guān)的寄存器的基地址;pSvcUdp是定義在AT91_SVC_USBCTL.h里的結(jié)構(gòu)體。 函數(shù)AT91F_SVC_USBCTL_Open注冊(cè)了相應(yīng)的服務(wù),Handler,Read;初始化了其他相關(guān)的數(shù)據(jù),包括緩沖、數(shù)據(jù)塊等。
第2.2.4步 為USB的另一個(gè)IN端點(diǎn)開啟DMA服務(wù),由AT91_SVC_USBCTL.c中的函數(shù) AT91PS_SVC_USBCTL AT91F_SVC_USBCTL_Open( AT91PS_SVC_USBCTL pSvcUdp, // \arg Pointer to an USBCTL service previously allocated AT91PS_UDP pUdp) // \arg Pointer to UDP registers 完成。其中pUdp的值是AT91C_BASE_UDP,為UDP相關(guān)的寄存器的基地址;pSvcUdp是定義在AT91_SVC_USBCTL.h里的結(jié)構(gòu)體。 函數(shù)AT91F_SVC_USBCTL_Open注冊(cè)了相應(yīng)的服務(wù),Handler,Write;初始化了其他相關(guān)的數(shù)據(jù),包括緩沖、數(shù)據(jù)塊等。
第2.3步 配置高級(jí)中斷控制器以處理UDP相應(yīng)的中斷,由lib_AT91RM9200.h中的函數(shù) __inline unsigned int AT91F_AIC_ConfigureIt ( AT91PS_AIC pAic, // \arg pointer to the AIC registers unsigned int irq_id, // \arg interrupt number to initialize unsigned int priority, // \arg priority to give to the interrupt unsigned int src_type, // \arg activation and sense of activation void (*newHandler) (void) ) // \arg address of the interrupt handler 完成。其中newHandler的值為AT91F_ASM_UDP_Handler,表示main.h中的函數(shù)extern void AT91F_UDP_Handler(void),該函數(shù)的定義在c_isr.c里。中斷信號(hào)由寄存器Interrupt Mask Register和Interrupt Status Register按位與得到。 然后將這些中斷使能。
第2.4步 使能UDP的上拉電阻,代碼如下: AT91F_PIO_CfgOutput(AT91C_BASE_PIOA, AT91C_PIO_PA10); AT91F_PIO_ClearOutput(AT91C_BASE_PIOA, AT91C_PIO_PA10); 這兩個(gè)函數(shù)都定義在lib_AT91RM9200.h
這樣,整個(gè)UDP設(shè)備就完成了初始化。
|