6LowPAN mesh-based network support for mbedConnectorInterface. The Atmel-based mbed 6LowPAN shield is the assumed network hardware.
Dependencies: libnsdl Nanostack_lib
Diff: mesh_nework/AtmelRFDriverLib/driverRFPhy.c
- Revision:
- 0:2a5a48a8b4d4
- Child:
- 6:f6288e89b02a
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mesh_nework/AtmelRFDriverLib/driverRFPhy.c Sun Feb 01 18:26:13 2015 +0000 @@ -0,0 +1,1235 @@ +/* + * driverRFPhy.c + * + * Created on: 14 July 2014 + * Author: mBed team + */ +#include "arm_hal_interrupt.h" +#include "arm_hal_phy.h" +#include "driverRFPhy.h" +#include "driverAtmelRFInterface.h" +#include <string.h> + +#include <stdio.h> + +#include "configuration.h" + +/*RF receive buffer*/ +static uint8_t rf_buffer[RF_BUFFER_SIZE]; +/*RF ACK receive buffer*/ +static uint8_t ack_rx_buf[5]; +/*ACK wait duration changes depending on data rate*/ +static uint16_t rf_ack_wait_duration = RF_ACK_WAIT_TIMEOUT; + +static uint8_t radio_tx_power = 0x07; +static uint8_t rf_channel; +static uint8_t rf_tuned = 1; +static uint8_t radio_rpc_value = 0xef; +static uint8_t rf_use_front_end = 0; +static uint8_t rf_use_antenna_diversity = 0; +static uint8_t rf_csd_port = 0; +static uint8_t rf_csd_pin = 0; +static uint8_t rf_cps_port = 0; +static uint8_t rf_cps_pin = 0; +static uint8_t tx_sequence = 0xff; +static uint8_t need_ack = 0; +static uint8_t rf_rx_mode = 0; +static uint8_t rf_flags = 0; +static uint8_t rf_rnd_rssi = 0; +static int8_t rf_radio_driver_id = -1; +static phy_device_driver_s device_driver; +static uint8_t atmel_MAC[8]; +static phy_device_channel_info_s channel_info; +static uint8_t mac_tx_handle = 0; + +/* + * \brief Function sets given RF flag on. + * + * \param x Given RF flag + * + * \return none + */ +void rf_flags_set(uint8_t x) +{ + rf_flags |= x; +} + +/* + * \brief Function clears given RF flag on. + * + * \param x Given RF flag + * + * \return none + */ +void rf_flags_clear(uint8_t x) +{ + rf_flags &= ~x; +} + +/* + * \brief Function checks if given RF flag is on. + * + * \param x Given RF flag + * + * \return states of the given flags + */ +uint8_t rf_flags_check(uint8_t x) +{ + return (rf_flags & x); +} + +/* + * \brief Function clears all RF flags. + * + * \param none + * + * \return none + */ +void rf_flags_reset(void) +{ + rf_flags = 0; +} + +/* + * \brief Function sets CPS and CSD pins of the Front end. + * + * \param none + * + * \return none + */ +void rf_front_end_rx_lna(void) +{ + /* not supported in this version */ +} + +/* + * \brief Function clears CPS and CSD pins of the Front end. + * + * \param none + * + * \return none + */ +void rf_front_end_sleep(void) +{ + /* not supported in this version */ +} + +/* + * \brief Function initialises and registers the RF driver. + * + * \param none + * + * \return rf_radio_driver_id Driver ID given by NET library + */ +int8_t rf_device_register(void) +{ + rf_init(); + /*Set pointer to MAC address*/ + device_driver.PHY_MAC = atmel_MAC; + device_driver.driver_description = "ATMEL_MAC"; +#if PHY_LINK_15_4_2_4GHZ_TYPE + /*Number of channels in PHY*/ + channel_info.channel_count = 16; + /*Channel mask 26-11*/ + channel_info.channel_mask = 0x07FFF800; + /*Type of RF PHY is SubGHz*/ + device_driver.link_type = PHY_LINK_15_4_2_4GHZ_TYPE; + device_driver.link_channel_info = &channel_info; +#else + /*Number of channels in PHY*/ + channel_info.channel_count = 11; + /*Channel mask 0-10*/ + channel_info.channel_mask = 0x000007ff; + /*Type of RF PHY is SubGHz*/ + device_driver.link_type = PHY_LINK_15_4_SUBGHZ_TYPE; + device_driver.link_channel_info = &channel_info; +#endif + /*Maximum size of payload is 127*/ + device_driver.phy_MTU = 127; + /*No header in PHY*/ + device_driver.phy_header_length = 0; + /*No tail in PHY*/ + device_driver.phy_tail_length = 0; + /*Set address write function*/ + device_driver.phy_xx_address_write = &rf_address_write; + /*Set RF extension function*/ + device_driver.phy_xx_extension = &rf_extension; + /*Set RF state control function*/ + device_driver.phy_xx_state_control = &rf_interface_state_control; + /*Set transmit function*/ + device_driver.phy_xx_tx = &rf_start_cca; + printf("RF Device Registration..."); + /*Register device driver*/ + rf_radio_driver_id = arm_net_phy_register(&device_driver); + printf("OK\r\n"); + return rf_radio_driver_id; +} + +/* + * \brief Function returns the generated 8-bit random value for seeding Pseudo-random generator. This value was generated by reading noise from RF channel in RF initialisation. + * + * \param none + * + * \return random RSSI value + */ +int8_t rf_read_random(void) +{ + return rf_rnd_rssi; +} + +/* + * \brief Function is a call back for ACK wait timeout. + * + * \param none + * + * \return none + */ +void rf_ack_wait_timer_interrupt(void) +{ + arm_enter_critical(); + /*Force PLL state*/ + rf_if_change_trx_state(FORCE_PLL_ON); + rf_poll_trx_state_change(PLL_ON); + /*Start receiver in RX_AACK_ON state*/ + rf_rx_mode = 0; + rf_flags_clear(RFF_RX); + rf_receive(); + arm_exit_critical(); +} + +/* + * \brief Function is a call back for calibration interval timer. + * + * \param none + * + * \return none + */ +void rf_calibration_timer_interrupt(void) +{ + /*Calibrate RF*/ + rf_calibration_cb(); + /*Start new calibration timeout*/ + rf_calibration_timer_start(RF_CALIBRATION_INTERVAL); +} + +/* + * \brief Function initialises the RF timer for ACK wait and calibration. + * + * \param none + * + * \return none + */ +void rf_timer_init(void) +{ + rf_if_timer_init(); +} + +/* + * \brief Function starts the ACK wait timeout. + * + * \param slots Given slots, resolution 50us + * + * \return none + */ +void rf_ack_wait_timer_start(uint16_t slots) +{ + rf_if_ack_wait_timer_start(slots); +} + +/* + * \brief Function starts the calibration interval. + * + * \param slots Given slots, resolution 50us + * + * \return none + */ +void rf_calibration_timer_start(uint32_t slots) +{ + rf_if_calibration_timer_start(slots); +} + +/* + * \brief Function stops the ACK wait timeout. + * + * \param none + * + * \return none + */ +void rf_ack_wait_timer_stop(void) +{ + rf_if_ack_wait_timer_stop(); +} + +/* + * \brief Function reads the MAC address array. + * + * \param ptr Pointer to read array + * + * \return none + */ +void rf_read_mac_address(uint8_t *ptr) +{ + memcpy(ptr, atmel_MAC, 8); +} + +/* + * \brief Function sets the MAC address array. + * + * \param ptr Pointer to given MAC address array + * + * \return none + */ +void rf_set_mac_address(const uint8_t *ptr) +{ + memcpy(atmel_MAC,ptr,8); +} + +/* + * \brief Function writes various RF settings in startup. + * + * \param none + * + * \return none + */ +void rf_write_settings(void) +{ + arm_enter_critical(); + + //printf("RF Write Settings: 1\r\n"); + rf_if_write_rf_settings(); + + //printf("RF Write Settings: 2\r\n"); + /*Set output power*/ + rf_if_write_set_tx_power_register(radio_tx_power); + + //printf("RF Write Settings: 3\r\n"); + /*Set RPC register*/ + rf_if_write_set_trx_rpc_register(radio_rpc_value); + + //printf("RF Write Settings: 4\r\n"); + /*Initialise Front end*/ + if(rf_use_front_end) + { + printf("RF Front End used\r\n"); + rf_if_enable_pa_ext(); + /* not supported in this version */ + } + + //printf("RF Write Settings: 5\r\n"); + /*Initialise Antenna Diversity*/ + if(rf_use_antenna_diversity) { + printf("RF Antenna diversity\r\n"); + rf_if_write_antenna_diversity_settings(); + } + + printf("RF Write Settings: 7\r\n"); + arm_exit_critical(); + printf("RF Write Settings End\r\n"); +} + +/* + * \brief Function writes 16-bit address in RF address filter. + * + * \param short_address Given short address + * + * \return none + */ +void rf_set_short_adr(uint8_t * short_address) +{ + uint8_t rf_off_flag = 0; + arm_enter_critical(); + /*Wake up RF if sleeping*/ + if(rf_if_read_trx_state() == 0x00 || rf_if_read_trx_state() == 0x1F) + { + rf_if_disable_slptr(); + rf_off_flag = 1; + rf_poll_trx_state_change(TRX_OFF); + } + /*Write address filter registers*/ + rf_if_write_short_addr_registers(short_address); + /*RF back to sleep*/ + if(rf_off_flag) + rf_if_enable_slptr(); + arm_exit_critical(); +} + +/* + * \brief Function writes PAN Id in RF PAN Id filter. + * + * \param pan_id Given PAN Id + * + * \return none + */ +void rf_set_pan_id(uint8_t *pan_id) +{ + uint8_t rf_off_flag = 0; + + arm_enter_critical(); + /*Wake up RF if sleeping*/ + if(rf_if_read_trx_state() == 0x00 || rf_if_read_trx_state() == 0x1F) + { + rf_if_disable_slptr(); + rf_off_flag = 1; + rf_poll_trx_state_change(TRX_OFF); + } + /*Write address filter registers*/ + rf_if_write_pan_id_registers(pan_id); + /*RF back to sleep*/ + if(rf_off_flag) + rf_if_enable_slptr(); + arm_exit_critical(); +} + +/* + * \brief Function writes 64-bit address in RF address filter. + * + * \param address Given 64-bit address + * + * \return none + */ +void rf_set_address(uint8_t *address) +{ + uint8_t rf_off_flag = 0; + + arm_enter_critical(); + /*Wake up RF if sleeping*/ + if(rf_if_read_trx_state() == 0x00 || rf_if_read_trx_state() == 0x1F) + { + rf_if_disable_slptr(); + rf_off_flag = 1; + rf_poll_trx_state_change(TRX_OFF); + } + /*Write address filter registers*/ + rf_if_write_ieee_addr_registers(address); + /*RF back to sleep*/ + if(rf_off_flag) + rf_if_enable_slptr(); + + arm_exit_critical(); +} + +/* + * \brief Function sets the RF channel. + * + * \param ch New channel + * + * \return none + */ +void rf_channel_set(uint8_t ch) +{ + arm_enter_critical(); + rf_channel = ch; + if(ch < 0x1f) + rf_if_set_channel_register(ch); + arm_exit_critical(); +} + + +/* + * \brief Function initialises the radio driver and resets the radio. + * + * \param none + * + * \return none + */ +void rf_init(void) +{ + printf("RF Init Start\r\n"); + /*Initialise timers*/ + rf_timer_init(); //TODO + rf_channel = RF_DEFAULT_CHANNEL; + printf("RF Reset\r\n"); + /*Reset RF module*/ + rf_if_reset_radio(); + printf("RF Write Settings\r\n"); + /*Write RF settings*/ + rf_write_settings(); + printf("RF Init PHY Mode\r\n"); + /*Initialise PHY mode*/ + rf_init_phy_mode(); + /*Clear RF flags*/ + rf_flags_reset(); + /*Set RF in TRX OFF state*/ + rf_if_change_trx_state(TRX_OFF); + /*Set RF in PLL_ON state*/ + rf_if_change_trx_state(PLL_ON); + /*Start receiver*/ + rf_receive(); + /*Read random variable. This will be used when seeding pseudo-random generator*/ + rf_rnd_rssi = rf_if_read_rnd(); + /*Start RF calibration timer*/ + rf_calibration_timer_start(RF_CALIBRATION_INTERVAL); //ACA! + printf("RF Init End\r\n"); +} + +/** + * \brief Function gets called when MAC is setting radio off. + * + * \param none + * + * \return none + */ +void rf_off(void) +{ + if(rf_flags_check(RFF_ON)) + { + rf_cca_abort(); + uint16_t while_counter = 0; + /*Wait while receiving*/ + while(rf_if_read_trx_state() == BUSY_RX_AACK || rf_if_read_trx_state() == BUSY_RX) + { + while_counter++; + if(while_counter == 0xffff) + break; + } + /*RF state change: RX_AACK_ON->PLL_ON->TRX_OFF->SLEEP*/ + if(rf_if_read_trx_state() == RX_AACK_ON) + { + rf_if_change_trx_state(PLL_ON); + } + rf_if_change_trx_state(TRX_OFF); + rf_if_enable_slptr(); + rf_flags_clear(~RFF_ON); + /*Front end in sleep*/ + if(rf_use_front_end) + { + rf_if_disable_pa_ext(); + rf_front_end_sleep(); + } + /*Disable Antenna Diversity*/ + if(rf_use_antenna_diversity) + rf_if_disable_ant_div(); + } +} + +/* + * \brief Function polls the RF state until it has changed to desired state. + * + * \param trx_state RF state + * + * \return none + */ +void rf_poll_trx_state_change(rf_trx_states_t trx_state) +{ + uint16_t while_counter = 0; + arm_enter_critical(); + + if(trx_state != RF_TX_START) + { + if(trx_state == FORCE_PLL_ON) + trx_state = PLL_ON; + else if(trx_state == FORCE_TRX_OFF) + trx_state = TRX_OFF; + + while(rf_if_read_trx_state() != trx_state) + { + while_counter++; + if(while_counter == 0x1ff) + break; + } + } + arm_exit_critical(); +} + +/* + * \brief Function starts the CCA process before starting data transmission and copies the data to RF TX FIFO. + * + * \param data_ptr Pointer to TX data + * \param data_length Length of the TX data + * \param tx_handle Handle to transmission + * \return 0 Success + * \return -1 Busy + */ +int8_t rf_start_cca(uint8_t *data_ptr, uint16_t data_length, uint8_t tx_handle) +{ + /*Check if transmitter is busy*/ + if((rf_if_read_trx_state() == BUSY_RX_AACK) || (rf_if_read_trx_state() == BUSY_RX)) + { + /*Return busy*/ + return -1; + } + else + { + arm_enter_critical(); + /*Check if transmitted data needs to be acked*/ + if(*data_ptr & 0x20) + need_ack = 1; + else + need_ack = 0; + /*Store the sequence number for ACK handling*/ + tx_sequence = *(data_ptr + 2); + /*Set radio in RX state to read channel*/ + rf_receive(); + /*Write TX FIFO*/ + rf_if_write_frame_buffer(data_ptr, (uint8_t)data_length); + rf_flags_set(RFF_CCA); + /*Start CCA process*/ + rf_if_enable_cca_ed_done_interrupt(); + rf_if_start_cca_process(); + /*Store TX handle*/ + mac_tx_handle = tx_handle; + arm_exit_critical(); + } + + /*Return success*/ + return 0; +} + +/* + * \brief Function aborts CCA process. + * + * \param none + * + * \return none + */ +void rf_cca_abort(void) +{ + /*Clear RFF_CCA RF flag*/ + rf_flags_clear(RFF_CCA); +} + + + +/* + * \brief Function starts the transmission of the frame. + * + * \param none + * + * \return none + */ +void rf_start_tx(void) +{ + /*Only start transmitting from RX state*/ + uint8_t trx_state = rf_if_read_trx_state(); + if((trx_state != RX_AACK_ON) && (trx_state != RX_ON)) + { + arm_net_phy_tx_done(rf_radio_driver_id, mac_tx_handle, PHY_LINK_CCA_FAIL, 1, 1); + } + else + { + /*RF state change: ->PLL_ON->RF_TX_START*/ + rf_if_change_trx_state(FORCE_PLL_ON); + rf_flags_clear(RFF_RX); + rf_if_enable_tx_end_interrupt(); + rf_flags_set(RFF_TX); + rf_if_change_trx_state(RF_TX_START); + } +} + +/* + * \brief Function sets the RF in RX state. + * + * \param none + * + * \return none + */ +void rf_receive(void) +{ + uint16_t while_counter = 0; + if(rf_flags_check(RFF_ON) == 0) + { + rf_on(); + } + /*If not yet in RX state set it*/ + if(rf_flags_check(RFF_RX) == 0) + { + arm_enter_critical(); + /*Wait while receiving data*/ + while((rf_if_read_trx_state() == BUSY_RX) || (rf_if_read_trx_state() == BUSY_RX_AACK)) + { + while_counter++; + if(while_counter == 0xffff) + { + break; + } + } + /*Wake up from sleep state*/ + if(rf_if_read_trx_state() == 0x00 || rf_if_read_trx_state() == 0x1f) + { + rf_if_disable_slptr(); + rf_poll_trx_state_change(TRX_OFF); + } + + rf_if_change_trx_state(PLL_ON); + /*ACK is always received in RX_ON state to bypass address filters*/ + if(rf_rx_mode) + { + rf_rx_mode = 0; + rf_if_change_trx_state(RX_ON); + } + else + { + rf_if_change_trx_state(RX_AACK_ON); + /*If calibration timer was unable to calibrate the RF, run calibration now*/ + if(!rf_tuned) + { + /*Start calibration. This can be done in states TRX_OFF, PLL_ON or in any receive state*/ + rf_if_calibration(); + /*RF is tuned now*/ + rf_tuned = 1; + } + } + rf_channel_set(rf_channel); + rf_flags_set(RFF_RX); + rf_if_enable_rx_end_interrupt(); + /*Enable LNA if Front end used*/ + if(rf_use_front_end) + rf_front_end_rx_lna(); + arm_exit_critical(); + } + /*Stop the running CCA process*/ + if(rf_flags_check(RFF_CCA)) + rf_cca_abort(); +} + +/* + * \brief Function calibrates the radio. + * + * \param none + * + * \return none + */ +void rf_calibration_cb(void) +{ + /*clear tuned flag to start tuning in rf_receive*/ + rf_tuned = 0; + /*If RF is in default receive state, start calibration*/ + if(rf_if_read_trx_state() == RX_AACK_ON) + { + arm_enter_critical(); + /*Set RF in PLL_ON state*/ + rf_if_change_trx_state(PLL_ON); + /*Set RF in TRX_OFF state to start PLL tuning*/ + rf_if_change_trx_state(TRX_OFF); + /*Set RF in RX_ON state to calibrate*/ + rf_if_change_trx_state(RX_ON); + /*Calibrate FTN*/ + rf_if_calibration(); + /*RF is tuned now*/ + rf_tuned = 1; + /*Back to default receive state*/ + rf_flags_clear(RFF_RX); + rf_receive(); + arm_exit_critical(); + } +} + +/* + * \brief Function sets RF_ON flag when radio is powered. + * + * \param none + * + * \return none + */ +void rf_on(void) +{ + /*Set RFF_ON flag*/ + if(rf_flags_check(RFF_ON) == 0) + { + rf_flags_set(RFF_ON); + /*Wake up Front end*/ + if(rf_use_front_end) + { + /*Set PA_EXT_EN to enable controlling of external front end*/ + rf_if_enable_pa_ext(); + rf_front_end_rx_lna(); + } + /*Enable Antenna diversity*/ + if(rf_use_antenna_diversity) + /*Set ANT_EXT_SW_EN to enable controlling of antenna diversity*/ + rf_if_enable_ant_div(); + } +} + +/* + * \brief Function handles the received ACK frame. + * + * \param seq_number Sequence number of received ACK + * \param data_pending Pending bit state in received ACK + * + * \return none + */ +void rf_handle_ack(uint8_t seq_number, uint8_t data_pending) +{ + phy_link_tx_status_e phy_status; + arm_enter_critical(); + /*Received ACK sequence must be equal with transmitted packet sequence*/ + if(tx_sequence == seq_number) + { + rf_ack_wait_timer_stop(); + /*When data pending bit in ACK frame is set, inform NET library*/ + if(data_pending) + phy_status = PHY_LINK_TX_DONE_PENDING; + else + phy_status = PHY_LINK_TX_DONE; + /*Call PHY TX Done API*/ + arm_net_phy_tx_done(rf_radio_driver_id, mac_tx_handle,phy_status, 1, 1); + } + arm_exit_critical(); +} + +/* + * \brief Function is a call back for RX end interrupt. + * + * \param none + * + * \return none + */ +void rf_handle_rx_end(void) +{ + uint8_t rf_lqi; + + /*Frame received interrupt*/ + if(rf_flags_check(RFF_RX)) + { + /*Check CRC_valid bit*/ + if(rf_if_check_crc()) + { + uint8_t *rf_rx_ptr; + uint8_t receiving_ack = 0; + /*Read length*/ + uint8_t len = rf_if_read_received_frame_length(); + /*Not ACK frame*/ + if(len > 5) + { + rf_rx_ptr = rf_buffer; + } + /*ACK received*/ + else + { + /*Read ACK in static ACK buffer*/ + receiving_ack = 1; + rf_rx_ptr = ack_rx_buf; + } + /*Check the length is valid*/ + if(len > 1 && len < RF_BUFFER_SIZE) + { + /*Read received packet*/ + rf_if_read_packet(rf_rx_ptr, len); + /*Get LQI*/ + rf_lqi = rf_if_read_lqi(); + /*Handle received ACK*/ + if(receiving_ack && ((ack_rx_buf[0] & 0x07) == 0x02)) + { + uint8_t pending = 0; + /*Check if data is pending*/ + if ((ack_rx_buf[0] & 0x10)) + { + pending=1; + } + /*Send sequence number in ACK handler*/ + rf_handle_ack(ack_rx_buf[2], pending); + } + /*Handle received data*/ + else if(rf_if_read_trx_state() != RX_ON && rf_if_read_trx_state() != BUSY_RX) + { + arm_net_phy_rx(rf_buffer,len - 2, rf_lqi, rf_radio_driver_id); + } + } + } + } + /*Start receiver*/ + rf_flags_clear(RFF_RX); + rf_receive(); +} + +/* + * \brief Function is called when MAC is shutting down the radio. + * + * \param none + * + * \return none + */ +void rf_shutdown(void) +{ + /*Call RF OFF*/ + rf_off(); + /*Clear RF flags*/ + rf_flags_reset(); +} + +/* + * \brief Function is a call back for TX end interrupt. + * + * \param none + * + * \return none + */ +void rf_handle_tx_end(void) +{ + phy_link_tx_status_e phy_status = PHY_LINK_TX_SUCCESS; + + rf_rx_mode = 0; + /*If ACK is needed for this transmission*/ + if(need_ack && rf_flags_check(RFF_TX)) + { + rf_ack_wait_timer_start(rf_ack_wait_duration); + rf_rx_mode = 1; + } + rf_flags_clear(RFF_RX); + /*Start receiver*/ + rf_receive(); + + /*Call PHY TX Done API*/ + arm_net_phy_tx_done(rf_radio_driver_id, mac_tx_handle, phy_status, 1, 1); +} + +/* + * \brief Function is a call back for CCA ED done interrupt. + * + * \param none + * + * \return none + */ +void rf_handle_cca_ed_done(void) +{ + rf_flags_clear(RFF_CCA); + /*Check the result of CCA process*/ + if(rf_if_check_cca()) + { + rf_start_tx(); + } + else + { + /*Send CCA fail notification*/ + arm_net_phy_tx_done(rf_radio_driver_id, mac_tx_handle, PHY_LINK_CCA_FAIL, 1, 1); + } +} + +/* + * \brief Function sets the TX power variable. + * + * \param power TX power setting + * + * \return 0 Success + * \return -1 Fail + */ +int8_t rf_tx_power_set(uint8_t power) +{ + int8_t ret_val = -1; + if(power < 16) + { + radio_tx_power = power; + ret_val = 0; + } + return ret_val; +} + +/* + * \brief Function returns the TX power variable. + * + * \param none + * + * \return radio_tx_power TX power variable + */ +uint8_t rf_tx_power_get(void) +{ + return radio_tx_power; +} + +/* + * \brief Function sets the RF RPC variable. + * + * \param rpc_value RPC setting + * + * \return 0 Success + */ +int8_t rf_rpc_set(uint8_t rpc_value) +{ + int8_t ret_val = -1; + radio_rpc_value = rpc_value; + ret_val = 0; + return ret_val; +} + +/* + * \brief Function enables the usage of Front end. + * + * \param none + * + * \return 0 Success + */ +int8_t rf_enable_pa(void) +{ + int8_t ret_val = 0; + rf_use_front_end = 1; + return ret_val; +} + +/* + * \brief Function enables the usage of Antenna diversity. + * + * \param none + * + * \return 0 Success + */ +int8_t rf_enable_antenna_diversity(void) +{ + int8_t ret_val = 0; + rf_use_antenna_diversity = 1; + return ret_val; +} + +/* + * \brief Function defines the CSD pin of the Front end. + * + * \param port CSD port + * \param port CSD pin + * + * \return 0 Success + */ +int8_t rf_set_csd_pin(uint8_t port, uint8_t pin) +{ + int8_t ret_val = -1; + + rf_csd_port = port; + rf_csd_pin = pin; + ret_val = 0; + + return ret_val; +} + +/* + * \brief Function defines the CPS pin of the Front end. + * + * \param port CPS port + * \param port CPS pin + * + * \return 0 Success + */ +int8_t rf_set_cps_pin(uint8_t port, uint8_t pin) +{ + int8_t ret_val = -1; + + rf_cps_port = port; + rf_cps_pin = pin; + ret_val = 0; + + return ret_val; +} + +/* + * \brief Function gives the control of RF states to MAC. + * + * \param new_state RF state + * \param rf_channel RF channel + * + * \return 0 Success + */ +static int8_t rf_interface_state_control(phy_interface_state_e new_state, uint8_t rf_channel) +{ + int8_t ret_val = 0; + switch (new_state) + { + /*Reset PHY driver and set to idle*/ + case PHY_INTERFACE_RESET: + break; + /*Disable PHY Interface driver*/ + case PHY_INTERFACE_DOWN: + rf_shutdown(); + break; + /*Enable PHY Interface driver*/ + case PHY_INTERFACE_UP: + rf_channel_set(rf_channel); + rf_receive(); + break; + /*Enable wireless interface ED scan mode*/ + case PHY_INTERFACE_RX_ENERGY_STATE: + break; + } + return ret_val; +} + +/* + * \brief Function controls the ACK pending, channel setting and energy detection. + * + * \param extension_type Type of control + * \param data_ptr Data from NET library + * + * \return 0 Success + */ +static int8_t rf_extension(phy_extension_type_e extension_type, uint8_t *data_ptr) +{ + switch (extension_type) + { + /*Control MAC pending bit for Indirect data transmission*/ + case PHY_EXTENSION_CTRL_PENDING_BIT: + if(*data_ptr) + { + rf_if_ack_pending_ctrl(1); + } + else + { + rf_if_ack_pending_ctrl(0); + } + break; + /*Return frame pending status*/ + case PHY_EXTENSION_READ_LAST_ACK_PENDING_STATUS: + *data_ptr = rf_if_last_acked_pending(); + break; + /*Set channel*/ + case PHY_EXTENSION_SET_CHANNEL: + break; + /*Read energy on the channel*/ + case PHY_EXTENSION_READ_CHANNEL_ENERGY: + break; + /*Read status of the link*/ + case PHY_EXTENSION_READ_LINK_STATUS: + break; + } + return 0; +} + +/* + * \brief Function sets the addresses to RF address filters. + * + * \param address_type Type of address + * \param address_ptr Pointer to given address + * + * \return 0 Success + */ +static int8_t rf_address_write(phy_address_type_e address_type, uint8_t *address_ptr) +{ + int8_t ret_val = 0; + switch (address_type) + { + /*Set 48-bit address*/ + case PHY_MAC_48BIT: + break; + /*Set 64-bit address*/ + case PHY_MAC_64BIT: + rf_set_address(address_ptr); + break; + /*Set 16-bit address*/ + case PHY_MAC_16BIT: + rf_set_short_adr(address_ptr); + break; + /*Set PAN Id*/ + case PHY_MAC_PANID: + rf_set_pan_id(address_ptr); + break; + } + return ret_val; +} + +/* + * \brief Function initialises the ACK wait time and returns the used PHY mode. + * + * \param none + * + * \return tmp Used PHY mode + */ +uint8_t rf_init_phy_mode(void) +{ + uint8_t tmp; + /*Read used PHY Mode*/ + tmp = rf_if_read_register(TRX_CTRL_2); + /*Set ACK wait time for used data rate*/ + if((tmp & 0x1f) == 0x00) + { + rf_ack_wait_duration = 938; + tmp = BPSK_20; + } + else if((tmp & 0x1f) == 0x04) + { + rf_ack_wait_duration = 469; + tmp = BPSK_40; + } + else if((tmp & 0x1f) == 0x14) + { + rf_ack_wait_duration = 469; + tmp = BPSK_40_ALT; + } + else if((tmp & 0x1f) == 0x08) + { + rf_ack_wait_duration = 100; + tmp = OQPSK_SIN_RC_100; + } + else if((tmp & 0x1f) == 0x09) + { + rf_ack_wait_duration = 50; + tmp = OQPSK_SIN_RC_200; + } + else if((tmp & 0x1f) == 0x18) + { + rf_ack_wait_duration = 100; + tmp = OQPSK_RC_100; + } + else if((tmp & 0x1f) == 0x19) + { + rf_ack_wait_duration = 50; + tmp = OQPSK_RC_200; + } + else if((tmp & 0x1f) == 0x0c) + { + rf_ack_wait_duration = 50; + tmp = OQPSK_SIN_250; + } + else if((tmp & 0x1f) == 0x0d) + { + rf_ack_wait_duration = 25; + tmp = OQPSK_SIN_500; + } + else if((tmp & 0x1f) == 0x0f) + { + rf_ack_wait_duration = 25; + tmp = OQPSK_SIN_500_ALT; + } + else if((tmp & 0x1f) == 0x1c) + { + rf_ack_wait_duration = 50; + tmp = OQPSK_RC_250; + } + else if((tmp & 0x1f) == 0x1d) + { + rf_ack_wait_duration = 25; + tmp = OQPSK_RC_500; + } + else if((tmp & 0x1f) == 0x1f) + { + rf_ack_wait_duration = 25; + tmp = OQPSK_RC_500_ALT; + } + else if((tmp & 0x3f) == 0x2A) + { + rf_ack_wait_duration = 25; + tmp = OQPSK_SIN_RC_400_SCR_ON; + } + else if((tmp & 0x3f) == 0x0A) + { + rf_ack_wait_duration = 25; + tmp = OQPSK_SIN_RC_400_SCR_OFF; + } + else if((tmp & 0x3f) == 0x3A) + { + rf_ack_wait_duration = 25; + tmp = OQPSK_RC_400_SCR_ON; + } + else if((tmp & 0x3f) == 0x1A) + { + rf_ack_wait_duration = 25; + tmp = OQPSK_RC_400_SCR_OFF; + } + else if((tmp & 0x3f) == 0x2E) + { + rf_ack_wait_duration = 13; + tmp = OQPSK_SIN_1000_SCR_ON; + } + else if((tmp & 0x3f) == 0x0E) + { + rf_ack_wait_duration = 13; + tmp = OQPSK_SIN_1000_SCR_OFF; + } + else if((tmp & 0x3f) == 0x3E) + { + rf_ack_wait_duration = 13; + tmp = OQPSK_RC_1000_SCR_ON; + } + else if((tmp & 0x3f) == 0x1E) + { + rf_ack_wait_duration = 13; + tmp = OQPSK_RC_1000_SCR_OFF; + } + return tmp; +} +