LoRaWAN end device MAC layer for SX1272 and SX1276. Supports LoRaWAN-1.0 and LoRaWAN-1.1
Dependents: LoRaWAN-SanJose_Bootcamp LoRaWAN-grove-cayenne LoRaWAN-classC-demo LoRaWAN-grove-cayenne ... more
radio chip selection
Radio chip driver is not included, because two options are available.
If you're using SX1272 or SX1276, then import sx127x driver into your program.
if you're using SX1261 or SX1262, then import sx126x driver into your program.
If you're using NAmote72 or Murata discovery, then you must import only sx127x driver.
application project requirements
This library requires mbed TLS to be enabled.
The file mbed_app.json
must be present in the project using this library:
{ "macros": [ "MBEDTLS_CMAC_C" ] }
regional PHY selection
All end device configuration is done in Commissioning.h, define desired radio frequency band of operation in this header file.
Commissioning.h is located in the application using this library.
end device provisioning
End device is provisioned by editing Commissioning.h in the application which is using this library
To use LoRaWAN-1.0 OTA: make sure LORAWAN_ROOT_APPKEY
is undefined.
To use LoRaWAN-1.1 OTA, define LORAWAN_ROOT_APPKEY
.
To select OTA operation, define LORAWAN_JOIN_EUI
, then LORAWAN_DEVICE_EUI
must be defined, along with root key(s).
To select ABP operation, undefine LORAWAN_JOIN_EUI
: then define session keys
LoRaWAN 1.0 name | LoRaWAN 1.1 name | Comissioning.h defne | description | |
---|---|---|---|---|
OTA | DevEUI | DevEUI | LORAWAN_DEVICE_EUI | uniquely identifies end device |
OTA | AppEUI | JoinEUI | LORAWAN_JOIN_EUI | |
OTA | AppKey | NwkKey | LORAWAN_ROOT_NWKKEY | root key for network server |
OTA | (note 1) | AppKey | LORAWAN_ROOT_APPKEY | root key for application server |
ABP | NwkSKey | (note 3) | LORAWAN_FNwkSIntKey | network session key |
ABP | (note 2) | SNwkSIntKey | LORAWAN_SNwkSIntKey | mac layer network integrity key |
ABP | (note 2) | NwkSEncKey | LORAWAN_NwkSEncKey | network session encryption key |
ABP | (note 2) | FNwkSIntKey | LORAWAN_FNwkSIntKey | forwarding network session integrity key |
ABP | AppSKey | AppSKey | LORAWAN_APPSKEY | application session encryption key |
(note 1): LoRaWAN-1.0 OTA uses a single root key for both network server and application server.
In LoRaWAN-1.0 OTA: the single root AppKey is used to generate NwkSkey and AppSKey.
(note 2): In LoRaWAN-1.0 (both OTA and ABP) SNwkSIntKey, NwkSEncKey. FNwkSIntKey are of same value and are collectively known as NwkSKey.
(note 3): LoRaWAN-1.0 uses single network session key, LoRaWAN-1.1 uses 3 network session keys. Both use a unique application session key.
In LoRaWAN-1.1 OTA: the root NwkKey is used to generate SNwkSIntKey, NwkSEncKey, FNwkSIntKey
In LoRaWAN-1.1 OTA: the root AppKey is used to generate AppSKey
in ABP mode, the DevAddr, and session keys are fixed (never change), and frame counters never reset to zero.
ABP operation has no concept of: root keys, or DevEUI or JoinEUI/AppEUI.
in OTA mode, the DevAddr and session keys are assigned at join procedure, and frame counters reset at join.
eeprom
This library includes eeprom driver to support non-volatile storage required by LoRaWAN specification.
Currently eeprom is implemented for STM32L1 family and STM32L0 family.
Writing of values are wear-leveled to increase endurance; each write operation circulates across several memory locations. A read operation returns the highest value found. This simple method is used for sequence numbers which only increase.
value name | used in | |
---|---|---|
DevNonce | OTA | for Join request (note 1) |
RJcount1 | OTA | for ReJoin Type 1 request |
FCntUp | ABP | uplink frame counter |
NFCntDown | ABP | downlink frame counter |
AFCntDown | ABP | downlink frame counter |
AFCntDown is only used in LoRaWAN-1.1 when application payload is present in downlink and FPort > 0.
NFCntDown is used in LoRaWAN-1.1 when FPort is zero in downlink or application payload not present.
NFCntDown is the only downlink frame counter used in LoRaWAN-1.0
(note 1) OTA DevNonce is random number in LoRaWAN-1.0, therefore not stored in eeprom. DevNonce in LoRaWAN-1.1 is forever increasing (non-volatile) number upon each join request,.
RJcount0 is only stored in RAM because the value resets upon new session from JoinAccept, therefore not stored in eeprom.
Frame counters in OTA mode reset upon new session in join request, therefore are stored in RAM instead of eeprom for OTA.
radio driver support
When SX127x driver is used, both SX1272 and SX1276 are supported without defining at compile time. The chip is detected at start-up.
Supported radio platforms:
Alternately, when SX126x driver is imported, the SX126xDVK1xAS board is used.
low-speed clock oscillator selection
LoRaWAN uses 32768Hz crystal to permit low-power operation.
However, some mbed targets might revert to low-speed internal oscillator, which is not accurate enough for LoRaWAN operation.
An oscillator check is performed at initialization; program will not start if internal oscillator is used.
To force LSE watch crystal, add to mbed_app.json
{ "macros": [ "MBEDTLS_CMAC_C" ], "target_overrides": { "<your-target>": { "target.lse_available": true } } }
radio/radio_sx126x.cpp@9:fe8e08792ae9, 2018-06-11 (annotated)
- Committer:
- Wayne Roberts
- Date:
- Mon Jun 11 14:09:16 2018 -0700
- Revision:
- 9:fe8e08792ae9
- Parent:
- 8:5a5ea7cc946f
sx126x: update xfer() calls
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Wayne Roberts |
8:5a5ea7cc946f | 1 | #include "radio.h" |
Wayne Roberts |
8:5a5ea7cc946f | 2 | #ifdef SX126x_H |
Wayne Roberts |
8:5a5ea7cc946f | 3 | #include "board.h" |
Wayne Roberts |
8:5a5ea7cc946f | 4 | #include "SPIu.h" |
Wayne Roberts |
8:5a5ea7cc946f | 5 | |
Wayne Roberts |
8:5a5ea7cc946f | 6 | LowPowerTimer Radio::lpt; |
Wayne Roberts |
8:5a5ea7cc946f | 7 | volatile us_timestamp_t dio1at; |
Wayne Roberts |
8:5a5ea7cc946f | 8 | |
Wayne Roberts |
8:5a5ea7cc946f | 9 | #ifdef TARGET_FF_ARDUINO |
Wayne Roberts |
8:5a5ea7cc946f | 10 | SPIu spi(D11, D12, D13); // mosi, miso, sclk |
Wayne Roberts |
8:5a5ea7cc946f | 11 | //spi, nss, busy, dio1 |
Wayne Roberts |
8:5a5ea7cc946f | 12 | SX126x Radio::radio(spi, D7, D3, D5); |
Wayne Roberts |
8:5a5ea7cc946f | 13 | |
Wayne Roberts |
8:5a5ea7cc946f | 14 | DigitalOut antswPower(D8); |
Wayne Roberts |
8:5a5ea7cc946f | 15 | AnalogIn xtalSel(A3); |
Wayne Roberts |
8:5a5ea7cc946f | 16 | |
Wayne Roberts |
8:5a5ea7cc946f | 17 | DigitalIn chipType(A2); |
Wayne Roberts |
8:5a5ea7cc946f | 18 | #define CHIP_TYPE_SX1262 0 |
Wayne Roberts |
8:5a5ea7cc946f | 19 | #define CHIP_TYPE_SX1261 1 |
Wayne Roberts |
8:5a5ea7cc946f | 20 | |
Wayne Roberts |
8:5a5ea7cc946f | 21 | #define PINNAME_NRST A0 |
Wayne Roberts |
8:5a5ea7cc946f | 22 | #endif /* TARGET_FF_ARDUINO */ |
Wayne Roberts |
8:5a5ea7cc946f | 23 | |
Wayne Roberts |
8:5a5ea7cc946f | 24 | const RadioEvents_t* RadioEvents; |
Wayne Roberts |
8:5a5ea7cc946f | 25 | PacketParams_t Radio::pp; |
Wayne Roberts |
8:5a5ea7cc946f | 26 | RadioModems_t Radio::_m_; |
Wayne Roberts |
8:5a5ea7cc946f | 27 | |
Wayne Roberts |
8:5a5ea7cc946f | 28 | #ifdef TARGET_FF_MORPHO |
Wayne Roberts |
8:5a5ea7cc946f | 29 | DigitalOut pc3(PC_3); // debug RX indication, for nucleo boards |
Wayne Roberts |
8:5a5ea7cc946f | 30 | #endif /* TARGET_FF_MORPHO */ |
Wayne Roberts |
8:5a5ea7cc946f | 31 | |
Wayne Roberts |
8:5a5ea7cc946f | 32 | void Radio::Rx(unsigned timeout) |
Wayne Roberts |
8:5a5ea7cc946f | 33 | { |
Wayne Roberts |
8:5a5ea7cc946f | 34 | antswPower = 1; |
Wayne Roberts |
8:5a5ea7cc946f | 35 | |
Wayne Roberts |
8:5a5ea7cc946f | 36 | { |
Wayne Roberts |
8:5a5ea7cc946f | 37 | uint8_t buf[8]; |
Wayne Roberts |
8:5a5ea7cc946f | 38 | IrqFlags_t irqEnable; |
Wayne Roberts |
8:5a5ea7cc946f | 39 | irqEnable.word = 0; |
Wayne Roberts |
8:5a5ea7cc946f | 40 | irqEnable.bits.RxDone = 1; |
Wayne Roberts |
8:5a5ea7cc946f | 41 | irqEnable.bits.Timeout = 1; |
Wayne Roberts |
8:5a5ea7cc946f | 42 | |
Wayne Roberts |
8:5a5ea7cc946f | 43 | buf[0] = irqEnable.word >> 8; // enable bits |
Wayne Roberts |
8:5a5ea7cc946f | 44 | buf[1] = irqEnable.word; // enable bits |
Wayne Roberts |
8:5a5ea7cc946f | 45 | buf[2] = irqEnable.word >> 8; // dio1 |
Wayne Roberts |
8:5a5ea7cc946f | 46 | buf[3] = irqEnable.word; // dio1 |
Wayne Roberts |
8:5a5ea7cc946f | 47 | buf[4] = 0; // dio2 |
Wayne Roberts |
8:5a5ea7cc946f | 48 | buf[5] = 0; // dio2 |
Wayne Roberts |
8:5a5ea7cc946f | 49 | buf[6] = 0; // dio3 |
Wayne Roberts |
8:5a5ea7cc946f | 50 | buf[7] = 0; // dio3 |
Wayne Roberts |
9:fe8e08792ae9 | 51 | radio.xfer(OPCODE_SET_DIO_IRQ_PARAMS, 8, 0, buf); |
Wayne Roberts |
8:5a5ea7cc946f | 52 | } |
Wayne Roberts |
8:5a5ea7cc946f | 53 | |
Wayne Roberts |
8:5a5ea7cc946f | 54 | #ifdef TARGET_FF_MORPHO |
Wayne Roberts |
8:5a5ea7cc946f | 55 | pc3 = 1; |
Wayne Roberts |
8:5a5ea7cc946f | 56 | #endif /* TARGET_FF_MORPHO */ |
Wayne Roberts |
8:5a5ea7cc946f | 57 | if (timeout == 0) |
Wayne Roberts |
8:5a5ea7cc946f | 58 | radio.start_rx(RX_TIMEOUT_CONTINUOUS); |
Wayne Roberts |
8:5a5ea7cc946f | 59 | else |
Wayne Roberts |
8:5a5ea7cc946f | 60 | radio.start_rx(timeout * RC_TICKS_PER_US); |
Wayne Roberts |
8:5a5ea7cc946f | 61 | } |
Wayne Roberts |
8:5a5ea7cc946f | 62 | |
Wayne Roberts |
8:5a5ea7cc946f | 63 | void Radio::Standby() |
Wayne Roberts |
8:5a5ea7cc946f | 64 | { |
Wayne Roberts |
8:5a5ea7cc946f | 65 | radio.setStandby(STBY_RC); // STBY_XOSC |
Wayne Roberts |
8:5a5ea7cc946f | 66 | |
Wayne Roberts |
8:5a5ea7cc946f | 67 | antswPower = 0; |
Wayne Roberts |
8:5a5ea7cc946f | 68 | } |
Wayne Roberts |
8:5a5ea7cc946f | 69 | |
Wayne Roberts |
8:5a5ea7cc946f | 70 | void Radio::Sleep() |
Wayne Roberts |
8:5a5ea7cc946f | 71 | { |
Wayne Roberts |
8:5a5ea7cc946f | 72 | radio.setSleep(true, false); |
Wayne Roberts |
8:5a5ea7cc946f | 73 | |
Wayne Roberts |
8:5a5ea7cc946f | 74 | antswPower = 0; |
Wayne Roberts |
8:5a5ea7cc946f | 75 | } |
Wayne Roberts |
8:5a5ea7cc946f | 76 | |
Wayne Roberts |
8:5a5ea7cc946f | 77 | void Radio::SetTxContinuousWave(unsigned hz, int8_t dbm, unsigned timeout_us) |
Wayne Roberts |
8:5a5ea7cc946f | 78 | { |
Wayne Roberts |
8:5a5ea7cc946f | 79 | SetChannel(hz); |
Wayne Roberts |
8:5a5ea7cc946f | 80 | radio.set_tx_dbm(chipType == CHIP_TYPE_SX1262, dbm); |
Wayne Roberts |
9:fe8e08792ae9 | 81 | radio.xfer(OPCODE_SET_TX_CONTINUOUS, 0, 0, NULL); |
Wayne Roberts |
8:5a5ea7cc946f | 82 | } |
Wayne Roberts |
8:5a5ea7cc946f | 83 | |
Wayne Roberts |
8:5a5ea7cc946f | 84 | uint32_t Radio::Random(void) |
Wayne Roberts |
8:5a5ea7cc946f | 85 | { |
Wayne Roberts |
8:5a5ea7cc946f | 86 | uint32_t ret; |
Wayne Roberts |
8:5a5ea7cc946f | 87 | |
Wayne Roberts |
8:5a5ea7cc946f | 88 | radio.start_rx(RX_TIMEOUT_CONTINUOUS); |
Wayne Roberts |
8:5a5ea7cc946f | 89 | |
Wayne Roberts |
8:5a5ea7cc946f | 90 | ret = radio.readReg(REG_ADDR_RANDOM, 4); |
Wayne Roberts |
8:5a5ea7cc946f | 91 | |
Wayne Roberts |
8:5a5ea7cc946f | 92 | Standby(); |
Wayne Roberts |
8:5a5ea7cc946f | 93 | |
Wayne Roberts |
8:5a5ea7cc946f | 94 | return ret; |
Wayne Roberts |
8:5a5ea7cc946f | 95 | } |
Wayne Roberts |
8:5a5ea7cc946f | 96 | |
Wayne Roberts |
8:5a5ea7cc946f | 97 | bool Radio::CheckRfFrequency(unsigned hz) |
Wayne Roberts |
8:5a5ea7cc946f | 98 | { |
Wayne Roberts |
8:5a5ea7cc946f | 99 | return true; |
Wayne Roberts |
8:5a5ea7cc946f | 100 | } |
Wayne Roberts |
8:5a5ea7cc946f | 101 | |
Wayne Roberts |
8:5a5ea7cc946f | 102 | void Radio::SetChannel(unsigned hz) |
Wayne Roberts |
8:5a5ea7cc946f | 103 | { |
Wayne Roberts |
8:5a5ea7cc946f | 104 | radio.setMHz(hz / 1000000.0); |
Wayne Roberts |
8:5a5ea7cc946f | 105 | } |
Wayne Roberts |
8:5a5ea7cc946f | 106 | |
Wayne Roberts |
8:5a5ea7cc946f | 107 | void Radio::SetRxConfig( |
Wayne Roberts |
8:5a5ea7cc946f | 108 | RadioModems_t modem, |
Wayne Roberts |
8:5a5ea7cc946f | 109 | uint32_t bandwidth, |
Wayne Roberts |
8:5a5ea7cc946f | 110 | uint32_t datarate, |
Wayne Roberts |
8:5a5ea7cc946f | 111 | uint8_t coderate, |
Wayne Roberts |
8:5a5ea7cc946f | 112 | uint32_t bandwidthAfc, |
Wayne Roberts |
8:5a5ea7cc946f | 113 | uint16_t preambleLen, |
Wayne Roberts |
8:5a5ea7cc946f | 114 | uint16_t symbTimeout, |
Wayne Roberts |
8:5a5ea7cc946f | 115 | bool fixLen, |
Wayne Roberts |
8:5a5ea7cc946f | 116 | uint8_t payloadLen, |
Wayne Roberts |
8:5a5ea7cc946f | 117 | bool crcOn, |
Wayne Roberts |
8:5a5ea7cc946f | 118 | bool iqInverted) |
Wayne Roberts |
8:5a5ea7cc946f | 119 | { |
Wayne Roberts |
8:5a5ea7cc946f | 120 | uint8_t buf[8]; |
Wayne Roberts |
8:5a5ea7cc946f | 121 | |
Wayne Roberts |
8:5a5ea7cc946f | 122 | if (modem == MODEM_FSK) |
Wayne Roberts |
8:5a5ea7cc946f | 123 | buf[0] = PACKET_TYPE_GFSK; |
Wayne Roberts |
8:5a5ea7cc946f | 124 | else |
Wayne Roberts |
8:5a5ea7cc946f | 125 | buf[0] = PACKET_TYPE_LORA; |
Wayne Roberts |
8:5a5ea7cc946f | 126 | |
Wayne Roberts |
9:fe8e08792ae9 | 127 | radio.xfer(OPCODE_SET_PACKET_TYPE, 1, 0, buf); |
Wayne Roberts |
8:5a5ea7cc946f | 128 | |
Wayne Roberts |
8:5a5ea7cc946f | 129 | buf[0] = 0; // TX base address |
Wayne Roberts |
8:5a5ea7cc946f | 130 | buf[1] = 0; // RX base address |
Wayne Roberts |
9:fe8e08792ae9 | 131 | radio.xfer(OPCODE_SET_BUFFER_BASE_ADDR, 2, 0, buf); |
Wayne Roberts |
8:5a5ea7cc946f | 132 | |
Wayne Roberts |
8:5a5ea7cc946f | 133 | if (modem == MODEM_FSK) { |
Wayne Roberts |
8:5a5ea7cc946f | 134 | FSKConfig(bandwidth, datarate, 0, preambleLen, fixLen, crcOn); |
Wayne Roberts |
8:5a5ea7cc946f | 135 | |
Wayne Roberts |
8:5a5ea7cc946f | 136 | pp.gfsk.PayloadLength = payloadLen; |
Wayne Roberts |
8:5a5ea7cc946f | 137 | |
Wayne Roberts |
8:5a5ea7cc946f | 138 | memcpy(buf, pp.buf, 8); |
Wayne Roberts |
9:fe8e08792ae9 | 139 | radio.xfer(OPCODE_SET_PACKET_PARAMS, 8, 0, buf); |
Wayne Roberts |
8:5a5ea7cc946f | 140 | } else if (modem == MODEM_LORA) { |
Wayne Roberts |
8:5a5ea7cc946f | 141 | LoRaConfig(bandwidth, datarate, coderate, preambleLen, fixLen, crcOn, iqInverted); |
Wayne Roberts |
8:5a5ea7cc946f | 142 | |
Wayne Roberts |
8:5a5ea7cc946f | 143 | pp.lora.PayloadLength = payloadLen; |
Wayne Roberts |
8:5a5ea7cc946f | 144 | |
Wayne Roberts |
8:5a5ea7cc946f | 145 | memcpy(buf, pp.buf, 6); |
Wayne Roberts |
9:fe8e08792ae9 | 146 | radio.xfer(OPCODE_SET_PACKET_PARAMS, 6, 0, buf); |
Wayne Roberts |
8:5a5ea7cc946f | 147 | |
Wayne Roberts |
8:5a5ea7cc946f | 148 | buf[0] = symbTimeout; |
Wayne Roberts |
9:fe8e08792ae9 | 149 | radio.xfer(OPCODE_SET_LORA_SYMBOL_TIMEOUT, 1, 0, buf); |
Wayne Roberts |
8:5a5ea7cc946f | 150 | } |
Wayne Roberts |
8:5a5ea7cc946f | 151 | |
Wayne Roberts |
8:5a5ea7cc946f | 152 | { |
Wayne Roberts |
8:5a5ea7cc946f | 153 | IrqFlags_t irqEnable; |
Wayne Roberts |
8:5a5ea7cc946f | 154 | irqEnable.word = 0; |
Wayne Roberts |
8:5a5ea7cc946f | 155 | irqEnable.bits.RxDone = 1; |
Wayne Roberts |
8:5a5ea7cc946f | 156 | irqEnable.bits.Timeout = 1; |
Wayne Roberts |
8:5a5ea7cc946f | 157 | |
Wayne Roberts |
8:5a5ea7cc946f | 158 | buf[0] = irqEnable.word >> 8; // enable bits |
Wayne Roberts |
8:5a5ea7cc946f | 159 | buf[1] = irqEnable.word; // enable bits |
Wayne Roberts |
8:5a5ea7cc946f | 160 | buf[2] = irqEnable.word >> 8; // dio1 |
Wayne Roberts |
8:5a5ea7cc946f | 161 | buf[3] = irqEnable.word; // dio1 |
Wayne Roberts |
8:5a5ea7cc946f | 162 | buf[4] = 0; // dio2 |
Wayne Roberts |
8:5a5ea7cc946f | 163 | buf[5] = 0; // dio2 |
Wayne Roberts |
8:5a5ea7cc946f | 164 | buf[6] = 0; // dio3 |
Wayne Roberts |
8:5a5ea7cc946f | 165 | buf[7] = 0; // dio3 |
Wayne Roberts |
9:fe8e08792ae9 | 166 | radio.xfer(OPCODE_SET_DIO_IRQ_PARAMS, 8, 0, buf); |
Wayne Roberts |
8:5a5ea7cc946f | 167 | } |
Wayne Roberts |
8:5a5ea7cc946f | 168 | |
Wayne Roberts |
8:5a5ea7cc946f | 169 | } // ..SetRxConfig() |
Wayne Roberts |
8:5a5ea7cc946f | 170 | |
Wayne Roberts |
8:5a5ea7cc946f | 171 | void Radio::FSKConfig( |
Wayne Roberts |
8:5a5ea7cc946f | 172 | uint32_t bandwidth, |
Wayne Roberts |
8:5a5ea7cc946f | 173 | uint32_t datarate, |
Wayne Roberts |
8:5a5ea7cc946f | 174 | uint32_t fdev, |
Wayne Roberts |
8:5a5ea7cc946f | 175 | uint32_t preambleLen, |
Wayne Roberts |
8:5a5ea7cc946f | 176 | bool fixLen, |
Wayne Roberts |
8:5a5ea7cc946f | 177 | bool crcOn) |
Wayne Roberts |
8:5a5ea7cc946f | 178 | { |
Wayne Roberts |
8:5a5ea7cc946f | 179 | ModulationParams_t mp; |
Wayne Roberts |
8:5a5ea7cc946f | 180 | uint32_t u32; |
Wayne Roberts |
8:5a5ea7cc946f | 181 | |
Wayne Roberts |
9:fe8e08792ae9 | 182 | u32 = 32 * (XTAL_FREQ_HZ / datarate); |
Wayne Roberts |
9:fe8e08792ae9 | 183 | mp.gfsk.bitrateHi = u32 >> 16; // param1 |
Wayne Roberts |
9:fe8e08792ae9 | 184 | mp.gfsk.bitrateMid = u32 >> 8; // param2 |
Wayne Roberts |
9:fe8e08792ae9 | 185 | mp.gfsk.bitrateLo = u32; // param3 |
Wayne Roberts |
8:5a5ea7cc946f | 186 | mp.gfsk.PulseShape = GFSK_SHAPE_BT1_0; // param4 |
Wayne Roberts |
8:5a5ea7cc946f | 187 | // param5: |
Wayne Roberts |
8:5a5ea7cc946f | 188 | if (bandwidth < 5800) |
Wayne Roberts |
9:fe8e08792ae9 | 189 | mp.gfsk.bandwidth = GFSK_RX_BW_4800; |
Wayne Roberts |
8:5a5ea7cc946f | 190 | else if (bandwidth < 7300) |
Wayne Roberts |
9:fe8e08792ae9 | 191 | mp.gfsk.bandwidth = GFSK_RX_BW_5800; |
Wayne Roberts |
8:5a5ea7cc946f | 192 | else if (bandwidth < 9700) |
Wayne Roberts |
9:fe8e08792ae9 | 193 | mp.gfsk.bandwidth = GFSK_RX_BW_7300; |
Wayne Roberts |
8:5a5ea7cc946f | 194 | else if (bandwidth < 11700) |
Wayne Roberts |
9:fe8e08792ae9 | 195 | mp.gfsk.bandwidth = GFSK_RX_BW_9700; |
Wayne Roberts |
8:5a5ea7cc946f | 196 | else if (bandwidth < 14600) |
Wayne Roberts |
9:fe8e08792ae9 | 197 | mp.gfsk.bandwidth = GFSK_RX_BW_11700; |
Wayne Roberts |
8:5a5ea7cc946f | 198 | else if (bandwidth < 19500) |
Wayne Roberts |
9:fe8e08792ae9 | 199 | mp.gfsk.bandwidth = GFSK_RX_BW_14600; |
Wayne Roberts |
8:5a5ea7cc946f | 200 | else if (bandwidth < 23400) |
Wayne Roberts |
9:fe8e08792ae9 | 201 | mp.gfsk.bandwidth = GFSK_RX_BW_19500; |
Wayne Roberts |
8:5a5ea7cc946f | 202 | else if (bandwidth < 29300) |
Wayne Roberts |
9:fe8e08792ae9 | 203 | mp.gfsk.bandwidth = GFSK_RX_BW_23400; |
Wayne Roberts |
8:5a5ea7cc946f | 204 | else if (bandwidth < 39000) |
Wayne Roberts |
9:fe8e08792ae9 | 205 | mp.gfsk.bandwidth = GFSK_RX_BW_29300; |
Wayne Roberts |
8:5a5ea7cc946f | 206 | else if (bandwidth < 46900) |
Wayne Roberts |
9:fe8e08792ae9 | 207 | mp.gfsk.bandwidth = GFSK_RX_BW_39000; |
Wayne Roberts |
8:5a5ea7cc946f | 208 | else if (bandwidth < 58600) |
Wayne Roberts |
9:fe8e08792ae9 | 209 | mp.gfsk.bandwidth = GFSK_RX_BW_46900; |
Wayne Roberts |
8:5a5ea7cc946f | 210 | else if (bandwidth < 78200) |
Wayne Roberts |
9:fe8e08792ae9 | 211 | mp.gfsk.bandwidth = GFSK_RX_BW_58600; |
Wayne Roberts |
8:5a5ea7cc946f | 212 | else if (bandwidth < 93800) |
Wayne Roberts |
9:fe8e08792ae9 | 213 | mp.gfsk.bandwidth = GFSK_RX_BW_78200; |
Wayne Roberts |
8:5a5ea7cc946f | 214 | else if (bandwidth < 117300) |
Wayne Roberts |
9:fe8e08792ae9 | 215 | mp.gfsk.bandwidth = GFSK_RX_BW_93800; |
Wayne Roberts |
8:5a5ea7cc946f | 216 | else if (bandwidth < 156200) |
Wayne Roberts |
9:fe8e08792ae9 | 217 | mp.gfsk.bandwidth = GFSK_RX_BW_117300; |
Wayne Roberts |
8:5a5ea7cc946f | 218 | else if (bandwidth < 187200) |
Wayne Roberts |
9:fe8e08792ae9 | 219 | mp.gfsk.bandwidth = GFSK_RX_BW_156200; |
Wayne Roberts |
8:5a5ea7cc946f | 220 | else if (bandwidth < 234300) |
Wayne Roberts |
9:fe8e08792ae9 | 221 | mp.gfsk.bandwidth = GFSK_RX_BW_187200; |
Wayne Roberts |
8:5a5ea7cc946f | 222 | else if (bandwidth < 312000) |
Wayne Roberts |
9:fe8e08792ae9 | 223 | mp.gfsk.bandwidth = GFSK_RX_BW_234300; |
Wayne Roberts |
8:5a5ea7cc946f | 224 | else if (bandwidth < 373600) |
Wayne Roberts |
9:fe8e08792ae9 | 225 | mp.gfsk.bandwidth = GFSK_RX_BW_312000; |
Wayne Roberts |
8:5a5ea7cc946f | 226 | else if (bandwidth < 467000) |
Wayne Roberts |
9:fe8e08792ae9 | 227 | mp.gfsk.bandwidth = GFSK_RX_BW_373600; |
Wayne Roberts |
8:5a5ea7cc946f | 228 | else |
Wayne Roberts |
9:fe8e08792ae9 | 229 | mp.gfsk.bandwidth = GFSK_RX_BW_467000; |
Wayne Roberts |
8:5a5ea7cc946f | 230 | |
Wayne Roberts |
8:5a5ea7cc946f | 231 | if (fdev > 0) { |
Wayne Roberts |
8:5a5ea7cc946f | 232 | u32 = fdev / FREQ_STEP; |
Wayne Roberts |
8:5a5ea7cc946f | 233 | mp.gfsk.fdevHi = u32 >> 16; // param6 |
Wayne Roberts |
8:5a5ea7cc946f | 234 | mp.gfsk.fdevMid = u32 >> 8; // param7 |
Wayne Roberts |
8:5a5ea7cc946f | 235 | mp.gfsk.fdevLo = u32; // param8 |
Wayne Roberts |
8:5a5ea7cc946f | 236 | } |
Wayne Roberts |
8:5a5ea7cc946f | 237 | |
Wayne Roberts |
9:fe8e08792ae9 | 238 | radio.xfer(OPCODE_SET_MODULATION_PARAMS, 8, 0, mp.buf); |
Wayne Roberts |
8:5a5ea7cc946f | 239 | |
Wayne Roberts |
8:5a5ea7cc946f | 240 | |
Wayne Roberts |
8:5a5ea7cc946f | 241 | pp.gfsk.PreambleLengthHi = preambleLen >> 8; |
Wayne Roberts |
8:5a5ea7cc946f | 242 | pp.gfsk.PreambleLengthLo = preambleLen; |
Wayne Roberts |
8:5a5ea7cc946f | 243 | pp.gfsk.PreambleDetectorLength = GFSK_PREAMBLE_DETECTOR_LENGTH_16BITS; |
Wayne Roberts |
8:5a5ea7cc946f | 244 | pp.gfsk.SyncWordLength = 24; // 0xC194C1 |
Wayne Roberts |
8:5a5ea7cc946f | 245 | pp.gfsk.AddrComp = 0; |
Wayne Roberts |
8:5a5ea7cc946f | 246 | pp.gfsk.PacketType = fixLen; |
Wayne Roberts |
8:5a5ea7cc946f | 247 | if (crcOn) |
Wayne Roberts |
8:5a5ea7cc946f | 248 | pp.gfsk.CRCType = GFSK_CRC_2_BYTE; |
Wayne Roberts |
8:5a5ea7cc946f | 249 | else |
Wayne Roberts |
8:5a5ea7cc946f | 250 | pp.gfsk.CRCType = GFSK_CRC_OFF; |
Wayne Roberts |
8:5a5ea7cc946f | 251 | } |
Wayne Roberts |
8:5a5ea7cc946f | 252 | |
Wayne Roberts |
8:5a5ea7cc946f | 253 | void Radio::LoRaConfig( |
Wayne Roberts |
8:5a5ea7cc946f | 254 | uint32_t bandwidth, |
Wayne Roberts |
8:5a5ea7cc946f | 255 | uint8_t datarate, |
Wayne Roberts |
8:5a5ea7cc946f | 256 | uint8_t coderate, |
Wayne Roberts |
8:5a5ea7cc946f | 257 | uint16_t preambleLen, |
Wayne Roberts |
8:5a5ea7cc946f | 258 | bool fixLen, |
Wayne Roberts |
8:5a5ea7cc946f | 259 | bool crcOn, |
Wayne Roberts |
8:5a5ea7cc946f | 260 | bool iqInverted) |
Wayne Roberts |
8:5a5ea7cc946f | 261 | { |
Wayne Roberts |
8:5a5ea7cc946f | 262 | ModulationParams_t mp; |
Wayne Roberts |
8:5a5ea7cc946f | 263 | float sp, khz; |
Wayne Roberts |
8:5a5ea7cc946f | 264 | |
Wayne Roberts |
8:5a5ea7cc946f | 265 | mp.lora.spreadingFactor = datarate; // param1 |
Wayne Roberts |
8:5a5ea7cc946f | 266 | mp.lora.bandwidth = bandwidth + 4; // param2 |
Wayne Roberts |
8:5a5ea7cc946f | 267 | mp.lora.codingRate = coderate; // param3 |
Wayne Roberts |
8:5a5ea7cc946f | 268 | |
Wayne Roberts |
8:5a5ea7cc946f | 269 | switch (mp.lora.bandwidth) { |
Wayne Roberts |
8:5a5ea7cc946f | 270 | case LORA_BW_7: khz = 7.81; break; |
Wayne Roberts |
8:5a5ea7cc946f | 271 | case LORA_BW_10: khz = 10.42; break; |
Wayne Roberts |
8:5a5ea7cc946f | 272 | case LORA_BW_15: khz = 15.625; break; |
Wayne Roberts |
8:5a5ea7cc946f | 273 | case LORA_BW_20: khz = 20.83; break; |
Wayne Roberts |
8:5a5ea7cc946f | 274 | case LORA_BW_31: khz = 31.25; break; |
Wayne Roberts |
8:5a5ea7cc946f | 275 | case LORA_BW_41: khz = 41.67; break; |
Wayne Roberts |
8:5a5ea7cc946f | 276 | case LORA_BW_62: khz = 62.5; break; |
Wayne Roberts |
8:5a5ea7cc946f | 277 | case LORA_BW_125: khz = 125; break; |
Wayne Roberts |
8:5a5ea7cc946f | 278 | case LORA_BW_250: khz = 250; break; |
Wayne Roberts |
8:5a5ea7cc946f | 279 | case LORA_BW_500: khz = 500; break; |
Wayne Roberts |
8:5a5ea7cc946f | 280 | default: khz = 0; break; |
Wayne Roberts |
8:5a5ea7cc946f | 281 | } |
Wayne Roberts |
8:5a5ea7cc946f | 282 | sp = (1 << mp.lora.spreadingFactor) / khz; |
Wayne Roberts |
8:5a5ea7cc946f | 283 | /* TCXO dependent */ |
Wayne Roberts |
8:5a5ea7cc946f | 284 | if (sp > 16) |
Wayne Roberts |
8:5a5ea7cc946f | 285 | mp.lora.LowDatarateOptimize = 1; // param4 |
Wayne Roberts |
8:5a5ea7cc946f | 286 | else |
Wayne Roberts |
8:5a5ea7cc946f | 287 | mp.lora.LowDatarateOptimize = 0; // param4 |
Wayne Roberts |
8:5a5ea7cc946f | 288 | |
Wayne Roberts |
9:fe8e08792ae9 | 289 | radio.xfer(OPCODE_SET_MODULATION_PARAMS, 4, 0, mp.buf); |
Wayne Roberts |
8:5a5ea7cc946f | 290 | |
Wayne Roberts |
8:5a5ea7cc946f | 291 | pp.lora.PreambleLengthHi = preambleLen >> 8; |
Wayne Roberts |
8:5a5ea7cc946f | 292 | pp.lora.PreambleLengthLo = preambleLen; |
Wayne Roberts |
8:5a5ea7cc946f | 293 | pp.lora.HeaderType = fixLen; |
Wayne Roberts |
8:5a5ea7cc946f | 294 | pp.lora.CRCType = crcOn; |
Wayne Roberts |
8:5a5ea7cc946f | 295 | pp.lora.InvertIQ = iqInverted; |
Wayne Roberts |
8:5a5ea7cc946f | 296 | } |
Wayne Roberts |
8:5a5ea7cc946f | 297 | |
Wayne Roberts |
8:5a5ea7cc946f | 298 | void Radio::SetTxConfig( |
Wayne Roberts |
8:5a5ea7cc946f | 299 | RadioModems_t modem, |
Wayne Roberts |
8:5a5ea7cc946f | 300 | int8_t dbm, |
Wayne Roberts |
8:5a5ea7cc946f | 301 | uint32_t fdev, |
Wayne Roberts |
8:5a5ea7cc946f | 302 | uint32_t bandwidth, |
Wayne Roberts |
8:5a5ea7cc946f | 303 | uint32_t datarate, |
Wayne Roberts |
8:5a5ea7cc946f | 304 | uint8_t coderate, |
Wayne Roberts |
8:5a5ea7cc946f | 305 | uint16_t preambleLen, |
Wayne Roberts |
8:5a5ea7cc946f | 306 | bool fixLen, |
Wayne Roberts |
8:5a5ea7cc946f | 307 | bool crcOn, |
Wayne Roberts |
8:5a5ea7cc946f | 308 | bool iqInverted) |
Wayne Roberts |
8:5a5ea7cc946f | 309 | { |
Wayne Roberts |
8:5a5ea7cc946f | 310 | uint8_t buf[8]; |
Wayne Roberts |
8:5a5ea7cc946f | 311 | |
Wayne Roberts |
8:5a5ea7cc946f | 312 | radio.set_tx_dbm(chipType == CHIP_TYPE_SX1262, dbm); |
Wayne Roberts |
8:5a5ea7cc946f | 313 | |
Wayne Roberts |
8:5a5ea7cc946f | 314 | if (modem == MODEM_FSK) |
Wayne Roberts |
8:5a5ea7cc946f | 315 | buf[0] = PACKET_TYPE_GFSK; |
Wayne Roberts |
8:5a5ea7cc946f | 316 | else |
Wayne Roberts |
8:5a5ea7cc946f | 317 | buf[0] = PACKET_TYPE_LORA; |
Wayne Roberts |
8:5a5ea7cc946f | 318 | |
Wayne Roberts |
9:fe8e08792ae9 | 319 | radio.xfer(OPCODE_SET_PACKET_TYPE, 1, 0, buf); |
Wayne Roberts |
8:5a5ea7cc946f | 320 | |
Wayne Roberts |
8:5a5ea7cc946f | 321 | |
Wayne Roberts |
8:5a5ea7cc946f | 322 | buf[0] = 0; // TX base address |
Wayne Roberts |
8:5a5ea7cc946f | 323 | buf[1] = 0; // RX base address |
Wayne Roberts |
9:fe8e08792ae9 | 324 | radio.xfer(OPCODE_SET_BUFFER_BASE_ADDR, 2, 0, buf); |
Wayne Roberts |
8:5a5ea7cc946f | 325 | |
Wayne Roberts |
8:5a5ea7cc946f | 326 | if (modem == MODEM_FSK) { |
Wayne Roberts |
8:5a5ea7cc946f | 327 | FSKConfig(bandwidth, datarate, fdev, preambleLen, fixLen, crcOn); |
Wayne Roberts |
8:5a5ea7cc946f | 328 | } else if (modem == MODEM_LORA) { |
Wayne Roberts |
8:5a5ea7cc946f | 329 | LoRaConfig(bandwidth, datarate, coderate, preambleLen, fixLen, crcOn, iqInverted); |
Wayne Roberts |
8:5a5ea7cc946f | 330 | } |
Wayne Roberts |
8:5a5ea7cc946f | 331 | |
Wayne Roberts |
8:5a5ea7cc946f | 332 | { |
Wayne Roberts |
8:5a5ea7cc946f | 333 | IrqFlags_t irqEnable; |
Wayne Roberts |
8:5a5ea7cc946f | 334 | irqEnable.word = 0; |
Wayne Roberts |
8:5a5ea7cc946f | 335 | irqEnable.bits.TxDone = 1; |
Wayne Roberts |
8:5a5ea7cc946f | 336 | irqEnable.bits.Timeout = 1; |
Wayne Roberts |
8:5a5ea7cc946f | 337 | |
Wayne Roberts |
8:5a5ea7cc946f | 338 | buf[0] = irqEnable.word >> 8; // enable bits |
Wayne Roberts |
8:5a5ea7cc946f | 339 | buf[1] = irqEnable.word; // enable bits |
Wayne Roberts |
8:5a5ea7cc946f | 340 | buf[2] = irqEnable.word >> 8; // dio1 |
Wayne Roberts |
8:5a5ea7cc946f | 341 | buf[3] = irqEnable.word; // dio1 |
Wayne Roberts |
8:5a5ea7cc946f | 342 | buf[4] = 0; // dio2 |
Wayne Roberts |
8:5a5ea7cc946f | 343 | buf[5] = 0; // dio2 |
Wayne Roberts |
8:5a5ea7cc946f | 344 | buf[6] = 0; // dio3 |
Wayne Roberts |
8:5a5ea7cc946f | 345 | buf[7] = 0; // dio3 |
Wayne Roberts |
9:fe8e08792ae9 | 346 | radio.xfer(OPCODE_SET_DIO_IRQ_PARAMS, 8, 0, buf); |
Wayne Roberts |
8:5a5ea7cc946f | 347 | } |
Wayne Roberts |
8:5a5ea7cc946f | 348 | |
Wayne Roberts |
8:5a5ea7cc946f | 349 | _m_ = modem; |
Wayne Roberts |
8:5a5ea7cc946f | 350 | /* SetPacketParams written at Send() where payloadLength provided */ |
Wayne Roberts |
8:5a5ea7cc946f | 351 | |
Wayne Roberts |
8:5a5ea7cc946f | 352 | antswPower = 1; |
Wayne Roberts |
8:5a5ea7cc946f | 353 | } // ..SetTxConfig() |
Wayne Roberts |
8:5a5ea7cc946f | 354 | |
Wayne Roberts |
8:5a5ea7cc946f | 355 | int Radio::Send(uint8_t size, timestamp_t maxListenTime, timestamp_t channelFreeTime, int rssiThresh) |
Wayne Roberts |
8:5a5ea7cc946f | 356 | { |
Wayne Roberts |
8:5a5ea7cc946f | 357 | uint8_t buf[8]; |
Wayne Roberts |
8:5a5ea7cc946f | 358 | |
Wayne Roberts |
8:5a5ea7cc946f | 359 | if (_m_ == MODEM_FSK) { |
Wayne Roberts |
8:5a5ea7cc946f | 360 | pp.gfsk.PayloadLength = size; |
Wayne Roberts |
8:5a5ea7cc946f | 361 | |
Wayne Roberts |
8:5a5ea7cc946f | 362 | memcpy(buf, pp.buf, 8); |
Wayne Roberts |
9:fe8e08792ae9 | 363 | radio.xfer(OPCODE_SET_PACKET_PARAMS, 8, 0, buf); |
Wayne Roberts |
8:5a5ea7cc946f | 364 | } else if (_m_ == MODEM_LORA) { |
Wayne Roberts |
8:5a5ea7cc946f | 365 | pp.lora.PayloadLength = size; |
Wayne Roberts |
8:5a5ea7cc946f | 366 | |
Wayne Roberts |
8:5a5ea7cc946f | 367 | memcpy(buf, pp.buf, 6); |
Wayne Roberts |
9:fe8e08792ae9 | 368 | radio.xfer(OPCODE_SET_PACKET_PARAMS, 6, 0, buf); |
Wayne Roberts |
8:5a5ea7cc946f | 369 | } |
Wayne Roberts |
8:5a5ea7cc946f | 370 | |
Wayne Roberts |
8:5a5ea7cc946f | 371 | if (maxListenTime > 0) { |
Wayne Roberts |
8:5a5ea7cc946f | 372 | int rssi; |
Wayne Roberts |
8:5a5ea7cc946f | 373 | us_timestamp_t startAt, chFreeAt, now; |
Wayne Roberts |
8:5a5ea7cc946f | 374 | radio.start_rx(RX_TIMEOUT_CONTINUOUS); |
Wayne Roberts |
8:5a5ea7cc946f | 375 | startAt = lpt.read_us(); |
Wayne Roberts |
8:5a5ea7cc946f | 376 | Lstart: |
Wayne Roberts |
8:5a5ea7cc946f | 377 | do { |
Wayne Roberts |
8:5a5ea7cc946f | 378 | now = lpt.read_us(); |
Wayne Roberts |
8:5a5ea7cc946f | 379 | if ((now - startAt) > maxListenTime) { |
Wayne Roberts |
8:5a5ea7cc946f | 380 | return -1; |
Wayne Roberts |
8:5a5ea7cc946f | 381 | } |
Wayne Roberts |
9:fe8e08792ae9 | 382 | radio.xfer(OPCODE_GET_RSSIINST, 0, 2, buf); |
Wayne Roberts |
8:5a5ea7cc946f | 383 | rssi = buf[1] / -2; |
Wayne Roberts |
8:5a5ea7cc946f | 384 | } while (rssi > rssiThresh); |
Wayne Roberts |
8:5a5ea7cc946f | 385 | chFreeAt = lpt.read_us(); |
Wayne Roberts |
8:5a5ea7cc946f | 386 | do { |
Wayne Roberts |
8:5a5ea7cc946f | 387 | now = lpt.read_us(); |
Wayne Roberts |
9:fe8e08792ae9 | 388 | radio.xfer(OPCODE_GET_RSSIINST, 0, 2, buf); |
Wayne Roberts |
8:5a5ea7cc946f | 389 | rssi = buf[1] / -2; |
Wayne Roberts |
8:5a5ea7cc946f | 390 | if (rssi > rssiThresh) { |
Wayne Roberts |
8:5a5ea7cc946f | 391 | goto Lstart; |
Wayne Roberts |
8:5a5ea7cc946f | 392 | } |
Wayne Roberts |
8:5a5ea7cc946f | 393 | } while ((now - chFreeAt) < channelFreeTime); |
Wayne Roberts |
8:5a5ea7cc946f | 394 | } |
Wayne Roberts |
8:5a5ea7cc946f | 395 | |
Wayne Roberts |
8:5a5ea7cc946f | 396 | radio.start_tx(size); |
Wayne Roberts |
8:5a5ea7cc946f | 397 | |
Wayne Roberts |
8:5a5ea7cc946f | 398 | return 0; |
Wayne Roberts |
8:5a5ea7cc946f | 399 | } // ..Send() |
Wayne Roberts |
8:5a5ea7cc946f | 400 | |
Wayne Roberts |
8:5a5ea7cc946f | 401 | void Radio::SetRxMaxPayloadLength(RadioModems_t modem, uint8_t max) |
Wayne Roberts |
8:5a5ea7cc946f | 402 | { |
Wayne Roberts |
8:5a5ea7cc946f | 403 | uint8_t buf[8]; |
Wayne Roberts |
8:5a5ea7cc946f | 404 | |
Wayne Roberts |
8:5a5ea7cc946f | 405 | if (modem == MODEM_FSK) { |
Wayne Roberts |
8:5a5ea7cc946f | 406 | pp.gfsk.PayloadLength = max; |
Wayne Roberts |
8:5a5ea7cc946f | 407 | memcpy(buf, pp.buf, 8); |
Wayne Roberts |
9:fe8e08792ae9 | 408 | radio.xfer(OPCODE_SET_PACKET_PARAMS, 8, 0, buf); |
Wayne Roberts |
8:5a5ea7cc946f | 409 | } else if (modem == MODEM_LORA) { |
Wayne Roberts |
8:5a5ea7cc946f | 410 | pp.lora.PayloadLength = max; |
Wayne Roberts |
8:5a5ea7cc946f | 411 | memcpy(buf, pp.buf, 6); |
Wayne Roberts |
9:fe8e08792ae9 | 412 | radio.xfer(OPCODE_SET_PACKET_PARAMS, 6, 0, buf); |
Wayne Roberts |
8:5a5ea7cc946f | 413 | } |
Wayne Roberts |
8:5a5ea7cc946f | 414 | } |
Wayne Roberts |
8:5a5ea7cc946f | 415 | |
Wayne Roberts |
8:5a5ea7cc946f | 416 | void Radio::dio1_top_half() |
Wayne Roberts |
8:5a5ea7cc946f | 417 | { |
Wayne Roberts |
8:5a5ea7cc946f | 418 | dio1at = lpt.read_us(); |
Wayne Roberts |
8:5a5ea7cc946f | 419 | |
Wayne Roberts |
8:5a5ea7cc946f | 420 | if (radio.chipMode == CHIPMODE_TX) { |
Wayne Roberts |
8:5a5ea7cc946f | 421 | /* TxDone handling requires low latency */ |
Wayne Roberts |
8:5a5ea7cc946f | 422 | if (RadioEvents->TxDone) { |
Wayne Roberts |
8:5a5ea7cc946f | 423 | RadioEvents->TxDone(dio1at); |
Wayne Roberts |
8:5a5ea7cc946f | 424 | } |
Wayne Roberts |
8:5a5ea7cc946f | 425 | } |
Wayne Roberts |
8:5a5ea7cc946f | 426 | #ifdef TARGET_FF_MORPHO |
Wayne Roberts |
8:5a5ea7cc946f | 427 | else |
Wayne Roberts |
8:5a5ea7cc946f | 428 | pc3 = 0; |
Wayne Roberts |
8:5a5ea7cc946f | 429 | #endif /* TARGET_FF_MORPHO */ |
Wayne Roberts |
8:5a5ea7cc946f | 430 | } |
Wayne Roberts |
8:5a5ea7cc946f | 431 | |
Wayne Roberts |
8:5a5ea7cc946f | 432 | void Radio::timeout_callback(bool tx) |
Wayne Roberts |
8:5a5ea7cc946f | 433 | { |
Wayne Roberts |
8:5a5ea7cc946f | 434 | if (!tx) { |
Wayne Roberts |
8:5a5ea7cc946f | 435 | if (RadioEvents->RxTimeout) |
Wayne Roberts |
8:5a5ea7cc946f | 436 | RadioEvents->RxTimeout(); |
Wayne Roberts |
8:5a5ea7cc946f | 437 | #ifdef TARGET_FF_MORPHO |
Wayne Roberts |
8:5a5ea7cc946f | 438 | pc3 = 0; |
Wayne Roberts |
8:5a5ea7cc946f | 439 | #endif /* TARGET_FF_MORPHO */ |
Wayne Roberts |
8:5a5ea7cc946f | 440 | } // else TODO tx timeout |
Wayne Roberts |
8:5a5ea7cc946f | 441 | } |
Wayne Roberts |
8:5a5ea7cc946f | 442 | |
Wayne Roberts |
8:5a5ea7cc946f | 443 | void Radio::rx_done(uint8_t size, float rssi, float snr) |
Wayne Roberts |
8:5a5ea7cc946f | 444 | { |
Wayne Roberts |
8:5a5ea7cc946f | 445 | RadioEvents->RxDone(radio.rx_buf, size, rssi, snr, dio1at); |
Wayne Roberts |
8:5a5ea7cc946f | 446 | } |
Wayne Roberts |
8:5a5ea7cc946f | 447 | |
Wayne Roberts |
8:5a5ea7cc946f | 448 | void Radio::Init(const RadioEvents_t* e) |
Wayne Roberts |
8:5a5ea7cc946f | 449 | { |
Wayne Roberts |
8:5a5ea7cc946f | 450 | radio.txDone = NULL; |
Wayne Roberts |
8:5a5ea7cc946f | 451 | radio.rxDone = rx_done; |
Wayne Roberts |
8:5a5ea7cc946f | 452 | radio.timeout = timeout_callback; |
Wayne Roberts |
8:5a5ea7cc946f | 453 | radio.dio1_topHalf = dio1_top_half; |
Wayne Roberts |
8:5a5ea7cc946f | 454 | |
Wayne Roberts |
8:5a5ea7cc946f | 455 | RadioEvents = e; |
Wayne Roberts |
8:5a5ea7cc946f | 456 | lpt.start(); |
Wayne Roberts |
8:5a5ea7cc946f | 457 | |
Wayne Roberts |
8:5a5ea7cc946f | 458 | radio.SetDIO2AsRfSwitchCtrl(1); |
Wayne Roberts |
8:5a5ea7cc946f | 459 | } |
Wayne Roberts |
8:5a5ea7cc946f | 460 | |
Wayne Roberts |
8:5a5ea7cc946f | 461 | void Radio::UserContext() |
Wayne Roberts |
8:5a5ea7cc946f | 462 | { |
Wayne Roberts |
8:5a5ea7cc946f | 463 | radio.service(); |
Wayne Roberts |
8:5a5ea7cc946f | 464 | } |
Wayne Roberts |
8:5a5ea7cc946f | 465 | |
Wayne Roberts |
8:5a5ea7cc946f | 466 | void Radio::SetPublicNetwork(bool en) |
Wayne Roberts |
8:5a5ea7cc946f | 467 | { |
Wayne Roberts |
8:5a5ea7cc946f | 468 | uint16_t ppg; |
Wayne Roberts |
8:5a5ea7cc946f | 469 | |
Wayne Roberts |
8:5a5ea7cc946f | 470 | if (en) |
Wayne Roberts |
8:5a5ea7cc946f | 471 | ppg = 0x3444; |
Wayne Roberts |
8:5a5ea7cc946f | 472 | else |
Wayne Roberts |
8:5a5ea7cc946f | 473 | ppg = 0x1424; |
Wayne Roberts |
8:5a5ea7cc946f | 474 | |
Wayne Roberts |
8:5a5ea7cc946f | 475 | radio.writeReg(REG_ADDR_LORA_SYNC, ppg, 2); |
Wayne Roberts |
8:5a5ea7cc946f | 476 | } |
Wayne Roberts |
8:5a5ea7cc946f | 477 | |
Wayne Roberts |
8:5a5ea7cc946f | 478 | void Radio::PrintStatus() |
Wayne Roberts |
8:5a5ea7cc946f | 479 | { |
Wayne Roberts |
8:5a5ea7cc946f | 480 | uint8_t buf[4]; |
Wayne Roberts |
8:5a5ea7cc946f | 481 | status_t status; |
Wayne Roberts |
8:5a5ea7cc946f | 482 | IrqFlags_t irqFlags; |
Wayne Roberts |
9:fe8e08792ae9 | 483 | radio.xfer(OPCODE_GET_IRQ_STATUS, 0, 3, buf); |
Wayne Roberts |
8:5a5ea7cc946f | 484 | irqFlags.word = buf[1] << 8; |
Wayne Roberts |
8:5a5ea7cc946f | 485 | irqFlags.word |= buf[2]; |
Wayne Roberts |
8:5a5ea7cc946f | 486 | |
Wayne Roberts |
8:5a5ea7cc946f | 487 | printf("dio1:%u irqFlags:%04x\r\n", radio.getDIO1(), irqFlags.word); |
Wayne Roberts |
9:fe8e08792ae9 | 488 | radio.xfer(OPCODE_GET_STATUS, 0, 1, &status.octet); |
Wayne Roberts |
8:5a5ea7cc946f | 489 | radio.PrintChipStatus(status); |
Wayne Roberts |
8:5a5ea7cc946f | 490 | } |
Wayne Roberts |
8:5a5ea7cc946f | 491 | |
Wayne Roberts |
8:5a5ea7cc946f | 492 | #endif /* ..SX126x_H */ |