904 lines
34 KiB
XML
904 lines
34 KiB
XML
<?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">
|
|
<brief>SPI Driver macros and structures.</brief>
|
|
<imports>
|
|
<import>hal_cb_driver.xml</import>
|
|
</imports>
|
|
<public>
|
|
<definitions_early>
|
|
<group description="SPI CS modes">
|
|
<define name="SPI_SELECT_MODE_NONE" value="0">
|
|
<brief>@p spiSelect() and @p spiUnselect() do nothing.</brief>
|
|
</define>
|
|
<define name="SPI_SELECT_MODE_PAD" value="1">
|
|
<brief>Selection by PAL port and pad number.</brief>
|
|
</define>
|
|
<define name="SPI_SELECT_MODE_PORT" value="2">
|
|
<brief>Selection by port and port mask.</brief>
|
|
</define>
|
|
<define name="SPI_SELECT_MODE_LINE" value="3">
|
|
<brief>Selection by PAL line identifier.</brief>
|
|
</define>
|
|
<define name="SPI_SELECT_MODE_LLD" value="4">
|
|
<brief>Selection by LLD-defined mode.</brief>
|
|
</define>
|
|
</group>
|
|
</definitions_early>
|
|
<configs>
|
|
<config name="SPI_USE_SYNCHRONIZATION" default="TRUE">
|
|
<brief>Support for thread synchronization API.</brief>
|
|
<assert invalid="($N != FALSE) && ($N != TRUE)" />
|
|
</config>
|
|
<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)" />
|
|
</config>
|
|
<verbatim><![CDATA[
|
|
/* Some modes have a dependency on the PAL driver, making the required
|
|
checks here.*/
|
|
#if ((SPI_SELECT_MODE != SPI_SELECT_MODE_PAD) || \
|
|
(SPI_SELECT_MODE != SPI_SELECT_MODE_PORT) || \
|
|
(SPI_SELECT_MODE != SPI_SELECT_MODE_LINE)) && \
|
|
(HAL_USE_PAL != TRUE)
|
|
#error "current SPI_SELECT_MODE requires HAL_USE_PAL"
|
|
#endif]]></verbatim>
|
|
</configs>
|
|
<macros>
|
|
<macro name="__spi_getconf">
|
|
<brief>Return a pointer to the configuration structure.</brief>
|
|
<param name="ip">Pointer to the @p hal_sio_driver_c object.</param>
|
|
<return>A pointer to the configuration structure.</return>
|
|
<notapi />
|
|
<implementation><![CDATA[((const hal_spi_config_t *)((ip)->config))]]></implementation>
|
|
</macro>
|
|
<macro name="__spi_getfield">
|
|
<brief>Retrieves a configuration field.</brief>
|
|
<param name="ip">Pointer to the @p hal_sio_driver_c object.</param>
|
|
<param name="field">Configuration field to be retrieved.</param>
|
|
<return>The field value.</return>
|
|
<notapi />
|
|
<implementation><![CDATA[(__spi_getconf(ip)->field)]]></implementation>
|
|
</macro>
|
|
</macros>
|
|
<types>
|
|
<typedef name="hal_spi_driver_c">
|
|
<brief>Type of structure representing a SPI driver.</brief>
|
|
<basetype ctype="struct hal_spi_driver" />
|
|
</typedef>
|
|
<typedef name="hal_spi_config_t">
|
|
<brief>Type of structure representing a SPI configuration.</brief>
|
|
<basetype ctype="struct hal_spi_config" />
|
|
</typedef>
|
|
<typedef name="SPIConfig">
|
|
<brief>Type of structure representing a SPI configuration
|
|
(legacy).</brief>
|
|
<basetype ctype="struct hal_spi_config" />
|
|
</typedef>
|
|
<typedef name="SPIDriver">
|
|
<brief>Type of structure representing a SPI driver (legacy).</brief>
|
|
<basetype ctype="struct hal_spi_driver" />
|
|
</typedef>
|
|
<verbatim><![CDATA[
|
|
/* Inclusion of LLD header.*/
|
|
#include "hal_spi_lld.h"
|
|
|
|
#if !defined(SPI_SUPPORTS_CIRCULAR)
|
|
#error "SPI_SUPPORTS_CIRCULAR not defined in SPI LLD driver"
|
|
#endif
|
|
|
|
#if !defined(SPI_SUPPORTS_SLAVE_MODE)
|
|
#error "SPI_SUPPORTS_SLAVE_MODE not defined in SPI LLD driver"
|
|
#endif]]></verbatim>
|
|
<struct name="hal_spi_config">
|
|
<brief>Driver configuration structure.</brief>
|
|
<note>Implementations may extend this structure to contain more,
|
|
architecture dependent, fields.
|
|
</note>
|
|
<fields>
|
|
<condition check="SPI_SUPPORTS_CIRCULAR == TRUE">
|
|
<field name="circular" ctype="bool">
|
|
<brief>Enables the circular buffer mode.</brief>
|
|
</field>
|
|
</condition>
|
|
<condition check="SPI_SUPPORTS_SLAVE_MODE == TRUE">
|
|
<field name="slave" ctype="bool">
|
|
<brief>Enables the slave mode.</brief>
|
|
</field>
|
|
</condition>
|
|
<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">
|
|
<field name="ssport" ctype="ioportid_t">
|
|
<brief>The chip select port.</brief>
|
|
<note>Only used in master mode.</note>
|
|
</field>
|
|
<field name="ssmask" ctype="ioportmask_t">
|
|
<brief>The chip select port mask.</brief>
|
|
<note>Only used in master mode.</note>
|
|
</field>
|
|
</condition>
|
|
<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>
|
|
</field>
|
|
<field name="sspad" ctype="ioportmask_t">
|
|
<brief>The chip select pad number.</brief>
|
|
<note>Only used in master mode.</note>
|
|
</field>
|
|
</condition>
|
|
<verbatim><![CDATA[
|
|
/* End of the mandatory fields.*/
|
|
spi_lld_config_fields;]]></verbatim>
|
|
<condition check="defined(SPI_CONFIG_EXT_FIELS)">
|
|
<verbatim><![CDATA[
|
|
SPI_CONFIG_EXT_FIELDS]]></verbatim>
|
|
</condition>
|
|
</fields>
|
|
</struct>
|
|
<class type="regular" name="hal_spi_driver" namespace="spi"
|
|
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">
|
|
<implementation><![CDATA[
|
|
|
|
/* Optional, user-defined initializer.*/
|
|
#if defined(SPI_DRIVER_EXT_INIT_HOOK)
|
|
SPI_DRIVER_EXT_INIT_HOOK(self);
|
|
#endif]]></implementation>
|
|
</objinit>
|
|
<dispose>
|
|
<implementation><![CDATA[ ]]></implementation>
|
|
</dispose>
|
|
<regular>
|
|
<method name="spiStartIgnoreI" ctype="msg_t">
|
|
<brief>Ignores data on the SPI bus.</brief>
|
|
<details><![CDATA[This asynchronous function starts the transmission
|
|
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>
|
|
<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
|
|
ignored.
|
|
</param>
|
|
<return>The operation status.</return>
|
|
<iclass />
|
|
<implementation><![CDATA[
|
|
msg_t msg;
|
|
|
|
osalDbgCheckClassI();
|
|
|
|
osalDbgCheck((self != NULL) && (n > 0U));
|
|
#if SPI_SUPPORTS_CIRCULAR
|
|
osalDbgCheck((__spi_getfield(self, circular) == false) || ((n & 1U) == 0U));
|
|
#endif
|
|
|
|
osalDbgAssert(self->state == HAL_DRV_STATE_READY, "not ready");
|
|
|
|
self->state = HAL_DRV_STATE_ACTIVE;
|
|
msg = spi_lld_ignore(self, n);
|
|
|
|
#if SPI_USE_ASSERT_ON_ERROR == TRUE
|
|
osalDbgAssert(msg == HAL_RET_SUCCESS, "function failed");
|
|
#endif
|
|
|
|
return msg;]]></implementation>
|
|
</method>
|
|
<method name="spiStartIgnore" ctype="msg_t">
|
|
<brief>Ignores data on the SPI bus.</brief>
|
|
<details><![CDATA[This asynchronous function starts the transmission
|
|
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>
|
|
<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
|
|
ignored.
|
|
</param>
|
|
<return>The operation status.</return>
|
|
<api />
|
|
<implementation><![CDATA[
|
|
msg_t msg;
|
|
|
|
osalSysLock();
|
|
msg = spiStartIgnoreI(self, n);
|
|
osalSysUnlock();
|
|
|
|
return msg;]]></implementation>
|
|
</method>
|
|
<method name="spiStartExchangeI" ctype="msg_t">
|
|
<brief>Exchanges data on the SPI bus.</brief>
|
|
<details><![CDATA[This asynchronous function starts a simultaneous
|
|
transmit/receive operation.]]></details>
|
|
<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>
|
|
<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
|
|
exchanged.
|
|
</param>
|
|
<param name="txbuf" ctype="const void *" dir="in">Pointer
|
|
to the
|
|
transmit buffer.
|
|
</param>
|
|
<param name="rxbuf" ctype="void *" dir="out">Pointer to
|
|
the
|
|
receive
|
|
buffer.
|
|
</param>
|
|
<return>The operation status.</return>
|
|
<iclass />
|
|
<implementation><![CDATA[
|
|
msg_t msg;
|
|
|
|
osalDbgCheckClassI();
|
|
|
|
osalDbgCheck((self != NULL) && (n > 0U) &&
|
|
(rxbuf != NULL) && (txbuf != NULL));
|
|
#if SPI_SUPPORTS_CIRCULAR
|
|
osalDbgCheck((__spi_getfield(self, circular) == false) || ((n & 1U) == 0U));
|
|
#endif
|
|
|
|
osalDbgAssert(self->state == HAL_DRV_STATE_READY, "not ready");
|
|
|
|
self->state = HAL_DRV_STATE_ACTIVE;
|
|
msg = spi_lld_exchange(self, n, txbuf, rxbuf);
|
|
|
|
#if SPI_USE_ASSERT_ON_ERROR == TRUE
|
|
osalDbgAssert(msg == HAL_RET_SUCCESS, "function failed");
|
|
#endif
|
|
|
|
return msg;]]></implementation>
|
|
</method>
|
|
<method name="spiStartExchange" ctype="msg_t">
|
|
<brief>Exchanges data on the SPI bus.</brief>
|
|
<details><![CDATA[This asynchronous function starts a simultaneous
|
|
transmit/receive operation.]]></details>
|
|
<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>
|
|
<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
|
|
exchanged.
|
|
</param>
|
|
<param name="txbuf" ctype="const void *" dir="in">Pointer
|
|
to the
|
|
transmit buffer.
|
|
</param>
|
|
<param name="rxbuf" ctype="void *" dir="out">Pointer to
|
|
the
|
|
receive
|
|
buffer.
|
|
</param>
|
|
<return>The operation status.</return>
|
|
<api />
|
|
<implementation><![CDATA[
|
|
msg_t msg;
|
|
|
|
osalSysLock();
|
|
msg = spiStartExchangeI(self, n, txbuf, rxbuf);
|
|
osalSysUnlock();
|
|
|
|
return msg;]]></implementation>
|
|
</method>
|
|
<method name="spiStartSendI" ctype="msg_t">
|
|
<brief>Sends data over the SPI bus.</brief>
|
|
<details><![CDATA[This asynchronous function starts a transmit
|
|
operation.]]></details>
|
|
<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>
|
|
<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
|
|
exchanged.
|
|
</param>
|
|
<param name="txbuf" ctype="const void *" dir="in">Pointer
|
|
to the
|
|
transmit buffer.
|
|
</param>
|
|
<return>The operation status.</return>
|
|
<iclass />
|
|
<implementation><![CDATA[
|
|
msg_t msg;
|
|
|
|
osalDbgCheckClassI();
|
|
|
|
osalDbgCheck((self != NULL) && (n > 0U) && (txbuf != NULL));
|
|
#if SPI_SUPPORTS_CIRCULAR
|
|
osalDbgCheck((__spi_getfield(self, circular) == false) || ((n & 1U) == 0U));
|
|
#endif
|
|
|
|
osalDbgAssert(self->state == HAL_DRV_STATE_READY, "not ready");
|
|
|
|
self->state = HAL_DRV_STATE_ACTIVE;
|
|
msg = spi_lld_send(self, n, txbuf);
|
|
|
|
#if SPI_USE_ASSERT_ON_ERROR == TRUE
|
|
osalDbgAssert(msg == HAL_RET_SUCCESS, "function failed");
|
|
#endif
|
|
|
|
return msg;]]></implementation>
|
|
</method>
|
|
<method name="spiStartSend" ctype="msg_t">
|
|
<brief>Sends data over the SPI bus.</brief>
|
|
<details><![CDATA[This asynchronous function starts a transmit
|
|
operation.]]></details>
|
|
<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>
|
|
<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
|
|
exchanged.
|
|
</param>
|
|
<param name="txbuf" ctype="const void *" dir="in">Pointer
|
|
to the
|
|
transmit buffer.
|
|
</param>
|
|
<return>The operation status.</return>
|
|
<api />
|
|
<implementation><![CDATA[
|
|
msg_t msg;
|
|
|
|
osalSysLock();
|
|
msg = spiStartSendI(self, n, txbuf);
|
|
osalSysUnlock();
|
|
|
|
return msg;]]></implementation>
|
|
</method>
|
|
<method name="spiStartReceiveI" ctype="msg_t">
|
|
<brief>Receives data from the SPI bus.</brief>
|
|
<details><![CDATA[This asynchronous function starts a receive
|
|
operation.]]></details>
|
|
<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>
|
|
<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
|
|
exchanged.
|
|
</param>
|
|
<param name="rxbuf" ctype="void *" dir="out">Pointer to
|
|
the
|
|
receive
|
|
buffer.
|
|
</param>
|
|
<return>The operation status.</return>
|
|
<iclass />
|
|
<implementation><![CDATA[
|
|
msg_t msg;
|
|
|
|
osalDbgCheckClassI();
|
|
|
|
osalDbgCheck((self != NULL) && (n > 0U) && (rxbuf != NULL));
|
|
#if SPI_SUPPORTS_CIRCULAR
|
|
osalDbgCheck((__spi_getfield(self, circular) == false) || ((n & 1U) == 0U));
|
|
#endif
|
|
|
|
osalDbgAssert(self->state == HAL_DRV_STATE_READY, "not ready");
|
|
|
|
self->state = HAL_DRV_STATE_ACTIVE;
|
|
msg = spi_lld_receive(self, n, rxbuf);
|
|
|
|
#if SPI_USE_ASSERT_ON_ERROR == TRUE
|
|
osalDbgAssert(msg == HAL_RET_SUCCESS, "function failed");
|
|
#endif
|
|
|
|
return msg;]]></implementation>
|
|
</method>
|
|
<method name="spiStartReceive" ctype="msg_t">
|
|
<brief>Receives data from the SPI bus.</brief>
|
|
<details><![CDATA[This asynchronous function starts a receive
|
|
operation.]]></details>
|
|
<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>
|
|
<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
|
|
exchanged.
|
|
</param>
|
|
<param name="rxbuf" ctype="void *" dir="out">Pointer to
|
|
the
|
|
receive
|
|
buffer.
|
|
</param>
|
|
<return>The operation status.</return>
|
|
<api />
|
|
<implementation><![CDATA[
|
|
msg_t msg;
|
|
|
|
osalSysLock();
|
|
msg = spiStartReceiveI(self, n, rxbuf);
|
|
osalSysUnlock();
|
|
|
|
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
|
|
of frames not yet transferred or @p NULL.
|
|
</param>
|
|
<return>The operation status.</return>
|
|
<iclass />
|
|
<implementation><![CDATA[
|
|
msg_t msg;
|
|
|
|
osalDbgCheckClassI();
|
|
|
|
osalDbgCheck(self != NULL);
|
|
|
|
osalDbgAssert((self->state == HAL_DRV_STATE_READY) ||
|
|
(self->state == HAL_DRV_STATE_ACTIVE) ||
|
|
(self->state == HAL_DRV_STATE_COMPLETE),
|
|
"invalid state");
|
|
|
|
if ((self->state == HAL_DRV_STATE_ACTIVE) ||
|
|
(self->state == HAL_DRV_STATE_COMPLETE)) {
|
|
|
|
/* Stopping transfer at low level.*/
|
|
msg = spi_lld_stop_transfer(self, np);
|
|
self->state = HAL_DRV_STATE_READY;
|
|
|
|
#if SPI_USE_SYNCHRONIZATION == TRUE
|
|
osalThreadResumeI(&self->sync_transfer, MSG_RESET);
|
|
#endif
|
|
}
|
|
else {
|
|
msg = HAL_RET_SUCCESS;
|
|
}
|
|
|
|
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
|
|
of frames not yet transferred or @p NULL.
|
|
</param>
|
|
<return>The operation status.</return>
|
|
<api />
|
|
<implementation><![CDATA[
|
|
msg_t msg;
|
|
|
|
osalSysLock();
|
|
|
|
msg = spiStopTransferI(self, np);
|
|
osalOsRescheduleS();
|
|
|
|
osalSysUnlock();
|
|
|
|
return msg;]]></implementation>
|
|
</method>
|
|
<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
|
|
timeout.
|
|
</param>
|
|
<return>The synchronization result.</return>
|
|
<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>
|
|
<sclass />
|
|
<implementation><![CDATA[
|
|
msg_t msg;
|
|
|
|
osalDbgCheck(self != NULL);
|
|
osalDbgAssert((self->state == HAL_DRV_STATE_ACTIVE) ||
|
|
(self->state == HAL_DRV_STATE_READY),
|
|
"invalid state");
|
|
|
|
if (self->state == HAL_DRV_STATE_ACTIVE) {
|
|
msg = osalThreadSuspendTimeoutS(&self->sync_transfer, timeout);
|
|
}
|
|
else {
|
|
msg = MSG_OK;
|
|
}
|
|
|
|
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
|
|
timeout.
|
|
</param>
|
|
<return>The synchronization result.</return>
|
|
<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>
|
|
<api />
|
|
<implementation><![CDATA[
|
|
msg_t msg;
|
|
|
|
osalSysLock();
|
|
msg = spiSynchronizeS(self, timeout);
|
|
osalSysUnlock();
|
|
|
|
return msg;]]></implementation>
|
|
</method>
|
|
<method name="spiIgnore" ctype="msg_t">
|
|
<brief>Ignores data on the SPI bus.</brief>
|
|
<details><![CDATA[This synchronous function performs the transmission
|
|
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
|
|
ignored.
|
|
</param>
|
|
<return>The operation status.</return>
|
|
<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>
|
|
<api />
|
|
<implementation><![CDATA[
|
|
msg_t msg;
|
|
|
|
osalSysLock();
|
|
|
|
msg = spiStartIgnoreI(self, n);
|
|
if (msg == MSG_OK) {
|
|
msg = spiSynchronizeS(self, TIME_INFINITE);
|
|
}
|
|
|
|
osalSysUnlock();
|
|
|
|
return msg;]]></implementation>
|
|
</method>
|
|
<method name="spiExchange" ctype="msg_t">
|
|
<brief>Exchanges data on the SPI bus.</brief>
|
|
<details><![CDATA[This synchronous function performs a simultaneous
|
|
transmit/receive operation.]]></details>
|
|
<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
|
|
exchanged.
|
|
</param>
|
|
<param name="txbuf" ctype="const void *" dir="in">Pointer
|
|
to
|
|
the
|
|
transmit buffer.
|
|
</param>
|
|
<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>
|
|
<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;
|
|
|
|
osalSysLock();
|
|
|
|
msg = spiStartExchangeI(self, n, txbuf, rxbuf);
|
|
if (msg == MSG_OK) {
|
|
msg = spiSynchronizeS(self, TIME_INFINITE);
|
|
}
|
|
|
|
osalSysUnlock();
|
|
|
|
return msg;]]></implementation>
|
|
</method>
|
|
<method name="spiSend" ctype="msg_t">
|
|
<brief>Sends data over the SPI bus.</brief>
|
|
<details><![CDATA[This synchronous function performs a transmit
|
|
operation.]]></details>
|
|
<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
|
|
exchanged.
|
|
</param>
|
|
<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>
|
|
<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;
|
|
|
|
msg = spiStartSendI(self, n, txbuf);
|
|
if (msg == MSG_OK) {
|
|
msg = spiSynchronizeS(self, TIME_INFINITE);
|
|
}
|
|
|
|
osalSysUnlock();
|
|
|
|
return msg;]]></implementation>
|
|
</method>
|
|
<method name="spiReceive" ctype="msg_t">
|
|
<brief>Receives data from the SPI bus.</brief>
|
|
<details><![CDATA[This synchronous function performs a receive
|
|
operation.]]></details>
|
|
<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
|
|
exchanged.
|
|
</param>
|
|
<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>
|
|
<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;
|
|
|
|
msg = spiStartReceiveI(self, n, rxbuf);
|
|
if (msg == MSG_OK) {
|
|
msg = spiSynchronizeS(self, TIME_INFINITE);
|
|
}
|
|
|
|
osalSysUnlock();
|
|
|
|
return msg;]]></implementation>
|
|
</method>
|
|
</condition>
|
|
</regular>
|
|
<inline>
|
|
<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>
|
|
<xclass />
|
|
<implementation><![CDATA[
|
|
|
|
spi_lld_select(self);]]></implementation>
|
|
</method>
|
|
<method name="spiUnselectX" ctype="void">
|
|
<brief>Deasserts the slave select signal.</brief>
|
|
<xclass />
|
|
<implementation><![CDATA[
|
|
|
|
spi_lld_unselect(self);]]></implementation>
|
|
</method>
|
|
<elseif check="SPI_SELECT_MODE == SPI_SELECT_MODE_LINE" />
|
|
<method name="spiSelectX" ctype="void">
|
|
<implementation><![CDATA[
|
|
|
|
palClearLine(__spi_getfield(self, ssline));]]></implementation>
|
|
</method>
|
|
<method name="spiUnselectX" ctype="void">
|
|
<implementation><![CDATA[
|
|
|
|
palSetLine(__spi_getfield(self, ssline));]]></implementation>
|
|
</method>
|
|
<elseif check="SPI_SELECT_MODE == SPI_SELECT_MODE_PORT" />
|
|
<method name="spiSelectX" ctype="void">
|
|
<implementation><![CDATA[
|
|
|
|
palClearPort(__spi_getfield(self, ssport), __spi_getfield(self, ssmask));]]></implementation>
|
|
</method>
|
|
<method name="spiUnselectX" ctype="void">
|
|
<implementation><![CDATA[
|
|
|
|
palSetPort(__spi_getfield(self, ssport), __spi_getfield(self, ssmask));]]></implementation>
|
|
</method>
|
|
<elseif check="SPI_SELECT_MODE == SPI_SELECT_MODE_PAD" />
|
|
<method name="spiSelectX" ctype="void">
|
|
<implementation><![CDATA[
|
|
|
|
palClearPad(__spi_getfield(self, ssport), __spi_getfield(self, sspad));]]></implementation>
|
|
</method>
|
|
<method name="spiUnselectX" ctype="void">
|
|
<implementation><![CDATA[
|
|
|
|
palSetPad(__spi_getfield(self, ssport), __spi_getfield(self, 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);
|
|
osalSysUnlockFromISR();]]></implementation>
|
|
</method>
|
|
<elseif />
|
|
<method name="__spi_wakeup_isr" ctype="void">
|
|
<param name="msg" ctype="msg_t" dir="in" />
|
|
<implementation><![CDATA[
|
|
|
|
(void)self;
|
|
(void)msg;]]></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[
|
|
|
|
__cbdrv_invoke_cb_with_transition(self,
|
|
HAL_DRV_STATE_COMPLETE,
|
|
HAL_DRV_STATE_READY);
|
|
__spi_wakeup_isr(self, MSG_OK);]]></implementation>
|
|
</method>
|
|
<method name="__spi_isr_half_code" ctype="void">
|
|
<brief>Half buffer filled ISR code in circular mode.</brief>
|
|
<details>
|
|
<verbatim><![CDATA[The callback is invoked with driver
|
|
state set to @p HAL_DRV_STATE_ACTIVE.]]></verbatim>
|
|
</details>
|
|
<note>This function is meant to be used in the low level
|
|
drivers
|
|
implementations only.
|
|
</note>
|
|
<notapi />
|
|
<implementation><![CDATA[
|
|
|
|
__cbdrv_invoke_cb(self);]]></implementation>
|
|
</method>
|
|
<method name="__spi_isr_full_code" ctype="void">
|
|
<brief>Full buffer filled ISR code in circular mode.</brief>
|
|
<details>
|
|
<verbatim><![CDATA[The callback is invoked with driver
|
|
state set to @p HAL_DRV_STATE_COMPLETE.]]></verbatim>
|
|
</details>
|
|
<note>This function is meant to be used in the low level
|
|
drivers
|
|
implementations only.
|
|
</note>
|
|
<notapi />
|
|
<implementation><![CDATA[
|
|
|
|
__cbdrv_invoke_cb_with_transition(self,
|
|
HAL_DRV_STATE_COMPLETE,
|
|
HAL_DRV_STATE_ACTIVE);]]></implementation>
|
|
</method>
|
|
<method name="__spi_isr_error_code" ctype="void">
|
|
<brief>ISR error reporting code..</brief>
|
|
<details>
|
|
<verbatim><![CDATA[The callback is invoked with driver
|
|
state set to @p HAL_DRV_STATE_ERROR.]]></verbatim>
|
|
</details>
|
|
<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 error code.</param>
|
|
<notapi />
|
|
<implementation><![CDATA[
|
|
|
|
__cbdrv_invoke_cb_with_transition(self,
|
|
HAL_DRV_STATE_ERROR,
|
|
HAL_DRV_STATE_READY);
|
|
__spi_wakeup_isr(self, msg);]]></implementation>
|
|
</method>
|
|
</inline>
|
|
<override>
|
|
<method shortname="start">
|
|
<implementation><![CDATA[
|
|
|
|
return spi_lld_start(self);]]></implementation>
|
|
</method>
|
|
<method shortname="stop">
|
|
<implementation><![CDATA[
|
|
|
|
spi_lld_stop(self);]]></implementation>
|
|
</method>
|
|
<method shortname="doconf">
|
|
<implementation><![CDATA[
|
|
|
|
return (const void *)spi_lld_configure(self, (const hal_spi_config_t *)config);]]></implementation>
|
|
</method>
|
|
</override>
|
|
</methods>
|
|
</class>
|
|
</types>
|
|
<functions>
|
|
<function name="spiInit" ctype="void">
|
|
<brief>SPI Driver initialization.</brief>
|
|
<note><![CDATA[This function is implicitly invoked by @p halInit(),
|
|
there is no need to explicitly initialize the driver.]]></note>
|
|
<init />
|
|
<implementation><![CDATA[
|
|
|
|
spi_lld_init();]]></implementation>
|
|
</function>
|
|
</functions>
|
|
</public>
|
|
<private>
|
|
<includes_always>
|
|
<include style="regular">hal.h</include>
|
|
</includes_always>
|
|
</private>
|
|
</module>
|