More SPI-related code in XHAL.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@16286 27425a3e-05d8-49a3-a47f-9c15f0e5edd8
This commit is contained in:
parent
a6e31ca42c
commit
e79ef9f801
|
@ -17,8 +17,6 @@
|
|||
<define name="HAL_DRV_STATE_STARTING" value="3U" />
|
||||
<define name="HAL_DRV_STATE_READY" value="4U" />
|
||||
<define name="HAL_DRV_STATE_ACTIVE" value="5U" />
|
||||
<define name="HAL_DRV_STATE_COMPLETE" value="6U" />
|
||||
<define name="HAL_DRV_STATE_ERROR" value="7U" />
|
||||
</group>
|
||||
</definitions_early>
|
||||
<configs>
|
||||
|
@ -66,6 +64,9 @@
|
|||
<field name="state" ctype="driver_state_t">
|
||||
<brief>Driver state.</brief>
|
||||
</field>
|
||||
<field name="config" ctype="const void$I*">
|
||||
<brief>Associated configuration structure.</brief>
|
||||
</field>
|
||||
<field name="arg" ctype="void$I*">
|
||||
<brief>Driver argument.</brief>
|
||||
</field>
|
||||
|
@ -91,6 +92,7 @@
|
|||
<implementation><![CDATA[
|
||||
self->state = HAL_DRV_STATE_STOP;
|
||||
self->arg = NULL;
|
||||
self->config = NULL;
|
||||
osalMutexObjectInit(&self->mutex);
|
||||
#if HAL_USE_REGISTRY == TRUE
|
||||
self->id = 0U;
|
||||
|
|
|
@ -7,6 +7,12 @@
|
|||
<import>hal_base_driver.xml</import>
|
||||
</imports>
|
||||
<public>
|
||||
<definitions_early>
|
||||
<group description="Callback-related driver states">
|
||||
<define name="HAL_DRV_STATE_COMPLETE" value="6U" />
|
||||
<define name="HAL_DRV_STATE_ERROR" value="7U" />
|
||||
</group>
|
||||
</definitions_early>
|
||||
<types>
|
||||
<typedef name="hal_cb_t">
|
||||
<brief>Generic HAL notification callback type.</brief>
|
||||
|
@ -29,22 +35,59 @@ self->cb = NULL;]]></implementation>
|
|||
<dispose>
|
||||
<implementation><![CDATA[ ]]></implementation>
|
||||
</dispose>
|
||||
<inline>
|
||||
<method name="drvSetCallback" ctype="void">
|
||||
<brief>Associates a callback to the driver instance.</brief>
|
||||
<virtual>
|
||||
<method name="drvSetCallback" ctype="void" shortname="setcb">
|
||||
<brief>
|
||||
Associates a callback to the driver instance.
|
||||
</brief>
|
||||
<param name="cb" ctype="hal_cb_t">
|
||||
Callback function to be associated. Passing @p NULL disables the
|
||||
existing callback, if any.</param>
|
||||
Callback function to be associated. Passing @p NULL
|
||||
disables the existing callback, if any.
|
||||
</param>
|
||||
<implementation><![CDATA[
|
||||
|
||||
self->cb = cb;]]></implementation>
|
||||
</method>
|
||||
</virtual>
|
||||
<inline>
|
||||
<method name="drvGetCallback" ctype="hal_cb_t">
|
||||
<brief>Returns the callback associated to the driver instance.</brief>
|
||||
<implementation><![CDATA[
|
||||
|
||||
return self->cb;]]></implementation>
|
||||
</method>
|
||||
<method name="drvStateIsCompleteI" ctype="bool">
|
||||
<brief>Checks for @p HAL_DRV_STATE_COMPLETE state.</brief>
|
||||
<details><![CDATA[The @p HAL_DRV_STATE_COMPLETE state is used by
|
||||
those drivers triggering multiple callbacks for a single
|
||||
asynchronous operation, it marks the last callback in the
|
||||
sequence.]]></details>
|
||||
<note><![CDATA[This function is meant to be called exclusively from
|
||||
the driver callback.]]></note>
|
||||
<return>The check result.</return>
|
||||
<retval value="false">If the current state is not @p HAL_DRV_STATE_COMPLETE.</retval>
|
||||
<retval value="true">If the current state is @p HAL_DRV_STATE_COMPLETE.</retval>
|
||||
<api />
|
||||
<implementation><![CDATA[
|
||||
|
||||
return (bool)(self->state == HAL_DRV_STATE_COMPLETE);]]></implementation>
|
||||
</method>
|
||||
<method name="drvStateIsErrorI" ctype="bool">
|
||||
<brief>Checks for @p HAL_DRV_STATE_ERROR state.</brief>
|
||||
<details><![CDATA[The @p HAL_DRV_STATE_ERROR state during a callback
|
||||
marks an error in an asynchronous operation, the operation is
|
||||
implicitly stopped and the driver is switched back to its
|
||||
@p HAL_DRV_STATE_READY state.]]></details>
|
||||
<note><![CDATA[This function is meant to be called exclusively from
|
||||
the driver callback.]]></note>
|
||||
<return>The check result.</return>
|
||||
<retval value="false">If the current state is not @p HAL_DRV_STATE_ERROR.</retval>
|
||||
<retval value="true">If the current state is @p HAL_DRV_STATE_ERROR.</retval>
|
||||
<api />
|
||||
<implementation><![CDATA[
|
||||
|
||||
return (bool)(self->state == HAL_DRV_STATE_ERROR);]]></implementation>
|
||||
</method>
|
||||
</inline>
|
||||
</methods>
|
||||
</class>
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="http://www.chibios.org/xml/schema/ccode/modules.xsd"
|
||||
name="hal_spi" descr="SPI Driver" check="HAL_USE_SPI == TRUE" editcode="false">
|
||||
name="hal_spi" descr="SPI Driver" check="HAL_USE_SPI == TRUE"
|
||||
editcode="false">
|
||||
<brief>SPI Driver macros and structures.</brief>
|
||||
<imports>
|
||||
<import>hal_cb_driver.xml</import>
|
||||
|
@ -31,7 +32,8 @@
|
|||
<brief>Support for thread synchronization API.</brief>
|
||||
<assert invalid="($N != FALSE) && ($N != TRUE)" />
|
||||
</config>
|
||||
<config name="SPI_SELECT_MODE" default="SPI_SELECT_MODE_PAD">
|
||||
<config name="SPI_SELECT_MODE"
|
||||
default="SPI_SELECT_MODE_PAD">
|
||||
<brief>Handling method for SPI CS line.</brief>
|
||||
<assert
|
||||
invalid="($N < SPI_SELECT_MODE_NONE) || ($N > SPI_SELECT_MODE_LLD)" />
|
||||
|
@ -53,7 +55,8 @@
|
|||
</typedef>
|
||||
<typedef name="SPIConfig">
|
||||
<brief>Type of structure representing a SPI configuration
|
||||
(legacy).</brief>
|
||||
(legacy).
|
||||
</brief>
|
||||
<basetype ctype="struct hal_spi_config" />
|
||||
</typedef>
|
||||
<typedef name="SPIDriver">
|
||||
|
@ -87,13 +90,15 @@
|
|||
<brief>Enables the slave mode.</brief>
|
||||
</field>
|
||||
</condition>
|
||||
<condition check="SPI_SELECT_MODE == SPI_SELECT_MODE_LINE">
|
||||
<condition
|
||||
check="SPI_SELECT_MODE == SPI_SELECT_MODE_LINE">
|
||||
<field name="ssline" ctype="ioline_t">
|
||||
<brief>The chip select line.</brief>
|
||||
<note>Only used in master mode.</note>
|
||||
</field>
|
||||
</condition>
|
||||
<condition check="SPI_SELECT_MODE == SPI_SELECT_MODE_PORT">
|
||||
<condition
|
||||
check="SPI_SELECT_MODE == SPI_SELECT_MODE_PORT">
|
||||
<field name="ssport" ctype="ioportid_t">
|
||||
<brief>The chip select port.</brief>
|
||||
<note>Only used in master mode.</note>
|
||||
|
@ -103,7 +108,8 @@
|
|||
<note>Only used in master mode.</note>
|
||||
</field>
|
||||
</condition>
|
||||
<condition check="SPI_SELECT_MODE == SPI_SELECT_MODE_PAD">
|
||||
<condition
|
||||
check="SPI_SELECT_MODE == SPI_SELECT_MODE_PAD">
|
||||
<field name="ssport" ctype="ioportid_t">
|
||||
<brief>The chip select port.</brief>
|
||||
<note>Only used in master mode.</note>
|
||||
|
@ -126,12 +132,18 @@ SPI_CONFIG_EXT_FIELDS]]></verbatim>
|
|||
ancestorname="hal_cb_driver" descr="SPI driver">
|
||||
<brief>Class of a SPI driver.</brief>
|
||||
<fields>
|
||||
<condition check="SPI_USE_SYNCHRONIZATION == TRUE">
|
||||
<field name="sync_transfer" ctype="thread_reference_t">
|
||||
<brief>Synchronization point for transfer.</brief>
|
||||
</field>
|
||||
</condition>
|
||||
<verbatim><![CDATA[
|
||||
#if defined(SPI_DRIVER_EXT_FIELS)
|
||||
SPI_DRIVER_EXT_FIELDS
|
||||
#endif
|
||||
/* End of the mandatory fields.*/
|
||||
spi_lld_driver_fields;]]></verbatim>
|
||||
|
||||
</fields>
|
||||
<methods>
|
||||
<objinit callsuper="true">
|
||||
|
@ -154,7 +166,8 @@ SPI_DRIVER_EXT_INIT_HOOK(self);
|
|||
<pre><![CDATA[A slave must have been selected using @p spiSelectX().]]></pre>
|
||||
<post><![CDATA[At the end of the operation the callback is invoked,
|
||||
if enabled.]]></post>
|
||||
<param name="n" ctype="size_t" dir="in">Number of frames to be
|
||||
<param name="n" ctype="size_t" dir="in">Number of frames
|
||||
to be
|
||||
ignored.
|
||||
</param>
|
||||
<return>The operation status.</return>
|
||||
|
@ -188,7 +201,8 @@ return msg;]]></implementation>
|
|||
<pre><![CDATA[A slave must have been selected using @p spiSelectX().]]></pre>
|
||||
<post><![CDATA[At the end of the operation the callback is invoked,
|
||||
if enabled.]]></post>
|
||||
<param name="n" ctype="size_t" dir="in">Number of frames to be
|
||||
<param name="n" ctype="size_t" dir="in">Number of frames
|
||||
to be
|
||||
ignored.
|
||||
</param>
|
||||
<return>The operation status.</return>
|
||||
|
@ -211,13 +225,16 @@ return msg;]]></implementation>
|
|||
if enabled.]]></post>
|
||||
<note><![CDATA[Buffers are organized as uint8_t arrays for frame
|
||||
sizes below or equal to 8 bits else uint16_t is used.]]></note>
|
||||
<param name="n" ctype="size_t" dir="in">Number of frames to be
|
||||
<param name="n" ctype="size_t" dir="in">Number of frames
|
||||
to be
|
||||
exchanged.
|
||||
</param>
|
||||
<param name="txbuf" ctype="const void *" dir="in">Pointer to the
|
||||
<param name="txbuf" ctype="const void *" dir="in">Pointer
|
||||
to the
|
||||
transmit buffer.
|
||||
</param>
|
||||
<param name="rxbuf" ctype="void *" dir="out">Pointer to the
|
||||
<param name="rxbuf" ctype="void *" dir="out">Pointer to
|
||||
the
|
||||
receive buffer.
|
||||
</param>
|
||||
<return>The operation status.</return>
|
||||
|
@ -253,13 +270,16 @@ return msg;]]></implementation>
|
|||
if enabled.]]></post>
|
||||
<note><![CDATA[Buffers are organized as uint8_t arrays for frame
|
||||
sizes below or equal to 8 bits else uint16_t is used.]]></note>
|
||||
<param name="n" ctype="size_t" dir="in">Number of frames to be
|
||||
<param name="n" ctype="size_t" dir="in">Number of frames
|
||||
to be
|
||||
exchanged.
|
||||
</param>
|
||||
<param name="txbuf" ctype="const void *" dir="in">Pointer to the
|
||||
<param name="txbuf" ctype="const void *" dir="in">Pointer
|
||||
to the
|
||||
transmit buffer.
|
||||
</param>
|
||||
<param name="rxbuf" ctype="void *" dir="out">Pointer to the
|
||||
<param name="rxbuf" ctype="void *" dir="out">Pointer to
|
||||
the
|
||||
receive buffer.
|
||||
</param>
|
||||
<return>The operation status.</return>
|
||||
|
@ -282,10 +302,12 @@ return msg;]]></implementation>
|
|||
if enabled.]]></post>
|
||||
<note><![CDATA[Buffers are organized as uint8_t arrays for frame
|
||||
sizes below or equal to 8 bits else uint16_t is used.]]></note>
|
||||
<param name="n" ctype="size_t" dir="in">Number of frames to be
|
||||
<param name="n" ctype="size_t" dir="in">Number of frames
|
||||
to be
|
||||
exchanged.
|
||||
</param>
|
||||
<param name="txbuf" ctype="const void *" dir="in">Pointer to the
|
||||
<param name="txbuf" ctype="const void *" dir="in">Pointer
|
||||
to the
|
||||
transmit buffer.
|
||||
</param>
|
||||
<return>The operation status.</return>
|
||||
|
@ -320,10 +342,12 @@ return msg;]]></implementation>
|
|||
if enabled.]]></post>
|
||||
<note><![CDATA[Buffers are organized as uint8_t arrays for frame
|
||||
sizes below or equal to 8 bits else uint16_t is used.]]></note>
|
||||
<param name="n" ctype="size_t" dir="in">Number of frames to be
|
||||
<param name="n" ctype="size_t" dir="in">Number of frames
|
||||
to be
|
||||
exchanged.
|
||||
</param>
|
||||
<param name="txbuf" ctype="const void *" dir="in">Pointer to the
|
||||
<param name="txbuf" ctype="const void *" dir="in">Pointer
|
||||
to the
|
||||
transmit buffer.
|
||||
</param>
|
||||
<return>The operation status.</return>
|
||||
|
@ -346,10 +370,12 @@ return msg;]]></implementation>
|
|||
if enabled.]]></post>
|
||||
<note><![CDATA[Buffers are organized as uint8_t arrays for frame
|
||||
sizes below or equal to 8 bits else uint16_t is used.]]></note>
|
||||
<param name="n" ctype="size_t" dir="in">Number of frames to be
|
||||
<param name="n" ctype="size_t" dir="in">Number of frames
|
||||
to be
|
||||
exchanged.
|
||||
</param>
|
||||
<param name="rxbuf" ctype="void *" dir="out">Pointer to the
|
||||
<param name="rxbuf" ctype="void *" dir="out">Pointer to
|
||||
the
|
||||
receive buffer.
|
||||
</param>
|
||||
<return>The operation status.</return>
|
||||
|
@ -384,10 +410,12 @@ return msg;]]></implementation>
|
|||
if enabled.]]></post>
|
||||
<note><![CDATA[Buffers are organized as uint8_t arrays for frame
|
||||
sizes below or equal to 8 bits else uint16_t is used.]]></note>
|
||||
<param name="n" ctype="size_t" dir="in">Number of frames to be
|
||||
<param name="n" ctype="size_t" dir="in">Number of frames
|
||||
to be
|
||||
exchanged.
|
||||
</param>
|
||||
<param name="rxbuf" ctype="void *" dir="out">Pointer to the
|
||||
<param name="rxbuf" ctype="void *" dir="out">Pointer to
|
||||
the
|
||||
receive buffer.
|
||||
</param>
|
||||
<return>The operation status.</return>
|
||||
|
@ -403,7 +431,8 @@ return msg;]]></implementation>
|
|||
</method>
|
||||
<method name="spiStopTransferI" ctype="msg_t">
|
||||
<brief>Stops the ongoing SPI operation.</brief>
|
||||
<param name="np" ctype="size_t *" dir="out">Pointer to the counter
|
||||
<param name="np" ctype="size_t *" dir="out">Pointer to the
|
||||
counter
|
||||
of frames not yet transferred or @p NULL.
|
||||
</param>
|
||||
<return>The operation status.</return>
|
||||
|
@ -439,7 +468,8 @@ return msg;]]></implementation>
|
|||
</method>
|
||||
<method name="spiStopTransfer" ctype="msg_t">
|
||||
<brief>Stops the ongoing SPI operation.</brief>
|
||||
<param name="np" ctype="size_t *" dir="out">Pointer to the counter
|
||||
<param name="np" ctype="size_t *" dir="out">Pointer to the
|
||||
counter
|
||||
of frames not yet transferred or @p NULL.
|
||||
</param>
|
||||
<return>The operation status.</return>
|
||||
|
@ -459,14 +489,18 @@ return msg;]]></implementation>
|
|||
<condition check="SPI_USE_SYNCHRONIZATION == TRUE">
|
||||
<method name="spiSynchronizeS" ctype="msg_t">
|
||||
<note><![CDATA[This function can only be called by a single thread at time.]]></note>
|
||||
<param name="timeout" ctype="sysinterval_t" dir="in">Synchronization
|
||||
<param name="timeout" ctype="sysinterval_t"
|
||||
dir="in">Synchronization
|
||||
timeout.
|
||||
</param>
|
||||
<return>The synchronization result.</return>
|
||||
<retval value="MSG_OK">If operation completed without errors.
|
||||
<retval value="MSG_OK">If operation completed without
|
||||
errors.
|
||||
</retval>
|
||||
<retval value="MSG_TIMEOUT">If synchronization timed out.
|
||||
</retval>
|
||||
<retval value="MSG_RESET">If the transfer has been stopped.
|
||||
</retval>
|
||||
<retval value="MSG_TIMEOUT">If synchronization timed out.</retval>
|
||||
<retval value="MSG_RESET">If the transfer has been stopped.</retval>
|
||||
<sclass />
|
||||
<implementation><![CDATA[
|
||||
msg_t msg;
|
||||
|
@ -487,14 +521,18 @@ return msg;]]></implementation>
|
|||
</method>
|
||||
<method name="spiSynchronize" ctype="msg_t">
|
||||
<note><![CDATA[This function can only be called by a single thread at time.]]></note>
|
||||
<param name="timeout" ctype="sysinterval_t" dir="in">Synchronization
|
||||
<param name="timeout" ctype="sysinterval_t"
|
||||
dir="in">Synchronization
|
||||
timeout.
|
||||
</param>
|
||||
<return>The synchronization result.</return>
|
||||
<retval value="MSG_OK">If operation completed without errors.
|
||||
<retval value="MSG_OK">If operation completed without
|
||||
errors.
|
||||
</retval>
|
||||
<retval value="MSG_TIMEOUT">If synchronization timed out.
|
||||
</retval>
|
||||
<retval value="MSG_RESET">If the transfer has been stopped.
|
||||
</retval>
|
||||
<retval value="MSG_TIMEOUT">If synchronization timed out.</retval>
|
||||
<retval value="MSG_RESET">If the transfer has been stopped.</retval>
|
||||
<api />
|
||||
<implementation><![CDATA[
|
||||
msg_t msg;
|
||||
|
@ -511,14 +549,18 @@ return msg;]]></implementation>
|
|||
of a series of idle words on the SPI bus and ignores the received
|
||||
data.]]></details>
|
||||
<pre><![CDATA[A slave must have been selected using @p spiSelectX().]]></pre>
|
||||
<param name="n" ctype="size_t" dir="in">Number of frames to be
|
||||
<param name="n" ctype="size_t" dir="in">Number of
|
||||
frames to be
|
||||
ignored.
|
||||
</param>
|
||||
<return>The operation status.</return>
|
||||
<retval value="MSG_OK">If operation completed without errors.
|
||||
<retval value="MSG_OK">If operation completed without
|
||||
errors.
|
||||
</retval>
|
||||
<retval value="MSG_TIMEOUT">If synchronization timed out.
|
||||
</retval>
|
||||
<retval value="MSG_RESET">If the transfer has been stopped.
|
||||
</retval>
|
||||
<retval value="MSG_TIMEOUT">If synchronization timed out.</retval>
|
||||
<retval value="MSG_RESET">If the transfer has been stopped.</retval>
|
||||
<api />
|
||||
<implementation><![CDATA[
|
||||
msg_t msg;
|
||||
|
@ -541,21 +583,27 @@ return msg;]]></implementation>
|
|||
<pre><![CDATA[A slave must have been selected using @p spiSelectX().]]></pre>
|
||||
<note><![CDATA[Buffers are organized as uint8_t arrays for frame
|
||||
sizes below or equal to 8 bits else uint16_t is used.]]></note>
|
||||
<param name="n" ctype="size_t" dir="in">Number of frames to be
|
||||
<param name="n" ctype="size_t" dir="in">Number of
|
||||
frames to be
|
||||
exchanged.
|
||||
</param>
|
||||
<param name="txbuf" ctype="const void *" dir="in">Pointer to
|
||||
<param name="txbuf" ctype="const void *" dir="in">Pointer
|
||||
to
|
||||
the
|
||||
transmit buffer.
|
||||
</param>
|
||||
<param name="rxbuf" ctype="void *" dir="out">Pointer to the
|
||||
<param name="rxbuf" ctype="void *" dir="out">Pointer to
|
||||
the
|
||||
receive buffer.
|
||||
</param>
|
||||
<return>The operation status.</return>
|
||||
<retval value="MSG_OK">If operation completed without errors.
|
||||
<retval value="MSG_OK">If operation completed without
|
||||
errors.
|
||||
</retval>
|
||||
<retval value="MSG_TIMEOUT">If synchronization timed out.
|
||||
</retval>
|
||||
<retval value="MSG_RESET">If the transfer has been stopped.
|
||||
</retval>
|
||||
<retval value="MSG_TIMEOUT">If synchronization timed out.</retval>
|
||||
<retval value="MSG_RESET">If the transfer has been stopped.</retval>
|
||||
<api />
|
||||
<implementation><![CDATA[
|
||||
msg_t msg;
|
||||
|
@ -578,18 +626,23 @@ return msg;]]></implementation>
|
|||
<pre><![CDATA[A slave must have been selected using @p spiSelectX().]]></pre>
|
||||
<note><![CDATA[Buffers are organized as uint8_t arrays for frame
|
||||
sizes below or equal to 8 bits else uint16_t is used.]]></note>
|
||||
<param name="n" ctype="size_t" dir="in">Number of frames to be
|
||||
<param name="n" ctype="size_t" dir="in">Number of
|
||||
frames to be
|
||||
exchanged.
|
||||
</param>
|
||||
<param name="txbuf" ctype="const void *" dir="in">Pointer to
|
||||
<param name="txbuf" ctype="const void *" dir="in">Pointer
|
||||
to
|
||||
the
|
||||
transmit buffer.
|
||||
</param>
|
||||
<return>The operation status.</return>
|
||||
<retval value="MSG_OK">If operation completed without errors.
|
||||
<retval value="MSG_OK">If operation completed without
|
||||
errors.
|
||||
</retval>
|
||||
<retval value="MSG_TIMEOUT">If synchronization timed out.
|
||||
</retval>
|
||||
<retval value="MSG_RESET">If the transfer has been stopped.
|
||||
</retval>
|
||||
<retval value="MSG_TIMEOUT">If synchronization timed out.</retval>
|
||||
<retval value="MSG_RESET">If the transfer has been stopped.</retval>
|
||||
<api />
|
||||
<implementation><![CDATA[
|
||||
msg_t msg;
|
||||
|
@ -610,17 +663,22 @@ return msg;]]></implementation>
|
|||
<pre><![CDATA[A slave must have been selected using @p spiSelectX().]]></pre>
|
||||
<note><![CDATA[Buffers are organized as uint8_t arrays for frame
|
||||
sizes below or equal to 8 bits else uint16_t is used.]]></note>
|
||||
<param name="n" ctype="size_t" dir="in">Number of frames to be
|
||||
<param name="n" ctype="size_t" dir="in">Number of
|
||||
frames to be
|
||||
exchanged.
|
||||
</param>
|
||||
<param name="rxbuf" ctype="void *" dir="out">Pointer to the
|
||||
<param name="rxbuf" ctype="void *" dir="out">Pointer to
|
||||
the
|
||||
receive buffer.
|
||||
</param>
|
||||
<return>The operation status.</return>
|
||||
<retval value="MSG_OK">If operation completed without errors.
|
||||
<retval value="MSG_OK">If operation completed without
|
||||
errors.
|
||||
</retval>
|
||||
<retval value="MSG_TIMEOUT">If synchronization timed out.
|
||||
</retval>
|
||||
<retval value="MSG_RESET">If the transfer has been stopped.
|
||||
</retval>
|
||||
<retval value="MSG_TIMEOUT">If synchronization timed out.</retval>
|
||||
<retval value="MSG_RESET">If the transfer has been stopped.</retval>
|
||||
<api />
|
||||
<implementation><![CDATA[
|
||||
msg_t msg;
|
||||
|
@ -637,10 +695,12 @@ return msg;]]></implementation>
|
|||
</condition>
|
||||
</regular>
|
||||
<inline>
|
||||
<condition check="SPI_SELECT_MODE == SPI_SELECT_MODE_LLD">
|
||||
<condition
|
||||
check="SPI_SELECT_MODE == SPI_SELECT_MODE_LLD">
|
||||
<method name="spiSelectX" ctype="void">
|
||||
<brief>Asserts the slave select signal and prepares for
|
||||
transfers.</brief>
|
||||
transfers.
|
||||
</brief>
|
||||
<xclass />
|
||||
<implementation><![CDATA[
|
||||
|
||||
|
@ -653,7 +713,8 @@ spi_lld_select(self);]]></implementation>
|
|||
|
||||
spi_lld_unselect(self);]]></implementation>
|
||||
</method>
|
||||
<elseif check="SPI_SELECT_MODE == SPI_SELECT_MODE_LINE" />
|
||||
<elseif
|
||||
check="SPI_SELECT_MODE == SPI_SELECT_MODE_LINE" />
|
||||
<method name="spiSelectX" ctype="void">
|
||||
<implementation><![CDATA[
|
||||
|
||||
|
@ -664,7 +725,8 @@ palClearLine(self->config->ssline);]]></implementation>
|
|||
|
||||
palSetLine(self->config->ssline);]]></implementation>
|
||||
</method>
|
||||
<elseif check="SPI_SELECT_MODE == SPI_SELECT_MODE_PORT" />
|
||||
<elseif
|
||||
check="SPI_SELECT_MODE == SPI_SELECT_MODE_PORT" />
|
||||
<method name="spiSelectX" ctype="void">
|
||||
<implementation><![CDATA[
|
||||
|
||||
|
@ -675,7 +737,8 @@ palClearPort(self->config->ssport, self->config->ssmask);]]></implementation>
|
|||
|
||||
palSetPort(self->config->ssport, self->config->ssmask);]]></implementation>
|
||||
</method>
|
||||
<elseif check="SPI_SELECT_MODE == SPI_SELECT_MODE_PAD" />
|
||||
<elseif
|
||||
check="SPI_SELECT_MODE == SPI_SELECT_MODE_PAD" />
|
||||
<method name="spiSelectX" ctype="void">
|
||||
<implementation><![CDATA[
|
||||
|
||||
|
@ -687,17 +750,90 @@ palClearPad(self->config->ssport, self->config->sspad);]]></implementation>
|
|||
palSetPad(self->config->ssport, self->config->sspad);]]></implementation>
|
||||
</method>
|
||||
</condition>
|
||||
<condition check="SPI_USE_SYNCHRONIZATION == TRUE">
|
||||
<method name="__spi_wakeup_isr" ctype="void">
|
||||
<brief>Wakes up the waiting thread.</brief>
|
||||
<note>This function is meant to be used in the low level
|
||||
drivers implementations only.
|
||||
</note>
|
||||
<param name="msg" ctype="msg_t" dir="in">The wakeup
|
||||
message.
|
||||
</param>
|
||||
<notapi />
|
||||
<implementation><![CDATA[
|
||||
|
||||
osalSysLockFromISR();
|
||||
osalThreadResumeI(&self->sync_transfer, MSG_OK);
|
||||
osalSysUnlockFromISR();]]></implementation>
|
||||
</method>
|
||||
<elseif />
|
||||
<method name="__spi_wakeup_isr" ctype="void">
|
||||
<param name="msg" ctype="msg_t" dir="in" />
|
||||
<implementation><![CDATA[
|
||||
|
||||
(void)self;]]></implementation>
|
||||
</method>
|
||||
</condition>
|
||||
<method name="__spi_isr_complete_code" ctype="void">
|
||||
<brief>Common ISR code in linear mode.</brief>
|
||||
<details><verbatim><![CDATA[
|
||||
This code handles the portable part of the ISR code:
|
||||
- Callback invocation.
|
||||
- Waiting thread wakeup, if any.
|
||||
- Driver state transitions.
|
||||
.
|
||||
]]></verbatim></details>
|
||||
<note>This function is meant to be used in the low level
|
||||
drivers implementations only.
|
||||
</note>
|
||||
<notapi />
|
||||
<implementation><![CDATA[
|
||||
if (self->config->data_cb) {
|
||||
self->state = HAL_DRV_STATE_COMPLETE;
|
||||
self->config->data_cb(spip);
|
||||
if (self->state == HAL_DRV_STATE_COMPLETE)
|
||||
self->state = HAL_DRV_STATE_READY;
|
||||
}
|
||||
else {
|
||||
self->state = HAL_DRV_STATE_READY;
|
||||
}
|
||||
|
||||
#if SPI_USE_SYNCHRONIZATION == TRUE
|
||||
/* Thread wakeup, if any.*/
|
||||
osalSysLockFromISR();
|
||||
osalThreadResumeI(&self->sync_transfer, MSG_OK);
|
||||
osalSysUnlockFromISR();
|
||||
#endif]]></implementation>
|
||||
</method>
|
||||
</inline>
|
||||
<override>
|
||||
<method shortname="start">
|
||||
<implementation><![CDATA[]]></implementation>
|
||||
</method>
|
||||
<method shortname="stop">
|
||||
<implementation><![CDATA[]]></implementation>
|
||||
</method>
|
||||
<method shortname="configure">
|
||||
<implementation><![CDATA[
|
||||
|
||||
self->config = config;]]></implementation>
|
||||
</method>
|
||||
<method shortname="setcb">
|
||||
<implementation><![CDATA[
|
||||
|
||||
__cbdrv_setcb_impl(self);
|
||||
|
||||
spi_lld_setcb(self, cb);]]></implementation>
|
||||
</method>
|
||||
</override>
|
||||
</methods>
|
||||
</class>
|
||||
</types>
|
||||
<functions>
|
||||
<function name="spiInit" ctype="void">
|
||||
<brief>SPI Driver initialization.</brief>
|
||||
<note>
|
||||
This function is implicitly invoked by @p halInit(), there is no
|
||||
need to explicitly initialize the driver.
|
||||
</note>
|
||||
<note><![CDATA[This function is implicitly invoked by @p halInit(),
|
||||
there is no need to explicitly initialize the driver.]]></note>
|
||||
<init />
|
||||
<implementation><![CDATA[
|
||||
|
||||
|
|
|
@ -43,8 +43,6 @@
|
|||
#define HAL_DRV_STATE_STARTING 3U
|
||||
#define HAL_DRV_STATE_READY 4U
|
||||
#define HAL_DRV_STATE_ACTIVE 5U
|
||||
#define HAL_DRV_STATE_COMPLETE 6U
|
||||
#define HAL_DRV_STATE_ERROR 7U
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
|
@ -161,6 +159,10 @@ struct hal_base_driver {
|
|||
* @brief Driver state.
|
||||
*/
|
||||
driver_state_t state;
|
||||
/**
|
||||
* @brief Associated configuration structure.
|
||||
*/
|
||||
const void *config;
|
||||
/**
|
||||
* @brief Driver argument.
|
||||
*/
|
||||
|
|
|
@ -90,6 +90,10 @@ struct hal_buffered_serial {
|
|||
* @brief Driver state.
|
||||
*/
|
||||
driver_state_t state;
|
||||
/**
|
||||
* @brief Associated configuration structure.
|
||||
*/
|
||||
const void *config;
|
||||
/**
|
||||
* @brief Driver argument.
|
||||
*/
|
||||
|
|
|
@ -31,6 +31,14 @@
|
|||
/* Module constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name Callback-related driver states
|
||||
* @{
|
||||
*/
|
||||
#define HAL_DRV_STATE_COMPLETE 6U
|
||||
#define HAL_DRV_STATE_ERROR 7U
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
@ -78,6 +86,7 @@ struct hal_cb_driver_vmt {
|
|||
void (*stop)(void *ip);
|
||||
msg_t (*configure)(void *ip, const void *config);
|
||||
/* From hal_cb_driver_c.*/
|
||||
void (*setcb)(void *ip, hal_cb_t cb);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -92,6 +101,10 @@ struct hal_cb_driver {
|
|||
* @brief Driver state.
|
||||
*/
|
||||
driver_state_t state;
|
||||
/**
|
||||
* @brief Associated configuration structure.
|
||||
*/
|
||||
const void *config;
|
||||
/**
|
||||
* @brief Driver argument.
|
||||
*/
|
||||
|
@ -134,6 +147,7 @@ extern "C" {
|
|||
/* Methods of hal_cb_driver_c.*/
|
||||
void *__cbdrv_objinit_impl(void *ip, const void *vmt);
|
||||
void __cbdrv_dispose_impl(void *ip);
|
||||
void __cbdrv_setcb_impl(void *ip, hal_cb_t cb);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -143,7 +157,7 @@ extern "C" {
|
|||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name Inline methods of hal_cb_driver_c
|
||||
* @name Virtual methods of hal_cb_driver_c
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
|
@ -160,9 +174,14 @@ CC_FORCE_INLINE
|
|||
static inline void drvSetCallback(void *ip, hal_cb_t cb) {
|
||||
hal_cb_driver_c *self = (hal_cb_driver_c *)ip;
|
||||
|
||||
self->cb = cb;
|
||||
self->vmt->setcb(ip, cb);
|
||||
}
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Inline methods of hal_cb_driver_c
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @memberof hal_cb_driver_c
|
||||
* @public
|
||||
|
@ -177,6 +196,60 @@ static inline hal_cb_t drvGetCallback(void *ip) {
|
|||
|
||||
return self->cb;
|
||||
}
|
||||
|
||||
/**
|
||||
* @memberof hal_cb_driver_c
|
||||
* @public
|
||||
*
|
||||
* @brief Checks for @p HAL_DRV_STATE_COMPLETE state.
|
||||
* @details The @p HAL_DRV_STATE_COMPLETE state is used by those drivers
|
||||
* triggering multiple callbacks for a single asynchronous
|
||||
* operation, it marks the last callback in the sequence.
|
||||
* @note This function is meant to be called exclusively from the driver
|
||||
* callback.
|
||||
*
|
||||
* @param[in,out] ip Pointer to a @p hal_cb_driver_c instance.
|
||||
* @return The check result.
|
||||
* @retval false If the current state is not @p
|
||||
* HAL_DRV_STATE_COMPLETE.
|
||||
* @retval true If the current state is @p
|
||||
* HAL_DRV_STATE_COMPLETE.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
CC_FORCE_INLINE
|
||||
static inline bool drvStateIsCompleteI(void *ip) {
|
||||
hal_cb_driver_c *self = (hal_cb_driver_c *)ip;
|
||||
|
||||
return (bool)(self->state == HAL_DRV_STATE_COMPLETE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @memberof hal_cb_driver_c
|
||||
* @public
|
||||
*
|
||||
* @brief Checks for @p HAL_DRV_STATE_ERROR state.
|
||||
* @details The @p HAL_DRV_STATE_ERROR state during a callback marks an
|
||||
* error in an asynchronous operation, the operation is implicitly
|
||||
* stopped and the driver is switched back to its @p
|
||||
* HAL_DRV_STATE_READY state.
|
||||
* @note This function is meant to be called exclusively from the driver
|
||||
* callback.
|
||||
*
|
||||
* @param[in,out] ip Pointer to a @p hal_cb_driver_c instance.
|
||||
* @return The check result.
|
||||
* @retval false If the current state is not @p
|
||||
* HAL_DRV_STATE_ERROR.
|
||||
* @retval true If the current state is @p HAL_DRV_STATE_ERROR.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
CC_FORCE_INLINE
|
||||
static inline bool drvStateIsErrorI(void *ip) {
|
||||
hal_cb_driver_c *self = (hal_cb_driver_c *)ip;
|
||||
|
||||
return (bool)(self->state == HAL_DRV_STATE_ERROR);
|
||||
}
|
||||
/** @} */
|
||||
|
||||
#endif /* HAL_CB_DRIVER_H */
|
||||
|
|
|
@ -565,6 +565,10 @@ struct hal_sio_driver {
|
|||
* @brief Driver state.
|
||||
*/
|
||||
driver_state_t state;
|
||||
/**
|
||||
* @brief Associated configuration structure.
|
||||
*/
|
||||
const void *config;
|
||||
/**
|
||||
* @brief Driver argument.
|
||||
*/
|
||||
|
@ -672,6 +676,10 @@ struct hal_buffered_sio {
|
|||
* @brief Driver state.
|
||||
*/
|
||||
driver_state_t state;
|
||||
/**
|
||||
* @brief Associated configuration structure.
|
||||
*/
|
||||
const void *config;
|
||||
/**
|
||||
* @brief Driver argument.
|
||||
*/
|
||||
|
|
|
@ -225,6 +225,7 @@ struct hal_spi_driver_vmt {
|
|||
void (*stop)(void *ip);
|
||||
msg_t (*configure)(void *ip, const void *config);
|
||||
/* From hal_cb_driver_c.*/
|
||||
void (*setcb)(void *ip, hal_cb_t cb);
|
||||
/* From hal_spi_driver_c.*/
|
||||
};
|
||||
|
||||
|
@ -240,6 +241,10 @@ struct hal_spi_driver {
|
|||
* @brief Driver state.
|
||||
*/
|
||||
driver_state_t state;
|
||||
/**
|
||||
* @brief Associated configuration structure.
|
||||
*/
|
||||
const void *config;
|
||||
/**
|
||||
* @brief Driver argument.
|
||||
*/
|
||||
|
@ -269,6 +274,12 @@ struct hal_spi_driver {
|
|||
* @note Can be @p NULL.
|
||||
*/
|
||||
hal_cb_t cb;
|
||||
#if (SPI_USE_SYNCHRONIZATION == TRUE) || defined (__DOXYGEN__)
|
||||
/**
|
||||
* @brief Synchronization point for transfer.
|
||||
*/
|
||||
thread_reference_t sync_transfer;
|
||||
#endif /* SPI_USE_SYNCHRONIZATION == TRUE */
|
||||
#if defined(SPI_DRIVER_EXT_FIELS)
|
||||
SPI_DRIVER_EXT_FIELDS
|
||||
#endif
|
||||
|
@ -287,6 +298,10 @@ extern "C" {
|
|||
/* Methods of hal_spi_driver_c.*/
|
||||
void *__spi_objinit_impl(void *ip, const void *vmt);
|
||||
void __spi_dispose_impl(void *ip);
|
||||
msg_t __spi_start_impl(void *ip);
|
||||
void __spi_stop_impl(void *ip);
|
||||
msg_t __spi_configure_impl(void *ip, const void *config);
|
||||
void __spi_setcb_impl(void *ip, hal_cb_t cb);
|
||||
msg_t spiStartIgnoreI(void *ip, size_t n);
|
||||
msg_t spiStartIgnore(void *ip, size_t n);
|
||||
msg_t spiStartExchangeI(void *ip, size_t n, const void *txbuf, void *rxbuf);
|
||||
|
@ -422,6 +437,74 @@ static inline void spiUnselectX(void *ip) {
|
|||
palSetPad(self->config->ssport, self->config->sspad);
|
||||
}
|
||||
#endif /* SPI_SELECT_MODE == SPI_SELECT_MODE_LLD */
|
||||
#if (SPI_USE_SYNCHRONIZATION == TRUE) || defined (__DOXYGEN__)
|
||||
/**
|
||||
* @memberof hal_spi_driver_c
|
||||
* @public
|
||||
*
|
||||
* @brief Wakes up the waiting thread.
|
||||
* @note This function is meant to be used in the low level drivers
|
||||
* implementations only.
|
||||
*
|
||||
* @param[in,out] ip Pointer to a @p hal_spi_driver_c instance.
|
||||
* @param[in] msg The wakeup message.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
CC_FORCE_INLINE
|
||||
static inline void __spi_wakeup_isr(void *ip, msg_t msg) {
|
||||
hal_spi_driver_c *self = (hal_spi_driver_c *)ip;
|
||||
|
||||
osalSysLockFromISR();
|
||||
osalThreadResumeI(&self->sync_transfer, MSG_OK);
|
||||
osalSysUnlockFromISR();
|
||||
}
|
||||
|
||||
#else
|
||||
CC_FORCE_INLINE
|
||||
static inline void __spi_wakeup_isr(void *ip, msg_t msg) {
|
||||
hal_spi_driver_c *self = (hal_spi_driver_c *)ip;
|
||||
|
||||
(void)self;
|
||||
}
|
||||
#endif /* SPI_USE_SYNCHRONIZATION == TRUE */
|
||||
/**
|
||||
* @memberof hal_spi_driver_c
|
||||
* @public
|
||||
*
|
||||
* @brief Common ISR code in linear mode.
|
||||
* This code handles the portable part of the ISR code:
|
||||
* - Callback invocation.
|
||||
* - Waiting thread wakeup, if any.
|
||||
* - Driver state transitions.
|
||||
* .
|
||||
* @note This function is meant to be used in the low level drivers
|
||||
* implementations only.
|
||||
*
|
||||
* @param[in,out] ip Pointer to a @p hal_spi_driver_c instance.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
CC_FORCE_INLINE
|
||||
static inline void __spi_isr_complete_code(void *ip) {
|
||||
hal_spi_driver_c *self = (hal_spi_driver_c *)ip;
|
||||
if (self->config->data_cb) {
|
||||
self->state = HAL_DRV_STATE_COMPLETE;
|
||||
self->config->data_cb(spip);
|
||||
if (self->state == HAL_DRV_STATE_COMPLETE)
|
||||
self->state = HAL_DRV_STATE_READY;
|
||||
}
|
||||
else {
|
||||
self->state = HAL_DRV_STATE_READY;
|
||||
}
|
||||
|
||||
#if SPI_USE_SYNCHRONIZATION == TRUE
|
||||
/* Thread wakeup, if any.*/
|
||||
osalSysLockFromISR();
|
||||
osalThreadResumeI(&self->sync_transfer, MSG_OK);
|
||||
osalSysUnlockFromISR();
|
||||
#endif
|
||||
}
|
||||
/** @} */
|
||||
|
||||
#endif /* HAL_USE_SPI == TRUE */
|
||||
|
|
|
@ -220,6 +220,7 @@ void *__drv_objinit_impl(void *ip, const void *vmt) {
|
|||
/* Initialization code.*/
|
||||
self->state = HAL_DRV_STATE_STOP;
|
||||
self->arg = NULL;
|
||||
self->config = NULL;
|
||||
osalMutexObjectInit(&self->mutex);
|
||||
#if HAL_USE_REGISTRY == TRUE
|
||||
self->id = 0U;
|
||||
|
|
|
@ -104,6 +104,23 @@ void __cbdrv_dispose_impl(void *ip) {
|
|||
/* Finalization of the ancestors-defined parts.*/
|
||||
__drv_dispose_impl(self);
|
||||
}
|
||||
|
||||
/**
|
||||
* @memberof hal_cb_driver_c
|
||||
* @protected
|
||||
*
|
||||
* @brief Implementation of method @p drvSetCallback().
|
||||
* @note This function is meant to be used by derived classes.
|
||||
*
|
||||
* @param[in,out] ip Pointer to a @p hal_cb_driver_c instance.
|
||||
* @param cb Callback function to be associated. Passing @p
|
||||
* NULL disables the existing callback, if any.
|
||||
*/
|
||||
void __cbdrv_setcb_impl(void *ip, hal_cb_t cb) {
|
||||
hal_cb_driver_c *self = (hal_cb_driver_c *)ip;
|
||||
|
||||
self->cb = cb;
|
||||
}
|
||||
/** @} */
|
||||
|
||||
/** @} */
|
||||
|
|
|
@ -122,6 +122,64 @@ void __spi_dispose_impl(void *ip) {
|
|||
/* Finalization of the ancestors-defined parts.*/
|
||||
__cbdrv_dispose_impl(self);
|
||||
}
|
||||
|
||||
/**
|
||||
* @memberof hal_spi_driver_c
|
||||
* @protected
|
||||
*
|
||||
* @brief Override of method @p __drv_start().
|
||||
*
|
||||
* @param[in,out] ip Pointer to a @p hal_spi_driver_c instance.
|
||||
* @return The operation status.
|
||||
*/
|
||||
msg_t __spi_start_impl(void *ip) {
|
||||
hal_spi_driver_c *self = (hal_spi_driver_c *)ip;
|
||||
}
|
||||
|
||||
/**
|
||||
* @memberof hal_spi_driver_c
|
||||
* @protected
|
||||
*
|
||||
* @brief Override of method @p __drv_stop().
|
||||
*
|
||||
* @param[in,out] ip Pointer to a @p hal_spi_driver_c instance.
|
||||
*/
|
||||
void __spi_stop_impl(void *ip) {
|
||||
hal_spi_driver_c *self = (hal_spi_driver_c *)ip;
|
||||
}
|
||||
|
||||
/**
|
||||
* @memberof hal_spi_driver_c
|
||||
* @protected
|
||||
*
|
||||
* @brief Override of method @p drvConfigureX().
|
||||
*
|
||||
* @param[in,out] ip Pointer to a @p hal_spi_driver_c instance.
|
||||
* @param[in] config New driver configuration.
|
||||
*/
|
||||
msg_t __spi_configure_impl(void *ip, const void *config) {
|
||||
hal_spi_driver_c *self = (hal_spi_driver_c *)ip;
|
||||
|
||||
self->config = config;
|
||||
}
|
||||
|
||||
/**
|
||||
* @memberof hal_spi_driver_c
|
||||
* @protected
|
||||
*
|
||||
* @brief Override of method @p drvSetCallback().
|
||||
*
|
||||
* @param[in,out] ip Pointer to a @p hal_spi_driver_c instance.
|
||||
* @param cb Callback function to be associated. Passing @p
|
||||
* NULL disables the existing callback, if any.
|
||||
*/
|
||||
void __spi_setcb_impl(void *ip, hal_cb_t cb) {
|
||||
hal_spi_driver_c *self = (hal_spi_driver_c *)ip;
|
||||
|
||||
__cbdrv_setcb_impl(self);
|
||||
|
||||
spi_lld_setcb(self, cb);
|
||||
}
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
|
@ -130,9 +188,10 @@ void __spi_dispose_impl(void *ip) {
|
|||
*/
|
||||
const struct hal_spi_driver_vmt __hal_spi_driver_vmt = {
|
||||
.dispose = __spi_dispose_impl,
|
||||
.start = NULL /* Method not found.*/,
|
||||
.stop = NULL /* Method not found.*/,
|
||||
.configure = NULL /* Method not found.*/
|
||||
.start = __spi_start_impl,
|
||||
.stop = __spi_stop_impl,
|
||||
.configure = __spi_configure_impl,
|
||||
.setcb = __spi_setcb_impl
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue