More SPI work in XHAL.

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@16281 27425a3e-05d8-49a3-a47f-9c15f0e5edd8
This commit is contained in:
Giovanni Di Sirio 2023-06-14 09:47:32 +00:00
parent f74f12ff56
commit a688fcbbf0
3 changed files with 128 additions and 326 deletions

View File

@ -31,10 +31,10 @@
<brief>Support for thread synchronization API.</brief>
<assert invalid="($N != FALSE) &amp;&amp; ($N != TRUE)" />
</config>
<config name="SPI_SELECT_MODE"
default="SPI_SELECT_MODE_PAD">
<config name="SPI_SELECT_MODE" default="SPI_SELECT_MODE_PAD">
<brief>Handling method for SPI CS line.</brief>
<assert invalid="($N &lt; SPI_SELECT_MODE_NONE) || ($N &gt; SPI_SELECT_MODE_LLD)" />
<assert
invalid="($N &lt; SPI_SELECT_MODE_NONE) || ($N &gt; SPI_SELECT_MODE_LLD)" />
</config>
</configs>
<types>
@ -44,8 +44,7 @@
</typedef>
<typedef name="SPIConfig">
<brief>Type of structure representing a SPI configuration
(legacy).
</brief>
(legacy).</brief>
<basetype ctype="struct hal_spi_config" />
</typedef>
<typedef name="SPIDriver">
@ -137,74 +136,58 @@ SPI_DRIVER_EXT_INIT_HOOK(self);
<dispose>
<implementation><![CDATA[ ]]></implementation>
</dispose>
</methods>
</class>
<class name="hal_buffered_spi" type="regular" namespace="bspi"
descr="buffered SPI wrapper" ancestorname="hal_buffered_serial">
<brief>This class implements a buffered channel interface on top of SPI.</brief>
<fields>
<field name="spip" ctype="hal_spi_driver_c$I*">
<brief>Pointer to the associated @p hal_spi_driver_c instance.</brief>
</field>
</fields>
<methods>
<objinit callsuper="false">
<param name="spip" ctype="hal_spi_driver_c *" dir="in">Pointer to
the @p hal_spi_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>
<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[
__bs_objinit_impl((void *)self, vmt,
ib, ibsize, NULL, NULL,
ob, obsize, __bspi_onotify, (void *)self);
drvSetArgumentX(spip, self);
self->spip = spip;]]></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 SPI driver.*/
msg = drvStart(self->spip);
if (msg == HAL_RET_SUCCESS) {
spiSetCallbackX(self->spip, &__bspi_default_cb);
spiWriteEnableFlagsX(self->spip, SPI_EV_ALL_EVENTS);
}
/* Back into the critical section and return.*/
osalSysLock();
return msg;]]></implementation>
spi_lld_select(self);]]></implementation>
</method>
<method shortname="stop">
<method name="spiUnselectX" ctype="void">
<brief>Deasserts the slave select signal.</brief>
<xclass />
<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->spip);
/* Back into the critical section and return.*/
osalSysLock();]]></implementation>
spi_lld_unselect(self);]]></implementation>
</method>
<method shortname="configure">
<elseif check="SPI_SELECT_MODE == SPI_SELECT_MODE_LINE" />
<method name="spiSelectX" ctype="void">
<implementation><![CDATA[
return drvConfigureX(self->spip, config);]]></implementation>
palClearLine(self->config->ssline);]]></implementation>
</method>
</override>
<method name="spiUnselectX" ctype="void">
<implementation><![CDATA[
palSetLine(self->config->ssline);]]></implementation>
</method>
<elseif check="SPI_SELECT_MODE == SPI_SELECT_MODE_PORT" />
<method name="spiSelectX" ctype="void">
<implementation><![CDATA[
palClearPort(self->config->ssport, (spip)->config->ssmask);]]></implementation>
</method>
<method name="spiUnselectX" ctype="void">
<implementation><![CDATA[
palSetPort(self->config->ssport, (spip)->config->ssmask);]]></implementation>
</method>
<elseif check="SPI_SELECT_MODE == SPI_SELECT_MODE_PAD" />
<method name="spiSelectX" ctype="void">
<implementation><![CDATA[
palClearPad(self->config->ssport, (spip)->config->sspad);]]></implementation>
</method>
<method name="spiUnselectX" ctype="void">
<implementation><![CDATA[
palSetPad(self->config->ssport, (spip)->config->sspad);]]></implementation>
</method>
</condition>
</inline>
</methods>
</class>
</types>

View File

@ -268,95 +268,6 @@ struct hal_spi_driver {
};
/** @} */
/**
* @class hal_buffered_spi_c
* @extends base_object_c, hal_base_driver_c, hal_buffered_serial_c.
*
* @brief This class implements a buffered channel interface on top of
* SPI.
*
* @name Class @p hal_buffered_spi_c structures
* @{
*/
/**
* @brief Type of a buffered SPI wrapper class.
*/
typedef struct hal_buffered_spi hal_buffered_spi_c;
/**
* @brief Class @p hal_buffered_spi_c virtual methods table.
*/
struct hal_buffered_spi_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_spi_c.*/
};
/**
* @brief Structure representing a buffered SPI wrapper class.
*/
struct hal_buffered_spi {
/**
* @brief Virtual Methods Table.
*/
const struct hal_buffered_spi_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_spi_driver_c instance.
*/
hal_spi_driver_c *spip;
};
/** @} */
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
@ -367,14 +278,6 @@ extern "C" {
/* Methods of hal_spi_driver_c.*/
void *__spi_objinit_impl(void *ip, const void *vmt);
void __spi_dispose_impl(void *ip);
/* Methods of hal_buffered_spi_c.*/
void *__bspi_objinit_impl(void *ip, const void *vmt, hal_spi_driver_c *spip,
uint8_t *ib, size_t ibsize, uint8_t *ob,
size_t obsize);
void __bspi_dispose_impl(void *ip);
msg_t __bspi_start_impl(void *ip);
void __bspi_stop_impl(void *ip);
msg_t __bspi_configure_impl(void *ip, const void *config);
/* Regular functions.*/
void spiInit(void);
#ifdef __cplusplus
@ -409,35 +312,89 @@ static inline hal_spi_driver_c *spiObjectInit(hal_spi_driver_c *self) {
/** @} */
/**
* @name Default constructor of hal_buffered_spi_c
* @name Inline methods of hal_spi_driver_c
* @{
*/
#if (SPI_SELECT_MODE == SPI_SELECT_MODE_LLD) || defined (__DOXYGEN__)
/**
* @memberof hal_buffered_spi_c
* @memberof hal_spi_driver_c
* @public
*
* @brief Default initialization function of @p hal_buffered_spi_c.
* @brief Asserts the slave select signal and prepares for transfers.
*
* @param[out] self Pointer to a @p hal_buffered_spi_c instance to
* be initialized.
* @param[in] spip Pointer to the @p hal_spi_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.
* @param[in,out] ip Pointer to a @p hal_spi_driver_c instance.
*
* @objinit
* @xclass
*/
CC_FORCE_INLINE
static inline hal_buffered_spi_c *bspiObjectInit(hal_buffered_spi_c *self,
hal_spi_driver_c *spip,
uint8_t *ib, size_t ibsize,
uint8_t *ob, size_t obsize) {
extern const struct hal_buffered_spi_vmt __hal_buffered_spi_vmt;
static inline void spiSelectX(void *ip) {
hal_spi_driver_c *self = (hal_spi_driver_c *)ip;
return __bspi_objinit_impl(self, &__hal_buffered_spi_vmt, spip, ib, ibsize,
ob, obsize);
spi_lld_select(self);
}
/**
* @memberof hal_spi_driver_c
* @public
*
* @brief Deasserts the slave select signal.
*
* @param[in,out] ip Pointer to a @p hal_spi_driver_c instance.
*
* @xclass
*/
CC_FORCE_INLINE
static inline void spiUnselectX(void *ip) {
hal_spi_driver_c *self = (hal_spi_driver_c *)ip;
spi_lld_unselect(self);
}
#elif SPI_SELECT_MODE == SPI_SELECT_MODE_LINE
CC_FORCE_INLINE
static inline void spiSelectX(void *ip) {
hal_spi_driver_c *self = (hal_spi_driver_c *)ip;
palClearLine(self->config->ssline);
}
CC_FORCE_INLINE
static inline void spiUnselectX(void *ip) {
hal_spi_driver_c *self = (hal_spi_driver_c *)ip;
palSetLine(self->config->ssline);
}
#elif SPI_SELECT_MODE == SPI_SELECT_MODE_PORT
CC_FORCE_INLINE
static inline void spiSelectX(void *ip) {
hal_spi_driver_c *self = (hal_spi_driver_c *)ip;
palClearPort(self->config->ssport, (spip)->config->ssmask);
}
CC_FORCE_INLINE
static inline void spiUnselectX(void *ip) {
hal_spi_driver_c *self = (hal_spi_driver_c *)ip;
palSetPort(self->config->ssport, (spip)->config->ssmask);
}
#elif SPI_SELECT_MODE == SPI_SELECT_MODE_PAD
CC_FORCE_INLINE
static inline void spiSelectX(void *ip) {
hal_spi_driver_c *self = (hal_spi_driver_c *)ip;
palClearPad(self->config->ssport, (spip)->config->sspad);
}
CC_FORCE_INLINE
static inline void spiUnselectX(void *ip) {
hal_spi_driver_c *self = (hal_spi_driver_c *)ip;
palSetPad(self->config->ssport, (spip)->config->sspad);
}
#endif /* SPI_SELECT_MODE == SPI_SELECT_MODE_LLD */
/** @} */
#endif /* HAL_USE_SPI == TRUE */

View File

@ -135,144 +135,6 @@ const struct hal_spi_driver_vmt __hal_spi_driver_vmt = {
.configure = NULL /* Method not found.*/
};
/*===========================================================================*/
/* Module class "hal_buffered_spi_c" methods. */
/*===========================================================================*/
/**
* @name Methods implementations of hal_buffered_spi_c
* @{
*/
/**
* @memberof hal_buffered_spi_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_spi_c instance to
* be initialized.
* @param[in] vmt VMT pointer for the new object.
* @param[in] spip Pointer to the @p hal_spi_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 *__bspi_objinit_impl(void *ip, const void *vmt, hal_spi_driver_c *spip,
uint8_t *ib, size_t ibsize, uint8_t *ob,
size_t obsize) {
hal_buffered_spi_c *self = (hal_buffered_spi_c *)ip;
/* Initialization code.*/
__bs_objinit_impl((void *)self, vmt,
ib, ibsize, NULL, NULL,
ob, obsize, __bspi_onotify, (void *)self);
drvSetArgumentX(spip, self);
self->spip = spip;
return self;
}
/**
* @memberof hal_buffered_spi_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_spi_c instance to
* be disposed.
*/
void __bspi_dispose_impl(void *ip) {
hal_buffered_spi_c *self = (hal_buffered_spi_c *)ip;
/* No finalization code.*/
(void)self;
/* Finalization of the ancestors-defined parts.*/
__bs_dispose_impl(self);
}
/**
* @memberof hal_buffered_spi_c
* @protected
*
* @brief Override of method @p __drv_start().
*
* @param[in,out] ip Pointer to a @p hal_buffered_spi_c instance.
* @return The operation status.
*/
msg_t __bspi_start_impl(void *ip) {
hal_buffered_spi_c *self = (hal_buffered_spi_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 SPI driver.*/
msg = drvStart(self->spip);
if (msg == HAL_RET_SUCCESS) {
spiSetCallbackX(self->spip, &__bspi_default_cb);
spiWriteEnableFlagsX(self->spip, SPI_EV_ALL_EVENTS);
}
/* Back into the critical section and return.*/
osalSysLock();
return msg;
}
/**
* @memberof hal_buffered_spi_c
* @protected
*
* @brief Override of method @p __drv_stop().
*
* @param[in,out] ip Pointer to a @p hal_buffered_spi_c instance.
*/
void __bspi_stop_impl(void *ip) {
hal_buffered_spi_c *self = (hal_buffered_spi_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->spip);
/* Back into the critical section and return.*/
osalSysLock();
}
/**
* @memberof hal_buffered_spi_c
* @protected
*
* @brief Override of method @p drvConfigureX().
*
* @param[in,out] ip Pointer to a @p hal_buffered_spi_c instance.
* @param[in] config New driver configuration.
*/
msg_t __bspi_configure_impl(void *ip, const void *config) {
hal_buffered_spi_c *self = (hal_buffered_spi_c *)ip;
return drvConfigureX(self->spip, config);
}
/** @} */
/**
* @brief VMT structure of buffered SPI wrapper class.
* @note It is public because accessed by the inlined constructor.
*/
const struct hal_buffered_spi_vmt __hal_buffered_spi_vmt = {
.dispose = __bspi_dispose_impl,
.start = __bspi_start_impl,
.stop = __bspi_stop_impl,
.configure = __bspi_configure_impl
};
#endif /* HAL_USE_SPI == TRUE */
/** @} */