xComPortHandle xSerialPortInitMinimal( unsigned portLONG ulWantedBaud, unsigned portBASE_TYPE uxQueueLength ) { unsigned portLONG ulDivisor, ulWantedClock; xComPortHandle xReturn = serHANDLE; /* The queues are used in the serial ISR routine, so are created from serialISR.c (which is always compiled to ARM mode). */ vSerialISRCreateQueues( uxQueueLength, &xRxedChars, &xCharsForTx, &plTHREEmpty ); if( ( xRxedChars != serINVALID_QUEUE ) && ( xCharsForTx != serINVALID_QUEUE ) && ( ulWantedBaud != ( unsigned portLONG ) 0 ) ) { portENTER_CRITICAL(); { /* The reference to the ISR function is required to load into the interrupt controller. The prototype is slightly different depending on whether in ARM or THUMB mode. */ #ifdef KEIL_THUMB_INTERWORK extern void ( vUART_ISR )( void ) __arm __task; #else extern void ( vUART_ISR )( void ) __task; #endif /* Setup the baud rate: Calculate the divisor value. */ ulWantedClock = ulWantedBaud * serWANTED_CLOCK_SCALING; ulDivisor = configCPU_CLOCK_HZ / ulWantedClock; /* Set the DLAB bit so we can access the divisor. */ U0LCR |= serDLAB; /* Setup the divisor. */ U0DLL = ( unsigned portCHAR ) ( ulDivisor & ( unsigned portLONG ) 0xff ); ulDivisor >>= 8; U0DLM = ( unsigned portCHAR ) ( ulDivisor & ( unsigned portLONG ) 0xff ); /* Turn on the FIFO's and clear the buffers. */ U0FCR = ( serFIFO_ON | serCLEAR_FIFO ); /* Setup transmission format. */ U0LCR = serNO_PARITY | ser1_STOP_BIT | ser8_BIT_CHARS; /* Setup the VIC for the UART. */ VICIntSelect &= ~( serU0VIC_CHANNEL_BIT ); VICIntEnable |= serU0VIC_CHANNEL_BIT; VICVectAddr1 = ( unsigned portLONG ) vUART_ISR; VICVectCntl1 = serU0VIC_CHANNEL | serU0VIC_ENABLE; /* Enable UART0 interrupts. */ U0IER |= serENABLE_INTERRUPTS; } portEXIT_CRITICAL(); }
xComPortHandle xSerialPortInitMinimal( unsigned long ulWantedBaud, unsigned portBASE_TYPE uxQueueLength ) { unsigned long ulDivisor, ulWantedClock; xComPortHandle xReturn = serHANDLE; extern void ( vUART_ISR_Wrapper )( void ); /* The queues are used in the serial ISR routine, so are created from serialISR.c (which is always compiled to ARM mode. */ vSerialISRCreateQueues( uxQueueLength, &xRxedChars, &xCharsForTx, &plTHREEmpty ); if( ( xRxedChars != serINVALID_QUEUE ) && ( xCharsForTx != serINVALID_QUEUE ) && ( ulWantedBaud != ( unsigned long ) 0 ) ) { portENTER_CRITICAL(); { /* Setup the baud rate: Calculate the divisor value. */ ulWantedClock = ulWantedBaud * serWANTED_CLOCK_SCALING; ulDivisor = configCPU_CLOCK_HZ / ulWantedClock; /* Set the DLAB bit so we can access the divisor. */ UART0_LCR |= serDLAB; /* Setup the divisor. */ UART0_DLL = ( unsigned char ) ( ulDivisor & ( unsigned long ) 0xff ); ulDivisor >>= 8; UART0_DLM = ( unsigned char ) ( ulDivisor & ( unsigned long ) 0xff ); /* Turn on the FIFO's and clear the buffers. */ UART0_FCR = ( serFIFO_ON | serCLEAR_FIFO ); /* Setup transmission format. */ UART0_LCR = serNO_PARITY | ser1_STOP_BIT | ser8_BIT_CHARS; /* Setup the VIC for the UART. */ VICIntSelect &= ~( serUART0_VIC_CHANNEL_BIT ); VICIntEnable |= serUART0_VIC_CHANNEL_BIT; VICVectAddr1 = ( long ) vUART_ISR_Wrapper; VICVectCntl1 = serUART0_VIC_CHANNEL | serUART0_VIC_ENABLE; /* Enable UART0 interrupts. */ UART0_IER |= serENABLE_INTERRUPTS; } portEXIT_CRITICAL(); }
xComPortHandle xSerialPortInitMinimal( unsigned long ulWantedBaud, unsigned portBASE_TYPE uxQueueLength ) { unsigned long ulSpeed; unsigned long ulCD; xComPortHandle xReturn = serHANDLE; extern void ( vUART_ISR_Wrapper )( void ); /* The queues are used in the serial ISR routine, so are created from serialISR.c (which is always compiled to ARM mode. */ vSerialISRCreateQueues( uxQueueLength, &xRxedChars, &xCharsForTx ); if( ( xRxedChars != serINVALID_QUEUE ) && ( xCharsForTx != serINVALID_QUEUE ) && ( ulWantedBaud != ( unsigned long ) 0 ) ) { portENTER_CRITICAL(); { /* Enable clock to USART0... */ AT91C_BASE_PS->PS_PCER = AT91C_PS_US0; /* Disable all USART0 interrupt sources to begin... */ AT91C_BASE_US0->US_IDR = 0xFFFFFFFF; /* Reset various status bits (just in case)... */ AT91C_BASE_US0->US_CR = US_RSTSTA; AT91C_BASE_PIO->PIO_PDR = TXD0 | RXD0; /* Enable RXD and TXD pins */ AT91C_BASE_US0->US_CR = US_RSTRX | US_RSTTX | US_RXDIS | US_TXDIS; /* Clear Transmit and Receive Counters */ AT91C_BASE_US0->US_RCR = 0; AT91C_BASE_US0->US_TCR = 0; /* Input clock to baud rate generator is MCK */ ulSpeed = configCPU_CLOCK_HZ * 10; ulSpeed = ulSpeed / 16; ulSpeed = ulSpeed / ulWantedBaud; /* compute the error */ ulCD = ulSpeed / 10; if ((ulSpeed - (ulCD * 10)) >= 5) ulCD++; /* Define the baud rate divisor register */ AT91C_BASE_US0->US_BRGR = ulCD; /* Define the USART mode */ AT91C_BASE_US0->US_MR = US_CLKS_MCK | US_CHRL_8 | US_PAR_NO | US_NBSTOP_1 | US_CHMODE_NORMAL; /* Write the Timeguard Register */ AT91C_BASE_US0->US_TTGR = 0; /* Setup the interrupt for USART0. Store interrupt handler function address in USART0 vector register... */ AT91C_BASE_AIC->AIC_SVR[ portUSART0_AIC_CHANNEL ] = (unsigned long)vUART_ISR_Wrapper; /* USART0 interrupt level-sensitive, priority 1... */ AT91C_BASE_AIC->AIC_SMR[ portUSART0_AIC_CHANNEL ] = AIC_SRCTYPE_INT_LEVEL_SENSITIVE | 1; /* Clear some pending USART0 interrupts (just in case)... */ AT91C_BASE_US0->US_CR = US_RSTSTA; /* Enable USART0 interrupt sources (but not Tx for now)... */ AT91C_BASE_US0->US_IER = US_RXRDY; /* Enable USART0 interrupts in the AIC... */ AT91C_BASE_AIC->AIC_IECR = ( 1 << portUSART0_AIC_CHANNEL ); /* Enable receiver and transmitter... */ AT91C_BASE_US0->US_CR = US_RXEN | US_TXEN; } portEXIT_CRITICAL(); } else { xReturn = ( xComPortHandle ) 0; } return xReturn; }