mirror of
https://github.com/elua/elua.git
synced 2025-01-08 20:56:17 +08:00
Starting to fix AVR32 UARt code:
- Check for error return values and return errors when they happen - Return error value when invalid parameters are passed - uart.setup(): return the actual baud rate set.
This commit is contained in:
parent
c0119c0908
commit
dfcde5bb47
@ -348,27 +348,42 @@ u32 platform_uart_setup( unsigned id, u32 baud, int databits, int parity, int st
|
||||
opts.baudrate = baud;
|
||||
|
||||
// Set stopbits
|
||||
if( stopbits == PLATFORM_UART_STOPBITS_1 )
|
||||
switch (stopbits) {
|
||||
case PLATFORM_UART_STOPBITS_1:
|
||||
opts.stopbits = USART_1_STOPBIT;
|
||||
else if( stopbits == PLATFORM_UART_STOPBITS_1_5 )
|
||||
break;
|
||||
case PLATFORM_UART_STOPBITS_1_5:
|
||||
opts.stopbits = USART_1_5_STOPBITS;
|
||||
else
|
||||
break;
|
||||
case PLATFORM_UART_STOPBITS_2:
|
||||
opts.stopbits = USART_2_STOPBITS;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Set parity
|
||||
if( parity == PLATFORM_UART_PARITY_EVEN )
|
||||
switch (parity) {
|
||||
case PLATFORM_UART_PARITY_EVEN:
|
||||
opts.paritytype = USART_EVEN_PARITY;
|
||||
else if( parity == PLATFORM_UART_PARITY_ODD )
|
||||
break;
|
||||
case PLATFORM_UART_PARITY_ODD:
|
||||
opts.paritytype = USART_ODD_PARITY;
|
||||
else
|
||||
break;
|
||||
case PLATFORM_UART_PARITY_NONE:
|
||||
opts.paritytype = USART_NO_PARITY;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Set actual interface
|
||||
gpio_enable_module(uart_pins + id * 2, 2 );
|
||||
usart_init_rs232( pusart, &opts, REQ_PBA_FREQ );
|
||||
if ( usart_init_rs232( pusart, &opts, REQ_PBA_FREQ ) != USART_SUCCESS )
|
||||
return 0;
|
||||
|
||||
// [TODO] Return actual baud here
|
||||
return baud;
|
||||
// Return actual baud here
|
||||
return usart_get_async_baudrate(pusart, REQ_PBA_FREQ);
|
||||
}
|
||||
|
||||
void platform_s_uart_send( unsigned id, u8 data )
|
||||
|
@ -111,6 +111,60 @@ static int usart_set_async_baudrate(volatile avr32_usart_t *usart, unsigned int
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Return the actual baud rate set into the USART
|
||||
*
|
||||
* Baud rate calculation:
|
||||
* \f$ Baudrate = \frac{SelectedClock}{Over \times (CD + \frac{FP}{8})} \f$, \e Over being 16 or 8.
|
||||
*
|
||||
* \param usart Base address of the USART instance.
|
||||
* \param pba_hz USART module input clock frequency (PBA clock, Hz).
|
||||
*
|
||||
* \retval baudrate The closest integer to the actual baud rate
|
||||
* \retval 0 UART clock is off or there was some error on our part
|
||||
*/
|
||||
unsigned int usart_get_async_baudrate(volatile avr32_usart_t *usart, unsigned long pba_hz)
|
||||
{
|
||||
unsigned int clock; // Master clock frequency
|
||||
unsigned int over; // divisor of 8 or 16
|
||||
unsigned int cd; // clock divider (0-65535)
|
||||
unsigned int fp; // fractional part of clock divider (0-7)
|
||||
unsigned int divisor; // What the master clock is divided by to get
|
||||
// the final baud rate
|
||||
|
||||
// Find
|
||||
switch ((usart->mr & AVR32_USART_MR_USCLKS_MASK) >> AVR32_USART_MR_USCLKS_OFFSET)
|
||||
{
|
||||
case AVR32_USART_MR_USCLKS_MCK:
|
||||
clock = pba_hz;
|
||||
break;
|
||||
|
||||
case AVR32_USART_MR_USCLKS_MCK_DIV:
|
||||
// I can't figure out where the divider is defined. The datasheet
|
||||
// section 26.7.1 says it is "product dependent, but generally set to 8".
|
||||
// Fortunately, the code above always selects MCK.
|
||||
case AVR32_USART_MR_USCLKS_SCK:
|
||||
// If we have an external clock, we don't know its frequency here.
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
over = usart->mr & AVR32_USART_MR_OVER_MASK;
|
||||
cd = (usart->brgr & AVR32_USART_BRGR_CD_MASK) >> AVR32_USART_BRGR_CD_OFFSET;
|
||||
fp = (usart->brgr & AVR32_USART_BRGR_FP_MASK) >> AVR32_USART_BRGR_FP_OFFSET;
|
||||
|
||||
// if CD==0, no baud rate is generated.
|
||||
// if CD==1, the clock divider and fractional part are bypassed.
|
||||
if (cd == 0) return 0;
|
||||
if (cd == 1) fp = 0;
|
||||
|
||||
// Rewriting "divisor = 8 * (2 - over) * (cd + fp/8)" for integer math:
|
||||
divisor = (2 - over) * (8 * cd + fp);
|
||||
|
||||
// Round to the integer that is closest to the actual result
|
||||
return (clock + divisor/2) / divisor;
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Calculates a clock divider (\e CD) for the USART synchronous master
|
||||
* modes to generate a baud rate as close as possible to the baud rate
|
||||
* set point.
|
||||
|
@ -230,6 +230,16 @@ extern void usart_reset(volatile avr32_usart_t *usart);
|
||||
*/
|
||||
extern int usart_init_rs232(volatile avr32_usart_t *usart, const usart_options_t *opt, long pba_hz);
|
||||
|
||||
/*! \brief Returns the actual baud rate set into the USART in async mode
|
||||
*
|
||||
* \param usart Base address of the USART instance.
|
||||
* \param pba_hz USART module input clock frequency (PBA clock, Hz).
|
||||
*
|
||||
* \retval baudrate The nearest integer to the actual baud rate
|
||||
* \retval 0 No baudrate is being generated or some error
|
||||
*/
|
||||
extern unsigned int usart_get_async_baudrate(volatile avr32_usart_t *usart, unsigned long pba_hz);
|
||||
|
||||
/*! \brief Sets up the USART to use the standard RS232 protocol in TX-only mode.
|
||||
*
|
||||
* Compared to \ref usart_init_rs232, this function allows very high baud rates
|
||||
|
Loading…
x
Reference in New Issue
Block a user