diff --git a/Boards.h b/Boards.h index ef2b8c5..c059cd6 100644 --- a/Boards.h +++ b/Boards.h @@ -149,6 +149,10 @@ #endif #endif + #define LORA_PA_UNKNOWN 0x00 + #define LORA_PA_GC1109 0x01 + #define LORA_PA_KCT8103L 0x02 + #define HAS_DISPLAY false #define HAS_BLUETOOTH false #define HAS_BLE false @@ -251,7 +255,7 @@ #define HAS_TCXO true #define HAS_BUSY true #define DIO2_AS_RF_SWITCH true - #define OCP_TUNED 0x18 + #define OCP_TUNED 0x28 const int pin_busy = 32; const int pin_dio = 33; const int pin_tcxo_enable = -1; @@ -357,7 +361,7 @@ #define HAS_SLEEP true #define PIN_WAKEUP GPIO_NUM_0 #define WAKEUP_LEVEL 0 - #define OCP_TUNED 0x18 + #define OCP_TUNED 0x28 const int pin_btn_usr1 = 0; @@ -399,8 +403,9 @@ #define HAS_LORA_LNA true #define PIN_WAKEUP GPIO_NUM_0 #define WAKEUP_LEVEL 0 - #define OCP_TUNED 0x18 + #define OCP_TUNED 0x28 #define Vext GPIO_NUM_36 + #define LORA_PA_MODEL LORA_PA_UNKNOWN; const int pin_btn_usr1 = 0; @@ -422,14 +427,17 @@ #define LORA_LNA_GAIN 17 #define LORA_LNA_GVT 12 - #define LORA_PA_GC1109 true #define LORA_PA_PWR_EN 7 - #define LORA_PA_CSD 2 - #define LORA_PA_CPS 46 + #define LORA_PA_CSD 2 // Same pin on GC1109 + #define LORA_PA_CPS 46 // Same pin on GC1109 + #define LORA_PA_CTX 5 // Only used on KCT8103 #define PA_MAX_OUTPUT 28 #define PA_GAIN_POINTS 22 - #define PA_GAIN_VALUES 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 10, 10, 9, 9, 8, 7 + + #define LORA_LNA_KCT8103L_GAIN 21 + const int PA_GC1109_VALUES[PA_GAIN_POINTS] = {11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 10, 10, 9, 9, 8, 7}; + const int PA_KCT8103L_VALUES[PA_GAIN_POINTS] = {13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 12, 12, 11, 11, 10, 9, 8, 7}; const int pin_cs = 8; const int pin_busy = 13; @@ -618,7 +626,7 @@ #define DIO2_AS_RF_SWITCH true #define HAS_BUSY true #define HAS_TCXO true - #define OCP_TUNED 0x18 + #define OCP_TUNED 0x28 #define HAS_DISPLAY true #define HAS_CONSOLE true @@ -921,7 +929,7 @@ // Default OCP value if not specified // in board configuration #ifndef OCP_TUNED - #define OCP_TUNED 0x18 + #define OCP_TUNED 0x28 #endif #ifndef NP_M diff --git a/Utilities.h b/Utilities.h index 8892f59..f6fbac2 100644 --- a/Utilities.h +++ b/Utilities.h @@ -1287,11 +1287,33 @@ int getTxPower() { } #if HAS_LORA_PA - const int tx_gain[PA_GAIN_POINTS] = {PA_GAIN_VALUES}; + #if BOARD_MODEL == BOARD_HELTEC32_V4 + bool pa_values_determined = false; + int tx_gain[PA_GAIN_POINTS] = {100}; + #else + bool pa_values_determined = true; + const int tx_gain[PA_GAIN_POINTS] = {PA_GAIN_VALUES}; + #endif #endif +extern uint8_t lora_pa_model; +void determine_pa_values() { + #if BOARD_MODEL == BOARD_HELTEC32_V4 + if (lora_pa_model == LORA_PA_GC1109) { + for (int i=0; i < PA_GAIN_POINTS; i++) { tx_gain[i] = PA_GC1109_VALUES[i]; } + pa_values_determined = true; + for (int i=0; i < PA_GAIN_POINTS; i++) { Serial.print(" "); Serial.printf("%d", tx_gain[i]); } + } else if (lora_pa_model == LORA_PA_KCT8103L) { + for (int i=0; i < PA_GAIN_POINTS; i++) { tx_gain[i] = PA_KCT8103L_VALUES[i]; } + pa_values_determined = true; + for (int i=0; i < PA_GAIN_POINTS; i++) { Serial.print(" "); Serial.printf("%d", tx_gain[i]); } + } + #endif +} + int map_target_power_to_modem_output(int target_tx_power) { #if HAS_LORA_PA + if (!pa_values_determined) { determine_pa_values(); } int modem_output_dbm = -9; for (int i = 0; i < PA_GAIN_POINTS; i++) { int gain = tx_gain[i]; diff --git a/sx126x.cpp b/sx126x.cpp index f8da5fa..97ca045 100644 --- a/sx126x.cpp +++ b/sx126x.cpp @@ -96,6 +96,14 @@ #define SPI spiModem #endif +#if HAS_LORA_PA + uint8_t lora_pa_model = LORA_PA_MODEL; +#endif + +#if HAS_LORA_LNA + int lora_lna_gain = LORA_LNA_GAIN; +#endif + extern SPIClass SPI; #define MAX_PKT_LENGTH 255 @@ -358,7 +366,22 @@ int sx126x::begin(long frequency) { setPacketParams(_preambleLength, _implicitHeaderMode, _payloadLength, _crcMode); #if HAS_LORA_PA - #if LORA_PA_GC1109 + if (lora_pa_model == LORA_PA_UNKNOWN) { + #if BOARD_MODEL == BOARD_HELTEC32_V4 + + pinMode(LORA_PA_PWR_EN, OUTPUT); + pinMode(LORA_PA_CSD, INPUT); + digitalWrite(LORA_PA_PWR_EN, HIGH); delay(5); + if (digitalRead(LORA_PA_CSD) == HIGH) { + lora_pa_model = LORA_PA_KCT8103L; + lora_lna_gain = LORA_LNA_KCT8103L_GAIN; + } else { + lora_pa_model = LORA_PA_GC1109; + } + #endif + } + + if (lora_pa_model == LORA_PA_GC1109) { // Enable Vfem_ctl for supply to // PA power net. pinMode(LORA_PA_PWR_EN, OUTPUT); @@ -383,7 +406,26 @@ int sx126x::begin(long frequency) { // is driven by the SX1262 DIO2 // pin directly, so we do not // need to manually raise this. - #endif + + } else if (lora_pa_model == LORA_PA_KCT8103L) { + // Enable Vfem_ctl for supply to + // PA power net. + pinMode(LORA_PA_PWR_EN, OUTPUT); + digitalWrite(LORA_PA_PWR_EN, HIGH); + + // Enable KCT8103L chip + pinMode(LORA_PA_CSD, OUTPUT); + digitalWrite(LORA_PA_CSD, HIGH); + + // Enable receive LNA + pinMode(LORA_PA_CTX, OUTPUT); + digitalWrite(LORA_PA_CTX, LOW); + + // On Heltec V4.3, the PA CPS pin + // is driven by the SX1262 DIO2 + // pin directly, so we do not + // need to manually raise this. + } #endif return 1; @@ -393,13 +435,15 @@ void sx126x::end() { sleep(); SPI.end(); _preinit_done = false; } int sx126x::beginPacket(int implicitHeader) { #if HAS_LORA_PA - #if LORA_PA_GC1109 + if (lora_pa_model == LORA_PA_GC1109) { // Enable PA CPS for transmit // digitalWrite(LORA_PA_CPS, HIGH); // Disabled since we're keeping it // on permanently as long as the // radio is powered up. - #endif + } else if (lora_pa_model == LORA_PA_KCT8103L) { + digitalWrite(LORA_PA_CTX, HIGH); + } #endif standby(); @@ -487,7 +531,7 @@ int ISR_VECT sx126x::currentRssi() { executeOpcodeRead(OP_CURRENT_RSSI_6X, &byte, 1); int rssi = -(int(byte)) / 2; #if HAS_LORA_LNA - rssi -= LORA_LNA_GAIN; + rssi -= lora_lna_gain; #endif return rssi; } @@ -503,7 +547,7 @@ int ISR_VECT sx126x::packetRssi() { executeOpcodeRead(OP_PACKET_STATUS_6X, buf, 3); int pkt_rssi = -buf[0] / 2; #if HAS_LORA_LNA - pkt_rssi -= LORA_LNA_GAIN; + pkt_rssi -= lora_lna_gain; #endif return pkt_rssi; } @@ -610,7 +654,7 @@ void sx126x::onReceive(void(*callback)(int)){ void sx126x::receive(int size) { #if HAS_LORA_PA - #if LORA_PA_GC1109 + if (lora_pa_model == LORA_PA_GC1109) { // Disable PA CPS for receive // digitalWrite(LORA_PA_CPS, LOW); // That turned out to be a bad idea. @@ -618,7 +662,9 @@ void sx126x::receive(int size) { // on and off too quickly. We'll keep // it on permanently, as long as the // radio is powered up. - #endif + } else if (lora_pa_model == LORA_PA_KCT8103L) { + digitalWrite(LORA_PA_CTX, LOW); + } #endif if (size > 0) {