📄 cc1000.c
字号:
} } else { // seeing more of the preamble preamble_count++; //ANS hack: Can loose a few preambles since the transmitter //sends out 12 preamble bytes and the recviever needs only 6 #ifdef GET_RSSI //First check whether the signal value is already not filled in if (cc1000_recv_buf->signal == 0) { cc1000_rssi_on(); rssival = rssi_poll(); cc1000_rssi_off(); cc1000_recv_buf->signal = rssival; //ANS hack ends }#endif#ifdef TS_PACKET if(cc1000_recv_buf->ts == 0) { cc1000_recv_buf->ts = *real_timer_get_ticks(); cc1000_recv_buf->tcnt = TCNT2; }#endif } prev_data = spi_data;}void state_recv_idle(void){ spi_data = SPDR; if (spi_data == PREAMBLE_BYTE || spi_data == 0x55) {#ifdef GET_RSSI //ANS hack: //We want to initilize the rssival of the cc1000_recv_buf to 0 cc1000_recv_buf->signal = 0; //ANS hack ends#endif #ifdef TS_PACKET cc1000_recv_buf->ts = 0;#endif preamble_count = 0; cc1000_state = state_recv_pre; }}// ***** Radio Configuration Functions *************/// Global variables for the current frequency and the power level/** @brief Current frequency. */uint8_t cur_freq;/** @brief Current power level. */uint8_t rf_power;static uint8_t cc1000Mode;#define PALE_HIGH() CONFIG_PORT |= (1 << PALE)#define PALE_LOW() CONFIG_PORT &= ~(1 << PALE)#define PCLK_HIGH() CONFIG_PORT |= (1 << PCLK)#define PCLK_LOW() CONFIG_PORT &= ~(1 << PCLK)#define PDATA_HIGH() CONFIG_PORT |= (1 << PDATA)#define PDATA_LOW() CONFIG_PORT &= ~(1 << PDATA)void cc1000_init (uint8_t freq){ uint8_t int_handle; int_handle = mos_disable_ints(); cur_freq = freq; // record the current setting frequency // record the current setting power#ifdef PLATFORM_NYMPH rf_power = PA_POW_PARAM; // Set the three configuration pin high CONFIG_PORT_DIR |= ((1 << PALE) | (1 << PCLK) | (1 << PDATA)); //PORTC |= ( (1<<PALE) | (1<<PCLK) | (1<<PDATA)); #elif defined(PLATFORM_MICA2) || defined(PLATFORM_MICA2DOT) rf_power = 0xff; //DDRA &= 0xBF; //DDRB &= 0x8F; //DDRA = 0; //DDRB = 0; CONFIG_PORT_DIR |= ((1 << PALE) | (1 << PCLK) | (1 << PDATA)); //CONFIG_PORT &= ~((1 << PALE) | (1 << PCLK) | (1 << PDATA));#else #error "Unimplemented platform"#endif // Make this three pin outputs*/ //DDRC |= ( (1<<PALE) | (1<<PCLK) | (1<<PDATA) ); // Set the three configuration pin high PALE_HIGH(); PCLK_HIGH(); PDATA_HIGH(); // Reset and turn on the crystal oscillator core // 0x3A // RXTX = 0 F_REG = 0 RX_PD = 1 TX_PD = 1 FS_PD = 1 CORE_PD = 0 // BIAS_PD = 1 RESET_N = 0 cc1000_write(CC1000_MAIN, ((1 << CC1000_RX_PD) | (1 << CC1000_TX_PD) | (1 << CC1000_FS_PD) | (1 << CC1000_BIAS_PD))); // RESET cc1000_write(CC1000_MAIN, ((1 << CC1000_RX_PD) | (1 << CC1000_TX_PD) | (1 << CC1000_FS_PD) | (1 << CC1000_BIAS_PD) | (1 << CC1000_RESET_N))); // wait 2 ms // Time to wait depends on crystal frequency and the load capacitance mos_udelay(2000); // Program all registers, Calibrate VCO and PLL and set the frequency cc1000_set(freq); //ANS: Start the clock so that we can start timestamping the packets#ifdef TS_PACKET real_timer_init(); real_timer_clear();#endif // Setup default baud rate UBRR0H = (uint8_t)(DEFAULT_BAUD_RATE >> 8); UBRR0L = (uint8_t)(DEFAULT_BAUD_RATE); // enable transmitter and receiver UCSR0B = (1 << RXEN0) | (1 << TXEN0); // no parity, 8 bits UCSR0C = (3 << UCSZ00); mos_enable_ints(int_handle);}inline uint8_t cc1000_get_mode (void){ return cc1000Mode;}void cc1000_change_freq (uint8_t new_freq){ int i; uint8_t j; // record the current setting frequency cur_freq = new_freq; // write the corresponding FREQ registers for(i = 1; i < 7; i++) { j = pgm_read_byte(&cc1000_params[cur_freq][i - 1]); cc1000_write(i, j); } //recalibrate after setting the new frequency cc1000_calibrate();}void cc1000_set (uint8_t new_freq){ int i; uint8_t j; // record the current setting frequency cur_freq = new_freq; // record the current setting power rf_power = PA_POW_PARAM; // write the corresponding FREQ registers for(i = 1; i < 7; i++) { j = pgm_read_byte(&cc1000_params[cur_freq][i - 1]); cc1000_write(i, j); } // First write the template to the registers //for (i=7;i<29;i++) // cc1000_write(i, cc1000_para_template[i] ); cc1000_write(CC1000_FSEP1, FSEP1_PARAM); cc1000_write(CC1000_FSEP0, FSEP0_PARAM); cc1000_write(CC1000_CURRENT, RX_CURRENT_PARAM); cc1000_write(CC1000_FRONT_END, FRONT_END_PARAM); cc1000_write(CC1000_PA_POW, PA_POW_PARAM); cc1000_write(CC1000_PLL, PLL_RX_PARAM); cc1000_write(CC1000_LOCK, LOCK_PARAM); cc1000_write(CC1000_CAL, CAL_PARAM); cc1000_write(CC1000_MODEM2, MODEM2_PARAM); cc1000_write(CC1000_MODEM1, MODEM1_PARAM); cc1000_write(CC1000_MODEM0, MODEM0_PARAM); cc1000_write(CC1000_MATCH, MATCH_PARAM); cc1000_write(CC1000_FSCTRL, FSCTRL_PARAM); cc1000_write(CC1000_FSHAPE7, FSHAPE7_PARAM); cc1000_write(CC1000_FSHAPE6, FSHAPE6_PARAM); cc1000_write(CC1000_FSHAPE5, FSHAPE5_PARAM); cc1000_write(CC1000_FSHAPE4, FSHAPE4_PARAM); cc1000_write(CC1000_FSHAPE3, FSHAPE3_PARAM); cc1000_write(CC1000_FSHAPE2, FSHAPE2_PARAM); cc1000_write(CC1000_FSHAPE1, FSHAPE1_PARAM); cc1000_write(CC1000_FSDELAY, FSDELAY_PARAM); cc1000_write(CC1000_TEST4, TEST4_PARAM); cc1000_write(CC1000_PRESCALER, PRESCALER_PARAM); //recalibrate after setting the new frequency cc1000_calibrate(); //set the cc1000 to receive mode cc1000_mode(CC1000_MODE_RX);}uint8_t cc1000_get_channel (void){ return cur_freq;}uint8_t cc1000_get_power (void){ return rf_power;}// TODO: Test and debug this function!uint8_t cc1000_read (uint8_t addr){ uint8_t i; uint8_t val = 0; uint8_t int_handle; int_handle = mos_disable_ints(); PALE_HIGH(); addr <<= 1; // We only want the lower 7 bits PALE_LOW(); // Send 7 address bits for(i = 0; i < 7; i++) { PCLK_HIGH(); if(addr & 0x80) PDATA_HIGH(); else PDATA_LOW(); addr <<= 1; // Now cycle PCLK to write the bit PCLK_LOW(); } // Send read bit PCLK_HIGH(); PDATA_LOW(); PCLK_LOW(); PCLK_HIGH(); PALE_HIGH(); PDATA_HIGH(); CONFIG_PORT_DIR &= ~(1 << PDATA); // Set up PDATA as an input // Receive data bits for(i = 0; i < 8; i++) { PCLK_LOW(); if(CONFIG_PORT_PIN & (1 << PDATA)) val = (val << 1) | 0x01; else val = (val << 1) & 0xFE; PCLK_HIGH(); } PALE_HIGH(); CONFIG_PORT_DIR |= (1 << PDATA); // Set up PDATA as an output again //CONFIG_PORT |= (1 << PDATA); PDATA_HIGH(); mos_enable_ints(int_handle); return val;}void cc1000_write (uint8_t addr, uint8_t val){ uint8_t i; uint8_t int_handle; int_handle = mos_disable_ints(); addr <<= 1; // We only want the lower 7 bits PALE_LOW(); // Send 7 address bits for(i = 0; i < 7; i++) { if(addr & 0x80) PDATA_HIGH(); else PDATA_LOW(); /* Now cycle PCLK to write the bit. */ PCLK_LOW(); PCLK_HIGH(); addr <<= 1; } // Send write bit PDATA_HIGH(); PCLK_LOW(); PCLK_HIGH(); PALE_HIGH(); // Send 8 data bits for(i = 0; i < 8; i++) { if(val & 0x80) PDATA_HIGH(); else PDATA_LOW(); // Now cycle PCLK to write the bit PCLK_LOW(); PCLK_HIGH(); val <<= 1; } // Set the three configuration pins high PALE_HIGH(); PDATA_HIGH(); PCLK_HIGH(); mos_enable_ints(int_handle);}void cc1000_reset (void){ uint8_t mainValue; mainValue = cc1000_read(CC1000_MAIN); // Reset CC1000 the reset pin to 0 cc1000_write(CC1000_MAIN, mainValue & 0xFE); cc1000_write(CC1000_MAIN, mainValue | 0x01); // Bring CC1000 out of reset}void cc1000_calibrate (void){ //the following procedure are follwing the data sheet // Write FREQ_A, FREQ_B If DR>=38kBd then write // TEST4: L2KIO=3Fh Write CAL: CAL_DUAL = 0 cc1000_write(CC1000_PA_POW, 0x00); // turn off radio power cc1000_write(CC1000_TEST4, TEST4_PARAM); // RX frequency register A is calibrated first // Write MAIN: RXTX = 0; F_REG = 0 RX_PD = 0; TX_PD = 1; // FS_PD = 0 CORE_PD = 0; BIAS_PD = 0; RESET_N=1 cc1000_write(CC1000_MAIN, ((1 << CC1000_TX_PD) | (1 << CC1000_RESET_N))); // RX current is the VCO current to be used in RX mode cc1000_write(CC1000_CURRENT, RX_CURRENT_PARAM); // Calibration is performed in RX mode, Result is // stored in TEST0 and TEST2, RX register // Write CAL: CAL_START=1, set the wait cc1000_write(CC1000_CAL, ((1 << CC1000_CAL_START) | (1 << CC1000_CAL_WAIT) | (6 << CC1000_CAL_ITERATE))); while((cc1000_read(CC1000_CAL) & (1 << CC1000_CAL_COMPLETE)) == 0); // Write CAL: CAL_START=0 cc1000_write(CC1000_CAL, ((1 << CC1000_CAL_WAIT) | (6 << CC1000_CAL_ITERATE))); // TX frequency register B is calibrated second // Write MAIN: RXTX = 1; F_REG = 1 RX_PD = 1; TX_PD = 0; // FS_PD = 0 CORE_PD = 0; BIAS_PD = 0; RESET_N=1 cc1000_write(CC1000_MAIN, ((1 << CC1000_RXTX) | (1 << CC1000_F_REG) | (1 << CC1000_RX_PD) | (1 << CC1000_RESET_N))); // TX current is the VCO current to be used in TX mode cc1000_write(CC1000_CURRENT, TX_CURRENT_PARAM); //PA is turned off to prevent spurious emission cc1000_write(CC1000_PA_POW, 0x00); // Write CAL: CAL_START=1 cc1000_write(CC1000_CAL, ((1 << CC1000_CAL_START) | (1 << CC1000_CAL_WAIT) | (6 << CC1000_CAL_ITERATE))); while((cc1000_read(CC1000_CAL) & (1 << CC1000_CAL_COMPLETE)) == 0); // Write CAL: CAL_START=0 cc1000_write(CC1000_CAL, ((1 << CC1000_CAL_WAIT) | (6 << CC1000_CAL_ITERATE)));}void cc1000_set_power(uint8_t power){ rf_power = power; // TODO it would be better to set the TX power only when we're transmitting cc1000_write(CC1000_PA_POW, power); mos_udelay(250);}void cc1000_mode (uint8_t mode){ switch (mode) { case CC1000_MODE_RX: cc1000Mode = CC1000_MODE_RX; // Procedures on the data sheet // Turn on RX: RX_PD = 0, FS_PD = 0 RX_PD = 0, FS_PD = 0 cc1000_write(CC1000_MAIN, ((1 << CC1000_TX_PD) | (1 << CC1000_RESET_N))); cc1000_write(CC1000_PA_POW, 0); // Writing current cc1000_write(CC1000_CURRENT, RX_CURRENT_PARAM); // Wait 250 us mos_udelay(250); break; case CC1000_MODE_TX: cc1000Mode = CC1000_MODE_TX; // Turn on TX: PA_POW = 00h MAIN: RXTX = 1, F_REG = 1 TX_PD = 0, // FS_PD = 0 cc1000_write(CC1000_MAIN, ((1 << CC1000_RXTX) | (1 << CC1000_F_REG) | (1 << CC1000_RX_PD) | (1 << CC1000_RESET_N))); // CURRENT = TX current cc1000_write(CC1000_CURRENT, TX_CURRENT_PARAM); // Wait 250 us mos_udelay(250); // PA_POW = Output power cc1000_write(CC1000_PA_POW, rf_power); // Wait 20 us mos_udelay(250); //mos_udelay (20); break; case CC1000_MODE_PD: cc1000_write(CC1000_MAIN, 0x3F); // Put CC1000 into power-down cc1000_write(CC1000_PA_POW, 0x00); // Turn off PA to minimise power break; case CC1000_MODE_SLEEP: // put the cc1000 to sleep cc1000_write(CC1000_MAIN, ((1 << CC1000_RX_PD) | (1 << CC1000_TX_PD) | (1 << CC1000_FS_PD) | (1 << CC1000_CORE_PD) | (1 << CC1000_BIAS_PD) | (1 << CC1000_RESET_N))); break; }}void cc1000_rssi_on (void){ cc1000_write(CC1000_FRONT_END, 0x32);}void cc1000_rssi_off (void){ cc1000_write(CC1000_FRONT_END, 0x30);}void cc1000_wakeup (void){ cc1000_on(); mos_udelay(500);}void cc1000_on (void){ cc1000_write(CC1000_MAIN, ((1 << CC1000_RX_PD) | (1 << CC1000_TX_PD) | (1 << CC1000_FS_PD) | (1 << CC1000_BIAS_PD) | (1 << CC1000_RESET_N))); mos_udelay(2000); cc1000_mode(CC1000_MODE_RX);}#endif#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -