dac.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544
  1. /*
  2. * This file is part of the MicroPython project, http://micropython.org/
  3. *
  4. * The MIT License (MIT)
  5. *
  6. * Copyright (c) 2013, 2014 Damien P. George
  7. *
  8. * Permission is hereby granted, free of charge, to any person obtaining a copy
  9. * of this software and associated documentation files (the "Software"), to deal
  10. * in the Software without restriction, including without limitation the rights
  11. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  12. * copies of the Software, and to permit persons to whom the Software is
  13. * furnished to do so, subject to the following conditions:
  14. *
  15. * The above copyright notice and this permission notice shall be included in
  16. * all copies or substantial portions of the Software.
  17. *
  18. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  21. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  22. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  23. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  24. * THE SOFTWARE.
  25. */
  26. #include <stdio.h>
  27. #include <stdint.h>
  28. #include <string.h>
  29. #include "py/runtime.h"
  30. #include "py/mphal.h"
  31. #include "timer.h"
  32. #include "dac.h"
  33. #include "dma.h"
  34. #include "pin.h"
  35. /// \moduleref pyb
  36. /// \class DAC - digital to analog conversion
  37. ///
  38. /// The DAC is used to output analog values (a specific voltage) on pin X5 or pin X6.
  39. /// The voltage will be between 0 and 3.3V.
  40. ///
  41. /// *This module will undergo changes to the API.*
  42. ///
  43. /// Example usage:
  44. ///
  45. /// from pyb import DAC
  46. ///
  47. /// dac = DAC(1) # create DAC 1 on pin X5
  48. /// dac.write(128) # write a value to the DAC (makes X5 1.65V)
  49. ///
  50. /// To output a continuous sine-wave:
  51. ///
  52. /// import math
  53. /// from pyb import DAC
  54. ///
  55. /// # create a buffer containing a sine-wave
  56. /// buf = bytearray(100)
  57. /// for i in range(len(buf)):
  58. /// buf[i] = 128 + int(127 * math.sin(2 * math.pi * i / len(buf)))
  59. ///
  60. /// # output the sine-wave at 400Hz
  61. /// dac = DAC(1)
  62. /// dac.write_timed(buf, 400 * len(buf), mode=DAC.CIRCULAR)
  63. #if defined(MICROPY_HW_ENABLE_DAC) && MICROPY_HW_ENABLE_DAC
  64. #if defined(STM32H7)
  65. #define DAC DAC1
  66. #endif
  67. STATIC DAC_HandleTypeDef DAC_Handle;
  68. void dac_init(void) {
  69. memset(&DAC_Handle, 0, sizeof DAC_Handle);
  70. DAC_Handle.Instance = DAC;
  71. DAC_Handle.State = HAL_DAC_STATE_RESET;
  72. HAL_DAC_Init(&DAC_Handle);
  73. }
  74. #if defined(TIM6)
  75. STATIC void TIM6_Config(uint freq) {
  76. // Init TIM6 at the required frequency (in Hz)
  77. TIM_HandleTypeDef *tim = timer_tim6_init(freq);
  78. // TIM6 TRGO selection
  79. TIM_MasterConfigTypeDef config;
  80. config.MasterOutputTrigger = TIM_TRGO_UPDATE;
  81. config.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  82. HAL_TIMEx_MasterConfigSynchronization(tim, &config);
  83. // TIM6 start counter
  84. HAL_TIM_Base_Start(tim);
  85. }
  86. #endif
  87. STATIC uint32_t TIMx_Config(mp_obj_t timer) {
  88. // TRGO selection to trigger DAC
  89. TIM_HandleTypeDef *tim = pyb_timer_get_handle(timer);
  90. TIM_MasterConfigTypeDef config;
  91. config.MasterOutputTrigger = TIM_TRGO_UPDATE;
  92. config.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  93. HAL_TIMEx_MasterConfigSynchronization(tim, &config);
  94. // work out the trigger channel (only certain ones are supported)
  95. if (tim->Instance == TIM2) {
  96. return DAC_TRIGGER_T2_TRGO;
  97. #if defined(TIM4)
  98. } else if (tim->Instance == TIM4) {
  99. return DAC_TRIGGER_T4_TRGO;
  100. #endif
  101. #if defined(TIM5)
  102. } else if (tim->Instance == TIM5) {
  103. return DAC_TRIGGER_T5_TRGO;
  104. #endif
  105. #if defined(TIM6)
  106. } else if (tim->Instance == TIM6) {
  107. return DAC_TRIGGER_T6_TRGO;
  108. #endif
  109. #if defined(TIM7)
  110. } else if (tim->Instance == TIM7) {
  111. return DAC_TRIGGER_T7_TRGO;
  112. #endif
  113. #if defined(TIM8)
  114. } else if (tim->Instance == TIM8) {
  115. return DAC_TRIGGER_T8_TRGO;
  116. #endif
  117. } else {
  118. mp_raise_ValueError("Timer does not support DAC triggering");
  119. }
  120. }
  121. /******************************************************************************/
  122. // MicroPython bindings
  123. typedef enum {
  124. DAC_STATE_RESET,
  125. DAC_STATE_WRITE_SINGLE,
  126. DAC_STATE_BUILTIN_WAVEFORM,
  127. DAC_STATE_DMA_WAVEFORM, // should be last enum since we use space beyond it
  128. } pyb_dac_state_t;
  129. typedef struct _pyb_dac_obj_t {
  130. mp_obj_base_t base;
  131. uint32_t dac_channel; // DAC_CHANNEL_1 or DAC_CHANNEL_2
  132. const dma_descr_t *tx_dma_descr;
  133. mp_hal_pin_obj_t pin; // pin_A4 or pin_A5
  134. uint8_t bits; // 8 or 12
  135. uint8_t state;
  136. uint8_t outbuf_single;
  137. uint8_t outbuf_waveform;
  138. } pyb_dac_obj_t;
  139. STATIC void pyb_dac_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
  140. pyb_dac_obj_t *self = MP_OBJ_TO_PTR(self_in);
  141. mp_printf(print, "DAC(%u, bits=%u)",
  142. self->dac_channel == DAC_CHANNEL_1 ? 1 : 2,
  143. self->bits);
  144. }
  145. STATIC mp_obj_t pyb_dac_init_helper(pyb_dac_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
  146. static const mp_arg_t allowed_args[] = {
  147. { MP_QSTR_bits, MP_ARG_INT, {.u_int = 8} },
  148. { MP_QSTR_buffering, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_PTR(&mp_const_none_obj)} },
  149. };
  150. // parse args
  151. mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
  152. mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
  153. // GPIO configuration
  154. mp_hal_pin_config(self->pin, MP_HAL_PIN_MODE_ANALOG, MP_HAL_PIN_PULL_NONE, 0);
  155. // DAC peripheral clock
  156. #if defined(STM32F4) || defined(STM32F7)
  157. __DAC_CLK_ENABLE();
  158. #elif defined(STM32H7)
  159. __HAL_RCC_DAC12_CLK_ENABLE();
  160. #elif defined(STM32F0) || defined(STM32L4)
  161. __HAL_RCC_DAC1_CLK_ENABLE();
  162. #else
  163. #error Unsupported Processor
  164. #endif
  165. // stop anything already going on
  166. __HAL_RCC_DMA1_CLK_ENABLE();
  167. DMA_HandleTypeDef DMA_Handle;
  168. /* Get currently configured dma */
  169. dma_init_handle(&DMA_Handle, self->tx_dma_descr, (void*)NULL);
  170. // Need to deinit DMA first
  171. DMA_Handle.State = HAL_DMA_STATE_READY;
  172. HAL_DMA_DeInit(&DMA_Handle);
  173. HAL_DAC_Stop(&DAC_Handle, self->dac_channel);
  174. if ((self->dac_channel == DAC_CHANNEL_1 && DAC_Handle.DMA_Handle1 != NULL)
  175. || (self->dac_channel == DAC_CHANNEL_2 && DAC_Handle.DMA_Handle2 != NULL)) {
  176. HAL_DAC_Stop_DMA(&DAC_Handle, self->dac_channel);
  177. }
  178. // set bit resolution
  179. if (args[0].u_int == 8 || args[0].u_int == 12) {
  180. self->bits = args[0].u_int;
  181. } else {
  182. mp_raise_ValueError("unsupported bits");
  183. }
  184. // set output buffer config
  185. if (args[1].u_obj == mp_const_none) {
  186. // due to legacy, default values differ for single and waveform outputs
  187. self->outbuf_single = DAC_OUTPUTBUFFER_DISABLE;
  188. self->outbuf_waveform = DAC_OUTPUTBUFFER_ENABLE;
  189. } else if (mp_obj_is_true(args[1].u_obj)) {
  190. self->outbuf_single = DAC_OUTPUTBUFFER_ENABLE;
  191. self->outbuf_waveform = DAC_OUTPUTBUFFER_ENABLE;
  192. } else {
  193. self->outbuf_single = DAC_OUTPUTBUFFER_DISABLE;
  194. self->outbuf_waveform = DAC_OUTPUTBUFFER_DISABLE;
  195. }
  196. // reset state of DAC
  197. self->state = DAC_STATE_RESET;
  198. return mp_const_none;
  199. }
  200. // create the dac object
  201. // currently support either DAC1 on X5 (id = 1) or DAC2 on X6 (id = 2)
  202. /// \classmethod \constructor(port)
  203. /// Construct a new DAC object.
  204. ///
  205. /// `port` can be a pin object, or an integer (1 or 2).
  206. /// DAC(1) is on pin X5 and DAC(2) is on pin X6.
  207. STATIC mp_obj_t pyb_dac_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
  208. // check arguments
  209. mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true);
  210. // get pin/channel to output on
  211. mp_int_t dac_id;
  212. if (MP_OBJ_IS_INT(args[0])) {
  213. dac_id = mp_obj_get_int(args[0]);
  214. } else {
  215. const pin_obj_t *pin = pin_find(args[0]);
  216. if (pin == pin_A4) {
  217. dac_id = 1;
  218. } else if (pin == pin_A5) {
  219. dac_id = 2;
  220. } else {
  221. nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "Pin(%q) doesn't have DAC capabilities", pin->name));
  222. }
  223. }
  224. pyb_dac_obj_t *dac = m_new_obj(pyb_dac_obj_t);
  225. dac->base.type = &pyb_dac_type;
  226. if (dac_id == 1) {
  227. dac->pin = pin_A4;
  228. dac->dac_channel = DAC_CHANNEL_1;
  229. dac->tx_dma_descr = &dma_DAC_1_TX;
  230. } else if (dac_id == 2) {
  231. dac->pin = pin_A5;
  232. dac->dac_channel = DAC_CHANNEL_2;
  233. dac->tx_dma_descr = &dma_DAC_2_TX;
  234. } else {
  235. nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "DAC(%d) doesn't exist", dac_id));
  236. }
  237. // configure the peripheral
  238. mp_map_t kw_args;
  239. mp_map_init_fixed_table(&kw_args, n_kw, args + n_args);
  240. pyb_dac_init_helper(dac, n_args - 1, args + 1, &kw_args);
  241. // return object
  242. return MP_OBJ_FROM_PTR(dac);
  243. }
  244. STATIC mp_obj_t pyb_dac_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
  245. return pyb_dac_init_helper(MP_OBJ_TO_PTR(args[0]), n_args - 1, args + 1, kw_args);
  246. }
  247. STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_dac_init_obj, 1, pyb_dac_init);
  248. /// \method deinit()
  249. /// Turn off the DAC, enable other use of pin.
  250. STATIC mp_obj_t pyb_dac_deinit(mp_obj_t self_in) {
  251. pyb_dac_obj_t *self = MP_OBJ_TO_PTR(self_in);
  252. if (self->dac_channel == DAC_CHANNEL_1) {
  253. DAC_Handle.Instance->CR &= ~DAC_CR_EN1;
  254. #if defined(STM32H7) || defined(STM32L4)
  255. DAC->MCR = (DAC->MCR & ~(7 << DAC_MCR_MODE1_Pos)) | 2 << DAC_MCR_MODE1_Pos;
  256. #else
  257. DAC_Handle.Instance->CR |= DAC_CR_BOFF1;
  258. #endif
  259. } else {
  260. DAC_Handle.Instance->CR &= ~DAC_CR_EN2;
  261. #if defined(STM32H7) || defined(STM32L4)
  262. DAC->MCR = (DAC->MCR & ~(7 << DAC_MCR_MODE2_Pos)) | 2 << DAC_MCR_MODE2_Pos;
  263. #else
  264. DAC_Handle.Instance->CR |= DAC_CR_BOFF2;
  265. #endif
  266. }
  267. return mp_const_none;
  268. }
  269. STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_dac_deinit_obj, pyb_dac_deinit);
  270. #if defined(TIM6)
  271. /// \method noise(freq)
  272. /// Generate a pseudo-random noise signal. A new random sample is written
  273. /// to the DAC output at the given frequency.
  274. STATIC mp_obj_t pyb_dac_noise(mp_obj_t self_in, mp_obj_t freq) {
  275. pyb_dac_obj_t *self = MP_OBJ_TO_PTR(self_in);
  276. // set TIM6 to trigger the DAC at the given frequency
  277. TIM6_Config(mp_obj_get_int(freq));
  278. if (self->state != DAC_STATE_BUILTIN_WAVEFORM) {
  279. // configure DAC to trigger via TIM6
  280. DAC_ChannelConfTypeDef config;
  281. config.DAC_Trigger = DAC_TRIGGER_T6_TRGO;
  282. config.DAC_OutputBuffer = self->outbuf_waveform;
  283. HAL_DAC_ConfigChannel(&DAC_Handle, &config, self->dac_channel);
  284. self->state = DAC_STATE_BUILTIN_WAVEFORM;
  285. }
  286. // set noise wave generation
  287. HAL_DACEx_NoiseWaveGenerate(&DAC_Handle, self->dac_channel, DAC_LFSRUNMASK_BITS10_0);
  288. HAL_DAC_SetValue(&DAC_Handle, self->dac_channel, DAC_ALIGN_12B_L, 0x7ff0);
  289. HAL_DAC_Start(&DAC_Handle, self->dac_channel);
  290. return mp_const_none;
  291. }
  292. STATIC MP_DEFINE_CONST_FUN_OBJ_2(pyb_dac_noise_obj, pyb_dac_noise);
  293. #endif
  294. #if defined(TIM6)
  295. /// \method triangle(freq)
  296. /// Generate a triangle wave. The value on the DAC output changes at
  297. /// the given frequency, and the frequence of the repeating triangle wave
  298. /// itself is 256 (or 1024, need to check) times smaller.
  299. STATIC mp_obj_t pyb_dac_triangle(mp_obj_t self_in, mp_obj_t freq) {
  300. pyb_dac_obj_t *self = MP_OBJ_TO_PTR(self_in);
  301. // set TIM6 to trigger the DAC at the given frequency
  302. TIM6_Config(mp_obj_get_int(freq));
  303. if (self->state != DAC_STATE_BUILTIN_WAVEFORM) {
  304. // configure DAC to trigger via TIM6
  305. DAC_ChannelConfTypeDef config;
  306. config.DAC_Trigger = DAC_TRIGGER_T6_TRGO;
  307. config.DAC_OutputBuffer = self->outbuf_waveform;
  308. HAL_DAC_ConfigChannel(&DAC_Handle, &config, self->dac_channel);
  309. self->state = DAC_STATE_BUILTIN_WAVEFORM;
  310. }
  311. // set triangle wave generation
  312. HAL_DACEx_TriangleWaveGenerate(&DAC_Handle, self->dac_channel, DAC_TRIANGLEAMPLITUDE_1023);
  313. HAL_DAC_SetValue(&DAC_Handle, self->dac_channel, DAC_ALIGN_12B_R, 0x100);
  314. HAL_DAC_Start(&DAC_Handle, self->dac_channel);
  315. return mp_const_none;
  316. }
  317. STATIC MP_DEFINE_CONST_FUN_OBJ_2(pyb_dac_triangle_obj, pyb_dac_triangle);
  318. #endif
  319. /// \method write(value)
  320. /// Direct access to the DAC output (8 bit only at the moment).
  321. STATIC mp_obj_t pyb_dac_write(mp_obj_t self_in, mp_obj_t val) {
  322. pyb_dac_obj_t *self = MP_OBJ_TO_PTR(self_in);
  323. if (self->state != DAC_STATE_WRITE_SINGLE) {
  324. DAC_ChannelConfTypeDef config;
  325. config.DAC_Trigger = DAC_TRIGGER_NONE;
  326. config.DAC_OutputBuffer = self->outbuf_single;
  327. HAL_DAC_ConfigChannel(&DAC_Handle, &config, self->dac_channel);
  328. self->state = DAC_STATE_WRITE_SINGLE;
  329. }
  330. // DAC output is always 12-bit at the hardware level, and we provide support
  331. // for multiple bit "resolutions" simply by shifting the input value.
  332. HAL_DAC_SetValue(&DAC_Handle, self->dac_channel, DAC_ALIGN_12B_R,
  333. mp_obj_get_int(val) << (12 - self->bits));
  334. HAL_DAC_Start(&DAC_Handle, self->dac_channel);
  335. return mp_const_none;
  336. }
  337. STATIC MP_DEFINE_CONST_FUN_OBJ_2(pyb_dac_write_obj, pyb_dac_write);
  338. #if defined(TIM6)
  339. /// \method write_timed(data, freq, *, mode=DAC.NORMAL)
  340. /// Initiates a burst of RAM to DAC using a DMA transfer.
  341. /// The input data is treated as an array of bytes (8 bit data).
  342. ///
  343. /// `freq` can be an integer specifying the frequency to write the DAC
  344. /// samples at, using Timer(6). Or it can be an already-initialised
  345. /// Timer object which is used to trigger the DAC sample. Valid timers
  346. /// are 2, 4, 5, 6, 7 and 8.
  347. ///
  348. /// `mode` can be `DAC.NORMAL` or `DAC.CIRCULAR`.
  349. ///
  350. // TODO add callback argument, to call when transfer is finished
  351. // TODO add double buffer argument
  352. //
  353. // TODO reconsider API, eg: write_trig(data, *, trig=None, loop=False)
  354. // Then trigger can be timer (preinitialised with desired freq) or pin (extint9),
  355. // and we can reuse the same timer for both DACs (and maybe also ADC) without
  356. // setting the freq twice.
  357. // Can still do 1-liner: dac.write_trig(buf, trig=Timer(6, freq=100), loop=True)
  358. mp_obj_t pyb_dac_write_timed(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
  359. static const mp_arg_t allowed_args[] = {
  360. { MP_QSTR_data, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
  361. { MP_QSTR_freq, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
  362. { MP_QSTR_mode, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = DMA_NORMAL} },
  363. };
  364. // parse args
  365. pyb_dac_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
  366. mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
  367. mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
  368. // get the data to write
  369. mp_buffer_info_t bufinfo;
  370. mp_get_buffer_raise(args[0].u_obj, &bufinfo, MP_BUFFER_READ);
  371. uint32_t dac_trigger;
  372. if (mp_obj_is_integer(args[1].u_obj)) {
  373. // set TIM6 to trigger the DAC at the given frequency
  374. TIM6_Config(mp_obj_get_int(args[1].u_obj));
  375. dac_trigger = DAC_TRIGGER_T6_TRGO;
  376. } else {
  377. // set the supplied timer to trigger the DAC (timer should be initialised)
  378. dac_trigger = TIMx_Config(args[1].u_obj);
  379. }
  380. __HAL_RCC_DMA1_CLK_ENABLE();
  381. DMA_HandleTypeDef DMA_Handle;
  382. /* Get currently configured dma */
  383. dma_init_handle(&DMA_Handle, self->tx_dma_descr, (void*)NULL);
  384. /*
  385. DMA_Cmd(DMA_Handle->Instance, DISABLE);
  386. while (DMA_GetCmdStatus(DMA_Handle->Instance) != DISABLE) {
  387. }
  388. DAC_Cmd(self->dac_channel, DISABLE);
  389. */
  390. /*
  391. // DAC channel configuration
  392. DAC_InitTypeDef DAC_InitStructure;
  393. DAC_InitStructure.DAC_Trigger = DAC_Trigger_T7_TRGO;
  394. DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;
  395. DAC_InitStructure.DAC_LFSRUnmask_TriangleAmplitude = DAC_TriangleAmplitude_1; // unused, but need to set it to a valid value
  396. DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Enable;
  397. DAC_Init(self->dac_channel, &DAC_InitStructure);
  398. */
  399. // Need to deinit DMA first
  400. DMA_Handle.State = HAL_DMA_STATE_READY;
  401. HAL_DMA_DeInit(&DMA_Handle);
  402. if (self->bits == 8) {
  403. DMA_Handle.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
  404. DMA_Handle.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
  405. } else {
  406. DMA_Handle.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
  407. DMA_Handle.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
  408. }
  409. DMA_Handle.Init.Mode = args[2].u_int;
  410. HAL_DMA_Init(&DMA_Handle);
  411. if (self->dac_channel == DAC_CHANNEL_1) {
  412. __HAL_LINKDMA(&DAC_Handle, DMA_Handle1, DMA_Handle);
  413. } else {
  414. __HAL_LINKDMA(&DAC_Handle, DMA_Handle2, DMA_Handle);
  415. }
  416. DAC_Handle.Instance = DAC;
  417. DAC_Handle.State = HAL_DAC_STATE_RESET;
  418. HAL_DAC_Init(&DAC_Handle);
  419. if (self->state != DAC_STATE_DMA_WAVEFORM + dac_trigger) {
  420. DAC_ChannelConfTypeDef config;
  421. config.DAC_Trigger = dac_trigger;
  422. config.DAC_OutputBuffer = self->outbuf_waveform;
  423. HAL_DAC_ConfigChannel(&DAC_Handle, &config, self->dac_channel);
  424. self->state = DAC_STATE_DMA_WAVEFORM + dac_trigger;
  425. }
  426. if (self->bits == 8) {
  427. HAL_DAC_Start_DMA(&DAC_Handle, self->dac_channel,
  428. (uint32_t*)bufinfo.buf, bufinfo.len, DAC_ALIGN_8B_R);
  429. } else {
  430. HAL_DAC_Start_DMA(&DAC_Handle, self->dac_channel,
  431. (uint32_t*)bufinfo.buf, bufinfo.len / 2, DAC_ALIGN_12B_R);
  432. }
  433. /*
  434. // enable DMA stream
  435. DMA_Cmd(DMA_Handle->Instance, ENABLE);
  436. while (DMA_GetCmdStatus(DMA_Handle->Instance) == DISABLE) {
  437. }
  438. // enable DAC channel
  439. DAC_Cmd(self->dac_channel, ENABLE);
  440. // enable DMA for DAC channel
  441. DAC_DMACmd(self->dac_channel, ENABLE);
  442. */
  443. //printf("DMA: %p %lu\n", bufinfo.buf, bufinfo.len);
  444. return mp_const_none;
  445. }
  446. STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_dac_write_timed_obj, 1, pyb_dac_write_timed);
  447. #endif
  448. STATIC const mp_rom_map_elem_t pyb_dac_locals_dict_table[] = {
  449. // instance methods
  450. { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&pyb_dac_init_obj) },
  451. { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&pyb_dac_deinit_obj) },
  452. { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&pyb_dac_write_obj) },
  453. #if defined(TIM6)
  454. { MP_ROM_QSTR(MP_QSTR_noise), MP_ROM_PTR(&pyb_dac_noise_obj) },
  455. { MP_ROM_QSTR(MP_QSTR_triangle), MP_ROM_PTR(&pyb_dac_triangle_obj) },
  456. { MP_ROM_QSTR(MP_QSTR_write_timed), MP_ROM_PTR(&pyb_dac_write_timed_obj) },
  457. #endif
  458. // class constants
  459. { MP_ROM_QSTR(MP_QSTR_NORMAL), MP_ROM_INT(DMA_NORMAL) },
  460. { MP_ROM_QSTR(MP_QSTR_CIRCULAR), MP_ROM_INT(DMA_CIRCULAR) },
  461. };
  462. STATIC MP_DEFINE_CONST_DICT(pyb_dac_locals_dict, pyb_dac_locals_dict_table);
  463. const mp_obj_type_t pyb_dac_type = {
  464. { &mp_type_type },
  465. .name = MP_QSTR_DAC,
  466. .print = pyb_dac_print,
  467. .make_new = pyb_dac_make_new,
  468. .locals_dict = (mp_obj_dict_t*)&pyb_dac_locals_dict,
  469. };
  470. #endif // MICROPY_HW_ENABLE_DAC