Advertisement
Guest User

Untitled

a guest
Jun 22nd, 2017
61
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 11.98 KB | None | 0 0
  1. /** *******************************************************************************************
  2. THIS FILE CONTAINS ALL THE LOW LEVEL FUNCTIONS SPECIFIC TO THE CC1020
  3. *******************************************************************************************
  4.  
  5.  
  6.  * <p>InitializeCC1020 is just a cozy place to call all of the functions needed to set up
  7.  * the CC1020 on power up.  All of these only need to be called at startup and having them
  8.  * here helps tidy up main().</p>
  9.  *
  10.  * @post The CC1020 needs to be placed into a mode. Enter TX mode (SetupCC1020TX), RX mode
  11.  * (SetupCC1020RX) or power down mode (SetupCC1020PD)
  12.  * From power-down mode to RX:
  13.  * 1) WakeUpCC1020ToRX
  14.  * 2) SetupCC1020RX
  15.  * From power-down mode to TX:
  16.  * 1) WakeUpCC1020ToTX
  17.  * 2) SetupCC1020TX
  18.  * Switching from RX to TX mode:
  19.  * 1) SetupCC1020TX
  20.  * Switching from TX to RX mode:
  21.  * 1) SetupCC1020RX
  22.  
  23.  **/
  24.  
  25. #include "CC1020.h"
  26.  
  27. char InitializeCC1020(unsigned char *Configuration, unsigned char setconfig)
  28. {
  29.     unsigned char success;
  30.     if(setconfig)
  31.     {
  32.         *Configuration={MAIN, INTERFACE, RESET, SEQUENCING,
  33.         FREQ_2A, FREQ_1A, FREQ_0A, CLOCK_A,
  34.         FREQ_2B, FREQ_1B, FREQ_0B, CLOCK_B,
  35.         VCO, MODEM, DEVIATION, AFC_CONTROL,
  36.         FILTER, VGA1, VGA2, VGA3, VGA4, LOCK,
  37.         FRONTEND, ANALOG, BUFF_SWING,
  38.         BUFF_CURRENT, PLL_BW, CALIBRATE,
  39.         PA_POWER, MATCH, PHASE_COMP, GAIN_COMP,
  40.         POWERDOWN};
  41.     }
  42.     SetupCC1020PD();
  43.     ResetCC1020();
  44.    
  45.     ConfigureCC1020(Configuration);
  46.    
  47.     WakeUpCC1020ToTX();
  48.     //DIO to output code goes here
  49.     success=CalibrateCC1020()<<1;
  50.    
  51.     WakeUpCC1020ToRX();
  52.     //DIO to input code goes here
  53.     success|=CalibrateCC1020();
  54.     //the two LSB of success let us know if the calibration worked.
  55.     return success;
  56. }
  57.  
  58. /** @} */
  59.  
  60. /*
  61.  * This routine calibrates the CC1020.  It should be called for both receive and transmit states.
  62.  *
  63.  * @pre All configuration registers have been populated and the CC1020 has been either placed in
  64.  *      transmit or receive mode.
  65.  *
  66.  * @post The CC1020 is calibrated for either transmit or receive mode.
  67.  *
  68.  * @return 0 if calibration fails, non-zero otherwise. Checks the LOCK to check for success
  69.  */
  70. char CalibrateCC1020(void)
  71. {
  72.   volatile int TimeOutCounter;
  73.   volatile int nCalAttempt;
  74.  
  75.   // Turn off PA to avoid spurs during calibration in TX mode
  76.   WriteToCC1020Register(CC1020_PA_POWER,0x00);
  77.  
  78.   // Calibrate, and re-calibrate if necessary:
  79.   for (nCalAttempt = 2 /*CAL_ATTEMPT_MAX*/; (nCalAttempt>0); nCalAttempt--) {
  80.  
  81.     // Start calibration
  82.     WriteToCC1020Register(CC1020_CALIBRATE,0xB4);
  83.  
  84.     // Monitor actual calibration start (ref. Errata Note 04 - CC1020)
  85.     for(TimeOutCounter=CAL_TIMEOUT; ((ReadFromCC1020Register(CC1020_STATUS)&0x80)==0x80)&&(TimeOutCounter>0); TimeOutCounter--);
  86.     /**
  87.      * @remarks
  88.      * Important note from Chipcon:
  89.      * In active mode the CC1020 should theoretically initiate an internal action/process more or less
  90.      * instantly upon receiving any command from e.g. an MCU. However, upon sending a [calibration start]
  91.      * command to CC1020, tests shows that the [STATUS.CAL_COMPLETE]-signal sometimes remains asserted
  92.      * (or idle) close to 100 usec after the command has been originally issued. Consequently this process
  93.      * must be carefully monitored to avoid premature PLL LOCK monitoring; do not proceed with subsequent
  94.      * PLL LOCK monitoring before the calibration has actually completed inside the CC1020! Errata Note 04
  95.      * suggests that [calibration start] should be monitored by a fixed timeout > 100 usec. However, the
  96.      * above method implements an adaptive monitoring of [calibration start], which basically waits for the
  97.      * [STATUS.CAL_COMPLETE]-signal to initialise/deassert (indicating calibration has actually started)
  98.      * before proceeding with monitoring calibration complete and PLL LOCK. Chipcon considers both methods
  99.      * safe, and thus leaves it up to the user, which one to use.
  100.      */
  101.  
  102.     // Monitor calibration complete
  103.     for(TimeOutCounter=CAL_TIMEOUT; ((ReadFromCC1020Register(CC1020_STATUS)&0x80)==0x00)&&(TimeOutCounter>0); TimeOutCounter--);
  104.  
  105.     // Monitor lock
  106.     for(TimeOutCounter=LOCK_TIMEOUT; ((ReadFromCC1020Register(CC1020_STATUS)&0x10)==0x00)&&(TimeOutCounter>0); TimeOutCounter--);
  107.  
  108.     // Abort further recalibration attempts if successful LOCK
  109.     if((ReadFromCC1020Register(CC1020_STATUS)&0x10) == 0x10) {
  110.       break;
  111.     }
  112.   }
  113.  
  114.   // Restore PA setting
  115.   WriteToCC1020Register(CC1020_PA_POWER, PA_POWER);
  116.  
  117.   // Return state of LOCK_CONTINUOUS bit
  118.   return ((ReadFromCC1020Register(CC1020_STATUS)&0x10)==0x10);
  119. }
  120.  
  121. /**
  122.  * Send configuration data to the CC1020.
  123.  *
  124.  * @pre Default configuration values have been defined in CC1020settings.h
  125.  *
  126.  * @post CC1020 Configuration registers are loaded with configuration values from
  127.  * CC1020settings.h
  128.  */
  129. void ConfigureCC1020(char* Configuration)
  130. {
  131.     short val;
  132.     char i;
  133.     for (i=0;i<33;i++)
  134.     {
  135.         val=Configuration[i];
  136.         WriteToCC1020Register(i,val);
  137.     }
  138. }
  139.  
  140. /**
  141.  * Reset the CC1020, clearing all registers.
  142.  *
  143.  * @post CC1020 is reset and all configuration registers are cleared.
  144.  */
  145. void ResetCC1020(void)
  146. {
  147.   // Reset CC1020
  148.   WriteToCC1020Register(CC1020_MAIN, 0x0F&~0x01);
  149.  
  150.   // Bring CC1020 out of reset
  151.   WriteToCC1020Register(CC1020_MAIN, 0x1F);
  152.  
  153. }
  154.  
  155. /**
  156.  * This routine puts the CC1020 into power down mode. Use WakeUpCC1020ToRX followed by SetupCC1020RX or WakeupCC1020ToTX
  157.  * followed by SetupCC1020TX to wake up from power down.
  158.  *
  159.  * @pre CC1020 is not in Power Down mode
  160.  *
  161.  * @post CC1020 is in Power Down mode.  Internal VCO and PA are off.
  162.  */
  163. void SetupCC1020PD(void)
  164. {
  165.   // Put CC1020 into power-down
  166.   WriteToCC1020Register(CC1020_MAIN,0x1F);
  167.  
  168.   // Turn off PA to minimise current draw
  169.   WriteToCC1020Register(CC1020_PA_POWER,0x00);
  170. }
  171.  
  172. /**
  173.  * This routine puts the CC1020 into RX mode.
  174.  *
  175.  * @pre CC1020 is not in receive mode.  If the CC1020 is coming out of Power Down mode, WakeupCC1020ToRx must be called first.
  176.  *
  177.  * @post CC1020 is in receive mode.
  178.  *
  179.  * @return Lock status.
  180.  */
  181. char SetupCC1020RX(void)
  182. {
  183.   volatile int TimeOutCounter;
  184.   char lock_status;
  185.     char dummy, addr;
  186.  
  187.   // Switch into RX, switch to freq. reg A
  188.   WriteToCC1020Register(CC1020_MAIN,0x11);
  189.  
  190.   // Setup bias current adjustment
  191.   WriteToCC1020Register(CC1020_ANALOG,RXANALOG);
  192.   WriteToCC1020Register(CC1020_DEVIATION,RXDEVIATION);
  193.   WriteToCC1020Register(CC1020_AFC_CONTROL,0xC3);
  194.   WriteToCC1020Register(CC1020_VGA3,0x2E);
  195.   WriteToCC1020Register(CC1020_VGA4,0x29);
  196.  
  197.   // Monitor LOCK
  198.   for(TimeOutCounter=LOCK_TIMEOUT; ((ReadFromCC1020Register(CC1020_STATUS)&0x10)==0)&&(TimeOutCounter>0); TimeOutCounter--);
  199.  
  200.   // If PLL in lock
  201.   if((ReadFromCC1020Register(CC1020_STATUS)&0x10)==0x10){
  202.     // Indicate PLL in LOCK
  203.     lock_status = LOCK_OK;
  204.   // Else (PLL out of LOCK)
  205.   }else{
  206.     // If recalibration ok
  207.     if(CalibrateCC1020()){
  208.       // Indicate PLL in LOCK
  209.       lock_status = LOCK_RECAL_OK;
  210.     // Else (recalibration failed)
  211.     }else{
  212.       // Indicate PLL out of LOCK
  213.       lock_status = LOCK_NOK;
  214.     }
  215.   }
  216.     WriteToCC1020Register(CC1020_MAIN,RXMAIN);
  217.   // Switch RX part of CC1020 on
  218.  
  219.   return lock_status;
  220. }
  221.  
  222. /**
  223.  * This routine puts the CC1020 into TX mode.
  224.  *
  225.  * @pre CC1020 is not in Tx mode.  When switching to TX from PD, use WakeupC1020ToTX first.
  226.  *
  227.  * @post CC1020 is in Tx mode.
  228.  *
  229.  * @return Lock status.
  230.  */
  231. char SetupCC1020TX(void)
  232. {
  233.   volatile int TimeOutCounter;
  234.   char lock_status;
  235.  
  236.   // Turn off PA to avoid frequency splatter
  237.   WriteToCC1020Register(CC1020_PA_POWER,0x00);
  238.  
  239.   // Setup bias current adjustment
  240.   WriteToCC1020Register(CC1020_ANALOG,TXANALOG);
  241.   WriteToCC1020Register(CC1020_DEVIATION,TXDEVIATION);
  242.   WriteToCC1020Register(CC1020_AFC_CONTROL,0xC1);
  243.   WriteToCC1020Register(CC1020_VGA3,0x2F);
  244.   WriteToCC1020Register(CC1020_VGA4,0x2D);
  245.  
  246.   // Switch into TX, switch to freq. reg B
  247.   WriteToCC1020Register(CC1020_MAIN,0xC1);
  248.  
  249.   // Monitor LOCK
  250.   for(TimeOutCounter=LOCK_TIMEOUT; ((ReadFromCC1020Register(CC1020_STATUS)&0x10)==0)&&(TimeOutCounter>0); TimeOutCounter--);
  251.  
  252.   // If PLL in lock
  253.   if((ReadFromCC1020Register(CC1020_STATUS)&0x10)==0x10){
  254.     // Indicate PLL in LOCK
  255.     lock_status = LOCK_OK;
  256.   // Else (PLL out of LOCK)
  257.   }else{
  258.     // If recalibration ok
  259.     if(CalibrateCC1020()){
  260.       // Indicate PLL in LOCK
  261.       lock_status = LOCK_RECAL_OK;
  262.     // Else (recalibration failed)
  263.     }else{
  264.       // Indicate PLL out of LOCK
  265.       lock_status = LOCK_NOK;
  266.     }
  267.   }
  268.  
  269.   // Restore PA setting
  270.   WriteToCC1020Register(CC1020_PA_POWER,PA_POWER);
  271.  
  272.   // Turn OFF DCLK squelch in TX
  273.   WriteToCC1020Register(CC1020_INTERFACE,ReadFromCC1020Register(CC1020_INTERFACE)&~0x10);
  274.  
  275.   // Return LOCK status to application
  276.   return (lock_status);
  277. }
  278.  
  279. /**
  280.  *  This routine wakes the CC1020 up from PD mode to RX mode
  281.  *
  282.  * @pre CC1020 is in Power Down mode.
  283.  *
  284.  * @post CC1020 is ready for SetupCC1020RX()
  285.  */
  286. void WakeUpCC1020ToRX(void)
  287. {
  288.   volatile int i;
  289.  
  290.   // Turn on xtal oscillator core
  291.   WriteToCC1020Register(CC1020_MAIN,0x1B);
  292.  
  293.   // Setup bias current adjustment
  294.   WriteToCC1020Register(CC1020_ANALOG,RXANALOG);
  295.   WriteToCC1020Register(CC1020_DEVIATION,RXDEVIATION);
  296.   WriteToCC1020Register(CC1020_AFC_CONTROL,0xC3);
  297.   WriteToCC1020Register(CC1020_VGA3,0x2E);
  298.   WriteToCC1020Register(CC1020_VGA4,0x29);
  299.  
  300.   // Insert wait routine here, must wait for xtal oscillator to stabilise,
  301.   // typically takes 2-5ms.
  302.   _delay_ms(5);
  303. //  for (i=0x0260; i > 0; i--);
  304.  
  305.   // Turn on bias generator
  306.   WriteToCC1020Register(CC1020_MAIN,0x19);
  307.  
  308.   // Wait for 150 usec
  309.   _delay_us(150);
  310. //  for (i=0x0010; i > 0; i--);
  311.  
  312.   // Turn on frequency synthesiser
  313.   WriteToCC1020Register(CC1020_MAIN,0x11);
  314. }
  315.  
  316. /**
  317.  *  This routine wakes the CC1020 up from PD mode to TX mode
  318.  *
  319.  * @pre CC1020 is in Power Down mode.
  320.  *
  321.  * @post CC1020 is ready for SetupCC1020TX()
  322.  */
  323. void WakeUpCC1020ToTX(void)
  324. {
  325.   volatile int i;
  326.  
  327.   // Turn on xtal oscillator core
  328.   WriteToCC1020Register(CC1020_MAIN,0xDB);
  329.  
  330.   // Setup bias current adjustment
  331.   WriteToCC1020Register(CC1020_ANALOG,TXANALOG);
  332.   WriteToCC1020Register(CC1020_DEVIATION,TXDEVIATION);
  333.   WriteToCC1020Register(CC1020_AFC_CONTROL,0xC1);
  334.   WriteToCC1020Register(CC1020_VGA3,0x2F);
  335.   WriteToCC1020Register(CC1020_VGA4,0x2D);
  336.  
  337.   // Insert wait routine here, must wait for xtal oscillator to stabilise,
  338.   // typically takes 2-5ms.
  339.   _delay_ms(5);
  340. //  for (i=0x0260; i > 0; i--);
  341.  
  342.   // Turn on bias generator
  343.   WriteToCC1020Register(CC1020_MAIN,0xD9);
  344.  
  345.   // Wait for 150 usec
  346.   _delay_us(150);
  347. //  for (i=0x0010; i > 0; i--);
  348.  
  349.   // Turn on frequency synthesiser
  350.   WriteToCC1020Register(CC1020_MAIN,0xD1);
  351. }
  352.  
  353. /**
  354.  * Reads a byte from one of the CC1020 registers.
  355.  *
  356.  * @pre SPI bus is open and configured
  357.  *
  358.  * @param addr The configuaration register address to read from.
  359.  *
  360.  * @return The specified CC1020 register value.
  361.  *
  362.  * @remarks There is a strange timing issue with either the implementation of the
  363.  * C18 SPI library or the CC1020's SPI implementation.  This is resolved by writing
  364.  * directly to the registers rather than using the Microchip provided function calls.
  365.  */
  366. char ReadFromCC1020Register(char addr)
  367. {
  368.     SS_LOW;
  369.     SPDR = (addr<<1)&0xFE;
  370.     while(!(SPSR & (1<<SPIF)))
  371.     ;
  372.     unsigned char a=SPDR;       //have to read this to clear the flag
  373.     SPDR = 0x00;            //dummy write
  374.     while(!(SPSR & (1<<SPIF)))
  375.     ;
  376.     a=SPDR;
  377.     SS_HIGH;
  378.     return a;
  379. }
  380.  
  381. /**
  382.  * Writes configuration data given by 'char data' to a register in the CC1020 configuration registers
  383.  * given by 'char addr'
  384.  *
  385.  * @pre SPI bus is open and configured.
  386.  *
  387.  * @post CC1020 register at 'addr' contains value of 'data.'
  388.  *
  389.  * @param addr The register address to write to.
  390.  * @param data Register contents to write.
  391.  */
  392. void WriteToCC1020Register(char addr, char data)
  393. {
  394.     SS_LOW;
  395.     SPDR = (addr<<1)|0x01;
  396.     while(!(SPSR & (1<<SPIF)))
  397.     ;
  398.     unsigned char a=SPDR;           //have to read this to clear the flag
  399.     SPDR = data;
  400.     while(!(SPSR & (1<<SPIF)))
  401.     ;
  402.     SS_HIGH;
  403. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement