Пример #1
0
void radio_getReceivedFrame(uint8_t* pBufRead,
                            uint8_t* pLenRead,
                            uint8_t  maxBufLen,
                             int8_t* pRssi,
                            uint8_t* pLqi,
                            uint8_t* pCrc) {
   uint8_t crc_corr,i;

   uint8_t len=0;

   /* Check the length */
    len = HWREG(RFCORE_SFR_RFDATA); //first byte is len


   /* Check for validity */
    if(len > CC2538_RF_MAX_PACKET_LEN) {
      /* wrong len */
      CC2538_RF_CSP_ISFLUSHRX();
      return;
    }


    if(len <= CC2538_RF_MIN_PACKET_LEN) {
        //too short
    	CC2538_RF_CSP_ISFLUSHRX();
        return;
    }

    //check if this fits to the buffer
    if(len > maxBufLen) {
        CC2538_RF_CSP_ISFLUSHRX();
        return;
     }

   // when reading the packet from the RX buffer, you get the following:
    // - *[1B]     length byte
    // -  [0-125B] packet (excluding CRC)
    // -  [1B]     RSSI
    // - *[2B]     CRC

  //skip first byte is len
    for(i = 1; i < len; i++) {
          pBufRead[i] = HWREG(RFCORE_SFR_RFDATA);
    }


    *pRssi = ((int8_t)(HWREG(RFCORE_SFR_RFDATA)) - RSSI_OFFSET);
    crc_corr = HWREG(RFCORE_SFR_RFDATA);
    *pCrc = crc_corr & CRC_BIT_MASK;
    *pLenRead = len;
    //flush it
    CC2538_RF_CSP_ISFLUSHRX();
}
Пример #2
0
port_INLINE void radio_off(){
	/* Wait for ongoing TX to complete (e.g. this could be an outgoing ACK) */
    while(HWREG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_TX_ACTIVE);
    CC2538_RF_CSP_ISFLUSHRX();

  /* 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();
	    //clear fifo isr flag
	    HWREG(RFCORE_SFR_RFIRQF0) = ~(RFCORE_SFR_RFIRQF0_FIFOP|RFCORE_SFR_RFIRQF0_RXPKTDONE);
	}

}
Пример #3
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();
}
Пример #4
0
/*---------------------------------------------------------------------------*/
static int
on(void)
{
  PRINTF("RF: On\n");

  if(!(rf_flags & RX_ACTIVE)) {
    CC2538_RF_CSP_ISFLUSHRX();
    CC2538_RF_CSP_ISRXON();

    rf_flags |= RX_ACTIVE;
  }

  ENERGEST_ON(ENERGEST_TYPE_LISTEN);
  return 1;
}
Пример #5
0
/*---------------------------------------------------------------------------*/
static int
off(void)
{
  PRINTF("RF: Off\n");

  /* Wait for ongoing TX to complete (e.g. this could be an outgoing ACK) */
  while(REG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_TX_ACTIVE);

  CC2538_RF_CSP_ISFLUSHRX();

  /* Don't turn off if we are off as this will trigger a Strobe Error */
  if(REG(RFCORE_XREG_RXENABLE) != 0) {
    CC2538_RF_CSP_ISRFOFF();
  }

  rf_flags &= ~RX_ACTIVE;

  ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
  return 1;
}
Пример #6
0
/*---------------------------------------------------------------------------*/
static int
read(void *buf, unsigned short bufsize)
{
  uint8_t i;
  uint8_t len;
  uint8_t crc_corr;
  int8_t rssi;

  PRINTF("RF: Read\n");

  if((REG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_FIFOP) == 0) {
    return 0;
  }

  /* Check the length */
  len = REG(RFCORE_SFR_RFDATA);

  /* Check for validity */
  if(len > CC2538_RF_MAX_PACKET_LEN) {
    /* Oops, we must be out of sync. */
    PRINTF("RF: bad sync\n");

    RIMESTATS_ADD(badsynch);
    CC2538_RF_CSP_ISFLUSHRX();
    return 0;
  }

  if(len <= CC2538_RF_MIN_PACKET_LEN) {
    PRINTF("RF: too short\n");

    RIMESTATS_ADD(tooshort);
    CC2538_RF_CSP_ISFLUSHRX();
    return 0;
  }

  if(len - CHECKSUM_LEN > bufsize) {
    PRINTF("RF: too long\n");

    RIMESTATS_ADD(toolong);
    CC2538_RF_CSP_ISFLUSHRX();
    return 0;
  }

  /* If we reach here, chances are the FIFO is holding a valid frame */
  PRINTF("RF: read (0x%02x bytes) = ", len);
  len -= CHECKSUM_LEN;

  /* Don't bother with uDMA for short frames (e.g. ACKs) */
  if(CC2538_RF_CONF_RX_USE_DMA && len > UDMA_RX_SIZE_THRESHOLD) {
    PRINTF("<uDMA payload>");

    /* Set the transfer destination's end address */
    udma_set_channel_dst(CC2538_RF_CONF_RX_DMA_CHAN,
                         (uint32_t)(buf) + len - 1);

    /* Configure the control word */
    udma_set_channel_control_word(CC2538_RF_CONF_RX_DMA_CHAN,
                                  UDMA_RX_FLAGS | udma_xfer_size(len));

    /* Enabled the RF RX uDMA channel */
    udma_channel_enable(CC2538_RF_CONF_RX_DMA_CHAN);

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

    /* Wait for the transfer to complete. */
    while(udma_channel_get_mode(CC2538_RF_CONF_RX_DMA_CHAN));
  } else {
    for(i = 0; i < len; ++i) {
      ((unsigned char *)(buf))[i] = REG(RFCORE_SFR_RFDATA);
      PRINTF("%02x", ((unsigned char *)(buf))[i]);
    }
  }

  /* Read the RSSI and CRC/Corr bytes */
  rssi = ((int8_t)REG(RFCORE_SFR_RFDATA)) - RSSI_OFFSET;
  crc_corr = REG(RFCORE_SFR_RFDATA);

  PRINTF("%02x%02x\n", (uint8_t)rssi, crc_corr);

  /* MS bit CRC OK/Not OK, 7 LS Bits, Correlation value */
  if(crc_corr & CRC_BIT_MASK) {
    packetbuf_set_attr(PACKETBUF_ATTR_RSSI, rssi);
    packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, crc_corr & LQI_BIT_MASK);
    RIMESTATS_ADD(llrx);
  } else {
    RIMESTATS_ADD(badcrc);
    PRINTF("RF: Bad CRC\n");
    CC2538_RF_CSP_ISFLUSHRX();
    return 0;
  }

#if CC2538_RF_CONF_SNIFFER
  write_byte(magic[0]);
  write_byte(magic[1]);
  write_byte(magic[2]);
  write_byte(magic[3]);
  write_byte(len + 2);
  for(i = 0; i < len; ++i) {
    write_byte(((unsigned char *)(buf))[i]);
  }
  write_byte(rssi);
  write_byte(crc_corr);
  flush();
#endif

  /* If FIFOP==1 and FIFO==0 then we had a FIFO overflow at some point. */
  if(REG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_FIFOP) {
    if(REG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_FIFO) {
      process_poll(&cc2538_rf_process);
    } else {
      CC2538_RF_CSP_ISFLUSHRX();
    }
  }

  return (len);
}
Пример #7
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;
}
Пример #8
0
port_INLINE void radio_on(){
    CC2538_RF_CSP_ISFLUSHRX();
    CC2538_RF_CSP_ISRXON();
}