FreeCalypso > hg > fc-magnetite
view src/g23m-gsm/dl/dl_trace.c @ 685:3fb7384e820d
tpudrv12.h: FCDEV3B goes back to being itself
A while back we had the idea of a FreeCalypso modem family whereby our
current fcdev3b target would some day morph into fcmodem, with multiple
FC modem family products, potentially either triband or quadband, being
firmware-compatible with each other and with our original FCDEV3B. But
in light of the discovery of Tango modules that earlier idea is now being
withdrawn: instead the already existing Tango hw is being adopted into
our FreeCalypso family.
Tango cannot be firmware-compatible with triband OM/FCDEV3B targets
because the original quadband RFFE on Tango modules is wired in TI's
original Leonardo arrangement. Because this Leonardo/Tango way is now
becoming the official FreeCalypso way of driving quadband RFFEs thanks
to the adoption of Tango into our FC family, our earlier idea of
extending FIC's triband RFFE control signals with TSPACT5 no longer makes
much sense - we will probably never produce any new hardware with that
once-proposed arrangement. Therefore, that triband-or-quadband FCFAM
provision is being removed from the code base, and FCDEV3B goes back to
being treated the same way as CONFIG_TARGET_GTAMODEM for RFFE control
purposes.
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Thu, 24 Sep 2020 21:03:08 +0000 |
parents | 27a4235405c6 |
children |
line wrap: on
line source
/* +----------------------------------------------------------------------------- | Project : | Modul : +----------------------------------------------------------------------------- | Copyright 2002 Texas Instruments Berlin, AG | All rights reserved. | | This file is confidential and a trade secret of Texas | Instruments Berlin, AG | The receipt of or possession of this file does not convey | any rights to reproduce or disclose its contents or to | manufacture, use, or sell anything it may describe, in | whole, or in part, without the specific written consent of | Texas Instruments Berlin, AG. +----------------------------------------------------------------------------- | Purpose : This Modul defines the offline trace functions | for the component DL of the mobile station. +----------------------------------------------------------------------------- */ #ifndef DL_TRACE_C #define DL_TRACE_C #define ENTITY_DL /*==== INCLUDES ===================================================*/ #include "typedefs.h" #include <string.h> #include "vsi.h" #include "pconst.cdg" #include "custom.h" #include "gsm.h" #include "mon_dl.h" #include "prim.h" #include "pei.h" #include "tok.h" #include "ccdapi.h" #include "dl.h" /*==== EXPORT =====================================================*/ /*==== PRIVAT =====================================================*/ #if defined(DL_TRACE_ENABLED) #ifdef OPTION_MULTITHREAD #define TRACE_TYPE _ENTITY_PREFIXED(TRACE_TYPE) #define CHANNEL _ENTITY_PREFIXED(CHANNEL) #define STATES _ENTITY_PREFIXED(STATES) #endif /* OPTION_MULTITHREAD */ LOCAL const char* const STATES[] = { "INVALID", "DISABLED", "IDLE_DL", "SUSPENDED", "AWAITING_ESTABLISHMENT", "MULTI_FRAME_ESTABLISHED", "TIMER_RECOVERY", "AWAITING_RELEASE" }; LOCAL const char* const TRACE_TYPE[] = { "UL", "DL", "Ev", "St", "PL", "RR" }; LOCAL const char* const CH_TYPE[] = { " ", "SA", "SD", "FH", "FF", "CC", "BC", "PC", "PE", "CB", "BE" }; LOCAL const char SAPI_TYPE[] = { '0', '1', '2', '3', ' '}; LOCAL void array2hex (UBYTE *inarray, char *outarray, int size); #if !defined(DL_IMMEDIATE_TRACE) /*==== TEST TRACE ===================================================*/ #define TEST_ENTITY_DL /*==== VARIABLES ==================================================*/ /*==== FUNCTIONS ==================================================*/ /* * The Data Link Layer Trace is a cyclic buffer for * debugging layer 2 problems. * * The buffer will be initialized at startup and will * be filled by the function dl_trace() until it is full. * The size of the buffer is IDLE_TRACE_SIZE. * * The content is * * trace_type (uplink, downlink, event state, alr_event, rr_event) * Channel Type (SACCH, SDDCH, FACCH) * real system clock * State (DL states) * pending disc request * data (layer frame, eevnt strings, state) * * During IDLE mode (triggered by RX_PERIODIC_IND in ALR/TIL_main.c) * an output is written to as SYST trace. * (IDLE_TRACE_MAX_READED traces each trigger) */ #define IDLE_TRACE_SIZE 512 #define IDLE_TRACE_MAX_READED 16 #if (((IDLE_TRACE_SIZE-1) & (~IDLE_TRACE_SIZE)) == (IDLE_TRACE_SIZE-1)) #define POWER_OF_2 #pragma message("IDLE_TRACE_SIZE is power of 2") #else #pragma message("IDLE_TRACE_SIZE is NOT power of 2") #endif typedef struct { UBYTE trace_type; UBYTE ch_type; UBYTE sapi; T_TIME sysClock; UBYTE disc_request; UBYTE state; UBYTE data [MAX_L2_FRAME_SIZE]; } T_IDLE_TRACE_DATA; #ifdef OPTION_MULTITHREAD #define IDLE_Trace_buffer _ENTITY_PREFIXED(IDLE_Trace_buffer) #define IDLE_Trace_write_index _ENTITY_PREFIXED(IDLE_Trace_write_index) #define IDLE_Trace_read_index _ENTITY_PREFIXED(IDLE_Trace_read_index) #endif /* OPTION_MULTITHREAD */ GLOBAL T_IDLE_TRACE_DATA IDLE_Trace_buffer [IDLE_TRACE_SIZE]; GLOBAL USHORT IDLE_Trace_write_index = 0; GLOBAL USHORT IDLE_Trace_read_index = 0; LOCAL T_HANDLE sem_DL_TRC; GLOBAL void dl_trace_init (void) { sem_DL_TRC = vsi_s_open (VSI_CALLER "DL_IDLE_TRACE",1); if (sem_DL_TRC NEQ VSI_ERROR) dl_trace_clear (0); else SYST_TRACE ("DL:canīt open semaphore \"DL_IDLE_TRACE\""); } GLOBAL void dl_trace_exit (void) { if (sem_DL_TRC NEQ VSI_ERROR) vsi_s_close (VSI_CALLER sem_DL_TRC); } GLOBAL void dl_trace_clear () { dl_trace_read_all (0); /* first, get all remaining traces (if exists) */ ENTER_CRITICAL_SECTION (sem_DL_TRC); IDLE_Trace_write_index = IDLE_Trace_read_index = 0; LEAVE_CRITICAL_SECTION (sem_DL_TRC); TRACE_EVENT ("offline trace reset"); DL_OFFLINE_TRACE (TRACE_DL_EVENT, TRACE_CH_UNKNOWN, 0, "offline trace reset"); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6147) MODULE : DL_COM | | STATE : code ROUTINE : dl_trace | +--------------------------------------------------------------------+ PURPOSE : Fill in a trace. */ GLOBAL void dl_trace (UCHAR trace_type, UCHAR channel, UCHAR ch_type, UCHAR* data) { T_IDLE_TRACE_DATA* trace_data; USHORT write_index1, write_index2;/* trace_size must not be greater than 2 */ UBYTE trace_size; if (data) { #if defined (DISABLE_MEASREPORT_TRACE) if ((ch_type EQ L2_CHANNEL_SACCH) AND (data[2] EQ 0x01) AND (data[3] EQ 0x03) AND (data[4] EQ 0x49)) return; #endif /* DISABLE_MEASREPORT_TRACE */ #if defined (DISABLE_EMPTY_UI) if ((trace_type EQ TRACE_DOWNLINK) OR (trace_type EQ TRACE_UPLINK)) { if ((ch_type EQ L2_CHANNEL_SACCH) AND (data[3] EQ 0x03) AND (data[4] EQ 0x01)) return; else if ( (data[1] EQ 0x03) AND (data[2] EQ 0x01)) return; } #endif /* DISABLE_EMPTY_UI */ } TEST_SEMAPHORE (sem_DL_TRC); ENTER_CRITICAL_SECTION(sem_DL_TRC); trace_size = 1; if ((trace_type EQ TRACE_PL_EVENT) OR (trace_type EQ TRACE_RR_EVENT)) { if (data AND strlen ((char *)data) >= 23) trace_size = 2; } #if defined(POWER_OF_2) write_index1 = (IDLE_Trace_write_index + 1) & (IDLE_TRACE_SIZE - 1); /* if IDLE_TRACE_SIZE power of 2 */ write_index2 = (IDLE_Trace_write_index + trace_size) & (IDLE_TRACE_SIZE - 1); /* if IDLE_TRACE_SIZE power of 2 */ #else write_index1 = (IDLE_Trace_write_index + 1) % IDLE_TRACE_SIZE; /* if IDLE_TRACE_SIZE not power of 2 */ write_index2 = (IDLE_Trace_write_index + trace_size) % IDLE_TRACE_SIZE; /* if IDLE_TRACE_SIZE not power of 2 */ #endif /* POWER_OF_2 */ if ((write_index1 NEQ IDLE_Trace_read_index) AND (write_index2 NEQ IDLE_Trace_read_index)) { /* buffer is not full */ trace_data = &IDLE_Trace_buffer[IDLE_Trace_write_index]; trace_data->trace_type = trace_type; if ((trace_type EQ TRACE_PL_EVENT) OR (trace_type EQ TRACE_RR_EVENT)) { trace_data->state = trace_size; } else { GET_INSTANCE_DATA; trace_data->ch_type = ch_type; switch (channel) { case C_SACCH0: case C_DCCH0: trace_data->disc_request = dl_data->dcch0_disc_request; trace_data->state = dl_data->state [C_DCCH0]; trace_data->sapi = PS_SAPI_0; break; case C_DCCH3: trace_data->disc_request = dl_data->dcch3_disc_request; trace_data->state = dl_data->state [C_DCCH3]; trace_data->sapi = PS_SAPI_3; break; default: trace_data->disc_request = 0; trace_data->state = 0; trace_data->sapi = NOT_PRESENT_8BIT; break; } } vsi_t_time (VSI_CALLER &trace_data->sysClock); if (data) { memcpy (trace_data->data, data, MAX_L2_FRAME_SIZE); if ((trace_type NEQ TRACE_UPLINK) AND (trace_type NEQ TRACE_DOWNLINK)) { trace_data->data[MAX_L2_FRAME_SIZE-1] = 0; } if (trace_size EQ 2) { if (IDLE_Trace_write_index EQ (IDLE_TRACE_SIZE - 1))/* the last buffer index ? */ trace_data = &IDLE_Trace_buffer[0];/* -> overflow to the first buffer index */ else trace_data++; memcpy (trace_data->data, data+MAX_L2_FRAME_SIZE-1, MAX_L2_FRAME_SIZE-1); trace_data->data[MAX_L2_FRAME_SIZE-1] = 0; } } IDLE_Trace_write_index = write_index2; }/* endif buffer is not full */ LEAVE_CRITICAL_SECTION (sem_DL_TRC); #if defined(_SIMULATION_) dl_trace_read (0); #endif /* _SIMULATION_ */ } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6147) MODULE : DL_COM | | STATE : code ROUTINE : dl_trace_read | +--------------------------------------------------------------------+ PURPOSE : Fill in a trace. */ GLOBAL void dl_trace_read_all () { USHORT write_index, read_index; do { dl_trace_read (); ENTER_CRITICAL_SECTION (sem_DL_TRC); write_index = IDLE_Trace_write_index; read_index = IDLE_Trace_read_index; LEAVE_CRITICAL_SECTION (sem_DL_TRC); } while (read_index NEQ write_index); } GLOBAL void dl_trace_read () { T_IDLE_TRACE_DATA* trace_data; USHORT write_index, read_index, left; UBYTE trace_size; static char buffer[80]; UBYTE j, o, readed = 0; TEST_SEMAPHORE (sem_DL_TRC); ENTER_CRITICAL_SECTION (sem_DL_TRC); write_index = IDLE_Trace_write_index; read_index = IDLE_Trace_read_index; LEAVE_CRITICAL_SECTION (sem_DL_TRC); if (read_index EQ write_index) { #if defined (_TARGET_) AND !defined( GPRS ) AND defined(FF_GTI) sleep_mode (); #endif /* _TARGET_ AND !GPRS AND !FF_GTI */ return; } while (read_index NEQ write_index) { ENTER_CRITICAL_SECTION (sem_DL_TRC); trace_data = &IDLE_Trace_buffer[read_index]; LEAVE_CRITICAL_SECTION (sem_DL_TRC); #if defined(POWER_OF_2) left = (write_index - read_index - 1) & (IDLE_TRACE_SIZE-1); #else left = (IDLE_TRACE_SIZE + write_index - read_index - 1) % IDLE_TRACE_SIZE; #endif /* POWER_OF_2 */ if (trace_data->ch_type > ELEMENTS(CH_TYPE)) trace_data->ch_type = 0; if (trace_data->sapi >= ELEMENTS (SAPI_TYPE)) trace_data->sapi = ELEMENTS (SAPI_TYPE) - 1; trace_size = 1;/* default */ switch (trace_data->trace_type) { case TRACE_UPLINK: case TRACE_DOWNLINK: sprintf (buffer, "[%03d]:%07lu %c%d %s %s ", left, trace_data->sysClock, trace_data->disc_request?'D':' ', trace_data->state, TRACE_TYPE[trace_data->trace_type], CH_TYPE[trace_data->ch_type]); o = strlen (buffer); array2hex (trace_data->data, buffer+o, 23); break; case TRACE_DL_EVENT: sprintf (buffer, "[%03d]:%07lu %c%d Ev %s%c %s", left, trace_data->sysClock, trace_data->disc_request?'D':' ', trace_data->state, CH_TYPE[trace_data->ch_type], SAPI_TYPE[trace_data->sapi], trace_data->data); break; case TRACE_PL_EVENT: case TRACE_RR_EVENT: trace_size = trace_data->state; if (trace_size EQ 2) { T_IDLE_TRACE_DATA *trace_data2; if (read_index EQ (IDLE_TRACE_SIZE - 1))/* the last buffer index ? */ trace_data2 = &IDLE_Trace_buffer[0];/* -> overflow to the first buffer index */ else trace_data2 = trace_data+1; sprintf (buffer, "[%03d]:%07lu %d Ev %s %s%s", left, trace_data->sysClock, trace_data->state, TRACE_TYPE[trace_data->trace_type], trace_data->data, trace_data2->data); } else { sprintf (buffer, "[%03d]:%07lu %d Ev %s %s", left, trace_data->sysClock, trace_data->state, TRACE_TYPE[trace_data->trace_type], trace_data->data); } break; case TRACE_CHSTATE: sprintf (buffer, "[%03d]:%07lu %c%d ST %s%c state=%s", left, trace_data->sysClock, trace_data->disc_request?'D':' ', trace_data->state, CH_TYPE[trace_data->ch_type], SAPI_TYPE[trace_data->sapi], STATES[trace_data->state]); break; default: buffer[0] = 0; break; } if (buffer[0]) { SYST_TRACE (buffer); } else { SYST_TRACE ("dl_trace_read() failed"); } ENTER_CRITICAL_SECTION (sem_DL_TRC); trace_data->sysClock = 0; /* readed */ IDLE_Trace_read_index += trace_size; #if defined(POWER_OF_2) IDLE_Trace_read_index &= (IDLE_TRACE_SIZE-1);/* if power of 2 */ #else IDLE_Trace_read_index %= IDLE_TRACE_SIZE; /* if not power of 2 */ #endif /* POWER_OF_2 */ read_index = IDLE_Trace_read_index; write_index = IDLE_Trace_write_index; LEAVE_CRITICAL_SECTION (sem_DL_TRC); if (readed++ >= IDLE_TRACE_MAX_READED) break; }/* endwhile */ } #else /* DL_IMMEDIATE_TRACE */ #define IMM_TRACE_SIZE 2 typedef struct { UBYTE sapi; T_TIME sysClock; UBYTE disc_request; UBYTE state; UBYTE data [IMM_TRACE_SIZE*MAX_L2_FRAME_SIZE]; } T_TRACE_DATA; #ifdef OPTION_MULTITHREAD #define print_buffer _ENTITY_PREFIXED(print_buffer) #define trace_buffer _ENTITY_PREFIXED(trace_buffer) #endif /* OPTION_MULTITHREAD */ LOCAL char print_buffer[25+IMM_TRACE_SIZE*MAX_L2_FRAME_SIZE]; LOCAL T_TRACE_DATA trace_buffer; /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6147) MODULE : DL_COM | | STATE : code ROUTINE : dl_trace | +--------------------------------------------------------------------+ PURPOSE : Fill in a trace. */ GLOBAL void dl_fast_trace (UBYTE trace_type, UBYTE channel, UBYTE ch_type, T_TIME trace_time, ULONG trace_mask, UBYTE* data) { T_TRACE_DATA* trace_data; UBYTE o; /* While TC_USER2 is set, measurements and empty frames will be traced always */ if (data AND ((trace_mask & TC_USER2) EQ 0)) { if ((ch_type EQ L2_CHANNEL_SACCH) AND (data[2] EQ 0x01) AND (data[3] EQ 0x03) AND (data[4] EQ 0x49)) return; if ((trace_type EQ TRACE_DOWNLINK) OR (trace_type EQ TRACE_UPLINK)) { if ((ch_type EQ L2_CHANNEL_SACCH) AND (data[3] EQ 0x03) AND (data[4] EQ 0x01)) return; else if ( (data[1] EQ 0x03) AND (data[2] EQ 0x01)) return; } } trace_data = &trace_buffer; trace_data->sysClock = trace_time; if (!((trace_type EQ TRACE_PL_EVENT) OR (trace_type EQ TRACE_RR_EVENT))) { GET_INSTANCE_DATA; switch (channel) { case C_SACCH0: case C_DCCH0: trace_data->disc_request = dl_data->dcch0_disc_request; trace_data->state = dl_data->state [C_DCCH0]; trace_data->sapi = PS_SAPI_0; break; case C_DCCH3: trace_data->disc_request = dl_data->dcch3_disc_request; trace_data->state = dl_data->state [C_DCCH3]; trace_data->sapi = PS_SAPI_3; break; default: trace_data->disc_request = 0; trace_data->state = 0; trace_data->sapi = NOT_PRESENT_8BIT; break; } } if (data) { if ((trace_type EQ TRACE_UPLINK) OR (trace_type EQ TRACE_DOWNLINK)) { memcpy (trace_data->data, data, MAX_L2_FRAME_SIZE); } else { strncpy ((char *)trace_data->data, (char *)data, IMM_TRACE_SIZE*MAX_L2_FRAME_SIZE-1); trace_data->data[IMM_TRACE_SIZE*MAX_L2_FRAME_SIZE-1] = 0; } } else { trace_data->data[0] = 0; } if (ch_type > ELEMENTS(CH_TYPE)) ch_type = 0; if (trace_data->sapi >= ELEMENTS (SAPI_TYPE)) trace_data->sapi = ELEMENTS (SAPI_TYPE) - 1; switch (trace_type) { case TRACE_UPLINK: case TRACE_DOWNLINK: sprintf (print_buffer, "DLTRC:%07lu %c%d %s %s%c ", trace_data->sysClock, trace_data->disc_request?'D':' ', trace_data->state, TRACE_TYPE[trace_type], CH_TYPE[ch_type], SAPI_TYPE[trace_data->sapi]); o = strlen (print_buffer); array2hex (trace_data->data, print_buffer+o, 23); break; case TRACE_DL_EVENT: sprintf (print_buffer, "DLTRC:%07lu %c%d Ev %s%c %s", trace_data->sysClock, trace_data->disc_request?'D':' ', trace_data->state, CH_TYPE[ch_type], SAPI_TYPE[trace_data->sapi], trace_data->data); break; case TRACE_PL_EVENT: case TRACE_RR_EVENT: sprintf (print_buffer, "DLTRC:%07lu %d Ev %s %s", trace_data->sysClock, trace_data->state, TRACE_TYPE[trace_type], trace_data->data); break; case TRACE_CHSTATE: sprintf (print_buffer, "DLTRC:%07lu %c%d ST %s%c state=%s", trace_data->sysClock, trace_data->disc_request?'D':' ', trace_data->state, CH_TYPE[ch_type], SAPI_TYPE[trace_data->sapi], STATES[trace_data->state]); break; default: print_buffer[0] = 0; break; } TRACE_USER_CLASS (TC_USER1, print_buffer); #if 0 if (print_buffer[0]) { #if defined(_SIMULATION_) TRACE_EVENT_WIN (print_buffer); #else /* _SIMULATION_ */ SYST_TRACE_P ((DLTRC,print_buffer)); #endif /* _SIMULATION_ */ } #endif /* 0 */ } #endif /* DL_IMMEDIATE_TRACE */ LOCAL void array2hex (UBYTE *inarray, char *outarray, int size) { int col=0, n=0; UBYTE b, nh, nl; while (n < size) { b = inarray[n++]; nh = b>>4; nl = b&0x0f; outarray[col++] = nh > 9 ? nh + 'A' - 10 : nh + '0'; outarray[col++] = nl > 9 ? nl + 'A' - 10 : nl + '0'; } outarray[col] = 0; } #endif /* DL_TRACE_ENABLED */ #if defined (DL_TRACE_PFREE) GLOBAL void* my_pfree(void *pointer, int line, char *file) { char buffer[23]; sprintf (buffer, "%s#%u:%p", file+2, line, pointer); dl_trace (TRACE_DL_EVENT, TRACE_CH_UNKNOWN, buffer); if (pointer) { PFREE (pointer); } else { SYST_TRACE_P((SYST, "%s#%u: PFREE(NULL)", file, line)); } return NULL; } #endif /* DL_TRACE_PFREE */ #endif /* DL_TRACE_C */