void rf_security_enable(uint8_t *key) { FASTSPI_SETREG(CC2420_SECCTRL0, 0x0306); // Enable CTR encryption with key 0 FASTSPI_SETREG(CC2420_SECCTRL1, 0x0e0e); // Encrypt / Decrypt 18 bytes into header security_enable=1; }
/********************************************************** * set the radio into "normal" mode (buffered TXFIFO) and go into (data) receive */ void rf_data_mode() { #ifdef RADIO_PRIORITY_CEILING nrk_sem_pend(radio_sem); #endif FASTSPI_STROBE(CC2420_SRFOFF); //stop radio FASTSPI_SETREG(CC2420_MDMCTRL1, 0x0500); // default MDMCTRL1 value FASTSPI_SETREG(CC2420_DACTST, 0); // default value rf_flush_rx_fifo(); #ifdef RADIO_PRIORITY_CEILING nrk_sem_post(radio_sem); #endif }
void cc2420_setreg(enum cc2420_register regname, unsigned value) { int s = splhigh(); FASTSPI_SETREG(regname, value); splx(s); }
/* This assumes that the CC2420 is always on and "stable" */ static void set_frq(int c) { int f; // We can read even other channels with CC2420! // Fc = 2048 + FSCTRL ; Fc = 2405 + 5(k-11) MHz, k=11,12, ... , 26 f = c + 352; // Start from 2400 MHz to 2485 MHz, FASTSPI_SETREG(CC2420_FSCTRL, f); FASTSPI_STROBE(CC2420_SRXON); }
void rf_test_mode() { #ifdef RADIO_PRIORITY_CEILING nrk_sem_pend(radio_sem); #endif FASTSPI_STROBE(CC2420_SRFOFF); //stop radio // NOTE ON SETTING CC2420_MDMCTRL1 // // RF studio" uses TX_MODE=3 (CC2420_MDMCTRL1=0x050C) // to send an unmodulated carrier; data sheet says TX_MODE // can be 2 or 3. So it should not matter... // HOWEVER, using (TX_MODE=3) sometimes causes problems when // going back to "data" mode! FASTSPI_SETREG(CC2420_MDMCTRL1, 0x0508); // MDMCTRL1 with TX_MODE=2 FASTSPI_SETREG(CC2420_DACTST, 0x1800); // send unmodulated carrier rf_flush_rx_fifo(); #ifdef RADIO_PRIORITY_CEILING nrk_sem_post(radio_sem); #endif }
void rf_tx_power(uint8_t pwr) { uint16_t tmp; //tmp=0x5070; #ifdef RADIO_PRIORITY_CEILING nrk_sem_pend (radio_sem); #endif tmp=0xA0E0; tmp=tmp | (pwr&0x1F); FASTSPI_SETREG(CC2420_TXCTRL, tmp); // Set the FIFOP threshold to maximum #ifdef RADIO_PRIORITY_CEILING nrk_sem_post(radio_sem); #endif }
//------------------------------------------------------------------------------------------------------- // void halRfSetChannel(UINT8 Channel) // // DESCRIPTION: // Programs CC2420 for a given IEEE 802.15.4 channel. // Note that SRXON, STXON or STXONCCA must be run for the new channel selection to take full effect. // // PARAMETERS: // UINT8 channel // The channel number (11-26) //------------------------------------------------------------------------------------------------------- void halRfSetChannel(uint8_t channel) { uint16_t f; // Derive frequency programming from the given channel number f = (uint16_t) (channel - 11); // Subtract the base channel f = f + (f << 2); // Multiply with 5, which is the channel spacing f = f + 357 + 0x4000; // 357 is 2405-2048, 0x4000 is LOCK_THR = 1 // Write it to the CC2420 DISABLE_GLOBAL_INT(); FASTSPI_SETREG(CC2420_FSCTRL, f); ENABLE_GLOBAL_INT(); } // rfSetChannel
void rf_set_cca_thresh(int8_t t) { // default is -32 // Higher number is less sensitive uint16_t val; #ifdef RADIO_PRIORITY_CEILING nrk_sem_pend(radio_sem); #endif val=(t<<8) | 0x80; FASTSPI_SETREG(CC2420_RSSI, val); #ifdef RADIO_PRIORITY_CEILING nrk_sem_post(radio_sem); #endif }
/*---------------------------------------------------------------------------*/ void cc2420_aes_cipher(uint8_t *data, int len, int key_index) { int i; uint16_t secctrl0; FASTSPI_GETREG(CC2420_SECCTRL0, secctrl0); secctrl0 &= ~(CC2420_SECCTRL0_SAKEYSEL0 | CC2420_SECCTRL0_SAKEYSEL1); switch(key_index) { case 0: secctrl0 |= CC2420_SECCTRL0_SAKEYSEL0; break; case 1: secctrl0 |= CC2420_SECCTRL0_SAKEYSEL1; break; } FASTSPI_SETREG(CC2420_SECCTRL0, secctrl0); for(i = 0; i < len; i = i + MAX_DATALEN) { cipher16(data + i, MIN(len - i, MAX_DATALEN)); } }
/********************************************************** * Specifies the number of symbols to be part of preamble * arg is equal to number of bytes - 1. * (3 bytes is 802.15.4 compliant, so length arg would be 2) * Length arg supports values 0 to 15. See the datasheet of course for more details */ void rf_set_preamble_length(uint8_t length) { mdmctrl0 &= (0xFFF0); mdmctrl0 |= (length & 0x000F); FASTSPI_SETREG(CC2420_MDMCTRL0, mdmctrl0); }
//------------------------------------------------------------------------------------------------------- // void rf_init(RF_RX_INFO *pRRI, uint8_t channel, WORD panId, WORD myAddr) // // DESCRIPTION: // Initializes CC2420 for radio communication via the basic RF library functions. Turns on the // voltage regulator, resets the CC2420, turns on the crystal oscillator, writes all necessary // registers and protocol addresses (for automatic address recognition). Note that the crystal // oscillator will remain on (forever). // // ARGUMENTS: // RF_RX_INFO *pRRI // A pointer the RF_RX_INFO data structure to be used during the first packet reception. // The structure can be switched upon packet reception. // uint8_t channel // The RF channel to be used (11 = 2405 MHz to 26 = 2480 MHz) // WORD panId // The personal area network identification number // WORD myAddr // The 16-bit short address which is used by this node. Must together with the PAN ID form a // unique 32-bit identifier to avoid addressing conflicts. Normally, in a 802.15.4 network, the // short address will be given to associated nodes by the PAN coordinator. //------------------------------------------------------------------------------------------------------- void rf_init(RF_RX_INFO *pRRI, uint8_t channel, uint16_t panId, uint16_t myAddr) { uint8_t n; #ifdef RADIO_PRIORITY_CEILING int8_t v; radio_sem = nrk_sem_create(1,RADIO_PRIORITY_CEILING); if (radio_sem == NULL) nrk_kernel_error_add (NRK_SEMAPHORE_CREATE_ERROR, nrk_get_pid ()); v = nrk_sem_pend (radio_sem); if (v == NRK_ERROR) { nrk_kprintf (PSTR ("CC2420 ERROR: Access to semaphore failed\r\n")); } #endif // Make sure that the voltage regulator is on, and that the reset pin is inactive SET_VREG_ACTIVE(); halWait(1000); SET_RESET_ACTIVE(); halWait(1); SET_RESET_INACTIVE(); halWait(100); // Initialize the FIFOP external interrupt //FIFOP_INT_INIT(); //ENABLE_FIFOP_INT(); // Turn off all interrupts while we're accessing the CC2420 registers DISABLE_GLOBAL_INT(); FASTSPI_STROBE(CC2420_SXOSCON); mdmctrl0=0x02E2; FASTSPI_SETREG(CC2420_MDMCTRL0, mdmctrl0); // Std Preamble, CRC, no auto ack, no hw addr decoding //FASTSPI_SETREG(CC2420_MDMCTRL0, 0x0AF2); // Turn on automatic packet acknowledgment // Turn on hw addre decoding FASTSPI_SETREG(CC2420_MDMCTRL1, 0x0500); // Set the correlation threshold = 20 FASTSPI_SETREG(CC2420_IOCFG0, 0x007F); // Set the FIFOP threshold to maximum FASTSPI_SETREG(CC2420_SECCTRL0, 0x01C4); // Turn off "Security" FASTSPI_SETREG(CC2420_RXCTRL1, 0x1A56); // All default except // reference bias current to RX // bandpass filter is set to 3uA /* // FIXME: remove later for auto ack myAddr=MY_MAC; panId=0x02; FASTSPI_SETREG(CC2420_MDMCTRL0, 0x0AF2); // Turn on automatic packet acknowledgment // FASTSPI_SETREG(CC2420_MDMCTRL0, 0x0AE2); // Turn on automatic packet acknowledgment nrk_spin_wait_us(500); nrk_spin_wait_us(500); FASTSPI_WRITE_RAM_LE(&myAddr, CC2420RAM_SHORTADDR, 2, n); nrk_spin_wait_us(500); FASTSPI_WRITE_RAM_LE(&panId, CC2420RAM_PANID, 2, n); nrk_spin_wait_us(500); printf( "myAddr=%d\r\n",myAddr ); */ nrk_spin_wait_us(500); FASTSPI_WRITE_RAM_LE(&panId, CC2420RAM_PANID, 2, n); nrk_spin_wait_us(500); ENABLE_GLOBAL_INT(); // Set the RF channel halRfSetChannel(channel); // Turn interrupts back on ENABLE_GLOBAL_INT(); // Set the protocol configuration rfSettings.pRxInfo = pRRI; rfSettings.panId = panId; rfSettings.myAddr = myAddr; rfSettings.txSeqNumber = 0; rfSettings.receiveOn = FALSE; // Wait for the crystal oscillator to become stable halRfWaitForCrystalOscillator(); // Write the short address and the PAN ID to the CC2420 RAM (requires that the XOSC is on and stable) // DISABLE_GLOBAL_INT(); // FASTSPI_WRITE_RAM_LE(&myAddr, CC2420RAM_SHORTADDR, 2, n); // FASTSPI_WRITE_RAM_LE(&panId, CC2420RAM_PANID, 2, n); // ENABLE_GLOBAL_INT(); #ifdef RADIO_PRIORITY_CEILING v = nrk_sem_post (radio_sem); if (v == NRK_ERROR) { nrk_kprintf (PSTR ("CC2420 ERROR: Release of semaphore failed\r\n")); _nrk_errno_set (2); } #endif auto_ack_enable=0; security_enable=0; last_pkt_encrypted=0; } // rf_init()
void rf_auto_ack_disable() { auto_ack_enable=0; mdmctrl0 &= (~0x0010); FASTSPI_SETREG(CC2420_MDMCTRL0, mdmctrl0); }
void rf_auto_ack_enable() { auto_ack_enable=1; mdmctrl0 |= 0x0010; FASTSPI_SETREG(CC2420_MDMCTRL0, mdmctrl0); }
void rf_addr_decode_disable() { mdmctrl0 &= (~0x0800); FASTSPI_SETREG(CC2420_MDMCTRL0, mdmctrl0); }
void rf_addr_decode_enable() { mdmctrl0 |= 0x0800; FASTSPI_SETREG(CC2420_MDMCTRL0, mdmctrl0); }
void rf_security_disable() { FASTSPI_SETREG(CC2420_SECCTRL0, 0x01C4); // Turn off "Security enable" security_enable=0; }
/*---------------------------------------------------------------------------*/ static void setreg(enum cc2420_register regname, unsigned value) { FASTSPI_SETREG(regname, value); }
/********************************************************** * Set the CCA mode * Accept 1-3 as argument */ void rf_set_cca_mode(uint8_t mode) { mdmctrl0 &= (0xFF3F); mdmctrl0 |= ((mode & 0x3) << 6); FASTSPI_SETREG(CC2420_MDMCTRL0, mdmctrl0); }
int8_t bmac_init (uint8_t chan) { bmac_running=0; tx_reserve=-1; cca_active=true; rx_failure_cnt=0; #ifdef NRK_SW_WDT #ifdef BMAC_SW_WDT_ID _bmac_check_period.secs=30; _bmac_check_period.nano_secs=0; nrk_sw_wdt_init(BMAC_SW_WDT_ID, &_bmac_check_period, NULL ); nrk_sw_wdt_start(BMAC_SW_WDT_ID); #endif #endif _bmac_check_period.secs=0; _bmac_check_period.nano_secs=BMAC_DEFAULT_CHECK_RATE_MS*NANOS_PER_MS; bmac_rx_pkt_signal=nrk_signal_create(); if(bmac_rx_pkt_signal==NRK_ERROR) { nrk_kprintf(PSTR("BMAC ERROR: creating rx signal failed\r\n")); nrk_kernel_error_add(NRK_SIGNAL_CREATE_ERROR,nrk_cur_task_TCB->task_ID); return NRK_ERROR; } bmac_tx_pkt_done_signal=nrk_signal_create(); if(bmac_tx_pkt_done_signal==NRK_ERROR) { nrk_kprintf(PSTR("BMAC ERROR: creating tx signal failed\r\n")); nrk_kernel_error_add(NRK_SIGNAL_CREATE_ERROR,nrk_cur_task_TCB->task_ID); return NRK_ERROR; } bmac_enable_signal=nrk_signal_create(); if(bmac_enable_signal==NRK_ERROR) { nrk_kprintf(PSTR("BMAC ERROR: creating enable signal failed\r\n")); nrk_kernel_error_add(NRK_SIGNAL_CREATE_ERROR,nrk_cur_task_TCB->task_ID); return NRK_ERROR; } tx_data_ready=0; // Set the one main rx buffer rx_buf_empty=0; bmac_rfRxInfo.pPayload = NULL; bmac_rfRxInfo.max_length = 0; // Setup the cc2420 chip rf_init (&bmac_rfRxInfo, chan, 0xffff, 0); g_chan=chan; FASTSPI_SETREG(CC2420_RSSI, 0xE580); // CCA THR=-25 FASTSPI_SETREG(CC2420_TXCTRL, 0x80FF); // TX TURNAROUND = 128 us FASTSPI_SETREG(CC2420_RXCTRL1, 0x0A56); // default cca thresh of -45 //rf_set_cca_thresh(-45); rf_set_cca_thresh(-45); bmac_running=1; is_enabled=1; return NRK_OK; }
/********************************************************** * Put the radio in serial TX mode, where data is sampled from the FIFO * pin to send after SFD, and timing is done using FIFOP * use rf_carrier_on() to start, set FIFO to first bit, then wait for it * to go up and down, then set next bit etc. * NOTE: You must set the FIFO pin to output mode in order to do this! * This can be undone by calling rf_data_mode() */ void rf_tx_set_serial() { FASTSPI_SETREG(CC2420_MDMCTRL1, 0x0504); // set TXMODE to 1 rf_flush_rx_fifo(); }
/********************************************************** * Set the radio into serial unbuffered RX mode * RX data is received through sampling the FIFO pin, timing is done using FIFOP * Use rf_rx_on() to start rcv, then wait for SFD / FIFOP. Sample during each high edge of FIFOP * This can be undone by using rf_data_mode() */ void rf_rx_set_serial() { FASTSPI_STROBE(CC2420_SRFOFF); // stop radio FASTSPI_SETREG(CC2420_MDMCTRL1, 0x0501); // Set RX_MODE to 1 rf_flush_rx_fifo(); }