From 18b825ef0cd7ad3eed9e76310d94178eb27307d5 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Tue, 7 Sep 2010 13:37:22 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2167 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/hal.dox | 674 ++++++++++++++++++++++++-------------- os/hal/include/serial.h | 4 +- os/hal/platforms/STM32/uart_lld.h | 4 +- os/hal/templates/adc_lld.h | 6 + os/hal/templates/can_lld.h | 6 + os/hal/templates/i2c_lld.h | 5 +- os/hal/templates/mac_lld.h | 6 + os/hal/templates/pal_lld.h | 12 +- os/hal/templates/pwm_lld.h | 4 + os/hal/templates/serial_lld.h | 5 +- os/hal/templates/spi_lld.h | 6 +- os/hal/templates/uart_lld.h | 11 +- 12 files changed, 480 insertions(+), 263 deletions(-) (limited to 'os') diff --git a/os/hal/hal.dox b/os/hal/hal.dox index 24e5d9292..591666580 100644 --- a/os/hal/hal.dox +++ b/os/hal/hal.dox @@ -21,22 +21,25 @@ * @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.
+ * 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: - * - @.c, the HLD implementation file. This file must be + * - @p @.c, the HLD implementation file. This file must be * included in the Makefile in order to use the driver. - * - @.h, the HLD header file. This file is implicitly + * - @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: - * - @_lld.c, the LLD implementation file. This file must be + * - @p @_lld.c, the LLD implementation file. This file must be * included in the Makefile in order to use the driver. - * - @_lld.h, the LLD header file. This file is implicitly + * - @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 @@ -44,24 +47,46 @@ * @ref MMC_SPI driver uses the @ref SPI and @ref PAL drivers in order * to implement its functionalities. * . - *

Available Device Drivers

- * The I/O subsystem currently includes support for: - * - @ref HAL. - * - @ref PAL. - * - @ref SERIAL. - * - @ref ADC. - * - @ref CAN. - * - @ref MAC. - * - @ref MMC_SPI. - * - @ref SPI. - * . + * @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 HAL 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 HAL */ /** * @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. + * 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 */ @@ -73,13 +98,6 @@ * @ingroup HAL */ -/** - * @defgroup HAL_CONF Configuration - * @brief @ref HAL Configuration. - * - * @ingroup HAL - */ - /** * @defgroup PAL PAL Driver * @brief I/O Ports Abstraction Layer @@ -96,11 +114,11 @@ * interfaces would not be portable. Such interfaces shall be marked with * the architecture name inside the function names. * - *

Implementation Rules

+ * @section pal_1 Implementation Rules * In implementing an @ref PAL_LLD there are some rules/behaviors that * should be respected. * - *

Writing on input pads

+ * @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: @@ -111,7 +129,7 @@ * pull up/down resistors or changing the pad direction. This scenario is * discouraged, please try to avoid this scenario. * . - *

Reading from output pads

+ * @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: @@ -119,27 +137,24 @@ * -# The output latch value is read (regardless of the actual pads states). * -# Unspecified, please try to avoid this scenario. * . - *

Writing unused or unimplemented port bits

+ * @subsection pal_1_3 Writing unused or unimplemented port bits * The behavior is not specified. * - *

Reading from unused or unimplemented port bits

+ * @subsection pal_1_4 Reading from unused or unimplemented port bits * The behavior is not specified. * - *

Reading or writing on pins associated to other functionalities

+ * @subsection pal_1_5 Reading or writing on pins associated to other functionalities * The behavior is not specified. * - *

Usage

- * The use of I/O ports requires the inclusion of the header file @p pal.h, - * this file is not automatically included @p ch.h like the other header - * files. - * * @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. + * @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 */ @@ -161,7 +176,9 @@ /** * @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. + * @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 */ @@ -169,30 +186,16 @@ /** * @defgroup I2C I2C Driver * @brief Generic I2C Driver. - * @details This module implements a generic I2C driver. The driver implements - * a state machine internally: - * @dot - digraph example { - rankdir="LR"; - node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true", width="0.8", height="0.8"]; - edge [fontname=Helvetica, fontsize=8]; - uninit [label="SPI_UNINIT", style="bold"]; - stop [label="SPI_STOP\nLow Power"]; - ready [label="SPI_READY\nClock Enabled"]; - active [label="SPI_ACTIVE\nBus Active"]; - uninit -> stop [label="spiInit()"]; - stop -> ready [label="spiStart()"]; - ready -> ready [label="spiStart()"]; - ready -> ready [label="spiIgnore()"]; - ready -> stop [label="spiStop()"]; - stop -> stop [label="spiStop()"]; - ready -> active [label="spiSelect()"]; - active -> active [label="spiSelect()"]; - active -> ready [label="spiUnselect()"]; - ready -> ready [label="spiUnselect()"]; - active -> active [label="spiIgnore()\nspiExchange()\nspiSend()\nspiReceive()"]; - } - * @enddot + * @details This module implements a generic I2C driver. + * + * @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 thread then use the @p i2cAcquireBus() and @@ -204,7 +207,9 @@ /** * @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. + * @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 */ @@ -212,30 +217,60 @@ /** * @defgroup SPI SPI Driver * @brief Generic SPI Driver. - * @details This module implements a generic SPI driver. The driver implements - * a state machine internally: + * @details This module implements a generic SPI driver. + * + * @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.8", height="0.8"]; + edge [fontname=Helvetica, fontsize=8]; + uninit [label="SPI_UNINIT", style="bold"]; + stop [label="SPI_STOP\nLow Power"]; + ready [label="SPI_READY\nClock Enabled"]; + active [label="SPI_ACTIVE\nBus Active"]; + uninit -> stop [label="spiInit()"]; + stop -> ready [label="spiStart()"]; + ready -> ready [label="spiStart()"]; + ready -> ready [label="spiIgnore()"]; + ready -> stop [label="spiStop()"]; + stop -> stop [label="spiStop()"]; + ready -> active [label="spiSelect()"]; + active -> active [label="spiSelect()"]; + active -> ready [label="spiUnselect()"]; + ready -> ready [label="spiUnselect()"]; + active -> active [label="spiIgnore()\nspiExchange()\nspiSend()\nspiReceive()"]; + } + * @else * @dot digraph example { - rankdir="LR"; - node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true", width="0.8", height="0.8"]; - edge [fontname=Helvetica, fontsize=8]; - uninit [label="SPI_UNINIT", style="bold"]; - stop [label="SPI_STOP\nLow Power"]; - ready [label="SPI_READY\nClock Enabled"]; - active [label="SPI_ACTIVE\nBus Active"]; - uninit -> stop [label="spiInit()"]; - stop -> ready [label="spiStart()"]; - ready -> ready [label="spiStart()"]; - ready -> ready [label="spiIgnore()"]; - ready -> stop [label="spiStop()"]; - stop -> stop [label="spiStop()"]; - ready -> active [label="spiSelect()"]; - active -> active [label="spiSelect()"]; - active -> ready [label="spiUnselect()"]; - ready -> ready [label="spiUnselect()"]; - active -> active [label="spiIgnore()\nspiExchange()\nspiSend()\nspiReceive()"]; + rankdir="LR"; + node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true", width="0.8", height="0.8"]; + edge [fontname=Helvetica, fontsize=8]; + uninit [label="SPI_UNINIT", style="bold"]; + stop [label="SPI_STOP\nLow Power"]; + ready [label="SPI_READY\nClock Enabled"]; + active [label="SPI_ACTIVE\nBus Active"]; + uninit -> stop [label="spiInit()"]; + stop -> ready [label="spiStart()"]; + ready -> ready [label="spiStart()"]; + ready -> ready [label="spiIgnore()"]; + ready -> stop [label="spiStop()"]; + stop -> stop [label="spiStop()"]; + ready -> active [label="spiSelect()"]; + active -> active [label="spiSelect()"]; + active -> ready [label="spiUnselect()"]; + ready -> ready [label="spiUnselect()"]; + active -> active [label="spiIgnore()\nspiExchange()\nspiSend()\nspiReceive()"]; } * @enddot + * @endif * * The driver is not thread safe for performance reasons, if you need to access * the SPI bus from multiple thread then use the @p spiAcquireBus() and @@ -247,7 +282,9 @@ /** * @defgroup SPI_LLD SPI Low Level Driver * @brief @ref SPI low level driver template. - * @details This file is a template for a SPI low level driver. + * @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 */ @@ -255,33 +292,67 @@ /** * @defgroup ADC ADC Driver * @brief Generic ADC Driver. - * @details This module implements a generic ADC driver. The driver implements - * a state machine internally: + * @details This module implements a generic ADC driver. + * + * @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 { - rankdir="LR"; - node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true", width="0.8", height="0.8"]; - edge [fontname=Helvetica, fontsize=8]; - uninit [label="ADC_UNINIT", style="bold"]; - stop [label="ADC_STOP\nLow Power"]; - ready [label="ADC_READY\nClock Enabled"]; - running [label="ADC_RUNNING"]; - complete [label="ADC_COMPLETE"]; - uninit -> stop [label="adcInit()"]; - stop -> ready [label="adcStart()"]; - ready -> ready [label="adcStart()"]; - ready -> ready [label="adcWaitConversion()"]; - ready -> stop [label="adcStop()"]; - stop -> stop [label="adcStop()"]; - ready -> running [label="adcStartConversion()"]; - running -> ready [label="adcStopConversion()"]; - running -> complete [label="End of Conversion"]; - complete -> running [label="adcStartConversion()"]; - complete -> ready [label="adcStopConversion()"]; - complete -> ready [label="adcWaitConversion()"]; - complete -> stop [label="adcStop()"]; + size="5, 7"; + rankdir="LR"; + node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true", width="0.8", height="0.8"]; + edge [fontname=Helvetica, fontsize=8]; + stop [label="ADC_STOP\nLow Power"]; + uninit [label="ADC_UNINIT", style="bold"]; + ready [label="ADC_READY\nClock Enabled"]; + running [label="ADC_RUNNING"]; + complete [label="ADC_COMPLETE"]; + uninit -> stop [label="adcInit()", constraint=false]; + stop -> ready [label="adcStart()"]; + ready -> ready [label="adcStart()"]; + ready -> ready [label="adcWaitConversion()"]; + ready -> stop [label="adcStop()"]; + stop -> stop [label="adcStop()"]; + ready -> running [label="adcStartConversion()"]; + running -> ready [label="adcStopConversion()"]; + running -> complete [label="End of Conversion"]; + complete -> running [label="adcStartConversion()"]; + complete -> ready [label="adcStopConversion()"]; + complete -> ready [label="adcWaitConversion()"]; + complete -> stop [label="adcStop()"]; } * @enddot + * @else + * @dot + digraph example { + rankdir="LR"; + node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true", width="0.8", height="0.8"]; + edge [fontname=Helvetica, fontsize=8]; + stop [label="ADC_STOP\nLow Power"]; + uninit [label="ADC_UNINIT", style="bold"]; + ready [label="ADC_READY\nClock Enabled"]; + running [label="ADC_RUNNING"]; + complete [label="ADC_COMPLETE"]; + uninit -> stop [label="adcInit()", constraint=false]; + stop -> ready [label="adcStart()"]; + ready -> ready [label="adcStart()"]; + ready -> ready [label="adcWaitConversion()"]; + ready -> stop [label="adcStop()"]; + stop -> stop [label="adcStop()"]; + ready -> running [label="adcStartConversion()"]; + running -> ready [label="adcStopConversion()"]; + running -> complete [label="End of Conversion"]; + complete -> running [label="adcStartConversion()"]; + complete -> ready [label="adcStopConversion()"]; + complete -> ready [label="adcWaitConversion()"]; + complete -> stop [label="adcStop()"]; + } + * @enddot + * @endif * * The driver supports a continuous conversion mode with circular buffer, * callback functions allow to process the converted data in real time. @@ -293,7 +364,9 @@ /** * @defgroup ADC_LLD ADC Low Level Driver * @brief @ref ADC low level driver template. - * @details This file is a template for a ADC low level driver. + * @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 */ @@ -301,29 +374,59 @@ /** * @defgroup CAN CAN Driver * @brief Generic CAN Driver. - * @details This module implements a generic ADC driver. The driver implements - * a state machine internally: + * @details This module implements a generic ADC driver. + * + * @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 { - rankdir="LR"; - node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true", width="0.8", height="0.8"]; - edge [fontname=Helvetica, fontsize=8]; - uninit [label="CAN_UNINIT", style="bold"]; - stop [label="CAN_STOP\nLow Power"]; - ready [label="CAN_READY\nClock Enabled"]; - sleep [label="CAN_SLEEP\nLow Power"]; - uninit -> stop [label="canInit()"]; - stop -> stop [label="canStop()"]; - stop -> ready [label="canStart()"]; - ready -> stop [label="canStop()"]; - ready -> ready [label="canReceive()\ncanTransmit()"]; - ready -> ready [label="canStart()"]; - ready -> sleep [label="canSleep()"]; - sleep -> sleep [label="canSleep()"]; - sleep -> ready [label="canWakeup()"]; - sleep -> ready [label="wakeup event"]; + size="5, 7"; + rankdir="LR"; + node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true", width="0.8", height="0.8"]; + edge [fontname=Helvetica, fontsize=8]; + uninit [label="CAN_UNINIT", style="bold"]; + stop [label="CAN_STOP\nLow Power"]; + ready [label="CAN_READY\nClock Enabled"]; + sleep [label="CAN_SLEEP\nLow Power"]; + uninit -> stop [label="canInit()"]; + stop -> stop [label="canStop()"]; + stop -> ready [label="canStart()"]; + ready -> stop [label="canStop()"]; + ready -> ready [label="canReceive()\ncanTransmit()"]; + ready -> ready [label="canStart()"]; + ready -> sleep [label="canSleep()"]; + sleep -> sleep [label="canSleep()"]; + sleep -> ready [label="canWakeup()"]; + sleep -> ready [label="wakeup event"]; } * @enddot + * @else + * @dot + digraph example { + rankdir="LR"; + node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true", width="0.8", height="0.8"]; + edge [fontname=Helvetica, fontsize=8]; + uninit [label="CAN_UNINIT", style="bold"]; + stop [label="CAN_STOP\nLow Power"]; + ready [label="CAN_READY\nClock Enabled"]; + sleep [label="CAN_SLEEP\nLow Power"]; + uninit -> stop [label="canInit()"]; + stop -> stop [label="canStop()"]; + stop -> ready [label="canStart()"]; + ready -> stop [label="canStop()"]; + ready -> ready [label="canReceive()\ncanTransmit()"]; + ready -> ready [label="canStart()"]; + ready -> sleep [label="canSleep()"]; + sleep -> sleep [label="canSleep()"]; + sleep -> ready [label="canWakeup()"]; + sleep -> ready [label="wakeup event"]; + } + * @enddot + * @endif * * @ingroup IO */ @@ -331,6 +434,9 @@ /** * @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 */ @@ -338,21 +444,26 @@ /** * @defgroup PWM PWM Driver * @brief Generic PWM Driver. - * @details This module implements a generic PWM driver. The driver implements - * a state machine internally: + * @details This module implements a generic PWM driver. + * + * @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.8", height="0.8"]; - 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()"]; + rankdir="LR"; + node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true", width="0.8", height="0.8"]; + 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 * @@ -362,6 +473,9 @@ /** * @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 */ @@ -378,7 +492,9 @@ /** * @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. + * @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 */ @@ -387,48 +503,95 @@ * @defgroup MMC_SPI MMC over SPI Driver * @brief Generic MMC driver. * @details This module implements a portable MMC driver that uses a SPI - * driver as physical layer.
- * The driver implements the following state machine: + * driver as physical layer. + * + * @section mmc_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 { - rankdir="LR"; - node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true", width="0.8", height="0.8"]; - edge [fontname=Helvetica, fontsize=8]; - - any [label="Any State"]; - stop2 [label="MMC_STOP\nLow Power"]; - uninit [label="MMC_UNINIT", style="bold"]; - stop [label="MMC_STOP\nLow Power"]; - wait [label="MMC_WAIT\nWaiting Card"]; - inserted [label="MMC_INSERTED\nCard Inserted"]; - ready [label="MMC_READY\nCard Ready"]; - reading [label="MMC_READING\nReading"]; - writing [label="MMC_WRITING\nWriting"]; - - uninit -> stop [label="mmcInit()"]; - stop -> wait [label="mmcStart()", constraint=false]; - wait -> inserted [label="insertion (inserted event)"]; - inserted -> inserted [label="mmcDisconnect()"]; - inserted -> ready [label="mmcConnect()"]; - ready -> ready [label="mmcConnect()"]; - ready -> inserted [label="mmcDisconnect()"]; - ready -> reading [label="mmcStartSequentialRead()"]; - reading -> reading [label="mmcSequentialRead()"]; - reading -> ready [label="mmcStopSequentialRead()"]; - reading -> ready [label="read error"]; - ready -> writing [label="mmcStartSequentialWrite()"]; - writing -> writing [label="mmcSequentialWrite()"]; - writing -> ready [label="mmcStopSequentialWrite()"]; - writing -> ready [label="write error"]; - - inserted -> wait [label="removal (removed event)"]; - ready -> wait [label="removal (removed event)"]; - reading -> wait [label="removal (removed event)"]; - writing -> wait [label="removal (removed event)"]; - - any -> stop2 [label="mmcStop()"]; + size="5, 7"; + rankdir="LR"; + node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true", width="0.8", height="0.8"]; + edge [fontname=Helvetica, fontsize=8]; + + any [label="Any State"]; + stop2 [label="MMC_STOP\nLow Power"]; + uninit [label="MMC_UNINIT", style="bold"]; + stop [label="MMC_STOP\nLow Power"]; + wait [label="MMC_WAIT\nWaiting Card"]; + inserted [label="MMC_INSERTED\nCard Inserted"]; + ready [label="MMC_READY\nCard Ready"]; + reading [label="MMC_READING\nReading"]; + writing [label="MMC_WRITING\nWriting"]; + + uninit -> stop [label="mmcInit()"]; + stop -> wait [label="mmcStart()", constraint=false]; + wait -> inserted [label="insertion (inserted event)"]; + inserted -> inserted [label="mmcDisconnect()"]; + inserted -> ready [label="mmcConnect()"]; + ready -> ready [label="mmcConnect()"]; + ready -> inserted [label="mmcDisconnect()"]; + ready -> reading [label="mmcStartSequentialRead()"]; + reading -> reading [label="mmcSequentialRead()"]; + reading -> ready [label="mmcStopSequentialRead()"]; + reading -> ready [label="read error"]; + ready -> writing [label="mmcStartSequentialWrite()"]; + writing -> writing [label="mmcSequentialWrite()"]; + writing -> ready [label="mmcStopSequentialWrite()"]; + writing -> ready [label="write error"]; + inserted -> wait [label="removal (removed event)"]; + ready -> wait [label="removal (removed event)"]; + reading -> wait [label="removal (removed event)"]; + writing -> wait [label="removal (removed event)"]; + + any -> stop2 [label="mmcStop()"]; } * @enddot + * @else + * @dot + digraph example { + rankdir="LR"; + node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true", width="0.8", height="0.8"]; + edge [fontname=Helvetica, fontsize=8]; + + any [label="Any State"]; + stop2 [label="MMC_STOP\nLow Power"]; + uninit [label="MMC_UNINIT", style="bold"]; + stop [label="MMC_STOP\nLow Power"]; + wait [label="MMC_WAIT\nWaiting Card"]; + inserted [label="MMC_INSERTED\nCard Inserted"]; + ready [label="MMC_READY\nCard Ready"]; + reading [label="MMC_READING\nReading"]; + writing [label="MMC_WRITING\nWriting"]; + + uninit -> stop [label="mmcInit()"]; + stop -> wait [label="mmcStart()", constraint=false]; + wait -> inserted [label="insertion (inserted event)"]; + inserted -> inserted [label="mmcDisconnect()"]; + inserted -> ready [label="mmcConnect()"]; + ready -> ready [label="mmcConnect()"]; + ready -> inserted [label="mmcDisconnect()"]; + ready -> reading [label="mmcStartSequentialRead()"]; + reading -> reading [label="mmcSequentialRead()"]; + reading -> ready [label="mmcStopSequentialRead()"]; + reading -> ready [label="read error"]; + ready -> writing [label="mmcStartSequentialWrite()"]; + writing -> writing [label="mmcSequentialWrite()"]; + writing -> ready [label="mmcStopSequentialWrite()"]; + writing -> ready [label="write error"]; + inserted -> wait [label="removal (removed event)"]; + ready -> wait [label="removal (removed event)"]; + reading -> wait [label="removal (removed event)"]; + writing -> wait [label="removal (removed event)"]; + + any -> stop2 [label="mmcStop()"]; + } + * @enddot + * @endif * * The MMC drivers currently supports only cards with capacity up to 2GB * and does not implement CRC checking. Hot plugging and removal are supported @@ -441,78 +604,102 @@ /** * @defgroup UART UART Driver * @brief Generic UART Driver. - * @details This module implements a generic UART driver. The driver implements - * a state machine internally: + * @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. + * + * @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.8", height="0.8"]; edge [fontname=Helvetica, fontsize=8]; - subgraph cluster_RECEIVER { - 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"]; - - color = blue; - label = "Receiver state machine (within driver state UART_READY)"; - } - - subgraph cluster_TRANSMITTER { - 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"]; - - color = blue; - label = "Transmitter state machine (within driver state UART_READY)"; - } - - subgraph cluster_DRIVER { - 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()"]; - - color = blue; - label = "Driver state machine"; - } + 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.8", height="0.8"]; + 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.8", height="0.8"]; + 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 - * The UART driver is meant for those application where unbuffered access to - * the physical device is required. The driver is totally asynchronous and - * invokes callbacks on relevant driver state transitions. If your application - * requires a buffered driver then the @ref SERIAL should be used instead.
- * 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. - * - Protocol decoders. - * . * * @ingroup IO */ @@ -520,6 +707,9 @@ /** * @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 */ diff --git a/os/hal/include/serial.h b/os/hal/include/serial.h index de2572f39..74969308f 100644 --- a/os/hal/include/serial.h +++ b/os/hal/include/serial.h @@ -99,7 +99,7 @@ typedef enum { /** * @brief Structure representing a serial driver. */ -typedef struct _SerialDriver SerialDriver; +typedef struct SerialDriver SerialDriver; #include "serial_lld.h" @@ -123,7 +123,7 @@ struct SerialDriverVMT { * @details This class extends @p BaseAsynchronousChannel by adding physical * I/O queues. */ -struct _SerialDriver { +struct SerialDriver { /** @brief Virtual Methods Table.*/ const struct SerialDriverVMT *vmt; _serial_driver_data diff --git a/os/hal/platforms/STM32/uart_lld.h b/os/hal/platforms/STM32/uart_lld.h index 4b5ee8dba..d030c2970 100644 --- a/os/hal/platforms/STM32/uart_lld.h +++ b/os/hal/platforms/STM32/uart_lld.h @@ -168,7 +168,7 @@ typedef uint32_t uartflags_t; /** * @brief Structure representing an UART driver. */ -typedef struct _UARTDriver UARTDriver; +typedef struct UARTDriver UARTDriver; /** * @brief Generic UART notification callback type. @@ -222,7 +222,7 @@ typedef struct { /** * @brief Structure representing an UART driver. */ -struct _UARTDriver { +struct UARTDriver { /** @brief Driver state.*/ uartstate_t ud_state; /** @brief Current configuration data.*/ diff --git a/os/hal/templates/adc_lld.h b/os/hal/templates/adc_lld.h index a36fc205f..d969b24e0 100644 --- a/os/hal/templates/adc_lld.h +++ b/os/hal/templates/adc_lld.h @@ -72,6 +72,8 @@ typedef void (*adccallback_t)(adcsample_t *buffer, size_t n); * @brief Conversion group configuration structure. * @details This implementation-dependent structure describes a conversion * operation. + * @note Implementations may extend this structure to contain more, + * architecture dependent, fields. */ typedef struct { /** @@ -87,6 +89,8 @@ typedef struct { /** * @brief Driver configuration structure. + * @note Implementations may extend this structure to contain more, + * architecture dependent, fields. * @note It could be empty on some architectures. */ typedef struct { @@ -95,6 +99,8 @@ typedef struct { /** * @brief Structure representing an ADC driver. + * @note Implementations may extend this structure to contain more, + * architecture dependent, fields. */ typedef struct { /** diff --git a/os/hal/templates/can_lld.h b/os/hal/templates/can_lld.h index 3049d8a94..afca6821e 100644 --- a/os/hal/templates/can_lld.h +++ b/os/hal/templates/can_lld.h @@ -130,6 +130,8 @@ typedef struct { /** * @brief CAN filter. + * @note Implementations may extend this structure to contain more, + * architecture dependent, fields. * @note It could not be present on some architectures. */ typedef struct { @@ -137,6 +139,8 @@ typedef struct { /** * @brief Driver configuration structure. + * @note Implementations may extend this structure to contain more, + * architecture dependent, fields. * @note It could be empty on some architectures. */ typedef struct { @@ -144,6 +148,8 @@ typedef struct { /** * @brief Structure representing an CAN driver. + * @note Implementations may extend this structure to contain more, + * architecture dependent, fields. */ typedef struct { /** diff --git a/os/hal/templates/i2c_lld.h b/os/hal/templates/i2c_lld.h index 3a2ceb4aa..77c67cc07 100644 --- a/os/hal/templates/i2c_lld.h +++ b/os/hal/templates/i2c_lld.h @@ -56,7 +56,8 @@ typedef void (*i2ccallback_t)(I2CDriver *i2cp, i2cstatus_t sts); /** * @brief Driver configuration structure. - * @note It could be empty on some architectures. + * @note Implementations may extend this structure to contain more, + * architecture dependent, fields. */ typedef struct { /** @brief I2C bus bit rate.*/ @@ -66,6 +67,8 @@ typedef struct { /** * @brief Structure representing an I2C driver. + * @note Implementations may extend this structure to contain more, + * architecture dependent, fields. */ typedef struct { /** @brief Driver state.*/ diff --git a/os/hal/templates/mac_lld.h b/os/hal/templates/mac_lld.h index 37b6d0ae9..ecd1b4339 100644 --- a/os/hal/templates/mac_lld.h +++ b/os/hal/templates/mac_lld.h @@ -69,6 +69,8 @@ /** * @brief Structure representing a MAC driver. + * @note Implementations may extend this structure to contain more, + * architecture dependent, fields. */ typedef struct { Semaphore md_tdsem; /**< Transmit semaphore. */ @@ -81,6 +83,8 @@ typedef struct { /** * @brief Structure representing a transmit descriptor. + * @note Implementations may extend this structure to contain more, + * architecture dependent, fields. */ typedef struct { size_t td_offset; /**< Current write offset. */ @@ -90,6 +94,8 @@ typedef struct { /** * @brief Structure representing a receive descriptor. + * @note Implementations may extend this structure to contain more, + * architecture dependent, fields. */ typedef struct { size_t rd_offset; /**< Current read offset. */ diff --git a/os/hal/templates/pal_lld.h b/os/hal/templates/pal_lld.h index b71b9d96e..dddc58e77 100644 --- a/os/hal/templates/pal_lld.h +++ b/os/hal/templates/pal_lld.h @@ -44,18 +44,12 @@ * system startup time in order to initialized the digital I/O * subsystem. This represents only the initial setup, specific pads * or whole ports can be reprogrammed at later time. - * @note This structure content is architecture dependent. The nome should - * be changed to include the architecture name following this - * pattern:
- * - [ARCH][CELL]Config. - * . - * As example:
- * - MSP430DIOConfig. - * . + * @note Implementations may extend this structure to contain more, + * architecture dependent, fields. */ typedef struct { -} GenericConfig; +} PALConfig; /** * @brief Width, in bits, of an I/O port. diff --git a/os/hal/templates/pwm_lld.h b/os/hal/templates/pwm_lld.h index 76a691a55..b74582d9d 100644 --- a/os/hal/templates/pwm_lld.h +++ b/os/hal/templates/pwm_lld.h @@ -63,6 +63,8 @@ typedef uint16_t pwmcnt_t; /** * @brief Driver configuration structure. + * @note Implementations may extend this structure to contain more, + * architecture dependent, fields. * @note It could be empty on some architectures. */ typedef struct { @@ -71,6 +73,8 @@ typedef struct { /** * @brief Structure representing an PWM driver. + * @note Implementations may extend this structure to contain more, + * architecture dependent, fields. */ typedef struct { /** diff --git a/os/hal/templates/serial_lld.h b/os/hal/templates/serial_lld.h index 2a2abb582..fe05d864b 100644 --- a/os/hal/templates/serial_lld.h +++ b/os/hal/templates/serial_lld.h @@ -55,9 +55,8 @@ typedef uint8_t sdflags_t; * @brief Generic Serial Driver configuration structure. * @details An instance of this structure must be passed to @p sdStart() * in order to configure and start a serial driver operations. - * @note This structure content is architecture dependent, each driver - * implementation defines its own version and the custom static - * initializers. + * @note Implementations may extend this structure to contain more, + * architecture dependent, fields. */ typedef struct { diff --git a/os/hal/templates/spi_lld.h b/os/hal/templates/spi_lld.h index 11409d9eb..67ca25b02 100644 --- a/os/hal/templates/spi_lld.h +++ b/os/hal/templates/spi_lld.h @@ -48,13 +48,17 @@ /** * @brief Driver configuration structure. + * @note Implementations may extend this structure to contain more, + * architecture dependent, fields. */ typedef struct { } SPIConfig; /** - * @brief Structure representing a SPI driver. + * @brief Structure representing an SPI driver. + * @note Implementations may extend this structure to contain more, + * architecture dependent, fields. */ typedef struct { /** diff --git a/os/hal/templates/uart_lld.h b/os/hal/templates/uart_lld.h index a1f9b9d38..ba55d723b 100644 --- a/os/hal/templates/uart_lld.h +++ b/os/hal/templates/uart_lld.h @@ -53,8 +53,10 @@ typedef uint32_t uartflags_t; /** * @brief Structure representing an UART driver. + * @note Implementations may extend this structure to contain more, + * architecture dependent, fields. */ -typedef struct _UARTDriver UARTDriver; +typedef struct UARTDriver UARTDriver; /** * @brief Generic UART notification callback type. @@ -81,7 +83,8 @@ typedef void (*uartecb_t)(UARTDriver *uartp, uartflags_t e); /** * @brief Driver configuration structure. - * @note It could be empty on some architectures. + * @note Implementations may extend this structure to contain more, + * architecture dependent, fields. */ typedef struct { /** @brief End of transmission buffer callback.*/ @@ -99,8 +102,10 @@ typedef struct { /** * @brief Structure representing an UART driver. + * @note Implementations may extend this structure to contain more, + * architecture dependent, fields. */ -struct _UARTDriver { +struct UARTDriver { /** * @brief Driver state. */ -- cgit v1.2.3