Example #1
0
/*---------------------------------------------------------------------------*/
static int
prepare(const void *payload, unsigned short payload_len)
{
  uint8_t i;

  PRINTF("RF: Prepare 0x%02x bytes\n", payload_len + CHECKSUM_LEN);

  /*
   * When we transmit in very quick bursts, make sure previous transmission
   * is not still in progress before re-writing to the TX FIFO
   */
  while(REG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_TX_ACTIVE);

  if((rf_flags & RX_ACTIVE) == 0) {
    on();
  }

  CC2538_RF_CSP_ISFLUSHTX();

  PRINTF("RF: data = ");
  /* Send the phy length byte first */
  REG(RFCORE_SFR_RFDATA) = payload_len + CHECKSUM_LEN;

  if(CC2538_RF_CONF_TX_USE_DMA) {
    PRINTF("<uDMA payload>");

    /* Set the transfer source's end address */
    udma_set_channel_src(CC2538_RF_CONF_TX_DMA_CHAN,
                         (uint32_t)(payload) + payload_len - 1);

    /* Configure the control word */
    udma_set_channel_control_word(CC2538_RF_CONF_TX_DMA_CHAN,
                                  UDMA_TX_FLAGS | udma_xfer_size(payload_len));

    /* Enabled the RF TX uDMA channel */
    udma_channel_enable(CC2538_RF_CONF_TX_DMA_CHAN);

    /* Trigger the uDMA transfer */
    udma_channel_sw_request(CC2538_RF_CONF_TX_DMA_CHAN);

    /*
     * No need to wait for this to end. Even if transmit() gets called
     * immediately, the uDMA controller will stream the frame to the TX FIFO
     * faster than transmit() can empty it
     */
  } else {
    for(i = 0; i < payload_len; i++) {
      REG(RFCORE_SFR_RFDATA) = ((unsigned char *)(payload))[i];
      PRINTF("%02x", ((unsigned char *)(payload))[i]);
    }
  }
  PRINTF("\n");

  return 0;
}
Example #2
0
void radio_reset() {
	 /* Wait for ongoing TX to complete (e.g. this could be an outgoing ACK) */
	  while(HWREG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_TX_ACTIVE);
      //flush fifos
	  CC2538_RF_CSP_ISFLUSHRX();
	  CC2538_RF_CSP_ISFLUSHTX();

	  /* Don't turn off if we are off as this will trigger a Strobe Error */
	  if(HWREG(RFCORE_XREG_RXENABLE) != 0) {
	    CC2538_RF_CSP_ISRFOFF();
	  }
	  radio_init();
}
Example #3
0
void radio_loadPacket(uint8_t* packet, uint8_t len) {
	uint8_t i=0;
   // change state
   radio_vars.state = RADIOSTATE_LOADING_PACKET;
   
   // load packet in TXFIFO
   /*
      * When we transmit in very quick bursts, make sure previous transmission
      * is not still in progress before re-writing to the TX FIFO
      */
     while(HWREG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_TX_ACTIVE);

     CC2538_RF_CSP_ISFLUSHTX();

     /* Send the phy length byte first --  */
     HWREG(RFCORE_SFR_RFDATA) = len; //crc len is included

     for(i = 0; i < len; i++) {
         HWREG(RFCORE_SFR_RFDATA) = packet[i];
     }

   // change state
   radio_vars.state = RADIOSTATE_PACKET_LOADED;
}
Example #4
0
/*---------------------------------------------------------------------------*/
static int
transmit(unsigned short transmit_len)
{
  uint8_t counter;
  int ret = RADIO_TX_ERR;
  rtimer_clock_t t0;
  uint8_t was_off = 0;

  PRINTF("RF: Transmit\n");

  if(!(rf_flags & RX_ACTIVE)) {
    t0 = RTIMER_NOW();
    on();
    was_off = 1;
    while(RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + ONOFF_TIME));
  }

  if(channel_clear() == CC2538_RF_CCA_BUSY) {
    RIMESTATS_ADD(contentiondrop);
    return RADIO_TX_COLLISION;
  }

  /*
   * prepare() double checked that TX_ACTIVE is low. If SFD is high we are
   * receiving. Abort transmission and bail out with RADIO_TX_COLLISION
   */
  if(REG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_SFD) {
    RIMESTATS_ADD(contentiondrop);
    return RADIO_TX_COLLISION;
  }

  /* Start the transmission */
  ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
  ENERGEST_ON(ENERGEST_TYPE_TRANSMIT);

  CC2538_RF_CSP_ISTXON();

  counter = 0;
  while(!((REG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_TX_ACTIVE))
        && (counter++ < 3)) {
    clock_delay_usec(6);
  }

  if(!(REG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_TX_ACTIVE)) {
    PRINTF("RF: TX never active.\n");
    CC2538_RF_CSP_ISFLUSHTX();
    ret = RADIO_TX_ERR;
  } else {
    /* Wait for the transmission to finish */
    while(REG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_TX_ACTIVE);
    ret = RADIO_TX_OK;
  }
  ENERGEST_OFF(ENERGEST_TYPE_TRANSMIT);
  ENERGEST_ON(ENERGEST_TYPE_LISTEN);

  if(was_off) {
    off();
  }

  RIMESTATS_ADD(lltx);

  return ret;
}
Example #5
0
void radio_init() {

   // clear variables
   memset(&radio_vars,0,sizeof(radio_vars_t));
   
   // change state
   radio_vars.state          = RADIOSTATE_STOPPED;
   //flush fifos
   CC2538_RF_CSP_ISFLUSHRX();
   CC2538_RF_CSP_ISFLUSHTX();

   radio_off();

   //disable radio interrupts
   disable_radio_interrupts();

   /* This CORR_THR value should be changed to 0x14 before attempting RX. Testing has shown that
      * too many false frames are received if the reset value is used. Make it more likely to detect
      * sync by removing the requirement that both symbols in the SFD must have a correlation value
      * above the correlation threshold, and make sync word detection less likely by raising the
      * correlation threshold.
      */
   HWREG(RFCORE_XREG_MDMCTRL1) = 0x14;
   /* tuning adjustments for optimal radio performance; details available in datasheet */

   HWREG(RFCORE_XREG_RXCTRL) = 0x3F;
   /* Adjust current in synthesizer; details available in datasheet. */
   HWREG(RFCORE_XREG_FSCTRL) = 0x55;

     /* Makes sync word detection less likely by requiring two zero symbols before the sync word.
      * details available in datasheet.
      */
   HWREG(RFCORE_XREG_MDMCTRL0) = 0x85;

   /* Adjust current in VCO; details available in datasheet. */
   HWREG(RFCORE_XREG_FSCAL1) = 0x01;
   /* Adjust target value for AGC control loop; details available in datasheet. */
   HWREG(RFCORE_XREG_AGCCTRL1) = 0x15;


   /* Tune ADC performance, details available in datasheet. */
   HWREG(RFCORE_XREG_ADCTEST0) = 0x10;
   HWREG(RFCORE_XREG_ADCTEST1) = 0x0E;
   HWREG(RFCORE_XREG_ADCTEST2) = 0x03;

   //update CCA register to -81db as indicated by manual.. won't be used..
   HWREG(RFCORE_XREG_CCACTRL0) = 0xF8;
   /*
    * Changes from default values
    * See User Guide, section "Register Settings Update"
    */
   HWREG(RFCORE_XREG_TXFILTCFG) = 0x09;    /** TX anti-aliasing filter bandwidth */
   HWREG(RFCORE_XREG_AGCCTRL1) = 0x15;     /** AGC target value */
   HWREG(ANA_REGS_O_IVCTRL) = 0x0B;        /** Bias currents */

   /* disable the CSPT register compare function */
   HWREG(RFCORE_XREG_CSPT) = 0xFFUL;
   /*
    * Defaults:
    * Auto CRC; Append RSSI, CRC-OK and Corr. Val.; CRC calculation;
    * RX and TX modes with FIFOs
    */
   HWREG(RFCORE_XREG_FRMCTRL0) = RFCORE_XREG_FRMCTRL0_AUTOCRC;

   //poipoi disable frame filtering by now.. sniffer mode.
   HWREG(RFCORE_XREG_FRMFILT0) &= ~RFCORE_XREG_FRMFILT0_FRAME_FILTER_EN;

   /* Disable source address matching and autopend */
   HWREG(RFCORE_XREG_SRCMATCH) = 0;

     /* MAX FIFOP threshold */
   HWREG(RFCORE_XREG_FIFOPCTRL) = CC2538_RF_MAX_PACKET_LEN;

   HWREG(RFCORE_XREG_TXPOWER) = CC2538_RF_TX_POWER;
   HWREG(RFCORE_XREG_FREQCTRL) = CC2538_RF_CHANNEL_MIN;

   /* Enable RF interrupts  see page 751  */
//      enable_radio_interrupts();

   //register interrupt
   IntRegister(INT_RFCORERTX, radio_isr);
   IntRegister(INT_RFCOREERR, radio_error_isr);

   IntPrioritySet(INT_RFCORERTX, HAL_INT_PRIOR_MAC);
   IntPrioritySet(INT_RFCOREERR, HAL_INT_PRIOR_MAC);

   IntEnable(INT_RFCORERTX);


     /* Enable all RF Error interrupts */
   HWREG(RFCORE_XREG_RFERRM) = RFCORE_XREG_RFERRM_RFERRM_M; //all errors
   IntEnable(INT_RFCOREERR);
   //radio_on();
   // change state
   radio_vars.state          = RADIOSTATE_RFOFF;
}