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/src/dac.c | 2667 +++++++----------------------------------------------- 1 file changed, 324 insertions(+), 2343 deletions(-) (limited to 'os/hal/src') 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