dac.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. /*
  2. * (c) danielinux 2020
  3. * GPLv.2
  4. *
  5. * See LICENSE for details
  6. */
  7. #include <unicore-mx/cm3/nvic.h>
  8. #include <unicore-mx/stm32/dma.h>
  9. #include <unicore-mx/stm32/dac.h>
  10. #include <unicore-mx/stm32/gpio.h>
  11. #include <unicore-mx/stm32/rcc.h>
  12. #include <unicore-mx/stm32/timer.h>
  13. #include <stdlib.h>
  14. #include "pot.h"
  15. #include "timer.h"
  16. #include "system.h"
  17. #define DAC_BUFSIZ (512)
  18. #define DAC_MEMSIZ (4 * DAC_BUFSIZ)
  19. extern const unsigned char raw_au[];
  20. extern volatile uint32_t jiffies;
  21. const unsigned int raw_au_len;
  22. static int dac_transfer_size;
  23. static uint8_t dac_memory[DAC_MEMSIZ];
  24. static volatile uint32_t dac_written;
  25. static volatile int direct = 0;
  26. static volatile int dac_busy = 0;
  27. int dac_is_busy(void)
  28. {
  29. return dac_busy;
  30. }
  31. static void dac_xmit(void)
  32. {
  33. uint32_t size = DAC_BUFSIZ;
  34. if ((dac_transfer_size == 0) || (dac_written >= dac_transfer_size)) {
  35. dac_written = 0;
  36. dac_transfer_size = 0;
  37. memset(dac_memory, 0, DAC_MEMSIZ);
  38. } else {
  39. if ((dac_transfer_size - dac_written) < size)
  40. size = dac_transfer_size - dac_written;
  41. if (size == 0) {
  42. dac_transfer_size = 0;
  43. dac_written = 0;
  44. memset(dac_memory, 0, DAC_MEMSIZ);
  45. }
  46. }
  47. if (dac_transfer_size == 0) {
  48. dma_disable_stream(DMA1, DMA_STREAM5);
  49. dac_trigger_disable(CHANNEL_1);
  50. dac_dma_disable(CHANNEL_1);
  51. return;
  52. }
  53. dma_set_number_of_data(DMA1, DMA_STREAM5, size);
  54. dma_set_memory_address(DMA1, DMA_STREAM5, (uint32_t)(dac_memory + dac_written));
  55. direct = 0;
  56. /* Start DMA transfer of waveform */
  57. dac_trigger_enable(CHANNEL_1);
  58. dac_set_trigger_source(DAC_CR_TSEL1_T2);
  59. dac_dma_enable(CHANNEL_1);
  60. dma_enable_transfer_complete_interrupt(DMA1, DMA_STREAM5);
  61. dma_channel_select(DMA1, DMA_STREAM5, DMA_SxCR_CHSEL_7);
  62. dma_enable_stream(DMA1, DMA_STREAM5);
  63. }
  64. int dac_space(void)
  65. {
  66. return DAC_MEMSIZ - dac_transfer_size;
  67. }
  68. /* IRQ Handler */
  69. void dma1_stream5_isr(void)
  70. {
  71. if (dma_get_interrupt_flag(DMA1, DMA_STREAM5, DMA_TCIF)) {
  72. dma_clear_interrupt_flags(DMA1, DMA_STREAM5, DMA_TCIF);
  73. dma_disable_stream(DMA1, DMA_STREAM5);
  74. dac_trigger_disable(CHANNEL_1);
  75. dac_dma_disable(CHANNEL_1);
  76. dac_busy = 0;
  77. if (!direct) {
  78. if (dac_written < dac_transfer_size) {
  79. dac_written += DAC_BUFSIZ;
  80. } else {
  81. dac_written = 0;
  82. dac_transfer_size = 0;
  83. return;
  84. }
  85. dac_xmit();
  86. }
  87. }
  88. }
  89. void dac_stop(void)
  90. {
  91. dma_clear_interrupt_flags(DMA1, DMA_STREAM5, DMA_TCIF);
  92. dma_disable_stream(DMA1, DMA_STREAM5);
  93. dac_trigger_disable(CHANNEL_1);
  94. dac_dma_disable(CHANNEL_1);
  95. dac_busy = 0;
  96. }
  97. void dac_play_direct(uint8_t *mem, uint32_t size)
  98. {
  99. dma_clear_interrupt_flags(DMA1, DMA_STREAM5, DMA_TCIF);
  100. dma_disable_stream(DMA1, DMA_STREAM5);
  101. dac_trigger_disable(CHANNEL_1);
  102. dac_dma_disable(CHANNEL_1);
  103. dma_set_number_of_data(DMA1, DMA_STREAM5, size);
  104. dma_set_memory_address(DMA1, DMA_STREAM5, (uint32_t)mem);
  105. direct = 1;
  106. dac_busy = 1;
  107. /* Start DMA transfer of waveform */
  108. dac_trigger_enable(CHANNEL_1);
  109. dac_set_trigger_source(DAC_CR_TSEL1_T2);
  110. dac_dma_enable(CHANNEL_1);
  111. dma_enable_transfer_complete_interrupt(DMA1, DMA_STREAM5);
  112. dma_channel_select(DMA1, DMA_STREAM5, DMA_SxCR_CHSEL_7);
  113. dma_enable_stream(DMA1, DMA_STREAM5);
  114. }
  115. /* Initialization functions */
  116. //#define PERIOD (5200)
  117. #define PERIOD 8800
  118. static void timer_setup(void)
  119. {
  120. /* Enable TIM2 clock. */
  121. rcc_periph_clock_enable(RCC_TIM2);
  122. timer_reset(TIM2);
  123. /* Timer global mode: - No divider, Alignment edge, Direction up */
  124. timer_set_mode(TIM2, TIM_CR1_CKD_CK_INT,
  125. TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP);
  126. timer_continuous_mode(TIM2);
  127. timer_set_period(TIM2, PERIOD);
  128. timer_disable_oc_output(TIM2, TIM_OC2 | TIM_OC3 | TIM_OC4);
  129. timer_enable_oc_output(TIM2, TIM_OC1);
  130. timer_disable_oc_clear(TIM2, TIM_OC1);
  131. timer_disable_oc_preload(TIM2, TIM_OC1);
  132. timer_set_oc_slow_mode(TIM2, TIM_OC1);
  133. timer_set_oc_mode(TIM2, TIM_OC1, TIM_OCM_TOGGLE);
  134. timer_set_oc_value(TIM2, TIM_OC1, 500);
  135. timer_disable_preload(TIM2);
  136. /* Set the timer trigger output (for the DAC) to the channel 1 output
  137. * compare */
  138. timer_set_master_mode(TIM2, TIM_CR2_MMS_COMPARE_OC1REF);
  139. timer_enable_counter(TIM2);
  140. }
  141. static void dac_dma_setup(void)
  142. {
  143. /* DAC channel 1 uses DMA controller 1 Stream 5 Channel 7. */
  144. /* Enable DMA1 clock and IRQ */
  145. rcc_periph_clock_enable(RCC_DMA1);
  146. nvic_set_priority(NVIC_DMA1_STREAM5_IRQ, 1);
  147. nvic_enable_irq(NVIC_DMA1_STREAM5_IRQ);
  148. dma_stream_reset(DMA1, DMA_STREAM5);
  149. dma_set_priority(DMA1, DMA_STREAM5, DMA_SxCR_PL_LOW);
  150. dma_set_memory_size(DMA1, DMA_STREAM5, DMA_SxCR_MSIZE_8BIT);
  151. dma_set_peripheral_size(DMA1, DMA_STREAM5, DMA_SxCR_PSIZE_8BIT);
  152. dma_enable_memory_increment_mode(DMA1, DMA_STREAM5);
  153. dma_enable_circular_mode(DMA1, DMA_STREAM5);
  154. dma_set_transfer_mode(DMA1, DMA_STREAM5,
  155. DMA_SxCR_DIR_MEM_TO_PERIPHERAL);
  156. /* The register to target is the DAC1 8-bit right justified data
  157. register */
  158. dma_set_peripheral_address(DMA1, DMA_STREAM5, (uint32_t) &DAC_DHR8R1);
  159. }
  160. static void dac_hw_init(data_channel c)
  161. {
  162. /* Set DAC GPIO pin to analog mode */
  163. rcc_periph_clock_enable(RCC_GPIOC);
  164. gpio_mode_setup(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO4);
  165. timer_setup();
  166. /* Set up DAC */
  167. rcc_periph_clock_enable(RCC_DAC);
  168. dac_enable(c);
  169. }
  170. void dac_reset(void)
  171. {
  172. dac_written = 0;
  173. dac_transfer_size = 0;
  174. }
  175. void dac_play(const uint8_t *buf, int len)
  176. {
  177. int i = 0;
  178. int space;
  179. int w = 0;
  180. dac_written = 0;
  181. dac_transfer_size = 0;
  182. while (len > 0) {
  183. space = DAC_MEMSIZ;
  184. if (space > len) {
  185. space = len;
  186. }
  187. if (dac_space() == 0) {
  188. WFI();
  189. continue;
  190. }
  191. memcpy(dac_memory, buf + w, space);
  192. dac_transfer_size = space;
  193. dac_xmit();
  194. len -= space;
  195. w += space;
  196. }
  197. }
  198. extern unsigned char drumkit_0_au[];
  199. extern unsigned char drumkit_1_au[];
  200. extern unsigned char drumkit_2_au[];
  201. extern unsigned int drumkit_0_au_len;
  202. extern unsigned int drumkit_1_au_len;
  203. extern unsigned int drumkit_2_au_len;
  204. int dac_init(void)
  205. {
  206. int i;
  207. uint32_t now;
  208. dac_hw_init(CHANNEL_1);
  209. dac_dma_setup();
  210. pot_set_master(100);
  211. // dac_play(drumkit_0_au, drumkit_0_au_len);
  212. // dac_play(raw_au, raw_au_len);
  213. dac_play_direct(drumkit_2_au, drumkit_2_au_len);
  214. while(dac_is_busy())
  215. WFI();
  216. return 0;
  217. }