Simple transmitter application for SX127x radio.

Dependencies:   MbedJSONValue SX127x sx12xx_hal

Committer:
corymast
Date:
Fri Sep 06 22:59:36 2019 +0000
Revision:
4:b2fc780be0b3
Parent:
3:5e25ec621190
Child:
5:a8b4e0857e8b
Added JSON functionality.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
LoRaToolbox 0:44fb2db84011 1 #include "radio.h"
corymast 3:5e25ec621190 2 #include "mbed.h"
corymast 3:5e25ec621190 3 #include "platform/CircularBuffer.h"
corymast 3:5e25ec621190 4 #include "MbedJSONValue/MbedJSONValue.h"
LoRaToolbox 0:44fb2db84011 5
LoRaToolbox 1:b277f5a65c1c 6 // Semtech radio definitions for SX127x, SX126x and SX128x
LoRaToolbox 1:b277f5a65c1c 7
LoRaToolbox 0:44fb2db84011 8 #if defined(SX127x_H)
LoRaToolbox 0:44fb2db84011 9 #define BW_KHZ 500
LoRaToolbox 0:44fb2db84011 10 #define SPREADING_FACTOR 11
LoRaToolbox 0:44fb2db84011 11 #define CF_HZ 912000000
LoRaToolbox 0:44fb2db84011 12 #define TX_DBM 20
LoRaToolbox 0:44fb2db84011 13 #elif defined(SX126x_H)
LoRaToolbox 0:44fb2db84011 14 #define BW_KHZ 500
LoRaToolbox 0:44fb2db84011 15 #define SPREADING_FACTOR 10
LoRaToolbox 0:44fb2db84011 16 #define CF_HZ 915000000
LoRaToolbox 0:44fb2db84011 17 #define TX_DBM (Radio::chipType == CHIP_TYPE_SX1262 ? 20 : 14)
LoRaToolbox 0:44fb2db84011 18 #elif defined(SX128x_H)
LoRaToolbox 0:44fb2db84011 19 #define BW_KHZ 200
LoRaToolbox 0:44fb2db84011 20 #define SPREADING_FACTOR 7
LoRaToolbox 0:44fb2db84011 21 #define CF_HZ 2487000000
LoRaToolbox 0:44fb2db84011 22 #define TX_DBM 6
LoRaToolbox 0:44fb2db84011 23 #endif
LoRaToolbox 0:44fb2db84011 24
corymast 3:5e25ec621190 25 // The buffer size should match the tx_buf length in sx12xx.h
corymast 3:5e25ec621190 26 #define BUF_SIZE 256
corymast 3:5e25ec621190 27
LoRaToolbox 1:b277f5a65c1c 28 /******************** Setup radio transmitter ****************************/
LoRaToolbox 1:b277f5a65c1c 29
corymast 4:b2fc780be0b3 30 // Configure the User button as an interrupt
corymast 4:b2fc780be0b3 31 InterruptIn button(USER_BUTTON, PullUp);
corymast 4:b2fc780be0b3 32
corymast 4:b2fc780be0b3 33 // Initialize global variables
corymast 4:b2fc780be0b3 34 uint8_t seq = 0; // Set initial transmit sequence to 0
LoRaToolbox 0:44fb2db84011 35 volatile bool txDone;
corymast 3:5e25ec621190 36 CircularBuffer<uint8_t, BUF_SIZE> msg;
corymast 4:b2fc780be0b3 37 MbedJSONValue message;
corymast 4:b2fc780be0b3 38 Timer t;
LoRaToolbox 0:44fb2db84011 39
corymast 4:b2fc780be0b3 40 // Transmit Done Callback Handler
LoRaToolbox 0:44fb2db84011 41 void txDoneCB()
LoRaToolbox 0:44fb2db84011 42 {
LoRaToolbox 0:44fb2db84011 43 txDone = true;
corymast 4:b2fc780be0b3 44 printf("Tx Done.\r\n");
LoRaToolbox 0:44fb2db84011 45 }
LoRaToolbox 0:44fb2db84011 46
corymast 4:b2fc780be0b3 47 // Receive Done Callback Handler
LoRaToolbox 0:44fb2db84011 48 void rxDoneCB(uint8_t size, float rssi, float snr)
LoRaToolbox 0:44fb2db84011 49 {
corymast 4:b2fc780be0b3 50 printf("Rx Done.\r\n");
LoRaToolbox 0:44fb2db84011 51 }
LoRaToolbox 0:44fb2db84011 52
corymast 4:b2fc780be0b3 53 // Transmit Timeout Callback Handler
corymast 4:b2fc780be0b3 54 void txTimeoutCB()
corymast 4:b2fc780be0b3 55 {
corymast 4:b2fc780be0b3 56 printf("Tx Timeout.\r\n");
corymast 4:b2fc780be0b3 57 }
LoRaToolbox 1:b277f5a65c1c 58
corymast 4:b2fc780be0b3 59 // Define radio events for transmitter
LoRaToolbox 0:44fb2db84011 60 const RadioEvents_t rev = {
LoRaToolbox 0:44fb2db84011 61 /* Dio0_top_half */ NULL,
LoRaToolbox 0:44fb2db84011 62 /* TxDone_topHalf */ NULL,
LoRaToolbox 0:44fb2db84011 63 /* TxDone_botHalf */ txDoneCB,
corymast 4:b2fc780be0b3 64 /* TxTimeout */ txTimeoutCB,
LoRaToolbox 0:44fb2db84011 65 /* RxDone */ rxDoneCB,
LoRaToolbox 0:44fb2db84011 66 /* RxTimeout */ NULL,
LoRaToolbox 0:44fb2db84011 67 /* RxError */ NULL,
LoRaToolbox 0:44fb2db84011 68 /* FhssChangeChannel */NULL,
LoRaToolbox 0:44fb2db84011 69 /* CadDone */ NULL
LoRaToolbox 0:44fb2db84011 70 };
LoRaToolbox 0:44fb2db84011 71
corymast 4:b2fc780be0b3 72 /**
corymast 4:b2fc780be0b3 73 * Function for printing the contents of the SX127x transmit buffer
corymast 4:b2fc780be0b3 74 */
corymast 3:5e25ec621190 75 void print_radio_tx_buffer(uint8_t len)
corymast 3:5e25ec621190 76 {
corymast 3:5e25ec621190 77 printf("Tx Buffer = ");
corymast 3:5e25ec621190 78 for(int i=0; i<len; i++)
corymast 3:5e25ec621190 79 {
corymast 3:5e25ec621190 80 printf("%d ", Radio::radio.tx_buf[i]);
corymast 3:5e25ec621190 81 }
corymast 3:5e25ec621190 82 printf("\r\n\n");
corymast 3:5e25ec621190 83 }
corymast 3:5e25ec621190 84
corymast 4:b2fc780be0b3 85 /**
corymast 4:b2fc780be0b3 86 * Function for adding bytes to the circular buffer for the message.
corymast 4:b2fc780be0b3 87 */
corymast 3:5e25ec621190 88 void msg_append_bytes(uint8_t data[], uint8_t len)
corymast 3:5e25ec621190 89 {
corymast 3:5e25ec621190 90 for(int i=0; i < len; i++)
corymast 3:5e25ec621190 91 {
corymast 3:5e25ec621190 92 if(!msg.full())
corymast 3:5e25ec621190 93 {
corymast 3:5e25ec621190 94 msg.push(data[i]);
corymast 3:5e25ec621190 95 }
corymast 3:5e25ec621190 96 else{
corymast 3:5e25ec621190 97 // If buffer is full, contents will be over-written
corymast 3:5e25ec621190 98 // TODO: Handle this error case
corymast 3:5e25ec621190 99 printf("buffer is full\n");
corymast 3:5e25ec621190 100 }
corymast 3:5e25ec621190 101 }
corymast 3:5e25ec621190 102 }
corymast 3:5e25ec621190 103
corymast 4:b2fc780be0b3 104 /**
corymast 4:b2fc780be0b3 105 * Function for adding a string to the circular buffer for the message
corymast 4:b2fc780be0b3 106 */
corymast 3:5e25ec621190 107 void msg_append_string(string str, uint8_t len)
LoRaToolbox 0:44fb2db84011 108 {
corymast 3:5e25ec621190 109 msg_append_bytes(reinterpret_cast<uint8_t*>(&str[0]), len);
corymast 3:5e25ec621190 110 }
corymast 3:5e25ec621190 111
corymast 4:b2fc780be0b3 112 /**
corymast 4:b2fc780be0b3 113 * Function for sending the message.
corymast 4:b2fc780be0b3 114 *
corymast 4:b2fc780be0b3 115 * @note This function copies the contents of the circular buffer to the transmit
corymast 4:b2fc780be0b3 116 * buffer.
corymast 4:b2fc780be0b3 117 */
corymast 3:5e25ec621190 118 void msg_send()
corymast 3:5e25ec621190 119 {
corymast 3:5e25ec621190 120 uint8_t len = 0;
corymast 3:5e25ec621190 121 while(!msg.empty())
corymast 3:5e25ec621190 122 {
corymast 3:5e25ec621190 123 // Pop data from the circular buffer to Radio tx_buf
corymast 3:5e25ec621190 124 msg.pop(Radio::radio.tx_buf[len]);
corymast 3:5e25ec621190 125
corymast 3:5e25ec621190 126 // Track the size of the tx_buf
corymast 3:5e25ec621190 127 len++;
corymast 3:5e25ec621190 128 }
corymast 3:5e25ec621190 129 print_radio_tx_buffer(len);
corymast 3:5e25ec621190 130 txDone = false;
corymast 3:5e25ec621190 131 Radio::Send(len, 0, 0, 0); // begin transmission of payload
corymast 4:b2fc780be0b3 132 }
corymast 3:5e25ec621190 133
corymast 4:b2fc780be0b3 134 /**
corymast 4:b2fc780be0b3 135 * Interrupt handler for the User button.
corymast 4:b2fc780be0b3 136 */
corymast 4:b2fc780be0b3 137 void button_send()
corymast 4:b2fc780be0b3 138 {
corymast 4:b2fc780be0b3 139 // Create an array to hold byte data
corymast 4:b2fc780be0b3 140 uint8_t data[] = {seq};
corymast 4:b2fc780be0b3 141
corymast 4:b2fc780be0b3 142 // Append the byte array to the message
corymast 4:b2fc780be0b3 143 msg_append_bytes(data, sizeof(data)/sizeof(data[0]));
corymast 4:b2fc780be0b3 144
corymast 4:b2fc780be0b3 145 // Append a new value to the message
corymast 4:b2fc780be0b3 146 data[0] = seq+1;
corymast 4:b2fc780be0b3 147 msg_append_bytes(data, sizeof(data)/sizeof(data[0]));
corymast 4:b2fc780be0b3 148
corymast 4:b2fc780be0b3 149 // Append a string to the message
corymast 4:b2fc780be0b3 150 string myString = "Hello World!";
corymast 4:b2fc780be0b3 151 msg_append_string(myString, myString.length());
corymast 4:b2fc780be0b3 152 msg_send();
corymast 4:b2fc780be0b3 153
corymast 4:b2fc780be0b3 154 seq+=2; // change payload (increment sequence number)
corymast 3:5e25ec621190 155 }
corymast 3:5e25ec621190 156
corymast 4:b2fc780be0b3 157 /**
corymast 4:b2fc780be0b3 158 * Interrupt Handler for the User button.
corymast 4:b2fc780be0b3 159 */
corymast 4:b2fc780be0b3 160 void button_send_json()
corymast 4:b2fc780be0b3 161 {
corymast 4:b2fc780be0b3 162 string s;
corymast 4:b2fc780be0b3 163 seq++;
corymast 4:b2fc780be0b3 164
corymast 4:b2fc780be0b3 165 //fill the object
corymast 4:b2fc780be0b3 166 message["btn_count"] = seq;
corymast 4:b2fc780be0b3 167 message["btn_timer"] = t.read();
corymast 4:b2fc780be0b3 168 message["my_str"] = "Hello World!";
corymast 4:b2fc780be0b3 169 message["my_boolean"] = false;
corymast 4:b2fc780be0b3 170
corymast 4:b2fc780be0b3 171 //serialize it into a JSON string
corymast 4:b2fc780be0b3 172 s = message.serialize();
corymast 4:b2fc780be0b3 173 printf("json: %s\r\n", s.c_str());
corymast 4:b2fc780be0b3 174
corymast 4:b2fc780be0b3 175 memcpy(Radio::radio.tx_buf, s.c_str(), s.length());
corymast 4:b2fc780be0b3 176 txDone = false;
corymast 4:b2fc780be0b3 177 Radio::Send(s.length(), 0, 0, 0); // begin transmission of payload
corymast 4:b2fc780be0b3 178 t.reset();
corymast 4:b2fc780be0b3 179 }
corymast 4:b2fc780be0b3 180
corymast 4:b2fc780be0b3 181 /**
corymast 4:b2fc780be0b3 182 * Function for initializing the SX127x radio.
corymast 4:b2fc780be0b3 183 */
corymast 3:5e25ec621190 184 void radio_init()
corymast 3:5e25ec621190 185 {
LoRaToolbox 1:b277f5a65c1c 186 // Start radio transmitter after POR or reset
LoRaToolbox 0:44fb2db84011 187 Radio::Init(&rev);
LoRaToolbox 0:44fb2db84011 188
LoRaToolbox 1:b277f5a65c1c 189 //Set radio properties for transmitter
LoRaToolbox 0:44fb2db84011 190 Radio::Standby();
LoRaToolbox 0:44fb2db84011 191 Radio::LoRaModemConfig(BW_KHZ, SPREADING_FACTOR, 1);
LoRaToolbox 0:44fb2db84011 192 Radio::SetChannel(CF_HZ);
LoRaToolbox 0:44fb2db84011 193
LoRaToolbox 1:b277f5a65c1c 194 // Set transmitter output power
LoRaToolbox 0:44fb2db84011 195 Radio::set_tx_dbm(TX_DBM);
LoRaToolbox 0:44fb2db84011 196
LoRaToolbox 1:b277f5a65c1c 197 // Setup transmit packet payload -> preambleLen, fixLen, crcOn, invIQ
LoRaToolbox 0:44fb2db84011 198 Radio::LoRaPacketConfig(8, false, true, false);
corymast 3:5e25ec621190 199 }
corymast 3:5e25ec621190 200
corymast 3:5e25ec621190 201 int main()
corymast 3:5e25ec621190 202 {
corymast 3:5e25ec621190 203 printf("\r\nreset-tx \n");
corymast 4:b2fc780be0b3 204 // button.fall(&button_send);
corymast 4:b2fc780be0b3 205 button.fall(&button_send_json);
LoRaToolbox 0:44fb2db84011 206
corymast 3:5e25ec621190 207 radio_init();
LoRaToolbox 0:44fb2db84011 208
corymast 4:b2fc780be0b3 209 // Start a timer to track time between button presses
corymast 4:b2fc780be0b3 210 t.start();
LoRaToolbox 0:44fb2db84011 211
corymast 4:b2fc780be0b3 212 for (;;)
corymast 4:b2fc780be0b3 213 {
corymast 4:b2fc780be0b3 214 // Transmit message on button press, service radio until tx complete.
corymast 4:b2fc780be0b3 215 while (!txDone)
corymast 4:b2fc780be0b3 216 {
corymast 4:b2fc780be0b3 217 Radio::service();
LoRaToolbox 1:b277f5a65c1c 218 }
corymast 4:b2fc780be0b3 219 }
LoRaToolbox 0:44fb2db84011 220 }