• 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_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 */