1 /*******************************************************************************
\r
2 * (c) Copyright 2007-2015 Microsemi SoC Products Group. All rights reserved.
\r
4 * Core16550 driver implementation. See file "core_16550.h" for a
\r
5 * description of the functions implemented in this file.
\r
7 * SVN $Revision: 7963 $
\r
8 * SVN $Date: 2015-10-09 17:58:21 +0530 (Fri, 09 Oct 2015) $
\r
11 #include "core_16550.h"
\r
12 #include "core16550_regs.h"
\r
13 #include "hal_assert.h"
\r
19 /*******************************************************************************
\r
20 * Definitions for transmitter states
\r
22 #define TX_COMPLETE 0x00U
\r
24 /*******************************************************************************
\r
25 * Definition for transmitter FIFO size
\r
27 #define TX_FIFO_SIZE 16U
\r
29 /*******************************************************************************
\r
30 * Default receive interrupt trigger level
\r
32 #define DEFAULT_RX_TRIG_LEVEL ((uint8_t)UART_16550_FIFO_SINGLE_BYTE)
\r
34 /*******************************************************************************
\r
35 * Receiver error status mask and shift offset
\r
37 #define STATUS_ERROR_MASK ( LSR_OE_MASK | LSR_PE_MASK | \
\r
38 LSR_FE_MASK | LSR_BI_MASK | LSR_FIER_MASK)
\r
40 /*******************************************************************************
\r
41 * Definitions for invalid parameters with proper type
\r
43 #define INVALID_INTERRUPT 0U
\r
44 #define INVALID_IRQ_HANDLER ( (uart_16550_irq_handler_t) 0 )
\r
46 /*******************************************************************************
\r
47 * Possible values for Interrupt Identification Register Field.
\r
49 #define IIRF_MODEM_STATUS 0x00U
\r
50 #define IIRF_THRE 0x02U
\r
51 #define IIRF_RX_DATA 0x04U
\r
52 #define IIRF_RX_LINE_STATUS 0x06U
\r
53 #define IIRF_DATA_TIMEOUT 0x0CU
\r
55 /*******************************************************************************
\r
56 * Null parameters with appropriate type definitions
\r
58 #define NULL_ADDR ( ( addr_t ) 0 )
\r
59 #define NULL_INSTANCE ( ( uart_16550_instance_t * ) 0 )
\r
60 #define NULL_BUFF ( ( uint8_t * ) 0 )
\r
62 /*******************************************************************************
\r
63 * Possible states for different register bit fields
\r
70 /*******************************************************************************
\r
71 * Static function declarations
\r
73 static void default_tx_handler(uart_16550_instance_t * this_uart);
\r
75 /*******************************************************************************
\r
76 * Public function definitions
\r
79 /***************************************************************************//**
\r
81 * See core_16550.h for details of how to use this function.
\r
86 uart_16550_instance_t* this_uart,
\r
88 uint16_t baud_value,
\r
96 uint8_t fifo_config;
\r
99 HAL_ASSERT( base_addr != NULL_ADDR );
\r
100 HAL_ASSERT( this_uart != NULL_INSTANCE );
\r
102 if( ( base_addr != NULL_ADDR ) && ( this_uart != NULL_INSTANCE ) )
\r
104 /* disable interrupts */
\r
105 HAL_set_8bit_reg(base_addr, IER, DISABLE);
\r
107 /* reset divisor latch */
\r
108 HAL_set_8bit_reg_field(base_addr, LCR_DLAB, ENABLE);
\r
110 dbg1 = HAL_get_8bit_reg_field(base_addr, LCR_DLAB );
\r
111 HAL_ASSERT( dbg1 == ENABLE );
\r
113 /* MSB of baud value */
\r
114 temp = (uint8_t)(baud_value >> 8);
\r
115 HAL_set_8bit_reg(base_addr, DMR, temp );
\r
116 /* LSB of baud value */
\r
117 HAL_set_8bit_reg(base_addr, DLR, ( (uint8_t)baud_value ) );
\r
119 dbg1 = HAL_get_8bit_reg(base_addr, DMR );
\r
120 dbg2 = HAL_get_8bit_reg(base_addr, DLR );
\r
121 HAL_ASSERT( ( ( ( (uint16_t) dbg1 ) << 8 ) | dbg2 ) == baud_value );
\r
123 /* reset divisor latch */
\r
124 HAL_set_8bit_reg_field(base_addr, LCR_DLAB, DISABLE);
\r
126 dbg1 = HAL_get_8bit_reg_field(base_addr, LCR_DLAB );
\r
127 HAL_ASSERT( dbg1 == DISABLE );
\r
129 /* set the line control register (bit length, stop bits, parity) */
\r
130 HAL_set_8bit_reg( base_addr, LCR, line_config );
\r
132 dbg1 = HAL_get_8bit_reg(base_addr, LCR );
\r
133 HAL_ASSERT( dbg1 == line_config)
\r
135 /* Enable and configure the RX and TX FIFOs. */
\r
136 fifo_config = ((uint8_t)(DEFAULT_RX_TRIG_LEVEL << FCR_TRIG_LEVEL_SHIFT) |
\r
137 FCR_RDYN_EN_MASK | FCR_CLEAR_RX_MASK |
\r
138 FCR_CLEAR_TX_MASK | FCR_ENABLE_MASK );
\r
139 HAL_set_8bit_reg( base_addr, FCR, fifo_config );
\r
141 /* disable loopback */
\r
142 HAL_set_8bit_reg_field( base_addr, MCR_LOOP, DISABLE );
\r
144 dbg1 = HAL_get_8bit_reg_field(base_addr, MCR_LOOP);
\r
145 HAL_ASSERT( dbg1 == DISABLE );
\r
148 /* Instance setup */
\r
149 this_uart->base_address = base_addr;
\r
150 this_uart->tx_buffer = NULL_BUFF;
\r
151 this_uart->tx_buff_size = TX_COMPLETE;
\r
152 this_uart->tx_idx = 0U;
\r
153 this_uart->tx_handler = default_tx_handler;
\r
155 this_uart->rx_handler = ( (uart_16550_irq_handler_t) 0 );
\r
156 this_uart->linests_handler = ( (uart_16550_irq_handler_t) 0 );
\r
157 this_uart->modemsts_handler = ( (uart_16550_irq_handler_t) 0 );
\r
158 this_uart->status = 0U;
\r
162 /***************************************************************************//**
\r
163 * UART_16550_polled_tx.
\r
164 * See core_16550.h for details of how to use this function.
\r
167 UART_16550_polled_tx
\r
169 uart_16550_instance_t * this_uart,
\r
170 const uint8_t * pbuff,
\r
174 uint32_t char_idx = 0U;
\r
175 uint32_t size_sent;
\r
178 HAL_ASSERT( this_uart != NULL_INSTANCE );
\r
179 HAL_ASSERT( pbuff != NULL_BUFF );
\r
180 HAL_ASSERT( tx_size > 0U );
\r
182 if( ( this_uart != NULL_INSTANCE ) &&
\r
183 ( pbuff != NULL_BUFF ) &&
\r
186 /* Remain in this loop until the entire input buffer
\r
187 * has been transferred to the UART.
\r
190 /* Read the Line Status Register and update the sticky record */
\r
191 status = HAL_get_8bit_reg( this_uart->base_address, LSR );
\r
192 this_uart->status |= status;
\r
194 /* Check if TX FIFO is empty. */
\r
195 if( status & LSR_THRE_MASK )
\r
197 uint32_t fill_size = TX_FIFO_SIZE;
\r
199 /* Calculate the number of bytes to transmit. */
\r
200 if ( tx_size < TX_FIFO_SIZE )
\r
202 fill_size = tx_size;
\r
205 /* Fill the TX FIFO with the calculated the number of bytes. */
\r
206 for ( size_sent = 0U; size_sent < fill_size; ++size_sent )
\r
208 /* Send next character in the buffer. */
\r
209 HAL_set_8bit_reg( this_uart->base_address, THR,
\r
210 (uint_fast8_t)pbuff[char_idx++]);
\r
213 /* Calculate the number of untransmitted bytes remaining. */
\r
214 tx_size -= size_sent;
\r
216 } while ( tx_size );
\r
220 /***************************************************************************//**
\r
221 * UART_16550_polled_tx_string.
\r
222 * See core_16550.h for details of how to use this function.
\r
225 UART_16550_polled_tx_string
\r
227 uart_16550_instance_t * this_uart,
\r
228 const uint8_t * p_sz_string
\r
231 uint32_t char_idx = 0U;
\r
232 uint32_t fill_size;
\r
233 uint_fast8_t data_byte;
\r
236 HAL_ASSERT( this_uart != NULL_INSTANCE );
\r
237 HAL_ASSERT( p_sz_string != NULL_BUFF );
\r
239 if( ( this_uart != NULL_INSTANCE ) && ( p_sz_string != NULL_BUFF ) )
\r
243 /* Get the first data byte from the input buffer */
\r
244 data_byte = (uint_fast8_t)p_sz_string[char_idx];
\r
246 /* First check for the NULL terminator byte.
\r
247 * Then remain in this loop until the entire string in the input buffer
\r
248 * has been transferred to the UART.
\r
250 while ( 0U != data_byte )
\r
252 /* Wait until TX FIFO is empty. */
\r
254 status = HAL_get_8bit_reg( this_uart->base_address,LSR);
\r
255 this_uart->status |= status;
\r
256 } while ( !( status & LSR_THRE_MASK ) );
\r
258 /* Send bytes from the input buffer until the TX FIFO is full
\r
259 * or we reach the NULL terminator byte.
\r
262 while ( (0U != data_byte) && (fill_size < TX_FIFO_SIZE) )
\r
264 /* Send the data byte */
\r
265 HAL_set_8bit_reg( this_uart->base_address, THR, data_byte );
\r
268 /* Get the next data byte from the input buffer */
\r
269 data_byte = (uint_fast8_t)p_sz_string[char_idx];
\r
276 /***************************************************************************//**
\r
277 * UART_16550_irq_tx.
\r
278 * See core_16550.h for details of how to use this function.
\r
283 uart_16550_instance_t * this_uart,
\r
284 const uint8_t * pbuff,
\r
288 HAL_ASSERT( this_uart != NULL_INSTANCE )
\r
289 HAL_ASSERT( pbuff != NULL_BUFF )
\r
290 HAL_ASSERT( tx_size > 0U )
\r
292 if( ( this_uart != NULL_INSTANCE ) &&
\r
293 ( pbuff != NULL_BUFF ) &&
\r
296 /*Initialize the UART instance with
\r
297 parameters required for transmission.*/
\r
298 this_uart->tx_buffer = pbuff;
\r
299 this_uart->tx_buff_size = tx_size;
\r
301 this_uart->tx_idx = 0U;
\r
302 /* assign handler for default data transmission */
\r
303 this_uart->tx_handler = default_tx_handler;
\r
305 /* enables TX interrupt */
\r
306 HAL_set_8bit_reg_field(this_uart->base_address, IER_ETBEI, ENABLE);
\r
310 /***************************************************************************//**
\r
311 * UART_16550_tx_complete.
\r
312 * See core_16550.h for details of how to use this function.
\r
315 UART_16550_tx_complete
\r
317 uart_16550_instance_t * this_uart
\r
320 int8_t returnvalue = 0;
\r
321 uint8_t status = 0U;
\r
323 HAL_ASSERT( this_uart != NULL_INSTANCE )
\r
325 if( this_uart != NULL_INSTANCE )
\r
327 status = HAL_get_8bit_reg(this_uart->base_address,LSR);
\r
328 this_uart->status |= status;
\r
330 if( ( this_uart->tx_buff_size == TX_COMPLETE ) &&
\r
331 ( status & LSR_TEMT_MASK ) )
\r
333 returnvalue = (int8_t)1;
\r
336 return returnvalue;
\r
340 /***************************************************************************//**
\r
341 * UART_16550_get_rx.
\r
342 * See core_16550.h for details of how to use this function.
\r
347 uart_16550_instance_t * this_uart,
\r
353 size_t rx_size = 0U;
\r
355 HAL_ASSERT( this_uart != NULL_INSTANCE )
\r
356 HAL_ASSERT( rx_buff != (uint8_t *)0 )
\r
357 HAL_ASSERT( buff_size > 0U )
\r
359 if( ( this_uart != NULL_INSTANCE ) &&
\r
360 ( rx_buff != (uint8_t *)0 ) &&
\r
361 ( buff_size > 0U ) )
\r
363 status = HAL_get_8bit_reg( this_uart->base_address, LSR );
\r
364 this_uart->status |= status;
\r
365 while ( ((status & LSR_DR_MASK) != 0U) && ( rx_size < buff_size ) )
\r
367 rx_buff[rx_size] = HAL_get_8bit_reg( this_uart->base_address, RBR );
\r
369 status = HAL_get_8bit_reg( this_uart->base_address, LSR );
\r
370 this_uart->status |= status;
\r
376 /***************************************************************************//**
\r
378 * See core_16550.h for details of how to use this function.
\r
383 uart_16550_instance_t * this_uart
\r
388 HAL_ASSERT( this_uart != NULL_INSTANCE )
\r
390 if(this_uart != NULL_INSTANCE )
\r
392 iirf = HAL_get_8bit_reg_field( this_uart->base_address, IIR_IIR );
\r
396 /* Modem status interrupt */
\r
397 case IIRF_MODEM_STATUS:
\r
399 if( INVALID_IRQ_HANDLER != this_uart->modemsts_handler )
\r
401 HAL_ASSERT( INVALID_IRQ_HANDLER != this_uart->modemsts_handler );
\r
402 if( INVALID_IRQ_HANDLER != this_uart->modemsts_handler )
\r
404 (*(this_uart->modemsts_handler))(this_uart);
\r
409 /* Transmitter Holding Register Empty interrupt */
\r
412 HAL_ASSERT( INVALID_IRQ_HANDLER != this_uart->tx_handler );
\r
413 if ( INVALID_IRQ_HANDLER != this_uart->tx_handler )
\r
415 (*(this_uart->tx_handler))(this_uart);
\r
419 /* Received Data Available interrupt */
\r
421 case IIRF_DATA_TIMEOUT:
\r
423 HAL_ASSERT( INVALID_IRQ_HANDLER != this_uart->rx_handler );
\r
424 if ( INVALID_IRQ_HANDLER != this_uart->rx_handler )
\r
426 (*(this_uart->rx_handler))(this_uart);
\r
430 /* Line status interrupt */
\r
431 case IIRF_RX_LINE_STATUS:
\r
433 HAL_ASSERT( INVALID_IRQ_HANDLER != this_uart->linests_handler );
\r
434 if ( INVALID_IRQ_HANDLER != this_uart->linests_handler )
\r
436 (*(this_uart->linests_handler))(this_uart);
\r
440 /* Unidentified interrupt */
\r
443 HAL_ASSERT( INVALID_INTERRUPT )
\r
449 /***************************************************************************//**
\r
450 * UART_16550_set_rx_handler.
\r
451 * See core_16550.h for details of how to use this function.
\r
454 UART_16550_set_rx_handler
\r
456 uart_16550_instance_t * this_uart,
\r
457 uart_16550_irq_handler_t handler,
\r
458 uart_16550_rx_trig_level_t trigger_level
\r
461 HAL_ASSERT( this_uart != NULL_INSTANCE )
\r
462 HAL_ASSERT( handler != INVALID_IRQ_HANDLER)
\r
463 HAL_ASSERT( trigger_level < UART_16550_FIFO_INVALID_TRIG_LEVEL)
\r
465 if( ( this_uart != NULL_INSTANCE ) &&
\r
466 ( handler != INVALID_IRQ_HANDLER) &&
\r
467 ( trigger_level < UART_16550_FIFO_INVALID_TRIG_LEVEL) )
\r
469 this_uart->rx_handler = handler;
\r
471 /* Set the receive interrupt trigger level. */
\r
472 HAL_set_8bit_reg_field( this_uart->base_address,
\r
473 FCR_TRIG_LEVEL, trigger_level );
\r
475 /* Enable receive interrupt. */
\r
476 HAL_set_8bit_reg_field( this_uart->base_address, IER_ERBFI, ENABLE );
\r
480 /***************************************************************************//**
\r
481 * UART_16550_set_loopback.
\r
482 * See core_16550.h for details of how to use this function.
\r
485 UART_16550_set_loopback
\r
487 uart_16550_instance_t * this_uart,
\r
488 uart_16550_loopback_t loopback
\r
491 HAL_ASSERT( this_uart != NULL_INSTANCE );
\r
492 HAL_ASSERT( loopback < UART_16550_INVALID_LOOPBACK );
\r
494 if( ( this_uart != NULL_INSTANCE ) &&
\r
495 ( loopback < UART_16550_INVALID_LOOPBACK ) )
\r
497 if ( loopback == UART_16550_LOOPBACK_OFF )
\r
499 HAL_set_8bit_reg_field( this_uart->base_address,
\r
505 HAL_set_8bit_reg_field( this_uart->base_address,
\r
512 /***************************************************************************//**
\r
513 * UART_16550_get_rx_status.
\r
514 * See core_16550.h for details of how to use this function.
\r
517 UART_16550_get_rx_status
\r
519 uart_16550_instance_t * this_uart
\r
522 uint8_t status = UART_16550_INVALID_PARAM;
\r
523 HAL_ASSERT( this_uart != NULL_INSTANCE );
\r
525 if( ( this_uart != NULL_INSTANCE ) )
\r
528 * Bit 1 - Overflow error status
\r
529 * Bit 2 - Parity error status
\r
530 * Bit 3 - Frame error status
\r
531 * Bit 4 - Break interrupt indicator
\r
532 * Bit 7 - FIFO data error status
\r
534 this_uart->status |= HAL_get_8bit_reg( this_uart->base_address, LSR );
\r
535 status = ( this_uart->status & STATUS_ERROR_MASK );
\r
537 * Clear the sticky status for this instance.
\r
539 this_uart->status = (uint8_t)0;
\r
544 /***************************************************************************//**
\r
545 * UART_16550_get_modem_status.
\r
546 * See core_16550.h for details of how to use this function.
\r
549 UART_16550_get_modem_status
\r
551 uart_16550_instance_t * this_uart
\r
554 uint8_t status = UART_16550_NO_ERROR;
\r
555 HAL_ASSERT( this_uart != NULL_INSTANCE )
\r
557 if( ( this_uart != NULL_INSTANCE ) )
\r
560 * Extract UART error status and place in lower bits of "status".
\r
561 * Bit 0 - Delta Clear to Send Indicator
\r
562 * Bit 1 - Delta Clear to Receive Indicator
\r
563 * Bit 2 - Trailing edge of Ring Indicator detector
\r
564 * Bit 3 - Delta Data Carrier Detect indicator
\r
565 * Bit 4 - Clear To Send
\r
566 * Bit 5 - Data Set Ready
\r
567 * Bit 6 - Ring Indicator
\r
568 * Bit 7 - Data Carrier Detect
\r
570 status = HAL_get_8bit_reg( this_uart->base_address, MSR );
\r
575 /***************************************************************************//**
\r
576 * Default TX interrupt handler to automatically transmit data from
\r
577 * user assgined TX buffer.
\r
582 uart_16550_instance_t * this_uart
\r
587 HAL_ASSERT( NULL_INSTANCE != this_uart )
\r
589 if ( this_uart != NULL_INSTANCE )
\r
591 HAL_ASSERT( NULL_BUFF != this_uart->tx_buffer )
\r
592 HAL_ASSERT( 0U != this_uart->tx_buff_size )
\r
594 if ( ( this_uart->tx_buffer != NULL_BUFF ) &&
\r
595 ( 0U != this_uart->tx_buff_size ) )
\r
597 /* Read the Line Status Register and update the sticky record. */
\r
598 status = HAL_get_8bit_reg( this_uart->base_address,LSR);
\r
599 this_uart->status |= status;
\r
602 * This function should only be called as a result of a THRE interrupt.
\r
603 * Verify that this is true before proceeding to transmit data.
\r
605 if ( status & LSR_THRE_MASK )
\r
607 uint32_t size_sent = 0U;
\r
608 uint32_t fill_size = TX_FIFO_SIZE;
\r
609 uint32_t tx_remain = this_uart->tx_buff_size - this_uart->tx_idx;
\r
611 /* Calculate the number of bytes to transmit. */
\r
612 if ( tx_remain < TX_FIFO_SIZE )
\r
614 fill_size = tx_remain;
\r
617 /* Fill the TX FIFO with the calculated the number of bytes. */
\r
618 for ( size_sent = 0U; size_sent < fill_size; ++size_sent )
\r
620 /* Send next character in the buffer. */
\r
621 HAL_set_8bit_reg( this_uart->base_address, THR,
\r
622 (uint_fast8_t)this_uart->tx_buffer[this_uart->tx_idx]);
\r
623 ++this_uart->tx_idx;
\r
627 /* Flag Tx as complete if all data has been pushed into the Tx FIFO. */
\r
628 if ( this_uart->tx_idx == this_uart->tx_buff_size )
\r
630 this_uart->tx_buff_size = TX_COMPLETE;
\r
631 /* disables TX interrupt */
\r
632 HAL_set_8bit_reg_field( this_uart->base_address,
\r
633 IER_ETBEI, DISABLE);
\r
639 /***************************************************************************//**
\r
640 * UART_16550_enable_irq.
\r
641 * See core_16550.h for details of how to use this function.
\r
644 UART_16550_enable_irq
\r
646 uart_16550_instance_t * this_uart,
\r
650 HAL_ASSERT( this_uart != NULL_INSTANCE )
\r
652 if( this_uart != NULL_INSTANCE )
\r
654 /* irq_mask encoding: 1- enable
\r
655 * bit 0 - Receive Data Available Interrupt
\r
656 * bit 1 - Transmitter Holding Register Empty Interrupt
\r
657 * bit 2 - Receiver Line Status Interrupt
\r
658 * bit 3 - Modem Status Interrupt
\r
660 /* read present interrupts for enabled ones*/
\r
661 irq_mask |= HAL_get_8bit_reg( this_uart->base_address, IER );
\r
662 /* Enable interrupts */
\r
663 HAL_set_8bit_reg( this_uart->base_address, IER, irq_mask );
\r
667 /***************************************************************************//**
\r
668 * UART_16550_disable_irq.
\r
669 * See core_16550.h for details of how to use this function.
\r
672 UART_16550_disable_irq
\r
674 uart_16550_instance_t * this_uart,
\r
678 HAL_ASSERT( this_uart != NULL_INSTANCE )
\r
680 if( this_uart != NULL_INSTANCE )
\r
682 /* irq_mask encoding: 1 - disable
\r
683 * bit 0 - Receive Data Available Interrupt
\r
684 * bit 1 - Transmitter Holding Register Empty Interrupt
\r
685 * bit 2 - Receiver Line Status Interrupt
\r
686 * bit 3 - Modem Status Interrupt
\r
688 /* read present interrupts for enabled ones */
\r
689 irq_mask = (( (uint8_t)~irq_mask ) &
\r
690 HAL_get_8bit_reg( this_uart->base_address, IER ));
\r
691 /* Disable interrupts */
\r
692 HAL_set_8bit_reg( this_uart->base_address, IER, irq_mask );
\r
696 /***************************************************************************//**
\r
697 * UART_16550_set_rxstatus_handler.
\r
698 * See core_16550.h for details of how to use this function.
\r
701 UART_16550_set_rxstatus_handler
\r
703 uart_16550_instance_t * this_uart,
\r
704 uart_16550_irq_handler_t handler
\r
707 HAL_ASSERT( this_uart != NULL_INSTANCE )
\r
708 HAL_ASSERT( handler != INVALID_IRQ_HANDLER)
\r
710 if( ( this_uart != NULL_INSTANCE ) &&
\r
711 ( handler != INVALID_IRQ_HANDLER) )
\r
713 this_uart->linests_handler = handler;
\r
714 /* Enable receiver line status interrupt. */
\r
715 HAL_set_8bit_reg_field( this_uart->base_address, IER_ELSI, ENABLE );
\r
719 /***************************************************************************//**
\r
720 * UART_16550_set_tx_handler.
\r
721 * See core_16550.h for details of how to use this function.
\r
724 UART_16550_set_tx_handler
\r
726 uart_16550_instance_t * this_uart,
\r
727 uart_16550_irq_handler_t handler
\r
730 HAL_ASSERT( this_uart != NULL_INSTANCE )
\r
731 HAL_ASSERT( handler != INVALID_IRQ_HANDLER)
\r
733 if( ( this_uart != NULL_INSTANCE ) &&
\r
734 ( handler != INVALID_IRQ_HANDLER) )
\r
736 this_uart->tx_handler = handler;
\r
738 /* Make TX buffer info invalid */
\r
739 this_uart->tx_buffer = NULL_BUFF;
\r
740 this_uart->tx_buff_size = 0U;
\r
742 /* Enable transmitter holding register Empty interrupt. */
\r
743 HAL_set_8bit_reg_field( this_uart->base_address, IER_ETBEI, ENABLE );
\r
747 /***************************************************************************//**
\r
748 * UART_16550_set_modemstatus_handler.
\r
749 * See core_16550.h for details of how to use this function.
\r
752 UART_16550_set_modemstatus_handler
\r
754 uart_16550_instance_t * this_uart,
\r
755 uart_16550_irq_handler_t handler
\r
758 HAL_ASSERT( this_uart != NULL_INSTANCE )
\r
759 HAL_ASSERT( handler != INVALID_IRQ_HANDLER)
\r
761 if( ( this_uart != NULL_INSTANCE ) &&
\r
762 ( handler != INVALID_IRQ_HANDLER) )
\r
764 this_uart->modemsts_handler = handler;
\r
765 /* Enable modem status interrupt. */
\r
766 HAL_set_8bit_reg_field( this_uart->base_address, IER_EDSSI, ENABLE );
\r
770 /***************************************************************************//**
\r
771 * UART_16550_fill_tx_fifo.
\r
772 * See core_16550.h for details of how to use this function.
\r
775 UART_16550_fill_tx_fifo
\r
777 uart_16550_instance_t * this_uart,
\r
778 const uint8_t * tx_buffer,
\r
783 size_t size_sent = 0U;
\r
785 HAL_ASSERT( this_uart != NULL_INSTANCE )
\r
786 HAL_ASSERT( tx_buffer != NULL_BUFF )
\r
787 HAL_ASSERT( tx_size > 0U )
\r
789 /* Fill the UART's Tx FIFO until the FIFO is full or the complete input
\r
790 * buffer has been written. */
\r
791 if( (this_uart != NULL_INSTANCE) &&
\r
792 (tx_buffer != NULL_BUFF) &&
\r
795 /* Read the Line Status Register and update the sticky record. */
\r
796 status = HAL_get_8bit_reg( this_uart->base_address, LSR );
\r
797 this_uart->status |= status;
\r
799 /* Check if TX FIFO is empty. */
\r
800 if( status & LSR_THRE_MASK )
\r
802 uint32_t fill_size = TX_FIFO_SIZE;
\r
804 /* Calculate the number of bytes to transmit. */
\r
805 if ( tx_size < TX_FIFO_SIZE )
\r
807 fill_size = tx_size;
\r
810 /* Fill the TX FIFO with the calculated the number of bytes. */
\r
811 for ( size_sent = 0U; size_sent < fill_size; ++size_sent )
\r
813 /* Send next character in the buffer. */
\r
814 HAL_set_8bit_reg( this_uart->base_address, THR,
\r
815 (uint_fast8_t)tx_buffer[size_sent]);
\r
822 /***************************************************************************//**
\r
823 * UART_16550_get_tx_status.
\r
824 * See core_16550.h for details of how to use this function.
\r
827 UART_16550_get_tx_status
\r
829 uart_16550_instance_t * this_uart
\r
832 uint8_t status = UART_16550_TX_BUSY;
\r
833 HAL_ASSERT( this_uart != NULL_INSTANCE );
\r
835 if( ( this_uart != NULL_INSTANCE ) )
\r
837 /* Read the Line Status Register and update the sticky record. */
\r
838 status = HAL_get_8bit_reg( this_uart->base_address, LSR );
\r
839 this_uart->status |= status;
\r
841 * Extract the transmit status bits from the UART's Line Status Register.
\r
842 * Bit 5 - Transmitter Holding Register/FIFO Empty (THRE) status. (If = 1, TX FIFO is empty)
\r
843 * Bit 6 - Transmitter Empty (TEMT) status. (If = 1, both TX FIFO and shift register are empty)
\r
845 status &= ( LSR_THRE_MASK | LSR_TEMT_MASK );
\r