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:
parent
f74f12ff56
commit
a688fcbbf0
|
@ -9,19 +9,19 @@
|
|||
<public>
|
||||
<definitions_early>
|
||||
<group description="SPI CS modes">
|
||||
<define name="SPI_SELECT_MODE_NONE" value="0" >
|
||||
<define name="SPI_SELECT_MODE_NONE" value="0">
|
||||
<brief>@p spiSelect() and @p spiUnselect() do nothing.</brief>
|
||||
</define>
|
||||
<define name="SPI_SELECT_MODE_PAD" value="1" >
|
||||
<define name="SPI_SELECT_MODE_PAD" value="1">
|
||||
<brief>Selection by PAL port and pad number.</brief>
|
||||
</define>
|
||||
<define name="SPI_SELECT_MODE_PORT" value="2" >
|
||||
<define name="SPI_SELECT_MODE_PORT" value="2">
|
||||
<brief>Selection by port and port mask.</brief>
|
||||
</define>
|
||||
<define name="SPI_SELECT_MODE_LINE" value="3" >
|
||||
<define name="SPI_SELECT_MODE_LINE" value="3">
|
||||
<brief>Selection by PAL line identifier.</brief>
|
||||
</define>
|
||||
<define name="SPI_SELECT_MODE_LLD" value="4" >
|
||||
<define name="SPI_SELECT_MODE_LLD" value="4">
|
||||
<brief>Selection by LLD-defined mode.</brief>
|
||||
</define>
|
||||
</group>
|
||||
|
@ -31,10 +31,10 @@
|
|||
<brief>Support for thread synchronization API.</brief>
|
||||
<assert invalid="($N != FALSE) && ($N != TRUE)" />
|
||||
</config>
|
||||
<config name="SPI_SELECT_MODE"
|
||||
default="SPI_SELECT_MODE_PAD">
|
||||
<config name="SPI_SELECT_MODE" default="SPI_SELECT_MODE_PAD">
|
||||
<brief>Handling method for SPI CS line.</brief>
|
||||
<assert invalid="($N < SPI_SELECT_MODE_NONE) || ($N > SPI_SELECT_MODE_LLD)" />
|
||||
<assert
|
||||
invalid="($N < SPI_SELECT_MODE_NONE) || ($N > 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>
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
||||
/** @} */
|
||||
|
|
Loading…
Reference in New Issue