Improved DAC driver, updated STM32 DACv1.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@16315 27425a3e-05d8-49a3-a47f-9c15f0e5edd8
This commit is contained in:
parent
f77d00b0c9
commit
665b0d48b4
|
@ -1,379 +1,385 @@
|
||||||
/*
|
/*
|
||||||
ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
|
ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
You may obtain a copy of the License at
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
Unless required by applicable law or agreed to in writing, software
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file hal_dac.h
|
* @file hal_dac.h
|
||||||
* @brief DAC Driver macros and structures.
|
* @brief DAC Driver macros and structures.
|
||||||
*
|
*
|
||||||
* @addtogroup DAC
|
* @addtogroup DAC
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef HAL_DAC_H
|
#ifndef HAL_DAC_H
|
||||||
#define HAL_DAC_H
|
#define HAL_DAC_H
|
||||||
|
|
||||||
#if (HAL_USE_DAC == TRUE) || defined(__DOXYGEN__)
|
#if (HAL_USE_DAC == TRUE) || defined(__DOXYGEN__)
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/* Driver constants. */
|
/* Driver constants. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/* Driver pre-compile time settings. */
|
/* Driver pre-compile time settings. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @name DAC configuration options
|
* @name DAC configuration options
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
/**
|
/**
|
||||||
* @brief Enables synchronous APIs.
|
* @brief Support for thread synchronization API.
|
||||||
* @note Disabling this option saves both code and data space.
|
*/
|
||||||
*/
|
#if !defined(DAC_USE_SYNCHRONIZATION) || defined(__DOXYGEN__)
|
||||||
#if !defined(DAC_USE_WAIT) || defined(__DOXYGEN__)
|
#if !defined(DAC_USE_WAIT) || defined(__DOXYGEN__)
|
||||||
#define DAC_USE_WAIT TRUE
|
#define DAC_USE_SYNCHRONIZATION FALSE
|
||||||
#endif
|
#else
|
||||||
|
#define DAC_USE_SYNCHRONIZATION DAC_USE_WAIT
|
||||||
/**
|
#endif
|
||||||
* @brief Enables the @p dacAcquireBus() and @p dacReleaseBus() APIs.
|
#endif
|
||||||
* @note Disabling this option saves both code and data space.
|
|
||||||
*/
|
/**
|
||||||
#if !defined(DAC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
|
* @brief Enables the @p dacAcquireBus() and @p dacReleaseBus() APIs.
|
||||||
#define DAC_USE_MUTUAL_EXCLUSION TRUE
|
* @note Disabling this option saves both code and data space.
|
||||||
#endif
|
*/
|
||||||
/** @} */
|
#if !defined(DAC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
|
||||||
|
#define DAC_USE_MUTUAL_EXCLUSION TRUE
|
||||||
/*===========================================================================*/
|
#endif
|
||||||
/* Derived constants and error checks. */
|
/** @} */
|
||||||
/*===========================================================================*/
|
|
||||||
|
/*===========================================================================*/
|
||||||
/*===========================================================================*/
|
/* Derived constants and error checks. */
|
||||||
/* Driver data structures and types. */
|
/*===========================================================================*/
|
||||||
/*===========================================================================*/
|
|
||||||
|
/*===========================================================================*/
|
||||||
/**
|
/* Driver data structures and types. */
|
||||||
* @brief Driver state machine possible states.
|
/*===========================================================================*/
|
||||||
*/
|
|
||||||
typedef enum {
|
/**
|
||||||
DAC_UNINIT = 0, /**< Not initialized. */
|
* @brief Driver state machine possible states.
|
||||||
DAC_STOP = 1, /**< Stopped. */
|
*/
|
||||||
DAC_READY = 2, /**< Ready. */
|
typedef enum {
|
||||||
DAC_ACTIVE = 3, /**< Exchanging data. */
|
DAC_UNINIT = 0, /**< Not initialized. */
|
||||||
DAC_COMPLETE = 4, /**< Asynchronous operation complete. */
|
DAC_STOP = 1, /**< Stopped. */
|
||||||
DAC_ERROR = 5 /**< Error. */
|
DAC_READY = 2, /**< Ready. */
|
||||||
} dacstate_t;
|
DAC_ACTIVE = 3, /**< Exchanging data. */
|
||||||
|
DAC_COMPLETE = 4, /**< Asynchronous operation complete. */
|
||||||
/**
|
DAC_ERROR = 5 /**< Error. */
|
||||||
* @brief Type of a structure representing an DAC driver.
|
} dacstate_t;
|
||||||
*/
|
|
||||||
typedef struct hal_dac_driver DACDriver;
|
/**
|
||||||
|
* @brief Type of a structure representing an DAC driver.
|
||||||
/**
|
*/
|
||||||
* @brief Type of a structure representing an DAC driver configuration.
|
typedef struct hal_dac_driver DACDriver;
|
||||||
*/
|
|
||||||
typedef struct hal_dac_config DACConfig;
|
/**
|
||||||
|
* @brief Type of a structure representing an DAC driver configuration.
|
||||||
/**
|
*/
|
||||||
* @brief Type of a DAC conversion group.
|
typedef struct hal_dac_config DACConfig;
|
||||||
*/
|
|
||||||
typedef struct hal_dac_conversion_group DACConversionGroup;
|
/**
|
||||||
|
* @brief Type of a DAC conversion group.
|
||||||
/* Including the low level driver header, it exports information required
|
*/
|
||||||
for completing types.*/
|
typedef struct hal_dac_conversion_group DACConversionGroup;
|
||||||
#include "hal_dac_lld.h"
|
|
||||||
|
/* Including the low level driver header, it exports information required
|
||||||
/**
|
for completing types.*/
|
||||||
* @brief DAC notification callback type.
|
#include "hal_dac_lld.h"
|
||||||
*
|
|
||||||
* @param[in] dacp pointer to the @p DACDriver object triggering the
|
/**
|
||||||
*/
|
* @brief DAC notification callback type.
|
||||||
typedef void (*daccallback_t)(DACDriver *dacp);
|
*
|
||||||
|
* @param[in] dacp pointer to the @p DACDriver object triggering the
|
||||||
/**
|
*/
|
||||||
* @brief DAC error callback type.
|
typedef void (*daccallback_t)(DACDriver *dacp);
|
||||||
*
|
|
||||||
* @param[in] dacp pointer to the @p DACDriver object triggering the
|
/**
|
||||||
* callback
|
* @brief DAC error callback type.
|
||||||
* @param[in] err DAC error code
|
*
|
||||||
*/
|
* @param[in] dacp pointer to the @p DACDriver object triggering the
|
||||||
typedef void (*dacerrorcallback_t)(DACDriver *dacp, dacerror_t err);
|
* callback
|
||||||
|
* @param[in] err DAC error code
|
||||||
/**
|
*/
|
||||||
* @brief DAC Conversion group structure.
|
typedef void (*dacerrorcallback_t)(DACDriver *dacp, dacerror_t err);
|
||||||
*/
|
|
||||||
struct hal_dac_conversion_group {
|
/**
|
||||||
/**
|
* @brief DAC Conversion group structure.
|
||||||
* @brief Number of DAC channels.
|
*/
|
||||||
*/
|
struct hal_dac_conversion_group {
|
||||||
uint32_t num_channels;
|
/**
|
||||||
/**
|
* @brief Number of DAC channels.
|
||||||
* @brief Operation complete callback or @p NULL.
|
*/
|
||||||
*/
|
uint32_t num_channels;
|
||||||
daccallback_t end_cb;
|
/**
|
||||||
/**
|
* @brief Operation complete callback or @p NULL.
|
||||||
* @brief Error handling callback or @p NULL.
|
*/
|
||||||
*/
|
daccallback_t end_cb;
|
||||||
dacerrorcallback_t error_cb;
|
/**
|
||||||
/* End of the mandatory fields.*/
|
* @brief Error handling callback or @p NULL.
|
||||||
dac_lld_conversion_group_fields;
|
*/
|
||||||
};
|
dacerrorcallback_t error_cb;
|
||||||
|
/* End of the mandatory fields.*/
|
||||||
/**
|
dac_lld_conversion_group_fields;
|
||||||
* @brief Driver configuration structure.
|
};
|
||||||
*/
|
|
||||||
struct hal_dac_config {
|
/**
|
||||||
/* End of the mandatory fields.*/
|
* @brief Driver configuration structure.
|
||||||
dac_lld_config_fields;
|
*/
|
||||||
};
|
struct hal_dac_config {
|
||||||
|
/* End of the mandatory fields.*/
|
||||||
/**
|
dac_lld_config_fields;
|
||||||
* @brief Structure representing a DAC driver.
|
};
|
||||||
*/
|
|
||||||
struct hal_dac_driver {
|
/**
|
||||||
/**
|
* @brief Structure representing a DAC driver.
|
||||||
* @brief Driver state.
|
*/
|
||||||
*/
|
struct hal_dac_driver {
|
||||||
dacstate_t state;
|
/**
|
||||||
/**
|
* @brief Driver state.
|
||||||
* @brief Conversion group.
|
*/
|
||||||
*/
|
dacstate_t state;
|
||||||
const DACConversionGroup *grpp;
|
/**
|
||||||
/**
|
* @brief Conversion group.
|
||||||
* @brief Samples buffer pointer.
|
*/
|
||||||
*/
|
const DACConversionGroup *grpp;
|
||||||
dacsample_t *samples;
|
/**
|
||||||
/**
|
* @brief Samples buffer pointer.
|
||||||
* @brief Samples buffer size.
|
*/
|
||||||
*/
|
dacsample_t *samples;
|
||||||
size_t depth;
|
/**
|
||||||
/**
|
* @brief Samples buffer size.
|
||||||
* @brief Current configuration data.
|
*/
|
||||||
*/
|
size_t depth;
|
||||||
const DACConfig *config;
|
/**
|
||||||
#if (DAC_USE_WAIT == TRUE) || defined(__DOXYGEN__)
|
* @brief Current configuration data.
|
||||||
/**
|
*/
|
||||||
* @brief Waiting thread.
|
const DACConfig *config;
|
||||||
*/
|
#if (DAC_USE_SYNCHRONIZATION == TRUE) || defined(__DOXYGEN__)
|
||||||
thread_reference_t thread;
|
/**
|
||||||
#endif /* DAC_USE_WAIT */
|
* @brief Waiting thread.
|
||||||
#if (DAC_USE_MUTUAL_EXCLUSION == TRUE) || defined(__DOXYGEN__)
|
*/
|
||||||
/**
|
thread_reference_t thread;
|
||||||
* @brief Mutex protecting the bus.
|
#endif /* DAC_USE_SYNCHRONIZATION */
|
||||||
*/
|
#if (DAC_USE_MUTUAL_EXCLUSION == TRUE) || defined(__DOXYGEN__)
|
||||||
mutex_t mutex;
|
/**
|
||||||
#endif /* DAC_USE_MUTUAL_EXCLUSION */
|
* @brief Mutex protecting the bus.
|
||||||
#if defined(DAC_DRIVER_EXT_FIELDS)
|
*/
|
||||||
DAC_DRIVER_EXT_FIELDS
|
mutex_t mutex;
|
||||||
#endif
|
#endif /* DAC_USE_MUTUAL_EXCLUSION */
|
||||||
/* End of the mandatory fields.*/
|
#if defined(DAC_DRIVER_EXT_FIELDS)
|
||||||
dac_lld_driver_fields;
|
DAC_DRIVER_EXT_FIELDS
|
||||||
};
|
#endif
|
||||||
|
/* End of the mandatory fields.*/
|
||||||
/*===========================================================================*/
|
dac_lld_driver_fields;
|
||||||
/* Driver macros. */
|
};
|
||||||
/*===========================================================================*/
|
|
||||||
|
/*===========================================================================*/
|
||||||
/**
|
/* Driver macros. */
|
||||||
* @name Low level driver helper macros
|
/*===========================================================================*/
|
||||||
* @{
|
|
||||||
*/
|
/**
|
||||||
/**
|
* @name Low level driver helper macros
|
||||||
* @brief Buffer state.
|
* @{
|
||||||
* @note This function is meant to be called from the DAC callback only.
|
*/
|
||||||
*
|
/**
|
||||||
* @param[in] dacp pointer to the @p DACDriver object
|
* @brief Buffer state.
|
||||||
* @return The buffer state.
|
* @note This function is meant to be called from the DAC callback only.
|
||||||
* @retval false if the driver filled/sent the first half of the
|
*
|
||||||
* buffer.
|
* @param[in] dacp pointer to the @p DACDriver object
|
||||||
* @retval true if the driver filled/sent the second half of the
|
* @return The buffer state.
|
||||||
* buffer.
|
* @retval false if the driver filled/sent the first half of the
|
||||||
*
|
* buffer.
|
||||||
* @special
|
* @retval true if the driver filled/sent the second half of the
|
||||||
*/
|
* buffer.
|
||||||
#define dacIsBufferComplete(dacp) ((bool)((dacp)->state == DAC_COMPLETE))
|
*
|
||||||
|
* @special
|
||||||
#if (DAC_USE_WAIT == TRUE) || defined(__DOXYGEN__)
|
*/
|
||||||
/**
|
#define dacIsBufferComplete(dacp) ((bool)((dacp)->state == DAC_COMPLETE))
|
||||||
* @brief Waits for operation completion.
|
|
||||||
* @details This function waits for the driver to complete the current
|
#if (DAC_USE_SYNCHRONIZATION == TRUE) || defined(__DOXYGEN__)
|
||||||
* operation.
|
/**
|
||||||
* @pre An operation must be running while the function is invoked.
|
* @brief Waits for operation completion.
|
||||||
* @note No more than one thread can wait on a DAC driver using
|
* @details This function waits for the driver to complete the current
|
||||||
* this function.
|
* operation.
|
||||||
*
|
* @pre An operation must be running while the function is invoked.
|
||||||
* @param[in] dacp pointer to the @p DACDriver object
|
* @note No more than one thread can wait on a DAC driver using
|
||||||
*
|
* this function.
|
||||||
* @notapi
|
*
|
||||||
*/
|
* @param[in] dacp pointer to the @p DACDriver object
|
||||||
#define _dac_wait_s(dacp) osalThreadSuspendS(&(dacp)->thread)
|
*
|
||||||
|
* @notapi
|
||||||
/**
|
*/
|
||||||
* @brief Resumes a thread waiting for a conversion completion.
|
#define _dac_wait_s(dacp) osalThreadSuspendS(&(dacp)->thread)
|
||||||
*
|
|
||||||
* @param[in] dacp pointer to the @p DACDriver object
|
/**
|
||||||
*
|
* @brief Resumes a thread waiting for a conversion completion.
|
||||||
* @notapi
|
*
|
||||||
*/
|
* @param[in] dacp pointer to the @p DACDriver object
|
||||||
#define _dac_reset_i(dacp) osalThreadResumeI(&(dacp)->thread, MSG_RESET)
|
*
|
||||||
|
* @notapi
|
||||||
/**
|
*/
|
||||||
* @brief Resumes a thread waiting for a conversion completion.
|
#define _dac_reset_i(dacp) osalThreadResumeI(&(dacp)->thread, MSG_RESET)
|
||||||
*
|
|
||||||
* @param[in] dacp pointer to the @p DACDriver object
|
/**
|
||||||
*
|
* @brief Resumes a thread waiting for a conversion completion.
|
||||||
* @notapi
|
*
|
||||||
*/
|
* @param[in] dacp pointer to the @p DACDriver object
|
||||||
#define _dac_reset_s(dacp) osalThreadResumeS(&(dacp)->thread, MSG_RESET)
|
*
|
||||||
|
* @notapi
|
||||||
/**
|
*/
|
||||||
* @brief Wakes up the waiting thread.
|
#define _dac_reset_s(dacp) osalThreadResumeS(&(dacp)->thread, MSG_RESET)
|
||||||
*
|
|
||||||
* @param[in] dacp pointer to the @p DACDriver object
|
/**
|
||||||
*
|
* @brief Wakes up the waiting thread.
|
||||||
* @notapi
|
*
|
||||||
*/
|
* @param[in] dacp pointer to the @p DACDriver object
|
||||||
#define _dac_wakeup_isr(dacp) { \
|
*
|
||||||
osalSysLockFromISR(); \
|
* @notapi
|
||||||
osalThreadResumeI(&(dacp)->thread, MSG_OK); \
|
*/
|
||||||
osalSysUnlockFromISR(); \
|
#define _dac_wakeup_isr(dacp) { \
|
||||||
}
|
osalSysLockFromISR(); \
|
||||||
|
osalThreadResumeI(&(dacp)->thread, MSG_OK); \
|
||||||
/**
|
osalSysUnlockFromISR(); \
|
||||||
* @brief Wakes up the waiting thread with a timeout message.
|
}
|
||||||
*
|
|
||||||
* @param[in] dacp pointer to the @p DACDriver object
|
/**
|
||||||
*
|
* @brief Wakes up the waiting thread with a timeout message.
|
||||||
* @notapi
|
*
|
||||||
*/
|
* @param[in] dacp pointer to the @p DACDriver object
|
||||||
#define _dac_timeout_isr(dacp) { \
|
*
|
||||||
osalSysLockFromISR(); \
|
* @notapi
|
||||||
osalThreadResumeI(&(dacp)->thread, MSG_TIMEOUT); \
|
*/
|
||||||
osalSysUnlockFromISR(); \
|
#define _dac_timeout_isr(dacp) { \
|
||||||
}
|
osalSysLockFromISR(); \
|
||||||
|
osalThreadResumeI(&(dacp)->thread, MSG_TIMEOUT); \
|
||||||
#else /* !DAC_USE_WAIT */
|
osalSysUnlockFromISR(); \
|
||||||
#define _dac_wait_s(dacp)
|
}
|
||||||
#define _dac_reset_i(dacp)
|
|
||||||
#define _dac_reset_s(dacp)
|
#else /* !DAC_USE_SYNCHRONIZATION */
|
||||||
#define _dac_wakeup_isr(dacp)
|
#define _dac_wait_s(dacp)
|
||||||
#define _dac_timeout_isr(dacp)
|
#define _dac_reset_i(dacp)
|
||||||
#endif /* !DAC_USE_WAIT */
|
#define _dac_reset_s(dacp)
|
||||||
|
#define _dac_wakeup_isr(dacp)
|
||||||
/**
|
#define _dac_timeout_isr(dacp)
|
||||||
* @brief Common ISR code, half buffer event.
|
#endif /* !DAC_USE_SYNCHRONIZATION */
|
||||||
* @details This code handles the portable part of the ISR code:
|
|
||||||
* - Callback invocation.
|
/**
|
||||||
* .
|
* @brief Common ISR code, half buffer event.
|
||||||
* @note This macro is meant to be used in the low level drivers
|
* @details This code handles the portable part of the ISR code:
|
||||||
* implementation only.
|
* - Callback invocation.
|
||||||
*
|
* .
|
||||||
* @param[in] dacp pointer to the @p DACDriver object
|
* @note This macro is meant to be used in the low level drivers
|
||||||
*
|
* implementation only.
|
||||||
* @notapi
|
*
|
||||||
*/
|
* @param[in] dacp pointer to the @p DACDriver object
|
||||||
#define _dac_isr_half_code(dacp) { \
|
*
|
||||||
if ((dacp)->grpp->end_cb != NULL) { \
|
* @notapi
|
||||||
(dacp)->grpp->end_cb(dacp); \
|
*/
|
||||||
} \
|
#define _dac_isr_half_code(dacp) { \
|
||||||
}
|
if ((dacp)->grpp->end_cb != NULL) { \
|
||||||
|
(dacp)->grpp->end_cb(dacp); \
|
||||||
/**
|
} \
|
||||||
* @brief Common ISR code, full buffer event.
|
}
|
||||||
* @details This code handles the portable part of the ISR code:
|
|
||||||
* - Callback invocation.
|
/**
|
||||||
* - Driver state transitions.
|
* @brief Common ISR code, full buffer event.
|
||||||
* .
|
* @details This code handles the portable part of the ISR code:
|
||||||
* @note This macro is meant to be used in the low level drivers
|
* - Callback invocation.
|
||||||
* implementation only.
|
* - Driver state transitions.
|
||||||
*
|
* .
|
||||||
* @param[in] dacp pointer to the @p DACDriver object
|
* @note This macro is meant to be used in the low level drivers
|
||||||
*
|
* implementation only.
|
||||||
* @notapi
|
*
|
||||||
*/
|
* @param[in] dacp pointer to the @p DACDriver object
|
||||||
#define _dac_isr_full_code(dacp) { \
|
*
|
||||||
if ((dacp)->grpp->end_cb) { \
|
* @notapi
|
||||||
(dacp)->state = DAC_COMPLETE; \
|
*/
|
||||||
(dacp)->grpp->end_cb(dacp); \
|
#define _dac_isr_full_code(dacp) { \
|
||||||
if ((dacp)->state == DAC_COMPLETE) \
|
if ((dacp)->grpp->end_cb) { \
|
||||||
(dacp)->state = DAC_ACTIVE; \
|
(dacp)->state = DAC_COMPLETE; \
|
||||||
} \
|
(dacp)->grpp->end_cb(dacp); \
|
||||||
}
|
if ((dacp)->state == DAC_COMPLETE) \
|
||||||
|
(dacp)->state = DAC_ACTIVE; \
|
||||||
/**
|
} \
|
||||||
* @brief Common ISR code, error event.
|
_dac_wakeup_isr(dacp); \
|
||||||
* @details This code handles the portable part of the ISR code:
|
}
|
||||||
* - Callback invocation.
|
|
||||||
* - Waiting thread timeout signaling, if any.
|
/**
|
||||||
* - Driver state transitions.
|
* @brief Common ISR code, error event.
|
||||||
* .
|
* @details This code handles the portable part of the ISR code:
|
||||||
* @note This macro is meant to be used in the low level drivers
|
* - Callback invocation.
|
||||||
* implementation only.
|
* - Waiting thread timeout signalling, if any.
|
||||||
*
|
* - Driver state transitions.
|
||||||
* @param[in] dacp pointer to the @p DACDriver object
|
* .
|
||||||
* @param[in] err platform dependent error code
|
* @note This macro is meant to be used in the low level drivers
|
||||||
*
|
* implementation only.
|
||||||
* @notapi
|
*
|
||||||
*/
|
* @param[in] dacp pointer to the @p DACDriver object
|
||||||
#define _dac_isr_error_code(dacp, err) { \
|
* @param[in] err platform dependent error code
|
||||||
dac_lld_stop_conversion(dacp); \
|
*
|
||||||
if ((dacp)->grpp->error_cb != NULL) { \
|
* @notapi
|
||||||
(dacp)->state = DAC_ERROR; \
|
*/
|
||||||
(dacp)->grpp->error_cb(dacp, err); \
|
#define _dac_isr_error_code(dacp, err) { \
|
||||||
if ((dacp)->state == DAC_ERROR) \
|
dac_lld_stop_conversion(dacp); \
|
||||||
(dacp)->state = DAC_READY; \
|
if ((dacp)->grpp->error_cb != NULL) { \
|
||||||
} \
|
(dacp)->state = DAC_ERROR; \
|
||||||
(dacp)->grpp = NULL; \
|
(dacp)->grpp->error_cb(dacp, err); \
|
||||||
_dac_timeout_isr(dacp); \
|
if ((dacp)->state == DAC_ERROR) \
|
||||||
}
|
(dacp)->state = DAC_READY; \
|
||||||
/** @} */
|
} \
|
||||||
|
(dacp)->grpp = NULL; \
|
||||||
/*===========================================================================*/
|
_dac_timeout_isr(dacp); \
|
||||||
/* External declarations. */
|
}
|
||||||
/*===========================================================================*/
|
/** @} */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
/*===========================================================================*/
|
||||||
extern "C" {
|
/* External declarations. */
|
||||||
#endif
|
/*===========================================================================*/
|
||||||
void dacInit(void);
|
|
||||||
void dacObjectInit(DACDriver *dacp);
|
#ifdef __cplusplus
|
||||||
msg_t dacStart(DACDriver *dacp, const DACConfig *config);
|
extern "C" {
|
||||||
void dacStop(DACDriver *dacp);
|
#endif
|
||||||
void dacPutChannelX(DACDriver *dacp,
|
void dacInit(void);
|
||||||
dacchannel_t channel,
|
void dacObjectInit(DACDriver *dacp);
|
||||||
dacsample_t sample);
|
msg_t dacStart(DACDriver *dacp, const DACConfig *config);
|
||||||
void dacStartConversion(DACDriver *dacp, const DACConversionGroup *grpp,
|
void dacStop(DACDriver *dacp);
|
||||||
dacsample_t *samples, size_t depth);
|
void dacPutChannelX(DACDriver *dacp,
|
||||||
void dacStartConversionI(DACDriver *dacp, const DACConversionGroup *grpp,
|
dacchannel_t channel,
|
||||||
dacsample_t *samples, size_t depth);
|
dacsample_t sample);
|
||||||
void dacStopConversion(DACDriver *dacp);
|
void dacStartConversion(DACDriver *dacp, const DACConversionGroup *grpp,
|
||||||
void dacStopConversionI(DACDriver *dacp);
|
dacsample_t *samples, size_t depth);
|
||||||
#if DAC_USE_WAIT
|
void dacStartConversionI(DACDriver *dacp, const DACConversionGroup *grpp,
|
||||||
msg_t dacConvert(DACDriver *dacp, const DACConversionGroup *grpp,
|
dacsample_t *samples, size_t depth);
|
||||||
dacsample_t *samples, size_t depth);
|
void dacStopConversion(DACDriver *dacp);
|
||||||
#endif
|
void dacStopConversionI(DACDriver *dacp);
|
||||||
#if DAC_USE_MUTUAL_EXCLUSION
|
#if DAC_USE_SYNCHRONIZATION
|
||||||
void dacAcquireBus(DACDriver *dacp);
|
msg_t dacConvert(DACDriver *dacp, const DACConversionGroup *grpp,
|
||||||
void dacReleaseBus(DACDriver *dacp);
|
dacsample_t *samples, size_t depth);
|
||||||
#endif
|
msg_t dacSynchronizeS(DACDriver *dacp, sysinterval_t timeout);
|
||||||
#ifdef __cplusplus
|
msg_t dacSynchronize(DACDriver *dacp, sysinterval_t timeout);
|
||||||
}
|
#endif /* DAC_USE_SYNCHRONIZATION */
|
||||||
#endif
|
#if DAC_USE_MUTUAL_EXCLUSION
|
||||||
|
void dacAcquireBus(DACDriver *dacp);
|
||||||
#endif /* HAL_USE_DAC == TRUE */
|
void dacReleaseBus(DACDriver *dacp);
|
||||||
|
#endif
|
||||||
#endif /* HAL_DAC_H */
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
/** @} */
|
#endif
|
||||||
|
|
||||||
|
#endif /* HAL_USE_DAC == TRUE */
|
||||||
|
|
||||||
|
#endif /* HAL_DAC_H */
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,365 +1,422 @@
|
||||||
/*
|
/*
|
||||||
ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
|
ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
You may obtain a copy of the License at
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
Unless required by applicable law or agreed to in writing, software
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file hal_dac.c
|
* @file hal_dac.c
|
||||||
* @brief DAC Driver code.
|
* @brief DAC Driver code.
|
||||||
*
|
*
|
||||||
* @addtogroup DAC
|
* @addtogroup DAC
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "hal.h"
|
#include "hal.h"
|
||||||
|
|
||||||
#if (HAL_USE_DAC == TRUE) || defined(__DOXYGEN__)
|
#if (HAL_USE_DAC == TRUE) || defined(__DOXYGEN__)
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/* Driver local definitions. */
|
/* Driver local definitions. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/* Driver exported variables. */
|
/* Driver exported variables. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/* Driver local variables. */
|
/* Driver local variables. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/* Driver local functions. */
|
/* Driver local functions. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/* Driver exported functions. */
|
/* Driver exported functions. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief DAC Driver initialization.
|
* @brief DAC Driver initialization.
|
||||||
* @note This function is implicitly invoked by @p halInit(), there is
|
* @note This function is implicitly invoked by @p halInit(), there is
|
||||||
* no need to explicitly initialize the driver.
|
* no need to explicitly initialize the driver.
|
||||||
*
|
*
|
||||||
* @init
|
* @init
|
||||||
*/
|
*/
|
||||||
void dacInit(void) {
|
void dacInit(void) {
|
||||||
|
|
||||||
dac_lld_init();
|
dac_lld_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initializes the standard part of a @p DACDriver structure.
|
* @brief Initializes the standard part of a @p DACDriver structure.
|
||||||
*
|
*
|
||||||
* @param[out] dacp pointer to the @p DACDriver object
|
* @param[out] dacp pointer to the @p DACDriver object
|
||||||
*
|
*
|
||||||
* @init
|
* @init
|
||||||
*/
|
*/
|
||||||
void dacObjectInit(DACDriver *dacp) {
|
void dacObjectInit(DACDriver *dacp) {
|
||||||
|
|
||||||
dacp->state = DAC_STOP;
|
dacp->state = DAC_STOP;
|
||||||
dacp->config = NULL;
|
dacp->config = NULL;
|
||||||
#if DAC_USE_WAIT
|
#if DAC_USE_WAIT
|
||||||
dacp->thread = NULL;
|
dacp->thread = NULL;
|
||||||
#endif
|
#endif
|
||||||
#if DAC_USE_MUTUAL_EXCLUSION
|
#if DAC_USE_MUTUAL_EXCLUSION
|
||||||
osalMutexObjectInit(&dacp->mutex);
|
osalMutexObjectInit(&dacp->mutex);
|
||||||
#endif
|
#endif
|
||||||
#if defined(DAC_DRIVER_EXT_INIT_HOOK)
|
#if defined(DAC_DRIVER_EXT_INIT_HOOK)
|
||||||
DAC_DRIVER_EXT_INIT_HOOK(dacp);
|
DAC_DRIVER_EXT_INIT_HOOK(dacp);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Configures and activates the DAC peripheral.
|
* @brief Configures and activates the DAC peripheral.
|
||||||
*
|
*
|
||||||
* @param[in] dacp pointer to the @p DACDriver object
|
* @param[in] dacp pointer to the @p DACDriver object
|
||||||
* @param[in] config pointer to the @p DACConfig object, it can be
|
* @param[in] config pointer to the @p DACConfig object, it can be
|
||||||
* @p NULL if the low level driver implementation
|
* @p NULL if the low level driver implementation
|
||||||
* supports a default configuration
|
* supports a default configuration
|
||||||
* @return The operation status.
|
* @return The operation status.
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
msg_t dacStart(DACDriver *dacp, const DACConfig *config) {
|
msg_t dacStart(DACDriver *dacp, const DACConfig *config) {
|
||||||
msg_t msg;
|
msg_t msg;
|
||||||
|
|
||||||
osalDbgCheck(dacp != NULL);
|
osalDbgCheck(dacp != NULL);
|
||||||
|
|
||||||
osalSysLock();
|
osalSysLock();
|
||||||
|
|
||||||
osalDbgAssert((dacp->state == DAC_STOP) || (dacp->state == DAC_READY),
|
osalDbgAssert((dacp->state == DAC_STOP) || (dacp->state == DAC_READY),
|
||||||
"invalid state");
|
"invalid state");
|
||||||
|
|
||||||
dacp->config = config;
|
dacp->config = config;
|
||||||
|
|
||||||
#if defined(DAC_LLD_ENHANCED_API)
|
#if defined(DAC_LLD_ENHANCED_API)
|
||||||
msg = dac_lld_start(dacp);
|
msg = dac_lld_start(dacp);
|
||||||
#else
|
#else
|
||||||
dac_lld_start(dacp);
|
dac_lld_start(dacp);
|
||||||
msg = HAL_RET_SUCCESS;
|
msg = HAL_RET_SUCCESS;
|
||||||
#endif
|
#endif
|
||||||
if (msg == HAL_RET_SUCCESS) {
|
if (msg == HAL_RET_SUCCESS) {
|
||||||
dacp->state = DAC_READY;
|
dacp->state = DAC_READY;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
dacp->state = DAC_STOP;
|
dacp->state = DAC_STOP;
|
||||||
}
|
}
|
||||||
|
|
||||||
osalSysUnlock();
|
osalSysUnlock();
|
||||||
|
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Deactivates the DAC peripheral.
|
* @brief Deactivates the DAC peripheral.
|
||||||
* @note Deactivating the peripheral also enforces a release of the slave
|
* @note Deactivating the peripheral also enforces a release of the slave
|
||||||
* select line.
|
* select line.
|
||||||
*
|
*
|
||||||
* @param[in] dacp pointer to the @p DACDriver object
|
* @param[in] dacp pointer to the @p DACDriver object
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
void dacStop(DACDriver *dacp) {
|
void dacStop(DACDriver *dacp) {
|
||||||
|
|
||||||
osalDbgCheck(dacp != NULL);
|
osalDbgCheck(dacp != NULL);
|
||||||
|
|
||||||
osalSysLock();
|
osalSysLock();
|
||||||
|
|
||||||
osalDbgAssert((dacp->state == DAC_STOP) || (dacp->state == DAC_READY),
|
osalDbgAssert((dacp->state == DAC_STOP) || (dacp->state == DAC_READY),
|
||||||
"invalid state");
|
"invalid state");
|
||||||
|
|
||||||
dac_lld_stop(dacp);
|
dac_lld_stop(dacp);
|
||||||
dacp->config = NULL;
|
dacp->config = NULL;
|
||||||
dacp->state = DAC_STOP;
|
dacp->state = DAC_STOP;
|
||||||
|
|
||||||
osalSysUnlock();
|
osalSysUnlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Outputs a value directly on a DAC channel.
|
* @brief Outputs a value directly on a DAC channel.
|
||||||
*
|
*
|
||||||
* @param[in] dacp pointer to the @p DACDriver object
|
* @param[in] dacp pointer to the @p DACDriver object
|
||||||
* @param[in] channel DAC channel number
|
* @param[in] channel DAC channel number
|
||||||
* @param[in] sample value to be output
|
* @param[in] sample value to be output
|
||||||
*
|
*
|
||||||
* @xclass
|
* @xclass
|
||||||
*/
|
*/
|
||||||
void dacPutChannelX(DACDriver *dacp, dacchannel_t channel, dacsample_t sample) {
|
void dacPutChannelX(DACDriver *dacp, dacchannel_t channel, dacsample_t sample) {
|
||||||
|
|
||||||
osalDbgCheck(channel < (dacchannel_t)DAC_MAX_CHANNELS);
|
osalDbgCheck(channel < (dacchannel_t)DAC_MAX_CHANNELS);
|
||||||
osalDbgAssert(dacp->state == DAC_READY, "invalid state");
|
osalDbgAssert(dacp->state == DAC_READY || dacp->state == DAC_ACTIVE,
|
||||||
|
"invalid state");
|
||||||
dac_lld_put_channel(dacp, channel, sample);
|
|
||||||
}
|
dac_lld_put_channel(dacp, channel, sample);
|
||||||
|
}
|
||||||
/**
|
|
||||||
* @brief Starts a DAC conversion.
|
/**
|
||||||
* @details Starts an asynchronous conversion operation.
|
* @brief Starts a DAC conversion.
|
||||||
* @note The buffer is organized as a matrix of M*N elements where M is the
|
* @details Starts an asynchronous conversion operation.
|
||||||
* channels number configured into the conversion group and N is the
|
* @note The buffer is organized as a matrix of M*N elements where M is the
|
||||||
* buffer depth. The samples are sequentially written into the buffer
|
* channels number configured into the conversion group and N is the
|
||||||
* with no gaps.
|
* buffer depth. The samples are sequentially written into the buffer
|
||||||
*
|
* with no gaps.
|
||||||
* @param[in] dacp pointer to the @p DACDriver object
|
*
|
||||||
* @param[in] grpp pointer to a @p DACConversionGroup object
|
* @param[in] dacp pointer to the @p DACDriver object
|
||||||
* @param[in] samples pointer to the samples buffer
|
* @param[in] grpp pointer to a @p DACConversionGroup object
|
||||||
* @param[in] depth buffer depth (matrix rows number). The buffer depth
|
* @param[in] samples pointer to the samples buffer
|
||||||
* must be one or an even number.
|
* @param[in] depth buffer depth (matrix rows number). The buffer depth
|
||||||
*
|
* must be one or an even number.
|
||||||
* @api
|
*
|
||||||
*/
|
* @api
|
||||||
void dacStartConversion(DACDriver *dacp,
|
*/
|
||||||
const DACConversionGroup *grpp,
|
void dacStartConversion(DACDriver *dacp,
|
||||||
dacsample_t *samples,
|
const DACConversionGroup *grpp,
|
||||||
size_t depth) {
|
dacsample_t *samples,
|
||||||
|
size_t depth) {
|
||||||
osalSysLock();
|
|
||||||
dacStartConversionI(dacp, grpp, samples, depth);
|
osalSysLock();
|
||||||
osalSysUnlock();
|
dacStartConversionI(dacp, grpp, samples, depth);
|
||||||
}
|
osalSysUnlock();
|
||||||
|
}
|
||||||
/**
|
|
||||||
* @brief Starts a DAC conversion.
|
/**
|
||||||
* @details Starts an asynchronous conversion operation.
|
* @brief Starts a DAC conversion.
|
||||||
* @post The callbacks associated to the conversion group will be invoked
|
* @details Starts an asynchronous conversion operation.
|
||||||
* on buffer fill and error events.
|
* @post The callbacks associated to the conversion group will be invoked
|
||||||
* @note The buffer is organized as a matrix of M*N elements where M is the
|
* on buffer complete and error events.
|
||||||
* channels number configured into the conversion group and N is the
|
* @note The buffer is organized as a matrix of M*N elements where M is the
|
||||||
* buffer depth. The samples are sequentially written into the buffer
|
* channels number configured into the conversion group and N is the
|
||||||
* with no gaps.
|
* buffer depth. The samples are sequentially organised in the buffer
|
||||||
*
|
* with no gaps.
|
||||||
* @param[in] dacp pointer to the @p DACDriver object
|
*
|
||||||
* @param[in] grpp pointer to a @p DACConversionGroup object
|
* @param[in] dacp pointer to the @p DACDriver object
|
||||||
* @param[in] samples pointer to the samples buffer
|
* @param[in] grpp pointer to a @p DACConversionGroup object
|
||||||
* @param[in] depth buffer depth (matrix rows number). The buffer depth
|
* @param[in] samples pointer to the samples buffer
|
||||||
* must be one or an even number.
|
* @param[in] depth buffer depth (matrix rows number). The buffer depth
|
||||||
*
|
* must be one or an even number.
|
||||||
* @iclass
|
*
|
||||||
*/
|
* @iclass
|
||||||
void dacStartConversionI(DACDriver *dacp,
|
*/
|
||||||
const DACConversionGroup *grpp,
|
void dacStartConversionI(DACDriver *dacp,
|
||||||
dacsample_t *samples,
|
const DACConversionGroup *grpp,
|
||||||
size_t depth) {
|
dacsample_t *samples,
|
||||||
|
size_t depth) {
|
||||||
osalDbgCheckClassI();
|
|
||||||
osalDbgCheck((dacp != NULL) && (grpp != NULL) && (samples != NULL) &&
|
osalDbgCheckClassI();
|
||||||
((depth == 1U) || ((depth & 1U) == 0U)));
|
osalDbgCheck((dacp != NULL) && (grpp != NULL) && (samples != NULL) &&
|
||||||
osalDbgAssert((dacp->state == DAC_READY) ||
|
((depth == 1U) || ((depth & 1U) == 0U)));
|
||||||
(dacp->state == DAC_COMPLETE) ||
|
osalDbgAssert((dacp->state == DAC_READY) ||
|
||||||
(dacp->state == DAC_ERROR),
|
(dacp->state == DAC_COMPLETE) ||
|
||||||
"not ready");
|
(dacp->state == DAC_ERROR),
|
||||||
|
"not ready");
|
||||||
dacp->samples = samples;
|
|
||||||
dacp->depth = depth;
|
dacp->samples = samples;
|
||||||
dacp->grpp = grpp;
|
dacp->depth = depth;
|
||||||
dacp->state = DAC_ACTIVE;
|
dacp->grpp = grpp;
|
||||||
dac_lld_start_conversion(dacp);
|
dacp->state = DAC_ACTIVE;
|
||||||
}
|
dac_lld_start_conversion(dacp);
|
||||||
|
}
|
||||||
/**
|
|
||||||
* @brief Stops an ongoing conversion.
|
/**
|
||||||
* @details This function stops the currently ongoing conversion and returns
|
* @brief Stops an ongoing conversion.
|
||||||
* the driver in the @p DAC_READY state. If there was no conversion
|
* @details This function stops the currently ongoing conversion and returns
|
||||||
* being processed then the function does nothing.
|
* the driver in the @p DAC_READY state. If there was no conversion
|
||||||
*
|
* being processed then the function does nothing.
|
||||||
* @param[in] dacp pointer to the @p DACDriver object
|
*
|
||||||
*
|
* @param[in] dacp pointer to the @p DACDriver object
|
||||||
* @api
|
*
|
||||||
*/
|
* @api
|
||||||
void dacStopConversion(DACDriver *dacp) {
|
*/
|
||||||
|
void dacStopConversion(DACDriver *dacp) {
|
||||||
osalDbgCheck(dacp != NULL);
|
|
||||||
|
osalDbgCheck(dacp != NULL);
|
||||||
osalSysLock();
|
|
||||||
|
osalSysLock();
|
||||||
osalDbgAssert((dacp->state == DAC_READY) ||
|
|
||||||
(dacp->state == DAC_ACTIVE),
|
osalDbgAssert((dacp->state == DAC_READY) ||
|
||||||
"invalid state");
|
(dacp->state == DAC_ACTIVE),
|
||||||
|
"invalid state");
|
||||||
if (dacp->state != DAC_READY) {
|
|
||||||
dac_lld_stop_conversion(dacp);
|
if (dacp->state != DAC_READY) {
|
||||||
dacp->grpp = NULL;
|
dac_lld_stop_conversion(dacp);
|
||||||
dacp->state = DAC_READY;
|
dacp->grpp = NULL;
|
||||||
_dac_reset_s(dacp);
|
dacp->state = DAC_READY;
|
||||||
}
|
_dac_reset_s(dacp);
|
||||||
|
}
|
||||||
osalSysUnlock();
|
|
||||||
}
|
osalSysUnlock();
|
||||||
|
}
|
||||||
/**
|
|
||||||
* @brief Stops an ongoing conversion.
|
/**
|
||||||
* @details This function stops the currently ongoing conversion and returns
|
* @brief Stops an ongoing conversion.
|
||||||
* the driver in the @p DAC_READY state. If there was no conversion
|
* @details This function stops the currently ongoing conversion and returns
|
||||||
* being processed then the function does nothing.
|
* the driver in the @p DAC_READY state. If there was no conversion
|
||||||
*
|
* being processed then the function does nothing.
|
||||||
* @param[in] dacp pointer to the @p DACDriver object
|
*
|
||||||
*
|
* @param[in] dacp pointer to the @p DACDriver object
|
||||||
* @iclass
|
*
|
||||||
*/
|
* @iclass
|
||||||
void dacStopConversionI(DACDriver *dacp) {
|
*/
|
||||||
|
void dacStopConversionI(DACDriver *dacp) {
|
||||||
osalDbgCheckClassI();
|
|
||||||
osalDbgCheck(dacp != NULL);
|
osalDbgCheckClassI();
|
||||||
osalDbgAssert((dacp->state == DAC_READY) ||
|
osalDbgCheck(dacp != NULL);
|
||||||
(dacp->state == DAC_ACTIVE) ||
|
osalDbgAssert((dacp->state == DAC_READY) ||
|
||||||
(dacp->state == DAC_COMPLETE),
|
(dacp->state == DAC_ACTIVE) ||
|
||||||
"invalid state");
|
(dacp->state == DAC_COMPLETE),
|
||||||
|
"invalid state");
|
||||||
if (dacp->state != DAC_READY) {
|
|
||||||
dac_lld_stop_conversion(dacp);
|
if (dacp->state != DAC_READY) {
|
||||||
dacp->grpp = NULL;
|
dac_lld_stop_conversion(dacp);
|
||||||
dacp->state = DAC_READY;
|
dacp->grpp = NULL;
|
||||||
_dac_reset_i(dacp);
|
dacp->state = DAC_READY;
|
||||||
}
|
_dac_reset_i(dacp);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#if (DAC_USE_WAIT == TRUE) || defined(__DOXYGEN__)
|
|
||||||
/**
|
#if (DAC_USE_SYNCHRONIZATION == TRUE) || defined(__DOXYGEN__)
|
||||||
* @brief Performs a DAC conversion.
|
/**
|
||||||
* @details Performs a synchronous conversion operation.
|
* @brief Performs a DAC conversion.
|
||||||
* @note The buffer is organized as a matrix of M*N elements where M is the
|
* @details Performs a synchronous conversion operation.
|
||||||
* channels number configured into the conversion group and N is the
|
* @note The buffer is organized as a matrix of M*N elements where M is the
|
||||||
* buffer depth. The samples are sequentially written into the buffer
|
* channels number configured into the conversion group and N is the
|
||||||
* with no gaps.
|
* buffer depth. The samples are sequentially organised in the buffer
|
||||||
*
|
* with no gaps.
|
||||||
* @param[in] dacp pointer to the @p DACDriver object
|
*
|
||||||
* @param[in] grpp pointer to a @p DACConversionGroup object
|
* @param[in] dacp pointer to the @p DACDriver object
|
||||||
* @param[out] samples pointer to the samples buffer
|
* @param[in] grpp pointer to a @p DACConversionGroup object
|
||||||
* @param[in] depth buffer depth (matrix rows number). The buffer depth
|
* @param[in] samples pointer to the samples buffer
|
||||||
* must be one or an even number.
|
* @param[in] depth buffer depth (matrix rows number). The buffer depth
|
||||||
* @return The operation result.
|
* must be one or an even number.
|
||||||
* @retval MSG_OK Conversion finished.
|
*
|
||||||
* @retval MSG_RESET The conversion has been stopped using
|
* @return The operation result.
|
||||||
* @p acdStopConversion() or @p acdStopConversionI(),
|
* @retval MSG_OK Conversion finished.
|
||||||
* the result buffer may contain incorrect data.
|
* @retval MSG_RESET The conversion has been stopped using
|
||||||
* @retval MSG_TIMEOUT The conversion has been stopped because an hardware
|
* @p dacStopConversion() or @p dacStopConversionI().
|
||||||
* error.
|
* @retval MSG_TIMEOUT The conversion has been stopped because an hardware
|
||||||
*
|
* error.
|
||||||
* @api
|
*
|
||||||
*/
|
* @api
|
||||||
msg_t dacConvert(DACDriver *dacp,
|
*/
|
||||||
const DACConversionGroup *grpp,
|
msg_t dacConvert(DACDriver *dacp,
|
||||||
dacsample_t *samples,
|
const DACConversionGroup *grpp,
|
||||||
size_t depth) {
|
dacsample_t *samples,
|
||||||
msg_t msg;
|
size_t depth) {
|
||||||
|
msg_t msg;
|
||||||
osalSysLock();
|
|
||||||
|
osalSysLock();
|
||||||
dacStartConversionI(dacp, grpp, samples, depth);
|
|
||||||
msg = osalThreadSuspendS(&dacp->thread);
|
dacStartConversionI(dacp, grpp, samples, depth);
|
||||||
|
msg = osalThreadSuspendS(&dacp->thread);
|
||||||
osalSysUnlock();
|
|
||||||
return msg;
|
osalSysUnlock();
|
||||||
}
|
return msg;
|
||||||
#endif /* DAC_USE_WAIT == TRUE */
|
}
|
||||||
|
|
||||||
#if (DAC_USE_MUTUAL_EXCLUSION == TRUE) || defined(__DOXYGEN__)
|
/**
|
||||||
/**
|
* @brief Synchronize to a conversion completion.
|
||||||
* @brief Gains exclusive access to the DAC bus.
|
* @note This function can only be called by a single thread at time.
|
||||||
* @details This function tries to gain ownership to the DAC bus, if the bus
|
*
|
||||||
* is already being used then the invoking thread is queued.
|
* @param[in] dacp pointer to the @p DACDriver object
|
||||||
* @pre In order to use this function the option @p DAC_USE_MUTUAL_EXCLUSION
|
* @param[in] timeout wait timeout
|
||||||
* must be enabled.
|
*
|
||||||
*
|
* @return The wait result.
|
||||||
* @param[in] dacp pointer to the @p DACDriver object
|
* @retval MSG_OK if operation completed without errors.
|
||||||
*
|
* @retval MSG_TIMEOUT if synchronization request timed out.
|
||||||
* @api
|
* @retval MSG_RESET if the conversion has been stopped.
|
||||||
*/
|
*
|
||||||
void dacAcquireBus(DACDriver *dacp) {
|
* @sclass
|
||||||
|
*/
|
||||||
osalDbgCheck(dacp != NULL);
|
msg_t dacSynchronizeS(DACDriver *dacp, sysinterval_t timeout) {
|
||||||
|
msg_t msg;
|
||||||
osalMutexLock(&dacp->mutex);
|
|
||||||
}
|
osalDbgCheckClassS();
|
||||||
|
osalDbgCheck(dacp != NULL);
|
||||||
/**
|
osalDbgAssert((dacp->state == DAC_ACTIVE) || (dacp->state == DAC_READY),
|
||||||
* @brief Releases exclusive access to the DAC bus.
|
"invalid state");
|
||||||
* @pre In order to use this function the option @p DAC_USE_MUTUAL_EXCLUSION
|
|
||||||
* must be enabled.
|
if (dacp->state == DAC_ACTIVE) {
|
||||||
*
|
msg = osalThreadSuspendTimeoutS(&dacp->thread, timeout);
|
||||||
* @param[in] dacp pointer to the @p DACDriver object
|
}
|
||||||
*
|
else {
|
||||||
* @api
|
msg = MSG_OK;
|
||||||
*/
|
}
|
||||||
void dacReleaseBus(DACDriver *dacp) {
|
|
||||||
|
return msg;
|
||||||
osalDbgCheck(dacp != NULL);
|
}
|
||||||
|
|
||||||
osalMutexUnlock(&dacp->mutex);
|
/**
|
||||||
}
|
* @brief Synchronize to a conversion completion.
|
||||||
#endif /* DAC_USE_MUTUAL_EXCLUSION == TRUE */
|
* @note This function can only be called by a single thread at time.
|
||||||
|
*
|
||||||
#endif /* HAL_USE_DAC == TRUE */
|
* @param[in] dacp pointer to the @p DACDriver object
|
||||||
|
* @param[in] timeout wait timeout
|
||||||
/** @} */
|
*
|
||||||
|
* @return The wait result.
|
||||||
|
* @retval MSG_OK if operation completed without errors.
|
||||||
|
* @retval MSG_TIMEOUT if synchronization request timed out.
|
||||||
|
* @retval MSG_RESET if the conversion has been stopped.
|
||||||
|
*
|
||||||
|
* @api
|
||||||
|
*/
|
||||||
|
msg_t dacSynchronize(DACDriver *dacp, sysinterval_t timeout) {
|
||||||
|
msg_t msg;
|
||||||
|
|
||||||
|
osalSysLock();
|
||||||
|
msg = dacSynchronizeS(dacp, timeout);
|
||||||
|
osalSysUnlock();
|
||||||
|
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
#endif /* DAC_USE_SYNCHRONIZATION == TRUE */
|
||||||
|
|
||||||
|
#if (DAC_USE_MUTUAL_EXCLUSION == TRUE) || defined(__DOXYGEN__)
|
||||||
|
/**
|
||||||
|
* @brief Gains exclusive access to the DAC bus.
|
||||||
|
* @details This function tries to gain ownership to the DAC bus, if the bus
|
||||||
|
* is already being used then the invoking thread is queued.
|
||||||
|
* @pre In order to use this function the option @p DAC_USE_MUTUAL_EXCLUSION
|
||||||
|
* must be enabled.
|
||||||
|
*
|
||||||
|
* @param[in] dacp pointer to the @p DACDriver object
|
||||||
|
*
|
||||||
|
* @api
|
||||||
|
*/
|
||||||
|
void dacAcquireBus(DACDriver *dacp) {
|
||||||
|
|
||||||
|
osalDbgCheck(dacp != NULL);
|
||||||
|
|
||||||
|
osalMutexLock(&dacp->mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Releases exclusive access to the DAC bus.
|
||||||
|
* @pre In order to use this function the option @p DAC_USE_MUTUAL_EXCLUSION
|
||||||
|
* must be enabled.
|
||||||
|
*
|
||||||
|
* @param[in] dacp pointer to the @p DACDriver object
|
||||||
|
*
|
||||||
|
* @api
|
||||||
|
*/
|
||||||
|
void dacReleaseBus(DACDriver *dacp) {
|
||||||
|
|
||||||
|
osalDbgCheck(dacp != NULL);
|
||||||
|
|
||||||
|
osalMutexUnlock(&dacp->mutex);
|
||||||
|
}
|
||||||
|
#endif /* DAC_USE_MUTUAL_EXCLUSION == TRUE */
|
||||||
|
|
||||||
|
#endif /* HAL_USE_DAC == TRUE */
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
|
|
@ -74,6 +74,7 @@
|
||||||
*****************************************************************************
|
*****************************************************************************
|
||||||
|
|
||||||
*** Next ***
|
*** Next ***
|
||||||
|
- NEW: Improved DAC driver, updated STM32 DACv1.
|
||||||
- NEW: STM32 RTCv2 and RTCv3 modified to not use shadow registers.
|
- NEW: STM32 RTCv2 and RTCv3 modified to not use shadow registers.
|
||||||
- NEW: Enhanced STM32F7xx MPU configuration in mcuconf.h.
|
- NEW: Enhanced STM32F7xx MPU configuration in mcuconf.h.
|
||||||
- NEW: I2C slave support in HAL high level driver.
|
- NEW: I2C slave support in HAL high level driver.
|
||||||
|
|
Loading…
Reference in New Issue