Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: fsl_phy_mcr20a fsl_smac mbed-rtos mbed
Fork of mcr20_wireless_uart by
RF_Drivers_Freescale/driverRFPhy.c
- Committer:
- cotigac
- Date:
- 2015-03-05
- Revision:
- 9:904334e768eb
- Parent:
- 8:e4c9f2b7a9d2
- Child:
- 12:4446d8228309
File content as of revision 9:904334e768eb:
/*
* 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 "options.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)
{
int i, j = 0;
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;
}
