summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Friesel <derf@finalrewind.org>2016-02-22 19:15:16 +0100
committerDaniel Friesel <derf@finalrewind.org>2016-02-22 19:15:16 +0100
commitcb1c87e6a371d405b7064b66002127c9d500c7d4 (patch)
tree9bf29dce0a6d00219f9d8dd3c4200a0913b28207
parent3a02241ad1fbd89a6603fb699989cb9f3c9b200d (diff)
Working loadPattern() code is working \o/
-rw-r--r--src/storage.cc104
-rw-r--r--src/storage.h9
-rw-r--r--src/system.cc12
3 files changed, 82 insertions, 43 deletions
diff --git a/src/storage.cc b/src/storage.cc
index a517f53..21eed31 100644
--- a/src/storage.cc
+++ b/src/storage.cc
@@ -1,3 +1,4 @@
+#include <util/delay.h>
#include <avr/io.h>
#include <stdlib.h>
@@ -8,12 +9,12 @@ Storage storage;
/*
* EEPROM data structure ("file system"):
*
- * Organized as 64B-pages, all animations/texts are page-aligned. Byte 0 ..
+ * Organized as 32B-pages, all animations/texts are page-aligned. Byte 0 ..
* 255 : storage metadata. Byte 0 contains the number of animations, byte 1 the
* page offset of the first animation, byte 2 of the second, and so on.
* Byte 256+: texts/animations without additional storage metadata, aligned
- * to 64B. So, a maximum of 256-(256/64) = 252 texts/animations can be stored,
- * and a maximum of 255 * 64 = 16320 Bytes (almost 16 kB / 128 kbit) can be
+ * to 32B. So, a maximum of 256-(256/32) = 248 texts/animations can be stored,
+ * and a maximum of 255 * 32 = 8160 Bytes (almost 8 kB / 64 kbit) can be
* addressed. To support larger EEPROMS, change the metadate area to Byte 2 ..
* 511 and use 16bit page pointers.
*
@@ -21,16 +22,16 @@ Storage storage;
*
* Example:
* Byte 0 = 3 -> we've got a total of three animations
- * Byte 1 = 4 -> first text/animation starts at byte 64*4 = 256
- * Byte 2 = 8 -> second starts at byte 64*8 = 512
- * Byte 3 = 9 -> third starts at 64*9 * 576
+ * Byte 1 = 0 -> first text/animation starts at byte 256 + 32*0 = 256
+ * Byte 2 = 4 -> second starts at byte 256 + 32*4 = 384
+ * Byte 3 = 5 -> third starts at 256 + 32*5 * 416
* Byte 4 = whatever
* .
* .
* .
* Byte 256ff = first text/animation. Has a header encoding its length in bytes.
- * Byte 512ff = second
- * Byte 576ff = third
+ * Byte 384ff = second
+ * Byte 416ff = third
* .
* .
* .
@@ -47,7 +48,7 @@ void Storage::enable()
TWSR = 0; // the lower two bits control TWPS
TWBR = ((F_CPU / 100000UL) - 16) / 2;
- i2c_read(0, 1, &num_anims);
+ i2c_read(0, 0, 1, &num_anims);
}
@@ -117,7 +118,7 @@ uint8_t Storage::i2c_send(uint8_t len, uint8_t *data)
return pos;
}
- return pos + 1;
+ return pos;
}
/*
@@ -140,7 +141,7 @@ uint8_t Storage::i2c_receive(uint8_t len, uint8_t *data)
data[pos] = TWDR;
}
- return pos + 1;
+ return pos;
}
/*
@@ -148,19 +149,33 @@ uint8_t Storage::i2c_receive(uint8_t len, uint8_t *data)
* Does not check for page boundaries yet.
* Includes a complete I2C transaction.
*/
-uint8_t Storage::i2c_write(uint16_t pos, uint8_t len, uint8_t *data)
+uint8_t Storage::i2c_write(uint8_t addrhi, uint8_t addrlo, uint8_t len, uint8_t *data)
{
uint8_t addr_buf[2];
+ uint8_t num_tries;
- addr_buf[0] = pos >> 8;
- addr_buf[1] = pos & 0xff;
+ addr_buf[0] = addrhi;
+ addr_buf[1] = addrlo;
- i2c_start_write();
- i2c_send(2, addr_buf);
- i2c_send(len, data);
- i2c_stop();
+ for (num_tries = 0; num_tries < 16; num_tries++) {
+ if (num_tries > 0)
+ _delay_ms(1);
+
+ if (i2c_start_write() != I2C_OK)
+ continue;
+
+ if (i2c_send(2, addr_buf) != 2)
+ continue;
+
+ if (i2c_send(len, data) != len)
+ continue;
- return 0; // TODO proper return code to indicate write errors
+ i2c_stop();
+ return I2C_OK;
+ }
+
+ i2c_stop();
+ return I2C_ERR;
}
/*
@@ -168,26 +183,43 @@ uint8_t Storage::i2c_write(uint16_t pos, uint8_t len, uint8_t *data)
* Does not check for page boundaries yet.
* Includes a complete I2C transaction.
*/
-uint8_t Storage::i2c_read(uint16_t pos, uint8_t len, uint8_t *data)
+uint8_t Storage::i2c_read(uint8_t addrhi, uint8_t addrlo, uint8_t len, uint8_t *data)
{
uint8_t addr_buf[2];
- addr_buf[0] = pos >> 8;
- addr_buf[1] = pos & 0xff;
+ uint8_t num_tries;
- i2c_start_write();
- i2c_send(2, addr_buf);
- i2c_start_read();
- i2c_receive(len, data);
- i2c_stop();
+ addr_buf[0] = addrhi;
+ addr_buf[1] = addrlo;
- return 0; // TODO proper return code to indicate read/write errors
+ for (num_tries = 0; num_tries < 16; num_tries++) {
+ if (num_tries > 0)
+ _delay_ms(1);
+
+ if (i2c_start_write() != I2C_OK)
+ continue;
+
+ if (i2c_send(2, addr_buf) != 2)
+ continue;
+
+ if (i2c_start_read() != I2C_OK)
+ continue;
+
+ if (i2c_receive(len, data) != len)
+ continue;
+
+ i2c_stop();
+ return I2C_OK;
+ }
+
+ i2c_stop();
+ return I2C_ERR;
}
void Storage::reset()
{
first_free_page = 0;
num_anims = 0xff;
- i2c_write(0, 1, &num_anims); // pretend the EEPROM was never written to
+ i2c_write(0, 0, 1, &num_anims); // pretend the EEPROM was never written to
num_anims = 0;
}
@@ -199,21 +231,21 @@ bool Storage::hasData()
return true;
}
-void Storage::load(uint16_t idx, uint8_t *data)
+void Storage::load(uint8_t idx, uint8_t *data)
{
uint8_t page_offset;
uint8_t header[2];
- i2c_read(1 + idx, 1, &page_offset);
+ i2c_read(0, 1 + idx, 1, &page_offset);
- i2c_read(256 + (64 * (uint16_t)page_offset), 2, header);
- i2c_read(256 + (64 * (uint16_t)page_offset), header[1] + 2, data);
+ i2c_read(1 + (page_offset / 8), (page_offset % 8) * 32, 2, header);
+ i2c_read(1 + (page_offset / 8), (page_offset % 8) * 32, header[1] + 2, data);
}
void Storage::save(uint8_t *data)
{
num_anims++;
- i2c_write(0, 1, &num_anims);
- i2c_write(num_anims, 1, &first_free_page);
+ i2c_write(0, 0, 1, &num_anims);
+ i2c_write(0, num_anims, 1, &first_free_page);
append(data);
}
@@ -222,6 +254,6 @@ void Storage::append(uint8_t *data)
// the header indicates the length of the data, but we really don't care
// - it's easier to just write the whole page and skip the trailing
// garbage when reading.
- i2c_write(256 + (64 * (uint16_t)first_free_page), 64, data);
+ i2c_write(1 + (first_free_page / 8), (first_free_page % 8) * 32, 32, data);
first_free_page++;
}
diff --git a/src/storage.h b/src/storage.h
index 5366ed9..d0a4a67 100644
--- a/src/storage.h
+++ b/src/storage.h
@@ -11,13 +11,14 @@ class Storage {
void i2c_stop(void);
uint8_t i2c_send(uint8_t len, uint8_t *data);
uint8_t i2c_receive(uint8_t len, uint8_t *data);
- uint8_t i2c_read(uint16_t addr, uint8_t len, uint8_t *data);
- uint8_t i2c_write(uint16_t addr, uint8_t len, uint8_t *data);
+ uint8_t i2c_read(uint8_t addrhi, uint8_t addrlo, uint8_t len, uint8_t *data);
+ uint8_t i2c_write(uint8_t addrhi, uint8_t addrlo, uint8_t len, uint8_t *data);
enum I2CStatus : uint8_t {
I2C_OK,
I2C_START_ERR,
- I2C_ADDR_ERR
+ I2C_ADDR_ERR,
+ I2C_ERR
};
public:
@@ -53,7 +54,7 @@ class Storage {
* @param data pointer to data structure for the pattern. Must be
* at least 256 Bytes
*/
- void load(uint16_t idx, uint8_t *data);
+ void load(uint8_t idx, uint8_t *data);
/**
* Save (possibly partial) pattern on the EEPROM. 64 bytes of
diff --git a/src/system.cc b/src/system.cc
index dd09b5a..1cbeec1 100644
--- a/src/system.cc
+++ b/src/system.cc
@@ -16,7 +16,7 @@ System rocket;
animation_t active_anim;
uint8_t disp_buf[260]; // 4 byte header + 256 byte data
-uint8_t *rx_buf = disp_buf + 64;
+uint8_t *rx_buf = disp_buf + sizeof(disp_buf) - 64;
void System::initialize()
{
@@ -33,11 +33,15 @@ void System::initialize()
modem.enable();
storage.enable();
+ storage.reset();
+ storage.save((uint8_t *)"\x10\x0a\x11\x00nootnoot");
+ storage.save((uint8_t *)"\x10\x0a\x20\x00nootnoot");
+
sei();
if (storage.hasData()) {
current_anim_no = 0;
- loadPattern(0);
+ loadPattern(1);
} else {
active_anim.type = AnimationType::TEXT;
active_anim.speed = (2 << 4) + 15;
@@ -82,7 +86,7 @@ void System::loadPattern(uint8_t anim_no)
storage.load(anim_no, disp_buf);
active_anim.type = (AnimationType)(disp_buf[0] >> 4);
- active_anim.length = disp_buf[1];
+ active_anim.length = disp_buf[1] - 2;
if (active_anim.type == AnimationType::TEXT) {
active_anim.speed = (disp_buf[2] & 0xf0) + 15;
@@ -116,6 +120,8 @@ void System::receive(void)
rx_buf[rx_pos] = modem.buffer_get();
}
+ // TODO adjust for 32 Byte rx buffer size
+
switch(rxExpect) {
case START1:
if (rx_byte == 0x99)