Exemple #1
0
/*---------------------------------------------------------------------------*/
static int
init(void)
{
  PRINTF("RF: Init\n");

  if(rf_flags & RF_ON) {
    return 0;
  }

  /* Enable clock for the RF Core while Running, in Sleep and Deep Sleep */
  REG(SYS_CTRL_RCGCRFC) = 1;
  REG(SYS_CTRL_SCGCRFC) = 1;
  REG(SYS_CTRL_DCGCRFC) = 1;

  REG(RFCORE_XREG_CCACTRL0) = CC2538_RF_CCA_THRES_USER_GUIDE;

  /*
   * Changes from default values
   * See User Guide, section "Register Settings Update"
   */
  REG(RFCORE_XREG_TXFILTCFG) = 0x09;    /** TX anti-aliasing filter bandwidth */
  REG(RFCORE_XREG_AGCCTRL1) = 0x15;     /** AGC target value */
  REG(ANA_REGS_IVCTRL) = 0x0B;          /** Bias currents */

  /*
   * Defaults:
   * Auto CRC; Append RSSI, CRC-OK and Corr. Val.; CRC calculation;
   * RX and TX modes with FIFOs
   */
  REG(RFCORE_XREG_FRMCTRL0) = RFCORE_XREG_FRMCTRL0_AUTOCRC;

#if CC2538_RF_AUTOACK
  REG(RFCORE_XREG_FRMCTRL0) |= RFCORE_XREG_FRMCTRL0_AUTOACK;
#endif

  /* If we are a sniffer, turn off frame filtering */
#if CC2538_RF_CONF_SNIFFER
  REG(RFCORE_XREG_FRMFILT0) &= ~RFCORE_XREG_FRMFILT0_FRAME_FILTER_EN;
#endif

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

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

  /* Set TX Power */
  REG(RFCORE_XREG_TXPOWER) = CC2538_RF_TX_POWER;

  set_channel(rf_channel);

  /* Acknowledge RF interrupts, FIFOP only */
  REG(RFCORE_XREG_RFIRQM0) |= RFCORE_XREG_RFIRQM0_FIFOP;
  nvic_interrupt_enable(NVIC_INT_RF_RXTX);

  /* Acknowledge all RF Error interrupts */
  REG(RFCORE_XREG_RFERRM) = RFCORE_XREG_RFERRM_RFERRM;
  nvic_interrupt_enable(NVIC_INT_RF_ERR);

  if(CC2538_RF_CONF_TX_USE_DMA) {
    /* Disable peripheral triggers for the channel */
    udma_channel_mask_set(CC2538_RF_CONF_TX_DMA_CHAN);

    /*
     * Set the channel's DST. SRC can not be set yet since it will change for
     * each transfer
     */
    udma_set_channel_dst(CC2538_RF_CONF_TX_DMA_CHAN, RFCORE_SFR_RFDATA);
  }

  if(CC2538_RF_CONF_RX_USE_DMA) {
    /* Disable peripheral triggers for the channel */
    udma_channel_mask_set(CC2538_RF_CONF_RX_DMA_CHAN);

    /*
     * Set the channel's SRC. DST can not be set yet since it will change for
     * each transfer
     */
    udma_set_channel_src(CC2538_RF_CONF_RX_DMA_CHAN, RFCORE_SFR_RFDATA);
  }

  process_start(&cc2538_rf_process, NULL);

  rf_flags |= RF_ON;

  ENERGEST_ON(ENERGEST_TYPE_LISTEN);

  return 1;
}
Exemple #2
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);
}
Exemple #3
0
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(mainProcess, ev, data) {
    PROCESS_BEGIN();

    GPIO_SET_OUTPUT(GPIO_A_BASE, 0xf8);
    GPIO_SET_OUTPUT(GPIO_B_BASE, 0x0f);
    GPIO_SET_OUTPUT(GPIO_C_BASE, 0x02);
    GPIO_CLR_PIN(GPIO_A_BASE, 0xf8);
    GPIO_CLR_PIN(GPIO_B_BASE, 0x07);
    GPIO_SET_PIN(EDISON_WAKEUP_BASE, EDISON_WAKEUP_PIN_MASK); // edison WAKEUP

    GPIO_SET_INPUT(RESET_PORT_BASE, RESET_PIN_MASK); // reset
    ioc_set_over(RESET_PORT, RESET_PIN, IOC_OVERRIDE_PUE);

    leds_off(LEDS_RED);
    leds_off(LEDS_GREEN);
    leds_off(LEDS_BLUE);

    // RESET interrupt, active low
    GPIO_DETECT_EDGE(RESET_PORT_BASE, RESET_PIN_MASK);
    GPIO_DETECT_FALLING(RESET_PORT_BASE, RESET_PIN_MASK);
    GPIO_TRIGGER_SINGLE_EDGE(RESET_PORT_BASE, RESET_PIN_MASK);
    gpio_register_callback(resetcallBack, RESET_PORT, RESET_PIN);
    GPIO_ENABLE_INTERRUPT(RESET_PORT_BASE, RESET_PIN_MASK);
    nvic_interrupt_enable(RESET_NVIC_PORT);

    GPIO_CLR_PIN(TRIUMVI_DATA_READY_PORT_BASE, TRIUMVI_DATA_READY_MASK);

    // SPI CS interrupt
    GPIO_DETECT_EDGE(SPI0_CS_PORT_BASE, SPI0_CS_PIN_MASK);
    GPIO_DETECT_RISING(SPI0_CS_PORT_BASE, SPI0_CS_PIN_MASK);
    GPIO_TRIGGER_SINGLE_EDGE(SPI0_CS_PORT_BASE, SPI0_CS_PIN_MASK);
    gpio_register_callback(spiCScallBack, SPI0_CS_PORT, SPI0_CS_PIN);
    GPIO_ENABLE_INTERRUPT(SPI0_CS_PORT_BASE, SPI0_CS_PIN_MASK);

    // SPI interface
    spix_slave_init(SPIDEV);
    spix_txdma_enable(SPIDEV);
    spi_register_callback(spiFIFOcallBack);
    spix_interrupt_enable(SPIDEV, SSI_IM_RXIM_M); // RX FIFO half full
    nvic_interrupt_enable(NVIC_INT_SSI0);

    // uDMA SPI0 TX
    udma_channel_disable(CC2538_SPI0_TX_DMA_CHAN);
    udma_channel_prio_set_default(CC2538_SPI0_TX_DMA_CHAN);
    udma_channel_use_primary(CC2538_SPI0_TX_DMA_CHAN);
    udma_channel_use_single(CC2538_SPI0_TX_DMA_CHAN);
    udma_channel_mask_clr(CC2538_SPI0_TX_DMA_CHAN);
    udma_set_channel_dst(CC2538_SPI0_TX_DMA_CHAN, SPI0DR);
    udma_set_channel_assignment(CC2538_SPI0_TX_DMA_CHAN, UDMA_CH11_SSI0TX);


    simple_network_set_callback(&rf_rx_handler);
    //NETSTACK_RADIO.off();
    
    process_start(&decryptProcess, NULL);
    process_start(&spiProcess, NULL);


    while (1){
        PROCESS_YIELD();
        // buffer is not empty, spi is not in use
        //if ((spiInUse==0) && (spix_busy(SPIDEV)==0) && ((triumviAvailIDX!=triumviFullIDX) || (triumviRXBufFull==1))){
        if ((spiInUse==0) && ((triumviAvailIDX!=triumviFullIDX) || (triumviRXBufFull==1))){
            GPIO_SET_PIN(TRIUMVI_DATA_READY_PORT_BASE, TRIUMVI_DATA_READY_MASK);
            if (triumviRXBufFull==1){
                resetCnt += 1;
                if (resetCnt==RESET_THRESHOLD){
                    watchdog_reboot();
                }
            }
            #ifdef LED_DEBUG
            leds_off(LEDS_RED);
            leds_off(LEDS_GREEN);
            leds_off(LEDS_BLUE);
            #endif
        }
        // Fail safe, CC2538 missing some SPI commands, reset spi state
        else if (triumviRXBufFull==1){
            spiState = SPI_RESET;
            process_poll(&spiProcess);
            #ifdef LED_DEBUG
            leds_off(LEDS_RED);
            leds_off(LEDS_GREEN);
            leds_on(LEDS_BLUE);
            #endif
        }
    }
    PROCESS_END();
}