From 590c1329a400a67c937b30dd55c58210549348b5 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 5 Mar 2014 10:24:50 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/kernel_3_dev@6753 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/hal.mk | 1 + os/hal/include/dac.h | 2321 ++++++++++++++++++++++++++++++ os/hal/ports/STM32/LLD/DACv1/dac_lld.c | 2370 +++++++++++++++++++++++++++++++ os/hal/ports/STM32/LLD/DACv1/dac_lld.h | 2416 ++++++++++++++++++++++++++++++++ os/hal/src/dac.c | 2343 +++++++++++++++++++++++++++++++ 5 files changed, 9451 insertions(+) create mode 100644 os/hal/include/dac.h create mode 100644 os/hal/ports/STM32/LLD/DACv1/dac_lld.c create mode 100644 os/hal/ports/STM32/LLD/DACv1/dac_lld.h create mode 100644 os/hal/src/dac.c (limited to 'os') diff --git a/os/hal/hal.mk b/os/hal/hal.mk index 892f1ed5d..ab3a781aa 100644 --- a/os/hal/hal.mk +++ b/os/hal/hal.mk @@ -5,6 +5,7 @@ HALSRC = ${CHIBIOS}/os/hal/src/hal.c \ ${CHIBIOS}/os/hal/src/hal_mmcsd.c \ ${CHIBIOS}/os/hal/src/adc.c \ ${CHIBIOS}/os/hal/src/can.c \ + ${CHIBIOS}/os/hal/src/dac.c \ ${CHIBIOS}/os/hal/src/ext.c \ ${CHIBIOS}/os/hal/src/gpt.c \ ${CHIBIOS}/os/hal/src/i2c.c \ diff --git a/os/hal/include/dac.h b/os/hal/include/dac.h new file mode 100644 index 000000000..69c82c864 --- /dev/null +++ b/os/hal/include/dac.h @@ -0,0 +1,2321 @@ + + + + + + + + + + + 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. +
+ + + + diff --git a/os/hal/ports/STM32/LLD/DACv1/dac_lld.c b/os/hal/ports/STM32/LLD/DACv1/dac_lld.c new file mode 100644 index 000000000..bd65728db --- /dev/null +++ b/os/hal/ports/STM32/LLD/DACv1/dac_lld.c @@ -0,0 +1,2370 @@ + + + + + + + + + + + ChibiOS/os/hal/ports/STM32/DACv1/dac_lld.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 + + 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. +
+ + + + diff --git a/os/hal/ports/STM32/LLD/DACv1/dac_lld.h b/os/hal/ports/STM32/LLD/DACv1/dac_lld.h new file mode 100644 index 000000000..6fe873faa --- /dev/null +++ b/os/hal/ports/STM32/LLD/DACv1/dac_lld.h @@ -0,0 +1,2416 @@ + + + + + + + + + + + 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 + +
+
+ +
+ + + + + + + + + +
+ + +
+ + + 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. +
+ + + + diff --git a/os/hal/src/dac.c b/os/hal/src/dac.c new file mode 100644 index 000000000..ae1667cbe --- /dev/null +++ b/os/hal/src/dac.c @@ -0,0 +1,2343 @@ + + + + + + + + + + + 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. +
+ + + + -- cgit v1.2.3