• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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(PTR, CH) ((CH > ADC12_SOC_MAX_CH_NUM && CH != ADC12_SOC_TEMP_CH_NUM) || \
27                                            ((uint32_t)PTR == ADC12_SOC_INVALID_TEMP_BASE && CH == ADC12_SOC_TEMP_CH_NUM))
28 
29 /** @brief Define ADC12 validity check for the trigger number */
30 #define ADC12_IS_TRIG_CH_INVLAID(CH) (CH > ADC12_SOC_MAX_TRIG_CH_NUM)
31 
32 /** @brief Define ADC12 validity check for the trigger length */
33 #define ADC12_IS_TRIG_LEN_INVLAID(TRIG_LEN) (TRIG_LEN > ADC_SOC_MAX_TRIG_CH_LEN)
34 
35 /** @brief Define ADC12 validity check for the sequence length */
36 #define ADC12_IS_SEQ_LEN_INVLAID(LEN)  ((LEN == 0) || (LEN > ADC_SOC_SEQ_MAX_LEN))
37 
38 /** @brief Define ADC12 validity check for the DMA buffer length in the sequence mode */
39 #define ADC12_IS_SEQ_DMA_BUFF_LEN_INVLAID(LEN)  ((LEN == 0) || (LEN > ADC_SOC_SEQ_MAX_DMA_BUFF_LEN_IN_4BYTES))
40 
41 /** @brief Define ADC12 validity check for the DMA buffer length in the preemption mode */
42 #define ADC12_IS_PMT_DMA_BUFF_LEN_INVLAID(LEN)  ((LEN == 0) || (LEN > ADC_SOC_PMT_MAX_DMA_BUFF_LEN_IN_4BYTES))
43 
44 /** @brief Define ADC12 sample signal types. */
45 typedef enum {
46     adc12_sample_signal_single_ended = 0,
47     adc12_sample_signal_differential = 1,
48     adc12_sample_signal_count = 2
49 } adc12_sample_signal_t;
50 
51 /** @brief Define ADC12 resolutions. */
52 typedef enum {
53     adc12_res_6_bits = 0,
54     adc12_res_8_bits,
55     adc12_res_10_bits,
56     adc12_res_12_bits
57 } adc12_resolution_t;
58 
59 /** @brief Define ADC12 conversion modes. */
60 typedef enum {
61     adc12_conv_mode_oneshot = 0,
62     adc12_conv_mode_period,
63     adc12_conv_mode_sequence,
64     adc12_conv_mode_preemption
65 } adc12_conversion_mode_t;
66 
67 /** @brief  Define ADC12 irq events. */
68 typedef enum {
69     /** This mask indicates that a trigger conversion is complete. */
70     adc12_event_trig_complete       = ADC12_INT_STS_TRIG_CMPT_MASK,
71 
72     /** This mask indicates that a conflict caused by software-triggered conversions. */
73     adc12_event_trig_sw_conflict    = ADC12_INT_STS_TRIG_SW_CFLCT_MASK,
74 
75     /** This mask indicates that a conflict caused by hardware-triggered conversions. */
76     adc12_event_trig_hw_conflict    = ADC12_INT_STS_TRIG_HW_CFLCT_MASK,
77 
78     /** This mask indicates that a conflict caused when bus reading from different channels. */
79     adc12_event_read_conflict       = ADC12_INT_STS_READ_CFLCT_MASK,
80 
81     /** This mask indicates that a conflict caused by sequence-triggered conversions. */
82     adc12_event_seq_sw_conflict     = ADC12_INT_STS_SEQ_SW_CFLCT_MASK,
83 
84     /** This mask indicates that a conflict caused by hardware-triggered conversions. */
85     adc12_event_seq_hw_conflict     = ADC12_INT_STS_SEQ_HW_CFLCT_MASK,
86 
87     /** This mask indicates that DMA is stopped currently. */
88     adc12_event_seq_dma_abort       = ADC12_INT_STS_SEQ_DMAABT_MASK,
89 
90     /** This mask indicates that all of the configured conversion(s) in a queue is(are) complete. */
91     adc12_event_seq_full_complete   = ADC12_INT_STS_SEQ_CMPT_MASK,
92 
93     /** This mask indicates that one of the configured conversion(s) in a queue is complete. */
94     adc12_event_seq_single_complete = ADC12_INT_STS_SEQ_CVC_MASK,
95 
96     /** This mask indicates that DMA FIFO is full currently. */
97     adc12_event_dma_fifo_full       = ADC12_INT_STS_DMA_FIFO_FULL_MASK
98 } adc12_irq_event_t;
99 
100 /** @brief ADC12 common configuration struct. */
101 typedef struct {
102     uint8_t res;
103     uint8_t conv_mode;
104     uint8_t wait_dis;
105     uint32_t adc_clk_div;
106     bool sel_sync_ahb;
107     bool adc_ahb_en;
108 } adc12_config_t;
109 
110 /** @brief ADC12 channel configuration struct. */
111 typedef struct {
112    uint8_t ch;
113    uint8_t diff_sel;
114    uint16_t thshdh;
115    uint16_t thshdl;
116    uint8_t sample_cycle_shift;
117    uint32_t sample_cycle;
118 } adc12_channel_config_t;
119 
120 /** @brief ADC12 DMA configuration struct. */
121 typedef struct {
122     uint32_t *start_addr;
123     uint32_t buff_len_in_4bytes;
124     uint32_t stop_pos;
125     bool stop_en;
126 } adc12_dma_config_t;
127 
128 /** @brief ADC12 DMA configuration struct for the sequence mode. */
129 typedef struct {
130     uint32_t           :4;
131     uint32_t result    :12;
132     uint32_t seq_num   :4;
133     uint32_t           :4;
134     uint32_t adc_ch    :5;
135     uint32_t           :2;
136     uint32_t cycle_bit :1;
137 } adc12_seq_dma_data_t;
138 
139 /** @brief ADC12 DMA configuration struct for the preemption mode. */
140 typedef struct {
141     uint32_t            :4;
142     uint32_t result     :12;
143     uint32_t trig_ch    :2;
144     uint32_t            :2;
145     uint32_t trig_index :4;
146     uint32_t adc_ch     :5;
147     uint32_t            :2;
148     uint32_t cycle_bit  :1;
149 } adc12_pmt_dma_data_t;
150 
151 /** @brief ADC12 configuration struct for the period mode. */
152 typedef struct {
153     uint32_t clk_src_freq_in_hz;
154     uint8_t ch;
155     uint8_t prescale;
156     uint8_t period_count;
157 } adc12_prd_config_t;
158 
159 /** @brief ADC12 queue configuration struct for the sequence mode. */
160 typedef struct {
161     bool seq_int_en;
162     uint8_t ch;
163 } adc12_seq_queue_config_t;
164 
165 /** @brief ADC12 configuration struct for the sequence mode. */
166 typedef struct {
167     adc12_seq_queue_config_t queue[ADC_SOC_SEQ_MAX_LEN];
168     bool restart_en;
169     bool cont_en;
170     bool sw_trig_en;
171     bool hw_trig_en;
172     uint8_t seq_len;
173 } adc12_seq_config_t;
174 
175 /** @brief ADC12 trigger configuration struct for the preemption mode. */
176 typedef struct {
177     bool    inten[ADC_SOC_MAX_TRIG_CH_LEN];
178     uint8_t adc_ch[ADC_SOC_MAX_TRIG_CH_LEN];
179     uint8_t trig_ch;
180     uint8_t trig_len;
181 } adc12_pmt_config_t;
182 
183 #ifdef __cplusplus
184 extern "C" {
185 #endif
186 /**
187  * @name Initialization and Deinitialization
188  * @{
189  */
190 
191 /**
192  * @brief Get a default configuration for an ADC12 instance.
193  *
194  * @param[out] config A pointer to the configuration struct of @ref adc12_config_t.
195  */
196 void adc12_get_default_config(adc12_config_t *config);
197 
198 /**
199  * @brief Get a default configuration for an ADC12 channel.
200  *
201  * @param[out] config A pointer to the configuration struct of @ref adc12_channel_config_t.
202  */
203 void adc12_get_channel_default_config(adc12_channel_config_t *config);
204 
205 /**
206  * @brief Initialize an ADC12 instance.
207  *
208  * @param[in] ptr An ADC12 peripheral base address.
209  * @param[in] config A pointer to the configuration struct of @ref adc12_config_t.
210  * @return A result of initializing an ADC12 instance.
211  * @retval status_success Initialize an ADC12 instance successfully. Please refer to @ref hpm_stat_t.
212  * @retval status_invalid_argument Initialize an ADC12 instance unsuccessfully due to passing one or more invalid arguments. Please refert to @ref hpm_stat_t.
213  */
214 hpm_stat_t adc12_init(ADC12_Type *ptr, adc12_config_t *config);
215 
216 /**
217  * @brief Initialize an ADC12 channel.
218  *
219  * @param[in] ptr An ADC12 peripheral base address.
220  * @param[in] config A pointer to the configuration struct of @ref adc12_channel_config_t.
221  * @return A result of initializing an ADC12 channel.
222  * @retval status_success Initialize an ADC12 channel successfully. Please refert to @ref hpm_stat_t.
223  * @retval status_invalid_argument Initialize an ADC12 channel unsuccessfully due to passing one or more invalid arguments. Please refert to @ref hpm_stat_t.
224  */
225 hpm_stat_t adc12_init_channel(ADC12_Type *ptr, adc12_channel_config_t *config);
226 
227 /**
228  * @brief Configure the the period mode for an ADC12 instance.
229  *
230  * @param[in] ptr An ADC12 peripheral base address.
231  * @param[in] config A pointer to the configuration struct of @ref adc12_prd_config_t.
232  * @return A result of configuring the the period mode for an ADC12 instance.
233  * @retval status_success Configure the the period mode successfully. Please refert to @ref hpm_stat_t.
234  * @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.
235  */
236 hpm_stat_t adc12_set_prd_config(ADC12_Type *ptr, adc12_prd_config_t *config);
237 
238 /**
239  * @brief Configure the the sequence mode for an ADC12 instance.
240  *
241  * @param[in] ptr An ADC12 peripheral base address.
242  * @param[in] config A pointer to configuration struct of @ref adc12_seq_config_t.
243  * @return A result of configuring the the sequence mode for an ADC12 instance.
244  * @retval status_success Configure the the sequence mode successfully. Please refert to @ref hpm_stat_t.
245  * @retval status_invalid_argument Configure the the sequence mode unsuccessfully due to passing one or more invalid arguments. Please refert to @ref hpm_stat_t.
246  */
247 hpm_stat_t adc12_set_seq_config(ADC12_Type *ptr, adc12_seq_config_t *config);
248 
249 /**
250  * @brief Configure the preemption mode for an ADC12 instance.
251  *
252  * @param[in] ptr An ADC12 peripheral base address.
253  * @param[in] config A pointer to configuration struct of @ref adc12_pmt_config_t.
254  * @return A result of configuring the preemption mode for an ADC12 instance.
255  * @retval status_success Configure the preemption mode successfully. Please refert to @ref hpm_stat_t.
256  * @retval status_invalid_argument Configure the preemption mode unsuccessfully due to passing one or more invalid arguments. Please refert to @ref hpm_stat_t.
257  */
258 hpm_stat_t adc12_set_pmt_config(ADC12_Type *ptr, adc12_pmt_config_t *config);
259 
260 /** @} */
261 
262 /**
263  * @name DMA Control
264  * @{
265  */
266 
267 /**
268  * @brief Configure the stop position offset in the specified memory of DMA write operation for the the sequence mode.
269  *
270  * @param[in] ptr An ADC12 peripheral base address.
271  * @param[in] stop_pos A stop position offset.
272  */
adc12_set_seq_stop_pos(ADC12_Type * ptr,uint16_t stop_pos)273 static inline void adc12_set_seq_stop_pos(ADC12_Type *ptr, uint16_t stop_pos)
274 {
275     ptr->SEQ_DMA_CFG = (ptr->SEQ_DMA_CFG & ~ADC12_SEQ_DMA_CFG_STOP_POS_MASK)
276                      | ADC12_SEQ_DMA_CFG_STOP_POS_SET(stop_pos);
277 }
278 
279 /**
280  * @brief Configure the start address of DMA write operation for the preemption mode.
281  *
282  * @param[in] ptr An ADC12 peripheral base address.
283  * @param[in] addr A start address of DMA write operation.
284  */
adc12_init_pmt_dma(ADC12_Type * ptr,uint32_t addr)285 static inline void adc12_init_pmt_dma(ADC12_Type *ptr, uint32_t addr)
286 {
287     ptr->TRG_DMA_ADDR = addr & ADC12_TRG_DMA_ADDR_TRG_DMA_ADDR_MASK;
288 }
289 
290 /**
291  * @brief Configure the start address of DMA write operation for the preemption mode.
292  *
293  * @param[in] ptr An ADC12 peripheral base address.
294  * @param[in] config A pointer to configuration struct of @ref adc12_dma_config_t.
295  * @return An implementation result of DMA initializing for the sequence mode
296  * @retval status_success Get the result of an ADC12 conversion in oneshot mode successfully. Please refert to @ref hpm_stat_t.
297  * @retval status_invalid_argument Get the result of an ADC12 conversion in oneshot mode unsuccessfully due to passing invalid arguments. Please refert to @ref hpm_stat_t.
298  */
299 hpm_stat_t adc12_init_seq_dma(ADC12_Type *ptr, adc12_dma_config_t *config);
300 
301 /** @} */
302 
303 /**
304  * @name Status
305  * @{
306  */
307 
308 /**
309  * @brief Get all ADC12 status flags.
310  *
311  * @param[in] ptr An ADC12 peripheral base address.
312  * @return A mask indicating all corresponding interrupt statuses.
313  * @retval A mask. Please refer to @ref adc12_irq_event_t.
314  */
adc12_get_status_flags(ADC12_Type * ptr)315 static inline uint32_t adc12_get_status_flags(ADC12_Type *ptr)
316 {
317     return ptr->INT_STS;
318 }
319 
320 /**
321  * @brief Get the setting value of the WAIT_DIS bit.
322  *
323  * @param[in] ptr An ADC12 peripheral base address.
324  * @return Status that indicats whether the current setting of the WAIT_DIS bit in the BUF_RESULT register is disabled.
325  * @retval true  It means that the WAIT_DIS bit is 1.
326  * @retval false It means that the WAIT_DIS bit is 0.
327  */
adc12_get_wait_dis_status(ADC12_Type * ptr)328 static inline bool adc12_get_wait_dis_status(ADC12_Type *ptr)
329 {
330     return ADC12_BUF_CFG0_WAIT_DIS_GET(ptr->BUF_CFG0);
331 }
332 
333 /**
334  * @brief Get the status of a conversion validity.
335  *
336  * @param[in] ptr An ADC12 peripheral base address.
337  * @param[in] ch An ADC12 peripheral channel.
338  * @retval Status indicating the validity of the current conversion result.
339  *
340  * @note This function is only used when the WAIT_DIS bit in the BUF_RESULT register is 1.
341  */
adc12_get_conv_valid_status(ADC12_Type * ptr,uint8_t ch)342 static inline bool adc12_get_conv_valid_status(ADC12_Type *ptr, uint8_t ch)
343 {
344     return ADC12_BUS_RESULT_VALID_GET(ptr->BUS_RESULT[ch]);
345 }
346 
347 /**
348  * @brief Clear the status flags.
349  *
350  *
351  * @param[in] ptr An ADC12 peripheral base address.
352  * @param[in] mask A mask that means the specified flags to be cleared. Please refer to @ref adc12_irq_event_t.
353  *
354  * @note Only the specified flags can be cleared by writing the INT_STS register.
355  */
adc12_clear_status_flags(ADC12_Type * ptr,uint32_t mask)356 static inline void adc12_clear_status_flags(ADC12_Type *ptr, uint32_t mask)
357 {
358     ptr->INT_STS |= mask;
359 }
360 
361 /** @} */
362 
363 /**
364  * @name Interrupts
365  * @{
366  */
367 
368 /**
369  * @brief Enable interrupts.
370  *
371  * @param[in] ptr An ADC12 peripheral base address.
372  * @param[in] mask A mask indicating the specified ADC interrupt events. Please refer to @ref adc12_irq_event_t.
373  */
adc12_enable_interrupts(ADC12_Type * ptr,uint32_t mask)374 static inline void adc12_enable_interrupts(ADC12_Type *ptr, uint32_t mask)
375 {
376     ptr->INT_EN |= mask;
377 }
378 
379 /**
380  * @brief Disable interrupts.
381  *
382  * @param[in] ptr An ADC12 peripheral base address.
383  * @param[in] mask A mask indicating the specified interrupt events. Please refer to @ref adc12_irq_event_t.
384  */
adc12_disable_interrupts(ADC12_Type * ptr,uint32_t mask)385 static inline void adc12_disable_interrupts(ADC12_Type *ptr, uint32_t mask)
386 {
387     ptr->INT_EN &= ~mask;
388 }
389 
390 /** @} */
391 
392 /**
393  * @name Trigger and Conversion
394  * @{
395  */
396 
397 /**
398  * @brief Trigger ADC coversions by software
399  *
400  * @param[in] ptr An ADC12 peripheral base address.
401  */
402 void adc12_trigger_seq_by_sw(ADC12_Type *ptr);
403 
404 /**
405  * @brief Get the result in oneshot mode.
406  *
407  * @param[in] ptr An ADC12 peripheral base address.
408  * @param[in] ch An ADC12 peripheral channel.
409  * @param[out] result A pointer to an ADC12 conversion result.
410  * @return An implementation result of getting an ADC12 conversion result in oneshot mode.
411  * @retval status_success Get the result of an ADC12 conversion in oneshot mode successfully. Please refert to @ref hpm_stat_t.
412  * @retval status_invalid_argument Get the result of an ADC12 conversion in oneshot mode unsuccessfully due to passing invalid arguments. Please refert to @ref hpm_stat_t.
413  */
414 hpm_stat_t adc12_get_oneshot_result(ADC12_Type *ptr, uint8_t ch, uint16_t *result);
415 
416 /**
417  * @brief Get the result in the period mode.
418  *
419  * @param[in] ptr An ADC12 peripheral base address.
420  * @param[in] ch An ADC12 peripheral channel.
421  * @param[out] result A pointer to a specified ADC12 conversion result
422  * @return An implementation of getting an ADC12 conversion result in the period mode.
423  * @retval status_success Get the result of an ADC12 conversion in the period mode successfully. Please refert to @ref hpm_stat_t.
424  * @retval status_invalid_argument Get the result of an ADC12 conversion in the period mode unsuccessfully due to passing invalid arguments. Please refert to @ref hpm_stat_t.
425  */
426 hpm_stat_t adc12_get_prd_result(ADC12_Type *ptr, uint8_t ch, uint16_t *result);
427 
428 /** @} */
429 
430 #ifdef __cplusplus
431 }
432 #endif
433 
434 /** @} */
435 #endif /* HPM_ADC12_DRV_H */
436