From a6224d1964ef80a53500bde178d639c12dda98ee Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 5 Mar 2014 10:30:58 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/kernel_3_dev@6754 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/include/dac.h | 2623 ++++------------------------ os/hal/ports/STM32/LLD/DACv1/dac_lld.c | 2717 ++++------------------------- os/hal/ports/STM32/LLD/DACv1/dac_lld.h | 2811 +++++------------------------- os/hal/ports/STM32/STM32F4xx/platform.mk | 2 + os/hal/src/dac.c | 2667 ++++------------------------ 5 files changed, 1373 insertions(+), 9447 deletions(-) (limited to 'os/hal') diff --git a/os/hal/include/dac.h b/os/hal/include/dac.h index 69c82c864..ac2396b1c 100644 --- a/os/hal/include/dac.h +++ b/os/hal/include/dac.h @@ -1,2321 +1,302 @@ - - - - - - - - - - - ChibiOS/os/hal/include/dac.h at dac-3.0 · mobyfab/ChibiOS · GitHub - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - -
-
- - - - - - - -
- - -
- - - - - -
- - This repository - - - -
- - - - - - - - -
-
- -
-
- - - - -
- -
-
- - - - -

- public - - - - - / - ChibiOS - - - Octocat-spinner-32 - - - - forked from mabl/ChibiOS - -

-
-
- -
-
-
- - -
-
- -
- - - -
-
- -
- - - - -
-

HTTPS clone URL

-
- - - -
-
- - - -
-

Subversion checkout URL

-
- - - -
-
- - -

You can clone with - HTTPS - or Subversion. - - - - - -

- - - - - Clone in Desktop - - - - - Download ZIP - -
-
- -
- - - - - - - - - -
- - -
- - - branch: - dac-3.0 - - - -
- - -
- - -
- Fetching contributors… - -
-

Octocat-spinner-32-eaf2f5

-

Cannot retrieve contributors at this time

-
-
- -
-
-
-
- - file - - 303 lines (270 sloc) - - 12.389 kb -
- -
-
- - - - - -
- 1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -202 -203 -204 -205 -206 -207 -208 -209 -210 -211 -212 -213 -214 -215 -216 -217 -218 -219 -220 -221 -222 -223 -224 -225 -226 -227 -228 -229 -230 -231 -232 -233 -234 -235 -236 -237 -238 -239 -240 -241 -242 -243 -244 -245 -246 -247 -248 -249 -250 -251 -252 -253 -254 -255 -256 -257 -258 -259 -260 -261 -262 -263 -264 -265 -266 -267 -268 -269 -270 -271 -272 -273 -274 -275 -276 -277 -278 -279 -280 -281 -282 -283 -284 -285 -286 -287 -288 -289 -290 -291 -292 -293 -294 -295 -296 -297 -298 -299 -300 -301 -302 - -
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
2011,2012 Giovanni Di Sirio.

This file is part of ChibiOS/RT.

ChibiOS/RT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.

ChibiOS/RT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

/**
* @file dac.h
* @brief DAC Driver macros and structures.
*
* @addtogroup DAC
* @{
*/

#ifndef _DAC_H_
#define _DAC_H_

#if HAL_USE_DAC || defined(__DOXYGEN__)

/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/

/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/

/**
* @name DAC configuration options
* @{
*/
/**
* @brief Enables synchronous APIs.
* @note Disabling this option saves both code and data space.
*/
#if !defined(DAC_USE_WAIT) || defined(__DOXYGEN__)
#define DAC_USE_WAIT TRUE
#endif

/**
* @brief Enables the @p dacAcquireBus() and @p dacReleaseBus() APIs.
* @note Disabling this option saves both code and data space.
*/
#if !defined(DAC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
#define DAC_USE_MUTUAL_EXCLUSION TRUE
#endif
/** @} */

/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/

#if DAC_USE_MUTUAL_EXCLUSION && !CH_USE_MUTEXES && !CH_USE_SEMAPHORES && !NIL_USE_MUTEXES && !NIL_USE_SEMAPHORES
//#error "DAC_USE_MUTUAL_EXCLUSION requires CH_USE_MUTEXES and/or CH_USE_SEMAPHORES"
#endif

/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/

/**
* @brief Driver state machine possible states.
*/
typedef enum {
  DAC_UNINIT = 0, /**< Not initialized. */
  DAC_STOP = 1, /**< Stopped. */
  DAC_READY = 2, /**< Ready. */
  DAC_ACTIVE = 3, /**< Exchanging data. */
  DAC_COMPLETE = 4, /**< Asynchronous operation complete. */
  DAC_ERROR = 5 /**< Error. */
} dacstate_t;

#include "dac_lld.h"

/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/

/**
* @name Low Level driver helper macros
* @{
*/
#if DAC_USE_WAIT || defined(__DOXYGEN__)
/**
* @brief Waits for operation completion.
* @details This function waits for the driver to complete the current
* operation.
* @pre An operation must be running while the function is invoked.
* @note No more than one thread can wait on a DAC driver using
* this function.
*
* @param[in] dacp pointer to the @p DACDriver object
*
* @notapi
*/
#define _dac_wait_s(dacp) osalThreadSuspendS(&(dacp)->thread)

/**
* @brief Resumes a thread waiting for a conversion completion.
*
* @param[in] dacp pointer to the @p DACDriver object
*
* @notapi
*/
#define _dac_reset_i(dacp) osalThreadResumeI(&(dacp)->thread, MSG_RESET)


/**
* @brief Resumes a thread waiting for a conversion completion.
*
* @param[in] dacp pointer to the @p DACDriver object
*
* @notapi
*/
#define _dac_reset_s(dacp) osalThreadResumeS(&(dacp)->thread, MSG_RESET)

/**
* @brief Wakes up the waiting thread.
*
* @param[in] dacp pointer to the @p DACDriver object
*
* @notapi
*/
#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
*
* @notapi
*/
#define _dac_timeout_isr(dacp) { \
osalSysLockFromISR(); \
osalThreadResumeI(&(dacp)->thread, MSG_TIMEOUT); \
osalSysUnlockFromISR(); \
}

#else /* !DAC_USE_WAIT */
#define _dac_wait_s(dacp)
#define _dac_reset_i(dacp)
#define _dac_reset_s(dacp)
#define _dac_wakeup_isr(dacp)
#define _dac_timeout_isr(dacp)
#endif /* !DAC_USE_WAIT */

/**
* @brief Common ISR code, half buffer event.
* @details This code handles the portable part of the ISR code:
* - Callback invocation.
* .
* @note This macro is meant to be used in the low level drivers
* implementation only.
*
* @param[in] dacp pointer to the @p DACDriver object
*
* @notapi
*/
#define _dac_isr_half_code(dacp) { \
if ((dacp)->grpp->end_cb != NULL) { \
(dacp)->grpp->end_cb(dacp, (dacp)->samples, (dacp)->depth / 2); \
} \
}

/**
* @brief Common ISR code, full buffer event.
* @details This code handles the portable part of the ISR code:
* - Callback invocation.
* - Waiting thread wakeup, if any.
* - Driver state transitions.
* .
* @note This macro is meant to be used in the low level drivers
* implementation only.
*
* @param[in] dacp pointer to the @p DACDriver object
*
* @notapi
*/
#define _dac_isr_full_code(dacp) { \
if ((dacp)->grpp->circular) { \
/* Callback handling.*/ \
if ((dacp)->grpp->end_cb != NULL) { \
if ((dacp)->depth > 1) { \
/* Invokes the callback passing the 2nd half of the buffer.*/ \
size_t half = (dacp)->depth / 2; \
size_t half_index = half * (dacp)->grpp->num_channels; \
(dacp)->grpp->end_cb(dacp, (dacp)->samples + half_index, half); \
} \
else { \
/* Invokes the callback passing the whole buffer.*/ \
(dacp)->grpp->end_cb(dacp, (dacp)->samples, (dacp)->depth); \
} \
} \
} \
else { \
/* End conversion.*/ \
dac_lld_stop_conversion(dacp); \
if ((dacp)->grpp->end_cb != NULL) { \
(dacp)->state = DAC_COMPLETE; \
if ((dacp)->depth > 1) { \
/* Invokes the callback passing the 2nd half of the buffer.*/ \
size_t half = (dacp)->depth / 2; \
size_t half_index = half * (dacp)->grpp->num_channels; \
(dacp)->grpp->end_cb(dacp, (dacp)->samples + half_index, half); \
} \
else { \
/* Invokes the callback passing the whole buffer.*/ \
(dacp)->grpp->end_cb(dacp, (dacp)->samples, (dacp)->depth); \
} \
if ((dacp)->state == DAC_COMPLETE) { \
(dacp)->state = DAC_READY; \
(dacp)->grpp = NULL; \
} \
} \
else { \
(dacp)->state = DAC_READY; \
(dacp)->grpp = NULL; \
} \
_dac_wakeup_isr(dacp); \
} \
}

/**
* @brief Common ISR code, error event.
* @details This code handles the portable part of the ISR code:
* - Callback invocation.
* - Waiting thread timeout signaling, if any.
* - Driver state transitions.
* .
* @note This macro is meant to be used in the low level drivers
* implementation only.
*
* @param[in] dacp pointer to the @p DACDriver object
* @param[in] err platform dependent error code
*
* @notapi
*/
#define _dac_isr_error_code(dacp, err) { \
dac_lld_stop_conversion(dacp); \
if ((dacp)->grpp->error_cb != NULL) { \
(dacp)->state = DAC_ERROR; \
(dacp)->grpp->error_cb(dacp, err); \
if ((dacp)->state == DAC_ERROR) \
(dacp)->state = DAC_READY; \
} \
(dacp)->grpp = NULL; \
_dac_timeout_isr(dacp); \
}
/** @} */

/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/

#ifdef __cplusplus
extern "C" {
#endif
  void dacInit(void);
  void dacObjectInit(DACDriver *dacp);
  void dacStart(DACDriver *dacp, const DACConfig *config);
  void dacStop(DACDriver *dacp);
  void dacStartConversion(DACDriver *dacp, const DACConversionGroup *grpp,
                          const dacsample_t *samples, size_t depth);
  void dacStartConversionI(DACDriver *dacp, const DACConversionGroup *grpp,
                           const dacsample_t *samples, size_t depth);
  void dacStopConversion(DACDriver *dacp);
  void dacStopConversionI(DACDriver *dacp);
#if DAC_USE_WAIT || defined(__DOXYGEN__)
  msg_t dacConvert(DACDriver *dacp, const DACConversionGroup *grpp,
                   const dacsample_t *samples, size_t depth);
#endif /* DAC_USE_WAIT */
#if DAC_USE_MUTUAL_EXCLUSION
  void dacAcquireBus(DACDriver *dacp);
  void dacReleaseBus(DACDriver *dacp);
#endif /* DAC_USE_MUTUAL_EXCLUSION */
#ifdef __cplusplus
}
#endif

#endif /* HAL_USE_DAC */

#endif /* _DAC_H_ */

/** @} */
-
- -
-
- - - - -
- -
- -
-
- - -
- -
- -
- - -
-
-
- -
-
- -
- - - -
- - - Something went wrong with that request. Please try again. -
- - - - +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011,2012 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file dac.h + * @brief DAC Driver macros and structures. + * + * @addtogroup DAC + * @{ + */ + +#ifndef _DAC_H_ +#define _DAC_H_ + +#if HAL_USE_DAC || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @name DAC configuration options + * @{ + */ +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(DAC_USE_WAIT) || defined(__DOXYGEN__) +#define DAC_USE_WAIT TRUE +#endif + +/** + * @brief Enables the @p dacAcquireBus() and @p dacReleaseBus() APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(DAC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define DAC_USE_MUTUAL_EXCLUSION TRUE +#endif +/** @} */ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +#if DAC_USE_MUTUAL_EXCLUSION && !CH_USE_MUTEXES && !CH_USE_SEMAPHORES && !NIL_USE_MUTEXES && !NIL_USE_SEMAPHORES +//#error "DAC_USE_MUTUAL_EXCLUSION requires CH_USE_MUTEXES and/or CH_USE_SEMAPHORES" +#endif + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/** + * @brief Driver state machine possible states. + */ +typedef enum { + DAC_UNINIT = 0, /**< Not initialized. */ + DAC_STOP = 1, /**< Stopped. */ + DAC_READY = 2, /**< Ready. */ + DAC_ACTIVE = 3, /**< Exchanging data. */ + DAC_COMPLETE = 4, /**< Asynchronous operation complete. */ + DAC_ERROR = 5 /**< Error. */ +} dacstate_t; + +#include "dac_lld.h" + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/** + * @name Low Level driver helper macros + * @{ + */ +#if DAC_USE_WAIT || defined(__DOXYGEN__) +/** + * @brief Waits for operation completion. + * @details This function waits for the driver to complete the current + * operation. + * @pre An operation must be running while the function is invoked. + * @note No more than one thread can wait on a DAC driver using + * this function. + * + * @param[in] dacp pointer to the @p DACDriver object + * + * @notapi + */ +#define _dac_wait_s(dacp) osalThreadSuspendS(&(dacp)->thread) + +/** + * @brief Resumes a thread waiting for a conversion completion. + * + * @param[in] dacp pointer to the @p DACDriver object + * + * @notapi + */ +#define _dac_reset_i(dacp) osalThreadResumeI(&(dacp)->thread, MSG_RESET) + + +/** + * @brief Resumes a thread waiting for a conversion completion. + * + * @param[in] dacp pointer to the @p DACDriver object + * + * @notapi + */ +#define _dac_reset_s(dacp) osalThreadResumeS(&(dacp)->thread, MSG_RESET) + +/** + * @brief Wakes up the waiting thread. + * + * @param[in] dacp pointer to the @p DACDriver object + * + * @notapi + */ +#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 + * + * @notapi + */ +#define _dac_timeout_isr(dacp) { \ + osalSysLockFromISR(); \ + osalThreadResumeI(&(dacp)->thread, MSG_TIMEOUT); \ + osalSysUnlockFromISR(); \ +} + +#else /* !DAC_USE_WAIT */ +#define _dac_wait_s(dacp) +#define _dac_reset_i(dacp) +#define _dac_reset_s(dacp) +#define _dac_wakeup_isr(dacp) +#define _dac_timeout_isr(dacp) +#endif /* !DAC_USE_WAIT */ + +/** + * @brief Common ISR code, half buffer event. + * @details This code handles the portable part of the ISR code: + * - Callback invocation. + * . + * @note This macro is meant to be used in the low level drivers + * implementation only. + * + * @param[in] dacp pointer to the @p DACDriver object + * + * @notapi + */ +#define _dac_isr_half_code(dacp) { \ + if ((dacp)->grpp->end_cb != NULL) { \ + (dacp)->grpp->end_cb(dacp, (dacp)->samples, (dacp)->depth / 2); \ + } \ +} + +/** + * @brief Common ISR code, full buffer event. + * @details This code handles the portable part of the ISR code: + * - Callback invocation. + * - Waiting thread wakeup, if any. + * - Driver state transitions. + * . + * @note This macro is meant to be used in the low level drivers + * implementation only. + * + * @param[in] dacp pointer to the @p DACDriver object + * + * @notapi + */ +#define _dac_isr_full_code(dacp) { \ + if ((dacp)->grpp->circular) { \ + /* Callback handling.*/ \ + if ((dacp)->grpp->end_cb != NULL) { \ + if ((dacp)->depth > 1) { \ + /* Invokes the callback passing the 2nd half of the buffer.*/ \ + size_t half = (dacp)->depth / 2; \ + size_t half_index = half * (dacp)->grpp->num_channels; \ + (dacp)->grpp->end_cb(dacp, (dacp)->samples + half_index, half); \ + } \ + else { \ + /* Invokes the callback passing the whole buffer.*/ \ + (dacp)->grpp->end_cb(dacp, (dacp)->samples, (dacp)->depth); \ + } \ + } \ + } \ + else { \ + /* End conversion.*/ \ + dac_lld_stop_conversion(dacp); \ + if ((dacp)->grpp->end_cb != NULL) { \ + (dacp)->state = DAC_COMPLETE; \ + if ((dacp)->depth > 1) { \ + /* Invokes the callback passing the 2nd half of the buffer.*/ \ + size_t half = (dacp)->depth / 2; \ + size_t half_index = half * (dacp)->grpp->num_channels; \ + (dacp)->grpp->end_cb(dacp, (dacp)->samples + half_index, half); \ + } \ + else { \ + /* Invokes the callback passing the whole buffer.*/ \ + (dacp)->grpp->end_cb(dacp, (dacp)->samples, (dacp)->depth); \ + } \ + if ((dacp)->state == DAC_COMPLETE) { \ + (dacp)->state = DAC_READY; \ + (dacp)->grpp = NULL; \ + } \ + } \ + else { \ + (dacp)->state = DAC_READY; \ + (dacp)->grpp = NULL; \ + } \ + _dac_wakeup_isr(dacp); \ + } \ +} + +/** + * @brief Common ISR code, error event. + * @details This code handles the portable part of the ISR code: + * - Callback invocation. + * - Waiting thread timeout signaling, if any. + * - Driver state transitions. + * . + * @note This macro is meant to be used in the low level drivers + * implementation only. + * + * @param[in] dacp pointer to the @p DACDriver object + * @param[in] err platform dependent error code + * + * @notapi + */ +#define _dac_isr_error_code(dacp, err) { \ + dac_lld_stop_conversion(dacp); \ + if ((dacp)->grpp->error_cb != NULL) { \ + (dacp)->state = DAC_ERROR; \ + (dacp)->grpp->error_cb(dacp, err); \ + if ((dacp)->state == DAC_ERROR) \ + (dacp)->state = DAC_READY; \ + } \ + (dacp)->grpp = NULL; \ + _dac_timeout_isr(dacp); \ +} +/** @} */ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + void dacInit(void); + void dacObjectInit(DACDriver *dacp); + void dacStart(DACDriver *dacp, const DACConfig *config); + void dacStop(DACDriver *dacp); + void dacStartConversion(DACDriver *dacp, const DACConversionGroup *grpp, + const dacsample_t *samples, size_t depth); + void dacStartConversionI(DACDriver *dacp, const DACConversionGroup *grpp, + const dacsample_t *samples, size_t depth); + void dacStopConversion(DACDriver *dacp); + void dacStopConversionI(DACDriver *dacp); +#if DAC_USE_WAIT || defined(__DOXYGEN__) + msg_t dacConvert(DACDriver *dacp, const DACConversionGroup *grpp, + const dacsample_t *samples, size_t depth); +#endif /* DAC_USE_WAIT */ +#if DAC_USE_MUTUAL_EXCLUSION + void dacAcquireBus(DACDriver *dacp); + void dacReleaseBus(DACDriver *dacp); +#endif /* DAC_USE_MUTUAL_EXCLUSION */ +#ifdef __cplusplus +} +#endif + +#endif /* HAL_USE_DAC */ + +#endif /* _DAC_H_ */ + +/** @} */ diff --git a/os/hal/ports/STM32/LLD/DACv1/dac_lld.c b/os/hal/ports/STM32/LLD/DACv1/dac_lld.c index bd65728db..4eee1725a 100644 --- a/os/hal/ports/STM32/LLD/DACv1/dac_lld.c +++ b/os/hal/ports/STM32/LLD/DACv1/dac_lld.c @@ -1,2370 +1,351 @@ - - - - - - - - - - - ChibiOS/os/hal/ports/STM32/DACv1/dac_lld.c at dac-3.0 · mobyfab/ChibiOS · GitHub - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011,2012 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file STM32/DACv1/dac_lld.c + * @brief STM32 DAC subsystem low level driver source. + * + * @addtogroup DAC + * @{ + */ + +#include "hal.h" + +#if HAL_USE_DAC || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +#if !defined(DAC1) +#define DAC1 DAC +#define rccEnableDAC1 rccEnableDAC +#define rccDisableDAC1 rccDisableDAC +#endif + +#define DAC_CHN1_DMA_CHANNEL \ + STM32_DMA_GETCHANNEL(STM32_DAC_CHN1_DMA_STREAM, \ + STM32_DAC_CHN1_DMA_CHN) + +#define DAC_CHN2_DMA_CHANNEL \ + STM32_DMA_GETCHANNEL(STM32_DAC_CHN2_DMA_STREAM, \ + STM32_DAC_CHN2_DMA_CHN) + +#define DAC_CHN3_DMA_CHANNEL \ + STM32_DMA_GETCHANNEL(STM32_DAC_CHN3_DMA_STREAM, \ + STM32_DAC_CHN3_DMA_CHN) + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** @brief CHN1 driver identifier.*/ +#if STM32_DAC_USE_CHN1 || defined(__DOXYGEN__) +DACDriver DACD1; +#endif + +/** @brief CHN2 driver identifier.*/ +#if STM32_DAC_USE_CHN2 || defined(__DOXYGEN__) +DACDriver DACD2; +#endif + +/** @brief CHN3 driver identifier.*/ +#if STM32_DAC_USE_CHN3 || defined(__DOXYGEN__) +DACDriver DACD3; +#endif + +/*===========================================================================*/ +/* Driver local variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + + +/** + * @brief Shared end/half-of-tx service routine. + * + * @param[in] dacp pointer to the @p DACDriver object + * @param[in] flags pre-shifted content of the ISR register + */ +static void dac_lld_serve_tx_interrupt(DACDriver *dacp, uint32_t flags) { +#if defined(STM32_DAC_DMA_ERROR_HOOK) + (void)dacp; + if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) { + /* DMA errors handling.*/ + //~ _dac_isr_error_code(dacp, flags); + } + else { + if ((flags & STM32_DMA_ISR_HTIF) != 0) { + /* Half transfer processing.*/ + //~ _dac_isr_half_code(dacp); + } + if ((flags & STM32_DMA_ISR_TCIF) != 0) { + /* Transfer complete processing.*/ + //~ _dac_isr_full_code(dacp); + } + } +#else + (void)dacp; + (void)flags; +#endif +} + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Low level DAC driver initialization. + * + * @notapi + */ +void dac_lld_init(void) { + +#if STM32_DAC_USE_CHN1 + dacObjectInit(&DACD1); + DACD1.dac = DAC1; + DACD1.tim = STM32_TIM6; + DACD1.irqprio = STM32_DAC_CHN1_IRQ_PRIORITY; + DACD1.dma = STM32_DMA_STREAM(STM32_DAC_CHN1_DMA_STREAM); + DACD1.dmamode = STM32_DMA_CR_CHSEL(DAC_CHN1_DMA_CHANNEL) | \ + STM32_DMA_CR_PL(STM32_DAC_CHN1_DMA_PRIORITY) | \ + STM32_DMA_CR_DIR_M2P | \ + STM32_DMA_CR_DMEIE | \ + STM32_DMA_CR_TEIE | \ + STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE; +#endif + +#if STM32_DAC_USE_CHN2 + dacObjectInit(&DACD2); + DACD2.dac = DAC1; + DACD2.tim = STM32_TIM7; + DACD2.irqprio = STM32_DAC_CHN2_IRQ_PRIORITY; + DACD2.dma = STM32_DMA_STREAM(STM32_DAC_CHN2_DMA_STREAM); + DACD2.dmamode = STM32_DMA_CR_CHSEL(DAC_CHN2_DMA_CHANNEL) | \ + STM32_DMA_CR_PL(STM32_DAC_CHN2_DMA_PRIORITY) | \ + STM32_DMA_CR_DIR_M2P | \ + STM32_DMA_CR_DMEIE | \ + STM32_DMA_CR_TEIE | \ + STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE; +#endif + +#if STM32_DAC_USE_CHN3 + dacObjectInit(&DACD3); + DACD3.dac = DAC2; + DACD3.tim = STM32_TIM18; + DACD3.irqprio = STM32_DAC_CHN3_IRQ_PRIORITY; + DACD3.dma = STM32_DMA_STREAM(STM32_DAC_CHN3_DMA_STREAM); + DACD3.dmamode = STM32_DMA_CR_CHSEL(DAC_CHN3_DMA_CHANNEL) | \ + STM32_DMA_CR_PL(STM32_DAC_CHN2_DMA_PRIORITY) | \ + STM32_DMA_CR_DIR_M2P | \ + STM32_DMA_CR_DMEIE | \ + STM32_DMA_CR_TEIE | \ + STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE; +#endif +} + +/** + * @brief Configures and activates the DAC peripheral. + * + * @param[in] dacp pointer to the @p DACDriver object + * + * @notapi + */ +void dac_lld_start(DACDriver *dacp) { + uint32_t arr, regshift, trgo, dataoffset; + bool b; + /* If in stopped state then enables the DAC and DMA clocks.*/ + if (dacp->state == DAC_STOP) { +#if STM32_DAC_USE_CHN1 + if (&DACD1 == dacp) { + rccEnableDAC1(FALSE); + /* DAC1 CR data is at bits 0:15 */ + regshift = 0; + dataoffset = 0; + /* Timer setup */ + rccEnableTIM6(FALSE); + rccResetTIM6(); + trgo = STM32_DAC_CR_TSEL_TIM6; + } +#endif +#if STM32_DAC_USE_CHN2 + if (&DACD2 == dacp) { + rccEnableDAC1(FALSE); + /* DAC2 CR data is at bits 16:31 */ + regshift = 16; + dataoffset = &dacp->dac->DHR12R2 - &dacp->dac->DHR12R1; + /* Timer setup */ + rccEnableTIM7(FALSE); + rccResetTIM7(); + trgo = STM32_DAC_CR_TSEL_TIM7; + } +#endif +#if STM32_DAC_USE_CHN3 + if (&DACD3 == dacp) { + rccEnableDAC2(FALSE); + /* DAC3 CR data is at bits 0:15 */ + regshift = 0; + dataoffset = 0; + /* Timer setup */ + rccEnableTIM18(FALSE); + rccResetTIM18(); + trgo = STM32_DAC_CR_TSEL_TIM18; + } +#endif +#if STM32_DAC_USE_CHN1 || STM32_DAC_USE_CHN2 || STM32_DAC_USE_CHN3 + dacp->clock = STM32_TIMCLK1; + arr = (dacp->clock / dacp->config->frequency); + osalDbgAssert((arr <= 0xFFFF), + "invalid frequency"); + + /* Timer configuration.*/ + dacp->tim->CR1 = 0; /* Initially stopped. */ + dacp->tim->PSC = 0; /* Prescaler value. */ + dacp->tim->DIER = 0; + dacp->tim->ARR = arr; + dacp->tim->EGR = TIM_EGR_UG; /* Update event. */ + dacp->tim->CR2 &= (uint16_t)~TIM_CR2_MMS; + dacp->tim->CR2 |= (uint16_t)TIM_CR2_MMS_1; /* Enable TRGO updates. */ + dacp->tim->CNT = 0; /* Reset counter. */ + dacp->tim->SR = 0; /* Clear pending IRQs. */ + /* Update Event IRQ enabled. */ + /* Timer start.*/ + dacp->tim->CR1 = TIM_CR1_CEN; + + /* DAC configuration */ + dacp->dac->CR |= ( (dacp->dac->CR & ~STM32_DAC_CR_MASK) | \ + (STM32_DAC_CR_EN | STM32_DAC_CR_DMAEN | dacp->config->cr_flags) ) << regshift; - - - - - - - - - - - - - -
- - - - - - - -
-
- - - - - - - -
- - -
- - - - - -
- - This repository - - - -
- - - - - - - - -
-
- -
-
- - - - -
- -
-
- - - - -

- public - - - - - / - ChibiOS - - - Octocat-spinner-32 - - - - forked from mabl/ChibiOS - -

-
-
- -
-
-
- - -
-
- -
- - - -
-
- -
- - - - -
-

HTTPS clone URL

-
- - - -
-
- + /* DMA setup. */ + b = dmaStreamAllocate(dacp->dma, + dacp->irqprio, + (stm32_dmaisr_t)dac_lld_serve_tx_interrupt, + (void *)dacp); + osalDbgAssert(!b, "stream already allocated"); + switch (dacp->config->dhrm) { + /* Sets the DAC data register */ + case DAC_DHRM_12BIT_RIGHT: + dmaStreamSetPeripheral(dacp->dma, &dacp->dac->DHR12R1 + dataoffset); + dacp->dmamode = (dacp->dmamode & ~STM32_DMA_CR_SIZE_MASK) | + STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD; + break; + case DAC_DHRM_12BIT_LEFT: + dmaStreamSetPeripheral(dacp->dma, &dacp->dac->DHR12L1 + dataoffset); + dacp->dmamode = (dacp->dmamode & ~STM32_DMA_CR_SIZE_MASK) | + STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD; + break; + case DAC_DHRM_8BIT_RIGHT: + dmaStreamSetPeripheral(dacp->dma, &dacp->dac->DHR8R1 + dataoffset); + dacp->dmamode = (dacp->dmamode & ~STM32_DMA_CR_SIZE_MASK) | + STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE; + break; +#if defined(STM32_HAS_DAC_CHN2) && STM32_HAS_DAC_CHN2 + case DAC_DHRM_12BIT_RIGHT_DUAL: + dmaStreamSetPeripheral(dacp->dma, &dacp->dac->DHR12RD); + dacp->dmamode = (dacp->dmamode & ~STM32_DMA_CR_SIZE_MASK) | + STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD; + break; + case DAC_DHRM_12BIT_LEFT_DUAL: + dmaStreamSetPeripheral(dacp->dma, &dacp->dac->DHR12LD); + dacp->dmamode = (dacp->dmamode & ~STM32_DMA_CR_SIZE_MASK) | + STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD; + break; + case DAC_DHRM_8BIT_RIGHT_DUAL: + dmaStreamSetPeripheral(dacp->dma, &dacp->dac->DHR8RD); + dacp->dmamode = (dacp->dmamode & ~STM32_DMA_CR_SIZE_MASK) | + STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE; + break; +#endif + } - -
-

Subversion checkout URL

-
- - - -
-
- - -

You can clone with - HTTPS - or Subversion. - - - - - -

- - - - - Clone in Desktop - - - - - Download ZIP - -
-
- -
- - - - - - - - - -
- - -
- - - branch: - dac-3.0 - - - -
- - -
- - -
- Fetching contributors… - -
-

Octocat-spinner-32-eaf2f5

-

Cannot retrieve contributors at this time

-
-
- -
-
-
-
- - file - - 352 lines (313 sloc) - - 12.38 kb -
- -
-
- - - - - -
- 1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -202 -203 -204 -205 -206 -207 -208 -209 -210 -211 -212 -213 -214 -215 -216 -217 -218 -219 -220 -221 -222 -223 -224 -225 -226 -227 -228 -229 -230 -231 -232 -233 -234 -235 -236 -237 -238 -239 -240 -241 -242 -243 -244 -245 -246 -247 -248 -249 -250 -251 -252 -253 -254 -255 -256 -257 -258 -259 -260 -261 -262 -263 -264 -265 -266 -267 -268 -269 -270 -271 -272 -273 -274 -275 -276 -277 -278 -279 -280 -281 -282 -283 -284 -285 -286 -287 -288 -289 -290 -291 -292 -293 -294 -295 -296 -297 -298 -299 -300 -301 -302 -303 -304 -305 -306 -307 -308 -309 -310 -311 -312 -313 -314 -315 -316 -317 -318 -319 -320 -321 -322 -323 -324 -325 -326 -327 -328 -329 -330 -331 -332 -333 -334 -335 -336 -337 -338 -339 -340 -341 -342 -343 -344 -345 -346 -347 -348 -349 -350 -351 - -
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
2011,2012 Giovanni Di Sirio.

This file is part of ChibiOS/RT.

ChibiOS/RT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.

ChibiOS/RT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

/**
* @file STM32/DACv1/dac_lld.c
* @brief STM32 DAC subsystem low level driver source.
*
* @addtogroup DAC
* @{
*/

#include "hal.h"

#if HAL_USE_DAC || defined(__DOXYGEN__)

/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/

#if !defined(DAC1)
#define DAC1 DAC
#define rccEnableDAC1 rccEnableDAC
#define rccDisableDAC1 rccDisableDAC
#endif

#define DAC_CHN1_DMA_CHANNEL \
STM32_DMA_GETCHANNEL(STM32_DAC_CHN1_DMA_STREAM, \
STM32_DAC_CHN1_DMA_CHN)

#define DAC_CHN2_DMA_CHANNEL \
STM32_DMA_GETCHANNEL(STM32_DAC_CHN2_DMA_STREAM, \
STM32_DAC_CHN2_DMA_CHN)
#define DAC_CHN3_DMA_CHANNEL \
STM32_DMA_GETCHANNEL(STM32_DAC_CHN3_DMA_STREAM, \
STM32_DAC_CHN3_DMA_CHN)

/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/

/** @brief CHN1 driver identifier.*/
#if STM32_DAC_USE_CHN1 || defined(__DOXYGEN__)
DACDriver DACD1;
#endif

/** @brief CHN2 driver identifier.*/
#if STM32_DAC_USE_CHN2 || defined(__DOXYGEN__)
DACDriver DACD2;
#endif

/** @brief CHN3 driver identifier.*/
#if STM32_DAC_USE_CHN3 || defined(__DOXYGEN__)
DACDriver DACD3;
#endif

/*===========================================================================*/
/* Driver local variables. */
/*===========================================================================*/

/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/


/**
* @brief Shared end/half-of-tx service routine.
*
* @param[in] dacp pointer to the @p DACDriver object
* @param[in] flags pre-shifted content of the ISR register
*/
static void dac_lld_serve_tx_interrupt(DACDriver *dacp, uint32_t flags) {
#if defined(STM32_DAC_DMA_ERROR_HOOK)
  (void)dacp;
  if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) {
    /* DMA errors handling.*/
    //~ _dac_isr_error_code(dacp, flags);
  }
  else {
    if ((flags & STM32_DMA_ISR_HTIF) != 0) {
      /* Half transfer processing.*/
      //~ _dac_isr_half_code(dacp);
    }
    if ((flags & STM32_DMA_ISR_TCIF) != 0) {
      /* Transfer complete processing.*/
      //~ _dac_isr_full_code(dacp);
    }
  }
#else
  (void)dacp;
  (void)flags;
#endif
}

/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/

/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/

/**
* @brief Low level DAC driver initialization.
*
* @notapi
*/
void dac_lld_init(void) {

#if STM32_DAC_USE_CHN1
  dacObjectInit(&DACD1);
  DACD1.dac = DAC1;
  DACD1.tim = STM32_TIM6;
  DACD1.irqprio = STM32_DAC_CHN1_IRQ_PRIORITY;
  DACD1.dma = STM32_DMA_STREAM(STM32_DAC_CHN1_DMA_STREAM);
  DACD1.dmamode = STM32_DMA_CR_CHSEL(DAC_CHN1_DMA_CHANNEL) | \
                  STM32_DMA_CR_PL(STM32_DAC_CHN1_DMA_PRIORITY) | \
                  STM32_DMA_CR_DIR_M2P | \
                  STM32_DMA_CR_DMEIE | \
                  STM32_DMA_CR_TEIE | \
                  STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE;
#endif

#if STM32_DAC_USE_CHN2
  dacObjectInit(&DACD2);
  DACD2.dac = DAC1;
  DACD2.tim = STM32_TIM7;
  DACD2.irqprio = STM32_DAC_CHN2_IRQ_PRIORITY;
  DACD2.dma = STM32_DMA_STREAM(STM32_DAC_CHN2_DMA_STREAM);
  DACD2.dmamode = STM32_DMA_CR_CHSEL(DAC_CHN2_DMA_CHANNEL) | \
                  STM32_DMA_CR_PL(STM32_DAC_CHN2_DMA_PRIORITY) | \
                  STM32_DMA_CR_DIR_M2P | \
                  STM32_DMA_CR_DMEIE | \
                  STM32_DMA_CR_TEIE | \
                  STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE;
#endif

#if STM32_DAC_USE_CHN3
  dacObjectInit(&DACD3);
  DACD3.dac = DAC2;
  DACD3.tim = STM32_TIM18;
  DACD3.irqprio = STM32_DAC_CHN3_IRQ_PRIORITY;
  DACD3.dma = STM32_DMA_STREAM(STM32_DAC_CHN3_DMA_STREAM);
  DACD3.dmamode = STM32_DMA_CR_CHSEL(DAC_CHN3_DMA_CHANNEL) | \
                  STM32_DMA_CR_PL(STM32_DAC_CHN2_DMA_PRIORITY) | \
                  STM32_DMA_CR_DIR_M2P | \
                  STM32_DMA_CR_DMEIE | \
                  STM32_DMA_CR_TEIE | \
                  STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE;
#endif
}

/**
* @brief Configures and activates the DAC peripheral.
*
* @param[in] dacp pointer to the @p DACDriver object
*
* @notapi
*/
void dac_lld_start(DACDriver *dacp) {
  uint32_t arr, regshift, trgo, dataoffset;
  bool b;
  /* If in stopped state then enables the DAC and DMA clocks.*/
  if (dacp->state == DAC_STOP) {
#if STM32_DAC_USE_CHN1
    if (&DACD1 == dacp) {
      rccEnableDAC1(FALSE);
      /* DAC1 CR data is at bits 0:15 */
      regshift = 0;
      dataoffset = 0;
      /* Timer setup */
      rccEnableTIM6(FALSE);
      rccResetTIM6();
      trgo = STM32_DAC_CR_TSEL_TIM6;
    }
#endif
#if STM32_DAC_USE_CHN2
    if (&DACD2 == dacp) {
      rccEnableDAC1(FALSE);
      /* DAC2 CR data is at bits 16:31 */
      regshift = 16;
      dataoffset = &dacp->dac->DHR12R2 - &dacp->dac->DHR12R1;
      /* Timer setup */
      rccEnableTIM7(FALSE);
      rccResetTIM7();
      trgo = STM32_DAC_CR_TSEL_TIM7;
    }
#endif
#if STM32_DAC_USE_CHN3
    if (&DACD3 == dacp) {
      rccEnableDAC2(FALSE);
      /* DAC3 CR data is at bits 0:15 */
      regshift = 0;
      dataoffset = 0;
      /* Timer setup */
      rccEnableTIM18(FALSE);
      rccResetTIM18();
      trgo = STM32_DAC_CR_TSEL_TIM18;
    }
#endif
#if STM32_DAC_USE_CHN1 || STM32_DAC_USE_CHN2 || STM32_DAC_USE_CHN3
    dacp->clock = STM32_TIMCLK1;
    arr = (dacp->clock / dacp->config->frequency);
    osalDbgAssert((arr <= 0xFFFF),
        "invalid frequency");

    /* Timer configuration.*/
    dacp->tim->CR1 = 0; /* Initially stopped. */
    dacp->tim->PSC = 0; /* Prescaler value. */
    dacp->tim->DIER = 0;
    dacp->tim->ARR = arr;
    dacp->tim->EGR = TIM_EGR_UG; /* Update event. */
    dacp->tim->CR2 &= (uint16_t)~TIM_CR2_MMS;
    dacp->tim->CR2 |= (uint16_t)TIM_CR2_MMS_1; /* Enable TRGO updates. */
    dacp->tim->CNT = 0; /* Reset counter. */
    dacp->tim->SR = 0; /* Clear pending IRQs. */
    /* Update Event IRQ enabled. */
    /* Timer start.*/
    dacp->tim->CR1 = TIM_CR1_CEN;

    /* DAC configuration */
    dacp->dac->CR |= ( (dacp->dac->CR & ~STM32_DAC_CR_MASK) | \
      (STM32_DAC_CR_EN | STM32_DAC_CR_DMAEN | dacp->config->cr_flags) ) << regshift;
      
    /* DMA setup. */
    b = dmaStreamAllocate(dacp->dma,
          dacp->irqprio,
          (stm32_dmaisr_t)dac_lld_serve_tx_interrupt,
          (void *)dacp);
    osalDbgAssert(!b, "stream already allocated");
    switch (dacp->config->dhrm) {
      /* Sets the DAC data register */
      case DAC_DHRM_12BIT_RIGHT:
        dmaStreamSetPeripheral(dacp->dma, &dacp->dac->DHR12R1 + dataoffset);
        dacp->dmamode = (dacp->dmamode & ~STM32_DMA_CR_SIZE_MASK) |
              STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD;
        break;
      case DAC_DHRM_12BIT_LEFT:
        dmaStreamSetPeripheral(dacp->dma, &dacp->dac->DHR12L1 + dataoffset);
        dacp->dmamode = (dacp->dmamode & ~STM32_DMA_CR_SIZE_MASK) |
              STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD;
        break;
      case DAC_DHRM_8BIT_RIGHT:
        dmaStreamSetPeripheral(dacp->dma, &dacp->dac->DHR8R1 + dataoffset);
        dacp->dmamode = (dacp->dmamode & ~STM32_DMA_CR_SIZE_MASK) |
              STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE;
        break;
#if defined(STM32_HAS_DAC_CHN2) && STM32_HAS_DAC_CHN2
      case DAC_DHRM_12BIT_RIGHT_DUAL:
        dmaStreamSetPeripheral(dacp->dma, &dacp->dac->DHR12RD);
        dacp->dmamode = (dacp->dmamode & ~STM32_DMA_CR_SIZE_MASK) |
              STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD;
        break;
      case DAC_DHRM_12BIT_LEFT_DUAL:
        dmaStreamSetPeripheral(dacp->dma, &dacp->dac->DHR12LD);
        dacp->dmamode = (dacp->dmamode & ~STM32_DMA_CR_SIZE_MASK) |
              STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD;
        break;
      case DAC_DHRM_8BIT_RIGHT_DUAL:
        dmaStreamSetPeripheral(dacp->dma, &dacp->dac->DHR8RD);
        dacp->dmamode = (dacp->dmamode & ~STM32_DMA_CR_SIZE_MASK) |
             STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE;
        break;
#endif
  }
  
  dacp->dac->CR |= trgo << regshift; /* Enable timer trigger */
#endif
  }
}

/**
* @brief Deactivates the DAC peripheral.
*
* @param[in] dacp pointer to the @p DACDriver object
*
* @notapi
*/
void dac_lld_stop(DACDriver *dacp) {

  /* If in ready state then disables the DAC clock.*/
  if (dacp->state == DAC_READY) {

    /* DMA disable.*/
    dmaStreamRelease(dacp->dma);

#if STM32_DAC_USE_CHN1
    if (&DACD1 == dacp) {
      dacp->dac->CR &= ~STM32_DAC_CR_EN; /* DAC1 disable.*/
    }
#endif
#if STM32_DAC_USE_CHN2
    if (&DACD2 == dacp) {
      dacp->dac->CR &= ~STM32_DAC_CR_EN << 16; /* DAC1 disable.*/
    }
#endif
#if STM32_DAC_USE_CHN3
    if (&DACD3 == dacp) {
      dacp->dac->CR &= ~STM32_DAC_CR_EN; /* DAC2 disable.*/
      rccDisableDAC2(FALSE); /* DAC Clock disable.*/
    }
#endif
    dacp->tim->CR1 &= ~TIM_CR1_CEN; /* Disable associated timer */
    dacp->state = DAC_STOP;

    if (!(DAC1->CR & (STM32_DAC_CR_EN | STM32_DAC_CR_EN << 16))) {
      /* DAC Clock disable only if all channels are off.*/
      rccDisableDAC1(FALSE);
    }
  }
}

/**
* @brief Sends data over the DAC bus.
* @details This asynchronous function starts a transmit operation.
* @post At the end of the operation the configured callback is invoked.
*
* @param[in] dacp pointer to the @p DACDriver object
* @param[in] n number of words to send
* @param[in] txbuf the pointer to the transmit buffer
*
* @notapi
*/
void dac_lld_start_conversion(DACDriver *dacp) {
  osalDbgAssert(dacp->samples,
    "dacp->samples is NULL pointer");
  dmaStreamSetMemory0(dacp->dma, dacp->samples);
  dmaStreamSetTransactionSize(dacp->dma, dacp->depth);
  dmaStreamSetMode(dacp->dma, dacp->dmamode | STM32_DMA_CR_EN |
  STM32_DMA_CR_CIRC);
}
#endif /* HAL_USE_DAC */

/** @} */
-
- -
-
- - - - -
- -
- -
-
- - -
- -
- -
- - -
-
-
- -
-
- -
- - - -
- - - Something went wrong with that request. Please try again. -
- - - - + dacp->dac->CR |= trgo << regshift; /* Enable timer trigger */ +#endif + } +} + +/** + * @brief Deactivates the DAC peripheral. + * + * @param[in] dacp pointer to the @p DACDriver object + * + * @notapi + */ +void dac_lld_stop(DACDriver *dacp) { + + /* If in ready state then disables the DAC clock.*/ + if (dacp->state == DAC_READY) { + + /* DMA disable.*/ + dmaStreamRelease(dacp->dma); + +#if STM32_DAC_USE_CHN1 + if (&DACD1 == dacp) { + dacp->dac->CR &= ~STM32_DAC_CR_EN; /* DAC1 disable.*/ + } +#endif +#if STM32_DAC_USE_CHN2 + if (&DACD2 == dacp) { + dacp->dac->CR &= ~STM32_DAC_CR_EN << 16; /* DAC1 disable.*/ + } +#endif +#if STM32_DAC_USE_CHN3 + if (&DACD3 == dacp) { + dacp->dac->CR &= ~STM32_DAC_CR_EN; /* DAC2 disable.*/ + rccDisableDAC2(FALSE); /* DAC Clock disable.*/ + } +#endif + dacp->tim->CR1 &= ~TIM_CR1_CEN; /* Disable associated timer */ + dacp->state = DAC_STOP; + + if (!(DAC1->CR & (STM32_DAC_CR_EN | STM32_DAC_CR_EN << 16))) { + /* DAC Clock disable only if all channels are off.*/ + rccDisableDAC1(FALSE); + } + } +} + +/** + * @brief Sends data over the DAC bus. + * @details This asynchronous function starts a transmit operation. + * @post At the end of the operation the configured callback is invoked. + * + * @param[in] dacp pointer to the @p DACDriver object + * @param[in] n number of words to send + * @param[in] txbuf the pointer to the transmit buffer + * + * @notapi + */ +void dac_lld_start_conversion(DACDriver *dacp) { + osalDbgAssert(dacp->samples, + "dacp->samples is NULL pointer"); + dmaStreamSetMemory0(dacp->dma, dacp->samples); + dmaStreamSetTransactionSize(dacp->dma, dacp->depth); + dmaStreamSetMode(dacp->dma, dacp->dmamode | STM32_DMA_CR_EN | + STM32_DMA_CR_CIRC); +} +#endif /* HAL_USE_DAC */ + +/** @} */ diff --git a/os/hal/ports/STM32/LLD/DACv1/dac_lld.h b/os/hal/ports/STM32/LLD/DACv1/dac_lld.h index 6fe873faa..0df5cc8cc 100644 --- a/os/hal/ports/STM32/LLD/DACv1/dac_lld.h +++ b/os/hal/ports/STM32/LLD/DACv1/dac_lld.h @@ -1,2416 +1,397 @@ - - - - - - - - - - - ChibiOS/os/hal/ports/STM32/DACv1/dac_lld.h at dac-3.0 · mobyfab/ChibiOS · GitHub - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - -
-
- - - - - - - -
- - -
- - - - - -
- - This repository - - - -
- - - - - - - - -
-
- -
-
- - - - -
- -
-
- - - - -

- public - - - - - / - ChibiOS - - - Octocat-spinner-32 - - - - forked from mabl/ChibiOS - -

-
-
- -
-
-
- - -
-
- -
- - - -
-
- -
- - - - -
-

HTTPS clone URL

-
- - - -
-
- - - -
-

Subversion checkout URL

-
- - - -
-
- - -

You can clone with - HTTPS - or Subversion. - - - - - -

- - - - - Clone in Desktop - - - - - Download ZIP - -
-
- -
- - - - - - - - - -
+/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011,2012 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file STM32/DACv1/dac_lld.h + * @brief STM32 DAC subsystem low level driver header. + * + * @addtogroup DAC + * @{ + */ + +#ifndef _DAC_LLD_H_ +#define _DAC_LLD_H_ + +#include "stm32_tim.h" + +#if HAL_USE_DAC || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +#define STM32_DAC_CR_EN DAC_CR_EN1 +#define STM32_DAC_CR_DMAEN DAC_CR_DMAEN1 +#define STM32_DAC_CR_TEN DAC_CR_TEN1 + +#define STM32_DAC_CR_MASK (uint32_t)0x00000FFE + +#define STM32_DAC_CR_BOFF_ENABLE (uint32_t)0x00000000 +#define STM32_DAC_CR_BOFF_DISABLE DAC_CR_BOFF1 + +#define STM32_DAC_CR_TSEL_NONE (uint32_t)0x00000000 +#define STM32_DAC_CR_TSEL_TIM2 DAC_CR_TEN1 | DAC_CR_TSEL1_2 +#define STM32_DAC_CR_TSEL_TIM4 DAC_CR_TEN1 | DAC_CR_TEN0 | DAC_CR_TSEL1_2 +#define STM32_DAC_CR_TSEL_TIM5 DAC_CR_TEN1 | DAC_CR_TEN0 | DAC_CR_TSEL1_1 +#define STM32_DAC_CR_TSEL_TIM6 DAC_CR_TEN1 +#define STM32_DAC_CR_TSEL_TIM7 DAC_CR_TEN1 | DAC_CR_TSEL1_1 +#define STM32_DAC_CR_TSEL_TIM3 DAC_CR_TEN1 | DAC_CR_TSEL1_0 +#define STM32_DAC_CR_TSEL_TIM18 DAC_CR_TEN1 | DAC_CR_TSEL1_0 | DAC_CR_TSEL1_1 +#define STM32_DAC_CR_TSEL_EXT_IT9 DAC_CR_TEN1 | DAC_CR_TEN1 | DAC_CR_TSEL1_2 +#define STM32_DAC_CR_TSEL_SOFT DAC_CR_TEN1 | DAC_CR_TEN0 | DAC_CR_TSEL1_1 | DAC_CR_TSEL1_2 + +#define STM32_DAC_CR_WAVE_NONE (uint32_t)0x00000000 +#define STM32_DAC_CR_WAVE_NOISE DAC_CR_WAVE1_0 +#define STM32_DAC_CR_WAVE_TRIANGLE DAC_CR_WAVE1_1 + +#define STM32_DAC_MAMP_1 (uint32_t)0x00000000 +#define STM32_DAC_MAMP_3 DAC_CR_MAMP1_0 +#define STM32_DAC_MAMP_7 DAC_CR_MAMP1_1 +#define STM32_DAC_MAMP_15 DAC_CR_MAMP1_0 | DAC_CR_MAMP1_1 +#define STM32_DAC_MAMP_31 DAC_CR_MAMP1_2 +#define STM32_DAC_MAMP_63 DAC_CR_MAMP1_0 | DAC_CR_MAMP1_2 +#define STM32_DAC_MAMP_127 DAC_CR_MAMP1_1 | DAC_CR_MAMP1_2 +#define STM32_DAC_MAMP_255 DAC_CR_MAMP1_0 | DAC_CR_MAMP1_1 | DAC_CR_MAMP1_2 +#define STM32_DAC_MAMP_511 DAC_CR_MAMP1_3 +#define STM32_DAC_MAMP_1023 DAC_CR_MAMP1_0 | DAC_CR_MAMP1_3 +#define STM32_DAC_MAMP_2047 DAC_CR_MAMP1_1 | DAC_CR_MAMP1_3 +#define STM32_DAC_MAMP_4095 DAC_CR_MAMP1_0 | DAC_CR_MAMP1_1 | DAC_CR_MAMP1_2 + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @name Configuration options + * @{ + */ +/** + * @brief DAC CHN1 driver enable switch. + * @details If set to @p TRUE the support for DAC CHN1 is included. + * @note The default is @p TRUE. + */ +#if !defined(STM32_DAC_USE_CHN1) || defined(__DOXYGEN__) +#define STM32_DAC_USE_CHN1 FALSE +#endif + +/** + * @brief DAC CHN2 driver enable switch. + * @details If set to @p TRUE the support for DAC CHN2 is included. + * @note The default is @p TRUE. + */ +#if !defined(STM32_DAC_USE_CHN2) || defined(__DOXYGEN__) +#define STM32_DAC_USE_CHN2 FALSE +#endif + +/** + * @brief DAC CHN3 driver enable switch. + * @details If set to @p TRUE the support for DAC CHN3 is included. + * @note The default is @p TRUE. + */ +#if !defined(STM32_DAC_USE_CHN3) || defined(__DOXYGEN__) +#define STM32_DAC_USE_CHN3 FALSE +#endif + +/** + * @brief DAC CHN1 interrupt priority level setting. + */ +#if !defined(STM32_DAC_CHN1_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define STM32_DAC_CHN1_IRQ_PRIORITY 10 +#endif + +/** + * @brief DAC CHN2 interrupt priority level setting. + */ +#if !defined(STM32_DAC_CHN2_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define STM32_DAC_CHN2_IRQ_PRIORITY 10 +#endif + +/** + * @brief DAC CHN3 interrupt priority level setting. + */ +#if !defined(STM32_DAC_CHN3_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define STM32_DAC_CHN3_IRQ_PRIORITY 10 +#endif + +/** + * @brief DAC CHN1 DMA priority (0..3|lowest..highest). + */ +#if !defined(STM32_DAC_CHN1_DMA_PRIORITY) || defined(__DOXYGEN__) +#define STM32_DAC_CHN1_DMA_PRIORITY 2 +#endif + +/** + * @brief DAC CHN2 DMA priority (0..3|lowest..highest). + */ +#if !defined(STM32_DAC_CHN2_DMA_PRIORITY) || defined(__DOXYGEN__) +#define STM32_DAC_CHN2_DMA_PRIORITY 2 +#endif + +/** + * @brief DAC CHN3 DMA priority (0..3|lowest..highest). + */ +#if !defined(STM32_DAC_CHN3_DMA_PRIORITY) || defined(__DOXYGEN__) +#define STM32_DAC_CHN2_DMA_PRIORITY 2 +#endif + +/** + * @brief DAC DMA error hook. + */ +#if !defined(STM32_DAC_DMA_ERROR_HOOK) || defined(__DOXYGEN__) +#define STM32_DAC_DMA_ERROR_HOOK(dacp) osalSysHalt() +#endif + +/** + * @brief DMA stream used for DAC CHN1 TX operations. + * @note This option is only available on platforms with enhanced DMA. + */ +#if !defined(STM32_DAC_CHN1_DMA_STREAM) || defined(__DOXYGEN__) +#define STM32_DAC_CHN1_DMA_STREAM STM32_DMA_STREAM_ID(1, 3) +#endif + +/** + * @brief DMA stream used for DAC CHN2 TX operations. + * @note This option is only available on platforms with enhanced DMA. + */ +#if !defined(STM32_DAC_CHN2_DMA_STREAM) || defined(__DOXYGEN__) +#define STM32_DAC_CHN2_DMA_STREAM STM32_DMA_STREAM_ID(1, 4) +#endif + +/** + * @brief DMA stream used for DAC CHN3 TX operations. + * @note This option is only available on platforms with enhanced DMA. + */ +#if !defined(STM32_DAC_CHN3_DMA_STREAM) || defined(__DOXYGEN__) +#define STM32_DAC_CHN3_DMA_STREAM STM32_DMA_STREAM_ID(1, 5) +#endif + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +#if STM32_DAC_USE_CHN1 && !STM32_HAS_DAC_CHN1 +#error "DAC CHN1 not present in the selected device" +#endif + +#if STM32_DAC_USE_CHN2 && !STM32_HAS_DAC_CHN2 +#error "DAC CHN2 not present in the selected device" +#endif + +#if STM32_DAC_USE_CHN3 && !STM32_HAS_DAC_CHN3 +#error "DAC CHN3 not present in the selected device" +#endif + +#if !STM32_DAC_USE_CHN1 && !STM32_DAC_USE_CHN2 && !STM32_DAC_USE_CHN3 +#error "DAC driver activated but no DAC peripheral assigned" +#endif + +#if STM32_DAC_USE_CHN1 && \ + !STM32_DMA_IS_VALID_ID(STM32_DAC_CHN1_DMA_STREAM, STM32_DAC_CHN1_DMA_MSK) +#error "invalid DMA stream associated to DAC CHN1" +#endif + +#if STM32_DAC_USE_CHN2 && \ + !STM32_DMA_IS_VALID_ID(STM32_DAC_CHN2_DMA_STREAM, STM32_DAC_CHN2_DMA_MSK) +#error "invalid DMA stream associated to DAC CHN2" +#endif + +#if STM32_DAC_USE_CHN3 && \ + !STM32_DMA_IS_VALID_ID(STM32_DAC_CHN3_DMA_STREAM, STM32_DAC_CHN3_DMA_MSK) +#error "invalid DMA stream associated to DAC CHN3" +#endif + +#if !defined(STM32_DMA_REQUIRED) +#define STM32_DMA_REQUIRED +#endif + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/** + * @brief Type of a structure representing an DAC driver. + */ +typedef struct DACDriver DACDriver; + +/** + * @brief Type representing a DAC sample. + */ +typedef uint16_t dacsample_t; + +/** + * @brief DAC notification callback type. + * + * @param[in] dacp pointer to the @p DACDriver object triggering the + * callback + */ +typedef void (*daccallback_t)(DACDriver *dacp); + +typedef enum { + DAC_DHRM_12BIT_RIGHT = 0, + DAC_DHRM_12BIT_LEFT = 1, + DAC_DHRM_8BIT_RIGHT = 2, +#if defined(STM32_HAS_DAC_CHN2) && STM32_HAS_DAC_CHN2 && !defined(__DOXYGEN__) + DAC_DHRM_12BIT_RIGHT_DUAL = 3, + DAC_DHRM_12BIT_LEFT_DUAL = 4, + DAC_DHRM_8BIT_RIGHT_DUAL = 5 +#endif +} dacdhrmode_t; + +/** + * @brief DAC Conversion group structure. + */ +typedef struct { + /** + * @brief Number of DAC channels. + */ + uint16_t num_channels; + /** + * @brief Operation complete callback or @p NULL. + */ + daccallback_t end_cb; + /** + * @brief Error handling callback or @p NULL. + */ + daccallback_t error_cb; - -
- - - branch: - dac-3.0 - - - -
- - -
- - -
- Fetching contributors… - -
-

Octocat-spinner-32-eaf2f5

-

Cannot retrieve contributors at this time

-
-
- -
-
-
-
- - file - - 398 lines (341 sloc) - - 11.847 kb -
- -
-
- - - - - -
- 1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -202 -203 -204 -205 -206 -207 -208 -209 -210 -211 -212 -213 -214 -215 -216 -217 -218 -219 -220 -221 -222 -223 -224 -225 -226 -227 -228 -229 -230 -231 -232 -233 -234 -235 -236 -237 -238 -239 -240 -241 -242 -243 -244 -245 -246 -247 -248 -249 -250 -251 -252 -253 -254 -255 -256 -257 -258 -259 -260 -261 -262 -263 -264 -265 -266 -267 -268 -269 -270 -271 -272 -273 -274 -275 -276 -277 -278 -279 -280 -281 -282 -283 -284 -285 -286 -287 -288 -289 -290 -291 -292 -293 -294 -295 -296 -297 -298 -299 -300 -301 -302 -303 -304 -305 -306 -307 -308 -309 -310 -311 -312 -313 -314 -315 -316 -317 -318 -319 -320 -321 -322 -323 -324 -325 -326 -327 -328 -329 -330 -331 -332 -333 -334 -335 -336 -337 -338 -339 -340 -341 -342 -343 -344 -345 -346 -347 -348 -349 -350 -351 -352 -353 -354 -355 -356 -357 -358 -359 -360 -361 -362 -363 -364 -365 -366 -367 -368 -369 -370 -371 -372 -373 -374 -375 -376 -377 -378 -379 -380 -381 -382 -383 -384 -385 -386 -387 -388 -389 -390 -391 -392 -393 -394 -395 -396 -397 - -
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
2011,2012 Giovanni Di Sirio.

This file is part of ChibiOS/RT.

ChibiOS/RT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.

ChibiOS/RT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

/**
* @file STM32/DACv1/dac_lld.h
* @brief STM32 DAC subsystem low level driver header.
*
* @addtogroup DAC
* @{
*/

#ifndef _DAC_LLD_H_
#define _DAC_LLD_H_

#include "stm32_tim.h"

#if HAL_USE_DAC || defined(__DOXYGEN__)

/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/

#define STM32_DAC_CR_EN DAC_CR_EN1
#define STM32_DAC_CR_DMAEN DAC_CR_DMAEN1
#define STM32_DAC_CR_TEN DAC_CR_TEN1

#define STM32_DAC_CR_MASK (uint32_t)0x00000FFE

#define STM32_DAC_CR_BOFF_ENABLE (uint32_t)0x00000000
#define STM32_DAC_CR_BOFF_DISABLE DAC_CR_BOFF1

#define STM32_DAC_CR_TSEL_NONE (uint32_t)0x00000000
#define STM32_DAC_CR_TSEL_TIM2 DAC_CR_TEN1 | DAC_CR_TSEL1_2
#define STM32_DAC_CR_TSEL_TIM4 DAC_CR_TEN1 | DAC_CR_TEN0 | DAC_CR_TSEL1_2
#define STM32_DAC_CR_TSEL_TIM5 DAC_CR_TEN1 | DAC_CR_TEN0 | DAC_CR_TSEL1_1
#define STM32_DAC_CR_TSEL_TIM6 DAC_CR_TEN1
#define STM32_DAC_CR_TSEL_TIM7 DAC_CR_TEN1 | DAC_CR_TSEL1_1
#define STM32_DAC_CR_TSEL_TIM3 DAC_CR_TEN1 | DAC_CR_TSEL1_0
#define STM32_DAC_CR_TSEL_TIM18 DAC_CR_TEN1 | DAC_CR_TSEL1_0 | DAC_CR_TSEL1_1
#define STM32_DAC_CR_TSEL_EXT_IT9 DAC_CR_TEN1 | DAC_CR_TEN1 | DAC_CR_TSEL1_2
#define STM32_DAC_CR_TSEL_SOFT DAC_CR_TEN1 | DAC_CR_TEN0 | DAC_CR_TSEL1_1 | DAC_CR_TSEL1_2

#define STM32_DAC_CR_WAVE_NONE (uint32_t)0x00000000
#define STM32_DAC_CR_WAVE_NOISE DAC_CR_WAVE1_0
#define STM32_DAC_CR_WAVE_TRIANGLE DAC_CR_WAVE1_1

#define STM32_DAC_MAMP_1 (uint32_t)0x00000000
#define STM32_DAC_MAMP_3 DAC_CR_MAMP1_0
#define STM32_DAC_MAMP_7 DAC_CR_MAMP1_1
#define STM32_DAC_MAMP_15 DAC_CR_MAMP1_0 | DAC_CR_MAMP1_1
#define STM32_DAC_MAMP_31 DAC_CR_MAMP1_2
#define STM32_DAC_MAMP_63 DAC_CR_MAMP1_0 | DAC_CR_MAMP1_2
#define STM32_DAC_MAMP_127 DAC_CR_MAMP1_1 | DAC_CR_MAMP1_2
#define STM32_DAC_MAMP_255 DAC_CR_MAMP1_0 | DAC_CR_MAMP1_1 | DAC_CR_MAMP1_2
#define STM32_DAC_MAMP_511 DAC_CR_MAMP1_3
#define STM32_DAC_MAMP_1023 DAC_CR_MAMP1_0 | DAC_CR_MAMP1_3
#define STM32_DAC_MAMP_2047 DAC_CR_MAMP1_1 | DAC_CR_MAMP1_3
#define STM32_DAC_MAMP_4095 DAC_CR_MAMP1_0 | DAC_CR_MAMP1_1 | DAC_CR_MAMP1_2

/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/

/**
* @name Configuration options
* @{
*/
/**
* @brief DAC CHN1 driver enable switch.
* @details If set to @p TRUE the support for DAC CHN1 is included.
* @note The default is @p TRUE.
*/
#if !defined(STM32_DAC_USE_CHN1) || defined(__DOXYGEN__)
#define STM32_DAC_USE_CHN1 FALSE
#endif

/**
* @brief DAC CHN2 driver enable switch.
* @details If set to @p TRUE the support for DAC CHN2 is included.
* @note The default is @p TRUE.
*/
#if !defined(STM32_DAC_USE_CHN2) || defined(__DOXYGEN__)
#define STM32_DAC_USE_CHN2 FALSE
#endif

/**
* @brief DAC CHN3 driver enable switch.
* @details If set to @p TRUE the support for DAC CHN3 is included.
* @note The default is @p TRUE.
*/
#if !defined(STM32_DAC_USE_CHN3) || defined(__DOXYGEN__)
#define STM32_DAC_USE_CHN3 FALSE
#endif

/**
* @brief DAC CHN1 interrupt priority level setting.
*/
#if !defined(STM32_DAC_CHN1_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_DAC_CHN1_IRQ_PRIORITY 10
#endif

/**
* @brief DAC CHN2 interrupt priority level setting.
*/
#if !defined(STM32_DAC_CHN2_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_DAC_CHN2_IRQ_PRIORITY 10
#endif

/**
* @brief DAC CHN3 interrupt priority level setting.
*/
#if !defined(STM32_DAC_CHN3_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_DAC_CHN3_IRQ_PRIORITY 10
#endif

/**
* @brief DAC CHN1 DMA priority (0..3|lowest..highest).
*/
#if !defined(STM32_DAC_CHN1_DMA_PRIORITY) || defined(__DOXYGEN__)
#define STM32_DAC_CHN1_DMA_PRIORITY 2
#endif

/**
* @brief DAC CHN2 DMA priority (0..3|lowest..highest).
*/
#if !defined(STM32_DAC_CHN2_DMA_PRIORITY) || defined(__DOXYGEN__)
#define STM32_DAC_CHN2_DMA_PRIORITY 2
#endif

/**
* @brief DAC CHN3 DMA priority (0..3|lowest..highest).
*/
#if !defined(STM32_DAC_CHN3_DMA_PRIORITY) || defined(__DOXYGEN__)
#define STM32_DAC_CHN2_DMA_PRIORITY 2
#endif

/**
* @brief DAC DMA error hook.
*/
#if !defined(STM32_DAC_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
#define STM32_DAC_DMA_ERROR_HOOK(dacp) osalSysHalt()
#endif

/**
* @brief DMA stream used for DAC CHN1 TX operations.
* @note This option is only available on platforms with enhanced DMA.
*/
#if !defined(STM32_DAC_CHN1_DMA_STREAM) || defined(__DOXYGEN__)
#define STM32_DAC_CHN1_DMA_STREAM STM32_DMA_STREAM_ID(1, 3)
#endif

/**
* @brief DMA stream used for DAC CHN2 TX operations.
* @note This option is only available on platforms with enhanced DMA.
*/
#if !defined(STM32_DAC_CHN2_DMA_STREAM) || defined(__DOXYGEN__)
#define STM32_DAC_CHN2_DMA_STREAM STM32_DMA_STREAM_ID(1, 4)
#endif

/**
* @brief DMA stream used for DAC CHN3 TX operations.
* @note This option is only available on platforms with enhanced DMA.
*/
#if !defined(STM32_DAC_CHN3_DMA_STREAM) || defined(__DOXYGEN__)
#define STM32_DAC_CHN3_DMA_STREAM STM32_DMA_STREAM_ID(1, 5)
#endif

/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/

#if STM32_DAC_USE_CHN1 && !STM32_HAS_DAC_CHN1
#error "DAC CHN1 not present in the selected device"
#endif

#if STM32_DAC_USE_CHN2 && !STM32_HAS_DAC_CHN2
#error "DAC CHN2 not present in the selected device"
#endif

#if STM32_DAC_USE_CHN3 && !STM32_HAS_DAC_CHN3
#error "DAC CHN3 not present in the selected device"
#endif

#if !STM32_DAC_USE_CHN1 && !STM32_DAC_USE_CHN2 && !STM32_DAC_USE_CHN3
#error "DAC driver activated but no DAC peripheral assigned"
#endif

#if STM32_DAC_USE_CHN1 && \
!STM32_DMA_IS_VALID_ID(STM32_DAC_CHN1_DMA_STREAM, STM32_DAC_CHN1_DMA_MSK)
#error "invalid DMA stream associated to DAC CHN1"
#endif

#if STM32_DAC_USE_CHN2 && \
!STM32_DMA_IS_VALID_ID(STM32_DAC_CHN2_DMA_STREAM, STM32_DAC_CHN2_DMA_MSK)
#error "invalid DMA stream associated to DAC CHN2"
#endif

#if STM32_DAC_USE_CHN3 && \
!STM32_DMA_IS_VALID_ID(STM32_DAC_CHN3_DMA_STREAM, STM32_DAC_CHN3_DMA_MSK)
#error "invalid DMA stream associated to DAC CHN3"
#endif

#if !defined(STM32_DMA_REQUIRED)
#define STM32_DMA_REQUIRED
#endif

/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/

/**
* @brief Type of a structure representing an DAC driver.
*/
typedef struct DACDriver DACDriver;

/**
* @brief Type representing a DAC sample.
*/
typedef uint16_t dacsample_t;

/**
* @brief DAC notification callback type.
*
* @param[in] dacp pointer to the @p DACDriver object triggering the
* callback
*/
typedef void (*daccallback_t)(DACDriver *dacp);

typedef enum {
  DAC_DHRM_12BIT_RIGHT = 0,
  DAC_DHRM_12BIT_LEFT = 1,
  DAC_DHRM_8BIT_RIGHT = 2,
#if defined(STM32_HAS_DAC_CHN2) && STM32_HAS_DAC_CHN2 && !defined(__DOXYGEN__)
  DAC_DHRM_12BIT_RIGHT_DUAL = 3,
  DAC_DHRM_12BIT_LEFT_DUAL = 4,
  DAC_DHRM_8BIT_RIGHT_DUAL = 5
#endif
} dacdhrmode_t;

/**
* @brief DAC Conversion group structure.
*/
typedef struct {
  /**
* @brief Number of DAC channels.
*/
  uint16_t num_channels;
  /**
* @brief Operation complete callback or @p NULL.
*/
  daccallback_t end_cb;
  /**
* @brief Error handling callback or @p NULL.
*/
  daccallback_t error_cb;
  
} DACConversionGroup;

/**
* @brief Driver configuration structure.
*/
typedef struct {
  /**
* @brief Timer frequency in Hz.
*/
  uint32_t frequency;
  /* End of the mandatory fields.*/
  /**
* @brief DAC data holding register mode.
*/
  dacdhrmode_t dhrm;
  /**
* @brief DAC initialization data.
*/
  uint32_t cr_flags;
} DACConfig;

/**
* @brief Structure representing a DAC driver.
*/
struct DACDriver {
  /**
* @brief Driver state.
*/
  dacstate_t state;
  /**
* @brief Conversion group.
*/
  const DACConversionGroup *grpp;
  /**
* @brief Samples buffer pointer.
*/
  const dacsample_t *samples;
  /**
* @brief Samples buffer size.
*/
  uint16_t depth;
  /**
* @brief Current configuration data.
*/
  const DACConfig *config;
#if DAC_USE_WAIT || defined(__DOXYGEN__)
  /**
* @brief Waiting thread.
*/
  thread_reference_t thread;
#endif /* DAC_USE_WAIT */
#if DAC_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__)
  /**
* @brief Mutex protecting the bus.
*/
  mutex_t mutex;
#endif /* DAC_USE_MUTUAL_EXCLUSION */
#if defined(DAC_DRIVER_EXT_FIELDS)
  DAC_DRIVER_EXT_FIELDS
#endif
  /* End of the mandatory fields.*/
  /**
* @brief Pointer to the DAC registers block.
*/
  DAC_TypeDef *dac;
  /**
* @brief Pointer to the TIMx registers block.
*/
  stm32_tim_t *tim;
  /**
* @brief The Timer IRQ priority.
*/
  uint32_t irqprio;
  /**
* @brief Transmit DMA stream.
*/
  const stm32_dma_stream_t *dma;
  /**
* @brief TX DMA mode bit mask.
*/
  uint32_t dmamode;
  /**
* @brief Timer base clock.
*/
  uint32_t clock;
};

/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/

/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/

#if STM32_DAC_USE_CHN1 && !defined(__DOXYGEN__)
extern DACDriver DACD1;
#endif

#if STM32_DAC_USE_CHN2 && !defined(__DOXYGEN__)
extern DACDriver DACD2;
#endif

#if STM32_DAC_USE_CHN3 && !defined(__DOXYGEN__)
extern DACDriver DACD3;
#endif

#ifdef __cplusplus
extern "C" {
#endif
  void dac_lld_init(void);
  void dac_lld_start(DACDriver *dacp);
  void dac_lld_stop(DACDriver *dacp);
  void dac_lld_start_conversion(DACDriver *dacp);
  void dac_lld_stop_conversion(DACDriver *dacp);
#ifdef __cplusplus
}
#endif

#endif /* HAL_USE_DAC */

#endif /* _DAC_LLD_H_ */

/** @} */
-
- -
-
- - - - -
- -
- -
-
- - -
- -
- -
- - -
-
-
- -
-
- -
- - - -
- - - Something went wrong with that request. Please try again. -
- - - - +} DACConversionGroup; + +/** + * @brief Driver configuration structure. + */ +typedef struct { + /** + * @brief Timer frequency in Hz. + */ + uint32_t frequency; + /* End of the mandatory fields.*/ + /** + * @brief DAC data holding register mode. + */ + dacdhrmode_t dhrm; + /** + * @brief DAC initialization data. + */ + uint32_t cr_flags; +} DACConfig; + +/** + * @brief Structure representing a DAC driver. + */ +struct DACDriver { + /** + * @brief Driver state. + */ + dacstate_t state; + /** + * @brief Conversion group. + */ + const DACConversionGroup *grpp; + /** + * @brief Samples buffer pointer. + */ + const dacsample_t *samples; + /** + * @brief Samples buffer size. + */ + uint16_t depth; + /** + * @brief Current configuration data. + */ + const DACConfig *config; +#if DAC_USE_WAIT || defined(__DOXYGEN__) + /** + * @brief Waiting thread. + */ + thread_reference_t thread; +#endif /* DAC_USE_WAIT */ +#if DAC_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__) + /** + * @brief Mutex protecting the bus. + */ + mutex_t mutex; +#endif /* DAC_USE_MUTUAL_EXCLUSION */ +#if defined(DAC_DRIVER_EXT_FIELDS) + DAC_DRIVER_EXT_FIELDS +#endif + /* End of the mandatory fields.*/ + /** + * @brief Pointer to the DAC registers block. + */ + DAC_TypeDef *dac; + /** + * @brief Pointer to the TIMx registers block. + */ + stm32_tim_t *tim; + /** + * @brief The Timer IRQ priority. + */ + uint32_t irqprio; + /** + * @brief Transmit DMA stream. + */ + const stm32_dma_stream_t *dma; + /** + * @brief TX DMA mode bit mask. + */ + uint32_t dmamode; + /** + * @brief Timer base clock. + */ + uint32_t clock; +}; + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#if STM32_DAC_USE_CHN1 && !defined(__DOXYGEN__) +extern DACDriver DACD1; +#endif + +#if STM32_DAC_USE_CHN2 && !defined(__DOXYGEN__) +extern DACDriver DACD2; +#endif + +#if STM32_DAC_USE_CHN3 && !defined(__DOXYGEN__) +extern DACDriver DACD3; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + void dac_lld_init(void); + void dac_lld_start(DACDriver *dacp); + void dac_lld_stop(DACDriver *dacp); + void dac_lld_start_conversion(DACDriver *dacp); + void dac_lld_stop_conversion(DACDriver *dacp); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_USE_DAC */ + +#endif /* _DAC_LLD_H_ */ + +/** @} */ diff --git a/os/hal/ports/STM32/STM32F4xx/platform.mk b/os/hal/ports/STM32/STM32F4xx/platform.mk index 0f793f18f..c9b74b45c 100644 --- a/os/hal/ports/STM32/STM32F4xx/platform.mk +++ b/os/hal/ports/STM32/STM32F4xx/platform.mk @@ -8,6 +8,7 @@ PLATFORMSRC = ${CHIBIOS}/os/hal/ports/common/ARMCMx/nvic.c \ ${CHIBIOS}/os/hal/ports/STM32/LLD/ext_lld.c \ ${CHIBIOS}/os/hal/ports/STM32/LLD/mac_lld.c \ ${CHIBIOS}/os/hal/ports/STM32/LLD/sdc_lld.c \ + ${CHIBIOS}/os/hal/ports/STM32/LLD/DACv1/dac_lld.c \ ${CHIBIOS}/os/hal/ports/STM32/LLD/GPIOv2/pal_lld.c \ ${CHIBIOS}/os/hal/ports/STM32/LLD/I2Cv1/i2c_lld.c \ ${CHIBIOS}/os/hal/ports/STM32/LLD/OTGv1/usb_lld.c \ @@ -25,6 +26,7 @@ PLATFORMSRC = ${CHIBIOS}/os/hal/ports/common/ARMCMx/nvic.c \ PLATFORMINC = ${CHIBIOS}/os/hal/ports/common/ARMCMx \ ${CHIBIOS}/os/hal/ports/STM32/STM32F4xx \ ${CHIBIOS}/os/hal/ports/STM32/LLD \ + ${CHIBIOS}/os/hal/ports/STM32/LLD/DACv1 \ ${CHIBIOS}/os/hal/ports/STM32/LLD/GPIOv2 \ ${CHIBIOS}/os/hal/ports/STM32/LLD/I2Cv1 \ ${CHIBIOS}/os/hal/ports/STM32/LLD/OTGv1 \ diff --git a/os/hal/src/dac.c b/os/hal/src/dac.c index ae1667cbe..92297e520 100644 --- a/os/hal/src/dac.c +++ b/os/hal/src/dac.c @@ -1,2343 +1,324 @@ - - - - - - - - - - - ChibiOS/os/hal/src/dac.c at dac-3.0 · mobyfab/ChibiOS · GitHub - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - - - - -
-
- - - - - - - -
- - -
- - - - - -
- - This repository - - - -
- - - - - - - - -
-
- -
-
- - - - -
- -
-
- - - - -

- public - - - - - / - ChibiOS - - - Octocat-spinner-32 - - - - forked from mabl/ChibiOS - -

-
-
- -
-
-
- - -
-
- -
- - - -
-
- -
- - - - -
-

HTTPS clone URL

-
- - - -
-
- - - -
-

Subversion checkout URL

-
- - - -
-
- - -

You can clone with - HTTPS - or Subversion. - - - - - -

- - - - - Clone in Desktop - - - - - Download ZIP - -
-
- -
- - - - - - - - - -
- - -
- - - branch: - dac-3.0 - - - -
- - -
- - -
- Fetching contributors… - -
-

Octocat-spinner-32-eaf2f5

-

Cannot retrieve contributors at this time

-
-
- -
-
-
-
- - file - - 325 lines (281 sloc) - - 10.304 kb -
- -
-
- - - - - -
- 1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -202 -203 -204 -205 -206 -207 -208 -209 -210 -211 -212 -213 -214 -215 -216 -217 -218 -219 -220 -221 -222 -223 -224 -225 -226 -227 -228 -229 -230 -231 -232 -233 -234 -235 -236 -237 -238 -239 -240 -241 -242 -243 -244 -245 -246 -247 -248 -249 -250 -251 -252 -253 -254 -255 -256 -257 -258 -259 -260 -261 -262 -263 -264 -265 -266 -267 -268 -269 -270 -271 -272 -273 -274 -275 -276 -277 -278 -279 -280 -281 -282 -283 -284 -285 -286 -287 -288 -289 -290 -291 -292 -293 -294 -295 -296 -297 -298 -299 -300 -301 -302 -303 -304 -305 -306 -307 -308 -309 -310 -311 -312 -313 -314 -315 -316 -317 -318 -319 -320 -321 -322 -323 -324 - -
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
2011,2012 Giovanni Di Sirio.

This file is part of ChibiOS/RT.

ChibiOS/RT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.

ChibiOS/RT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

/**
* @file dac.c
* @brief DAC Driver code.
*
* @addtogroup DAC
* @{
*/

#include "hal.h"

#if HAL_USE_DAC || defined(__DOXYGEN__)

/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/

/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/

/*===========================================================================*/
/* Driver local variables. */
/*===========================================================================*/

/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/

/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/

/**
* @brief DAC Driver initialization.
* @note This function is implicitly invoked by @p halInit(), there is
* no need to explicitly initialize the driver.
*
* @init
*/
void dacInit(void) {

  dac_lld_init();
}

/**
* @brief Initializes the standard part of a @p DACDriver structure.
*
* @param[out] dacp pointer to the @p DACDriver object
*
* @init
*/
void dacObjectInit(DACDriver *dacp) {

  dacp->state = DAC_STOP;
  dacp->config = NULL;
#if DAC_USE_WAIT
  dacp->thread = NULL;
#endif /* DAC_USE_WAIT */
#if DAC_USE_MUTUAL_EXCLUSION
  osalMutexObjectInit(&dacp->mutex);
#endif /* DAC_USE_MUTUAL_EXCLUSION */
#if defined(DAC_DRIVER_EXT_INIT_HOOK)
  DAC_DRIVER_EXT_INIT_HOOK(dacp);
#endif
}

/**
* @brief Configures and activates the DAC peripheral.
*
* @param[in] dacp pointer to the @p DACDriver object
* @param[in] config pointer to the @p DACConfig object
*
* @api
*/
void dacStart(DACDriver *dacp, const DACConfig *config) {

  osalDbgCheck((dacp != NULL) && (config != NULL));

  osalSysLock();
  osalDbgAssert((dacp->state == DAC_STOP) || (dacp->state == DAC_READY),
              "invalid state");
  dacp->config = config;
  dac_lld_start(dacp);
  dacp->state = DAC_READY;
  osalSysUnlock();
}

/**
* @brief Deactivates the DAC peripheral.
* @note Deactivating the peripheral also enforces a release of the slave
* select line.
*
* @param[in] dacp pointer to the @p DACDriver object
*
* @api
*/
void dacStop(DACDriver *dacp) {

  osalDbgCheck(dacp != NULL);

  osalSysLock();
  osalDbgAssert((dacp->state == DAC_STOP) || (dacp->state == DAC_READY),
              "invalid state");
  dac_lld_stop(dacp);
  dacp->state = DAC_STOP;
  osalSysUnlock();
}

/**
* @brief Starts a DAC conversion.
* @details Starts an asynchronous conversion operation.
* @note The buffer is organized as a matrix of M*N elements where M is the
* channels number configured into the conversion group and N is the
* 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] samples pointer to the samples buffer
* @param[in] depth buffer depth (matrix rows number). The buffer depth
* must be one or an even number.
*
* @api
*/
void dacStartConversion(DACDriver *dacp,
                        const DACConversionGroup *grpp,
                        const dacsample_t *samples,
                        size_t depth) {

  osalSysLock();
  dacStartConversionI(dacp, grpp, samples, depth);
  osalSysUnlock();
}

/**
* @brief Starts a DAC conversion.
* @details Starts an asynchronous conversion operation.
* @post The callbacks associated to the conversion group will be invoked
* on buffer fill and error events.
* @note The buffer is organized as a matrix of M*N elements where M is the
* channels number configured into the conversion group and N is the
* 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] samples pointer to the samples buffer
* @param[in] depth buffer depth (matrix rows number). The buffer depth
* must be one or an even number.
*
* @iclass
*/
void dacStartConversionI(DACDriver *dacp,
                         const DACConversionGroup *grpp,
                         const dacsample_t *samples,
                         size_t depth) {

  osalDbgCheckClassI();
  osalDbgCheck((dacp != NULL) && (grpp != NULL) && (samples != NULL) &&
             ((depth == 1) || ((depth & 1) == 0)));
  osalDbgAssert((dacp->state == DAC_READY) ||
              (dacp->state == DAC_COMPLETE) ||
              (dacp->state == DAC_ERROR),
              "not ready");

  dacp->samples = samples;
  dacp->depth = depth;
  dacp->grpp = grpp;
  dacp->state = DAC_ACTIVE;
  dac_lld_start_conversion(dacp);
}

/**
* @brief Stops an ongoing conversion.
* @details This function stops the currently ongoing conversion and returns
* 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
*
* @api
*/
void dacStopConversion(DACDriver *dacp) {

  osalDbgCheck(dacp != NULL);

  osalSysLock();
  osalDbgAssert((dacp->state == DAC_READY) ||
              (dacp->state == DAC_ACTIVE),
              "invalid state");
  if (dacp->state != DAC_READY) {
    dac_lld_stop_conversion(dacp);
    dacp->grpp = NULL;
    dacp->state = DAC_READY;
    _dac_reset_s(dacp);
  }
  osalSysUnlock();
}

/**
* @brief Stops an ongoing conversion.
* @details This function stops the currently ongoing conversion and returns
* 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
*
* @iclass
*/
void dacStopConversionI(DACDriver *dacp) {

  osalDbgCheckClassI();
  osalDbgCheck(dacp != NULL);
  osalDbgAssert((dacp->state == DAC_READY) ||
              (dacp->state == DAC_ACTIVE) ||
              (dacp->state == DAC_COMPLETE),
              "invalid state");

  if (dacp->state != DAC_READY) {
    dac_lld_stop_conversion(dacp);
    dacp->grpp = NULL;
    dacp->state = DAC_READY;
    _dac_reset_i(dacp);
  }
}

#if DAC_USE_WAIT || defined(__DOXYGEN__)
/**
* @brief Performs a DAC conversion.
* @details Performs a synchronous conversion operation.
* @note The buffer is organized as a matrix of M*N elements where M is the
* channels number configured into the conversion group and N is the
* 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[out] samples pointer to the samples buffer
* @param[in] depth buffer depth (matrix rows number). The buffer depth
* must be one or an even number.
* @return The operation result.
* @retval RDY_OK Conversion finished.
* @retval RDY_RESET The conversion has been stopped using
* @p acdStopConversion() or @p acdStopConversionI(),
* the result buffer may contain incorrect data.
* @retval RDY_TIMEOUT The conversion has been stopped because an hardware
* error.
*
* @api
*/
msg_t dacConvert(DACDriver *dacp,
                 const DACConversionGroup *grpp,
                 const dacsample_t *samples,
                 size_t depth) {
  msg_t msg;

  osalSysLock();
  osalDbgAssert(dacp->thread == NULL, "already waiting");
  dacStartConversionI(dacp, grpp, samples, depth);
  msg = osalThreadSuspendS(&dacp->thread);
  osalSysUnlock();
  return msg;
}
#endif /* DAC_USE_WAIT */

#if DAC_USE_MUTUAL_EXCLUSION || 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 */

#endif /* HAL_USE_DAC */

/** @} */
-
- -
-
- - - - -
- -
- -
-
- - -
- -
- -
- - -
-
-
- -
-
- -
- - - -
- - - Something went wrong with that request. Please try again. -
- - - - +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011,2012 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file dac.c + * @brief DAC Driver code. + * + * @addtogroup DAC + * @{ + */ + +#include "hal.h" + +#if HAL_USE_DAC || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief DAC Driver initialization. + * @note This function is implicitly invoked by @p halInit(), there is + * no need to explicitly initialize the driver. + * + * @init + */ +void dacInit(void) { + + dac_lld_init(); +} + +/** + * @brief Initializes the standard part of a @p DACDriver structure. + * + * @param[out] dacp pointer to the @p DACDriver object + * + * @init + */ +void dacObjectInit(DACDriver *dacp) { + + dacp->state = DAC_STOP; + dacp->config = NULL; +#if DAC_USE_WAIT + dacp->thread = NULL; +#endif /* DAC_USE_WAIT */ +#if DAC_USE_MUTUAL_EXCLUSION + osalMutexObjectInit(&dacp->mutex); +#endif /* DAC_USE_MUTUAL_EXCLUSION */ +#if defined(DAC_DRIVER_EXT_INIT_HOOK) + DAC_DRIVER_EXT_INIT_HOOK(dacp); +#endif +} + +/** + * @brief Configures and activates the DAC peripheral. + * + * @param[in] dacp pointer to the @p DACDriver object + * @param[in] config pointer to the @p DACConfig object + * + * @api + */ +void dacStart(DACDriver *dacp, const DACConfig *config) { + + osalDbgCheck((dacp != NULL) && (config != NULL)); + + osalSysLock(); + osalDbgAssert((dacp->state == DAC_STOP) || (dacp->state == DAC_READY), + "invalid state"); + dacp->config = config; + dac_lld_start(dacp); + dacp->state = DAC_READY; + osalSysUnlock(); +} + +/** + * @brief Deactivates the DAC peripheral. + * @note Deactivating the peripheral also enforces a release of the slave + * select line. + * + * @param[in] dacp pointer to the @p DACDriver object + * + * @api + */ +void dacStop(DACDriver *dacp) { + + osalDbgCheck(dacp != NULL); + + osalSysLock(); + osalDbgAssert((dacp->state == DAC_STOP) || (dacp->state == DAC_READY), + "invalid state"); + dac_lld_stop(dacp); + dacp->state = DAC_STOP; + osalSysUnlock(); +} + +/** + * @brief Starts a DAC conversion. + * @details Starts an asynchronous conversion operation. + * @note The buffer is organized as a matrix of M*N elements where M is the + * channels number configured into the conversion group and N is the + * 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] samples pointer to the samples buffer + * @param[in] depth buffer depth (matrix rows number). The buffer depth + * must be one or an even number. + * + * @api + */ +void dacStartConversion(DACDriver *dacp, + const DACConversionGroup *grpp, + const dacsample_t *samples, + size_t depth) { + + osalSysLock(); + dacStartConversionI(dacp, grpp, samples, depth); + osalSysUnlock(); +} + +/** + * @brief Starts a DAC conversion. + * @details Starts an asynchronous conversion operation. + * @post The callbacks associated to the conversion group will be invoked + * on buffer fill and error events. + * @note The buffer is organized as a matrix of M*N elements where M is the + * channels number configured into the conversion group and N is the + * 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] samples pointer to the samples buffer + * @param[in] depth buffer depth (matrix rows number). The buffer depth + * must be one or an even number. + * + * @iclass + */ +void dacStartConversionI(DACDriver *dacp, + const DACConversionGroup *grpp, + const dacsample_t *samples, + size_t depth) { + + osalDbgCheckClassI(); + osalDbgCheck((dacp != NULL) && (grpp != NULL) && (samples != NULL) && + ((depth == 1) || ((depth & 1) == 0))); + osalDbgAssert((dacp->state == DAC_READY) || + (dacp->state == DAC_COMPLETE) || + (dacp->state == DAC_ERROR), + "not ready"); + + dacp->samples = samples; + dacp->depth = depth; + dacp->grpp = grpp; + dacp->state = DAC_ACTIVE; + dac_lld_start_conversion(dacp); +} + +/** + * @brief Stops an ongoing conversion. + * @details This function stops the currently ongoing conversion and returns + * 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 + * + * @api + */ +void dacStopConversion(DACDriver *dacp) { + + osalDbgCheck(dacp != NULL); + + osalSysLock(); + osalDbgAssert((dacp->state == DAC_READY) || + (dacp->state == DAC_ACTIVE), + "invalid state"); + if (dacp->state != DAC_READY) { + dac_lld_stop_conversion(dacp); + dacp->grpp = NULL; + dacp->state = DAC_READY; + _dac_reset_s(dacp); + } + osalSysUnlock(); +} + +/** + * @brief Stops an ongoing conversion. + * @details This function stops the currently ongoing conversion and returns + * 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 + * + * @iclass + */ +void dacStopConversionI(DACDriver *dacp) { + + osalDbgCheckClassI(); + osalDbgCheck(dacp != NULL); + osalDbgAssert((dacp->state == DAC_READY) || + (dacp->state == DAC_ACTIVE) || + (dacp->state == DAC_COMPLETE), + "invalid state"); + + if (dacp->state != DAC_READY) { + dac_lld_stop_conversion(dacp); + dacp->grpp = NULL; + dacp->state = DAC_READY; + _dac_reset_i(dacp); + } +} + +#if DAC_USE_WAIT || defined(__DOXYGEN__) +/** + * @brief Performs a DAC conversion. + * @details Performs a synchronous conversion operation. + * @note The buffer is organized as a matrix of M*N elements where M is the + * channels number configured into the conversion group and N is the + * 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[out] samples pointer to the samples buffer + * @param[in] depth buffer depth (matrix rows number). The buffer depth + * must be one or an even number. + * @return The operation result. + * @retval RDY_OK Conversion finished. + * @retval RDY_RESET The conversion has been stopped using + * @p acdStopConversion() or @p acdStopConversionI(), + * the result buffer may contain incorrect data. + * @retval RDY_TIMEOUT The conversion has been stopped because an hardware + * error. + * + * @api + */ +msg_t dacConvert(DACDriver *dacp, + const DACConversionGroup *grpp, + const dacsample_t *samples, + size_t depth) { + msg_t msg; + + osalSysLock(); + osalDbgAssert(dacp->thread == NULL, "already waiting"); + dacStartConversionI(dacp, grpp, samples, depth); + msg = osalThreadSuspendS(&dacp->thread); + osalSysUnlock(); + return msg; +} +#endif /* DAC_USE_WAIT */ + +#if DAC_USE_MUTUAL_EXCLUSION || 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 */ + +#endif /* HAL_USE_DAC */ + +/** @} */ -- cgit v1.2.3