Skip to content

Commit 7e9030f

Browse files
committed
[sam] Add SAMx7x DAC driver
1 parent 8a9fe61 commit 7e9030f

File tree

5 files changed

+462
-4
lines changed

5 files changed

+462
-4
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,9 @@ git clone --recurse-submodules --jobs 8 https://github.com/modm-io/modm.git
8181

8282
## Microcontrollers
8383

84-
modm can create a HAL for <!--allcount-->3607<!--/allcount--> devices of these vendors:
84+
modm can create a HAL for <!--allcount-->3628<!--/allcount--> devices of these vendors:
8585

86-
- STMicroelectronics STM32: <!--stmcount-->2802<!--/stmcount--> devices.
86+
- STMicroelectronics STM32: <!--stmcount-->2823<!--/stmcount--> devices.
8787
- Microchip SAM: <!--samcount-->416<!--/samcount--> devices.
8888
- Microchip AVR: <!--avrcount-->388<!--/avrcount--> devices.
8989
- Raspberry Pi: <!--rpicount-->1<!--/rpicount--> device.
@@ -221,7 +221,7 @@ Please [discover modm's peripheral drivers for your specific device][discover].
221221
<td align="center">✅</td>
222222
<td align="center">○</td>
223223
<td align="center">○</td>
224-
<td align="center"></td>
224+
<td align="center"></td>
225225
<td align="center">✕</td>
226226
<td align="center">✕</td>
227227
<td align="center">✕</td>
Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
/*
2+
* Copyright (c) 2023, Christopher Durand
3+
*
4+
* This file is part of the modm project.
5+
*
6+
* This Source Code Form is subject to the terms of the Mozilla Public
7+
* License, v. 2.0. If a copy of the MPL was not distributed with this
8+
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
9+
*/
10+
// ----------------------------------------------------------------------------
11+
12+
#ifndef MODM_SAMX7X_DAC_HPP
13+
#define MODM_SAMX7X_DAC_HPP
14+
15+
#include <cstdint>
16+
#include <modm/math/algorithm/prescaler.hpp>
17+
#include <modm/platform/clock/clockgen.hpp>
18+
#include <modm/platform/gpio/connector.hpp>
19+
20+
namespace modm::platform
21+
{
22+
23+
/**
24+
* Digital-to-Analog Converter (DACC)
25+
*
26+
* @author Christopher Durand
27+
* @ingroup modm_platform_dac
28+
*/
29+
class Dac : public PeripheralDriver
30+
{
31+
public:
32+
enum class Channel : uint8_t
33+
{
34+
Channel0 = 0,
35+
Channel1 = 1
36+
};
37+
38+
enum class Mode
39+
{
40+
/// DAC conversion is started by writing data register
41+
FreeRunning = 0,
42+
/// DAC conversion is started by external trigger event
43+
Trigger = 1,
44+
/// Continuous conversion at a rate of DAC clock / 12
45+
MaxSpeed = 2
46+
};
47+
48+
enum class TriggerSource
49+
{
50+
Datrg = 0,
51+
Tc0 = 1,
52+
Tc1 = 2,
53+
Tc2 = 3,
54+
Pwm0Event0 = 4,
55+
Pwm0Event1 = 5,
56+
Pwm1Event0 = 6,
57+
Pwm1Event1 = 7
58+
};
59+
60+
enum class ChannelStatus : uint32_t
61+
{
62+
Ch0Enabled = Bit0,
63+
Ch1Enabled = Bit1,
64+
Ch0Ready = Bit8,
65+
Ch1Ready = Bit9
66+
};
67+
MODM_FLAGS32(ChannelStatus);
68+
69+
enum class Interrupt : uint32_t
70+
{
71+
/// Set if the peripheral is ready to accept new data for channel 0.
72+
TxReadyCh0 = Bit0,
73+
/// Set if the peripheral is ready to accept new data for channel 1.
74+
TxReadyCh1 = Bit1,
75+
/// A conversion has completed for channel 0. Cleared on read of DACC_ISR.
76+
EnfOfConversionCh0 = Bit4,
77+
/// A conversion has completed for channel 1. Cleared on read of DACC_ISR.
78+
EnfOfConversionCh1 = Bit5
79+
};
80+
MODM_FLAGS32(Interrupt);
81+
82+
/// Maximum DAC peripheral clock. The maximum sampling rate is MaxClock / 12.
83+
static constexpr auto MaxClock = 12_MHz;
84+
static constexpr size_t ResolutionBits = 12;
85+
static constexpr size_t MaxOutput = ((1 << ResolutionBits) - 1);
86+
87+
template<typename... Pins>
88+
static void
89+
connect();
90+
91+
/**
92+
* Initialize the D/A converter.
93+
*
94+
* @tparam SystemClock System clock struct
95+
* @tparam frequency Max DAC clock, sampling rate in max speed mode is frequency / 12
96+
*/
97+
template<typename SystemClock, frequency_t frequency=12_MHz, percent_t tolerance=5_pct>
98+
static void
99+
initialize();
100+
101+
/**
102+
* Enable DAC output for the given channel
103+
* The corresponding GPIO pin will be connected to the DAC if enabled.
104+
*
105+
* @param chan The channel to be enabled
106+
*
107+
* @pre The DAC clock must be enabled with initialize()
108+
*/
109+
static void
110+
enableChannel(Channel chan);
111+
112+
/**
113+
* Disable DAC output for the given channel
114+
*
115+
* @param chan The channel to be disabled
116+
*
117+
* @pre The DAC clock must be enabled with initialize()
118+
*/
119+
static void
120+
disableChannel(Channel chan);
121+
122+
/**
123+
* Configure the channel conversion mode
124+
*
125+
*/
126+
static void
127+
setChannelMode(Channel chan, Mode mode);
128+
129+
/**
130+
* Set the output voltage for a DAC channel
131+
*
132+
* @param chan The channel to set
133+
* @param value The 12-bit DAC output value, range 0-4095.
134+
*
135+
* @pre The DAC clock must be enabled with initialize()
136+
*/
137+
static void
138+
setOutput(Channel chan, uint32_t value);
139+
140+
/**
141+
* Set output value for Channel1
142+
*
143+
* Equivalent to setOutput(modm::platform::Dac::Channel1, value)
144+
*
145+
* @param value The 12-bit DAC output value, range 0-4095
146+
*
147+
* @pre The DAC clock must be enabled with initialize()
148+
*/
149+
static void
150+
setOutput0(uint32_t value);
151+
152+
/**
153+
* Set output value for Channel2
154+
*
155+
* Equivalent to setOutput(modm::platform::Dac::Channel2, value)
156+
*
157+
* @param value The 12-bit DAC output value, range 0-4095
158+
*
159+
* @pre The DAC clock must be enabled with initialize()
160+
*/
161+
static void
162+
setOutput1(uint32_t value);
163+
164+
/**
165+
* Set word transfer mode.
166+
*
167+
* If enabled every write to the data register will store two 16 bit
168+
* values to the channel FIFO. This is useful with DMA to reduce the number
169+
* of bus accesses.
170+
*
171+
* @pre The DAC clock must be enabled with initialize()
172+
*/
173+
static void
174+
setWordTransferMode(bool enabled);
175+
176+
/**
177+
* Read channel status flags
178+
*/
179+
static ChannelStatus_t
180+
channelStatus();
181+
182+
/**
183+
* Get channel 0 data register pointer for use with DMA.
184+
*/
185+
static volatile uint32_t*
186+
channel0DataRegister();
187+
188+
/**
189+
* Get channel 1 data register pointer for use with DMA.
190+
*/
191+
static volatile uint32_t*
192+
channel1DataRegister();
193+
194+
/**
195+
* Set DAC trigger source. The setting only has an effect
196+
* if the respective channel is configured in trigger mode.
197+
*/
198+
static void
199+
setTriggerSource(Channel channel, TriggerSource source);
200+
201+
static void
202+
enableInterruptFlag(Interrupt_t interrupt);
203+
204+
static void
205+
disableInterruptFlag(Interrupt_t interrupt);
206+
207+
/**
208+
* Read interrupt status register.
209+
*
210+
* End of conversion flags are cleared after reading.
211+
*/
212+
static Interrupt_t
213+
readInterruptFlags();
214+
215+
static void
216+
enableInterruptVector(uint32_t priority);
217+
218+
static void
219+
disableInterruptVector();
220+
};
221+
222+
} // namespace modm::platform
223+
224+
#include "dac_impl.hpp"
225+
226+
#endif // MODM_SAMX7X_DAC_HPP

0 commit comments

Comments
 (0)