PASDK-258:Merge remote-tracking branch 'origin/dev_pasdk_frank_pasdk258Alpha4Release'
[processor-sdk/performance-audio-sr.git] / psdk_cust / libarch_k2g_1_0_1_0 / examples / dsponly / test_app_dsp.c
1 /******************************************************************************
2  * Copyright (c) 2015-2017, Texas Instruments Incorporated - http://www.ti.com
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 are met:
7  *       * Redistributions of source code must retain the above copyright
8  *         notice, this list of conditions and the following disclaimer.
9  *       * Redistributions in binary form must reproduce the above copyright
10  *         notice, this list of conditions and the following disclaimer in the
11  *         documentation and/or other materials provided with the distribution.
12  *       * Neither the name of Texas Instruments Incorporated nor the
13  *         names of its contributors may be used to endorse or promote products
14  *         derived from this software without specific prior written permission.
15  *
16  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  *   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  *   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  *   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20  *   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  *   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  *   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  *   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  *   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  *   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
26  *   THE POSSIBILITY OF SUCH DAMAGE.
27  *****************************************************************************/
28 /*==============================================================================
29   This file shows an example of using libarch in TI RTOS environment. 
30 ===============================================================================*/ 
31 #include <string.h>
32 #include <stdio.h>
33 #include <math.h>
34 #include <time.h>
35 #include <stdlib.h>
36 #include <assert.h>
37 #include <stdint.h>
38 #include <ti/libarch/libarch.h>
39 #include "../common/test_dsp_kernel.h"
40 #include <ti/sdo/edma3/drv/edma3_drv.h>
41 #include <ti/sdo/edma3/drv/sample/bios6_edma3_drv_sample.h>
43 #define TEST_MEM_NOERR 0
44 #define TEST_MEM_ERROR 1
45 #define NUM_MAX_LINKED_TRANSER 1
47 #define TEST_DATA_SIZE (1024)        //1K data points
48 #ifdef SOC_C6678
49 #include "omp.h"
50 #define L2_SCRATCH_SIZE    (20*1024UL)
51 #define MSMC_SCRATCH_SIZE  (2*1024*1024UL)   //2M Bytes
52 #define DDR_SCRATCH_SIZE   (10*1024*1024UL)  //10M Bytes
53 #define USE_OPENMP
54 #endif
56 #ifdef SOC_K2H
57 #include "omp.h"
58 #define L2_SCRATCH_SIZE    (512*1024UL)
59 #define MSMC_SCRATCH_SIZE  (4608*1024UL)   //4.5M Bytes
60 #define DDR_SCRATCH_SIZE   (10240*1024UL)  //10M Bytes
61 #define USE_OPENMP
62 #endif
64 #ifdef SOC_K2G
65 #define L2_SCRATCH_SIZE    (20*1024UL)
66 #define MSMC_SCRATCH_SIZE  (128*1024UL)   //128K Bytes
67 #define DDR_SCRATCH_SIZE   (1024*1024UL)  //1M Bytes
68 #endif
70 #ifdef SOC_K2G
71 #define LIB_NUM_EDMA3_INSTANCES 2      /**< Number of EDMA3 instances */
72 #endif
75 #pragma DATA_SECTION(l2_scratch_buf, ".IRAM_DATA")
76 char l2_scratch_buf[L2_SCRATCH_SIZE];
78 #pragma DATA_SECTION(msmc_scratch_buf, ".MSMC_DATA")
79 char msmc_scratch_buf[MSMC_SCRATCH_SIZE];
81 #pragma DATA_SECTION(ddr_scratch_buf, ".DDR_DATA")
82 char ddr_scratch_buf[DDR_SCRATCH_SIZE];
84 #pragma DATA_SECTION(l2_data_buf, ".IRAM_DATA")
85 char l2_data_buf[TEST_DATA_SIZE*sizeof(double)];
87 #pragma DATA_SECTION(ddr_data_buf, ".DDR_DATA")
88 char ddr_data_buf[TEST_DATA_SIZE*sizeof(double)];
90 #pragma DATA_SECTION(ddr_data_buf2, ".DDR_DATA")
91 char ddr_data_buf2[TEST_DATA_SIZE*sizeof(double)];
93 #pragma DATA_SECTION(msmc_data_buf, ".MSMC_DATA");
94 char msmc_data_buf[TEST_DATA_SIZE*sizeof(double)];
96 EDMA3_DRV_Handle edma3_handle;
97 uint32_t edma3_id;
99 void app_fill_buffers(double *buf1, double *buf2, int num_elements);
100 double app_err_check(double *in1, double *in2, double *out, int num_elements);
101 int app_config_memory( void *l2_mem_base, size_t l2_mem_size,
102                     void *msmc_mem_base,  size_t msmc_mem_size, 
103                        void *ddr_mem_base,   size_t ddr_mem_size,   
104                        size_t *l1D_SRAM_size_orig);
105 void app_reconfig_memory(size_t l1D_SRAM_size_orig);
106 void app_init_transfer();
107 void app_cleanup_transfer();
108 extern void lib_benchmark_data_transfer();
109 extern EDMA3_DRV_Handle edma3init (uint32_t edma3Id, EDMA3_DRV_Result *errorCode);
111 /*==============================================================================
112  * Application code on the host which calls library functions to process data.
113  *============================================================================*/
114 int main()
115 {  
116     size_t l1D_SRAM_size_orig;
117     double err;
118     
119 #ifdef USE_OPENMP    
120     int nthreads, tid;
122     /* Verify OpenMP working properly */
123     #pragma omp parallel private(nthreads, tid)
124     {
125         /* Obtain thread number */
126         tid = omp_get_thread_num();
127         printf("Hello World from thread = %d\n", tid);
129         /* Only master thread does this */
130         if (tid == 0) {
131             nthreads = omp_get_num_threads();
132             printf("Number of threads = %d\n", nthreads);
133         }
134     }  /* All threads join master thread and disband */
135 #endif
136     
137     printf("Allocating memory for input/output buffers.\n");   
138     double *in1_ptr  = (double *)&l2_data_buf[0];
139     double *in2_ptr  = (double *)&ddr_data_buf[0];
140     double *out_ptr  = (double *)&msmc_data_buf[0];
142     printf("Input buffer 1 address: 0x%08x.\n", (unsigned int)in1_ptr);
143     printf("Input buffer 2 address: 0x%08x.\n", (unsigned int)in2_ptr);
144     printf("Output buffer  address: 0x%08x.\n", (unsigned int)out_ptr);
146     if(in1_ptr==NULL || in2_ptr==NULL || out_ptr==NULL) {
147         printf("No memory!\n");
148         exit(0);
149     }
150     else {
151         printf("Memory allocated.\n");
152     }
154     /* Fill buffers with data for testing. */
155     app_fill_buffers(in1_ptr, in2_ptr, TEST_DATA_SIZE);
157     /* Allocate scratch memory for DSP acceleration */
158     printf("Allocating scratch memory for library kernel.\n");   
159     void *l2_ptr    = (void *)l2_scratch_buf;
160     void *msmc_ptr  = (void *)msmc_scratch_buf;
161     void *ddr_ptr   = (void *)ddr_scratch_buf;
162     printf("L2 scratch starts from: 0x%08x.\n", (unsigned int)l2_ptr);
163     printf("MSMC scratch starts from: 0x%08x.\n", (unsigned int)msmc_ptr);
164     printf("DDR scratch starts from: 0x%08x.\n", (unsigned int)ddr_ptr);
166     /* Configure memory before calling library kernel */
167     printf("Configuring memory for library kernel...\n");   
168     if(app_config_memory(l2_ptr, L2_SCRATCH_SIZE, msmc_ptr, MSMC_SCRATCH_SIZE, 
169                          ddr_ptr, DDR_SCRATCH_SIZE, &l1D_SRAM_size_orig) != TEST_MEM_NOERR) {
170         printf("Memory configuration failed.\n");
171         exit (0);
172     }
173     else {
174         printf("Memory configured.\n");   
175     }
176     
177     /* Initialize for data transfer */
178     app_init_transfer();
179     
180     /* Pass input/output buffers to library function which sums two input buffers
181        and return the sum in the output buffer. */     
182     lib_dsp_func(in1_ptr, in2_ptr, out_ptr, TEST_DATA_SIZE);
184     /* Restore L1D and L2 original settings after the processing */
185     app_reconfig_memory(l1D_SRAM_size_orig);
186  
187     /* Check the result of DSP function */
188     err = app_err_check(in1_ptr, in2_ptr, out_ptr, TEST_DATA_SIZE);
189  
190     printf("Error checking.\n");
191  
192     if(err != 0) {
193         printf("DSP Function Failed!\n\n");
194     }
195     else {
196         printf("DSP Function Passed!\n\n");  
197     }
199     /* Benchmark libArch data transfer API vs. memcpy */
200     printf("Benchmarking data transfer API of LibArch versus standard memcpy...\n");
201     lib_benchmark_data_transfer();
202     
203     app_cleanup_transfer();
204     
205     return(0);
208 /*==============================================================================
209  * Filling memory with random data.
210  *============================================================================*/
211 void app_fill_buffers(double *buf1, double *buf2, int num_elements)
213     int i;
215     for(i=0; i<num_elements; i++)
216     {
217         buf1[i] = (double)i;
218         buf2[i] = (double)i*2;
219     }
220 } /* app_fill_buffers */
222 /*==============================================================================
223  * Error checking: check if buffer out is the sum of buffer in1 and buffer in2.
224  *============================================================================*/
225 double app_err_check(double *in1, double *in2, double *out, int num_elements)
227     double error = 0.0;
228     int i;
229   
230     for(i=0; i<num_elements; i++)
231     {
232         error += out[i] - (in1[i]+in2[i]);
233     }
234    
235     return(error);
236 } /* app_err_check */
239 /*==============================================================================
240  * This function prepares memory for the processing function 
241  *============================================================================*/
242 int app_config_memory( void *l2_mem_base,    size_t l2_mem_size,
243                        void *msmc_mem_base,  size_t msmc_mem_size, 
244                        void *ddr_mem_base,   size_t ddr_mem_size,   
245                        size_t *l1D_SRAM_size_orig)
247     size_t smem_size_vfast, smem_size_fast, smem_size_med, smem_size_slow;
248     void *l1d_SRAM_ptr;
249     int l1d_cfg_err;
250     
251     /* First, verify the provided/available memory meet requirements */
252     printf("Check memory requirement and configure L1D if necessary.\n");
253     test_GetSizes(&smem_size_vfast, &smem_size_fast, &smem_size_med, &smem_size_slow);
255     if(  (smem_size_vfast> lib_get_L1D_total_size()) // available L1D SRAM 
256        ||(smem_size_fast > l2_mem_size)              // provided L2 SRAM  
257        ||(smem_size_med  > msmc_mem_size)            // provided MSMC memory                  
258        ||(smem_size_slow > ddr_mem_size)             // provided DDR memory
259       ) {                                                            
260         return(TEST_MEM_ERROR);
261     }
262     
263     /* Configure L1D if necessary */
264     *l1D_SRAM_size_orig = lib_get_L1D_SRAM_size();  // get current L1D SRAM size 
265     printf("Original L1D SRAM size is %d.\n", *l1D_SRAM_size_orig);
266  
267     l1d_cfg_err = LIB_CACHE_SUCCESS;
268     if(*l1D_SRAM_size_orig <= smem_size_vfast) {    // configure L1D if needs more SRAM 
269 #ifdef USE_OPENMP        
270         #pragma omp parallel     
271 #endif        
272         {
273             l1d_cfg_err = lib_L1D_config_SRAM(smem_size_vfast);  
274             if(l1d_cfg_err) {
275                 printf("Error in configuring L1D on core %d!\n.", lib_get_coreID());
276             }
277             else {
278                 printf("Configured L1D SRAM size is %d on core %d.\n", 
279                        lib_get_L1D_SRAM_size(), lib_get_coreID());
280             }
281         }
282     }      
283     
284     /* get L1D SRAM base address */
285     l1d_SRAM_ptr = lib_get_L1D_SRAM_base();  
286     printf("L1D SRAM base address is 0x%x.\n", (unsigned int)l1d_SRAM_ptr);
287  
288     /* pass allocated memories for heap initialization */
289     if(test_Init(l1d_SRAM_ptr,  smem_size_vfast,
290                  l2_mem_base,   smem_size_fast,
291                  msmc_mem_base, smem_size_med, 
292                  ddr_mem_base,  smem_size_slow)) {
293       return(TEST_MEM_ERROR);        
294     }
296     return(TEST_MEM_NOERR);            
297 } /* app_config_memory */
299 /*==============================================================================
300  * This function reconfigures L1D after processing is finished
301  *============================================================================*/
302 void app_reconfig_memory(size_t l1D_SRAM_size_orig)
304     int l1d_cfg_err;
305     
306     /* configure L1D back */    
307     l1d_cfg_err = LIB_CACHE_SUCCESS;
308     if(l1D_SRAM_size_orig!=lib_get_L1D_SRAM_size()) {
309 #ifdef USE_OPENMP
310         #pragma omp parallel     
311 #endif        
312         {
313             l1d_cfg_err = lib_L1D_config_SRAM(l1D_SRAM_size_orig);    
314             if(l1d_cfg_err) {
315                 printf("Error in reconfiguring L1D on core %d!\n.", lib_get_coreID());
316             }
317             else {
318                 printf("Reconfigured L1D SRAM size is %d on core %d.\n", lib_get_L1D_SRAM_size(), lib_get_coreID());
319             }
320         }
321     }     
322 } /* app_reconfig_memory */
324 /*==============================================================================
325  * This function initializes the LibArch external memory data transfer.
326  * For K2G, it first initializes EDMA3 and obtains a handle, and then pass the 
327  *     handle to LibArch through lib_emt_init().
328  *
329  * For other platforms, it calls lib_emt_init() without passing EDMA3 handle as
330  *     LibArch is based on EdmaMgr. This will be removed when EdmaMgr is replaced
331  *     by EDMA3 LLD in LibArch. 
332  *============================================================================*/
333 void app_init_transfer()
335 #ifdef USE_OPENMP
336     #pragma omp parallel
337 #endif    
338     {
339     
340 #ifdef SOC_K2G
341     lib_emt_Config_t lib_emt_cfg;
342     EDMA3_DRV_Result edma3_error_code;
343     int i, lib_error_code;
344     
345     /* Scan through all EDMA3 instances until finding available resource. */
346     for(i=0; i<LIB_NUM_EDMA3_INSTANCES; i++)
347     {
348         edma3_handle = edma3init(i, &edma3_error_code);
349         if(edma3_error_code == EDMA3_DRV_SOK) {
350             edma3_id = i;   /* used for deinitialization */
351             break;
352         }
353         else {
354             printf("Initialization error for EDMA3 instance %d with error code: %d.\n", 
355                    i, edma3_error_code);
356         }
357     }
359     /* Check if resource is available. */
360     if (i < LIB_NUM_EDMA3_INSTANCES) {
361         /* Initialize libArch when edma3init succeeds. */
362         lib_emt_cfg.hEdma = edma3_handle;
363         lib_error_code = lib_emt_init(&lib_emt_cfg);
364         if(lib_error_code != LIB_EMT_SUCCESS) {
365             printf("Data transfer not initialized for core %d. Error code is %d.\n", 
366                    lib_get_coreID(), lib_error_code);
367         }
368         else {
369             printf("Data transfer initialized successfully for core %d.\n", 
370                    lib_get_coreID());
371         }
372     }
373     else {
374         /* Set Edma handle to NULl and return error if edma3init fails. */
375         printf("Data transfer NOT initialized due to EDMA3 init error.\n");
376     }
377     
378 #else    
379         int lib_error_code = lib_emt_init();
380    
381         if(lib_error_code != LIB_EMT_SUCCESS) {
382             printf("Data transfer not initialized for core %d. Error code is %d.\n", 
383                    lib_get_coreID(), lib_error_code);
384         }
385         else {
386             printf("Data transfer initialized successfully for core %d.\n", 
387                    lib_get_coreID());
388         }
389 #endif    
390     }
393 /*==============================================================================
394  * This function deinitializes EDMA3. 
395  *============================================================================*/
396 void app_cleanup_transfer()
398 #ifdef SOC_K2G    
399     EDMA3_DRV_Result status = edma3deinit(edma3_id, edma3_handle);
400    
401     if(status != EDMA3_DRV_SOK) {
402         printf("Deinitialization failed for core %d. Error code is %d.\n", 
403                lib_get_coreID(), status);
404     }
405 #endif    
408 /* Nothing past this point */