px-fwlib 0.10.0
Cross-platform embedded library and documentation for 8/16/32-bit microcontrollers generated with Doxygen 1.9.2
px_dac.c
1/* =============================================================================
2 ____ ___ ____ ___ _ _ ___ __ __ ___ __ __ TM
3 | _ \ |_ _| / ___| / _ \ | \ | | / _ \ | \/ | |_ _| \ \/ /
4 | |_) | | | | | | | | | | \| | | | | | | |\/| | | | \ /
5 | __/ | | | |___ | |_| | | |\ | | |_| | | | | | | | / \
6 |_| |___| \____| \___/ |_| \_| \___/ |_| |_| |___| /_/\_\
7
8 Copyright (c) 2018 Pieter Conradie <https://piconomix.com>
9
10 License: MIT
11 https://github.com/piconomix/px-fwlib/blob/master/LICENSE.md
12
13 Title: px_dac.h : DAC peripheral driver
14 Author(s): Pieter Conradie
15 Creation Date: 2018-11-15
16
17============================================================================= */
18
19/* _____STANDARD INCLUDES____________________________________________________ */
20
21/* _____PROJECT INCLUDES_____________________________________________________ */
22#include "px_dac.h"
23#include "px_board.h"
24#include "px_stm32cube.h"
25#include "px_log.h"
26
27/* _____LOCAL DEFINITIONS____________________________________________________ */
28PX_LOG_NAME("px_dac");
29
30/// Internal data for each DAC handle
31typedef struct px_dac_per_s
32{
33 DAC_TypeDef * dac_base_adr; ///< DAC peripheral base register address
34 px_dac_nr_t dac_nr; ///< Peripheral
35 uint8_t open_counter; ///< Number of open handles referencing peripheral
37
38/* _____MACROS_______________________________________________________________ */
39
40/* _____GLOBAL VARIABLES_____________________________________________________ */
41
42/* _____LOCAL VARIABLES______________________________________________________ */
43/// Allocate data for each enabled DAC peripheral
44#if PX_DAC_CFG_DAC1_EN
45static px_dac_per_t px_dac_per_1;
46#endif
47
48/* _____LOCAL FUNCTION DECLARATIONS__________________________________________ */
49
50/* _____LOCAL FUNCTIONS______________________________________________________ */
51static void px_dac_init_per(DAC_TypeDef * dac_base_adr,
52 px_dac_nr_t dac_nr)
53{
54 uint32_t dac_channel = 0;
55
56 // Enable peripheral clock
57 switch(dac_nr)
58 {
59#if PX_DAC_CFG_DAC1_EN
60 case PX_DAC_NR_1:
61 LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_DAC1);
62 break;
63#endif
64 default:
65 PX_LOG_E("Invalid peripheral");
66 return;
67 }
68 // Enable peripheral
69#if PX_DAC_CFG_DAC1_CH1_EN
70 dac_channel |= LL_DAC_CHANNEL_1;
71#endif
72#if PX_DAC_CFG_DAC1_CH2_EN
73 dac_channel |= LL_DAC_CHANNEL_2;
74#endif
75 LL_DAC_Enable(dac_base_adr, dac_channel);
76}
77
78
79static void px_dac_init_per_data(px_dac_nr_t dac_nr,
80 px_dac_per_t * dac_per)
81{
82 // Set peripheral
83 dac_per->dac_nr = dac_nr;
84 // Set peripheral base address
85 switch(dac_nr)
86 {
87#if PX_DAC_CFG_DAC1_EN
88 case PX_DAC_NR_1:
89 dac_per->dac_base_adr = DAC1;
90 break;
91#endif
92 default:
93 PX_LOG_E("Invalid peripheral");
94 return;
95 }
96 // Clear reference counter
97 dac_per->open_counter = 0;
98}
99
100/* _____GLOBAL FUNCTIONS_____________________________________________________ */
101void px_dac_init(void)
102{
103 // Initialize peripheral data for each enabled peripheral
104#if PX_DAC_CFG_DAC1_EN
105 px_dac_init_per_data(PX_DAC_NR_1, &px_dac_per_1);
106#endif
107}
108
110 px_dac_nr_t dac_nr)
111{
112 px_dac_per_t * dac_per;
113
114#if PX_LOG
115 // Verify that pointer to handle is not NULL
116 if(handle == NULL)
117 {
118 PX_LOG_ASSERT(false);
119 return false;
120 }
121#endif
122
123 // Handle not initialised
124 handle->dac_per = NULL;
125 // Set pointer to peripheral data
126 switch(dac_nr)
127 {
128#if PX_DAC_CFG_DAC1_EN
129 case PX_DAC_NR_1:
130 dac_per = &px_dac_per_1;
131 break;
132#endif
133 default:
134 PX_LOG_E("Invalid peripheral specified");
135 return false;
136 }
137#if PX_LOG
138 // Check that px_adc_init() has been called
139 if(dac_per->dac_base_adr == NULL)
140 {
141 PX_LOG_ASSERT(false);
142 return false;
143 }
144#endif
145 // Initialise peripheral
146 px_dac_init_per(dac_per->dac_base_adr, dac_nr);
147 // Point handle to peripheral
148 handle->dac_per = dac_per;
149 // Success
150 dac_per->open_counter++;
151 return true;
152}
153
155{
156 px_dac_per_t * dac_per;
157 DAC_TypeDef * dac_base_adr;
158 uint32_t dac_channel = 0;
159
160#if PX_LOG
161 // Check handle
162 if( (handle == NULL)
163 ||(handle->dac_per == NULL)
164 ||(handle->dac_per->dac_base_adr == NULL)
165 ||(handle->dac_per->open_counter == 0 ) )
166 {
167 PX_LOG_ASSERT(false);
168 return false;
169 }
170#endif
171
172 // Set pointer to peripheral
173 dac_per = handle->dac_per;
174 // Get DAC peripheral base register address
175 dac_base_adr = dac_per->dac_base_adr;
176 // Decrement open count
177 dac_per->open_counter--;
178 // More open handles referencing peripheral?
179 if(dac_per->open_counter != 0)
180 {
181 // Close handle
182 handle->dac_per = NULL;
183 // Success
184 return true;
185 }
186 // Disable peripheral
187#if PX_DAC_CFG_DAC1_CH1_EN
188 dac_channel |= LL_DAC_CHANNEL_1;
189#endif
190#if PX_DAC_CFG_DAC1_CH2_EN
191 dac_channel |= LL_DAC_CHANNEL_2;
192#endif
193 LL_DAC_Disable(dac_base_adr, dac_channel);
194 // Disable peripheral clock
195 switch(handle->dac_per->dac_nr)
196 {
197#if PX_DAC_CFG_DAC1_EN
198 case PX_DAC_NR_1:
199 LL_APB1_GRP1_DisableClock(LL_APB1_GRP1_PERIPH_DAC1);
200 break;
201#endif
202 default:
203 break;
204 }
205 // Close handle
206 handle->dac_per = NULL;
207 // Success
208 return true;
209}
210
212 px_dac_channel_t channel,
213 uint16_t data)
214{
215 px_dac_per_t * dac_per;
216 DAC_TypeDef * dac_base_adr;
217
218#if PX_LOG
219 // Check handle
220 if( (handle == NULL)
221 ||(handle->dac_per == NULL)
222 ||(handle->dac_per->dac_base_adr == NULL)
223 ||(handle->dac_per->open_counter == 0 ) )
224 {
225 PX_LOG_ASSERT(false);
226 return;
227 }
228#endif
229
230 // Set pointer to peripheral
231 dac_per = handle->dac_per;
232 // Get DAC peripheral base register address
233 dac_base_adr = dac_per->dac_base_adr;
234 // Ouput data
235 switch(channel)
236 {
237 case PX_DAC_CHANNEL_1:
238 dac_base_adr->DHR12R1 = data;
239 break;
240 case PX_DAC_CHANNEL_2:
241 dac_base_adr->DHR12R2 = data;
242 break;
243 default:
244 PX_LOG_E("Invalid DAC channel specified");
245 break;
246 }
247}
#define NULL
NULL pointer.
Definition: px_defs.h:49
#define PX_LOG_NAME(name)
Macro to declare a log name string once for each file to reduce code size.
Definition: px_log.h:349
#define PX_LOG_E(format,...)
Macro to display a formatted ERROR message.
Definition: px_log.h:377
#define PX_LOG_ASSERT(expression)
Macro that will test an expression, and block indefinitely if false.
Definition: px_log.h:440
struct px_dac_per_s * dac_per
DAC peripheral data.
Definition: px_dac.h:88
bool px_dac_close(px_dac_handle_t *handle)
Close specified device.
Definition: px_dac.c:154
px_dac_channel_t
Specify DAC channel.
Definition: px_dac.h:80
void px_dac_wr(px_dac_handle_t *handle, px_dac_channel_t channel, uint16_t data)
Perform a single output on the specified DAC channel.
Definition: px_dac.c:211
void px_dac_init(void)
Initialise DAC driver.
Definition: px_dac.c:101
px_dac_nr_t
Specify DAC peripheral.
Definition: px_dac.h:74
bool px_dac_open(px_dac_handle_t *handle, px_dac_nr_t dac_nr)
Open DAC peripheral using predefined (default) parameters.
Definition: px_dac.c:109
Define DAC handle.
Definition: px_dac.h:87
Internal data for each DAC handle.
Definition: px_dac.c:32
uint8_t open_counter
Number of open handles referencing peripheral.
Definition: px_dac.c:35
px_dac_nr_t dac_nr
Peripheral.
Definition: px_dac.c:34
DAC_TypeDef * dac_base_adr
DAC peripheral base register address.
Definition: px_dac.c:33