Adwait D
/
SX126X_TXonly
Transmit only code for SX1262 LoRa experiments
main_txonly.cpp
- Committer:
- adwaitnd
- Date:
- 2020-07-16
- Revision:
- 3:1d624648c88e
- Parent:
- 2:46047d562278
File content as of revision 3:1d624648c88e:
/*! * \file main_pingpong.cpp * * \brief Ping implementation * * \copyright Revised BSD License, see section \ref LICENSE. * * \code * - Changed to be transmit only code * ______ _ * / _____) _ | | * ( (____ _____ ____ _| |_ _____ ____| |__ * \____ \| ___ | (_ _) ___ |/ ___) _ \ * _____) ) ____| | | || |_| ____( (___| | | | * (______/|_____)_|_|_| \__)_____)\____)_| |_| * (C)2013-2018 Semtech * * \endcode * */ #include "mbed.h" #include "sx126x-hal.h" #include "sx126x.h" //#include "debug.h" #define SEND_PING_BEAT_US 300000 #define RX_TIMEOUT_US 200000 /* Set this flag to '1' to display debug messages on the console */ #define DEBUG_MESSAGE 1 /* Set this flag to '1' to use the LoRa modulation or to '0' to use FSK modulation */ #define USE_MODEM_LORA 1 #define USE_MODEM_FSK !USE_MODEM_LORA #define RF_FREQUENCY 434000000 // Hz #define TX_OUTPUT_POWER 10 // max 14 dBm #if USE_MODEM_LORA == 1 #define LORA_BANDWIDTH LORA_BW_125 // [0: 125 kHz, // 1: 250 kHz, // 2: 500 kHz, // 3: Reserved] #define LORA_SPREADING_FACTOR LORA_SF10 // [SF7..SF12] #define LORA_LOWDATARATEOPTIMIZE 0 #define LORA_CODINGRATE LORA_CR_4_5 // [1: 4/5, // 2: 4/6, // 3: 4/7, // 4: 4/8] #define LORA_PREAMBLE_LENGTH 8 // Same for Tx and Rx #define LORA_SYMBOL_TIMEOUT 5 // Symbols #define LORA_HEADER_TYPE LORA_PACKET_VARIABLE_LENGTH #define LORA_FHSS_ENABLED false #define LORA_NB_SYMB_HOP 4 #define LORA_IQ LORA_IQ_NORMAL #define LORA_CRC_MODE LORA_CRC_OFF #elif USE_MODEM_FSK == 1 #define FSK_FDEV 25000 // Hz #define FSK_DATARATE 19200 // bps #define FSK_BANDWIDTH RX_BW_93800 // Hz #define FSK_MODULATION_SHAPPING MOD_SHAPING_G_BT_05 #define FSK_PREAMBLE_LENGTH 5 // Same for Tx and Rx #define FSK_HEADER_TYPE RADIO_PACKET_VARIABLE_LENGTH #define FSK_CRC_MODE RADIO_CRC_2_BYTES_CCIT #define FSK_ADDR_FILTERING RADIO_ADDRESSCOMP_FILT_NODE; #define FSK_WHITENING_MODE RADIO_DC_FREE_OFF #define FSK_PREAMBLE_DETECTOR_MODE RADIO_PREAMBLE_DETECTOR_OFF #define FSK_SYNCWORD_LENGTH 8 #else #error "Please define a modem in the compiler options." #endif #define RX_TIMEOUT_VALUE 3500 // in ms #define BUFFER_SIZE 32 // Define the payload size here #if( defined ( TARGET_KL25Z ) || defined ( TARGET_LPC11U6X ) ) DigitalOut led( LED2 ); #else DigitalOut led( LED1 ); #endif //DigitalOut led1( LED1 ); //DigitalOut led2( LED2 ); /* * Callback functions prototypes */ /*! * @brief Function to be executed on Radio Tx Done event */ void OnTxDone( void ); /*! * @brief Function to be executed on Radio Rx Done event */ void OnRxDone( void ); /*! * @brief Function executed on Radio Tx Timeout event */ void OnTxTimeout( void ); /*! * @brief Function executed on Radio Rx Timeout event */ void OnRxTimeout( void ); /*! * @brief Function executed on Radio Rx Error event */ void OnRxError( IrqErrorCode_t errCode ); /*! * @brief Function executed on Radio Fhss Change Channel event */ void OnFhssChangeChannel( uint8_t channelIndex ); typedef struct{ RadioPacketTypes_t packetType; int8_t txPower; RadioRampTimes_t txRampTime; ModulationParams_t modParams; PacketParams_t packetParams; uint32_t rfFrequency; uint16_t irqTx; uint16_t irqRx; uint32_t txTimeout; uint32_t rxTimeout; }RadioConfigurations_t; RadioConfigurations_t radioConfiguration; /* * Global variables declarations */ typedef enum { SEND_PACKET, WAIT_SEND_DONE, }AppStates_t; volatile AppStates_t State = SEND_PACKET; typedef struct{ bool rxDone; bool rxError; bool txDone; bool rxTimeout; bool txTimeout; }RadioFlags_t; RadioFlags_t radioFlags = { .txDone = false, .txTimeout = false, }; /*! * Radio events function pointer */ static RadioCallbacks_t RadioEvents = { .txDone = &OnTxDone, .txTimeout = &OnTxTimeout, .rxDone = NULL, .rxPreambleDetect = NULL, .rxHeaderDone = NULL, .rxTimeout = NULL, .rxError = NULL, .cadDone = NULL, }; /* * Global variables declarations */ //Radio Radio( NULL ); #define MESSAGE_SIZE 4 typedef uint8_t Messages_t[MESSAGE_SIZE]; const Messages_t PingMsg = {'P', 'I', 'N', 'G'}; const Messages_t *messageToSend = &PingMsg; SX126xHal Radio( D11, D12, D13, D7, D3, D5, NC, NC, A0, A1, A2, D8, &RadioEvents ); void SetToMaster(void); void RunTXStateMachine(); void SetConfiguration(RadioConfigurations_t *config); void ConfigureGeneralRadio(SX126xHal *radio, RadioConfigurations_t *config); void ConfigureRadioTx(SX126xHal *radio, RadioConfigurations_t *config); void PrepareBuffer(SX126xHal *radio, const Messages_t *messageToSend); bool proceed = true; uint32_t count = 0; // function to run void MasterSendNextEvent(void) { proceed = true; } Ticker masterSendNextTicker; Serial serial(USBTX, USBRX); int main( void ) { Radio.Reset(); Radio.Init(); serial.baud(115200); SetConfiguration(&radioConfiguration); ConfigureGeneralRadio(&Radio, &radioConfiguration); // initialize transmitter printf("-->TX mode\n"); State = SEND_PACKET; messageToSend = &PingMsg; masterSendNextTicker.attach_us(&MasterSendNextEvent, SEND_PING_BEAT_US); while(true){ RunTXStateMachine(); } } // let's keep the state machine because waiting for transmission to be done // will take multiple instances of the state machine running. We could use a // for loop, but the state machine seems g void RunTXStateMachine(){ switch(State){ case SEND_PACKET:{ if (proceed == true) { // wait for timer to say it's fine to proceed with transmission proceed = false; count++; PrepareBuffer(&Radio, messageToSend); ConfigureRadioTx(&Radio, &radioConfiguration); Radio.SetTx(radioConfiguration.txTimeout); printf("%u: TX", count); State = WAIT_SEND_DONE; } break; } case WAIT_SEND_DONE:{ if(radioFlags.txDone){ // transmission successful, wait radioFlags.txDone = false; // reset interrupted flag printf(" done\r\n"); State = SEND_PACKET; } if(radioFlags.txTimeout){ // transmission failed, try again! radioFlags.txTimeout = false; // reset interrupted flag printf(" err\r\n"); State = SEND_PACKET; } break; } } } // Interrupt handler functions - Adwait void SetToMaster(){ } void OnTxDone( void ) { radioFlags.txDone = true; } void OnTxTimeout( void ) { radioFlags.txTimeout = true; debug_if( DEBUG_MESSAGE, "> OnTxTimeout\n\r" ); } // Other helper functions - Adwait void SetConfiguration(RadioConfigurations_t *config){ config->irqRx = IRQ_RX_DONE | IRQ_RX_TX_TIMEOUT; config->irqTx = IRQ_TX_DONE | IRQ_RX_TX_TIMEOUT; config->rfFrequency = RF_FREQUENCY; config->txTimeout = 0; config->rxTimeout = (uint32_t)(RX_TIMEOUT_US / 15.625); config->txPower = TX_OUTPUT_POWER; config->txRampTime = RADIO_RAMP_200_US; #if USE_MODEM_LORA == 1 config->packetType = PACKET_TYPE_LORA; config->modParams.PacketType = PACKET_TYPE_LORA; config->modParams.Params.LoRa.Bandwidth = LORA_BANDWIDTH; config->modParams.Params.LoRa.CodingRate = LORA_CODINGRATE; config->modParams.Params.LoRa.LowDatarateOptimize = LORA_LOWDATARATEOPTIMIZE; config->modParams.Params.LoRa.SpreadingFactor = LORA_SPREADING_FACTOR; config->packetParams.PacketType = PACKET_TYPE_LORA; config->packetParams.Params.LoRa.CrcMode = LORA_CRC_MODE; config->packetParams.Params.LoRa.HeaderType = LORA_HEADER_TYPE; config->packetParams.Params.LoRa.InvertIQ = LORA_IQ; config->packetParams.Params.LoRa.PayloadLength = BUFFER_SIZE; config->packetParams.Params.LoRa.PreambleLength = LORA_PREAMBLE_LENGTH; #elif USE_MODEM_FSK == 1 config->packetType = PACKET_TYPE_GFSK; config->modParams.PacketType = PACKET_TYPE_GFSK; config->modParams.Params.Gfsk.Bandwidth = FSK_BANDWIDTH; config->modParams.Params.Gfsk.BitRate = 1024000000 / FSK_DATARATE; config->modParams.Params.Gfsk.Fdev = FSK_FDEV * 1.048576; config->modParams.Params.Gfsk.ModulationShaping = FSK_MODULATION_SHAPPING; config->packetParams.PacketType = PACKET_TYPE_GFSK; config->packetParams.Params.Gfsk.AddrComp = FSK_ADDR_FILTERING; config->packetParams.Params.Gfsk.CrcLength = FSK_CRC_MODE; config->packetParams.Params.Gfsk.DcFree = FSK_WHITENING_MODE; config->packetParams.Params.Gfsk.HeaderType = FSK_HEADER_TYPE; config->packetParams.Params.Gfsk.PayloadLength = BUFFER_SIZE; config->packetParams.Params.Gfsk.PreambleLength = FSK_PREAMBLE_LENGTH; config->packetParams.Params.Gfsk.PreambleMinDetect = FSK_PREAMBLE_DETECTOR_MODE; config->packetParams.Params.Gfsk.SyncWordLength = FSK_SYNCWORD_LENGTH; #endif } void ConfigureGeneralRadio(SX126xHal *radio, RadioConfigurations_t *config){ radio->SetPacketType(config->packetType); radio->SetPacketParams(&config->packetParams); radio->SetModulationParams(&config->modParams); radio->SetRfFrequency(config->rfFrequency); radio->SetTxParams(config->txPower, config->txRampTime); radio->SetInterruptMode(); if(config->packetType == PACKET_TYPE_GFSK){ uint8_t syncword[8] = {0xF0, 0x0F, 0x55, 0xAA, 0xF0, 0x0F, 0x55, 0xAA}; radio->SetSyncWord(syncword); } } void ConfigureRadioTx(SX126xHal *radio, RadioConfigurations_t *config){ radio->SetDioIrqParams(config->irqTx, config->irqTx, IRQ_RADIO_NONE, IRQ_RADIO_NONE); } void PrepareBuffer(SX126xHal *radio, const Messages_t *messageToSend){ radio->SetPayload((uint8_t*)messageToSend, MESSAGE_SIZE); }