From 94304b11e7220f060dbc345de5fa1952d0465016 Mon Sep 17 00:00:00 2001 From: Brett Weiland Date: Tue, 27 Sep 2022 16:14:28 -0500 Subject: working on serial syncronization for programming eeprom --- docs/atmega328p.pdf | Bin 0 -> 8585103 bytes docs/mega2560_schematic.pdf | Bin 0 -> 48189 bytes docs/nano.pdf | Bin 0 -> 874520 bytes src/br24t_eeprom_driver.c | 31 +++++++------- src/br24t_eeprom_driver.h | 5 ++- src/compile_commands.json | 26 ++++++++++++ src/compile_eeprom.py | 22 +++++----- src/debug.c | 72 ++++++++++++++++++++++++++++++++- src/debug.h | 9 +++++ src/eeprom_address.h | 94 +++++++++++++++++++++---------------------- src/eeprom_dump | 0 src/i2c.c | 30 +++++++++----- src/i2c.h | 1 + src/main.c | 25 +++++++----- src/makefile | 28 ++++++++----- src/pcf_clock_driver.c | 9 ++--- src/pcf_clock_driver.h | 3 ++ src/pins.h | 25 ++++++++++++ src/ssd1306_display_driver.c | 41 +------------------ src/uart.c | 18 +++++++-- src/uart.h | 5 +++ src/write_eeprom.py | 64 ++++++++++++++++++++--------- 22 files changed, 336 insertions(+), 172 deletions(-) create mode 100644 docs/atmega328p.pdf create mode 100644 docs/mega2560_schematic.pdf create mode 100644 docs/nano.pdf create mode 100644 src/eeprom_dump create mode 100644 src/pins.h diff --git a/docs/atmega328p.pdf b/docs/atmega328p.pdf new file mode 100644 index 0000000..4a9dad4 Binary files /dev/null and b/docs/atmega328p.pdf differ diff --git a/docs/mega2560_schematic.pdf b/docs/mega2560_schematic.pdf new file mode 100644 index 0000000..bdd9be1 Binary files /dev/null and b/docs/mega2560_schematic.pdf differ diff --git a/docs/nano.pdf b/docs/nano.pdf new file mode 100644 index 0000000..cddb795 Binary files /dev/null and b/docs/nano.pdf 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 #include +#include +#include #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 #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 #include #include +#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 #include #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 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 +#include +#include +#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 + +#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 #include #include +#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") -- cgit v1.2.3