• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 HPMicro
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 #ifndef HPM_SMIX_DRV_H
9 #define HPM_SMIX_DRV_H
10 
11 #include "hpm_common.h"
12 #include "hpm_soc_feature.h"
13 #include "hpm_smix_regs.h"
14 #include <math.h>
15 
16 /**
17  * @brief SMIX driver APIs
18  * @defgroup smix_interface SMIX driver APIs
19  * @ingroup smix_interface
20  * @{
21  */
22 
23 typedef enum {
24     smix_dma_transfer_burst_1t = 0U,
25     smix_dma_transfer_burst_2t = 1U,
26     smix_dma_transfer_burst_4t = 2U,
27     smix_dma_transfer_burst_8t = 3U,
28     smix_dma_transfer_burst_16t = 4U,
29     smix_dma_transfer_burst_32t = 5U,
30     smix_dma_transfer_burst_64t = 6U,
31     smix_dma_transfer_burst_128t = 7U,
32 } smix_dma_transfer_burst_t;
33 
34 typedef enum {
35     smix_dma_transfer_byte = 0U,
36     smix_dma_transfer_half_word = 1U,
37     smix_dma_transfer_word = 2U,
38 } smix_dma_transfer_width_t;
39 
40 typedef enum {
41     smix_dma_address_increment = 0U,
42     smix_dma_address_decrement = 1U,
43     smix_dma_address_fixed = 2U
44 } smix_dma_address_control_t;
45 
46 typedef enum {
47     smix_dma_mode_normal = 0,
48     smix_dma_mode_handshake = 1,
49 } smix_dma_handshake_mode_t;
50 
51 typedef enum {
52     smix_dma_req_i2s0_rx = 6,
53     smix_dma_req_i2s0_tx = 7,
54     smix_dma_req_i2s1_rx = 8,
55     smix_dma_req_i2s1_tx = 9,
56     smix_dma_req_i2s2_rx = 10,
57     smix_dma_req_i2s2_tx = 11,
58     smix_dma_req_i2s3_rx = 12,
59     smix_dma_req_i2s3_tx = 13,
60 
61     smix_dma_req_mixer_src_ch0 = 16,
62     smix_dma_req_mixer_src_ch1 = 17,
63     smix_dma_req_mixer_src_ch2 = 18,
64     smix_dma_req_mixer_src_ch3 = 19,
65     smix_dma_req_mixer_src_ch4 = 20,
66     smix_dma_req_mixer_src_ch5 = 21,
67     smix_dma_req_mixer_src_ch6 = 22,
68     smix_dma_req_mixer_src_ch7 = 23,
69     smix_dma_req_mixer_src_ch8 = 24,
70     smix_dma_req_mixer_src_ch9 = 25,
71     smix_dma_req_mixer_src_ch10 = 26,
72     smix_dma_req_mixer_src_ch11 = 27,
73     smix_dma_req_mixer_src_ch12 = 28,
74     smix_dma_req_mixer_src_ch13 = 29,
75 
76     smix_dma_req_mixer_dst_ch0 = 30,
77     smix_dma_req_mixer_dst_ch1 = 31,
78 } smix_dma_req_t;
79 
80 
81 typedef enum {
82     smix_src_clk_i2s0_bclk = 0,
83     smix_src_clk_i2s0_fclk = 1,
84     smix_src_clk_i2s0_mclk = 2,
85     smix_src_clk_i2s1_bclk = 3,
86     smix_src_clk_i2s1_fclk = 4,
87     smix_src_clk_i2s1_mclk = 5,
88     smix_src_clk_i2s2_bclk = 6,
89     smix_src_clk_i2s2_fclk = 7,
90     smix_src_clk_i2s2_mclk = 8,
91     smix_src_clk_i2s3_bclk = 9,
92     smix_src_clk_i2s3_fclk = 10,
93     smix_src_clk_i2s3_mclk = 11,
94     smix_src_clk_none      = 15,
95 } smix_src_clk_source_t;
96 
97 
98 typedef struct {
99     uint32_t ctrl;              /**< Control */
100     uint32_t trans_size;        /**< Transfer size in source width */
101     uint32_t src_addr;          /**< Source address */
102     uint32_t reserved0;         /**< reserved */
103     uint32_t dst_addr;          /**< Destination address */
104     uint32_t reserved1;         /**< reserved */
105     uint32_t linked_ptr;        /**< Linked descriptor address */
106     uint32_t reserved2;         /**< resetved */
107 } smix_dma_linked_descriptor_t;
108 
109 
110 typedef struct {
111     uint8_t priority;               /**< Channel priority */
112     uint8_t src_burst_size;         /**< Source burst size */
113     uint8_t src_req_sel;
114     uint8_t dst_req_sel;
115     uint8_t src_mode;               /**< Source work mode */
116     uint8_t dst_mode;               /**< Destination work mode */
117     uint8_t src_width;              /**< Source width */
118     uint8_t dst_width;              /**< Destination width */
119     uint8_t src_addr_ctrl;          /**< Source address control */
120     uint8_t dst_addr_ctrl;          /**< Destination address control */
121     bool abort_int_en;              /**< enable abort interrupt */
122     bool error_int_en;              /**< enable error interrupt */
123     bool complete_int_en;           /**< enable complete interrupt */
124     uint32_t src_addr;              /**< Source address */
125     uint32_t dst_addr;              /**< Destination address */
126     uint32_t linked_ptr;            /**< Next linked descriptor */
127     uint32_t trans_bytes;           /**< Total size to be transferred in byte */
128 } smix_dma_ch_config_t;
129 
130 
131 typedef enum {
132     smix_mixer_gain_decrease_12db = 0x400,
133     smix_mixer_gain_decrease_6db = 0x800,
134     smix_mixer_gain_0db = 0xfff,
135     smix_mixer_gain_increase_6db = 0x1800,
136     smix_mixer_gain_increase_12db = 0x1fff,
137 } smix_mixer_gain_t;
138 
139 typedef enum {
140     smix_mixer_no_rate_convert,
141     smix_mixer_upper_2x_sample,
142     smix_mixer_upper_3x_sample,
143     smix_mixer_upper_4x_sample,
144     smix_mixer_upper_6x_sample,
145     smix_mixer_upper_8x_sample,
146     smix_mixer_upper_12x_sample,
147     smix_mixer_lower_2x_sample,
148 } smix_mixer_rate_convert_t;
149 
150 typedef struct {
151     bool underflow_int_en;
152     uint8_t fifo_thr;
153     bool calsat_int_en;
154     bool da_int_en;
155     bool auto_deactivate_en;
156     bool fadeout_done_int_en;
157     bool deactivate_en;
158     bool active_en;
159     bool fadeout_now_en;
160     bool fadeout_auto_en;
161     bool fadein_en;
162     bool channel_en;
163     bool mixer_en;
164 
165     uint16_t gain;
166     uint32_t length;
167     uint32_t fadein_delta;
168     uint32_t fadeout_delta;
169     uint8_t src_ch_mask;
170 } smix_mixer_dst_config_t;
171 
172 
173 typedef struct {
174     uint8_t fifo_thr;
175     bool calsat_int_en;
176     bool dn_int_en;
177     uint8_t fir_shift;
178     bool auto_deactivate_en;
179     bool fadeout_int_en;
180     uint8_t convert_rate;
181 
182     uint16_t gain;
183     uint32_t fadein_delta;
184     uint32_t fadeout_delta;
185     uint32_t length;
186 } smix_mixer_source_config_t;
187 
188 #ifdef __cplusplus
189 extern "C" {
190 #endif
191 
192 /**
193  * @brief smix dma check transfer complete status
194  *
195  * @param [in] ptr SMIX base address
196  * @param [in] ch_index dma channel
197  * @retval true for transfer complete
198  */
smix_dma_check_transfer_complete(SMIX_Type * ptr,uint8_t ch_index)199 static inline bool smix_dma_check_transfer_complete(SMIX_Type *ptr, uint8_t ch_index)
200 {
201     if ((SMIX_DMAC_TC_ST_CH_GET(ptr->DMAC_TC_ST) & (1U << ch_index)) != 0) {
202         ptr->DMAC_TC_ST = (1U << ch_index); /* W1C clear status*/
203         return true;
204     }
205     return false;
206 }
207 
208 /**
209  * @brief smix dma check transfer abort status
210  *
211  * @param [in] ptr SMIX base address
212  * @param [in] ch_index dma channel
213  * @retval true for transfer abort
214  */
smix_dma_check_transfer_abort(SMIX_Type * ptr,uint8_t ch_index)215 static inline bool smix_dma_check_transfer_abort(SMIX_Type *ptr, uint8_t ch_index)
216 {
217     if ((SMIX_DMAC_ABRT_ST_CH_GET(ptr->DMAC_ABRT_ST) & (1U << ch_index)) != 0) {
218         ptr->DMAC_ABRT_ST = (1U << ch_index); /* W1C clear status*/
219         return true;
220     }
221     return false;
222 }
223 
224 /**
225  * @brief smix dma check transfer error status
226  *
227  * @param [in] ptr SMIX base address
228  * @param [in] ch_index dma channel
229  * @retval true for transfer error
230  */
smix_dma_check_transfer_error(SMIX_Type * ptr,uint8_t ch_index)231 static inline bool smix_dma_check_transfer_error(SMIX_Type *ptr, uint8_t ch_index)
232 {
233     if ((SMIX_DMAC_ERR_ST_CH_GET(ptr->DMAC_ERR_ST) & (1U << ch_index)) != 0) {
234         ptr->DMAC_ERR_ST = (1U << ch_index); /* W1C clear status*/
235         return true;
236     }
237     return false;
238 }
239 
240 /**
241  * @brief smix mixer enable source channel for dst
242  *
243  * @param [in] ptr SMIX base address
244  * @param [in] dst_ch dst channel
245  * @param [in] source_ch_mask source channel mask
246  */
smix_mixer_dst_enable_source_channel(SMIX_Type * ptr,uint8_t dst_ch,uint32_t source_ch_mask)247 static inline void smix_mixer_dst_enable_source_channel(SMIX_Type *ptr, uint8_t dst_ch, uint32_t source_ch_mask)
248 {
249     ptr->DST_CH[dst_ch].SOURCE_EN |= source_ch_mask;
250 }
251 
252 /**
253  * @brief smix mixer disable source channel for dst
254  *
255  * @param [in] ptr SMIX base address
256  * @param [in] dst_ch dst channel
257  * @param [in] source_ch_mask source channel mask
258  */
smix_mixer_dst_disable_source_channel(SMIX_Type * ptr,uint8_t dst_ch,uint32_t source_ch_mask)259 static inline void smix_mixer_dst_disable_source_channel(SMIX_Type *ptr, uint8_t dst_ch, uint32_t source_ch_mask)
260 {
261     ptr->DST_CH[dst_ch].SOURCE_EN &= ~source_ch_mask;
262 }
263 
264 /**
265  * @brief smix mixer active source channel for dst
266  *
267  * @param [in] ptr SMIX base address
268  * @param [in] dst_ch dst channel
269  * @param [in] source_ch_mask source channel mask
270  */
smix_mixer_dst_active_source_channel(SMIX_Type * ptr,uint8_t dst_ch,uint32_t source_ch_mask)271 static inline void smix_mixer_dst_active_source_channel(SMIX_Type *ptr, uint8_t dst_ch, uint32_t source_ch_mask)
272 {
273     ptr->DST_CH[dst_ch].SOURCE_ACT |= source_ch_mask;
274 }
275 
276 /**
277  * @brief smix mixer deactive source channel for dst
278  *
279  * @param [in] ptr SMIX base address
280  * @param [in] dst_ch dst channel
281  * @param [in] source_ch_mask source channel mask
282  */
smix_mixer_dst_deactive_source_channel(SMIX_Type * ptr,uint8_t dst_ch,uint32_t source_ch_mask)283 static inline void smix_mixer_dst_deactive_source_channel(SMIX_Type *ptr, uint8_t dst_ch, uint32_t source_ch_mask)
284 {
285     ptr->DST_CH[dst_ch].SOURCE_DEACT |= source_ch_mask;
286 }
287 
288 /**
289  * @brief smix mixer fadein source channel for dst
290  *
291  * @param [in] ptr SMIX base address
292  * @param [in] dst_ch dst channel
293  * @param [in] source_ch_mask source channel mask
294  */
smix_mixer_dst_fadein_source_channel(SMIX_Type * ptr,uint8_t dst_ch,uint32_t source_ch_mask)295 static inline void smix_mixer_dst_fadein_source_channel(SMIX_Type *ptr, uint8_t dst_ch, uint32_t source_ch_mask)
296 {
297     ptr->DST_CH[dst_ch].SOURCE_FADEIN_CTRL |= source_ch_mask;
298 }
299 
300 /**
301  * @brief smix mixer fadeout source channel for dst
302  *
303  * @param [in] ptr SMIX base address
304  * @param [in] dst_ch dst channel
305  * @param [in] source_ch_mask source channel mask
306  */
smix_mixer_dst_fadeout_source_channel(SMIX_Type * ptr,uint8_t dst_ch,uint32_t source_ch_mask)307 static inline void smix_mixer_dst_fadeout_source_channel(SMIX_Type *ptr, uint8_t dst_ch, uint32_t source_ch_mask)
308 {
309     ptr->DST_CH[dst_ch].SOURCE_MFADEOUT_CTRL |= source_ch_mask;
310 }
311 
312 /**
313  * @brief smix mixer enable dst channel
314  *
315  * @param [in] ptr SMIX base address
316  *
317  * @note two dst channel share same enable bit in DST_CH[0].CTRL.MIXER_EN, DST_CH[1].CTRL.MIXER_EN should not be set
318  */
smix_mixer_dst_enable(SMIX_Type * ptr)319 static inline void smix_mixer_dst_enable(SMIX_Type *ptr)
320 {
321     ptr->DST_CH[0].CTRL |= SMIX_DST_CH_CTRL_DST_EN_MASK;
322     ptr->DST_CH[1].CTRL &= ~SMIX_DST_CH_CTRL_DST_EN_MASK;
323 }
324 
325 /**
326  * @brief smix mixer disable dst channel
327  *
328  * @param [in] ptr SMIX base address
329  *
330  * @note two dst channel share same enable bit in DST_CH[0].CTRL.MIXER_EN, DST_CH[1].CTRL.MIXER_EN should not be set
331  */
smix_mixer_dst_disable(SMIX_Type * ptr)332 static inline void smix_mixer_dst_disable(SMIX_Type *ptr)
333 {
334     ptr->DST_CH[0].CTRL &= ~SMIX_DST_CH_CTRL_DST_EN_MASK;
335 }
336 
337 /**
338  * @brief smix mixer get calculate saturation register value
339  *
340  * @param [in] ptr SMIX base address
341  * @retval calculate saturation register value
342  */
smix_mixer_get_calsat_status(SMIX_Type * ptr)343 static inline uint32_t smix_mixer_get_calsat_status(SMIX_Type *ptr)
344 {
345     return ptr->CALSAT_ST;
346 }
347 
348 /**
349  * @brief smix mixer check dst channel calculate saturation error
350  *
351  * @param [in] ptr SMIX base address
352  * @param [in] dst_ch dst channel
353  * @retval true for calculate saturation error occurred
354  */
smix_mixer_check_dst_cal_saturation_error(SMIX_Type * ptr,uint8_t dst_ch)355 static inline bool smix_mixer_check_dst_cal_saturation_error(SMIX_Type *ptr, uint8_t dst_ch)
356 {
357     return ((SMIX_CALSAT_ST_DST_GET(ptr->CALSAT_ST) & (1U << dst_ch)) != 0) ? true : false;
358 }
359 
360 /**
361  * @brief smix mixer check source channel calculate saturation error
362  *
363  * @param [in] ptr SMIX base address
364  * @param [in] source_ch source channel
365  * @retval true for calculate saturation error occurred
366  */
smix_mixer_check_source_cal_saturation_error(SMIX_Type * ptr,uint8_t source_ch)367 static inline bool smix_mixer_check_source_cal_saturation_error(SMIX_Type *ptr, uint8_t source_ch)
368 {
369     return ((SMIX_CALSAT_ST_SRC_GET(ptr->CALSAT_ST) & (1U << source_ch)) != 0) ? true : false;
370 }
371 
372 /**
373  * @brief smix mixer check dst channel data ubderflew
374  *
375  * @param [in] ptr SMIX base address
376  * @param [in] dst_ch dst channel
377  * @retval true for data underflew
378  */
smix_mixer_check_dst_data_underflew(SMIX_Type * ptr,uint8_t dst_ch)379 static inline bool smix_mixer_check_dst_data_underflew(SMIX_Type *ptr, uint8_t dst_ch)
380 {
381     return ((SMIX_DATA_ST_DST_UNDL_GET(ptr->DATA_ST) & (1U << dst_ch)) != 0) ? true : false;
382 }
383 
384 /**
385  * @brief smix mixer check dst channel data available
386  *
387  * @param [in] ptr SMIX base address
388  * @param [in] dst_ch dst channel
389  * @retval true for data available
390  */
smix_mixer_check_dst_data_available(SMIX_Type * ptr,uint8_t dst_ch)391 static inline bool smix_mixer_check_dst_data_available(SMIX_Type *ptr, uint8_t dst_ch)
392 {
393     return ((SMIX_DATA_ST_DST_DA_GET(ptr->DATA_ST) & (1U << dst_ch)) != 0) ? true : false;
394 }
395 
396 /**
397  * @brief smix mixer check source channel data available
398  *
399  * @param [in] ptr SMIX base address
400  * @param [in] source_ch source channel
401  * @retval true for source channel need new data
402  */
smix_mixer_check_source_data_needed(SMIX_Type * ptr,uint8_t source_ch)403 static inline bool smix_mixer_check_source_data_needed(SMIX_Type *ptr, uint8_t source_ch)
404 {
405     return ((SMIX_DATA_ST_SRC_DN_GET(ptr->DATA_ST) & (1U << source_ch)) != 0) ? true : false;
406 }
407 
408 /**
409  * @brief smix mixer config dst channel fadein delta
410  *
411  * @param [in] ptr SMIX base address
412  * @param [in] ch dst channel
413  * @param [in] target_sample_rate target sample rate
414  * @param [in] ms fadein consumed time in ms
415  * @retval status_success if no error occurs
416  */
417 hpm_stat_t smix_mixer_config_dst_fadein_delta(SMIX_Type *ptr, uint8_t ch, uint32_t target_sample_rate, uint32_t ms);
418 
419 /**
420  * @brief smix mixer config dst channel fadeout delta
421  *
422  * @param [in] ptr SMIX base address
423  * @param [in] ch dst channel
424  * @param [in] target_sample_rate target sample rate
425  * @param [in] ms fadeout consumed time in ms
426  * @retval status_success if no error occurs
427  */
428 hpm_stat_t smix_mixer_config_dst_fadeout_delta(SMIX_Type *ptr, uint8_t ch, uint32_t target_sample_rate, uint32_t ms);
429 
430 /**
431  * @brief smix mixer config source channel fadein delta
432  *
433  * @param [in] ptr SMIX base address
434  * @param [in] ch source channel
435  * @param [in] target_sample_rate target sample rate
436  * @param [in] ms fadein consumed time in ms
437  * @retval status_success if no error occurs
438  */
439 hpm_stat_t smix_mixer_config_source_fadein_delta(SMIX_Type *ptr, uint8_t ch, uint32_t target_sample_rate, uint32_t ms);
440 
441 /**
442  * @brief smix mixer config source channel fadeout delta
443  *
444  * @param [in] ptr SMIX base address
445  * @param [in] ch source channel
446  * @param [in] target_sample_rate target sample rate
447  * @param [in] ms fadeout consumed time in ms
448  * @retval status_success if no error occurs
449  */
450 hpm_stat_t smix_mixer_config_source_fadeout_delta(SMIX_Type *ptr, uint8_t ch, uint32_t target_sample_rate, uint32_t ms);
451 
452 /**
453  * @brief smix get dma channel default config
454  *
455  * @param [in] ptr SMIX base address
456  * @param [in] config smix_dma_ch_config_t
457  */
458 void smix_get_dma_default_ch_config(SMIX_Type *ptr, smix_dma_ch_config_t *config);
459 
460 /**
461  * @brief smix get dst channel default config
462  *
463  * @param [in] ptr SMIX base address
464  * @param [in] config smix_mixer_dst_config_t
465  */
466 void smix_get_mixer_dst_ch_default_config(SMIX_Type *ptr, smix_mixer_dst_config_t *config);
467 
468 /**
469  * @brief smix get source channel default config
470  *
471  * @param [in] ptr SMIX base address
472  * @param [in] config smix_mixer_source_config_t
473  */
474 void smix_get_mixer_source_ch_default_config(SMIX_Type *ptr, smix_mixer_source_config_t *config);
475 
476 /**
477  * @brief smix config dma channel
478  *
479  * @param [in] ptr SMIX base address
480  * @param [in] ch dma channel
481  * @param [in] config smix_dma_ch_config_t
482  * @param [in] start true for start dma
483  * @retval status_success if no error occurs
484  */
485 hpm_stat_t smix_config_dma_channel(SMIX_Type *ptr, uint8_t ch, smix_dma_ch_config_t *config, bool start);
486 
487 /**
488  * @brief smix mixer config source channel
489  *
490  * @param [in] ptr SMIX base address
491  * @param [in] ch source channel
492  * @param [in] src smix_mixer_source_config_t
493  * @retval status_success if no error occurs
494  */
495 hpm_stat_t smix_mixer_config_source_ch(SMIX_Type *ptr, uint8_t ch, smix_mixer_source_config_t *src);
496 
497 /**
498  * @brief smix mixer config dst channel
499  *
500  * @param [in] ptr SMIX base address
501  * @param [in] ch dst channel
502  * @param [in] src smix_mixer_dst_config_t
503  * @retval status_success if no error occurs
504  */
505 hpm_stat_t smix_mixer_config_dst_ch(SMIX_Type *ptr, uint8_t ch, smix_mixer_dst_config_t *dst);
506 
507 /**
508  * @}
509  */
510 
511 #ifdef __cplusplus
512 }
513 #endif
514 
515 #endif /* HPM_SMIX_DRV_H */
516