/* ChibiOS - Copyright (C) 2006,2007,2008,2009,2010, 2011,2012,2013,2014 Giovanni Di Sirio. This file is part of ChibiOS/HAL ChibiOS/HAL is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. ChibiOS/RT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /** * @defgroup UART UART Driver * @brief Generic UART Driver. * @details This driver abstracts a generic UART (Universal Asynchronous * Receiver Transmitter) peripheral, the API is designed to be: * - Unbuffered and copy-less, transfers are always directly performed * from/to the application-level buffers without extra copy * operations. * - Asynchronous, the API is always non blocking. * - Callbacks capable, operations completion and other events are * notified using callbacks. * . * Special hardware features like deep hardware buffers, DMA transfers * are hidden to the user but fully supportable by the low level * implementations.
* This driver model is best used where communication events are * meant to drive an higher level state machine, as example: * - RS485 drivers. * - Multipoint network drivers. * - Serial protocol decoders. * . * If your application requires a synchronous buffered driver then * the @ref SERIAL should be used instead. * @pre In order to use the UART driver the @p HAL_USE_UART option * must be enabled in @p halconf.h. * * @section uart_1 Driver State Machine * The driver implements a state machine internally, not all the driver * functionalities can be used in any moment, any transition not explicitly * shown in the following diagram has to be considered an error and shall * be captured by an assertion (if enabled). * @dot digraph example { rankdir="LR"; node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true", width="0.9", height="0.9"]; edge [fontname=Helvetica, fontsize=8]; uninit [label="UART_UNINIT", style="bold"]; stop [label="UART_STOP\nLow Power"]; ready [label="UART_READY\nClock Enabled"]; uninit -> stop [label="\nuartInit()"]; stop -> ready [label="\nuartStart()"]; ready -> ready [label="\nuartStart()"]; ready -> stop [label="\nuartStop()"]; stop -> stop [label="\nuartStop()"]; } * @enddot * * @subsection uart_1_1 Transmitter sub State Machine * The follow diagram describes the transmitter state machine, this diagram * is valid while the driver is in the @p UART_READY state. This state * machine is automatically reset to the @p TX_IDLE state each time the * driver enters the @p UART_READY state. * @dot digraph example { rankdir="LR"; node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true", width="0.9", height="0.9"]; edge [fontname=Helvetica, fontsize=8]; tx_idle [label="TX_IDLE", style="bold"]; tx_active [label="TX_ACTIVE"]; tx_complete [label="TX_COMPLETE"]; tx_fatal [label="Fatal Error", style="bold"]; tx_idle -> tx_active [label="\nuartStartSend()"]; tx_idle -> tx_idle [label="\nuartStopSend()\n>uc_txend2<"]; tx_active -> tx_complete [label="\nbuffer transmitted\n>uc_txend1<"]; tx_active -> tx_idle [label="\nuartStopSend()"]; tx_active -> tx_fatal [label="\nuartStartSend()"]; tx_complete -> tx_active [label="\nuartStartSendI()\nthen\ncallback return"]; tx_complete -> tx_idle [label="\ncallback return"]; } * @enddot * * @subsection uart_1_2 Receiver sub State Machine * The follow diagram describes the receiver state machine, this diagram * is valid while the driver is in the @p UART_READY state. This state * machine is automatically reset to the @p RX_IDLE state each time the * driver enters the @p UART_READY state. * @dot digraph example { rankdir="LR"; node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true", width="0.9", height="0.9"]; edge [fontname=Helvetica, fontsize=8]; rx_idle [label="RX_IDLE", style="bold"]; rx_active [label="RX_ACTIVE"]; rx_complete [label="RX_COMPLETE"]; rx_fatal [label="Fatal Error", style="bold"]; rx_idle -> rx_idle [label="\nuartStopReceive()\n>uc_rxchar<\n>uc_rxerr<"]; rx_idle -> rx_active [label="\nuartStartReceive()"]; rx_active -> rx_complete [label="\nbuffer filled\n>uc_rxend<"]; rx_active -> rx_idle [label="\nuartStopReceive()"]; rx_active -> rx_active [label="\nreceive error\n>uc_rxerr<"]; rx_active -> rx_fatal [label="\nuartStartReceive()"]; rx_complete -> rx_active [label="\nuartStartReceiveI()\nthen\ncallback return"]; rx_complete -> rx_idle [label="\ncallback return"]; } * @enddot * * @ingroup IO */