1 /*
2 * Copyright (c) 2016, Texas Instruments Incorporated
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * * Neither the name of Texas Instruments Incorporated nor the names of
17 * its contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 */
33 \r
34 /*=================================================================\r
35 * sys.c: Basic system functions.\r
36 *=================================================================*/\r
37 \r
38 #include <string.h>\r
39 \r
40 #include <xdc/std.h>\r
41 #include <ti/sysbios/BIOS.h>\r
42 #include <xdc/runtime/System.h>\r
43 \r
44 #include <types.h>\r
45 #include <ti/mas/util/ecomem.h>\r
46 //#include <ti/mas/mhm/mhm.h>\r
47 \r
48 #include "mhm/mhm.h"\r
49 \r
50 #include "sys.h"\r
51 #include "syseram.h"\r
52 #include "sysiram.h"\r
53 #include "sysbfflt.h"\r
54 \r
55 /* Globals */\r
56 \r
57 /* Buffer descriptor array for memory allocations */\r
58 ecomemBuffer_t sysCompBufs[SYS_COMP_MAXBUFS];\r
59 \r
60 /* Input sample buffer (dual) (align=8) */\r
61 #pragma DATA_ALIGN(sysInBuf,8)\r
62 tword sysInBuf[SYS_IN_SIZE];\r
63 \r
64 /* Virtual microphone frame outputs (align=8)*/\r
65 #pragma DATA_ALIGN(sysVmicFrame,8)\r
66 linSample sysVmicFrame[SYS_VMICS_MAX*SYS_FRAME_LENGTH];\r
67 \r
68 /* Virtual microphone angles to be used (default is all 12, every 30 degrees) */\r
69 tint sysBfVMicAngles[SYS_VMICS_MAX] = {\r
70 SYS_BF_ANGLE_P0,\r
71 SYS_BF_ANGLE_P30,\r
72 SYS_BF_ANGLE_P60,\r
73 SYS_BF_ANGLE_P90,\r
74 SYS_BF_ANGLE_P120,\r
75 SYS_BF_ANGLE_P150,\r
76 SYS_BF_ANGLE_P180,\r
77 SYS_BF_ANGLE_M150,\r
78 SYS_BF_ANGLE_M120,\r
79 SYS_BF_ANGLE_M90,\r
80 SYS_BF_ANGLE_M60,\r
81 SYS_BF_ANGLE_M30\r
82 };\r
83 \r
84 sysContext_t sysContext; /* Global System Context structure */\r
85 \r
86 #define max(a,b) (((a)>(b))?(a):(b))\r
87 \r
88 /*=============================\r
89 * Functions\r
90 *=============================*/\r
91 \r
92 /*=================================================================\r
93 * int sysAngleConfig( Configure default virtual microphones\r
94 * tint nvmics) - Number of virtual mics to configure\r
95 * \r
96 * This function accespts only 4,6,8,12 virtual microphones.\r
97 * If different number is used, manual configuration must be done\r
98 * with potentially providing different microphone filters for the array.\r
99 *=================================================================*/\r
100 \r
101 int sysAngleConfig(tint nvmics)\r
102 {\r
103 int err;\r
104 \r
105 err = SYS_ERR_SUCCESS;\r
106 nvmics = sysContext.nvmics;\r
107 switch (nvmics) {\r
108 case 4:\r
109 sysBfVMicAngles[0] = SYS_BF_ANGLE_P0;\r
110 sysBfVMicAngles[1] = SYS_BF_ANGLE_P90;\r
111 sysBfVMicAngles[2] = SYS_BF_ANGLE_P180;\r
112 sysBfVMicAngles[3] = SYS_BF_ANGLE_M90;\r
113 break;\r
114 case 6:\r
115 sysBfVMicAngles[0] = SYS_BF_ANGLE_P0;\r
116 sysBfVMicAngles[1] = SYS_BF_ANGLE_P60;\r
117 sysBfVMicAngles[2] = SYS_BF_ANGLE_P120;\r
118 sysBfVMicAngles[3] = SYS_BF_ANGLE_P180;\r
119 sysBfVMicAngles[4] = SYS_BF_ANGLE_M120;\r
120 sysBfVMicAngles[5] = SYS_BF_ANGLE_M60;\r
121 break;\r
122 case 8:\r
123 sysBfVMicAngles[0] = SYS_BF_ANGLE_P0;\r
124 sysBfVMicAngles[1] = SYS_BF_ANGLE_P45;\r
125 sysBfVMicAngles[2] = SYS_BF_ANGLE_P90;\r
126 sysBfVMicAngles[3] = SYS_BF_ANGLE_P135;\r
127 sysBfVMicAngles[4] = SYS_BF_ANGLE_P180;\r
128 sysBfVMicAngles[5] = SYS_BF_ANGLE_M135;\r
129 sysBfVMicAngles[6] = SYS_BF_ANGLE_M90;\r
130 sysBfVMicAngles[7] = SYS_BF_ANGLE_M45;\r
131 break;\r
132 case 12:\r
133 sysBfVMicAngles[0] = SYS_BF_ANGLE_P0;\r
134 sysBfVMicAngles[1] = SYS_BF_ANGLE_P30;\r
135 sysBfVMicAngles[2] = SYS_BF_ANGLE_P60;\r
136 sysBfVMicAngles[3] = SYS_BF_ANGLE_P90;\r
137 sysBfVMicAngles[4] = SYS_BF_ANGLE_P120;\r
138 sysBfVMicAngles[5] = SYS_BF_ANGLE_P150;\r
139 sysBfVMicAngles[6] = SYS_BF_ANGLE_P180;\r
140 sysBfVMicAngles[7] = SYS_BF_ANGLE_M150;\r
141 sysBfVMicAngles[8] = SYS_BF_ANGLE_M120;\r
142 sysBfVMicAngles[9] = SYS_BF_ANGLE_M90;\r
143 sysBfVMicAngles[10] = SYS_BF_ANGLE_M60;\r
144 sysBfVMicAngles[11] = SYS_BF_ANGLE_M30;\r
145 break;\r
146 default:\r
147 err = SYS_ERR_ANGLECONFIG;\r
148 break;\r
149 }\r
150 return(err);\r
151 } /* sysAngleConfig */\r
152 \r
153 /*=================================================================\r
154 * int sysCreate(\r
155 * sysConfig_t cfg); - System configuration (see sys.h)\r
156 *=================================================================*/\r
157 \r
158 int sysCreate(sysConfig_t *cfg)\r
159 {\r
160 int k, err, nvmics;\r
161 void *heap_p;\r
162 linSample *x_p;\r
163 \r
164 if (cfg->nmics < 1 || cfg->nmics > SYS_MICS_MAX ||\r
165 cfg->nvmics < 1 || cfg->nvmics > SYS_VMICS_MAX) {\r
166 return(SYS_ERR_BADCONFIG);\r
167 }\r
168 sysContext.nmics = cfg->nmics; /* Store # of mics used */\r
169 nvmics = sysContext.nvmics = cfg->nvmics; /* Store # of virtual mics used */\r
170 sysContext.use_fileio = cfg->use_fileio; /* probably FALSE since slow */\r
171 sysContext.eof = FALSE; /* no EOF reached yet */\r
172 sysContext.use_default = cfg->use_default; /* TRUE for default vmic angles */\r
173 for (k = 0; k < 3; k++) {\r
174 sysContext.asnr_attn[k] = cfg->asnr_attn[k];\r
175 }\r
176 sysContext.asnr_delay = cfg->asnr_delay;\r
177 sysContext.asnr_enable = cfg->asnr_enable;\r
178 sysContext.vad_enable = cfg->vad_enable;\r
179 sysContext.drc_exp_knee = cfg->drc_exp_knee;\r
180 sysContext.drc_max_amp = cfg->drc_max_amp;\r
181 sysContext.drc_enable = cfg->drc_enable;\r
182 \r
183 /* Initialize input buffer pointers and read portion */\r
184 sysContext.in_lo = &sysInBuf[0]; /* Input buffer start (Low part) */\r
185 sysContext.in_hi = &sysInBuf[SYS_IN_SIZE/2]; /* High part of input buffer */\r
186 sysContext.in_w = sysContext.in_lo; /* Write pointer */\r
187 sysContext.in_r = sysContext.in_hi; /* Read pointer */\r
188 memset(sysContext.in_r, 0xBA, SYS_IN_SIZE/2); /* Initialize the read portion */\r
189 \r
190 /* Clear instance pointers */\r
191 for (k = 0; k < SYS_VMICS_MAX; k++) {\r
192 sysContext.bfInst_p[k] = sysContext.asnrInst_p[k] = NULL;\r
193 }\r
194 sysContext.mssInst_p = sysContext.vauInst_p = NULL;\r
195 \r
196 /* Initialize virtual microphone frame pointers */\r
197 \r
198 /* First check to see if default configurations are used */\r
199 if (sysContext.use_default) {\r
200 err = sysAngleConfig(nvmics);\r
201 if (err != SYS_ERR_SUCCESS) {\r
202 return(err);\r
203 }\r
204 }\r
205 x_p = &sysVmicFrame[0];\r
206 for (k = 0; k < nvmics; k++) {\r
207 sysContext.vmicfrm[k] = &x_p[k*SYS_FRAME_LENGTH];\r
208 sysContext.vmicangles[k] = sysBfVMicAngles[k];\r
209 }\r
210 for ( ; k < SYS_VMICS_MAX; k++) {\r
211 sysContext.vmicfrm[k] = (linSample*)NULL;\r
212 sysContext.vmicangles[k] = 0;\r
213 }\r
214 \r
215 /* Create heaps */\r
216 heap_p = mhmCreate(sysEramPermanent,SYS_ERAM_PERMANENT_SIZE,0);\r
217 if (heap_p == NULL) {\r
218 return(SYS_ERR_HEAPINIT);\r
219 }\r
220 sysContext.heapEP = heap_p;\r
221 \r
222 heap_p = mhmCreate(sysEramScratch,SYS_ERAM_SCRATCH_SIZE,0);\r
223 if (heap_p == NULL) {\r
224 return(SYS_ERR_HEAPINIT);\r
225 }\r
226 sysContext.heapES = heap_p;\r
227 \r
228 heap_p = mhmCreate(sysIramPermanent,SYS_IRAM_PERMANENT_SIZE,0);\r
229 if (heap_p == NULL) {\r
230 return(SYS_ERR_HEAPINIT);\r
231 }\r
232 sysContext.heapIP = heap_p;\r
233 \r
234 heap_p = mhmCreate(sysIramScratch,SYS_IRAM_SCRATCH_SIZE,0);\r
235 if (heap_p == NULL) {\r
236 return(SYS_ERR_HEAPINIT);\r
237 }\r
238 sysContext.heapIS = heap_p;\r
239 \r
240 return(SYS_ERR_SUCCESS);\r
241 } /* sysCreate */\r
242 \r
243 /*=================================================================\r
244 * void sysError( Print error and exit\r
245 * int err); - System errror code (see sys.h)\r
246 *=================================================================*/\r
247 \r
248 void sysError(int err)\r
249 {\r
250 System_printf("*** ERROR: %d\n", err);\r
251 BIOS_exit(0);\r
252 } /* sysError */\r
253 \r
254 /*=================================================================\r
255 * int sysHeapAlloc( Allocate buffer from appropriate heap\r
256 * void *bd, - buffer descriptor\r
257 * tint reset) - 1: reset heap, 0: don't\r
258 *=================================================================*/\r
259 \r
260 int sysHeapAlloc(void *bd_in, tint reset)\r
261 {\r
262 int err = SYS_ERR_SUCCESS;\r
263 tuint size;\r
264 void *handle;\r
265 tword *base_w;\r
266 tulong *used_p;\r
267 \r
268 ecomemBuffer_t *bd_p = (ecomemBuffer_t*) bd_in;\r
269 \r
270 if (bd_p->mclass == ecomem_CLASS_EXTERNAL) {\r
271 if (bd_p->volat) {\r
272 handle = sysContext.heapES;\r
273 used_p = &sysContext.heapES_used;\r
274 }\r
275 else { /* permanent */\r
276 handle = sysContext.heapEP;\r
277 used_p = &sysContext.heapEP_used;\r
278 }\r
279 }\r
280 else if (bd_p->mclass == ecomem_CLASS_INTERNAL) {\r
281 if (bd_p->volat) {\r
282 handle = sysContext.heapIS;\r
283 used_p = &sysContext.heapIS_used;\r
284 }\r
285 else { /* permanent */\r
286 handle = sysContext.heapIP;\r
287 used_p = &sysContext.heapIP_used;\r
288 }\r
289 }\r
290 else {\r
291 return(SYS_ERR_INVHEAPCLASS);\r
292 }\r
293 \r
294 if (reset != 0) {\r
295 mhmReset(handle); /* optionally reset the heap */\r
296 *used_p = 0; /* reset used size to zero */\r
297 }\r
298 size = bd_p->size;\r
299 base_w = (tword*)mhmAllocAligned(handle, size, bd_p->log2align);\r
300 *used_p += size; /* update the used size */\r
301 \r
302 bd_p->base = base_w; /* store the bsae address for a buffer */\r
303 \r
304 if (base_w == NULL) {\r
305 err = SYS_ERR_NOMEMORY;\r
306 }\r
307 return(err);\r
308 } /* sysHeapAlloc */\r
309 \r
310 /*=================================================================\r
311 * int sysHeapAllocAll( Allocate ALL buffers from appropriate heaps\r
312 * tint nbufs, - number of buffers\r
313 * void *bdout, - output buffer descriptors\r
314 * void *bdin) - input buffer descriptors\r
315 *=================================================================*/\r
316 \r
317 int sysHeapAllocAll(tint nbufs, void *bdout_p, const void *bdin_p)\r
318 {\r
319 int err;\r
320 tint k, volatile_found;\r
321 tulong es_used, is_used; /* place to save scratch used sizes */\r
322 ecomemBuffer_t *bdout = bdout_p;\r
323 const ecomemBuffer_t *bdin = bdin_p;\r
324 \r
325 es_used = sysContext.heapES_used; /* save in case scratch was reset */\r
326 is_used = sysContext.heapIS_used;\r
327 \r
328 /* Allocate memory for all buffers */\r
329 volatile_found = FALSE;\r
330 for (k = 0; k < nbufs; k++) {\r
331 bdout[k] = bdin[k];\r
332 if (bdout[k].volat && !volatile_found) { /* first volatile? */\r
333 err=sysHeapAlloc(&bdout[k], TRUE); /* reset heap for the first volatile buffer */\r
334 if (err < 0) {\r
335 return(err);\r
336 }\r
337 volatile_found = TRUE;\r
338 }\r
339 else { /* no need to reset heap */\r
340 err=sysHeapAlloc(&bdout[k], FALSE);\r
341 if (err < 0) {\r
342 return(err);\r
343 }\r
344 }\r
345 }\r
346 \r
347 /* fix the scratch heap used sizes if necessary */\r
348 sysContext.heapES_used = max(es_used,sysContext.heapES_used);\r
349 sysContext.heapIS_used = max(is_used,sysContext.heapIS_used);\r
350 \r
351 return(SYS_ERR_SUCCESS);\r
352 } /* sysHeapAllocAll */\r
353 \r
354 /*==================================================*/\r
355 /* The following was based on MHM implementation!!! */\r
356 /*==================================================*/\r
357 \r
358 /* Heap header that is placed at the beginning of a memory pool. */\r
359 typedef struct {\r
360 tuint total_size; /* total number of words in a memory pool */\r
361 tuint used_size; /* index of the first available word */\r
362 } sysMhmHead_t;\r
363 typedef tulong sysMhmAddress_t;\r
364 \r
365 /*=================================================================\r
366 * int sysPrintConfig(\r
367 * tuint scope); - SYSM_SCOPE_STATIC: Static configuration like default constants\r
368 * SYSM_SCOPE_DYNAMIC: Dynamic configuraiton like actual run-time values \r
369 *=================================================================*/\r
370 \r
371 int sysPrintConfig(tuint scope)\r
372 {\r
373 if (SYS_MASK_TEST(scope,SYSM_SCOPE_STATIC)) {\r
374 System_printf("\nStatic information:\n");\r
375 System_printf("tword: %d\n", sizeof(tword));\r
376 System_printf("tint: %d\n", sizeof(tint));\r
377 System_printf("tlong: %d\n", sizeof(tlong));\r
378 System_printf("Max #mics: %d\n", SYS_MICS_MAX);\r
379 System_printf("Max #vmics: %d\n", SYS_VMICS_MAX);\r
380 System_printf("Fs: %d [Hz]\n", SYS_FS_HZ);\r
381 System_printf("Frame duration: %d [ms]\n", SYS_FRAME_DURATION_MS);\r
382 System_printf("Frame length: %ld samples\n", SYS_FRAME_LENGTH);\r
383 System_printf("Frame size: %ld bytes\n", SYS_FRAME_SIZE);\r
384 System_printf("Input buffer length: %ld samples\n", SYS_IN_LENGTH);\r
385 System_printf("Frame buffer size: %ld bytes\n", SYS_IN_SIZE);\r
386 }\r
387 if (SYS_MASK_TEST(scope,SYSM_SCOPE_DYNAMIC)) {\r
388 System_printf("\nDynamic information:\n");\r
389 System_printf("#mics: %d\n", sysContext.nmics);\r
390 System_printf("#vmics: %d\n", sysContext.nvmics);\r
391 }\r
392 return(SYS_ERR_SUCCESS);\r
393 } /* sysPrintConfig */\r
394 \r
395 /* nothing past this point */\r
396 \r