This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CC2420 change center frequency and channel width

Other Parts Discussed in Thread: CC2420

Hi I am using the CC2420 2.4 GHz IEEE 802.15.4 / ZigBee-ready RF Transceiver in my Contiki-run Zolertia motes. I aware that I can enable single unmodulated carrier which is what I need to do in order to produce reliable interference for protocol testing.

However, because I am trying to introduce interference in wifi networks, I was wondering if it is possible to also change the center frequency, and the width - preferably something along the lines of 20MHz ? The obvious intention here is to produce activity in the same channel occupied by one of my mesh routers. Using the predefined channels of the rime stack is not sufficient for our purposes. 

We are busy with protocol testing here and need this for our research. We were motivated to use your products from similar research from the Swedish Institute of Computer Science -  a paper entitled: "Controllable Radio Interference for Experimental and Testing Purposes in Wireless Sensor Networks".

Regards

Dominic

UCT

South Africa

  • Dominic, 

    The CC2420 can only perform 802.15.4 specific modulation. It is not capable generating a 20MHz wide signal, the only other mode is a Constant Wave carrier (CW). 

    You can select any frequency in 1MHz steps.

    Regards,
    /TA 

  • Hi, 

    thanks for your reply. I note in the CC2420 datasheet that continuous (unmodulated) carrier is enabled by  setting the MDMCTRL1.TX_MODE register to 2 or 3, writing 0x1800 to the DACTST register, and issuing a STXON command strobe. The transmitter is then enabled while I/Q DACs are set to static values, at which point continuous carrier is available on the RF pins. Is this what you mean by Constant Wave carrier (CW)? Or is CW another modulation scheme with a wider channel width?

    I note that CC2420 also allows for a modulated spectrum though use of the CRC generator...

    Best Regards

    Dominic

  • Yes, Constant Wave or unmodulated carrier.

    Regards,
    /TA 

  • Thanks, 

    I am looking for where the MDMCTRL1.TX_MODE's are defined, but can't find it in any of the headers.

    Regards

    Dominic

  • My mistake, I have figured it out.

    I understand that the register MDMCTRL1 is 16 bits wide. By setting the appropriate bits, the entire bit pattern is changed and can be represented back in hex, for example for TX_MODE 3 = 0000010100001100 = (hex) 0x050C 

    and TX_MODE 2 = 0000010100001000 = (hex) 0x0508

    here the important bits to change were 3:2: i.e. 11 -> 10

  • Hello Dominic,

    I'm trying to do the same thing as you, I need to generate interfence in a wifi network to analyze the performance of a channel analyzer tool.

    Did you have success?

    This is the part of my code to generate the unmodulated carrier:

      CC2420_WRITE_REG(CC2420_MAIN, 0xF800);
      CC2420_STROBE(CC2420_STXON);
      CC2420_WRITE_REG(CC2420_MDMCTRL1, 0x0508);
      CC2420_WRITE_REG(CC2420_DACTST, 0X1800);
     
      cc2420_set_txpower(3);
      cc2420_set_channel(26);

    Best Regards,

    Marcelo

  • Hi Marcelo,  here is some code I wrote earlier this year that I got working. Parts of it are designed to read signals from a serial port program I wrote/edited.  I Hope this helps. Also if you are interested in radio communications in mesh networks, please find me on LinkedIn :Dominic Follett-Smith

    /*
     * Copyright (c) 2011, Swedish Institute of Computer Science.
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     * 1. Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     * 2. Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     * 3. Neither the name of the Institute nor the names of its contributors
     *    may be used to endorse or promote products derived from this software
     *    without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
     * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
     * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     * SUCH DAMAGE.
     *
     * Author Dominic Follett-Smith
     *
     */

    #include "dev/cc2420.h"
    #include "dev/cc2420_const.h"

    #include "contiki.h"

    #if defined(__AVR__)
    #include <avr/io.h>
    #endif

    #include "dev/leds.h"
    #include "dev/spi.h"
    #include "dev/cc2420.h"
    #include "dev/cc2420_const.h"

    #include "net/packetbuf.h"
    #include "net/rime/rimestats.h"
    #include "net/netstack.h"

    #include "sys/timetable.h"

    #include "dev/serial-line.h"

    #include <stdio.h>
    #include <string.h>

    #define DEBUG 1
    #if DEBUG
    #include <stdio.h>
    #define REG_DEBUG(...) printf(__VA_ARGS__)
    #else
    #define REG_DEBUG(...)
    #endif

    #define START_TEST 1

    static uint8_t locked, lock_on, lock_off;
    static uint8_t receive_on;

    //function prototypes
    static void on(void);
    static void off(void);
    static void RELEASE_LOCK(void);

    /*---------------------------------------------------------------------------*/
    #define GET_LOCK() locked++
    static void RELEASE_LOCK(void) {
      if(locked == 1) {
        if(lock_on) {
          on();
          lock_on = 0;
        }
        if(lock_off) {
          off();
          lock_off = 0;
        }
      }
      locked--;
    }
    /*---------------------------------------------------------------------------*/

    /*---------------------------------------------------------------------------*/
    #define BUSYWAIT_UNTIL(cond, max_time)                                  \
      do {                                                                  \
        rtimer_clock_t t0;                                                  \
        t0 = RTIMER_NOW();                                                  \
        while(!(cond) && RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + (max_time)));   \
      } while(0)
    /*---------------------------------------------------------------------------*/
    static void flushrx(void)
    {
          uint8_t dummy;

          CC2420_READ_FIFO_BYTE(dummy);
          CC2420_STROBE(CC2420_SFLUSHRX);
          CC2420_STROBE(CC2420_SFLUSHRX);
    }
    /*---------------------------------------------------------------------------*/

    /*---------------------------------------------------------------------------*/
    static void strobe(enum cc2420_register regname)
    {
        CC2420_STROBE(regname);
    }
    /*---------------------------------------------------------------------------*/

    /*---------------------------------------------------------------------------*/
    static void setreg(enum cc2420_register regname, unsigned value)
    {
        CC2420_WRITE_REG(regname, value);
    }
    /*---------------------------------------------------------------------------*/

    /*---------------------------------------------------------------------------*/
    static unsigned getreg(enum cc2420_register regname)
    {
        unsigned reg;
          CC2420_READ_REG(regname, reg);
          return reg;
    }
    /*---------------------------------------------------------------------------*/

    /*---------------------------------------------------------------------------*/
    static unsigned int status(void)
    {
          uint8_t status;
          CC2420_GET_STATUS(status);
          return status;
    }
    /*---------------------------------------------------------------------------*/

    /*---------------------------------------------------------------------------*/
    static int cc2420_set_frequency(uint16_t freq){ //freq in MHz

        if((freq>2500) || (freq < 2400)){
            printf("invalid frequency as argument...");
            return 0;
        }
        uint16_t FSCTRL_FREQ;

        //From data sheet: Fc = 2048 + FSCTRL.FREQ[9:0] MHz
        FSCTRL_FREQ = freq - 2048;
        GET_LOCK();

        /*
           * Writing RAM requires crystal oscillator to be stable.
           */
          BUSYWAIT_UNTIL((status() & (BV(CC2420_XOSC16M_STABLE))), RTIMER_SECOND / 10);

          /* Wait for any transmission to end. */
          BUSYWAIT_UNTIL(!(status() & BV(CC2420_TX_ACTIVE)), RTIMER_SECOND / 10);

          setreg(CC2420_FSCTRL, FSCTRL_FREQ);

          /* If we are in receive mode, we issue an SRXON command to ensure
             that the VCO is calibrated. */
          if(receive_on) {
            strobe(CC2420_SRXON);
          }

          RELEASE_LOCK();
          return 1;

    }
    /*---------------------------------------------------------------------------*/

    /*---------------------------------------------------------------------------*/
    static uint16_t cc2420_get_frequency(enum cc2420_register regname){
        unsigned reg;
        CC2420_READ_REG(regname, reg);
        //datasheet specifies: Fc = 2048 + FSCTRL.FREQ[9:0] MHz
        return reg + 2048;
    }
    /*---------------------------------------------------------------------------*/

    /*---------------------------------------------------------------------------*/
    static void on(void)
    {
            CC2420_ENABLE_FIFOP_INT();
            strobe(CC2420_SRXON);

            BUSYWAIT_UNTIL(status() & (BV(CC2420_XOSC16M_STABLE)), RTIMER_SECOND / 100);

            ENERGEST_ON(ENERGEST_TYPE_LISTEN);
            receive_on = 1;
    }
    /*---------------------------------------------------------------------------*/

    /*---------------------------------------------------------------------------*/
    static void off(void)
    {
            receive_on = 0;

            /* Wait for transmission to end before turning radio off. */
            BUSYWAIT_UNTIL(!(status() & BV(CC2420_TX_ACTIVE)), RTIMER_SECOND / 10);

            ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
            strobe(CC2420_SRFOFF);
            CC2420_DISABLE_FIFOP_INT();

            if(!CC2420_FIFOP_IS_1) {
                    flushrx();
            }
    }
    /*---------------------------------------------------------------------------*/


    /*---------------------------------------------------------------------------*/
    PROCESS(single_carrier, "Process to generate umodulated carrier on CC2420 RF pins."); //definition of processs and name for debugging
    AUTOSTART_PROCESSES(&single_carrier); //load on boot
    /*---------------------------------------------------------------------------*/



    PROCESS_THREAD(single_carrier, ev, data) //content of the process
    {
         PROCESS_BEGIN(); //begining on the process -  this should come before any variables are intialised

            SET_VREG_ACTIVE();
            clock_delay(500);
            SET_RESET_ACTIVE();
            clock_delay(234);
            SET_RESET_INACTIVE();
            clock_delay(234);
         

        printf("Process begun...\n\n");
       
        /* wait for a signal before starting the test */
        for(;;) {
                    PROCESS_YIELD();
                    if(ev == serial_line_event_message) {
                            printf("received line: %s\n", (char *)data);
                if( START_TEST == atoi( (char*)data ) ){
                    goto start;
                }
                    }
            }

        start:
       
        REG_DEBUG("TX_UNDERFLOW reg: 0x%x \n", getreg(CC2420_TX_UNDERFLOW));
            REG_DEBUG("TX_ACTIVE reg: 0x%x \n", getreg(CC2420_TX_ACTIVE));
        REG_DEBUG("XOSC16M_STABLE reg: 0x%x \n ", getreg(CC2420_XOSC16M_STABLE));
            REG_DEBUG("LOCK reg: 0x%x \n ", getreg(CC2420_LOCK));
            REG_DEBUG("SFD_IS_1 reg: 0x%x \n", getreg(CC2420_SFD_IS_1));    
        REG_DEBUG("CC2420_FSMSTATE: 0x%x \n",getreg(CC2420_FSMSTATE));   
        REG_DEBUG("TXCTRL (txpower) reg: 0x%x \n\n", getreg(CC2420_TXCTRL));

          /* Turn on voltage regulator and reset. */
          SET_VREG_ACTIVE();
          clock_delay(500);
          SET_RESET_ACTIVE();
          clock_delay(234);
          SET_RESET_INACTIVE();
          clock_delay(234);

          /* Turn on the crystal oscillator. */
          CC2420_STROBE(CC2420_SXOSCON);   
        //printf("CC2420_XOSC16M_STABLE reg: 0x%x \n", getreg(CC2420_XOSC16M_STABLE));
     
        BUSYWAIT_UNTIL((status() & (BV(CC2420_XOSC16M_STABLE))), RTIMER_SECOND / 10);
        REG_DEBUG("cc2420: Crystal oscillator enabled. \n");

        //set the TX_MODE
        setreg(CC2420_MDMCTRL1, 0x50C); //0x000C //0x50c   
        REG_DEBUG("cc2420: MDMCTRL1 register value: 0x%x \n", getreg(CC2420_MDMCTRL1));

        //write 0x1800 to DACTST
        //setreg(CC2420_DACTST, 0x1800);
        //REG_DEBUG("cc2420: DACTST register value: 0x%x \n", getreg(CC2420_DACTST));
       

        //set channel
        //cc2420_set_channel(17);
            if(cc2420_set_frequency(2437))
                   REG_DEBUG("cc2420: centre frequency set: %d\n", cc2420_get_frequency(CC2420_FSCTRL)); 
       
            //set txpower
            cc2420_set_txpower(7);      
            REG_DEBUG("tx_power: %d\n\n",cc2420_get_txpower() );

        //issue STXON command strobe
        //strobe(CC2420_STXCAL);
        CC2420_STROBE(CC2420_STXON);

            REG_DEBUG("TX_UNDERFLOW reg: 0x%x \n", getreg(CC2420_TX_UNDERFLOW));
            REG_DEBUG("TX_ACTIVE reg: 0x%x \n", getreg(CC2420_TX_ACTIVE));
        REG_DEBUG("XOSC16M_STABLE reg: 0x%x \n ", getreg(CC2420_XOSC16M_STABLE));
        REG_DEBUG("LOCK reg: 0x%x \n ", getreg(CC2420_LOCK));
        REG_DEBUG("SFD_IS_1 reg: 0x%x \n", getreg(CC2420_SFD_IS_1));   
        REG_DEBUG("CC2420_FSMSTATE: 0x%x \n",getreg(CC2420_FSMSTATE));  
        REG_DEBUG("TXCTRL (txpower) reg: 0x%x \n", getreg(CC2420_TXCTRL));
       

                 for(;;) {
                    PROCESS_YIELD();
                    if(ev == serial_line_event_message) {
                            REG_DEBUG("PROCESS YIELD 2: received line: %s\n", (char *)data);
                if(2 == atoi( (char*)data )){
                PROCESS_EXIT();
                }            
                    if( START_TEST == atoi( (char*)data ) ){
                                    goto start;
                            }else{ //we stop the test
                    //set the TX_MODE
                        setreg(CC2420_MDMCTRL1, 0x0); //0x000C //0x50c      
                        printf("cc2420: MDMCTRL1 register value: 0x%x \n", getreg(CC2420_MDMCTRL1));
                    CC2420_STROBE(CC2420_STXON);
                }

                    }
            }

      PROCESS_END(); //defines the end of a process
    }

  • Thank you Dominic!

    I'll try your code, I'm start thinking it can be my zolertia with problems.