view src/cs/layer1/tpu_drivers/source0/tpudrv10.c @ 639:026c98f757a6

tpudrv12.h & targets/gtm900.h: our current support is for MGC2GSMT version only As it turns out, there exist two different Huawei-made hw platforms both bearing the marketing name GTM900-B: one is MG01GSMT, the other is MGC2GSMT. The two are NOT fw-compatible: aside from flash chip differences which should be handled by autodetection, the two hw platforms are already known to have different RFFEs with different control signals, and there may be other differences not yet known. Our current gtm900 build target is for MGC2GSMT only; we do not yet have a specimen of MG01GSMT on hand, hence no support for that version will be possible until and unless someone provides one.
author Mychaela Falconia <falcon@freecalypso.org>
date Thu, 30 Jan 2020 18:19:01 +0000
parents f8e74b692c80
children
line wrap: on
line source

/*
 * The situation with the tpudrv10 RF TPU driver is even worse than with
 * tpudrv12: not only are we missing the original tpudrv10.c source,
 * but we don't even have a tpudrv10.obj to reconstruct from.
 * The present reconstruction has been made from the 20020917 fw
 * image that came with our D-Sample board.
 *
 * The deep sleep functions haven't been reconstructed yet,
 * thus the firmware needs to be built with DISABLE_SLEEP=1.
 */

#define TPUDRV10_C

#include "board.cfg"
#include "chipset.cfg"
#include "l1sw.cfg"
#include "rf.cfg"
#include "swconfig.cfg"
#include "sys.cfg"

#include "sys_types.h"
#include "l1_confg.h"

#include "l1_macro.h"
#include "l1_const.h"
#include "l1_types.h"
#if TESTMODE
  #include "l1tm_defty.h"
#endif
#if (AUDIO_TASK == 1)
  #include "l1audio_const.h"
  #include "l1audio_cust.h"
  #include "l1audio_defty.h"
#endif
#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

#include "l1_defty.h"
#include "l1_time.h"
#include "l1_ctl.h"
#include "tpudrv.h"
#include "tpudrv10.h"
#include "l1_rf10.h"

#include "mem.h"
#include "armio.h"
#include "clkm.h"

// Global variables
extern T_L1_CONFIG l1_config;
extern UWORD16  AGC_TABLE[];
extern UWORD16  *TP_Ptr;

static UWORD8  rf_index;	/* index into rf_path[] */
static UWORD8  rfband;		/* ditto */
static UWORD8  magic2_byte;
static UWORD16 lna_off_flag;

static UWORD8  magic_83be24 = 0x0E;
static UWORD8  magic_83be25 = 0x01;
static UWORD8  magic_83be26 = 0x00;

// Internal function prototypes
void l1dmacro_rx_down (WORD32 t);

SYS_UWORD16 Convert_l1_radio_freq(SYS_UWORD16 radio_freq);
WORD32 rf_init(WORD32 t);

// External function prototypes
UWORD8 Cust_is_band_high(UWORD16 radio_freq);


extern T_RF_BAND rf_band[];
extern T_RF rf;

/**************************************************************************/
/**************************************************************************/
/*         DEFINITION OF MACROS FOR CHIPS SERIAL PROGRAMMATION            */
/**************************************************************************/
/**************************************************************************/

/*------------------------------------------*/
/*   Is arfcn in the DCS band (512-885) ?   */
/*------------------------------------------*/
#define IS_HIGH_BAND(arfcn) (((arfcn >= 512) && (arfcn <= 885)) ? 1 : 0)

/*------------------------------------------*/
/*   Send a value to Clara RF               */
/*------------------------------------------*/
#define TSP_TO_RF_24(rf_data)\
	{\
	*TP_Ptr++ = TPU_MOVE(TSP_TX_REG_1, ((rf_data) >> 16) & 0xFF);	\
	*TP_Ptr++ = TPU_MOVE(TSP_TX_REG_2, ((rf_data) >> 8) & 0xFF);	\
	*TP_Ptr++ = TPU_MOVE(TSP_TX_REG_3, (rf_data) & 0xFF);		\
	*TP_Ptr++ = TPU_MOVE(TSP_CTRL1, TC1_DEVICE_RF | 0x17);		\
	*TP_Ptr++ = TPU_MOVE(TSP_CTRL2, TC2_WR);			\
	}

#define TSP_TO_RF_16(rf_data)\
	{\
	*TP_Ptr++ = TPU_MOVE(TSP_TX_REG_1, ((rf_data) >> 8) & 0xFF);	\
	*TP_Ptr++ = TPU_MOVE(TSP_TX_REG_2, (rf_data) & 0xFF);		\
	*TP_Ptr++ = TPU_MOVE(TSP_CTRL1, TC1_DEVICE_RF | 0x0F);		\
	*TP_Ptr++ = TPU_MOVE(TSP_CTRL2, TC2_WR);			\
	}

#define TSP_TO_RF_8(rf_data)\
	{\
	*TP_Ptr++ = TPU_MOVE(TSP_TX_REG_1, (rf_data) & 0xFF);		\
	*TP_Ptr++ = TPU_MOVE(TSP_CTRL1, TC1_DEVICE_RF | 0x07);		\
	*TP_Ptr++ = TPU_MOVE(TSP_CTRL2, TC2_WR);			\
	}

/*------------------------------------------*/
/*   Send a TSP command to ABB              */
/*------------------------------------------*/
#define TSP_TO_ABB(data)\
	{\
	*TP_Ptr++ = TPU_MOVE(TSP_TX_REG_1, (data) & 0xFF);		\
	*TP_Ptr++ = TPU_MOVE(TSP_CTRL1, TC1_DEVICE_ABB | 0x06);		\
	*TP_Ptr++ = TPU_MOVE(TSP_CTRL2, TC2_WR);			\
	}

/*------------------------------------------*/
/*    Trace arfcn for conversion debug      */
/*------------------------------------------*/
#ifdef ARFCN_DEBUG
  // ----Debug information : record all arfcn programmed into synthesizer!
  #define MAX_ARFCN_TRACE     4096  // enough for 5 sessions of 124+374
  SYS_UWORD16 arfcn_trace[MAX_ARFCN_TRACE];
  static UWORD32 arfcn_trace_index = 0;

  void trace_arfcn(SYS_UWORD16 arfcn)
  {
    arfcn_trace[arfcn_trace_index++] = arfcn;

    // Wrap to beginning
    if (arfcn_trace_index == MAX_ARFCN_TRACE)
      arfcn_trace_index = 0;
  }
#endif


/**************************************************************************/
/**************************************************************************/
/*               DEFINITION OF HARWARE DEPENDANT CONSTANTS                */
/**************************************************************************/
/**************************************************************************/

/**************************************************************************/
/**************************************************************************/
/*                  INTERNAL FUNCTIONS OF TPUDRV14.C                      */
/*                 EFFECTIVE DOWNLOADING THROUGH TSP                      */
/**************************************************************************/
/**************************************************************************/

struct synth_s {
  // common
  UWORD16 arfcn0;
  UWORD16 limit;
  // Tx
  UWORD16 ul_farfcn0;
  WORD8   ul_sign;
  // Rx
  UWORD16 dl_farfcn0;
  UWORD8  dl_mult;
};

struct magic1_s {
  UWORD16 limit;
  UWORD16 magic;
};

struct magic2_s {
  UWORD16 limit;
  UWORD8  magic;
};

struct rf_path_s {
  UWORD16 rf_chip_band;
  UWORD8  rx_up;
  UWORD8  rx_down;
  UWORD8  tx_up;
  UWORD8  tx_down;
  UWORD8  tx_up_rev;
  const struct synth_s  *synth;
  const struct magic1_s *tx_magic1;
  const struct magic2_s *rx_magic2;
};

static const struct synth_s synth_900[] =
{
  {  0,  124, 890, 1, 935, 4},// gsm    0 - 124
  {974, 1023, 880, 1, 925, 4},// egsm 975 - 1023
};

static const struct magic1_s magic1_900[] =
{
  {  26, 0x0820},
  {  35, 0x0854},
  {  42, 0x0847},
  {  54, 0x0861},
  {  60, 0x0847},
  {  69, 0x0861},
  {  79, 0x0847},
  {  94, 0x083A},
  { 105, 0x0847},
  { 112, 0x0854},
  { 117, 0x082D},
  { 124, 0x0847},
  { 988, 0x0820},
  {1014, 0x083A},
  {1023, 0x0820},
};

static const struct magic2_s magic2_rx900[] =
{
  {0x4B00, 7},
  {0x4E20, 7},
  {0xFFFF, 7},
};

static const struct synth_s synth_1800[] =
{
  {511, 885, 1710, -1, 1805, 1}, // dcs  512 - 885
};

static const struct magic1_s magic1_1800[] =
{
  {571, 0x0820},
  {610, 0x0847},
  {671, 0x083A},
  {688, 0x082D},
  {719, 0x083A},
  {730, 0x0861},
  {755, 0x083A},
  {794, 0x0847},
  {845, 0x0820},
  {885, 0x082D},
};

static const struct magic2_s magic2_rx1800[] =
{
  {0x24B8, 0},
  {0x2710, 0},
  {0xFFFF, 0},
};

static const struct synth_s synth_1900[] =
{
  {511, 810, 1850, -1, 1930, 1}, // pcs  512 - 810;
};

static const struct magic1_s magic1_1900[] =
{
  {550, 0x0847},
  {615, 0x082D},
  {642, 0x083A},
  {702, 0x0820},
  {777, 0x0854},
  {810, 0x0861},
};

static const struct magic2_s magic2_rx1900[] =
{
  {0x26DE, 0},
  {0x2710, 0},
  {0xFFFF, 0},
};

static const struct synth_s synth_850[] =
{
  {127, 251, 824, 1, 869, 4}, // gsm850
};

static const struct magic1_s magic1_850[] =
{
  {251, 0x0924},
};

static const struct magic2_s magic2_rx850[] =
{
  {0x4B00, 7},
  {0x4E20, 7},
  {0xFFFF, 7},
};

static const struct magic2_s magic2_tx[] =
{
  {0x1A90, 6},
  {0x1CED, 7},
  {0x1D4C, 7},
  {0xFFFF, 7},
};

static const struct rf_path_s rf_path[] = {
    //same index used as for band_config[] - 1
  /* EGSM */
  { BAND_SELECT_GSM, RU_900,  RD_900,  TU_900,  TD_900,  TU_REV_900,
    synth_900,  magic1_900,  magic2_rx900},
  /* DCS */
  { BAND_SELECT_DCS, RU_1800, RD_1800, TU_1800, TD_1800, TU_REV_1800,
    synth_1800, magic1_1800, magic2_rx1800},
  /* PCS */
  { BAND_SELECT_PCS, RU_1900, RD_1900, TU_1900, TD_1900, TU_REV_1900,
    synth_1900, magic1_1900, magic2_rx1900},
  /* GSM850 */
  { BAND_SELECT_850, RU_850,  RD_850,  TU_850,  TD_850,  TU_REV_850,
    synth_850,  magic1_850,  magic2_rx850},
  /* PCS in dual-us */
  { BAND_SELECT_PCS, RU_1900, RD_1900, TU_1900, TD_1900, TU_REV_1900,
    synth_1900, magic1_1900, magic2_rx1900},
  /* non-E GSM */
  { BAND_SELECT_GSM, RU_900,  RD_900,  TU_900,  TD_900,  TU_REV_900,
    synth_900,  magic1_900,  magic2_rx900},
};

static UWORD16 calc_tx_magic(UWORD16 arfcn)
{
  const struct magic1_s *m1;
  UWORD16 sp6, sp8;

  m1 = rf_path[rf_index].tx_magic1;
  while(m1->limit < arfcn)
    m1++;
  sp6 = m1->magic << 1;
  sp8 = sp6 / 13;
  return ((sp8 & 0x1FF) << 5);
}

static UWORD32 calc_freq_prog(UWORD16 arfcn, UWORD8 downlink)
{
  UWORD32 farfcn;	/* sp+0x1C, in 200 kHz units */
  const struct synth_s  *s;
  const struct magic1_s *m1;
  const struct magic2_s *m2;
  UWORD32 magic1;	/* sp+0x24 */
  UWORD16 sp4;
  UWORD32 sp8, sp0xC, sp0x10, sp0x14, sp0x18, sp0x20;

  s = rf_path[rf_index].synth;
  while(s->limit < arfcn)
    s++;

  m1 = rf_path[rf_index].tx_magic1;
  while(m1->limit < arfcn)
    m1++;
  magic1 = m1->magic;

  if (downlink) {
    sp0x20 = 0x27627 * s->dl_mult + 8;
    farfcn = 5*s->dl_farfcn0 + (arfcn - s->arfcn0);
    sp4 = farfcn * s->dl_mult;
    sp0x18 = sp4 << 21;
    sp0x14 = sp0x20 * farfcn;
    m2 = rf_path[rf_index].rx_magic2;
  } else {
    sp0x20 = 0x2762F;
    farfcn = 5*s->ul_farfcn0 + (arfcn - s->arfcn0);
    sp4 = magic1 * s->ul_sign + farfcn;
    sp0x18 = sp4 << 21;
    sp0x14 = sp0x20 * (magic1 * s->ul_sign + farfcn);
    m2 = magic2_tx;
  }

  while(m2->limit < sp4)
    m2++;
  magic2_byte = (m2->magic & 7) << 5;

  sp8 = (sp0x14 / 16) >> 21;
  sp0xC = sp0x14 - (sp8 << 25);
  sp0x10 = (((sp8 << 4) + sp0xC) * 0x1A00000 - 0x18) >> 21;

  return ((sp0xC & 0xF) << 12) | ((sp8 & 0x7F) << 16) | ((sp0x10 & 0xF) << 8);
}

/*------------------------------------------*/
/*          Convert_l1_radio_freq           */
/*------------------------------------------*/
/*      conversion of l1 radio_freq to      */
/*         real channel number              */
/*------------------------------------------*/
SYS_UWORD16 Convert_l1_radio_freq(SYS_UWORD16 radio_freq)
{
  switch(l1_config.std.id)
  {
    case GSM:
    case DCS1800:
    case PCS1900:
    case GSM850:
      return (radio_freq);
//omaps00090550    break;

    case DUAL:
    {
      if (radio_freq < l1_config.std.first_radio_freq_band2)
      // GSM band...
        return(radio_freq);
      else
      // DCS band...
        return (radio_freq - l1_config.std.first_radio_freq_band2 + 512);
    }
//omaps00090550    break;

    case DUALEXT:
    {
      if (radio_freq < l1_config.std.first_radio_freq_band2)
      // E-GSM band...
      {
        if(radio_freq <= 124)
        // GSM part...
          return(radio_freq);
        if(radio_freq < 174)
        // Extended part...
          return (radio_freq - 125 + 975);
        else
        // Extended part, special case of ARFCN=0
          return(0);
      }
      else
      {
      // DCS band...
        return (radio_freq - l1_config.std.first_radio_freq_band2 + 512);
      }
    }
//    break;

   case GSM_E:
    {
      if(radio_freq <= 124)
      // GSM part...
        return(radio_freq);
      else
      if(radio_freq < 174)
      // Extended part...
        return (radio_freq - 125 + 975);
      else
      // Extended part, special case of ARFCN=0
        return(0);
    }
//omaps00090550    break;

    case DUAL_US:
    {
      if (radio_freq < l1_config.std.first_radio_freq_band2)
      {
        return(radio_freq - l1_config.std.first_radio_freq + 128);
      }
      else
      {
      // PCS band...
        return (radio_freq - l1_config.std.first_radio_freq_band2 + 512);
      }
    }
//    break;

    default: // should never occur.
      return(radio_freq);
  }  // end of switch
}

/*------------------------------------------*/
/*              rf_init                     */
/*------------------------------------------*/
/*    Initialization routine for PLL        */
/*   Effective downloading through TSP      */
/*------------------------------------------*/
/* Rita and LoCosto versions look totally   */
/* different, reconstructing from disasm.   */
/*------------------------------------------*/
WORD32 rf_init(WORD32 t)
{
	*TP_Ptr++ = TPU_AT(t);
	*TP_Ptr++ = TPU_MOVE(TSP_CTRL1, 0x47);
	*TP_Ptr++ = TPU_MOVE(TSP_ACT, 0x01);
	*TP_Ptr++ = TPU_MOVE(TSP_ACT, 0x00);
	*TP_Ptr++ = TPU_MOVE(TSP_ACT, 0x01);
	t += 8;
	*TP_Ptr++ = TPU_AT(t);
	TSP_TO_RF_16(0x8008);
	*TP_Ptr++ = TPU_MOVE(TSP_ACT, 0x1F);
	t += 7;
	*TP_Ptr++ = TPU_AT(t);
	*TP_Ptr++ = TPU_AT(t);
	*TP_Ptr++ = TPU_AT(t);
	*TP_Ptr++ = TPU_AT(t);
	*TP_Ptr++ = TPU_AT(t);
	*TP_Ptr++ = TPU_AT(t);
	*TP_Ptr++ = TPU_MOVE(TSP_ACT, 0x1F);
	*TP_Ptr++ = TPU_MOVE(TSP_ACT, 0x1E);
	*TP_Ptr++ = TPU_MOVE(TSP_ACT, 0x1F);
	TSP_TO_RF_16(0x8018);
	t += 9;
	*TP_Ptr++ = TPU_AT(t);
	TSP_TO_RF_24(0x140753);
	t += 8;
	*TP_Ptr++ = TPU_AT(t);
	TSP_TO_RF_24(0x2db084);
	t += 8;
	*TP_Ptr++ = TPU_AT(t);
	TSP_TO_RF_8((magic_83be26 << 4) | (magic_83be25 << 5) | 0x06);
	t += 384;
	*TP_Ptr++ = TPU_AT(t);
	TSP_TO_RF_24(((UWORD32) magic_83be24 << 19) | 7);
	t += 8;
	return(t);
}

/*------------------------------------------*/
/*              rf_init_light               */
/*------------------------------------------*/
/*    Initialization routine for PLL        */
/*   Effective downloading through TSP      */
/*------------------------------------------*/
WORD32 rf_init_light(WORD32 t)
{
  // initialization for change of multi-band configuration dependent on STD
  return(t);
}

UWORD8 arfcn_to_rf_index(SYS_UWORD16 arfcn)
{
  UWORD8 index;
  extern const T_STD_CONFIG std_config[];
  index = std_config[l1_config.std.id].band[0];

  if ((std_config[l1_config.std.id].band[1] != BAND_NONE) && IS_HIGH_BAND(arfcn))
    index = std_config[l1_config.std.id].band[1];

  return (index - 1);
}

/*------------------------------------------*/
/*              rf_program                  */
/*------------------------------------------*/
/*      Programs the RF synthesizer         */
/*           called each frame              */
/*      downloads NA counter value          */
/*    t = start time in the current frame   */
/*------------------------------------------*/        //change 2 UWORD8
UWORD32 rf_program(UWORD32 t, SYS_UWORD16 radio_freq, UWORD32 rx)
{
  SYS_UWORD16 arfcn;
  UWORD32 sp0x10, sp0x14;

  rfband = Cust_is_band_high(radio_freq);

  arfcn = Convert_l1_radio_freq(radio_freq);
  #ifdef ARFCN_DEBUG
    trace_arfcn(arfcn);
  #endif
  rf_index = arfcn_to_rf_index(arfcn);

  sp0x10 = calc_freq_prog(arfcn, rx);
  if (rx == 1) {
    TSP_TO_RF_24(sp0x10 | magic2_byte | MODE2);
    *TP_Ptr++ = TPU_WAIT(1);
    TSP_TO_RF_16(0x8A18 | rf_path[rf_index].rf_chip_band);
    TSP_TO_RF_24(sp0x10 | magic2_byte | MODE2);
  } else {
    sp0x14 = calc_tx_magic(arfcn);
    TSP_TO_ABB(0x80);
    *TP_Ptr++ = TPU_MOVE(TSP_ACT, 0x17);
    TSP_TO_RF_16(0x0518 | rf_path[rf_index].rf_chip_band);
    TSP_TO_RF_24(sp0x10 | magic2_byte | MODE2);
    *TP_Ptr++ = TPU_FAT(0x1280);
    TSP_TO_ABB(0xC0);
    *TP_Ptr++ = TPU_FAT(0x128B);
    TSP_TO_RF_16(sp0x14 | MODE5);
    *TP_Ptr++ = TPU_FAT(0x12F7);
    TSP_TO_RF_24(0x140973);
    *TP_Ptr++ = TPU_FAT(0x1305);
    TSP_TO_ABB(0x80);
  }

  return(t);
}

/**************************************************************************/
/**************************************************************************/
/*                    EXTERNAL FUNCTIONS CALLED BY LAYER1                 */
/*                          COMMON TO L1 and TOOLKIT                      */
/**************************************************************************/
/**************************************************************************/

/*------------------------------------------*/
/*                agc                       */
/*------------------------------------------*/
/*      Program a gain into IF amp          */
/*      agc_value : gain in dB              */
/*                                          */
/*   additional parameter for LNA setting   */
/*------------------------------------------*/
/* Rita and LoCosto versions look totally   */
/* different, reconstructing from disasm.   */
/*------------------------------------------*/

void l1dmacro_agc(SYS_UWORD16 radio_freq, WORD8 gain, UWORD8 lna_off)
{
	int agc_table_index;

	agc_table_index = gain - 6;
	if (agc_table_index < 0)
		agc_table_index++;
	agc_table_index >>= 1;
	if (agc_table_index >= 27)
		agc_table_index = 26;
	if (agc_table_index < 0)
		agc_table_index = 0;
	*TP_Ptr++ = TPU_FAT(0x1313);
	TSP_TO_RF_16(AGC_TABLE[agc_table_index] << 11 | 0x3B9);
	lna_off_flag = (lna_off & 1) << 15;
}

/*------------------------------------------*/
/*             l1dmacro_rx_synth            */
/*------------------------------------------*/
/*       programs RF synth for recceive     */
/*------------------------------------------*/
void l1dmacro_rx_synth(SYS_UWORD16 radio_freq)
{
   UWORD32 t;

   // Important: always use rx_synth_start_time for first TPU_AT
   // Never remove below 2 lines!!!
   t = l1_config.params.rx_synth_start_time;
   *TP_Ptr++ = TPU_FAT (t);

   t = rf_program(t, radio_freq, 1);   // direction is set to 1 for Rx
}

/*------------------------------------------*/
/*            l1dmacro_tx_synth             */
/*------------------------------------------*/
/*      programs RF synth for transmit      */
/*      programs OPLL for transmit          */
/*------------------------------------------*/
void l1dmacro_tx_synth(SYS_UWORD16 radio_freq)
{
   UWORD32 t;

   // Important: always use tx_synth_start_time for first TPU_AT
   // Never remove below 2 lines!!!
   t =   l1_config.params.tx_synth_start_time;
   *TP_Ptr++ = TPU_FAT (t);

   t = rf_program(t, radio_freq, 0); // direction set to 0 for Tx
}

/*------------------------------------------*/
/*            l1dmacro_rx_up                */
/*------------------------------------------*/
/* Open window for normal burst reception   */
/*------------------------------------------*/
/* Rita version differs from LoCosto,       */
/* reconstructing from disassembly.         */
/*------------------------------------------*/
void l1dmacro_rx_up (void)
{
	*TP_Ptr++ = TPU_FAT(0x1321);
	TSP_TO_RF_16(0x9A18 | rf_path[rf_index].rf_chip_band);
	*TP_Ptr++ = TPU_FAT(7);
	TSP_TO_RF_16(0x0238 | rf_path[rf_index].rf_chip_band | lna_off_flag);
	*TP_Ptr++ = TPU_WAIT(5);
	TSP_TO_ABB(0x10);
	*TP_Ptr++ = TPU_FAT(0x1B);
	TSP_TO_ABB(0x18);
	*TP_Ptr++ = TPU_FAT(0x36);
	*TP_Ptr++ = TPU_MOVE(TSP_ACT, rf_path[rf_index].rx_up | 0x09);
	*TP_Ptr++ = TPU_FAT(62);
	TSP_TO_ABB(0x14);
}

/*------------------------------------------*/
/*            l1pdmacro_rx_down             */
/*------------------------------------------*/
/* Close window for normal burst reception  */
/*------------------------------------------*/
/* Rita version differs from LoCosto,       */
/* reconstructing from disassembly.         */
/*------------------------------------------*/
void l1dmacro_rx_down (WORD32 t)
{
	*TP_Ptr++ = TPU_FAT(t - 36);
	TSP_TO_RF_16(0x8018);
	*TP_Ptr++ = TPU_MOVE(TSP_ACT, rf_path[rf_index].rx_down | 0x09);
	*TP_Ptr++ = TPU_FAT(t - 4);
	TSP_TO_ABB(0x00);
}

/*------------------------------------------*/
/*            l1dmacro_tx_up                */
/*------------------------------------------*/
/* Open transmission window for normal burst*/
/*------------------------------------------*/
/* Rita version differs from LoCosto,       */
/* reconstructing from disassembly.         */
/*------------------------------------------*/
void l1dmacro_tx_up (void)
{
	*TP_Ptr++ = TPU_FAT(0x1309);
	TSP_TO_RF_16(0x0558 | rf_path[rf_index].rf_chip_band);
	*TP_Ptr++ = TPU_FAT(0x133A);
	TSP_TO_RF_24(0x140753);
	*TP_Ptr++ = TPU_FAT(0x1384);
	TSP_TO_ABB(0xA0);
	*TP_Ptr++ = TPU_FAT(16);
	*TP_Ptr++ = TPU_MOVE(TSP_ACT, rf_path[rf_index].tx_up | 0x01);
	*TP_Ptr++ = TPU_FAT(24);
	*TP_Ptr++ = TPU_MOVE(TSP_ACT, rf_path[rf_index].tx_up | 0x21);
}

/*-------------------------------------------*/
/*            l1dmacro_tx_down               */
/*-------------------------------------------*/
/* Close transmission window for normal burst*/
/*-------------------------------------------*/
/* Rita version differs from LoCosto,        */
/* reconstructing from disassembly.          */
/*-------------------------------------------*/
void l1dmacro_tx_down (WORD32 t, BOOL tx_flag, UWORD8 adc_active)
{
	if (adc_active == ACTIVE)
		l1dmacro_adc_read_tx(t - 44);
	*TP_Ptr++ = TPU_FAT(t - 4);
	TSP_TO_ABB(0x80);
	*TP_Ptr++ = TPU_FAT(t + 13);
	*TP_Ptr++ = TPU_MOVE(TSP_ACT, rf_path[rf_index].tx_down | 0x21);
	*TP_Ptr++ = TPU_FAT(t + 22);
	*TP_Ptr++ = TPU_MOVE(TSP_ACT, rf_path[rf_index].tx_down | 0x01);
	TSP_TO_RF_8(0x18);
	*TP_Ptr++ = TPU_FAT(t + 29);
	TSP_TO_ABB(0x00);
	*TP_Ptr++ = TPU_MOVE(TSP_ACT, rf_path[rf_index].tx_down | 0x09);
}

/*
 * l1dmacro_rx_nb
 *
 * Receive Normal burst
 */
void l1dmacro_rx_nb (SYS_UWORD16 radio_freq)
{
	l1dmacro_rx_up();
	l1dmacro_rx_down(STOP_RX_SNB);
}

/*
 * l1dmacro_rx_sb
 * Receive Synchro burst
 */
void l1dmacro_rx_sb (SYS_UWORD16 radio_freq)
{
  l1dmacro_rx_up();
  l1dmacro_rx_down (STOP_RX_SB);
}

/*
 * l1dmacro_rx_ms
 *
 * Receive Power Measurement window
 */
void l1dmacro_rx_ms (SYS_UWORD16 radio_freq)
{
  l1dmacro_rx_up();
  l1dmacro_rx_down (STOP_RX_PW_1);
}

/*
 * l1dmacro_rx_fb
 *
 * Receive Frequency burst
 */
void l1dmacro_rx_fb (SYS_UWORD16 radio_freq)
{
  l1dmacro_rx_up();

  *TP_Ptr++ = TPU_AT(0);
  *TP_Ptr++ = TPU_AT(0);
  *TP_Ptr++ = TPU_AT(0);
  *TP_Ptr++ = TPU_AT(0);
  *TP_Ptr++ = TPU_AT(0);
  *TP_Ptr++ = TPU_AT(0);
  *TP_Ptr++ = TPU_AT(0);
  *TP_Ptr++ = TPU_AT(0);
  *TP_Ptr++ = TPU_AT(0);
  *TP_Ptr++ = TPU_AT(0);
  *TP_Ptr++ = TPU_AT(0);

  l1dmacro_rx_down (STOP_RX_FB);
}

/*
 * l1dmacro_rx_fb26
 *
 * Receive Frequency burst for TCH.
 */
void l1dmacro_rx_fb26 (SYS_UWORD16 radio_freq)
{
  l1dmacro_rx_up();

  *TP_Ptr++ = TPU_AT(0);

  l1dmacro_rx_down (STOP_RX_FB26);
}

/*
 * l1dmacro_tx_nb
 *
 * Transmit Normal burst
 */
void l1dmacro_tx_nb (SYS_UWORD16 radio_freq, UWORD8 txpwr, UWORD8 adc_active)
{
  l1dmacro_tx_up ();
  l1dmacro_tx_down (l1_config.params.tx_nb_duration, FALSE, adc_active);
}

/*
 * l1dmacro_tx_ra
 *
 * Transmit Random Access burst
 */
void l1dmacro_tx_ra (SYS_UWORD16 radio_freq, UWORD8 txpwr, UWORD8 adc_active)
{
  l1dmacro_tx_up ();
  l1dmacro_tx_down (l1_config.params.tx_ra_duration, FALSE, adc_active);
}

#if TESTMODE
/*
 * l1dmacro_rx_cont
 *
 * Receive continuously
 */
void l1dmacro_rx_cont (SYS_UWORD16 radio_freq, UWORD8 txpwr)
{
  l1dmacro_rx_up ();
}

/*
 * l1dmacro_tx_cont
 *
 * Transmit continuously
 */
void l1dmacro_tx_cont (SYS_UWORD16 radio_freq, UWORD8 txpwr)
{
  l1dmacro_tx_up ();
}

/*
 * l1d_macro_stop_cont
 *
 * Stop continuous Tx or Rx
 */
void l1dmacro_stop_cont (void)
{
  if (l1_config.tmode.rf_params.down_up == TMODE_DOWNLINK)
    l1dmacro_rx_down(STOP_RX_SNB);
  else
    l1dmacro_tx_down(l1_config.params.tx_nb_duration, FALSE, 0);
}
#endif	/* TESTMODE */


/*------------------------------------------*/
/*             l1dmacro_reset_hw            */
/*------------------------------------------*/
/*      Reset and set OFFSET register       */
/*------------------------------------------*/

void l1dmacro_reset_hw(UWORD32 servingCellOffset)
{
   TPU_Reset(1); // reset TPU only, no TSP reset
   TPU_Reset(0);
   TP_Ptr = (UWORD16 *) TPU_RAM;

   *TP_Ptr++ = TPU_OFFSET(servingCellOffset);
}

//  l1dmacro_RF_sleep
//  Program RF for BIG or DEEP sleep


/* Rita version differs from LoCosto, reconstructing from disassembly */
void l1dmacro_RF_sleep  (void)
{
#if 0
	TSP_TO_RF(0x0002);
	*TP_Ptr++ = TPU_MOVE(TSP_ACT, RF_SER_ON);
	*TP_Ptr++ = TPU_WAIT(1);
	*TP_Ptr++ = TPU_MOVE(TSP_SPI_SET1, 0x21);
	*TP_Ptr++ = TPU_MOVE(TSP_SPI_SET2, 0x02);
	*TP_Ptr++ = TPU_MOVE(TSP_CTRL1, TC1_DEVICE_RF | 0x01);
	*TP_Ptr++ = TPU_MOVE(TSP_CTRL2, TC2_WR);
	*TP_Ptr++ = TPU_WAIT(100);
#endif
	/* code from tpudrv61.c follows, same for Rita and LoCosto */
	*TP_Ptr++ = TPU_SLEEP;
	TP_Ptr = (SYS_UWORD16 *) TPU_RAM;
	TP_Enable(1);
	#if 0	/* present in LoCosto but not in TCS211 */
	  TPU_wait_idle();
	#endif
}

//  l1dmacro_RF_wakeup
//* wakeup RF from BIG or DEEP sleep

/* Rita version differs from LoCosto, reconstructing from disassembly */
void l1dmacro_RF_wakeup  (void)
{
	TP_Ptr = (SYS_UWORD16 *) TPU_RAM;
#if 0
	*TP_Ptr++ = TPU_MOVE(TSP_SPI_SET1, 0x01);
	*TP_Ptr++ = TPU_MOVE(TSP_SPI_SET2, 0x06);
	*TP_Ptr++ = TPU_MOVE(TSP_CTRL1, TC1_DEVICE_RF | 0x01);
	*TP_Ptr++ = TPU_MOVE(TSP_CTRL2, TC2_WR);
	*TP_Ptr++ = TPU_WAIT(100);
	*TP_Ptr++ = TPU_MOVE(TSP_ACT, rf_path[rf_index].rx_down | RF_SER_ON);
	*TP_Ptr++ = TPU_WAIT(1);
	*TP_Ptr++ = TPU_MOVE(TSP_ACT, rf_path[rf_index].rx_down | RF_SER_OFF);
	*TP_Ptr++ = TPU_WAIT(8);
	*TP_Ptr++ = TPU_MOVE(TSP_ACT, rf_path[rf_index].rx_down | RF_SER_ON);
	*TP_Ptr++ = TPU_WAIT(5);
	TSP_TO_RF(0x0012);
	*TP_Ptr++ = TPU_FAT(0);
	*TP_Ptr++ = TPU_FAT(0);
	*TP_Ptr++ = TPU_FAT(0);
	*TP_Ptr++ = TPU_FAT(0);
	*TP_Ptr++ = TPU_FAT(0);
	*TP_Ptr++ = TPU_FAT(0);
	TSP_TO_RF(0x003A);
	*TP_Ptr++ = TPU_WAIT(7);
	TSP_TO_RF(0xC003);
	*TP_Ptr++ = TPU_WAIT(7);
	TSP_TO_RF(0x02FE);
	*TP_Ptr++ = TPU_WAIT(7);
	TSP_TO_RF(0x401F);
	*TP_Ptr++ = TPU_WAIT(7);
	TSP_TO_RF(0x043D);
	*TP_Ptr++ = TPU_WAIT(7);
	*TP_Ptr++ = TPU_WAIT(117);
#endif
	/* code from tpudrv61.c follows, same for Rita and LoCosto */
	*TP_Ptr++ = TPU_SLEEP;
	TP_Ptr = (SYS_UWORD16 *) TPU_RAM;
	TP_Enable(1);
	#if 0	/* present in LoCosto but not in TCS211 */
	  TPU_wait_idle();
	#endif
}


//              l1dmacro_init_hw
//      Reset VEGA, then remove reset
//      Init RF/IF synthesizers

void l1dmacro_init_hw(void)
{
   WORD32 t = 100;    // start time for actions

   TP_Reset(1); // reset TPU and TSP

   // GSM 1.5 : TPU clock enable is in TPU
   //---------------------------------------
   TPU_ClkEnable(1);         // TPU CLOCK ON

   TP_Reset(0);


   TP_Ptr = (UWORD16 *) TPU_RAM;

   // TPU_SLEEP
   l1dmacro_idle();

   *TP_Ptr++ = TPU_AT(t);
   *TP_Ptr++ = TPU_SYNC(0);

   /* from disassembly, differs from LoCosto version */
   *TP_Ptr++ = TPU_MOVE(TSP_SPI_SET1, 0x20);
   *TP_Ptr++ = TPU_MOVE(TSP_SPI_SET2, 0x06);
   *TP_Ptr++ = TPU_MOVE(TSP_SPI_SET3, 0x00);

   t = 1000;      // arbitrary start time

   t = rf_init(t); // Initialize RF Board

   *TP_Ptr++ = TPU_AT(t);

   // TPU_SLEEP
   l1dmacro_idle();

   return;
}

/*------------------------------------------*/
/*         l1dmacro_init_hw_light           */
/*------------------------------------------*/
/*      Reset VEGA, then remove reset       */
/*      Init RF/IF synthesizers             */
/*------------------------------------------*/
void l1dmacro_init_hw_light(void)
{
   UWORD32 t = 100;    // start time for actions //
   TP_Ptr = (SYS_UWORD16 *) TPU_RAM; //
   *TP_Ptr++ = TPU_AT(t);  //
   t = 1000;      // arbitrary start time //

   /* D-Sample 20020917 fw does full rf_init() here */
   t = rf_init(t); // Initialize RF Board //

   *TP_Ptr++ = TPU_AT(t); //
   l1dmacro_idle(); //

   return;
}