1 /*
2  * Copyright (c) 2022 HPMicro
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 #ifndef HPM_FFA_DRV_H
8 #define HPM_FFA_DRV_H
9 
10 #include "hpm_common.h"
11 #include "hpm_ffa_regs.h"
12 #include "hpm_soc_ip_feature.h"
13 
14 /**
15  * @brief FFA driver APIs
16  * @defgroup ffa_interface FFA driver APIs
17  * @ingroup ffa_interfaces
18  * @{
19  *
20  */
21 
22 /***********************************************************************************************************************
23  *
24  * Definitions
25  *
26  **********************************************************************************************************************/
27 /**
28  * @brief Operation commands supported by FFA
29  */
30 #define FFA_OPCMD_FIR (0U)      /* !< FIR operation command index */
31 #define FFA_OPCMD_FFT (2U)      /* !< FFT operation command index */
32 
33 /**
34  * @brief Data type supported by FFA
35  */
36 #define FFA_DATA_TYPE_REAL_Q31      (0U)    /* !< FFA Data type:  Real Q31 */
37 #define FFA_DATA_TYPE_REAL_Q15      (1U)    /* !< FFA Data type: Real Q15 */
38 #define FFA_DATA_TYPE_COMPLEX_Q31   (2U)    /* !< FFA Data type: Complex Q31 */
39 #define FFA_DATA_TYPE_COMPLEX_Q15   (3U)    /* !< FFA Data type: Complex Q15 */
40 #if defined(HPM_IP_FEATURE_FFA_FP32) && HPM_IP_FEATURE_FFA_FP32
41 #define FFA_DATA_TYPE_COMPLEX_FP32  (4U)    /* !< FFA Data type: Complex Q15 */
42 #define FFA_DATA_TYPE_REAL_FP32     (5U)    /* !< FFA Data type: Complex Q15 */
43 #endif
44 
45 /**
46  * @brief FFA Q31 data type definition
47  */
48 typedef int32_t ffa_q31_t;
49 
50 /**
51  * @brief FFA Q15 data type definition
52  */
53 typedef int16_t ffa_q15_t;
54 
55 /**
56  * @brief FFA complex Q31 data type definition
57  */
58 typedef struct {
59     ffa_q31_t real;
60     ffa_q31_t image;
61 } ffa_complex_q31_t;
62 
63 /**
64  * @brief FFA complex Q15 data type definition
65  */
66 typedef struct {
67     ffa_q15_t real;
68     ffa_q15_t image;
69 } ffa_complex_q15_t;
70 
71 /**
72  * @brief FFT transform context
73  */
74 typedef struct {
75     uint16_t is_ifft;           /* !< Is Inverse FFT transform */
76     uint8_t src_data_type;      /* !< Source data type */
77     uint8_t dst_data_type;      /* !< Destination date type */
78     uint32_t num_points;        /* !< Number of points */
79     const void *src;            /* !< Source data buffer */
80     void *dst;                  /* !< Destination Data buffer */
81     uint32_t interrupt_mask;    /* !< Interrupt mask */
82 } fft_xfer_t;
83 
84 /**
85  * @brief FIR transform context
86  */
87 typedef struct {
88     uint16_t data_type;         /* !< Data type */
89     uint16_t coef_taps;         /* !< Coefficient taps */
90     uint32_t input_taps;        /* !< Input data taps */
91     const void *src;            /* !< Source data buffer */
92     const void *coeff;          /* !< Coefficient data buffer */
93     void *dst;                  /* !< Destination data buffer */
94     uint32_t interrupt_mask;    /* !< Interrupt mask */
95 } fir_xfer_t;
96 
97 /**
98  * @brief FFA error codes
99  */
100 enum {
101     status_ffa_fir_overflow = MAKE_STATUS(status_group_ffa, 0),         /* !< FIR overflow */
102     status_ffa_fft_overflow = MAKE_STATUS(status_group_ffa, 1),         /* !< FFR overflow */
103     status_ffa_write_error = MAKE_STATUS(status_group_ffa, 2),          /* !< FFA write error */
104     status_ffa_read_next_error = MAKE_STATUS(status_group_ffa, 3),      /* !< FFA read next data error */
105     status_ffa_read_error = MAKE_STATUS(status_group_ffa, 4),           /*!< FFA read error */
106 };
107 
108 #if defined(HPM_IP_FEATURE_FFA_FP32) && HPM_IP_FEATURE_FFA_FP32
109 typedef enum {
110     input_data = 0,
111     output_data = 1,
112     coeff_data = 2
113 } ffa_fp32_status_source_t;
114 #endif
115 
116 #ifdef __cplusplus
117 extern "C" {
118 #endif
119 
120 /**
121  * @brief Enable FFA module and start an specified FFA operation
122  *
123  * @param [in] ptr FFA base address
124  */
ffa_enable(FFA_Type * ptr)125 static inline void ffa_enable(FFA_Type *ptr)
126 {
127     ptr->CTRL = (ptr->CTRL & ~FFA_CTRL_SFTRST_MASK) | FFA_CTRL_EN_MASK;
128 }
129 
130 /**
131  * @brief Stop FFA module
132  *
133  * @param [in] ptr FFA base address
134  */
ffa_disable(FFA_Type * ptr)135 static inline void ffa_disable(FFA_Type *ptr)
136 {
137     ptr->CTRL = (ptr->CTRL & ~FFA_CTRL_EN_MASK) | FFA_CTRL_SFTRST_MASK;
138 }
139 
140 /**
141  * @brief Get FFA status
142  *
143  * @param [in] ptr FFA base address
144  * @return FFA status register value
145  */
ffa_get_status(FFA_Type * ptr)146 static inline uint32_t ffa_get_status(FFA_Type *ptr)
147 {
148     return ptr->STATUS;
149 }
150 
151 /**
152  * @brief Enable FFA Interrupt
153  *
154  * @param [in] ptr FFA base address
155  * @param [in] mask FFA interrupt mask
156  */
ffa_enable_interrupt(FFA_Type * ptr,uint32_t mask)157 static inline void ffa_enable_interrupt(FFA_Type *ptr, uint32_t mask)
158 {
159     ptr->INT_EN |= mask;
160 }
161 
162 /**
163  * @brief Disable FFA interrupt
164  *
165  * @param [in] ptr FFA base address
166  * @param [in] mask FFA interrupt mask
167  */
ffa_disable_interrupt(FFA_Type * ptr,uint32_t mask)168 static inline void ffa_disable_interrupt(FFA_Type *ptr, uint32_t mask)
169 {
170     ptr->INT_EN &= ~mask;
171 }
172 
173 #if defined(HPM_IP_FEATURE_FFA_FP32) && HPM_IP_FEATURE_FFA_FP32
174 
ffa_enable_fp32_interrupt(FFA_Type * ptr,uint32_t mask)175 static inline void ffa_enable_fp32_interrupt(FFA_Type *ptr, uint32_t mask)
176 {
177     ptr->FP_CTRL |= mask;
178 }
179 
ffa_disable_fp32_interrupt(FFA_Type * ptr,uint32_t mask)180 static inline void ffa_disable_fp32_interrupt(FFA_Type *ptr, uint32_t mask)
181 {
182     ptr->FP_CTRL &= ~mask;
183 }
184 
ffa_set_fp_status_source(FFA_Type * ptr,ffa_fp32_status_source_t source)185 static inline void ffa_set_fp_status_source(FFA_Type *ptr, ffa_fp32_status_source_t source)
186 {
187     ptr->FP_CTRL = FFA_FP_CTRL_EXP_ST_SEL_SET(source);
188 }
189 
ffa_enable_fp_bias(FFA_Type * ptr)190 static inline void ffa_enable_fp_bias(FFA_Type *ptr)
191 {
192     ptr->FP_CTRL |= FFA_FP_CTRL_OPT_BIAS_EXP_MASK;
193 }
194 
ffa_disable_fp_bias(FFA_Type * ptr)195 static inline void ffa_disable_fp_bias(FFA_Type *ptr)
196 {
197     ptr->FP_CTRL &= ~FFA_FP_CTRL_OPT_BIAS_EXP_MASK;
198 }
199 
ffa_set_coef_max_index(FFA_Type * ptr,uint8_t max)200 static inline void ffa_set_coef_max_index(FFA_Type *ptr, uint8_t max)
201 {
202     ptr->FP_CTRL = (ptr->FP_CTRL & ~FFA_FP_CTRL_COEF_MAX_MASK) | FFA_FP_CTRL_COEF_MAX_SET(max);
203 }
204 
ffa_set_output_max_index(FFA_Type * ptr,uint8_t max)205 static inline void ffa_set_output_max_index(FFA_Type *ptr, uint8_t max)
206 {
207     ptr->FP_CTRL = (ptr->FP_CTRL & ~FFA_FP_CTRL_OUT_MAX_MASK) | FFA_FP_CTRL_OUT_MAX_SET(max);
208 }
209 
ffa_set_input_max_index(FFA_Type * ptr,uint8_t max)210 static inline void ffa_set_input_max_index(FFA_Type *ptr, uint8_t max)
211 {
212     ptr->FP_CTRL = (ptr->FP_CTRL & ~FFA_FP_CTRL_IN_MAX_MASK) | FFA_FP_CTRL_IN_MAX_SET(max);
213 }
214 
ffa_get_fp_status(FFA_Type * ptr)215 static inline uint32_t ffa_get_fp_status(FFA_Type *ptr)
216 {
217     return ptr->FP_ST;
218 }
219 
220 #endif
221 
222 /**
223  * @brief Start an FFT operation
224  *
225  * @param [in] ptr FFA base address
226  * @param [in] fft_xfer FFT transform context
227  */
228 void ffa_start_fft(FFA_Type *ptr, fft_xfer_t *fft_xfer);
229 
230 /**
231  * @brief Start an FIR operation
232  *
233  * @param [in] ptr FFA base address
234  * @param [in] fir_xfer FIR transform context
235  */
236 void ffa_start_fir(FFA_Type *ptr, fir_xfer_t *fir_xfer);
237 
238 /**
239  * @brief Perform FFT transformation in blocking mode
240  *
241  * @param [in] ptr FFA base address
242  * @param [in, out] fft_xfer FFT transform context
243  * @return FFT operation result
244  */
245 hpm_stat_t ffa_calculate_fft_blocking(FFA_Type *ptr, fft_xfer_t *fft_xfer);
246 
247 /**
248  * @brief Perform FIR transform in blocking mode
249  *
250  * @param [in] ptr FFA base address
251  * @param [in, out] fir_xfer FIR transform context
252  * @return FIR operation result
253  */
254 hpm_stat_t ffa_calculate_fir_blocking(FFA_Type *ptr, fir_xfer_t *fir_xfer);
255 
256 
257 #ifdef __cplusplus
258 }
259 #endif
260 /**
261  * @}
262  *
263  */
264 
265 
266 #endif /* HPM_FFA_DRV_H */
267