diff --git a/Arduino/ReceiveCart/ReceiveCart.ino b/Arduino/ReceiveCart/ReceiveCart.ino new file mode 100644 index 0000000..b1a41d8 --- /dev/null +++ b/Arduino/ReceiveCart/ReceiveCart.ino @@ -0,0 +1,117 @@ +#include +#include + +static const int eeprom_addr = 0b1010000; + +// Send a two bytes address via I²C which selects an address within the EEPROM. +void write_addr(uint16_t addr) { + Wire.write((uint8_t)(addr >> 8)); + Wire.write((uint8_t)addr); +} + +void write_page(uint8_t page[128], uint16_t page_addr) { + uint8_t bytes_written = 0; + for (int i = 0; i < 5; i++) { + int ret; + int write_bytes = min(128 - bytes_written, 30); + do { + Wire.beginTransmission(eeprom_addr); + write_addr(page_addr + bytes_written); + Wire.write(page + bytes_written, write_bytes); + ret = Wire.endTransmission(); + delay(5); + } while (ret != 0); + bytes_written += write_bytes; + } +} + +bool check_sumcomplement(uint8_t data[128], uint16_t checksum) { + uint16_t sum = 0; + for (int i = 0; i<128; i += 2) { + sum += (data[i+1] << 8) | data[i]; + } + sum += checksum; + return !sum; +} + +volatile uint8_t pageData[128] = {}; +volatile uint16_t pageChecksum = 0; +volatile uint16_t pageAddr = 0; +volatile bool pageOk = false; +volatile bool reicivingCart = false; +volatile uint32_t last_page_update = 0; + +void setup() { + Serial.begin(115200); + pinMode(LED_BUILTIN, OUTPUT); + Wire.begin(); +} + +void loop() { + if (reicivingCart && millis() - last_page_update > 1000) { + Serial.print("TO"); + reicivingCart = false; + pageOk = false; + pageAddr = 0; + digitalWrite(LED_BUILTIN, HIGH); + delay(500); + digitalWrite(LED_BUILTIN, LOW); + delay(500); + digitalWrite(LED_BUILTIN, HIGH); + delay(500); + digitalWrite(LED_BUILTIN, LOW); + } + + if (pageOk) { + pageOk = false; + bool pageValid = check_sumcomplement((uint8_t *)pageData, pageChecksum); + Serial.print(pageValid ? "ACK" : "NAK"); + if (pageValid) { + write_page(pageData, pageAddr); + pageAddr += 128; + } + + /* for (int i = 0; i<128; i++) { + if (i%16 == 0) + Serial.println(); + Serial.print(pageData[i], HEX); + Serial.print(" "); + } + Serial.println(); + Serial.println(pageChecksum, HEX);*/ + + Serial.print("OK"); + } +} + +void serialEvent() { + static size_t read = 0; + digitalWrite(LED_BUILTIN, HIGH); + if (Serial.available() == 5) { + char control[4] = {}; + Serial.readBytesUntil('\n', control, 4); + Serial.read(); /* Drop the '\n' */ + if (!strncmp(control, "CART", 4)) { + reicivingCart = true; + Serial.print("OK"); + } else if (!strncmp(control, "DONE", 4)) { + reicivingCart = false; + } else { + Serial.print("KO"); + } + pageOk = false; + pageAddr = 0; + read = 0; + } + + while (reicivingCart && Serial.available() && read < 128) { + read += Serial.readBytes((char *)pageData+read, min(128-read, 64)); + } + if (reicivingCart && read >= 128) { + pageOk = true; + Serial.readBytes((char*)&pageChecksum, 2); + read = 0; + } + digitalWrite(LED_BUILTIN, LOW); + last_page_update = millis(); +} diff --git a/Arduino/SendCart/SendCart.ino b/Arduino/SendCart/SendCart.ino new file mode 100644 index 0000000..54de478 --- /dev/null +++ b/Arduino/SendCart/SendCart.ino @@ -0,0 +1,98 @@ +#include +#include + +// Arduino constants +static constexpr uint8_t i2c_buff_size = 32; +static constexpr uint8_t serial_buff_size = 64; + +// EEPROM constants +static constexpr int page_count = 512; +static constexpr int page_size = 128; +static constexpr int i2c_buff_per_page = page_size / i2c_buff_size; +static constexpr uint8_t eeprom_addr = 0b1010000; + +uint8_t pageData[page_size] = {}; +uint16_t pageAddr = 0; + +// Send a two bytes address via I²C which selects an address within the EEPROM. +void write_addr(uint16_t addr) { + Wire.write((uint8_t)(addr >> 8)); + Wire.write((uint8_t)addr); +} + +// When the receiver sums on its side, it can just add this sum and check that is 0. +uint16_t sum_complement(const uint8_t data[page_size]) { + uint16_t sum = 0; + for (int i = 0; i