FreeCalypso > hg > fc-tourmaline
view src/g23m-gsm/alr2/alr_em.c @ 287:3dee79757ae4
UI fw: load handheld audio mode on boot
We have now reached the point where use of audio mode config files
should be considered mandatory. In ACI usage we can tell users that
they need to perform an AT@AUL of some appropriate audio mode, but
in UI-enabled fw we really need to have the firmware load audio modes
on its own, so that correct audio config gets established when the
handset or development board runs on its own, without a connected host
computer.
Once have FC Venus with both main and headset audio channels and
headset plug insertion detection, our fw will need to automatically
load the handheld mode or the headset mode depending on the plug
insertion state. For now we load only the handheld mode, which has
been tuned for FC-HDS4 on FC Luna.
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sat, 13 Nov 2021 03:20:57 +0000 |
parents | 3a14ee9a9843 |
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 Module defines the engineering mode (EM) device driver for the | G23 protocol stack. This driver is used to control all engineering | mode related functions. +----------------------------------------------------------------------------- */ #ifndef ALR_EM_C #define ALR_EM_C #define ENTITY_PL /*==== INCLUDES ===================================================*/ #include <string.h> #include <stdlib.h> #include <ctype.h> #include "typedefs.h" #include "pconst.cdg" #include "mconst.cdg" #include "message.h" #include "ccdapi.h" #include "vsi.h" #include "custom.h" #include "gsm.h" #include "prim.h" #include "cnf_alr.h" #include "mon_alr.h" #include "pei.h" #include "tok.h" #include "pcm.h" #ifdef GPRS #include "alr_gprs.h" #endif #ifdef GPRS #ifdef _TARGET_ #include "inth/iq.h" #endif /* * obsolete (msb / 2002-04-25) #include "armio/armio.h" */ #endif #include "alr.h" #include "alr_em.h" /*==== IMPORT =====================================================*/ /*==== EXPORT =====================================================*/ /*==== PRIVAT =====================================================*/ /*==== VARIABLES ==================================================*/ #if defined (FF_EM_MODE) AND defined (ALR) /* Event tracing flags for EM */ GLOBAL BOOL alr_v[EM_MAX_ALR_EVENTS]; LOCAL UBYTE em_alr_trace_occured = 0; /* These variables are used between entities. Even this is not a clean solution it is a straigth forward way to reduce the overhead to a minimum. A clean solution would be based on an only usage of primitives which would stress the os with no aditional advantage!! */ GLOBAL volatile UBYTE em_l1_sem_buffer [EM_L1_SEM_SIZE]; /*lint -esym(765,em_l1_sem_buffer) | external could be made static | used externally */ GLOBAL volatile UBYTE em_l1_sem_index = 0; /*lint -esym(765,em_l1_sem_index) | external could be made static | used externally */ static T_HANDLE sem_EM_L1; #define ENTER_CRITICAL_SECTION(sem) if (alr_em_enter_critical_section(sem))return FALSE; #define LEAVE_CRITICAL_SECTION(sem) if (alr_em_leave_critical_section(sem))return FALSE; #endif /* FF_EM_MODE */ /*==== FUNCTIONS ==================================================*/ #if defined (FF_EM_MODE) AND defined (ALR) LOCAL UBYTE em_l1_sem (UBYTE length, UBYTE * data); LOCAL int em_l1_sem_clear (void); LOCAL void alr_em_first_event_check (void); /*Check for ACI - Notification*/ static void alr_em_semaphore_err (void); #if !defined(SYST_TRACE) #define SYST_TRACE(a) vsi_o_ttrace(0, TC_SYSTEM, a); #endif /* !SYST_TRACE */ static int alr_em_enter_critical_section (T_HANDLE sem); static int alr_em_leave_critical_section (T_HANDLE sem); /* +------------------------------------------------------------------------------ | Function : em_init_l1_event_trace +------------------------------------------------------------------------------ | Description : Initialize the event tracing flags | | Parameters : | | Return : | +------------------------------------------------------------------------------ */ GLOBAL void em_init_l1_event_trace(void) { UBYTE i; TRACE_FUNCTION("em_init_l1_event_trace ()"); for(i=0; i<EM_MAX_ALR_EVENTS; i++) alr_v[i] = 0; } /* +------------------------------------------------------------------------------ | Function : l1_em_l1_event_req +------------------------------------------------------------------------------ | Description : Set the event tracing flags according the bitmask | | Parameters : Primitive - Bitmask | | Return : | +------------------------------------------------------------------------------ */ GLOBAL const void l1_em_l1_event_req (T_EM_L1_EVENT_REQ *em_l1_event_req) { UBYTE i; TRACE_FUNCTION("l1_em_l1_event_req ()"); /* * The event tracing flags are set according the bitmask. alr_v[i] are * the flags belonging to the event number described in 8443.601 */ for(i=1; i<33; i++) { alr_v[i] = ((em_l1_event_req->bitmask_l1_l & (0x01<<(i-1))) > 0) ? TRUE : FALSE; } for(i=33; i<(EM_MAX_ALR_EVENTS); i++) { alr_v[i] = ((em_l1_event_req->bitmask_l1_h & (0x01<<(i-1))) > 0) ? TRUE : FALSE; } /* * A new event trace is generated therefor the flag is set to zero. */ em_alr_trace_occured = 0; PFREE(em_l1_event_req); } /* +------------------------------------------------------------------------------ | Function : em_write_buffer_2 +------------------------------------------------------------------------------ | Description : Perform buffer check and store corresponding data in it. | | Parameters : Event number | | Return : TRUE/FALSE | +------------------------------------------------------------------------------ */ GLOBAL UBYTE em_write_buffer_2 (UBYTE event_no) { UBYTE em_l1_event_buffer[2]; UBYTE em_l1_buffer_write = 0; UBYTE length = 2; TRACE_FUNCTION("alr_em_write_buffer_2 ()"); /* ACI is informed about the first event trace, used for later data processing. */ alr_em_first_event_check(); memset(em_l1_event_buffer, 0, 2); em_l1_event_buffer[em_l1_buffer_write++] = event_no; /* Event number */ em_l1_event_buffer[em_l1_buffer_write++] = length-2; /* Value length - 0 equals no data */ return (em_l1_sem (length, em_l1_event_buffer)); /* Data is stored inside buffer, reset flag */ } /* +------------------------------------------------------------------------------ | Function : em_write_buffer_3 +------------------------------------------------------------------------------ | Description : Perform buffer check and store corresponding data in it. | | Parameters : Event number, data value | | Return : TRUE/FALSE | +------------------------------------------------------------------------------ */ GLOBAL UBYTE em_write_buffer_3 (UBYTE event_no, UBYTE value) { UBYTE em_l1_event_buffer[3]; UBYTE em_l1_buffer_write = 0; UBYTE length = 3; TRACE_FUNCTION("alr_em_write_buffer_3 ()"); /* ACI is informed about the first event trace, used for later data processing. */ alr_em_first_event_check(); memset(em_l1_event_buffer, 0, 3); em_l1_event_buffer[em_l1_buffer_write++] = event_no; /* Event number */ em_l1_event_buffer[em_l1_buffer_write++] = length-2; /* Value length - 0 equals no value */ em_l1_event_buffer[em_l1_buffer_write++] = value; /* Data to be stored */ return (em_l1_sem (length, em_l1_event_buffer)); /* Data is stored inside buffer, reset flag */ } /* +------------------------------------------------------------------------------ | Function : em_write_buffer_3a +------------------------------------------------------------------------------ | Description : Perform buffer check and store corresponding data in it. | | Parameters : Event number, data value (USHORT) | | Return : TRUE/FALSE | +------------------------------------------------------------------------------ */ GLOBAL UBYTE em_write_buffer_3a (UBYTE event_no, USHORT value) { UBYTE em_l1_event_buffer[4]; UBYTE em_l1_buffer_write = 0; UBYTE length = 4; TRACE_FUNCTION("alr_em_write_buffer_4 ()"); /* ACI is informed about the first event trace, used for later data processing. */ alr_em_first_event_check(); memset(em_l1_event_buffer, 0, 4); em_l1_event_buffer[em_l1_buffer_write++] = event_no; /* Event number */ em_l1_event_buffer[em_l1_buffer_write++] = length-2; /* Value length - 0 equals no value */ em_l1_event_buffer[em_l1_buffer_write++] = (UBYTE)(value >> 8); /* Data to be stored - MSB first */ em_l1_event_buffer[em_l1_buffer_write++] = (UBYTE)(value); /* LSB second */ return (em_l1_sem (length, em_l1_event_buffer)); /* Data is stored inside buffer, reset flag */ } /* +------------------------------------------------------------------------------ | Function : em_write_buffer_4 +------------------------------------------------------------------------------ | Description : Perform buffer check and store corresponding data in it. | | Parameters : Event number, data value1 & value2 | | Return : TRUE/FALSE | +------------------------------------------------------------------------------ */ GLOBAL UBYTE em_write_buffer_4 (UBYTE event_no, UBYTE value1, UBYTE value2) { UBYTE em_l1_event_buffer[4]; UBYTE em_l1_buffer_write = 0; UBYTE length = 4; TRACE_FUNCTION("alr_em_write_buffer_4 ()"); /* ACI is informed about the first event trace, used for later data processing. */ alr_em_first_event_check(); memset(em_l1_event_buffer, 0, 4); em_l1_event_buffer[em_l1_buffer_write++] = event_no; /* Event number */ em_l1_event_buffer[em_l1_buffer_write++] = length-2; /* Value length - 0 equals no value */ em_l1_event_buffer[em_l1_buffer_write++] = value1; /* Data to be stored */ em_l1_event_buffer[em_l1_buffer_write++] = value2; /* Data to be stored */ return (em_l1_sem (length, em_l1_event_buffer)); /* Data is stored inside buffer, reset flag */ } /* +------------------------------------------------------------------------------ | Function : em_l1_sem_init +------------------------------------------------------------------------------ | Description : Initialize the semaphor for alr event traces. | | Parameters : void | | Return : void | +------------------------------------------------------------------------------ */ GLOBAL void em_l1_sem_init (void) { sem_EM_L1 = vsi_s_open (VSI_CALLER "EM_L1_SEM",1); if (sem_EM_L1 NEQ VSI_ERROR) em_l1_sem_clear (); else SYST_TRACE ("D1:canīt open semaphore \"EM_D1_SEM\""); } /* +------------------------------------------------------------------------------ | Function : em_l1_sem_exit +------------------------------------------------------------------------------ | Description : Close the semaphor for alr event traces. | | Parameters : void | | Return : void | +------------------------------------------------------------------------------ */ GLOBAL void em_l1_sem_exit (void) { if (sem_EM_L1 NEQ VSI_ERROR) vsi_s_close (VSI_CALLER sem_EM_L1); } /* +------------------------------------------------------------------------------ | Function : em_l1_sem_clear +------------------------------------------------------------------------------ | Description : Reset the index of the semaphor. | | Parameters : void | | Return : UBYTE | +------------------------------------------------------------------------------ */ LOCAL int em_l1_sem_clear (void) { ENTER_CRITICAL_SECTION (sem_EM_L1); em_l1_sem_index = 0; LEAVE_CRITICAL_SECTION (sem_EM_L1); SYST_TRACE ("L1:em_l1_sem_index cleared"); return TRUE; } /* +------------------------------------------------------------------------------ | Function : em_l1_sem_reset +------------------------------------------------------------------------------ | Description : Clears the content of the semaphor, must called after em_l1_sem_read. | | Parameters : void | | Return : UBYTE | +------------------------------------------------------------------------------ */ GLOBAL int em_l1_sem_reset (void) /*lint -esym(765,em_l1_sem_reset) | external could be made static | used externally */ { /* ENTER_CRITICAL_SECTION (sem_EM_L1); */ em_l1_sem_index = 0; LEAVE_CRITICAL_SECTION (sem_EM_L1); SYST_TRACE ("L1:em_l1_sem_index reseted"); return TRUE; } /* +------------------------------------------------------------------------------ | Function : em_l1_sem_read +------------------------------------------------------------------------------ | Description : Reads the content of the semaphor. | | Parameters : void | | Return : UBYTE | +------------------------------------------------------------------------------ */ GLOBAL int em_l1_sem_read (void) /*lint -esym(765,em_l1_sem_read) | external could be made static | used externally */ { USHORT semCount; TRACE_FUNCTION ("em_l1_sem_read()"); if (vsi_s_status (VSI_CALLER sem_EM_L1, &semCount) NEQ VSI_OK) { alr_em_semaphore_err(); return TRUE; } if (semCount EQ 0) { vsi_o_ttrace(VSI_CALLER TC_EVENT, "semCount = %d", semCount); SYST_TRACE ("semCount EQ 0"); return TRUE; } ENTER_CRITICAL_SECTION (sem_EM_L1); /* * The l1/alr semaphor will be read by the engineering mode via aci, * therefore the functions em_l1_sem_read and em_l1_sem_reset are defined * as global. To ensure that during reading only aci has access to the * semaphor the macro LEAVE_CRITICAL_SECTION is called after the read process * toke place - in the em_l1_sem_resest function. */ return TRUE; } /* Return value TRUE/FALSE - TRUE keeps the event flag valid, FALSE indicates a successful flag handle */ /* +------------------------------------------------------------------------------ | Function : em_l1_sem +------------------------------------------------------------------------------ | Description : Writes the data inside the semaphor. | | Parameters : void | | Return : UBYTE | +------------------------------------------------------------------------------ */ LOCAL UBYTE em_l1_sem (UBYTE length, UBYTE *data) { USHORT semCount; USHORT write_index; UBYTE i; TRACE_FUNCTION ("em_l1_sem()"); if (vsi_s_status (VSI_CALLER sem_EM_L1, &semCount) NEQ VSI_OK) { alr_em_semaphore_err(); return TRUE; } if (semCount EQ 0) { vsi_o_ttrace(VSI_CALLER TC_EVENT, "semCount = %d", semCount); SYST_TRACE ("semCount EQ 0"); return TRUE; } /* * buffer overflow protection */ if ( ((write_index = em_l1_sem_index) + length) > EM_L1_SEM_SIZE ) { TRACE_FUNCTION ("alr buffer full"); return FALSE; } ENTER_CRITICAL_SECTION(sem_EM_L1); for (i=0; i<length; i++) em_l1_sem_buffer[em_l1_sem_index++] = *(data++); LEAVE_CRITICAL_SECTION (sem_EM_L1); return FALSE; /* indicates that flag was handled */ } /* endfunc em_l1_sem */ /* +------------------------------------------------------------------------------ | Function : alr_em_semaphore_err +------------------------------------------------------------------------------ | Description : Semaphor error | | | Parameters : void | | Return : void | +------------------------------------------------------------------------------ */ static void alr_em_semaphore_err (void) { static UCHAR out = 0; if (!out) { out = 1; vsi_o_ttrace(VSI_CALLER TC_EVENT, "semaphore error"); } } /* +------------------------------------------------------------------------------ | Function : alr_em_enter_critical_section +------------------------------------------------------------------------------ | Description : Check on critical section entrance | | | Parameters : Handle | | Return : -1 semaphore error | 0 Ok. | +------------------------------------------------------------------------------ */ #if defined (NEW_FRAME) static int alr_em_enter_critical_section (T_HANDLE sem) #else static int alr_em_enter_critical_section (T_VSI_SHANDLE sem) #endif /* NEW_FRAME */ { if (vsi_s_get (VSI_CALLER sem) NEQ VSI_OK) { alr_em_semaphore_err(); return -1; } else { return 0; } }/* endfunc rr_enter_critical_section */ /* +------------------------------------------------------------------------------ | Function : alr_em_leave_critical_section +------------------------------------------------------------------------------ | Description : Check on critical section exit | | | Parameters : Handle | | Return : -1 semaphore error | 0 Ok. | +------------------------------------------------------------------------------ */ #if defined (NEW_FRAME) static int alr_em_leave_critical_section (T_HANDLE sem) #else static int alr_em_leave_critical_section (T_VSI_SHANDLE sem) #endif /* NEW_FRAME */ { if (vsi_s_release (VSI_CALLER sem) NEQ VSI_OK) { alr_em_semaphore_err(); return -1; } else { return 0; } }/* endfunc rr_leave_critical_section */ /* +------------------------------------------------------------------------------ | Function : alr_em_error_cause +------------------------------------------------------------------------------ | Description : Check the error cause and store it in the event buffer | | Parameters : Cause | | Return : None | +------------------------------------------------------------------------------ */ GLOBAL void alr_em_error_cause (UBYTE cause, USHORT arfcn) { switch(cause) { case CS_BCCH_READ_ERROR: { /* Power measurement request */ ALR_EM_BCCH_READ_ERROR; break; } case CS_DOWN_LINK_FAIL: { /* Downlink signalling failure */ ALR_EM_DOWNLINK_FAILURE; break; } case CS_NO_BCCH_AVAIL: { /* neighbourcell BCCH not available */ ALR_EM_NEIGHBOURCELL_BCCH(EM_NOT_AVAIL); break; } }/*switch*/ }/* alr_em_error_cause */ /* +------------------------------------------------------------------------------ | Function : alr_em_first_event_check() +------------------------------------------------------------------------------ | Description : Checks if first EM-Event ocured | | Parameters : None | | Return : None | +------------------------------------------------------------------------------ */ /* ACI is informed about the first event trace, used for later data processing. */ LOCAL void alr_em_first_event_check (void) { TRACE_FUNCTION("alr_em_first_event_check()"); if(em_alr_trace_occured EQ 0) { PALLOC(em_notification, EM_DATA_IND); em_notification->entity = EM_L1; PSENDX(MMI, em_notification); em_alr_trace_occured++; } }/* alr_em_first_event_check */ #endif /* FF_EM_MODE */ #endif /* ALR_EM_C */