This section briefs about the implementation and configuration details of different components of the SigmaStudio+ for SHARC
Integrating target and communication libraries into custom real-time application
In order to create an Application (SHARC in this case), running the communication library and target libraries, users must do the following:
1. In CrossCore Embedded Studio, start a new CrossCore Project. Enter the name of the project, type of project,
processor etc. when requested, and proceed by pressing ‘Next’.
2. Add the SigmaStudio+ for SHARC communication library and target library to the project from the installed Add-ins
for the project.
3. Include the following header files in the Application code.
a. adi_ss_smap.h b. adi_ss_connection.h c. adi_ss_communication.h d. adi_ss_ssn.h
4. Add the Backchannel information structure present in Framework\Include\ adi_ss_ipc.h to the application code.
/* Backchannel info structure.*/ typedef struct ADI_SS_BACKCH_INFO { float32_t nPeakMIPS[ADI_SS_FW_MAX_PROC_BLOCKS]; float32_t nAvgMIPS[ADI_SS_FW_MAX_PROC_BLOCKS]; uint32_t nVersionInfo; uint32_t nSSnDownloadStatus; }ADI_SS_BACKCH_INFO;
5. Update the GMAP structure to allocate the total memory for each the memory blocks, to be sent to the SigmaStudio
Host. An example is as shown below.
#define NUM_BLOCKS 7 #define SIZE_GMAP (NUM_BLOCKS*2 + 1) .global _GMAP; .ALIGN 4; _GMAP: .var = NUM_BLOCKS; /* Number of memory blocks */ .var = _Block0_L1_space; /* Mem Block 0 L1 in LDF */ .var = _Block0_L1_space_length; /* Total Mem Size available for SigmaStudio Host from L1 Block0 */ .var = _Block0_L1_space_flag; /* Currently not used */ .var = _Block1_L1_space; /* Mem Block 1 L1 in LDF */ .var = _Block1_L1_space_length; /* Total Mem Size available for SigmaStudio Host from L1 Block1 */ .var = _Block1_L1_space_flag; /* Currently not used */ .var = _Block2_L1_space; /* Mem Block 2 L1 in LDF */ .var = _Block2_L1_space_length; /* Total Mem Size available for SigmaStudio Host from L1 Block2 */ .var = _Block2_L1_space_flag; /* Currently not used */ .var = _Block3_L1_space; /* Mem Block 3 L1 in LDF */ .var = _Block3_L1_space_length; /* Total Mem Size available for SigmaStudio Host from L1 Block3 */ .var = _Block3_L1_space_flag; /* Currently not used */ .var = _Block_L3_code_space; /* Mem L3 Code (external) in LDF */ .var = _Block_L3_code_space_length; /* Total Mem Size available for SigmaStudio Host from L3 code */ .var = _Block_L3_code_space_flag; /* Currently not used */ .var = _Block_L3_data_space; /* Mem L3 Data (external) in LDF */ .var = _Block_L3_data_space_length; /* Total Mem Size available for SigmaStudio Host from L3 data */ .var = _Block_L3_data_space_flag; /* Currently not used */ .var = _Block_L2_data_space; /* Mem L2 Data (data cache) in LDF */ .var = _Block_L2_data_space_length; /* Total Mem Size available for SigmaStudio Host from L2 data cache */ .var = _Block_L2_data_space_flag; /* Currently not used */ ._GMAP.end:
6. Allocate instance memory for connection and communication component within the application as shown below
/* Connection and Communication Instance Mem */ ALIGN(4) SECTION("ss_app_data0_fast") uint8_t adi_ss_commn_mem[ADI_SS_COMM_MEMSIZE]; ALIGN(4) SECTION("ss_app_data0_fast") uint8_t adi_ss_connection_mem[ADI_SS_CONNECTION_MEMSIZE];
7. Initialize memory block structure for the connection instance and call the “adi_ss_connection_init()” function to initialize the connection instance as shown below.
/* Connection Instance Initialization */ pConnConfig = &oConnConfig; pConnConfig->eConnectionType = ADI_SS_CONNECTION_SPI; pConnConfig->nDevId = 1; pConnConfig->eProcID = PROCESSOR_SH0;
pConnectionMemBlk = &oConnectionMemBlk; pConnectionMemBlk->nSize = ADI_SS_CONNECTION_MEMSIZE; pConnectionMemBlk->pMem = adi_ss_connection_mem; eConnRet = adi_ss_connection_Init(pConnectionMemBlk, pConnConfig, &hConnHandle);
8. Initialize memory block structure for the communication instance and call the “adi_ss_comm_init()” function to initialize the communication instance as shown below
/* Communication Instance Initialization */ pCommnConfig = &oCommnConfig; pCommnConfig->bCRCBypass = false; pCommnConfig->bFullPacketCRC = true; pCommnConfig->pfCommCmd4CallBack = (ADI_SS_COMM_CMD4_CB) adi_ss_comm_callback_cmd4; pCommnConfig->pfCommSMAPCallBack = (ADI_SS_COMM_SMAP_CB) adi_SMAP_Application_Callback; pCommnConfig->hConnectionHandle = hConnHandle; pCommnConfig->pMemSMap[PROCESSOR_SH0] = &oSMAP; pCommnConfig->pMemSMap[PROCESSOR_SH1] = &oSMAP1; pCommnConfig->pBkChnlInfo[PROCESSOR_SH0] = &oBkChannelInfo; pCommnConfig->pBkChnlInfo[PROCESSOR_SH1] = &oBkChannelInfo1;
pCommMemBlk = &oCommMemBlk; pCommMemBlk->nSize = ADI_SS_COMM_MEMSIZE; pCommMemBlk->pMem = adi_ss_commn_mem; adi_ss_comm_Init(pCommMemBlk, pCommnConfig,&hCommHandle);
9. Wait for the SMAP information to be received from the host by waiting on a flag which is set in the SMAP callback.
/* Wait for SMAP to be received */ while(!nSMAPReceived) { ; }
void adi_SMAP_Application_Callback(ADI_SS_PROC_ID eCoreID) { if(eCoreID==PROCESSOR_ARM) { nSMAPReceived = 1; } }
10. Populate the memory addresses of SigmaStudio+ memory blocks from the SMAP received from the host
/*Populating Memory addresses of different blocks from SMAO*/ oSSnMemMap.nMemBlocks = MAX_SMAP_SSN_BUFFERS; pSSnInfo=&oSMAP.oSSnInfo[0]; for(i=0;i<oSSnMemMap.nMemBlocks;i++) { oSSnMemMap.pMemBlocks[i] =&pSSnInfo->oSSnBuff[i]; }
11. Create the SSn instance
/*Creating SSn handle*/ adi_ss_create(&hSSnHandle, &oSSnMemMap);
12. Populate the SigmaStudio+ handle in the Communication properties structure in the communication library using the “adi_ss_comm_SetProperties’” API.
/*Populating the SigmaStudio+ handle in Comm Properties structure*/ pCommProp.haSSnHandle[PROCESSOR_SH0][0] = hSSnHandle; pCommProp.nNumProcBlocks = 1; pCommProp.nProcId = PROCESSOR_ARM; eCommRet = adi_ss_comm_SetProperties(hCommHandle,ADI_COMM_PROP_SSN_HANDLE,&pCommProp);
13. Initialize the SigmaStudio+ instance using the “adi_ss_init” API. All default configurations are sent through the oSSnConfig structure
/*SSnConfig initialization */ pSSnConfig=&oSSnConfig; pSSnConfig->hSSComm = hCommHandle; pSSnConfig->nBlockSize = BLOCK_SIZE; pSSnConfig->nInChannels = NUM_INPUT_CHANNELS; pSSnConfig->nOutChannels = NUM_OUTPUT_CHANNELS; pSSnConfig->bSkipProcessOnCRCError = 0; pSSnConfig->bSkipInitialDownload = 0U; pSSnConfig->nInitNoWait = 0; pSSnConfig->eProcID = 0; pSSnConfig->bClearUnusedOutput = 1; eSSRes = adi_ss_init(hSSnHandle, pSSnConfig);
14. Assign the input and output buffers to the pointer array.
for(idx=0;idx<NUM_INPUT_CHANNELS;idx++) { input_buff[idx]=&Block_In[idx * BLOCK_SIZE]; }
for(idx=0;idx<NUM_OUTPUT_CHANNELS;idx++) { output_buff[idx]=&Block_Out[idx * BLOCK_SIZE]; }
15. Call the “adi_ss_schematic_process()” function to perform the SSn operation. One or more extra audio processing modules may be added to the system either before or after the adi_ss_schematic_process() function.
adi_ss_schematic_process(hSSnHandle,BLOCK_SIZE,input_buff,output_buff,pSSnProperties);