FreeCalypso > hg > freecalypso-sw
comparison gsm-fw/services/etm/etm_tmcore.c @ 164:d78219c43fbf
gsm-fw/services/etm: initial import from the Leonardo semi-src
author | Michael Spacefalcon <msokolov@ivan.Harhan.ORG> |
---|---|
date | Mon, 18 Nov 2013 06:39:44 +0000 |
parents | |
children | 13af69b6a3dc |
comparison
equal
deleted
inserted
replaced
163:5e0e41cd7c9f | 164:d78219c43fbf |
---|---|
1 /******************************************************************************** | |
2 * Enhanced TestMode (ETM) | |
3 * @file tmcore.c | |
4 * | |
5 * @author Kim T. Peteren (ktp@ti.com) | |
6 * @version 0.1 | |
7 * | |
8 | |
9 * | |
10 * History: | |
11 * | |
12 * Date Modification | |
13 * ------------------------------------ | |
14 * 16/06/2003 Creation | |
15 * 02/07/2003 Removed l1_config.TestMode check from CODEC Write | |
16 * 17/03/2004 Updated etm_version | |
17 * 30/03/2004 Updated etm_dieID_read() func. regarding get die id for 16 bits | |
18 * instead of 8 bits. | |
19 * | |
20 * (C) Copyright 2003 by Texas Instruments Incorporated, All Rights Reserved | |
21 *********************************************************************************/ | |
22 | |
23 #include "rv/rv_defined_swe.h" | |
24 #include "rv/rv_general.h" | |
25 | |
26 #include "etm/etm.h" | |
27 #include "etm/etm_api.h" | |
28 #include "etm/etm_trace.h" | |
29 #include "etm/etm_version.h" | |
30 | |
31 #include "abb/abb.h" | |
32 | |
33 #include "spi/spi_drv.h" | |
34 extern void tr_etm_init(unsigned int mask); | |
35 | |
36 // Version of the ETM CORE module | |
37 // See the file etm_version.h | |
38 | |
39 /****************************************************************************** | |
40 * DIE ID settings | |
41 *****************************************************************************/ | |
42 | |
43 #define BE_STREAM_TO_ARRAY(a, p, l) {register INT32 i; for (i = 0; i < l; i++) a[i] = *(UINT8*)(p)++;} | |
44 | |
45 /* DIE ID register */ | |
46 #if ((CHIPSET == 8) || (CHIPSET == 10) || (CHIPSET == 11)) //For D-Sample: $CHIPSET = 8 (=10 for D-sample AMR, 11 for GSMLITE). | |
47 #define DIE_ID_REG (MEM_DEV_ID0 | 0xF010) //+ 0xFFFEF010 for Calypso | |
48 #else | |
49 #if (CHIPSET == 12) //For E-Sample: $CHIPSET = 12. | |
50 #define DIE_ID_REG (0xFFFE0000 | 0xF004) //+ 0xFFFEF004 for Calypso Plus | |
51 #endif | |
52 #endif | |
53 | |
54 /* DIE ID SIZE is 4 words (16 bits)long */ | |
55 #define DIE_ID_SIZE 4 | |
56 | |
57 //Copied from rv_general.h: | |
58 //#define BE_STREAM_TO_ARRAY(a, p, l) {register INT32 i; for (i = 0; i < l; i++) a[i] = *(UINT16*)(p)++;} | |
59 | |
60 | |
61 /****************************************************************************** | |
62 * Internal prototypes | |
63 *****************************************************************************/ | |
64 | |
65 T_ETM_PKT *etm_core_setup(uint8 fid); | |
66 int etm_core(uint8 *buf, int size); | |
67 | |
68 /****************************************************************************** | |
69 * Register the Core Module to the ETM database | |
70 *****************************************************************************/ | |
71 | |
72 int etm_core_init(void) | |
73 { | |
74 int result; | |
75 | |
76 result = etm_register("CORE", ETM_CORE, 0, 0, etm_core); | |
77 return result; | |
78 } | |
79 | |
80 | |
81 /****************************************************************************** | |
82 * Memory read/write Functions | |
83 *****************************************************************************/ | |
84 | |
85 // Describe the payload of the mem protocol !!!!!! | |
86 // |--type(1)-|--partnum(1)-|--addr(4)-|--data(?)-| | |
87 | |
88 int etm_mem(T_ETM_PKT *pkt, uint8 *buf) | |
89 { | |
90 int num, unitsize, error; | |
91 uint8 type, param; | |
92 uint8 *mem8; | |
93 uint16 *mem16; | |
94 uint32 *mem32; | |
95 uint32 addr, tmp; | |
96 static unsigned char test_buf[64]; | |
97 | |
98 param = unitsize = *buf & 0x3; | |
99 if (unitsize == 0) | |
100 unitsize = 4; | |
101 | |
102 type = *buf & 0x10; | |
103 buf++; | |
104 | |
105 num = *buf++; | |
106 addr = etm_get32(buf); | |
107 buf += 4; | |
108 | |
109 tr_etm(TgTrCore, "ETM CORE: _mem: type(0x%x) addr(0x%x) partnum(%d)", type, addr, num); | |
110 | |
111 // Put 'parameter' in return packet | |
112 if ((error = etm_pkt_put8(pkt, param)) < 0) { | |
113 return error; | |
114 } | |
115 | |
116 switch (type) { | |
117 case 0: // READ(0x00) | |
118 switch (unitsize) { | |
119 case 1: | |
120 mem8 = (uint8 *) addr; | |
121 while (num--) { | |
122 if ((error = etm_pkt_put8(pkt, *mem8++)) < 0) | |
123 break; | |
124 } | |
125 break; | |
126 case 2: | |
127 mem16 = (uint16 *) addr; | |
128 while (num--) { | |
129 if ((error = etm_pkt_put16(pkt, *mem16++)) < 0) | |
130 break; | |
131 } | |
132 break; | |
133 case 4: | |
134 mem32 = (uint32 *) addr; | |
135 while (num--) { | |
136 if ((error = etm_pkt_put32(pkt, *mem32++)) < 0) | |
137 break; | |
138 } | |
139 break; | |
140 } | |
141 break; | |
142 | |
143 case 16: // WRITE(0x10) | |
144 switch (unitsize) { | |
145 case 1: | |
146 mem8 = (uint8 *) addr; | |
147 while (num--) { | |
148 *mem8++ = etm_get8(buf); | |
149 buf += 1; | |
150 } | |
151 break; | |
152 case 2: | |
153 mem16 = (uint16 *) addr; | |
154 while (num--) { | |
155 *mem16++ = tmp = etm_get16(buf); | |
156 buf += 2; | |
157 } | |
158 break; | |
159 case 4: | |
160 mem32 = (uint32 *) addr; | |
161 while (num--) { | |
162 *mem32++ = etm_get32(buf); | |
163 buf += 4; | |
164 } | |
165 break; | |
166 } | |
167 break; | |
168 default: | |
169 return ETM_NOSYS; | |
170 } | |
171 | |
172 if (error < 0) | |
173 return error; | |
174 | |
175 return ETM_OK; | |
176 } | |
177 | |
178 | |
179 /****************************************************************************** | |
180 * CODEC Functions | |
181 *****************************************************************************/ | |
182 | |
183 // ETM sends both page value and register address in one byte. | |
184 // Bit field is: PPPR RRRR | |
185 // where P = page bit, R = register address bits and X = don't care bits. | |
186 | |
187 int etm_codec_write(T_ETM_PKT *pkt, uint8 *buf) | |
188 { | |
189 extern void ABB_Write_Register_on_page(SYS_UWORD16 page, SYS_UWORD16 reg_id, SYS_UWORD16 value); | |
190 uint16 page, reg, data; | |
191 int result, reg_data; | |
192 | |
193 reg_data = *buf++; | |
194 if ((result = etm_pkt_put8(pkt, reg_data)) < 0) | |
195 return result; | |
196 | |
197 page = (reg_data >> 5) & 0x3; | |
198 reg = reg_data & 0x1F; | |
199 data = etm_get16(buf); | |
200 | |
201 tr_etm(TgTrCore, "ETM CORE: _codec_write: page(%d) reg(%d) data(0x%x)", | |
202 page, reg, (data & 0x3ff)); | |
203 | |
204 if (page > 7 && reg > 32) | |
205 return ETM_INVAL; | |
206 else { | |
207 // The function below expects a 1 for page 0 and a 2 for page 1. | |
208 // The register address value is left-shifted by 1 since LSB is read/write command bit. | |
209 // The value is written in the 10 MSB's of register. | |
210 ABB_Write_Register_on_page(page + 1, reg << 1, (data & 0x3ff)); | |
211 } | |
212 | |
213 return ETM_OK; | |
214 } | |
215 | |
216 | |
217 int etm_codec_read(T_ETM_PKT *pkt, uint8 *buf) | |
218 { | |
219 extern SYS_UWORD16 ABB_Read_Register_on_page(SYS_UWORD16 page, SYS_UWORD16 reg_id); | |
220 volatile uint16 value; | |
221 uint16 page, reg; | |
222 int result, reg_data; | |
223 | |
224 reg_data = *buf; | |
225 if ((result = etm_pkt_put8(pkt, reg_data)) < 0) | |
226 return result; | |
227 | |
228 page = (reg_data >> 5) & 0x3; | |
229 reg = reg_data & 0x1F; | |
230 | |
231 if (page > 7 && reg > 32) | |
232 return ETM_INVAL; | |
233 | |
234 // The function below expects a 1 for page 0 and a 2 for page 1. | |
235 // The register value is left-shifted by 1 since LSB is read/write command bit. | |
236 value = ABB_Read_Register_on_page(page + 1, (reg << 1)); | |
237 | |
238 tr_etm(TgTrCore, "ETM CORE: _codec_read: page(%d) reg(%d) value(0x%x)", page, reg, value); | |
239 | |
240 result = etm_pkt_put16(pkt, value); | |
241 return result; | |
242 } | |
243 | |
244 | |
245 /****************************************************************************** | |
246 * Echo and Reset Functions | |
247 *****************************************************************************/ | |
248 | |
249 //structur of data dl: |delay|recvsize|num| = 3x2 bytes | |
250 int etm_echo(T_ETM_PKT *pkt, uint8 *data) | |
251 { | |
252 int delay, sendsize, i, num, count; | |
253 | |
254 tr_etm(TgTrCore, "etm_echo:"); | |
255 | |
256 delay = etm_get16(data); | |
257 data += 2; | |
258 | |
259 sendsize = etm_get16(data); | |
260 if (sendsize > 240) | |
261 return ETM_INVAL; | |
262 | |
263 data += 2; | |
264 num = etm_get16(data); | |
265 | |
266 tr_etm(TgTrCore, "ETM CORE: _echo: delay(%d) sendsize(%d) num(%d)", | |
267 delay, sendsize, num); | |
268 | |
269 if (delay > 0) { | |
270 rvf_delay((delay + 32) * 14 / 64); | |
271 } | |
272 | |
273 for (i = 0; i < sendsize; i++) { | |
274 pkt->data[i+1] = i; // data[0] = fid | |
275 } | |
276 | |
277 pkt->size = sendsize; | |
278 | |
279 return ETM_OK; | |
280 } | |
281 | |
282 | |
283 int etm_reset(void) | |
284 { | |
285 // The reset code is taken form Fluid->cmd.c | |
286 int i; | |
287 | |
288 tr_etm(TgTrCore, "ETM CORE: _reset: Target is Reset"); | |
289 | |
290 // Setup watchdog timer and let it timeout to make a reset | |
291 *(volatile uint16*) 0xfffff804 = 0xFFFF; // Timer to watchdog | |
292 *(volatile uint16*) 0xfffff800 = 0x0080; // Start timer | |
293 // Apparently works it only if we read this register? | |
294 i = *(volatile uint16*) 0xfffff802; | |
295 *(volatile uint16*) 0xfffff802 = 0x0001; // Load timer | |
296 | |
297 return ETM_OK; | |
298 } | |
299 | |
300 | |
301 /****************************************************************************** | |
302 * Set Test Controls | |
303 *****************************************************************************/ | |
304 | |
305 int etm_debug(T_ETM_PKT *pkt, uint8 *buf) | |
306 { | |
307 int type, error, data; | |
308 | |
309 static char *p; | |
310 | |
311 type = *buf & 0x0F; | |
312 buf++; | |
313 | |
314 data = etm_get32(buf); | |
315 | |
316 tr_etm(TgTrCore, "ETM CORE: _debug: type(%d) data(0x%x)", type, data); | |
317 | |
318 switch (type) { | |
319 case 0: // (0x00) Allocate Test Buffer | |
320 if ((p = etm_malloc(data)) == NULL) | |
321 error = ETM_NOMEM; | |
322 error = etm_pkt_put32(pkt, (int) p); | |
323 break; | |
324 case 1: // (0x01) Free Test Buffer. | |
325 p = (char *) data; | |
326 etm_free(p); | |
327 break; | |
328 case 2: // (0x02) Set ETM Trace mask | |
329 tr_etm_init(data); | |
330 break; | |
331 case 3: // (0x03) Set read all mem banks stat | |
332 rvf_dump_mem(); | |
333 rvf_dump_pool(); | |
334 rvf_dump_tasks(); | |
335 break; | |
336 default: | |
337 error = ETM_NOSYS; | |
338 } | |
339 | |
340 if (error < 0) | |
341 return error; | |
342 | |
343 return ETM_OK; | |
344 } | |
345 | |
346 /****************************************************************************** | |
347 * Get Version of ... | |
348 *****************************************************************************/ | |
349 // This is in development ... | |
350 | |
351 int etm_version(T_ETM_PKT *pkt, uint8 *buf) | |
352 { | |
353 extern uint16 etm_audio_revision; | |
354 extern uint16 etm_task_revision; | |
355 int error, fid, ffs_tm_version; | |
356 volatile int revision = 0; | |
357 T_VERSION *l1s_version; | |
358 | |
359 fid = etm_get32(buf); | |
360 | |
361 tr_etm(TgTrCore, "ETM CORE: _version: fid(0x%x)", fid); | |
362 | |
363 l1s_version = (T_VERSION*) l1s_get_version(); | |
364 | |
365 switch (fid) { | |
366 // Code Versions related to ETM modules | |
367 case SW_REV_ETM_CORE: | |
368 error = etm_pkt_put32(pkt, ETM_CORE_VERSION); | |
369 break; | |
370 case SW_REV_ETM_AUDIO: | |
371 error = etm_pkt_put32(pkt, ETM_AUDIO_VERSION); | |
372 break; | |
373 // case SW_REV_ETM_FFS: | |
374 // ffs_query(Q_FFS_TM_VERSION, &ffs_tm_version); | |
375 // error = etm_pkt_put32(pkt, ffs_tm_version); | |
376 break; | |
377 // case SW_REV_ETM_RF: // Layer1 Testmode Version | |
378 // error = etm_pkt_put32(pkt, TESTMODEVERSION); | |
379 // break; | |
380 case SW_REV_ETM_PWR: | |
381 error = etm_pkt_put32(pkt, ETM_PWR_VERSION); | |
382 break; | |
383 case SW_REV_ETM_BT: | |
384 error = ETM_NOSYS; | |
385 break; | |
386 case SW_REV_ETM_TASK: | |
387 error = etm_pkt_put32(pkt, ETM_VERSION); | |
388 break; | |
389 case SW_REV_ETM_API: | |
390 error = etm_pkt_put32(pkt, ETM_API_VERSION); | |
391 break; | |
392 // Code Versions related to L1, see in l1_defty.h | |
393 // Get the version on this way "revision = l1s.version.dsp_code_version;" | |
394 // doesn't work because of struct aligment -> compile flag -mw !!!! | |
395 case SW_DSP_CODE_VERSION: | |
396 revision = ((T_VERSION*) l1s_version)->dsp_code_version; | |
397 error = etm_pkt_put32(pkt, revision); | |
398 break; | |
399 case SW_DSP_PATCH_VERSION: | |
400 revision = ((T_VERSION*) l1s_version)->dsp_patch_version; | |
401 error = etm_pkt_put32(pkt, revision); | |
402 break; | |
403 case SW_MCU_TCS_PROGRAM_RELEASE: | |
404 revision = ((T_VERSION*) l1s_version)->mcu_tcs_program_release; | |
405 error = etm_pkt_put32(pkt, revision); | |
406 break; | |
407 case SW_MCU_TCS_OFFICIAL: // This version allso identify version of Layer1 | |
408 revision = ((T_VERSION*) l1s_version)->mcu_tcs_official; | |
409 error = etm_pkt_put32(pkt, revision); | |
410 break; | |
411 case SW_MCU_TCS_INTERNAL: | |
412 revision = ((T_VERSION*) l1s_version)->mcu_tcs_internal; | |
413 error = etm_pkt_put32(pkt, revision); | |
414 break; | |
415 case SW_MCU_TM_VERSION: | |
416 revision = ((T_VERSION*) l1s_version)->mcu_tm_version; | |
417 error = etm_pkt_put32(pkt, revision); | |
418 break; | |
419 default: | |
420 error = ETM_NOSYS; | |
421 } | |
422 | |
423 tr_etm(TgTrCore, "ETM CORE: _version: version(%d)", revision); | |
424 | |
425 if (error < 0) | |
426 return error; | |
427 | |
428 return ETM_OK; | |
429 } | |
430 | |
431 | |
432 /****************************************************************************** | |
433 * Function for reading the Die-ID from base band processor. | |
434 *****************************************************************************/ | |
435 | |
436 int etm_dieID_read(T_ETM_PKT *pkt, uint8 *inbuf) | |
437 { | |
438 T_RV_RET result; | |
439 int8 byteCount; | |
440 UINT16 dieID[DIE_ID_SIZE]; | |
441 int16 index; | |
442 volatile UINT16 *reg_p = (UINT16 *) DIE_ID_REG; | |
443 | |
444 tr_etm(TgTrCore, "ETM CORE: _dieID_read: started - Die-ID address(0x%x)", DIE_ID_REG); | |
445 | |
446 BE_STREAM_TO_ARRAY(dieID, reg_p, DIE_ID_SIZE); | |
447 | |
448 for (byteCount = 0; byteCount < DIE_ID_SIZE; byteCount++) { | |
449 | |
450 tr_etm(TgTrCore, "ETM CORE: Die-ID[%i] Byte Read(0x%x)", byteCount, (UINT16)dieID[byteCount]); | |
451 result = etm_pkt_put16(pkt, (UINT8)(((dieID[byteCount]) & 0xFFFF))); | |
452 if (result < 0) | |
453 return result; | |
454 } | |
455 | |
456 | |
457 return ETM_OK; | |
458 } | |
459 | |
460 | |
461 /****************************************************************************** | |
462 * ETM CORE Main Function - Module | |
463 *****************************************************************************/ | |
464 | |
465 int etm_core(uint8 *buf, int size) | |
466 { | |
467 // Structur of protocol data dl-link: |fid|index|data| | |
468 | |
469 uint8 mid; | |
470 uint8 fid; | |
471 int error = 0; | |
472 T_ETM_PKT *pkt = NULL; | |
473 | |
474 fid = *buf++; | |
475 | |
476 tr_etm(TgTrCore, "ETM CORE: _core: fid(%c):", fid); | |
477 | |
478 /* Create TestMode return Packet */ | |
479 if ((pkt = (T_ETM_PKT *) etm_malloc(sizeof(T_ETM_PKT))) == NULL) { | |
480 return ETM_NOMEM; | |
481 } | |
482 | |
483 // Init. of return packet | |
484 pkt->mid = ETM_CORE; | |
485 pkt->status = ETM_OK; | |
486 pkt->size = 0; | |
487 pkt->index = 0; | |
488 etm_pkt_put8(pkt, fid); | |
489 | |
490 switch (fid) { | |
491 #ifdef RVM_ATP_SWE | |
492 case 0x60: // old 'G' | |
493 error = etm_at(pkt, (char *) buf); | |
494 break; | |
495 #endif | |
496 case 0x61: // old 'M' | |
497 error = etm_mem(pkt, buf); | |
498 break; | |
499 case 0x62: // old 'E' | |
500 error = etm_echo(pkt, buf); | |
501 break; | |
502 case 0x63: // old 'R' | |
503 error = etm_reset(); | |
504 break; | |
505 case 0x64: // old 'T' | |
506 error = etm_debug(pkt, buf); | |
507 break; | |
508 case 0x65: // old 'V' | |
509 error = etm_version(pkt, buf); | |
510 break; | |
511 case 0x66: // old 'C' | |
512 error = etm_codec_read(pkt, buf); | |
513 break; | |
514 case 0x67: // old 'D' | |
515 error = etm_codec_write(pkt, buf); | |
516 break; | |
517 case 0x68: // old 'd' | |
518 error = etm_dieID_read(pkt, buf); | |
519 break; | |
520 default: | |
521 tr_etm(TgTrCore,"ETM CORE: _core: fid ERROR"); | |
522 error = ETM_NOSYS; | |
523 break; | |
524 } | |
525 | |
526 if (error < 0) { | |
527 tr_etm(TgTrCore,"ETM CORE: _core: FAILED"); | |
528 pkt->status = -error; | |
529 } | |
530 | |
531 // etm_at(): send func. is controlled by primitive | |
532 if (fid == 'G' && error >= RV_OK) {} | |
533 else | |
534 etm_pkt_send(pkt); | |
535 | |
536 etm_free(pkt); | |
537 return ETM_OK; | |
538 } |