comparison gsm-fw/services/etm/etm_task.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 etm.c
4 *
5 * @author Kim T. Peteren (ktp@ti.com)
6 * @version 0.1
7 *
8
9
10 *
11 * History:
12 *
13 * Date Modification
14 * ------------------------------------
15 * 16/06/2003 Creation
16 * 03/03/2004 Upadted regarding the ATP + minor ETM DB handling updates
17 * 28/07/2004 Fixed ETM database issue
18 *
19 * (C) Copyright 2003 by Texas Instruments Incorporated, All Rights Reserved
20 *********************************************************************************/
21
22
23 #include "etm/etm.h"
24 #include "etm/etm_api.h"
25 #include "etm/etm_messages_i.h"
26 #include "etm/etm_trace.h"
27 #include "etm/etm_env.h"
28
29 #include "audio/audio_api.h"
30
31 #include "rv/rv_general.h"
32 #include "rvf/rvf_api.h"
33 #include "rvt/rvt_gen.h"
34 #include "rvf/rvf_target.h"
35 #include "rv/rv_defined_swe.h"
36
37 #include <string.h>
38
39 #ifdef RVM_LCC_SWE
40 #include "lcc/lcc_api.h"
41 #include "lcc/lcc_cfg_i.h"
42 #include "lcc/lcc.h"
43 #include "lcc/lcc_env.h"
44 #include "lcc/lcc_trace.h"
45 #endif
46
47 // Version of the ETM TASK moved to etm_version.h
48 //const uint16 etm_task_revision = (1<<12) | (0x1);
49
50 /******************************************************************************
51 * Globals
52 *****************************************************************************/
53
54 #define ETM_DB_MAX 16 // Limited of registered SWEntities into ETM DB
55 #define ETM_DB_NO_USE 0xFFFFFFFF //
56
57 typedef struct
58 {
59 char swe_name[ETM_NAME_MAX_LEN];
60 int mid;
61 int task_id;
62 T_RVF_ADDR_ID addr_id; // Unique mailbox (ID) of the SWE which will
63 //receive the message
64 ETM_CALLBACK_FUNC rx_callback_func;
65 } T_ETM_USER_DB;
66
67
68 static T_ETM_USER_DB etm_user_db[ETM_DB_MAX];
69
70 static int etm_db_counter = 0;
71
72
73 /******************************************************************************
74 * Prototypes
75 *****************************************************************************/
76
77 extern T_ETM_ENV_CTRL_BLK *etm_env_ctrl_blk;
78 #ifdef RVM_LCC_SWE
79 extern T_PWR_CTRL_BLOCK *pwr_ctrl;
80 #endif
81
82 int etm_database_manager(T_RV_HDR *msg_p);
83 int etm_forward_packet(int mid, T_RV_HDR *msg);
84 void etm_error_packet_send(int mid, int error);
85 void etm_receive(unsigned char *inbuf, unsigned short size);
86 int etm_ffs_pkt_receive(uint8 *data, int size);
87
88 extern int etm_at_atp_message(void *msg);
89 #ifdef RVM_LCC_SWE
90 extern int etm_pwr_ul(void *msg);
91 extern int etm_pwr_dl(T_ETM_PKT *pkt, uint8 *buf, int insize);
92 #endif
93
94 /******************************************************************************
95 * Main Testmode Task Loop
96 *****************************************************************************/
97
98 T_RV_RET etm_task(void)
99 {
100 extern int etm_core_init(void);
101 extern int etm_audio_init(void);
102 #ifdef RVM_LCC_SWE
103 extern int etm_pwr_init(void);
104 #endif
105
106 T_RV_HDR *msg = NULL;
107 T_ETM_PKT *pkt = NULL;
108 UINT32 start_time = 0;
109 UINT32 end_time = 0;
110 UINT16 recv_event, i;
111
112 int status = RV_OK, buf_size;
113
114 /* Entity registration to ETM */
115 /* This should be in the individual SWE init. function*/
116 status = etm_core_init();
117 status = etm_audio_init();
118 #ifdef RVM_LCC_SWE
119 status = etm_pwr_init();
120 #endif
121
122 while (1)
123 {
124 recv_event = rvf_wait(0xffff,0); /* Wait (infinite) for all events. */
125
126 start_time = rvf_get_tick_count();
127 tr_etm(TgTrEtmLow,"ETM: _task: Time Waiting (%d) tick", start_time - end_time);
128 tr_etm(TgTrEtmLow,"ETM: _task: Time Start(%d)", start_time);
129
130 tr_etm(TgTrEtmLow,"ETM: _task: Got message passing to bit filter (0x%x)", recv_event);
131
132
133 if (!(recv_event & RVF_TASK_MBOX_0_EVT_MASK))
134 continue;
135
136 /* Read the message in the ETM mailbox */
137 if ((msg = rvf_read_mbox(ETM_MAILBOX)) == NULL)
138 continue;
139
140 tr_etm(TgTrEtmLow,"ETM: _task: msg_id(0x%x)", msg->msg_id);
141
142 switch (msg->msg_id) {
143 /* Entity registration request or unregistration */
144 case ETM_REGISTER_REQ:
145 case ETM_UNREGISTER:
146 status = etm_database_manager(msg);
147 break;
148 /* ETM packet received */
149 case ETM_DATA_FWR:
150 if ((status = etm_forward_packet(((T_ETM_DATA_FWR *) msg)->mid, msg))
151 != ETM_OK)
152 etm_error_packet_send(((T_ETM_DATA_FWR *) msg)->mid, status);
153 break;
154 /* TM3 packet received */
155 case ETM_TM3_DATA_FWR:
156 if ((status = etm_forward_packet(ETM_TM3, msg)) != ETM_OK)
157 etm_error_packet_send(ETM_TM3, status);
158 break;
159 default:
160 tr_etm(TgTrEtmLow,"ETM: _task: msg_id '0x%x' NOT supported",
161 msg->msg_id);
162 }
163
164 if (status != ETM_OK) {
165 tr_etm(TgTrFatal,"ETM: _task: mid(0x%x) ERROR(%d)",
166 ((T_ETM_DATA_FWR *) msg)->mid, status);
167 etm_free(msg); // Free the message
168 }
169
170 end_time = rvf_get_tick_count();
171 tr_etm(TgTrEtmLow,"ETM: _task: Time End (%d)", end_time);
172 tr_etm(TgTrEtmLow,"ETM: _task: Time Total (%d) tick", end_time - start_time);
173 }
174
175 return RV_OK;
176 }
177
178
179 void etm_error_packet_send(int mid, int error)
180 {
181 T_ETM_PKT *pkt;
182
183 tr_etm(TgTrFatal,"ETM: _error_packet_send: Module(0x%x) ERROR(%d)", mid, error);
184
185 if (error == ETM_NOMEM) {
186 rvf_dump_mem();
187 }
188
189 if ((pkt = (T_ETM_PKT *) etm_malloc(sizeof(T_ETM_PKT))) == NULL) {
190 rvf_dump_mem();
191 return;
192 }
193
194 // Init. of return packet
195 pkt->mid = mid;
196 pkt->status = -error;
197 pkt->size = 0;
198 pkt->index = 0;
199
200 etm_pkt_send(pkt);
201 etm_free(pkt); // Free return packet
202 }
203
204
205 /* Forwarding of DATA to the SWE can either be done by message/primitive or callback */
206 int etm_forward_packet(int mid, T_RV_HDR* msg)
207 {
208 ETM_CALLBACK_FUNC rx_callback_func = NULL;
209 int i, cid, status = ETM_OK;
210 T_ETM_DATA_READY* message_p;
211 T_RVF_ADDR_ID swe_addr_id = 0;
212
213 // Search for supported MID in the table
214 for (i = 0; etm_user_db[i].mid != TABLE_END; i++)
215 {
216 tr_etm(TgTrEtmLow,"ETM: _forward_packet: Lookup in db for mid(0x%x)", mid);
217
218 if (etm_user_db[i].mid == mid) {
219 rx_callback_func = etm_user_db[i].rx_callback_func;
220 swe_addr_id = etm_user_db[i].addr_id;
221 break;
222 }
223 }
224
225 tr_etm(TgTrEtmLow,"ETM: _forward_packet: rx_callback_func(%d) swe_addr_id(%d)",
226 *rx_callback_func, swe_addr_id);
227
228 // Invoke the SWE mailbox
229 if (swe_addr_id) {
230 /* Allocate the memory for the message to send */
231 if ((message_p = (T_ETM_DATA_READY*) etm_malloc(sizeof(T_ETM_DATA_READY))) == NULL)
232 return ETM_NOMEM;
233
234 /* Fill the header of the message */
235 message_p->header.msg_id = ETM_DATA_READY;
236
237 /* Fill the address source id */
238 message_p->header.src_addr_id = rvf_get_taskid();
239 message_p->header.dest_addr_id = etm_env_ctrl_blk->addr_id;
240 message_p->header.callback_func = NULL;
241
242 /* Fill the data in the message */
243 memcpy(((T_ETM_DATA_READY*) message_p)->data, ((T_ETM_DATA_FWR*) msg)->data,
244 ((T_ETM_DATA_FWR*) msg)->size);
245
246 /* Send the message to the entity */
247 if ((status = rvf_send_msg(swe_addr_id, message_p)) != RV_OK) {
248 tr_etm(TgTrFatal,"ETM: _forward_packet: Failed to sent message - ERROR(%d)",
249 status);
250 return ETM_RV_FATAL;
251 }
252 etm_free(msg); // Free the message
253 }
254 // Invoke the SWE callback function
255 else if (rx_callback_func) {
256 tr_etm(TgTrEtmLow,"ETM: _forward_packet: to mid(0x%x)", mid);
257 status = rx_callback_func (((T_ETM_DATA_FWR*) msg)->data, ((T_ETM_DATA_FWR*) msg)->size);
258 rx_callback_func = NULL;
259 if (status != ETM_OK)
260 return status;
261 etm_free(msg); // Free the message
262 }
263 else {
264 return ETM_NOSYS;
265 }
266
267 return ETM_OK;
268 }
269
270
271 /******************************************************************************
272 * Get and Free buffer (Internal Functions)
273 *****************************************************************************/
274
275 void *etm_malloc(int size)
276 {
277 /* Memory bank status (red, yellow, green) */
278 T_RVF_MB_STATUS mb_status;
279 void *addr;
280
281 mb_status = rvf_get_buf(etm_env_ctrl_blk->prim_id, size, &addr);
282
283 /* The flag returned by rvf_get_buf is red, there is not enough
284 * memory to allocate the buffer. */
285 if (mb_status == RVF_RED) {
286 tr_etm(TgTrFatal, "ETM: _malloc: Error to get memory");
287 return NULL;
288 }
289 /* The flag is yellow, there will soon be not enough memory anymore. */
290 else if (mb_status == RVF_YELLOW) {
291 tr_etm(TgTrFatal, "ETM: _malloc: Getting short on memory");
292 }
293
294 tr_etm(TgTrEtmLow,"ETM: _malloc: size(%d) at addr(0x%x)", size, addr);
295 return addr;
296 }
297
298 int etm_free(void *addr)
299 {
300 int status;
301
302 tr_etm(TgTrEtmLow,"ETM: _free: addr(0x%x)", addr);
303
304 if ((status = rvf_free_buf(addr)) != RV_OK) {
305 tr_etm(TgTrFatal, "ETM: _free: ERROR(%d)", status);
306 }
307
308 return ETM_RV_FATAL;
309 }
310
311
312 /******************************************************************************
313 * ETM receive Functions API (Internal Functions)
314 ******************************************************************************/
315
316 /* The input pointer buf point at a complete TM3 packet. */
317 int etm_tm3_data_forward(uint8 *buf, int size)
318 {
319 /* Type for a registration event. */
320 T_ETM_TM3_DATA_FWR *msg;
321
322 tr_etm(TgTrEtmLow, "ETM: _tm3_data_forward: cid(0x%x) size(%d)", *buf, size);
323
324 /* Allocate the memory for the message to send */
325 if ((msg = (T_ETM_TM3_DATA_FWR*) etm_malloc(sizeof(T_ETM_TM3_DATA_FWR))) == NULL)
326 return ETM_NOMEM;
327
328 /* Fill the message id */
329 msg->header.msg_id = ETM_TM3_DATA_FWR;
330
331 /* Fill the address source id */
332 msg->header.src_addr_id = rvf_get_taskid();
333 msg->header.dest_addr_id = etm_env_ctrl_blk->addr_id;
334 msg->header.callback_func = NULL;
335
336 /* Fill the message parameters */
337 msg->size = size;
338 msg->cid = *buf;
339 memcpy(&msg->data, buf, size);
340
341 // At this point, all the data have been parsed and copied into
342 // the ETM primitive. Now we send the primitive to the ETM task.
343 if (rvf_send_msg(etm_env_ctrl_blk->addr_id, msg) != RV_OK) {
344 tr_etm(TgTrFatal, "ETM: _tm3_data_forward: FAILED");
345 return ETM_RV_FATAL; // msg is auto freed by rvf_send_msg() if error
346 }
347
348 return ETM_OK;
349 }
350
351
352 /* The input pointer buf point at payload of the TM packet, minus mid and cksum. */
353 int etm_data_forward(char mid, uint8 *inbuf, int size)
354 {
355 /* Type for a registration event. */
356 T_ETM_DATA_FWR *msg;
357
358 tr_etm(TgTrEtmLow, "ETM: _data_forward: mid(0x%x) size(%d)", mid, size);
359
360 /* Allocate the memory for the message to send */
361 if ((msg = (T_ETM_DATA_FWR*) etm_malloc(sizeof(T_ETM_DATA_FWR))) == NULL)
362 return ETM_NOMEM;
363
364 /* Fill the message id */
365 msg->header.msg_id = ETM_DATA_FWR;
366
367 /* Fill the address source id */
368 msg->header.src_addr_id = rvf_get_taskid();
369 msg->header.dest_addr_id = etm_env_ctrl_blk->addr_id;
370 msg->header.callback_func = NULL;
371
372 /* Fill the message parameters */
373 msg->size = size;
374 msg->mid = mid;
375 memcpy(&msg->data, inbuf, size);
376
377 // At this point, all the data have been parsed and copied into
378 // the ETM primitive. Now we send the primitive to the ETM task.
379 if (rvf_send_msg(etm_env_ctrl_blk->addr_id, msg) != RV_OK) {
380 tr_etm(TgTrFatal, "ETM: _data_forward: FAILED");
381 return ETM_RV_FATAL; // msg is auto freed by rvf_send_msg() if error
382 }
383
384 return ETM_OK;
385 }
386
387
388 /* This function is registred in the RVT module as the TestMode receive function */
389 /* It's called every time a TestMode packet is received on the UART and the */
390 /* data is forwarded to the ETM Entity via a message/primitiv */
391 /* The function is a callback func. used by the RVT TASK -> UART RX. */
392
393 void etm_receive(uint8 *inbuf, unsigned short size)
394 {
395 int error = ETM_NOSYS, i, index;
396 char mid;
397 unsigned char cksum;
398 T_ETM_PKT *pkt;
399
400 tr_etm(TgTrEtmLow, "ETM: _receive: inbuf size(%d)", size);
401
402 // Copy data payload size (size minus MID/CID byte and checksum byte)
403 mid = *inbuf++;
404
405 cksum = mid;
406 for (i = 0; i < size - 1; i++) {
407 cksum ^= inbuf[i];
408 }
409
410 if (cksum != 0) {
411 error = ETM_PACKET;
412 goto ETM_RECEIVE_END;
413 }
414
415 // Check it's a TM3 packet
416 if ((0x20 <= mid && mid < 0x27) ||
417 (0x30 <= mid && mid < 0x3A) ||
418 (0x40 <= mid && mid < 0x49) ||
419 (0x50 <= mid && mid < 0x57)) {
420 // Forward complete TM3 packet
421 error = etm_tm3_data_forward(--inbuf, size);
422 }
423 else {
424 /* Controlling of receptor for regisration */
425 for (index=0; index < etm_db_counter; index++)
426 {
427 if (etm_user_db[index].mid == mid) {
428 // Forward ETM packet without <mid> and <cksum>, -2 in size
429 error = etm_data_forward(mid, inbuf, size - 2);
430 break;
431 }
432 else if ((index == etm_db_counter) && (etm_user_db[index].mid != mid)) {
433 tr_etm(TgTrFatal, "ETM: _receive: mid(0x%x) not supported", mid);
434 }
435 }
436 }
437
438 ETM_RECEIVE_END:
439 /* Fill in Error status in ETM packet and send */
440 if (error) {
441 if (error == ETM_NOMEM) {
442 rvf_dump_mem();
443 return;
444 }
445
446 if ((pkt = (T_ETM_PKT *) etm_malloc(sizeof(T_ETM_PKT))) == NULL)
447 return;
448 pkt->size = 0;
449 pkt->mid = mid;
450 pkt->status = -error;
451
452 etm_pkt_send(pkt);
453 etm_free(pkt); // Free return Packet
454 }
455 }
456
457
458 /******************************************************************************
459 * Registration manager Functions API (Internal function)
460 ******************************************************************************/
461
462 int etm_database_add(T_ETM_REGISTER_REQ *msg_p, int index)
463 {
464
465 memcpy(etm_user_db[index].swe_name, msg_p->name, strlen(msg_p->name));
466 etm_user_db[index].mid = msg_p->mid;
467 etm_user_db[index].task_id = msg_p->task_id;
468 etm_user_db[index].addr_id = msg_p->addr_id;
469 etm_user_db[index].rx_callback_func = msg_p->rx_callback_func;
470
471 etm_user_db[index+1].mid = TABLE_END;
472
473 return ETM_OK;
474 }
475
476
477 int etm_database_manager(T_RV_HDR *msg_p)
478 {
479 int index, mid, status;
480
481 if (msg_p->msg_id == ETM_REGISTER_REQ) {
482 mid = ((T_ETM_REGISTER_REQ *) msg_p)->mid;
483
484 tr_etm(TgTrEtmLow,"ETM: _database_manager: _REGISTER_REQ reguest is received from (%s)",
485 ((T_ETM_REGISTER_REQ *) msg_p)->name);
486
487 /* Lookup in the ETM DB array */
488 for (index=0; index < ETM_DB_MAX; index++)
489 {
490 /* Use unregistrered space */
491 if ((etm_user_db[index].mid == ETM_DB_NO_USE) && (etm_user_db[index].addr_id == 0) &&
492 (etm_user_db[index].rx_callback_func == NULL)) {
493 status = etm_database_add((T_ETM_REGISTER_REQ*) msg_p, index);
494 etm_db_counter++;
495 etm_free(msg_p); // Free Message
496 return ETM_OK;
497 }
498 /* Reject double registration */
499 else if ((etm_user_db[index].mid == mid) &&
500 ((etm_user_db[index].addr_id != 0) || (etm_user_db[index].rx_callback_func != NULL))) {
501 tr_etm(TgTrFatal,"ETM: _database_manager: The Module(0x%x) is registrered", mid);
502 etm_free(msg_p); // Free Message
503 return ETM_OK;
504 }
505 }
506
507 /* Add the entity to the etm database */
508 if (etm_db_counter < ETM_DB_MAX) {
509 status = etm_database_add((T_ETM_REGISTER_REQ*) msg_p, etm_db_counter);
510 etm_db_counter++;
511 etm_free(msg_p); // Free Message
512 return ETM_OK;
513 }
514
515 etm_free(msg_p); // Free Message
516 return ETM_DB_LIMIT;
517 }
518
519
520 if (msg_p->msg_id == ETM_UNREGISTER) {
521 mid = ((T_ETM_UNREGISTER *) msg_p)->mid;
522 tr_etm(TgTrEtmLow,"ETM: _database_manager: _UNREGISTER reguest is received from (%s)",
523 ((T_ETM_REGISTER_REQ *) msg_p)->name);
524
525 /* Lookup in the array, if the SWE is stocked then clean it*/
526 for (index=0; index < ETM_DB_MAX; index++) {
527 if (etm_user_db[index].mid == mid) {
528 etm_user_db[index].mid = ETM_DB_NO_USE;
529 etm_user_db[index].addr_id = 0;
530 etm_user_db[index].rx_callback_func = NULL;
531 etm_db_counter--;
532 etm_free(msg_p); // Free Message
533 return ETM_OK;
534 }
535 }
536
537 etm_free(msg_p); // Free Message
538 return ETM_INVAL;
539 }
540
541 etm_free(msg_p); // Free Message
542 return ETM_OK;
543 }