/* ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio. This file is part of ChibiOS/RT. ChibiOS/RT 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 IO HAL * @brief Hardware Abstraction Layer. * @details Under ChibiOS/RT the set of the various device driver interfaces * is called the HAL subsystem: Hardware Abstraction Layer. The HAL is the * abstract interface between ChibiOS/RT application and hardware. * * @section hal_device_driver_arch HAL Device Drivers Architecture * A device driver is usually split in two layers: * - High Level Device Driver (HLD). This layer contains the definitions * of the driver's APIs and the platform independent part of the driver.
* An HLD is composed by two files: * - @p @.c, the HLD implementation file. This file must be * included in the Makefile in order to use the driver. * - @p @.h, the HLD header file. This file is implicitly * included by the HAL header file @p hal.h. * . * - Low Level Device Driver (LLD). This layer contains the platform * dependent part of the driver.
* A LLD is composed by two files: * - @p @_lld.c, the LLD implementation file. This file must be * included in the Makefile in order to use the driver. * - @p @_lld.h, the LLD header file. This file is implicitly * included by the HLD header file. * . * The LLD may be not present in those drivers that do not access the * hardware directly but through other device drivers, as example the * @ref MMC_SPI driver uses the @ref SPI and @ref PAL drivers in order * to implement its functionalities. * . * @subsection hal_device_driver_diagram Diagram * @dot digraph example { node [shape=rectangle, fontname=Helvetica, fontsize=8, fixedsize="true", width="2.0", height="0.4"]; edge [fontname=Helvetica, fontsize=8]; app [label="Application"]; hld [label="High Level Driver"]; lld [label="Low Level Driver"]; hw [label="Microcontroller Hardware"]; hal_lld [label="HAL shared low level code"]; app->hld; hld->lld; lld-> hw; lld->hal_lld; hal_lld->hw; } * @enddot */ /** * @defgroup HAL_CONF Configuration * @brief @ref HAL Configuration. * @details The file @p halconf.h contains the high level settings for all * the drivers supported by the HAL. The low level, platform dependent, * settings are contained in the @p mcuconf.h file instead and are describe * in the various platforms reference manuals. * * @ingroup IO */ /** * @defgroup HAL HAL Driver * @brief Hardware Abstraction Layer. * @details The HAL driver performs the system initialization and includes * the platform support code shared by the other drivers. This driver does * contain any API function except for a general initialization function * @p halInit() that must be invoked before any HAL service can be used, * usually the HAL initialization is performed immediately before the * kernel initialization. * * @ingroup IO */ /** * @defgroup HAL_LLD HAL Low Level Driver * @brief @ref HAL low level driver template. * * @ingroup HAL */ /** * @defgroup PAL PAL Driver * @brief I/O Ports Abstraction Layer * @details This module defines an abstract interface for digital I/O ports. * Note that most I/O ports functions are just macros. The macros * have default software implementations that can be redefined in a * @ref PAL_LLD if the target hardware supports special features like, as * example, atomic bit set/reset/masking. Please refer to the ports specific * documentation for details.
* The @ref PAL has the advantage to make the access to the I/O ports platform * independent and still be optimized for the specific architectures.
* Note that the @ref PAL_LLD may also offer non standard macro and functions * in order to support specific features but, of course, the use of such * interfaces would not be portable. Such interfaces shall be marked with * the architecture name inside the function names. * @pre In order to use the ADC driver the @p CH_HAL_USE_PAL option * must be enabled in @p halconf.h. * * @section pal_1 Implementation Rules * In implementing an @ref PAL_LLD there are some rules/behaviors that * should be respected. * * @subsection pal_1_1 Writing on input pads * The behavior is not specified but there are implementations better than * others, this is the list of possible implementations, preferred options * are on top: * -# The written value is not actually output but latched, should the pads * be reprogrammed as outputs the value would be in effect. * -# The write operation is ignored. * -# The write operation has side effects, as example disabling/enabling * pull up/down resistors or changing the pad direction. This scenario is * discouraged, please try to avoid this scenario. * . * @subsection pal_1_2 Reading from output pads * The behavior is not specified but there are implementations better than * others, this is the list of possible implementations, preferred options * are on top: * -# The actual pads states are read (not the output latch). * -# The output latch value is read (regardless of the actual pads states). * -# Unspecified, please try to avoid this scenario. * . * @subsection pal_1_3 Writing unused or unimplemented port bits * The behavior is not specified. * * @subsection pal_1_4 Reading from unused or unimplemented port bits * The behavior is not specified. * * @subsection pal_1_5 Reading or writing on pins associated to other functionalities * The behavior is not specified. * * @ingroup IO */ /** * @defgroup PAL_LLD PAL Low Level Driver * @brief @ref PAL low level driver template. * @details This file is a template for an I/O port low level driver not an * actual implementation. This template is only meant as documentation of * a generic @ref PAL_LLD entry points. * * @ingroup PAL */ /** * @defgroup SERIAL Serial Driver * @brief Generic Serial Driver. * @details This module implements a generic full duplex serial driver. The * driver implements a @p SerialDriver interface and uses I/O Queues for * communication between the upper and the lower driver. Event flags are used * to notify the application about incoming data, outgoing data and other I/O * events.
* The module also contains functions that make the implementation of the * interrupt service routines much easier. * @pre In order to use the ADC driver the @p CH_HAL_USE_SERIAL option * must be enabled in @p halconf.h. * * @ingroup IO */ /** * @defgroup SERIAL_LLD Serial Low Level Driver * @brief @ref SERIAL low level driver template. * @details This file is a template for a serial low level driver not an * actual implementation. This template is only meant as documentation of * a generic @ref SERIAL_LLD entry points. * * @ingroup SERIAL */ /** * @defgroup I2C I2C Driver * @brief Generic I2C Driver. * @details This module implements a generic I2C driver. * @pre In order to use the ADC driver the @p CH_HAL_USE_I2C option * must be enabled in @p halconf.h. * * @section i2c_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). * @if LATEX_PDF * @else * @endif * * The driver is not thread safe for performance reasons, if you need to access * the I2C bus from multiple threads then use the @p i2cAcquireBus() and * @p i2cReleaseBus() APIs in order to gain exclusive access. * * @ingroup IO */ /** * @defgroup I2C_LLD I2C Low Level Driver * @brief @ref I2C low level driver template. * @details This file is a template for an I2C low level driver not an * actual implementation. This template is only meant as documentation of * a generic @ref I2C_LLD entry points. * * @ingroup I2C */ /** * @defgroup SPI SPI Driver * @brief Generic SPI Driver. * @details This module implements a generic SPI driver. * @pre In order to use the ADC driver the @p CH_HAL_USE_SPI option * must be enabled in @p halconf.h. * * @section spi_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). * @if LATEX_PDF * @dot digraph example { size="5, 7"; rankdir="LR"; node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true", width="0.9", height="0.9"]; edge [fontname=Helvetica, fontsize=8]; stop [label="SPI_STOP\nLow Power"]; uninit [label="SPI_UNINIT", style="bold"]; ready [label="SPI_READY\nClock Enabled"]; active [label="SPI_ACTIVE\nBus Active"]; complete [label="SPI_COMPLETE\nComplete"]; uninit -> stop [label="\n spiInit()", constraint=false]; stop -> ready [label="\nspiStart()"]; ready -> ready [label="\nspiSelect()\nspiUnselect()\nspiStart()"]; ready -> stop [label="\nspiStop()"]; stop -> stop [label="\nspiStop()"]; ready -> active [label="\nspiStartXXXI() (async)\nspiXXX() (sync)"]; active -> ready [label="\nsync return"]; active -> complete [label="\nasync callback\n>spc_endcb<"]; complete -> active [label="\nspiStartXXXI() (async)\nthen\ncallback return"]; complete -> ready [label="\ncallback return"]; } * @else * @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]; stop [label="SPI_STOP\nLow Power"]; uninit [label="SPI_UNINIT", style="bold"]; ready [label="SPI_READY\nClock Enabled"]; active [label="SPI_ACTIVE\nBus Active"]; complete [label="SPI_COMPLETE\nComplete"]; uninit -> stop [label="\n spiInit()", constraint=false]; stop -> ready [label="\nspiStart()"]; ready -> ready [label="\nspiSelect()\nspiUnselect()\nspiStart()"]; ready -> stop [label="\nspiStop()"]; stop -> stop [label="\nspiStop()"]; ready -> active [label="\nspiStartXXX() (async)\nspiXXX() (sync)"]; active -> ready [label="\nsync return"]; active -> complete [label="\nasync callback\n>spc_endcb<"]; complete -> active [label="\nspiStartXXXI() (async)\nthen\ncallback return"]; complete -> ready [label="\ncallback return"]; } * @enddot * @endif * * The driver is not thread safe for performance reasons, if you need to access * the SPI bus from multiple threads then use the @p spiAcquireBus() and * @p spiReleaseBus() APIs in order to gain exclusive access. * * @ingroup IO */ /** * @defgroup SPI_LLD SPI Low Level Driver * @brief @ref SPI low level driver template. * @details This file is a template for an SPI low level driver not an * actual implementation. This template is only meant as documentation of * a generic @ref SPI_LLD entry points. * * @ingroup SPI */ /** * @defgroup ADC ADC Driver * @brief Generic ADC Driver. * @details This module implements a generic ADC driver. * @pre In order to use the ADC driver the @p CH_HAL_USE_ADC option * must be enabled in @p halconf.h. * * @section adc_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). * @if LATEX_PDF * @dot digraph example { size="5, 7"; rankdir="LR"; node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true", width="0.9", height="0.9"]; edge [fontname=Helvetica, fontsize=8]; stop [label="ADC_STOP\nLow Power"]; uninit [label="ADC_UNINIT", style="bold"]; ready [label="ADC_READY\nClock Enabled"]; active [label="ADC_ACTIVE\nConverting"]; complete [label="ADC_COMPLETE\nComplete"]; uninit -> stop [label="\n adcInit()", constraint=false]; stop -> ready [label="\nadcStart()"]; ready -> ready [label="\nadcStart()\nadcStopConversion()"]; ready -> stop [label="\nadcStop()"]; stop -> stop [label="\nadcStop()"]; ready -> active [label="\nadcStartConversion() (async)\nadcConvert() (sync)"]; active -> ready [label="\nadcStopConversion()\nsync return"]; active -> active [label="\nasync callback (half buffer)\nasync callback (full buffer circular)\n>acg_endcb<"]; active -> complete [label="\nasync callback (full buffer)\n>acg_endcb<"]; complete -> active [label="\nadcStartConversionI()\nthen\ncallback return()"]; complete -> ready [label="\ncallback return"]; } * @enddot * @else * @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]; stop [label="ADC_STOP\nLow Power"]; uninit [label="ADC_UNINIT", style="bold"]; ready [label="ADC_READY\nClock Enabled"]; active [label="ADC_ACTIVE\nConverting"]; complete [label="ADC_COMPLETE\nComplete"]; uninit -> stop [label="\n adcInit()", constraint=false]; stop -> ready [label="\nadcStart()"]; ready -> ready [label="\nadcStart()\nadcStopConversion()"]; ready -> stop [label="\nadcStop()"]; stop -> stop [label="\nadcStop()"]; ready -> active [label="\nadcStartConversion() (async)\nadcConvert() (sync)"]; active -> ready [label="\nadcStopConversion()\nsync return"]; active -> active [label="\nasync callback (half buffer)\nasync callback (full buffer circular)\n>acg_endcb<"]; active -> complete [label="\nasync callback (full buffer)\n>acg_endcb<"]; complete -> active [label="\nadcStartConversionI()\nthen\ncallback return()"]; complete -> ready [label="\ncallback return"]; } * @enddot * @endif * * @section adc_2 ADC Operations * The ADC driver is quite complex, an explanation of the terminology and of * the operational details follows. * * @subsection adc_2_1 ADC Conversion Groups * The @p ADCConversionGroup is the objects that specifies a physical * conversion operation. This structure contains some standard fields and * several implementation-dependent fields.
* The standard fields define the CG mode, the number of channels belonging * to the CG and the optional callbacks.
* The implementation-dependent fields specify the physical ADC operation * mode, the analog channels belonging to the group and any other * implementation-specific setting. Usually the extra fields just mirror * the physical ADC registers, please refer to the vendor's MCU Reference * Manual for details about the available settings. Details are also available * into the documentation of the ADC low level drivers and in the various * sample applications. * * @subsection adc_2_2 ADC Conversion Modes * The driver supports several conversion modes: * - One Shot, the driver performs a single group conversion then stops. * - Linear Buffer, the driver performs a series of group conversions * then stops. This mode is like a one shot conversion repeated N times, * the buffer pointer increases after each conversion. The buffer is * organized as an S(CG)*N samples matrix, when S(CG) is the conversion * group size (number of channels) and N is the buffer depth (number of * repeated conversions). * - Circular Buffer, much like the linear mode but the operation does * not stop when the buffer is filled, it is automatically restarted * with the buffer pointer wrapping back to the buffer base. * . * @subsection adc_2_3 ADC Callbacks * The driver is able to invoke callbacks during the conversion process. A * callback is invoked when the operation has been completed or, in circular * mode, when the buffer has been filled and the operation is restarted. In * linear and circular modes a callback is also invoked when the buffer is * half filled.
* The "half filled" and "filled" callbacks in circular mode allow to * implement "streaming processing" of the sampled data, while the driver is * busy filling one half of the buffer the application can process the * other half, this allows for continuous interleaved operations. * * @ingroup IO */ /** * @defgroup ADC_LLD ADC Low Level Driver * @brief @ref ADC low level driver template. * @details This file is a template for an ADC low level driver not an * actual implementation. This template is only meant as documentation of * a generic @ref ADC_LLD entry points. * * @ingroup ADC */ /** * @defgroup CAN CAN Driver * @brief Generic CAN Driver. * @details This module implements a generic CAN driver. * @pre In order to use the CAN driver the @p CH_HAL_USE_CAN option * must be enabled in @p halconf.h. * * @section can_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). * @if LATEX_PDF * @dot digraph example { size="5, 7"; rankdir="LR"; node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true", width="0.9", height="0.9"]; edge [fontname=Helvetica, fontsize=8]; stop [label="CAN_STOP\nLow Power"]; uninit [label="CAN_UNINIT", style="bold"]; starting [label="CAN_STARTING\nInitializing"]; ready [label="CAN_READY\nClock Enabled"]; sleep [label="CAN_SLEEP\nLow Power"]; uninit -> stop [label=" canInit()", constraint=false]; stop -> stop [label="\ncanStop()"]; stop -> ready [label="\ncanStart()\n(fast implementation)"]; stop -> starting [label="\ncanStart()\n(slow implementation)"]; starting -> starting [label="\ncanStart()\n(other thread)"]; starting -> ready [label="\ninitialization complete\n(all threads)"]; ready -> stop [label="\ncanStop()"]; ready -> ready [label="\ncanStart()\ncanReceive()\ncanTransmit()"]; ready -> sleep [label="\ncanSleep()"]; sleep -> sleep [label="\ncanSleep()"]; sleep -> ready [label="\ncanWakeup()"]; sleep -> ready [label="\nhardware\nwakeup event"]; } * @enddot * @else * @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]; stop [label="CAN_STOP\nLow Power"]; uninit [label="CAN_UNINIT", style="bold"]; starting [label="CAN_STARTING\nInitializing"]; ready [label="CAN_READY\nClock Enabled"]; sleep [label="CAN_SLEEP\nLow Power"]; uninit -> stop [label=" canInit()", constraint=false]; stop -> stop [label="\ncanStop()"]; stop -> ready [label="\ncanStart()\n(fast implementation)"]; stop -> starting [label="\ncanStart()\n(slow implementation)"]; starting -> starting [label="\ncanStart()\n(other thread)"]; starting -> ready [label="\ninitialization complete\n(all threads)"]; ready -> stop [label="\ncanStop()"]; ready -> ready [label="\ncanStart()\ncanReceive()\ncanTransmit()"]; ready -> sleep [label="\ncanSleep()"]; sleep -> sleep [label="\ncanSleep()"]; sleep -> ready [label="\ncanWakeup()"]; sleep -> ready [label="\nhardware\nwakeup event"]; } * @enddot * @endif * * @ingroup IO */ /** * @defgroup CAN_LLD CAN Low Level Driver * @brief @ref CAN low level driver template. * @details This file is a template for a CAN low level driver not an * actual implementation. This template is only meant as documentation of * a generic @ref CAN_LLD entry points. * * @ingroup CAN */ /** * @defgroup PWM PWM Driver * @brief Generic PWM Driver. * @details This module implements a generic PWM driver. * @pre In order to use the ADC driver the @p CH_HAL_USE_PWM option * must be enabled in @p halconf.h. * * @section pwm_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="PWM_UNINIT", style="bold"]; stop [label="PWM_STOP\nLow Power"]; ready [label="PWM_READY\nClock Enabled"]; uninit -> stop [label="pwmInit()"]; stop -> stop [label="pwmStop()"]; stop -> ready [label="pwmStart()"]; ready -> stop [label="pwmStop()"]; ready -> ready [label="pwmEnableChannel()\npwmDisableChannel()"]; } * @enddot * * @section pwm_1 PWM Operations. * This driver abstracts a generic PWM times composed of: * - A main up counter. * - A comparator register that resets the main counter to zero when the limit * is reached. An optional callback can be generated when this happens. * - An array of @p PWM_CHANNELS PWM channels, each channel has an output, * a comparator and is able to invoke an optional callback when a comparator * match with the main counter happens. * . * A PWM channel output can be in two different states: * - IDLE, when the channel is disabled or after a match occurred. * - ACTIVE, when the channel is enabled and a match didn't occur yet * in the current PWM cycle. * . * Note that the two states can be associated to both logical zero or one in * the @p PWMChannelConfig structure. * * @ingroup IO */ /** * @defgroup PWM_LLD PWM Low Level Driver * @brief @ref PWM low level driver template. * @details This file is a template for a PWM low level driver not an * actual implementation. This template is only meant as documentation of * a generic @ref PWM_LLD entry points. * * @ingroup PWM */ /** * @defgroup MAC MAC Driver * @brief Generic MAC driver. * @details This module implements a generic interface for MAC (Media * Access Control) drivers, as example Ethernet controllers. * @pre In order to use the ADC driver the @p CH_HAL_USE_MAC option * must be enabled in @p halconf.h. * * @ingroup IO */ /** * @defgroup MAC_LLD MAC Low Level Driver * @brief @ref MAC low level driver template. * @details This file is a template for a MAC low level driver not an * actual implementation. This template is only meant as documentation of * a generic @ref MAC_LLD entry points. * * @ingroup MAC */ /** * @defgroup UART UART Driver * @brief Generic UART Driver. * @details This driver abstracts a generic UART 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 * via 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 synchronoyus buffered driver then the * @ref SERIAL should be used instead. * @pre In order to use the ADC driver the @p CH_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 */ /** * @defgroup UART_LLD UART Low Level Driver * @brief @ref UART low level driver template. * @details This file is a template for a UART low level driver not an * actual implementation. This template is only meant as documentation of * a generic @ref UART_LLD entry points. * * @ingroup UART */