1
0
Fork 0

Arduino: Add full Arduino code

This is the full working Arduino code, for writing and loading.

This shouldn not be used by students.
This commit is contained in:
Teo-CD 2023-11-12 20:58:05 +00:00
parent f34d81ad87
commit edb3d35464
2 changed files with 189 additions and 0 deletions

View file

@ -0,0 +1,118 @@
#include <Wire.h>
#include <inttypes.h>
static const int eeprom_addr = 0b1010000;
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() {
// put your setup code here, to run once:
Serial.begin(115200);
pinMode(LED_BUILTIN, OUTPUT);
Wire.begin();
//Serial.println("Arduino started");
}
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();
}

View file

@ -0,0 +1,71 @@
#include <Wire.h>
#include <inttypes.h>
static const int eeprom_addr = 0b1010000;
uint8_t pageData[128] = {};
uint16_t pageAddr = 0;
void write_addr(uint16_t addr) {
Wire.write((uint8_t)(addr >> 8));
Wire.write((uint8_t)addr);
}
uint16_t sum_complement(const uint8_t data[128]) {
uint16_t sum = 0;
for (int i = 0; i<128; i += 2) {
sum += (data[i+1] << 8) | data[i];
}
return -sum;
}
void setup() {
Serial.begin(115200);
pinMode(LED_BUILTIN, OUTPUT);
Wire.begin();
}
void loop() {
char ret[4] = "";
// put your main code here, to run repeatedly:
do {
if (!Serial.readBytesUntil('\n', ret, 2))
Serial.read();
} while (strncmp(ret, "GO", 2) != 0);
// Reset the EEPROM internal address to 0. It autoincrements after.
Wire.beginTransmission(eeprom_addr);
write_addr(0);
Wire.endTransmission(false);
digitalWrite(LED_BUILTIN, HIGH);
/*
* We don't know the size of the cartridge, and it could be the whole EEPROM.
* Read and send all the pages (64kiB), it should not impact the final PNG.
*/
for (int i = 0; i < 512; i++) {
memset(pageData, 0, 128);
// Arduino I2C buffer is 32 bytes, so we need multiple requests per page.
for (int j = 0; j < 4; j++) {
Wire.requestFrom(eeprom_addr, 32);
for (int k = 0; k < 32; k++) {
pageData[32*j + k] = Wire.read();
}
}
// Try to send the full page until the recipient ACKs
uint16_t page_checksum = sum_complement(pageData);
do {
memset(ret, 0, 4);
size_t written = 0;
while (written < 128) {
written += Serial.write(pageData + written, min(128 - written, 64));
}
Serial.write((uint8_t*)&page_checksum, 2);
while(!Serial.readBytesUntil('\n', ret, 3));
Serial.read();
} while(strncmp(ret, "ACK", 3) != 0);
}
digitalWrite(LED_BUILTIN, LOW);
}