cc1020config.c

来自「Atmega8L控制CC1020 TI的另外一款使用很多的RF IC。」· C语言 代码 · 共 560 行 · 第 1/2 页

C
560
字号
    // Abort further recalibration attempts if successful LOCK
    if((ReadFromCC1020Register(CC1020_STATUS)&0x10) == 0x10) {
      break;
    }
  }

  // Restore PA setting
  WriteToCC1020Register(CC1020_PA_POWER, PA_POWER);

  // Return state of LOCK_CONTINUOUS bit
  return ((ReadFromCC1020Register(CC1020_STATUS)&0x10)==0x10);
}

/****************************************************************************/
/*  This routine puts the CC1020 into RX mode (from TX). When switching to  */
/*  RX from PD, use WakeupC1020ToRX first                                   */
/****************************************************************************/

char SetupCC1020RX(char RXANALOG, char PA_POWER)
{
  volatile int TimeOutCounter,i;
  char lock_status;

  // Switch into RX, switch to freq. reg A
  WriteToCC1020Register(CC1020_MAIN,0x11);

  // Setup bias current adjustment
  WriteToCC1020Register(CC1020_ANALOG,RXANALOG);  
  
  for(i=0;i<=0x1000;i++);
  // Monitor LOCK
  for(TimeOutCounter=LOCK_TIMEOUT; ((ReadFromCC1020Register(CC1020_STATUS)&0x10)==0)&&(TimeOutCounter>0); TimeOutCounter--);

  // If PLL in lock
  if((ReadFromCC1020Register(CC1020_STATUS)&0x10)==0x10){
    // Indicate PLL in LOCK
    lock_status = LOCK_OK;
  // Else (PLL out of LOCK)
  }else{
    // If recalibration ok
    if(CalibrateCC1020(PA_POWER)){
      // Indicate PLL in LOCK
      lock_status = LOCK_RECAL_OK;
    // Else (recalibration failed)
    }else{
      // Indicate PLL out of LOCK
      lock_status = LOCK_NOK;
    }
  }

  // Switch RX part of CC1020 on
  WriteToCC1020Register(CC1020_MAIN,0x01);

  // Return LOCK status to application
  return (lock_status);
}

/****************************************************************************/
/*  This routine puts the CC1020 into TX mode (from RX). When switching to  */
/*  TX from PD, use WakeupCC1020ToTX first                                  */
/****************************************************************************/

char SetupCC1020TX(char TXANALOG, char PA_POWER)
{
  volatile int TimeOutCounter,i;
  char lock_status;

  // Turn off PA to avoid frequency splatter
  WriteToCC1020Register(CC1020_PA_POWER,0x00);

  // Setup bias current adjustment
  WriteToCC1020Register(CC1020_ANALOG,TXANALOG);

  // Switch into TX, switch to freq. reg B
  WriteToCC1020Register(CC1020_MAIN,0xC1);
  
 for(i=0;i<=0x1000;i++);
  // Monitor LOCK
  for(TimeOutCounter=LOCK_TIMEOUT; ((ReadFromCC1020Register(CC1020_STATUS)&0x10)==0)&&(TimeOutCounter>0); TimeOutCounter--);

  // If PLL in lock
  if((ReadFromCC1020Register(CC1020_STATUS)&0x10)==0x10){
    // Indicate PLL in LOCK
    lock_status = LOCK_OK;
  // Else (PLL out of LOCK)
  }else{
    // If recalibration ok
    if(CalibrateCC1020(PA_POWER)){
      // Indicate PLL in LOCK
      lock_status = LOCK_RECAL_OK;
    // Else (recalibration failed)
    }else{
      // Indicate PLL out of LOCK
      lock_status = LOCK_NOK;
    }
  }

  // Restore PA setting
  WriteToCC1020Register(CC1020_PA_POWER,PA_POWER);

  // Turn OFF DCLK squelch in TX  // Interface[4]=0;
  WriteToCC1020Register(CC1020_INTERFACE,ReadFromCC1020Register(CC1020_INTERFACE)&~0x10);

  // Return LOCK status to application
  return (lock_status);
}

/****************************************************************************/
/*  This routine puts the CC1020 into power down mode. Use WakeUpCC1020ToRX */
/*  followed by SetupCC1020RX or WakeupCC1020ToTX followed by SetupCC1020TX */
/*  to wake up from power down                                              */
/****************************************************************************/

void SetupCC1020PD(void)
{
  // Put CC1020 into power-down
  WriteToCC1020Register(CC1020_MAIN,0x1F);

  // Turn off PA to minimise current draw
  WriteToCC1020Register(CC1020_PA_POWER,0x00);
}

/****************************************************************************/
/*  This routine wakes the CC1020 up from PD mode to RX mode                */
/****************************************************************************/

void WakeUpCC1020ToRX(char RXANALOG)
{
  volatile int i;

  // Turn on xtal oscillator core
  WriteToCC1020Register(CC1020_MAIN,0x1B);

  // Setup bias current adjustment
  WriteToCC1020Register(CC1020_ANALOG,RXANALOG);

  // Insert wait routine here, must wait for xtal oscillator to stabilise, 
  // typically takes 2-5ms.
  for (i=0x0260; i > 0; i--);

  // Turn on bias generator
  WriteToCC1020Register(CC1020_MAIN,0x19);

  // Wait for 150 usec
  for (i=0x0010; i > 0; i--);

  // Turn on frequency synthesiser
  WriteToCC1020Register(CC1020_MAIN,0x11);
}

/****************************************************************************/
/*  This routine wakes the CC1020 up from PD mode to TX mode                */
/****************************************************************************/

void WakeUpCC1020ToTX(char TXANALOG)
{
  volatile int i;

  // Turn on xtal oscillator core
  WriteToCC1020Register(CC1020_MAIN,0xDB);

  // Setup bias current adjustment
  WriteToCC1020Register(CC1020_ANALOG,TXANALOG);

  // Insert wait routine here, must wait for xtal oscillator to stabilise, 
  // typically takes 2-5ms. 
  for (i=0x0260; i > 0; i--);

  // Turn on bias generator
  WriteToCC1020Register(CC1020_MAIN,0xD9);

  // Wait for 150 usec
  for (i=0x0010; i > 0; i--);

  // Turn on frequency synthesiser
  WriteToCC1020Register(CC1020_MAIN,0xD1);
}

/****************************************************************************/
/*  This routine acquires the average RSSI level in dBm                        */
/****************************************************************************/
int ReadRSSIlevelCC1020(void){
  char i;
  unsigned char RSSI[5];
  unsigned char FILTER;
  int RSSI_dBm;

  // RSSI formula based on CC1020 datahseet and application note 30:
  // P = 1.5 x RSSI - 3 x VGA_SETTING - RSSI_Offset [dBm]

  /*
  VGA_SETTING based on SmartRF Studio - CC1020, v5.3.0.0
  Note: these settings could be subject to optimisation.
  
  434MHz range:
  -------------------------------------------------
  12.5 => VGA3 = 0x31 => VGA_SETTING = 0x11 = 17dec
  25   => VGA3 = 0x2F => VGA_SETTING = 0x0F = 15dec
  50   => VGA3 = 0x2E => VGA_SETTING = 0x0E = 14dec
  100  => VGA3 = 0x2D => VGA_SETTING = 0x0D = 13dec
  150  => VGA3 = 0x2F => VGA_SETTING = 0x0F = 15dec
  200  => VGA3 = 0x32 => VGA_SETTING = 0x12 = 18dec
  500  => VGA3 = 0x33 => VGA_SETTING = 0x13 = 19dec
  
  868MHz range:
  -------------------------------------------------
  12.5 => VGA3 = 0x2F => VGA_SETTING = 0x0F = 15dec
  25   => VGA3 = 0x2E => VGA_SETTING = 0x0E = 14dec
  50   => VGA3 = 0x2D => VGA_SETTING = 0x0D = 13dec
  100  => VGA3 = 0x2D => VGA_SETTING = 0x0D = 13dec
  150  => VGA3 = 0x2E => VGA_SETTING = 0x0E = 14dec
  200  => VGA3 = 0x30 => VGA_SETTING = 0x10 = 16dec
  500  => VGA3 = 0x34 => VGA_SETTING = 0x14 = 20dec
  */

  // Get current channel spacing
  FILTER = ReadFromCC1020Register(CC1020_FILTER)&0x7F;

  // Calculate average RSSI in dBm (initially without offset):
  for(i = 0; i < 5; i++) {
    RSSI[i] = ReadFromCC1020Register(CC1020_RSSI);
  }
  RSSI_dBm = (int)((((unsigned int)RSSI[0]+(unsigned int)RSSI[1]+(unsigned int)RSSI[2]+(unsigned int)RSSI[3]+(unsigned int)RSSI[4])*3)/(2*5));
  RSSI_dBm = ((RSSI_dBm*3) - (3*(int)(ReadFromCC1020Register(CC1020_VGA3)&0x1F)*2)) / 2;

  // Calculate average RSSI in dBm with offset, according to frequency band:
  // Active frequency is in 800 MHz band
  if( (ReadFromCC1020Register(CC1020_ANALOG)&0x80) == 0x80 ) {
    switch ( FILTER ) {
      case 0x58://12.5 kHz spacing
      case 0x3F://12.5 kHz spacing, optimal sensitivity
        RSSI_dBm = RSSI_dBm - 95;
        break;
      case 0x2F://25 kHz spacing
        RSSI_dBm = RSSI_dBm - 96;
        break;
      case 0x2B://50 kHz spacing
        RSSI_dBm = RSSI_dBm - 95;
        break;
      case 0x25://100 kHz spacing
        RSSI_dBm = RSSI_dBm - 96;
        break;
      case 0x22://150 kHz spacing
        RSSI_dBm = RSSI_dBm - 99;
        break;
      case 0x01://200 kHz spacing
        RSSI_dBm = RSSI_dBm - 99;
        break;
      case 0x00://500 kHz spacing
        RSSI_dBm = RSSI_dBm - 101;
        break;
    }
  // Active frequency is in 434 MHz band
  } else {
    switch ( FILTER ) {
      case 0x38://12.5 kHz spacing
      case 0x2F://25 kHz spacing
        RSSI_dBm = RSSI_dBm - 102;
        break;
      case 0x2B://50 kHz spacing
        RSSI_dBm = RSSI_dBm - 100;
        break;
      case 0x25://100 kHz spacing
        RSSI_dBm = RSSI_dBm - 99;
        break;
      case 0x22://150 kHz spacing
        RSSI_dBm = RSSI_dBm - 101;
        break;
      case 0x01://200 kHz spacing
        RSSI_dBm = RSSI_dBm - 102;
        break;
      case 0x00://500 kHz spacing
        RSSI_dBm = RSSI_dBm - 103;
        break;
      }
  }

  return(RSSI_dBm);
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?