1 /*******************************************************************************
\r
2 * (c) Copyright 2007-2017 Microsemi SoC Products Group. All rights reserved.
\r
4 * CoreUARTapb driver implementation. See file "core_uart_apb.h" for a
\r
5 * description of the functions implemented in this file.
\r
7 * SVN $Revision: 9082 $
\r
8 * SVN $Date: 2017-04-28 11:51:36 +0530 (Fri, 28 Apr 2017) $
\r
11 #include "coreuartapb_regs.h"
\r
12 #include "core_uart_apb.h"
\r
13 #include "hal_assert.h"
\r
19 #define NULL_INSTANCE ( ( UART_instance_t* ) 0 )
\r
20 #define NULL_BUFFER ( ( uint8_t* ) 0 )
\r
22 #define MAX_LINE_CONFIG ( ( uint8_t )( DATA_8_BITS | ODD_PARITY ) )
\r
23 #define MAX_BAUD_VALUE ( ( uint16_t )( 0x1FFF ) )
\r
24 #define STATUS_ERROR_MASK ( ( uint8_t )( STATUS_PARITYERR_MASK | \
\r
25 STATUS_OVERFLOW_MASK | \
\r
26 STATUS_FRAMERR_MASK ) )
\r
27 #define BAUDVALUE_LSB ( (uint16_t) (0x00FF) )
\r
28 #define BAUDVALUE_MSB ( (uint16_t) (0xFF00) )
\r
29 #define BAUDVALUE_SHIFT ( (uint8_t) (5) )
\r
31 #define STATUS_ERROR_OFFSET STATUS_PARITYERR_SHIFT
\r
33 /***************************************************************************//**
\r
35 * See "core_uart_apb.h" for details of how to use this function.
\r
40 UART_instance_t * this_uart,
\r
42 uint16_t baud_value,
\r
48 HAL_ASSERT( this_uart != NULL_INSTANCE )
\r
49 HAL_ASSERT( line_config <= MAX_LINE_CONFIG )
\r
50 HAL_ASSERT( baud_value <= MAX_BAUD_VALUE )
\r
52 if( ( this_uart != NULL_INSTANCE ) &&
\r
53 ( line_config <= MAX_LINE_CONFIG ) &&
\r
54 ( baud_value <= MAX_BAUD_VALUE ) )
\r
57 * Store lower 8-bits of baud value in CTRL1.
\r
59 HAL_set_8bit_reg( base_addr, CTRL1, (uint_fast8_t)(baud_value &
\r
63 * Extract higher 5-bits of baud value and store in higher 5-bits
\r
64 * of CTRL2, along with line configuration in lower 3 three bits.
\r
66 HAL_set_8bit_reg( base_addr, CTRL2, (uint_fast8_t)line_config |
\r
67 (uint_fast8_t)((baud_value &
\r
68 BAUDVALUE_MSB) >> BAUDVALUE_SHIFT ) );
\r
70 this_uart->base_address = base_addr;
\r
76 baud_val = HAL_get_8bit_reg( this_uart->base_address, CTRL1 );
\r
77 config = HAL_get_8bit_reg( this_uart->base_address, CTRL2 );
\r
79 * To resolve operator precedence between & and <<
\r
81 temp = ( config & (uint8_t)(CTRL2_BAUDVALUE_MASK ) );
\r
82 baud_val |= (uint16_t)( (uint16_t)(temp) << BAUDVALUE_SHIFT );
\r
83 config &= (uint8_t)(~CTRL2_BAUDVALUE_MASK);
\r
84 HAL_ASSERT( baud_val == baud_value );
\r
85 HAL_ASSERT( config == line_config );
\r
90 * Flush the receive FIFO of data that may have been received before the
\r
91 * driver was initialized.
\r
93 rx_full = HAL_get_8bit_reg( this_uart->base_address, STATUS ) &
\r
97 HAL_get_8bit_reg( this_uart->base_address, RXDATA );
\r
98 rx_full = HAL_get_8bit_reg( this_uart->base_address, STATUS ) &
\r
103 * Clear status of the UART instance.
\r
105 this_uart->status = (uint8_t)0;
\r
109 /***************************************************************************//**
\r
111 * See "core_uart_apb.h" for details of how to use this function.
\r
116 UART_instance_t * this_uart,
\r
117 const uint8_t * tx_buffer,
\r
124 HAL_ASSERT( this_uart != NULL_INSTANCE )
\r
125 HAL_ASSERT( tx_buffer != NULL_BUFFER )
\r
126 HAL_ASSERT( tx_size > 0 )
\r
128 if( (this_uart != NULL_INSTANCE) &&
\r
129 (tx_buffer != NULL_BUFFER) &&
\r
130 (tx_size > (size_t)0) )
\r
132 for ( char_idx = (size_t)0; char_idx < tx_size; char_idx++ )
\r
134 /* Wait for UART to become ready to transmit. */
\r
136 tx_ready = HAL_get_8bit_reg( this_uart->base_address, STATUS ) &
\r
138 } while ( !tx_ready );
\r
139 /* Send next character in the buffer. */
\r
140 HAL_set_8bit_reg( this_uart->base_address, TXDATA,
\r
141 (uint_fast8_t)tx_buffer[char_idx] );
\r
146 /***************************************************************************//**
\r
147 * UART_fill_tx_fifo()
\r
148 * See "core_uart_apb.h" for details of how to use this function.
\r
153 UART_instance_t * this_uart,
\r
154 const uint8_t * tx_buffer,
\r
159 size_t size_sent = 0u;
\r
161 HAL_ASSERT( this_uart != NULL_INSTANCE )
\r
162 HAL_ASSERT( tx_buffer != NULL_BUFFER )
\r
163 HAL_ASSERT( tx_size > 0 )
\r
165 /* Fill the UART's Tx FIFO until the FIFO is full or the complete input
\r
166 * buffer has been written. */
\r
167 if( (this_uart != NULL_INSTANCE) &&
\r
168 (tx_buffer != NULL_BUFFER) &&
\r
171 tx_ready = HAL_get_8bit_reg( this_uart->base_address, STATUS ) &
\r
176 HAL_set_8bit_reg( this_uart->base_address, TXDATA,
\r
177 (uint_fast8_t)tx_buffer[size_sent] );
\r
179 tx_ready = HAL_get_8bit_reg( this_uart->base_address, STATUS ) &
\r
181 } while ( (tx_ready) && ( size_sent < tx_size ) );
\r
187 /***************************************************************************//**
\r
189 * See "core_uart_apb.h" for details of how to use this function.
\r
194 UART_instance_t * this_uart,
\r
195 uint8_t * rx_buffer,
\r
199 uint8_t new_status;
\r
201 size_t rx_idx = 0u;
\r
203 HAL_ASSERT( this_uart != NULL_INSTANCE )
\r
204 HAL_ASSERT( rx_buffer != NULL_BUFFER )
\r
205 HAL_ASSERT( buff_size > 0 )
\r
207 if( (this_uart != NULL_INSTANCE) &&
\r
208 (rx_buffer != NULL_BUFFER) &&
\r
212 new_status = HAL_get_8bit_reg( this_uart->base_address, STATUS );
\r
213 this_uart->status |= new_status;
\r
214 rx_full = new_status & STATUS_RXFULL_MASK;
\r
215 while ( ( rx_full ) && ( rx_idx < buff_size ) )
\r
217 rx_buffer[rx_idx] = HAL_get_8bit_reg( this_uart->base_address,
\r
220 new_status = HAL_get_8bit_reg( this_uart->base_address, STATUS );
\r
221 this_uart->status |= new_status;
\r
222 rx_full = new_status & STATUS_RXFULL_MASK;
\r
228 /***************************************************************************//**
\r
229 * UART_polled_tx_string()
\r
230 * See "core_uart_apb.h" for details of how to use this function.
\r
233 UART_polled_tx_string
\r
235 UART_instance_t * this_uart,
\r
236 const uint8_t * p_sz_string
\r
242 HAL_ASSERT( this_uart != NULL_INSTANCE )
\r
243 HAL_ASSERT( p_sz_string != NULL_BUFFER )
\r
245 if( ( this_uart != NULL_INSTANCE ) && ( p_sz_string != NULL_BUFFER ) )
\r
248 while( 0U != p_sz_string[char_idx] )
\r
250 /* Wait for UART to become ready to transmit. */
\r
252 tx_ready = HAL_get_8bit_reg( this_uart->base_address, STATUS ) &
\r
254 } while ( !tx_ready );
\r
255 /* Send next character in the buffer. */
\r
256 HAL_set_8bit_reg( this_uart->base_address, TXDATA,
\r
257 (uint_fast8_t)p_sz_string[char_idx] );
\r
263 /***************************************************************************//**
\r
264 * UART_get_rx_status()
\r
265 * See "core_uart_apb.h" for details of how to use this function.
\r
270 UART_instance_t * this_uart
\r
273 uint8_t status = UART_APB_INVALID_PARAM;
\r
275 HAL_ASSERT( this_uart != NULL_INSTANCE )
\r
277 * Extract UART error status and place in lower bits of "status".
\r
278 * Bit 0 - Parity error status
\r
279 * Bit 1 - Overflow error status
\r
280 * Bit 2 - Frame error status
\r
282 if( this_uart != NULL_INSTANCE )
\r
284 status = ( ( this_uart->status & STATUS_ERROR_MASK ) >>
\r
285 STATUS_ERROR_OFFSET );
\r
287 * Clear the sticky status for this instance.
\r
289 this_uart->status = (uint8_t)0;
\r