diff --git a/src/addon_io.c b/src/addon_io.c new file mode 100644 index 0000000..39befcc --- /dev/null +++ b/src/addon_io.c @@ -0,0 +1,35 @@ +#include + +#include "pinout.h" + +#include "addon_io.h" + +static const uint32_t OUTPUT_LIST[2] = {ADDON_ISO_IO_OUT1, ADDON_ISO_IO_OUT2}; + +void addon_io_init(void) +{ + // Isolated outputs configuration: output, initially low = off + gpio_clear(ADDON_ISO_IO_PORT, ADDON_ISO_IO_OUT1 | ADDON_ISO_IO_OUT2); + gpio_mode_setup(ADDON_ISO_IO_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, ADDON_ISO_IO_OUT1 | ADDON_ISO_IO_OUT2); + + // Isolated inputs configuration: input, no pull resistors + gpio_mode_setup(ADDON_ISO_IO_PORT, GPIO_MODE_INPUT, GPIO_PUPD_NONE, ADDON_ISO_IO_IN); +} + + +void addon_io_iso_out_on(uint8_t idx) +{ + gpio_set(ADDON_ISO_IO_PORT, OUTPUT_LIST[idx]); +} + + +void addon_io_iso_out_off(uint8_t idx) +{ + gpio_clear(ADDON_ISO_IO_PORT, OUTPUT_LIST[idx]); +} + + +bool addon_io_read_iso_in(void) +{ + return gpio_get(ADDON_ISO_IO_PORT, ADDON_ISO_IO_IN) != 0; +} diff --git a/src/addon_io.h b/src/addon_io.h new file mode 100644 index 0000000..511fcc5 --- /dev/null +++ b/src/addon_io.h @@ -0,0 +1,14 @@ +#ifndef ADDON_IO_H +#define ADDON_IO_H + +#include +#include + +void addon_io_init(void); + +void addon_io_iso_out_on(uint8_t idx); +void addon_io_iso_out_off(uint8_t idx); + +bool addon_io_read_iso_in(void); + +#endif // ADDON_IO_H diff --git a/src/charge_control.c b/src/charge_control.c index e1898e8..117bfd5 100644 --- a/src/charge_control.c +++ b/src/charge_control.c @@ -8,6 +8,7 @@ #include "charge_pump.h" #include "rs485.h" #include "flash_config.h" +#include "addon_io.h" #include "charge_control.h" @@ -243,12 +244,18 @@ static void solar_fsm_update(uint64_t uptime_ms, struct MeasurementResult *meas) case CHARGE_LOW_EXTERNAL_TEMPERATURE: if(charge_state_entered) { power_switch_solar_off(); + + // switch on the heater via the isolated I/O addon board + addon_io_iso_out_on(0); } // this state can only be entered if the BMP280 measurement is valid, so // no need to check it again here. if(bmp280_get_temperature() > external_temperature_recovery) { charge_state = CHARGE_WAIT_CHARGEPUMP; + + // switch the heater off again when this state is left + addon_io_iso_out_off(0); break; } break; diff --git a/src/pinout.h b/src/pinout.h index 84a24eb..d1893e7 100644 --- a/src/pinout.h +++ b/src/pinout.h @@ -43,6 +43,8 @@ #define RS485_TX_PIN GPIO6 #define RS485_RX_PIN GPIO7 +/*** Expansion connector signals ***/ + /* BMP280 I²C */ #define BMP280_I2C_PORT GPIOA @@ -50,4 +52,12 @@ #define BMP280_I2C_SCL GPIO9 #define BMP280_I2C_SDA GPIO10 +/* Isolated inputs and outputs on I/O addon board */ + +#define ADDON_ISO_IO_PORT GPIOA + +#define ADDON_ISO_IO_OUT1 GPIO5 +#define ADDON_ISO_IO_OUT2 GPIO6 +#define ADDON_ISO_IO_IN GPIO7 + #endif // PINOUT_H