diff --git a/platform/drivers/baseband/SA8x8.c b/platform/drivers/baseband/SA8x8.c index b07cb9cd..68739e73 100644 --- a/platform/drivers/baseband/SA8x8.c +++ b/platform/drivers/baseband/SA8x8.c @@ -40,11 +40,13 @@ #endif #define RADIO_PDN_NODE DT_ALIAS(radio_pdn) +#define RADIO_PWR_NODE DT_NODELABEL(radio_pwr) #define SA8X8_MSG_SIZE 32U static const struct device *const uart_dev = DEVICE_DT_GET(UART_RADIO_DEV_NODE); static const struct gpio_dt_spec radio_pdn = GPIO_DT_SPEC_GET(RADIO_PDN_NODE, gpios); +static const struct gpio_dt_spec radio_pwr = GPIO_DT_SPEC_GET_OR(RADIO_PWR_NODE, gpios, {0}); K_MSGQ_DEFINE(uart_msgq, SA8X8_MSG_SIZE, 10, 4); @@ -149,6 +151,21 @@ int sa8x8_init() return ret; } + // Initialize GPIO for SA868S high power mode + if(gpio_is_ready_dt(&radio_pwr) == false) + { + printk("SA8x8: error, high power GPIO %s is not ready\n", radio_pdn.port->name); + return ret; + } + + ret = gpio_pin_configure_dt(&radio_pwr, GPIO_OUTPUT); + if (ret != 0) + { + printk("SA8x8: error %d, failed to configure %s pin %d\n", ret, + radio_pwr.port->name, radio_pwr.pin); + return ret; + } + // Reset the SA868S baseband gpio_pin_set_dt(&radio_pdn, 1); delayMs(100); @@ -254,6 +271,17 @@ int sa8x8_enableHSMode() return 0; } +void sa8x8_setTxPower(const float power) +{ + char buf[SA8X8_MSG_SIZE] = { 0 }; + + // TODO: Implement fine-grained power control through PA_BIAS SA8x8 register + uint8_t amp_enable = (power > 1.0f) ? 1 : 0; + int ret = gpio_pin_set_dt(&radio_pwr, amp_enable); + if(ret != 0) + printk("SA8x8: failed to enable high power mode"); +} + void sa8x8_writeAT1846Sreg(uint8_t reg, uint16_t value) { char buf[SA8X8_MSG_SIZE]; diff --git a/platform/drivers/baseband/SA8x8.h b/platform/drivers/baseband/SA8x8.h index 18e70b68..b36bd12a 100644 --- a/platform/drivers/baseband/SA8x8.h +++ b/platform/drivers/baseband/SA8x8.h @@ -55,6 +55,13 @@ const char *sa8x8_getFwVersion(); */ int sa8x8_enableHSMode(); +/** + * Set the transmission power. + * + * @param power: transmission power in Watt. + */ +void sa8x8_setTxPower(const float power); + /** * Write a register of the AT1846S radio IC contained in the SA8x8 module. * diff --git a/platform/drivers/baseband/radio_ttwrplus.cpp b/platform/drivers/baseband/radio_ttwrplus.cpp index 06f6d196..1eb1e977 100644 --- a/platform/drivers/baseband/radio_ttwrplus.cpp +++ b/platform/drivers/baseband/radio_ttwrplus.cpp @@ -19,6 +19,7 @@ ***************************************************************************/ #include +#include #include #include "radioUtils.h" #include "AT1846S.h" @@ -129,6 +130,10 @@ void radio_enableTx() { if(config->txDisable == 1) return; + // Constrain output power between 1W and 5W. + float power = std::max(std::min(config->txPower, 5.0f), 1.0f); + sa8x8_setTxPower(power); + at1846s.setFrequency(config->txFrequency); at1846s.setFuncMode(AT1846S_FuncMode::TX); diff --git a/platform/targets/ttwrplus/pmu.cpp b/platform/targets/ttwrplus/pmu.cpp index b5e59414..f2f2b8b0 100644 --- a/platform/targets/ttwrplus/pmu.cpp +++ b/platform/targets/ttwrplus/pmu.cpp @@ -99,6 +99,8 @@ void pmu_init() // Set VSY off voltage as 2600mV , Adjustment range 2600mV ~ 3300mV PMU.setSysPowerDownVoltage(2600); + // High transmit power may cause voltage dropoff, disable PMU protection + PMU.disableDC3LowVoltageTurnOff(); //! DC1 ESP32S3 Core VDD , Don't change // PMU.setDC1Voltage(3300);