/* 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.
* 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 * included in the Makefile in order to use the driver. * - @.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 * included in the Makefile in order to use the driver. * - @_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. * . *

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. * . */ /** * @defgroup platforms Platforms * @brief Supported platforms. * @details The implementation of the device drivers can be sligthly different * on the various platforms because architectural constrains. This section * describes the implementation of the various device drivers on the various * supported platforms. * * @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. * * @ingroup IO */ /** * @defgroup HAL_LLD HAL Low Level Driver * @brief @ref HAL low level driver template. * * @ingroup HAL */ /** * @defgroup HAL_CONF Configuration * @brief @ref HAL Configuration. * * @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. * *

Implementation Rules

* In implementing an @ref PAL_LLD there are some rules/behaviors that * should be respected. * *

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. * . *

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. * . *

Writing unused or unimplemented port bits

* The behavior is not specified. * *

Reading from unused or unimplemented port bits

* The behavior is not specified. * *

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. * * @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. * * @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. * * @ingroup SERIAL */ /** * @defgroup SPI SPI Driver * @brief Generic SPI Driver. * @details This module implements a generic SPI 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 * * 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 * @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 a SPI low level driver. * * @ingroup SPI */ /** * @defgroup ADC ADC Driver * @brief Generic ADC Driver. * @details This module implements a generic ADC 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="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()"]; } * @enddot * * The driver supports a continuous conversion mode with circular buffer, * callback functions allow to process the converted data in real time. * Please refer to the documentation of the function @p adcStartConversion(). * * @ingroup IO */ /** * @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. * * @ingroup ADC */ /** * @defgroup CAN CAN Driver * @brief Generic CAN Driver. * @details This module implements a generic ADC 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="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 * * @ingroup IO */ /** * @defgroup CAN_LLD CAN Low Level Driver * @brief @ref CAN low level driver template. * * @ingroup CAN */ /** * @defgroup PWM PWM Driver * @brief Generic PWM Driver. * @details This module implements a generic PWM 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="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 * * @ingroup IO */ /** * @defgroup PWM_LLD PWM Low Level Driver * @brief @ref PWM low level driver template. * * @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. * * @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. * * @ingroup MAC */ /** * @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: * @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 * * The MMC drivers currently supports only cards with capacity up to 2GB * and does not implement CRC checking. Hot plugging and removal are supported * through kernel events. * * @ingroup IO */