1 /*
2 ** =============================================================================
3 ** Copyright (c) 2016 Texas Instruments Inc.
4 **
5 ** This program is free software; you can redistribute it and/or modify it under
6 ** the terms of the GNU General Public License as published by the Free Software
7 ** Foundation; version 2.
8 **
9 ** This program is distributed in the hope that it will be useful, but WITHOUT
10 ** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 ** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12 **
13 ** You should have received a copy of the GNU General Public License along with
14 ** this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
15 ** Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 **
17 ** File:
18 ** factorytest.c
19 **
20 ** Description:
21 ** main program for TAS2555 factory test
22 **
23 ** =============================================================================
24 */
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <stdbool.h>
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 #include <string.h>
32 #include <fcntl.h>
34 #include "tas2557_ftc.h"
36 // ================================================================ Definitions
37 // Obtained from Speaker Manufacturer
38 #define SPK_T_MAX 100 // Speaker Maximum Temperature (C)
39 #define SPK_RE_TOL_PER 10 // Re +/- tolerance (%)
40 #define SPK_RE_ALPHA 0.0039 // Temperature coefficient alpha (1/K)
42 // Obtained from PurePath Console 3 (PPC3)
43 #define PPC3_RE0 7.41 // Re0 (ohm)
44 #define PPC3_FWARP 891
45 #define PPC3_BL 0.814
46 #define PPC3_MMS 0.0666
47 #define PPC3_RTV 46.5 // Rtv (K/W)
48 #define PPC3_RTM 78.2 // Rtm (K/W)
49 #define PPC3_RTVA 2460 // Rtva (K/W)
50 #define PPC3_SYSGAIN 9.35 // System Gain (V/FS)
51 #define PPC3_DEV_NONLIN_PER 1.5 // Device Non-linearity (%)
52 #define PPC3_PIG 1
54 #define DEV_A_I2C_ADDR 0x98
55 #define DEV_B_I2C_ADDR 0x9a
57 void ExitWithHint(char *pHint)
58 {
59 printf("factorytest: invalid command line: %s\n\r\n\r", pHint);
61 printf("usage: factorytest [-t temperature] [-c configuration file] [-l load calibration] [-v verbose]\n\r");
62 exit(-1);
63 }
65 void InitFTCC(struct TFTCConfiguration *pFTCC)
66 {
67 pFTCC->nCalibrationTime = 2000;
68 pFTCC->nPPC3_FS = 48000;
70 pFTCC->bVerbose = false;
71 pFTCC->bLoadCalibration = false;
73 pFTCC->nTSpkCharDevA.nSpkTMax = SPK_T_MAX;
74 pFTCC->nTSpkCharDevA.nSpkReTolPer = SPK_RE_TOL_PER;
75 pFTCC->nTSpkCharDevA.nSpkReAlpha = SPK_RE_ALPHA;
76 pFTCC->nTSpkCharDevA.nReHi = PPC3_RE0*1.15;
77 pFTCC->nTSpkCharDevA.nReLo = PPC3_RE0*0.85;
78 pFTCC->nTSpkCharDevA.nPPC3_Re0 = PPC3_RE0;
79 pFTCC->nTSpkCharDevA.nPPC3_FWarp = PPC3_FWARP;
80 pFTCC->nTSpkCharDevA.nPPC3_Bl = PPC3_BL;
81 pFTCC->nTSpkCharDevA.nPPC3_Mms = PPC3_MMS;
82 pFTCC->nTSpkCharDevA.nPPC3_RTV = PPC3_RTV;
83 pFTCC->nTSpkCharDevA.nPPC3_RTM = PPC3_RTM;
84 pFTCC->nTSpkCharDevA.nPPC3_RTVA = PPC3_RTVA;
85 pFTCC->nTSpkCharDevA.nPPC3_SysGain = PPC3_SYSGAIN;
86 pFTCC->nTSpkCharDevA.nPPC3_DevNonlinPer = PPC3_DEV_NONLIN_PER;
87 pFTCC->nTSpkCharDevA.nPPC3_PIG = PPC3_PIG;
88 pFTCC->nTSpkCharDevA.nDevAddr = DEV_A_I2C_ADDR;
90 pFTCC->nTSpkCharDevB.nSpkTMax = SPK_T_MAX;
91 pFTCC->nTSpkCharDevB.nSpkReTolPer = SPK_RE_TOL_PER;
92 pFTCC->nTSpkCharDevB.nSpkReAlpha = SPK_RE_ALPHA;
93 pFTCC->nTSpkCharDevB.nReHi = PPC3_RE0*1.15;
94 pFTCC->nTSpkCharDevB.nReLo = PPC3_RE0*0.85;
95 pFTCC->nTSpkCharDevB.nPPC3_Re0 = PPC3_RE0;
96 pFTCC->nTSpkCharDevB.nPPC3_FWarp = PPC3_FWARP;
97 pFTCC->nTSpkCharDevB.nPPC3_Bl = PPC3_BL;
98 pFTCC->nTSpkCharDevB.nPPC3_Mms = PPC3_MMS;
99 pFTCC->nTSpkCharDevB.nPPC3_RTV = PPC3_RTV;
100 pFTCC->nTSpkCharDevB.nPPC3_RTM = PPC3_RTM;
101 pFTCC->nTSpkCharDevB.nPPC3_RTVA = PPC3_RTVA;
102 pFTCC->nTSpkCharDevB.nPPC3_SysGain = PPC3_SYSGAIN;
103 pFTCC->nTSpkCharDevB.nPPC3_DevNonlinPer = PPC3_DEV_NONLIN_PER;
104 pFTCC->nTSpkCharDevB.nPPC3_PIG = PPC3_PIG;
105 pFTCC->nTSpkCharDevB.nDevAddr = DEV_B_I2C_ADDR;
106 }
108 unsigned int SkipCharacter(char *pData, char cCharacter, unsigned int nSize)
109 {
110 unsigned int nRIndex;
111 unsigned int nWIndex = 0;
113 for (nRIndex = 0; nRIndex < nSize; nRIndex++)
114 if (pData[nRIndex] != cCharacter) pData[nWIndex++] = pData[nRIndex];
116 return nWIndex;
117 }
119 unsigned int RemoveComments(char *pData, char cCharacter, unsigned int nSize)
120 {
121 unsigned int nRIndex;
122 unsigned int nWIndex = 0;
124 for (nRIndex = 0; nRIndex < nSize; nRIndex++)
125 {
126 if (pData[nRIndex] == cCharacter)
127 while ((nRIndex < nSize) && (pData[nRIndex] != '\r')) nRIndex++;
128 pData[nWIndex++] = pData[nRIndex];
129 }
131 return nWIndex;
132 }
134 void ReadValue(struct TFTCConfiguration *pFTCC, struct TSPKCharData *pSpk, char *pLine, char *pValue)
135 {
136 if (!strcmp(pLine, "CALIBRATION_TIME")) {pFTCC->nCalibrationTime = atoi(pValue); return;};
137 if (!strcmp(pLine, "FS_RATE")) {pFTCC->nPPC3_FS = atof(pValue); return;};
138 if (!strcmp(pLine, "SPK_T_MAX")) {pSpk->nSpkTMax = atof(pValue); return;};
139 if (!strcmp(pLine, "SPK_RE_TOL_PER")) {pSpk->nSpkReTolPer = atof(pValue); return;};
140 if (!strcmp(pLine, "PPC3_RE_ALPHA")) {pSpk->nSpkReAlpha = atof(pValue); return;};
141 if (!strcmp(pLine, "PPC3_RE0")) {pSpk->nPPC3_Re0 = atof(pValue); return;};
142 if (!strcmp(pLine, "PPC3_FWARP")) {pSpk->nPPC3_FWarp = atof(pValue); return;};
143 if (!strcmp(pLine, "PPC3_BL")) {pSpk->nPPC3_Bl = atof(pValue); return;};
144 if (!strcmp(pLine, "PPC3_MMS")) {pSpk->nPPC3_Mms = atof(pValue); return;};
145 if (!strcmp(pLine, "PPC3_RTV")) {pSpk->nPPC3_RTV = atof(pValue); return;};
146 if (!strcmp(pLine, "PPC3_RTM")) {pSpk->nPPC3_RTM = atof(pValue); return;};
147 if (!strcmp(pLine, "PPC3_RTVA")) {pSpk->nPPC3_RTVA = atof(pValue); return;};
148 if (!strcmp(pLine, "PPC3_SYSGAIN")) {pSpk->nPPC3_SysGain = atof(pValue); return;};
149 if (!strcmp(pLine, "PPC3_DEV_NONLIN_PER")) {pSpk->nPPC3_DevNonlinPer = atof(pValue); return;};
150 if (!strcmp(pLine, "PPC3_PIG")) {pSpk->nPPC3_PIG = atof(pValue); return;};
151 if (!strcmp(pLine, "RE_HI")) {pSpk->nReHi = atof(pValue); return;};
152 if (!strcmp(pLine, "RE_LO")) {pSpk->nReLo = atof(pValue); return;};
153 if (!strcmp(pLine, "DEV_ADDR")){
154 char *endptr;
155 pSpk->nDevAddr = strtol(pValue, &endptr, 16);
156 return;
157 };
158 }
160 void ftcc_print(struct TFTCConfiguration *pFTCC)
161 {
162 printf("factorytest configuration: \n\r");
164 printf(" CALIBRATION_TIME = %d\n\r", pFTCC->nCalibrationTime);
165 printf("Speaker A characterization data: \n\r");
167 printf(" SPKA SPK_T_MAX = %2.2f\n\r", pFTCC->nTSpkCharDevA.nSpkTMax);
168 printf(" SPKA SPK_RE_TOL_PER = %2.2f\n\r", pFTCC->nTSpkCharDevA.nSpkReTolPer);
169 printf(" SPKA SPK_RE_ALPHA = %2.4f\n\r\n\r", pFTCC->nTSpkCharDevA.nSpkReAlpha);
171 printf(" SPKA PPC3_RE0 = %2.2f\n\r", pFTCC->nTSpkCharDevA.nPPC3_Re0);
172 printf(" SPKA PPC3_FWARP = %2.2f\n\r", pFTCC->nTSpkCharDevA.nPPC3_FWarp);
173 printf(" SPKA PPC3_BL = %2.6f\n\r", pFTCC->nTSpkCharDevA.nPPC3_Bl);
174 printf(" SPKA PPC3_MMS = %2.6f\n\r", pFTCC->nTSpkCharDevA.nPPC3_Mms);
175 printf(" SPKA PPC3_RTV = %2.2f\n\r", pFTCC->nTSpkCharDevA.nPPC3_RTV);
176 printf(" SPKA PPC3_RTM = %2.2f\n\r", pFTCC->nTSpkCharDevA.nPPC3_RTM);
177 printf(" SPKA PPC3_RTVA = %2.2f\n\r", pFTCC->nTSpkCharDevA.nPPC3_RTVA);
178 printf(" SPKA PPC3_SYSGAIN = %2.2f\n\r", pFTCC->nTSpkCharDevA.nPPC3_SysGain);
179 printf(" SPKA PPC3_DEV_NONLIN_PER = %2.2f\n\r", pFTCC->nTSpkCharDevA.nPPC3_DevNonlinPer);
180 printf(" SPKA PPC3_PIG = %f\n\r", pFTCC->nTSpkCharDevA.nPPC3_PIG);
181 printf(" DEVA ADDR = 0x%x\n\r", pFTCC->nTSpkCharDevA.nDevAddr);
183 printf("Speaker B characterization data: \n\r");
185 printf(" SPKB SPK_T_MAX = %2.2f\n\r", pFTCC->nTSpkCharDevB.nSpkTMax);
186 printf(" SPKB SPK_RE_TOL_PER = %2.2f\n\r", pFTCC->nTSpkCharDevB.nSpkReTolPer);
187 printf(" SPKB SPK_RE_ALPHA = %2.4f\n\r\n\r", pFTCC->nTSpkCharDevB.nSpkReAlpha);
189 printf(" SPKB PPC3_RE0 = %2.2f\n\r", pFTCC->nTSpkCharDevB.nPPC3_Re0);
190 printf(" SPKB PPC3_FWARP = %2.2f\n\r", pFTCC->nTSpkCharDevB.nPPC3_FWarp);
191 printf(" SPKB PPC3_BL = %2.6f\n\r", pFTCC->nTSpkCharDevB.nPPC3_Bl);
192 printf(" SPKB PPC3_MMS = %2.6f\n\r", pFTCC->nTSpkCharDevB.nPPC3_Mms);
193 printf(" SPKB PPC3_RTV = %2.2f\n\r", pFTCC->nTSpkCharDevB.nPPC3_RTV);
194 printf(" SPKB PPC3_RTM = %2.2f\n\r", pFTCC->nTSpkCharDevB.nPPC3_RTM);
195 printf(" SPKB PPC3_RTVA = %2.2f\n\r", pFTCC->nTSpkCharDevB.nPPC3_RTVA);
196 printf(" SPKB PPC3_SYSGAIN = %2.2f\n\r", pFTCC->nTSpkCharDevB.nPPC3_SysGain);
197 printf(" SPKB PPC3_DEV_NONLIN_PER = %2.2f\n\r", pFTCC->nTSpkCharDevB.nPPC3_DevNonlinPer);
198 printf(" SPKB PPC3_PIG = %f\n\r", pFTCC->nTSpkCharDevB.nPPC3_PIG);
199 printf(" DEVB ADDR = 0x%x\n\r", pFTCC->nTSpkCharDevB.nDevAddr);
201 }
203 int ftcc_parse(struct TFTCConfiguration *pFTCC, struct TSPKCharData *pSpk, char *pData, unsigned int nSize)
204 {
205 unsigned int nRIndex = 0;
206 char *pLine;
207 char *pEqual;
208 double nTest;
210 nSize = SkipCharacter(pData, ' ', nSize);
211 nSize = RemoveComments(pData, ';', nSize);
213 pData[nSize] = 0;
215 pLine = strtok(pData, "\n\r");
217 // printf("ftcc_parse: pData = %s\n\r", pData);
219 // printf("ftcc_parse: size = %d, pLine = 0x%08x\n\r", nSize, pLine);
220 while (pLine) {
221 // printf("ftcc_parse: pLine = 0x%08x\n\r", pLine);
222 if (pLine[0]) {
223 printf("Line = %s\n\r", pLine);
224 pEqual = strstr(pLine, "=");
225 if ((pEqual) && (strlen(pEqual) > 1)) {
226 pEqual[0] = 0;
227 ReadValue(pFTCC, pSpk, pLine, pEqual + 1);
228 pEqual[0] = '=';
229 }
230 }
231 pLine = strtok(NULL, "\n\r");
232 }
234 return 0;
235 }
237 void LoadFTCC(char *pFileName, struct TFTCConfiguration *pFTCC, struct TSPKCharData *pSpk)
238 {
239 struct stat st;
240 char *pData;
241 int nFile;
243 // printf("LoadFTCC: %s\n\r", pFileName);
245 if (stat(pFileName, &st) < 0) ExitWithHint("configuration file doesn't exist");
247 pData = malloc(st.st_size);
248 if (!pData) ExitWithHint("cannot allocate memory for configuation file");
250 nFile = open(pFileName, O_RDONLY);
251 if (nFile < 0) ExitWithHint("cannot open configuration file");
253 read(nFile, pData, st.st_size);
254 close(nFile);
256 ftcc_parse(pFTCC, pSpk, pData, st.st_size);
258 free(pData);
259 }
261 int main(int argc, char *argv[])
262 {
263 double nTemp = 20.0;
264 int nArg = 1;
265 bool bValidArg;
266 bool bSpkChk = false;
267 char pHint[256];
268 struct TFTCConfiguration sFTCC;
270 printf("\nTI TAS2557 factory test calibration sequence V1.0\n");
272 InitFTCC(&sFTCC);
273 // printf("argc = %d\n\r", argc);
274 while (nArg < argc)
275 {
276 // printf("argv[%d] = %s: ", nArg, argv[nArg]);
277 bValidArg = false;
278 if (!strcmp(argv[nArg], "-t")) {
279 printf("nArg = %d, argc = %d\n\r", nArg, argc);
280 if (argc <= (nArg + 1))
281 ExitWithHint("temperature parameter is missing");
282 nTemp = atof(argv[nArg + 1]);
283 nArg++;
284 bValidArg = true;
285 }
287 if (!strcmp(argv[nArg], "-l")) {
288 // printf("found configuration file argument\n\r");
289 if (argc <= (nArg + 1))
290 ExitWithHint("configuration file name is missing");
291 LoadFTCC(argv[nArg + 1], &sFTCC, &(sFTCC.nTSpkCharDevA));
292 nArg++;
293 bValidArg = true;
294 }
296 if (!strcmp(argv[nArg], "-r")) {
297 // printf("found configuration file argument\n\r");
298 if (argc <= (nArg + 1)) ExitWithHint("configuration file name is missing");
299 LoadFTCC(argv[nArg + 1], &sFTCC, &(sFTCC.nTSpkCharDevB));
300 nArg++;
301 bValidArg = true;
302 }
304 if (!strcmp(argv[nArg], "-v")) {
305 sFTCC.bVerbose = true;
306 bValidArg = true;
307 }
309 if (!strcmp(argv[nArg], "-u")) {
310 sFTCC.bLoadCalibration = true;
311 bValidArg = true;
312 }
314 if (!strcmp(argv[nArg], "-m")) {
315 bSpkChk = true;
316 bValidArg = true;
317 }
319 if (!bValidArg) {
320 sprintf(pHint, "don't know argument %s", argv[nArg]);
321 ExitWithHint(pHint);
322 }
323 nArg++;
324 }
326 if (sFTCC.bVerbose) {
327 printf("\n\rambient temperature = %2.1f\n\r", nTemp);
328 ftcc_print(&sFTCC);
329 }
331 if (bSpkChk)
332 tas2557_chk(nTemp, &sFTCC);
333 else
334 tas2557_ftc(nTemp, &sFTCC);
335 return 0;
336 }