1 /*******************************************************************************
\r
2 * (c) Copyright 2007 Actel Corporation. All rights reserved.
\r
4 * SmartFusion Microcontroller Subsystem UART bare metal software driver public API.
\r
6 * SVN $Revision: 1942 $
\r
7 * SVN $Date: 2009-12-22 17:48:07 +0000 (Tue, 22 Dec 2009) $
\r
9 /*=========================================================================*//**
\r
10 @mainpage SmartFusion MSS UART Bare Metal Driver.
\r
12 @section intro_sec Introduction
\r
13 The SmartFusion MicroController Subsystem (MSS) includes two UART peripherals
\r
14 for serial communications.
\r
15 This driver provides a set of functions for controlling the MSS UARTs as part
\r
16 of a bare metal system where no operating system is available. These drivers
\r
17 can be adapted for use as part of an operating system but the implementation
\r
18 of the adaptation layer between this driver and the operating system's driver
\r
19 model is outside the scope of this driver.
\r
21 @section hw_dependencies Hardware Flow Dependencies
\r
22 The configuration of all features of the MSS UARTs is covered by this driver
\r
23 with the exception of the SmartFusion IOMUX configuration. SmartFusion allows
\r
24 multiple non-concurrent uses of some external pins through IOMUX configuration.
\r
25 This feature allows optimization of external pin usage by assigning external
\r
26 pins for use by either the microcontroller subsystem or the FPGA fabric. The
\r
27 MSS UARTs serial signals are routed through IOMUXes to the SmartFusion device
\r
28 external pins. These IOMUXes are configured automatically by the MSS
\r
29 configurator tool in the hardware flow correctly when the MSS UARTs are enabled
\r
30 in that tool. You must ensure that the MSS UARTs are enabled by the MSS
\r
31 configurator tool in the hardware flow; otherwise the serial inputs and outputs
\r
32 will not be connected to the chip's external pins. For more information on
\r
33 IOMUX, refer to the IOMUX section of the SmartFusion Datasheet.
\r
34 The base address, register addresses and interrupt number assignment for the MSS
\r
35 UART blocks are defined as constants in the SmartFusion CMSIS-PAL You must ensure
\r
36 that the SmartFusion CMSIS-PAL is either included in the software tool chain used
\r
37 to build your project or is included in your project.
\r
40 @section theory_op Theory of Operation
\r
41 The MSS UART driver uses the SmartFusion "Cortex Microcontroler Software
\r
42 Interface Standard - Peripheral Access Layer" (CMSIS-PAL) to access hadware
\r
43 registers. You must ensure that the SmartFusion CMSIS-PAL is either included
\r
44 in the software toolchain used to build your project or is included in your
\r
45 project. The most up to date SmartFusion CMSIS-PAL files can be obtained using
\r
46 the Actel Firmware Catalog.
\r
48 The MSS UART driver functions are logically grouped into three groups:
\r
49 - Initialization functions
\r
50 - Polled transmit and receive functions
\r
51 - Interrupt driven transmit and receive functions
\r
53 The MSS UART driver is initialized through a call to the UART_init() function.
\r
54 This function takes the UART's configuration as parameters. The UART_init()
\r
55 function must be called before any other UART driver functions can be called.
\r
56 The first parameter of the UART_init() function is a pointer to one of two
\r
57 global data structures used to store state information for each UART driver.
\r
58 A pointer to these data structures is also used as first parameter to any of
\r
59 the driver functions to identify which UART will be used by the called
\r
60 function. The name of these two data structures are g_mss_uart0 and
\r
61 g_mss_uart1. Therefore any call to a MSS UART function should be of the form
\r
62 UART_function_name( &g_mss_uart0, ... ) or UART_function_name( &g_mss_uart1, ... ).
\r
63 The two SmartFusion MSS UARTs can also be configured to loop back to each
\r
64 other using the MSS_set_loopback() function for debugging purposes.
\r
66 Polled operations where the processor constantly poll the UART registers state
\r
67 in order to control data transmit or data receive is performed using functions:
\r
68 - MSS_UART_polled_tx()
\r
71 Interrupt driven operations where the processor sets up transmit or receive
\r
72 then returns to performing some other operation until an interrupts occurs
\r
73 indicating that its attention is required is performed using functions:
\r
75 - MSS_UART_tx_complete()
\r
76 - MSS_UART_set_rx_handler()
\r
78 Interrupt driven transmit is initiated by a call to MSS_UART_irq_tx() specifying
\r
79 the block of data to transmit. The processor can then perform some other
\r
80 operation and later inquire whether transmit has completed by calling the
\r
81 MSS_UART_tx_complete() function.
\r
82 Interrupt driven receive is performed by first registering a receive handler
\r
83 function that will be called by the driver whenever receive data is available.
\r
84 This receive handler function in turns calls the MSS_UART_get_rx() function to
\r
85 actually read the received data.
\r
87 *//*=========================================================================*/
\r
88 #ifndef __MSS_UART_H_
\r
89 #define __MSS_UART_H_ 1
\r
91 #include "../../CMSIS/a2fxxxm3.h"
\r
98 /***************************************************************************//**
\r
100 The following definitions are used to specify standard baud rates as a
\r
101 parameter to the MSS_UART_init() function.
\r
103 #define MSS_UART_110_BAUD 110
\r
104 #define MSS_UART_300_BAUD 300
\r
105 #define MSS_UART_1200_BAUD 1200
\r
106 #define MSS_UART_2400_BAUD 2400
\r
107 #define MSS_UART_4800_BAUD 4800
\r
108 #define MSS_UART_9600_BAUD 9600
\r
109 #define MSS_UART_19200_BAUD 19200
\r
110 #define MSS_UART_38400_BAUD 38400
\r
111 #define MSS_UART_57600_BAUD 57600
\r
112 #define MSS_UART_115200_BAUD 115200
\r
113 #define MSS_UART_230400_BAUD 230400
\r
114 #define MSS_UART_460800_BAUD 460800
\r
115 #define MSS_UART_921600_BAUD 921600
\r
117 /***************************************************************************//**
\r
118 Data bits length values.
\r
120 The following defines are used to build the value of the MSS_UART_init()
\r
121 function line_config parameter.
\r
123 #define MSS_UART_DATA_5_BITS 0x00
\r
124 #define MSS_UART_DATA_6_BITS 0x01
\r
125 #define MSS_UART_DATA_7_BITS 0x02
\r
126 #define MSS_UART_DATA_8_BITS 0x03
\r
128 /***************************************************************************//**
\r
130 The following defines are used to build the value of the MSS_UART_init()
\r
131 function line_config parameter.
\r
133 #define MSS_UART_NO_PARITY 0x00
\r
134 #define MSS_UART_ODD_PARITY 0x08
\r
135 #define MSS_UART_EVEN_PARITY 0x18
\r
136 #define MSS_UART_STICK_PARITY_0 0x38
\r
137 #define MSS_UART_STICK_PARITY_1 0x28
\r
139 /***************************************************************************//**
\r
141 The following defines are used to build the value of the MSS_UART_init()
\r
142 function line_config parameter.
\r
144 #define MSS_UART_ONE_STOP_BIT 0x00
\r
145 #define MSS_UART_ONEHALF_STOP_BIT 0x04
\r
146 #define MSS_UART_TWO_STOP_BITS 0x04
\r
148 /***************************************************************************//**
\r
150 This enumeration specifies the number of bytes that must be received before a
\r
151 receive interrupt is generated. This enumeration provides the allowed values for
\r
152 the MSS_UART_set_rx_handler() function trigger_level parameter.
\r
154 typedef enum __mss_uart_rx_trig_level_t {
\r
155 MSS_UART_FIFO_SINGLE_BYTE = 0x00,
\r
156 MSS_UART_FIFO_FOUR_BYTES = 0x40,
\r
157 MSS_UART_FIFO_EIGHT_BYTES = 0x80,
\r
158 MSS_UART_FIFO_FOURTEEN_BYTES = 0xC0
\r
159 } mss_uart_rx_trig_level_t;
\r
161 /***************************************************************************//**
\r
163 This enumeration is used as parameter to function MSS_UART_set_loopback(). It
\r
164 specifies the loopback configuration of the UARTs. Using MSS_UART_LOOPBACK_ON
\r
165 as parameter to function MSS_UART_set_loopback() will set up the UART to locally
\r
166 loopback its Tx and Rx lines.
\r
168 typedef enum __mss_uart_loopback_t {
\r
169 MSS_UART_LOOPBACK_OFF = 0,
\r
170 MSS_UART_LOOPBACK_ON = 1
\r
171 } mss_uart_loopback_t;
\r
173 /***************************************************************************//**
\r
174 Receive handler prototype.
\r
175 This typedef specifies the prototype of functions that can be registered with
\r
176 this driver as receive handler functions.
\r
178 typedef void (*mss_uart_rx_handler_t)(void);
\r
180 /***************************************************************************//**
\r
181 mss_uart_instance_t.
\r
183 There is one instance of this structure for each instance of the Microcontroller
\r
184 Subsystem's UARTs. Instances of this structure are used to identify a specific
\r
185 UART. A pointer to an instance of the mss_uart_instance_t structure is passed
\r
186 as the first parameter to MSS UART driver functions to identify which UART
\r
187 should perform the requested operation.
\r
190 /* CMSIS related defines identifying the UART hardware. */
\r
191 UART_TypeDef * hw_reg; /*!< Pointer to UART registers. */
\r
192 UART_BitBand_TypeDef * hw_reg_bit; /*!< Pointer to UART registers bit band area. */
\r
193 IRQn_Type irqn; /*!< UART's Cortex-M3 NVIC interrupt number. */
\r
195 /* transmit related info (used with interrupt driven trnasmit): */
\r
196 const uint8_t * tx_buffer; /*!< Pointer to transmit buffer. */
\r
197 uint32_t tx_buff_size; /*!< Transmit buffer size. */
\r
198 uint32_t tx_idx; /*!< Index within trnamit buffer of next byte to transmit.*/
\r
200 /* receive interrupt handler:*/
\r
201 mss_uart_rx_handler_t rx_handler; /*!< Pointer to user registered received handler. */
\r
202 } mss_uart_instance_t;
\r
204 /***************************************************************************//**
\r
205 This instance of mss_uart_instance_t holds all data related to the operations
\r
206 performed by UART0. A pointer to g_mss_uart0 is passed as the first parameter
\r
207 to MSS UART driver functions to indicate that UART0 should perform the requested
\r
210 extern mss_uart_instance_t g_mss_uart0;
\r
212 /***************************************************************************//**
\r
213 This instance of mss_uart_instance_t holds all data related to the operations
\r
214 performed by UART1. A pointer to g_mss_uart1 is passed as the first parameter
\r
215 to MSS UART driver functions to indicate that UART1 should perform the requested
\r
218 extern mss_uart_instance_t g_mss_uart1;
\r
220 /***************************************************************************//**
\r
221 The MSS_UART_init() function initializes and configures one of the SmartFusion
\r
222 MSS UARTs with the configuration passed as a parameter. The configuration
\r
223 parameters are the baud_rate which is used to generate the baud value and the
\r
224 line_config which is used to specify the line configuration (bit length, stop
\r
229 #include "mss_uart.h"
\r
236 MSS_UART_57600_BAUD,
\r
237 MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT
\r
244 The this_uart parameter is a pointer to an mss_uart_instance_t structure
\r
245 identifying the MSS UART hardware block to be initialized. There are two
\r
246 such data structures, g_mss_uart0 and g_mss_uart1, associated with MSS UART0
\r
247 and MSS UART1 respectively. This parameter must point to either the
\r
248 g_mss_uart0 or g_mss_uart1 global data structure defined within the UART
\r
253 The baud_rate parameter specifies the baud rate. It can be specified for
\r
254 common baud rates' using the following defines:
\r
255 - MSS_UART_110_BAUD
\r
256 - MSS_UART_300_BAUD
\r
257 - MSS_UART_1200_BAUD
\r
258 - MSS_UART_2400_BAUD
\r
259 - MSS_UART_4800_BAUD
\r
260 - MSS_UART_9600_BAUD
\r
261 - MSS_UART_19200_BAUD
\r
262 - MSS_UART_38400_BAUD
\r
263 - MSS_UART_57600_BAUD
\r
264 - MSS_UART_115200_BAUD
\r
265 - MSS_UART_230400_BAUD
\r
266 - MSS_UART_460800_BAUD
\r
267 - MSS_UART_921600_BAUD
\r
268 Alternatively, any non standard baud rate can be specified by simply passing
\r
269 the actual required baud rate as value for this parameter.
\r
272 The line_config parameter is the line configuration specifying the bit length,
\r
273 number of stop bits and parity settings. This is a logical OR of one of the
\r
274 following to specify the transmit/receive data bit length:
\r
275 - MSS_UART_DATA_5_BITS
\r
276 - MSS_UART_DATA_6_BITS,
\r
277 - MSS_UART_DATA_7_BITS
\r
278 - MSS_UART_DATA_8_BITS
\r
279 with one of the following to specify the parity setting:
\r
280 - MSS_UART_NO_PARITY
\r
281 - MSS_UART_EVEN_PARITY
\r
282 - MSS_UART_ODD_PARITY
\r
283 - MSS_UART_STICK_PARITY_0
\r
284 - MSS_UART_STICK_PARITY_1
\r
285 with one of the following to specify the number of stop bits:
\r
286 - MSS_UART_ONE_STOP_BIT
\r
287 - MSS_UART_ONEHALF_STOP_BIT
\r
288 - MSS_UART_TWO_STOP_BITS
\r
291 This function does not return a value.
\r
296 mss_uart_instance_t* this_uart,
\r
297 uint32_t baud_rate,
\r
298 uint8_t line_config
\r
301 /***************************************************************************//**
\r
302 The function MSS_UART_polled_tx() is used to transmit data. It transfers the
\r
303 contents of the transmitter data buffer, passed as a function parameter, into
\r
304 the UART's hardware transmitter FIFO. It returns when the full content of the
\r
305 transmit data buffer has been transferred to the UART's transmit FIFO.
\r
308 The this_uart parameter is a pointer to an mss_uart_instance_t structure
\r
309 identifying the MSS UART hardware block that will perform the requested
\r
310 function. There are two such data structures, g_mss_uart0 and g_mss_uart1,
\r
311 associated with MSS UART0 and MSS UART1. This parameter must point to either
\r
312 the g_mss_uart0 or g_mss_uart1 global data structure defined within the UART
\r
316 The pbuff parameter is a pointer to a buffer containing the data to be
\r
320 The tx_size parameter specifies the size, in bytes, of the data to be
\r
323 @return This function does not return a value.
\r
328 mss_uart_instance_t * this_uart,
\r
329 const uint8_t * pbuff,
\r
333 /***************************************************************************//**
\r
334 The function MSS_UART_polled_tx_string() is used to transmit a zero-terminated
\r
335 string. It transfers the text found starting at the address pointed to by
\r
336 p_sz_string into the UART's hardware transmitter FIFO. It returns when the
\r
337 complete string has been transferred to the UART's transmit FIFO.
\r
340 The this_uart parameter is a pointer to an mss_uart_instance_t structure
\r
341 identifying the MSS UART hardware block that will perform the requested
\r
342 function. There are two such data structures, g_mss_uart0 and g_mss_uart1,
\r
343 associated with MSS UART0 and MSS UART1. This parameter must point to either
\r
344 the g_mss_uart0 or g_mss_uart1 global data structure defined within the UART
\r
348 The p_sz_string parameter is a pointer to a buffer containing the
\r
349 zero-terminated string to be transmitted.
\r
351 @return This function does not return a value.
\r
354 MSS_UART_polled_tx_string
\r
356 mss_uart_instance_t * this_uart,
\r
357 const uint8_t * p_sz_string
\r
361 /***************************************************************************//**
\r
362 The function MSS_UART_irq_tx() is used to initiate interrupt driven transmit. It
\r
363 returns immediately after making a note of the transmit buffer location and
\r
364 enabling transmit interrupts both at the UART and Cortex-M3 NVIC level.
\r
365 This function takes a pointer to a memory buffer containing the data to
\r
366 transmit as parameter. The memory buffer specified through this pointer
\r
367 should remain allocated and contain the data to transmit until the transmit
\r
368 completion has been detected through calls to function MSS_UART_tx_complete().
\r
369 NOTE: The MSS_UART_irq_tx() function also enables the Transmitter Holding
\r
370 Register Empty (THRE) interrupt and the UART instance interrupt in the
\r
371 Cortex-M3 NVIC as part of its implementation.
\r
375 #include "mss_uart.h"
\r
379 uint8_t tx_buff[10] = "abcdefghi";
\r
380 MSS_UART_init( &g_mss_uart0, MSS_UART_57600_BAUD, MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT );
\r
381 MSS_UART_irq_tx( &g_mss_uart0, tx_buff, sizeof(tx_buff));
\r
382 while ( 0 == MSS_UART_tx_complete( &g_mss_uart0 ) )
\r
391 The this_uart parameter is a pointer to an mss_uart_instance_t structure
\r
392 identifying the MSS UART hardware block that will perform the requested
\r
393 function. There are two such data structures, g_mss_uart0 and g_mss_uart1,
\r
394 associated with MSS UART0 and MSS UART1. This parameter must point to either
\r
395 the g_mss_uart0 or g_mss_uart1 global data structure defined within the UART
\r
399 The pbuff parameter is a pointer to a buffer containing the data to be
\r
403 The tx_size parameter specifies the size, in bytes, of the data to be
\r
407 This function does not return a value.
\r
412 mss_uart_instance_t * this_uart,
\r
413 const uint8_t * pbuff,
\r
417 /***************************************************************************//**
\r
418 The MSS_UART_tx_complete() function is used to find out if interrupt driven
\r
419 transmit previously initiated through a call to MSS_UART_irq_tx() is complete.
\r
420 This is typically used to find out when it is safe to reuse or release the
\r
421 memory buffer holding transmit data.
\r
424 The this_uart parameter is a pointer to an mss_uart_instance_t structure
\r
425 identifying the MSS UART hardware block that will perform the requested
\r
426 function. There are two such data structures, g_mss_uart0 and g_mss_uart1,
\r
427 associated with MSS UART0 and MSS UART1. This parameter must point to either
\r
428 the g_mss_uart0 or g_mss_uart1 global data structure defined within the UART
\r
432 This function return a non-zero value if transmit has completed, otherwise
\r
436 See the MSS_UART_irq_tx() function for an example that uses the
\r
437 MSS_UART_tx_complete() function.
\r
440 MSS_UART_tx_complete
\r
442 mss_uart_instance_t * this_uart
\r
445 /***************************************************************************//**
\r
446 The MSS_UART_get_rx() function is used to read the content of a UART's receive
\r
447 FIFO. It can be used in polled mode where it is called at regular interval
\r
448 to find out if any data has been received or in interrupt driven mode where
\r
449 it is called as part of a receive handler called by the driver as a result of
\r
450 data being received. This function is non-blocking and will return 0
\r
451 immediately if no data has been received.
\r
452 NOTE: In interrupt driven mode you should call the MSS_UART_get_rx() function
\r
453 as part of the receive handler function that you register with the MSS UART
\r
454 driver through a call to MSS_UART_set_rx_handler().
\r
457 The this_uart parameter is a pointer to an mss_uart_instance_t structure
\r
458 identifying the MSS UART hardware block that will perform the requested
\r
459 function. There are two such data structures, g_mss_uart0 and g_mss_uart1,
\r
460 associated with MSS UART0 and MSS UART1. This parameter must point to either
\r
461 the g_mss_uart0 or g_mss_uart1 global data structure defined within the UART
\r
465 The rx_buff parameter is a pointer to a buffer where the received data will
\r
469 The buff_size parameter specifies the size of the receive buffer in bytes.
\r
472 This function return the number of bytes that were copied into the rx_buff
\r
473 buffer. It returns 0 if no data has been received.
\r
475 Polled mode example:
\r
479 uint8_t rx_buff[RX_BUFF_SIZE];
\r
480 uint32_t rx_idx = 0;
\r
482 MSS_UART_init( &g_mss_uart0, MSS_UART_57600_BAUD, MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT );
\r
486 rx_size = MSS_UART_get_rx( &g_mss_uart0, rx_buff, sizeof(rx_buff) );
\r
489 process_rx_data( rx_buff, rx_size );
\r
498 Interrupt driven example:
\r
502 MSS_UART_init( &g_mss_uart1, MSS_UART_57600_BAUD, MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT );
\r
503 MSS_UART_set_rx_handler( &g_mss_uart1, uart1_rx_handler, MSS_UART_FIFO_SINGLE_BYTE );
\r
513 void uart1_rx_handler( void )
\r
515 uint8_t rx_buff[RX_BUFF_SIZE];
\r
516 uint32_t rx_idx = 0;
\r
517 rx_size = MSS_UART_get_rx( &g_mss_uart1, rx_buff, sizeof(rx_buff) );
\r
518 process_rx_data( rx_buff, rx_size );
\r
525 mss_uart_instance_t * this_uart,
\r
530 /***************************************************************************//**
\r
531 The MSS_UART_set_rx_handler() function is used to register a receive handler
\r
532 function which will be called by the driver when a UART Received Data Available
\r
533 (RDA) interrupt occurs. You must create and register the handler function to
\r
534 suit your application. The MSS_UART_set_rx_handler() function also enables the UART
\r
535 Received Data Available interrupt and the UART instance interrupt in the
\r
536 Cortex-M3 NVIC as part of its implementation.
\r
539 The this_uart parameter is a pointer to an mss_uart_instance_t structure
\r
540 identifying the MSS UART hardware block that will perform the requested
\r
541 function. There are two such data structures, g_mss_uart0 and g_mss_uart1,
\r
542 associated with MSS UART0 and MSS UART1. This parameter must point to either
\r
543 the g_mss_uart0 or g_mss_uart1 global data structure defined within the UART
\r
547 The handler parameter is a pointer to a receive handler function provided
\r
548 by your application which will be called as a result of a UART Received
\r
549 Data Available interrupt.
\r
551 @param trigger_level
\r
552 The trigger_level parameter is the receive FIFO trigger level. This specifies
\r
553 the number of bytes that must be received before the UART triggers a Received
\r
554 Data Available interrupt.
\r
557 This function does not return a value.
\r
561 #include "mss_uart.h"
\r
563 #define RX_BUFF_SIZE 64
\r
565 uint8_t g_rx_buff[RX_BUFF_SIZE];
\r
567 void uart0_rx_handler( void )
\r
569 MSS_UART_get_rx( &g_mss_uart, &g_rx_buff[g_rx_idx], sizeof(g_rx_buff) );
\r
574 MSS_UART_init( &g_mss_uart0, MSS_UART_57600_BAUD, MSS_UART_DATA_8_BITS | MSS_UART_NO_PARITY | MSS_UART_ONE_STOP_BIT );
\r
575 MSS_UART_set_rx_handler( &g_mss_uart0, uart0_rx_handler, MSS_UART_FIFO_SINGLE_BYTE );
\r
586 MSS_UART_set_rx_handler
\r
588 mss_uart_instance_t * this_uart,
\r
589 mss_uart_rx_handler_t handler,
\r
590 mss_uart_rx_trig_level_t trigger_level
\r
593 /***************************************************************************//**
\r
594 The MSS_UART_set_loopback() function is used to locally loopback the Tx and Rx
\r
596 This is not to be confused with the loopback of UART0 to UART1 which can be
\r
597 achieved through the microcontroller subsystem's system registers
\r
600 The this_uart parameter is a pointer to an mss_uart_instance_t structure
\r
601 identifying the MSS UART hardware block that will perform the requested
\r
602 function. There are two such data structures, g_mss_uart0 and g_mss_uart1,
\r
603 associated with MSS UART0 and MSS UART1. This parameter must point to either
\r
604 the g_mss_uart0 or g_mss_uart1 global data structure defined within the UART
\r
608 The loopback parameter indicates whether or not the UART's transmit and receive lines
\r
609 should be looped back. Allowed values are:
\r
610 - MSS_UART_LOOPBACK_ON
\r
611 - MSS_UART_LOOPBACK_OFF
\r
613 This function does not return a value.
\r
616 MSS_UART_set_loopback
\r
618 mss_uart_instance_t * this_uart,
\r
619 mss_uart_loopback_t loopback
\r
626 #endif /* __MSS_UART_H_ */
\r