Unverified Commit b35dfb3f authored by Birte Kristina Friesel's avatar Birte Kristina Friesel
Browse files

lora32u4ii test app (reads version from SX1276)

parent a6128153
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
# Copyright 2021 Daniel Friesel
#
# SPDX-License-Identifier: CC0-1.0

prompt "LoRa32u4 II v1.3 Test App"
depends on loop && !wakeup
+9 −0
Original line number Diff line number Diff line
# vim:ft=make
#
# Copyright 2021 Daniel Friesel
#
# SPDX-License-Identifier: CC0-1.0

ifdef app
	loop = 1
endif
+135 −0
Original line number Diff line number Diff line
/*
 * Copyright 2021 Daniel Friesel
 *
 * SPDX-License-Identifier: BSD-2-Clause
 */
#include "arch.h"
#include "driver/gpio.h"
#include "driver/stdout.h"
#include "driver/uptime.h"
#include "driver/adc.h"
#include "driver/spi.h"

#define CFG_eu868 1
#define CFG_sx1276_radio 1

#include "radio.h"
#include "oslmic.h"

unsigned char txbuf[4];
unsigned char rxbuf[4];

// DIYMall BSFrance LoRa32u4 II v1.3
// See also: arduino packages/adafruit/hardware/avr/1.4.13/variants/feather32u4/pins_arduino.h
// PB0 -> Charger enable and Vbat/2 measurement voltage divider enable
// PB0 is also the !SS pin, so it must be configured as output in order to use SPI.
// PB5 "D9" <- Vbat/2 via voltage divider. Appears to also have a connection to the user LED
// PC7 "D13" -> User LED
const GPIO::Pin rstpin = GPIO::pd4; // "D4" -> RST
const GPIO::Pin  cspin = GPIO::pb4; // "D8" -> NSS
const GPIO::Pin dio0pin = GPIO::pe6; // "D7" <- DIO0 / IRQ
const GPIO::Pin dio1pin = GPIO::pc6; // "D5" <- DIO1

static void writeReg (u1_t addr, u1_t data) {
	txbuf[0] = addr | 0x80;
	txbuf[1] = data;
	gpio.write(cspin, 0);
	spi.xmit(2, txbuf, 0, rxbuf);
	gpio.write(cspin, 1);
}

static u1_t readReg (u1_t addr) {
	txbuf[0] = addr & 0x7f;
	gpio.write(cspin, 0);
	spi.xmit(1, txbuf, 2, rxbuf);
	gpio.write(cspin, 1);
	return rxbuf[1];
}
/*
static void writeBuf (u1_t addr, xref2u1_t buf, u1_t len) {
	txbuf[0] = addr | 0x80;
	for (uint8_t i = 0; i < len; i++) {
		txbuf[i+1] = buf[i];
	}
	spi.xmit(len+1, txbuf, 0, rxbuf);
}

static void readBuf (u1_t addr, xref2u1_t buf, u1_t len) {
	txbuf[0] = addr & 0x7f;
	spi.xmit(1, txbuf, len, buf);
}
*/

static void writeOpmode(u1_t mode) {
	u1_t const maskedMode = mode & OPMODE_MASK;
	writeReg(RegOpMode, mode);
}

static void opmode (u1_t mode) {
	writeOpmode((readReg(RegOpMode) & ~OPMODE_MASK) | mode);
}



bool radio_init()
{
	// requestModuleActive(1); not required for sx yadayada
	gpio.output(cspin, 1);
#ifdef CFG_sx1276_radio
	gpio.output(rstpin, 0);
#else
	gpio.output(rstpin, 1);
#endif
	arch.delay_ms(1);
	gpio.input(rstpin);
	gpio.write(rstpin, 0); // disable pull-up
	arch.delay_ms(5);
	opmode(OPMODE_SLEEP);

	u1_t v = readReg(RegVersion);
#ifdef CFG_sx1276_radio
	if(v != 0x12 ) {
		kout << "Radio version mismatch: expected " << hex << 0x12 << ", got " << v << endl;
		return false;
	}
#elif CFG_sx1272_radio
	if(v != 0x22) {
		kout << "Radio version mismatch: expected " << hex << 0x22 << ", got " << v << endl;
		return false;
	}
#else
#error Missing CFG_sx1272_radio/CFG_sx1276_radio
#endif
	return true;
}

void loop(void)
{
	//gpio.led_toggle(1);
#ifdef TIMER_S
	kout << dec << uptime.get_s() << endl;
#else
	kout << "beep boop" << endl;
#endif
	kout << "VCC  = " << adc.getVCC_mV() << " mV" << endl;
	kout << "Vbat = " << adc.getVBat_mV(false) << " mV" << endl;
	gpio.led_toggle(0);
}

int main(void)
{
	arch.setup();
	gpio.setup();
	kout.setup();
	spi.setup();
	gpio.input(GPIO::pb5);

	radio_init();

	kout << "Hello, World!" << endl;
	kout << "Test, World!" << endl;

	arch.idle_loop();

	return 0;
}
+42 −0
Original line number Diff line number Diff line
#pragma once
/*
 * Copyright (c) 2014-2016 IBM Corporation.
 * Copyright (c) 2018, 2019 MCCI Corporation
 * Copyright (c) 2021 Daniel Friesel
 * All rights reserved.
 *
 *  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 the <organization> 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 <COPYRIGHT HOLDER> 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 <stdint.h>
typedef uint8_t            bit_t;
typedef uint8_t            u1_t;
typedef int8_t             s1_t;
typedef uint16_t           u2_t;
typedef int16_t            s2_t;
typedef uint32_t           u4_t;
typedef int32_t            s4_t;
typedef unsigned int       uint;
typedef const char*        str_t;

+369 −0
Original line number Diff line number Diff line
#pragma once
/*
 * Copyright (c) 2014-2016 IBM Corporation.
 * Copyright (c) 2016-2019 MCCI Corporation.
 * All rights reserved.
 *
 *  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 the <organization> 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 <COPYRIGHT HOLDER> 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.
 */

// ----------------------------------------
// Registers Mapping
//                                                      // -type-       1272 vs 1276
#define RegFifo                                    0x00 // common
#define RegOpMode                                  0x01 // common       see below
#define FSKRegBitrateMsb                           0x02 //              -
#define FSKRegBitrateLsb                           0x03 //              -
#define FSKRegFdevMsb                              0x04 //              -
#define FSKRegFdevLsb                              0x05 //              -
#define RegFrfMsb                                  0x06 // common       FSK: 1272: 915; 1276: 434 MHz
#define RegFrfMid                                  0x07 // common       ditto
#define RegFrfLsb                                  0x08 // common       ditto
#define RegPaConfig                                0x09 // common       see below, many diffs
#define RegPaRamp                                  0x0A // common       see below: bits 6..4 are diff
#define RegOcp                                     0x0B // common       -
#define RegLna                                     0x0C // common       bits 4..0 are diff.
#define FSKRegRxConfig                             0x0D //              -
#define LORARegFifoAddrPtr                         0x0D
#define FSKRegRssiConfig                           0x0E //              -
#define LORARegFifoTxBaseAddr                      0x0E
#define FSKRegRssiCollision                        0x0F //              -
#define LORARegFifoRxBaseAddr                      0x0F
#define FSKRegRssiThresh                           0x10 //              -
#define LORARegFifoRxCurrentAddr                   0x10
#define FSKRegRssiValue                            0x11 //              -
#define LORARegIrqFlagsMask                        0x11
#define FSKRegRxBw                                 0x12 //              -
#define LORARegIrqFlags                            0x12
#define FSKRegAfcBw                                0x13 //              -
#define LORARegRxNbBytes                           0x13
#define FSKRegOokPeak                              0x14 //              -
#define LORARegRxHeaderCntValueMsb                 0x14
#define FSKRegOokFix                               0x15 //              -
#define LORARegRxHeaderCntValueLsb                 0x15
#define FSKRegOokAvg                               0x16 //              -
#define LORARegRxPacketCntValueMsb                 0x16
#define LORARegRxpacketCntValueLsb                 0x17
#define LORARegModemStat                           0x18
#define LORARegPktSnrValue                         0x19
#define FSKRegAfcFei                               0x1A //              -
#define LORARegPktRssiValue                        0x1A
#define FSKRegAfcMsb                               0x1B //              -
#define LORARegRssiValue                           0x1B
#define FSKRegAfcLsb                               0x1C //              -
#define LORARegHopChannel                          0x1C
#define FSKRegFeiMsb                               0x1D //              -
#define LORARegModemConfig1                        0x1D
#define FSKRegFeiLsb                               0x1E //              -
#define LORARegModemConfig2                        0x1E
#define FSKRegPreambleDetect                       0x1F //              -
#define LORARegSymbTimeoutLsb                      0x1F
#define FSKRegRxTimeout1                           0x20 //              -
#define LORARegPreambleMsb                         0x20
#define FSKRegRxTimeout2                           0x21 //              -
#define LORARegPreambleLsb                         0x21
#define FSKRegRxTimeout3                           0x22 //              -
#define LORARegPayloadLength                       0x22
#define FSKRegRxDelay                              0x23 //              -
#define LORARegPayloadMaxLength                    0x23
#define FSKRegOsc                                  0x24 //              -
#define LORARegHopPeriod                           0x24
#define FSKRegPreambleMsb                          0x25 //              -
#define LORARegFifoRxByteAddr                      0x25
#define FSKRegPreambleLsb                          0x26 //              -
#define LORARegModemConfig3                        0x26
#define FSKRegSyncConfig                           0x27 //              -
#define LORARegFeiMsb                              0x28
#define FSKRegSyncValue1                           0x28 //              -
#define LORAFeiMib                                 0x29
#define FSKRegSyncValue2                           0x29 //              -
#define LORARegFeiLsb                              0x2A
#define FSKRegSyncValue3                           0x2A //              -
#define FSKRegSyncValue4                           0x2B //              -
#define LORARegRssiWideband                        0x2C
#define FSKRegSyncValue5                           0x2C //              -
#define FSKRegSyncValue6                           0x2D //              -
#define FSKRegSyncValue7                           0x2E //              -
#define FSKRegSyncValue8                           0x2F //              -
#define LORARegIffReq1                             0x2F
#define FSKRegPacketConfig1                        0x30 //              -
#define LORARegIffReq2                             0x30
#define FSKRegPacketConfig2                        0x31 //              -
#define LORARegDetectOptimize                      0x31
#define FSKRegPayloadLength                        0x32 //              -
#define FSKRegNodeAdrs                             0x33 //              -
#define LORARegInvertIQ                            0x33
#define FSKRegBroadcastAdrs                        0x34 //              -
#define FSKRegFifoThresh                           0x35 //              -
#define FSKRegSeqConfig1                           0x36 //              -
#define LORARegHighBwOptimize1                     0x36
#define FSKRegSeqConfig2                           0x37 //              -
#define LORARegDetectionThreshold                  0x37
#define FSKRegTimerResol                           0x38 //              -
#define FSKRegTimer1Coef                           0x39 //              -
#define LORARegSyncWord                            0x39
#define FSKRegTimer2Coef                           0x3A //              -
#define LORARegHighBwOptimize2                     0x3A
#define FSKRegImageCal                             0x3B //              -
#define FSKRegTemp                                 0x3C //              -
#define FSKRegLowBat                               0x3D //              -
#define FSKRegIrqFlags1                            0x3E //              -
#define FSKRegIrqFlags2                            0x3F //              -
#define RegDioMapping1                             0x40 // common
#define RegDioMapping2                             0x41 // common
#define RegVersion                                 0x42 // common
// #define RegAgcRef                                  0x43 // common
// #define RegAgcThresh1                              0x44 // common
// #define RegAgcThresh2                              0x45 // common
// #define RegAgcThresh3                              0x46 // common
// #define RegPllHop                                  0x4B // common
// #define RegTcxo                                    0x58 // common
// #define RegPll                                     0x5C // common
// #define RegPllLowPn                                0x5E // common
// #define RegFormerTemp                              0x6C // common
// #define RegBitRateFrac                             0x70 // common

#if defined(CFG_sx1276_radio)
#define RegTcxo                                    0x4B // common       different addresses, same bits
#define RegPaDac                                   0x4D // common       differnet addresses, same bits
#elif defined(CFG_sx1272_radio)
#define RegTcxo                                    0x58 // common
#define RegPaDac                                   0x5A // common
#endif

#define RegTcxo_TcxoInputOn                        (1u << 4)

// ----------------------------------------
// spread factors and mode for RegModemConfig2
#define SX1272_MC2_FSK  0x00
#define SX1272_MC2_SF7  0x70
#define SX1272_MC2_SF8  0x80
#define SX1272_MC2_SF9  0x90
#define SX1272_MC2_SF10 0xA0
#define SX1272_MC2_SF11 0xB0
#define SX1272_MC2_SF12 0xC0
// bandwidth for RegModemConfig1
#define SX1272_MC1_BW_125  0x00
#define SX1272_MC1_BW_250  0x40
#define SX1272_MC1_BW_500  0x80
// coding rate for RegModemConfig1
#define SX1272_MC1_CR_4_5 0x08
#define SX1272_MC1_CR_4_6 0x10
#define SX1272_MC1_CR_4_7 0x18
#define SX1272_MC1_CR_4_8 0x20
#define SX1272_MC1_IMPLICIT_HEADER_MODE_ON 0x04 // required for receive
#define SX1272_MC1_RX_PAYLOAD_CRCON        0x02
#define SX1272_MC1_LOW_DATA_RATE_OPTIMIZE  0x01 // mandated for SF11 and SF12
// transmit power configuration for RegPaConfig
#define SX1272_PAC_PA_SELECT_PA_BOOST 0x80
#define SX1272_PAC_PA_SELECT_RFIO_PIN 0x00


// sx1276 RegModemConfig1
#define SX1276_MC1_BW_125                0x70
#define SX1276_MC1_BW_250                0x80
#define SX1276_MC1_BW_500                0x90
#define SX1276_MC1_CR_4_5            0x02
#define SX1276_MC1_CR_4_6            0x04
#define SX1276_MC1_CR_4_7            0x06
#define SX1276_MC1_CR_4_8            0x08

#define SX1276_MC1_IMPLICIT_HEADER_MODE_ON    0x01

#ifdef CFG_sx1276_radio
# define SX127X_MC1_IMPLICIT_HEADER_MODE_ON	SX1276_MC1_IMPLICIT_HEADER_MODE_ON
#else
# define SX127X_MC1_IMPLICIT_HEADER_MODE_ON	SX1272_MC1_IMPLICIT_HEADER_MODE_ON
#endif

// transmit power configuration for RegPaConfig
#define SX1276_PAC_PA_SELECT_PA_BOOST 0x80
#define SX1276_PAC_PA_SELECT_RFIO_PIN 0x00
#define SX1276_PAC_MAX_POWER_MASK     0x70

// the bits to change for max power.
#define SX127X_PADAC_POWER_MASK       0x07
#define SX127X_PADAC_POWER_NORMAL     0x04
#define SX127X_PADAC_POWER_20dBm      0x07

// convert milliamperes to equivalent value for
// RegOcp; delivers conservative value.
#define SX127X_OCP_MAtoBITS(mA)                 \
    ((mA) < 45   ? 0 :                          \
     (mA) <= 120 ? ((mA) - 45) / 5 :            \
     (mA) < 130  ? 0xF :                        \
     (mA) < 240  ? ((mA) - 130) / 10 + 0x10 :   \
                   27)

// bit in RegOcp that enables overcurrent protect.
#define SX127X_OCP_ENA                     0x20

// sx1276 RegModemConfig2
#define SX1276_MC2_RX_PAYLOAD_CRCON        0x04

// sx1276 RegModemConfig3
#define SX1276_MC3_LOW_DATA_RATE_OPTIMIZE  0x08
#define SX1276_MC3_AGCAUTO                 0x04

// preamble for lora networks (nibbles swapped)
#define LORA_MAC_PREAMBLE                  0x34

#define RXLORA_RXMODE_RSSI_REG_MODEM_CONFIG1 0x0A
#ifdef CFG_sx1276_radio
#define RXLORA_RXMODE_RSSI_REG_MODEM_CONFIG2 0x70
#elif CFG_sx1272_radio
#define RXLORA_RXMODE_RSSI_REG_MODEM_CONFIG2 0x74
#endif

//-----------------------------------------
// Parameters for RSSI monitoring
#define SX127X_FREQ_LF_MAX      525000000       // per datasheet 6.3

// per datasheet 5.5.3 and 5.5.5:
#define SX1272_RSSI_ADJUST      -139            // add to rssi value to get dB (LF)

// per datasheet 5.5.3 and 5.5.5:
#define SX1276_RSSI_ADJUST_LF   -164            // add to rssi value to get dB (LF)
#define SX1276_RSSI_ADJUST_HF   -157            // add to rssi value to get dB (HF)

#ifdef CFG_sx1276_radio
# define SX127X_RSSI_ADJUST_LF  SX1276_RSSI_ADJUST_LF
# define SX127X_RSSI_ADJUST_HF  SX1276_RSSI_ADJUST_HF
#else
# define SX127X_RSSI_ADJUST_LF  SX1272_RSSI_ADJUST
# define SX127X_RSSI_ADJUST_HF  SX1272_RSSI_ADJUST
#endif

// per datasheet 2.5.2 (but note that we ought to ask Semtech to confirm, because
// datasheet is unclear).
#define SX127X_RX_POWER_UP      us2osticks(500) // delay this long to let the receiver power up.

// ----------------------------------------
// Constants for radio registers
#define OPMODE_LORA      0x80
#define OPMODE_MASK      0x07
#define OPMODE_SLEEP     0x00
#define OPMODE_STANDBY   0x01
#define OPMODE_FSTX      0x02
#define OPMODE_TX        0x03
#define OPMODE_FSRX      0x04
#define OPMODE_RX        0x05
#define OPMODE_RX_SINGLE 0x06
#define OPMODE_CAD       0x07

// ----------------------------------------
// FSK opmode bits
// bits 6:5 are the same for 1272 and 1276
#define OPMODE_FSK_SX127x_ModulationType_FSK            (0u << 5)
#define OPMODE_FSK_SX127x_ModulationType_OOK            (1u << 5)
#define OPMODE_FSK_SX127x_ModulationType_MASK           (3u << 5)

// bits 4:3 are different for 1272
#define OPMODE_FSK_SX1272_ModulationShaping_FSK_None    (0u << 3)
#define OPMODE_FSK_SX1272_ModulationShaping_FSK_BT1_0   (1u << 3)
#define OPMODE_FSK_SX1272_ModulationShaping_FSK_BT0_5   (2u << 3)
#define OPMODE_FSK_SX1272_ModulationShaping_FSK_BT0_3   (3u << 3)
#define OPMODE_FSK_SX1272_ModulationShaping_OOK_None    (0u << 3)
#define OPMODE_FSK_SX1272_ModulationShaping_OOK_BR      (1u << 3)
#define OPMODE_FSK_SX1272_ModulationShaping_OOK_2BR     (2u << 3)

#define OPMODE_FSK_SX1272_ModulationShaping_MASK        (3u << 3)

// SX1276
#define OPMODE_FSK_SX1276_LowFrequencyModeOn            (1u << 3)

// define the opmode bits apporpriate for the 127x in use.
#if defined(CFG_sx1272_radio)
# define    OPMODE_FSK_SX127X_SETUP     (OPMODE_FSK_SX127x_ModulationType_FSK | \
                                         OPMODE_FSK_SX1272_ModulationShaping_FSK_BT0_5)
#elif defined(CFG_sx1276_radio)
# define    OPMODE_FSK_SX127X_SETUP     (OPMODE_FSK_SX127x_ModulationType_FSK)
#endif

// ----------------------------------------
// LoRa opmode bits
#define OPMODE_LORA_SX127x_AccessSharedReg              (1u << 6)
#define OPMODE_LORA_SX1276_LowFrequencyModeOn           (1u << 3)

// ----------------------------------------
// Bits masking the corresponding IRQs from the radio
#define IRQ_LORA_RXTOUT_MASK 0x80
#define IRQ_LORA_RXDONE_MASK 0x40
#define IRQ_LORA_CRCERR_MASK 0x20
#define IRQ_LORA_HEADER_MASK 0x10
#define IRQ_LORA_TXDONE_MASK 0x08
#define IRQ_LORA_CDDONE_MASK 0x04
#define IRQ_LORA_FHSSCH_MASK 0x02
#define IRQ_LORA_CDDETD_MASK 0x01

#define IRQ_FSK1_MODEREADY_MASK         0x80
#define IRQ_FSK1_RXREADY_MASK           0x40
#define IRQ_FSK1_TXREADY_MASK           0x20
#define IRQ_FSK1_PLLLOCK_MASK           0x10
#define IRQ_FSK1_RSSI_MASK              0x08
#define IRQ_FSK1_TIMEOUT_MASK           0x04
#define IRQ_FSK1_PREAMBLEDETECT_MASK    0x02
#define IRQ_FSK1_SYNCADDRESSMATCH_MASK  0x01
#define IRQ_FSK2_FIFOFULL_MASK          0x80
#define IRQ_FSK2_FIFOEMPTY_MASK         0x40
#define IRQ_FSK2_FIFOLEVEL_MASK         0x20
#define IRQ_FSK2_FIFOOVERRUN_MASK       0x10
#define IRQ_FSK2_PACKETSENT_MASK        0x08
#define IRQ_FSK2_PAYLOADREADY_MASK      0x04
#define IRQ_FSK2_CRCOK_MASK             0x02
#define IRQ_FSK2_LOWBAT_MASK            0x01

// ----------------------------------------
// DIO function mappings                D0D1D2D3
#define MAP_DIO0_LORA_RXDONE   0x00  // 00------
#define MAP_DIO0_LORA_TXDONE   0x40  // 01------
#define MAP_DIO1_LORA_RXTOUT   0x00  // --00----
#define MAP_DIO1_LORA_NOP      0x30  // --11----
#define MAP_DIO2_LORA_NOP      0x0C  // ----11--

#define MAP_DIO0_FSK_READY     0x00  // 00------ (packet sent / payload ready)
#define MAP_DIO1_FSK_NOP       0x30  // --11----
#define MAP_DIO2_FSK_TXNOP     0x04  // ----01--
#define MAP_DIO2_FSK_TIMEOUT   0x08  // ----10--


// FSK IMAGECAL defines
#define RF_IMAGECAL_AUTOIMAGECAL_MASK               0x7F
#define RF_IMAGECAL_AUTOIMAGECAL_ON                 0x80
#define RF_IMAGECAL_AUTOIMAGECAL_OFF                0x00  // Default

#define RF_IMAGECAL_IMAGECAL_MASK                   0xBF
#define RF_IMAGECAL_IMAGECAL_START                  0x40

#define RF_IMAGECAL_IMAGECAL_RUNNING                0x20
#define RF_IMAGECAL_IMAGECAL_DONE                   0x00  // Default

// LNA gain constant. Bits 4..0 have different meaning for 1272 and 1276, but
// by chance, the bit patterns we use are the same.
#ifdef CFG_sx1276_radio
#define LNA_RX_GAIN (0x20|0x3)
#elif CFG_sx1272_radio
#define LNA_RX_GAIN (0x20|0x03)
#else
#error Missing CFG_sx1272_radio/CFG_sx1276_radio
#endif