1 /*
2 * Copyright (c) 2021 HPMicro
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8 #ifndef HPM_ADC16_DRV_H
9 #define HPM_ADC16_DRV_H
10
11 #include "hpm_common.h"
12 #include "hpm_adc16_regs.h"
13 #include "hpm_soc_feature.h"
14
15 /**
16 * @brief ADC16 driver APIs
17 * @defgroup adc16_interface ADC16 driver APIs
18 * @ingroup adc_interfaces
19 * @{
20 */
21
22 /** @brief Define ADC16 validity check for the channel number */
23 #define ADC16_IS_CHANNEL_INVALID(CH) (CH > ADC16_SOC_MAX_CH_NUM && CH != ADC16_SOC_TEMP_CH_NUM)
24
25 /** @brief Define ADC16 validity check for the trigger number */
26 #define ADC16_IS_TRIG_CH_INVLAID(CH) (CH > ADC16_SOC_MAX_TRIG_CH_NUM)
27
28 /** @brief Define ADC16 validity check for the trigger length */
29 #define ADC16_IS_TRIG_LEN_INVLAID(TRIG_LEN) (TRIG_LEN > ADC_SOC_MAX_TRIG_CH_LEN)
30
31 /** @brief Define ADC16 validity check for the sequence length */
32 #define ADC16_IS_SEQ_LEN_INVLAID(LEN) ((LEN == 0) || (LEN > ADC_SOC_SEQ_MAX_LEN))
33
34 /** @brief Define ADC16 validity check for the DMA buffer length in the sequence mode */
35 #define ADC16_IS_SEQ_DMA_BUFF_LEN_INVLAID(LEN) ((LEN == 0) || (LEN > ADC_SOC_SEQ_MAX_DMA_BUFF_LEN_IN_4BYTES))
36
37 /** @brief Define ADC16 validity check for the DMA buffer length in the preemption mode */
38 #define ADC16_IS_PMT_DMA_BUFF_LEN_INVLAID(LEN) ((LEN == 0) || (LEN > ADC_SOC_PMT_MAX_DMA_BUFF_LEN_IN_4BYTES))
39
40 /** @brief Define ADC16 conversion modes. */
41 typedef enum {
42 adc16_conv_mode_oneshot = 0,
43 adc16_conv_mode_period,
44 adc16_conv_mode_sequence,
45 adc16_conv_mode_preemption
46 } adc16_conversion_mode_t;
47
48 /** @brief Define ADC16 irq events. */
49 typedef enum {
50 /** This mask indicates that a trigger conversion is complete. */
51 adc16_event_trig_complete = ADC16_INT_STS_TRIG_CMPT_MASK,
52
53 /** This mask indicates that a conflict caused by software-triggered conversions. */
54 adc16_event_trig_sw_conflict = ADC16_INT_STS_TRIG_SW_CFLCT_MASK,
55
56 /** This mask indicates that a conflict caused by hardware-triggered conversions. */
57 adc16_event_trig_hw_conflict = ADC16_INT_STS_TRIG_HW_CFLCT_MASK,
58
59 /** This mask indicates that a conflict caused when bus reading from different channels. */
60 adc16_event_read_conflict = ADC16_INT_STS_READ_CFLCT_MASK,
61
62 /** This mask indicates that a conflict caused by sequence-triggered conversions. */
63 adc16_event_seq_sw_conflict = ADC16_INT_STS_SEQ_SW_CFLCT_MASK,
64
65 /** This mask indicates that a conflict caused by hardware-triggered conversions. */
66 adc16_event_seq_hw_conflict = ADC16_INT_STS_SEQ_HW_CFLCT_MASK,
67
68 /** This mask indicates that DMA is stopped currently. */
69 adc16_event_seq_dma_abort = ADC16_INT_STS_SEQ_DMAABT_MASK,
70
71 /** This mask indicates that all of the configured conversion(s) in a queue is(are) complete. */
72 adc16_event_seq_full_complete = ADC16_INT_STS_SEQ_CMPT_MASK,
73
74 /** This mask indicates that one of the configured conversion(s) in a queue is complete. */
75 adc16_event_seq_single_complete = ADC16_INT_STS_SEQ_CVC_MASK,
76
77 /** This mask indicates that DMA FIFO is full currently. */
78 adc16_event_dma_fifo_full = ADC16_INT_STS_DMA_FIFO_FULL_MASK
79 } adc16_irq_event_t;
80
81 /** @brief ADC16 common configuration struct. */
82 typedef struct {
83 uint8_t conv_mode;
84 uint8_t wait_dis;
85 uint32_t adc_clk_div;
86 uint16_t conv_duration;
87 bool port3_rela_time;
88 bool sel_sync_ahb;
89 bool adc_ahb_en;
90 } adc16_config_t;
91
92 /** @brief ADC16 channel configuration struct. */
93 typedef struct {
94 uint8_t ch;
95 uint16_t thshdh;
96 uint16_t thshdl;
97 uint8_t sample_cycle_shift;
98 uint32_t sample_cycle;
99 } adc16_channel_config_t;
100
101 /** @brief ADC16 DMA configuration struct. */
102 typedef struct {
103 uint32_t *start_addr;
104 uint32_t buff_len_in_4bytes;
105 uint32_t stop_pos;
106 bool stop_en;
107 } adc16_dma_config_t;
108
109 /** @brief ADC16 DMA configuration struct for the sequence mode. */
110 typedef struct {
111 uint32_t result :16;
112 uint32_t seq_num :4;
113 uint32_t :4;
114 uint32_t adc_ch :5;
115 uint32_t :2;
116 uint32_t cycle_bit :1;
117 } adc16_seq_dma_data_t;
118
119 /** @brief ADC16 DMA configuration struct for the preemption mode. */
120 typedef struct {
121 uint32_t result :16;
122 uint32_t trig_ch :2;
123 uint32_t :2;
124 uint32_t trig_index :4;
125 uint32_t adc_ch :5;
126 uint32_t :2;
127 uint32_t cycle_bit :1;
128 } adc16_pmt_dma_data_t;
129
130 /** @brief ADC16 configuration struct for the the period mode. */
131 typedef struct {
132 uint32_t clk_src_freq_in_hz;
133 uint8_t ch;
134 uint8_t prescale;
135 uint8_t period_count;
136 } adc16_prd_config_t;
137
138 /** @brief ADC16 queue configuration struct for the sequence mode. */
139 typedef struct {
140 bool seq_int_en;
141 uint8_t ch;
142 } adc16_seq_queue_config_t;
143
144 /** @brief ADC16 configuration struct for the sequence mode. */
145 typedef struct {
146 adc16_seq_queue_config_t queue[ADC_SOC_SEQ_MAX_LEN];
147 bool restart_en;
148 bool cont_en;
149 bool sw_trig_en;
150 bool hw_trig_en;
151 uint8_t seq_len;
152 } adc16_seq_config_t;
153
154 /** @brief ADC16 trigger configuration struct for the preemption mode. */
155 typedef struct {
156 bool inten[ADC_SOC_MAX_TRIG_CH_LEN];
157 uint8_t adc_ch[ADC_SOC_MAX_TRIG_CH_LEN];
158 uint8_t trig_ch;
159 uint8_t trig_len;
160 } adc16_pmt_config_t;
161
162 #ifdef __cplusplus
163 extern "C" {
164 #endif
165 /**
166 * @name Initialization and Deinitialization
167 * @{
168 */
169
170 /**
171 * @brief Get a default configuration for an ADC16 instance.
172 *
173 * @param[out] config A pointer to the configuration struct of @ref adc16_config_t.
174 *
175 */
176 void adc16_get_default_config(adc16_config_t *config);
177
178 /**
179 * @brief Get a default configuration for an ADC16 Channel.
180 *
181 * @param[out] config A pointer to the configuration struct of @ref adc16_channel_config_t.
182 */
183 void adc16_get_channel_default_config(adc16_channel_config_t *config);
184
185 /**
186 * @brief Initialize an ADC16 instance.
187 *
188 * @param[in] ptr An ADC16 peripheral base address.
189 * @param[in] config A pointer to the configuration struct of @ref adc16_config_t.
190 * @return A result of initializing an ADC16 instance.
191 * @retval status_success Initialize an ADC16 instance successfully. Please refer to @ref hpm_stat_t.
192 * @retval status_invalid_argument Initialize an ADC16 instance unsuccessfully due to passing one or more invalid arguments. Please refer to @ref hpm_stat_t.
193 */
194 hpm_stat_t adc16_init(ADC16_Type *ptr, adc16_config_t *config);
195
196 /**
197 * @brief Initialize an ADC16 channel
198 *
199 * @param[in] ptr An ADC16 peripheral base address.
200 * @param[in] config A pointer to the configuration struct of @ref adc16_channel_config_t.
201 * @return A result of initializing an ADC16 channel.
202 * @retval status_success Initialize an ADC16 channel successfully. Please refert to @ref hpm_stat_t.
203 * @retval status_invalid_argument Initialize an ADC16 channel unsuccessfully due to passing one or more invalid arguments. Please refert to @ref hpm_stat_t.
204 */
205 hpm_stat_t adc16_init_channel(ADC16_Type *ptr, adc16_channel_config_t *config);
206
207 /**
208 * @brief Configure the the period mode for an ADC16 instance.
209 *
210 * @param[in] ptr An ADC16 peripheral base address.
211 * @param[in] config A pointer to the configuration struct of @ref adc16_prd_config_t.
212 * @return A result of configuring the the period mode for an ADC16 instance.
213 * @retval status_success Configure the the period mode successfully. Please refert to @ref hpm_stat_t.
214 * @retval status_invalid_argument Configure the the period mode unsuccessfully due to passing one or more invalid arguments. Please refert to @ref hpm_stat_t.
215 */
216 hpm_stat_t adc16_set_prd_config(ADC16_Type *ptr, adc16_prd_config_t *config);
217
218 /**
219 * @brief Configure the sequence mode for an ADC16 instance.
220 *
221 * @param[in] ptr An ADC16 peripheral base address.
222 * @param[in] config A pointer to configuration struct of @ref adc16_seq_config_t.
223 * @return A result of configuring the sequence mode for an ADC16 instance.
224 * @retval status_success Configure the sequence mode successfully. Please refert to @ref hpm_stat_t.
225 * @retval status_invalid_argument Configure the sequence mode unsuccessfully due to passing one or more invalid arguments. Please refert to @ref hpm_stat_t.
226 */
227 hpm_stat_t adc16_set_seq_config(ADC16_Type *ptr, adc16_seq_config_t *config);
228
229 /**
230 * @brief Configure the preemption mode for an ADC16 instance.
231 *
232 * @param[in] ptr An ADC16 peripheral base address.
233 * @param[in] config A pointer to configuration struct of @ref adc16_pmt_config_t.
234 * @return A result of configuring the preemption mode for an ADC16 instance.
235 * @retval status_success Configure the preemption mode successfully. Please refert to @ref hpm_stat_t.
236 * @retval status_invalid_argument Configure the preemption mode unsuccessfully due to passing one or more invalid arguments. Please refert to @ref hpm_stat_t.
237 */
238 hpm_stat_t adc16_set_pmt_config(ADC16_Type *ptr, adc16_pmt_config_t *config);
239
240 /**
241 * @brief Set the queue enable control.
242 *
243 * @param[in] ptr An ADC16 peripheral base address.
244 * @param[in] trig_ch An ADC16 peripheral trigger channel.
245 * @param[in] enable A enable control
246 * @retval status_success Get the result of an ADC16 conversion in oneshot mode successfully.
247 * @retval status_invalid_argument Get the result of an ADC16 conversion in oneshot mode unsuccessfully due to passing invalid arguments.
248 */
249 hpm_stat_t adc16_set_pmt_queue_enable(ADC16_Type *ptr, uint8_t trig_ch, bool enable);
250
251 /** @} */
252
253 /**
254 * @name DMA Control
255 * @{
256 */
257
258 /**
259 * @brief Configure the stop position offset in the specified memory of DMA write operation for the sequence mode.
260 *
261 * @param[in] ptr An ADC16 peripheral base address.
262 * @param[in] stop_pos A stop position offset.
263 */
adc16_set_seq_stop_pos(ADC16_Type * ptr,uint16_t stop_pos)264 static inline void adc16_set_seq_stop_pos(ADC16_Type *ptr, uint16_t stop_pos)
265 {
266 ptr->SEQ_DMA_CFG = (ptr->SEQ_DMA_CFG & ~ADC16_SEQ_DMA_CFG_STOP_POS_MASK)
267 | ADC16_SEQ_DMA_CFG_STOP_POS_SET(stop_pos);
268 }
269
270 /**
271 * @brief Configure the start address of DMA write operation for the preemption mode.
272 *
273 * @param[in] ptr An ADC16 peripheral base address.
274 * @param[in] addr A start address of DMA write operation.
275 */
adc16_init_pmt_dma(ADC16_Type * ptr,uint32_t addr)276 static inline void adc16_init_pmt_dma(ADC16_Type *ptr, uint32_t addr)
277 {
278 ptr->TRG_DMA_ADDR = addr & ADC16_TRG_DMA_ADDR_TRG_DMA_ADDR_MASK;
279 }
280
281 /**
282 * @brief Configure the start address of DMA write operation for the preemption mode.
283 *
284 * @param[in] ptr An ADC16 peripheral base address.
285 * @param[in] config A pointer to configuration struct of @ref adc16_dma_config_t.
286 */
287 void adc16_init_seq_dma(ADC16_Type *ptr, adc16_dma_config_t *config);
288
289 /** @} */
290
291 /**
292 * @name Status
293 * @{
294 */
295
296 /**
297 * @brief Get all ADC16 status flags.
298 *
299 * @param[in] ptr An ADC16 peripheral base address.
300 * @return A mask indicating all corresponding interrupt statuses.
301 * @retval A mask. Please refer to @ref adc16_irq_event_t.
302 */
adc16_get_status_flags(ADC16_Type * ptr)303 static inline uint32_t adc16_get_status_flags(ADC16_Type *ptr)
304 {
305 return ptr->INT_STS;
306 }
307
308 /**
309 * @brief Get the setting value of the WAIT_DIS bit.
310 *
311 * @param[in] ptr An ADC16 peripheral base address.
312 * @return Status that indicats whether the current setting of the WAIT_DIS bit in the BUF_RESULT register is disabled.
313 * @retval true It means that the WAIT_DIS bit is 1.
314 * @retval false It means that the WAIT_DIS bit is 0.
315 */
adc16_get_wait_dis_status(ADC16_Type * ptr)316 static inline bool adc16_get_wait_dis_status(ADC16_Type *ptr)
317 {
318 return ADC16_BUF_CFG0_WAIT_DIS_GET(ptr->BUF_CFG0);
319 }
320
321 /**
322 * @brief Get the status of a conversion validity.
323 *
324 * @param[in] ptr An ADC16 peripheral base address.
325 * @param[in] ch An ADC16 peripheral channel.
326 * @retval Status indicating the validity of the current conversion result.
327 *
328 * @note This function is only used when the WAIT_DIS bit in the BUF_RESULT register is 1.
329 */
adc16_get_conv_valid_status(ADC16_Type * ptr,uint8_t ch)330 static inline bool adc16_get_conv_valid_status(ADC16_Type *ptr, uint8_t ch)
331 {
332 return ADC16_BUS_RESULT_VALID_GET(ptr->BUS_RESULT[ch]);
333 }
334
335 /**
336 * @brief Clear the status flags.
337 *
338 *
339 * @param[in] ptr An ADC16 peripheral base address.
340 * @param[in] mask A mask that means the specified flags to be cleared. Please refer to @ref adc16_irq_event_t.
341 *
342 * @note Only the specified flags can be cleared by writing the INT_STS register.
343 */
adc16_clear_status_flags(ADC16_Type * ptr,uint32_t mask)344 static inline void adc16_clear_status_flags(ADC16_Type *ptr, uint32_t mask)
345 {
346 ptr->INT_STS |= mask;
347 }
348
349 /** @} */
350
351 /**
352 * @name Interrupts
353 * @{
354 */
355
356 /**
357 * @brief Enable interrupts.
358 *
359 * @param[in] ptr An ADC16 peripheral base address.
360 * @param[in] mask A mask indicating the specified ADC interrupt events. Please refer to @ref adc16_irq_event_t.
361 */
adc16_enable_interrupts(ADC16_Type * ptr,uint32_t mask)362 static inline void adc16_enable_interrupts(ADC16_Type *ptr, uint32_t mask)
363 {
364 ptr->INT_EN |= mask;
365 }
366
367 /**
368 * @brief Disable interrupts.
369 *
370 * @param[in] ptr An ADC16 peripheral base address.
371 * @param[in] mask A mask indicating the specified interrupt events. Please refer to @ref adc16_irq_event_t.
372 */
adc16_disable_interrupts(ADC16_Type * ptr,uint32_t mask)373 static inline void adc16_disable_interrupts(ADC16_Type *ptr, uint32_t mask)
374 {
375 ptr->INT_EN &= ~mask;
376 }
377
378 /** @} */
379
380 /**
381 * @name Trigger and Conversion
382 * @{
383 */
384
385 /**
386 * @brief Trigger ADC coversions by software
387 *
388 * @param[in] ptr An ADC16 peripheral base address.
389 */
390 void adc16_trigger_seq_by_sw(ADC16_Type *ptr);
391
392 /**
393 * @brief Get the result in oneshot mode.
394 *
395 * @param[in] ptr An ADC16 peripheral base address.
396 * @param[in] ch An ADC16 peripheral channel.
397 * @param[out] result A pointer to an ADC16 conversion result.
398 * @return An implementation result of getting an ADC16 conversion result in oneshot mode.
399 * @retval status_success Get the result of an ADC16 conversion in oneshot mode successfully. Please refert to @ref hpm_stat_t.
400 * @retval status_invalid_argument Get the result of an ADC16 conversion in oneshot mode unsuccessfully due to passing invalid arguments. Please refert to @ref hpm_stat_t.
401 */
402 hpm_stat_t adc16_get_oneshot_result(ADC16_Type *ptr, uint8_t ch, uint16_t *result);
403
404 /**
405 * @brief Get the result in the period mode.
406 *
407 * @param[in] ptr An ADC16 peripheral base address.
408 * @param[in] ch An ADC16 peripheral channel.
409 * @param[out] result A pointer to a specified ADC16 conversion result
410 * @return An implementation of getting an ADC16 conversion result in the period mode.
411 * @retval status_success Get the result of an ADC16 conversion in the period mode successfully. Please refert to @ref hpm_stat_t.
412 * @retval status_invalid_argument Get the result of an ADC16 conversion in the period mode unsuccessfully due to passing invalid arguments. Please refert to @ref hpm_stat_t.
413 */
414 hpm_stat_t adc16_get_prd_result(ADC16_Type *ptr, uint8_t ch, uint16_t *result);
415
416 /** @} */
417
418 #ifdef __cplusplus
419 }
420 #endif
421
422 /** @} */
423 #endif /* HPM_ADC16_DRV_H */