#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(); Wire.setClock(400000); } 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(); }