init
This commit is contained in:
		
						commit
						7b006d6f20
					
				
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | ||||
| src/compiled_payload.elf | ||||
| src/compiled_eeprom | ||||
| src/.cache | ||||
							
								
								
									
										23
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,23 @@ | ||||
| # AVR WRISTWATCH | ||||
| ## What is it? | ||||
| This repository contains the code in development (and soon schematics) for a small wristwatch with a 128x32 OLED display. I'm hoping it will last the whole day, have cool animated visuals, and be pretty to look at. | ||||
| 
 | ||||
| ## Desired Features and Goals  | ||||
| * 128x32 OLED monochrome display | ||||
| * 128kb upgradable external EEPROM for images and short videos | ||||
| * Fancy graphics, display images and videos that can overlay time with inverting filter | ||||
| * Battery that lasts at least a day | ||||
| * USB-C charging (may switch to micro-usb depending on IC prices/availability) | ||||
| * Display the time | ||||
| 
 | ||||
| ## Parts | ||||
| * Microcontroller: Any ATmega chip with TWI/I2C I can get my hands on | ||||
| * Display: Waveshare 128x32 0.91inch OLED display  | ||||
| * RTC clock: PCF85063A | ||||
| * EEPROM: BR24T128-W | ||||
| * Battery Management: TBD | ||||
|    | ||||
| 
 | ||||
| ## Why | ||||
| This project is to help me learn how to develop for AVR without Arduino libraries, read datasheets faster, and to prove I can solder small SMD components. It will be my first physical project where I design my own PCB, which has been something I've wanted to do for a long time. | ||||
| 
 | ||||
							
								
								
									
										
											BIN
										
									
								
								docs/Quiescent_Current.pdf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								docs/Quiescent_Current.pdf
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										2
									
								
								docs/README.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								docs/README.txt
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,2 @@ | ||||
| This folder is simply for my own refrence for the chips I buy. | ||||
| This is NOT any documentation for the watch. | ||||
							
								
								
									
										58581
									
								
								docs/atmega2560.pdf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58581
									
								
								docs/atmega2560.pdf
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								docs/clock.pdf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								docs/clock.pdf
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								docs/display_driver.pdf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								docs/display_driver.pdf
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								docs/eeprom.pdf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								docs/eeprom.pdf
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								docs/i2c_summary.pdf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								docs/i2c_summary.pdf
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										62
									
								
								src/br24t_eeprom_driver.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								src/br24t_eeprom_driver.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,62 @@ | ||||
| #include <stdio.h> | ||||
| #include "i2c.h" | ||||
| #include "br24t_eeprom_driver.h" | ||||
| 
 | ||||
| #define EEPROM_ADDR       0x57 | ||||
| #define EEPROM_PAGE_SIZE  64 | ||||
| 
 | ||||
| //for burning eeprom
 | ||||
| #define MAGIC_SYN         0xdeadbeef | ||||
| #define MAGIC_ACK         0xf00dd00d | ||||
| 
 | ||||
| #define PAGE_WRITE_OK                 0x00 | ||||
| #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; | ||||
|   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?
 | ||||
|    | ||||
|   //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) { | ||||
| 
 | ||||
|     fread(eeprom_buffer_out, EEPROM_PAGE_SIZE, 1, stdin); | ||||
| 
 | ||||
|     i2c_start(EEPROM_I2C_ADDR, I2C_READ); | ||||
|     i2c_send((uint8_t)(page * EEPROM_PAGE_SIZE) & 0xff); | ||||
|     i2c_send((uint8_t)(page * EEPROM_PAGE_SIZE) >> 8); | ||||
|     for(on_byte = 0; on_byte < EEPROM_PAGE_SIZE; on_byte++)  | ||||
|       i2c_send(eeprom_buffer_out[on_byte]);  | ||||
|     i2c_stop(); | ||||
| 
 | ||||
|     //verify
 | ||||
|     eeprom_buffer_in[0] = EEPROM_READBYTE(page * EEPROM_PAGE_SIZE); | ||||
|     //eeprom_buffer_in[0] = i2c_read_reg_addr16(EEPROM_I2C_ADDR, page * EEPROM_PAGE_SIZE);
 | ||||
|     i2c_start(EEPROM_I2C_ADDR, I2C_READ); | ||||
|     for(on_byte = 1; on_byte < EEPROM_PAGE_SIZE; on_byte++) | ||||
|       eeprom_buffer_in[on_byte] = i2c_recv(); | ||||
|     i2c_stop(); | ||||
| 
 | ||||
|     if(memcmp(eeprom_buffer_in, eeprom_buffer_out, EEPROM_PAGE_SIZE)) { | ||||
|       fputc(PAGE_WRITE_CORRUPTED, stdout); | ||||
|       error(); | ||||
|     } | ||||
|     fputc(PAGE_WRITE_OK, stdout); | ||||
|   } | ||||
| } | ||||
| #endif | ||||
							
								
								
									
										21
									
								
								src/br24t_eeprom_driver.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								src/br24t_eeprom_driver.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,21 @@ | ||||
| #ifndef __BR24_INC | ||||
| #define __BR24_INC | ||||
| 
 | ||||
| #include <stdint.h> | ||||
| #include "i2c.h" | ||||
| 
 | ||||
| #define EEPROM_I2C_ADDR   0x50 //fix to represent custom address setting
 | ||||
| 
 | ||||
| 
 | ||||
| #ifdef FLASH_EEPROM | ||||
| void flash_eeprom(); | ||||
| #endif | ||||
| 
 | ||||
| typedef uint16_t EEPROM_ADDR; | ||||
| 
 | ||||
| #define EEPROM_READBYTE(addr) i2c_read_reg_addr16(EEPROM_I2C_ADDR, addr); | ||||
| 
 | ||||
| 
 | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
							
								
								
									
										114
									
								
								src/compile_commands.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										114
									
								
								src/compile_commands.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,114 @@ | ||||
| [ | ||||
|  { | ||||
|   "directory": "/home/indigo/projects/watch/src", | ||||
|   "arguments": [ | ||||
|    "/home/indigo/packs/avr8-gnu-toolchain-linux_x86_64/bin/avr-gcc", | ||||
|    "-v", | ||||
|    "-mmcu=atmega2560", | ||||
|    "-I", | ||||
|    "/home/indigo/packs/avr8-gnu-toolchain-linux_x86_64/avr/include", | ||||
|    "-o", | ||||
|    "compiled_payload", | ||||
|    "-DBAUD=9600", | ||||
|    "-DF_CPU=16000000", | ||||
|    "-Wall", | ||||
|    "-O1", | ||||
|    "main.c" | ||||
|   ], | ||||
|   "file": "main.c" | ||||
|  }, | ||||
|  { | ||||
|   "directory": "/home/indigo/projects/watch/src", | ||||
|   "arguments": [ | ||||
|    "/home/indigo/packs/avr8-gnu-toolchain-linux_x86_64/bin/avr-gcc", | ||||
|    "-lc", | ||||
|    "-mmcu=atmega2560", | ||||
|    "-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_serial.c", | ||||
|    "i2c.c", | ||||
|    "ssd1306_driver.h" | ||||
|   ], | ||||
|   "file": "i2c.c" | ||||
|  }, | ||||
|  { | ||||
|   "directory": "/home/indigo/projects/watch/src", | ||||
|   "arguments": [ | ||||
|    "/home/indigo/packs/avr8-gnu-toolchain-linux_x86_64/bin/avr-gcc", | ||||
|    "-mmcu=atmega2560", | ||||
|    "-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_driver.c", | ||||
|    "uart.c", | ||||
|    "-Wall" | ||||
|   ], | ||||
|   "file": "uart.c" | ||||
|  }, | ||||
|  { | ||||
|   "directory": "/home/indigo/projects/watch/src", | ||||
|   "arguments": [ | ||||
|    "/home/indigo/packs/avr8-gnu-toolchain-linux_x86_64/bin/avr-gcc", | ||||
|    "-mmcu=atmega2560", | ||||
|    "-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", | ||||
|    "-Wall" | ||||
|   ], | ||||
|   "file": "br24t_eeprom_driver.c" | ||||
|  }, | ||||
|  { | ||||
|   "directory": "/home/indigo/projects/watch/src", | ||||
|   "arguments": [ | ||||
|    "/home/indigo/packs/avr8-gnu-toolchain-linux_x86_64/bin/avr-gcc", | ||||
|    "-mmcu=atmega2560", | ||||
|    "-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", | ||||
|    "-Wall" | ||||
|   ], | ||||
|   "file": "paint.c" | ||||
|  } | ||||
| ] | ||||
							
								
								
									
										116
									
								
								src/compile_eeprom.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										116
									
								
								src/compile_eeprom.py
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,116 @@ | ||||
| #!/usr/bin/env python3 | ||||
| from PIL import BdfFontFile, Image | ||||
| import os | ||||
| import serial | ||||
| import argparse | ||||
| 
 | ||||
| compiled_output_path = 'compiled_eeprom' | ||||
| header_path = 'eeprom_address.h' | ||||
| eeprom_length = 131072 # 128 kib | ||||
| 
 | ||||
| data_path = "./eeprom_data" | ||||
| 
 | ||||
| output = open(compiled_output_path, 'wb') | ||||
| header = open(header_path, 'w') | ||||
| 
 | ||||
| page_bit_width = 128 | ||||
| page_bit_height = 8 | ||||
| page_cnt = 4 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| #fonts | ||||
| # for some reason BdfFontFile.BdfFontFile.bitmap doesn't have proper spacing | ||||
| # so we'll just manually go through each character ourselves | ||||
| # it's expected I'll rename fonts to how I think they should be refrenced beorehand | ||||
| # 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") | ||||
| 
 | ||||
| for file in os.listdir("{}/fonts/".format(data_path)): | ||||
|     path = "{}/fonts/{}".format(data_path, file) | ||||
|     if os.path.isfile(path) and path.split('.')[-1] == 'bdf': | ||||
|         with open(path, 'rb') as font_fd: | ||||
|             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())) | ||||
| 
 | ||||
|             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( | ||||
|                             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())) | ||||
| 
 | ||||
| image_cnt = 0 | ||||
| 
 | ||||
| # images | ||||
| for file in os.listdir("{}/images/".format(data_path)): | ||||
|     path = "{}/images/{}".format(data_path, file) | ||||
|     if os.path.isfile(path) and path.split('.')[-1] == 'png': | ||||
|         with open(path, 'rb') as image_fd: | ||||
|             image_cnt += 1 | ||||
|             image_bitmap = [] | ||||
|             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") | ||||
|                 exit(1) | ||||
|             header.write("#define IMG_{}_ADDR\t0x{:04x}\n".format( | ||||
|                 file.split('.')[0].capitalize(), | ||||
|                 output.tell())) | ||||
|             for byte in range(0, len(image.tobytes()), 3): | ||||
|                 if (byte / 3) % 8 == 0: | ||||
|                     image_bitmap.append(0)  | ||||
|                 if sum(image.tobytes()[byte:byte+3]) > 0: | ||||
|                     image_bitmap[-1] |= (int(byte / 3)) % 8 | ||||
| 
 | ||||
|             # is this supposed to be big endian? | ||||
|             image_bitmap_remapped = [0] * len(image_bitmap) | ||||
|             for bit in range(0, page_bit_width * page_bit_height * page_cnt): | ||||
|                 w = page_bit_width | ||||
|                 h = page_bit_height | ||||
|                 i = bit | ||||
|                 #I am so sorry. | ||||
|                 extract_bit = (((i % w) * page_bit_height) +  | ||||
|                                        (int(i / w) % page_bit_height) +  | ||||
|                                        (int(i / (w * page_bit_height)) *  | ||||
|                                        (w * page_bit_height))) | ||||
| 
 | ||||
|                 if (extract_bit % 8) - (bit % 8) >= 0: | ||||
|                     image_bitmap_remapped[int(bit / 8)] |= \ | ||||
|                     (image_bitmap[int(extract_bit / 8)] & (extract_bit % 8)) >> \ | ||||
|                     ((extract_bit % 8) - (bit % 8))  | ||||
|                 else: | ||||
|                     image_bitmap_remapped[int(bit / 8)] |= \ | ||||
|                     (image_bitmap[int(extract_bit / 8)] & (extract_bit % 8)) << \ | ||||
|                     ((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)) | ||||
|              | ||||
| 
 | ||||
| 
 | ||||
| print("EEPROM used: {}% ({} out of {} bits)".format( | ||||
|     (output.tell() / eeprom_length) * 100,  | ||||
|     output.tell(), eeprom_length)) | ||||
| 
 | ||||
| if(output.tell() > eeprom_length): | ||||
|     print("WARNING: You've used more eeprom then there is available!\n") | ||||
| 
 | ||||
| output.close() | ||||
| header.close() | ||||
|                      | ||||
| 
 | ||||
| 
 | ||||
							
								
								
									
										31
									
								
								src/debug.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								src/debug.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,31 @@ | ||||
| #include <avr/io.h> | ||||
| #include <stdio.h> | ||||
| #include <util/delay.h> | ||||
| #include "debug.h" | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| /*
 | ||||
|  * TCNTn: timer/counter | ||||
|  * TCCRnA/B/C: timer/counter control registers | ||||
|  */ | ||||
| void timer_init() { | ||||
|   TCCR1A = 0;         //no waveform generation or something like that
 | ||||
|   TCCR1B = _BV(CS00); //no prescaling; use internal clock
 | ||||
|   TCCR1C = 0; | ||||
| } | ||||
| 
 | ||||
| //makes it easier to print time; is an unsigned int and NOT to be used for more then printing
 | ||||
| unsigned int ticks_to_seconds(uint16_t start, uint16_t end) {  | ||||
|   return ((unsigned int)(end - start) / F_CPU); | ||||
| } | ||||
| 
 | ||||
| void test_timer() { | ||||
|   uint16_t start, end; | ||||
|   start = TCNT1; | ||||
|   _delay_ms(1000); | ||||
|   end = TCNT1; | ||||
|   printf("1 second is %u ticks\n",  end - start); | ||||
| } | ||||
							
								
								
									
										14
									
								
								src/debug.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								src/debug.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,14 @@ | ||||
| #ifndef __DEBUG_SERIAL_H | ||||
| #define __DEBUG_SERIAL_H | ||||
| 
 | ||||
| #include <stdio.h> | ||||
| #include <avr/io.h> | ||||
| #include "uart.h" | ||||
| 
 | ||||
| void timer_init(); | ||||
| void test_timer(); | ||||
| unsigned int ticks_to_seconds(); | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| #endif | ||||
							
								
								
									
										47
									
								
								src/eeprom_address.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								src/eeprom_address.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +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 | ||||
| 
 | ||||
							
								
								
									
										
											BIN
										
									
								
								src/eeprom_data/compiled_eeprom
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/eeprom_data/compiled_eeprom
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										0
									
								
								src/eeprom_data/eeprom_locations.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								src/eeprom_data/eeprom_locations.h
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										1070
									
								
								src/eeprom_data/fonts/4thD.bdf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1070
									
								
								src/eeprom_data/fonts/4thD.bdf
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1165
									
								
								src/eeprom_data/fonts/5thElement.bdf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1165
									
								
								src/eeprom_data/fonts/5thElement.bdf
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										7567
									
								
								src/eeprom_data/fonts/bitbuntu-full.bdf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7567
									
								
								src/eeprom_data/fonts/bitbuntu-full.bdf
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										2550
									
								
								src/eeprom_data/fonts/bitbuntu.bdf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2550
									
								
								src/eeprom_data/fonts/bitbuntu.bdf
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										5450
									
								
								src/eeprom_data/fonts/bitocra-13-full.bdf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5450
									
								
								src/eeprom_data/fonts/bitocra-13-full.bdf
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										3810
									
								
								src/eeprom_data/fonts/bitocra-13.bdf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3810
									
								
								src/eeprom_data/fonts/bitocra-13.bdf
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										8010
									
								
								src/eeprom_data/fonts/bitocra-full.bdf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8010
									
								
								src/eeprom_data/fonts/bitocra-full.bdf
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										2538
									
								
								src/eeprom_data/fonts/bitocra.bdf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2538
									
								
								src/eeprom_data/fonts/bitocra.bdf
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										2720
									
								
								src/eeprom_data/fonts/bitocra7.bdf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2720
									
								
								src/eeprom_data/fonts/bitocra7.bdf
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								src/eeprom_data/fonts/bitorca-full.pcf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/eeprom_data/fonts/bitorca-full.pcf
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										10
									
								
								src/eeprom_data/fonts/fonts.dir
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								src/eeprom_data/fonts/fonts.dir
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,10 @@ | ||||
| 9 | ||||
| 4thD.bdf -aaron-4thd-medium-r-normal--4-40-86-86-c-30-iso8859-1 | ||||
| 5thElement.bdf -aaron-5thelement-medium-r-normal--5-40-86-86-c-30-iso8859-1 | ||||
| bitbuntu-full.bdf -aaron-bitbuntufull-medium-r-normal--10-100-72-72-c-90-utf8-1 | ||||
| bitbuntu.bdf -aaron-bitbuntu-medium-r-normal--10-100-72-72-c-90-iso8859-1 | ||||
| bitocra-13-full.bdf -aaron-bitocra13full-medium-r-normal--13-130-84-84-c-90-iso8859-1 | ||||
| bitocra-13.bdf -aaron-bitocra13-medium-r-normal--13-130-84-84-c-90-iso8859-1 | ||||
| bitocra-full.bdf -aaron-bitocrafull-medium-r-normal--11-100-72-72-m-90-iso8859-1 | ||||
| bitocra.bdf -aaron-bitocra-medium-r-normal--11-100-72-72-m-90-iso8859-1 | ||||
| bitocra7.bdf -aaron-bitocra7-medium-r-normal--7-60-75-75-c-40-iso8859-1 | ||||
							
								
								
									
										1
									
								
								src/eeprom_data/fonts/fonts.scale
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								src/eeprom_data/fonts/fonts.scale
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | ||||
| 0 | ||||
							
								
								
									
										
											BIN
										
									
								
								src/eeprom_data/fonts/test.bmp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/eeprom_data/fonts/test.bmp
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 82 B | 
							
								
								
									
										
											BIN
										
									
								
								src/eeprom_data/fonts/test.pbm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/eeprom_data/fonts/test.pbm
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 1.2 KiB | 
							
								
								
									
										
											BIN
										
									
								
								src/eeprom_data/fonts/test.pil
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/eeprom_data/fonts/test.pil
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								src/eeprom_data/images/test_image_1.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/eeprom_data/images/test_image_1.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 887 B | 
							
								
								
									
										
											BIN
										
									
								
								src/eeprom_data/images/test_image_2.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/eeprom_data/images/test_image_2.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 1.0 KiB | 
							
								
								
									
										
											BIN
										
									
								
								src/eeprom_data/sketches/test_image_1.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/eeprom_data/sketches/test_image_1.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 887 B | 
							
								
								
									
										
											BIN
										
									
								
								src/eeprom_data/sketches/test_image_1.xcf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/eeprom_data/sketches/test_image_1.xcf
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								src/eeprom_data/sketches/test_image_2.xcf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/eeprom_data/sketches/test_image_2.xcf
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								src/eeprom_data/test.bmp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/eeprom_data/test.bmp
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										130
									
								
								src/i2c.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										130
									
								
								src/i2c.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,130 @@ | ||||
| #include <stdio.h> | ||||
| #include <avr/io.h> | ||||
| #include <util/twi.h> | ||||
| #include <util/delay.h> | ||||
| #include <stdbool.h> | ||||
| #include <string.h> | ||||
| #ifdef DEBUG_BUILD | ||||
| #include "debug.h" | ||||
| #endif | ||||
| 
 | ||||
| #include "i2c.h" | ||||
| 
 | ||||
| 
 | ||||
| /** I2C notes
 | ||||
|  * TWDR: data address shift register | ||||
|  *  contians address or data bytes to be transmitted/recieved | ||||
|  *  ACK bit not accesible | ||||
|  * TWAR: matches recieved addresses | ||||
|  * TWCR: control register, sets settings | ||||
|   *  TWINT: tw interrupt flag  | ||||
|   *  also is dependent on GIE in SREG | ||||
|   * TWSR: TWI status register (only matters if TWI interurupt flag asserted) | ||||
|    | ||||
|  * Steps simplified: | ||||
|  * SEND START | ||||
|   * Send START with TWCR | ||||
|   * Set TWINT in TWCR to 1; as this clears the flag | ||||
|   * TWSR will then say start has begun | ||||
|  * Load SLA+W into TWDR (what is this? TODO) | ||||
|  * Write something to TWCR to initiate send? (make sure twint is set after) | ||||
|  * poll TWSR interrupt bit to see if we recieve a message (or figure out interrupts) | ||||
|  *  | ||||
|  * Note: You may be wondering why I'm not handling i2c errors. | ||||
|  * I have limited time, and I don't think it's nessesary unless I start running into them. | ||||
|  * | ||||
|  * Some I may work on handling later. | ||||
|  *  | ||||
|   */ | ||||
| 
 | ||||
| void error() {} | ||||
| 
 | ||||
| void i2c_init() { | ||||
|   TWBR = 12; | ||||
|   TWSR &= 0b11111100; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 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) {  | ||||
|     #ifdef DEBUG_BUILD | ||||
|       printf("Couldn't set start condition?\n"); | ||||
|     #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) {  | ||||
|     #ifdef DEBUG_BUILD | ||||
|       printf("unhandled NACK in address transmission\
 | ||||
|           TWCR: 0x%x\ | ||||
|           TWSR: 0x%x\n", TWCR, (TWSR & ~(0b11))); | ||||
|     #endif | ||||
|     error(); | ||||
|   } | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| void i2c_stop() { TWCR = (_BV(TWSTO) | _BV(TWEN) | _BV(TWINT)); } | ||||
| 
 | ||||
| void i2c_send(uint8_t byte) { | ||||
|   TWDR = byte; //fist packet is address 
 | ||||
|   TWCR = _BV(TWINT) | _BV(TWEN); //send over the byte
 | ||||
|   loop_until_bit_is_set(TWCR, TWINT); | ||||
|   | ||||
|   if((TWSR & 0xf8) != TW_MT_DATA_ACK) {  | ||||
|     #ifdef DEBUG_BUILD | ||||
|       printf("unhandled NACK in data transmission\
 | ||||
|           TWCR: 0x%x\ | ||||
|           TWSR: 0x%x\n", TWCR, (TWSR & ~(0b11))); | ||||
|     #endif | ||||
|     error(); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| uint8_t i2c_recv() { | ||||
|   uint8_t value; | ||||
|   loop_until_bit_is_set(TWCR, TWINT); | ||||
|   value = TWDR; | ||||
|   if((TWSR & 0xf8) != TW_MR_SLA_ACK) { | ||||
| #ifdef DEBUG_BUILD | ||||
|     printf("Error recieving byte from i2c device\n"); | ||||
| #endif | ||||
|   error(); | ||||
|   } | ||||
|   return value; | ||||
| } | ||||
| 
 | ||||
| //does NOT control start/stop, simply reads TWDR
 | ||||
| 
 | ||||
| uint8_t i2c_read_reg_addr16(uint8_t device, uint16_t addr) { | ||||
|   uint8_t value; | ||||
| 
 | ||||
|   i2c_start(device, I2C_WRITE);  | ||||
|   i2c_send((uint8_t)addr & 0xff); | ||||
|   i2c_send((uint8_t)addr >> 8); | ||||
|   i2c_start(device, I2C_READ); | ||||
|   value = i2c_recv(); | ||||
|   i2c_stop(); | ||||
| 
 | ||||
|   return(value); | ||||
| } | ||||
| 
 | ||||
| void i2c_write_reg(uint8_t device_addr, uint8_t device_reg, uint8_t value) { | ||||
|   i2c_start(device_addr, I2C_WRITE); | ||||
|   i2c_send(device_reg); | ||||
|   i2c_send(value); | ||||
|   i2c_stop(); | ||||
| } | ||||
| 
 | ||||
| void i2c_write_reg_multi(uint8_t device_addr, uint8_t device_reg, size_t len, uint8_t *values) { | ||||
|   i2c_start(device_addr, I2C_WRITE); | ||||
|   i2c_send(device_reg); | ||||
|   for(size_t on_byte = 0; on_byte < len; on_byte++) i2c_send(values[on_byte]); | ||||
|   i2c_stop(); | ||||
| } | ||||
							
								
								
									
										25
									
								
								src/i2c.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								src/i2c.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,25 @@ | ||||
| #ifndef __I2C_H | ||||
| #define __I2C_H | ||||
| 
 | ||||
| #include <stddef.h> | ||||
| #include <stdbool.h> | ||||
| 
 | ||||
| #define I2C_WRITE   0 | ||||
| #define I2C_READ    1 | ||||
| 
 | ||||
| //higher level functions write registers
 | ||||
| //TODO rename if we end up only using for screen
 | ||||
| void i2c_write_reg(uint8_t device_addr, uint8_t device_reg, uint8_t value); | ||||
| void i2c_write_reg_multi(uint8_t device_addr, uint8_t device_reg, size_t len, uint8_t *values); | ||||
| 
 | ||||
| //for drivers with weird i2c processes
 | ||||
| void i2c_send(uint8_t byte); | ||||
| 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_init(); | ||||
| 
 | ||||
| 
 | ||||
| #endif | ||||
							
								
								
									
										57
									
								
								src/main.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								src/main.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,57 @@ | ||||
| #include <stdio.h> | ||||
| #include <avr/io.h> | ||||
| #include <util/twi.h> | ||||
| #include <util/delay.h> | ||||
| 
 | ||||
| #include "i2c.h" | ||||
| #include "ssd1306_display_driver.h" | ||||
| #include "debug.h" //TODO move to timer | ||||
| #include "br24t_eeprom_driver.h" | ||||
| /**
 | ||||
|  * TODO | ||||
|  * make sure desired functions are static (it's just good practice) | ||||
|  * crashing, stack tracing, if that ever matters | ||||
|  * see if stdio is ever needed in non debug builds | ||||
|  * Battery factors to test: | ||||
|  *  OLED clock (command 0xd5) | ||||
|  *  OLED stay on/off | ||||
|  * organize i2c eeprom/timer code | ||||
|  */ | ||||
| 
 | ||||
| 
 | ||||
| #if defined(DEBUG_BUILD) || defined(EEPROM_INSTALL) | ||||
| #include "uart.h" //TODO remove if needed | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| int main() { | ||||
|   //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
 | ||||
|   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(); | ||||
| #endif | ||||
|    | ||||
|   //initilize timer
 | ||||
|   timer_init(); | ||||
| 
 | ||||
| #ifdef EEPROM_INSTALL | ||||
|   flash_eeprom(); | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
|   //initlizes screen registers with good values since we dont have control over reset functionallity
 | ||||
|   screen_init(); | ||||
| 
 | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
							
								
								
									
										48
									
								
								src/makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								src/makefile
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,48 @@ | ||||
| #compile options
 | ||||
| TOOLCHAIN_DIR=/home/indigo/packs/avr8-gnu-toolchain-linux_x86_64 | ||||
| CC=$(TOOLCHAIN_DIR)/bin/avr-gcc | ||||
| LD=$(TOOLCHAIN_DIR)/bin/avr-ld | ||||
| INC=$(TOOLCHAIN_DIR)/avr/include | ||||
| OUT=compiled_payload.elf | ||||
| DEVICE=atmega2560 | ||||
| F_CPU=16000000 | ||||
| 
 | ||||
| DEBUG=1 | ||||
| 
 | ||||
| #avrdude options
 | ||||
| PARTNO=ATmega2560 | ||||
| PORT=/dev/ttyACM1 | ||||
| BAUD=115200 | ||||
| 
 | ||||
| 
 | ||||
| #baudrate
 | ||||
| RUNTIME_BAUDRATE=9600 | ||||
| 
 | ||||
| 
 | ||||
| make: | ||||
| 	#$(CC) -mmcu=$(DEVICE) -I $(INC) -c debug_serial.o -DDEBUG_BUILD=$(DEBUG) -DBAUD=$(RUNTIME_BAUDRATE) -DF_CPU=$(F_CPU) -Wall -O1 debug_serial.c | ||||
| 	#$(CC) -mmcu=$(DEVICE) -I $(INC) -c main.o -DDEBUG_BUILD=$(DEBUG) -DBAUD=$(RUNTIME_BAUDRATE) -DF_CPU=$(F_CPU) -Wall -O1 main.c | ||||
| 	#$(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 | ||||
| 	compiledb make --dry-run > /dev/null | ||||
| 
 | ||||
| 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) | ||||
| 
 | ||||
| 
 | ||||
| install: $(OUT) | ||||
| 	doas avrdude -v -p $(PARTNO) -P $(PORT) -c wiring -b $(BAUD) -D -U flash:w:$(OUT):e | ||||
| 
 | ||||
| screen: | ||||
| 	screen $(PORT) $(RUNTIME_BAUDRATE) | ||||
| 	 | ||||
| clean: | ||||
| 	rm -f *.o *.elf compiled_eeprom  | ||||
| 
 | ||||
							
								
								
									
										35
									
								
								src/paint.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								src/paint.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,35 @@ | ||||
| #include <string.h> | ||||
| #include "ssd1306_display_driver.h" | ||||
| #include "paint.h" | ||||
| #include "br24t_eeprom_driver.h" | ||||
| 
 | ||||
| #define TWOD_INDEX(x, y) ((y * SCREEN_RES_Y) / 8) + x //TODO rename to insinuate /8
 | ||||
|                                                       //
 | ||||
| /** I'm not using the screen's buffer as a standard 2d array, 
 | ||||
|  *  this is because of how pixels are represented in the display's GDRAM. | ||||
|  * | ||||
|  *  While it would be nicer to just resort the array every time it's updated, | ||||
|  *  keeping driver abstractions in it's own file (like we should), | ||||
|  *  this way we don't have to resort every time we redraw. | ||||
|  * | ||||
|  *  Some operations may not need a resort, for example, images/videos optmimized | ||||
|  *  for GDRAM. Doing it in each function helps us prevent unnessesary calculations | ||||
|  *  while doing real time operations like videos. | ||||
|  */ | ||||
| 
 | ||||
| void screen_clear() { memset(&screen_buffer, 0, sizeof(screen_buffer)); } | ||||
| 
 | ||||
| //images are optimized to follow page formatting
 | ||||
| void draw_image(EEPROM_ADDR image) { | ||||
|   for(int on_pix = 0; on_pix < (SCREEN_RES_X * SCREEN_RES_Y) / 8; on_pix++) | ||||
|     screen_buffer[on_pix] = EEPROM_READBYTE(image + on_pix);  | ||||
| } | ||||
| 
 | ||||
| //however here we need to compensate 
 | ||||
| void draw_hline(int pos_y) { | ||||
|   for(int on_pix = 0; on_pix < SCREEN_RES_X; on_pix++) | ||||
|     screen_buffer[((pos_y / 8) * 8) + on_pix] |= (1 << (pos_y % 8)); | ||||
| } | ||||
| 
 | ||||
| void draw_text(char *text, int x, int y, EEPROM_ADDR font) {  | ||||
| } | ||||
							
								
								
									
										13
									
								
								src/paint.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								src/paint.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,13 @@ | ||||
| #ifndef __PAINT_H | ||||
| #define __PAINT_H | ||||
| 
 | ||||
| #include "ssd1306_display_driver.h" | ||||
| #include "br24t_eeprom_driver.h" | ||||
| 
 | ||||
| void screen_clear(); | ||||
| void draw_image(EEPROM_ADDR image); | ||||
| void draw_hline(int pos_y); | ||||
| void draw_text(char *text, int x, int y, EEPROM_ADDR font); | ||||
| 
 | ||||
| #endif | ||||
| 
 | ||||
							
								
								
									
										15
									
								
								src/pcf_clock_driver.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								src/pcf_clock_driver.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,15 @@ | ||||
| #include <i2c.h> | ||||
| #define CLOCK_ADDR 0x51 | ||||
| 
 | ||||
| #ifdef FLASH_EEPROM | ||||
| 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 | ||||
							
								
								
									
										6
									
								
								src/pcf_clock_driver.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								src/pcf_clock_driver.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,6 @@ | ||||
| #include <time.h> | ||||
| 
 | ||||
| void clock_init(); | ||||
| void set_time(time_t time);  | ||||
| time_t get_time(); | ||||
| void set_alarm(time_t time); | ||||
							
								
								
									
										127
									
								
								src/ssd1306_display_driver.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										127
									
								
								src/ssd1306_display_driver.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,127 @@ | ||||
| #include <util/twi.h> | ||||
| #include <stdio.h> | ||||
| #include <util/delay.h> | ||||
| #include <string.h> | ||||
| #include "i2c.h" | ||||
| #include "ssd1306_display_driver.h" | ||||
| 
 | ||||
| 
 | ||||
| #define SSD1306_ADDR      0x3c | ||||
| #define SSD1306_CMD_REG   0x00 | ||||
| #define SSD1306_DATA_REG  0x40 | ||||
| 
 | ||||
| //on the datasheet we have 32 extra rows (4 more pages) of GDRAM that don't fit on the display; we just ignore them everywhere
 | ||||
| #define SCREEN_PAGE_CNT   SCREEN_RES_Y / 8  | ||||
| 
 | ||||
| #define I2C_WRITE   0 | ||||
| #define I2C_READ    1 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| void screen_init() { | ||||
| #ifdef DEBUG_BUILD | ||||
|     printf("initlizing SSD1306 display driver\n"); | ||||
| #endif | ||||
|   //turn on screen while we configure shit, it might look cooler
 | ||||
|   i2c_write_reg(SSD1306_ADDR, SSD1306_CMD_REG, 0xaf);  | ||||
|   | ||||
|   //don't inverse display
 | ||||
|   i2c_write_reg(SSD1306_ADDR, SSD1306_CMD_REG, 0xa6);  | ||||
| 
 | ||||
|   //set contrast to 255 (try chainging?)
 | ||||
|   i2c_write_reg_multi(SSD1306_ADDR, SSD1306_CMD_REG, 2, (uint8_t[]){0x81, 0xff});  | ||||
| 
 | ||||
|   //set lower nibble of column ptr to 0
 | ||||
|   i2c_write_reg(SSD1306_ADDR, SSD1306_CMD_REG, 0x00);  | ||||
|   //set upper nibble of column ptr to 0
 | ||||
|   i2c_write_reg(SSD1306_ADDR, SSD1306_CMD_REG, 0x10);  | ||||
| 
 | ||||
|   //memory mode is paging
 | ||||
|   i2c_write_reg_multi(SSD1306_ADDR, SSD1306_CMD_REG, 2, (uint8_t[]){0x20, 0x02});  | ||||
| 
 | ||||
|   //no vertical shift
 | ||||
|   i2c_write_reg_multi(SSD1306_ADDR, SSD1306_CMD_REG, 2, (uint8_t[]){0xd3, 0x00});  | ||||
| 
 | ||||
|   //page address is at 0
 | ||||
|   i2c_write_reg(SSD1306_ADDR, SSD1306_CMD_REG, 0xb0);  | ||||
| 
 | ||||
|   //ram display start register is at 0
 | ||||
|   i2c_write_reg(SSD1306_ADDR, SSD1306_CMD_REG, 0x40);  | ||||
| 
 | ||||
|   //column address 0 is mapped to seg0
 | ||||
|   i2c_write_reg(SSD1306_ADDR, SSD1306_CMD_REG, 0xa0);  //a1
 | ||||
| 
 | ||||
|   i2c_write_reg(SSD1306_ADDR, SSD1306_CMD_REG, 0xc8);  | ||||
| 
 | ||||
| 
 | ||||
|   //set mux ratio to 32 mux 
 | ||||
|   i2c_write_reg_multi(SSD1306_ADDR, SSD1306_CMD_REG, 2, (uint8_t[]){0xa8, 0x1f});   | ||||
| 
 | ||||
|   //alternative COM hardware mapping (stolen from lib)
 | ||||
|   i2c_write_reg_multi(SSD1306_ADDR, SSD1306_CMD_REG, 2, (uint8_t[]){0xda, 0x02});   | ||||
| 
 | ||||
|   //volage regulator on
 | ||||
|   i2c_write_reg_multi(SSD1306_ADDR, SSD1306_CMD_REG, 2, (uint8_t[]){0x8d, 0x14});   | ||||
| 
 | ||||
| 
 | ||||
|   //set clock divider to zero, and oscillator frequency as high as it goes
 | ||||
|   //Maybe we save battery to run slower?
 | ||||
|   i2c_write_reg_multi(SSD1306_ADDR, SSD1306_CMD_REG, 2, (uint8_t[]){0xd5, 0xf0}); //TODO look
 | ||||
| 
 | ||||
|   //deactivate scroll
 | ||||
|   i2c_write_reg(SSD1306_ADDR, SSD1306_CMD_REG, 0x2e);  | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| void screen_off() { i2c_write_reg(SSD1306_ADDR, SSD1306_CMD_REG, 0xaf); } | ||||
| 
 | ||||
| void screen_on() { i2c_write_reg(SSD1306_ADDR, SSD1306_CMD_REG, 0xae); } | ||||
| 
 | ||||
| void screen_update() { | ||||
|   for(int 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, sizeof(screen_buffer), screen_buffer); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| #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 | ||||
							
								
								
									
										17
									
								
								src/ssd1306_display_driver.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								src/ssd1306_display_driver.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,17 @@ | ||||
| #ifndef __SSD1306_H | ||||
| #define __SSD1306_H | ||||
| 
 | ||||
| #include <stdint.h> | ||||
| 
 | ||||
| #define SCREEN_RES_X        128 | ||||
| #define SCREEN_RES_Y        32 | ||||
| 
 | ||||
| uint8_t screen_buffer[(SCREEN_RES_X * SCREEN_RES_Y) / 8]; | ||||
| 
 | ||||
| void screen_init(); | ||||
| void screen_testdraw(); | ||||
| void screen_off(); | ||||
| void screen_on(); | ||||
| void screen_update(); | ||||
| 
 | ||||
| #endif | ||||
							
								
								
									
										74
									
								
								src/uart.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								src/uart.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,74 @@ | ||||
| #include <avr/io.h> | ||||
| #include <stdio.h> | ||||
| #include <util/setbaud.h> | ||||
| 
 | ||||
| /** UART notes
 | ||||
|  * UCSR0A: | ||||
|  *  0: MP communication mode | ||||
|  *  1: U2X (double trans speed) | ||||
|  *  2: USART parity error | ||||
|  *  3: Data overrun (udr0 not read before next frame) | ||||
|  *  4: Frame error | ||||
|  *  5: Data register empty (new data can be transmitted) | ||||
|  *  6: USART transmit complete | ||||
|  *  7: USART recieve complete | ||||
|  * ____________________________________________________________ | ||||
|  * UCSR0B: | ||||
|  *  0: transmit data bit 8 | ||||
|  *  1: recieve data bit 8 | ||||
|  *  2: USART char size 0 (used with UCSZ01 and UCSZ00 to set data frame size) | ||||
|  *  3: Transmitter enable | ||||
|  *  4: Reciever  enable | ||||
|  *  5: USART data reg empty interrupt table | ||||
|  *  6: TX complete int enable | ||||
|  *  7: RX complete int enable | ||||
|  * ____________________________________________________________ | ||||
|  * UCSR0C: | ||||
|  *  0: Clock polarity (1: falling edge trasmit, recieve rising edge) | ||||
|  *  1: USART char size 0 | ||||
|  *  2: USART char size 1 | ||||
|  *  3: USART stop bit select (1: 1 stop bit, 0: 2 stop bits) | ||||
|  *  4: USART parity mode (00: async, 01: sync) | ||||
|  *  5: USART Parity mode (02: master SPI) | ||||
|  *  6: USART mode select (00: async 01: sync) | ||||
|  *  7: USART mode select (02: master SPI) | ||||
|  * ____________________________________________________________ | ||||
|  * 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);  | ||||
|   UDR0 = byte;  | ||||
| } | ||||
| 
 | ||||
| //TODO replace with static void and just use high level functions?
 | ||||
| uint8_t uart_recvbyte() { | ||||
|   loop_until_bit_is_set(UCSR0A, RXC0); | ||||
|   return UDR0; | ||||
| } | ||||
| 
 | ||||
| void uart_init() { | ||||
|   //set baud rate
 | ||||
|   UBRR0H = UBRRH_VALUE; | ||||
|   UBRR0L = UBRRL_VALUE; | ||||
| 
 | ||||
| 
 | ||||
| /**
 | ||||
| TODO figure out why USE_2X is enable when it shoudn't be | ||||
|    //set baud rate
 | ||||
| #ifdef USE_2X //is set by header
 | ||||
|   UCSR0A |= _BV(U2X0); | ||||
| #else | ||||
|   UCSR0A &= ~(_BV(U2X0)); | ||||
| #endif | ||||
| **/  | ||||
| 
 | ||||
|   UCSR0A &= ~(_BV(U2X0)); | ||||
| 
 | ||||
|   UCSR0C = ((_BV(UCSZ01)) | _BV(UCSZ00)); // set 8 bit char size, yes the '=' is intentional
 | ||||
|   UCSR0B = (_BV(RXEN0) | _BV(TXEN0)); | ||||
| 
 | ||||
| } | ||||
							
								
								
									
										3
									
								
								src/uart.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								src/uart.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | ||||
| void uart_init(); | ||||
| void uart_sendbyte(uint8_t byte); | ||||
| uint8_t uart_recvbyte(); | ||||
							
								
								
									
										50
									
								
								src/write_eeprom.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										50
									
								
								src/write_eeprom.py
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,50 @@ | ||||
| #!/usr/bin/env python3 | ||||
| import serial | ||||
| import argparse | ||||
| import os | ||||
| 
 | ||||
| #we send syn, recv ack | ||||
| SYN_MAGIC = 0xdeafbeef  | ||||
| ACK_MAGIC = 0xf00dd00d | ||||
| 
 | ||||
| EEPROM_PAGESIZE = 64 | ||||
| EEPROM_FILE = "./compiled_eeprom" | ||||
| 
 | ||||
| 
 | ||||
| parser = argparse.ArgumentParser(description="sends binary file over serial so the avr can write it to eeprom") | ||||
| parser.add_argument('port', type=str) | ||||
| parser.add_argument('baud', type=int) | ||||
| args = parser.parse_args() | ||||
| 
 | ||||
| eeprom_file = open("./compiled_eeprom", "rb") | ||||
| eeprom_filesize = os.fstat(eeprom_file.fileno()).st_size | ||||
| 
 | ||||
| s = serial.Serial(args.port, args.baud, timeout = 0) | ||||
| s.write(SYN_MAGIC) | ||||
| 
 | ||||
| def handle_writer_error(): | ||||
|     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 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) | ||||
| 
 | ||||
| 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) | ||||
|     if not write_status == 0: | ||||
|         handle_writer_error(write_status) | ||||
| 
 | ||||
| 
 | ||||
| print("Done writing to EEPROM! You are still alone!") | ||||
							
								
								
									
										8
									
								
								unison_project_config.prf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								unison_project_config.prf
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,8 @@ | ||||
| root=/home/indigo/projects/watch | ||||
| root=ssh://root@bpcspace.com//unison/watch | ||||
| ignore=Name *.out | ||||
| ignore=Name .tmp* | ||||
| ignore=Name compiled_payload.elf | ||||
| ignore=Name compiled_eeprom | ||||
| ignore=Path bin/* | ||||
| auto=true | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Brett Weiland
						Brett Weiland