From 6c48ebb65ff795463d18fe73fbe0298769e252a7 Mon Sep 17 00:00:00 2001 From: Erick Ahmed Date: Sat, 4 Oct 2025 15:12:25 +0200 Subject: [PATCH] Add data receiving capabilities using a buffer with overflow protection --- firmware/atmega/include/twi.h | 7 +++++ firmware/atmega/source/main.c | 18 +++++++---- firmware/atmega/source/twi.c | 58 +++++++++++++++++++++++++++++++++++ 3 files changed, 77 insertions(+), 6 deletions(-) create mode 100644 firmware/atmega/include/twi.h create mode 100644 firmware/atmega/source/twi.c diff --git a/firmware/atmega/include/twi.h b/firmware/atmega/include/twi.h new file mode 100644 index 0000000..b3222e4 --- /dev/null +++ b/firmware/atmega/include/twi.h @@ -0,0 +1,7 @@ +#ifndef TWI_H +#define TWI_H + +void twiInit(void); +void twiAlert(void); + +#endif diff --git a/firmware/atmega/source/main.c b/firmware/atmega/source/main.c index 4bdb821..621978b 100644 --- a/firmware/atmega/source/main.c +++ b/firmware/atmega/source/main.c @@ -3,15 +3,21 @@ #include #include #include +#include "config.h" #include "adc.h" #include "moisture.h" #include "pump.h" +#include "twi.h" ISR(WDT_vect) { triggerMoistureRead(); } -void watchdogs(void) { +ISR(TWI_vect) { + twiAlert(); +} + +static void watchdogs(void) { cli(); MCUSR &= ~(1 << WDRF); WDTCSR |= (1 << WDCE) | (1 << WDE); @@ -19,15 +25,16 @@ void watchdogs(void) { sei(); } -void enterSleep(void) { +static inline void enterSleep(void) { set_sleep_mode(SLEEP_MODE_PWR_DOWN); sleep_enable(); sleep_cpu(); sleep_disable(); } -void setup(void) { +static void setup(void) { adcInit(); + twiInit(); sensorsInit(); pumpsInit(); watchdogs(); @@ -39,10 +46,9 @@ int main(void) { while(true) { if (readSensors) { uint16_t result = moistureRead(); - //espSend(VASE_NUM, result) + // nested if: (result outside range (see config.h)) {waterPlant()} + } - // if(espGet("ask if i need to water plants") == true) {waterPlant()} - // or maybe it's better to do this with interrupts? readSensors = false; enterSleep(); diff --git a/firmware/atmega/source/twi.c b/firmware/atmega/source/twi.c new file mode 100644 index 0000000..7494d20 --- /dev/null +++ b/firmware/atmega/source/twi.c @@ -0,0 +1,58 @@ +#include +#include +#include "config.h" + +#define BUFFER_SIZE 8 + +static inline void twiReset(void) { + // Enable TWI; enable ACK; clear interrupt flag; enable twi external interrupt + TWCR = (1 << TWEN) | (1 << TWEA) | (1 << TWINT) | (1 << TWIE); +} + +void twiInit(void) { + TWAR = TWI_ADDR; //address definition found in config.h + twiReset(); +} + +static inline void twiSendAck(void) { + TWCR = (1 << TWEA) | (1 << TWINT); +} + +static inline void twiSendNack(void) { + TWCR = (TWCR & ~(1 << TWEA)) | (1 << TWINT); +} + +static void twiRespond(int8_t response[]) { + // Respond to TWI requests +} + + +static void twiExecute(int8_t buffer[]) { + // Perform actions based on received message + // if needed: + // twiRespond(); +} + +void twiAlert(void) { + static int8_t twiBuffer[BUFFER_SIZE] = {0}; + static uint8_t bufferIndex = 0; + + switch (TWSR & 0xF8) { + case 0x60: // SLA+W received + twiSendAck(); + break; + case 0x80: // data received + if(bufferIndex < BUFFER_SIZE) { + twiBuffer[bufferIndex++] = TWDR; + twiSendAck(); + } else twiSendNack(); + break; + case 0xA0: // stop condition + twiExecute(twiBuffer); + twiReset(); + break; + default: + twiSendNack(); + break; + } +}