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