From dd2902b3f886959f38507e1c3877259628061ecc Mon Sep 17 00:00:00 2001 From: Edward Longman <el7g15@soton.ac.uk> Date: Thu, 9 May 2019 12:36:04 +0100 Subject: [PATCH] Add the code for trx demo --- source/test/LaunchPad_trx_demo.c | 1386 ++++++++++++++++++++++++++++++ source/test/LaunchPad_trx_demo.h | 127 +++ source/test/LaunchPad_trx_main.c | 338 ++++++++ source/test/main_rxer.c | 0 source/test/main_txer.c | 0 5 files changed, 1851 insertions(+) create mode 100644 source/test/LaunchPad_trx_demo.c create mode 100644 source/test/LaunchPad_trx_demo.h create mode 100644 source/test/LaunchPad_trx_main.c delete mode 100644 source/test/main_rxer.c delete mode 100644 source/test/main_txer.c diff --git a/source/test/LaunchPad_trx_demo.c b/source/test/LaunchPad_trx_demo.c new file mode 100644 index 0000000..2c796ce --- /dev/null +++ b/source/test/LaunchPad_trx_demo.c @@ -0,0 +1,1386 @@ +/****************************************************************************** + * Filename: LaunchPad_trx_demo.c + * + * Description: Range Test for various EVM boards and transcievers + * This wireless demo applications is meant to show the + * advantage of using. Frequency hopping Spread Spectrum (FHSS) + * to implement your wireless sensor network. This code base + * has been developed to run on a number of TI devices including + * most MSP430F2x and MSP430F5x series microcontrolers using stand + * alone wireless transcievers (CC1101, CC112x). + * + * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *******************************************************************************/ + +#include <cc1x_utils.h> +#include "stdio.h" +#include "stdlib.h" +#include "msp430.h" +#include "hal_timer.h" +#include "LaunchPad_trx_demo.h" +#include "uart_drv.h" +#include "hal_spi_rf.h" +#include "radio_drv.h" + +/****************************************************************************** + * DEFINES - define the system ID and channel hopping scheme + */ +#define ENABLE_DEBUG_UART TRUE // display data over a UART link +#define MAX_HOP_CHANNELS 50 // Sets the number of channels +#define SYSTEM_ID 0 // 0 and 255 +#define ENABLE_HOPPING FALSE // can be disable for debugging +#define ENABLE_TWO_WAY_LINK TRUE // a reverse packet is expected +#define PRE_SYNC_CRC_LEN 10 // 10 bytes of preamble, sync, and CRC +#define MAX_PACKET_ERROR_COUNT 50 // after 50 dropped packets re-link + +/****************************************************************************** + * EXTERNAL FUNCTIONS + */ +int ee_printf(const char *fmt, ...); +unsigned int hal_timer_get_time(unsigned long *sec, unsigned long *ms); + +/****************************************************************************** + * INTERNAL FUNCTIONS + */ +void uartSendString(char *str); +unsigned char data_to_uart(unsigned char *data, unsigned char length); +void byte_to_hex(unsigned char byte, char *hex); +unsigned char str_to_data(char *str, unsigned int *data, unsigned char length); + +/****************************************************************************** + * INTERNAL VARIABLES - state machine control + */ +char radio_mode; // statemachine control variable +char radio_mode_idle_count = 0; // timeout counter +unsigned char chan_hop_seq[MAX_HOP_CHANNELS]; // channels hopping sequence + +/****************************************************************************** + * INTERNAL VARIABLES - state machine control + */ +extern char user_button_pushed; // user button has been pressed +extern const unsigned char rand_data[]; // pointer to predefined payload + +/****************************************************************************** + * @fn parse_ui_cmd + * + * @brief Parses commands implementing a simple menu system on a terminal + * + * input parameters + * + * @param trx_cfg_struct *trx_cfg - structure for control information + * char *ui_cmd - pointer to buffer from terminal + * + * output parameters + * + * @return trx_cfg->trx_mode + * + */ +char parse_ui_cmd(trx_cfg_struct *trx_cfg, char *ui_cmd, unsigned char ui_cmd_length) +{ + unsigned int data_s[4], line; + unsigned long timer_values; + + + str_to_data(ui_cmd, data_s, ui_cmd_length); + line = data_s[0]; + switch(line) + { + case 1: /* "Unmodulated TX" */ + trx_cfg->trx_mode = MENU_TX_UNMOD; + trx_cfg->cc_state = CC_IDLE; + trx_cfg->rf_channel = data_s[1]; + break; + case 2: /* "Modulated TX w. MCU" */ + trx_cfg->trx_mode = MENU_TX_nMCU; + trx_cfg->cc_state = CC_IDLE; + trx_cfg->rf_channel = data_s[1]; + break; + case 3: /* Modulated TX no MCU" */ + trx_cfg->trx_mode = MENU_RX_STATIC; + trx_cfg->cc_state = CC_IDLE; + trx_cfg->rf_channel = data_s[1]; + break; + case 4: /* " TX burst BER test" */ + trx_cfg->trx_mode = MENU_TX_BER; + trx_cfg->cc_state = CC_IDLE; + trx_cfg->rf_channel = data_s[1]; + trx_cfg->no_burst = data_s[2]; + break; + case 5: /* "RX burst BER test" */ + trx_cfg->trx_mode = MENU_RX_BER; + trx_cfg->cc_state = CC_IDLE; + trx_cfg->rf_channel = data_s[1]; + trx_cfg->no_burst = data_s[2]; + break; + case 6: /* "TX FHSS BER test" */ + trx_cfg->trx_mode = MENU_TX_FHSS_BER; + trx_cfg->cc_state = CC_IDLE; + trx_cfg->no_burst = data_s[1]; + break; + case 7: /* "RX FHSS BER test" */ + trx_cfg->trx_mode = MENU_RX_FHSS_BER; + trx_cfg->cc_state = CC_IDLE; + trx_cfg->no_burst = data_s[1]; + break; + case 8: /* " Packet Sniffer */ + trx_cfg->trx_mode = MENU_RX_SNIFF; + trx_cfg->cc_state = CC_IDLE; + trx_cfg->rf_channel = data_s[1]; + trx_cfg->b_length = data_s[2]; + break; + case 9: /* " SmartRF Studio selector" */ + trx_cfg->trx_mode = MENU_RESTART; + trx_cfg->cc_state = CC_IDLE; + trx_cfg->smartrf_selector = data_s[1]; + trx_cfg->bit_rate = radio_init(trx_cfg->smartrf_selector); + trx_cfg->bit_rate = trx_cfg->bit_rate * 100; + // use worst case packet length for calculations + if(trx_cfg->bit_rate == 1200) + { + trx_cfg->b_length = 20; + } else { + trx_cfg->b_length = 64; + } + // master packet timing (assuming 32768 Hz ACLK) + timer_values = trx_cfg->b_length+PRE_SYNC_CRC_LEN; + timer_values = (timer_values*640000)/trx_cfg->bit_rate; + trx_cfg->packet_timer = (unsigned int)timer_values; + + // packet timeout - if it has not happen, just turn off the RX. + trx_cfg->normal_wait_timer = trx_cfg->packet_timer/2; + + // packet timeout - this setting is long enough to have at least 1 burst and + trx_cfg->max_wait_timer = trx_cfg->packet_timer*3; + + // burst timing - This calibrates the timer to the burst duration and period + timer_values = trx_cfg->b_length+PRE_SYNC_CRC_LEN; + timer_values = (timer_values*256000)/trx_cfg->bit_rate; + trx_cfg->sync_timer = (unsigned int)timer_values+32; + + // xtal statup wait - this values make the mcu wait for the xtal to start up + trx_cfg->xtal_wait_timer = 32; + + break; + case 10: /* "9) Setup Radio page" */ + trx_cfg->trx_mode = MENU_RESTART; + trx_cfg->cc_state = CC_IDLE; + trx_cfg->start_freq = (unsigned long)data_s[1]*1000 + data_s[2]; + radio_set_freq(trx_cfg->start_freq); + trx_cfg->ch_spc = data_s[3]; + break; + default: + trx_cfg->trx_mode = MENU_RESTART; + trx_cfg->cc_state = CC_IDLE; + break; + } + + return trx_cfg->trx_mode; +} + +/****************************************************************************** + * @fn rf_default_setup + * + * @brief read chip information to identity the specific device in circuit + * + * input parameters + * + * @param trx_cfg_struct *trx_cfg - structure for control information + * + * output parameters + * + * @return void + * + */ +void rf_default_setup(trx_cfg_struct *trx_cfg) +{ + trx_cfg->trx_mode = MENU_RESTART; + trx_cfg->cc_state = CC_IDLE; + trx_cfg->no_burst = 1000; + trx_cfg->rf_channel = 0; + trx_cfg->smartrf_selector = 1; + trx_cfg->packet_timer = 16000; + trx_cfg->normal_wait_timer = 8000; + trx_cfg->max_wait_timer = 32000; + trx_cfg->sync_timer = 6432; + trx_cfg->xtal_wait_timer = 32; + trx_cfg->b_length = 20; + trx_cfg->start_freq = 902750; + trx_cfg->ch_spc = 500; + trx_cfg->cc_device_id = get_device_id(); +} + +/****************************************************************************** + * @fn unmodulated_tx + * + * @brief configure unmodulated TX mode + * + * input parameters + * + * @param trx_cfg_struct *trx_cfg - structure for control information + * + * output parameters + * + * @return void + * + */ +void unmodulated_tx(trx_cfg_struct *trx_cfg) +{ + unsigned char payload = 255; + + // Make sure the radio is IDLE, then reprogram the registers for umodulated tx + radio_idle(); + + /* small delay */ + __delay_cycles(1000000); + + /* configure the tx frequency */ + radio_set_freq(trx_cfg->start_freq+(trx_cfg->ch_spc*trx_cfg->rf_channel)); + + /* configure teh unmodulated test mode */ + set_tx_unmodulated_test_mode(); + + /* add one byte to the FIFO */ + radio_prepare(&payload, 1); + + /* start the TX chain */ + radio_transmit(); + + uartSendString("\n\r"); + uartSendString("Started unmodulated TX, Press RETURN key twice to stop\n\r"); + return; +} + + +/****************************************************************************** + * @fn modulated_tx_no_mcu + * + * @brief configure modulated TX mode + * + * input parameters + * + * @param trx_cfg_struct *trx_cfg - structure for control information + * + * output parameters + * + * @return void + * + */ +void modulated_tx_no_mcu(trx_cfg_struct *trx_cfg) +{ + + unsigned char payload = 255; + + // Make sure the radio is IDLE, then reprogram the registers for modulated tx + radio_idle(); + + /* small delay */ + __delay_cycles(1000000); + + /* configure the rx frequency to perform packet sniffing on */ + radio_set_freq(trx_cfg->start_freq+(trx_cfg->ch_spc*trx_cfg->rf_channel)); + + set_tx_modulated_test_mode(); + + /* add one byte to the FIFO */ + radio_prepare(&payload, 1); + + radio_transmit(); + + uartSendString("\n\r"); + uartSendString("Started modulated TX using PN9 inside CC device\n\r"); + uartSendString("Press RETURN key twice to stop\n\r"); + return; +} + + +/****************************************************************************** + * @fn rx_static + * + * @brief configure continuous RX mode + * + * input parameters + * + * @param trx_cfg_struct *trx_cfg - structure for control information + * + * output parameters + * + * @return void + * + */ +void rx_static(trx_cfg_struct *trx_cfg) +{ + + /* configure the rx frequency to perform packet sniffing on */ + radio_set_freq(trx_cfg->start_freq+(trx_cfg->ch_spc*trx_cfg->rf_channel)); + + radio_receive_on(); + uartSendString("\n\r"); + uartSendString("Started static RX, Press RETURN key twice to stop\n\r"); + return; +} + + +/****************************************************************************** + * @fn main_menu + * + * @brief displays the main menu text + * + * input parameters + * + * @param trx_cfg_struct *trx_cfg - structure for control information + * + * output parameters + * + * @return void + * + */ +void main_menu(trx_cfg_struct *trx_cfg) +{ + unsigned int freq_mhz, freq_khz; + + uartSendString("\n\r"); + uartSendString("Long Range Sub1Ghz demonstration\n\r"); + uartSendString("Select from items below:\n\r"); + uartSendString("***********************************************************************\n\r"); + uartSendString(" 1) Continuous Unmodulated TX (line, chan) eg.(1 25)\n\r"); + uartSendString(" 2) Continuous Modulated TX (line, chan) eg.(2 25)\n\r"); + uartSendString(" 3) Static RX (RX leakage test) (line, chan) eg.(3 25)\n\r"); + uartSendString(" 4) TX Single Channel BER (line, chan, pkt) eg.(4 25 1000)\n\r"); + uartSendString(" 5) RX Single Channel BER (line, chan, pkt) eg.(5 25 1000)\n\r"); + uartSendString(" 6) TX freq. hopping BER (line, pkt) eg.(6 1000)\n\r"); + uartSendString(" 7) RX freq. hopping BER (line, pkt) eg.(7 1000)\n\r"); + uartSendString(" 8) RX sniff mode (line, chan, len) eg.(8 25 20) len=0 > variable\n\r"); + uartSendString(" 9) SmartRF Selector (line, 1=Low, 2=Med, 3=High) eg.(9 2)\n\r"); + uartSendString("10) Radio Setup (line, freq, chan spc) eg. (10 902 750 500)\n\r"); + uartSendString("***********************************************************************\n\r"); + + ee_printf("Current configuration: (Device = "); + switch (trx_cfg->cc_device_id) + { + case DEV_UNKNOWN: + ee_printf("Unknown)\n\r"); + break; + case DEV_CC2500: + ee_printf("CC2500)\n\r"); + break; + case DEV_CC1100: + ee_printf("CC1100)\n\r"); + break; + case DEV_CC1101: + ee_printf("CC1101)\n\r"); + break; + case DEV_CC430x: + ee_printf("CC430x)\n\r"); + break; + case DEV_CC1125: + ee_printf("CC1125)\n\r"); + break; + case DEV_CC1120: + ee_printf("CC1120)\n\r"); + break; + case DEV_CC1121: + ee_printf("CC1121)\n\r"); + break; + case DEV_CC1175: + ee_printf("CC1175)\n\r"); + break; + } + + ee_printf(" Current configuration:\n\r"); + + switch (trx_cfg->bit_rate) + { + case 1200: + ee_printf("Config: 9 Low data rate => 1200bps, 4kHz dev, 25kHz RX BW \n\r"); + break; + case 38400: + ee_printf("Config: 9 Med data rate => 38.4kbps, 20kHz dev, 100kHz RX BW \n\r"); + break; + case 50000: + ee_printf("Config: 9 High data rate => 50kbps, 25kHz dev, 100kHz RX BW \n\r"); + break; + case 250000: + ee_printf("Config: 9 High data rate => 250kbps, 127kHz dev, 542kHz RX BW \n\r"); + break; + default: + ee_printf("Unknown)\n\r"); + break; + } + freq_mhz = (unsigned int)(trx_cfg->start_freq/1000); + freq_khz = (unsigned int)(trx_cfg->start_freq - freq_mhz*1000); + ee_printf("Freq : 10 %03i %03i %3i\n\r", freq_mhz, freq_khz, trx_cfg->ch_spc); + + uartSendString("*************************************************************\n\r"); + uartSendString("CMD >\n\r"); + return; +} + +/****************************************************************************** + * @fn generate_hopping_table + * + * @brief generate the table required to perform frequency hopping + * + * input parameters + * + * @param unsigned char *hop_table - structure for hopping table + * + * output parameters + * + * @return void + * + */ +void generate_hopping_table(unsigned char *hop_table, unsigned char length_table) +{ + int channel_found,ii,jj; + unsigned int chan_int; + int rand_seed = SYSTEM_ID; + + /* if the rand_seed is positive generate a PN hopping table */ + if(ENABLE_HOPPING == TRUE) + { + + /* start by placing the seed */ + srand(rand_seed); + + /* ii is the table index */ + for (ii=0;ii<length_table;ii++) + { + /* search for overlaps */ + channel_found = 1; + + while(channel_found > 0) + { + + /* find a new random number */ + chan_int = length_table * (rand()>>7); + hop_table[ii] = chan_int >> 8; + channel_found = 0; + + /* check to see if already exists */ + for (jj=0;jj<ii;jj++) + { + if(hop_table[ii] == hop_table[jj]) channel_found++; + } + } + } + } + else + { + /* generate a simple table of all the same values based on the negative input */ + for (ii=0;ii<length_table;ii++) + { + hop_table[ii] = rand_seed; + } + } + + return; +} + +/****************************************************************************** + * @fn tx_ber_fhss + * + * @brief Perform RF burst transmit function with frequency hopping + * + * input parameters + * + * @param trx_cfg_struct *trx_cfg - structure for control information + * + * output parameters + * + * @return void + * + */ +void tx_ber_fhss(unsigned char *txBuffer, trx_cfg_struct *trx_cfg) +{ + unsigned int bb, cc, dd; + unsigned short rx_length, data_error; + signed int rssi_forward, rssi_reverse, freq_error; + unsigned int status, total_pkt_count; + unsigned long error_forward, error_reverse; + + uartSendString("\n\r"); + uartSendString("Perform RF burst transmit function with frequency hopping\n\r"); + + // Generate the frequency hopping sequence table that we will be using + generate_hopping_table(chan_hop_seq, MAX_HOP_CHANNELS); + + data_to_uart(chan_hop_seq, MAX_HOP_CHANNELS); + uartSendString("\n\r"); + + // Set the packet length to a fixed packet size + set_rf_packet_length(trx_cfg->b_length); + + HAL_LED1_OFF(); // Initialize LED1 + HAL_LED2_OFF(); // Initialize LED2 + + error_forward = 0; + error_reverse = 0; + total_pkt_count = 0; + + // start the timer + hal_timer_init(trx_cfg->packet_timer); + // start transmitting burst, one on each of the MAX_HOP_CHANNELS channels in the PN sequence + + ee_printf("PKT CHAN FW-RSSI/ERR RW-RSSI/ERR\n\r"); + + bb = 0; + for(cc=0; cc<trx_cfg->no_burst; cc++) + { + + /* update channel counter */ + if(bb-- == 0) bb=(MAX_HOP_CHANNELS-1); + + // enter low power mode and wait for TimerA1 + hal_timer_expire(); + + // put some data into the payload + txBuffer[0] = SYSTEM_ID; // System ID + txBuffer[1] = (cc>>8) & 0xFF; // Burst number (MSB) + txBuffer[2] = cc & 0xFF; // Burst number (LSB) + for(dd=3;dd<trx_cfg->b_length;dd++) + { + txBuffer[dd] = rand_data[dd]; + } + // Transmit packet. The MCU does not exit this until the TX is complete. + HAL_LED2_ON(); + radio_set_freq(trx_cfg->start_freq+(trx_cfg->ch_spc*chan_hop_seq[bb])); + radio_send(txBuffer, trx_cfg->b_length); + radio_wait_for_idle(0); // 0 = no timeout, just wait + HAL_LED2_OFF(); + + if(ENABLE_TWO_WAY_LINK == TRUE) + { + HAL_LED2_ON(); + radio_receive_on(); // Change state to RX, receive packet + // wait until end_of_packet is found or timeout (if packet is not found) + status = radio_wait_for_idle(trx_cfg->normal_wait_timer); + HAL_LED2_OFF(); + + if(status < trx_cfg->normal_wait_timer) + { + rx_length = trx_cfg->b_length; + radio_read(txBuffer, &rx_length); + + /* calculate the RSSI from the information from the RADIO registers */ + rssi_reverse = radio_get_rssi(); + freq_error = radio_freq_error(); + if(txBuffer[3] >= 128) + { + rssi_forward = -(256 - txBuffer[3]); + } else { + rssi_forward = txBuffer[3]; + } + /* count the byte error in the incomming packet */ + data_error = 0; + for(dd=5; dd<trx_cfg->b_length; dd++) + { + if( txBuffer[dd] != rand_data[dd] ) + { + data_error++; + } + } + dd = (txBuffer[1] << 8) + txBuffer[2]; + error_forward = error_forward + txBuffer[4]; + error_reverse = error_reverse + data_error; + total_pkt_count++; + } + else + { + /* packet error hanppenned, blink red LED and flush FIFO */ + HAL_LED1_ON(); + __delay_cycles(1000); // this is just so we can see the LED blink + radio_idle(); // Force IDLE state and Flush the RX FIFO's + rssi_forward = 0; + rssi_reverse = 0; + data_error = trx_cfg->b_length; + error_forward = error_forward + data_error; + error_reverse = error_reverse + data_error; + total_pkt_count++; + HAL_LED1_OFF(); + } + } + +#if ENABLE_DEBUG_UART == TRUE + if(ENABLE_TWO_WAY_LINK == TRUE) + { + ee_printf("%4d %2d %3i %3i %3i %3i %3i\n\r", cc, chan_hop_seq[bb], + rssi_forward, txBuffer[4], rssi_reverse, data_error, freq_error); + } else { + ee_printf("%4d %2d %3i\n\r", cc, chan_hop_seq[bb], freq_error); + } +#endif + } + hal_timer_stop(); + + radio_mode = RADIO_IDLE; + + ee_printf("Total packets Sent : %5d\n\r", trx_cfg->no_burst); + ee_printf("Total packets Received : %5d\n\r", total_pkt_count); + ee_printf("Forward Error count : %7ld\n\r", error_forward); + ee_printf("Reverse Error count : %7ld\n\r", error_reverse); + + return; +} + + +/****************************************************************************** + * @fn rx_ber_fhss + * + * @brief Perform RF burst receive function with frequency hopping + * + * input parameters + * + * @param unsigned char *txBuffer + * trx_cfg_struct *trx_cfg - structure for control information + * + * output parameters + * + * @return void + * + */ +void rx_ber_fhss(unsigned char *txBuffer, trx_cfg_struct *trx_cfg) +{ + int channel_index, mis_packet_counter, dd, rssi, freq_error, status; + unsigned short rx_length; + char char_rssi; + unsigned char done = FALSE, cc_status; + unsigned int pck_cnt = 0, pck_good_cnt = 0, max_wait_current, curr_pkt_id; + + +#if ENABLE_DEBUG_UART == TRUE + + uartSendString("\n\r"); + uartSendString("Perform RF burst receive function with frequency hopping\n\r"); +#endif + + // Generate the frequency hopping sequence table that we will be using + generate_hopping_table(chan_hop_seq, MAX_HOP_CHANNELS ); + + data_to_uart(chan_hop_seq, MAX_HOP_CHANNELS); + uartSendString("\n\r"); + + // Set the packet length to a fixed packet size + set_rf_packet_length(trx_cfg->b_length); + + user_button_pushed = 0; + + // Initialize various control variable used in the FHSS algorithm + channel_index = 0; // determines the current channels index (lookup value) + mis_packet_counter = 0; // counts how many packets we have missed in a row + + // Sets the mode in which we operate: + // trx_cfg->max_wait_timer; indicates that we are not locked to a basestation and we + // need to perform adaptive seeking of basestation signal + // trx_cfg->normal_wait_timer: We are locked to a basestation and should proceed in + // normal operation + max_wait_current = trx_cfg->max_wait_timer; // sets the mode it which we operate + + // start the medium access control timer, this timer is used to figure out when + // to wake up to receive a new burst. + hal_timer_init(trx_cfg->packet_timer); + + HAL_LED1_ON(); + HAL_LED2_OFF(); + HAL_LED3_OFF(); + HAL_LED4_OFF(); + + done = FALSE; + while (done == FALSE) + { + // Wait for the next burst time slot + + hal_timer_expire(); // wait for timer to expire + + /* update channel counter */ + if(channel_index-- == 0) channel_index=(MAX_HOP_CHANNELS-1); + + // Wake radio from sleep + radio_idle(); + + //hal_timer_wait(XTAL_START_WAIT); + radio_set_freq(trx_cfg->start_freq+(trx_cfg->ch_spc*chan_hop_seq[channel_index])); + + HAL_LED1_ON(); + HAL_LED2_OFF(); + HAL_LED3_OFF(); + HAL_LED4_OFF(); + radio_receive_on(); // Change state to RX, receive packet + + // wait until end_of_packet is found, but with timeout (if packet is not found) + status = radio_wait_for_idle(max_wait_current); + HAL_LED1_OFF(); + + // This case we have been waiting for a burst with RX continuesly running + if(max_wait_current == trx_cfg->max_wait_timer) + { + // This means we have found a packet and should syncronize to it + if(status < trx_cfg->max_wait_timer) + { + + // Aligns timer for next burst to arrive + hal_timer_adjust(trx_cfg->sync_timer); // align the timer with burst + + pck_cnt = 1; // reset the counter for display + + max_wait_current = trx_cfg->normal_wait_timer; + rx_length = trx_cfg->b_length; + cc_status = radio_read(txBuffer, &rx_length); + rssi = radio_get_rssi(); + + if(cc_status > 0) + { + pck_good_cnt = 1; + HAL_LED2_ON(); + char_rssi = (char)rssi; + txBuffer[3] = (unsigned char)char_rssi; // insert measurement in + txBuffer[4] = 0; + + for(dd=5;dd<trx_cfg->b_length;dd++) // count errors in data + { + if( txBuffer[dd] != rand_data[dd] ) + { + txBuffer[4] = txBuffer[4] + 1; // error count is byte 3 + txBuffer[dd] = rand_data[dd]; // clean data for return + } + } + + if(ENABLE_TWO_WAY_LINK == TRUE) + { + radio_send(txBuffer, trx_cfg->b_length); // standard packet send + } + curr_pkt_id = (txBuffer[1]<<8) + txBuffer[2]; +#if ENABLE_DEBUG_UART == TRUE + ee_printf("F:%d %d %i %d\n\r", channel_index, chan_hop_seq[channel_index], + curr_pkt_id, txBuffer[3]); +#endif + mis_packet_counter = 0; + } else { + pck_good_cnt = 0; + HAL_LED1_ON(); + } + } + } + + // default setting is that we have been running a standard RX burst + if( max_wait_current == trx_cfg->normal_wait_timer ) + { + if(status < max_wait_current ) + { + pck_cnt++; + mis_packet_counter = 0; + hal_timer_adjust(trx_cfg->sync_timer); // align the timer with burst + + rx_length = trx_cfg->b_length; + cc_status = radio_read(txBuffer, &rx_length); // read content of FIFO + rssi = radio_get_rssi(); + freq_error = radio_freq_error(); + + if(cc_status > 0) + { + pck_good_cnt++; + HAL_LED2_ON(); + } + else + { + HAL_LED1_ON(); + } + char_rssi = (char)rssi; + txBuffer[3] = (unsigned char)char_rssi; // insert measurement in + txBuffer[4] = 0; // return data + + for(dd=5;dd<trx_cfg->b_length;dd++) // count errors in data + { + if( txBuffer[dd] != rand_data[dd] ) + { + txBuffer[4] = txBuffer[4] + 1; // error count is byte 3 + txBuffer[dd] = rand_data[dd]; // clean data for return + } + } + if(ENABLE_TWO_WAY_LINK == TRUE) { + + radio_send(txBuffer, trx_cfg->b_length); // standard packet send + } +#if ENABLE_DEBUG_UART == TRUE + curr_pkt_id = (txBuffer[1]<<8) + txBuffer[2]; + ee_printf("N: %d %d %i %d %d\n\r", channel_index, chan_hop_seq[channel_index], + curr_pkt_id, rssi, freq_error); +#endif + } + else + { + // Check to see if we have lost the connection and we need to stop and hold + radio_idle(); // force idle and flush fifos + // if max_wait == 0 that means we are waiting for first sync burst to appear + + if(mis_packet_counter > MAX_PACKET_ERROR_COUNT) + { + max_wait_current = trx_cfg->max_wait_timer; + } + else + { + mis_packet_counter++; + } +#if ENABLE_DEBUG_UART == TRUE + ee_printf("M:%d %d\n\r", channel_index, chan_hop_seq[channel_index]); +#endif + } + } + // Check to see if the user button has been pressed, exit the rx_ber() + if(user_button_pushed == 1) + { + user_button_pushed = 0; + done = TRUE; + } + } + hal_timer_stop(); + + return; +} + + +/****************************************************************************** + * @fn tx_ber_single + * + * @brief Perform RF burst transmit function on a single channel + * + * input parameters + * + * @param trx_cfg_struct *trx_cfg - structure for control information + * + * output parameters + * + * @return void + * + */ +void tx_ber_single(unsigned char *txBuffer, trx_cfg_struct *trx_cfg) +{ + unsigned int cc, dd; + unsigned short rx_length, data_error; + signed int rssi_forward, rssi_reverse, freq_error; + unsigned int status, total_pkt_count; + unsigned long error_forward, error_reverse; + + uartSendString("\n\r"); + uartSendString("Perform RF burst transmit function with fixed channel\n\r"); + + // Set the packet length to a fixed packet size + set_rf_packet_length(trx_cfg->b_length); + + /* configure the rx frequency to perform packet sniffing on */ + radio_set_freq(trx_cfg->start_freq+(trx_cfg->ch_spc*trx_cfg->rf_channel)); + + HAL_LED1_OFF(); // Initialize LED1 + HAL_LED2_OFF(); // Initialize LED2 + + error_forward = 0; + error_reverse = 0; + total_pkt_count = 0; + + // start the timer + hal_timer_init(trx_cfg->packet_timer); + + // start transmitting burst + ee_printf(" PKT FW-RSSI/ERR RW-RSSI/ERR FREQ_ERR\n\r"); + + for(cc=0; cc<trx_cfg->no_burst; cc++) + { + + // enter low power mode and wait for TimerA1 + hal_timer_expire(); + + // put some data into the payload + txBuffer[0] = SYSTEM_ID; // System ID + txBuffer[1] = (cc>>8) & 0xFF; // Burst number (MSB) + txBuffer[2] = cc & 0xFF; // Burst number (LSB) + for(dd=3;dd<trx_cfg->b_length;dd++) + { + txBuffer[dd] = rand_data[dd]; + } + // Transmit packet. The MCU does not exit this until the TX is complete. + HAL_LED2_ON(); + radio_send(txBuffer, trx_cfg->b_length); + radio_wait_for_idle(0); // 0 = no timeout, just wait + HAL_LED2_OFF(); + + if(ENABLE_TWO_WAY_LINK == TRUE) + { + HAL_LED2_ON(); + radio_receive_on(); // Change state to RX, receive packet + // wait until end_of_packet is found or timeout (if packet is not found) + status = radio_wait_for_idle(trx_cfg->normal_wait_timer); + HAL_LED2_OFF(); + + if(status < trx_cfg->normal_wait_timer) + { + + rx_length = trx_cfg->b_length; + radio_read(txBuffer, &rx_length); + + /* calculate the RSSI from the information from the RADIO registers */ + rssi_reverse = radio_get_rssi(); + freq_error = radio_freq_error(); + if(txBuffer[3] >= 128) + { + rssi_forward = -(256 - txBuffer[3]); + } else { + rssi_forward = txBuffer[3]; + } + + data_error = 0; + for(dd=5; dd<trx_cfg->b_length; dd++){ + if( txBuffer[dd] != rand_data[dd] ) + { + data_error++; + } + } + dd = (txBuffer[1] << 8) + txBuffer[2]; + error_forward = error_forward + txBuffer[4]; + error_reverse = error_reverse + data_error; + total_pkt_count++; + } + else + { + HAL_LED1_ON(); + __delay_cycles(1000); // this is just so we can see the LED blink + radio_idle(); // Force IDLE state and Flush the RX FIFO's + rssi_forward = 0; + rssi_reverse = 0; + data_error = trx_cfg->b_length; + error_forward = error_forward + data_error; + error_reverse = error_reverse + data_error; + total_pkt_count++; + HAL_LED1_OFF(); + } + } + +#if ENABLE_DEBUG_UART == TRUE + if(ENABLE_TWO_WAY_LINK == TRUE) + { + ee_printf("%4d %3i %3i %3i %3i %3i\n\r", cc, rssi_forward, txBuffer[4], + rssi_reverse, data_error, freq_error); + } + else + { + ee_printf("%4d %3i\n\r", cc, freq_error); + } +#endif + } + hal_timer_stop(); + + radio_mode = RADIO_IDLE; + + ee_printf("Total packets Sent : %5d\n\r", trx_cfg->no_burst); + ee_printf("Total packets Received : %5d\n\r", total_pkt_count); + ee_printf("Forward Error count : %7ld\n\r", error_forward); + ee_printf("Reverse Error count : %7ld\n\r", error_reverse); + + return; +} + + +/****************************************************************************** + * @fn rx_ber_single + * + * @brief Perform RF burst receive function with frequency hopping + * + * input parameters + * + * @param unsigned char *txBuffer + * trx_cfg_struct *trx_cfg - structure for control information + * + * output parameters + * + * @return void + * + */ +void rx_ber_single(unsigned char *txBuffer, trx_cfg_struct *trx_cfg) +{ + int dd; + unsigned short rx_length; + unsigned char done = FALSE, cc_status; + unsigned int pck_good_cnt = 0; + int rssi, freq_error; + char char_rssi; + unsigned int curr_pkt_id; + +#if ENABLE_DEBUG_UART == TRUE + + uartSendString("\n\r"); + uartSendString("Perform RF burst receive function with fixed channel\n\r"); +#endif + + // Set the packet length to a fixed packet size + set_rf_packet_length(trx_cfg->b_length); + + /* configure the rx frequency to perform packet sniffing on */ + radio_set_freq(trx_cfg->start_freq+(trx_cfg->ch_spc*trx_cfg->rf_channel)); + + /* configure the timer for a 1 second tick */ + hal_timer_init(32768); + + user_button_pushed = 0; + + HAL_LED1_OFF(); + HAL_LED2_OFF(); + HAL_LED3_OFF(); + HAL_LED4_OFF(); + + done = FALSE; + + /* Initialize the RX chain, receive packet */ + radio_receive_on(); + + // start transmitting burst + ee_printf(" PKT FW-RSSI/ERR FREQ_ERR\n\r"); + + while (done == FALSE) + { + + // wait until end_of_packet is found, no timeout + radio_wait_for_idle(0); + + rx_length = trx_cfg->b_length; + cc_status = radio_read(txBuffer, &rx_length); // read content of FIFO + + if(cc_status > 0) + { + pck_good_cnt++; + HAL_LED2_ON(); + rssi = radio_get_rssi(); + freq_error = radio_freq_error(); + if(ENABLE_TWO_WAY_LINK == TRUE) + { + char_rssi = (char)rssi; + txBuffer[3] = (unsigned char)char_rssi; // insert measurement in + txBuffer[4] = 0; // return data + + for(dd=5;dd<trx_cfg->b_length;dd++) // count errors in data + { + if( txBuffer[dd] != rand_data[dd] ) + { + txBuffer[4] = txBuffer[4] + 1; // error count is byte 3 + txBuffer[dd] = rand_data[dd]; // clean data for return + } + } + + radio_send(txBuffer, trx_cfg->b_length); // standard packet send + + radio_wait_for_idle(0); // 0 = no timeout, just wait + } + } + else + { + HAL_LED1_ON(); + // Check to see if we have lost the connection and we need to stop and hold + radio_idle(); // force idle and flush fifos + // if max_wait == 0 that means we are waiting for first sync burst to appear + } + + /* Initialize the RX chain, receive packet */ + radio_receive_on(); + +#if ENABLE_DEBUG_UART == TRUE + curr_pkt_id = (txBuffer[1]<<8) + txBuffer[2]; + ee_printf("%4d %3i %3i\n\r", curr_pkt_id, rssi, freq_error); +#endif + + // Check to see if the user button has been pressed, exit the rx_ber() + if(user_button_pushed == 1) + { + user_button_pushed = 0; + done = TRUE; + } + } + + return; +} + + +/****************************************************************************** + * @fn rx_sniff + * + * @brief Implements a simple packet sniffer printing all data on uart + * + * input parameters + * + * @param unsigned char *txBuffer + * trx_cfg_struct *trx_cfg - structure for control information + * + * output parameters + * + * @return void + * + */ +void rx_sniff(unsigned char *txBuffer, trx_cfg_struct *trx_cfg) +{ + unsigned int done; + int rssi; + unsigned short rx_length; + unsigned long sec, ms; + int cc_status; + + uartSendString("\n\r"); + uartSendString("Started RX sniff analyzer:\n\r"); + + done = FALSE; + + /* if the packet length is 0, then configure variable packet length mode */ + if(trx_cfg->b_length > 0) + { + // Set the packet length to a fixed packet size + set_rf_packet_length(trx_cfg->b_length); + } + else + { + /* re-initialize the radio, this reset the configuration to variable packet length */ + radio_init(trx_cfg->smartrf_selector); + trx_cfg->b_length = TX_BUFF_SIZE; + } + + /* configure the timer for a 1 second tick */ + hal_timer_init(32768); + + /* configure the rx frequency to perform packet sniffing on */ + radio_set_freq(trx_cfg->start_freq+(trx_cfg->ch_spc*trx_cfg->rf_channel)); + + /* Initialize the RX chain, receive packet */ + radio_receive_on(); + + while (done == FALSE) + { + + HAL_LED3_OFF(); + HAL_LED4_OFF(); + + // wait until end_of_packet is found, no timeout + radio_wait_for_idle(0); + HAL_LED4_ON(); + + //get time passed in seconds and milliseconds + hal_timer_get_time(&sec, &ms); + + // read content of FIFO + rx_length = trx_cfg->b_length; + cc_status = radio_read(txBuffer, &rx_length); + rssi = radio_get_rssi(); + + //re-start the receiver as fast as possible. + radio_receive_on(); + + if(cc_status > 0) + { + HAL_LED4_OFF(); + HAL_LED3_ON(); + } + +#if ENABLE_DEBUG_UART == TRUE + ee_printf("%4u.%03u: ", (unsigned int)sec, (unsigned int)ms); + data_to_uart(txBuffer, rx_length); + ee_printf("[%i] \n\r", rssi); +#endif + } + return; +} + + +/****************************************************************************** + * @fn uartSendString + * + * @brief Implements a simple uart string sender by automatically finding + * the end of line delimeter and using it to call the uart sub + * functions + * + * input parameters + * + * @param unsigned char *str + * + * output parameters + * + * @return void + * + */ +void uartSendString(char *str) +{ + unsigned char ii; + + for(ii=0;ii<UART_BUFF_SIZE;ii++) + { + if(str[ii] == 13) + { + uart_put_str(str, ii+1); + ii = UART_BUFF_SIZE; + } + } + + return; +} + +/****************************************************************************** + * @fn data_to_uart + * + * @brief Implements a simple data to hex converter by translating each + * incomming unsigned 8bit value into ascii hex. The function will + * add a space between each 8bit hex value to enable easy reading + * + * input parameters + * + * @param unsigned char *data + * unsigned char length + * + * output parameters + * + * @return unsigned char length - number of characters generated + * + */ +unsigned char data_to_uart(unsigned char *data, unsigned char length) +{ + unsigned char dd; + char str[3]; + + for (dd=0; dd<length; dd++) + { + // check to see if the next byte is a valid hex character if so convert it + byte_to_hex(data[dd], str); + uart_put_char(str[0]); + uart_put_char(str[1]); + uart_put_char(' '); + } + return dd; +} + +/****************************************************************************** + * @fn byte_to_hex + * + * @brief Implements a simple data to hex converter by translating each + * incomming unsigned 8bit value into ascii hex. + * + * input parameters + * + * @param unsigned char byte + * char *hex + * + * output parameters + * + * @return void + * + */ +void byte_to_hex(unsigned char byte, char *hex) +{ + unsigned char tmp; + unsigned char ii; + + tmp = (byte & 0xF0)>>4; + for (ii=0; ii<2; ii++) + { + if(tmp < 10) + { + hex[ii] = tmp + '0'; + } + else + { + hex[ii] = tmp - 10 + 'A'; + } + tmp = (byte & 0x0F); + } + return; +} + +/****************************************************************************** + * @fn chars_to_data + * + * @brief Implements a simple str to data converter by translating each + * incomming char value into unsigned 16bit int. The function will + * look for space's between each value to identify new values. + * + * input parameters + * + * @param unsigned char *data + * char *str + * unsigned char length + * + * output parameters + * + * @return unsigned char length - number of integers generated + * + */ +unsigned int chars_to_data(char *str, unsigned char length) +{ + unsigned int cc; + unsigned char dd, tmp; + + cc = 0; + for (dd=0; dd<length; dd++) + { + tmp = str[dd]; + cc = 10 * cc; + if((tmp >= '0') && (tmp <= '9')) + { + cc = cc + (tmp -'0'); + } + } + return cc; +} + +/****************************************************************************** + * @fn str_to_data + * + * @brief Implements a simple str to data converter by translating each + * incomming char value into unsigned 16bit int. The function will + * look for space's between each value to identify new values. + * + * input parameters + * + * @param unsigned char *data + * char *str + * unsigned char length + * + * output parameters + * + * @return unsigned char length - number of integers generated + * + */ +unsigned char str_to_data(char *str, unsigned int *data, unsigned char length) +{ + unsigned char cc, dd, ee; + + cc = 0; + ee = 0; + for (dd=0; dd<length; dd++) + { + if(str[dd] == ' ' || str[dd] == 13) { + data[ee++] = chars_to_data(&str[cc], dd-cc); + cc = dd; + } + } + return cc; +} + diff --git a/source/test/LaunchPad_trx_demo.h b/source/test/LaunchPad_trx_demo.h new file mode 100644 index 0000000..b5e8b65 --- /dev/null +++ b/source/test/LaunchPad_trx_demo.h @@ -0,0 +1,127 @@ +/****************************************************************************** + * Filename: LaunchPAD_TrxDemo.h + * + * Description: TRX_ui Range Test for various EVM boards and transcievers + * This wireless demo applications is meant to show the + * advantage of using. Frequency hopping Spread Spectrum (FHSS) + * to implement your wireless sensor network. This code base + * has been developed to run on a number of TI devices including + * most MSP430F2x and MSP430F5x series microcontrolers using stand + * alone wireless transcievers (CC2500 and CC1101/CC1100). + * + * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *******************************************************************************/ +#define DCO_MULT_1MHZ 30 +#define DCO_MULT_4MHZ 122 +#define DCO_MULT_8MHZ 244 +#define DCO_MULT_12MHZ 366 +#define DCO_MULT_16MHZ 488 +#define DCO_MULT_20MHZ 610 +#define DCO_MULT_25MHZ 763 + +#define DCORSEL_1MHZ DCORSEL_2 +#define DCORSEL_4MHZ DCORSEL_4 +#define DCORSEL_8MHZ DCORSEL_4 +#define DCORSEL_12MHZ DCORSEL_5 +#define DCORSEL_16MHZ DCORSEL_5 +#define DCORSEL_20MHZ DCORSEL_6 +#define DCORSEL_25MHZ DCORSEL_7 + +// CC State machine definition +#define CC_BOOT 1 +#define CC_IDLE 2 +#define CC_SETUP 3 +#define CC_TX_ACTIVE 4 +#define CC_RX_ACTIVE 5 +#define CC_RF_ACTIVE 6 + +// Memu system state machine variables +#define MENU_SETUP 20 +#define MENU_RESTART 21 +#define MENU_IDLE 22 +#define MENU_RF_IDLE 23 +#define MENU_TX_UNMOD 24 +#define MENU_TX_nMCU 25 +#define MENU_TX_wMCU 26 +#define MENU_RX_STATIC 27 +#define MENU_RX_SINGLE 28 +#define MENU_RX_SNIFF 29 +#define MENU_TX_BER 30 +#define MENU_RX_BER 31 +#define MENU_TX_FHSS_BER 32 +#define MENU_RX_FHSS_BER 33 + + +// Buffer sizes +#define UART_BUFF_SIZE 80 +#define TX_BUFF_SIZE 64 +#define RSSI_OFFSET 72 + +typedef struct trx_cfg { + unsigned char trx_mode; // mode of operation in progress + unsigned char cc_state; // lastest state of CC device + unsigned char cc_device_id; // ID from CC device (is it a CC1101 or CC2500) + unsigned char smartrf_selector; // Select Low, Mid or high data rate pre-config + unsigned long start_freq; // start frequency for all tasks + unsigned char rf_channel; // current RF channel + unsigned int ch_spc; // channel spacing to be used by CC device + unsigned int no_burst; // number of TX burst requested + unsigned int tx_pwr; // actual TX power to be used + unsigned long bit_rate; // TRX bitrate + unsigned char b_length; // burst length in bytes. + unsigned int packet_timer; + unsigned int normal_wait_timer; + unsigned int max_wait_timer; + unsigned int sync_timer; + unsigned int xtal_wait_timer; +} trx_cfg_struct; + + +void main_menu(trx_cfg_struct *trx_cfg); +char parse_ui_cmd(trx_cfg_struct *trx_cfg, char *ui_cmd, unsigned char ui_cmd_length); +void uartSendString(char *UART_Text); +void rf_default_setup(trx_cfg_struct *trx_cfg); +void rf_initial_setup(trx_cfg_struct *trx_cfg); +void rf_send_setup(trx_cfg_struct *trx_cfg); +void rf_get_setup(trx_cfg_struct *trx_cfg); +void unmodulated_tx(trx_cfg_struct *trx_cfg); +void modulated_tx_no_mcu(trx_cfg_struct *trx_cfg); +void rx_static(trx_cfg_struct *trx_cfg); +void tx_ber_single(unsigned char *txBuffer, trx_cfg_struct *trx_cfg); +void rx_ber_single(unsigned char *txBuffer, trx_cfg_struct *trx_cfg); +void tx_ber_fhss(unsigned char *txBuffer, trx_cfg_struct *trx_cfg); +void rx_ber_fhss(unsigned char *txBuffer, trx_cfg_struct *trx_cfg); +void rx_sniff(unsigned char *txBuffer, trx_cfg_struct *trx_cfg); +void print_rf_settings(void); +int calculate_rssi(unsigned char cc_rssi); +void generate_hopping_table(unsigned char *hop_table, unsigned char length_table); + diff --git a/source/test/LaunchPad_trx_main.c b/source/test/LaunchPad_trx_main.c new file mode 100644 index 0000000..d66b19c --- /dev/null +++ b/source/test/LaunchPad_trx_main.c @@ -0,0 +1,338 @@ +/****************************************************************************** + * Filename: LaunchPad_trx_main.c + * + * Description: TRX_ui Range Test for various EVM boards and transcievers + * This wireless demo applications is meant to show the + * advantage of using. Frequency hopping Spread Spectrum (FHSS) + * to implement your wireless sensor network. + * + * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Texas Instruments Incorporated nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *******************************************************************************/ + +/****************************************************************************** + * INCLUDES + */ +#include "msp430.h" +#include "stdio.h" +#include "radio_drv.h" +#include "cc1x_utils.h" +#include "hal_spi_rf.h" +#include "uart_drv.h" +#include "LaunchPad_trx_demo.h" + +/****************************************************************************** + * LOCAL FUNCTIONS + */ +extern void msp_setup(void); +extern unsigned long volatile time_counter; + +/****************************************************************************** + * GLOBALS + */ +char u_str[UART_BUFF_SIZE]; +unsigned char txBuffer[TX_BUFF_SIZE]; +char user_button_pushed; +unsigned char wakeup_on_wdt; +trx_cfg_struct trx_cfg; + +/****************************************************************************** + * PAYLOAD + */ +const unsigned char rand_data[60] = {49,231,121,199,255,153,138,232,220,203, + 51,253,117,172,161,191,79,58,225,215,149,251,15,163,153,236,141,172,3, + 186,224,37,224,210,75,69,117,58,153,207,61,203,19,125,76,90,143,226,11, + 208,16,72,109,217,100,12,128,228,185,142}; + + +/****************************************************************************** + * @fn main + * + * @brief Main GUI application level control loop is implemented in the + * main loop. It is a state machine that cycles thru various states + * during the interactive use by the operator. The presents a text + * based GUI, the user is then promted to type in a command with + * a given set of parameters. The state machine then calls a simpler + * parser that tries to figure out what the user wants to do. + * + * input parameters + * + * @param void + * + * output parameters + * + * @return void + * + */ +void main (void) +{ + + char idle_counter = 0; + unsigned char u_str_length; + + /* Stop WDT */ + WDTCTL = WDTPW + WDTHOLD; + + /* Setup MSP specific functions, IO's, timers and WDT */ + msp_setup(); + + /* Initialize the UART port */ + hal_uart_init(); + + /* enable uart echo function */ + uart_drv_toggle_echo(); + + /* initialize the radio subsystem */ + trx_cfg.bit_rate = radio_init(1); + trx_cfg.bit_rate = trx_cfg.bit_rate * 100; + + // Perform initial setup of the CC radio + trx_cfg.b_length = TX_BUFF_SIZE; + rf_default_setup(&trx_cfg); + + /* Configure LED ports */ + LED1_PxDIR |= LED1_PIN; + LED2_PxDIR |= LED2_PIN; + LED3_PxDIR |= LED3_PIN; + LED4_PxDIR |= LED4_PIN; + + /* default all LEDs to off */ + HAL_LED1_OFF(); + HAL_LED2_OFF(); + HAL_LED3_OFF(); + HAL_LED4_OFF(); + + /* Generally we use the WDT time wake the statemachine */ + wakeup_on_wdt = 1; + + /* indicator that button has been pressed */ + user_button_pushed = 0; + + /* Infinite loop with a 1 second timer */ + while(1) + { + + /* Put MCU in low power mode, wait for UART and blink LED */ + HAL_LED2_OFF(); + _BIS_SR(LPM0_bits + GIE); + HAL_LED2_ON(); + idle_counter++; + + /* Check to see if the user has pushed the putton and take appropriate action */ + if(user_button_pushed == 1) + { + user_button_pushed = 0; + trx_cfg.trx_mode = MENU_RX_BER; + // trx_cfg.trx_mode = MENU_RX_FHSS_BER; + } + + /* + * For each idle loop (1 second) a counter is incremented, if check to see + * if we have had 60 idle loops, if so we enter a default action. This enables + * the board to automatically start doing something (used for becoming a + * reciever in a TX/RX BER system + */ + if((idle_counter>60) && trx_cfg.cc_state == CC_IDLE) + { + trx_cfg.trx_mode = MENU_TX_BER; + // trx_cfg.trx_mode = MENU_TX_FHSS_BER; + idle_counter = 0; + } + + /* + * Check to see if the UART driver has detected an end-of-line from the user + * if we have an end-of-line event decode the command and take action + */ + if (uart_get_rx_end_of_str() == END_OF_LINE_DETECTED ) + { + uart_reset_rx_end_of_str(); + idle_counter = 0; + if(uart_get_rx_str_length() > 1) + { + trx_cfg.trx_mode = MENU_SETUP; + } else { + trx_cfg.trx_mode = MENU_IDLE; + } + } + + /* + * Main loop of state machine + */ + switch(trx_cfg.trx_mode) + { + /* print the main menu to the UART buffer */ + case MENU_RESTART: + main_menu(&trx_cfg); + trx_cfg.trx_mode = MENU_IDLE; + break; + /* command string has been found on UART, parse it */ + case MENU_SETUP: + u_str_length = uart_get_rx_str_length(); // get the number of bytes in fifo + uart_get_str(u_str, u_str_length); // retrieve all data + parse_ui_cmd(&trx_cfg, u_str, u_str_length); + break; + /* blink led to indicate alive but idle state */ + case MENU_IDLE: + HAL_LED1_TOGGLE(); + break; + /* force idle on the RF subsystem and restart the statemachine */ + case MENU_RF_IDLE: + trx_cfg.trx_mode = MENU_RESTART; + trx_cfg.cc_state = CC_IDLE; + break; + /* FCC test case, enable unmodulated TX carrier */ + case MENU_TX_UNMOD: + wakeup_on_wdt = 0; + unmodulated_tx(&trx_cfg); + trx_cfg.trx_mode = MENU_IDLE; + trx_cfg.cc_state = CC_TX_ACTIVE; + wakeup_on_wdt = 1; + break; + /* FCC test case, enable modulated TX carrier */ + case MENU_TX_nMCU: + wakeup_on_wdt = 0; + modulated_tx_no_mcu(&trx_cfg); + trx_cfg.trx_mode = MENU_IDLE; + trx_cfg.cc_state = CC_TX_ACTIVE; + wakeup_on_wdt = 1; + break; + /* ETSI test case, enable RX mode to check for LO leakage */ + case MENU_RX_STATIC: + wakeup_on_wdt = 0; + rx_static(&trx_cfg); + trx_cfg.trx_mode = MENU_IDLE; + trx_cfg.cc_state = CC_RX_ACTIVE; + wakeup_on_wdt = 1; + break; + /* Packet sniffer mode, print all date on UART port */ + case MENU_RX_SNIFF: + wakeup_on_wdt = 0; + rx_sniff(txBuffer, &trx_cfg); + trx_cfg.trx_mode = MENU_RESTART; + trx_cfg.cc_state = CC_IDLE; + wakeup_on_wdt = 1; + break; + /* TX Packet error rate mode, non frequency hopping */ + case MENU_TX_BER: + wakeup_on_wdt = 0; + tx_ber_single(txBuffer, &trx_cfg); + wakeup_on_wdt = 1; + trx_cfg.trx_mode = MENU_RESTART; + trx_cfg.cc_state = CC_IDLE; + break; + /* RX Packet error rate mode, non frequency hopping */ + case MENU_RX_BER: + wakeup_on_wdt = 0; + rx_ber_single(txBuffer, &trx_cfg); + wakeup_on_wdt = 1; + trx_cfg.trx_mode = MENU_RESTART; + trx_cfg.cc_state = CC_IDLE; + break; + /* TX Packet error rate mode, with frequency hopping */ + case MENU_TX_FHSS_BER: + wakeup_on_wdt = 0; + tx_ber_fhss(txBuffer, &trx_cfg); + wakeup_on_wdt = 1; + trx_cfg.trx_mode = MENU_RESTART; + trx_cfg.cc_state = CC_IDLE; + break; + /* RX Packet error rate mode, with frequency hopping */ + case MENU_RX_FHSS_BER: + wakeup_on_wdt = 0; + rx_ber_fhss(txBuffer, &trx_cfg); + wakeup_on_wdt = 1; + trx_cfg.trx_mode = MENU_RESTART; + trx_cfg.cc_state = CC_IDLE; + break; + default: + trx_cfg.trx_mode = MENU_RESTART; + break; + } + } +} + + +/****************************************************************************** + * @fn wdt_isr + * + * @brief Interrupt service routine for watch dog timer. + * + * input parameters + * + * @param void + * + * output parameters + * + * @return void + * + */ +#pragma vector=WDT_VECTOR +__interrupt void wdt_isr (void) +{ + /* global "1-second" counter used for printing time stamped packet sniffer data */ + time_counter++; + + /* check to see if wake on wdt is enabled */ + if(wakeup_on_wdt == 1) + { + + /* exit from low power mode on ISR exit */ + _BIC_SR_IRQ(LPM3_bits); + } +} + + +/****************************************************************************** + * @fn button_isr + * + * @brief Interrupt service routine for button function + * + * input parameters + * + * @param void + * + * output parameters + * + * @return void + * + */ +#pragma vector=BUTTON_VECTOR +__interrupt void button_isr(void) +{ + /* reset the RF_GDO_PIN */ + BUTTON_PxIFG &= ~BUTTON_PIN; + + /* indicate button event */ + user_button_pushed = 1; + + /* exit from low power mode on ISR exit */ + _BIC_SR_IRQ(LPM3_bits); +} diff --git a/source/test/main_rxer.c b/source/test/main_rxer.c deleted file mode 100644 index e69de29..0000000 diff --git a/source/test/main_txer.c b/source/test/main_txer.c deleted file mode 100644 index e69de29..0000000 -- GitLab