1 /*
2 * Copyright 2018-2022 NXP
3 * All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8 #include "fsl_powerquad.h"
9
10 /*******************************************************************************
11 * Definitions
12 ******************************************************************************/
13
14 /* Component ID definition, used by tools. */
15 #ifndef FSL_COMPONENT_ID
16 #define FSL_COMPONENT_ID "platform.drivers.powerquad_filter"
17 #endif
18
19 /*******************************************************************************
20 * Code
21 ******************************************************************************/
PQ_VectorBiquadDf2F32(float * pSrc,float * pDst,int32_t length)22 void PQ_VectorBiquadDf2F32(float *pSrc, float *pDst, int32_t length)
23 {
24 int32_t remainderBy8 = length % 8;
25 pq_float_t val;
26
27 if (remainderBy8 > 0)
28 {
29 length -= remainderBy8;
30 while ((remainderBy8--) > 0)
31 {
32 val.floatX = *pSrc++;
33 _pq_biquad0(val.integerX);
34 val.integerX = _pq_readAdd0();
35 *pDst++ = val.floatX;
36 }
37 }
38
39 if (length > 0)
40 {
41 PQ_StartVector(pSrc, pDst, length);
42 PQ_Vector8BiquadDf2F32();
43 PQ_EndVector();
44 }
45 }
46
PQ_VectorBiquadDf2Fixed32(int32_t * pSrc,int32_t * pDst,int32_t length)47 void PQ_VectorBiquadDf2Fixed32(int32_t *pSrc, int32_t *pDst, int32_t length)
48 {
49 int32_t remainderBy8 = length % 8;
50
51 if (remainderBy8 > 0)
52 {
53 length -= remainderBy8;
54 while ((remainderBy8--) > 0)
55 {
56 _pq_biquad0_fx(*pSrc++);
57 *pDst++ = (int32_t)_pq_readAdd0_fx();
58 }
59 }
60
61 if (length > 0)
62 {
63 PQ_StartVector(pSrc, pDst, length);
64 PQ_Vector8BiquadDf2Fixed32();
65 PQ_EndVector();
66 }
67 }
68
PQ_VectorBiquadDf2Fixed16(int16_t * pSrc,int16_t * pDst,int32_t length)69 void PQ_VectorBiquadDf2Fixed16(int16_t *pSrc, int16_t *pDst, int32_t length)
70 {
71 int32_t remainderBy8 = length % 8;
72
73 if (remainderBy8 > 0)
74 {
75 length -= remainderBy8;
76 while ((remainderBy8--) > 0)
77 {
78 _pq_biquad0_fx(*pSrc++);
79 *pDst++ = (int16_t)_pq_readAdd0_fx();
80 }
81 }
82
83 if (length > 0)
84 {
85 PQ_StartVectorFixed16(pSrc, pDst, length);
86 PQ_Vector8BiquadDf2Fixed16();
87 PQ_EndVector();
88 }
89 }
90
PQ_VectorBiquadCascadeDf2F32(float * pSrc,float * pDst,int32_t length)91 void PQ_VectorBiquadCascadeDf2F32(float *pSrc, float *pDst, int32_t length)
92 {
93 int32_t remainderBy8 = length % 8;
94 pq_float_t val;
95
96 if (remainderBy8 > 0)
97 {
98 length -= remainderBy8;
99
100 PQ_Biquad1F32(&pSrc[0], &pDst[0]);
101
102 for (int i = 1; i < remainderBy8; i++)
103 {
104 val.floatX = pSrc[i - 1];
105 _pq_biquad0(val.integerX);
106
107 val.floatX = pSrc[i];
108 _pq_biquad1(val.integerX);
109
110 val.integerX = _pq_readAdd0();
111 pDst[i - 1] = val.floatX;
112
113 val.integerX = _pq_readAdd1();
114 pDst[i] = val.floatX;
115 }
116
117 PQ_BiquadF32(&pSrc[remainderBy8 - 1], &pDst[remainderBy8 - 1]);
118 }
119
120 if (length > 0)
121 {
122 PQ_StartVector(&pSrc[remainderBy8], &pDst[remainderBy8], length);
123 PQ_Vector8BiquadDf2CascadeF32();
124 PQ_EndVector();
125 }
126 }
127
PQ_VectorBiquadCascadeDf2Fixed32(int32_t * pSrc,int32_t * pDst,int32_t length)128 void PQ_VectorBiquadCascadeDf2Fixed32(int32_t *pSrc, int32_t *pDst, int32_t length)
129 {
130 int32_t remainderBy8 = length % 8;
131
132 if (remainderBy8 > 0)
133 {
134 length -= remainderBy8;
135
136 _pq_biquad1_fx(pSrc[0]);
137 pDst[0] = (int32_t)_pq_readAdd1_fx();
138
139 for (int i = 1; i < remainderBy8; i++)
140 {
141 _pq_biquad0_fx(pSrc[i - 1]);
142 _pq_biquad1_fx(pSrc[i]);
143 pDst[i - 1] = (int32_t)_pq_readAdd0_fx();
144 pDst[i] = (int32_t)_pq_readAdd1_fx();
145 }
146
147 _pq_biquad0_fx(pSrc[remainderBy8 - 1]);
148 pDst[remainderBy8 - 1] = (int32_t)_pq_readAdd0_fx();
149 }
150
151 if (length > 0)
152 {
153 PQ_StartVector(&pSrc[remainderBy8], &pDst[remainderBy8], length);
154 PQ_Vector8BiquadDf2CascadeFixed32();
155 PQ_EndVector();
156 }
157 }
158
PQ_VectorBiquadCascadeDf2Fixed16(int16_t * pSrc,int16_t * pDst,int32_t length)159 void PQ_VectorBiquadCascadeDf2Fixed16(int16_t *pSrc, int16_t *pDst, int32_t length)
160 {
161 int32_t remainderBy8 = length % 8;
162
163 if (remainderBy8 > 0)
164 {
165 length -= remainderBy8;
166
167 _pq_biquad1_fx(pSrc[0]);
168 pDst[0] = (int16_t)_pq_readAdd1_fx();
169
170 for (int i = 1; i < remainderBy8; i++)
171 {
172 _pq_biquad0_fx(pSrc[i - 1]);
173 _pq_biquad1_fx(pSrc[i]);
174 pDst[i - 1] = (int16_t)_pq_readAdd0_fx();
175 pDst[i] = (int16_t)_pq_readAdd1_fx();
176 }
177
178 _pq_biquad0_fx(pSrc[remainderBy8 - 1]);
179 pDst[remainderBy8 - 1] = (int16_t)_pq_readAdd0_fx();
180 }
181
182 if (length > 0)
183 {
184 PQ_StartVectorFixed16(&pSrc[remainderBy8], &pDst[remainderBy8], length);
185 PQ_Vector8BiquadDf2CascadeFixed16();
186 PQ_EndVector();
187 }
188 }
189
PQ_BiquadBackUpInternalState(POWERQUAD_Type * base,int32_t biquad_num,pq_biquad_state_t * state)190 void PQ_BiquadBackUpInternalState(POWERQUAD_Type *base, int32_t biquad_num, pq_biquad_state_t *state)
191 {
192 pq_float_t v_n_1;
193 pq_float_t v_n;
194
195 #if defined(__GNUC__)
196 #pragma GCC diagnostic push
197 #pragma GCC diagnostic ignored "-Wstrict-aliasing"
198 #endif
199 if (0 == biquad_num)
200 {
201 v_n_1.integerX = base->GPREG[0];
202 v_n.integerX = base->GPREG[1];
203
204 state->param.v_n_1 = v_n_1.floatX;
205 state->param.v_n = v_n.floatX;
206 state->compreg = base->COMPREG[1];
207 }
208 else
209 {
210 v_n_1.integerX = base->GPREG[8];
211 v_n.integerX = base->GPREG[9];
212
213 state->param.v_n_1 = v_n_1.floatX;
214 state->param.v_n = v_n.floatX;
215 state->compreg = base->COMPREG[3];
216 }
217 #if defined(__GNUC__)
218 #pragma GCC diagnostic pop
219 #endif
220 }
221
PQ_BiquadRestoreInternalState(POWERQUAD_Type * base,int32_t biquad_num,pq_biquad_state_t * state)222 void PQ_BiquadRestoreInternalState(POWERQUAD_Type *base, int32_t biquad_num, pq_biquad_state_t *state)
223 {
224 pq_float_t v_n_1;
225 pq_float_t v_n;
226 pq_float_t a_1;
227 pq_float_t a_2;
228 pq_float_t b_0;
229 pq_float_t b_1;
230 pq_float_t b_2;
231
232 if (0 == biquad_num)
233 {
234 v_n_1.floatX = state->param.v_n_1;
235 v_n.floatX = state->param.v_n;
236 a_1.floatX = state->param.a_1;
237 a_2.floatX = state->param.a_2;
238 b_0.floatX = state->param.b_0;
239 b_1.floatX = state->param.b_1;
240 b_2.floatX = state->param.b_2;
241
242 base->GPREG[0] = v_n_1.integerX;
243 base->GPREG[1] = v_n.integerX;
244 base->GPREG[2] = a_1.integerX;
245 base->GPREG[3] = a_2.integerX;
246 base->GPREG[4] = b_0.integerX;
247 base->GPREG[5] = b_1.integerX;
248 base->GPREG[6] = b_2.integerX;
249 base->COMPREG[1] = state->compreg;
250 }
251 else
252 {
253 v_n_1.floatX = state->param.v_n_1;
254 v_n.floatX = state->param.v_n;
255 a_1.floatX = state->param.a_1;
256 a_2.floatX = state->param.a_2;
257 b_0.floatX = state->param.b_0;
258 b_1.floatX = state->param.b_1;
259 b_2.floatX = state->param.b_2;
260
261 base->GPREG[8] = v_n_1.integerX;
262 base->GPREG[9] = v_n.integerX;
263 base->GPREG[10] = a_1.integerX;
264 base->GPREG[11] = a_2.integerX;
265 base->GPREG[12] = b_0.integerX;
266 base->GPREG[13] = b_1.integerX;
267 base->GPREG[14] = b_2.integerX;
268 base->COMPREG[3] = state->compreg;
269 }
270 }
271
PQ_FIR(POWERQUAD_Type * base,const void * pAData,int32_t ALength,const void * pBData,int32_t BLength,void * pResult,uint32_t opType)272 void PQ_FIR(POWERQUAD_Type *base,
273 const void *pAData,
274 int32_t ALength,
275 const void *pBData,
276 int32_t BLength,
277 void *pResult,
278 uint32_t opType)
279 {
280 assert(NULL != pAData);
281 assert(NULL != pBData);
282 assert(NULL != pResult);
283
284 base->INABASE = (uint32_t)(const uint32_t *)pAData;
285 base->INBBASE = (uint32_t)(const uint32_t *)pBData;
286 base->LENGTH = ((uint32_t)BLength << 16U) + (uint32_t)ALength;
287 base->OUTBASE = (uint32_t)(uint32_t *)pResult;
288 base->CONTROL = (CP_FIR << 4U) | opType;
289 }
290
PQ_FIRIncrement(POWERQUAD_Type * base,int32_t ALength,int32_t BLength,int32_t xOffset)291 void PQ_FIRIncrement(POWERQUAD_Type *base, int32_t ALength, int32_t BLength, int32_t xOffset)
292 {
293 base->MISC = (uint32_t)xOffset;
294 base->LENGTH = ((uint32_t)BLength << 16U) + (uint32_t)ALength;
295 base->CONTROL = (CP_FIR << 4U) | PQ_FIR_INCREMENTAL;
296 }
297
PQ_BiquadCascadeDf2Init(pq_biquad_cascade_df2_instance * S,uint8_t numStages,pq_biquad_state_t * pState)298 void PQ_BiquadCascadeDf2Init(pq_biquad_cascade_df2_instance *S, uint8_t numStages, pq_biquad_state_t *pState)
299 {
300 S->numStages = numStages;
301 S->pState = pState;
302 }
303
PQ_BiquadCascadeDf2F32(const pq_biquad_cascade_df2_instance * S,float * pSrc,float * pDst,uint32_t blockSize)304 void PQ_BiquadCascadeDf2F32(const pq_biquad_cascade_df2_instance *S, float *pSrc, float *pDst, uint32_t blockSize)
305 {
306 uint32_t stage = S->numStages;
307 pq_biquad_state_t *states = S->pState;
308
309 if (pDst != pSrc)
310 {
311 (void)memcpy(pDst, pSrc, 4U * blockSize);
312 }
313
314 if ((stage & 0x01U) == 0x01U)
315 {
316 PQ_BiquadRestoreInternalState(POWERQUAD, 0, states);
317
318 PQ_VectorBiquadDf2F32(pSrc, pDst, (int32_t)blockSize);
319
320 PQ_BiquadBackUpInternalState(POWERQUAD, 0, states);
321
322 states++;
323 stage--;
324 }
325
326 while (stage > 0U)
327 {
328 PQ_BiquadRestoreInternalState(POWERQUAD, 1, states);
329 states++;
330 PQ_BiquadRestoreInternalState(POWERQUAD, 0, states);
331
332 PQ_VectorBiquadCascadeDf2F32(pDst, pDst, (int32_t)blockSize);
333
334 states--;
335 PQ_BiquadBackUpInternalState(POWERQUAD, 1, states);
336 states++;
337 PQ_BiquadBackUpInternalState(POWERQUAD, 0, states);
338
339 states++;
340 stage -= 2U;
341 }
342 }
343
PQ_BiquadCascadeDf2Fixed32(const pq_biquad_cascade_df2_instance * S,int32_t * pSrc,int32_t * pDst,uint32_t blockSize)344 void PQ_BiquadCascadeDf2Fixed32(const pq_biquad_cascade_df2_instance *S,
345 int32_t *pSrc,
346 int32_t *pDst,
347 uint32_t blockSize)
348 {
349 uint32_t stage = S->numStages;
350 pq_biquad_state_t *states = S->pState;
351
352 if (pDst != pSrc)
353 {
354 (void)memcpy(pDst, pSrc, 4U * blockSize);
355 }
356
357 if ((stage & 0x01U) == 0x01U)
358 {
359 PQ_BiquadRestoreInternalState(POWERQUAD, 0, states);
360
361 PQ_VectorBiquadDf2Fixed32(pSrc, pDst, (int32_t)blockSize);
362
363 PQ_BiquadBackUpInternalState(POWERQUAD, 0, states);
364
365 states++;
366 stage--;
367 }
368
369 while (stage > 0U)
370 {
371 PQ_BiquadRestoreInternalState(POWERQUAD, 0, states);
372 states++;
373 PQ_BiquadRestoreInternalState(POWERQUAD, 1, states);
374
375 PQ_VectorBiquadCascadeDf2Fixed32(pDst, pDst, (int32_t)blockSize);
376
377 states--;
378 PQ_BiquadBackUpInternalState(POWERQUAD, 0, states);
379 states++;
380 PQ_BiquadBackUpInternalState(POWERQUAD, 1, states);
381
382 states++;
383 stage -= 2U;
384 }
385 }
386
PQ_BiquadCascadeDf2Fixed16(const pq_biquad_cascade_df2_instance * S,int16_t * pSrc,int16_t * pDst,uint32_t blockSize)387 void PQ_BiquadCascadeDf2Fixed16(const pq_biquad_cascade_df2_instance *S,
388 int16_t *pSrc,
389 int16_t *pDst,
390 uint32_t blockSize)
391 {
392 uint32_t stage = S->numStages;
393 pq_biquad_state_t *states = S->pState;
394
395 if (pDst != pSrc)
396 {
397 (void)memcpy(pDst, pSrc, 2U * blockSize);
398 }
399
400 if ((stage & 0x01U) == 0x01U)
401 {
402 PQ_BiquadRestoreInternalState(POWERQUAD, 0, states);
403
404 PQ_VectorBiquadDf2Fixed16(pSrc, pDst, (int32_t)blockSize);
405
406 PQ_BiquadBackUpInternalState(POWERQUAD, 0, states);
407
408 states++;
409 stage--;
410 }
411
412 while (stage > 0U)
413 {
414 PQ_BiquadRestoreInternalState(POWERQUAD, 0, states);
415 states++;
416 PQ_BiquadRestoreInternalState(POWERQUAD, 1, states);
417
418 PQ_VectorBiquadCascadeDf2Fixed16(pDst, pDst, (int32_t)blockSize);
419
420 states--;
421 PQ_BiquadBackUpInternalState(POWERQUAD, 0, states);
422 states++;
423 PQ_BiquadBackUpInternalState(POWERQUAD, 1, states);
424
425 states++;
426 stage -= 2U;
427 }
428 }
429