1 /*
2 * Copyright (c) 2021-2024 HPMicro
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8 #ifndef HPM_ADC12_DRV_H
9 #define HPM_ADC12_DRV_H
10
11 #include "hpm_common.h"
12 #include "hpm_adc12_regs.h"
13 #include "hpm_soc_feature.h"
14
15 /**
16 * @brief ADC12 driver APIs
17 * @defgroup adc12_interface ADC12 driver APIs
18 * @ingroup adc_interfaces
19 * @{
20 */
21
22 /** @brief Define ADC12 validity check for the signal type */
23 #define ADC12_IS_SIGNAL_TYPE_INVALID(TYPE) (TYPE > (uint32_t)adc12_sample_signal_count)
24
25 /** @brief Define ADC12 validity check for the channel number */
26 #define ADC12_IS_CHANNEL_INVALID(CH) (CH > ADC12_SOC_MAX_CH_NUM)
27
28 /** @brief Define ADC12 validity check for the channel sample cycle */
29 #define ADC12_IS_CHANNEL_SAMPLE_CYCLE_INVALID(CYC) (CYC == 0)
30
31 /** @brief Define ADC12 validity check for the trigger number */
32 #define ADC12_IS_TRIG_CH_INVLAID(CH) (CH > ADC_SOC_MAX_TRIG_CH_NUM)
33
34 /** @brief Define ADC12 validity check for the trigger length */
35 #define ADC12_IS_TRIG_LEN_INVLAID(TRIG_LEN) (TRIG_LEN > ADC_SOC_MAX_TRIG_CH_LEN)
36
37 /** @brief Define ADC12 validity check for the sequence length */
38 #define ADC12_IS_SEQ_LEN_INVLAID(LEN) ((LEN == 0) || (LEN > ADC_SOC_SEQ_MAX_LEN))
39
40 /** @brief Define ADC12 validity check for the DMA buffer length in the sequence mode */
41 #define ADC12_IS_SEQ_DMA_BUFF_LEN_INVLAID(LEN) ((LEN == 0) || (LEN > ADC_SOC_SEQ_MAX_DMA_BUFF_LEN_IN_4BYTES))
42
43 /** @brief Define ADC12 validity check for the DMA buffer length in the preemption mode */
44 #define ADC12_IS_PMT_DMA_BUFF_LEN_INVLAID(LEN) ((LEN == 0) || (LEN > ADC_SOC_PMT_MAX_DMA_BUFF_LEN_IN_4BYTES))
45
46 /** @brief Define ADC12 sample signal types. */
47 typedef enum {
48 adc12_sample_signal_single_ended = 0,
49 adc12_sample_signal_differential = 1,
50 adc12_sample_signal_count = 2
51 } adc12_sample_signal_t;
52
53 /** @brief Define ADC12 resolutions. */
54 typedef enum {
55 adc12_res_6_bits = 0,
56 adc12_res_8_bits,
57 adc12_res_10_bits,
58 adc12_res_12_bits
59 } adc12_resolution_t;
60
61 /** @brief Define ADC12 conversion modes. */
62 typedef enum {
63 adc12_conv_mode_oneshot = 0,
64 adc12_conv_mode_period,
65 adc12_conv_mode_sequence,
66 adc12_conv_mode_preemption
67 } adc12_conversion_mode_t;
68
69 /** @brief Define ADC12 Clock Divider */
70 typedef enum {
71 adc12_clock_divider_1 = 1,
72 adc12_clock_divider_2,
73 adc12_clock_divider_3,
74 adc12_clock_divider_4,
75 adc12_clock_divider_5,
76 adc12_clock_divider_6,
77 adc12_clock_divider_7,
78 adc12_clock_divider_8,
79 adc12_clock_divider_9,
80 adc12_clock_divider_10,
81 adc12_clock_divider_11,
82 adc12_clock_divider_12,
83 adc12_clock_divider_13,
84 adc12_clock_divider_14,
85 adc12_clock_divider_15,
86 adc12_clock_divider_16,
87 } adc12_clock_divider_t;
88
89 /** @brief Define ADC12 irq events. */
90 typedef enum {
91 /** This mask indicates that a trigger conversion is complete. */
92 adc12_event_trig_complete = ADC12_INT_STS_TRIG_CMPT_MASK,
93
94 /** This mask indicates that a conflict caused by software-triggered conversions. */
95 adc12_event_trig_sw_conflict = ADC12_INT_STS_TRIG_SW_CFLCT_MASK,
96
97 /** This mask indicates that a conflict caused by hardware-triggered conversions. */
98 adc12_event_trig_hw_conflict = ADC12_INT_STS_TRIG_HW_CFLCT_MASK,
99
100 /** This mask indicates that a conflict caused when bus reading from different channels. */
101 adc12_event_read_conflict = ADC12_INT_STS_READ_CFLCT_MASK,
102
103 /** This mask indicates that a conflict caused by sequence-triggered conversions. */
104 adc12_event_seq_sw_conflict = ADC12_INT_STS_SEQ_SW_CFLCT_MASK,
105
106 /** This mask indicates that a conflict caused by hardware-triggered conversions. */
107 adc12_event_seq_hw_conflict = ADC12_INT_STS_SEQ_HW_CFLCT_MASK,
108
109 /** This mask indicates that DMA is stopped currently. */
110 adc12_event_seq_dma_abort = ADC12_INT_STS_SEQ_DMAABT_MASK,
111
112 /** This mask indicates that all of the configured conversion(s) in a queue is(are) complete. */
113 adc12_event_seq_full_complete = ADC12_INT_STS_SEQ_CMPT_MASK,
114
115 /** This mask indicates that one of the configured conversion(s) in a queue is complete. */
116 adc12_event_seq_single_complete = ADC12_INT_STS_SEQ_CVC_MASK,
117
118 /** This mask indicates that DMA FIFO is full currently. */
119 adc12_event_dma_fifo_full = ADC12_INT_STS_DMA_FIFO_FULL_MASK
120 } adc12_irq_event_t;
121
122 /** @brief ADC12 common configuration struct. */
123 typedef struct {
124 uint8_t res;
125 uint8_t conv_mode;
126 uint32_t adc_clk_div;
127 bool wait_dis;
128 bool sel_sync_ahb;
129 bool adc_ahb_en;
130 } adc12_config_t;
131
132 /** @brief ADC12 channel configuration struct. */
133 typedef struct {
134 uint8_t ch;
135 uint8_t diff_sel;
136 uint16_t thshdh;
137 uint16_t thshdl;
138 bool wdog_int_en;
139 uint8_t sample_cycle_shift;
140 uint32_t sample_cycle;
141 } adc12_channel_config_t;
142
143 /** @brief ADC12 channel configuration struct. */
144 typedef struct {
145 uint8_t ch;
146 uint16_t thshdh;
147 uint16_t thshdl;
148 } adc12_channel_threshold_t;
149
150 /** @brief ADC12 DMA configuration struct. */
151 typedef struct {
152 uint32_t *start_addr;
153 uint32_t buff_len_in_4bytes;
154 uint32_t stop_pos;
155 bool stop_en;
156 } adc12_dma_config_t;
157
158 /** @brief ADC12 DMA configuration struct for the sequence mode. */
159 typedef struct {
160 uint32_t :4;
161 uint32_t result :12;
162 uint32_t seq_num :4;
163 uint32_t :4;
164 uint32_t adc_ch :5;
165 uint32_t :2;
166 uint32_t cycle_bit :1;
167 } adc12_seq_dma_data_t;
168
169 /** @brief ADC12 DMA configuration struct for the preemption mode. */
170 typedef struct {
171 uint32_t :4;
172 uint32_t result :12;
173 uint32_t seq_num :2;
174 uint32_t :2;
175 uint32_t trig_ch :4;
176 uint32_t adc_ch :5;
177 uint32_t :2;
178 uint32_t cycle_bit :1;
179 } adc12_pmt_dma_data_t;
180
181 /** @brief ADC12 configuration struct for the period mode. */
182 typedef struct {
183 uint8_t ch;
184 uint8_t prescale;
185 uint8_t period_count;
186 } adc12_prd_config_t;
187
188 /** @brief ADC12 queue configuration struct for the sequence mode. */
189 typedef struct {
190 bool seq_int_en;
191 uint8_t ch;
192 } adc12_seq_queue_config_t;
193
194 /** @brief ADC12 configuration struct for the sequence mode. */
195 typedef struct {
196 adc12_seq_queue_config_t queue[ADC_SOC_SEQ_MAX_LEN];
197 bool restart_en;
198 bool cont_en;
199 bool sw_trig_en;
200 bool hw_trig_en;
201 uint8_t seq_len;
202 } adc12_seq_config_t;
203
204 /** @brief ADC12 trigger configuration struct for the preemption mode. */
205 typedef struct {
206 bool inten[ADC_SOC_MAX_TRIG_CH_LEN];
207 uint8_t adc_ch[ADC_SOC_MAX_TRIG_CH_LEN];
208 uint8_t trig_ch;
209 uint8_t trig_len;
210 } adc12_pmt_config_t;
211
212 #ifdef __cplusplus
213 extern "C" {
214 #endif
215 /**
216 * @name Initialization and Deinitialization
217 * @{
218 */
219
220 /**
221 * @brief Get a default configuration for an ADC12 instance.
222 *
223 * @param[out] config A pointer to the configuration struct of @ref adc12_config_t.
224 */
225 void adc12_get_default_config(adc12_config_t *config);
226
227 /**
228 * @brief Get a default configuration for an ADC12 channel.
229 *
230 * @param[out] config A pointer to the configuration struct of @ref adc12_channel_config_t.
231 */
232 void adc12_get_channel_default_config(adc12_channel_config_t *config);
233
234 /**
235 * @brief De-initialize an ADC12 instance.
236 *
237 * @param[in] ptr An ADC12 peripheral base address.
238 * @return A result of de-initializing an ADC12 instance.
239 * @retval status_success De-initialize an ADC12 instance successfully. Please refer to @ref hpm_stat_t.
240 * @retval status_invalid_argument De-initialize an ADC12 instance unsuccessfully due to passing one or more invalid arguments. Please refer to @ref hpm_stat_t.
241 */
242 hpm_stat_t adc12_deinit(ADC12_Type *ptr);
243
244 /**
245 * @brief Initialize an ADC12 instance.
246 *
247 * @param[in] ptr An ADC12 peripheral base address.
248 * @param[in] config A pointer to the configuration struct of @ref adc12_config_t.
249 * @return A result of initializing an ADC12 instance.
250 * @retval status_success Initialize an ADC12 instance successfully. Please refer to @ref hpm_stat_t.
251 * @retval status_invalid_argument Initialize an ADC12 instance unsuccessfully due to passing one or more invalid arguments. Please refer to @ref hpm_stat_t.
252 */
253 hpm_stat_t adc12_init(ADC12_Type *ptr, adc12_config_t *config);
254
255 /**
256 * @brief Initialize an ADC12 channel.
257 *
258 * @param[in] ptr An ADC12 peripheral base address.
259 * @param[in] config A pointer to the configuration struct of @ref adc12_channel_config_t.
260 * @return A result of initializing an ADC12 channel.
261 * @retval status_success Initialize an ADC12 channel successfully. Please refer to @ref hpm_stat_t.
262 * @retval status_invalid_argument Initialize an ADC12 channel unsuccessfully due to passing one or more invalid arguments. Please refer to @ref hpm_stat_t.
263 */
264 hpm_stat_t adc12_init_channel(ADC12_Type *ptr, adc12_channel_config_t *config);
265
266 /**
267 * @brief Get thresholds of an ADC12 channel
268 *
269 * @param[in] ptr An ADC12 peripheral base address.
270 * @param[in] ch An ADC12 channel number
271 * @param[out] config A pointer to the structure of channel threshold
272 * @return A result of getting thresholds of an ADC12 channel .
273 * @retval status_success Initialize an ADC12 channel successfully. Please refer to @ref hpm_stat_t.
274 * @retval status_invalid_argument Initialize an ADC12 channel unsuccessfully due to passing one or more invalid arguments. Please refer to @ref hpm_stat_t.
275 */
276 hpm_stat_t adc12_get_channel_threshold(ADC12_Type *ptr, uint8_t ch, adc12_channel_threshold_t *config);
277
278 /**
279 * @brief Configure the the period mode for an ADC12 instance.
280 *
281 * @param[in] ptr An ADC12 peripheral base address.
282 * @param[in] config A pointer to the configuration struct of @ref adc12_prd_config_t.
283 * @return A result of configuring the the period mode for an ADC12 instance.
284 * @retval status_success Configure the the period mode successfully. Please refer to @ref hpm_stat_t.
285 * @retval status_invalid_argument Configure the the period mode unsuccessfully due to passing one or more invalid arguments. Please refer to @ref hpm_stat_t.
286 */
287 hpm_stat_t adc12_set_prd_config(ADC12_Type *ptr, adc12_prd_config_t *config);
288
289 /**
290 * @brief Configure the the sequence mode for an ADC12 instance.
291 *
292 * @param[in] ptr An ADC12 peripheral base address.
293 * @param[in] config A pointer to configuration struct of @ref adc12_seq_config_t.
294 * @return A result of configuring the the sequence mode for an ADC12 instance.
295 * @retval status_success Configure the the sequence mode successfully. Please refer to @ref hpm_stat_t.
296 * @retval status_invalid_argument Configure the the sequence mode unsuccessfully due to passing one or more invalid arguments. Please refer to @ref hpm_stat_t.
297 */
298 hpm_stat_t adc12_set_seq_config(ADC12_Type *ptr, adc12_seq_config_t *config);
299
300 /**
301 * @brief Configure the preemption mode for an ADC12 instance.
302 *
303 * @param[in] ptr An ADC12 peripheral base address.
304 * @param[in] config A pointer to configuration struct of @ref adc12_pmt_config_t.
305 * @return A result of configuring the preemption mode for an ADC12 instance.
306 * @retval status_success Configure the preemption mode successfully. Please refer to @ref hpm_stat_t.
307 * @retval status_invalid_argument Configure the preemption mode unsuccessfully due to passing one or more invalid arguments. Please refer to @ref hpm_stat_t.
308 */
309 hpm_stat_t adc12_set_pmt_config(ADC12_Type *ptr, adc12_pmt_config_t *config);
310
311 /** @} */
312
313 /**
314 * @name DMA Control
315 * @{
316 */
317
318 /**
319 * @brief Configure the stop position offset in the specified memory of DMA write operation for the sequence mode.
320 *
321 * @param[in] ptr An ADC12 peripheral base address.
322 * @param[in] stop_pos A stop position offset.
323 */
adc12_set_seq_stop_pos(ADC12_Type * ptr,uint16_t stop_pos)324 static inline void adc12_set_seq_stop_pos(ADC12_Type *ptr, uint16_t stop_pos)
325 {
326 ptr->SEQ_DMA_CFG = (ptr->SEQ_DMA_CFG & ~ADC12_SEQ_DMA_CFG_STOP_POS_MASK)
327 | ADC12_SEQ_DMA_CFG_STOP_POS_SET(stop_pos);
328 }
329
330 /**
331 * @brief Configure the start address of DMA write operation for the preemption mode.
332 *
333 * @param[in] ptr An ADC12 peripheral base address.
334 * @param[in] addr A start address of DMA write operation.
335 */
adc12_init_pmt_dma(ADC12_Type * ptr,uint32_t addr)336 static inline void adc12_init_pmt_dma(ADC12_Type *ptr, uint32_t addr)
337 {
338 ptr->TRG_DMA_ADDR = addr & ADC12_TRG_DMA_ADDR_TRG_DMA_ADDR_MASK;
339 }
340
341 /**
342 * @brief Configure the start address of DMA write operation for the sequence mode.
343 *
344 * @param[in] ptr An ADC12 peripheral base address.
345 * @param[in] config A pointer to configuration struct of @ref adc12_dma_config_t.
346 * @return An implementation result of DMA initializing for the sequence mode
347 * @retval status_success ADC12 initialize in sequence mode successfully. Please refert to @ref hpm_stat_t.
348 * @retval status_invalid_argument ADC12 initialize in sequence mode unsuccessfully due to passing invalid arguments. Please refert to @ref hpm_stat_t.
349 */
350 hpm_stat_t adc12_init_seq_dma(ADC12_Type *ptr, adc12_dma_config_t *config);
351
352 /** @} */
353
354 /**
355 * @name Status
356 * @{
357 */
358
359 /**
360 * @brief Get all ADC12 status flags.
361 *
362 * @param[in] ptr An ADC12 peripheral base address.
363 * @return A mask indicating all corresponding interrupt statuses.
364 * @retval A mask. Please refer to @ref adc12_irq_event_t.
365 */
adc12_get_status_flags(ADC12_Type * ptr)366 static inline uint32_t adc12_get_status_flags(ADC12_Type *ptr)
367 {
368 return ptr->INT_STS;
369 }
370
371 /**
372 * @brief Set value of the WAIT_DIS bit. The ADC does not block access to the associated peripheral bus
373 * until the ADC has completed its conversion. *
374 *
375 * @param[in] ptr An ADC12 peripheral base address.
376 * @deprecated This API will be removed from V2.0.x
377 */
adc12_disable_busywait(ADC12_Type * ptr)378 static inline void adc12_disable_busywait(ADC12_Type *ptr)
379 {
380 ptr->BUF_CFG0 |= ADC12_BUF_CFG0_WAIT_DIS_SET(1);
381 }
382
383 /**
384 * @brief Set value of the WAIT_DIS bit. ADC blocks access to the associated peripheral bus
385 * until the ADC completes the conversion.
386 *
387 * @param[in] ptr An ADC12 peripheral base address.
388 * @deprecated This API will be removed from V2.0.x
389 */
adc12_enable_busywait(ADC12_Type * ptr)390 static inline void adc12_enable_busywait(ADC12_Type *ptr)
391 {
392 ptr->BUF_CFG0 &= ~ADC12_BUF_CFG0_WAIT_DIS_MASK;
393 }
394
395 /**
396 * @brief Set nonblocking read in oneshot mode.
397 * @note An ADC does not block access to the associated peripheral whether it completes a conversion or not.
398 *
399 * @param[in] ptr An ADC12 peripheral base address.
400 */
adc12_set_nonblocking_read(ADC12_Type * ptr)401 static inline void adc12_set_nonblocking_read(ADC12_Type *ptr)
402 {
403 ptr->BUF_CFG0 |= ADC12_BUF_CFG0_WAIT_DIS_MASK;
404 }
405
406 /**
407 * @brief Set blocking read in oneshot mode.
408 * @note An ADC blocks access to the associated peripheral bus until it completes a conversion.
409 *
410 * @param[in] ptr An ADC12 peripheral base address.
411 */
adc12_set_blocking_read(ADC12_Type * ptr)412 static inline void adc12_set_blocking_read(ADC12_Type *ptr)
413 {
414 ptr->BUF_CFG0 &= ~ADC12_BUF_CFG0_WAIT_DIS_MASK;
415 }
416
417 /**
418 * @brief Judge whether the current setting is none-blocking mode or not.
419 *
420 * @param[in] ptr An ADC12 peripheral base address.
421 * @return A result indicating the status of bus waiting.
422 * @retval True means that nonblocking reading.
423 * @retval False means that blocking reading.
424 *
425 */
adc12_is_nonblocking_mode(ADC12_Type * ptr)426 static inline bool adc12_is_nonblocking_mode(ADC12_Type *ptr)
427 {
428 return (ADC12_BUF_CFG0_WAIT_DIS_GET(ptr->BUF_CFG0) ? true : false);
429 }
430
431 /**
432 * @brief Get the status of a conversion validity.
433 *
434 * @param[in] ptr An ADC12 peripheral base address.
435 * @param[in] ch An ADC12 peripheral channel.
436 * @return Status indicating the validity of the current conversion result.
437 *
438 * @note This function is only used when the WAIT_DIS bit in the BUF_RESULT register is 1.
439 */
adc12_get_conv_valid_status(ADC12_Type * ptr,uint8_t ch)440 static inline bool adc12_get_conv_valid_status(ADC12_Type *ptr, uint8_t ch)
441 {
442 return ADC12_BUS_RESULT_VALID_GET(ptr->BUS_RESULT[ch]);
443 }
444
445 /**
446 * @brief Clear the status flags.
447 *
448 *
449 * @param[in] ptr An ADC12 peripheral base address.
450 * @param[in] mask A mask that means the specified flags to be cleared. Please refer to @ref adc12_irq_event_t.
451 *
452 * @note Only the specified flags can be cleared by writing the INT_STS register.
453 */
adc12_clear_status_flags(ADC12_Type * ptr,uint32_t mask)454 static inline void adc12_clear_status_flags(ADC12_Type *ptr, uint32_t mask)
455 {
456 ptr->INT_STS = mask;
457 }
458
459 /** @} */
460
461 /**
462 * @name Interrupts
463 * @{
464 */
465
466 /**
467 * @brief Enable interrupts.
468 *
469 * @param[in] ptr An ADC12 peripheral base address.
470 * @param[in] mask A mask indicating the specified ADC interrupt events. Please refer to @ref adc12_irq_event_t.
471 */
adc12_enable_interrupts(ADC12_Type * ptr,uint32_t mask)472 static inline void adc12_enable_interrupts(ADC12_Type *ptr, uint32_t mask)
473 {
474 ptr->INT_EN |= mask;
475 }
476
477 /**
478 * @brief Disable interrupts.
479 *
480 * @param[in] ptr An ADC12 peripheral base address.
481 * @param[in] mask A mask indicating the specified interrupt events. Please refer to @ref adc12_irq_event_t.
482 */
adc12_disable_interrupts(ADC12_Type * ptr,uint32_t mask)483 static inline void adc12_disable_interrupts(ADC12_Type *ptr, uint32_t mask)
484 {
485 ptr->INT_EN &= ~mask;
486 }
487
488 /** @} */
489
490 /**
491 * @name Trigger and Conversion
492 * @{
493 */
494
495 /**
496 * @brief Trigger ADC conversions by software in sequence mode
497 *
498 * @param[in] ptr An ADC12 peripheral base address.
499 * @return An implementation result of getting an ADC12 software trigger.
500 * @retval status_success ADC12 software triggers successfully. Please refer to @ref hpm_stat_t.
501 * @retval status_fail ADC12 software triggers unsuccessfully. Please refer to @ref hpm_stat_t.
502 */
503 hpm_stat_t adc12_trigger_seq_by_sw(ADC12_Type *ptr);
504
505 /**
506 * @brief Trigger ADC conversions by software in preemption mode
507 *
508 * @param[in] ptr An ADC12 peripheral base address.
509 * @param[in] trig_ch A trigger channel number(e.g. TRIG0A,TRIG0B,TRIG0C...).
510 * @return An implementation result of getting an ADC12 software trigger.
511 * @retval status_success ADC12 software triggers successfully. Please refer to @ref hpm_stat_t.
512 * @retval status_fail ADC12 software triggers unsuccessfully. Please refer to @ref hpm_stat_t.
513 */
514 hpm_stat_t adc12_trigger_pmt_by_sw(ADC12_Type *ptr, uint8_t trig_ch);
515
516 /**
517 * @brief Get the result in oneshot mode.
518 *
519 * @param[in] ptr An ADC12 peripheral base address.
520 * @param[in] ch An ADC12 peripheral channel.
521 * @param[out] result A pointer to an ADC12 conversion result.
522 * @return An implementation result of getting an ADC12 conversion result in oneshot mode.
523 * @retval status_success Get the result of an ADC12 conversion in oneshot mode successfully. Please refer to @ref hpm_stat_t.
524 * @retval status_invalid_argument Get the result of an ADC12 conversion in oneshot mode unsuccessfully due to passing invalid arguments. Please refer to @ref hpm_stat_t.
525 */
526 hpm_stat_t adc12_get_oneshot_result(ADC12_Type *ptr, uint8_t ch, uint16_t *result);
527
528 /**
529 * @brief Get the result in the period mode.
530 *
531 * @param[in] ptr An ADC12 peripheral base address.
532 * @param[in] ch An ADC12 peripheral channel.
533 * @param[out] result A pointer to a specified ADC12 conversion result
534 * @return An implementation of getting an ADC12 conversion result in the period mode.
535 * @retval status_success Get the result of an ADC12 conversion in the period mode successfully. Please refer to @ref hpm_stat_t.
536 * @retval status_invalid_argument Get the result of an ADC12 conversion in the period mode unsuccessfully due to passing invalid arguments. Please refer to @ref hpm_stat_t.
537 */
538 hpm_stat_t adc12_get_prd_result(ADC12_Type *ptr, uint8_t ch, uint16_t *result);
539
540 /** @} */
541
542 #ifdef __cplusplus
543 }
544 #endif
545
546 /** @} */
547 #endif /* HPM_ADC12_DRV_H */
548