diff --git a/variants/m5stack_unit_c6l/UnitC6LBoard.h b/variants/m5stack_unit_c6l/UnitC6LBoard.h index a4ea3ee6e5..c710634fea 100644 --- a/variants/m5stack_unit_c6l/UnitC6LBoard.h +++ b/variants/m5stack_unit_c6l/UnitC6LBoard.h @@ -1,12 +1,96 @@ #pragma once #include +#include #include +#define PI4IO_ADDR 0x43 + +// PI4IO registers +#define PI4IO_REG_CHIP_RESET 0x01 +#define PI4IO_REG_IO_DIR 0x03 +#define PI4IO_REG_OUT_SET 0x05 +#define PI4IO_REG_OUT_H_IM 0x07 +#define PI4IO_REG_IN_DEF_STA 0x09 +#define PI4IO_REG_PULL_EN 0x0B +#define PI4IO_REG_PULL_SEL 0x0D +#define PI4IO_REG_IRQ_STA 0x13 +#define PI4IO_REG_INT_MASK 0x11 + class UnitC6LBoard : public ESP32Board { +private: + bool i2c_write_byte(uint8_t addr, uint8_t reg, uint8_t value) { + Wire.beginTransmission(addr); + Wire.write(reg); + Wire.write(value); + return Wire.endTransmission() == 0; + } + + bool i2c_read_byte(uint8_t addr, uint8_t reg, uint8_t *value) { + Wire.beginTransmission(addr); + Wire.write(reg); + if (Wire.endTransmission() != 0) return false; + if (Wire.requestFrom(addr, (uint8_t)1) != 1) return false; + if (!Wire.available()) return false; + *value = Wire.read(); + return true; + } + + // P0=button, P1=unused input, P5=LNA_EN, P6=ANT_SW, P7=NRST(LoRa reset) + void resetLoRaViaPI4IO() { + uint8_t in_data; + + // Reset the I/O expander to a known state + i2c_write_byte(PI4IO_ADDR, PI4IO_REG_CHIP_RESET, 0xFF); + delay(10); + i2c_read_byte(PI4IO_ADDR, PI4IO_REG_CHIP_RESET, &in_data); + delay(10); + + // Set P5, P6, P7 as outputs (0: input, 1: output) + i2c_write_byte(PI4IO_ADDR, PI4IO_REG_IO_DIR, 0b11100000); + delay(10); + + // Disable output high-impedance (i.e. enable the output driver) for + // every pin actually wired on this board: P0, P1, P5, P6, P7. + // Without this, IO_DIR + OUT_SET have no effect on the physical pin — + // it stays in the power-on Hi-Z state, so NRST never actually toggles. + i2c_write_byte(PI4IO_ADDR, PI4IO_REG_OUT_H_IM, 0b00011100); + delay(10); + + // Pull up/down select (0: down, 1: up) + i2c_write_byte(PI4IO_ADDR, PI4IO_REG_PULL_SEL, 0b11100011); + delay(10); + + // Pull up/down enable (0: disable, 1: enable) + i2c_write_byte(PI4IO_ADDR, PI4IO_REG_PULL_EN, 0b11100011); + delay(10); + + // Default input state for P0, P1 (buttons) + i2c_write_byte(PI4IO_ADDR, PI4IO_REG_IN_DEF_STA, 0b00000011); + delay(10); + + // Enable interrupts for P0, P1 (0: enable, 1: disable) + i2c_write_byte(PI4IO_ADDR, PI4IO_REG_INT_MASK, 0b11111100); + delay(10); + + // Set P7 (NRST) high, P5/P6 will be set after + i2c_write_byte(PI4IO_ADDR, PI4IO_REG_OUT_SET, 0b10000000); + delay(10); + + // Clear IRQ status + i2c_read_byte(PI4IO_ADDR, PI4IO_REG_IRQ_STA, &in_data); + + // Enable RF switch (P6 high) and LNA (P5 high) + i2c_read_byte(PI4IO_ADDR, PI4IO_REG_OUT_SET, &in_data); + in_data |= (1 << 6); // P6 = RF Switch = HIGH + in_data |= (1 << 5); // P5 = LNA Enable = HIGH + i2c_write_byte(PI4IO_ADDR, PI4IO_REG_OUT_SET, in_data); + } + public: void begin() { - ESP32Board::begin(); + ESP32Board::begin(); // already calls Wire.begin(PIN_BOARD_SDA, PIN_BOARD_SCL) + resetLoRaViaPI4IO(); } const char* getManufacturerName() const override { diff --git a/variants/m5stack_unit_c6l/platformio.ini b/variants/m5stack_unit_c6l/platformio.ini index 190add0436..ba2ff6b84b 100644 --- a/variants/m5stack_unit_c6l/platformio.ini +++ b/variants/m5stack_unit_c6l/platformio.ini @@ -6,7 +6,7 @@ build_flags = ${esp32c6_base.build_flags} ${sensor_base.build_flags} -I variants/m5stack_unit_c6l - -D P_LORA_TX_LED=15 +; -D P_LORA_TX_LED=15 -D P_LORA_SCLK=20 -D P_LORA_MISO=22 -D P_LORA_MOSI=21 @@ -15,11 +15,11 @@ build_flags = -D P_LORA_BUSY=19 -D P_LORA_RESET=-1 -D PIN_BUZZER=11 - -D PIN_BOARD_SDA=16 - -D PIN_BOARD_SCL=17 + -D PIN_BOARD_SDA=10 + -D PIN_BOARD_SCL=8 -D SX126X_RXEN=5 -D SX126X_DIO2_AS_RF_SWITCH=true - -D SX126X_DIO3_TCXO_VOLTAGE=1.8 + -D SX126X_DIO3_TCXO_VOLTAGE=3.0 -D SX126X_CURRENT_LIMIT=140 -D SX126X_RX_BOOSTED_GAIN=1 -D USE_SX1262