Skip to content

Commit 69e0f7f

Browse files
committed
Add firmware example + some formating cleanup
1 parent 769b193 commit 69e0f7f

File tree

3 files changed

+108
-43
lines changed

3 files changed

+108
-43
lines changed

examples/board_sh1106/README

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
SH1106 OLED demo (navigation menu for a motor controller)
2+
=========================================================
3+
See detailed description of the emulated system here https://github.com/jpcornil-git/Cone2Hank
4+
5+
- Use arrows to navigate menu
6+
- <enter> to select
7+
- <space> to start,pause or stop (long press) motor
8+
- 'v' to start/stop VCD traces
9+
- 'q' or ESC to quit
10+
11+
NOTE: Emulation may be slightly slower than realtime and a keypress has to be long enough to cope with that.
12+
13+
Usage
14+
=====
15+
Command line options:
16+
17+
$ sh1106demo.elf --help
18+
Usage: sh1106demo.elf [...] <firmware>
19+
[--help|-h|-?] Display this usage message and exit
20+
[--list-cores] List all supported AVR cores and exit
21+
[-v] Raise verbosity level
22+
(can be passed more than once)
23+
[--freq|-f <freq>] Sets the frequency for an .hex firmware
24+
[--mcu|-m <device>] Sets the MCU type for an .hex firmware
25+
[--gdb|-g [<port>]] Listen for gdb connection on <port> (default 1234)
26+
[--output|-o <file>] VCD file to save signal traces (default gtkwave_trace.vcd)
27+
[--start-vcd|-s Start VCD output from reset
28+
[--pc-trace|-p Add PC to VCD traces
29+
[--add-trace|-at <name=[portpin|irq|trace]@addr/mask or [sram8|sram16]@addr>]
30+
Add signal to be included in VCD output
31+
<firmware> An ELF file (can include debugging syms)
32+
33+
Examples
34+
========
35+
Execute firmware.elf (with no .mmcu section -> -m and -f required) on system
36+
37+
$ sh1106demo.elf -m atmega32u4 -f 16000000 firmware_no_mmcu.elf
38+
39+
Start system and wait for gdb to connect, load firmware, ...
40+
41+
$ sh1106demo.elf -m atmega32u4 -f 16000000 -g
42+
43+
Execute firmware.elf on system and trace signals in a VCD file
44+
45+
1. .mmcu section of the firmware includes something like:
46+
47+
#include "avr_mcu_section.h"
48+
49+
extern void *__brkval;
50+
51+
AVR_MCU (F_CPU, "atmega32u4" );
52+
AVR_MCU_VOLTAGES(3300, 3300, 3300);
53+
AVR_MCU_VCD_FILE("simavr.vcd", 10000000);
54+
55+
const struct avr_mmcu_vcd_trace_t _mytrace[] _MMCU_ = {
56+
{ AVR_MCU_VCD_SYMBOL("Encoder"), .what = (void*) &PIND, .mask=(1<<PIND2), },
57+
{ AVR_MCU_VCD_SRAM_16("Heap"), .what = (void*)(&__brkval), },
58+
};
59+
60+
2. Options from the command line:
61+
- Add a 16 bits trace for Stack Pointer (SPL/SPH) (could also be in the section above)
62+
- Add a (16 bits) trace for Program Counter (PC)
63+
- Start VCD dump (set to "simavr.vcd" in the .mmcu section) from reset
64+
65+
$ sh1106demo.elf --add-trace Stack=sram16@0x5d -p -s firmware_mmcu.elf
50.6 KB
Binary file not shown.

examples/parts/sh1106_virt.c

Lines changed: 43 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -61,14 +61,14 @@ sh1106_update_command_register (sh1106_t *part)
6161
return;
6262
case SH1106_VIRT_DISP_NORMAL:
6363
sh1106_set_flag (part, SH1106_FLAG_DISPLAY_INVERTED,
64-
0);
64+
0);
6565
sh1106_set_flag (part, SH1106_FLAG_DIRTY, 1);
6666
//printf ("SH1106: DISPLAY NORMAL\n");
6767
SH1106_CLEAR_COMMAND_REG(part);
6868
return;
6969
case SH1106_VIRT_DISP_INVERTED:
7070
sh1106_set_flag (part, SH1106_FLAG_DISPLAY_INVERTED,
71-
1);
71+
1);
7272
sh1106_set_flag (part, SH1106_FLAG_DIRTY, 1);
7373
//printf ("SH1106: DISPLAY INVERTED\n");
7474
SH1106_CLEAR_COMMAND_REG(part);
@@ -86,48 +86,48 @@ sh1106_update_command_register (sh1106_t *part)
8686
SH1106_CLEAR_COMMAND_REG(part);
8787
return;
8888
case SH1106_VIRT_SET_PAGE_START_ADDR
89-
... SH1106_VIRT_SET_PAGE_START_ADDR
90-
+ SH1106_VIRT_PAGES - 1:
89+
... SH1106_VIRT_SET_PAGE_START_ADDR
90+
+ SH1106_VIRT_PAGES - 1:
9191
part->cursor.page = part->spi_data
92-
- SH1106_VIRT_SET_PAGE_START_ADDR;
92+
- SH1106_VIRT_SET_PAGE_START_ADDR;
9393
//printf ("SH1106: SET PAGE ADDRESS: 0x%02x\n", part->cursor.page);
9494
SH1106_CLEAR_COMMAND_REG(part);
9595
return;
9696
case SH1106_VIRT_SET_COLUMN_LOW_NIBBLE
97-
... SH1106_VIRT_SET_COLUMN_LOW_NIBBLE + 0xF:
97+
... SH1106_VIRT_SET_COLUMN_LOW_NIBBLE + 0xF:
9898
part->spi_data -= SH1106_VIRT_SET_COLUMN_LOW_NIBBLE;
9999
part->cursor.column = (part->cursor.column & 0xF0) | (part->spi_data & 0xF);
100100
//printf ("SH1106: SET COLUMN LOW NIBBLE: 0x%02x\n",part->spi_data);
101101
SH1106_CLEAR_COMMAND_REG(part);
102102
return;
103103
case SH1106_VIRT_SET_COLUMN_HIGH_NIBBLE
104-
... SH1106_VIRT_SET_COLUMN_HIGH_NIBBLE + 0xF:
104+
... SH1106_VIRT_SET_COLUMN_HIGH_NIBBLE + 0xF:
105105
part->spi_data -= SH1106_VIRT_SET_COLUMN_HIGH_NIBBLE;
106106
part->cursor.column = (part->cursor.column & 0xF) | ((part->spi_data & 0xF) << 4);
107107
//printf ("SH1106: SET COLUMN HIGH NIBBLE: 0x%02x\n", part->spi_data);
108108
SH1106_CLEAR_COMMAND_REG(part);
109109
return;
110110
case SH1106_VIRT_SET_SEG_REMAP_0:
111111
sh1106_set_flag (part, SH1106_FLAG_SEGMENT_REMAP_0,
112-
1);
112+
1);
113113
//printf ("SH1106: SET COLUMN ADDRESS 0 TO OLED SEG0 to \n");
114114
SH1106_CLEAR_COMMAND_REG(part);
115115
return;
116116
case SH1106_VIRT_SET_SEG_REMAP_131:
117117
sh1106_set_flag (part, SH1106_FLAG_SEGMENT_REMAP_0,
118-
0);
118+
0);
119119
//printf ("SH1106: SET COLUMN ADDRESS 131 TO OLED SEG0 to \n");
120120
SH1106_CLEAR_COMMAND_REG(part);
121121
return;
122122
case SH1106_VIRT_SET_COM_SCAN_NORMAL:
123123
sh1106_set_flag (part, SH1106_FLAG_COM_SCAN_NORMAL,
124-
1);
124+
1);
125125
//printf ("SH1106: SET COM OUTPUT SCAN DIRECTION NORMAL \n");
126126
SH1106_CLEAR_COMMAND_REG(part);
127127
return;
128128
case SH1106_VIRT_SET_COM_SCAN_INVERTED:
129129
sh1106_set_flag (part, SH1106_FLAG_COM_SCAN_NORMAL,
130-
0);
130+
0);
131131
//printf ("SH1106: SET COM OUTPUT SCAN DIRECTION REMAPPED \n");
132132
SH1106_CLEAR_COMMAND_REG(part);
133133
return;
@@ -356,51 +356,51 @@ void
356356
sh1106_connect (sh1106_t * part, sh1106_wiring_t * wiring)
357357
{
358358
avr_connect_irq (
359-
avr_io_getirq (part->avr, AVR_IOCTL_SPI_GETIRQ(0),
360-
SPI_IRQ_OUTPUT),
361-
part->irq + IRQ_SH1106_SPI_BYTE_IN);
359+
avr_io_getirq (part->avr, AVR_IOCTL_SPI_GETIRQ(0),
360+
SPI_IRQ_OUTPUT),
361+
part->irq + IRQ_SH1106_SPI_BYTE_IN);
362362

363363
avr_connect_irq (
364-
avr_io_getirq (part->avr,
365-
AVR_IOCTL_IOPORT_GETIRQ(
366-
wiring->chip_select.port),
367-
wiring->chip_select.pin),
368-
part->irq + IRQ_SH1106_ENABLE);
364+
avr_io_getirq (part->avr,
365+
AVR_IOCTL_IOPORT_GETIRQ(
366+
wiring->chip_select.port),
367+
wiring->chip_select.pin),
368+
part->irq + IRQ_SH1106_ENABLE);
369369

370370
avr_connect_irq (
371-
avr_io_getirq (part->avr,
372-
AVR_IOCTL_IOPORT_GETIRQ(
373-
wiring->data_instruction.port),
374-
wiring->data_instruction.pin),
375-
part->irq + IRQ_SH1106_DATA_INSTRUCTION);
371+
avr_io_getirq (part->avr,
372+
AVR_IOCTL_IOPORT_GETIRQ(
373+
wiring->data_instruction.port),
374+
wiring->data_instruction.pin),
375+
part->irq + IRQ_SH1106_DATA_INSTRUCTION);
376376

377377
avr_connect_irq (
378-
avr_io_getirq (part->avr,
379-
AVR_IOCTL_IOPORT_GETIRQ(
380-
wiring->reset.port),
381-
wiring->reset.pin),
382-
part->irq + IRQ_SH1106_RESET);
378+
avr_io_getirq (part->avr,
379+
AVR_IOCTL_IOPORT_GETIRQ(
380+
wiring->reset.port),
381+
wiring->reset.pin),
382+
part->irq + IRQ_SH1106_RESET);
383383
}
384384

385385
void
386386
sh1106_connect_twi (sh1106_t * part, sh1106_wiring_t * wiring)
387387
{
388388
avr_connect_irq (
389-
avr_io_getirq (part->avr, AVR_IOCTL_TWI_GETIRQ(0), TWI_IRQ_OUTPUT),
390-
part->irq + IRQ_SH1106_TWI_OUT);
389+
avr_io_getirq (part->avr, AVR_IOCTL_TWI_GETIRQ(0), TWI_IRQ_OUTPUT),
390+
part->irq + IRQ_SH1106_TWI_OUT);
391391

392392
avr_connect_irq (
393-
part->irq + IRQ_SH1106_TWI_IN,
394-
avr_io_getirq (part->avr, AVR_IOCTL_TWI_GETIRQ(0), TWI_IRQ_INPUT));
393+
part->irq + IRQ_SH1106_TWI_IN,
394+
avr_io_getirq (part->avr, AVR_IOCTL_TWI_GETIRQ(0), TWI_IRQ_INPUT));
395395

396396
if (wiring)
397397
{
398398
avr_connect_irq (
399399
avr_io_getirq (part->avr,
400-
AVR_IOCTL_IOPORT_GETIRQ(
401-
wiring->reset.port),
402-
wiring->reset.pin),
403-
part->irq + IRQ_SH1106_RESET);
400+
AVR_IOCTL_IOPORT_GETIRQ(
401+
wiring->reset.port),
402+
wiring->reset.pin),
403+
part->irq + IRQ_SH1106_RESET);
404404
}
405405
}
406406

@@ -418,21 +418,21 @@ sh1106_init (struct avr_t *avr, struct sh1106_t * part, int width, int height)
418418
part->write_cursor_end.page = SH1106_VIRT_PAGES-1;
419419
part->write_cursor_end.column = SH1106_VIRT_COLUMNS-1;
420420

421-
AVR_LOG(avr, LOG_OUTPUT, "SH1106: size %dx%d (flags=0x%04x)\n", part->columns, part->rows, part->flags);
421+
AVR_LOG(avr, LOG_OUTPUT, "SH1106: size %dx%d (flags=0x%04x)\n", part->columns, part->rows, part->flags);
422422
/*
423423
* Register callbacks on all our IRQs
424424
*/
425425
part->irq = avr_alloc_irq (&avr->irq_pool, 0, IRQ_SH1106_COUNT,
426426
irq_names);
427427

428428
avr_irq_register_notify (part->irq + IRQ_SH1106_SPI_BYTE_IN,
429-
sh1106_spi_in_hook, part);
429+
sh1106_spi_in_hook, part);
430430
avr_irq_register_notify (part->irq + IRQ_SH1106_RESET,
431-
sh1106_reset_hook, part);
431+
sh1106_reset_hook, part);
432432
avr_irq_register_notify (part->irq + IRQ_SH1106_ENABLE,
433-
sh1106_cs_hook, part);
433+
sh1106_cs_hook, part);
434434
avr_irq_register_notify (part->irq + IRQ_SH1106_DATA_INSTRUCTION,
435-
sh1106_di_hook, part);
435+
sh1106_di_hook, part);
436436
avr_irq_register_notify (part->irq + IRQ_SH1106_TWI_OUT,
437-
sh1106_twi_hook, part);
437+
sh1106_twi_hook, part);
438438
}

0 commit comments

Comments
 (0)