I2C driver state diagram modified, documentation improvements.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3751 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
parent
dcbb613f6d
commit
54c975bed0
|
@ -22,16 +22,7 @@
|
|||
* @defgroup I2C I2C Driver
|
||||
* @brief Generic I2C Driver.
|
||||
* @details This module implements a generic I2C (Inter-Integrated Circuit)
|
||||
* driver. On STM32 platform you can choose method of waiting START
|
||||
* and STOP bits: polling wait or wait using GPT. GPT method use
|
||||
* one timer per I2C interface, on the other hand -- polling is
|
||||
* block function that starts transfer.
|
||||
* @note If you decide to use polling wait -- do NOT start transmit or
|
||||
* receive from callback because it run in ISR context.
|
||||
* @note You must set I2C interrupts priority to highest level in the
|
||||
* system.
|
||||
* @note If you use GPT than set GPT interrupts priority level over I2C
|
||||
* interrupts priority level.
|
||||
* driver.
|
||||
* @pre In order to use the I2C driver the @p HAL_USE_I2C option
|
||||
* must be enabled in @p halconf.h.
|
||||
*
|
||||
|
@ -40,29 +31,69 @@
|
|||
* 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="false",
|
||||
|
||||
node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true",
|
||||
width="0.9", height="0.9"];
|
||||
edge [fontname=Helvetica, fontsize=8];
|
||||
|
||||
uninit [label="I2C_UNINIT", style="bold"];
|
||||
stop [label="I2C_STOP\nLow Power"];
|
||||
uninit [label="I2C_UNINIT", style="bold"];
|
||||
ready [label="I2C_READY\nClock Enabled"];
|
||||
active_tx [label="I2C_ACTIVE_TRANSMIT\nBus TX Active"];
|
||||
active_rx [label="I2C_ACTIVE_RECEIVE\nBus RX Active"];
|
||||
active_tx [label="I2C_ACTIVE_TX\nBus TX Active"];
|
||||
active_rx [label="I2C_ACTIVE_RX\nBus RX Active"];
|
||||
locked [label="I2C_LOCKED\nBus Locked"];
|
||||
|
||||
uninit -> stop [label="i2cInit()"];
|
||||
stop -> stop [label="i2cStop()"];
|
||||
stop -> ready [label="i2cStart()"];
|
||||
ready -> active_tx [label="i2cMasterTransmit()"];
|
||||
ready -> active_rx [label="i2cMasterReceive()"];
|
||||
active_tx -> ready [label="_i2c_isr_code()"];
|
||||
active_rx -> ready [label="_i2c_isr_code()"];
|
||||
ready -> stop [label="i2cStop()"];
|
||||
uninit -> stop [label="i2cInit()", constraint=false];
|
||||
stop -> stop [label="i2cStop()"];
|
||||
stop -> ready [label="i2cStart()"];
|
||||
ready -> ready [label="i2cStart()"];
|
||||
ready -> stop [label="i2cStop()"];
|
||||
ready -> active_tx [label="i2cMasterTransmit()"];
|
||||
ready -> active_rx [label="i2cMasterReceive()"];
|
||||
active_tx -> ready [label="completed"];
|
||||
active_rx -> ready [label="completed"];
|
||||
active_tx -> locked [label="RDY_TIMEOUT"];
|
||||
active_rx -> locked [label="RDY_TIMEOUT"];
|
||||
locked -> stop [label="i2cStop()"];
|
||||
locked -> ready [label="i2cStart()"];
|
||||
}
|
||||
* @else
|
||||
* @dot
|
||||
digraph example {
|
||||
rankdir="LR";
|
||||
|
||||
node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true",
|
||||
width="0.9", height="0.9"];
|
||||
edge [fontname=Helvetica, fontsize=8];
|
||||
|
||||
stop [label="I2C_STOP\nLow Power"];
|
||||
uninit [label="I2C_UNINIT", style="bold"];
|
||||
ready [label="I2C_READY\nClock Enabled"];
|
||||
active_tx [label="I2C_ACTIVE_TX\nBus TX Active"];
|
||||
active_rx [label="I2C_ACTIVE_RX\nBus RX Active"];
|
||||
locked [label="I2C_LOCKED\nBus Locked"];
|
||||
|
||||
uninit -> stop [label="i2cInit()", constraint=false];
|
||||
stop -> stop [label="i2cStop()"];
|
||||
stop -> ready [label="i2cStart()"];
|
||||
ready -> ready [label="i2cStart()"];
|
||||
ready -> stop [label="i2cStop()"];
|
||||
ready -> active_tx [label="i2cMasterTransmit()"];
|
||||
ready -> active_rx [label="i2cMasterReceive()"];
|
||||
active_tx -> ready [label="completed"];
|
||||
active_rx -> ready [label="completed"];
|
||||
active_tx -> locked [label="RDY_TIMEOUT"];
|
||||
active_rx -> locked [label="RDY_TIMEOUT"];
|
||||
locked -> stop [label="i2cStop()"];
|
||||
locked -> ready [label="i2cStart()"];
|
||||
}
|
||||
* @enddot
|
||||
* @endif
|
||||
* The driver is not thread safe for performance reasons, if you need to access
|
||||
* the I2C bus from multiple threads then use the @p i2cAcquireBus() and
|
||||
* @p i2cReleaseBus() APIs in order to gain exclusive access.
|
||||
|
|
|
@ -21,12 +21,8 @@
|
|||
/**
|
||||
* @defgroup RTC RTC Driver
|
||||
* @brief Real Time Clock Abstraction Layer
|
||||
* @details This module defines an abstract interface for Real Time Clock cell.
|
||||
* If you do not need callback functionality than disable
|
||||
* @p RTC_SUPPORTS_CALLBACKS option in @p halconf.h.
|
||||
* In @p halconf.h you also can select clock source for RTC in
|
||||
* @p RTC_CLOCK_SOURCE option.
|
||||
*
|
||||
* @details This module defines an abstract interface for a Real Time Clock
|
||||
* Peripheral.
|
||||
* @pre In order to use the RTC driver the @p HAL_USE_RTC option
|
||||
* must be enabled in @p halconf.h.
|
||||
*
|
||||
|
|
|
@ -37,7 +37,8 @@
|
|||
digraph example {
|
||||
size="5, 7";
|
||||
rankdir="LR";
|
||||
node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true", width="0.9", height="0.9"];
|
||||
node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true",
|
||||
width="0.9", height="0.9"];
|
||||
edge [fontname=Helvetica, fontsize=8];
|
||||
|
||||
stop [label="SPI_STOP\nLow Power"];
|
||||
|
@ -57,6 +58,7 @@
|
|||
complete -> active [label="\nspiStartXXXI() (async)\nthen\ncallback return"];
|
||||
complete -> ready [label="\ncallback return"];
|
||||
}
|
||||
* @enddot
|
||||
* @else
|
||||
* @dot
|
||||
digraph example {
|
||||
|
|
|
@ -89,8 +89,9 @@ typedef enum {
|
|||
I2C_UNINIT = 0, /**< Not initialized. */
|
||||
I2C_STOP = 1, /**< Stopped. */
|
||||
I2C_READY = 2, /**< Ready. */
|
||||
I2C_ACTIVE_TRANSMIT = 3, /**< Transmitting. */
|
||||
I2C_ACTIVE_RECEIVE = 4, /**< Receiving. */
|
||||
I2C_ACTIVE_TX = 3, /**< Transmitting. */
|
||||
I2C_ACTIVE_RX = 4, /**< Receiving. */
|
||||
I2C_LOCKED = 5 /**> Bus or driver locked. */
|
||||
} i2cstate_t;
|
||||
|
||||
#include "i2c_lld.h"
|
||||
|
|
|
@ -101,7 +101,8 @@ void i2cObjectInit(I2CDriver *i2cp) {
|
|||
void i2cStart(I2CDriver *i2cp, const I2CConfig *config) {
|
||||
|
||||
chDbgCheck((i2cp != NULL) && (config != NULL), "i2cStart");
|
||||
chDbgAssert((i2cp->state == I2C_STOP) || (i2cp->state == I2C_READY),
|
||||
chDbgAssert((i2cp->state == I2C_STOP) || (i2cp->state == I2C_READY) ||
|
||||
(i2cp->state == I2C_LOCKED),
|
||||
"i2cStart(), #1",
|
||||
"invalid state");
|
||||
|
||||
|
@ -122,7 +123,8 @@ void i2cStart(I2CDriver *i2cp, const I2CConfig *config) {
|
|||
void i2cStop(I2CDriver *i2cp) {
|
||||
|
||||
chDbgCheck(i2cp != NULL, "i2cStop");
|
||||
chDbgAssert((i2cp->state == I2C_STOP) || (i2cp->state == I2C_READY),
|
||||
chDbgAssert((i2cp->state == I2C_STOP) || (i2cp->state == I2C_READY) ||
|
||||
(i2cp->state == I2C_LOCKED),
|
||||
"i2cStop(), #1",
|
||||
"invalid state");
|
||||
|
||||
|
@ -193,10 +195,13 @@ msg_t i2cMasterTransmitTimeout(I2CDriver *i2cp,
|
|||
|
||||
chSysLock();
|
||||
i2cp->errors = I2CD_NO_ERROR;
|
||||
i2cp->state = I2C_ACTIVE_TRANSMIT;
|
||||
i2cp->state = I2C_ACTIVE_TX;
|
||||
rdymsg = i2c_lld_master_transmit_timeout(i2cp, addr, txbuf, txbytes,
|
||||
rxbuf, rxbytes, timeout);
|
||||
i2cp->state = I2C_READY;
|
||||
if (rdymsg == RDY_TIMEOUT)
|
||||
i2cp->state = I2C_LOCKED;
|
||||
else
|
||||
i2cp->state = I2C_READY;
|
||||
chSysUnlock();
|
||||
return rdymsg;
|
||||
}
|
||||
|
@ -239,9 +244,12 @@ msg_t i2cMasterReceiveTimeout(I2CDriver *i2cp,
|
|||
|
||||
chSysLock();
|
||||
i2cp->errors = I2CD_NO_ERROR;
|
||||
i2cp->state = I2C_ACTIVE_RECEIVE;
|
||||
i2cp->state = I2C_ACTIVE_RX;
|
||||
rdymsg = i2c_lld_master_receive_timeout(i2cp, addr, rxbuf, rxbytes, timeout);
|
||||
i2cp->state = I2C_READY;
|
||||
if (rdymsg == RDY_TIMEOUT)
|
||||
i2cp->state = I2C_LOCKED;
|
||||
else
|
||||
i2cp->state = I2C_READY;
|
||||
chSysUnlock();
|
||||
return rdymsg;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue