git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2167 35acf78f-673a-0410-8e92-d51de3d6d3f4

This commit is contained in:
gdisirio 2010-09-07 13:37:22 +00:00
parent beb42840f6
commit 18b825ef0c
13 changed files with 478 additions and 260 deletions

View File

@ -21,22 +21,25 @@
* @defgroup IO HAL * @defgroup IO HAL
* @brief Hardware Abstraction Layer. * @brief Hardware Abstraction Layer.
* @details Under ChibiOS/RT the set of the various device driver interfaces * @details Under ChibiOS/RT the set of the various device driver interfaces
* is called the HAL subsystem: Hardware Abstraction Layer.<br> * 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: * A device driver is usually split in two layers:
* - High Level Device Driver (<b>HLD</b>). This layer contains the definitions * - High Level Device Driver (<b>HLD</b>). This layer contains the definitions
* of the driver's APIs and the platform independent part of the driver.<br> * of the driver's APIs and the platform independent part of the driver.<br>
* An HLD is composed by two files: * An HLD is composed by two files:
* - @<driver@>.c, the HLD implementation file. This file must be * - @p @<driver@>.c, the HLD implementation file. This file must be
* included in the Makefile in order to use the driver. * included in the Makefile in order to use the driver.
* - @<driver@>.h, the HLD header file. This file is implicitly * - @p @<driver@>.h, the HLD header file. This file is implicitly
* included by the HAL header file @p hal.h. * included by the HAL header file @p hal.h.
* . * .
* - Low Level Device Driver (<b>LLD</b>). This layer contains the platform * - Low Level Device Driver (<b>LLD</b>). This layer contains the platform
* dependent part of the driver.<br> * dependent part of the driver.<br>
* A LLD is composed by two files: * A LLD is composed by two files:
* - @<driver@>_lld.c, the LLD implementation file. This file must be * - @p @<driver@>_lld.c, the LLD implementation file. This file must be
* included in the Makefile in order to use the driver. * included in the Makefile in order to use the driver.
* - @<driver@>_lld.h, the LLD header file. This file is implicitly * - @p @<driver@>_lld.h, the LLD header file. This file is implicitly
* included by the HLD header file. * included by the HLD header file.
* . * .
* The LLD may be not present in those drivers that do not access the * 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 * @ref MMC_SPI driver uses the @ref SPI and @ref PAL drivers in order
* to implement its functionalities. * to implement its functionalities.
* . * .
* <h2>Available Device Drivers</h2> * @subsection hal_device_driver_diagram Diagram
* The I/O subsystem currently includes support for: * @dot
* - @ref HAL. digraph example {
* - @ref PAL. node [shape=rectangle, fontname=Helvetica, fontsize=8,
* - @ref SERIAL. fixedsize="true", width="2.0", height="0.4"];
* - @ref ADC. edge [fontname=Helvetica, fontsize=8];
* - @ref CAN. app [label="Application"];
* - @ref MAC. hld [label="High Level Driver"];
* - @ref MMC_SPI. lld [label="Low Level Driver"];
* - @ref SPI. 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 * @defgroup HAL HAL Driver
* @brief Hardware Abstraction Layer. * @brief Hardware Abstraction Layer.
* @details The HAL driver performs the system initialization and includes * @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 * @ingroup IO
*/ */
@ -73,13 +98,6 @@
* @ingroup HAL * @ingroup HAL
*/ */
/**
* @defgroup HAL_CONF Configuration
* @brief @ref HAL Configuration.
*
* @ingroup HAL
*/
/** /**
* @defgroup PAL PAL Driver * @defgroup PAL PAL Driver
* @brief I/O Ports Abstraction Layer * @brief I/O Ports Abstraction Layer
@ -96,11 +114,11 @@
* interfaces would not be portable. Such interfaces shall be marked with * interfaces would not be portable. Such interfaces shall be marked with
* the architecture name inside the function names. * the architecture name inside the function names.
* *
* <h2>Implementation Rules</h2> * @section pal_1 Implementation Rules
* In implementing an @ref PAL_LLD there are some rules/behaviors that * In implementing an @ref PAL_LLD there are some rules/behaviors that
* should be respected. * should be respected.
* *
* <h3>Writing on input pads</h3> * @subsection pal_1_1 Writing on input pads
* The behavior is not specified but there are implementations better than * The behavior is not specified but there are implementations better than
* others, this is the list of possible implementations, preferred options * others, this is the list of possible implementations, preferred options
* are on top: * are on top:
@ -111,7 +129,7 @@
* pull up/down resistors or changing the pad direction. This scenario is * pull up/down resistors or changing the pad direction. This scenario is
* discouraged, please try to avoid this scenario. * discouraged, please try to avoid this scenario.
* . * .
* <h3>Reading from output pads</h3> * @subsection pal_1_2 Reading from output pads
* The behavior is not specified but there are implementations better than * The behavior is not specified but there are implementations better than
* others, this is the list of possible implementations, preferred options * others, this is the list of possible implementations, preferred options
* are on top: * are on top:
@ -119,27 +137,24 @@
* -# The output latch value is read (regardless of the actual pads states). * -# The output latch value is read (regardless of the actual pads states).
* -# Unspecified, please try to avoid this scenario. * -# Unspecified, please try to avoid this scenario.
* . * .
* <h3>Writing unused or unimplemented port bits</h3> * @subsection pal_1_3 Writing unused or unimplemented port bits
* The behavior is not specified. * The behavior is not specified.
* *
* <h3>Reading from unused or unimplemented port bits</h3> * @subsection pal_1_4 Reading from unused or unimplemented port bits
* The behavior is not specified. * The behavior is not specified.
* *
* <h3>Reading or writing on pins associated to other functionalities</h3> * @subsection pal_1_5 Reading or writing on pins associated to other functionalities
* The behavior is not specified. * The behavior is not specified.
* *
* <h2>Usage</h2>
* 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 * @ingroup IO
*/ */
/** /**
* @defgroup PAL_LLD PAL Low Level Driver * @defgroup PAL_LLD PAL Low Level Driver
* @brief @ref PAL low level driver template. * @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 * @ingroup PAL
*/ */
@ -161,7 +176,9 @@
/** /**
* @defgroup SERIAL_LLD Serial Low Level Driver * @defgroup SERIAL_LLD Serial Low Level Driver
* @brief @ref SERIAL low level driver template. * @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 * @ingroup SERIAL
*/ */
@ -169,30 +186,16 @@
/** /**
* @defgroup I2C I2C Driver * @defgroup I2C I2C Driver
* @brief Generic I2C Driver. * @brief Generic I2C Driver.
* @details This module implements a generic I2C driver. The driver implements * @details This module implements a generic I2C driver.
* a state machine internally: *
* @dot * @section i2c_1 Driver State Machine
digraph example { * The driver implements a state machine internally, not all the driver
rankdir="LR"; * functionalities can be used in any moment, any transition not explicitly
node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true", width="0.8", height="0.8"]; * shown in the following diagram has to be considered an error and shall
edge [fontname=Helvetica, fontsize=8]; * be captured by an assertion (if enabled).
uninit [label="SPI_UNINIT", style="bold"]; * @if LATEX_PDF
stop [label="SPI_STOP\nLow Power"]; * @else
ready [label="SPI_READY\nClock Enabled"]; * @endif
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
* *
* The driver is not thread safe for performance reasons, if you need to access * 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 * the I2C bus from multiple thread then use the @p i2cAcquireBus() and
@ -204,7 +207,9 @@
/** /**
* @defgroup I2C_LLD I2C Low Level Driver * @defgroup I2C_LLD I2C Low Level Driver
* @brief @ref I2C low level driver template. * @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 * @ingroup I2C
*/ */
@ -212,30 +217,60 @@
/** /**
* @defgroup SPI SPI Driver * @defgroup SPI SPI Driver
* @brief Generic SPI Driver. * @brief Generic SPI Driver.
* @details This module implements a generic SPI driver. The driver implements * @details This module implements a generic SPI driver.
* a state machine internally: *
* @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 * @dot
digraph example { digraph example {
rankdir="LR"; size="5, 7";
node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true", width="0.8", height="0.8"]; rankdir="LR";
edge [fontname=Helvetica, fontsize=8]; node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true", width="0.8", height="0.8"];
uninit [label="SPI_UNINIT", style="bold"]; edge [fontname=Helvetica, fontsize=8];
stop [label="SPI_STOP\nLow Power"]; uninit [label="SPI_UNINIT", style="bold"];
ready [label="SPI_READY\nClock Enabled"]; stop [label="SPI_STOP\nLow Power"];
active [label="SPI_ACTIVE\nBus Active"]; ready [label="SPI_READY\nClock Enabled"];
uninit -> stop [label="spiInit()"]; active [label="SPI_ACTIVE\nBus Active"];
stop -> ready [label="spiStart()"]; uninit -> stop [label="spiInit()"];
ready -> ready [label="spiStart()"]; stop -> ready [label="spiStart()"];
ready -> ready [label="spiIgnore()"]; ready -> ready [label="spiStart()"];
ready -> stop [label="spiStop()"]; ready -> ready [label="spiIgnore()"];
stop -> stop [label="spiStop()"]; ready -> stop [label="spiStop()"];
ready -> active [label="spiSelect()"]; stop -> stop [label="spiStop()"];
active -> active [label="spiSelect()"]; ready -> active [label="spiSelect()"];
active -> ready [label="spiUnselect()"]; active -> active [label="spiSelect()"];
ready -> ready [label="spiUnselect()"]; active -> ready [label="spiUnselect()"];
active -> active [label="spiIgnore()\nspiExchange()\nspiSend()\nspiReceive()"]; 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()"];
} }
* @enddot * @enddot
* @endif
* *
* The driver is not thread safe for performance reasons, if you need to access * 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 * the SPI bus from multiple thread then use the @p spiAcquireBus() and
@ -247,7 +282,9 @@
/** /**
* @defgroup SPI_LLD SPI Low Level Driver * @defgroup SPI_LLD SPI Low Level Driver
* @brief @ref SPI low level driver template. * @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 * @ingroup SPI
*/ */
@ -255,33 +292,67 @@
/** /**
* @defgroup ADC ADC Driver * @defgroup ADC ADC Driver
* @brief Generic ADC Driver. * @brief Generic ADC Driver.
* @details This module implements a generic ADC driver. The driver implements * @details This module implements a generic ADC driver.
* a state machine internally: *
* @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 * @dot
digraph example { digraph example {
rankdir="LR"; size="5, 7";
node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true", width="0.8", height="0.8"]; rankdir="LR";
edge [fontname=Helvetica, fontsize=8]; node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true", width="0.8", height="0.8"];
uninit [label="ADC_UNINIT", style="bold"]; edge [fontname=Helvetica, fontsize=8];
stop [label="ADC_STOP\nLow Power"]; stop [label="ADC_STOP\nLow Power"];
ready [label="ADC_READY\nClock Enabled"]; uninit [label="ADC_UNINIT", style="bold"];
running [label="ADC_RUNNING"]; ready [label="ADC_READY\nClock Enabled"];
complete [label="ADC_COMPLETE"]; running [label="ADC_RUNNING"];
uninit -> stop [label="adcInit()"]; complete [label="ADC_COMPLETE"];
stop -> ready [label="adcStart()"]; uninit -> stop [label="adcInit()", constraint=false];
ready -> ready [label="adcStart()"]; stop -> ready [label="adcStart()"];
ready -> ready [label="adcWaitConversion()"]; ready -> ready [label="adcStart()"];
ready -> stop [label="adcStop()"]; ready -> ready [label="adcWaitConversion()"];
stop -> stop [label="adcStop()"]; ready -> stop [label="adcStop()"];
ready -> running [label="adcStartConversion()"]; stop -> stop [label="adcStop()"];
running -> ready [label="adcStopConversion()"]; ready -> running [label="adcStartConversion()"];
running -> complete [label="End of Conversion"]; running -> ready [label="adcStopConversion()"];
complete -> running [label="adcStartConversion()"]; running -> complete [label="End of Conversion"];
complete -> ready [label="adcStopConversion()"]; complete -> running [label="adcStartConversion()"];
complete -> ready [label="adcWaitConversion()"]; complete -> ready [label="adcStopConversion()"];
complete -> stop [label="adcStop()"]; complete -> ready [label="adcWaitConversion()"];
complete -> stop [label="adcStop()"];
} }
* @enddot * @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, * The driver supports a continuous conversion mode with circular buffer,
* callback functions allow to process the converted data in real time. * callback functions allow to process the converted data in real time.
@ -293,7 +364,9 @@
/** /**
* @defgroup ADC_LLD ADC Low Level Driver * @defgroup ADC_LLD ADC Low Level Driver
* @brief @ref ADC low level driver template. * @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 * @ingroup ADC
*/ */
@ -301,29 +374,59 @@
/** /**
* @defgroup CAN CAN Driver * @defgroup CAN CAN Driver
* @brief Generic CAN Driver. * @brief Generic CAN Driver.
* @details This module implements a generic ADC driver. The driver implements * @details This module implements a generic ADC driver.
* a state machine internally: *
* @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 * @dot
digraph example { digraph example {
rankdir="LR"; size="5, 7";
node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true", width="0.8", height="0.8"]; rankdir="LR";
edge [fontname=Helvetica, fontsize=8]; node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true", width="0.8", height="0.8"];
uninit [label="CAN_UNINIT", style="bold"]; edge [fontname=Helvetica, fontsize=8];
stop [label="CAN_STOP\nLow Power"]; uninit [label="CAN_UNINIT", style="bold"];
ready [label="CAN_READY\nClock Enabled"]; stop [label="CAN_STOP\nLow Power"];
sleep [label="CAN_SLEEP\nLow Power"]; ready [label="CAN_READY\nClock Enabled"];
uninit -> stop [label="canInit()"]; sleep [label="CAN_SLEEP\nLow Power"];
stop -> stop [label="canStop()"]; uninit -> stop [label="canInit()"];
stop -> ready [label="canStart()"]; stop -> stop [label="canStop()"];
ready -> stop [label="canStop()"]; stop -> ready [label="canStart()"];
ready -> ready [label="canReceive()\ncanTransmit()"]; ready -> stop [label="canStop()"];
ready -> ready [label="canStart()"]; ready -> ready [label="canReceive()\ncanTransmit()"];
ready -> sleep [label="canSleep()"]; ready -> ready [label="canStart()"];
sleep -> sleep [label="canSleep()"]; ready -> sleep [label="canSleep()"];
sleep -> ready [label="canWakeup()"]; sleep -> sleep [label="canSleep()"];
sleep -> ready [label="wakeup event"]; sleep -> ready [label="canWakeup()"];
sleep -> ready [label="wakeup event"];
} }
* @enddot * @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 * @ingroup IO
*/ */
@ -331,6 +434,9 @@
/** /**
* @defgroup CAN_LLD CAN Low Level Driver * @defgroup CAN_LLD CAN Low Level Driver
* @brief @ref CAN low level driver template. * @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 * @ingroup CAN
*/ */
@ -338,21 +444,26 @@
/** /**
* @defgroup PWM PWM Driver * @defgroup PWM PWM Driver
* @brief Generic PWM Driver. * @brief Generic PWM Driver.
* @details This module implements a generic PWM driver. The driver implements * @details This module implements a generic PWM driver.
* a state machine internally: *
* @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 * @dot
digraph example { digraph example {
rankdir="LR"; rankdir="LR";
node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true", width="0.8", height="0.8"]; node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true", width="0.8", height="0.8"];
edge [fontname=Helvetica, fontsize=8]; edge [fontname=Helvetica, fontsize=8];
uninit [label="PWM_UNINIT", style="bold"]; uninit [label="PWM_UNINIT", style="bold"];
stop [label="PWM_STOP\nLow Power"]; stop [label="PWM_STOP\nLow Power"];
ready [label="PWM_READY\nClock Enabled"]; ready [label="PWM_READY\nClock Enabled"];
uninit -> stop [label="pwmInit()"]; uninit -> stop [label="pwmInit()"];
stop -> stop [label="pwmStop()"]; stop -> stop [label="pwmStop()"];
stop -> ready [label="pwmStart()"]; stop -> ready [label="pwmStart()"];
ready -> stop [label="pwmStop()"]; ready -> stop [label="pwmStop()"];
ready -> ready [label="pwmEnableChannel()\npwmDisableChannel()"]; ready -> ready [label="pwmEnableChannel()\npwmDisableChannel()"];
} }
* @enddot * @enddot
* *
@ -362,6 +473,9 @@
/** /**
* @defgroup PWM_LLD PWM Low Level Driver * @defgroup PWM_LLD PWM Low Level Driver
* @brief @ref PWM low level driver template. * @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 * @ingroup PWM
*/ */
@ -378,7 +492,9 @@
/** /**
* @defgroup MAC_LLD MAC Low Level Driver * @defgroup MAC_LLD MAC Low Level Driver
* @brief @ref MAC low level driver template. * @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 * @ingroup MAC
*/ */
@ -387,48 +503,95 @@
* @defgroup MMC_SPI MMC over SPI Driver * @defgroup MMC_SPI MMC over SPI Driver
* @brief Generic MMC driver. * @brief Generic MMC driver.
* @details This module implements a portable MMC driver that uses a SPI * @details This module implements a portable MMC driver that uses a SPI
* driver as physical layer.<br> * driver as physical layer.
* The driver implements the following state machine: *
* @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 * @dot
digraph example { digraph example {
rankdir="LR"; size="5, 7";
node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true", width="0.8", height="0.8"]; rankdir="LR";
edge [fontname=Helvetica, fontsize=8]; node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true", width="0.8", height="0.8"];
edge [fontname=Helvetica, fontsize=8];
any [label="Any State"]; any [label="Any State"];
stop2 [label="MMC_STOP\nLow Power"]; stop2 [label="MMC_STOP\nLow Power"];
uninit [label="MMC_UNINIT", style="bold"]; uninit [label="MMC_UNINIT", style="bold"];
stop [label="MMC_STOP\nLow Power"]; stop [label="MMC_STOP\nLow Power"];
wait [label="MMC_WAIT\nWaiting Card"]; wait [label="MMC_WAIT\nWaiting Card"];
inserted [label="MMC_INSERTED\nCard Inserted"]; inserted [label="MMC_INSERTED\nCard Inserted"];
ready [label="MMC_READY\nCard Ready"]; ready [label="MMC_READY\nCard Ready"];
reading [label="MMC_READING\nReading"]; reading [label="MMC_READING\nReading"];
writing [label="MMC_WRITING\nWriting"]; writing [label="MMC_WRITING\nWriting"];
uninit -> stop [label="mmcInit()"]; uninit -> stop [label="mmcInit()"];
stop -> wait [label="mmcStart()", constraint=false]; stop -> wait [label="mmcStart()", constraint=false];
wait -> inserted [label="insertion (inserted event)"]; wait -> inserted [label="insertion (inserted event)"];
inserted -> inserted [label="mmcDisconnect()"]; inserted -> inserted [label="mmcDisconnect()"];
inserted -> ready [label="mmcConnect()"]; inserted -> ready [label="mmcConnect()"];
ready -> ready [label="mmcConnect()"]; ready -> ready [label="mmcConnect()"];
ready -> inserted [label="mmcDisconnect()"]; ready -> inserted [label="mmcDisconnect()"];
ready -> reading [label="mmcStartSequentialRead()"]; ready -> reading [label="mmcStartSequentialRead()"];
reading -> reading [label="mmcSequentialRead()"]; reading -> reading [label="mmcSequentialRead()"];
reading -> ready [label="mmcStopSequentialRead()"]; reading -> ready [label="mmcStopSequentialRead()"];
reading -> ready [label="read error"]; reading -> ready [label="read error"];
ready -> writing [label="mmcStartSequentialWrite()"]; ready -> writing [label="mmcStartSequentialWrite()"];
writing -> writing [label="mmcSequentialWrite()"]; writing -> writing [label="mmcSequentialWrite()"];
writing -> ready [label="mmcStopSequentialWrite()"]; writing -> ready [label="mmcStopSequentialWrite()"];
writing -> ready [label="write error"]; 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)"];
inserted -> wait [label="removal (removed event)"]; any -> stop2 [label="mmcStop()"];
ready -> wait [label="removal (removed event)"];
reading -> wait [label="removal (removed event)"];
writing -> wait [label="removal (removed event)"];
any -> stop2 [label="mmcStop()"];
} }
* @enddot * @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 * The MMC drivers currently supports only cards with capacity up to 2GB
* and does not implement CRC checking. Hot plugging and removal are supported * and does not implement CRC checking. Hot plugging and removal are supported
@ -441,78 +604,102 @@
/** /**
* @defgroup UART UART Driver * @defgroup UART UART Driver
* @brief Generic UART Driver. * @brief Generic UART Driver.
* @details This module implements a generic UART driver. The driver implements * @details This driver abstracts a generic UART peripheral, the API is
* a state machine internally: * 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.<br>
* 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 * @dot
digraph example { digraph example {
rankdir="LR"; rankdir="LR";
node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true", width="0.8", height="0.8"]; node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true", width="0.8", height="0.8"];
edge [fontname=Helvetica, fontsize=8]; edge [fontname=Helvetica, fontsize=8];
subgraph cluster_RECEIVER { uninit [label="UART_UNINIT", style="bold"];
rx_idle [label="RX_IDLE", style="bold"]; stop [label="UART_STOP\nLow Power"];
rx_active [label="RX_ACTIVE"]; ready [label="UART_READY\nClock Enabled"];
rx_complete [label="RX_COMPLETE"];
rx_fatal [label="Fatal Error", style="bold"];
rx_idle -> rx_idle [label="\nuartStopReceive()\n>uc_rxchar<\n>uc_rxerr<"]; uninit -> stop [label="\nuartInit()"];
rx_idle -> rx_active [label="\nuartStartReceive()"]; stop -> ready [label="\nuartStart()"];
ready -> ready [label="\nuartStart()"];
rx_active -> rx_complete [label="\nbuffer filled\n>uc_rxend<"]; ready -> stop [label="\nuartStop()"];
rx_active -> rx_idle [label="\nuartStopReceive()"]; stop -> stop [label="\nuartStop()"];
rx_active -> rx_active [label="\nreceive error\n>uc_rxerr<"]; }
rx_active -> rx_fatal [label="\nuartStartReceive()"]; * @enddot
rx_complete -> rx_active [label="\nuartStartReceiveI()\nthen\ncallback return"]; *
rx_complete -> rx_idle [label="\ncallback return"]; * @subsection uart_1_1 Transmitter sub State Machine
* The follow diagram describes the transmitter state machine, this diagram
color = blue; * is valid while the driver is in the @p UART_READY state. This state
label = "Receiver state machine (within driver state UART_READY)"; * machine is automatically reset to the @p TX_IDLE state each time the
} * driver enters the @p UART_READY state.
* @dot
subgraph cluster_TRANSMITTER { digraph example {
tx_idle [label="TX_IDLE", style="bold"]; rankdir="LR";
tx_active [label="TX_ACTIVE"]; node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true", width="0.8", height="0.8"];
tx_complete [label="TX_COMPLETE"]; edge [fontname=Helvetica, fontsize=8];
tx_fatal [label="Fatal Error", style="bold"];
tx_idle [label="TX_IDLE", style="bold"];
tx_idle -> tx_active [label="\nuartStartSend()"]; tx_active [label="TX_ACTIVE"];
tx_idle -> tx_idle [label="\nuartStopSend()\n>uc_txend2<"]; tx_complete [label="TX_COMPLETE"];
tx_active -> tx_complete [label="\nbuffer transmitted\n>uc_txend1<"]; tx_fatal [label="Fatal Error", style="bold"];
tx_active -> tx_idle [label="\nuartStopSend()"];
tx_active -> tx_fatal [label="\nuartStartSend()"]; tx_idle -> tx_active [label="\nuartStartSend()"];
tx_complete -> tx_active [label="\nuartStartSendI()\nthen\ncallback return"]; tx_idle -> tx_idle [label="\nuartStopSend()\n>uc_txend2<"];
tx_complete -> tx_idle [label="\ncallback return"]; tx_active -> tx_complete [label="\nbuffer transmitted\n>uc_txend1<"];
tx_active -> tx_idle [label="\nuartStopSend()"];
color = blue; tx_active -> tx_fatal [label="\nuartStartSend()"];
label = "Transmitter state machine (within driver state UART_READY)"; tx_complete -> tx_active [label="\nuartStartSendI()\nthen\ncallback return"];
} tx_complete -> tx_idle [label="\ncallback return"];
}
subgraph cluster_DRIVER { * @enddot
uninit [label="UART_UNINIT", style="bold"]; *
stop [label="UART_STOP\nLow Power"]; * @subsection uart_1_2 Receiver sub State Machine
ready [label="UART_READY\nClock Enabled"]; * The follow diagram describes the receiver state machine, this diagram
* is valid while the driver is in the @p UART_READY state. This state
uninit -> stop [label="\nuartInit()"]; * machine is automatically reset to the @p RX_IDLE state each time the
stop -> ready [label="\nuartStart()"]; * driver enters the @p UART_READY state.
ready -> ready [label="\nuartStart()"]; * @dot
ready -> stop [label="\nuartStop()"]; digraph example {
stop -> stop [label="\nuartStop()"]; rankdir="LR";
node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true", width="0.8", height="0.8"];
color = blue; edge [fontname=Helvetica, fontsize=8];
label = "Driver state machine";
} 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 * @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.<br>
* 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 * @ingroup IO
*/ */
@ -520,6 +707,9 @@
/** /**
* @defgroup UART_LLD UART Low Level Driver * @defgroup UART_LLD UART Low Level Driver
* @brief @ref UART low level driver template. * @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 * @ingroup UART
*/ */

View File

@ -99,7 +99,7 @@ typedef enum {
/** /**
* @brief Structure representing a serial driver. * @brief Structure representing a serial driver.
*/ */
typedef struct _SerialDriver SerialDriver; typedef struct SerialDriver SerialDriver;
#include "serial_lld.h" #include "serial_lld.h"
@ -123,7 +123,7 @@ struct SerialDriverVMT {
* @details This class extends @p BaseAsynchronousChannel by adding physical * @details This class extends @p BaseAsynchronousChannel by adding physical
* I/O queues. * I/O queues.
*/ */
struct _SerialDriver { struct SerialDriver {
/** @brief Virtual Methods Table.*/ /** @brief Virtual Methods Table.*/
const struct SerialDriverVMT *vmt; const struct SerialDriverVMT *vmt;
_serial_driver_data _serial_driver_data

View File

@ -168,7 +168,7 @@ typedef uint32_t uartflags_t;
/** /**
* @brief Structure representing an UART driver. * @brief Structure representing an UART driver.
*/ */
typedef struct _UARTDriver UARTDriver; typedef struct UARTDriver UARTDriver;
/** /**
* @brief Generic UART notification callback type. * @brief Generic UART notification callback type.
@ -222,7 +222,7 @@ typedef struct {
/** /**
* @brief Structure representing an UART driver. * @brief Structure representing an UART driver.
*/ */
struct _UARTDriver { struct UARTDriver {
/** @brief Driver state.*/ /** @brief Driver state.*/
uartstate_t ud_state; uartstate_t ud_state;
/** @brief Current configuration data.*/ /** @brief Current configuration data.*/

View File

@ -72,6 +72,8 @@ typedef void (*adccallback_t)(adcsample_t *buffer, size_t n);
* @brief Conversion group configuration structure. * @brief Conversion group configuration structure.
* @details This implementation-dependent structure describes a conversion * @details This implementation-dependent structure describes a conversion
* operation. * operation.
* @note Implementations may extend this structure to contain more,
* architecture dependent, fields.
*/ */
typedef struct { typedef struct {
/** /**
@ -87,6 +89,8 @@ typedef struct {
/** /**
* @brief Driver configuration structure. * @brief Driver configuration structure.
* @note Implementations may extend this structure to contain more,
* architecture dependent, fields.
* @note It could be empty on some architectures. * @note It could be empty on some architectures.
*/ */
typedef struct { typedef struct {
@ -95,6 +99,8 @@ typedef struct {
/** /**
* @brief Structure representing an ADC driver. * @brief Structure representing an ADC driver.
* @note Implementations may extend this structure to contain more,
* architecture dependent, fields.
*/ */
typedef struct { typedef struct {
/** /**

View File

@ -130,6 +130,8 @@ typedef struct {
/** /**
* @brief CAN filter. * @brief CAN filter.
* @note Implementations may extend this structure to contain more,
* architecture dependent, fields.
* @note It could not be present on some architectures. * @note It could not be present on some architectures.
*/ */
typedef struct { typedef struct {
@ -137,6 +139,8 @@ typedef struct {
/** /**
* @brief Driver configuration structure. * @brief Driver configuration structure.
* @note Implementations may extend this structure to contain more,
* architecture dependent, fields.
* @note It could be empty on some architectures. * @note It could be empty on some architectures.
*/ */
typedef struct { typedef struct {
@ -144,6 +148,8 @@ typedef struct {
/** /**
* @brief Structure representing an CAN driver. * @brief Structure representing an CAN driver.
* @note Implementations may extend this structure to contain more,
* architecture dependent, fields.
*/ */
typedef struct { typedef struct {
/** /**

View File

@ -56,7 +56,8 @@ typedef void (*i2ccallback_t)(I2CDriver *i2cp, i2cstatus_t sts);
/** /**
* @brief Driver configuration structure. * @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 { typedef struct {
/** @brief I2C bus bit rate.*/ /** @brief I2C bus bit rate.*/
@ -66,6 +67,8 @@ typedef struct {
/** /**
* @brief Structure representing an I2C driver. * @brief Structure representing an I2C driver.
* @note Implementations may extend this structure to contain more,
* architecture dependent, fields.
*/ */
typedef struct { typedef struct {
/** @brief Driver state.*/ /** @brief Driver state.*/

View File

@ -69,6 +69,8 @@
/** /**
* @brief Structure representing a MAC driver. * @brief Structure representing a MAC driver.
* @note Implementations may extend this structure to contain more,
* architecture dependent, fields.
*/ */
typedef struct { typedef struct {
Semaphore md_tdsem; /**< Transmit semaphore. */ Semaphore md_tdsem; /**< Transmit semaphore. */
@ -81,6 +83,8 @@ typedef struct {
/** /**
* @brief Structure representing a transmit descriptor. * @brief Structure representing a transmit descriptor.
* @note Implementations may extend this structure to contain more,
* architecture dependent, fields.
*/ */
typedef struct { typedef struct {
size_t td_offset; /**< Current write offset. */ size_t td_offset; /**< Current write offset. */
@ -90,6 +94,8 @@ typedef struct {
/** /**
* @brief Structure representing a receive descriptor. * @brief Structure representing a receive descriptor.
* @note Implementations may extend this structure to contain more,
* architecture dependent, fields.
*/ */
typedef struct { typedef struct {
size_t rd_offset; /**< Current read offset. */ size_t rd_offset; /**< Current read offset. */

View File

@ -44,18 +44,12 @@
* system startup time in order to initialized the digital I/O * system startup time in order to initialized the digital I/O
* subsystem. This represents only the initial setup, specific pads * subsystem. This represents only the initial setup, specific pads
* or whole ports can be reprogrammed at later time. * or whole ports can be reprogrammed at later time.
* @note This structure content is architecture dependent. The nome should * @note Implementations may extend this structure to contain more,
* be changed to include the architecture name following this * architecture dependent, fields.
* pattern:<br>
* - [ARCH][CELL]Config.
* .
* As example:<br>
* - MSP430DIOConfig.
* .
*/ */
typedef struct { typedef struct {
} GenericConfig; } PALConfig;
/** /**
* @brief Width, in bits, of an I/O port. * @brief Width, in bits, of an I/O port.

View File

@ -63,6 +63,8 @@ typedef uint16_t pwmcnt_t;
/** /**
* @brief Driver configuration structure. * @brief Driver configuration structure.
* @note Implementations may extend this structure to contain more,
* architecture dependent, fields.
* @note It could be empty on some architectures. * @note It could be empty on some architectures.
*/ */
typedef struct { typedef struct {
@ -71,6 +73,8 @@ typedef struct {
/** /**
* @brief Structure representing an PWM driver. * @brief Structure representing an PWM driver.
* @note Implementations may extend this structure to contain more,
* architecture dependent, fields.
*/ */
typedef struct { typedef struct {
/** /**

View File

@ -55,9 +55,8 @@ typedef uint8_t sdflags_t;
* @brief Generic Serial Driver configuration structure. * @brief Generic Serial Driver configuration structure.
* @details An instance of this structure must be passed to @p sdStart() * @details An instance of this structure must be passed to @p sdStart()
* in order to configure and start a serial driver operations. * in order to configure and start a serial driver operations.
* @note This structure content is architecture dependent, each driver * @note Implementations may extend this structure to contain more,
* implementation defines its own version and the custom static * architecture dependent, fields.
* initializers.
*/ */
typedef struct { typedef struct {

View File

@ -48,13 +48,17 @@
/** /**
* @brief Driver configuration structure. * @brief Driver configuration structure.
* @note Implementations may extend this structure to contain more,
* architecture dependent, fields.
*/ */
typedef struct { typedef struct {
} SPIConfig; } 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 { typedef struct {
/** /**

View File

@ -53,8 +53,10 @@ typedef uint32_t uartflags_t;
/** /**
* @brief Structure representing an UART driver. * @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. * @brief Generic UART notification callback type.
@ -81,7 +83,8 @@ typedef void (*uartecb_t)(UARTDriver *uartp, uartflags_t e);
/** /**
* @brief Driver configuration structure. * @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 { typedef struct {
/** @brief End of transmission buffer callback.*/ /** @brief End of transmission buffer callback.*/
@ -99,8 +102,10 @@ typedef struct {
/** /**
* @brief Structure representing an UART driver. * @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. * @brief Driver state.
*/ */

View File

@ -119,7 +119,8 @@
the name in order to make names more consistent. the name in order to make names more consistent.
NOTE: ****** Make sure to use a chconf.h file taken from ****** NOTE: ****** Make sure to use a chconf.h file taken from ******
****** this version in your project. ****** ****** this version in your project. ******
- HAL documentation improvements.
*** 2.1.1 *** *** 2.1.1 ***
- FIX: Fixed insufficient stack size for idle thread (bug 3033624)(backported - FIX: Fixed insufficient stack size for idle thread (bug 3033624)(backported
to 2.0.3). to 2.0.3).