/* Copyright (c) 2016, Texas Instruments Incorporated - http://www.ti.com/ All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the * distribution. * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ // // // Framework -- System Stream Function Definitions // // System Stream Functions Main and 1-5. // // // // See: pa/f/s3/ss0.c // // Specific ASP usage requires inter-file symbol definitions ... #include "noasp.h" // ... end of specific usage definitions. #include //#include //#include //#include #include #include #include #include #include #include //#include "alg.h" #include "logp.h" #include "systemStream.h" #include #include #include #include #include //#include "pafhjt.h" // //#ifdef RAM_REPORT //#include //extern int IRAM; //extern int SDRAM; //extern int L3RAM; //#endif /* RAM_REPORT */ #ifndef FULL_SPEAKER #define FULL_SPEAKER #endif extern IALG_Status pafIdentification; // // systemStream : audio stream control function (main) // LINNO_DEFN (systemStreamMain); ERRNO_DEFN (systemStreamMain); Void systemStreamMain( const PAF_SST_Params *pP, PAF_SST_Config *pC ) { Int32 ss = pP->ss; const PAF_SST_Fxns *fxns= pP->fxns; PAF_SystemStatus *pStatus = pC->pStatus; LINNO_RPRT (systemStreamMain, -1); // Initialize on first invocation: if (!pC->acp) { ALG_Handle acpAlg; ACP_Handle acp; Int32 betaPrimeValue = ss - 1; Int32 betaPrimeOffset; Int32 betaPrime; // Initialize algorithms // Create an ACP algorithm instance with trace enabled ACP_MDS_init(); if ( !(acpAlg = (ALG_Handle )ACP_MDS_create (NULL)) ) { //LOG_printf(&trace, "SS%d: ACP algorithm instance creation failed", // ss); Log_error1("SS%d: ACP algorithm instance creation failed", (IArg)ss); LINNO_RPRT (systemStreamMain, __LINE__); return; } acpAlg->fxns->algControl(acpAlg, ACP_GETBETAPRIMEOFFSET, (IALG_Status *) &betaPrimeOffset); betaPrime = betaPrimeOffset * betaPrimeValue; acp = (ACP_Handle )acpAlg; acp->fxns->attach(acp, ACP_SERIES_STD, STD_BETA_SYSIDL+betaPrime, (IALG_Status *)pStatus); acpAlg->fxns->algControl(acpAlg, ACP_SETBETAPRIMEVALUE, (IALG_Status *) &betaPrimeValue); pC->acp = acp; //LOG_printf(&trace, "SS%d: ACP processing initialized", ss); Log_info1("SS%d: ACP processing initialized", (IArg)ss); LINNO_RPRT(systemStreamMain, -2); // Attach PAF IDENTITY acp->fxns->attach(acp, ACP_SERIES_STD, STD_BETA_IDENTITY, (IALG_Status *) &pafIdentification); } #ifdef RAM_REPORT { static int count=0; if (count < 10) { count++; } else if (count == 10) { PAF_ALG_memStatusPrint(IRAM,SDRAM,L3RAM); count++; } } #endif /* RAM_REPORT */ // Invoke sub-functions as per mode: if (fxns) { Int32 i; Int64 x[PAF_SYSTEMSTREAMFXNS_XN]; for (i=0; i < fxns->count; i++) { if ((pStatus->mode & (1 << i)) == 0) continue; if (! fxns->sub[i].compute) continue; if (fxns->sub[i].compute (pP, pC, x)) continue; if (! fxns->sub[i].transmit) continue; if (fxns->sub[i].transmit (pP, pC, x)) continue; } } } // // systemStream1 : audio stream control functions (sub) // // Process listening mode, recreation mode, and speaker configuration // to set Decode Channel Configuration Request and Override Select // Registers. // #ifndef NODEC Int32 systemStream1Compute( const PAF_SST_Params *pP, PAF_SST_Config *pC, Int64 x[] ) { PAF_SystemStatus *pStatus = pC->pStatus; static const PAF_ChannelConfiguration cs[PAF_SYS_RECREATIONMODE_N] = { // PAF_SYS_RECREATIONMODE_NONE { PAF_CC_SAT_NONE, PAF_CC_SUB_ZERO, 0, 0, 0, 0, 0, 0, }, // PAF_SYS_RECREATIONMODE_MONO (unused below) { PAF_CC_SAT_MONO, PAF_CC_SUB_ZERO, 0, 0, 0, 0, 0, 0, }, // PAF_SYS_RECREATIONMODE_STEREO { PAF_CC_SAT_STEREO, PAF_CC_SUB_ZERO, 0, 0, 0, 0, 0, 0, }, // PAF_SYS_RECREATIONMODE_PHANTOM0_1 { PAF_CC_SAT_STEREO, PAF_CC_SUB_ONE, 0, 0, 0, 0, 0, 0, }, // PAF_SYS_RECREATIONMODE_SURROUND0_1 { PAF_CC_SAT_3STEREO, PAF_CC_SUB_ONE, 0, 0, 0, 0, 0, 0, }, // PAF_SYS_RECREATIONMODE_PHANTOM2_1 { PAF_CC_SAT_PHANTOM2, PAF_CC_SUB_ONE, 0, 0, 0, 0, 0, 0, }, // PAF_SYS_RECREATIONMODE_SURROUND2_1 { PAF_CC_SAT_SURROUND2, PAF_CC_SUB_ONE, 0, 0, 0, 0, 0, 0, }, }; XDAS_UInt8 n; PAF_ChannelConfiguration ccr; /* Channel Configuration Request */ PAF_ChannelConfiguration cco; /* Channel Configuration Override */ // Listening mode: ignored. // Recreation mode: direct, select, or auto. switch (n = pStatus->recreationMode) { case PAF_SYS_RECREATIONMODE_DONT: ccr.full = -1; cco.full = -1; break; case PAF_SYS_RECREATIONMODE_DIRECT: ccr = pStatus->channelConfigurationRequest; cco.full = PAF_CC_UNKNOWN; break; case PAF_SYS_RECREATIONMODE_AUTO: ccr.full = 0; ccr.part.sat = PAF_CC_SAT_STEREO + (pStatus->speakerCntr & PAF_SYS_SPEAKERNUMB) * 5 + (pStatus->speakerSurr & PAF_SYS_SPEAKERNUMB) + (pStatus->speakerBack & PAF_SYS_SPEAKERNUMB); ccr.part.sub = (pStatus->speakerSubw & PAF_SYS_SPEAKERNUMB); ccr.part.extMask = ((pStatus->speakerWide & PAF_SYS_SPEAKERNUMB) ? PAF_CC_EXTMASK_LwRw : 0) #ifdef FULL_SPEAKER | ((pStatus->speakerLRCntr & PAF_SYS_SPEAKERNUMB) ? PAF_CC_EXTMASK_LcRc : 0) #endif | ((pStatus->speakerHead & PAF_SYS_SPEAKERNUMB) ? PAF_CC_EXTMASK_LhRh : 0) ; #ifdef FULL_SPEAKER ccr.part.extMask2 = ((pStatus->speakerCntrSurr & PAF_SYS_SPEAKERNUMB) ? PAF_CC_EXTMASK_Cs : 0) | ((pStatus->speakerLRCntrSurr & PAF_SYS_SPEAKERNUMB) ? PAF_CC_EXTMASK_LcsRcs : 0) | ((pStatus->speakerRearSurr2 & PAF_SYS_SPEAKERNUMB) ? PAF_CC_EXTMASK_Lrs2Rrs2 : 0) | ((pStatus->speakerRearSurr1 & PAF_SYS_SPEAKERNUMB) ? PAF_CC_EXTMASK_Lrs1Rrs1 : 0) | ((pStatus->speakerSurr2 & PAF_SYS_SPEAKERNUMB) ? PAF_CC_EXTMASK_Ls2Rs2 : 0) | ((pStatus->speakerSurr1 & PAF_SYS_SPEAKERNUMB) ? PAF_CC_EXTMASK_Ls1Rs1 : 0) | ((pStatus->speakerScreen & PAF_SYS_SPEAKERNUMB) ? PAF_CC_EXTMASK_LscRsc : 0); #endif ccr.part.extMask3 = ((pStatus->speakerTopfront & PAF_SYS_SPEAKERNUMB) ? PAF_CC_EXTMASK_LtfRtf : 0) | ((pStatus->speakerToprear & PAF_SYS_SPEAKERNUMB) ? PAF_CC_EXTMASK_LtrRtr : 0) | ((pStatus->speakerTopmiddle & PAF_SYS_SPEAKERNUMB) ? PAF_CC_EXTMASK_LtmRtm : 0) | ((pStatus->speakerFrontheight & PAF_SYS_SPEAKERNUMB) ? PAF_CC_EXTMASK_LfhRfh : 0) | ((pStatus->speakerRearheight & PAF_SYS_SPEAKERNUMB) ? PAF_CC_EXTMASK_LrhRrh : 0); pStatus->channelConfigurationRequest = ccr; cco.full = PAF_CC_UNKNOWN; break; case PAF_SYS_RECREATIONMODE_MONO: ccr.full = (pStatus->speakerCntr & PAF_SYS_SPEAKERNUMB) ? PAF_CC_MONO : PAF_CC_STEREO_MONO; pStatus->channelConfigurationRequest = ccr; cco.full = PAF_CC_UNKNOWN; break; default: ccr = cs[n < lengthof (cs) ? n : 0]; pStatus->channelConfigurationRequest = ccr; cco.full = PAF_CC_UNKNOWN; break; } if (pStatus->channelConfigurationRequestType != PAF_SYS_CCRTYPE_STANDARD) { PAF_ChannelConfiguration ccs; ccs = cco; // CCO is computed CCR. cco = ccr; // CCR is as per request type: // DecodeBypass - PAF_CC_UNKNOWN (see above) // DecodeDirect - don't write, allow use as control register ccr.full = pStatus->channelConfigurationRequestType == PAF_SYS_CCRTYPE_DECODEDIRECT ? -1 : ccs.full; } x[0] = ccr.full; /* Channel Configuration Request */ x[1] = cco.full; /* Channel Configuration Override */ return 0; } Int32 systemStream1Transmit( const PAF_SST_Params *pP, PAF_SST_Config *pC, Int64 x[] ) { Int32 ss = pP->ss; ACP_Handle acp = pC->acp; PAF_ChannelConfiguration ccr; /* Channel Configuration Request */ PAF_ChannelConfiguration cco; /* Channel Configuration Override */ ccr.full = x[0]; /* Channel Configuration Request */ cco.full = x[1]; /* Channel Configuration Override */ // Send Request to Audio Stream 1 Decode Status. if (ccr.full != -1) { ACP_Unit from[7]; Int32 errno; // writeDECChannelConfigurationRequest 0xce24,0x3808 from[0] = 0xc906; from[1] = 0xce24; from[2] = 0x3808; from[3] = ccr.full; from[4] = ccr.full >> 16; from[5] = ccr.full >> 32; from[6] = ccr.full >> 48; if (errno = acp->fxns->sequence(acp, from, NULL)) { //LOG_printf(&trace, "SS%d: DEC sequence processing error (0x%04x)", // ss, errno); Log_error2("SS%d: DEC sequence processing error (0x%04x)", (IArg)ss, (IArg)errno); ERRNO_RPRT (systemStreamMain, errno); } // writeENCChannelConfigurationCompact(sat,sub,aux,ext0,ext2,ext3,rsvd1,rsvd2) 0xce25,0x9808 from[0] = 0xc906; from[1] = 0xce25; from[2] = 0x9808; from[3] = ccr.full; from[4] = ccr.full >> 16; from[5] = ccr.full >> 32; from[6] = ccr.full >> 48; if (errno = acp->fxns->sequence(acp, from, NULL)) { //LOG_printf(&trace, "SS%d: ENC sequence processing error (0x%04x)", // ss, errno); Log_error2("SS%d: ENC sequence processing error (0x%04x)", (IArg)ss, (IArg)errno); ERRNO_RPRT (systemStreamMain, errno); } } // Send Override to Audio Stream 1 Decode Status. if (cco.full != -1) { ACP_Unit from[7]; Int32 errno; // writeDECChannelConfigurationOverride 0xce24,0x5808 from[0] = 0xc906; from[1] = 0xce24; from[2] = 0x5808; from[3] = cco.full; from[4] = cco.full >> 16; from[5] = cco.full >> 32; from[6] = cco.full >> 48; if (errno = acp->fxns->sequence(acp, from, NULL)) { //LOG_printf(&trace, "SS%d: DEC sequence processing error (0x%04x)", // ss, errno); Log_error2("SS%d: DEC sequence processing error (0x%04x)", (IArg)ss, (IArg)errno); ERRNO_RPRT (systemStreamMain, errno); } } return 0; } #else /* NODEC */ asm(" .global _systemStream1Compute"); asm("_systemStream1Compute .set 0"); asm(" .global _systemStream1Transmit"); asm("_systemStream1Transmit .set 0"); #endif /* NODEC */ // // systemStream2 : audio stream control functions (sub) // // Process listening mode, recreation mode, and speaker configuration // to set Bass Management Output Configuration Select Register. // #ifndef NOBM #define DOC_AUTO 0x0f // 15, to leave some room Int32 systemStream2Compute( const PAF_SST_Params *pP, PAF_SST_Config *pC, Int64 x[] ) { PAF_SystemStatus *pStatus = pC->pStatus; Int32 oc; // Determine BM Output Configuration Select (if auto mode): if ( pStatus->recreationMode == PAF_SYS_RECREATIONMODE_DONT || pStatus->recreationMode == PAF_SYS_RECREATIONMODE_DIRECT ) { return 1; } // Set channel flags, including channels beyond Dolby spec: oc = (DOC_AUTO << 24) + ((pStatus->speakerSubw & PAF_SYS_SPEAKERFREQ_HI ? 1 : 0) << 0) + ((pStatus->speakerMain & PAF_SYS_SPEAKERFREQ_LO ? 1 : 0) << 1) + ((pStatus->speakerCntr & PAF_SYS_SPEAKERFREQ_LO ? 1 : 0) << 2) + ((pStatus->speakerSurr & PAF_SYS_SPEAKERFREQ_LO ? 1 : 0) << 3) + ((pStatus->speakerBack & PAF_SYS_SPEAKERFREQ_LO ? 1 : 0) << 4) + ((pStatus->speakerWide & PAF_SYS_SPEAKERFREQ_LO ? 1 : 0) << 5) + ((pStatus->speakerHead & PAF_SYS_SPEAKERFREQ_LO ? 1 : 0) << 6) ; x[0] = oc; /* Output Configuration */ return 0; } Int32 systemStream2Transmit( const PAF_SST_Params *pP, PAF_SST_Config *pC, Int64 x[] ) { Int32 ss = pP->ss; ACP_Handle acp = pC->acp; Int32 oc; oc = x[0]; /* Output Configuration */ // Send Select to Audio Stream 1 Bass Management Status if valid: { Int32 errno; ACP_Unit from[6]; from[0] = 0xc905; // writeBMOCSelectOCAuto(OCNO,AUTO) 0xcb40,0x000a, // ((OCNO) << 8)&0xff00+(AUTO)&0x00ff from[1] = 0xcb40; from[2] = 0x000a; from[3] = (oc>>16) & 0xffff; // writeBMOCSelectChannels(CHANS) 0xca40, // 0x0800+((CHANS) & 0x00ff) from[4] = 0xca40; from[5] = 0x0800 + (oc & 0xff); if (errno = acp->fxns->sequence(acp, from, NULL)) { if (errno == ACPERR_APPLY_NOBETA) { // Return without reporting to trace Log if BM is not // part of the stream. return 1; } else { //LOG_printf(&trace, "SS%d: BM sequence processing error (0x%04x)", // ss, errno); Log_error2("SS%d: BM sequence processing error (0x%04x)", (IArg)ss, (IArg)errno); ERRNO_RPRT (systemStreamMain, errno); } } } return 0; } #else /* NOBM */ asm(" .global _systemStream2Compute"); asm("_systemStream2Compute .set 0"); asm(" .global _systemStream2Transmit"); asm("_systemStream2Transmit .set 0"); #endif /* NOBM */ // // systemStream3 : audio stream control functions (sub) // // Process S/PDIF pre-emphasis flag information and Deemphasis Filter // Mode Control information to set Deemphasis Filter Active Select // Register if needed. // // Note that this implementation is quite arbitrary and could be done // another way, including completely via a shortcut! --Kurt // #ifndef NODEM Int32 systemStream3Compute( const PAF_SST_Params *pP, PAF_SST_Config *pC, Int64 x[] ) { Int32 ss = pP->ss; ACP_Handle acp = pC->acp; Int32 errno; ACP_Unit from[3], to[3]; // readDEMFilterMode 0xc250,0x0500 from[0] = 0xc902; from[1] = 0xc250; from[2] = 0x0500; if (errno = acp->fxns->sequence(acp, from, to)) { if (errno == ACPERR_APPLY_NOBETA) { // Return without reporting to trace Log if DEM is not // part of the stream. return 1; } else { //LOG_printf(&trace, "SS%d: DEM sequence processing error (0x%04x)", // ss, errno); Log_error2("SS%d: DEM sequence processing error (0x%04x)", (IArg)ss, (IArg)errno); ERRNO_RPRT (systemStreamMain, errno); } } // If Deemphasis Filter Mode Control is not "Auto", no further action. if ((to[2] & 0xff) != 1) return 1; // readDECEmphasis 0xc224,0x33 from[0] = 0xc902; from[1] = 0xc224; from[2] = 0x3300; if (errno = acp->fxns->sequence(acp, from, to)) { //LOG_printf(&trace, "SS%d: DEC sequence processing error (0x%04x)", // ss, errno); Log_error2("SS%d: DEC sequence processing error (0x%04x)", (IArg)ss, (IArg)errno); ERRNO_RPRT (systemStreamMain, errno); } x[0] = (to[2] & 0xff) == 2 ? 1 : 0; return 0; } Int32 systemStream3Transmit( const PAF_SST_Params *pP, PAF_SST_Config *pC, Int64 x[] ) { Int32 ss = pP->ss; ACP_Handle acp = pC->acp; ACP_Unit from[3]; Int32 errno; from[0] = 0xc902; from[1] = 0xca50; from[2] = 0x0600 + x[0]; if (errno = acp->fxns->sequence(acp, from, NULL)) { if (errno == ACPERR_APPLY_NOBETA) { // Return without reporting to trace Log if DEM is not // part of the stream. return 1; } else { //LOG_printf(&trace, "SS%d: DEM sequence processing error (0x%04x)", // ss, errno); Log_error2("SS%d: DEM sequence processing error (0x%04x)", (IArg)ss, (IArg)errno); ERRNO_RPRT (systemStreamMain, errno); } } return 0; } #else /* NODEM */ asm(" .global _systemStream3Compute"); asm("_systemStream3Compute .set 0"); asm(" .global _systemStream3Transmit"); asm("_systemStream3Transmit .set 0"); #endif /* NODEM */ // // systemStream5 : CPU Load Graph // //#include //#include //#include //#include Int32 systemStream5Compute( const PAF_SST_Params *pP, PAF_SST_Config *pC, Int64 x[] ) { PAF_SystemStatus *pStatus = pC->pStatus; Load_Stat stat; Load_getTaskLoad(Task_getIdleTask(), &stat); pStatus->cpuLoad = (100 - Load_calculateLoad(&stat)) * 256; if (pStatus->peakCpuLoad < pStatus->cpuLoad) pStatus->peakCpuLoad = pStatus->cpuLoad; return 0; } Int32 systemStream5Transmit( const PAF_SST_Params *pP, PAF_SST_Config *pC, Int64 x[] ) { return 0; }