You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

539 lines
18 KiB
C

/***************************************************************************//**
* @file
* @brief This header file defines variables to be shared between the main
* test application and customer specific sections.
*******************************************************************************
* # License
* <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
*******************************************************************************
*
* SPDX-License-Identifier: Zlib
*
* The licensor of this software is Silicon Laboratories Inc.
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
******************************************************************************/
#ifndef __APPS_COMMON_H__
#define __APPS_COMMON_H__
#include "sl_cli.h"
#include "em_gpio.h" // For ButtonArray definition
#include "circular_queue.h"
#include "rail_types.h"
#include "rail_ble.h"
#include "rail_zwave.h"
#include "pa_conversions_efr32.h"
#include "sl_rail_util_init_inst0_config.h"
#include "sl_rail_test_config.h"
#if SL_RAIL_UTIL_INIT_RADIO_CONFIG_SUPPORT_INST0_ENABLE
#include "rail_config.h"
#endif
/******************************************************************************
* Macros
*****************************************************************************/
#define RAILTEST_PRINTF(...) \
do { \
if (printingEnabled) { \
printf(__VA_ARGS__); \
} \
} while (false)
#ifdef RAIL_MULTIPROTOCOL
#define CHECK_RAIL_HANDLE(command) \
do { \
if (!checkRailHandle(command)) { \
return; \
} \
\
} while (0)
#else //RAIL_MULTIPROTOCOL
#define CHECK_RAIL_HANDLE(command) //no-op
#endif //RAIL_MULTIPROTOCOL
/******************************************************************************
* Constants
*****************************************************************************/
#define COUNTOF(a) (sizeof(a) / sizeof(a[0]))
#define TX_CONTINUOUS_COUNT (0xFFFFFFFF)
#define RAIL_EVENT_STRINGS \
{ \
"RSSI_AVERAGE_DONE", \
"RX_ACK_TIMEOUT", \
"RX_FIFO_ALMOST_FULL", \
"RX_PACKET_RECEIVED", \
"RX_PREAMBLE_LOST", \
"RX_PREAMBLE_DETECT", \
"RX_SYNC1_DETECT", \
"RX_SYNC2_DETECT", \
"RX_FRAME_ERROR", \
"RX_FIFO_FULL", \
"RX_FIFO_OVERFLOW", \
"RX_ADDRESS_FILTERED", \
"RX_TIMEOUT", \
"SCHEDULED_RX/TX_STARTED", \
"RX_SCHEDULED_RX_END", \
"RX_SCHEDULED_RX_MISSED", \
"RX_PACKET_ABORTED", \
"RX_FILTER_PASSED", \
"RX_TIMING_LOST", \
"RX_TIMING_DETECT", \
"RX_CHANNEL_HOPPING_COMPLETE/RX_DUTY_CYCLE_RX_END", \
"IEEE802154_DATA_REQUEST_COMMAND/ZWAVE_BEAM", \
"TX_FIFO_ALMOST_EMPTY", \
"TX_PACKET_SENT", \
"TXACK_PACKET_SENT", \
"TX_ABORTED", \
"TXACK_ABORTED", \
"TX_BLOCKED", \
"TXACK_BLOCKED", \
"TX_UNDERFLOW", \
"TXACK_UNDERFLOW", \
"TX_CHANNEL_CLEAR", \
"TX_CHANNEL_BUSY", \
"TX_CCA_RETRY", \
"TX_START_CCA", \
"TX_STARTED", \
"TX_SCHEDULED_TX_MISSED", \
"CONFIG_UNSCHEDULED", \
"CONFIG_SCHEDULED", \
"SCHEDULED_STATUS", \
"CAL_NEEDED", \
"RF_SENSED", \
"PA_PROTECTION", \
}
// Since channel hopping is pretty space intensive, put some limitations on it
// 125 32 bit words per channel should be plenty
// MAX_NUMBER_CHANNELS can generally be safely increased if more channels
// are needed for a channel hopping sequencer, the only limit being chip
// flash size
#if (_SILICON_LABS_32B_SERIES_2_CONFIG >= 2)
#define MAX_NUMBER_CHANNELS 6 // up to 4 (9.6, 40, 100, LR) + 2 for conc. autoack (9.6 and 40)
#define CHANNEL_HOPPING_BUFFER_SIZE (1050U)
#else
#define MAX_NUMBER_CHANNELS 4
#define CHANNEL_HOPPING_BUFFER_SIZE (200U * MAX_NUMBER_CHANNELS)
#endif
extern uint32_t channelHoppingBufferSpace[CHANNEL_HOPPING_BUFFER_SIZE];
/******************************************************************************
* Variable Export
*****************************************************************************/
typedef struct PhySwitchToRx{
bool enable;
bool disableWhitening;
RAIL_BLE_Phy_t phy;
uint16_t physicalChannel;
uint16_t logicalChannel;
uint32_t timeDelta;
uint32_t crcInit;
uint32_t accessAddress;
} PhySwitchToRx_t;
typedef enum RailTxType {
TX_TYPE_NORMAL,
TX_TYPE_CSMA,
TX_TYPE_LBT
} RailTxType_t;
typedef struct ButtonArray {
GPIO_Port_TypeDef port;
unsigned int pin;
} ButtonArray_t;
typedef enum RailAppEventType {
RAIL_EVENT,
RX_PACKET,
BEAM_PACKET,
MULTITIMER,
AVERAGE_RSSI,
} RailAppEventType_t;
typedef enum RailRfSenseMode {
RAIL_RFSENSE_MODE_OFF,
RAIL_RFSENSE_MODE_ENERGY_DETECTION,
RAIL_RFSENSE_MODE_SELECTIVE_OOK,
} RailRfSenseMode_t;
typedef struct ZWaveBeamData {
/**
* The channel index in the currently configured channel hopping scheme
* on which the beam was received.
*/
uint8_t channelIndex;
/**
* If a long range beam is received, it will hold the Tx Power at which
* the beam was sent.
*/
uint8_t lrBeamTxPower;
/**
* The node ID contained in the received beam frame.
*/
RAIL_ZWAVE_NodeId_t nodeId;
} ZWaveBeamData_t;
typedef struct RxPacketData {
/**
* A structure containing the extra information associated with this received
* packet.
*/
RAIL_RxPacketDetails_t appendedInfo;
/**
* The railHandle on which this packet was received.
*/
RAIL_Handle_t railHandle;
/**
* A pointer to a buffer that holds receive packet data bytes.
*/
uint8_t *dataPtr;
/**
* The number of bytes that are in the dataPtr array.
*/
uint16_t dataLength;
/**
* The packet's frequency offset
*/
RAIL_FrequencyOffset_t freqOffset;
/**
* The packet's status
*/
RAIL_RxPacketStatus_t packetStatus;
/**
* A bitmask representing which address filter(s) this packet
* has passed.
*/
RAIL_AddrFilterMask_t filterMask;
} RxPacketData_t;
typedef struct RailEvent {
// Use uint32_t array for events rather than RAIL_Events_t to reduce
// alignment requirement and hence reduce sizeof(RailEvent_t).
uint32_t events[sizeof(RAIL_Events_t) / sizeof(uint32_t)];
uint32_t timestamp;
RAIL_Handle_t handle;
uint32_t parameter; /**< This field is open to interpretation based on the event type.
It may hold information related to the event e.g. status. */
} RailEvent_t;
typedef struct Multitimer {
RAIL_Time_t currentTime;
RAIL_Time_t expirationTime;
uint32_t index;
} Multitimer_t;
typedef struct AverageRssi {
int16_t rssi;
} AverageRssi_t;
typedef struct RailAppEvent {
RailAppEventType_t type;
union {
RxPacketData_t rxPacket;
ZWaveBeamData_t beamPacket;
RailEvent_t railEvent;
Multitimer_t multitimer;
AverageRssi_t rssi;
};
} RailAppEvent_t;
typedef struct Stats{
uint32_t samples;
int32_t min;
int32_t max;
float mean;
float varianceTimesSamples;
} Stats_t;
typedef struct Counters{
// Counts all successful user transmits
// "user" in this and following variable names refers to
// a transmit that a user initiated, i.e. not an ack
uint32_t userTx;
// Counts all successful ack transmits
uint32_t ackTx;
uint32_t userTxAborted;
uint32_t ackTxAborted;
uint32_t userTxBlocked;
uint32_t ackTxBlocked;
uint32_t userTxUnderflow;
uint32_t ackTxUnderflow;
uint32_t ackTxFpSet;
uint32_t ackTxFpFail;
uint32_t ackTxFpAddrFail;
// Counts all users transmits that get on-air (when TX_STARTED event enabled)
uint32_t userTxStarted;
// Channel busy doesn't differentiate
// between ack/user packets
uint32_t txChannelBusy;
uint32_t receive;
uint32_t syncDetect;
uint32_t preambleLost;
uint32_t preambleDetect;
uint32_t frameError;
uint32_t rxOfEvent;
uint32_t addrFilterEvent;
uint32_t rxFail;
uint32_t calibrations;
uint32_t noRxBuffer;
uint32_t rfSensedEvent;
uint32_t perTriggers;
uint32_t ackTimeout;
uint32_t lbtSuccess;
uint32_t lbtRetry;
uint32_t lbtStartCca;
uint32_t txFifoAlmostEmpty;
uint32_t rxFifoAlmostFull;
uint32_t rxFifoFull;
uint32_t timingLost;
uint32_t timingDetect;
uint32_t radioConfigChanged;
uint32_t rxBeams;
uint32_t dataRequests;
Stats_t rssi;
uint32_t paProtect;
} Counters_t;
typedef RAIL_Status_t (*TxTimestampFunc)(RAIL_Handle_t, RAIL_TxPacketDetails_t *);
typedef RAIL_Status_t (*RxTimestampFunc)(RAIL_Handle_t, RAIL_RxPacketDetails_t *);
extern const char* eventNames[];
extern uint8_t numRailEvents;
extern bool printingEnabled;
extern PhySwitchToRx_t phySwitchToRx;
extern Counters_t counters;
extern int currentConfig;
extern bool receiveModeEnabled;
extern RAIL_RadioState_t rxSuccessTransition;
extern bool transmitting;
extern bool txParameterChanged;
extern uint16_t channel;
extern uint8_t configIndex;
extern uint32_t continuousTransferPeriod;
extern bool enableRandomTxDelay;
extern int32_t txCount;
extern uint32_t txAfterRxDelay;
extern int32_t txCancelDelay;
extern RAIL_StopMode_t txCancelMode;
extern RAIL_ChannelConfigEntry_t channels[];
extern const RAIL_ChannelConfig_t channelConfig;
extern bool skipCalibrations;
extern bool schRxStopOnRxEvent;
extern volatile bool serEvent;
extern volatile bool rxPacketEvent;
extern uint32_t perCount;
extern uint32_t perDelay;
extern uint32_t rxOverflowDelay;
extern uint32_t dataReqLatencyUs;
extern bool afterRxCancelAck;
extern bool afterRxUseTxBufferForAck;
extern volatile bool newTxError;
extern volatile uint32_t failPackets;
extern RAIL_Events_t enablePrintEvents;
extern bool printRxErrorPackets;
extern bool printRxFreqOffsetData;
extern RAIL_VerifyConfig_t configVerify;
extern uint32_t internalTransmitCounter;
extern const char buildDateTime[];
extern bool ieee802154EnhAckEnabled;
extern uint8_t ieee802154PhrLen; // 15.4 PHY Header Length (1 or 2 bytes)
extern TxTimestampFunc txTimePosition;
extern RxTimestampFunc rxTimePosition;
extern RAIL_StreamMode_t streamMode;
extern bool rxHeld;
extern volatile bool rxProcessHeld;
extern volatile uint32_t packetsHeld;
#ifdef SL_RAIL_UTIL_IC_SIMULATION_BUILD
#define PERIPHERAL_ENABLE (0x00)
#define ASYNC_RESPONSE (0x00)
#else
#define PERIPHERAL_ENABLE (0x01)
#define ASYNC_RESPONSE (0x02)
#endif
extern uint8_t logLevel;
extern uint8_t txData[SL_RAIL_TEST_MAX_PACKET_LENGTH];
extern uint16_t txDataLen;
extern uint8_t ackData[RAIL_AUTOACK_MAX_LENGTH];
extern uint8_t ackDataLen;
extern RailTxType_t txType;
extern RAIL_LbtConfig_t *lbtConfig;
extern RAIL_CsmaConfig_t *csmaConfig;
// Structure that holds txOptions
extern RAIL_TxOptions_t txOptions;
// Structure that holds Antenna Options
extern RAIL_TxOptions_t antOptions;
// Structure that holds (default) rxOptions
extern RAIL_RxOptions_t rxOptions;
// Data Management
extern Queue_t railAppEventQueue;
extern volatile uint32_t eventsMissed;
extern RAIL_DataConfig_t railDataConfig;
// Fifo mode Test bits
extern bool rxFifoManual;
extern bool txFifoManual;
// RAIL instance handle
extern RAIL_Handle_t railHandle;
// Indicator of whether or not to print tx acks as they happens
extern bool printTxAck;
// Strings representing the possible PA selections
extern const char* paStrings[];
// LQI offset variable
extern int16_t lqiOffset;
// Verify config in RAILCb_RadioConfigChanged
extern bool verifyConfigEnabled;
// Variable containing current RSSI
extern float averageRssi;
// Channel Hopping configuration structures
extern uint32_t* channelHoppingBuffer;
// Variable containing current receive frequency offset
extern RAIL_FrequencyOffset_t rxFreqOffset;
/**
* @enum AppMode
* @brief Enumeration of RAILtest transmit states.
*/
typedef enum AppMode{
NONE = 0, /**< RAILtest is not doing anything special */
TX_STREAM = 1, /**< Send a stream of pseudo-random bits */
TX_CONTINUOUS = 3, /**< Send an unending stream of packets*/
DIRECT = 4, /**< Send data to and from a GPIO, without any packet handling */
TX_N_PACKETS = 5, /**< Send a specific number of packets */
TX_SCHEDULED = 6, /**< Send one packet scheduled in the future */
SCHTX_AFTER_RX = 7, /**< Schedule a TX for a fixed delay after receiving a packet */
RX_OVERFLOW = 8, /**< Cause overflow on receive */
TX_UNDERFLOW = 9, /**< Cause underflows on the next TX sequence */
TX_CANCEL = 10, /**< Cancel a single packet transmit to force an error event */
RF_SENSE = 11, /**< Sense RF energy to wake the radio */
PER = 12, /**< Packet Error Rate test mode */
BER = 13, /**< Bit Error Rate test mode */
RX_SCHEDULED = 14, /**< Enable receive at a time scheduled in the future */
} AppMode_t;
/**
* @enum RailTxType
* @brief Enumeration of the types of tx available in RAIL
*
* These are used to decide which type of tx to do, based on
* what's been configured in RAILtest. Scheduled is not included
* as RAILtest handles it somewhat separately.
*/
void sl_rail_test_internal_app_init(void);
void sl_rail_test_internal_app_process_action(void);
void RAILCb_TimerExpired(RAIL_Handle_t railHandle);
void RAILCb_SwTimerExpired(RAIL_Handle_t railHandle);
AppMode_t previousAppMode(void);
AppMode_t currentAppMode(void);
void enableAppMode(AppMode_t appMode, bool enable, char *command);
bool enableAppModeSync(AppMode_t appMode, bool enable, char *command);
void setNextAppMode(AppMode_t appMode, char *command);
void changeAppModeIfPending();
const char *appModeNames(AppMode_t appMode);
bool inAppMode(AppMode_t appMode, char *command);
bool inRadioState(RAIL_RadioState_t state, char *command);
bool parseTimeModeFromString(char *str, RAIL_TimeMode_t *mode);
const char *configuredRxAntenna(RAIL_RxOptions_t rxOptions);
void updateStats(int32_t newValue, Stats_t *stats);
void rfSensedCheck(void);
RAIL_FrequencyOffset_t getRxFreqOffset(void);
void changeChannel(uint32_t i);
void pendPacketTx(void);
RAIL_RxPacketHandle_t processRxPacket(RAIL_Handle_t railHandle,
RAIL_RxPacketHandle_t packetHandle);
void pendFinishTxSequence(void);
void pendFinishTxAckSequence(void);
void radioTransmit(uint32_t iterations, char *command);
void configureTxAfterRx(uint32_t delay, bool enable, char *command);
void scheduleNextTx(void);
void printPacket(char *cmdName,
uint8_t *data,
uint16_t dataLength,
RxPacketData_t *packetInfo);
void updateGraphics(void);
void enableGraphics(void);
void disableGraphics(void);
void initButtons(void);
void deinitButtons(void);
void LedSet(int led);
void LedToggle(int led);
void LedsDisable(void);
void appHalInit(void);
void PeripheralDisable(void);
void PeripheralEnable(void);
void usDelay(uint32_t microseconds);
void serialWaitForTxIdle(void);
void enqueueEvents(RAIL_Events_t events);
void rxFifoPrep(void);
void printRailEvents(RailEvent_t *railEvent);
void printRailAppEvents(void);
RAIL_Status_t chooseTxType(void);
const char *getRfStateName(RAIL_RadioState_t state);
char *getRfStateDetailName(RAIL_RadioState_t state, char *buffer);
const char *getStatusMessage(RAIL_Status_t status);
void disableIncompatibleProtocols(RAIL_PtiProtocol_t newProtocol);
bool checkRailHandle(char *command);
bool getRxDutyCycleSchedWakeupEnable(RAIL_Time_t *sleepInterval);
void RAILCb_TxPacketSent(RAIL_Handle_t railHandle, bool isAck);
void RAILCb_RxPacketAborted(RAIL_Handle_t railHandle);
void RAILCb_RxPacketReceived(RAIL_Handle_t railHandle);
void RAILCb_TxFifoAlmostEmpty(RAIL_Handle_t railHandle);
void RAILCb_RxFifoAlmostFull(RAIL_Handle_t railHandle);
void RAILCb_RxChannelHoppingComplete(RAIL_Handle_t railHandle);
void RAILCb_IEEE802154_DataRequestCommand(RAIL_Handle_t railHandle);
void RAILCb_ZWAVE_BeamFrame(RAIL_Handle_t railHandle);
void printAddresses(sl_cli_command_arg_t *args);
void getAddressFilter(sl_cli_command_arg_t *args);
void printTxPacket(sl_cli_command_arg_t *args);
void resetCounters(sl_cli_command_arg_t *args);
#endif // __APPS_COMMON_H__