From f74f12ff569a15c526bbbbeb71d63ff5714917ed Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Tue, 13 Jun 2023 13:12:40 +0000 Subject: [PATCH] XHAL SPI driver, unfinished. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@16280 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- os/xhal/codegen/hal_base_driver.xml | 3 +- os/xhal/codegen/hal_spi.xml | 230 ++++++++++++++ os/xhal/codegen/modules.xml | 2 + os/xhal/hal.mk | 5 + os/xhal/include/hal.h | 2 +- os/xhal/include/hal_base_driver.h | 3 +- os/xhal/include/hal_spi.h | 447 ++++++++++++++++++++++++++++ os/xhal/src/hal_spi.c | 278 +++++++++++++++++ 8 files changed, 967 insertions(+), 3 deletions(-) create mode 100644 os/xhal/codegen/hal_spi.xml create mode 100644 os/xhal/include/hal_spi.h create mode 100644 os/xhal/src/hal_spi.c diff --git a/os/xhal/codegen/hal_base_driver.xml b/os/xhal/codegen/hal_base_driver.xml index d2a5671fd..c676d2798 100644 --- a/os/xhal/codegen/hal_base_driver.xml +++ b/os/xhal/codegen/hal_base_driver.xml @@ -17,7 +17,8 @@ - + + diff --git a/os/xhal/codegen/hal_spi.xml b/os/xhal/codegen/hal_spi.xml new file mode 100644 index 000000000..d482fd43e --- /dev/null +++ b/os/xhal/codegen/hal_spi.xml @@ -0,0 +1,230 @@ + + + SPI Driver macros and structures. + + hal_cb_driver.xml + + + + + + @p spiSelect() and @p spiUnselect() do nothing. + + + Selection by PAL port and pad number. + + + Selection by port and port mask. + + + Selection by PAL line identifier. + + + Selection by LLD-defined mode. + + + + + + Support for thread synchronization API. + + + + Handling method for SPI CS line. + + + + + + Type of structure representing a SPI configuration. + + + + Type of structure representing a SPI configuration + (legacy). + + + + + Type of structure representing a SPI driver (legacy). + + + + + Driver configuration structure. + Implementations may extend this structure to contain more, + architecture dependent, fields. + + + + + Enables the circular buffer mode. + + + + + Enables the slave mode. + + + + + The chip select line. + Only used in master mode. + + + + + The chip select port. + Only used in master mode. + + + The chip select port mask. + Only used in master mode. + + + + + The chip select port. + Only used in master mode. + + + The chip select pad number. + Only used in master mode. + + + + + + + + + + Class of a SPI driver. + + + + + + + + + + + + + + This class implements a buffered channel interface on top of SPI. + + + Pointer to the associated @p hal_spi_driver_c instance. + + + + + Pointer to + the @p hal_spi_driver_c object. + Pointer to the input buffer. + Size of the input buffer. + Pointer to the output buffer. + Size of the output buffer. + spip = spip;]]> + + + + + + + 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;]]> + + + state = HAL_DRV_STATE_STOPPING; +osalSysUnlock(); + +drvStop(self->spip); + +/* Back into the critical section and return.*/ +osalSysLock();]]> + + + spip, config);]]> + + + + + + + + SPI Driver initialization. + + This function is implicitly invoked by @p halInit(), there is no + need to explicitly initialize the driver. + + + + + + + + + hal.h + + + \ No newline at end of file diff --git a/os/xhal/codegen/modules.xml b/os/xhal/codegen/modules.xml index b6863e6d5..c0fa25378 100644 --- a/os/xhal/codegen/modules.xml +++ b/os/xhal/codegen/modules.xml @@ -6,6 +6,7 @@ + ]> @@ -19,5 +20,6 @@ &hal_block_io; &hal_buffered_serial; &hal_sio; + &hal_spi; diff --git a/os/xhal/hal.mk b/os/xhal/hal.mk index f880f4264..e1c8c30e8 100644 --- a/os/xhal/hal.mk +++ b/os/xhal/hal.mk @@ -15,6 +15,7 @@ HALCONF := $(strip $(shell cat $(HALCONFDIR)/halconf.h | egrep -e "\#define")) HALSRC := $(CHIBIOS)/os/xhal/src/hal.c \ $(CHIBIOS)/os/xhal/src/hal_base_driver.c \ + $(CHIBIOS)/os/xhal/src/hal_cb_driver.c \ $(CHIBIOS)/os/xhal/src/hal_st.c \ $(CHIBIOS)/os/xhal/src/hal_buffered_serial.c \ $(CHIBIOS)/os/xhal/src/hal_queues.c @@ -24,6 +25,9 @@ endif ifneq ($(findstring HAL_USE_SIO TRUE,$(HALCONF)),) HALSRC += $(CHIBIOS)/os/xhal/src/hal_sio.c endif +ifneq ($(findstring HAL_USE_SPI TRUE,$(HALCONF)),) +HALSRC += $(CHIBIOS)/os/xhal/src/hal_spi.c +endif else HALSRC = $(CHIBIOS)/os/xhal/src/hal.c \ $(CHIBIOS)/os/xhal/src/hal_base_driver.c \ @@ -31,6 +35,7 @@ HALSRC = $(CHIBIOS)/os/xhal/src/hal.c \ $(CHIBIOS)/os/xhal/src/hal_queues.c \ $(CHIBIOS)/os/xhal/src/hal_pal.c \ $(CHIBIOS)/os/xhal/src/hal_sio.c + $(CHIBIOS)/os/xhal/src/hal_spi.c endif # Required include directories diff --git a/os/xhal/include/hal.h b/os/xhal/include/hal.h index 87daa1721..d348e9459 100644 --- a/os/xhal/include/hal.h +++ b/os/xhal/include/hal.h @@ -321,7 +321,7 @@ static inline halfreq_t halClockGetPointX(halclkpt_t clkpt) { //#include "hal_serial.h" //#include "hal_sdc.h" #include "hal_sio.h" -//#include "hal_spi.h" +#include "hal_spi.h" //#include "hal_trng.h" //#include "hal_uart.h" //#include "hal_usb.h" diff --git a/os/xhal/include/hal_base_driver.h b/os/xhal/include/hal_base_driver.h index 92e83ef8c..397b0bdbe 100644 --- a/os/xhal/include/hal_base_driver.h +++ b/os/xhal/include/hal_base_driver.h @@ -43,7 +43,8 @@ #define HAL_DRV_STATE_STARTING 3U #define HAL_DRV_STATE_READY 4U #define HAL_DRV_STATE_ACTIVE 5U -#define HAL_DRV_STATE_ERROR 6U +#define HAL_DRV_STATE_COMPLETE 6U +#define HAL_DRV_STATE_ERROR 7U /** @} */ /*===========================================================================*/ diff --git a/os/xhal/include/hal_spi.h b/os/xhal/include/hal_spi.h new file mode 100644 index 000000000..28b262e0f --- /dev/null +++ b/os/xhal/include/hal_spi.h @@ -0,0 +1,447 @@ +/* + ChibiOS - Copyright (C) 2006..2023 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 hal_spi.h + * @brief Generated SPI Driver header. + * @note This is a generated file, do not edit directly. + * + * @addtogroup HAL_SPI + * @brief SPI Driver macros and structures. + * @{ + */ + +#ifndef HAL_SPI_H +#define HAL_SPI_H + +#if (HAL_USE_SPI == TRUE) || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Module constants. */ +/*===========================================================================*/ + +/** + * @name SPI CS modes + * @{ + */ +/** + * @brief @p spiSelect() and @p spiUnselect() do nothing. + */ +#define SPI_SELECT_MODE_NONE 0 + +/** + * @brief Selection by PAL port and pad number. + */ +#define SPI_SELECT_MODE_PAD 1 + +/** + * @brief Selection by port and port mask. + */ +#define SPI_SELECT_MODE_PORT 2 + +/** + * @brief Selection by PAL line identifier. + */ +#define SPI_SELECT_MODE_LINE 3 + +/** + * @brief Selection by LLD-defined mode. + */ +#define SPI_SELECT_MODE_LLD 4 +/** @} */ + +/*===========================================================================*/ +/* Module pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @name Configuration options + * @{ + */ +/** + * @brief Support for thread synchronization API. + */ +#if !defined(SPI_USE_SYNCHRONIZATION) || defined(__DOXYGEN__) +#define SPI_USE_SYNCHRONIZATION TRUE +#endif + +/** + * @brief Handling method for SPI CS line. + */ +#if !defined(SPI_SELECT_MODE) || defined(__DOXYGEN__) +#define SPI_SELECT_MODE SPI_SELECT_MODE_PAD +#endif +/** @} */ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/* Checks on SPI_USE_SYNCHRONIZATION configuration.*/ +#if (SPI_USE_SYNCHRONIZATION != FALSE) && (SPI_USE_SYNCHRONIZATION != TRUE) +#error "invalid SPI_USE_SYNCHRONIZATION value" +#endif + +/* Checks on SPI_SELECT_MODE configuration.*/ +#if (SPI_SELECT_MODE < SPI_SELECT_MODE_NONE) || (SPI_SELECT_MODE > SPI_SELECT_MODE_LLD) +#error "invalid SPI_SELECT_MODE value" +#endif + +/*===========================================================================*/ +/* Module macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module data structures and types. */ +/*===========================================================================*/ + +/** + * @brief Type of structure representing a SPI configuration. + */ +typedef struct hal_spi_config hal_spi_config_t; + +/** + * @brief Type of structure representing a SPI configuration (legacy). + */ +typedef struct hal_spi_config SPIConfig; + +/** + * @brief Type of structure representing a SPI driver (legacy). + */ +typedef struct hal_spi_driver SPIDriver; + +/* Inclusion of LLD header.*/ +#include "hal_spi_lld.h" + +#if !defined(SPI_SUPPORTS_CIRCULAR) +#error "SPI_SUPPORTS_CIRCULAR not defined in SPI LLD driver" +#endif + +#if !defined(SPI_SUPPORTS_SLAVE_MODE) +#error "SPI_SUPPORTS_SLAVE_MODE not defined in SPI LLD driver" +#endif + +/** + * @brief Driver configuration structure. + * @note Implementations may extend this structure to contain more, + * architecture dependent, fields. + */ +struct hal_spi_config { +#if (SPI_SUPPORTS_CIRCULAR == TRUE) || defined (__DOXYGEN__) + /** + * @brief Enables the circular buffer mode. + */ + bool circular; +#endif /* SPI_SUPPORTS_CIRCULAR == TRUE */ +#if (SPI_SUPPORTS_SLAVE_MODE == TRUE) || defined (__DOXYGEN__) + /** + * @brief Enables the slave mode. + */ + bool slave; +#endif /* SPI_SUPPORTS_SLAVE_MODE == TRUE */ +#if (SPI_SELECT_MODE == SPI_SELECT_MODE_LINE) || defined (__DOXYGEN__) + /** + * @brief The chip select line. + * @note Only used in master mode. + */ + ioline_t ssline; +#endif /* SPI_SELECT_MODE == SPI_SELECT_MODE_LINE */ +#if (SPI_SELECT_MODE == SPI_SELECT_MODE_PORT) || defined (__DOXYGEN__) + /** + * @brief The chip select port. + * @note Only used in master mode. + */ + ioportid_t ssport; + /** + * @brief The chip select port mask. + * @note Only used in master mode. + */ + ioportmask_t ssmask; +#endif /* SPI_SELECT_MODE == SPI_SELECT_MODE_PORT */ +#if (SPI_SELECT_MODE == SPI_SELECT_MODE_PAD) || defined (__DOXYGEN__) + /** + * @brief The chip select port. + * @note Only used in master mode. + */ + ioportid_t ssport; + /** + * @brief The chip select pad number. + * @note Only used in master mode. + */ + ioportmask_t sspad; +#endif /* SPI_SELECT_MODE == SPI_SELECT_MODE_PAD */ + /* End of the mandatory fields.*/ + spi_lld_config_fields; +#if (defined(SPI_CONFIG_EXT_FIELS)) || defined (__DOXYGEN__) + SPI_CONFIG_EXT_FIELDS +#endif /* defined(SPI_CONFIG_EXT_FIELS) */ +}; + +/** + * @class hal_spi_driver_c + * @extends base_object_c, hal_base_driver_c, hal_cb_driver_c. + * + * @brief Class of a SPI driver. + * + * @name Class @p hal_spi_driver_c structures + * @{ + */ + +/** + * @brief Type of a SPI driver class. + */ +typedef struct hal_spi_driver hal_spi_driver_c; + +/** + * @brief Class @p hal_spi_driver_c virtual methods table. + */ +struct hal_spi_driver_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_cb_driver_c.*/ + /* From hal_spi_driver_c.*/ +}; + +/** + * @brief Structure representing a SPI driver class. + */ +struct hal_spi_driver { + /** + * @brief Virtual Methods Table. + */ + const struct hal_spi_driver_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 Driver callback. + * @note Can be @p NULL. + */ + hal_cb_t cb; +#if defined(SPI_DRIVER_EXT_FIELS) + SPI_DRIVER_EXT_FIELDS +#endif + /* End of the mandatory fields.*/ + spi_lld_driver_fields; +}; +/** @} */ + +/** + * @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. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + /* 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 +} +#endif + +/*===========================================================================*/ +/* Module inline functions. */ +/*===========================================================================*/ + +/** + * @name Default constructor of hal_spi_driver_c + * @{ + */ +/** + * @memberof hal_spi_driver_c + * + * @brief Default initialization function of @p hal_spi_driver_c. + * + * @param[out] self Pointer to a @p hal_spi_driver_c instance to be + * initialized. + * @return Pointer to the initialized object. + * + * @objinit + */ +CC_FORCE_INLINE +static inline hal_spi_driver_c *spiObjectInit(hal_spi_driver_c *self) { + extern const struct hal_spi_driver_vmt __hal_spi_driver_vmt; + + return __spi_objinit_impl(self, &__hal_spi_driver_vmt); +} +/** @} */ + +/** + * @name Default constructor of hal_buffered_spi_c + * @{ + */ +/** + * @memberof hal_buffered_spi_c + * + * @brief Default initialization function of @p hal_buffered_spi_c. + * + * @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. + * + * @objinit + */ +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; + + return __bspi_objinit_impl(self, &__hal_buffered_spi_vmt, spip, ib, ibsize, + ob, obsize); +} +/** @} */ + +#endif /* HAL_USE_SPI == TRUE */ + +#endif /* HAL_SPI_H */ + +/** @} */ diff --git a/os/xhal/src/hal_spi.c b/os/xhal/src/hal_spi.c new file mode 100644 index 000000000..819137436 --- /dev/null +++ b/os/xhal/src/hal_spi.c @@ -0,0 +1,278 @@ +/* + ChibiOS - Copyright (C) 2006..2023 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 hal_spi.c + * @brief Generated SPI Driver source. + * @note This is a generated file, do not edit directly. + * + * @addtogroup HAL_SPI + * @{ + */ + +#include "hal.h" + +#if (HAL_USE_SPI == TRUE) || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Module local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module exported variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module exported functions. */ +/*===========================================================================*/ + +/** + * @brief SPI Driver initialization. + * @note This function is implicitly invoked by @p halInit(), there is + * no need to explicitly initialize the driver. + * + * @init + */ +void spiInit(void) { + + spi_lld_init(); +} + +/*===========================================================================*/ +/* Module class "hal_spi_driver_c" methods. */ +/*===========================================================================*/ + +/** + * @name Methods implementations of hal_spi_driver_c + * @{ + */ +/** + * @memberof hal_spi_driver_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_spi_driver_c instance to be + * initialized. + * @param[in] vmt VMT pointer for the new object. + * @return A new reference to the object. + */ +void *__spi_objinit_impl(void *ip, const void *vmt) { + hal_spi_driver_c *self = (hal_spi_driver_c *)ip; + + /* Initialization of the ancestors-defined parts.*/ + __cbdrv_objinit_impl(self, vmt); + + /* Initialization code.*/ + + /* Optional, user-defined initializer.*/ +#if defined(SPI_DRIVER_EXT_INIT_HOOK) + SPI_DRIVER_EXT_INIT_HOOK(self); +#endif + + return self; +} + +/** + * @memberof hal_spi_driver_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_spi_driver_c instance to be + * disposed. + */ +void __spi_dispose_impl(void *ip) { + hal_spi_driver_c *self = (hal_spi_driver_c *)ip; + + /* No finalization code.*/ + (void)self; + + /* Finalization of the ancestors-defined parts.*/ + __cbdrv_dispose_impl(self); +} +/** @} */ + +/** + * @brief VMT structure of SPI driver class. + * @note It is public because accessed by the inlined constructor. + */ +const struct hal_spi_driver_vmt __hal_spi_driver_vmt = { + .dispose = __spi_dispose_impl, + .start = NULL /* Method not found.*/, + .stop = NULL /* Method not found.*/, + .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 */ + +/** @} */