Exemplo n.º 1
0
/*---------------------------------------------------------------------------*/
int
cc2420_init(void)
{
  uint16_t reg;
  {
    int s = splhigh();
    cc2420_arch_init();		/* Initalize ports and SPI. */
    CC2420_DISABLE_FIFOP_INT();
    CC2420_FIFOP_INT_INIT();
    splx(s);
  }

  /* Turn on voltage regulator and reset. */
  SET_VREG_ACTIVE();
  BUSYWAIT_UNTIL(0, RTIMER_SECOND / 100);
  SET_RESET_ACTIVE();
  BUSYWAIT_UNTIL(0, RTIMER_SECOND / 100);
  SET_RESET_INACTIVE();
  BUSYWAIT_UNTIL(0, RTIMER_SECOND / 100);

  pan = 0xffff;
  addr = 0x0000;
  
  BUSYWAIT_UNTIL(0, RTIMER_SECOND / 100);

  powerup();
  configure();
  flushrx();

  process_start(&cc2420_process, NULL);
  return 1;
}
Exemplo n.º 2
0
/*---------------------------------------------------------------------------*/
static int
spirit_radio_off(void)
{  
  PRINTF("Spirit1: ->off\n");
  if(spirit_on == ON) {
    /* Disables the mcu to get IRQ from the SPIRIT1 */
    IRQ_DISABLE();

    /* first stop rx/tx */
    spirit1_strobe(SPIRIT1_STROBE_SABORT);

    /* Clear any pending irqs */
    SpiritIrqClearStatus();
    
    BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_READY, 5 * RTIMER_SECOND/1000);
    if(SPIRIT1_STATUS() != SPIRIT1_STATE_READY) {
      PRINTF("Spirit1: failed off->ready\n");
      return 1;
    }

    /* Puts the SPIRIT1 in STANDBY */
    spirit1_strobe(SPIRIT1_STROBE_STANDBY);
    BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_STANDBY, 5 * RTIMER_SECOND/1000);
    if(SPIRIT1_STATUS() != SPIRIT1_STATE_STANDBY) {
      PRINTF("Spirit1: failed off->stdby\n");
      return 1;
    }

    spirit_on = OFF;
    CLEAR_TXBUF();
    CLEAR_RXBUF(); 
  }
  PRINTF("Spirit1: off.\n");
  return 0; 
}
Exemplo n.º 3
0
/*---------------------------------------------------------------------------*/
int
cc2520_set_channel(int c)
{
  uint16_t f;

  GET_LOCK();
  /*
   * Subtract the base channel (11), multiply by 5, which is the
   * channel spacing. 357 is 2405-2048 and 0x4000 is LOCK_THR = 1.
   */
  channel = c;

  f = MIN_CHANNEL + ((channel - MIN_CHANNEL) * CHANNEL_SPACING);
  /*
   * Writing RAM requires crystal oscillator to be stable.
   */
  BUSYWAIT_UNTIL((status() & (BV(CC2520_XOSC16M_STABLE))), RTIMER_SECOND / 10);

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

  /* Define radio channel (between 11 and 25) */
  setreg(CC2520_FREQCTRL, f);

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

  RELEASE_LOCK();
  return 1;
}
Exemplo n.º 4
0
/*---------------------------------------------------------------------------*/
int
cc2420_set_channel(int c)
{
  uint16_t f;

  GET_LOCK();
  /*
   * Subtract the base channel (11), multiply by 5, which is the
   * channel spacing. 357 is 2405-2048 and 0x4000 is LOCK_THR = 1.
   */
  channel = c;

  f = 5 * (c - 11) + 357 + 0x4000;
  /*
   * 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, f);

  /* 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;
}
Exemplo n.º 5
0
/*---------------------------------------------------------------------------*/
static int
spirit_radio_on(void)
{
  PRINTF("Spirit1: on\n");
  if(spirit_on == OFF) {
    IRQ_DISABLE();

    /* ensure we are in READY state as we go from there to Rx */
    spirit1_strobe(SPIRIT1_STROBE_READY);
    BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_READY, 5 * RTIMER_SECOND/1000);
    if(SPIRIT1_STATUS() != SPIRIT1_STATE_READY) {
      PRINTF("Spirit1: failed to turn on\n");
      panic_ra(4);
      return 1;
    }

    /* now we go to Rx */
    spirit1_strobe(SPIRIT1_STROBE_RX);
    BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, 5 * RTIMER_SECOND/1000);
    if(SPIRIT1_STATUS() != SPIRIT1_STATE_RX) {
      PRINTF("Spirit1: failed to enter rx\n");
      panic_ra(5);
      return 1;
    }
    
    /* Enables the mcu to get IRQ from the SPIRIT1 */
    IRQ_ENABLE();
    spirit_on = ON;
  }

  return 0;
}
Exemplo n.º 6
0
/*---------------------------------------------------------------------------*/
static int
transmit(unsigned short payload_len)
{
  if(tx_in_progress) {
    return RADIO_TX_COLLISION;
  }
  tx_in_progress = 1;

  /* Energest */
  if(listen_on) {
    ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
  }
  ENERGEST_ON(ENERGEST_TYPE_TRANSMIT);

  /* Transmit and wait */
  vMMAC_StartPhyTransmit(&tx_frame_buffer,
                         E_MMAC_TX_START_NOW |
                         (send_on_cca ? E_MMAC_TX_USE_CCA : E_MMAC_TX_NO_CCA));

  if(poll_mode) {
    BUSYWAIT_UNTIL(u32MMAC_PollInterruptSource(E_MMAC_INT_TX_COMPLETE), MAX_PACKET_DURATION);
  } else {
    if(in_ack_transmission) {
      /* as nested interupts are not possible, the tx flag will never be cleared */
      BUSYWAIT_UNTIL(FALSE, MAX_ACK_DURATION);
    } else {
      /* wait until the tx flag is cleared */
      BUSYWAIT_UNTIL(!tx_in_progress, MAX_PACKET_DURATION);
    }
  }

  /* Energest */
  ENERGEST_OFF(ENERGEST_TYPE_TRANSMIT);
  if(listen_on) {
    ENERGEST_ON(ENERGEST_TYPE_LISTEN);
  }
  tx_in_progress = 0;

  /* Check error code */
  int ret;
  uint32_t tx_error = u32MMAC_GetTxErrors();
  if(tx_error == 0) {
    ret = RADIO_TX_OK;
    RIMESTATS_ADD(acktx);
  } else if(tx_error & E_MMAC_TXSTAT_ABORTED) {
    ret = RADIO_TX_ERR;
    RIMESTATS_ADD(sendingdrop);
  } else if(tx_error & E_MMAC_TXSTAT_CCA_BUSY) {
    ret = RADIO_TX_COLLISION;
    RIMESTATS_ADD(contentiondrop);
  } else if(tx_error & E_MMAC_TXSTAT_NO_ACK) {
    ret = RADIO_TX_NOACK;
    RIMESTATS_ADD(noacktx);
  } else {
    ret = RADIO_TX_ERR;
  }
  return ret;
}
Exemplo n.º 7
0
/*---------------------------------------------------------------------------*/
void
cc2520_set_pan_addr(unsigned pan,
                    unsigned addr,
                    const uint8_t *ieee_addr)
{
  uint8_t tmp[2];

  GET_LOCK();

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

  tmp[0] = pan & 0xff;
  tmp[1] = pan >> 8;
  CC2520_WRITE_RAM(&tmp, CC2520RAM_PANID, 2);


  tmp[0] = addr & 0xff;
  tmp[1] = addr >> 8;
  CC2520_WRITE_RAM(&tmp, CC2520RAM_SHORTADDR, 2);
  if(ieee_addr != NULL) {
    int f;
    uint8_t tmp_addr[8];
    // LSB first, MSB last for 802.15.4 addresses in CC2520
    for (f = 0; f < 8; f++) {
      tmp_addr[7 - f] = ieee_addr[f];
    }
    CC2520_WRITE_RAM(tmp_addr, CC2520RAM_IEEEADDR, 8);
  }
  RELEASE_LOCK();
}
Exemplo n.º 8
0
/*---------------------------------------------------------------------------*/
void
cc1200_arch_init(void)
{
	SPI_InitHighFreq(1);
	
	CC1200_CLK_ALT_MODE;
	CC1200_MISO_ALT_MODE;
	CC1200_MOSI_ALT_MODE;
  /* First leave RESET high */
  CC1200_RESET_OUTPUT;
  CC1200_RESET_SET;

  /* Initialize CSn, enable CSn and then wait for MISO to go low*/
  SPI_WAITFORTx_BEFORE();

  /* Configure GPIOx */
  CC1200_GDO2_INPUT_FLOAT;
	CC1200_GDO0_INPUT_FLOAT;

  /* Leave CSn as default */
  cc1200_arch_spi_deselect();

  /* Ensure MISO is high */
  BUSYWAIT_UNTIL(
    CC1200_MISO_GET(),
    RTIMER_SECOND / 10);
}
Exemplo n.º 9
0
/*---------------------------------------------------------------------------*/
int
cc2520_rssi(void)
{
  int rssi;
  int radio_was_off = 0;

  if(locked) {
    return 0;
  }

  GET_LOCK();

  if(!receive_on) {
    radio_was_off = 1;
    cc2520_on();
  }
  BUSYWAIT_UNTIL(status() & BV(CC2520_RSSI_VALID), RTIMER_SECOND / 100);

  rssi = (int)((signed char)getreg(CC2520_RSSI));

  if(radio_was_off) {
    cc2520_off();
  }
  RELEASE_LOCK();
  return rssi;
}
Exemplo n.º 10
0
/*---------------------------------------------------------------------------*/
void
cc1200_arch_init(void)
{
  /* First leave RESET high */
  GPIO_SOFTWARE_CONTROL(CC1200_RESET_PORT_BASE, CC1200_RESET_PIN_MASK);
  GPIO_SET_OUTPUT(CC1200_RESET_PORT_BASE, CC1200_RESET_PIN_MASK);
  ioc_set_over(CC1200_RESET_PORT, CC1200_RESET_PIN, IOC_OVERRIDE_OE);
  GPIO_SET_PIN(CC1200_RESET_PORT_BASE, CC1200_RESET_PIN_MASK);

  /* Initialize CSn, enable CSn and then wait for MISO to go low*/
  spix_cs_init(CC1200_SPI_CSN_PORT, CC1200_SPI_CSN_PIN);

  /* Initialize SPI */
  spix_init(CC1200_SPI_INSTANCE);

  /* Configure GPIOx */
  GPIO_SOFTWARE_CONTROL(CC1200_GDO0_PORT_BASE, CC1200_GDO0_PIN_MASK);
  GPIO_SET_INPUT(CC1200_GDO0_PORT_BASE, CC1200_GDO0_PIN_MASK);
  GPIO_SOFTWARE_CONTROL(CC1200_GDO2_PORT_BASE, CC1200_GDO2_PIN_MASK);
  GPIO_SET_INPUT(CC1200_GDO2_PORT_BASE, CC1200_GDO2_PIN_MASK);

  /* Leave CSn as default */
  cc1200_arch_spi_deselect();

  /* Ensure MISO is high */
  BUSYWAIT_UNTIL(
    GPIO_READ_PIN(CC1200_SPI_MISO_PORT_BASE, CC1200_SPI_MISO_PIN_MASK),
    RTIMER_SECOND / 10);
}
Exemplo n.º 11
0
/*---------------------------------------------------------------------------*/
void
cc1200_arch_spi_select(void)
{
  /* Set CSn to low (0) */
  GPIO_CLR_PIN(CC1200_SPI_CSN_PORT_BASE, CC1200_SPI_CSN_PIN_MASK);
  /* The MISO pin should go low before chip is fully enabled. */
  BUSYWAIT_UNTIL(
    GPIO_READ_PIN(CC1200_SPI_MISO_PORT_BASE, CC1200_SPI_MISO_PIN_MASK) == 0,
    RTIMER_SECOND / 100);
}
Exemplo n.º 12
0
/*---------------------------------------------------------------------------*/
void
cc1200_arch_spi_select(void)
{
  /* Set CSn to low (0) */
  CC1200_CSN_CLR;
  /* The MISO pin should go low before chip is fully enabled. */
  BUSYWAIT_UNTIL(
	CC1200_MISO_GET() == 0,
    RTIMER_SECOND / 100);
}
Exemplo n.º 13
0
static void
on(void)
{
  CC2520_ENABLE_FIFOP_INT();
  strobe(CC2520_INS_SRXON);

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

  ENERGEST_ON(ENERGEST_TYPE_LISTEN);
  receive_on = 1;
}
Exemplo n.º 14
0
/*---------------------------------------------------------------------------*/
static int
spirit_radio_channel_clear(void)
{
  float rssi_value;
  /* Local variable used to memorize the SPIRIT1 state */
  uint8_t spirit_state = ON;
  
  PRINTF("CHANNEL CLEAR IN\n");
  
  if(spirit_on == OFF) {
    /* Wakes up the SPIRIT1 */
    spirit_radio_on();
    spirit_state = OFF;
  }
  
  /*  */
  IRQ_DISABLE();
  spirit1_strobe(SPIRIT1_STROBE_SABORT);
/*  SpiritCmdStrobeSabort();*/
  SpiritIrqClearStatus();
  IRQ_ENABLE();
  {
    rtimer_clock_t timeout = RTIMER_NOW() + 5 * RTIMER_SECOND/1000;
    do {
      SpiritRefreshStatus();
    } while((g_xStatus.MC_STATE != MC_STATE_READY) && (RTIMER_NOW() < timeout));
    if(RTIMER_NOW() < timeout) {
      return 1;
    }
  }

  /* Stores the RSSI value */
  rssi_value = SpiritQiGetRssidBm();
  
  /* Puts the SPIRIT1 in its previous state */
  if(spirit_state==OFF) {
    spirit_radio_off();
  } else {
    spirit1_strobe(SPIRIT1_STROBE_RX);
/*    SpiritCmdStrobeRx();*/
    BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, 5 * RTIMER_SECOND/1000);
  }
  
  PRINTF("CHANNEL CLEAR OUT\n");
  
  /* Checks the RSSI value with the threshold */
  if(rssi_value<CCA_THRESHOLD) {
    return 0;
  } else {
    return 1;
  }
}
Exemplo n.º 15
0
bool amb8420SetDstAddress(uint8_t dstAddress)
{
    bool ok;
    Handle_t handle;

    RPRINTF("set dst addr to %#02x\n", dstAddress);

    // disable radio rx/tx
    AMB8420ModeContext_t ctx;
    AMB8420_ENTER_STANDBY_MODE(ctx);

    // better be safe than sorry - treat 0 as broadcast too
    if (dstAddress == 0) dstAddress = 0xff;

    // Wait for device to become ready
    AMB8420_WAIT_FOR_RTS_READY(ok);
    if (!ok) goto end;

    // PRINTF("set dst, tar=%u\n", TAR);
//    ATOMIC_START_TIMESAVE(handle);
    AMB8420_SERIAL_CAPTURE(ok);

    commandInProgress = AMB8420_CMD_SET_DESTADDR_REQ;

    serialSendByte(AMB8420_UART_ID, AMB8420_START_DELIMITER);
    serialSendByte(AMB8420_UART_ID, AMB8420_CMD_SET_DESTADDR_REQ);
    serialSendByte(AMB8420_UART_ID, 0x1);
    serialSendByte(AMB8420_UART_ID, dstAddress);
    serialSendByte(AMB8420_UART_ID, AMB8420_START_DELIMITER
            ^ AMB8420_CMD_SET_DESTADDR_REQ ^ 0x1 ^ dstAddress);

    AMB8420_SERIAL_FREE();
//    ATOMIC_END_TIMESAVE(handle);
    // PRINTF("end set dst, tar=%u\n", TAR);

    // wait for reply
    INTERRUPT_ENABLED_START(handle);
    BUSYWAIT_UNTIL(!commandInProgress, TIMER_100_MS, ok);
//    if (commandInProgress) PRINTF("set dst addr: command wait fail\n");
    INTERRUPT_ENABLED_END(handle);
    // if (!ok) goto end;

    // Wait for device to become ready
    AMB8420_WAIT_FOR_RTS_READY(ok);
  end:
    AMB8420_RESTORE_MODE(ctx);
    // PRINTF(" ok = %d\n", (int)ok);
    // if (!ok) amb8420Reset();
    return ok;
}
Exemplo n.º 16
0
/*---------------------------------------------------------------------------*/
static void
flushrx(void)
{
  restart_input();

  LOCK_SPI();
  if(state() == CC1101_STATE_RXFIFO_OVERFLOW) {
    strobe(CC1101_SFRX);
  }
  strobe(CC1101_SIDLE);
  BUSYWAIT_UNTIL((state() == CC1101_STATE_IDLE), RTIMER_SECOND / 10);
  strobe(CC1101_SFRX);
  strobe(CC1101_SRX);
  RELEASE_SPI();
}
Exemplo n.º 17
0
/*---------------------------------------------------------------------------*/
static int
spirit_radio_transmit(unsigned short payload_len)
{ 
  /* This function blocks until the packet has been transmitted */
  rtimer_clock_t rtimer_txdone, rtimer_rxack;

  PRINTF("TRANSMIT IN\n");
  if(!packet_is_prepared) {
    return RADIO_TX_ERR;
  }

  /* Stores the length of the packet to send */
  /* Others spirit_radio_prepare will be in hold */
  spirit_txbuf[0] = payload_len;
  
  /* Puts the SPIRIT1 in TX state */
  receiving_packet = 0;
  SpiritSetReadyState(); 
  spirit1_strobe(SPIRIT1_STROBE_TX);
  just_got_an_ack = 0;
  BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_TX, 5 * RTIMER_SECOND/1000);
  BUSYWAIT_UNTIL(SPIRIT1_STATUS() != SPIRIT1_STATE_TX, 50 * RTIMER_SECOND/1000);

  /* Reset radio - needed for immediate RX of ack */
  CLEAR_TXBUF();
  CLEAR_RXBUF();
  SpiritIrqClearStatus();
  spirit1_strobe(SPIRIT1_STROBE_SABORT);
  BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_READY, 1 * RTIMER_SECOND/1000);
  spirit1_strobe(SPIRIT1_STROBE_READY);
  BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_READY, 1 * RTIMER_SECOND/1000);
  spirit1_strobe(SPIRIT1_STROBE_RX);
  BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, 1 * RTIMER_SECOND/1000);

#if NULLRDC_CONF_802154_AUTOACK
  if (wants_an_ack) {
    rtimer_txdone = RTIMER_NOW();
    BUSYWAIT_UNTIL(just_got_an_ack, 15 * RTIMER_SECOND/1000);
    rtimer_rxack = RTIMER_NOW();

    if(just_got_an_ack) {
      ACKPRINTF("debug_ack: ack received after %u/%u ticks\n",
             (uint32_t)(rtimer_rxack - rtimer_txdone), 15 * RTIMER_SECOND/1000);
    } else {
      ACKPRINTF("debug_ack: no ack received\n");
    }
  }
#endif /* NULLRDC_CONF_802154_AUTOACK */

  PRINTF("TRANSMIT OUT\n");

  CLEAR_TXBUF();

  packet_is_prepared = 0;
  return RADIO_TX_OK;
}
Exemplo n.º 18
0
static void
on(void)
{
  if(completely_off) {
    completely_off = 0;
    powerup();
    configure();
  }
  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;
}
Exemplo n.º 19
0
static void
off(void)
{
  /*  PRINTF("off\n");*/
  receive_on = 0;

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

  ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
  strobe(CC2520_INS_SRFOFF);
  CC2520_DISABLE_FIFOP_INT();

  if(!CC2520_FIFOP_IS_1) {
    flushrx();
  }
}
Exemplo n.º 20
0
static void
configure(void)
{
  uint16_t reg;
  BUSYWAIT_UNTIL(status() & (BV(CC2420_XOSC16M_STABLE)), RTIMER_SECOND / 100);

  /* Turn on/off automatic packet acknowledgment and address decoding. */
  reg = getreg(CC2420_MDMCTRL0);

#if CC2420_CONF_AUTOACK
  reg |= AUTOACK | ADR_DECODE;
#else
  reg &= ~(AUTOACK | ADR_DECODE);
#endif /* CC2420_CONF_AUTOACK */
  setreg(CC2420_MDMCTRL0, reg);

  /* Set transmission turnaround time to the lower setting (8 symbols
     = 0.128 ms) instead of the default (12 symbols = 0.192 ms). */
  /*  reg = getreg(CC2420_TXCTRL);
  reg &= ~(1 << 13);
  setreg(CC2420_TXCTRL, reg);*/

  /* Change default values as recomended in the data sheet, */
  /* correlation threshold = 20, RX bandpass filter = 1.3uA. */
  setreg(CC2420_MDMCTRL1, CORR_THR(20));
  reg = getreg(CC2420_RXCTRL1);
  reg |= RXBPF_LOCUR;
  setreg(CC2420_RXCTRL1, reg);

  /* Set the FIFOP threshold to maximum. */
  setreg(CC2420_IOCFG0, FIFOP_THR(127));

  /* Turn off "Security enable" (page 32). */
  reg = getreg(CC2420_SECCTRL0);
  reg &= ~RXFIFO_PROTECTION;
  setreg(CC2420_SECCTRL0, reg);

  cc2420_set_pan_addr(pan, addr, NULL);
  cc2420_set_channel(channel);

  flushrx();

}
Exemplo n.º 21
0
/*---------------------------------------------------------------------------*/
static int
spirit_radio_prepare(const void *payload, unsigned short payload_len)
{
  PRINTF("Spirit1: prep %u\n", payload_len);
  packet_is_prepared = 0;

  /* Checks if the payload length is supported */
  if(payload_len > MAX_PACKET_LEN) {
    return RADIO_TX_ERR;
  }
  
  /* Waits the end of a still running spirit_radio_transmit */
  BUSYWAIT_UNTIL(IS_TXBUF_EMPTY(), TX_WAIT_PCKT_PERIOD * RTIMER_SECOND/1000);
  if(!IS_TXBUF_EMPTY()) {
    PRINTF("PREPARE OUT ERR\n");
    return RADIO_TX_ERR;
  }

  /* Should we delay for an ack? */
#if NULLRDC_CONF_802154_AUTOACK
  frame802154_t info154;
  wants_an_ack = 0;
  if(payload_len > ACK_LEN
      && frame802154_parse((char*)payload, payload_len, &info154) != 0) {
    if(info154.fcf.frame_type == FRAME802154_DATAFRAME
        && info154.fcf.ack_required != 0) {
      wants_an_ack = 1;
    }
  }
#endif /* NULLRDC_CONF_802154_AUTOACK */

  /* Sets the length of the packet to send */
  spirit1_strobe(SPIRIT1_STROBE_FTX);
  SpiritPktBasicSetPayloadLength(payload_len);
  SpiritSpiWriteLinearFifo(payload_len, (uint8_t *)payload);
  
  PRINTF("PREPARE OUT\n");

  packet_is_prepared = 1;
  return RADIO_TX_OK;
}
Exemplo n.º 22
0
/*---------------------------------------------------------------------------*/
void
ST_RadioReceiveIsrCallback(uint8_t *packet,
                           boolean ackFramePendingSet,
                           uint32_t time, uint16_t errors, int8_t rssi)
{
  LED_RX_ON();
  PRINTF("stm32w: incomming packet received\n");
  receiving_packet = 0;

  /* Copy packet into the buffer. It is better to do this here. */
  if(add_to_rxbuf(packet)) {
    process_poll(&stm32w_radio_process);
    last_rssi = rssi;
  }
  LED_RX_OFF();
  GET_LOCK();
  is_transmit_ack = 1;
  /* Wait for sending ACK */
  BUSYWAIT_UNTIL(!is_transmit_ack, RTIMER_SECOND / 1500);
  RELEASE_LOCK();
}
Exemplo n.º 23
0
/**
 * \brief      perform a clear channel assessment 
 * \retval >0  Channel is clear
 * \retval 0   Channel is not clear
 */
int
rf233_channel_clear(void)
{
  uint8_t regsave;
  int was_off = 0;
  
  if(rf233_status() != STATE_RX_ON) {
    /* CCA can only be performed in RX state */
    was_off = 1;
    RF233_COMMAND(TRXCMD_RX_ON);
  }
   delay_us(200);
  /* request a CCA, storing the channel number (set with the same reg) */
  regsave = trx_reg_read(RF233_REG_PHY_CC_CCA);
  regsave |= PHY_CC_CCA_DO_CCA | PHY_CC_CCA_MODE_CS_OR_ED;
  trx_reg_write(RF233_REG_PHY_CC_CCA, regsave);
  
  BUSYWAIT_UNTIL(trx_reg_read(RF233_REG_TRX_STATUS) & TRX_CCA_DONE,
      RTIMER_SECOND / 1000);
  //regsave = rf233_status();
  regsave = trx_reg_read(RF233_REG_TRX_STATUS);
  /* return to previous state */
  if(was_off) {
    RF233_COMMAND(TRXCMD_TRX_OFF);
  }
  #if NULLRDC_CONF_802154_AUTOACK_HW 
  else{
	  RF233_COMMAND(TRXCMD_RX_AACK_ON);
  }
  #endif

  /* check CCA */
  if((regsave & TRX_CCA_DONE) && (regsave & TRX_CCA_STATUS)) {
    PRINTF("RF233: CCA 1\r\n");
    return 1;
  }
  PRINTF("RF233: CCA 0\r\n");
  return 0;
}
Exemplo n.º 24
0
/*---------------------------------------------------------------------------*/
static int
cc2520_cca(void)
{
  int cca;
  int radio_was_off = 0;

  /* If the radio is locked by an underlying thread (because we are
     being invoked through an interrupt), we preted that the coast is
     clear (i.e., no packet is currently being transmitted by a
     neighbor). */
  if(locked) {
    return 1;
  }

  GET_LOCK();
  if(!receive_on) {
    radio_was_off = 1;
    cc2520_on();
  }

  /* Make sure that the radio really got turned on. */
  if(!receive_on) {
    RELEASE_LOCK();
    if(radio_was_off) {
      cc2520_off();
    }
    return 1;
  }

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

  cca = CC2520_CCA_IS_1;

  if(radio_was_off) {
    cc2520_off();
  }
  RELEASE_LOCK();
  return cca;
}
Exemplo n.º 25
0
/**
 * \brief      prepare a frame and the radio for immediate transmission 
 * \param payload         Pointer to data to copy/send
 * \param payload_len     length of data to copy
 * \return     Returns success/fail, refer to radio.h for explanation
 */
int
rf233_prepare(const void *payload, unsigned short payload_len)
{
#if DEBUG_PRINTDATA
  int i;
#endif  /* DEBUG_PRINTDATA */
  uint8_t templen;
  uint8_t radio_status;
  uint8_t data[130];

#if USE_HW_FCS_CHECK
  /* Add length of the FCS (2 bytes) */
  templen = payload_len + 2;
#else   /* USE_HW_FCS_CHECK */
  /* FCS is assumed to already be included in the payload */
  templen = payload_len;
#endif  /* USE_HW_FCS_CHECK */
 //data = templen;
 
/*
for(i = 0; i < templen; i++) {
	data++;
	data =(uint8_t *)(payload + i);
	
}*/
//memcpy(data,&templen,1);
data[0] = templen;
memcpy(&data[1],payload,templen);
//data--;
#if DEBUG_PRINTDATA
  PRINTF("RF233 prepare (%u/%u): 0x", payload_len, templen);
  for(i = 0; i < templen; i++) {
    PRINTF("%02x", *(uint8_t *)(payload + i));
  }
  PRINTF("\r\n");
#endif  /* DEBUG_PRINTDATA */
   
  PRINTF("RF233: prepare %u\r\n", payload_len);
  if(payload_len > MAX_PACKET_LEN) {
    PRINTF("RF233: error, frame too large to tx\r\n");
    return RADIO_TX_ERR;
  }

  /* check that the FIFO is clear to access */
  radio_status=rf233_status();
  #if NULLRDC_CONF_802154_AUTOACK_HW
  if(radio_status == STATE_BUSY_RX_AACK || radio_status == STATE_BUSY_TX_ARET) {
	  PRINTF("RF233: TRX buffer unavailable: prep when %s\r\n", radio_status == STATE_BUSY_RX_AACK ? "rx" : "tx");
  #else
   if(radio_status == STATE_BUSY_RX || radio_status == STATE_BUSY_TX) {
	   PRINTF("RF233: TRX buffer unavailable: prep when %s\r\n", radio_status == STATE_BUSY_RX? "rx" : "tx");
  #endif
    
    return RADIO_TX_ERR;
  }

  /* Write packet to TX FIFO. */
  PRINTF("RF233 len = %u\r\n", payload_len);
  trx_frame_write((uint8_t *)data, templen+1);
  return RADIO_TX_OK;
}
/*---------------------------------------------------------------------------*/
/**
 * \brief      Transmit a frame already put in the radio with 'prepare'
 * \param payload_len    Length of the frame to send
 * \return     Returns success/fail, refer to radio.h for explanation
 */
int
rf233_transmit(unsigned short payload_len)
{
  static uint8_t status_now;
  PRINTF("RF233: tx %u\r\n", payload_len);

  /* prepare for TX */
  
  status_now = rf233_status();
   //status_now = trx_reg_read(RF233_REG_TRX_RPC);
  #if NULLRDC_CONF_802154_AUTOACK_HW
  if(status_now == STATE_BUSY_RX_AACK || status_now == STATE_BUSY_TX_ARET) {
  #else
  if(status_now == STATE_BUSY_RX || status_now == STATE_BUSY_TX) {
  #endif
    PRINTF("RF233: collision, was receiving 0x%02X\r\n",status_now);
    /* NOTE: to avoid loops */
    return RADIO_TX_ERR;;
    // return RADIO_TX_COLLISION;
  }
  if(status_now != STATE_PLL_ON) {
    /* prepare for going to state TX, should take max 80 us */
    //RF233_COMMAND(TRXCMD_PLL_ON);
	trx_reg_write(RF233_REG_TRX_STATE,0x09);
   // BUSYWAIT_UNTIL(trx_reg_read(RF233_REG_TRX_STATUS) == STATE_PLL_ON, 1 * RTIMER_SECOND/1000);
   //delay_ms(10);
   //status_now = trx_reg_read(RF233_REG_TRX_STATE);
   do 
   {
	   status_now = trx_bit_read(0x01, 0x1F, 0);
   } while (status_now == 0x1f);
  }

  if(rf233_status() != STATE_PLL_ON) {
    /* failed moving into PLL_ON state, gracefully try to recover */
    PRINTF("RF233: failed going to PLLON\r\n");
    RF233_COMMAND(TRXCMD_PLL_ON);   /* try again */
	static uint8_t state;
	state = rf233_status();
    if(state != STATE_PLL_ON) {
      /* give up and signal big fail (should perhaps reset radio core instead?) */
      PRINTF("RF233: graceful recovery (in tx) failed, giving up. State: 0x%02X\r\n", rf233_status());
      return RADIO_TX_ERR;
    }
  }

  /* perform transmission */
  ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
  ENERGEST_ON(ENERGEST_TYPE_TRANSMIT);
#if NULLRDC_CONF_802154_AUTOACK_HW
  RF233_COMMAND(TRXCMD_TX_ARET_ON);
#endif
  RF233_COMMAND(TRXCMD_TX_START);
   flag_transmit=1;
   //delay_ms(5);
  //printf("RTIMER value %d",RTIMER_NOW());

#if !NULLRDC_CONF_802154_AUTOACK_HW
    BUSYWAIT_UNTIL(rf233_status() == STATE_BUSY_TX, RTIMER_SECOND/2000);
   // printf("RTIMER value1 %d",RTIMER_NOW());
   // printf("\r\nSTATE_BUSY_TX");
  BUSYWAIT_UNTIL(rf233_status() != STATE_BUSY_TX, 10 * RTIMER_SECOND/1000);
  // printf("RTIMER value2 %d",RTIMER_NOW());
#endif

  ENERGEST_OFF(ENERGEST_TYPE_TRANSMIT);
  ENERGEST_ON(ENERGEST_TYPE_LISTEN);

#if !NULLRDC_CONF_802154_AUTOACK_HW
   if(rf233_status() != STATE_PLL_ON) {
    // something has failed 
    PRINTF("RF233: radio fatal err after tx\r\n");
    radiocore_hard_recovery();
    return RADIO_TX_ERR;
  }
  RF233_COMMAND(TRXCMD_RX_ON);
#else
	BUSYWAIT_UNTIL(ack_status == 1, 10 * RTIMER_SECOND/1000);
	if((ack_status))
	{
	//	printf("\r\nrf233 sent\r\n ");
		ack_status=0;
	//	printf("\nACK received");
		return RADIO_TX_OK;
	}
	else
	{
	//	printf("\nNOACK received");		
		return RADIO_TX_NOACK;
	}
	
#endif

  PRINTF("RF233: tx ok\r\n");
  return RADIO_TX_OK;
}
/*---------------------------------------------------------------------------*/
/**
 * \brief      Send data: first prepares, then transmits
 * \param payload         Pointer to data to copy/send
 * \param payload_len     length of data to copy
 * \return     Returns success/fail, refer to radio.h for explanation
 */
int
rf233_send(const void *payload, unsigned short payload_len)
{
  PRINTF("RF233: send %u\r\n", payload_len);
  if(rf233_prepare(payload, payload_len) == RADIO_TX_ERR) {
  return RADIO_TX_ERR;
  } 
  return rf233_transmit(payload_len);
}
/*---------------------------------------------------------------------------*/
/**
 * \brief      read a received frame out of the radio buffer 
 * \param buf         pointer to where to copy received data
 * \param bufsize     Maximum size we can copy into bufsize
 * \return     Returns length of data read (> 0) if successful
 * \retval -1  Failed, was transmitting so FIFO is invalid
 * \retval -2  Failed, rx timed out (stuck in rx?)
 * \retval -3  Failed, too large frame for buffer
 * \retval -4  Failed, CRC/FCS failed (if USE_HW_FCS_CHECK is true)
 */
int
rf233_read(void *buf, unsigned short bufsize)
{
//  uint8_t radio_state;
  uint8_t ed;       /* frame metadata */
  uint8_t frame_len = 0;
  uint8_t len = 0;
  int rssi;
#if DEBUG_PRINTDATA
  uint8_t tempreadlen;
#endif  /* DEBUG_PRINTDATA */

  if(pending_frame == 0) {
    return 0;
  }
  pending_frame = 0;

 /* / * check that data in FIFO is valid * /
  radio_state = RF233_STATUS();
  if(radio_state == STATE_BUSY_TX) {
    / * data is invalid, bail out * /
    PRINTF("RF233: read while in BUSY_TX ie invalid, dropping.\n");
    return -1;
  }
  if(radio_state == STATE_BUSY_RX) {
    / * still receiving - data is invalid, wait for it to finish * /
    PRINTF("RF233: read while BUSY_RX, waiting.\n");
    BUSYWAIT_UNTIL(RF233_STATUS() != STATE_BUSY_RX, 10 * RTIMER_SECOND/1000);
	if(RF233_STATUS() == STATE_BUSY_RX) {
      PRINTF("RF233: timed out, still BUSY_RX, dropping.\n");
      return -2;
    }
  }
*/

  /* get length of data in FIFO */
  trx_frame_read(&frame_len, 1);
#if DEBUG_PRINTDATA
  tempreadlen = frame_len;
#endif  /* DEBUG_PRINTDATA */
  if(frame_len == 1) {
    frame_len = 0;
  }

  len = frame_len;
#if USE_HW_FCS_CHECK
  /* FCS has already been stripped */
  len = frame_len - 2;
#endif  /* USE_HW_FCS_CHECK */

  if(frame_len == 0) {
    return 0;
  }
  if(len > bufsize) {
    /* too large frame for the buffer, drop */
    PRINTF("RF233: too large frame for buffer, dropping (%u > %u).\r\n", frame_len, bufsize);
    flush_buffer();
    return -3;
  }
  PRINTF("RF233 read %u B\r\n", frame_len);

  /* read out the data into the buffer, disregarding the length and metadata bytes */
  trx_sram_read(1,(uint8_t *)buf, len);
#if DEBUG_PRINTDATA
  {
    int k;
    PRINTF("RF233: Read frame (%u/%u): ", tempreadlen, frame_len);
    for(k = 0; k < frame_len; k++) {
      PRINTF("%02x", *((uint8_t *)buf + k));
    }
    PRINTF("\r\n");
  }
#endif  /* DEBUG_PRINTDATA */

  /* 
   * Energy level during reception, ranges from 0x00 to 0x53 (=83d) with a
   * resolution of 1dB and accuracy of +/- 5dB. 0xFF means invalid measurement.
   * 0x00 means <= RSSI(base_val), which is -91dBm (typ). See datasheet 12.7.
   * Ergo, real RSSI is (ed-91) dBm or less.
   */
  #define RSSI_OFFSET       (91)
  ed = trx_reg_read(RF233_REG_PHY_ED_LEVEL);
  rssi = (int) ed - RSSI_OFFSET;
  packetbuf_set_attr(PACKETBUF_ATTR_RSSI, rssi);
  flush_buffer();

/*
#if USE_HW_FCS_CHECK
  {
    uint8_t crc_ok;   / * frame metadata * /
    crc_ok = rf233_arch_read_reg(RF233_REG_PHY_RSSI) & PHY_RSSI_CRC_VALID;
    if(crc_ok == 0) {
      / * CRC/FCS fail, drop * /
      PRINTF("RF233: CRC/FCS fail, dropping.\n");
      flush_buffer();
      return -4;
    }
  }
#endif  / * USE_HW_FCS_CHECK * /*/

  return len;
}
Exemplo n.º 26
0
/*---------------------------------------------------------------------------*/
static int
spirit_radio_init(void)
{  
  PRINTF("RADIO INIT IN\n");

  SpiritSpiInit();
  
  /* Configure radio shut-down (SDN) pin and activate radio */
  SdkEvalM2SGpioInit(M2S_GPIO_SDN, M2S_MODE_GPIO_OUT);
  
  /* Configures the SPIRIT1 library */
  SpiritRadioSetXtalFrequency(XTAL_FREQUENCY);
  SpiritManagementSetVersion(SPIRIT1_VERSION);
  SpiritGeneralSetSpiritVersion(SPIRIT1_VERSION);
  SpiritManagementSetXtalFrequency(XTAL_FREQUENCY);
  
  /* wake up to READY state */
  /* weirdly enough, this *should* actually *set* the pin, not clear it! The pins is declared as GPIO_pin13 == 0x2000 */
  M2S_GPIO_SDN_PORT->BSRRL = M2S_GPIO_SDN_PIN;
/*  GPIOC->BSRRL = M2S_GPIO_SDN_PIN;*/
  GPIO_ResetBits(M2S_GPIO_SDN_PORT, M2S_GPIO_SDN_PIN);

  /* wait minimum 1.5 ms to allow SPIRIT1 a proper boot-up sequence */
  BUSYWAIT_UNTIL(0, 3 * RTIMER_SECOND/2000);
  
  /* Soft reset of core */
  spirit1_strobe(SPIRIT1_STROBE_SRES);
/*  SpiritCmdStrobeSres();*/
  
  /* Configures the SPIRIT1 radio part */
  SRadioInit xRadioInit = {
    XTAL_FREQUENCY,
    XTAL_OFFSET_PPM,
    BASE_FREQUENCY,
    CHANNEL_SPACE,
    CHANNEL_NUMBER,
    MODULATION_SELECT,
    DATARATE,
    FREQ_DEVIATION,
    BANDWIDTH
  };
  SpiritRadioInit(&xRadioInit);
  SpiritRadioSetPALeveldBm(0,POWER_DBM);
  SpiritRadioSetPALevelMaxIndex(0);
  
  /* Configures the SPIRIT1 packet handler part*/
  PktBasicInit xBasicInit = {
    PREAMBLE_LENGTH,
    SYNC_LENGTH,
    SYNC_WORD,
    LENGTH_TYPE,
    LENGTH_WIDTH,
    CRC_MODE,
    CONTROL_LENGTH,
    EN_ADDRESS,
    EN_FEC,
    EN_WHITENING
  };
  SpiritPktBasicInit(&xBasicInit);
  
  /* Enable the following interrupt sources, routed to GPIO */
  SpiritIrqDeInit(NULL);
  SpiritIrqClearStatus();
  SpiritIrq(TX_DATA_SENT, S_ENABLE);
  SpiritIrq(RX_DATA_READY,S_ENABLE);
  SpiritIrq(VALID_SYNC,S_ENABLE);
  SpiritIrq(RX_DATA_DISC, S_ENABLE);
  SpiritIrq(TX_FIFO_ERROR, S_ENABLE);
  SpiritIrq(RX_FIFO_ERROR, S_ENABLE);

  /* Configure Spirit1 */
  SpiritRadioPersistenRx(S_ENABLE);
  SpiritQiSetSqiThreshold(SQI_TH_0);
  SpiritQiSqiCheck(S_ENABLE);
  SpiritQiSetRssiThresholddBm(CCA_THRESHOLD);
  SpiritTimerSetRxTimeoutStopCondition(SQI_ABOVE_THRESHOLD);
  SET_INFINITE_RX_TIMEOUT();
  SpiritRadioAFCFreezeOnSync(S_ENABLE);
  
  /* Puts the SPIRIT1 in STANDBY mode (125us -> rx/tx) */
  spirit1_strobe(SPIRIT1_STROBE_STANDBY);
/*  SpiritCmdStrobeCommand(SPIRIT1_STROBE_STANDBY);*/
/*  SpiritCmdStrobeStandby();*/
  spirit_on = OFF;
  CLEAR_RXBUF();
  CLEAR_TXBUF();
  
  /* Initializes the mcu pin as input, used for IRQ */
  SdkEvalM2SGpioInit(M2S_GPIO_0, M2S_MODE_EXTI_IN);
  SdkEvalM2SGpioInit(M2S_GPIO_1, M2S_MODE_EXTI_IN);
  SdkEvalM2SGpioInit(M2S_GPIO_2, M2S_MODE_EXTI_IN);
  SdkEvalM2SGpioInit(M2S_GPIO_3, M2S_MODE_EXTI_IN);
  
  /* Configure the radio to route the IRQ signal to its GPIO 3 */
  SpiritGpioInit(&(SGpioInit){SPIRIT_GPIO_3, SPIRIT_GPIO_MODE_DIGITAL_OUTPUT_LP, SPIRIT_GPIO_DIG_OUT_IRQ});

  process_start(&spirit_radio_process, NULL);

  PRINTF("Spirit1 init done\n");

  return 0;
}
Exemplo n.º 27
0
PROCESS_THREAD(spirit_radio_process, ev, data)
{
  PROCESS_BEGIN();
  PRINTF("Spirit1: process started\n");
  
  while(1) {
    int len;

    PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL);    
    PRINTF("Spirit1: polled\n");

    packetbuf_clear();
    len = spirit_radio_read(packetbuf_dataptr(), PACKETBUF_SIZE);

    if(len > 0) {

#if NULLRDC_CONF_802154_AUTOACK
      /* Check if the packet has an ACK request */
      frame802154_t info154;
      if(len > ACK_LEN &&
          frame802154_parse((char*)packetbuf_dataptr(), len, &info154) != 0) {
        if(info154.fcf.frame_type == FRAME802154_DATAFRAME &&
            info154.fcf.ack_required != 0 &&
            rimeaddr_cmp((rimeaddr_t *)&info154.dest_addr,
                         &rimeaddr_node_addr)) {

          /* Send an ACK packet */
          uint8_t ack_frame[ACK_LEN] = {
              FRAME802154_ACKFRAME,
              0x00,
              info154.seq
          };

          spirit1_strobe(SPIRIT1_STROBE_FTX);
          SpiritPktBasicSetPayloadLength((uint16_t) ACK_LEN);
          SpiritSpiWriteLinearFifo((uint16_t) ACK_LEN, (uint8_t *) ack_frame);

          SpiritSetReadyState();
          spirit1_strobe(SPIRIT1_STROBE_TX);
          BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_TX, 1 * RTIMER_SECOND/1000);
          BUSYWAIT_UNTIL(SPIRIT1_STATUS() != SPIRIT1_STATE_TX, 1 * RTIMER_SECOND/1000);

          ACKPRINTF("debug_ack: sent ack %d\n", ack_frame[2]);
        }
      }
#endif /* NULLRDC_CONF_802154_AUTOACK */

      packetbuf_set_datalen(len);   
      NETSTACK_RDC.input();
    }
    if(!IS_RXBUF_EMPTY()){
      process_poll(&spirit_radio_process);
    }

    if(interrupt_callback_wants_poll) {
      spirit1_interrupt_callback();

      if(SPIRIT1_STATUS() == SPIRIT1_STATE_READY) {
        spirit1_strobe(SPIRIT1_STROBE_RX);
        BUSYWAIT_UNTIL(SPIRIT1_STATUS() == SPIRIT1_STATE_RX, 1 * RTIMER_SECOND/1000);
      }

    }
  }

  PROCESS_END();
}
Exemplo n.º 28
0
/**
 * \brief      prepare a frame and the radio for immediate transmission 
 * \param payload         Pointer to data to copy/send
 * \param payload_len     length of data to copy
 * \return     Returns success/fail, refer to radio.h for explanation
 */
static int
rf212_prepare(const void *payload, unsigned short payload_len)
{
#if DEBUG_PRINTDATA
  int i;
#endif  /* DEBUG_PRINTDATA */
  uint8_t templen;
  uint8_t radio_status;
  uint8_t data[130];

#if USE_HW_FCS_CHECK
  /* Add length of the FCS (2 bytes) */
  templen = payload_len + 2;
#else   /* USE_HW_FCS_CHECK */
  /* FCS is assumed to already be included in the payload */
  templen = payload_len;
#endif  /* USE_HW_FCS_CHECK */
data[0] = templen;
memcpy(&data[1],payload,templen);
#if DEBUG_PRINTDATA
  PRINTF("RF212 prepare (%u/%u): 0x", payload_len, templen);
  for(i = 0; i < templen; i++) {
    PRINTF("%02x", *(uint8_t *)(payload + i));
  }
  PRINTF("\n");
#endif  /* DEBUG_PRINTDATA */

  PRINTF("RF212: prepare %u\n", payload_len);
  if(payload_len > MAX_PACKET_LEN) {
    PRINTF("RF212: error, frame too large to tx\n");
    return RADIO_TX_ERR;
  }

  /* check that the FIFO is clear to access */
  radio_status = rf212_status();
  #if NULLRDC_CONF_802154_AUTOACK_HW
  if(radio_status == STATE_BUSY_RX_AACK || radio_status == STATE_BUSY_TX_ARET) {
	  PRINTF("RF212B: TRX buffer unavailable: prep when %s\n", radio_status == STATE_BUSY_RX_AACK ? "rx" : "tx");
  #else
   if(radio_status == STATE_BUSY_RX || radio_status == STATE_BUSY_TX) {
	   PRINTF("RF212B: TRX buffer unavailable: prep when %s\n", radio_status == STATE_BUSY_RX? "rx" : "tx");
  #endif
    return RADIO_TX_ERR;
  }

  /* Write packet to TX FIFO. */
  PRINTF("RF212 len = %u\n", payload_len);
  trx_frame_write((uint8_t *)data, templen+1);
  return RADIO_TX_OK;
}
/*---------------------------------------------------------------------------*/
/**
 * \brief      Transmit a frame already put in the radio with 'prepare'
 * \param payload_len    Length of the frame to send
 * \return     Returns success/fail, refer to radio.h for explanation
 */
static int
rf212_transmit(unsigned short payload_len)
{
  uint8_t status_now;//,temp;
  PRINTF("RF212: tx %u\n", payload_len);

  /* prepare for TX */
  status_now = rf212_status();
  #if NULLRDC_CONF_802154_AUTOACK_HW
  if(status_now == STATE_BUSY_RX_AACK || status_now == STATE_BUSY_TX_ARET) {
  #else
  if(status_now == STATE_BUSY_RX || status_now == STATE_BUSY_TX) {
  #endif
    PRINTF("RF212: collision, was receiving\n");
    /* NOTE: to avoid loops */
    return RADIO_TX_ERR;
    // return RADIO_TX_COLLISION;
  }
  if(status_now != STATE_PLL_ON) {
    /* prepare for going to state TX, should take max 80 us */
    //RF212_COMMAND(TRXCMD_PLL_ON);
	trx_reg_write(RF212_REG_TRX_STATE,0x09);
	do 
   {
	   status_now = trx_bit_read(0x01, 0x1F, 0);
   } while (status_now == 0x1f);
    //BUSYWAIT_UNTIL(RF212_STATUS() == STATE_PLL_ON, 1 * RTIMER_SECOND/1000);
  }

  if(rf212_status() != STATE_PLL_ON) {
    /* failed moving into PLL_ON state, gracefully try to recover */
    PRINTF("RF212: failed going to PLLON\n");
    RF212_COMMAND(TRXCMD_PLL_ON);   /* try again */
    if(rf212_status() != STATE_PLL_ON) {
      /* give up and signal big fail (should perhaps reset radio core instead?) */
      PRINTF("RF212: graceful recovery (in tx) failed, giving up. State: 0x%02X\n", RF212_STATUS());
      return RADIO_TX_ERR;
    }
  }

  /* perform transmission */
  ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
  ENERGEST_ON(ENERGEST_TYPE_TRANSMIT);
#if NULLRDC_CONF_802154_AUTOACK_HW
  RF212_COMMAND(TRXCMD_TX_ARET_ON);
#endif  
  RF212_COMMAND(TRXCMD_TX_START);
  flag_transmit=1;

#if !NULLRDC_CONF_802154_AUTOACK_HW  
  BUSYWAIT_UNTIL(RF212_STATUS() == STATE_BUSY_TX, RTIMER_SECOND/2000);
  BUSYWAIT_UNTIL(RF212_STATUS() != STATE_BUSY_TX, 10 * RTIMER_SECOND/1000);
  #if (DATA_RATE==BPSK_20||BPSK_40||OQPSK_SIN_RC_100)
  BUSYWAIT_UNTIL(RF212_STATUS() != STATE_BUSY_TX, 10 * RTIMER_SECOND/1000);
  BUSYWAIT_UNTIL(RF212_STATUS() != STATE_BUSY_TX, 10 * RTIMER_SECOND/1000);
  BUSYWAIT_UNTIL(RF212_STATUS() != STATE_BUSY_TX, 10 * RTIMER_SECOND/1000);
  #endif
#endif  
  ENERGEST_OFF(ENERGEST_TYPE_TRANSMIT);
  ENERGEST_ON(ENERGEST_TYPE_LISTEN);
#if !NULLRDC_CONF_802154_AUTOACK_HW  
  if(RF212_STATUS() != STATE_PLL_ON) {
    /* something has failed */
    printf("RF212: radio fatal err after tx\n");
    radiocore_hard_recovery();
	return RADIO_TX_ERR;
  }
 // printf("#RTIMER_SECOND");
  RF212_COMMAND(TRXCMD_RX_ON);
#else
	BUSYWAIT_UNTIL(ack_status == 1, 10 * RTIMER_SECOND/1000);
	if((ack_status))
	{
	//	printf("\r\nrf233 sent\r\n ");
		ack_status=0;
	//	printf("\nACK received");
		return RADIO_TX_OK;
	}
	else
	{
	//	printf("\nNOACK received");		
		return RADIO_TX_NOACK;
	}
	
#endif  

 PRINTF("RF212: tx ok\n");
  return RADIO_TX_OK;
}
void
goto_sleep(void)
{
	port_pin_set_output_level(AT86RFX_SLP_PIN, true);
}
Exemplo n.º 29
0
/*---------------------------------------------------------------------------*/
static int
cc2520_transmit(unsigned short payload_len)
{
  int i, txpower;

  GET_LOCK();

  txpower = 0;
  if(packetbuf_attr(PACKETBUF_ATTR_RADIO_TXPOWER) > 0) {
    /* Remember the current transmission power */
    txpower = cc2520_get_txpower();
    /* Set the specified transmission power */
    set_txpower(packetbuf_attr(PACKETBUF_ATTR_RADIO_TXPOWER) - 1);
  }

  /* The TX FIFO can only hold one packet. Make sure to not overrun
   * FIFO by waiting for transmission to start here and synchronizing
   * with the CC2520_TX_ACTIVE check in cc2520_send.
   *
   * Note that we may have to wait up to 320 us (20 symbols) before
   * transmission starts.
   */
#ifndef CC2520_CONF_SYMBOL_LOOP_COUNT
#error CC2520_CONF_SYMBOL_LOOP_COUNT needs to be set!!!
#else
#define LOOP_20_SYMBOLS CC2520_CONF_SYMBOL_LOOP_COUNT
#endif

#if WITH_SEND_CCA
  strobe(CC2520_INS_SRXON);
  BUSYWAIT_UNTIL(status() & BV(CC2520_RSSI_VALID) , RTIMER_SECOND / 10);
  strobe(CC2520_INS_STXONCCA);
#else /* WITH_SEND_CCA */
  strobe(CC2520_INS_STXON);
#endif /* WITH_SEND_CCA */
  for(i = LOOP_20_SYMBOLS; i > 0; i--) {
    if(CC2520_SFD_IS_1) {
      {
        rtimer_clock_t sfd_timestamp;
        sfd_timestamp = cc2520_sfd_start_time;
        if(packetbuf_attr(PACKETBUF_ATTR_PACKET_TYPE) ==
           PACKETBUF_ATTR_PACKET_TYPE_TIMESTAMP) {
          /* Write timestamp to last two bytes of packet in TXFIFO. */
          CC2520_WRITE_RAM(&sfd_timestamp, CC2520RAM_TXFIFO + payload_len - 1, 2);
        }
      }

      if(!(status() & BV(CC2520_TX_ACTIVE))) {
        /* SFD went high but we are not transmitting. This means that
           we just started receiving a packet, so we drop the
           transmission. */
        RELEASE_LOCK();
        return RADIO_TX_COLLISION;
      }
      if(receive_on) {
	ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
      }
      ENERGEST_ON(ENERGEST_TYPE_TRANSMIT);
      /* We wait until transmission has ended so that we get an
	 accurate measurement of the transmission time.*/
     //BUSYWAIT_UNTIL(getreg(CC2520_EXCFLAG0) & TX_FRM_DONE , RTIMER_SECOND / 100);
      BUSYWAIT_UNTIL(!(status() & BV(CC2520_TX_ACTIVE)), RTIMER_SECOND / 10);

#ifdef ENERGEST_CONF_LEVELDEVICE_LEVELS
      ENERGEST_OFF_LEVEL(ENERGEST_TYPE_TRANSMIT,cc2520_get_txpower());
#endif
      ENERGEST_OFF(ENERGEST_TYPE_TRANSMIT);
      if(receive_on) {
	ENERGEST_ON(ENERGEST_TYPE_LISTEN);
      } else {
	/* We need to explicitly turn off the radio,
	 * since STXON[CCA] -> TX_ACTIVE -> RX_ACTIVE */
	off();
      }

      if(packetbuf_attr(PACKETBUF_ATTR_RADIO_TXPOWER) > 0) {
        /* Restore the transmission power */
        set_txpower(txpower & 0xff);
      }

      RELEASE_LOCK();

      return RADIO_TX_OK;
    }
  }

  /* If we are using WITH_SEND_CCA, we get here if the packet wasn't
     transmitted because of other channel activity. */
  RIMESTATS_ADD(contentiondrop);
  PRINTF("cc2520: do_send() transmission never started\n");

  if(packetbuf_attr(PACKETBUF_ATTR_RADIO_TXPOWER) > 0) {
    /* Restore the transmission power */
    set_txpower(txpower & 0xff);
  }

  RELEASE_LOCK();
  return RADIO_TX_COLLISION;
}
Exemplo n.º 30
0
/*---------------------------------------------------------------------------*/
int
cc2520_init(void)
{
  {
    int s = splhigh();
    cc2520_arch_init();		/* Initalize ports and SPI. */
    CC2520_DISABLE_FIFOP_INT();
    CC2520_FIFOP_INT_INIT();
    splx(s);
  }

  SET_VREG_INACTIVE();
  clock_delay(250);
  /* Turn on voltage regulator and reset. */
  SET_VREG_ACTIVE();
  clock_delay(250);
  SET_RESET_ACTIVE();
  clock_delay(127);
  SET_RESET_INACTIVE();
  clock_delay(125);
  /* Turn on the crystal oscillator. */
  strobe(CC2520_INS_SXOSCON);
  clock_delay(125);

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

  /* Change default values as recommended in the data sheet, */
  /* correlation threshold = 20, RX bandpass filter = 1.3uA.*/

  setreg(CC2520_TXCTRL,      0x94);
  setreg(CC2520_TXPOWER,     0x13);    // Output power 1 dBm

  /*

	valeurs de TXPOWER
	  0x03 -> -18 dBm
	  0x2C -> -7 dBm
	  0x88 -> -4 dBm
	  0x81 -> -2 dBm
	  0x32 -> 0 dBm
	  0x13 -> 1 dBm
	  0x32 -> 0 dBm
	  0x13 -> 1 dBm
	  0xAB -> 2 dBm
	  0xF2 -> 3 dBm
	  0xF7 -> 5 dBm
  */
  setreg(CC2520_CCACTRL0,    0xF8);  // CCA treshold -80dBm

  // Recommended RX settings
  setreg(CC2520_MDMCTRL0,    0x84);  // Controls modem
  setreg(CC2520_MDMCTRL1,    0x14);  // Controls modem
  setreg(CC2520_RXCTRL,      0x3F);  // Adjust currents in RX related analog modules
  setreg(CC2520_FSCTRL,      0x5A);  // Adjust currents in synthesizer.
  setreg(CC2520_FSCAL1,      0x2B);  // Adjust currents in VCO
  setreg(CC2520_AGCCTRL1,    0x11);  // Adjust target value for AGC control loop
  setreg(CC2520_AGCCTRL2,    0xEB);

  //  Disable external clock
  setreg(CC2520_EXTCLOCK,    0x00);

  //  Tune ADC performance
  setreg(CC2520_ADCTEST0,    0x10);
  setreg(CC2520_ADCTEST1,    0x0E);
  setreg(CC2520_ADCTEST2,    0x03);

  /* Set auto CRC on frame. */
#if CC2520_CONF_AUTOACK
  setreg(CC2520_FRMCTRL0,    AUTOCRC | AUTOACK);
  setreg(CC2520_FRMFILT0,    FRAME_MAX_VERSION|FRAME_FILTER_ENABLE);
#else
  /* setreg(CC2520_FRMCTRL0,    0x60); */
  setreg(CC2520_FRMCTRL0,    AUTOCRC);
  /* Disable filter on @ (remove if you want to address specific wismote) */
  setreg(CC2520_FRMFILT0,    0x00);
#endif /* CC2520_CONF_AUTOACK */
  /* SET_RXENMASK_ON_TX */
  setreg(CC2520_FRMCTRL1,          1);
  /* Set FIFOP threshold to maximum .*/
  setreg(CC2520_FIFOPCTRL,   FIFOP_THR(0x7F));

  cc2520_set_pan_addr(0xffff, 0x0000, NULL);
  cc2520_set_channel(26);

  flushrx();

  process_start(&cc2520_process, NULL);
  return 1;
}