VIO LLD for XHAL. Added buffering capability to SIO.

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@16242 27425a3e-05d8-49a3-a47f-9c15f0e5edd8
This commit is contained in:
Giovanni Di Sirio 2023-04-30 08:27:07 +00:00
parent 831d2840df
commit f09aa2ef09
17 changed files with 1991 additions and 76 deletions

View File

@ -13,9 +13,11 @@
<group description="Common driver states">
<define name="HAL_DRV_STATE_UNINIT" value="0U" />
<define name="HAL_DRV_STATE_STOP" value="1U" />
<define name="HAL_DRV_STATE_READY" value="2U" />
<define name="HAL_DRV_STATE_ACTIVE" value="3U" />
<define name="HAL_DRV_STATE_ERROR" value="4U" />
<define name="HAL_DRV_STATE_STOPPING" value="2U" />
<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_ERROR" value="6U" />
</group>
</definitions_early>
<configs>
@ -143,7 +145,10 @@ osalDbgCheck(self != NULL);
osalSysLock();
osalDbgAssert(self->state != HAL_DRV_STATE_UNINIT, "not initialized");
osalDbgAssert((self->state != HAL_DRV_STATE_UNINIT) &&
(self->state != HAL_DRV_STATE_STOPPING) &&
(self->state != HAL_DRV_STATE_STARTING),
"invalid state");
if (self->state == HAL_DRV_STATE_STOP) {
/* Physically starting the peripheral.*/
@ -151,6 +156,9 @@ if (self->state == HAL_DRV_STATE_STOP) {
if (msg == HAL_RET_SUCCESS) {
self->state = HAL_DRV_STATE_READY;
}
else {
self->state = HAL_DRV_STATE_STOP;
}
}
osalSysUnlock();
@ -169,7 +177,9 @@ osalDbgCheck(self != NULL);
osalSysLock();
osalDbgAssert(self->state != HAL_DRV_STATE_UNINIT, "not initialized");
osalDbgAssert((self->state != HAL_DRV_STATE_UNINIT) &&
(self->state != HAL_DRV_STATE_STARTING),
"invalid state");
if (self->state != HAL_DRV_STATE_STOP) {
__drv_stop(self);

View File

@ -6,27 +6,36 @@
<imports>
<import>hal_base_driver.xml</import>
<import>hal_channels.xml</import>
<import>hal_buffered_serial.xml</import>
</imports>
<public>
<definitions_early>
<group description="SIO events">
<define name="SIO_EV_NONE" value="CHN_FL_NONE" />
<define name="SIO_EV_PARITY_ERR_POS" value="CHN_FL_PARITY_ERR_POS" />
<define name="SIO_EV_PARITY_ERR_POS"
value="CHN_FL_PARITY_ERR_POS" />
<define name="SIO_EV_PARITY_ERR" value="CHN_FL_PARITY_ERR" />
<define name="SIO_EV_FRAMING_ERR_POS" value="CHN_FL_FRAMING_ERR_POS" />
<define name="SIO_EV_FRAMING_ERR_POS"
value="CHN_FL_FRAMING_ERR_POS" />
<define name="SIO_EV_FRAMING_ERR" value="CHN_FL_FRAMING_ERR" />
<define name="SIO_EV_NOISE_ERR_POS" value="CHN_FL_NOISE_ERR_POS" />
<define name="SIO_EV_NOISE_ERR" value="CHN_FL_NOISE_ERR" />
<define name="SIO_EV_OVERRUN_ERR_POS" value="CHN_FL_OVERRUN_ERR_POS" />
<define name="SIO_EV_OVERRUN_ERR_POS"
value="CHN_FL_OVERRUN_ERR_POS" />
<define name="SIO_EV_OVERRUN_ERR" value="CHN_FL_OVERRUN_ERR" />
<define name="SIO_EV_ALL_ERRORS_POS" value="SIO_EV_PARITY_ERR_POS" />
<define name="SIO_EV_ALL_ERRORS" value="(15U &lt;&lt; SIO_EV_ALL_ERRORS_POS)" />
<define name="SIO_EV_TX_NOTFULL_POS" value="CHN_FL_TX_NOTFULL_POS" />
<define name="SIO_EV_ALL_ERRORS_POS"
value="SIO_EV_PARITY_ERR_POS" />
<define name="SIO_EV_ALL_ERRORS"
value="(15U &lt;&lt; SIO_EV_ALL_ERRORS_POS)" />
<define name="SIO_EV_TX_NOTFULL_POS"
value="CHN_FL_TX_NOTFULL_POS" />
<define name="SIO_EV_TX_NOTFULL" value="CHN_FL_TX_NOTFULL" />
<define name="SIO_EV_RX_NOTEMPTY_POS" value="CHN_FL_RX_NOTEMPTY_POS" />
<define name="SIO_EV_RX_NOTEMPTY_POS"
value="CHN_FL_RX_NOTEMPTY_POS" />
<define name="SIO_EV_RX_NOTEMPTY" value="CHN_FL_RX_NOTEMPTY" />
<define name="SIO_EV_ALL_DATA_POS" value="SIO_EV_TX_NOTFULL_POS" />
<define name="SIO_EV_ALL_DATA" value="(3U &lt;&lt; SIO_EV_ALL_DATA_POS)" />
<define name="SIO_EV_ALL_DATA"
value="(3U &lt;&lt; SIO_EV_ALL_DATA_POS)" />
<define name="SIO_EV_TX_END_POS" value="CHN_FL_TX_END_POS" />
<define name="SIO_EV_TX_END" value="CHN_FL_TX_END" />
<define name="SIO_EV_RX_IDLE_POS" value="CHN_FL_RX_IDLE_POS" />
@ -34,9 +43,11 @@
<define name="SIO_EV_RX_BREAK_POS" value="CHN_FL_RX_BREAK_POS" />
<define name="SIO_EV_RX_BREAK" value="CHN_FL_RX_BREAK" />
<define name="SIO_EV_ALL_STATUS_POS" value="SIO_EV_TX_END_POS" />
<define name="SIO_EV_ALL_STATUS" value="(7U &lt;&lt; SIO_EV_ALL_STATUS_POS)" />
<define name="SIO_EV_ALL_STATUS"
value="(7U &lt;&lt; SIO_EV_ALL_STATUS_POS)" />
<define name="SIO_EV_NONE_MASK" value="0U" />
<define name="SIO_EV_ALL_EVENTS" value="(SIO_EV_ALL_ERRORS | SIO_EV_ALL_DATA | SIO_EV_ALL_STATUS)" />
<define name="SIO_EV_ALL_EVENTS"
value="(SIO_EV_ALL_ERRORS | SIO_EV_ALL_DATA | SIO_EV_ALL_STATUS)" />
</group>
<group description="Additional messages">
<define name="SIO_MSG_ERRORS" value="1" />
@ -46,7 +57,8 @@
<config name="SIO_DEFAULT_BITRATE" default="38400">
<brief>Default bit rate.</brief>
<details>Configuration parameter, this is the baud rate selected
for the default configuration.
for the
default configuration.
</details>
<assert invalid="$N &lt;= 0" />
</config>
@ -59,6 +71,10 @@
<brief>Support for streams interface.</brief>
<assert invalid="($N != FALSE) &amp;&amp; ($N != TRUE)" />
</config>
<config name="SIO_USE_BUFFERING" default="TRUE">
<brief>Support for buffering wrapper class.</brief>
<assert invalid="($N != FALSE) &amp;&amp; ($N != TRUE)" />
</config>
</configs>
<macros>
<macro name="sioSetCallbackX">
@ -174,7 +190,8 @@ do {
<macro name="sioGetAndClearErrorsX">
<brief>Gets and clears SIO error flags.</brief>
<param name="siop" dir="both">pointer to the @p hal_sio_driver_c
object</param>
object
</param>
<return>The pending error flags.</return>
<xclass />
<implementation><![CDATA[sio_lld_get_and_clear_errors(siop)]]></implementation>
@ -182,9 +199,12 @@ do {
<macro name="sioGetAndClearEventsX">
<brief>Gets and clears SIO event flags.</brief>
<param name="siop" dir="both">pointer to the @p hal_sio_driver_c
object</param>
object
</param>
<param name="mask" ctype="sioevents_t" dir="in">Mask of events
to be returned and cleared.</param>
to be
returned and cleared.
</param>
<return>The pending event flags.</return>
<xclass />
<implementation><![CDATA[sio_lld_get_and_clear_events(siop, mask)]]></implementation>
@ -224,10 +244,12 @@ do {
<macro name="sioAsyncReadX">
<brief>Reads data from the RX FIFO.</brief>
<details>This function is non-blocking, data is read if present
and the effective amount is returned.
and the
effective amount is returned.
</details>
<note>This function can be called from any context but it is
meant to be called from the @p cb callback handler.
meant to be
called from the @p cb callback handler.
</note>
<param name="siop" dir="both">pointer to the @p hal_sio_driver_c
object
@ -244,10 +266,12 @@ do {
<macro name="sioAsyncWriteX">
<brief>Writes data into the TX FIFO.</brief>
<details>This function is non-blocking, data is written if there
is space in the FIFO and the effective amount is returned.
is space
in the FIFO and the effective amount is returned.
</details>
<note>This function can be called from any context but it is
meant to be called from the @p cb callback handler.
meant to be
called from the @p cb callback handler.
</note>
<param name="siop" dir="both">pointer to the @p hal_sio_driver_c
object
@ -292,7 +316,8 @@ do {
<macro name="__sio_wakeup_errors">
<brief>Wakes up because RX errors.</brief>
<param name="siop" dir="both">pointer to the @p
hal_sio_driver_c object
hal_sio_driver_c
object
</param>
<notapi />
<implementation><![CDATA[
@ -306,7 +331,8 @@ do {
<macro name="__sio_wakeup_rx">
<brief>Wakes up the RX-waiting thread.</brief>
<param name="siop" dir="both">pointer to the @p
hal_sio_driver_c object
hal_sio_driver_c
object
</param>
<notapi />
<implementation><![CDATA[
@ -319,7 +345,8 @@ do {
<macro name="__sio_wakeup_rxidle">
<brief>Wakes up the RX-idle-waiting thread.</brief>
<param name="siop" dir="both">pointer to the @p
hal_sio_driver_c object
hal_sio_driver_c
object
</param>
<notapi />
<implementation><![CDATA[
@ -332,7 +359,8 @@ do {
<macro name="__sio_wakeup_tx">
<brief>Wakes up the TX-waiting thread.</brief>
<param name="siop" dir="both">pointer to the @p
hal_sio_driver_c object
hal_sio_driver_c
object
</param>
<notapi />
<implementation><![CDATA[
@ -345,7 +373,8 @@ do {
<macro name="__sio_wakeup_txend">
<brief>Wakes up the TXend-waiting thread.</brief>
<param name="siop" dir="both">pointer to the @p
hal_sio_driver_c object
hal_sio_driver_c
object
</param>
<notapi />
<implementation><![CDATA[
@ -403,8 +432,7 @@ do {
</typedef>
<typedef name="siocb_t">
<brief>Generic SIO notification callback type.</brief>
<basetype
ctype="void (*$N)(struct hal_sio_driver *siop)" />
<basetype ctype="void (*$N)(struct hal_sio_driver *siop)" />
</typedef>
<verbatim><![CDATA[
/* Inclusion of LLD header.*/
@ -580,7 +608,8 @@ SIO_DRIVER_EXT_INIT_HOOK(self);
<method name="sioWriteEnableFlags" ctype="void">
<brief>Writes the enabled events flags mask.</brief>
<param name="mask" ctype="sioevents_t">enabled events mask to be
written</param>
written
</param>
<api />
<implementation><![CDATA[
@ -594,7 +623,8 @@ osalSysUnlock();]]></implementation>
<method name="sioSetEnableFlags" ctype="void">
<brief>Sets flags into the enabled events flags mask.</brief>
<param name="mask" ctype="sioevents_t">enabled events mask to be
set</param>
set
</param>
<api />
<implementation><![CDATA[
@ -608,7 +638,8 @@ osalSysUnlock();]]></implementation>
<method name="sioClearEnableFlags" ctype="void">
<brief>Clears flags from the enabled events flags mask.</brief>
<param name="mask" ctype="sioevents_t">enabled events mask to be
cleared</param>
cleared
</param>
<api />
<implementation><![CDATA[
@ -619,8 +650,7 @@ osalDbgAssert(self->state == HAL_DRV_STATE_READY, "invalid state");
sioClearEnableFlagsX(self, mask);
osalSysUnlock();]]></implementation>
</method>
<method name="sioGetAndClearErrors"
ctype="sioevents_t">
<method name="sioGetAndClearErrors" ctype="sioevents_t">
<brief>Get and clears SIO error event flags.</brief>
<return>The pending error event flags.</return>
<api />
@ -636,11 +666,12 @@ osalSysUnlock();
return errors;]]></implementation>
</method>
<method name="sioGetAndClearEvents"
ctype="sioevents_t">
<method name="sioGetAndClearEvents" ctype="sioevents_t">
<brief>Get and clears SIO event flags.</brief>
<param name="mask" ctype="sioevents_t" dir="in">Mask of events
to be returned and cleared.</param>
to
be returned and cleared.
</param>
<return>The pending event flags.</return>
<api />
<implementation><![CDATA[
@ -675,13 +706,15 @@ return events;]]></implementation>
<method name="sioSynchronizeRX" ctype="msg_t">
<brief>Synchronizes with RX FIFO data availability.</brief>
<note>The exact behavior depends on low level FIFO
settings such as thresholds, etc.
settings such
as thresholds, etc.
</note>
<note>This function can only be called by a single
thread at time.
thread at
time.
</note>
<param name="timeout" ctype="sysinterval_t"
dir="in">synchronization timeout
<param name="timeout" ctype="sysinterval_t" dir="in">synchronization
timeout
</param>
<return>The synchronization result.</return>
<retval value="MSG_OK">If there is data in the RX FIFO.
@ -689,9 +722,12 @@ return events;]]></implementation>
<retval value="MSG_TIMEOUT">If synchronization timed out.
</retval>
<retval value="MSG_RESET">It the driver has been stopped
while waiting.</retval>
while
waiting.
</retval>
<retval value="SIO_MSG_ERRORS">It RX errors occurred before or
during wait.</retval>
during wait.
</retval>
<api />
<implementation><![CDATA[
msg_t msg;
@ -727,10 +763,11 @@ return msg;]]></implementation>
<method name="sioSynchronizeRXIdle" ctype="msg_t">
<brief>Synchronizes with RX going idle.</brief>
<note>This function can only be called by a single
thread at time.
thread at
time.
</note>
<param name="timeout" ctype="sysinterval_t"
dir="in">synchronization timeout
<param name="timeout" ctype="sysinterval_t" dir="in">synchronization
timeout
</param>
<return>The synchronization result.</return>
<retval value="MSG_OK">If there is data in the RX FIFO.
@ -738,9 +775,12 @@ return msg;]]></implementation>
<retval value="MSG_TIMEOUT">If synchronization timed out.
</retval>
<retval value="MSG_RESET">It the driver has been stopped
while waiting.</retval>
while
waiting.
</retval>
<retval value="SIO_MSG_ERRORS">It RX errors occurred before or
during wait.</retval>
during wait.
</retval>
<api />
<implementation><![CDATA[
msg_t msg;
@ -776,13 +816,15 @@ return msg;]]></implementation>
<method name="sioSynchronizeTX" ctype="msg_t">
<brief>Synchronizes with TX FIFO space availability.</brief>
<note>The exact behavior depends on low level FIFO
settings such as thresholds, etc.
settings such
as thresholds, etc.
</note>
<note>This function can only be called by a single
thread at time.
thread at
time.
</note>
<param name="timeout" ctype="sysinterval_t"
dir="in">synchronization timeout
<param name="timeout" ctype="sysinterval_t" dir="in">synchronization
timeout
</param>
<return>The synchronization result.</return>
<retval value="MSG_OK">If there is space in the TX FIFO.
@ -790,7 +832,9 @@ return msg;]]></implementation>
<retval value="MSG_TIMEOUT">If synchronization timed out.
</retval>
<retval value="MSG_RESET">It the driver has been stopped
while waiting.</retval>
while
waiting.
</retval>
<api />
<implementation><![CDATA[
msg_t msg;
@ -820,10 +864,11 @@ return msg;]]></implementation>
<method name="sioSynchronizeTXEnd" ctype="msg_t">
<brief>Synchronizes with TX completion.</brief>
<note>This function can only be called by a single
thread at time.
thread at
time.
</note>
<param name="timeout" ctype="sysinterval_t"
dir="in">synchronization timeout
<param name="timeout" ctype="sysinterval_t" dir="in">synchronization
timeout
</param>
<return>The synchronization result.</return>
<retval value="MSG_OK">If there is space in the TX FIFO.
@ -831,7 +876,9 @@ return msg;]]></implementation>
<retval value="MSG_TIMEOUT">If synchronization timed out.
</retval>
<retval value="MSG_RESET">It the driver has been stopped
while waiting.</retval>
while
waiting.
</retval>
<api />
<implementation><![CDATA[
msg_t msg;
@ -861,7 +908,7 @@ return msg;]]></implementation>
</regular>
<override>
<method shortname="start">
<implementation><![CDATA[
<implementation><![CDATA[
msg_t msg;
msg = sio_lld_start(self);
@ -878,7 +925,7 @@ if (msg == HAL_RET_SUCCESS) {
return msg;]]></implementation>
</method>
<method shortname="stop">
<implementation><![CDATA[
<implementation><![CDATA[
sio_lld_stop(self);
self->cb = NULL;
@ -894,20 +941,88 @@ osalOsRescheduleS();
#endif]]></implementation>
</method>
<method shortname="configure">
<implementation><![CDATA[
<implementation><![CDATA[
return sio_lld_configure(self, (const hal_sio_config_t *)config);]]></implementation>
</method>
</override>
</methods>
</class>
<class name="hal_buffered_sio" type="regular" namespace="bsio"
descr="buffered SIO wrapper" ancestorname="hal_buffered_serial">
<brief>This class implements a buffered channel interface on top of SIO.</brief>
<fields>
<field name="siop" ctype="hal_sio_driver_c$I*">
<brief>Pointer to the associated @p hal_sio_driver_c instance.</brief>
</field>
</fields>
<methods>
<objinit callsuper="false">
<param name="siop" ctype="hal_sio_driver_c *" dir="in">Pointer to
the @p hal_sio_driver_c object.</param>
<param name="ib" ctype="uint8_t *" dir="in">Pointer to the input buffer.</param>
<param name="ibsize" ctype="size_t" dir="in">Size of the input buffer.</param>
<param name="ob" ctype="uint8_t *" dir="in">Pointer to the output buffer.</param>
<param name="obsize" ctype="size_t" dir="in">Size of the output buffer.</param>
<implementation><![CDATA[
__bs_objinit_impl((void *)self, (const void *)&vmt,
ib, ibsize, NULL, NULL,
ob, obsize, __bsio_onotify, (void *)self);
drvSetArgumentX(siop, self);
self->siop = siop;]]></implementation>
</objinit>
<dispose>
<implementation><![CDATA[
]]></implementation>
</dispose>
<override>
<method shortname="start">
<implementation><![CDATA[
msg_t msg;
/* Start is a slow operation in this driver, we need to switch to the
HAL_DRV_STATE_STARTING state.*/
self->state = HAL_DRV_STATE_STARTING;
osalSysUnlock();
/* Starting the undelying SIO driver.*/
msg = drvStart(self->siop);
if (msg == HAL_RET_SUCCESS) {
sioSetCallbackX(self->siop, &__bsio_default_cb);
sioWriteEnableFlagsX(self->siop, SIO_EV_ALL_EVENTS);
}
/* Back into the critical section and return.*/
osalSysLock();
return msg;]]></implementation>
</method>
<method shortname="stop">
<implementation><![CDATA[
/* Start is a slow operation in this driver, we need to switch to the
HAL_DRV_STATE_STOPPING state.*/
self->state = HAL_DRV_STATE_STOPPING;
osalSysUnlock();
drvStop(self->siop);
/* Back into the critical section and return.*/
osalSysLock();]]></implementation>
</method>
<method shortname="configure">
<implementation><![CDATA[
return drvConfigureX(self->siop, config);]]></implementation>
</method>
</override>
</methods>
</class>
</types>
<functions>
<function name="sioInit" ctype="void">
<brief>SIO Driver initialization.</brief>
<note>
This function is implicitly invoked by @p halInit(), there is no need
to explicitly initialize the driver.
This function is implicitly invoked by @p halInit(), there is no
need to explicitly initialize the driver.
</note>
<init />
<implementation><![CDATA[
@ -971,6 +1086,65 @@ while (i < n) {
return i;]]></implementation>
</function>
</condition>
<condition check="SIO_USE_BUFFERING == TRUE">
<function name="__bsio_push_data" ctype="void">
<param name="bsiop" ctype="hal_buffered_sio_c *"></param>
<implementation><![CDATA[
while (!sioIsTXFullX(bsiop->siop)) {
msg_t msg;
msg = oqGetI(&bsiop->oqueue);
if (msg < MSG_OK) {
bsAddFlagsI(bsiop, CHN_FL_TX_NOTFULL);
return;
}
sioPutX(bsiop->siop, (uint_fast16_t)msg);
}]]></implementation>
</function>
<function name="__bsio_pop_data" ctype="void">
<param name="bsiop" ctype="hal_buffered_sio_c *"></param>
<implementation><![CDATA[
/* RX FIFO needs to be fully emptied or SIO will not generate more RX FIFO
events.*/
while (!sioIsRXEmptyX(bsiop->siop)) {
bsIncomingDataI(bsiop, sioGetX(bsiop->siop));
}]]></implementation>
</function>
<function name="__bsio_default_cb" ctype="void">
<param name="siop" ctype="hal_sio_driver_c *"></param>
<implementation><![CDATA[
hal_buffered_sio_c *bsiop = (hal_buffered_sio_c *)siop->arg;
sioevents_t events;
osalSysLockFromISR();
/* Posting the non-data SIO events as channel event flags, the masks are
made to match.*/
events = sioGetAndClearEventsX(siop, SIO_EV_ALL_EVENTS);
bsAddFlagsI(bsiop, (eventflags_t)(events & ~SIO_EV_ALL_DATA));
/* RX FIFO event.*/
if ((events & SIO_EV_RX_NOTEMPTY) != (sioevents_t)0) {
__bsio_pop_data(bsiop);
}
/* TX FIFO event.*/
if ((events & SIO_EV_TX_NOTFULL) != (sioevents_t)0) {
__bsio_push_data(bsiop);
}
osalSysUnlockFromISR();]]></implementation>
</function>
<function name="__bsio_onotify" ctype="void">
<param name="qp" ctype="io_queue_t *"></param>
<implementation><![CDATA[
__bsio_push_data((hal_buffered_sio_c *)qp->q_link);]]></implementation>
</function>
</condition>
</functions>
</private>
</module>

View File

@ -23,13 +23,32 @@
*
* state UNINIT
* state STOP
* state STOPPING
* state STARTING
* state READY
* state ACTIVE
* state ERROR
* note left of STOPPING
* Optional state used when
* stopping a driver is a
* slow operation.
* end note
* note left of STARTING
* Optional state used when
* starting a driver is a
* slow operation.
* end note
* note left of ERROR
* Optional state is used by drivers
* requiring a persistent error
* condition.
* end note
*
* [*] -> UNINIT
* [*] --> UNINIT
* UNINIT --> STOP : xxxObjectInit()
* STOP --> READY : drvStart()
* STOP --> STARTING : drvStart()\nslow start
* STARTING -[dotted]-> READY : slow start\ncomplete
* READY --> READY : drvStart()\nignored
* READY --> READY : drvConfigure()
* READY --> STOP : drvStop()
@ -38,6 +57,8 @@
* ACTIVE -[dotted]-> READY : asynchronous\nend operation\ncallback
* ACTIVE --> STOP : drvStop()\nhard abort
* ACTIVE -[dotted]-> ERROR : asynchronous\noperation error\ncallback
* ACTIVE --> STOPPING : drvStop()\nslow stop
* STOPPING -[dotted]-> STOP : slow stop\ncomplete
* ERROR --> READY : drvStart()
* ERROR --> STOP : drvStop()
* ERROR --> READY : error cleared
@ -64,7 +85,7 @@
* condition.
* end note
*
* [*] -> UNINIT
* [*] --> UNINIT
* UNINIT --> STOP : xxxObjectInit()
* STOP --> READY : drvOpen()\ncall start()
* READY --> READY : drvOpen() cnt++

View File

@ -39,9 +39,11 @@
*/
#define HAL_DRV_STATE_UNINIT 0U
#define HAL_DRV_STATE_STOP 1U
#define HAL_DRV_STATE_READY 2U
#define HAL_DRV_STATE_ACTIVE 3U
#define HAL_DRV_STATE_ERROR 4U
#define HAL_DRV_STATE_STOPPING 2U
#define HAL_DRV_STATE_STARTING 3U
#define HAL_DRV_STATE_READY 4U
#define HAL_DRV_STATE_ACTIVE 5U
#define HAL_DRV_STATE_ERROR 6U
/** @} */
/*===========================================================================*/

View File

@ -103,6 +103,13 @@
#if !defined(SIO_USE_STREAMS_INTERFACE) || defined(__DOXYGEN__)
#define SIO_USE_STREAMS_INTERFACE SIO_USE_SYNCHRONIZATION
#endif
/**
* @brief Support for buffering wrapper class.
*/
#if !defined(SIO_USE_BUFFERING) || defined(__DOXYGEN__)
#define SIO_USE_BUFFERING TRUE
#endif
/** @} */
/*===========================================================================*/
@ -124,6 +131,11 @@
#error "invalid SIO_USE_STREAMS_INTERFACE value"
#endif
/* Checks on SIO_USE_BUFFERING configuration.*/
#if (SIO_USE_BUFFERING != FALSE) && (SIO_USE_BUFFERING != TRUE)
#error "invalid SIO_USE_BUFFERING value"
#endif
/*===========================================================================*/
/* Module macros. */
/*===========================================================================*/
@ -618,6 +630,95 @@ struct hal_sio_driver {
};
/** @} */
/**
* @class hal_buffered_sio_c
* @extends base_object_c, hal_base_driver_c, hal_buffered_serial_c.
*
* @brief This class implements a buffered channel interface on top of
* SIO.
*
* @name Class @p hal_buffered_sio_c structures
* @{
*/
/**
* @brief Type of a buffered SIO wrapper class.
*/
typedef struct hal_buffered_sio hal_buffered_sio_c;
/**
* @brief Class @p hal_buffered_sio_c virtual methods table.
*/
struct hal_buffered_sio_vmt {
/* From base_object_c.*/
void (*dispose)(void *ip);
/* From hal_base_driver_c.*/
msg_t (*start)(void *ip);
void (*stop)(void *ip);
msg_t (*configure)(void *ip, const void *config);
/* From hal_buffered_serial_c.*/
/* From hal_buffered_sio_c.*/
};
/**
* @brief Structure representing a buffered SIO wrapper class.
*/
struct hal_buffered_sio {
/**
* @brief Virtual Methods Table.
*/
const struct hal_buffered_sio_vmt *vmt;
/**
* @brief Driver state.
*/
driver_state_t state;
/**
* @brief Driver argument.
*/
void *arg;
#if (HAL_USE_MUTUAL_EXCLUSION == TRUE) || defined (__DOXYGEN__)
/**
* @brief Driver mutex.
*/
mutex_t mutex;
#endif /* HAL_USE_MUTUAL_EXCLUSION == TRUE */
#if (HAL_USE_REGISTRY == TRUE) || defined (__DOXYGEN__)
/**
* @brief Driver identifier.
*/
unsigned int id;
/**
* @brief Driver name.
*/
const char *name;
/**
* @brief Registry link structure.
*/
hal_regent_t regent;
#endif /* HAL_USE_REGISTRY == TRUE */
/**
* @brief Implemented interface @p asynchronous_channel_i.
*/
asynchronous_channel_i chn;
/**
* @brief Input queue.
*/
input_queue_t iqueue;
/**
* @brief Output queue.
*/
output_queue_t oqueue;
/**
* @brief I/O condition event source.
*/
event_source_t event;
/**
* @brief Pointer to the associated @p hal_sio_driver_c instance.
*/
hal_sio_driver_c *siop;
};
/** @} */
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
@ -643,6 +744,14 @@ extern "C" {
msg_t sioSynchronizeTX(void *ip, sysinterval_t timeout);
msg_t sioSynchronizeTXEnd(void *ip, sysinterval_t timeout);
#endif /* SIO_USE_SYNCHRONIZATION == TRUE */
/* Methods of hal_buffered_sio_c.*/
void *__bsio_objinit_impl(void *ip, const void *vmt, hal_sio_driver_c *siop,
uint8_t *ib, size_t ibsize, uint8_t *ob,
size_t obsize);
void __bsio_dispose_impl(void *ip);
msg_t __bsio_start_impl(void *ip);
void __bsio_stop_impl(void *ip);
msg_t __bsio_configure_impl(void *ip, const void *config);
/* Regular functions.*/
void sioInit(void);
#ifdef __cplusplus
@ -676,6 +785,38 @@ static inline hal_sio_driver_c *sioObjectInit(hal_sio_driver_c *self) {
}
/** @} */
/**
* @name Default constructor of hal_buffered_sio_c
* @{
*/
/**
* @memberof hal_buffered_sio_c
*
* @brief Default initialization function of @p hal_buffered_sio_c.
*
* @param[out] self Pointer to a @p hal_buffered_sio_c instance to
* be initialized.
* @param[in] siop Pointer to the @p hal_sio_driver_c object.
* @param[in] ib Pointer to the input buffer.
* @param[in] ibsize Size of the input buffer.
* @param[in] ob Pointer to the output buffer.
* @param[in] obsize Size of the output buffer.
* @return Pointer to the initialized object.
*
* @objinit
*/
CC_FORCE_INLINE
static inline hal_buffered_sio_c *bsioObjectInit(hal_buffered_sio_c *self,
hal_sio_driver_c *siop,
uint8_t *ib, size_t ibsize,
uint8_t *ob, size_t obsize) {
extern const struct hal_buffered_sio_vmt __hal_buffered_sio_vmt;
return __bsio_objinit_impl(self, &__hal_buffered_sio_vmt, siop, ib, ibsize,
ob, obsize);
}
/** @} */
#endif /* HAL_USE_SIO == TRUE */
#endif /* HAL_SIO_H */

View File

@ -596,8 +596,8 @@ sioevents_t sio_lld_get_and_clear_events(SIODriver *siop, sioevents_t events) {
/* Status flags cleared, now the RX-related interrupts can be
enabled again.*/
usart_enable_rx_irq(siop);
usart_enable_rx_errors_irq(siop);
usart_enable_rx_irq(siop); /* TODO - not always.*/
usart_enable_rx_errors_irq(siop); /* TODO - not always.*/
/* Translating the status flags in SIO events.*/
return usart_isr2evt(isr);

View File

@ -0,0 +1,60 @@
/*
ChibiOS - Copyright (C) 2006..2021 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file sandbox/hal_lld.c
* @brief SandBox HAL subsystem low level driver source.
*
* @addtogroup HAL
* @{
*/
#include "hal.h"
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local variables and types. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* @brief Low level HAL driver initialization.
*
* @notapi
*/
void hal_lld_init(void) {
}
/** @} */

View File

@ -0,0 +1,97 @@
/*
ChibiOS - Copyright (C) 2006..2021 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file sandbox/hal_lld.h
* @brief SandBox HAL subsystem low level driver header.
*
* @addtogroup HAL
* @{
*/
#ifndef HAL_LLD_H
#define HAL_LLD_H
#include "sbuser.h"
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
/**
* @brief Specifies implementation of dynamic clock management.
*/
/*#define HAL_LLD_USE_CLOCK_MANAGEMENT*/
/**
* @name Platform identification macros
* @{
*/
#define PLATFORM_NAME "SandBox"
/** @} */
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/**
* @name PLATFORM configuration options
* @{
*/
/** @} */
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
/*
* Configuration-related checks.
*/
#if !defined(SANDBOX_MCUCONF)
#error "Using a wrong mcuconf.h file, SANDBOX_MCUCONF not defined"
#endif
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/**
* @brief Type of a clock point identifier.
*/
typedef unsigned halclkpt_t;
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
#define __MK_VECTOR(n) __sb_vector##n
#define MK_VECTOR(n) __MK_VECTOR(n)
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#ifdef __cplusplus
extern "C" {
#endif
void hal_lld_init(void);
#ifdef __cplusplus
}
#endif
#endif /* HAL_LLD_H */
/** @} */

View File

@ -0,0 +1,55 @@
/*
ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file sandbox/hal_pal_lld.c
* @brief Sandbox PAL subsystem low level driver source.
*
* @addtogroup PAL
* @{
*/
#include "hal.h"
#if (HAL_USE_PAL == TRUE) || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local variables and types. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
#endif /* HAL_USE_PAL == TRUE */
/** @} */

View File

@ -0,0 +1,275 @@
/*
ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file sandbox/hal_pal_lld.h
* @brief Sanbox PAL subsystem low level driver header.
*
* @addtogroup PAL
* @{
*/
#ifndef HAL_PAL_LLD_H
#define HAL_PAL_LLD_H
#if (HAL_USE_PAL == TRUE) || defined(__DOXYGEN__)
#if PAL_USE_CALLBACKS
#error "PAL_USE_CALLBACKS not supported"
#endif
#if PAL_USE_WAIT
#error "PAL_USE_WAIT not supported"
#endif
/*===========================================================================*/
/* Unsupported modes and specific modes */
/*===========================================================================*/
/* Specifies palInit() without parameter, required until all platforms will
be updated to the new style.*/
#define PAL_NEW_INIT
/*===========================================================================*/
/* I/O Ports Types and constants. */
/*===========================================================================*/
/**
* @name Port related definitions
* @{
*/
/**
* @brief Width, in bits, of an I/O port.
*/
#define PAL_IOPORTS_WIDTH 32U
/**
* @brief Whole port mask.
* @details This macro specifies all the valid bits into a port.
*/
#define PAL_WHOLE_PORT ((ioportmask_t)0xFFFFFFFFU)
/** @} */
/**
* @name Line handling macros
* @{
*/
/**
* @brief Forms a line identifier.
* @details A port/pad pair are encoded into an @p ioline_t type. The encoding
* of this type is platform-dependent.
*/
#define PAL_LINE(port, pad) \
((ioline_t)((uint32_t)(port) << 8) | ((uint32_t)(pad)))
/**
* @brief Decodes a port identifier from a line identifier.
*/
#define PAL_PORT(line) \
(ioportid_t)((uint32_t)(line) >> 8)
/**
* @brief Decodes a pad identifier from a line identifier.
*/
#define PAL_PAD(line) \
((iopadid_t)((uint32_t)(line) & 0x000000FFU))
/**
* @brief Value identifying an invalid line.
*/
#define PAL_NOLINE 0xFFFFFFFFU
/** @} */
/**
* @brief Digital I/O port sized unsigned type.
*/
typedef uint32_t ioportmask_t;
/**
* @brief Digital I/O modes.
*/
typedef uint32_t iomode_t;
/**
* @brief Type of an I/O line.
*/
typedef uint32_t ioline_t;
/**
* @brief Port Identifier.
* @details This type can be a scalar or some kind of pointer, do not make
* any assumption about it, use the provided macros when populating
* variables of this type.
*/
typedef uint32_t ioportid_t;
/**
* @brief Type of an pad identifier.
*/
typedef uint32_t iopadid_t;
/*===========================================================================*/
/* I/O Ports Identifiers. */
/*===========================================================================*/
/**
* @name Generic port identifiers.
* @{
*/
#define IOPORT1 VPIO0
#define IOPORT2 VPIO1
#define IOPORT3 VPIO2
#define IOPORT4 VPIO3
#define IOPORT5 VPIO4
#define IOPORT6 VPIO5
#define IOPORT7 VPIO6
#define IOPORT8 VPIO7
/** @} */
/*===========================================================================*/
/* Implementation, some of the following macros could be implemented as */
/* functions, if so please put them in pal_lld.c. */
/*===========================================================================*/
/**
* @brief Low level PAL subsystem initialization.
*
* @notapi
*/
#define pal_lld_init()
/**
* @brief Reads the physical I/O port states.
*
* @param[in] port port identifier
* @return The port bits.
*
* @notapi
*/
#define pal_lld_readport(port) __pal_lld_readport(port)
/**
* @brief Reads the output latch.
* @details The purpose of this function is to read back the latched output
* value.
*
* @param[in] port port identifier
* @return The latched logical states.
*
* @notapi
*/
#define pal_lld_readlatch(port) __pal_lld_readlatch(port)
/**
* @brief Writes a bits mask on a I/O port.
*
* @param[in] port port identifier
* @param[in] bits bits to be written on the specified port
*
* @notapi
*/
#define pal_lld_writeport(port, bits) __pal_lld_writeport(port, bits)
/**
* @brief Sets a bits mask on a I/O port.
* @note The @ref PAL provides a default software implementation of this
* functionality, implement this function if can optimize it by using
* special hardware functionalities or special coding.
*
* @param[in] port port identifier
* @param[in] bits bits to be ORed on the specified port
*
* @notapi
*/
#define pal_lld_setport(port, bits) __pal_lld_setport(port, bits)
/**
* @brief Clears a bits mask on a I/O port.
* @note The @ref PAL provides a default software implementation of this
* functionality, implement this function if can optimize it by using
* special hardware functionalities or special coding.
*
* @param[in] port port identifier
* @param[in] bits bits to be cleared on the specified port
*
* @notapi
*/
#define pal_lld_clearport(port, bits) __pal_lld_clearport(port, bits)
/**
* @brief Toggles a bits mask on a I/O port.
* @note The @ref PAL provides a default software implementation of this
* functionality, implement this function if can optimize it by using
* special hardware functionalities or special coding.
*
* @param[in] port port identifier
* @param[in] bits bits to be XORed on the specified port
*
* @notapi
*/
#define pal_lld_toggleport(port, bits) __pal_lld_toggleport(port, bits)
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
__attribute__((always_inline))
static inline uint32_t __pal_lld_readport(ioportid_t port) {
__syscall2r(96, SB_VGPIO_READ, port);
return (ioportmask_t)r0;
}
__attribute__((always_inline))
static inline uint32_t __pal_lld_readlatch(ioportid_t port) {
__syscall2r(96, SB_VGPIO_READLATCH, port);
return (ioportmask_t)r0;
}
__attribute__((always_inline))
static inline void __pal_lld_writeport(ioportid_t port, uint32_t bits) {
__syscall3r(96, SB_VGPIO_WRITE, port, bits);
}
__attribute__((always_inline))
static inline void __pal_lld_setport(ioportid_t port, uint32_t bits) {
__syscall3r(96, SB_VGPIO_SET, port, bits);
}
__attribute__((always_inline))
static inline void __pal_lld_clearport(ioportid_t port, uint32_t bits) {
__syscall3r(96, SB_VGPIO_CLEAR, port, bits);
}
__attribute__((always_inline))
static inline void __pal_lld_toggleport(ioportid_t port, uint32_t bits) {
__syscall3r(96, SB_VGPIO_TOGGLE, port, bits);
}
#endif /* HAL_USE_PAL == TRUE */
#endif /* HAL_PAL_LLD_H */
/** @} */

View File

@ -0,0 +1,521 @@
/*
ChibiOS - Copyright (C) 2006..2021 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file sandbox/hal_sio_lld.c
* @brief Sandbox SIO subsystem low level driver source.
*
* @addtogroup SIO
* @{
*/
#include "hal.h"
#if (HAL_USE_SIO == TRUE) || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/**
* @brief VUART1 SIO driver identifier.
*/
#if (SB_SIO_USE_VUART1 == TRUE) || defined(__DOXYGEN__)
SIODriver SIOD1;
#endif
/**
* @brief VUART2 SIO driver identifier.
*/
#if (SB_SIO_USE_VUART2 == TRUE) || defined(__DOXYGEN__)
SIODriver SIOD2;
#endif
/*===========================================================================*/
/* Driver local variables and types. */
/*===========================================================================*/
/**
* @brief Driver default configuration.
*/
static const SIOConfig default_config = {
.ncfg = 0U
};
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
CC_FORCE_INLINE
static inline uint32_t __sio_vuart_init(uint32_t nvuart) {
__syscall2r(225, SB_VUART_INIT, nvuart);
return (uint32_t)r0;
}
CC_FORCE_INLINE
static inline uint32_t __sio_vuart_deinit(uint32_t nvuart) {
__syscall2r(225, SB_VUART_DEINIT, nvuart);
return (uint32_t)r0;
}
CC_FORCE_INLINE
static inline uint32_t __sio_vuart_setcfg(uint32_t nvuart, uint32_t ncfg) {
__syscall3r(225, SB_VUART_SETCFG, nvuart, ncfg);
return (uint32_t)r0;
}
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
#if SB_SIO_USE_VUART1 || defined(__DOXYGEN__)
#if !defined(SB_VUART1_SUPPRESS_ISR)
OSAL_IRQ_HANDLER(MK_VECTOR(SB_SIO_VUART1_IRQ)) {
OSAL_IRQ_PROLOGUE();
sio_lld_serve_interrupt(&SIOD1);
OSAL_IRQ_EPILOGUE();
}
#endif
#endif
#if SB_SIO_USE_VUART2 || defined(__DOXYGEN__)
#if !defined(SB_VUART2_SUPPRESS_ISR)
OSAL_IRQ_HANDLER(MK_VECTOR(SB_SIO_VUART2_IRQ)) {
OSAL_IRQ_PROLOGUE();
sio_lld_serve_interrupt(&SIOD2);
OSAL_IRQ_EPILOGUE();
}
#endif
#endif
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* @brief Low level SIO driver initialization.
*
* @notapi
*/
void sio_lld_init(void) {
/* Driver instances initialization.*/
#if SB_SIO_USE_VUART1 == TRUE
sioObjectInit(&SIOD1);
SIOD1.nvuart = 0U;
__sb_vrq_seten(1U << SB_SIO_VUART1_IRQ);
#endif
#if SB_SIO_USE_VUART2 == TRUE
sioObjectInit(&SIOD2);
SIOD2.nvuart = 1U;
__sb_vrq_seten(1U << SB_SIO_VUART2_IRQ);
#endif
}
/**
* @brief Configures and activates the SIO peripheral.
*
* @param[in] siop pointer to the @p SIODriver object
* @return The operation status.
*
* @notapi
*/
msg_t sio_lld_start(SIODriver *siop) {
msg_t msg = HAL_RET_SUCCESS;
/* Enables the peripheral.*/
if (false) {
}
#if SB_SIO_USE_VUART1 == TRUE
else if (&SIOD1 == siop) {
msg = (msg_t)__sio_vuart_init(siop->nvuart);
}
#endif
#if SB_SIO_USE_VUART2 == TRUE
else if (&SIOD2 == siop) {
msg = (msg_t)__sio_vuart_init(siop->nvuart);
}
#endif
else {
osalDbgAssert(false, "invalid SIO instance");
}
/* Configures the peripheral.*/
sio_lld_configure(siop, &default_config);
return msg;
}
/**
* @brief Deactivates the SIO peripheral.
*
* @param[in] siop pointer to the @p SIODriver object
*
* @notapi
*/
void sio_lld_stop(SIODriver *siop) {
msg_t msg = HAL_RET_SUCCESS;
/* Disables the peripheral.*/
if (false) {
}
#if SB_SIO_USE_VUART1 == TRUE
else if (&SIOD1 == siop) {
msg = __sio_vuart_deinit(siop->nvuart);
}
#endif
#if SB_SIO_USE_VUART2 == TRUE
else if (&SIOD2 == siop) {
msg = __sio_vuart_deinit(siop->nvuart);
}
#endif
else {
osalDbgAssert(false, "invalid SIO instance");
}
osalDbgAssert(msg = HAL_RET_SUCCESS, "unexpected failure");
}
msg_t sio_lld_configure(SIODriver *siop, const SIOConfig *config) {
return __sio_vuart_setcfg(siop->nvuart, config->ncfg);
}
/**
* @brief Determines the state of the RX FIFO.
*
* @param[in] siop pointer to the @p SIODriver object
* @return The RX FIFO state.
* @retval false if RX FIFO is not empty
* @retval true if RX FIFO is empty
*
* @notapi
*/
bool sio_lld_is_rx_empty(SIODriver *siop) {
__syscall2r(97, SB_VUART_ISRXE, siop->nvuart);
osalDbgAssert(r0 != (uint32_t)-1, "unexpected failure");
return (bool)r0;
}
/**
* @brief Determines the activity state of the receiver.
*
* @param[in] siop pointer to the @p SIODriver object
* @return The RX activity state.
* @retval false if RX is in active state.
* @retval true if RX is in idle state.
*
* @notapi
*/
bool sio_lld_is_rx_idle(SIODriver *siop) {
__syscall2r(97, SB_VUART_ISRXI, siop->nvuart);
osalDbgAssert(r0 != (uint32_t)-1, "unexpected failure");
return (bool)r0;
}
/**
* @brief Determines if RX has pending error events to be read and cleared.
* @note Only error and protocol errors are handled, data events are not
* considered.
*
* @param[in] siop pointer to the @p SIODriver object
* @return The RX error events.
* @retval false if RX has no pending events
* @retval true if RX has pending events
*
* @notapi
*/
bool sio_lld_has_rx_errors(SIODriver *siop) {
__syscall2r(97, SB_VUART_HASERR, siop->nvuart);
osalDbgAssert(r0 != (uint32_t)-1, "unexpected failure");
return (bool)r0;
}
/**
* @brief Determines the state of the TX FIFO.
*
* @param[in] siop pointer to the @p SIODriver object
* @return The TX FIFO state.
* @retval false if TX FIFO is not full
* @retval true if TX FIFO is full
*
* @notapi
*/
bool sio_lld_is_tx_full(SIODriver *siop) {
__syscall2r(97, SB_VUART_ISTXF, siop->nvuart);
osalDbgAssert(r0 != (uint32_t)-1, "unexpected failure");
return (bool)r0;
}
/**
* @brief Determines the transmission state.
*
* @param[in] siop pointer to the @p SIODriver object
* @return The TX FIFO state.
* @retval false if transmission is idle
* @retval true if transmission is ongoing
*
* @notapi
*/
bool sio_lld_is_tx_ongoing(SIODriver *siop) {
__syscall2r(97, SB_VUART_ISTXO, siop->nvuart);
osalDbgAssert(r0 != (uint32_t)-1, "unexpected failure");
return (bool)r0;
}
/**
* @brief Enable flags change notification.
*
* @param[in] siop pointer to the @p SIODriver object
*/
void sio_lld_update_enable_flags(SIODriver *siop) {
__syscall3r(97, SB_VUART_WREN, siop->nvuart, siop->enabled);
osalDbgAssert(r0 != (uint32_t)-1, "unexpected failure");
}
/**
* @brief Get and clears SIO error event flags.
*
* @param[in] siop pointer to the @p SIODriver object
* @return The pending event flags.
*
* @notapi
*/
sioevents_t sio_lld_get_and_clear_errors(SIODriver *siop) {
__syscall2r(97, SB_VUART_GCERR, siop->nvuart);
osalDbgAssert(r0 != (uint32_t)-1, "unexpected failure");
return (sioevents_t)r0;
}
/**
* @brief Get and clears SIO event flags.
*
* @param[in] siop pointer to the @p SIODriver object
* @param[in] events events to be returned and cleared
* @return The pending event flags.
*
* @notapi
*/
sioevents_t sio_lld_get_and_clear_events(SIODriver *siop, sioevents_t events) {
__syscall3r(97, SB_VUART_GCEVT, siop->nvuart, events);
osalDbgAssert(r0 != (uint32_t)-1, "unexpected failure");
return (sioevents_t)r0;
}
/**
* @brief Returns pending SIO event flags.
*
* @param[in] siop pointer to the @p SIODriver object
* @return The pending event flags.
*
* @notapi
*/
sioevents_t sio_lld_get_events(SIODriver *siop) {
__syscall2r(97, SB_VUART_GEVT, siop->nvuart);
osalDbgAssert(r0 != (uint32_t)-1, "unexpected failure");
return (sioevents_t)r0;
}
/**
* @brief Reads data from the RX FIFO.
* @details The function is not blocking, it writes frames until there
* is space available without waiting.
*
* @param[in] siop pointer to an @p SIODriver structure
* @param[in] buffer pointer to the buffer for read frames
* @param[in] n maximum number of frames to be read
* @return The number of frames copied from the buffer.
* @retval 0 if the TX FIFO is full.
*/
size_t sio_lld_read(SIODriver *siop, uint8_t *buffer, size_t n) {
__syscall4r(97, SB_VUART_READ, siop->nvuart, buffer, n);
osalDbgAssert(r0 != (uint32_t)-1, "unexpected failure");
return (size_t)r0;
}
/**
* @brief Writes data into the TX FIFO.
* @details The function is not blocking, it writes frames until there
* is space available without waiting.
*
* @param[in] siop pointer to an @p SIODriver structure
* @param[in] buffer pointer to the buffer for read frames
* @param[in] n maximum number of frames to be written
* @return The number of frames copied from the buffer.
* @retval 0 if the TX FIFO is full.
*/
size_t sio_lld_write(SIODriver *siop, const uint8_t *buffer, size_t n) {
__syscall4r(97, SB_VUART_WRITE, siop->nvuart, buffer, n);
osalDbgAssert(r0 != (uint32_t)-1, "unexpected failure");
return (size_t)r0;
}
/**
* @brief Returns one frame from the RX FIFO.
* @note If the FIFO is empty then the returned value is unpredictable.
*
* @param[in] siop pointer to the @p SIODriver object
* @return The frame from RX FIFO.
*
* @notapi
*/
msg_t sio_lld_get(SIODriver *siop) {
__syscall2r(97, SB_VUART_GET, siop->nvuart);
osalDbgAssert(r0 != (uint32_t)-1, "unexpected failure");
return (size_t)r0;
}
/**
* @brief Pushes one frame into the TX FIFO.
* @note If the FIFO is full then the behavior is unpredictable.
*
* @param[in] siop pointer to the @p SIODriver object
* @param[in] data frame to be written
*
* @notapi
*/
void sio_lld_put(SIODriver *siop, uint_fast16_t data) {
__syscall3r(97, SB_VUART_PUT, siop->nvuart, data);
osalDbgAssert(r0 != (uint32_t)-1, "unexpected failure");
}
/**
* @brief Control operation on a serial port.
*
* @param[in] siop pointer to the @p SIODriver object
* @param[in] operation control operation code
* @param[in,out] arg operation argument
*
* @return The control operation status.
* @retval MSG_OK in case of success.
* @retval MSG_TIMEOUT in case of operation timeout.
* @retval MSG_RESET in case of operation reset.
*
* @notapi
*/
msg_t sio_lld_control(SIODriver *siop, unsigned int operation, void *arg) {
__syscall4r(97, SB_VUART_CTL, siop->nvuart, operation, arg);
osalDbgAssert(r0 != (uint32_t)-1, "unexpected failure");
return (msg_t)r0;
}
/**
* @brief Serves an VUART interrupt.
*
* @param[in] siop pointer to the @p SIODriver object
*
* @notapi
*/
void sio_lld_serve_interrupt(SIODriver *siop) {
sioevents_t events;
#if SIO_USE_SYNCHRONIZATION == TRUE
__syscall2rr(97, SB_VUART_GEVT, siop->nvuart);
osalDbgAssert(r0 != (uint32_t)-1, "unexpected failure");
/* Processing enabled events, if any.*/
events = (sioevents_t)r0 & siop->enabled;
if (events != (sioevents_t)0) {
/* Error events handled as a group.*/
if ((events & SIO_EV_ALL_ERRORS) != 0U) {
/* Waiting thread woken, if any.*/
__sio_wakeup_errors(siop);
}
/* If there are no errors then we check for the other RX events.*/
else {
/* Idle RX event.*/
if ((events & SIO_EV_RX_IDLE) != 0U) {
/* Waiting thread woken, if any.*/
__sio_wakeup_rxidle(siop);
}
/* RX FIFO is non-empty.*/
if ((events & SIO_EV_RX_NOTEMPTY) != 0U) {
/* Waiting thread woken, if any.*/
__sio_wakeup_rx(siop);
}
}
/* TX FIFO is non-full.*/
if ((events & SIO_EV_TX_NOTFULL) != 0U) {
/* Waiting thread woken, if any.*/
__sio_wakeup_tx(siop);
}
/* Physical transmission end.*/
if ((events & SIO_EV_TX_END) != 0U) {
/* Waiting thread woken, if any.*/
__sio_wakeup_txend(siop);
}
/* The callback is finally invoked.*/
__sio_callback(siop);
}
#else
/* Simply invokes the callback.*/
__sio_callback(siop);
#endif
}
#endif /* HAL_USE_SIO == TRUE */
/** @} */

View File

@ -0,0 +1,151 @@
/*
ChibiOS - Copyright (C) 2006..2021 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file sandbox/hal_sio_lld.h
* @brief Sandbox SIO subsystem low level driver header.
*
* @addtogroup SIO
* @{
*/
#ifndef HAL_SIO_LLD_H
#define HAL_SIO_LLD_H
#if (HAL_USE_SIO == TRUE) || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/**
* @name VSIO configuration options
* @{
*/
/**
* @brief SIO driver 1 enable switch.
* @details If set to @p TRUE the support for VUART1 is included.
* @note The default is @p FALSE.
*/
#if !defined(SB_SIO_USE_VUART1) || defined(__DOXYGEN__)
#define SB_SIO_USE_VUART1 FALSE
#endif
/**
* @brief SIO driver 2 enable switch.
* @details If set to @p TRUE the support for VUART2 is included.
* @note The default is @p FALSE.
*/
#if !defined(SB_SIO_USE_VUART2) || defined(__DOXYGEN__)
#define SB_SIO_USE_VUART2 FALSE
#endif
/**
* @brief SIO driver 1 virtual IRQ number.
* @details If set to @p TRUE the support for VUART1 is included.
* @note Must match with the IRQ number generated by the host.
*/
#if !defined(SB_SIO_VUART1_IRQ) || defined(__DOXYGEN__)
#define SB_SIO_VUART1_IRQ 8
#endif
/**
* @brief SIO driver 2 virtual IRQ number.
* @details If set to @p TRUE the support for VUART1 is included.
* @note Must match with the IRQ number generated by the host.
*/
#if !defined(SB_SIO_VUART2_IRQ) || defined(__DOXYGEN__)
#define SB_SIO_VUART2_IRQ 9
#endif
/** @} */
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
#if !SB_SIO_USE_VUART1 && !SB_SIO_USE_VUART2
#error "SIO driver activated but no VUART peripheral assigned"
#endif
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
/**
* @brief Low level fields of the SIO driver structure.
*/
#define sio_lld_driver_fields \
/* Number of the associated VUART.*/ \
uint32_t nvuart
/**
* @brief Low level fields of the SIO configuration structure.
*/
#define sio_lld_config_fields \
/* Predefined configuration index.*/ \
uint32_t ncfg
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#if (SB_SIO_USE_VUART1 == TRUE) && !defined(__DOXYGEN__)
extern SIODriver SIOD1;
#endif
#if (SB_SIO_USE_VUART2 == TRUE) && !defined(__DOXYGEN__)
extern SIODriver SIOD2;
#endif
#ifdef __cplusplus
extern "C" {
#endif
void sio_lld_init(void);
msg_t sio_lld_start(SIODriver *siop);
void sio_lld_stop(SIODriver *siop);
msg_t sio_lld_configure(SIODriver *siop, const SIOConfig *config);
bool sio_lld_is_rx_empty(SIODriver *siop);
bool sio_lld_is_rx_idle(SIODriver *siop);
bool sio_lld_has_rx_errors(SIODriver *siop);
bool sio_lld_is_tx_full(SIODriver *siop);
bool sio_lld_is_tx_ongoing(SIODriver *siop);
void sio_lld_update_enable_flags(SIODriver *siop);
sioevents_t sio_lld_get_and_clear_errors(SIODriver *siop);
sioevents_t sio_lld_get_and_clear_events(SIODriver *siop, sioevents_t events);
sioevents_t sio_lld_get_events(SIODriver *siop);
size_t sio_lld_read(SIODriver *siop, uint8_t *buffer, size_t n);
size_t sio_lld_write(SIODriver *siop, const uint8_t *buffer, size_t n);
msg_t sio_lld_get(SIODriver *siop);
void sio_lld_put(SIODriver *siop, uint_fast16_t data);
msg_t sio_lld_control(SIODriver *siop, unsigned int operation, void *arg);
void sio_lld_serve_interrupt(SIODriver *siop);
#ifdef __cplusplus
}
#endif
#endif /* HAL_USE_SIO == TRUE */
#endif /* HAL_SIO_LLD_H */
/** @} */

View File

@ -0,0 +1,82 @@
/*
ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file sandbox/hal_st_lld.c
* @brief ST Driver subsystem low level driver code.
*
* @addtogroup ST
* @{
*/
#include "hal.h"
#if (OSAL_ST_MODE != OSAL_ST_MODE_NONE) || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local types. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local variables and types. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
/**
* @brief Interrupt handler.
*
* @isr
*/
OSAL_IRQ_HANDLER(xxxxx) {
OSAL_IRQ_PROLOGUE();
// st_lld_serve_interrupt();
OSAL_IRQ_EPILOGUE();
}
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* @brief Low level ST driver initialization.
*
* @notapi
*/
void st_lld_init(void) {
}
#endif /* OSAL_ST_MODE != OSAL_ST_MODE_NONE */
/** @} */

View File

@ -0,0 +1,94 @@
/*
ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file sandbox/hal_st_lld.h
* @brief ST Driver subsystem low level driver header.
* @details This header is designed to be include-able without having to
* include other files from the HAL.
*
* @addtogroup ST
* @{
*/
#ifndef HAL_ST_LLD_H
#define HAL_ST_LLD_H
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/**
* @name Configuration options
* @{
*/
/**
* @brief SysTick timer IRQ priority.
*/
#if !defined(STM32_ST_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_ST_VRQ_VECTOR 0
#endif
/** @} */
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
#if OSAL_ST_MODE == OSAL_ST_MODE_FREERUNNING
#error "OSAL_ST_MODE_FREERUNNING unsupported"
#elif OSAL_ST_MODE == OSAL_ST_MODE_PERIODIC
#elif OSAL_ST_MODE == OSAL_ST_MODE_NONE
#else
#error "invalid OSAL_ST_MODE"
#endif
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#ifdef __cplusplus
extern "C" {
#endif
void st_lld_init(void);
#ifdef __cplusplus
}
#endif
/*===========================================================================*/
/* Driver inline functions. */
/*===========================================================================*/
#endif /* HAL_ST_LLD_H */
/** @} */

View File

@ -0,0 +1,31 @@
# Required platform files.
PLATFORMSRC := $(CHIBIOS)/os/xhal/ports/vio/hal_lld.c \
$(CHIBIOS)/os/xhal/ports/vio/hal_st_lld.c \
$(CHIBIOS)/os/xhal/ports/vio/hal_pal_lld.c \
$(CHIBIOS)/os/xhal/ports/vio/hal_sio_lld.c
# Required include directories.
PLATFORMINC := $(CHIBIOS)/os/xhal/ports/vio
# Optional platform files.
ifeq ($(USE_SMART_BUILD),yes)
# Configuration files directory
ifeq ($(HALCONFDIR),)
ifeq ($(CONFDIR),)
HALCONFDIR = .
else
HALCONFDIR := $(CONFDIR)
endif
endif
HALCONF := $(strip $(shell cat $(HALCONFDIR)/halconf.h | egrep -e "\#define"))
else
endif
# Drivers compatible with the platform.
# Shared variables
ALLCSRC += $(PLATFORMSRC)
ALLINC += $(PLATFORMINC)

View File

@ -280,7 +280,10 @@ msg_t drvStart(void *ip) {
osalSysLock();
osalDbgAssert(self->state != HAL_DRV_STATE_UNINIT, "not initialized");
osalDbgAssert((self->state != HAL_DRV_STATE_UNINIT) &&
(self->state != HAL_DRV_STATE_STOPPING) &&
(self->state != HAL_DRV_STATE_STARTING),
"invalid state");
if (self->state == HAL_DRV_STATE_STOP) {
/* Physically starting the peripheral.*/
@ -288,6 +291,9 @@ msg_t drvStart(void *ip) {
if (msg == HAL_RET_SUCCESS) {
self->state = HAL_DRV_STATE_READY;
}
else {
self->state = HAL_DRV_STATE_STOP;
}
}
osalSysUnlock();
@ -314,7 +320,9 @@ void drvStop(void *ip) {
osalSysLock();
osalDbgAssert(self->state != HAL_DRV_STATE_UNINIT, "not initialized");
osalDbgAssert((self->state != HAL_DRV_STATE_UNINIT) &&
(self->state != HAL_DRV_STATE_STARTING),
"invalid state");
if (self->state != HAL_DRV_STATE_STOP) {
__drv_stop(self);

View File

@ -95,6 +95,61 @@ static size_t sio_sync_read(hal_sio_driver_c *siop, uint8_t *bp, size_t n,
}
#endif /* SIO_USE_STREAMS_INTERFACE == TRUE */
#if (SIO_USE_BUFFERING == TRUE) || defined (__DOXYGEN__)
static void __bsio_push_data(hal_buffered_sio_c *bsiop) {
while (!sioIsTXFullX(bsiop->siop)) {
msg_t msg;
msg = oqGetI(&bsiop->oqueue);
if (msg < MSG_OK) {
bsAddFlagsI(bsiop, CHN_FL_TX_NOTFULL);
return;
}
sioPutX(bsiop->siop, (uint_fast16_t)msg);
}
}
static void __bsio_pop_data(hal_buffered_sio_c *bsiop) {
/* RX FIFO needs to be fully emptied or SIO will not generate more RX FIFO
events.*/
while (!sioIsRXEmptyX(bsiop->siop)) {
bsIncomingDataI(bsiop, sioGetX(bsiop->siop));
}
}
static void __bsio_default_cb(hal_sio_driver_c *siop) {
hal_buffered_sio_c *bsiop = (hal_buffered_sio_c *)siop->arg;
sioevents_t events;
osalSysLockFromISR();
/* Posting the non-data SIO events as channel event flags, the masks are
made to match.*/
events = sioGetAndClearEventsX(siop, SIO_EV_ALL_EVENTS);
bsAddFlagsI(bsiop, (eventflags_t)(events & ~SIO_EV_ALL_DATA));
/* RX FIFO event.*/
if ((events & SIO_EV_RX_NOTEMPTY) != (sioevents_t)0) {
__bsio_pop_data(bsiop);
}
/* TX FIFO event.*/
if ((events & SIO_EV_TX_NOTFULL) != (sioevents_t)0) {
__bsio_push_data(bsiop);
}
osalSysUnlockFromISR();
}
static void __bsio_onotify(io_queue_t *qp) {
__bsio_push_data((hal_buffered_sio_c *)qp->q_link);
}
#endif /* SIO_USE_BUFFERING == TRUE */
/*===========================================================================*/
/* Module exported functions. */
/*===========================================================================*/
@ -698,7 +753,7 @@ sioevents_t sioGetEvents(void *ip) {
* @note This function can only be called by a single thread at time.
*
* @param[in,out] ip Pointer to a @p hal_sio_driver_c instance.
* @param[in] timeout Synchronization timeout.
* @param[in] timeout Synchronization timeout
* @return The synchronization result.
* @retval MSG_OK If there is data in the RX FIFO.
* @retval MSG_TIMEOUT If synchronization timed out.
@ -748,7 +803,7 @@ msg_t sioSynchronizeRX(void *ip, sysinterval_t timeout) {
* @note This function can only be called by a single thread at time.
*
* @param[in,out] ip Pointer to a @p hal_sio_driver_c instance.
* @param[in] timeout Synchronization timeout.
* @param[in] timeout Synchronization timeout
* @return The synchronization result.
* @retval MSG_OK If there is data in the RX FIFO.
* @retval MSG_TIMEOUT If synchronization timed out.
@ -800,7 +855,7 @@ msg_t sioSynchronizeRXIdle(void *ip, sysinterval_t timeout) {
* @note This function can only be called by a single thread at time.
*
* @param[in,out] ip Pointer to a @p hal_sio_driver_c instance.
* @param[in] timeout Synchronization timeout.
* @param[in] timeout Synchronization timeout
* @return The synchronization result.
* @retval MSG_OK If there is space in the TX FIFO.
* @retval MSG_TIMEOUT If synchronization timed out.
@ -843,7 +898,7 @@ msg_t sioSynchronizeTX(void *ip, sysinterval_t timeout) {
* @note This function can only be called by a single thread at time.
*
* @param[in,out] ip Pointer to a @p hal_sio_driver_c instance.
* @param[in] timeout Synchronization timeout.
* @param[in] timeout Synchronization timeout
* @return The synchronization result.
* @retval MSG_OK If there is space in the TX FIFO.
* @retval MSG_TIMEOUT If synchronization timed out.
@ -879,6 +934,144 @@ msg_t sioSynchronizeTXEnd(void *ip, sysinterval_t timeout) {
#endif /* SIO_USE_SYNCHRONIZATION == TRUE */
/** @} */
/*===========================================================================*/
/* Module class "hal_buffered_sio_c" methods. */
/*===========================================================================*/
/**
* @name Methods implementations of hal_buffered_sio_c
* @{
*/
/**
* @memberof hal_buffered_sio_c
* @protected
*
* @brief Implementation of object creation.
* @note This function is meant to be used by derived classes.
*
* @param[out] ip Pointer to a @p hal_buffered_sio_c instance to
* be initialized.
* @param[in] vmt VMT pointer for the new object.
* @param[in] siop Pointer to the @p hal_sio_driver_c object.
* @param[in] ib Pointer to the input buffer.
* @param[in] ibsize Size of the input buffer.
* @param[in] ob Pointer to the output buffer.
* @param[in] obsize Size of the output buffer.
* @return A new reference to the object.
*/
void *__bsio_objinit_impl(void *ip, const void *vmt, hal_sio_driver_c *siop,
uint8_t *ib, size_t ibsize, uint8_t *ob,
size_t obsize) {
hal_buffered_sio_c *self = (hal_buffered_sio_c *)ip;
/* Initialization code.*/
__bs_objinit_impl((void *)self, (const void *)&vmt,
ib, ibsize, NULL, NULL,
ob, obsize, __bsio_onotify, (void *)self);
drvSetArgumentX(siop, self);
self->siop = siop;
return self;
}
/**
* @memberof hal_buffered_sio_c
* @protected
*
* @brief Implementation of object finalization.
* @note This function is meant to be used by derived classes.
*
* @param[in,out] ip Pointer to a @p hal_buffered_sio_c instance to
* be disposed.
*/
void __bsio_dispose_impl(void *ip) {
hal_buffered_sio_c *self = (hal_buffered_sio_c *)ip;
/* No finalization code.*/
(void)self;
/* Finalization of the ancestors-defined parts.*/
__bs_dispose_impl(self);
}
/**
* @memberof hal_buffered_sio_c
* @protected
*
* @brief Override of method @p __drv_start().
*
* @param[in,out] ip Pointer to a @p hal_buffered_sio_c instance.
* @return The operation status.
*/
msg_t __bsio_start_impl(void *ip) {
hal_buffered_sio_c *self = (hal_buffered_sio_c *)ip;
msg_t msg;
/* Start is a slow operation in this driver, we need to switch to the
HAL_DRV_STATE_STARTING state.*/
self->state = HAL_DRV_STATE_STARTING;
osalSysUnlock();
/* Starting the undelying SIO driver.*/
msg = drvStart(self->siop);
if (msg == HAL_RET_SUCCESS) {
sioSetCallbackX(self->siop, &__bsio_default_cb);
sioWriteEnableFlagsX(self->siop, SIO_EV_ALL_EVENTS);
}
/* Back into the critical section and return.*/
osalSysLock();
return msg;
}
/**
* @memberof hal_buffered_sio_c
* @protected
*
* @brief Override of method @p __drv_stop().
*
* @param[in,out] ip Pointer to a @p hal_buffered_sio_c instance.
*/
void __bsio_stop_impl(void *ip) {
hal_buffered_sio_c *self = (hal_buffered_sio_c *)ip;
/* Start is a slow operation in this driver, we need to switch to the
HAL_DRV_STATE_STOPPING state.*/
self->state = HAL_DRV_STATE_STOPPING;
osalSysUnlock();
drvStop(self->siop);
/* Back into the critical section and return.*/
osalSysLock();
}
/**
* @memberof hal_buffered_sio_c
* @protected
*
* @brief Override of method @p drvConfigureX().
*
* @param[in,out] ip Pointer to a @p hal_buffered_sio_c instance.
* @param[in] config New driver configuration.
*/
msg_t __bsio_configure_impl(void *ip, const void *config) {
hal_buffered_sio_c *self = (hal_buffered_sio_c *)ip;
return drvConfigureX(self->siop, config);
}
/** @} */
/**
* @brief VMT structure of buffered SIO wrapper class.
* @note It is public because accessed by the inlined constructor.
*/
const struct hal_buffered_sio_vmt __hal_buffered_sio_vmt = {
.dispose = __bsio_dispose_impl,
.start = __bsio_start_impl,
.stop = __bsio_stop_impl,
.configure = __bsio_configure_impl
};
#endif /* HAL_USE_SIO == TRUE */
/** @} */