diff --git a/examples/board_sh1106/README b/examples/board_sh1106/README new file mode 100644 index 00000000..dfae12e7 --- /dev/null +++ b/examples/board_sh1106/README @@ -0,0 +1,65 @@ +SH1106 OLED demo (navigation menu for a motor controller) +========================================================= +See detailed description of the emulated system here https://github.com/jpcornil-git/Cone2Hank + +- Use arrows to navigate menu +- to select +- to start,pause or stop (long press) motor +- 'v' to start/stop VCD traces +- 'q' or ESC to quit + +NOTE: Emulation may be slightly slower than realtime and a keypress has to be long enough to cope with that. + +Usage +===== +Command line options: + +$ sh1106demo.elf --help +Usage: sh1106demo.elf [...] + [--help|-h|-?] Display this usage message and exit + [--list-cores] List all supported AVR cores and exit + [-v] Raise verbosity level + (can be passed more than once) + [--freq|-f ] Sets the frequency for an .hex firmware + [--mcu|-m ] Sets the MCU type for an .hex firmware + [--gdb|-g []] Listen for gdb connection on (default 1234) + [--output|-o ] VCD file to save signal traces (default gtkwave_trace.vcd) + [--start-vcd|-s Start VCD output from reset + [--pc-trace|-p Add PC to VCD traces + [--add-trace|-at ] + Add signal to be included in VCD output + An ELF file (can include debugging syms) + +Examples +======== +Execute firmware.elf (with no .mmcu section -> -m and -f required) on system + +$ sh1106demo.elf -m atmega32u4 -f 16000000 firmware_no_mmcu.elf + +Start system and wait for gdb to connect, load firmware, ... + +$ sh1106demo.elf -m atmega32u4 -f 16000000 -g + +Execute firmware.elf on system and trace signals in a VCD file + +1. .mmcu section of the firmware includes something like: + + #include "avr_mcu_section.h" + + extern void *__brkval; + + AVR_MCU (F_CPU, "atmega32u4" ); + AVR_MCU_VOLTAGES(3300, 3300, 3300); + AVR_MCU_VCD_FILE("simavr.vcd", 10000000); + + const struct avr_mmcu_vcd_trace_t _mytrace[] _MMCU_ = { + { AVR_MCU_VCD_SYMBOL("Encoder"), .what = (void*) &PIND, .mask=(1<cursor.page = part->spi_data - - SH1106_VIRT_SET_PAGE_START_ADDR; + - SH1106_VIRT_SET_PAGE_START_ADDR; //printf ("SH1106: SET PAGE ADDRESS: 0x%02x\n", part->cursor.page); SH1106_CLEAR_COMMAND_REG(part); return; case SH1106_VIRT_SET_COLUMN_LOW_NIBBLE - ... SH1106_VIRT_SET_COLUMN_LOW_NIBBLE + 0xF: + ... SH1106_VIRT_SET_COLUMN_LOW_NIBBLE + 0xF: part->spi_data -= SH1106_VIRT_SET_COLUMN_LOW_NIBBLE; part->cursor.column = (part->cursor.column & 0xF0) | (part->spi_data & 0xF); //printf ("SH1106: SET COLUMN LOW NIBBLE: 0x%02x\n",part->spi_data); SH1106_CLEAR_COMMAND_REG(part); return; case SH1106_VIRT_SET_COLUMN_HIGH_NIBBLE - ... SH1106_VIRT_SET_COLUMN_HIGH_NIBBLE + 0xF: + ... SH1106_VIRT_SET_COLUMN_HIGH_NIBBLE + 0xF: part->spi_data -= SH1106_VIRT_SET_COLUMN_HIGH_NIBBLE; part->cursor.column = (part->cursor.column & 0xF) | ((part->spi_data & 0xF) << 4); //printf ("SH1106: SET COLUMN HIGH NIBBLE: 0x%02x\n", part->spi_data); @@ -109,25 +109,25 @@ sh1106_update_command_register (sh1106_t *part) return; case SH1106_VIRT_SET_SEG_REMAP_0: sh1106_set_flag (part, SH1106_FLAG_SEGMENT_REMAP_0, - 1); + 1); //printf ("SH1106: SET COLUMN ADDRESS 0 TO OLED SEG0 to \n"); SH1106_CLEAR_COMMAND_REG(part); return; case SH1106_VIRT_SET_SEG_REMAP_131: sh1106_set_flag (part, SH1106_FLAG_SEGMENT_REMAP_0, - 0); + 0); //printf ("SH1106: SET COLUMN ADDRESS 131 TO OLED SEG0 to \n"); SH1106_CLEAR_COMMAND_REG(part); return; case SH1106_VIRT_SET_COM_SCAN_NORMAL: sh1106_set_flag (part, SH1106_FLAG_COM_SCAN_NORMAL, - 1); + 1); //printf ("SH1106: SET COM OUTPUT SCAN DIRECTION NORMAL \n"); SH1106_CLEAR_COMMAND_REG(part); return; case SH1106_VIRT_SET_COM_SCAN_INVERTED: sh1106_set_flag (part, SH1106_FLAG_COM_SCAN_NORMAL, - 0); + 0); //printf ("SH1106: SET COM OUTPUT SCAN DIRECTION REMAPPED \n"); SH1106_CLEAR_COMMAND_REG(part); return; @@ -356,51 +356,51 @@ void sh1106_connect (sh1106_t * part, sh1106_wiring_t * wiring) { avr_connect_irq ( - avr_io_getirq (part->avr, AVR_IOCTL_SPI_GETIRQ(0), - SPI_IRQ_OUTPUT), - part->irq + IRQ_SH1106_SPI_BYTE_IN); + avr_io_getirq (part->avr, AVR_IOCTL_SPI_GETIRQ(0), + SPI_IRQ_OUTPUT), + part->irq + IRQ_SH1106_SPI_BYTE_IN); avr_connect_irq ( - avr_io_getirq (part->avr, - AVR_IOCTL_IOPORT_GETIRQ( - wiring->chip_select.port), - wiring->chip_select.pin), - part->irq + IRQ_SH1106_ENABLE); + avr_io_getirq (part->avr, + AVR_IOCTL_IOPORT_GETIRQ( + wiring->chip_select.port), + wiring->chip_select.pin), + part->irq + IRQ_SH1106_ENABLE); avr_connect_irq ( - avr_io_getirq (part->avr, - AVR_IOCTL_IOPORT_GETIRQ( - wiring->data_instruction.port), - wiring->data_instruction.pin), - part->irq + IRQ_SH1106_DATA_INSTRUCTION); + avr_io_getirq (part->avr, + AVR_IOCTL_IOPORT_GETIRQ( + wiring->data_instruction.port), + wiring->data_instruction.pin), + part->irq + IRQ_SH1106_DATA_INSTRUCTION); avr_connect_irq ( - avr_io_getirq (part->avr, - AVR_IOCTL_IOPORT_GETIRQ( - wiring->reset.port), - wiring->reset.pin), - part->irq + IRQ_SH1106_RESET); + avr_io_getirq (part->avr, + AVR_IOCTL_IOPORT_GETIRQ( + wiring->reset.port), + wiring->reset.pin), + part->irq + IRQ_SH1106_RESET); } void sh1106_connect_twi (sh1106_t * part, sh1106_wiring_t * wiring) { avr_connect_irq ( - avr_io_getirq (part->avr, AVR_IOCTL_TWI_GETIRQ(0), TWI_IRQ_OUTPUT), - part->irq + IRQ_SH1106_TWI_OUT); + avr_io_getirq (part->avr, AVR_IOCTL_TWI_GETIRQ(0), TWI_IRQ_OUTPUT), + part->irq + IRQ_SH1106_TWI_OUT); avr_connect_irq ( - part->irq + IRQ_SH1106_TWI_IN, - avr_io_getirq (part->avr, AVR_IOCTL_TWI_GETIRQ(0), TWI_IRQ_INPUT)); + part->irq + IRQ_SH1106_TWI_IN, + avr_io_getirq (part->avr, AVR_IOCTL_TWI_GETIRQ(0), TWI_IRQ_INPUT)); if (wiring) { avr_connect_irq ( avr_io_getirq (part->avr, - AVR_IOCTL_IOPORT_GETIRQ( - wiring->reset.port), - wiring->reset.pin), - part->irq + IRQ_SH1106_RESET); + AVR_IOCTL_IOPORT_GETIRQ( + wiring->reset.port), + wiring->reset.pin), + part->irq + IRQ_SH1106_RESET); } } @@ -418,7 +418,7 @@ sh1106_init (struct avr_t *avr, struct sh1106_t * part, int width, int height) part->write_cursor_end.page = SH1106_VIRT_PAGES-1; part->write_cursor_end.column = SH1106_VIRT_COLUMNS-1; - AVR_LOG(avr, LOG_OUTPUT, "SH1106: size %dx%d (flags=0x%04x)\n", part->columns, part->rows, part->flags); + AVR_LOG(avr, LOG_OUTPUT, "SH1106: size %dx%d (flags=0x%04x)\n", part->columns, part->rows, part->flags); /* * Register callbacks on all our IRQs */ @@ -426,13 +426,13 @@ sh1106_init (struct avr_t *avr, struct sh1106_t * part, int width, int height) irq_names); avr_irq_register_notify (part->irq + IRQ_SH1106_SPI_BYTE_IN, - sh1106_spi_in_hook, part); + sh1106_spi_in_hook, part); avr_irq_register_notify (part->irq + IRQ_SH1106_RESET, - sh1106_reset_hook, part); + sh1106_reset_hook, part); avr_irq_register_notify (part->irq + IRQ_SH1106_ENABLE, - sh1106_cs_hook, part); + sh1106_cs_hook, part); avr_irq_register_notify (part->irq + IRQ_SH1106_DATA_INSTRUCTION, - sh1106_di_hook, part); + sh1106_di_hook, part); avr_irq_register_notify (part->irq + IRQ_SH1106_TWI_OUT, - sh1106_twi_hook, part); + sh1106_twi_hook, part); }