/* ** ============================================================================= ** Copyright (c) 2016 Texas Instruments Inc. ** ** This program is free software; you can redistribute it and/or modify it under ** the terms of the GNU General Public License as published by the Free Software ** Foundation; version 2. ** ** This program is distributed in the hope that it will be useful, but WITHOUT ** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS ** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License along with ** this program; if not, write to the Free Software Foundation, Inc., 51 Franklin ** Street, Fifth Floor, Boston, MA 02110-1301, USA. ** ** File: ** factorytest.c ** ** Description: ** main program for TAS2555 factory test ** ** ============================================================================= */ #include #include #include #include #include #include #include #include "tas2557_ftc.h" // ================================================================ Definitions // Obtained from Speaker Manufacturer #define SPK_T_MAX 100 // Speaker Maximum Temperature (C) #define SPK_RE_TOL_PER 10 // Re +/- tolerance (%) #define SPK_RE_ALPHA 0.0039 // Temperature coefficient alpha (1/K) // Obtained from PurePath Console 3 (PPC3) #define PPC3_RE0 7.41 // Re0 (ohm) #define PPC3_RTV 46.5 // Rtv (K/W) #define PPC3_RTM 78.2 // Rtm (K/W) #define PPC3_RTVA 2460 // Rtva (K/W) #define PPC3_SYSGAIN 9.35 // System Gain (V/FS) #define PPC3_DEV_NONLIN_PER 1.5 // Device Non-linearity (%) #define PPC3_PIG 1 #define DEV_A_I2C_ADDR 0x98 #define DEV_B_I2C_ADDR 0x9a void ExitWithHint(char *pHint) { printf("factorytest: invalid command line: %s\n\r\n\r", pHint); printf("usage: factorytest [-t temperature] [-c configuration file] [-l load calibration] [-v verbose]\n\r"); exit(-1); } void InitFTCC(struct TFTCConfiguration *pFTCC) { pFTCC->nCalibrationTime = 4000; pFTCC->bVerbose = false; pFTCC->bLoadCalibration = false; pFTCC->nTSpkCharDevA.nSpkTMax = SPK_T_MAX; pFTCC->nTSpkCharDevA.nSpkReTolPer = SPK_RE_TOL_PER; pFTCC->nTSpkCharDevA.nSpkReAlpha = SPK_RE_ALPHA; pFTCC->nTSpkCharDevA.nReHi = PPC3_RE0*1.15; pFTCC->nTSpkCharDevA.nReLo = PPC3_RE0*0.85; pFTCC->nTSpkCharDevA.nPPC3_Re0 = PPC3_RE0; pFTCC->nTSpkCharDevA.nPPC3_RTV = PPC3_RTV; pFTCC->nTSpkCharDevA.nPPC3_RTM = PPC3_RTM; pFTCC->nTSpkCharDevA.nPPC3_RTVA = PPC3_RTVA; pFTCC->nTSpkCharDevA.nPPC3_SysGain = PPC3_SYSGAIN; pFTCC->nTSpkCharDevA.nPPC3_DevNonlinPer = PPC3_DEV_NONLIN_PER; pFTCC->nTSpkCharDevA.nPPC3_PIG = PPC3_PIG; pFTCC->nTSpkCharDevA.nDevAddr = DEV_A_I2C_ADDR; pFTCC->nTSpkCharDevB.nSpkTMax = SPK_T_MAX; pFTCC->nTSpkCharDevB.nSpkReTolPer = SPK_RE_TOL_PER; pFTCC->nTSpkCharDevB.nSpkReAlpha = SPK_RE_ALPHA; pFTCC->nTSpkCharDevB.nReHi = PPC3_RE0*1.15; pFTCC->nTSpkCharDevB.nReLo = PPC3_RE0*0.85; pFTCC->nTSpkCharDevB.nPPC3_Re0 = PPC3_RE0; pFTCC->nTSpkCharDevB.nPPC3_RTV = PPC3_RTV; pFTCC->nTSpkCharDevB.nPPC3_RTM = PPC3_RTM; pFTCC->nTSpkCharDevB.nPPC3_RTVA = PPC3_RTVA; pFTCC->nTSpkCharDevB.nPPC3_SysGain = PPC3_SYSGAIN; pFTCC->nTSpkCharDevB.nPPC3_DevNonlinPer = PPC3_DEV_NONLIN_PER; pFTCC->nTSpkCharDevB.nPPC3_PIG = PPC3_PIG; pFTCC->nTSpkCharDevB.nDevAddr = DEV_B_I2C_ADDR; } unsigned int SkipCharacter(char *pData, char cCharacter, unsigned int nSize) { unsigned int nRIndex; unsigned int nWIndex = 0; for (nRIndex = 0; nRIndex < nSize; nRIndex++) if (pData[nRIndex] != cCharacter) pData[nWIndex++] = pData[nRIndex]; return nWIndex; } unsigned int RemoveComments(char *pData, char cCharacter, unsigned int nSize) { unsigned int nRIndex; unsigned int nWIndex = 0; for (nRIndex = 0; nRIndex < nSize; nRIndex++) { if (pData[nRIndex] == cCharacter) while ((nRIndex < nSize) && (pData[nRIndex] != '\r')) nRIndex++; pData[nWIndex++] = pData[nRIndex]; } return nWIndex; } void ReadValue(struct TFTCConfiguration *pFTCC, struct TSPKCharData *pSpk, char *pLine, char *pValue) { if (!strcmp(pLine, "CALIBRATION_TIME")) {pFTCC->nCalibrationTime = atoi(pValue); return;}; if (!strcmp(pLine, "SPK_T_MAX")) {pSpk->nSpkTMax = atof(pValue); return;}; if (!strcmp(pLine, "SPK_RE_TOL_PER")) {pSpk->nSpkReTolPer = atof(pValue); return;}; if (!strcmp(pLine, "SPK_RE_ALPHA")) {pSpk->nSpkReAlpha = atof(pValue); return;}; if (!strcmp(pLine, "PPC3_RE0")) {pSpk->nPPC3_Re0 = atof(pValue); return;}; if (!strcmp(pLine, "PPC3_RTV")) {pSpk->nPPC3_RTV = atof(pValue); return;}; if (!strcmp(pLine, "PPC3_RTM")) {pSpk->nPPC3_RTM = atof(pValue); return;}; if (!strcmp(pLine, "PPC3_RTVA")) {pSpk->nPPC3_RTVA = atof(pValue); return;}; if (!strcmp(pLine, "PPC3_SYSGAIN")) {pSpk->nPPC3_SysGain = atof(pValue); return;}; if (!strcmp(pLine, "PPC3_DEV_NONLIN_PER")) {pSpk->nPPC3_DevNonlinPer = atof(pValue); return;}; if (!strcmp(pLine, "PPC3_PIG")) {pSpk->nPPC3_PIG = atof(pValue); return;}; if (!strcmp(pLine, "RE_HI")) {pSpk->nReHi = atof(pValue); return;}; if (!strcmp(pLine, "RE_LO")) {pSpk->nReLo = atof(pValue); return;}; if (!strcmp(pLine, "DEV_ADDR")){ char *endptr; pSpk->nDevAddr = strtol(pValue, &endptr, 16); return; }; } void ftcc_print(struct TFTCConfiguration *pFTCC) { printf("factorytest configuration: \n\r"); printf(" CALIBRATION_TIME = %d\n\r", pFTCC->nCalibrationTime); printf("Speaker A characterization data: \n\r"); printf(" SPKA SPK_T_MAX = %2.2f\n\r", pFTCC->nTSpkCharDevA.nSpkTMax); printf(" SPKA SPK_RE_TOL_PER = %2.2f\n\r", pFTCC->nTSpkCharDevA.nSpkReTolPer); printf(" SPKA SPK_RE_ALPHA = %2.4f\n\r\n\r", pFTCC->nTSpkCharDevA.nSpkReAlpha); printf(" SPKA PPC3_RE0 = %2.2f\n\r", pFTCC->nTSpkCharDevA.nPPC3_Re0); printf(" SPKA PPC3_RTV = %2.2f\n\r", pFTCC->nTSpkCharDevA.nPPC3_RTV); printf(" SPKA PPC3_RTM = %2.2f\n\r", pFTCC->nTSpkCharDevA.nPPC3_RTM); printf(" SPKA PPC3_RTVA = %2.2f\n\r", pFTCC->nTSpkCharDevA.nPPC3_RTVA); printf(" SPKA PPC3_SYSGAIN = %2.2f\n\r", pFTCC->nTSpkCharDevA.nPPC3_SysGain); printf(" SPKA PPC3_DEV_NONLIN_PER = %2.2f\n\r", pFTCC->nTSpkCharDevA.nPPC3_DevNonlinPer); printf(" SPKA PPC3_PIG = %f\n\r", pFTCC->nTSpkCharDevA.nPPC3_PIG); printf(" DEVA ADDR = 0x%x\n\r", pFTCC->nTSpkCharDevA.nDevAddr); printf("Speaker B characterization data: \n\r"); printf(" SPKB SPK_T_MAX = %2.2f\n\r", pFTCC->nTSpkCharDevB.nSpkTMax); printf(" SPKB SPK_RE_TOL_PER = %2.2f\n\r", pFTCC->nTSpkCharDevB.nSpkReTolPer); printf(" SPKB SPK_RE_ALPHA = %2.4f\n\r\n\r", pFTCC->nTSpkCharDevB.nSpkReAlpha); printf(" SPKB PPC3_RE0 = %2.2f\n\r", pFTCC->nTSpkCharDevB.nPPC3_Re0); printf(" SPKB PPC3_RTV = %2.2f\n\r", pFTCC->nTSpkCharDevB.nPPC3_RTV); printf(" SPKB PPC3_RTM = %2.2f\n\r", pFTCC->nTSpkCharDevB.nPPC3_RTM); printf(" SPKB PPC3_RTVA = %2.2f\n\r", pFTCC->nTSpkCharDevB.nPPC3_RTVA); printf(" SPKB PPC3_SYSGAIN = %2.2f\n\r", pFTCC->nTSpkCharDevB.nPPC3_SysGain); printf(" SPKB PPC3_DEV_NONLIN_PER = %2.2f\n\r", pFTCC->nTSpkCharDevB.nPPC3_DevNonlinPer); printf(" SPKB PPC3_PIG = %f\n\r", pFTCC->nTSpkCharDevB.nPPC3_PIG); printf(" DEVB ADDR = 0x%x\n\r", pFTCC->nTSpkCharDevB.nDevAddr); } int ftcc_parse(struct TFTCConfiguration *pFTCC, struct TSPKCharData *pSpk, char *pData, unsigned int nSize) { unsigned int nRIndex = 0; char *pLine; char *pEqual; double nTest; nSize = SkipCharacter(pData, ' ', nSize); nSize = RemoveComments(pData, ';', nSize); pData[nSize] = 0; pLine = strtok(pData, "\n\r"); // printf("ftcc_parse: pData = %s\n\r", pData); // printf("ftcc_parse: size = %d, pLine = 0x%08x\n\r", nSize, pLine); while (pLine) { // printf("ftcc_parse: pLine = 0x%08x\n\r", pLine); if (pLine[0]) { printf("Line = %s\n\r", pLine); pEqual = strstr(pLine, "="); if ((pEqual) && (strlen(pEqual) > 1)) { pEqual[0] = 0; ReadValue(pFTCC, pSpk, pLine, pEqual + 1); pEqual[0] = '='; } } pLine = strtok(NULL, "\n\r"); } return 0; } void LoadFTCC(char *pFileName, struct TFTCConfiguration *pFTCC, struct TSPKCharData *pSpk) { struct stat st; char *pData; int nFile; // printf("LoadFTCC: %s\n\r", pFileName); if (stat(pFileName, &st) < 0) ExitWithHint("configuration file doesn't exist"); pData = malloc(st.st_size); if (!pData) ExitWithHint("cannot allocate memory for configuation file"); nFile = open(pFileName, O_RDONLY); if (nFile < 0) ExitWithHint("cannot open configuration file"); read(nFile, pData, st.st_size); close(nFile); ftcc_parse(pFTCC, pSpk, pData, st.st_size); free(pData); } int main(int argc, char *argv[]) { double nTemp = 20.0; int nArg = 1; bool bValidArg; char pHint[256]; struct TFTCConfiguration sFTCC; printf("\nTI TAS2557 factory test calibration sequence V1.0\n"); InitFTCC(&sFTCC); // printf("argc = %d\n\r", argc); while (nArg < argc) { // printf("argv[%d] = %s: ", nArg, argv[nArg]); bValidArg = false; if (!strcmp(argv[nArg], "-t")) { printf("nArg = %d, argc = %d\n\r", nArg, argc); if (argc <= (nArg + 1)) ExitWithHint("temperature parameter is missing"); nTemp = atof(argv[nArg + 1]); nArg++; bValidArg = true; } if (!strcmp(argv[nArg], "-l")) { // printf("found configuration file argument\n\r"); if (argc <= (nArg + 1)) ExitWithHint("configuration file name is missing"); LoadFTCC(argv[nArg + 1], &sFTCC, &(sFTCC.nTSpkCharDevA)); nArg++; bValidArg = true; } if (!strcmp(argv[nArg], "-r")) { // printf("found configuration file argument\n\r"); if (argc <= (nArg + 1)) ExitWithHint("configuration file name is missing"); LoadFTCC(argv[nArg + 1], &sFTCC, &(sFTCC.nTSpkCharDevB)); nArg++; bValidArg = true; } if (!strcmp(argv[nArg], "-v")) { sFTCC.bVerbose = true; bValidArg = true; } if (!strcmp(argv[nArg], "-u")) { sFTCC.bLoadCalibration = true; bValidArg = true; } if (!bValidArg) { sprintf(pHint, "don't know argument %s", argv[nArg]); ExitWithHint(pHint); } nArg++; } if (sFTCC.bVerbose) { printf("\n\rambient temperature = %2.1f\n\r", nTemp); ftcc_print(&sFTCC); } tas2557_ftc(nTemp, &sFTCC); return 0; }