📄 radio.c
字号:
return pll_calibration_status;}/*----------------------------------------------------------------------------*//** \brief This function return the Radio Transceivers current state. * * \retval P_ON When the external supply voltage (VDD) is * first supplied to the transceiver IC, the * system is in the P_ON (Poweron) mode. * \retval BUSY_RX The radio transceiver is busy receiving a * frame. * \retval BUSY_TX The radio transceiver is busy transmitting a * frame. * \retval RX_ON The RX_ON mode enables the analog and digital * receiver blocks and the PLL frequency * synthesizer. * \retval TRX_OFF In this mode, the SPI module and crystal * oscillator are active. * \retval PLL_ON Entering the PLL_ON mode from TRX_OFF will * first enable the analog voltage regulator. The * transceiver is ready to transmit a frame. * \retval BUSY_RX_AACK The radio was in RX_AACK_ON mode and received * the Start of Frame Delimiter (SFD). State * transition to BUSY_RX_AACK is done if the SFD * is valid. * \retval BUSY_TX_ARET The radio transceiver is busy handling the * auto retry mechanism. * \retval RX_AACK_ON The auto acknowledge mode of the radio is * enabled and it is waiting for an incomming * frame. * \retval TX_ARET_ON The auto retry mechanism is enabled and the * radio transceiver is waiting for the user to * send the TX_START command. * \retval RX_ON_NOCLK The radio transceiver is listening for * incomming frames, but the CLKM is disabled so * that the controller could be sleeping. * However, this is only true if the controller * is run from the clock output of the radio. * \retval RX_AACK_ON_NOCLK Same as the RX_ON_NOCLK state, but with the * auto acknowledge module turned on. * \retval BUSY_RX_AACK_NOCLK Same as BUSY_RX_AACK, but the controller * could be sleeping since the CLKM pin is * disabled. * \retval STATE_TRANSITION The radio transceiver's state machine is in * transition between two states. */uint8_tradio_get_trx_state(void){ return hal_subregister_read(SR_TRX_STATUS);}/*----------------------------------------------------------------------------*//** \brief This function checks if the radio transceiver is sleeping. * * \retval true The radio transceiver is in SLEEP or one of the *_NOCLK * states. * \retval false The radio transceiver is not sleeping. */bool radio_is_sleeping(void){ bool sleeping = false; /* The radio transceiver will be at SLEEP or one of the *_NOCLK states only if */ /* the SLP_TR pin is high. */ if (hal_get_slptr() != 0){ sleeping = true; } return sleeping;}/*----------------------------------------------------------------------------*//** \brief This function will change the current state of the radio * transceiver's internal state machine. * * \param new_state Here is a list of possible states: * - RX_ON Requested transition to RX_ON state. * - TRX_OFF Requested transition to TRX_OFF state. * - PLL_ON Requested transition to PLL_ON state. * - RX_AACK_ON Requested transition to RX_AACK_ON state. * - TX_ARET_ON Requested transition to TX_ARET_ON state. * * \retval RADIO_SUCCESS Requested state transition completed * successfully. * \retval RADIO_INVALID_ARGUMENT Supplied function parameter out of bounds. * \retval RADIO_WRONG_STATE Illegal state to do transition from. * \retval RADIO_BUSY_STATE The radio transceiver is busy. * \retval RADIO_TIMED_OUT The state transition could not be completed * within resonable time. */radio_status_tradio_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;}/*----------------------------------------------------------------------------*//** \brief This function will put the radio transceiver to sleep. * * \retval RADIO_SUCCESS Sleep mode entered successfully. * \retval RADIO_TIMED_OUT The transition to TRX_OFF took too long. */radio_status_tradio_enter_sleep_mode(void){ if (radio_is_sleeping() == true){ return RADIO_SUCCESS; } radio_reset_state_machine(); /* Force the device into TRX_OFF. */ radio_status_t enter_sleep_status = RADIO_TIMED_OUT; if (radio_get_trx_state() == TRX_OFF){ /* Enter Sleep. */ hal_set_slptr_high(); enter_sleep_status = RADIO_SUCCESS; } return enter_sleep_status;}/*----------------------------------------------------------------------------*//** \brief This function will take the radio transceiver from sleep mode and * put it into the TRX_OFF state. * * \retval RADIO_SUCCESS Left sleep mode and entered TRX_OFF state. * \retval RADIO_TIMED_OUT Transition to TRX_OFF state timed out. */radio_status_tradio_leave_sleep_mode(void){ /* Check if the radio transceiver is actually sleeping. */ if (radio_is_sleeping() == false){ return RADIO_SUCCESS; } hal_set_slptr_low(); delay_us(TIME_SLEEP_TO_TRX_OFF); radio_status_t leave_sleep_status = RADIO_TIMED_OUT; /* Ensure that the radio transceiver is in the TRX_OFF state. */ if (radio_get_trx_state() == TRX_OFF){ leave_sleep_status = RADIO_SUCCESS; } return leave_sleep_status;}/*----------------------------------------------------------------------------*//** \brief This function will reset the state machine (to TRX_OFF) from any of * its states, except for the SLEEP state. */voidradio_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);}/*----------------------------------------------------------------------------*//** \brief This function will reset all the registers and the state machine of * the radio transceiver. */voidradio_reset_trx(void){ hal_set_rst_low(); hal_set_slptr_low(); delay_us(TIME_RESET); hal_set_rst_high();}/*----------------------------------------------------------------------------*//** \brief This function will enable or disable automatic CRC during frame * transmission. * * \param auto_crc_on If this parameter equals true auto CRC will be used for * all frames to be transmitted. The framelength must be * increased by two bytes (16 bit CRC). If the parameter equals * false, the automatic CRC will be disabled. */voidradio_use_auto_tx_crc(bool auto_crc_on){ if (auto_crc_on == true){ hal_subregister_write(SR_TX_AUTO_CRC_ON, 1); } else { hal_subregister_write(SR_TX_AUTO_CRC_ON, 0); }}/*----------------------------------------------------------------------------*//** \brief This function will download a frame to the radio transceiver's * transmit buffer and send it. * * \param data_length Length of the frame to be transmitted. 1 to 128 bytes are the valid lengths. * \param *data Pointer to the data to transmit * * \retval RADIO_SUCCESS Frame downloaded and sent successfully. * \retval RADIO_INVALID_ARGUMENT If the dataLength is 0 byte or more than 127 * bytes the frame will not be sent. * \retval RADIO_WRONG_STATE It is only possible to use this function in the * PLL_ON and TX_ARET_ON state. If any other state is * detected this error message will be returned. */radio_status_tradio_send_data(uint8_t data_length, uint8_t *data){ /*Check function parameters and current state.*/ if (data_length > RF230_MAX_TX_FRAME_LENGTH){ return RADIO_INVALID_ARGUMENT; } /* If we are busy, return */ if ((radio_get_trx_state() == BUSY_TX) || (radio_get_trx_state() == BUSY_TX_ARET) ) { return RADIO_WRONG_STATE; } radio_set_trx_state(TRX_OFF); radio_set_trx_state(TX_ARET_ON); /*Do frame transmission.*/ /* Toggle the SLP_TR pin to initiate the frame transmission. */ hal_set_slptr_high(); hal_set_slptr_low(); hal_frame_write(data, data_length); /* Then write data to the frame buffer. */ return RADIO_SUCCESS;}/*----------------------------------------------------------------------------*//** \brief This function will read the I_AM_COORD sub register. * * \retval 0 Not coordinator. * \retval 1 Coordinator role enabled. */uint8_tradio_get_device_role(void){ return hal_subregister_read(SR_I_AM_COORD);}/*----------------------------------------------------------------------------*//** \brief This function will set the I_AM_COORD sub register. * * \param[in] i_am_coordinator If this parameter is true, the associated * coordinator role will be enabled in the radio * transceiver's address filter. * False disables the same feature. */voidradio_set_device_role(bool i_am_coordinator){ if (i_am_coordinator == true){ hal_subregister_write(SR_I_AM_COORD, 0); } else { hal_subregister_write(SR_I_AM_COORD, 0); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -