www.pudn.com > uCOS_II_uart.rar > bsp.c
//=============================================================================================== //=============================================================================================== #define ext extern #include "data.h" #include "bsp.h" #include#include /* ********************************************************************************************************* * DATA TYPES ********************************************************************************************************* */ typedef void (*BSP_PFNCT)(void); /* ********************************************************************************************************* * PROTOTYPES ********************************************************************************************************* */ static void BSP_DummyISR_Handler(void); static void BSP_IntCtrlInit(void); extern void Tmr_TickInit(void); static void Tmr_TickISR_Handler(void); extern void LED_On (INT8U); extern void LED_Off (INT8U); //*---------------------------------------------------------------------------- //* \fn AT91F_US_Get //* \brief Get a Char to USART //*---------------------------------------------------------------------------- int AT91F_DBGU_Get( char *val) { if ((AT91F_US_RxReady((AT91PS_USART)AT91C_BASE_DBGU)) == 0) return (FALSE); else { *val= AT91F_US_GetChar((AT91PS_USART)AT91C_BASE_DBGU); return (TRUE); } } //*--------------------------1-------------------------------------------------- //* \fn AT91F_DBGU_Printk //* \brief This function is used to send a string through the DBGU channel //*---------------------------------------------------------------------------- void AT91F_DBGU_Ready(void) { while (!(AT91C_BASE_DBGU->DBGU_CSR & AT91C_US_TXEMPTY)); } //*---------------------------------------------------------------------------- //* \fn AT91F_DBGU_Frame //* \brief This function is used to send a string through the DBGU channel //*---------------------------------------------------------------------------- void AT91F_DBGU_Frame( char *buffer) { unsigned char len; for (len =0; buffer[len] != '\0'; len++){} AT91F_US_SendFrame((AT91PS_USART)AT91C_BASE_DBGU, buffer,len,0,0); } //*---------------------------------------------------------------------------- //* Function Name : Send_reset //* Object : Acknoledeg AIC and send reset //*---------------------------------------------------------------------------- void Send_reset(void) { void(*pfct)(void) = (void (*)(void) ) 0x00000000; // Acknoledge the interrupt // Mark the End of Interrupt on the AIC AT91C_BASE_AIC->AIC_EOICR=0; AT91F_DBGU_Ready(); // Jump in reset pfct(); } //*---------------------------------------------------------------------------- //* Function Name : DBGU_irq_handler //* Object : C handler interrupt function called by the interrupts //* assembling routine //*---------------------------------------------------------------------------- void DBGU_irq_handler(void) { /* char value; AT91PS_DBGU USART_pt = AT91C_BASE_DBGU; unsigned int status; INT16U rec; // get Usart status register //int *val; //val = AT91F_DBGU_Get(USART_pt); status = USART_pt->DBGU_CSR; if ( status & AT91C_US_RXRDY){ rec = AT91F_US_GetChar(USART_pt); DBBuffer[dbcount] = rec; // Get byte and send AT91F_US_PutChar (USART_pt,DBBuffer); } AT91F_DBGU_Get(&value); switch (value) { case '0': // info AT91F_DBGU_Frame("\n\rSet Pull up\n\r"); // Set AT91F_PIO_ClearOutput(AT91C_BASE_PIOA,AT91C_PIO_PA16); break; case '1': // info AT91F_PIO_SetOutput(AT91C_BASE_PIOA,AT91C_PIO_PA16); AT91F_DBGU_Printk("\n\rClear Pull up\n\r"); // Reset Application Send_reset(); break; default: AT91F_DBGU_Printk("\n\r"); break; }// end switch */ AT91C_BASE_AIC->AIC_IVR = 0; // Debug variant of vector read (protect mode is used) AT91C_BASE_AIC->AIC_ICCR = AT91C_ID_SYS; // Clear timer #0 interrupt AT91C_BASE_AIC->AIC_EOICR = 0; // Signal end of interrupt } //======================================================== void AT91F_DBGU_Init(void) { //* Open PIO for DBGU AT91F_DBGU_CfgPIO(); AT91F_DBGU_CfgPMC(); //* Enable Transmitter & receivier ((AT91PS_USART)AT91C_BASE_DBGU)->US_CR = AT91C_US_RSTTX |AT91C_US_RSTRX; //* Configure DBGU AT91F_US_Configure ( (AT91PS_USART) AT91C_BASE_DBGU, // DBGU base address MCK, AT91C_US_ASYNC_MODE , // Mode Register to be programmed AT91C_USAR_BAUD , // Baudrate to be programmed 0); // Timeguard to be programmed //* Enable Transmitter & receivier ((AT91PS_USART)AT91C_BASE_DBGU)->US_CR = AT91C_US_RXEN | AT91C_US_TXEN; //* Enable USART IT error and AT91C_US_ENDRX // AT91F_US_EnableIt((AT91PS_USART) AT91C_BASE_DBGU,AT91C_US_RXRDY); //* open interrupt //AT91F_AIC_ConfigureIt ( AT91C_BASE_AIC, AT91C_ID_SYS, USART_SYS_LEVEL,AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE, DBGU_irq_handler); // AT91F_AIC_EnableIt (AT91C_BASE_AIC, AT91C_ID_SYS); //AT91F_PDC_DisableRx ((AT91PS_PDC) AT91C_BASE_PDC_DBGU); // \arg pointer to a PDC controller //AT91F_PDC_DisableTx ((AT91PS_PDC) AT91C_BASE_PDC_DBGU); //AT91F_DBGU_Printk(S0Buffer); } /* ********************************************************************************************************* * DUMMY IRQ HANDLER * * Description : This function is called to handle invalid IRQs * * Arguments : none ********************************************************************************************************* */ static void BSP_DummyISR_Handler (void) { AT91C_BASE_AIC->AIC_IVR = 0; /* Debug variant of vector read (protect mode is used) */ } /* ********************************************************************************************************* * BSP INITIALIZATION * * Description : This function should be called by your application code before you make use of any of the * functions found in this module. * * Arguments : none ********************************************************************************************************* */ void BSP_Init (void) { BSP_IntCtrlInit(); /* Initialize the Interrupt Controller */ Tmr_TickInit(); AT91F_DBGU_Init(); LED_Init(); } //------------------------------------------------ void AT91F_DBGU_Printk( char *buffer) { while(*buffer != '\0') { while (!AT91F_US_TxReady((AT91PS_USART)AT91C_BASE_DBGU)); AT91F_US_PutChar((AT91PS_USART)AT91C_BASE_DBGU, *buffer++); } } void uprintf(char *fmt,...) { va_list ap; char string[256]; va_start(ap,fmt); vsprintf(string,fmt,ap); AT91F_DBGU_Printk(string); va_end(ap); } //================================================================================================ static void BSP_IntCtrlInit (void) { INT16U i; AT91C_BASE_AIC->AIC_EOICR = 0x00000000; /* End-of-interrupt command */ for (i = 0; i < 32; i++) { /* Disable all ISRs */ AT91C_BASE_AIC->AIC_SVR[i] = (INT32U)BSP_DummyISR_Handler; AT91C_BASE_AIC->AIC_SMR[i] = 0; } } /* ********************************************************************************************************* * DISABLE ALL INTERRUPTS * * Description : This function is called to disable ALL interrupts. * * Arguments : none ********************************************************************************************************* */ void BSP_IntDisAll (void) { AT91C_BASE_AIC->AIC_IDCR = 0xFFFFFFFF; /* Disable all interrupts */ } /* ********************************************************************************************************* * BSP INITIALIZATION * * Description : This function should be called by your application code before you make use of any of the * functions found in this module. * * Arguments : none ********************************************************************************************************* */ void LED_Init (void) { // First, enable the clock of the PIO AT91F_PMC_EnablePeriphClock ( AT91C_BASE_PMC, 1 << AT91C_ID_PIOA ); // then, we configure the PIO Lines corresponding to LED1 to LED4 // to be outputs. No need to set these pins to be driven by the PIO because it is GPIO pins only. AT91F_PIO_CfgOutput( AT91D_BASE_PIO_LED, LED_MASK ); // Clear the LED's. On the EB55 we must apply a "1" to turn off LEDs AT91F_PIO_SetOutput( AT91D_BASE_PIO_LED, LED_MASK ); // Clear the LED's. On the EB55 we must apply a "1" to turn off LEDs AT91F_PIO_ClearOutput( AT91D_BASE_PIO_LED, LED_MASK ); // Turn off LEDs AT91F_PIO_SetOutput( AT91D_BASE_PIO_LED, LED_MASK ); } /* ********************************************************************************************************* * LED ON * * Description : This function is used to control any or all the LEDs on the board. * * Arguments : led is the number of the LED to control * 0 indicates that you want ALL the LEDs to be ON * 1 turns ON LED1 on the board * . * . * 4 turns ON LED4 on the board ********************************************************************************************************* */ void LED_On (INT8U led) { } void LED_TurnOff(unsigned int led) { AT91F_PIO_SetOutput( AT91C_BASE_PIOB, led) ; } /* ********************************************************************************************************* * LED OFF * * Description : This function is used to control any or all the LEDs on the board. * * Arguments : led is the number of the LED to turn OFF * 0 indicates that you want ALL the LEDs to be OFF * 1 turns OFF LED1 on the board * . * . * 4 turns OFF LED4 on the board ********************************************************************************************************* */ void LED_Off (INT8U led) { } void LED_TurnOn(unsigned int led) { AT91F_PIO_ClearOutput( AT91C_BASE_PIOB, led); } /* ********************************************************************************************************* * LED TOGGLE * * Description : This function is used to toggle any or all the LEDs on the board. * * Arguments : led is the number of the LED to toggle * 0 indicates that you want ALL the LEDs to be toggle * 1 toggles LED1 on the board * . * . * 4 toggles LED4 on the board ********************************************************************************************************* */ void LED_Toggle (INT8U led) { } /* ********************************************************************************************************* * IRQ ISR HANDLER * * Description : This function is called by OS_CPU_IRQ_ISR() to determine the source of the interrupt * and process it accordingly. * * Arguments : none ********************************************************************************************************* */ void OS_CPU_IRQ_ISR_Handler (void) { BSP_PFNCT pfnct; #if 1 pfnct = (BSP_PFNCT)AT91C_BASE_AIC->AIC_IVR; /* Read the interrupt vector from the VIC */ if (pfnct != (BSP_PFNCT)0) { /* Make sure we don't have a NULL pointer */ (*pfnct)(); /* Execute the ISR for the interrupting device */ } #else pfnct = (BSP_PFNCT)AT91C_BASE_AIC->AIC_IVR; /* Read the interrupt vector from the VIC */ while (pfnct != (BSP_PFNCT)0) { /* Make sure we don't have a NULL pointer */ (*pfnct)(); /* Execute the ISR for the interrupting device */ pfnct = (BSP_PFNCT)AT91C_BASE_AIC->AIC_IVR; /* Read the interrupt vector from the VIC */ } #endif } /* ********************************************************************************************************* * FIQ ISR HANDLER * * Description : This function is called by OS_CPU_FIQ_ISR() to determine the source of the interrupt * and process it accordingly. * * Arguments : none ********************************************************************************************************* */ void OS_CPU_FIQ_ISR_Handler (void) { BSP_PFNCT pfnct; #if 1 pfnct = (BSP_PFNCT)AT91C_BASE_AIC->AIC_FVR; /* Read the interrupt vector from the VIC */ if (pfnct != (BSP_PFNCT)0) { /* Make sure we don't have a NULL pointer */ (*pfnct)(); /* Execute the ISR for the interrupting device */ } #else pfnct = (BSP_PFNCT)AT91C_BASE_AIC->AIC_FVR; /* Read the interrupt vector from the VIC */ while (pfnct != (BSP_PFNCT)0) { /* Make sure we don't have a NULL pointer */ (*pfnct)(); /* Execute the ISR for the interrupting device */ pfnct = (BSP_PFNCT)AT91C_BASE_AIC->AIC_FVR; /* Read the interrupt vector from the VIC */ } #endif } /* ********************************************************************************************************* * TICKER INITIALIZATION * * Description : This function is called to initialize uC/OS-II's tick source which uses the PIT * (typically a timer generating interrupts every 1 to 100 mS). * * Arguments : none * * Note(s) : 1) PIT Interrupt frequency: * * MCLK 1 * Freq = ---- * ----------- * 16 (PIV + 1) * * * MCLK 1 * PIV = ( ---- * ------ ) - 1 * 16 Freq * * Where: * MCLK = 48 MHz (i.e 48,000,000) * Freq = Desired frequency (i.e. OS_TICKS_PER_SEC) ********************************************************************************************************* */ void Tmr_TickInit (void) { INT32U counts; /* Set the vector address for PIT */ AT91C_BASE_AIC->AIC_SVR[AT91C_ID_SYS] = (INT32U)Tmr_TickISR_Handler; AT91C_BASE_AIC->AIC_SMR[AT91C_ID_SYS] = AT91C_AIC_SRCTYPE_INT_POSITIVE_EDGE | AT91C_AIC_PRIOR_LOWEST; AT91C_BASE_AIC->AIC_ICCR = 1 << AT91C_ID_SYS; AT91C_BASE_AIC->AIC_IECR = 1 << AT91C_ID_SYS; counts = (48000000 / 16 / OS_TICKS_PER_SEC) - 1; AT91C_BASE_PITC->PITC_PIMR = AT91C_PITC_PITEN | AT91C_PITC_PITIEN | counts; } /* ********************************************************************************************************* * PIT IRQ HANDLER * * Description : This function handles the PIT interrupt that is used to generate TICKs for uC/OS-II. * * Arguments : none ********************************************************************************************************* */ static void Tmr_TickISR_Handler (void) { volatile static INT32U status; AT91C_BASE_AIC->AIC_IVR = 0; /* Debug variant of vector read (protect mode is used) */ AT91C_BASE_AIC->AIC_ICCR = AT91C_ID_SYS; /* Clear timer #0 interrupt */ AT91C_BASE_AIC->AIC_EOICR = 0; /* Signal end of interrupt */ //OSTimeTick(); if((AT91PS_PITC)AT91C_BASE_PITC->PITC_PISR) { status = AT91C_BASE_PITC->PITC_PIVR; OSTimeTick(); // Tell uC/OS-II about clock tick } else { if((int)((AT91PS_DBGU)AT91C_BASE_DBGU->DBGU_CSR) & (int)0x01) { if(pRxdt==&RXDT[19]) { pRxdt=RXDT; } *(++pRxdt)=(int)(AT91PS_DBGU)AT91C_BASE_DBGU->DBGU_RHR; OSSemPost (pE_Key); } } } //--------------------------------------------------------------------------------------------------------- void time_delay(int dly) { int i; for(; dly>0; dly--) for(i=0; i<500; i++); } //-------------------------------------------------------- void pri_info(void) { AT91F_DBGU_Printk("\n\r ================================================"); AT91F_DBGU_Printk("\n\r | 欢迎使用深圳英贝德公司的产品 |"); AT91F_DBGU_Printk("\n\r | SAM7X256 uCOS-II的演示测试 |"); AT91F_DBGU_Printk("\n\r | 更多的帮助请到 http://www.szembed.com |"); AT91F_DBGU_Printk("\n\r ================================================\n\r\n\r"); } //*---------------------------------------------------------------------------- //* 函数名: AT91F_DBGU_GetStatus_zzf //* 功能:获得USART(DBGU,US0,US1)通道状态寄存器的值,供中断程序用 //*---------------------------------------------------------------------------- unsigned int AT91F_USART_GetStatus_zzf(AT91PS_USART pUSART ) { return(pUSART->US_CSR); } //*---------------------------------------------------------------------------- //* 函数名: AT91F_DBGU_GetInterruptMaskStatus_zzf //* 功能:中断屏蔽寄存器的值,供中断程序使用 //*---------------------------------------------------------------------------- unsigned int AT91F_USRT_GetInterruptMaskStatus_zzf(AT91PS_USART pUSART) { return(pUSART->US_IMR); } void US0_irq_handler(void) { unsigned int status; //变量定义 //禁止系统中断(DBGU属于系统中断) AT91F_AIC_DisableIt(AT91C_BASE_AIC, AT91C_ID_US0); //查看是那类中断,读取状态积存器/中断屏蔽积存器,以清除中断标志, status=(AT91F_USART_GetStatus_zzf((AT91PS_USART)AT91C_BASE_US0)&AT91F_USRT_GetInterruptMaskStatus_zzf((AT91PS_USART)AT91C_BASE_US0)); if ( status & AT91C_US_RXRDY) { while (!AT91F_US_TxReady((AT91PS_USART)AT91C_BASE_US0)); AT91F_US_PutChar (AT91C_BASE_US0, AT91F_US_GetChar(AT91C_BASE_US0)); } //* Clear the interrupt. AT91F_AIC_ClearIt(AT91C_BASE_AIC, AT91C_ID_US0); //* End of interrupt AT91C_BASE_AIC->AIC_EOICR = 0; AT91F_AIC_EnableIt(AT91C_BASE_AIC, AT91C_ID_US0); } void prvSetupUARTInterrupt() { //* 允许接受缓冲区满中断 AT91F_US_EnableIt((AT91PS_USART)AT91C_BASE_US0,AT91C_US_RXRDY); //* 允许接受缓冲区满中断 AT91F_AIC_ConfigureIt ( AT91C_BASE_AIC, AT91C_ID_US0, US0_INT_LEVEL, AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, ( void (*)( void ) ) US0_irq_handler ); //* 允许中断 AT91F_AIC_EnableIt (AT91C_BASE_AIC, AT91C_ID_US0); } void US0_init() { //* 配置I/O AT91F_US0_CfgPIO (); //调用库函数 //开US0时钟 AT91F_US0_CfgPMC(); //* 配置 US0 AT91F_US_Configure ( // 调用库函数 (AT91PS_USART) AT91C_BASE_US0, // US0 基地址 AT91B_MCK, AT91C_US_ASYNC_MODE , // 模式积存器 AT91C_US0_BAUD , // 波特率 0); // 触发时间 //*允许串口接受发送 AT91F_US_EnableTxRx((AT91PS_USART)AT91C_BASE_US0); //*中断设置 prvSetupUARTInterrupt(); }