view src/cs/layer1/dl1/dl1_com.c @ 303:f76436d19a7a default tip

!GPRS config: fix long-standing AT+COPS chance hanging bug There has been a long-standing bug in FreeCalypso going back years: sometimes in the AT command bring-up sequence of an ACI-only MS, the AT+COPS command would produce only a power scan followed by cessation of protocol stack activity (only L1 ADC traces), instead of the expected network search sequence. This behaviour was seen in different FC firmware versions going back to Citrine, and seemed to follow some law of chance, not reliably repeatable. This bug has been tracked down and found to be specific to !GPRS configuration, stemming from our TCS2/TCS3 hybrid and reconstruction of !GPRS support that was bitrotten in TCS3.2/LoCosto version. ACI module psa_mms.c, needed only for !GPRS, was missing in the TCS3 version and had to be pulled from TCS2 - but as it turns out, there is a new field in the MMR_REG_REQ primitive that needs to be set correctly, and that psa_mms.c module is the place where this initialization needed to be added.
author Mychaela Falconia <falcon@freecalypso.org>
date Thu, 08 Jun 2023 08:23:37 +0000
parents 4e78acac3d88
children
line wrap: on
line source

/*
 * This module contains the LISR and HISR glue functions for L1
 * which used to be in the dl1_com module in the Leonardo version.
 * The LoCosto source from which we got our L1 code no longer has a
 * dl1_com.c module, and the ISR glue functions in question have been
 * moved into csw-system/init_common/init.c - an incredibly messy C
 * module that is mostly devoted to LoCosto BSP initialization.
 *
 * The present C code has been extracted from LoCosto's init.c,
 * guided by the disassembly of dl1_com.obj from the Leonardo version.
 */

/* Include Files */
#include <assert.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "nucleus.h"

#include "l1_types.h"
#include "l1_confg.h"
#include "l1_const.h"

#if TESTMODE
  #include "l1tm_defty.h"
#endif // TESTMODE

#if (AUDIO_TASK == 1)
  #include "l1audio_const.h"
  #include "l1audio_cust.h"
  #include "l1audio_defty.h"
#endif // AUDIO_TASK

#if (L1_GTT == 1)
  #include "l1gtt_const.h"
  #include "l1gtt_defty.h"
#endif

#if (L1_MP3 == 1)
  #include "l1mp3_defty.h"
#endif

#if (L1_MIDI == 1)
  #include "l1midi_defty.h"
#endif

#if (L1_AAC == 1)
  #include "l1aac_defty.h"
#endif
#if (L1_DYN_DSP_DWNLD == 1)
  #include "l1_dyn_dwl_defty.h"
#endif

#if (TRACE_TYPE == 4)
  #include "l1_defty.h"
#endif

#include "armio.h"
#include "timer.h"

#include "iq.h"
#include "mem.h"
#include "clkm.h"
#include "inth.h"

/*
 * Timing monitor
 */
#if (TRACE_TYPE == 4)
  extern T_L1A_L1S_COM l1a_l1s_com;
  extern T_L1S_GLOBAL  l1s;
  UNSIGNED             max_cpu, fn_max_cpu;
  unsigned short       layer_1_sync_end_time;
  unsigned short       max_cpu_flag;
  #if (DSP >= 38)
  // DSP CPU load measurement trace variables
  UWORD32              dsp_max_cpu_load_trace_array[4];
  UWORD32              dsp_max_cpu_load_idle_frame;
  unsigned short       l1_dsp_cpu_load_trace_flag;
  #endif
#endif

#if (L1_EXT_AUDIO_MGT == 1)
  NU_HISR  EXT_AUDIO_MGT_hisr;
  char FAR ext_audio_mgt_hisr_stack[500];
  extern void Cust_ext_audio_mgt_hisr(void);
#endif

#if ( (L1_MP3 == 1) || (L1_MIDI == 1) || (L1_AAC == 1) || (L1_DYN_DSP_DWNLD == 1) )   // equivalent to an API_HISR flag
  extern void api_hisr(void);
  #ifdef __GNUC__
    #define SECTION_ATTR __attribute__ ((section (".API_HISR_stack")))
  #else
    #define SECTION_ATTR
    #pragma DATA_SECTION (API_HISR_stack,"API_HISR_stack");
  #endif
  char FAR API_HISR_stack[0x400] SECTION_ATTR;
  #undef SECTION_ATTR
  NU_HISR apiHISR;
#endif // (L1_MP3 == 1) || (L1_MIDI == 1) || (L1_DYN_DSP_DWNLD == 1)

#if (FF_L1_IT_DSP_USF == 1) || (FF_L1_IT_DSP_DTX == 1)
  char FAR API_MODEM_HISR_stack[0x400]; // stack size to be tuned
  NU_HISR api_modemHISR;
#endif // FF_L1_IT_DSP_USF

/*
 * HISR stack and semaphore needed by L1
 */
#if (OP_L1_STANDALONE == 0)
  #define LAYER_1_SYNC_STACK_SIZE	4000	/* matching Leonardo version */
  unsigned char layer_1_sync_stack[LAYER_1_SYNC_STACK_SIZE];
#else
  #if TESTMODE
    char FAR layer_1_sync_stack[2600 /*3600*/];   // Frame interrupt task stack for EVA3
  #else
    char FAR layer_1_sync_stack[1600 /* 2600 */];   // Frame interrupt task stack for EVA3
  #endif
#endif   /* OP_L1_STANDALONE */

NU_HISR  layer_1_sync_HISR;    // Frame interrupt task stack for EVA3

/* forward declaration */
void layer_1_sync_HISR_entry (void);

/*
 * l1_create_ISR
 *
 * Create L1 HISR.  This function is called from l1_pei.
 */
void l1_create_ISR (void)
{
  STATUS status;

  #if (OP_L1_STANDALONE == 0)
    // Fill the entire stack with the pattern 0xFE
    memset (layer_1_sync_stack, 0xFE, LAYER_1_SYNC_STACK_SIZE);
  #endif

  status = NU_Create_HISR (&layer_1_sync_HISR,
                           "L1_HISR",
                           layer_1_sync_HISR_entry,
  #if (OP_L1_STANDALONE == 0)
                           0,
                           layer_1_sync_stack,
                           LAYER_1_SYNC_STACK_SIZE);
  #else
                           0,
                           layer_1_sync_stack,
                           sizeof(layer_1_sync_stack));
  #endif

  #if (L1_EXT_AUDIO_MGT)
    // Create HISR for Ext MIDI activity
    //==================================
    status += NU_Create_HISR(&EXT_AUDIO_MGT_hisr,
                             "H_EXT_AUDIO_MGT",
                             Cust_ext_audio_mgt_hisr,
                             1,
                             ext_audio_mgt_hisr_stack,
                             sizeof(ext_audio_mgt_hisr_stack));
  #endif

  #if ( (L1_MP3 == 1) || (L1_MIDI == 1) || (L1_AAC == 1) || (L1_DYN_DSP_DWNLD == 1) )    // equivalent to an API_HISR flag
    status += NU_Create_HISR(&apiHISR,
                             "API_HISR",
                             api_hisr,
                             1,
                             API_HISR_stack,
                             sizeof(API_HISR_stack));
  #endif // (L1_MP3 == 1) || (L1_MIDI == 1) || (L1_AAC == 1) || (L1_DYN_DSP_DWNLD == 1)

  #if (FF_L1_IT_DSP_USF == 1) || (FF_L1_IT_DSP_DTX == 1) // equivalent to an API_MODEM_HISR flag
    // Create HISR for USF  DSP interrupt !!!!. This HISR needs
    // to have the highest priority since the USF status needs
    // to be known before the next block starts.
    //========================================================
    status += NU_Create_HISR(&api_modemHISR,
                             "MODEM",
                             api_modem_hisr,
                             0,
                             API_MODEM_HISR_stack,
                             sizeof(API_MODEM_HISR_stack));
  #endif

  assert (status == 0);
}

/*
 * The versions of TP_FrameIntHandler() and layer_1_sync_HISR_entry()
 * in the TCS211 dl1_com.obj module contain CPU load measurement
 * code.  TI changed things for LoCosto, so we have to revert their
 * changes and restore the TCS211 way.
 */

#if (TRACE_TYPE == 4)
  #define TIMER_RESET_VALUE (0xFFFF)
  #define TICKS_PER_TDMA    (1875)
#endif

/*-------------------------------------------------------*/
/* TP_FrameIntHandler() Low Interrupt service routine    */
/*-------------------------------------------------------*/
/* Parameters :                                          */
/* Return     :                                          */
/* Functionality :  activate Hisr on each frame interrupt*/
/*-------------------------------------------------------*/
void TP_FrameIntHandler(void)
{

  #if (OP_L1_STANDALONE == 1)

    #if (TRACE_TYPE==1)
       if (trace_info.current_config->l1_dyn_trace & 1<<L1_DYN_TRACE_L1S_CPU_LOAD)
       {
         TM_ResetTimer (2, 0xFFFF, 1, 0);
         TM_StartTimer (2);
       }
    #endif

    #if (TRACE_TYPE==6)
       TM_ResetTimer (2, 0xFFFF, 1, 0);
       TM_StartTimer (2);
    #endif

    #if (TRACE_TYPE==7)   /* CPU_LOAD */
       l1_cpu_load_start();
    #endif

  #else

    #if (TRACE_TYPE == 4) && (TI_NUC_MONITOR != 1)
              TM_ResetTimer (2, TIMER_RESET_VALUE, 1, 0);
              TM_StartTimer (2);
    #endif

    #if (TI_NUC_MONITOR == 1)
       /* Copy LISR buffer in Log buffer each end of HISR */
       ti_nuc_monitor_tdma_action();
    #endif

    #if WCP_PROF == 1
       prf_LogFNSwitch(l1s.actual_time.fn_mod42432);
    #endif

  #endif   /* OP_L1_STANDALONE */

  NU_Activate_HISR(&layer_1_sync_HISR);   /* Activate HISR interrupt */

  #if (OP_L1_STANDALONE == 0)
    #if (WCP_PROF == 1)
      #if (PRF_CALIBRATION == 1)
      NU_Activate_HISR(&prf_CalibrationHISR);
      #endif
    #endif
  #endif

}

/*
 * layer_1_sync_HISR_entry
 *
 * HISR associated to layer 1 sync.
 */

void layer_1_sync_HISR_entry (void)
{
  /* automatic var for the CPU load measurement code below */
  #if (TRACE_TYPE == 4)
    unsigned long cpu;
  #endif

  // Call Synchronous Layer1
  hisr();

  /*
   * FreeCalypso: the following code has been reconstructed from
   * the disassembly of the TCS211 binary object; it was found to be
   * similar to the Trace_L1S_CPU_load() function in l1_trace.c
   * which appears to have been only for (TRACE_TYPE == 1) originally.
   */
  #if (TRACE_TYPE == 4)
    layer_1_sync_end_time = TIMER_RESET_VALUE - TM_ReadTimer(2);

    cpu = (100 * layer_1_sync_end_time) / TICKS_PER_TDMA;
    if (cpu > max_cpu)
    {
      max_cpu=cpu;
      fn_max_cpu=l1s.actual_time.fn;
      max_cpu_flag = 1;
      /*
       * TCS211 object has this bogus code here:

       if (some non-understood condition) {
         static int i;
         i++;	// static var never used anywhere
         max_cpu_flag = 1;
       }

       * Because this bogus code does not change the result,
       * I decided not to bother with reconstructing it.
       */
    }

    if (((l1s.actual_time.fn%1326) == 0) && (max_cpu_flag == 0))
      max_cpu = 0;
  #endif
}

/* the following stub functions live in the dl1_com module per TCS211 */

void           rx_tch_data        (API     *data_address,
                                   UWORD8  channel_mode,
                                   UWORD8  blk_seq_number)
{
}
 
UWORD8           *tx_tch_data     (void)
{
  return(NULL); 
}