ChibiOS/os/xhal/codegen/hal_base_driver.xml

477 lines
17 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_base_driver" descr="Base Driver" editcode="false">
<brief>Common driver base abstract class.</brief>
<details><![CDATA[This abstract class is the common ancestor of all HAL
stateful HAL drivers.]]></details>
<imports>
<import>oop_base_object.xml</import>
</imports>
<public>
<definitions_early>
<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_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" />
</group>
</definitions_early>
<configs>
<config name="HAL_USE_MUTUAL_EXCLUSION" default="TRUE">
<brief>Enables the mutual exclusion APIs on driver instances.</brief>
<note>Disabling this option saves both code and data space.</note>
<assert invalid="($N != FALSE) &amp;&amp; ($N != TRUE)" />
</config>
<config name="HAL_USE_REGISTRY" default="TRUE">
<brief>Enables the HAL registry for drivers.</brief>
<note>Disabling this option saves both code and data space.</note>
<assert invalid="($N != FALSE) &amp;&amp; ($N != TRUE)" />
</config>
</configs>
<macros></macros>
<types>
<typedef name="hal_base_driver_c">
<basetype ctype="struct hal_base_driver" />
</typedef>
<typedef name="driver_state_t">
<brief>Type of a driver state variable.</brief>
<basetype ctype="unsigned int" />
</typedef>
<condition check="HAL_USE_REGISTRY == TRUE">
<typedef name="hal_regent_t">
<brief>Type of a registry entry structure.</brief>
<basetype ctype="struct hal_regent" />
</typedef>
<struct name="hal_regent">
<brief>Structure representing a registry entry.</brief>
<fields>
<field name="next" ctype="hal_regent_t$I*">
<brief>Next entry in the drivers registry.</brief>
</field>
<field name="prev" ctype="hal_regent_t$I*">
<brief>Previous entry in the drivers registry.</brief>
</field>
</fields>
</struct>
</condition>
<class type="abstract" name="hal_base_driver" namespace="drv"
ancestorname="base_object" descr="HAL base driver">
<brief>Ancestor class of stateful HAL drivers.</brief>
<fields>
<field name="state" ctype="driver_state_t">
<brief>Driver state.</brief>
</field>
<field name="config" ctype="const void$I*">
<brief>Associated configuration structure.</brief>
</field>
<field name="arg" ctype="void$I*">
<brief>Driver argument.</brief>
</field>
<condition check="HAL_USE_MUTUAL_EXCLUSION == TRUE">
<field name="mutex" ctype="mutex_t">
<brief>Driver mutex.</brief>
</field>
</condition>
<condition check="HAL_USE_REGISTRY == TRUE">
<field name="id" ctype="unsigned int">
<brief>Driver identifier.</brief>
</field>
<field name="name" ctype="const char$I*">
<brief>Driver name.</brief>
</field>
<field name="regent" ctype="hal_regent_t">
<brief>Registry link structure.</brief>
</field>
</condition>
</fields>
<methods>
<objinit callsuper="true">
<implementation><![CDATA[
self->state = HAL_DRV_STATE_STOP;
self->arg = NULL;
self->config = NULL;
osalMutexObjectInit(&self->mutex);
#if HAL_USE_REGISTRY == TRUE
self->id = 0U;
self->name = "unk";
drv_reg_insert(self);
#endif]]></implementation>
</objinit>
<dispose>
<implementation><![CDATA[
#if HAL_USE_REGISTRY == TRUE
drv_reg_remove(self);
#endif]]></implementation>
</dispose>
<virtual>
<method name="__drv_start" shortname="start" ctype="msg_t">
<brief>Low level driver start.</brief>
<return>The operation status.</return>
<notapi />
</method>
<method name="__drv_stop" shortname="stop" ctype="void">
<brief>Low level driver stop.</brief>
<notapi />
</method>
<method name="__drv_do_configure" shortname="doconf"
ctype="const void *">
<brief>Performs driver configuration.</brief>
<param ctype="const void *" name="config" dir="in">New driver
configuration.</param>
<return>The configuration pointer.</return>
<retval value="NULL">If the configuration has been rejected.</retval>
<api />
</method>
</virtual>
<regular>
<method name="drvStart" ctype="msg_t">
<brief>Driver start.</brief>
<details><![CDATA[Starts driver operations, on the 1st
call the peripheral is physically initialized using a
default configuration, subsequent calls are ignored.]]>
</details>
<note><![CDATA[The function can fail with error
@p HAL_RET_INV_STATE if called while the driver is already
being started or stopped. In case you need multiple threads
to perform start and stop operation on the driver then it is
suggested to lock/unlock the driver during such operations.]]></note>
<return>The operation status.</return>
<retval value="HAL_RET_SUCCESS">Operation successful.</retval>
<retval value="HAL_RET_INV_STATE"><![CDATA[If the driver was
in one of @p HAL_DRV_STATE_UNINIT, @p HAL_DRV_STATE_STARTING
or @p HAL_DRV_STATE_STOPPING states.]]></retval>
<retval value="HAL_RET_NO_RESOURCE">If a required resources
cannot be allocated.
</retval>
<retval value="HAL_RET_HW_BUSY">If a required HW resource is
already in use.
</retval>
<retval value="HAL_RET_HW_FAILURE">If an HW failure occurred.</retval>
<api />
<implementation><![CDATA[
msg_t msg = HAL_RET_SUCCESS;
osalDbgCheck(self != NULL);
osalSysLock();
switch (self->state) {
case HAL_DRV_STATE_UNINIT:
/* Falls through.*/
case HAL_DRV_STATE_STARTING:
/* Falls through.*/
case HAL_DRV_STATE_STOPPING:
msg = HAL_RET_INV_STATE;
break;
case HAL_DRV_STATE_STOP:
/* Physically starting the peripheral.*/
msg = __drv_start(self);
if (msg == HAL_RET_SUCCESS) {
self->state = HAL_DRV_STATE_READY;
/* LLD is supposed to set a default configuration.*/
osalDbgAssert(self->config != NULL, "no configuration");
}
else {
self->state = HAL_DRV_STATE_STOP;
}
default:
/* Any other state ignored, driver already started.*/
break;
}
osalSysUnlock();
return msg;]]></implementation>
</method>
<method name="drvStop" ctype="void">
<brief>Driver close.</brief>
<details><![CDATA[Stops driver operations. The peripheral
is physically uninitialized.]]>
</details>
<api />
<implementation><![CDATA[
osalDbgCheck(self != NULL);
osalSysLock();
osalDbgAssert(self->state != HAL_DRV_STATE_UNINIT, "invalid state");
if ((self->state != HAL_DRV_STATE_STOP) &&
(self->state != HAL_DRV_STATE_STARTING)) {
__drv_stop(self);
self->state = HAL_DRV_STATE_STOP;
self->config = NULL;
}
osalSysUnlock();]]></implementation>
</method>
<method name="drvConfigureX" ctype="msg_t">
<brief>Driver configure.</brief>
<details><![CDATA[Applies a new configuration to the driver. The
configuration structure is architecture-dependent.]]>
</details>
<note><![CDATA[Applying a configuration should be done while the
peripheral is not actively operating, this function can fail
depending on the driver implementation and current state.]]>
</note>
<param ctype="const void *" name="config" dir="in">New driver
configuration.
</param>
<api />
<implementation><![CDATA[]]>
msg_t msg;
osalSysLock();
osalDbgAssert(self->state != HAL_DRV_STATE_UNINIT, "invalid state");
self->config = __drv_do_configure(self, config);
if (self->config == NULL) {
msg = HAL_RET_CONFIG_ERROR;
}
else {
msg = HAL_RET_SUCCESS;
}
osalSysUnlock();
return msg;</implementation>
</method>
</regular>
<inline>
<method name="drvGetStateX" ctype="driver_state_t">
<brief>Driver state get.</brief>
<return>The driver state.</return>
<api />
<implementation><![CDATA[
return self->state;]]></implementation>
</method>
<method name="drvSetStateX" ctype="void">
<brief>Driver state set.</brief>
<param ctype="driver_state_t" name="state" dir="in">New driver
state.
</param>
<api />
<implementation><![CDATA[
self->state = state;]]></implementation>
</method>
<method name="drvGetArgumentX" ctype="void *">
<brief>Driver argument get.</brief>
<return>The driver argument.</return>
<api />
<implementation><![CDATA[
return self->arg;]]></implementation>
</method>
<method name="drvSetArgumentX" ctype="void">
<brief>Driver argument set.</brief>
<param ctype="void *" name="arg" dir="in">New driver argument.
</param>
<api />
<implementation><![CDATA[
self->arg = arg;]]></implementation>
</method>
<method name="drvGetNameX" ctype="const char *">
<brief>Driver name get.</brief>
<note>Returns "unk" if registry is disabled.</note>
<return>The driver name.</return>
<api />
<implementation><![CDATA[
#if HAL_USE_REGISTRY == TRUE
return self->name;
#else
return "unk";
#endif]]></implementation>
</method>
<method name="drvSetNameX" ctype="void">
<brief>Driver name set.</brief>
<note>Does nothing if registry is disabled.</note>
<param ctype="const char *" name="name" dir="in">
New driver name.
</param>
<api />
<implementation><![CDATA[
#if HAL_USE_REGISTRY == TRUE
self->name = name;
#else
(void)name;
#endif]]></implementation>
</method>
<condition check="HAL_USE_MUTUAL_EXCLUSION == TRUE">
<method name="drvLock" ctype="void">
<brief>Driver lock.</brief>
<api />
<implementation><![CDATA[
osalMutexLock(&self->mutex);]]></implementation>
</method>
<method name="drvUnlock" ctype="void">
<brief>Driver unlock.</brief>
<api />
<implementation><![CDATA[
osalMutexUnlock(&self->mutex);]]></implementation>
</method>
</condition>
</inline>
</methods>
</class>
</types>
<variables>
<condition check="HAL_USE_REGISTRY == TRUE">
<variable name="hal_registry" ctype="hal_regent_t">
<brief>List header for the HAL registry</brief>
</variable>
</condition>
</variables>
<functions>
<function name="drvInit" ctype="void">
<brief>Drivers manager initialization.</brief>
<init />
<implementation><![CDATA[
#if HAL_USE_REGISTRY == TRUE
/* Registry list initialization.*/
hal_registry.next = &hal_registry;
hal_registry.prev = &hal_registry;
#endif
]]></implementation>
</function>
<condition check="HAL_USE_REGISTRY == TRUE">
<function name="drvRegGetFirstX" ctype="hal_base_driver_c *">
<brief>Return the first driver in the HAL registry.</brief>
<return>A pointer to the first driver object.</return>
<retval value="NULL">If the registry is empty.</retval>
<api />
<implementation><![CDATA[
hal_regent_t *rep;
rep = hal_registry.next;
if (rep == &hal_registry) {
return NULL;
}
return oopGetOwner(hal_base_driver_c, regent, rep);]]></implementation>
</function>
<function name="drvRegGetNextX" ctype="hal_base_driver_c *">
<brief>Return the next driver in the HAL registry.</brief>
<note>
This function is only available when HAL registry is enabled.
</note>
<param name="drvp" ctype="hal_base_driver_c *" dir="in">
Previously
found driver.
</param>
<return>A pointer to the next driver object.</return>
<retval value="NULL">If there is no next driver.</retval>
<api />
<implementation><![CDATA[
hal_regent_t *rep;
rep = drvp->regent.next;
if (rep == &hal_registry) {
return NULL;
}
return oopGetOwner(hal_base_driver_c, regent, rep);]]></implementation>
</function>
<function name="drvStartByName" ctype="hal_base_driver_c *">
<brief>Driver open by name.</brief>
<details><![CDATA[Returns a reference to the driver, on the
1st open the peripheral is physically initialized. An
implementation-dependent default configuration is used
for initialization.]]>
</details>
<note>
This function is only available when HAL registry is enabled.
</note>
<param name="name" ctype="const char *" dir="in">Driver name.</param>
<param name="msgp" ctype="msg_t *" dir="out">
Pointer to store the
error code or @p NULL. Note that in case of
driver not found the
returned code is @p HAL_RET_SUCCESS.
</param>
<return>A reference to the driver.</return>
<retval value="NULL">If an error occurred.</retval>
<api />
<implementation><![CDATA[
msg_t msg = HAL_RET_SUCCESS;
hal_base_driver_c *drvp;
osalSysLock();
drvp = drvRegGetFirstX();
while (drvp != NULL) {
if (strcmp(drvGetNameX(drvp), name) ==0) {
msg = drvStart(drvp);
if (msg != HAL_RET_SUCCESS) {
drvp = NULL;
}
break;
}
drvp = drvRegGetNextX(drvp);
}
if (msgp != NULL) {
*msgp = msg;
}
osalSysUnlock();
return drvp;]]></implementation>
</function>
</condition>
</functions>
</public>
<private>
<includes>
<include style="angular">string.h</include>
<include style="regular">hal.h</include>
</includes>
<functions>
<condition check="HAL_USE_REGISTRY == TRUE">
<function name="drv_reg_insert" ctype="void">
<brief>Driver insertion in the HAL registry.</brief>
<note>
This function is only available when HAL registry is enabled.
</note>
<param name="drvp" ctype="hal_base_driver_c *" dir="both">
Pointer to
the @p hal_base_driver_c instance to be inserted.
</param>
<implementation><![CDATA[
drvp->regent.next = &hal_registry;
drvp->regent.prev = hal_registry.prev;
drvp->regent.prev->next = &drvp->regent;
hal_registry.prev = &drvp->regent;]]></implementation>
</function>
<function name="drv_reg_remove" ctype="void">
<brief>Driver removal from the HAL registry.</brief>
<param name="drvp" ctype="hal_base_driver_c *" dir="both">
Pointer to
the @p hal_base_driver_c instance to be inserted.
</param>
<implementation><![CDATA[
drvp->regent.prev->next = drvp->regent.next;
drvp->regent.next->prev = drvp->regent.prev;
]]></implementation>
</function>
</condition>
</functions>
</private>
</module>