U8 drvr_set_trx_state(U8 state) { U8 curr_state, delay; // if we're sleeping then don't allow transition if (hal_get_slptr() != 0) { return RADIO_WRONG_STATE; } // if we're in a transition state, wait for the state to become stable curr_state = drvr_get_trx_state(); if ((curr_state == BUSY_TX_ARET) || (curr_state == BUSY_RX_AACK) || (curr_state == BUSY_RX) || (curr_state == BUSY_TX)) { while (drvr_get_trx_state() == curr_state); } // At this point it is clear that the requested new_state is: // TRX_OFF, RX_ON, PLL_ON, RX_AACK_ON or TX_ARET_ON. // we need to handle some special cases before we transition to the new state switch (state) { case TRX_OFF: /* Go to TRX_OFF from any state. */ drvr_reset_fsm(); break; case TX_ARET_ON: if (curr_state == RX_AACK_ON) { /* First do intermediate state transition to PLL_ON, then to TX_ARET_ON. */ hal_subregister_write(SR_TRX_CMD, PLL_ON); delay_us(TIME_STATE_TRANSITION_PLL_ACTIVE); } break; case RX_AACK_ON: if (curr_state == TX_ARET_ON) { /* First do intermediate state transition to RX_ON, then to RX_AACK_ON. */ hal_subregister_write(SR_TRX_CMD, RX_ON); delay_us(TIME_STATE_TRANSITION_PLL_ACTIVE); } break; } /* Now we're okay to transition to any new state. */ hal_subregister_write(SR_TRX_CMD, state); /* When the PLL is active most states can be reached in 1us. However, from */ /* TRX_OFF the PLL needs time to activate. */ delay = (curr_state == TRX_OFF) ? TIME_TRX_OFF_TO_PLL_ACTIVE : TIME_STATE_TRANSITION_PLL_ACTIVE; delay_us(delay); if (drvr_get_trx_state() == state) { return RADIO_SUCCESS; } return RADIO_TIMED_OUT; }
void drvr_reset_fsm() { hal_set_slptr_low(); delay_us(TIME_NOCLK_TO_WAKE); hal_subregister_write(SR_TRX_CMD, CMD_FORCE_TRX_OFF); delay_us(TIME_CMD_FORCE_TRX_OFF); }
/** \brief This function will reset the state machine (to TRX_OFF) from any of * its states, except for the SLEEP state. */ void radio_reset_state_machine(void) { hal_set_slptr_low(); delay_us(TIME_NOCLK_TO_WAKE); hal_subregister_write(SR_TRX_CMD, CMD_FORCE_TRX_OFF); delay_us(TIME_CMD_FORCE_TRX_OFF); }
U8 drvr_config_csma(U8 seed0, U8 seed1, U8 min_be, U8 frame_retries, U8 csma_retries) { // make sure the device ain't sleeping if (hal_get_slptr()) { return RADIO_WRONG_STATE; } // note: in revA, max frame retries should be set to 0 due to errata. i'm assuming i only have // rev B parts with no known errata...i hope... hal_subregister_write(SR_MAX_FRAME_RETRIES, frame_retries); hal_subregister_write(SR_MAX_CSMA_RETRIES, csma_retries); hal_subregister_write(SR_MIN_BE, min_be); hal_register_write(RG_CSMA_SEED_0, seed0); hal_subregister_write(SR_CSMA_SEED_1, (seed1 & 0x7)); return RADIO_SUCCESS; }
U8 drvr_set_cca(U8 mode, U8 ed_thresh) { if ((mode != CCA_ED) && (mode != CCA_CARRIER_SENSE) && (mode != CCA_CARRIER_SENSE_WITH_ED)) { return RADIO_INVALID_ARGUMENT; } if (hal_get_slptr()) { return RADIO_WRONG_STATE; } /*Change cca mode and ed threshold.*/ hal_subregister_write(SR_CCA_MODE, mode); hal_subregister_write(SR_CCA_ED_THRES, ed_thresh); return RADIO_SUCCESS; }
/*---------------------------------------------------------------------------*/ void rf230_set_channel(int c) { /* Wait for any transmission to end. */ nrf24l01_waitidle(); //channel=c; hal_subregister_write(SR_CHANNEL, c); }
U8 drvr_set_tx_pwr(U8 pwr_level) { if (hal_get_slptr()) { return RADIO_WRONG_STATE; } hal_subregister_write(SR_TX_PWR, pwr_level & 0xf); return RADIO_SUCCESS; }
void drvr_init() { U8 part_num, ver_num, irq; U16 man_id = 0; memset(&dcb, 0, sizeof(at86_dcb_t)); delay_us(TIME_TO_ENTER_P_ON); hal_init(); // reset all regs in at86rf drvr_at86_reset(); part_num = hal_register_read(AT86_PART_NUM); ver_num = hal_register_read(AT86_VERSION_NUM); man_id |= hal_register_read(AT86_MAN_ID_1) << 8; man_id |= hal_register_read(AT86_MAN_ID_0); hal_register_write(AT86_IRQ_MASK, 0); irq = hal_register_read(AT86_IRQ_STATUS); // force transceiver off while we configure the intps hal_subregister_write(SR_TRX_CMD, CMD_FORCE_TRX_OFF); delay_us(TIME_P_ON_TO_TRX_OFF); // wait for transceiver to transition to the off state while (drvr_get_trx_state() != TRX_OFF); hal_register_write(AT86_IRQ_MASK, (1<<IRQ_MASK_TRX_END) | (1<<IRQ_MASK_RX_START)); // configure the CSMA parameters drvr_config_csma(drvr_get_rand() & 0xf, drvr_get_rand() & 0xf, aMinBE, aMacMaxFrameRetries, aMaxCsmaBackoffs); // set the default channel drvr_set_channel(11); // set autocrc mode drvr_set_auto_crc(true); // start the contiki driver process and register the event number process_start(&drvr_process, NULL); event_drvr_conf = process_alloc_event(); // put trx in rx auto ack mode drvr_set_trx_state(RX_AACK_ON); while (drvr_get_trx_state() != RX_AACK_ON); }
U8 drvr_set_channel(U8 channel) { U8 state; hal_subregister_write(SR_CHANNEL, channel); // add a delay to allow the PLL to lock if in active mode. state = drvr_get_trx_state(); if ((state == RX_ON) || (state == PLL_ON)) { delay_us(TIME_PLL_LOCK); } if (drvr_get_channel() == channel) { return (U8)RADIO_SUCCESS; } return (U8)RADIO_TIMED_OUT; }
void drvr_set_frm_pend(bool pend) { hal_subregister_write(SR_AACK_SET_PD, pend); }
void drvr_set_coord(bool coord) { hal_subregister_write(SR_I_AM_COORD, coord); }
void drvr_set_auto_crc(bool auto_crc_on) { hal_subregister_write(SR_TX_AUTO_CRC_ON, auto_crc_on); }
radio_status_t radio_set_trx_state(uint8_t new_state) { uint8_t original_state; /*Check function paramter and current state of the radio transceiver.*/ if (!((new_state == TRX_OFF) || (new_state == RX_ON) || (new_state == PLL_ON) || (new_state == RX_AACK_ON) || (new_state == TX_ARET_ON))){ return RADIO_INVALID_ARGUMENT; } if (radio_is_sleeping() == true){ return RADIO_WRONG_STATE; } // Wait for radio to finish previous operation for(;;) { original_state = radio_get_trx_state(); if (original_state != BUSY_TX_ARET && original_state != BUSY_RX_AACK && original_state != BUSY_RX && original_state != BUSY_TX) break; } if (new_state == original_state){ return RADIO_SUCCESS; } /* At this point it is clear that the requested new_state is: */ /* TRX_OFF, RX_ON, PLL_ON, RX_AACK_ON or TX_ARET_ON. */ /* The radio transceiver can be in one of the following states: */ /* TRX_OFF, RX_ON, PLL_ON, RX_AACK_ON, TX_ARET_ON. */ if(new_state == TRX_OFF){ radio_reset_state_machine(); /* Go to TRX_OFF from any state. */ } else { /* It is not allowed to go from RX_AACK_ON or TX_AACK_ON and directly to */ /* TX_AACK_ON or RX_AACK_ON respectively. Need to go via RX_ON or PLL_ON. */ if ((new_state == TX_ARET_ON) && (original_state == RX_AACK_ON)){ /* First do intermediate state transition to PLL_ON, then to TX_ARET_ON. */ /* The final state transition to TX_ARET_ON is handled after the if-else if. */ hal_subregister_write(SR_TRX_CMD, PLL_ON); delay_us(TIME_STATE_TRANSITION_PLL_ACTIVE); } else if ((new_state == RX_AACK_ON) && (original_state == TX_ARET_ON)){ /* First do intermediate state transition to RX_ON, then to RX_AACK_ON. */ /* The final state transition to RX_AACK_ON is handled after the if-else if. */ hal_subregister_write(SR_TRX_CMD, RX_ON); delay_us(TIME_STATE_TRANSITION_PLL_ACTIVE); } /* Any other state transition can be done directly. */ hal_subregister_write(SR_TRX_CMD, new_state); /* When the PLL is active most states can be reached in 1us. However, from */ /* TRX_OFF the PLL needs time to activate. */ if (original_state == TRX_OFF){ delay_us(TIME_TRX_OFF_TO_PLL_ACTIVE); } else { delay_us(TIME_STATE_TRANSITION_PLL_ACTIVE); } } /* end: if(new_state == TRX_OFF) ... */ /*Verify state transition.*/ radio_status_t set_state_status = RADIO_TIMED_OUT; if (radio_get_trx_state() == new_state){ set_state_status = RADIO_SUCCESS; /* set rx_mode flag based on mode we're changing to */ if (new_state == RX_ON || new_state == RX_AACK_ON){ rx_mode = true; } else { rx_mode = false; } } return set_state_status; }