source: rtos_arduino/trunk/arduino_lib/libraries/Audio/src/DAC.cpp@ 136

Last change on this file since 136 was 136, checked in by ertl-honda, 8 years ago

ライブラリとOS及びベーシックなサンプルの追加.

File size: 3.5 KB
Line 
1/*
2 * Copyright (c) 2012 by Cristian Maglie <c.maglie@arduino.cc>
3 * DAC library for Arduino Due.
4 *
5 * This file is free software; you can redistribute it and/or modify
6 * it under the terms of either the GNU General Public License version 2
7 * or the GNU Lesser General Public License version 2.1, both as
8 * published by the Free Software Foundation.
9 */
10
11#include <DAC.h>
12
13void DACClass::begin(uint32_t period) {
14 // Enable clock for DAC
15 pmc_enable_periph_clk(dacId);
16
17 dacc_reset(dac);
18
19 // Set transfer mode to double word
20 dacc_set_transfer_mode(dac, 1);
21
22 // Power save:
23 // sleep mode - 0 (disabled)
24 // fast wakeup - 0 (disabled)
25 dacc_set_power_save(dac, 0, 0);
26
27 // DAC refresh/startup timings:
28 // refresh - 0x08 (1024*8 dacc clocks)
29 // max speed mode - 0 (disabled)
30 // startup time - 0x10 (1024 dacc clocks)
31 dacc_set_timing(dac, 0x08, 0, DACC_MR_STARTUP_1024);
32
33 // Flexible channel selection with tags
34 dacc_enable_flexible_selection(dac);
35
36 // Set up analog current
37 dacc_set_analog_control(dac,
38 DACC_ACR_IBCTLCH0(0x02) |
39 DACC_ACR_IBCTLCH1(0x02) |
40 DACC_ACR_IBCTLDACCORE(0x01));
41
42 // Enable output channels
43 dacc_enable_channel(dac, 0);
44 dacc_enable_channel(dac, 1);
45
46 // Configure Timer Counter to trigger DAC
47 // --------------------------------------
48 pmc_enable_periph_clk(ID_TC1);
49 TC_Configure(TC0, 1,
50 TC_CMR_TCCLKS_TIMER_CLOCK2 | // Clock at MCR/8
51 TC_CMR_WAVE | // Waveform mode
52 TC_CMR_WAVSEL_UP_RC | // Counter running up and reset when equals to RC
53 TC_CMR_ACPA_SET | TC_CMR_ACPC_CLEAR);
54 const uint32_t TC = period / 8;
55 TC_SetRA(TC0, 1, TC / 2);
56 TC_SetRC(TC0, 1, TC);
57 TC_Start(TC0, 1);
58
59 // Configure clock source for DAC (2 = TC0 Output Chan. 1)
60 dacc_set_trigger(dac, 2);
61
62 // Configure pins
63 PIO_Configure(g_APinDescription[DAC0].pPort,
64 g_APinDescription[DAC0].ulPinType,
65 g_APinDescription[DAC0].ulPin,
66 g_APinDescription[DAC0].ulPinConfiguration);
67 PIO_Configure(g_APinDescription[DAC1].pPort,
68 g_APinDescription[DAC1].ulPinType,
69 g_APinDescription[DAC1].ulPin,
70 g_APinDescription[DAC1].ulPinConfiguration);
71
72 // Enable interrupt controller for DAC
73 dacc_disable_interrupt(dac, 0xFFFFFFFF);
74 NVIC_DisableIRQ(isrId);
75 NVIC_ClearPendingIRQ(isrId);
76 NVIC_SetPriority(isrId, 0);
77 NVIC_EnableIRQ(isrId);
78}
79
80void DACClass::end() {
81 TC_Stop(TC0, 1);
82 NVIC_DisableIRQ(isrId);
83 dacc_disable_channel(dac, 0);
84 dacc_disable_channel(dac, 1);
85}
86
87bool DACClass::canQueue() {
88 return (dac->DACC_TNCR == 0);
89}
90
91size_t DACClass::queueBuffer(const uint32_t *buffer, size_t size) {
92 // Try the first PDC buffer
93 if ((dac->DACC_TCR == 0) && (dac->DACC_TNCR == 0)) {
94 dac->DACC_TPR = (uint32_t) buffer;
95 dac->DACC_TCR = size;
96 dac->DACC_PTCR = DACC_PTCR_TXTEN;
97 if (cb)
98 dacc_enable_interrupt(dac, DACC_IER_ENDTX);
99 return size;
100 }
101
102 // Try the second PDC buffer
103 if (dac->DACC_TNCR == 0) {
104 dac->DACC_TNPR = (uint32_t) buffer;
105 dac->DACC_TNCR = size;
106 dac->DACC_PTCR = DACC_PTCR_TXTEN;
107 if (cb)
108 dacc_enable_interrupt(dac, DACC_IER_ENDTX);
109 return size;
110 }
111
112 // PDC buffers full, try again later...
113 return 0;
114}
115
116void DACClass::setOnTransmitEnd_CB(OnTransmitEnd_CB _cb, void *_data) {
117 cb = _cb;
118 cbData = _data;
119 if (!cb)
120 dacc_disable_interrupt(dac, DACC_IDR_ENDTX);
121}
122
123void DACClass::onService() {
124 uint32_t sr = dac->DACC_ISR;
125 if (sr & DACC_ISR_ENDTX) {
126 // There is a free slot, enqueue data
127 dacc_disable_interrupt(dac, DACC_IDR_ENDTX);
128 if (cb)
129 cb(cbData);
130 }
131}
132
133DACClass DAC(DACC_INTERFACE, DACC_INTERFACE_ID, DACC_ISR_ID);
134
135void DACC_ISR_HANDLER(void) {
136 DAC.onService();
137}
138
Note: See TracBrowser for help on using the repository browser.