├── INIT ├── font.bmp └── gfx.bmp ├── Wuff ├── eata.bmp ├── eatb.bmp ├── wca.bmp ├── wcb.bmp ├── sleep.bmp ├── allfours.bmp └── standing.bmp ├── AVR ├── sound.h ├── icon.h ├── progmem.h ├── ir.h ├── progmem.c ├── i2c.h ├── lcd.h ├── sound.c ├── kemochi.aws ├── main.h ├── exee.c ├── icon.c ├── exee.h ├── lcd.c ├── i2c.c ├── default │ ├── Makefile │ └── kemochi.hex ├── ir.c ├── kemochi.aps └── main.c └── README.md /INIT/font.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/furrtek/Kemochi/HEAD/INIT/font.bmp -------------------------------------------------------------------------------- /INIT/gfx.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/furrtek/Kemochi/HEAD/INIT/gfx.bmp -------------------------------------------------------------------------------- /Wuff/eata.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/furrtek/Kemochi/HEAD/Wuff/eata.bmp -------------------------------------------------------------------------------- /Wuff/eatb.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/furrtek/Kemochi/HEAD/Wuff/eatb.bmp -------------------------------------------------------------------------------- /Wuff/wca.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/furrtek/Kemochi/HEAD/Wuff/wca.bmp -------------------------------------------------------------------------------- /Wuff/wcb.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/furrtek/Kemochi/HEAD/Wuff/wcb.bmp -------------------------------------------------------------------------------- /AVR/sound.h: -------------------------------------------------------------------------------- 1 | #include "main.h" 2 | 3 | void selbeep(); 4 | void valbeep(); 5 | -------------------------------------------------------------------------------- /Wuff/sleep.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/furrtek/Kemochi/HEAD/Wuff/sleep.bmp -------------------------------------------------------------------------------- /Wuff/allfours.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/furrtek/Kemochi/HEAD/Wuff/allfours.bmp -------------------------------------------------------------------------------- /Wuff/standing.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/furrtek/Kemochi/HEAD/Wuff/standing.bmp -------------------------------------------------------------------------------- /AVR/icon.h: -------------------------------------------------------------------------------- 1 | #include "main.h" 2 | 3 | void draw_icon(uint8_t n, uint8_t invert); 4 | void draw_icons(); 5 | void refresh_icon(); 6 | -------------------------------------------------------------------------------- /AVR/progmem.h: -------------------------------------------------------------------------------- 1 | #include "main.h" 2 | #include 3 | 4 | void load_struct(uint8_t * dest, uint8_t * src, uint8_t size); 5 | -------------------------------------------------------------------------------- /AVR/ir.h: -------------------------------------------------------------------------------- 1 | #include "main.h" 2 | 3 | #define IR_MAGIC 0xB1 4 | 5 | #define IR_CMD_PING 1 6 | 7 | #define IR_CMD_FLASHPROG 8 8 | #define IR_CMD_EEPROG 9 9 | 10 | #define IR_CMD_SPECID 16 11 | 12 | void ir_decode(); 13 | -------------------------------------------------------------------------------- /AVR/progmem.c: -------------------------------------------------------------------------------- 1 | #include "main.h" 2 | #include "progmem.h" 3 | 4 | void load_struct(uint8_t * dest, uint8_t * src, uint8_t size) { 5 | uint8_t b; 6 | 7 | for (b = 0; b < size; b++) 8 | *dest++ = pgm_read_byte(src++); 9 | } 10 | -------------------------------------------------------------------------------- /AVR/i2c.h: -------------------------------------------------------------------------------- 1 | #include "main.h" 2 | 3 | void i2c_io_set_sda(uint8_t hi); 4 | void i2c_io_set_scl(uint8_t hi); 5 | void i2c_start(); 6 | void i2c_stop(); 7 | uint8_t i2c_write(uint8_t byte); 8 | uint8_t i2c_read(); 9 | void i2c_readack(); 10 | void i2c_noreadack(); 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Kemochi 2 | WIP customizable Tamagotchi-type device aimed towards the furry (Kemono) community. 3 | 4 | * Cute pixels 5 | * 8kB firmware ! 6 | * IR communication 7 | * 0% Arduino poop 8 | 9 | ATTiny84 + 24xx128 + 3 buttons + 5110 LCD + Piezzo speaker + TSOP4838 + 940nm IR LED + Battery 10 | -------------------------------------------------------------------------------- /AVR/lcd.h: -------------------------------------------------------------------------------- 1 | #include "main.h" 2 | 3 | void lcd_write(uint8_t b); 4 | void lcd_clear(uint8_t start, uint8_t count); 5 | void lcd_txt(char * txt, uint8_t maxlen); 6 | void lcd_xy(uint8_t x, uint8_t y); 7 | void lcd_draw(uint8_t x, uint8_t y, uint8_t s, uint8_t e, uint8_t inv, uint8_t flip); 8 | void draw_fur(uint8_t frame, uint8_t flip); 9 | -------------------------------------------------------------------------------- /AVR/sound.c: -------------------------------------------------------------------------------- 1 | #include "main.h" 2 | #include "sound.h" 3 | 4 | void selbeep() { 5 | uint8_t c; 6 | 7 | PCMSK1 = 0b00000010; 8 | DDRB |= 1; 9 | for (c = 0; c < 64; c++) { 10 | PORTB ^= 1; 11 | _delay_us(400); 12 | } 13 | DDRB &= ~1; 14 | PORTB |= 1; 15 | } 16 | 17 | void valbeep() { 18 | uint8_t c; 19 | 20 | PCMSK1 = 0b00000010; 21 | DDRB |= 1; 22 | for (c=0;c<64;c++) { 23 | PORTB ^= 1; 24 | _delay_us(200); 25 | } 26 | DDRB &= ~1; 27 | PORTB |= 1; 28 | } 29 | -------------------------------------------------------------------------------- /AVR/kemochi.aws: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /AVR/main.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define IR_LED PA0 6 | 7 | #define LCD_CE PA2 8 | #define LCD_DC PA3 9 | #define LCD_CLK PA4 10 | #define LCD_DIN PA5 11 | #define LCD_RST PA6 12 | 13 | #define BTN_A PB0 14 | #define BTN_B PB1 15 | #define BTN_C PA1 16 | 17 | #define I2C_SDA PA7 18 | #define I2C_SCL PA4 19 | 20 | // IR stuff 21 | 22 | #define IR_RX_IDLE 0 23 | #define IR_RX_RECV 1 24 | #define IR_RX_DECODE 2 25 | 26 | uint8_t volatile ir_rx_buf[32]; 27 | 28 | extern uint8_t volatile icon_sel, prev_icon; 29 | -------------------------------------------------------------------------------- /AVR/exee.c: -------------------------------------------------------------------------------- 1 | #include "main.h" 2 | #include "i2c.h" 3 | #include "exee.h" 4 | 5 | void exee_set_address(uint16_t addr) { 6 | i2c_start(); 7 | i2c_write(EE_WRITE); 8 | i2c_write(addr >> 8); 9 | i2c_write(addr & 0xFF); 10 | } 11 | 12 | uint8_t exee_read_byte(uint16_t addr) { 13 | uint8_t v; 14 | 15 | exee_set_address(addr); 16 | i2c_start(); 17 | i2c_write(EE_READ); 18 | v = i2c_read(); 19 | i2c_noreadack(); 20 | 21 | return v; 22 | } 23 | 24 | void exee_read_page(uint16_t page) { 25 | uint8_t c; 26 | 27 | exee_set_address(page << 6); 28 | i2c_start(); 29 | i2c_write(EE_READ); 30 | 31 | for (c = 0; c < 63; c++) { 32 | exee_buf[c] = i2c_read(); 33 | i2c_readack(); 34 | } 35 | i2c_noreadack(); 36 | 37 | exee_last_page = page; 38 | } 39 | -------------------------------------------------------------------------------- /AVR/icon.c: -------------------------------------------------------------------------------- 1 | #include "icon.h" 2 | #include "lcd.h" 3 | #include "progmem.h" 4 | #include "exee.h" 5 | 6 | typedef struct { 7 | uint8_t x; 8 | uint8_t page; 9 | uint8_t start; 10 | } icon_def_t; 11 | 12 | const icon_def_t PROGMEM icon_defs[10] = { 13 | { 0+7, EEP_ICONS_A, 0 }, 14 | { 15+7, EEP_ICONS_A, 9 }, 15 | { 30+7, EEP_ICONS_A, 18 }, 16 | { 45+7, EEP_ICONS_A, 27 }, 17 | { 60+7, EEP_ICONS_A, 36 }, 18 | { 0+7, EEP_ICONS_A, 45 }, 19 | { 15+7, EEP_ICONS_A, 54 }, 20 | { 30+7, EEP_ICONS_B, 0 }, 21 | { 45+7, EEP_ICONS_B, 9 }, 22 | { 60+7, EEP_ICONS_B, 18 } 23 | }; 24 | 25 | void draw_icon(uint8_t n, uint8_t invert) { 26 | icon_def_t icon_def; 27 | uint8_t page; 28 | 29 | exee_last_page = 0xFF; 30 | 31 | load_struct((uint8_t*)&icon_def, (uint8_t*)&icon_defs[n], sizeof(icon_def_t)); 32 | page = icon_def.page; 33 | if (page != exee_last_page) 34 | exee_read_page(page); 35 | lcd_draw(icon_def.x, (n < 5) ? 0 : 5, icon_def.start, 9, invert, 0); 36 | } 37 | 38 | void draw_icons() { 39 | uint8_t i; 40 | 41 | // This is SLOW ! 42 | for (i = 0; i < 10; i++) 43 | draw_icon(i, (icon_sel == i) ? 0xFF : 0x00); 44 | } 45 | 46 | void refresh_icon() { 47 | // Redraw previous icon 48 | draw_icon(prev_icon, 0x00); 49 | 50 | // Redraw current icon 51 | draw_icon(icon_sel, 0xFF); 52 | } 53 | -------------------------------------------------------------------------------- /AVR/exee.h: -------------------------------------------------------------------------------- 1 | #include "main.h" 2 | 3 | #define EE_WRITE 0xA0 4 | #define EE_READ 0xA1 5 | 6 | 7 | #define EEP_ICONS_A 0 8 | #define EEP_ICONS_B 1 9 | 10 | #define EEP_PINFO_A 8 11 | #define EEP_PINFO_B 9 12 | 13 | uint8_t exee_buf[64]; 14 | uint8_t exee_last_page; 15 | 16 | typedef struct { 17 | char name[12]; 18 | char species[12]; 19 | char country[12]; 20 | char speaksA[14]; 21 | char speaksB[14]; 22 | } player_info_A; 23 | 24 | typedef struct { 25 | char likesA[12]; 26 | char likesB[12]; 27 | char likesC[12]; 28 | char birthyear[4]; 29 | char padding[24]; 30 | } player_info_B; 31 | 32 | // EEPROM layout: 33 | 34 | //Page 00: 7 icons 35 | //Page 01: 3 icons 36 | //Page 02: Alphabet 0 37 | //Page 03: Alphabet 1 38 | //Page 04: Alphabet 2 39 | //Page 05: Alphabet 3 40 | 41 | //Page 08: Player info A 42 | // 00: Name (12) NAME: 43 | // 0C: Specie (12) IS A: 44 | // 18: Country (12) FROM: 45 | // 24: Spoken A (14) SPEAKS: 46 | // 32: Spoken B (14) 47 | 48 | //Page 09: Player info B 49 | // 00: Spoken C (14) 50 | // 0E: Likes A (12) LIKES: 51 | // 1A: Likes B (12) 52 | // 26: Likes C (12) 53 | // 32: Year of birth (4) 54 | 55 | //Page 0A: Player status 56 | // 00: Hunger 57 | // 01: Sleepyness 58 | // 02: Boredom 59 | // 03: Discipline 60 | // 04: Happyness 61 | 62 | //Page 10-11: STANDING 63 | //Page 12-13: ON ALL FOURS 64 | //Page 14-15: SLEEPING 65 | //Page 16-17: WCA 66 | //Page 18-19: WCB 67 | //Page 1A-1B: EATA 68 | //Page 1C-1D: EATB 69 | 70 | //Page F0: Sound effects 71 | 72 | void exee_set_address(uint16_t addr); 73 | uint8_t exee_read_byte(uint16_t addr); 74 | void exee_read_page(uint16_t addr); 75 | -------------------------------------------------------------------------------- /AVR/lcd.c: -------------------------------------------------------------------------------- 1 | #include "main.h" 2 | #include "lcd.h" 3 | #include "exee.h" 4 | 5 | extern uint8_t xpos; 6 | 7 | void lcd_write(uint8_t v) { 8 | uint8_t bit; 9 | 10 | PORTA &= ~_BV(LCD_CE); 11 | for (bit = 0; bit < 8; bit++) { 12 | if ((v << bit) & 0x80) 13 | PORTA |= _BV(LCD_DIN); 14 | else 15 | PORTA &= ~_BV(LCD_DIN); 16 | _delay_us(1); 17 | PORTA |= _BV(LCD_CLK); 18 | _delay_us(1); 19 | PORTA &= ~_BV(LCD_CLK); 20 | } 21 | _delay_us(1); 22 | PORTA |= _BV(LCD_CE); 23 | _delay_us(1); 24 | } 25 | 26 | void lcd_clear(uint8_t start, uint8_t count) { 27 | uint8_t c, s; 28 | 29 | lcd_xy(0, start); 30 | PORTA |= _BV(LCD_DC); 31 | for (s = 0; s < count; s++) 32 | for (c = 0; c < 84; c++) 33 | lcd_write(0); 34 | } 35 | 36 | void lcd_txt(char * txt, uint8_t maxlen) { 37 | uint8_t c, ch, i = 0; 38 | 39 | while ((ch = (*txt++)) && (i < maxlen)) { 40 | if (ch == 32) { 41 | // Space 42 | for (c = 0; c < 5; c++) 43 | lcd_write(0); 44 | } else { 45 | // Remap 46 | if (ch == 33) { 47 | ch = 11 * 5; 48 | } else if (ch == 63) { 49 | ch = 12 * 5; 50 | } else { 51 | ch = (ch - 0x30) * 5; 52 | } 53 | // Draw 54 | for (c = 0; c < 5; c++) 55 | lcd_write(exee_read_byte(128 + ch + c)); 56 | } 57 | lcd_write(0); // Remove ? 58 | i++; 59 | } 60 | } 61 | 62 | void lcd_xy(uint8_t x, uint8_t y) { 63 | PORTA &= ~_BV(LCD_DC); 64 | lcd_write(0x80 | x); 65 | lcd_write(0x40 | y); 66 | } 67 | 68 | void lcd_draw(uint8_t x, uint8_t y, uint8_t s, uint8_t e, uint8_t inv, uint8_t flip) { 69 | uint8_t b; 70 | 71 | lcd_xy(x, y); 72 | 73 | PORTA |= _BV(LCD_DC); 74 | if (!flip) { 75 | for (b = s; b < e + s; b++) 76 | lcd_write(exee_buf[b] ^ inv); 77 | } else { 78 | for (b = e + s; b > s; b--) 79 | lcd_write(exee_buf[b] ^ inv); 80 | } 81 | } 82 | 83 | void draw_fur(uint8_t frame, uint8_t flip) { 84 | exee_read_page(frame); 85 | lcd_draw(xpos, 1, 0, 32, 0, flip); // Stripes 1 to 4 (32*32 pixels) 86 | lcd_draw(xpos, 2, 32, 32, 0, flip); 87 | exee_read_page(frame + 1); 88 | lcd_draw(xpos, 3, 0, 32, 0, flip); 89 | lcd_draw(xpos, 4, 32, 32, 0, flip); 90 | } 91 | -------------------------------------------------------------------------------- /AVR/i2c.c: -------------------------------------------------------------------------------- 1 | #include "main.h" 2 | #include "i2c.h" 3 | 4 | void i2c_set_sda(uint8_t v) { 5 | if (v) 6 | DDRA &= ~_BV(I2C_SDA); 7 | else 8 | DDRA |= _BV(I2C_SDA); 9 | 10 | PORTA &= ~_BV(I2C_SDA); 11 | } 12 | 13 | void i2c_set_scl(uint8_t v) { 14 | if (v) 15 | PORTA |= _BV(I2C_SCL); 16 | else 17 | PORTA &= ~_BV(I2C_SCL); 18 | } 19 | 20 | void i2c_start() { 21 | i2c_set_scl(1); 22 | _delay_us(2); 23 | i2c_set_sda(0); 24 | _delay_us(2); 25 | i2c_set_scl(0); 26 | _delay_us(10); 27 | } 28 | 29 | void i2c_stop() { 30 | _delay_us(2); 31 | i2c_set_scl(0); 32 | _delay_us(2); 33 | i2c_set_sda(0); 34 | _delay_us(2); 35 | i2c_set_scl(1); 36 | _delay_us(2); 37 | i2c_set_sda(1); 38 | } 39 | 40 | uint8_t i2c_write(uint8_t byte) { 41 | uint8_t ack, bit; 42 | 43 | for (bit = 0; bit < 8; bit++) { 44 | if ((byte << bit) & 0x80) 45 | i2c_set_sda(1); 46 | else 47 | i2c_set_sda(0); 48 | _delay_us(2); 49 | i2c_set_scl(1); 50 | _delay_us(2); 51 | i2c_set_scl(0); 52 | } 53 | i2c_set_sda(1); 54 | _delay_us(5); 55 | 56 | i2c_set_scl(1); 57 | _delay_us(2); 58 | ack = PINA & I2C_SDA; // >> I2C_SDA; 59 | _delay_us(2); 60 | i2c_set_scl(0); 61 | _delay_us(2); 62 | 63 | return ack; 64 | } 65 | 66 | uint8_t i2c_read() { 67 | uint8_t byte = 0x00, bit; 68 | 69 | i2c_set_sda(1); 70 | 71 | for (bit = 0; bit < 8; bit++) { 72 | i2c_set_scl(0); 73 | _delay_us(2); 74 | i2c_set_scl(1); 75 | _delay_us(2); 76 | 77 | byte <<= 1; 78 | if (PINA & _BV(I2C_SDA)) 79 | byte |= 1; 80 | } 81 | 82 | _delay_us(1); 83 | i2c_set_scl(0); 84 | 85 | return byte; 86 | } 87 | 88 | void i2c_readack() { 89 | i2c_set_scl(0); 90 | _delay_us(2); 91 | i2c_set_sda(0); 92 | _delay_us(2); 93 | i2c_set_scl(1); 94 | _delay_us(2); 95 | i2c_set_scl(0); 96 | _delay_us(2); 97 | i2c_set_sda(1); 98 | _delay_us(2); 99 | } 100 | 101 | void i2c_noreadack() { 102 | i2c_set_scl(0); 103 | _delay_us(2); 104 | i2c_set_sda(1); 105 | _delay_us(2); 106 | i2c_set_scl(1); 107 | _delay_us(2); 108 | i2c_set_scl(0); 109 | _delay_us(5); 110 | } 111 | -------------------------------------------------------------------------------- /AVR/default/Makefile: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Makefile for the project tamagochi 3 | ############################################################################### 4 | 5 | ## General Flags 6 | PROJECT = tamagochi 7 | MCU = attiny44 8 | TARGET = kemochi.elf 9 | CC = avr-gcc 10 | 11 | CPP = avr-g++ 12 | 13 | ## Options common to compile, link and assembly rules 14 | COMMON = -mmcu=$(MCU) 15 | 16 | ## Compile options common for all C compilation units. 17 | CFLAGS = $(COMMON) 18 | CFLAGS += -Wall -gdwarf-2 -std=gnu99 -DF_CPU=1000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums 19 | CFLAGS += -MD -MP -MT $(*F).o -MF dep/$(@F).d 20 | 21 | ## Assembly specific flags 22 | ASMFLAGS = $(COMMON) 23 | ASMFLAGS += $(CFLAGS) 24 | ASMFLAGS += -x assembler-with-cpp -Wa,-gdwarf2 25 | 26 | ## Linker flags 27 | LDFLAGS = $(COMMON) 28 | LDFLAGS += -Wl,-Map=kemochi.map 29 | 30 | 31 | ## Intel Hex file production flags 32 | HEX_FLASH_FLAGS = -R .eeprom -R .fuse -R .lock -R .signature 33 | 34 | HEX_EEPROM_FLAGS = -j .eeprom 35 | HEX_EEPROM_FLAGS += --set-section-flags=.eeprom="alloc,load" 36 | HEX_EEPROM_FLAGS += --change-section-lma .eeprom=0 --no-change-warnings 37 | 38 | 39 | ## Objects that must be built in order to link 40 | OBJECTS = lcd.o exee.o main.o i2c.o sound.o ir.o icon.o progmem.o 41 | 42 | ## Objects explicitly added by the user 43 | LINKONLYOBJECTS = 44 | 45 | ## Build 46 | all: $(TARGET) kemochi.hex kemochi.eep kemochi.lss size 47 | 48 | ## Compile 49 | lcd.o: ../lcd.c 50 | $(CC) $(INCLUDES) $(CFLAGS) -c $< 51 | 52 | exee.o: ../exee.c 53 | $(CC) $(INCLUDES) $(CFLAGS) -c $< 54 | 55 | main.o: ../main.c 56 | $(CC) $(INCLUDES) $(CFLAGS) -c $< 57 | 58 | i2c.o: ../i2c.c 59 | $(CC) $(INCLUDES) $(CFLAGS) -c $< 60 | 61 | sound.o: ../sound.c 62 | $(CC) $(INCLUDES) $(CFLAGS) -c $< 63 | 64 | ir.o: ../ir.c 65 | $(CC) $(INCLUDES) $(CFLAGS) -c $< 66 | 67 | icon.o: ../icon.c 68 | $(CC) $(INCLUDES) $(CFLAGS) -c $< 69 | 70 | progmem.o: ../progmem.c 71 | $(CC) $(INCLUDES) $(CFLAGS) -c $< 72 | 73 | ##Link 74 | $(TARGET): $(OBJECTS) 75 | $(CC) $(LDFLAGS) $(OBJECTS) $(LINKONLYOBJECTS) $(LIBDIRS) $(LIBS) -o $(TARGET) 76 | 77 | %.hex: $(TARGET) 78 | avr-objcopy -O ihex $(HEX_FLASH_FLAGS) $< $@ 79 | 80 | %.eep: $(TARGET) 81 | -avr-objcopy $(HEX_EEPROM_FLAGS) -O ihex $< $@ || exit 0 82 | 83 | %.lss: $(TARGET) 84 | avr-objdump -h -S $< > $@ 85 | 86 | size: ${TARGET} 87 | @echo 88 | @avr-size -C --mcu=${MCU} ${TARGET} 89 | 90 | ## Clean target 91 | .PHONY: clean 92 | clean: 93 | -rm -rf $(OBJECTS) kemochi.elf dep/* kemochi.hex kemochi.eep kemochi.lss kemochi.map 94 | 95 | 96 | ## Other dependencies 97 | -include $(shell mkdir dep 2>/dev/null) $(wildcard dep/*) 98 | 99 | -------------------------------------------------------------------------------- /AVR/ir.c: -------------------------------------------------------------------------------- 1 | #include "main.h" 2 | #include "exee.h" 3 | #include "i2c.h" 4 | #include "lcd.h" 5 | #include "ir.h" 6 | 7 | // IR frame format: 8 | // 10110001 sccccccc 000lllll d... kkkkkkkk 9 | // 10110001 = 0xB1 = magic byte 10 | // s = source (0=programmer, 1=other kemochi) 11 | // c = command 12 | // l = length - 1 (max 31) 13 | // k = checksum (start=0xAA) 14 | 15 | void ir_pulse() { 16 | uint8_t c; 17 | 18 | // Shitty ~38kHz software generator 19 | // Todo: put IR LED on OC0B (ADC + 38kHz gen) ? 20 | for (c = 0; c < 20; c++) { 21 | PORTA ^= _BV(IR_LED); 22 | _delay_us(13); 23 | } 24 | } 25 | 26 | void ir_send_byte(uint8_t byte) { 27 | uint8_t c, w; 28 | 29 | for (c = 0; c < 4; c++) { 30 | ir_pulse(); 31 | for (w = 0; w < (byte & 3); w++) 32 | _delay_ms(4); 33 | byte >>= 2; 34 | } 35 | } 36 | 37 | void ir_frame(uint8_t cmd, uint8_t * data, uint8_t len) { 38 | uint8_t c, checksum; 39 | 40 | checksum = 0xAA + len + cmd; 41 | for (c = 0; c < len; c++) 42 | checksum += data[c]; 43 | 44 | ir_send_byte(IR_MAGIC); 45 | ir_send_byte(cmd); 46 | ir_send_byte(len); 47 | for (c = 0; c < len; c++) 48 | ir_send_byte(data[c]); 49 | ir_send_byte(checksum); 50 | ir_pulse(); // Last pulse 51 | } 52 | 53 | void ir_send_specid() { 54 | player_info_A * p_info = (player_info_A*)exee_buf; 55 | 56 | exee_read_page(EEP_PINFO_A); 57 | ir_frame(IR_CMD_SPECID, (uint8_t*)&p_info->name[0], 12); 58 | } 59 | 60 | void ir_decode() { 61 | uint8_t c, checksum, cmd, len; 62 | player_info_A * p_info = (player_info_A*)exee_buf; 63 | 64 | if (ir_rx_buf[0] != IR_MAGIC) 65 | return; // Invalid magic byte 66 | 67 | checksum = 0xAA; 68 | for (c = 1; c <= ir_rx_buf[2]; c++) 69 | checksum += ir_rx_buf[c]; 70 | 71 | if (checksum != ir_rx_buf[c]) // + 1 ? 72 | return; // Invalid checksum 73 | 74 | // Beep 75 | PCMSK1 = 0b00000010; 76 | DDRB |= _BV(BTN_A); 77 | for (c = 0; c < 32; c++) { 78 | PORTB ^= _BV(BTN_A); 79 | _delay_us(200); 80 | } 81 | DDRB &= ~_BV(BTN_A); 82 | PORTB |= 1; 83 | PCMSK1 = 0b00000011; 84 | 85 | cmd = ir_rx_buf[1]; 86 | len = ir_rx_buf[2]; 87 | 88 | if (cmd == IR_CMD_PING) { 89 | // Todo 90 | 91 | } else if (cmd == IR_CMD_FLASHPROG) { 92 | // Todo 93 | 94 | } else if (cmd == IR_CMD_EEPROG) { 95 | exee_set_address((ir_rx_buf[3] << 8) | ir_rx_buf[4]); 96 | i2c_write(EE_WRITE); 97 | for (c = 0; c < len - 2; c++) 98 | i2c_write(ir_rx_buf[c + 5]); 99 | i2c_stop(); 100 | } else if (cmd == IR_CMD_SPECID) { 101 | // Compare species 102 | exee_read_page(EEP_PINFO_A); 103 | for (c = 0; c < 12; c++) 104 | if (p_info->name[c] != ir_rx_buf[c + 3]) 105 | break; 106 | 107 | if (c == 12) { 108 | // Same ! 109 | lcd_clear(0, 6); 110 | 111 | lcd_xy(6, 2); 112 | lcd_txt("HEY! ANOTHER", 16); 113 | } else { 114 | // Different 115 | lcd_clear(0, 6); 116 | 117 | lcd_xy(6, 2); 118 | lcd_txt("RMT IS A", 16); 119 | } 120 | lcd_xy(12, 3); 121 | lcd_txt(&p_info->name[0], 12); 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /AVR/kemochi.aps: -------------------------------------------------------------------------------- 1 | tamagochi15-Jul-2015 02:02:2217-Apr-2017 21:36:06241015-Jul-2015 02:02:2244, 18, 0, 670AVR GCCdefault\kemochi.elfC:\Users\furrtek\Documents\Electro\Kemochi\trunk\AVR\AVR SimulatorATtiny44.xmlfalseR00R01R02R03R04R05R06R07R08R09R10R11R12R13R14R15R16R17R18R19R20R21R22R23R24R25R26R27R28R29R30R31Auto000lcd.cexee.cmain.ci2c.csound.cir.cicon.cprogmem.cexee.hlcd.hi2c.hmain.hsound.hir.hicon.hprogmem.hdefaultNOattiny44111kemochi.elfdefault\0-Wall -gdwarf-2 -std=gnu99 -DF_CPU=1000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enumsdefault1D:\WinAVR-20100110\bin\avr-gcc.exeD:\WinAVR-20100110\utils\bin\make.exeC:\Users\furrtek\Documents\Electro\Kemochi\trunk\AVR\exee.hC:\Users\furrtek\Documents\Electro\Kemochi\trunk\AVR\lcd.hC:\Users\furrtek\Documents\Electro\Kemochi\trunk\AVR\i2c.hC:\Users\furrtek\Documents\Electro\Kemochi\trunk\AVR\main.hC:\Users\furrtek\Documents\Electro\Kemochi\trunk\AVR\sound.hC:\Users\furrtek\Documents\Electro\Kemochi\trunk\AVR\ir.hC:\Users\furrtek\Documents\Electro\Kemochi\trunk\AVR\icon.hC:\Users\furrtek\Documents\Electro\Kemochi\trunk\AVR\progmem.hC:\Users\furrtek\Documents\Electro\Kemochi\trunk\AVR\lcd.cC:\Users\furrtek\Documents\Electro\Kemochi\trunk\AVR\exee.cC:\Users\furrtek\Documents\Electro\Kemochi\trunk\AVR\main.cC:\Users\furrtek\Documents\Electro\Kemochi\trunk\AVR\i2c.cC:\Users\furrtek\Documents\Electro\Kemochi\trunk\AVR\sound.cC:\Users\furrtek\Documents\Electro\Kemochi\trunk\AVR\ir.cC:\Users\furrtek\Documents\Electro\Kemochi\trunk\AVR\icon.cC:\Users\furrtek\Documents\Electro\Kemochi\trunk\AVR\progmem.c00000main.c100001icon.c1 2 | -------------------------------------------------------------------------------- /AVR/main.c: -------------------------------------------------------------------------------- 1 | // Kemochi fw 0.1 2 | // furrtek 2015~2017 3 | // ATTiny44 1MHz RC 4 | 5 | // Todo: Use an LCD line with LCD /CE not asserted for buzzer, not a button line ! 6 | 7 | // 79.2% 8 | // 78.1% 9 | // 74.8% 10 | // 73.8% 11 | // 73.7% 12 | 13 | #define P_STANDING 0x10 14 | #define P_FOURS 0x12 15 | #define P_SLEEPING 0x14 16 | #define P_WC_A 0x16 17 | #define P_WC_B 0x18 18 | #define P_EAT 0x1A 19 | 20 | #include "main.h" 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include "i2c.h" 27 | #include "exee.h" 28 | #include "sound.h" 29 | #include "lcd.h" 30 | #include "progmem.h" 31 | #include "icon.h" 32 | #include "ir.h" 33 | 34 | #define AWAKE 0 35 | #define SLEEP 1 36 | #define FALLING_ASLEEP 2 37 | #define WAKING_UP 3 38 | 39 | uint8_t get_adc() { 40 | uint8_t value; 41 | 42 | ADCSRA |= (1 << ADSC); 43 | while (ADCSRA & (1 << ADSC)); 44 | value = ADCH; // Discard 45 | 46 | ADCSRA |= (1 << ADSC); 47 | while (ADCSRA & (1 << ADSC)); 48 | 49 | return ADCH; 50 | } 51 | 52 | uint8_t volatile ir_rx_dibits, ir_rx_sr, ir_rx_state, ir_rx_index, state, anim_timer, tick = 0; 53 | uint16_t volatile stat_sleepy = 0; 54 | uint16_t volatile xpos = 26, xdir; 55 | uint8_t volatile icon_sel = 0, prev_icon, need_refresh = 0; 56 | 57 | const uint8_t PROGMEM walk_cycle[4] = { 58 | P_STANDING, P_WC_A, P_STANDING, P_WC_B 59 | }; 60 | 61 | // Button press 62 | ISR(PCINT0_vect) { 63 | 64 | _delay_ms(10); // Debounce 65 | 66 | // Left (PCINT8) 67 | if (!(PINB & _BV(BTN_A))) { 68 | prev_icon = icon_sel; 69 | if (icon_sel == 0) 70 | icon_sel = 9; 71 | else 72 | icon_sel--; 73 | need_refresh = 1; 74 | valbeep(); 75 | } 76 | 77 | // Right (PCINT1) 78 | if (!(PINA & _BV(BTN_C))) { 79 | prev_icon = icon_sel; 80 | if (icon_sel == 9) 81 | icon_sel = 0; 82 | else 83 | icon_sel++; 84 | need_refresh = 1; 85 | valbeep(); 86 | } 87 | 88 | // Select (PCINT9) 89 | if (!(PINB & _BV(BTN_B))) { 90 | selbeep(); 91 | } 92 | 93 | _delay_ms(10); // Debounce 94 | 95 | PCMSK1 = 0b00000011; 96 | } 97 | 98 | ISR(PCINT1_vect, ISR_ALIASOF(PCINT0_vect)); 99 | 100 | // Animation tick 101 | ISR(TIM0_OVF_vect) { 102 | tick = 1; 103 | } 104 | 105 | // IR timeout 106 | ISR(TIM1_OVF_vect) { 107 | if (ir_rx_index) 108 | ir_rx_state = IR_RX_DECODE; 109 | 110 | TCCR1B = 0b00000000; // Stop timer 111 | } 112 | 113 | // IR receive 114 | ISR(INT0_vect) { 115 | uint16_t t; 116 | 117 | t = TCNT1; 118 | TCNT1 = 0; 119 | 120 | if (ir_rx_state == IR_RX_IDLE) { 121 | ir_rx_index = 0; // Init 122 | ir_rx_dibits = 0; 123 | ir_rx_state = IR_RX_IDLE; 124 | 125 | TCCR1B = 0b00000001; // Start timer 126 | ir_rx_state = IR_RX_RECV; 127 | } else if (ir_rx_state == IR_RX_RECV) { 128 | // New dibit 129 | 130 | ir_rx_sr >>= 2; 131 | 132 | if ((t >= 800) && (t < 1600)) 133 | ir_rx_sr |= 0x00; 134 | else if ((t >= 1600) && (t < 2400)) 135 | ir_rx_sr |= 0x40; 136 | else if ((t >= 2400) && (t < 3200)) 137 | ir_rx_sr |= 0x80; 138 | else // if ((v >= 3200) && (v < 4000)) 139 | ir_rx_sr |= 0xC0; 140 | 141 | if (ir_rx_dibits == 3) { 142 | ir_rx_buf[ir_rx_index & 0x1F] = ir_rx_sr; 143 | ir_rx_index++; 144 | ir_rx_dibits = 0; 145 | } else { 146 | ir_rx_dibits++; 147 | } 148 | } 149 | } 150 | 151 | void wake_up() { 152 | lcd_clear(1, 4); 153 | draw_fur(P_FOURS, xdir); 154 | anim_timer = 10; 155 | state = WAKING_UP; 156 | valbeep(); 157 | } 158 | 159 | int main(void) { 160 | uint8_t anim = 0, light, frame; 161 | 162 | // Disable watchdog 163 | WDTCSR |= (1<> 1) * 9; 242 | exee_read_page(1); 243 | if (xpos >= 10) 244 | lcd_draw(xpos - 10, 2, frame, 9, 0, 0); 245 | else 246 | lcd_draw(xpos + 33, 2, frame, 9, 0, 0); 247 | } 248 | if (stat_sleepy) 249 | stat_sleepy--; // Decrease sleepiness 250 | else 251 | wake_up(); // Wake up if not tired anymore 252 | } 253 | 254 | // Awake, walking 255 | if ((state == AWAKE) && (!(anim & 3))) { 256 | frame = (anim >> 2) & 3; 257 | 258 | draw_fur(pgm_read_byte(&walk_cycle[frame]), xdir); 259 | 260 | if (!xdir) { 261 | if (xpos >= 2) { 262 | xpos -= 2; 263 | } else { 264 | xdir = 1; 265 | } 266 | } else { 267 | if (xpos < 51) { 268 | xpos += 2; 269 | } else { 270 | xdir = 0; 271 | } 272 | } 273 | 274 | if (stat_sleepy != 255) 275 | stat_sleepy++; // Increase sleepiness 276 | } 277 | 278 | // Wake up because of light if not too sleepy 279 | if (((state == SLEEP) || (state == FALLING_ASLEEP)) && (light > 90)) { 280 | if (stat_sleepy < 64) 281 | wake_up(); 282 | } 283 | 284 | // Fall asleep because of dark if sleepy enough 285 | if ((state == AWAKE) && (light < 80) && (stat_sleepy > 128)) { 286 | draw_fur(P_FOURS, xdir); 287 | anim_timer = 10; 288 | state = FALLING_ASLEEP; 289 | valbeep(); 290 | } 291 | 292 | if (anim_timer) 293 | anim_timer--; 294 | else { 295 | if (state == FALLING_ASLEEP) { 296 | draw_fur(P_SLEEPING, xdir); 297 | selbeep(); 298 | state = SLEEP; 299 | } else if (state == WAKING_UP) { 300 | draw_fur(P_STANDING, xdir); 301 | selbeep(); 302 | _delay_ms(80); 303 | valbeep(); 304 | _delay_ms(80); 305 | state = AWAKE; 306 | } 307 | } 308 | 309 | 310 | anim++; 311 | } 312 | 313 | return 0; 314 | } 315 | -------------------------------------------------------------------------------- /AVR/default/kemochi.hex: -------------------------------------------------------------------------------- 1 | :1000000021C091C171C370C338C037C036C035C07C 2 | :1000100076C133C032C064C130C02FC02EC02DC0E5 3 | :100020002CC0101610180700001600092500123405 4 | :10003000001B43002407002D160036250100340163 5 | :100040000943011211241FBECFE5D1E0DEBFCDBFB1 6 | :1000500010E0A0E6B0E0E0E2FCE002C005900D9206 7 | :10006000A837B107D9F710E0A8E7B0E001C01D92AA 8 | :10007000A73EB107E1F7DAD1D1C5C2CFDA9820E0C7 9 | :1000800030E0482F50E061E0CA01022E02C0880F24 10 | :10009000991F0A94E2F787FF02C0DD9A01C0DD983C 11 | :1000A00091E0862F8A95F1F7DC9A862F8A95F1F7F1 12 | :1000B000DC982F5F3F4F2830310531F7892F8A9523 13 | :1000C000F1F7DA9A892F8A95F1F708951F93162F81 14 | :1000D000DB988068D3DF812F8064D0DF1F91089583 15 | :1000E000FF920F931F93982FF62E80E0692FEEDF7B 16 | :1000F000DB9A00E007C010E080E0C0DF1F5F14352E 17 | :10010000D9F70F5F0F15B8F31F910F91FF90089566 18 | :10011000EF92FF920F931F93CF93DF93142FF22E42 19 | :10012000D5DFDB9AEE2091F4E12EC12FD0E0CF0D88 20 | :10013000D11D06C0E256FF4F808180279FDFE394E8 21 | :10014000EE2DF0E0EC17FD07ACF30DC0EF2CE10E47 22 | :1001500008C0EE2DF0E0E256FF4F808180278EDF51 23 | :10016000EA941E15B0F3DF91CF911F910F91FF908C 24 | :10017000EF900895CF92DF92EF920F931F93C82EC6 25 | :10018000162F90E07AD08091600061E040E020E29C 26 | :1001900000E0E12EBDDF8091600062E040E220E2FD 27 | :1001A000B7DFDD24C601019668D08091600063E06E 28 | :1001B00040E020E2ADDF8091600064E040E220E2B8 29 | :1001C000A7DF1F910F91EF90DF90CF900895CF920E 30 | :1001D000DF92EF92FF920F931F93CF93DF93D82E6E 31 | :1001E000C62E282F392F79012AC0903239F410E019 32 | :1001F00080E044DF1F5F1530D9F71CC0913211F445 33 | :1002000087E30AC09F3311F48CE306C0892F90E086 34 | :1002100065E070E0F1D4805F90E0EC01C058DF4F02 35 | :100220008C010B571F4FCE0147D028DF2196C017F6 36 | :10023000D107C9F780E022DF0894E11CF11CF70127 37 | :100240009081992321F08E2D8D198C1570F2DF91FC 38 | :10025000CF911F910F91FF90EF90DF90CF90089575 39 | :100260000F931F938C01A6D280EAC9D2812FC7D2E7 40 | :10027000802FC5D21F910F9108950F931F93CF9395 41 | :10028000DF938C0126E0880F991F2A95E1F7E8DFBC 42 | :1002900091D281EAB4D2CEE9D0E0ECD2899302D3F4 43 | :1002A00080E0CD3DD807C9F716D300939D00DF91BC 44 | :1002B000CF911F910F9108951F93D2DF7BD281EAD6 45 | :1002C0009ED2D8D2182F07D3812F1F910895369A26 46 | :1002D0003699FECF85B1369A3699FECF85B108950D 47 | :1002E0001F920F920FB60F9211248F9381E080938B 48 | :1002F00078008F910F900FBE0F901F9018951F924E 49 | :100300000F920FB60F9211248F938091DF008823F4 50 | :1003100019F082E08093E2001EBC8F910F900FBE17 51 | :100320000F901F9018951F920F920FB60F921124E5 52 | :100330002F933F934F938F939F93EF93FF932CB5FE 53 | :100340003DB51DBC1CBC8091E200882359F410927D 54 | :10035000DF001092E3001092E20081E08EBD8093F6 55 | :10036000E20047C08091E200813009F042C08091F4 56 | :10037000E400869586958093E400C90180529340FD 57 | :100380008052934018F48091E40016C0C901805453 58 | :1003900096408052934020F48091E40080640CC029 59 | :1003A000205639402052334020F48091E400806888 60 | :1003B00003C08091E400806C8093E4008091E300AE 61 | :1003C000833091F4E091DF00F0E0EF71F070809104 62 | :1003D000E400E358FF4F80838091DF008F5F8093BC 63 | :1003E000DF001092E30005C08091E3008F5F8093EF 64 | :1003F000E300FF91EF919F918F914F913F912F914A 65 | :100400000F900FBE0F901F90189581E064E068DE9A 66 | :100410006091E5007091E60082E1ACDE8AE08093B5 67 | :10042000DE0083E08093E0007CD20895BF92CF92FB 68 | :10043000DF92EF92FF920F931F93CF93DF9381B5DB 69 | :10044000886181BD11BC8CEF8ABB17BA92E09BBB5F 70 | :1004500023E028BB95BF80E78BBF20BD92BB1FBCAC 71 | :1004600011E01CB910BE84E083BF19BF24EC39E051 72 | :10047000C9010197F1F7DA9896EC9BBBF901319726 73 | :10048000F1F786E88BBBE4EDF0E33197F1F79BBB26 74 | :10049000C9010197F1F7DA9ADB9881E2EFDD84E197 75 | :1004A000EDDD85EBEBDD80E2E9DD8CE0E7DD80E092 76 | :1004B00066E016DE80E887B984E886B980E183B912 77 | :1004C00011B91092E00076D380E160E053DE7894B9 78 | :1004D000FF243AE0B32EC0E2DEE4CC24C3941092B1 79 | :1004E00078000EC08091E200823019F48FD2109211 80 | :1004F000E20080917C00882319F053D310927C0095 81 | :1005000080917800882371F3E2DED82E8091E0009C 82 | :100510008130C1F58F2D90E0F0FE23C08270907085 83 | :100520009695879569E070E067D3182F155E81E096 84 | :1005300090E0A3DE80916000909161000A9730F016 85 | :1005400080916000909161008A5005C080916000A8 86 | :10055000909161008F5D62E0412F29E000E0EE2480 87 | :10056000D7DD8091790090917A00892B51F08091AC 88 | :10057000790090917A00019790937A0080937900A6 89 | :1005800001C043DF8091E000882309F052C08F2D25 90 | :1005900090E083709070892B09F04BC0EF2DE695A9 91 | :1005A000E695E370F0E0EE5DFF4FE4916091E500C9 92 | :1005B0007091E6008E2FDEDD8091E5009091E600DF 93 | :1005C000892B99F48091600090916100029730F03E 94 | :1005D0008091600090916100029712C081E090E0EC 95 | :1005E0009093E6008093E50014C0809160009091A4 96 | :1005F0006100C39750F48091600090916100029671 97 | :10060000909361008093600004C01092E600109205 98 | :10061000E5008091790090917A008F3F910549F033 99 | :100620008091790090917A00019690937A0080935E 100 | :1006300079008091E000813021F08091E0008230EB 101 | :1006400059F48AE58D1540F48091790090917A00F3 102 | :100650008034910508F4D9DE8091E0008823B1F45C 103 | :100660008FE48D1598F08091790090917A0081380F 104 | :10067000910560F06091E5007091E60082E17ADD1D 105 | :10068000B092DE0082E08093E0004BD18091DE00EA 106 | :10069000882331F08091DE0081508093DE0022C0FB 107 | :1006A0008091E000823051F46091E5007091E600A5 108 | :1006B00084E160DD24D1C092E00014C08091E000AC 109 | :1006C000833081F46091E5007091E60080E152DDB5 110 | :1006D00016D1CE010197F1F724D1CE010197F1F7A0 111 | :1006E0001092E000F394FBCE1F920F920FB60F9280 112 | :1006F00011242F933F934F935F936F937F938F9327 113 | :100700009F93AF93BF93EF93FF9384EC99E001978E 114 | :10071000F1F7B09913C080917B008093E100809144 115 | :100720007B00882311F489E003C080917B00815015 116 | :1007300080937B0081E080937C00F3D0C99914C042 117 | :1007400080917B008093E10080917B00893019F4D7 118 | :1007500010927B0005C080917B008F5F80937B00AF 119 | :1007600081E080937C00DDD0B19BC9D084EC99E01E 120 | :100770000197F1F783E080BDFF91EF91BF91AF91B9 121 | :100780009F918F917F916F915F914F913F912F91A9 122 | :100790000F900FBE0F901F901895882311F0D798D7 123 | :1007A00001C0D79ADF980895882311F0DC9A089544 124 | :1007B000DC9808951F93DC9A11E0812F8A95F1F758 125 | :1007C00080E0EBDF1A95F1F7DC9883E08A95F1F78A 126 | :1007D0001F9108951F9311E0812F8A95F1F7DC98FE 127 | :1007E000812F8A95F1F780E0D8DF812F8A95F1F784 128 | :1007F000DC9A1A95F1F781E0D0DF1F910895EF920E 129 | :10080000FF921F93CF93DF93C0E0D0E0E82EFF2448 130 | :10081000C7010C2E02C0880F991F0A94E2F787FFC8 131 | :1008200002C081E001C080E0B8DF11E0812F8A952D 132 | :10083000F1F7DC9A812F8A95F1F7DC982196C83080 133 | :10084000D10531F781E0A9DF812F8A95F1F7DC9A94 134 | :10085000812F8A95F1F789B3912F9A95F1F7DC985A 135 | :10086000912F9A95F1F78770DF91CF911F91FF90AB 136 | :10087000EF90089581E091DF80E020E031E0DC98A6 137 | :10088000932F9A95F1F7DC9A932F9A95F1F7880FA9 138 | :10089000CF9981602F5F283091F791E09A95F1F719 139 | :1008A000DC9808951F93DC9811E0812F8A95F1F769 140 | :1008B00080E073DF812F8A95F1F7DC9A812F8A958A 141 | :1008C000F1F7DC98812F8A95F1F781E066DF1A95C0 142 | :1008D000F1F71F9108951F93DC9811E0812F8A95FD 143 | :1008E000F1F781E05ADF812F8A95F1F7DC9A812FA9 144 | :1008F0008A95F1F7DC981A95F1F71F91089582E037 145 | :1009000080BDB89A90E031E025E888B3832788BBA2 146 | :10091000822F8A95F1F79F5F9034B9F7B898C09A03 147 | :10092000089582E080BDB89A90E031E022E488B377 148 | :10093000832788BB822F8A95F1F79F5F9034B9F7A0 149 | :10094000B898C09A089590E031E024E08BB38327F3 150 | :100950008BBB822F8A95F1F79F5F9431B9F7089589 151 | :100960000F931F93CF93DF93082F10E0C8EED3E0CF 152 | :10097000EADF40E0202F30E02370307004C0CE0169 153 | :100980000197F1F74F5F842F90E082179307BCF334 154 | :100990001F5F143019F006950695EACFDF91CF91CD 155 | :1009A0001F910F910895FF920F931F93CF93DF93A1 156 | :1009B000182F042F1655F12EF40E1A5AEB01FB01D5 157 | :1009C00090E003C08191F80E9F5F9017D8F381EB00 158 | :1009D000C7DF812FC5DF802FC3DF10E003C08991FF 159 | :1009E000BFDF1F5F1017D8F38F2DBADFACDFDF91A9 160 | :1009F000CF911F910F91FF90089588E090E03DDC2A 161 | :100A000080E16EE970E04CE0CEDF08950F931F9314 162 | :100A1000CF93DF93CEE9D0E080917D00813B09F058 163 | :100A200086C091E02AEA05C0E358FF4F8081280F75 164 | :100A30009F5F80917F00E92FF0E08917A8F7E358C6 165 | :100A4000FF4F8081281709F072C082E080BDB89AFC 166 | :100A500090E031E022E488B3832788BB822F8A9517 167 | :100A6000F1F79F5F9032B9F7B898C09A83E080BDE4 168 | :100A700080917E0000917F00813009F458C0883059 169 | :100A800009F455C08930E9F440918000209181003B 170 | :100A9000942F80E030E0822B932BE2DB80EAAFDE04 171 | :100AA00010E0C02FD0E0229705C0EE57FF4F8081A5 172 | :100AB000A6DE1F5FE12FF0E0EC17FD07B4F38ADE3E 173 | :100AC00036C08031A1F588E090E0D7DB1C2F0D2FD8 174 | :100AD000CE01DC0123E030E0F901E358FF4F9081C3 175 | :100AE0008C91891799F4822F825011962F5F3F4F76 176 | :100AF0002F30310589F78C3049F480E066E0F0DA78 177 | :100B000086E062E0E3DA82E690E008C080E066E03A 178 | :100B1000E7DA86E062E0DADA8FE690E060E157DB60 179 | :100B20008CE063E0D3DA812F902F6CE050DBDF9113 180 | :100B3000CF911F910F910895EF920F931F93DF9321 181 | :100B4000CF9300D00F92CDB7DEB7182F062F8FEFBF 182 | :100B500080939D00812F90E063E070E04DD0BC0158 183 | :100B60006A5D7F4FCE01019643E034D09A81809137 184 | :100B70009D00981719F0892F90E07FDB898115304F 185 | :100B800010F065E001C060E04B8129E0EE24C0DA9E 186 | :100B90000F900F900F90CF91DF911F910F91EF90D9 187 | :100BA00008958091E10060E0C7DF80917B006FEFE6 188 | :100BB000C3DF08951F9310E080917B00811711F02F 189 | :100BC00060E001C06FEF812FB7DF1F5F1A30A1F720 190 | :100BD0001F9108951F93582F142F282F392FD901B3 191 | :100BE00005C0FB016F5F7F4FE491ED938A2F851B5A 192 | :100BF0008117B8F31F9108955527002480FF02C084 193 | :100C0000060E571F660F771F6115710521F0969527 194 | :100C10008795009799F7952F802D0895F894FFCF29 195 | :100C20001A004845592120414E4F54484552005220 196 | :080C30004D54204953204100FE 197 | :00000001FF 198 | --------------------------------------------------------------------------------