summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrett Weiland <brett_weiland@bpcsapce.com>2022-09-27 16:14:28 -0500
committerBrett Weiland <brett_weiland@bpcsapce.com>2022-09-27 16:14:28 -0500
commit94304b11e7220f060dbc345de5fa1952d0465016 (patch)
treef16e84c54b27f67e089ded1175fbf8b561896b42
parent7b006d6f2032ac46074d693ae59a971bee327ace (diff)
working on serial syncronization for programming eeprom
-rw-r--r--docs/atmega328p.pdfbin0 -> 8585103 bytes
-rw-r--r--docs/mega2560_schematic.pdfbin0 -> 48189 bytes
-rw-r--r--docs/nano.pdfbin0 -> 874520 bytes
-rw-r--r--src/br24t_eeprom_driver.c31
-rw-r--r--src/br24t_eeprom_driver.h5
-rw-r--r--src/compile_commands.json26
-rwxr-xr-xsrc/compile_eeprom.py22
-rw-r--r--src/debug.c72
-rw-r--r--src/debug.h9
-rw-r--r--src/eeprom_address.h94
-rw-r--r--src/eeprom_dump0
-rw-r--r--src/i2c.c30
-rw-r--r--src/i2c.h1
-rw-r--r--src/main.c25
-rw-r--r--src/makefile28
-rw-r--r--src/pcf_clock_driver.c9
-rw-r--r--src/pcf_clock_driver.h3
-rw-r--r--src/pins.h25
-rw-r--r--src/ssd1306_display_driver.c41
-rw-r--r--src/uart.c18
-rw-r--r--src/uart.h5
-rwxr-xr-xsrc/write_eeprom.py64
22 files changed, 336 insertions, 172 deletions
diff --git a/docs/atmega328p.pdf b/docs/atmega328p.pdf
new file mode 100644
index 0000000..4a9dad4
--- /dev/null
+++ b/docs/atmega328p.pdf
Binary files differ
diff --git a/docs/mega2560_schematic.pdf b/docs/mega2560_schematic.pdf
new file mode 100644
index 0000000..bdd9be1
--- /dev/null
+++ b/docs/mega2560_schematic.pdf
Binary files differ
diff --git a/docs/nano.pdf b/docs/nano.pdf
new file mode 100644
index 0000000..cddb795
--- /dev/null
+++ b/docs/nano.pdf
Binary files differ
diff --git a/src/br24t_eeprom_driver.c b/src/br24t_eeprom_driver.c
index 53165d3..2fc0bd0 100644
--- a/src/br24t_eeprom_driver.c
+++ b/src/br24t_eeprom_driver.c
@@ -1,6 +1,12 @@
+#include <avr/io.h>
#include <stdio.h>
+#include <string.h>
+#include <util/delay.h>
#include "i2c.h"
#include "br24t_eeprom_driver.h"
+#include "uart.h"
+#include "pins.h"
+#include "debug.h"
#define EEPROM_ADDR 0x57
#define EEPROM_PAGE_SIZE 64
@@ -13,29 +19,24 @@
#define PAGE_WRITE_CORRUPTED 0x01
#define PAGE_WRITE_UNKNOWN_ERROR 0xff
-//we need another function cause it's got a 16 bit register address
#ifdef FLASH_EEPROM
void flash_eeprom() {
- uint16_t data_len;
- uint32_t syn = 0;
+ uint16_t page_len;
uint8_t on_byte;
uint8_t eeprom_buffer_out[EEPROM_PAGE_SIZE];
uint8_t eeprom_buffer_in[EEPROM_PAGE_SIZE];
- while(syn != MAGIC_SYN) fread(&syn, 4, 1, stdin); //not sure we _really_ need to do this?
+ fread(&page_len, 1, 1, stdin);
- //this feels ugly
- syn = MAGIC_ACK;
- fwrite(&syn, 4, 1, stdout);
-
- //get amount of data we'll be using
- data_len = uart_recvbyte();
- data_len |= (uart_recvbyte() >> 8);
-
- for(int page = 0; page < (data_len / EEPROM_PAGE_SIZE); data_len -= EEPROM_PAGE_SIZE) {
+ for(int page = 0; page < page_len; page -= page_len) {
fread(eeprom_buffer_out, EEPROM_PAGE_SIZE, 1, stdin);
+ //fread(eeprom_buffer_out, 11, 1, stdin);
+ fputc(PAGE_WRITE_CORRUPTED, stdout);
+
+ DEBUG_LED_ON();
+ for(;;);
i2c_start(EEPROM_I2C_ADDR, I2C_READ);
i2c_send((uint8_t)(page * EEPROM_PAGE_SIZE) & 0xff);
@@ -52,9 +53,9 @@ void flash_eeprom() {
eeprom_buffer_in[on_byte] = i2c_recv();
i2c_stop();
- if(memcmp(eeprom_buffer_in, eeprom_buffer_out, EEPROM_PAGE_SIZE)) {
+ if(!memcmp(eeprom_buffer_in, eeprom_buffer_out, EEPROM_PAGE_SIZE)) {
fputc(PAGE_WRITE_CORRUPTED, stdout);
- error();
+ for(;;); //TODO error here
}
fputc(PAGE_WRITE_OK, stdout);
}
diff --git a/src/br24t_eeprom_driver.h b/src/br24t_eeprom_driver.h
index a289f86..0e57786 100644
--- a/src/br24t_eeprom_driver.h
+++ b/src/br24t_eeprom_driver.h
@@ -4,7 +4,7 @@
#include <stdint.h>
#include "i2c.h"
-#define EEPROM_I2C_ADDR 0x50 //fix to represent custom address setting
+#define EEPROM_I2C_ADDR 0x50
#ifdef FLASH_EEPROM
@@ -13,7 +13,8 @@ void flash_eeprom();
typedef uint16_t EEPROM_ADDR;
-#define EEPROM_READBYTE(addr) i2c_read_reg_addr16(EEPROM_I2C_ADDR, addr);
+#define EEPROM_READBYTE(addr) i2c_read_reg_addr16(EEPROM_I2C_ADDR, addr)
+#define EEPROM_WRITEBYTE(addr, data) i2c_write_reg_addr16(EEPROM_I2C_ADDR, addr, data);
#endif
diff --git a/src/compile_commands.json b/src/compile_commands.json
index dcb24f5..7cb5d9c 100644
--- a/src/compile_commands.json
+++ b/src/compile_commands.json
@@ -110,5 +110,31 @@
"-Wall"
],
"file": "paint.c"
+ },
+ {
+ "directory": "/home/indigo/projects/watch/src",
+ "arguments": [
+ "/home/indigo/packs/avr8-gnu-toolchain-linux_x86_64/bin/avr-gcc",
+ "-mmcu=atmega328p",
+ "-I",
+ "/home/indigo/packs/avr8-gnu-toolchain-linux_x86_64/avr/include",
+ "-o",
+ "compiled_payload.elf",
+ "-DDEBUG_BUILD=1",
+ "-DBAUD=9600",
+ "-DF_CPU=16000000",
+ "-Wall",
+ "-O1",
+ "main.c",
+ "debug.c",
+ "i2c.c",
+ "ssd1306_display_driver.c",
+ "uart.c",
+ "br24t_eeprom_driver.c",
+ "paint.c",
+ "pcf_clock_driver.c",
+ "-Wall"
+ ],
+ "file": "pcf_clock_driver.c"
}
]
diff --git a/src/compile_eeprom.py b/src/compile_eeprom.py
index 52dbbfc..dee9341 100755
--- a/src/compile_eeprom.py
+++ b/src/compile_eeprom.py
@@ -26,8 +26,8 @@ page_cnt = 4
# also note we have no protection from using unsed chars, I can't let this project
# get to big for litteraly no reason
-header.write("/** GENERATED BY EEPROM COMPILER SCRIPT **/\n\n")
-header.write("// FONTS\n")
+header.write("/** GENERATED BY EEPROM COMPILER SCRIPT **/\r\n\r\n")
+header.write("// FONTS\r\n")
for file in os.listdir("{}/fonts/".format(data_path)):
path = "{}/fonts/{}".format(data_path, file)
@@ -36,22 +36,22 @@ for file in os.listdir("{}/fonts/".format(data_path)):
font_bdf = BdfFontFile.BdfFontFile(font_fd)
font_name = file.split('.')[0].capitalize()
- header.write("#define FONT_{}_ADDR\t0x{:04x}\n".format(font_name, output.tell()))
+ header.write("#define FONT_{}_ADDR\t0x{:04x}\r\n".format(font_name, output.tell()))
first_char = False
for char in enumerate(font_bdf.glyph):
if char[1]:
if not first_char:
first_char = True
- header.write(("#define FONT_{}_FIRST_CHAR\t{}\n"
- "#define FONT_{}_WIDTH\t{}\n"
- "#define FONT_{}_HEIGHT\t{}\n").format(
+ header.write(("#define FONT_{}_FIRST_CHAR\t{}\r\n"
+ "#define FONT_{}_WIDTH\t{}\r\n"
+ "#define FONT_{}_HEIGHT\t{}\r\n").format(
font_name, char[0],
font_name, char[1][-1].size[0],
font_name, char[1][-1].size[1]))
output.write(char[1][-1].tobytes('raw'))
-header.write("\n\n// IMAGES\n#define IMG_BEGIN\t0x{:04x}\n".format(output.tell()))
+header.write("\r\n\r\n// IMAGES\r\n#define IMG_BEGIN\t0x{:04x}\r\n".format(output.tell()))
image_cnt = 0
@@ -65,9 +65,9 @@ for file in os.listdir("{}/images/".format(data_path)):
image_bitmap_remapped = []
image = Image.open(image_fd)
if not image.mode == 'RGB':
- print("this script only compiles RGB formatted photos! (I'm lazy\n")
+ print("this script only compiles RGB formatted photos! (I'm lazy\r\n")
exit(1)
- header.write("#define IMG_{}_ADDR\t0x{:04x}\n".format(
+ header.write("#define IMG_{}_ADDR\t0x{:04x}\r\n".format(
file.split('.')[0].capitalize(),
output.tell()))
for byte in range(0, len(image.tobytes()), 3):
@@ -98,7 +98,7 @@ for file in os.listdir("{}/images/".format(data_path)):
((bit % 8) - (extract_bit % 8))
[output.write(byte.to_bytes(1, 'big')) for byte in image_bitmap_remapped]
-header.write("#define IMG_COUNT\t{}\n\n".format(image_cnt))
+header.write("#define IMG_COUNT\t{}\r\n\r\n".format(image_cnt))
@@ -107,7 +107,7 @@ print("EEPROM used: {}% ({} out of {} bits)".format(
output.tell(), eeprom_length))
if(output.tell() > eeprom_length):
- print("WARNING: You've used more eeprom then there is available!\n")
+ print("WARNING: You've used more eeprom then there is available!\r\n")
output.close()
header.close()
diff --git a/src/debug.c b/src/debug.c
index 858195e..d7babda 100644
--- a/src/debug.c
+++ b/src/debug.c
@@ -1,10 +1,71 @@
#include <avr/io.h>
#include <stdio.h>
#include <util/delay.h>
+#include "ssd1306_display_driver.h"
+#include "i2c.h"
#include "debug.h"
+#include "br24t_eeprom_driver.h"
+//this is used elsewhere (only one file) besides debug but kind of gross, maybe move to a header or something
+#define SSD1306_ADDR 0x3c
+#define SSD1306_CMD_REG 0x00
+#define SSD1306_DATA_REG 0x40
+#define SCREEN_PAGE_CNT SCREEN_RES_Y / 8
+#define I2C_WRITE 0
+#define I2C_READ 1
+
+void scroll_test() {
+ //sets scroll area to whole screen
+ i2c_write_reg_multi(SSD1306_ADDR, SSD1306_CMD_REG, 3, (uint8_t[]){0xa3, 0x00, 0x20});
+ //set up scroll options
+ i2c_write_reg_multi(SSD1306_ADDR, SSD1306_CMD_REG, 6, (uint8_t[]){0x29, 0x00, 0x00, 0x00, 0x04, 0x00});
+ //actually activate scroll
+ i2c_write_reg_multi(SSD1306_ADDR, SSD1306_CMD_REG, 6, (uint8_t[]){0x2f});
+}
+
+void screen_lowlvl_testdraw() {
+ unsigned int on_pix;
+ unsigned int on_page;
+
+ printf("running screen time tests\r\n");
+ printf("generating test image...\r\n");
+ for(on_pix = 0; on_pix < sizeof(screen_buffer); on_pix++)
+ screen_buffer[on_pix] = ((uint8_t)0xaa << (on_pix % 8));
+
+ printf("page mode, individual byte per i2c call...\r\n");
+ for(on_page = 0; on_page < SCREEN_PAGE_CNT; on_page++) {
+ i2c_write_reg(SSD1306_ADDR, SSD1306_CMD_REG, 0xb0 + on_page);
+ i2c_write_reg(SSD1306_ADDR, SSD1306_CMD_REG, 0x00);
+ i2c_write_reg(SSD1306_ADDR, SSD1306_CMD_REG, 0x10);
+ for(on_pix = 0; on_pix < SCREEN_RES_X; on_pix++)
+ i2c_write_reg(SSD1306_ADDR, SSD1306_DATA_REG, screen_buffer[(on_page * 8) + on_pix]);
+ }
+ printf("page mode, 1 page per i2c call...\r\n");
+ for(on_page = 0; on_page < SCREEN_PAGE_CNT; on_page++) {
+ i2c_write_reg(SSD1306_ADDR, SSD1306_CMD_REG, 0xb0 + on_page);
+ i2c_write_reg(SSD1306_ADDR, SSD1306_CMD_REG, 0x00);
+ i2c_write_reg(SSD1306_ADDR, SSD1306_CMD_REG, 0x10);
+ i2c_write_reg_multi(SSD1306_ADDR, SSD1306_DATA_REG, SCREEN_RES_X, &screen_buffer[on_page * SCREEN_RES_X]);
+ }
+ printf("screen test draw done!\n");
+}
+
+
+void uart_echo() {
+ char buff;
+ for(;;) {
+ fread(&buff, 1, 1, stdin);
+ fwrite(&buff, 1, 1, stdout);
+ }
+}
+
+void test_clock() {
+ printf("The time is %s, waiting 5 mintes...\r\n", "not implimented");
+ _delay_ms(300000);
+ printf("The time is now %s, hope your RTC clock works\r\n", "not implimented");
+}
/*
@@ -27,5 +88,14 @@ void test_timer() {
start = TCNT1;
_delay_ms(1000);
end = TCNT1;
- printf("1 second is %u ticks\n", end - start);
+ printf("1 second is %u ticks\r\n", end - start);
+}
+
+void eeprom_testbyte() {
+ uint8_t data_in = 0xde;
+ uint8_t data_out = 0;
+ printf("writing 0x%x to eeprom...\r\n", data_in);
+ EEPROM_WRITEBYTE(0x0000, data_in);
+ data_out = EEPROM_READBYTE(0x0000);
+ printf("byte read from eeprom: 0x%x\r\n", data_out);
}
diff --git a/src/debug.h b/src/debug.h
index 095e87f..fe8e968 100644
--- a/src/debug.h
+++ b/src/debug.h
@@ -4,11 +4,20 @@
#include <stdio.h>
#include <avr/io.h>
#include "uart.h"
+#include "pins.h"
void timer_init();
void test_timer();
+void scroll_test();
+void screen_lowlvl_testdraw();
+void uart_echo();
+void test_clock();
+void eeprom_testbyte();
unsigned int ticks_to_seconds();
+#define DEBUG_LED_ON() LED_DEBUG_PORT |= _BV(LED_DEBUG)
+#define DEBUG_LED_OFF() LED_DEBUG_PORT &= ~(_BV(LED_DEBUG))
+
#endif
diff --git a/src/eeprom_address.h b/src/eeprom_address.h
index 4f0aa87..8dda9cf 100644
--- a/src/eeprom_address.h
+++ b/src/eeprom_address.h
@@ -1,47 +1,47 @@
-/** GENERATED BY EEPROM COMPILER SCRIPT **/
-
-// FONTS
-#define FONT_5thelement_ADDR 0x0000
-#define FONT_5thelement_FIRST_CHAR 32
-#define FONT_5thelement_WIDTH 4
-#define FONT_5thelement_HEIGHT 5
-#define FONT_4thd_ADDR 0x01db
-#define FONT_4thd_FIRST_CHAR 32
-#define FONT_4thd_WIDTH 4
-#define FONT_4thd_HEIGHT 4
-#define FONT_Bitocra-13-full_ADDR 0x0357
-#define FONT_Bitocra-13-full_FIRST_CHAR 32
-#define FONT_Bitocra-13-full_WIDTH 7
-#define FONT_Bitocra-13-full_HEIGHT 13
-#define FONT_Bitocra-13_ADDR 0x0cf0
-#define FONT_Bitocra-13_FIRST_CHAR 32
-#define FONT_Bitocra-13_WIDTH 7
-#define FONT_Bitocra-13_HEIGHT 13
-#define FONT_Bitocra_ADDR 0x1689
-#define FONT_Bitocra_FIRST_CHAR 32
-#define FONT_Bitocra_WIDTH 0
-#define FONT_Bitocra_HEIGHT 0
-#define FONT_Bitbuntu_ADDR 0x1b1d
-#define FONT_Bitbuntu_FIRST_CHAR 32
-#define FONT_Bitbuntu_WIDTH 0
-#define FONT_Bitbuntu_HEIGHT 0
-#define FONT_Bitocra-full_ADDR 0x1fbd
-#define FONT_Bitocra-full_FIRST_CHAR 32
-#define FONT_Bitocra-full_WIDTH 6
-#define FONT_Bitocra-full_HEIGHT 11
-#define FONT_Bitbuntu-full_ADDR 0x27e7
-#define FONT_Bitbuntu-full_FIRST_CHAR 32
-#define FONT_Bitbuntu-full_WIDTH 6
-#define FONT_Bitbuntu-full_HEIGHT 10
-#define FONT_Bitocra7_ADDR 0x2f53
-#define FONT_Bitocra7_FIRST_CHAR 0
-#define FONT_Bitocra7_WIDTH 4
-#define FONT_Bitocra7_HEIGHT 7
-
-
-// IMAGES
-#define IMG_BEGIN 0x3493
-#define IMG_Test_image_2_ADDR 0x3493
-#define IMG_Test_image_1_ADDR 0x3693
-#define IMG_COUNT 2
-
+/** GENERATED BY EEPROM COMPILER SCRIPT **/
+
+// FONTS
+#define FONT_5thelement_ADDR 0x0000
+#define FONT_5thelement_FIRST_CHAR 32
+#define FONT_5thelement_WIDTH 4
+#define FONT_5thelement_HEIGHT 5
+#define FONT_Bitbuntu_ADDR 0x01db
+#define FONT_Bitbuntu_FIRST_CHAR 32
+#define FONT_Bitbuntu_WIDTH 0
+#define FONT_Bitbuntu_HEIGHT 0
+#define FONT_Bitocra-13_ADDR 0x067b
+#define FONT_Bitocra-13_FIRST_CHAR 32
+#define FONT_Bitocra-13_WIDTH 7
+#define FONT_Bitocra-13_HEIGHT 13
+#define FONT_Bitocra-13-full_ADDR 0x1014
+#define FONT_Bitocra-13-full_FIRST_CHAR 32
+#define FONT_Bitocra-13-full_WIDTH 7
+#define FONT_Bitocra-13-full_HEIGHT 13
+#define FONT_4thd_ADDR 0x19ad
+#define FONT_4thd_FIRST_CHAR 32
+#define FONT_4thd_WIDTH 4
+#define FONT_4thd_HEIGHT 4
+#define FONT_Bitocra_ADDR 0x1b29
+#define FONT_Bitocra_FIRST_CHAR 32
+#define FONT_Bitocra_WIDTH 0
+#define FONT_Bitocra_HEIGHT 0
+#define FONT_Bitocra7_ADDR 0x1fbd
+#define FONT_Bitocra7_FIRST_CHAR 0
+#define FONT_Bitocra7_WIDTH 4
+#define FONT_Bitocra7_HEIGHT 7
+#define FONT_Bitbuntu-full_ADDR 0x24fd
+#define FONT_Bitbuntu-full_FIRST_CHAR 32
+#define FONT_Bitbuntu-full_WIDTH 6
+#define FONT_Bitbuntu-full_HEIGHT 10
+#define FONT_Bitocra-full_ADDR 0x2c69
+#define FONT_Bitocra-full_FIRST_CHAR 32
+#define FONT_Bitocra-full_WIDTH 6
+#define FONT_Bitocra-full_HEIGHT 11
+
+
+// IMAGES
+#define IMG_BEGIN 0x3493
+#define IMG_Test_image_2_ADDR 0x3493
+#define IMG_Test_image_1_ADDR 0x3693
+#define IMG_COUNT 2
+
diff --git a/src/eeprom_dump b/src/eeprom_dump
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/eeprom_dump
diff --git a/src/i2c.c b/src/i2c.c
index 25b2d0f..0b1cb90 100644
--- a/src/i2c.c
+++ b/src/i2c.c
@@ -37,7 +37,7 @@
*
*/
-void error() {}
+void error() { }
void i2c_init() {
TWBR = 12;
@@ -48,29 +48,30 @@ void i2c_init() {
void i2c_start(uint8_t addr, bool rw) {
TWCR = (_BV(TWSTA) | _BV(TWEN) | _BV(TWINT)); //send start signal
loop_until_bit_is_set(TWCR, TWINT);
- if((TWSR & 0xf8) != TW_START) {
+ if(((TWSR & 0xf8) != (TW_START)) && ((TWSR & 0xf8) != (TW_REP_START))) {
#ifdef DEBUG_BUILD
- printf("Couldn't set start condition?\n");
+ printf("Couldn't set start condition? TWSR: 0x%x\r\n", TWSR & 0xf8);
#endif
error();
}
+
TWDR = (addr << 1) | rw;
TWCR = _BV(TWINT) | _BV(TWEN);
loop_until_bit_is_set(TWCR, TWINT);
- if((TWSR & 0xf8) != TW_MT_SLA_ACK) {
+ if(((TWSR & 0xf8) != (TW_MT_SLA_ACK)) && (TWSR & 0xf8) != (TW_MR_SLA_ACK)) {
#ifdef DEBUG_BUILD
printf("unhandled NACK in address transmission\
TWCR: 0x%x\
- TWSR: 0x%x\n", TWCR, (TWSR & ~(0b11)));
+ TWSR: 0x%x\r\n", TWCR, (TWSR & ~(0b11)));
#endif
error();
}
}
-void i2c_stop() { TWCR = (_BV(TWSTO) | _BV(TWEN) | _BV(TWINT)); }
+void i2c_stop() { TWCR = (_BV(TWSTO) | _BV(TWEN) | _BV(TWINT)); _delay_ms(500); }
void i2c_send(uint8_t byte) {
TWDR = byte; //fist packet is address
@@ -81,7 +82,7 @@ void i2c_send(uint8_t byte) {
#ifdef DEBUG_BUILD
printf("unhandled NACK in data transmission\
TWCR: 0x%x\
- TWSR: 0x%x\n", TWCR, (TWSR & ~(0b11)));
+ TWSR: 0x%x\r\n", TWCR, (TWSR & ~(0b11)));
#endif
error();
}
@@ -89,11 +90,14 @@ void i2c_send(uint8_t byte) {
uint8_t i2c_recv() {
uint8_t value;
+ TWCR = _BV(TWINT) | _BV(TWEN);
loop_until_bit_is_set(TWCR, TWINT);
value = TWDR;
- if((TWSR & 0xf8) != TW_MR_SLA_ACK) {
+ //the eeprom supposedly doesn't return an ack here,
+ //as it should (according to its datasheet), but it still works?
+ if(((TWSR & 0xf8) != TW_MR_DATA_ACK) && ((TWSR & 0xf8) != TW_MR_DATA_NACK)) {
#ifdef DEBUG_BUILD
- printf("Error recieving byte from i2c device\n");
+ printf("Error recieving byte from i2c device: 0x%x\r\n", TWSR & 0xf8);
#endif
error();
}
@@ -128,3 +132,11 @@ void i2c_write_reg_multi(uint8_t device_addr, uint8_t device_reg, size_t len, ui
for(size_t on_byte = 0; on_byte < len; on_byte++) i2c_send(values[on_byte]);
i2c_stop();
}
+
+void i2c_write_reg_addr16(uint8_t device_addr, uint16_t device_reg, uint8_t data) {
+ i2c_start(device_addr, I2C_WRITE);
+ i2c_send((uint8_t)device_reg & 0xff);
+ i2c_send((uint8_t)device_reg >> 8);
+ i2c_send(data);
+ i2c_stop();
+}
diff --git a/src/i2c.h b/src/i2c.h
index c5d5034..1c83a41 100644
--- a/src/i2c.h
+++ b/src/i2c.h
@@ -18,6 +18,7 @@ uint8_t i2c_recv();
void i2c_stop();
void i2c_start(uint8_t addr, bool rw);
uint8_t i2c_read_reg_addr16(uint8_t device, uint16_t addr);
+void i2c_write_reg_addr16(uint8_t device_addr, uint16_t device_reg, uint8_t data);
void i2c_init();
diff --git a/src/main.c b/src/main.c
index 46f2f3b..93903c9 100644
--- a/src/main.c
+++ b/src/main.c
@@ -7,6 +7,9 @@
#include "ssd1306_display_driver.h"
#include "debug.h" //TODO move to timer
#include "br24t_eeprom_driver.h"
+#include "pcf_clock_driver.h"
+#include "pins.h"
+#include "uart.h"
/**
* TODO
* make sure desired functions are static (it's just good practice)
@@ -19,37 +22,41 @@
*/
-#if defined(DEBUG_BUILD) || defined(EEPROM_INSTALL)
-#include "uart.h" //TODO remove if needed
-#endif
int main() {
+ LED_DEBUG_DDR |= _BV(LED_DEBUG); //TODO move to debug file or somethin
+ LED_DEBUG_PORT &= ~(_BV(LED_DEBUG));
//initlizes i2c, right now only speed //TODO don't delegate a whole function if desired
i2c_init();
- screen_init();
-#if defined(DEBUG_BUILD) || defined(EEPROM_INSTALL)
- //initlizes usart registers
+ //screen_init();
+#if defined(DEBUG_BUILD) || defined(FLASH_EEPROM)
+
uart_init();
FILE stdout_replacement = FDEV_SETUP_STREAM((void *)uart_sendbyte, NULL, _FDEV_SETUP_WRITE);
FILE stdin_replacement = FDEV_SETUP_STREAM(NULL, (void *)uart_recvbyte, _FDEV_SETUP_READ);
stdout = &stdout_replacement;
stdin = &stdin_replacement;
- screen_testdraw();
+
+ //screen_lowlvl_testdraw();
+ //eeprom_testbyte();
+ //test_clock();
#endif
+
//initilize timer
timer_init();
-#ifdef EEPROM_INSTALL
+#ifdef FLASH_EEPROM
+ //uart_echo();
flash_eeprom();
#endif
//initlizes screen registers with good values since we dont have control over reset functionallity
- screen_init();
+ //screen_init();
return 0;
}
diff --git a/src/makefile b/src/makefile
index 67a36c0..8c6b06d 100644
--- a/src/makefile
+++ b/src/makefile
@@ -4,14 +4,16 @@ CC=$(TOOLCHAIN_DIR)/bin/avr-gcc
LD=$(TOOLCHAIN_DIR)/bin/avr-ld
INC=$(TOOLCHAIN_DIR)/avr/include
OUT=compiled_payload.elf
-DEVICE=atmega2560
+#DEVICE=atmega2560
+DEVICE=atmega328p
F_CPU=16000000
DEBUG=1
#avrdude options
-PARTNO=ATmega2560
-PORT=/dev/ttyACM1
+#PARTNO=ATmega2560
+PARTNO=ATmega328p
+PORT=/dev/ttyUSB0
BAUD=115200
@@ -25,23 +27,31 @@ make:
#$(CC) -mmcu=$(DEVICE) -I $(INC) -c debug_serial.o -DDEBUG_BUILD=$(DEBUG) -DBAUD=$(RUNTIME_BAUDRATE) -DF_CPU=$(F_CPU) -Wall -O1 i2c.c
#$(LD) -mavr6 -o $(OUT) -s main.o debug_serial.o #TODO wish I knew how to make -mavr6 dependent on DEVICE
#TODO no debug.c if debug disabled
- $(CC) -mmcu=$(DEVICE) -I $(INC) -o $(OUT) -DDEBUG_BUILD=$(DEBUG) -DBAUD=$(RUNTIME_BAUDRATE) -DF_CPU=$(F_CPU) -Wall -O1 main.c debug.c i2c.c ssd1306_display_driver.c uart.c br24t_eeprom_driver.c paint.c -Wall
+ $(CC) -mmcu=$(DEVICE) -I $(INC) -o $(OUT) -DDEBUG_BUILD=$(DEBUG) -DBAUD=$(RUNTIME_BAUDRATE) -DF_CPU=$(F_CPU) -Wall -O1 main.c debug.c i2c.c ssd1306_display_driver.c uart.c br24t_eeprom_driver.c paint.c pcf_clock_driver.c -Wall
compiledb make --dry-run > /dev/null
+reset:
+ doas avrdude -c usbtiny -p $(PARTNO)
+
+eeprom_write:
+ doas avrdude -c usbtiny -p $(PARTNO)
+ doas ./write_eeprom.py $(PORT) $(RUNTIME_BAUDRATE)
+
eeprom:
./compile_eeprom.py
eeprom_install:
- $(CC) -lc -mmcu=$(DEVICE) -I $(INC) -o $(OUT) -DBAUD=$(RUNTIME_BAUDRATE) -DF_CPU=$(F_CPU) -DEEPROM_INSTALL -Wall -O1 debug.c i2c.c ssd1306_driver.c uart.c main.c -Wall
- doas avrdude -v -p $(PARTNO) -P $(PORT) -c wiring -b $(BAUD) -D -U flash:w:$(OUT):e
- doas ./write_eeprom.py $(PORT) $(SPEED)
+ $(CC) -mmcu=$(DEVICE) -I $(INC) -o $(OUT) -DFLASH_EEPROM -DDEBUG_BUILD=$(DEBUG) -DBAUD=$(RUNTIME_BAUDRATE) -DF_CPU=$(F_CPU) -Wall -O1 main.c debug.c i2c.c ssd1306_display_driver.c uart.c br24t_eeprom_driver.c paint.c -Wall
+ doas avrdude -B 1 -v -p $(PARTNO) -c usbtiny -U flash:w:$(OUT):e
install: $(OUT)
- doas avrdude -v -p $(PARTNO) -P $(PORT) -c wiring -b $(BAUD) -D -U flash:w:$(OUT):e
+ doas avrdude -B 1 -v -p $(PARTNO) -c usbtiny -U flash:w:$(OUT):e
+ #doas avrdude -v -p $(PARTNO) -P $(PORT) -c wiring -b $(BAUD) -D -U flash:w:$(OUT):e
screen:
- screen $(PORT) $(RUNTIME_BAUDRATE)
+ doas avrdude -c usbtiny -p $(PARTNO)
+ doas screen $(PORT) $(RUNTIME_BAUDRATE)
clean:
rm -f *.o *.elf compiled_eeprom
diff --git a/src/pcf_clock_driver.c b/src/pcf_clock_driver.c
index c02a934..d4a0b64 100644
--- a/src/pcf_clock_driver.c
+++ b/src/pcf_clock_driver.c
@@ -1,4 +1,6 @@
-#include <i2c.h>
+#include <util/delay.h>
+#include <stdio.h>
+#include "i2c.h"
#define CLOCK_ADDR 0x51
#ifdef FLASH_EEPROM
@@ -6,10 +8,5 @@ void flash_clock() {
i2c_write_reg(EEPROM_ADDR, 0x00, 0x58); //resets clock
i2c_write_reg(CLOCK_ADDR, 0x00, 0x40); //sets to 12 hour time
i2c_write_reg(CLOCK_ADDR, 0x01, 0x08); //sets alarm interrupts on
-
- //recieve time
-
-
}
- i2c_write_reg(CLOCK_ADDR, 0x03, 0x01); //free ram byte; says we've set the time
#endif
diff --git a/src/pcf_clock_driver.h b/src/pcf_clock_driver.h
index af20689..29b6c85 100644
--- a/src/pcf_clock_driver.h
+++ b/src/pcf_clock_driver.h
@@ -4,3 +4,6 @@ void clock_init();
void set_time(time_t time);
time_t get_time();
void set_alarm(time_t time);
+
+//TODO REMOVE ME
+void test_clock();
diff --git a/src/pins.h b/src/pins.h
new file mode 100644
index 0000000..f874e19
--- /dev/null
+++ b/src/pins.h
@@ -0,0 +1,25 @@
+#ifndef __PINS_INC
+/**
+ * CTS is connected to CTS, CTS is 1 when we are ready
+ * scope pins:
+ * 1: desktop tx
+ * 2: desktop rx
+ * 3: desktop rts
+ * 4: desktop cts
+ */
+#define __PINS_INC
+
+#include <avr/io.h>
+
+#define UART_DDR DDRD
+#define UART_CTS PD2 //cyan
+#define UART_RTS PD3 //yellow
+#define UART_PORT PORTD
+
+#define LED_DEBUG_DDR DDRB
+#define LED_DEBUG_PORT PORTB
+#define LED_DEBUG PB5
+
+
+#endif
+
diff --git a/src/ssd1306_display_driver.c b/src/ssd1306_display_driver.c
index 0e7d4cc..0bff3b0 100644
--- a/src/ssd1306_display_driver.c
+++ b/src/ssd1306_display_driver.c
@@ -20,7 +20,7 @@
void screen_init() {
#ifdef DEBUG_BUILD
- printf("initlizing SSD1306 display driver\n");
+ printf("initlizing SSD1306 display driver\r\n");
#endif
//turn on screen while we configure shit, it might look cooler
i2c_write_reg(SSD1306_ADDR, SSD1306_CMD_REG, 0xaf);
@@ -86,42 +86,3 @@ void screen_update() {
}
}
-#ifdef DEBUG_BUILD
-//ugly code below
-
-void scroll_test() {
- //sets scroll area to whole screen
- i2c_write_reg_multi(SSD1306_ADDR, SSD1306_CMD_REG, 3, (uint8_t[]){0xa3, 0x00, 0x20});
- //set up scroll options
- i2c_write_reg_multi(SSD1306_ADDR, SSD1306_CMD_REG, 6, (uint8_t[]){0x29, 0x00, 0x00, 0x00, 0x04, 0x00});
- //actually activate scroll
- i2c_write_reg_multi(SSD1306_ADDR, SSD1306_CMD_REG, 6, (uint8_t[]){0x2f});
-}
-
-void screen_testdraw() {
- unsigned int on_pix;
- unsigned int on_page;
-
- printf("running screen time tests\n");
- printf("generating test image...\n");
- for(on_pix = 0; on_pix < sizeof(screen_buffer); on_pix++)
- screen_buffer[on_pix] = ((uint8_t)0xaa << (on_pix % 8));
-
- printf("page mode, individual byte per i2c call...\n");
- for(on_page = 0; on_page < SCREEN_PAGE_CNT; on_page++) {
- i2c_write_reg(SSD1306_ADDR, SSD1306_CMD_REG, 0xb0 + on_page);
- i2c_write_reg(SSD1306_ADDR, SSD1306_CMD_REG, 0x00);
- i2c_write_reg(SSD1306_ADDR, SSD1306_CMD_REG, 0x10);
- for(on_pix = 0; on_pix < SCREEN_RES_X; on_pix++)
- i2c_write_reg(SSD1306_ADDR, SSD1306_DATA_REG, screen_buffer[(on_page * 8) + on_pix]);
- }
- printf("page mode, 1 page per i2c call...\n");
- for(on_page = 0; on_page < SCREEN_PAGE_CNT; on_page++) {
- i2c_write_reg(SSD1306_ADDR, SSD1306_CMD_REG, 0xb0 + on_page);
- i2c_write_reg(SSD1306_ADDR, SSD1306_CMD_REG, 0x00);
- i2c_write_reg(SSD1306_ADDR, SSD1306_CMD_REG, 0x10);
- i2c_write_reg_multi(SSD1306_ADDR, SSD1306_DATA_REG, SCREEN_RES_X, &screen_buffer[on_page * SCREEN_RES_X]);
- }
-}
-
-#endif
diff --git a/src/uart.c b/src/uart.c
index 3ba75db..ca1e587 100644
--- a/src/uart.c
+++ b/src/uart.c
@@ -1,6 +1,7 @@
#include <avr/io.h>
#include <stdio.h>
#include <util/setbaud.h>
+#include "pins.h"
/** UART notes
* UCSR0A:
@@ -35,27 +36,36 @@
* ____________________________________________________________
* UBRR0(H,L): baudrates
*
+ *
**/
//TODO replace with static void and just use high level functions?
void uart_sendbyte(uint8_t byte) {
- if(byte == '\n') uart_sendbyte('\r');
- loop_until_bit_is_set(UCSR0A, UDRE0);
+ UART_PORT &= ~(_BV(UART_RTS)); //us: ready to send
+ loop_until_bit_is_clear(UART_PORT, UART_CTS); //them: go ahead
+ //also wait for buffer to be empty, should never be a problem
+ loop_until_bit_is_set(UCSR0A, UDRE0); //done recieving
UDR0 = byte;
+ UART_PORT |= _BV(UART_RTS); //keep in mind cts is inverted; low is 1 and high is 0
}
//TODO replace with static void and just use high level functions?
uint8_t uart_recvbyte() {
- loop_until_bit_is_set(UCSR0A, RXC0);
+ loop_until_bit_is_clear(UART_PORT, UART_CTS); //wait for their request
+ UART_PORT &= ~(_BV(UART_RTS)); //hey, you can send now
+ loop_until_bit_is_set(UCSR0A, RXC0); //wait for them to actually send
+ UART_PORT |= _BV(UART_RTS); //okay, you can no longer send
return UDR0;
}
void uart_init() {
//set baud rate
+ UART_DDR |= _BV(UART_RTS);
+ UART_PORT |= _BV(UART_RTS); //keep in mind cts is inverted; low is 1 and high is 0
+
UBRR0H = UBRRH_VALUE;
UBRR0L = UBRRL_VALUE;
-
/**
TODO figure out why USE_2X is enable when it shoudn't be
//set baud rate
diff --git a/src/uart.h b/src/uart.h
index b5f043a..5536df0 100644
--- a/src/uart.h
+++ b/src/uart.h
@@ -1,3 +1,8 @@
+#ifndef __UART_INC
+#define __UART_INC
void uart_init();
void uart_sendbyte(uint8_t byte);
uint8_t uart_recvbyte();
+
+#define HARDWARE_FLOW 1 //TODO
+#endif
diff --git a/src/write_eeprom.py b/src/write_eeprom.py
index 9b76e51..e0a8604 100755
--- a/src/write_eeprom.py
+++ b/src/write_eeprom.py
@@ -2,9 +2,11 @@
import serial
import argparse
import os
+from time import sleep
+from math import ceil
#we send syn, recv ack
-SYN_MAGIC = 0xdeafbeef
+SYN_MAGIC = 0xdeadbeef
ACK_MAGIC = 0xf00dd00d
EEPROM_PAGESIZE = 64
@@ -18,33 +20,57 @@ args = parser.parse_args()
eeprom_file = open("./compiled_eeprom", "rb")
eeprom_filesize = os.fstat(eeprom_file.fileno()).st_size
+page_len = ceil(eeprom_filesize / EEPROM_PAGESIZE)
-s = serial.Serial(args.port, args.baud, timeout = 0)
-s.write(SYN_MAGIC)
+s = serial.Serial(port=args.port, baudrate=args.baud, parity=serial.PARITY_NONE, timeout=0, dsrdtr=1)
-def handle_writer_error():
+#slow method
+def write_hwf(data):
+ debugval = 0
+ print("writing")
+ data_parsed = [data[b:b+1] for b in range(len(data))]
+ for c in data_parsed:
+ print(debugval)
+ debugval += 1
+ s.rts = 1
+ while not s.cts:
+ pass
+ s.rts = 0
+ s.write(c)
+
+def read_hwf(length):
+ print("reading")
+ msg = b''
+ for c in range(length):
+ s.rts = 1
+ while not s.cts:
+ pass
+ s.rts = 0
+ msg += s.read(size=1)
+ return(msg)
+
+def handle_writer_error(write_status):
if write_status == 1: # verification failed
print("Verification failed on page {}!".format(page))
elif write_status == 0xff:
print("Unknown error writing page {}!".format(page))
+#while True:
+# write_hwf(b"abcdef\r\n")
+# print(read_hwf(10))
-while not s.read(4) == ACK_MAGIC:
- pass
-
-print("Device detected, writing eeprom...")
-for page in range(0, int(eeprom_filesize / EEPROM_PAGESIZE)):
- s.write(eeprom_file.read(EEPROM_PAGESIZE))
- write_status = s.read(1)
- if not write_status == 0:
- handle_writer_error(write_status)
+write_hwf(page_len.to_bytes(1, 'little'))
-if eeprom_file.tell() < eeprom_filesize:
- s.write(eeprom_file.read())
- [s.write(0) for b in range(0, eeprom_filesize % EEPROM_PAGESIZE)]
- write_status = s.read(1)
+for page in range(0, page_len):
+ print(page)
+ if EEPROM_PAGESIZE > (eeprom_filesize - eeprom_file.tell()):
+ write_hwf(eeprom_file.read())
+ [write_hwf(b'\x00') for b in range(0, eeprom_filesize % EEPROM_PAGESIZE)]
+ else:
+ write_hwf(eeprom_file.read(EEPROM_PAGESIZE))
+ write_status = read_hwf(1)
+ print("WRITE STATUS: {}".format(write_status))
if not write_status == 0:
handle_writer_error(write_status)
-
-print("Done writing to EEPROM! You are still alone!")
+print("Done writing to EEPROM!\n")