cleanups, optimizations
This commit is contained in:
parent
940096746f
commit
a9dcc52b10
@ -74,7 +74,7 @@ ASFLAGS += -Wa,--defsym,GPU_SRAM_BASE=$(GPU_SRAM_BASE) -Wa,--defsym,GPU_SRAM_SIZ
|
||||
|
||||
|
||||
TARGET_ELF = $(TARGET_NAME).elf
|
||||
TARGETS = $(TARGET_NAME).lss $(TARGET_NAME).bin $(TARGET_NAME).sym
|
||||
TARGETS = $(TARGET_NAME).lss $(TARGET_NAME).bin $(TARGET_NAME).sym gpu_binary.py
|
||||
|
||||
all: $(TARGETS)
|
||||
|
||||
@ -120,10 +120,16 @@ DELIVERABLES = $(TARGET_NAME).bin $(TARGET_NAME).lss gpu_binary.py
|
||||
# package the binary into a mpy file to be frozen/included into main micro code
|
||||
gpu_binary.py: version.txt $(TARGET_NAME).bin
|
||||
./repackage.py `cat version.txt` $(TARGET_NAME).bin > $@
|
||||
wc -c $(TARGET_NAME).bin
|
||||
|
||||
checksums.txt: $(DELIVERABLES)
|
||||
shasum -a 256 $(DELIVERABLES) > $@
|
||||
|
||||
lcd.o: barcode.h
|
||||
#barcode.h: version.h make_barcode.py Makefile
|
||||
barcode.h: make_barcode.py Makefile
|
||||
python3 make_barcode.py
|
||||
|
||||
# Track released versions
|
||||
.PHONY: capture
|
||||
capture: version.txt version-full.txt $(DELIVERABLES) checksums.txt
|
||||
|
||||
@ -37,47 +37,21 @@ Useful commands:
|
||||
|
||||
flash erase_sector 0 0 last
|
||||
|
||||
Set EMPTY bit, so goes into BL:
|
||||
|
||||
> mdw 0x40022000
|
||||
0x40022000: 00040600
|
||||
> mmw 0x40022000 0x10000 0
|
||||
> mdw 0x40022000
|
||||
0x40022000: 00050600
|
||||
|
||||
|
||||
|
||||
## In-Circuit Programming
|
||||
|
||||
- AN4221 describes the protocol used to load the flash
|
||||
- timing is sensitive, but more important is where the i2c start/stops fall:
|
||||
|
||||
```python
|
||||
>>> from machine import I2C, Pin
|
||||
>>> i2c = I2C(1, freq=400000)
|
||||
|
||||
>>> r = Pin('G_RESET')
|
||||
>>> r
|
||||
Pin(Pin.cpu.E6, mode=Pin.OUT)
|
||||
>>> r.init(mode=Pin.OPEN_DRAIN, pull=Pin.PULL_UP)
|
||||
>>> r()
|
||||
0
|
||||
>>> r(1)
|
||||
>>> r()
|
||||
1
|
||||
>>> [hex(i) for i in i2c.scan()]
|
||||
['0x2d', '0x51', '0x53', '0x55', '0x57', '0x64']
|
||||
|
||||
# for SWI to work, also:
|
||||
>>> gg=Pin('G_SWCLK_B0')
|
||||
>>> gg.init(mode=Pin.IN)
|
||||
|
||||
|
||||
# Get - reveals bootloader version, commands (v1.2)
|
||||
>>> i2c.writeto(0x64, b'\x00\xff'); i2c.readfrom(0x64, 1); i2c.readfrom(0x64, 20); i2c.readfrom(0x64, 1);
|
||||
2
|
||||
b'y'
|
||||
b'\x12\x11\x00\x01\x02\x11!1Dcs\x82\x922Edt\x83\x93\xa1'
|
||||
b'y'
|
||||
|
||||
# Get ID command
|
||||
>>> i2c.writeto(0x64, b'\x02\xfd'); i2c.readfrom(0x64, 1); [hex(i) for i in i2c.readfrom(0x64, 3)]; i2c.readfrom(2x64, 1);
|
||||
b'y'
|
||||
['0x1', '0x4', '0x43']
|
||||
b'y'
|
||||
```
|
||||
|
||||
## First Time Boot
|
||||
|
||||
- on a fresh device, there is an `EMPTY` bit set on power-up (only) if flash looks empty
|
||||
@ -85,6 +59,7 @@ b'y'
|
||||
- so must clear bit 16 of `FLASH_ACR` after loading image: @ `0x40022000`
|
||||
- also, main micro has control over `BOOT0` (PE2) which stop main flash from running too
|
||||
- and the reset line on E6
|
||||
- we use this flag to get into boot mode from working code
|
||||
|
||||
## Getting BOOT0 to work
|
||||
|
||||
@ -93,6 +68,7 @@ b'y'
|
||||
- `NRST_MODE` should be 0b01 (input only) not default (0b11 = bidirectional)
|
||||
- register `FLASH_OPTR` at 0x40022020 => found as 0xfffffeaa
|
||||
- loads from 0x1FFF7800 at power up
|
||||
- TODO XXX still need this!
|
||||
|
||||
## AN4221 / Bootloader Bugs
|
||||
|
||||
@ -101,6 +77,7 @@ b'y'
|
||||
- command 0x01 - 'getversion' ... return 1 byte, and doesn't include length prefix byte
|
||||
- memory read only works from flash, some parts of SRAM... not IO registers
|
||||
- undocumented need for N-1 as length in read/write commands
|
||||
- flash writes need to be 256-aligned, or else they do nothing and don't fail
|
||||
|
||||
## Resource Sharing
|
||||
|
||||
|
||||
8
misc/gpu/barcode.h
Normal file
8
misc/gpu/barcode.h
Normal file
@ -0,0 +1,8 @@
|
||||
// autogen file, see make_barcode.py
|
||||
|
||||
// in python: b'\x00\x00\x00\x00\x00\x00\x00?\x1c\x0e\x00\x1f\x8e\x00\xe0\x0f\xf8\xff\x8f\xc7\xe3\xfe?\xe3\xf1\xf8\xff\xf1\xf8\x03\xfe8\xfc\x00\x00\x00\x00\x00\x00\x00'
|
||||
static const uint8_t test_barcode[40] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x1c, 0x0e, 0x00, 0x1f, 0x8e, 0x00, 0xe0, 0x0f, 0xf8, 0xff, 0x8f, 0xc7, 0xe3, 0xfe, 0x3f, 0xe3, 0xf1, 0xf8, 0xff, 0xf1, 0xf8, 0x03, 0xfe, 0x38, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
// EOF
|
||||
@ -4,107 +4,130 @@
|
||||
#
|
||||
# see misc/gpu for source
|
||||
#
|
||||
VERSION = '1.0.0'
|
||||
VERSION = '1.1.0'
|
||||
|
||||
LENGTH = const(3140) # bytes
|
||||
LENGTH = const(3500) # bytes
|
||||
|
||||
BINARY = (b'\x00\x18\x00 \t\x01\x00\x08\x99\x06\x00\x08\x9b\x06\x00\x08\x00\x00\x00\x00'
|
||||
BINARY = (b'\x00\x18\x00 \t\x01\x00\x08\x19\t\x00\x08\x1b\t\x00\x08\x00\x00\x00\x00'
|
||||
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
b'\x00\x00\x00\x00\x00\x00\x00\x00\x9d\x06\x00\x08\x00\x00\x00\x00'
|
||||
b'\x00\x00\x00\x00\x9f\x06\x00\x08\xa1\x06\x00\x08U\x01\x00\x08'
|
||||
b'\x00\x00\x00\x00U\x01\x00\x08U\x01\x00\x08U\x01\x00\x08U\x01\x00\x08'
|
||||
b'U\x01\x00\x08U\x01\x00\x08\x00\x00\x00\x00U\x01\x00\x08U\x01\x00\x08'
|
||||
b'U\x01\x00\x08U\x01\x00\x08U\x01\x00\x08U\x01\x00\x08\x00\x00\x00\x00'
|
||||
b'U\x01\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00U\x01\x00\x08\x00\x00\x00\x00'
|
||||
b'\x00\x00\x00\x00\x00\x00\x00\x00\x1d\t\x00\x08\x00\x00\x00\x00'
|
||||
b'\x00\x00\x00\x00\x1f\t\x00\x08!\t\x00\x08U\x01\x00\x08\x00\x00\x00\x00'
|
||||
b'U\x01\x00\x08U\x01\x00\x08U\x01\x00\x08U\x01\x00\x08U\x01\x00\x08'
|
||||
b'U\x01\x00\x08\x00\x00\x00\x00U\x01\x00\x08U\x01\x00\x08U\x01\x00\x08'
|
||||
b'U\x01\x00\x08U\x01\x00\x08U\x01\x00\x08\x00\x00\x00\x00U\x01\x00\x08'
|
||||
b'\x00\x00\x00\x00U\x01\x00\x08U\x01\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
b'\x00\x00\x00\x00\x10\xb5\x06L#x\x00+\x07\xd1\x05K\x00+\x02\xd0\x04H\x00\xe0'
|
||||
b'\x00\xbf\x01##p\x10\xbd\x0c\x00\x00 \x00\x00\x00\x004\x0c\x00\x08'
|
||||
b'\x04K\x10\xb5\x00+\x03\xd0\x03I\x04H\x00\xe0\x00\xbf\x10\xbd\xc0F'
|
||||
b'\x00\x00\x00\x00\x10\x00\x00 4\x0c\x00\x08\x0cH\x85F\x00\xf0T\xf9'
|
||||
b'\x00!\x03\xe0\nK[XCP\x041\tH\nKB\x18\x9aB\xf6\xd3\tJ\x02\xe0\x00#\x13`\x042'
|
||||
b'\x07K\x9aB\xf9\xd3\x00\xf0\x83\xf9\xfe\xe7\x00\x18\x00 \x04\x00\x00 '
|
||||
b'\x00\x00\x00 \x0c\x00\x00 \x0c\x00\x00 @\x00\x00 \xfe\xe7\x00\x00'
|
||||
b'\x00\xb5\x89\xb0\x14"\x00!\x03\xa8\x00\xf0)\xfd\x01 \tJQk\x01CQcSk\x02\xa9'
|
||||
b'\x03@\x01\x93\x01\x9b?#\x9f0\x02\x93\xc0\x05=;\x04\x93\x00\xf0\x8c\xfa\t\xb0'
|
||||
b'\x00\xbd\xc0F\x00\x10\x02@\x10\xb5\x02$ K!IZm\x88\xb0\n@ZeZk\x00!"CZc[k\x0c"'
|
||||
b'#@\x00\x93\x03\xa8\x00\x9b\x00\xf0\xfe\xfc\xc0#\x01\x93\xbf;\x04\x93'
|
||||
b'\x01\xa9\x053\x16H\x06\x93\x02\x94\x00\xf0h\xfa\x1c"\x00!\x01\xa8'
|
||||
b'\x00\xf0\xee\xfc\x12K\x13L\x02\x93\xca# \x00\x01\xa9\x05\x93\x00\xf0'
|
||||
b'\xeb\xfb\x80#bh\x9b\x04\x13Cc`\xe3h\rJ\x13@\xe3`\xe3h\x0cJ\x13@\xe3`#h\x0bJ'
|
||||
b'\x13@#`#h\nJ\x13@#`\x08\xb0\x10\xbd\x00\x10\x02@\xff\xcf\xff\xff'
|
||||
b'\x00\x04\x00P\x13\x04\x10\x00\x00T\x00@\x01\xf8\xff\xff\xff\x7f\xff\xff'
|
||||
b'\xff\xff\xf7\xff\xff\xff\xfd\xff\x80#\x03J[\x02\x11h\x0bC\x13`pG\xc0F'
|
||||
b'\x00 \x02@\x08#\xf7\xb5KLLJ\xa1i\x19B\x10\xd0\xe1i\x0bC\x80!\xe3a\xa3i'
|
||||
b'I\x02\x0b@\x19\x00H\x1e\x81A\x11p\x00+!\xd1DI\x0bpDI\x0bp\x13x\xa1i'
|
||||
b'\x01\x93AK\x1dxAK\x1bx\x00\x93 #\x19B(\xd0\xe2i\x13C\xe3a\x01\x9b\x00+'
|
||||
b'"\xd1<O<Np-@\xd0\x0c\xd8V-\x11\xd0b-?\xd09K;`\x08#\t\xe0#h8I\x0b@#`'
|
||||
b'\xdc\xe7v-\xf4\xd16K;`\x06#3p\x05\xe04H8`\x00\xf0t\xfc\x0100p\x01#\xa2i'
|
||||
b'\x13C\xa3a\x00"0K\x11\x00\x01 \x9cF\x04&\xa3i3B"\xd1\x00)\x01\xd0#K'
|
||||
b'\x1dp\x00*\x02\xd0"K\x00\x9a\x1ap\xff\'\x00%\x02&\xbcF H\x1fI\x03x\nh'
|
||||
b'\x01\x9f\x00/#\xd1\x00-\x01\xd0\x03p\n`\xf7\xbd\x1fK;`\x00\x9b\xcd\xe7'
|
||||
b'\xff\xf7\x82\xff\x1dK;`\x03#\xc7\xe7cj\xdb\xb2\x00-\n\xd0\x00\x9e\x07.'
|
||||
b'\xd1\xd82\x00gF\x012\xbbU\xd3\xb2\x00\x93\x02\x00\xc9\xe7\x1d\x00'
|
||||
b'\x01\x00\xc6\xe7gF\xa7b\xd8\xe7\xa7i7B\xd8\xd0\x00+\xf7\xd0\x15x\x01;'
|
||||
b'\xa5b\x012\x01\x9d\xdb\xb2\xcc\xe7\xc0F\x00T\x00@2\x00\x00 1\x00\x00 '
|
||||
b'(\x00\x00 4\x00\x00 8\x00\x00 \xf9\x0b\x00\x08\xff\xff\xfe\xff'
|
||||
b'\xf0\x0b\x00\x08\x02\x0c\x00\x08)\x00\x00 \xf6\x0b\x00\x08\x80"\x1aK'
|
||||
b'\x12\x05\x10\xb5\x9a`\x80"\x18KR\x00\x19h\nC\x1a`\x80"\xd2\x00\x19h'
|
||||
b'\x11B\xfc\xd0Zh\x14I\x11@\x80"\xd2\x01\nCZ`\x1ah\x11I\x11@\x80"R\x01\nC\x1a`'
|
||||
b'\x9ah\x0fI\n@\x07!\x9a`\x9ah\x8aC\x9a`8"\x99h\x11B\xfc\xd1\x9ah\nI\nH\n@'
|
||||
b'\x9a`\x00\xf0\x0f\xfb\x08H\x00\xf0\x1c\xfb\x10\xbd\xc0F\x00\xed\x00\xe0'
|
||||
b'\x00\x10\x02@\xff\x80\xff\xff\xff\xc7\xff\xff\xff\xf0\xff\xff'
|
||||
b'\xff\x8f\xff\xff\x00\x1b\xb7\x00\x18Ks\xb5\x19l\x18H\xa0$\x01C\x19d\x81!'
|
||||
b'\x01&\x1alI\x05\x02@\x01\x92\x01\x9a\xdak\xe4\x05\nC\xdac\xdbk\x0b@'
|
||||
b'\x00\x93\x00\x9b\xff\xf7t\xfe\x00\xf0n\xf8\xff\xf7\x8e\xfe\x0cJ\rI\x13h\x0b@'
|
||||
b'\x13`\xff\xf7\xe7\xfe#i3B\xfa\xd1 %#i+B\xf6\xd0\x00\xf0\xc0\xf8#i+B'
|
||||
b'\xf1\xd0\xff\xf7\xd9\xfe\xf9\xe7\x00\x10\x02@\x01\x10\x00\x00\x00 \x02@'
|
||||
b'\xff\xff\xfe\xff\xa0#\x10"\x08!\xdb\x05\x10\xb5\x9aa\x99b\x9ab\xc0#[\x01'
|
||||
b'\x1c\x00\x08J\x91h\x19@\xa1B\xfb\xd0\x10s\x91h\x19B\xfc\xd1\xa0#\x10"'
|
||||
b'\xdb\x05\x9aa\x08:\x9aa\x10\xbd\xc0F\x000\x01@\xa0#0\xb5\x10"\x08$'
|
||||
b'\xdb\x05\x9aa\x9ca\x9ab\xc0"\x00#\tLR\x01\x98B\x07\xdc\xa3h\x13B'
|
||||
b'\xfc\xd1\xa0#\x10"\xdb\x05\x9aa0\xbd\xa5h\x15@\x95B\xfb\xd0\xcd\\\x013'
|
||||
b'%s\xed\xe7\x000\x01@\x13\xb5\x0b\n\x01\xac#p\x13\nap\xa3p\xe2p'
|
||||
b'\xff\xf7\xb8\xff!\x00\x04 \xff\xf7\xd2\xff\x13\xbd\x00\x00\x10\xb5\x8a\xb0'
|
||||
b'\x1c"\x00!\x03\xa8\x00\xf0-\xfb\xc0#\x1b\x02\x00\x93\x82#[\x00\x01\x93\xe0#'
|
||||
b'\xdb\x00\x02\x93\x80#\x08L\x9b\x00iF \x00\x05\x93\x00\xf0\xe4\xf9@#"h'
|
||||
b'\x13C\x00"#`\x03K\x1a`\n\xb0\x10\xbd\xc0F\x000\x01@<\x00\x00 \xf8\xb5\x1aK'
|
||||
b'R!\x00\xaf\x9dDmF\x00"\x06$\x17H\xff1\x13\x00#@^BsA\x15N[B\x03@\x9b\x19'
|
||||
b'V\x00\x012\xabS\x8aB\xf2\xd1@"\x00!* \xff2\xff\xf7\xad\xff\xef"\xed!+ '
|
||||
b'\xff\xf7\xa8\xff\xa0&, \xff\xf7f\xff\x03$\xb6\x00\tK0\x00\x19h\x0f#'
|
||||
b'Y\x1aI\x00i\x18\x01<\xff\xf7x\xff\x00,\xf3\xd1\xbdF\xf8\xbdX\xfd\xff\xff'
|
||||
b'\x03\x9f\xff\xff\xfd`\x00\x00<\x00\x00 \x10\xb5\x86\xb0\x0c"\x00!'
|
||||
b'\x03\xa8\x00\xf0\xc9\xfa\x06#\xa0 \x03$iF\x00\x93\xc0\x05\x04;'
|
||||
b'\x01\x93\x02\x94\x00\xf03\xf8\x18#\xa0 \x00\x93\x17;\x01\x93\x00#iF\xc0\x05'
|
||||
b'\x04\x93\x03\x93\x05\x93\x02\x94\x00\xf0%\xf8\xff\xf7\xa0\xff\x0cJ\rI'
|
||||
b'\x13h\x013\x0b@\x04\xd5\x10!\x01;IB\x0bC\x013\x13`\x00!\x14"\x01\xa8\x00\xf0'
|
||||
b'\x9d\xfa\xa0 \x1e#iF\xc0\x05\x00\x93\x00\xf0\x0b\xf8\x06\xb0\x10\xbd'
|
||||
b'<\x00\x00 \x0f\x00\x00\x80\xfe\xe7\xfe\xe7pGpGpG\xf0\xb5\x87\xb0\x0bh'
|
||||
b'\x02\x91\x1f"\x01!\x01\x93\x05\x00\x01\x98[\x08\x00+\x1e\xd1\x90@ 3\x00('
|
||||
b'\x02\xd0\x00\xf0[\xfa\xc3\xb2\x03\x93\x02\x9b\x03\x9a[h\x04\x93\x01\x9b'
|
||||
b'\xd3@\x16\xd1\x04\x9b\x01;\x01+\x08\xd8kh\x01\x9a\x01\x99\x93C\x02\x9a\xd2h'
|
||||
b'JC\x13Ck`\x00 \x07\xb0\xf0\xbd\x1c\x00@\x00\x0c@ C\x01:[\x08\xd7\xe7\x01#'
|
||||
b'\x03\x9a\x01\x9c\x93@\x01\x9a\x1c@\x1aB\x00\xd1\xd3\xe0f\x08 \x003\x00\x1f"'
|
||||
b'/h\x00+p\xd1\x90@ 3\x00(\x02\xd0\x00\xf0%\xfa\xc3\xb2\x03"[\x00\x9a@ \x00'
|
||||
b'\x97C3\x00\x1f"\x00+g\xd1\x90@ 3\x00(\x02\xd0\x00\xf0\x15\xfa\xc3\xb2'
|
||||
b'\x04\x9a[\x00\x9a@\x04\x9b\x17C\x01;/`\x01+$\xd8\x02\x9b \x00\x9bh'
|
||||
b'\x1f"\x05\x933\x00\xafh\x00+U\xd1\x90@ 3\x00(\x02\xd0\x00\xf0\xfc\xf9'
|
||||
b'\xc3\xb2\x03"[\x00\x9a@ \x00\x97C3\x00\x1f"\x00+L\xd1\x90@ 3\x00(\x02\xd0'
|
||||
b'\x00\xf0\xec\xf9\xc3\xb2\x05\x9a[\x00\x9a@\x17C\xaf`\x02\x9b \x00\x1bi\x1f"'
|
||||
b'\x05\x933\x00\xefh\x00+>\xd1\x90@ 3\x00(\x02\xd0\x00\xf0\xd7\xf9\xc3\xb2'
|
||||
b'\x03"[\x00\x9a@ \x00\x97C3\x00\x1f"\x00+5\xd1\x90@ 3\x00(\x02\xd0\x00\xf0'
|
||||
b'\xc7\xf9\xc3\xb2\x05\x9a[\x00\x9a@\x04\x9b\x17C\xef`\x02+_\xd1 \x003\x00'
|
||||
b'\x1f"/\xe0\x01!@\x00\x19@\x08C\x01:[\x08\x85\xe7\x01!@\x00\x19@\x08C\x01:'
|
||||
b'[\x08\x8e\xe7\x01!@\x00\x19@\x08C\x01:[\x08\xa0\xe7\x01!@\x00\x19@\x08C\x01:'
|
||||
b'[\x08\xa9\xe7\x01!@\x00\x19@\x08C\x01:[\x08\xb7\xe7\x01!@\x00\x19@\x08C\x01:'
|
||||
b'[\x08\xc0\xe7\x01!@\x00\x19@\x08C\x01:[\x08\x00+\xf7\xd1\x02\x9b\x90@'
|
||||
b'[i\x04\x935\xd0\x00\xf0\x81\xf9\x07(1\xdc \x003\x00\x1f"/j\x00+\x1d\xd1\x90@'
|
||||
b' 3\x00(\x02\xd0\x00\xf0s\xf9\xc3\xb2\x0f"\x9b\x00\x9a@\x1f#\x97C\x00.'
|
||||
b'\x16\xd1 \x00\x98@ #\x00(\x02\xd0\x00\xf0d\xf9\xc3\xb2\x04\x9a\x9b\x00\x9a@'
|
||||
b'\x17C/b\x03\x9b\x013\x00\xe7\x01!@\x00\x19@\x08C\x01:[\x08\xd8\xe7\x01 d\x00'
|
||||
b'0@\x04C\x01;v\x08\xdf\xe7&\nd\n0\x00#\x00\x1f"oj\x00+\x1b\xd1\x90@ 3\x00('
|
||||
b'\x02\xd0\x00\xf0?\xf9\xc3\xb2\x0f"\x9b\x00\x9a@\x1f#\x97C\x00,\x14\xd10\x00'
|
||||
b'\x98@ #\x00(\x02\xd0\x00\xf00\xf9\xc3\xb2\x04\x9a\x9b\x00\x9a@\x17Cob'
|
||||
b'\x00\x00\x00\x00\x00\x00\x00\x00U\x01\x00\x08\x00\x00\x00\x00U\x01\x00\x08'
|
||||
b'U\x01\x00\x08U\x01\x00\x08\x00\x00\x00\x00U\x01\x00\x08\x00\x00\x00\x00'
|
||||
b'U\x01\x00\x08U\x01\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
|
||||
b'\x10\xb5\x06L#x\x00+\x07\xd1\x05K\x00+\x02\xd0\x04H\x00\xe0\x00\xbf\x01#'
|
||||
b'#p\x10\xbd\x08\x00\x00 \x00\x00\x00\x00\xa0\r\x00\x08\x04K\x10\xb5'
|
||||
b'\x00+\x03\xd0\x03I\x04H\x00\xe0\x00\xbf\x10\xbd\xc0F\x00\x00\x00\x00'
|
||||
b'\x0c\x00\x00 \xa0\r\x00\x08\x0cH\x85F\x00\xf0\x96\xf9\x00!\x03\xe0\nK[X'
|
||||
b'CP\x041\tH\nKB\x18\x9aB\xf6\xd3\tJ\x02\xe0\x00#\x13`\x042\x07K\x9aB'
|
||||
b'\xf9\xd3\x00\xf0\xc7\xf9\xfe\xe7\x00\x18\x00 \x00\x00\x00 \x00\x00\x00 '
|
||||
b'\x08\x00\x00 \x08\x00\x00 D\x00\x00 \xfe\xe7\x00\x00\x00\xb5\x89\xb0'
|
||||
b'\x14"\x00!\x03\xa8\x00\xf0\xc7\xfd\x01 \tJQk\x01CQcSk\x02\xa9\x03@\x01\x93'
|
||||
b'\x01\x9b?#\x9f0\x02\x93\xc0\x05=;\x04\x93\x00\xf0\xcc\xfb\t\xb0\x00\xbd\xc0F'
|
||||
b'\x00\x10\x02@\x10\xb5\x02$ K!IZm\x88\xb0\n@ZeZk\x00!"CZc[k\x0c"#@\x00\x93'
|
||||
b'\x03\xa8\x00\x9b\x00\xf0\x9c\xfd\xc0#\x01\x93\xbf;\x04\x93\x01\xa9\x053'
|
||||
b'\x16H\x06\x93\x02\x94\x00\xf0\xa8\xfb\x1c"\x00!\x01\xa8\x00\xf0\x8c\xfd'
|
||||
b'\x12K\x13L\x02\x93\xca# \x00\x01\xa9\x05\x93\x00\xf0+\xfd\x80#bh\x9b\x04'
|
||||
b'\x13Cc`\xe3h\rJ\x13@\xe3`\xe3h\x0cJ\x13@\xe3`#h\x0bJ\x13@#`#h\nJ\x13@#`'
|
||||
b'\x08\xb0\x10\xbd\x00\x10\x02@\xff\xcf\xff\xff\x00\x04\x00P\x13\x04\x10\x00'
|
||||
b'\x00T\x00@\x01\xf8\xff\xff\xff\x7f\xff\xff\xff\xff\xf7\xff\xff\xff\xfd\xff'
|
||||
b'\x80#\x03J[\x02\x11h\x0bC\x13`pG\xc0F\x00 \x02@\x08#\xf7\xb5jLkJ\xa1i\x19B'
|
||||
b'\x10\xd0\xe1i\x0bC\x80!\xe3a\xa3iI\x02\x0b@\x19\x00H\x1e\x81A\x11p\x00+$\xd1'
|
||||
b'cI\x0bpcI\x0bp\x13x\xa1i\x01\x93`K\x1fx`K\x1dx #\x19B4\xd0\xe2i\x13C'
|
||||
b'\xe3a\x01\x9b\x00+.\xd1[N3pc/[\xd0\x10\xd8a/\x00\xd1r\xe0b/L\xd0V/\x15\xd0'
|
||||
b'VKWJ\x1a`\x08#C\xe0#hUI\x0b@#`\xd9\xe7t/\x00\xd1l\xe0PKv/3\xd0p/\xed\xd1PJ5p'
|
||||
b'\x1a`\x08\xe0\x00-h\xd1NHJK\x18`\x00\xf0\x07\xfd\x0100p\x01#\xa2i\x13C'
|
||||
b'\xa3a\x00"\x04#\x11\x00\x9cF\x01 fF\xa3i3BY\xd1\x00)\x01\xd0<K\x1fp'
|
||||
b"\x00*\x01\xd0;K\x1dp\xff'\x00%\x02&\xbcF9H:I\x03x\nh\x01\x9f\x00/X\xd1\x00-"
|
||||
b'\x01\xd0\x03p\n`\xf7\xbd\x00-:\xd18J\x1a`\x06#3p\xd3\xe7\x00-3\xd1\xff\xf7'
|
||||
b's\xff5K.J\x13`\x03#\xf4\xe7\x04-*\xd1.I2J\x0bxSpKx\x93p\x8bxXBXA^\x1e'
|
||||
b'\xb3A\xc0\x00\x9b\x00\x03C\xc8xA\x1e\x88A=!\x00\x01\x03C\x10x\x88C\x03C\x13p'
|
||||
b'\xaf\xe7\x00-\x0f\xd1\r"$I\x0bx\x93C\x1a\x00\x01#\x13C\x0bp\xa4\xe7'
|
||||
b'\x00-\x04\xd1\x02#\x1fJ\x11x\x0bC\xeb\xe7\x16K\x1dJ\x1a`\t#\xc2\xe7'
|
||||
b'cj\xdb\xb2\x00/\x07\xd0\x07-\x9b\xd8\x13Nj\x1csU\xd5\xb2\x02\x00\x95\xe7'
|
||||
b'\x1f\x00\x01\x00\x92\xe7gF\xa7b\xa3\xe7\xa7i7B\xa3\xd0\x00+\xf7\xd0\x15x'
|
||||
b'\x01;\xa5b\x012\x01\x9d\xdb\xb2\x97\xe7\x00T\x00@.\x00\x00 -\x00\x00 '
|
||||
b'$\x00\x00 4\x00\x00 0\x00\x00 5\r\x00\x08\xff\xff\xfe\xff%\x00\x00 '
|
||||
b'p\r\x00\x08,\r\x00\x082\r\x00\x08<\x00\x00 >\r\x00\x08\x80"\x1aK'
|
||||
b'\x12\x05\x9a`\x80"\x19KR\x00\x19h\nC\x1a`\x80"\xd2\x00\x19h\x11B\xfc\xd0Zh'
|
||||
b'\x14I\x11@\x80"\xd2\x01\nCZ`\x1ah\x12I\x11@\x80"R\x01\nC\x1a`\x9ah\x0fI\n@'
|
||||
b'\x07!\x9a`\x9ah\x8aC\x9a`8"\x99h\x08\x00\x10@\x11B\xfa\xd1\x9ah\tI\n@'
|
||||
b'\x9a`\tK\tJZ`\x05"\x98`\x1a`pG\x00\xed\x00\xe0\x00\x10\x02@\xff\x80\xff\xff'
|
||||
b'\xff\xc7\xff\xff\xff\xf0\xff\xff\xff\x8f\xff\xff\x10\xe0\x00\xe0'
|
||||
b'\xdf.\x00\x00\x18Ks\xb5\x19l\x18H\xa0$\x01C\x19d\x81!\x01&\x1alI\x05\x02@'
|
||||
b'\x01\x92\x01\x9a\xdak\xe4\x05\nC\xdac\xdbk\x0b@\x00\x93\x00\x9b\xff\xf70\xfe'
|
||||
b'\x00\xf0\xbc\xf8\xff\xf7J\xfe\x0cJ\rI\x13h\x0b@\x13`\xff\xf7\xa3\xfe#i'
|
||||
b'3B\xfa\xd1 %#i+B\xf6\xd0\x00\xf0\x92\xf9#i+B\xf1\xd0\xff\xf7\x95\xfe\xf9\xe7'
|
||||
b'\x00\x10\x02@\x01\x10\x00\x00\x00 \x02@\xff\xff\xfe\xff\xa0#\x10"'
|
||||
b'\x08!\xdb\x05\x10\xb5\x9aa\x99b\x9ab\xc0#[\x01\x1c\x00\x08J\x91h\x19@'
|
||||
b'\xa1B\xfb\xd0\x10s\x91h\x19B\xfc\xd1\xa0#\x10"\xdb\x05\x9aa\x08:\x9aa'
|
||||
b'\x10\xbd\xc0F\x000\x01@\xa0#0\xb5\x10"\x08$\xdb\x05\x9aa\x9ca\x9ab\xc0"\x00#'
|
||||
b'\tLR\x01\x98B\x07\xdc\xa3h\x13B\xfc\xd1\xa0#\x10"\xdb\x05\x9aa0\xbd'
|
||||
b'\xa5h\x15@\x95B\xfb\xd0\xcd\\\x013%s\xed\xe7\x000\x01@s\xb5\x0e\x00'
|
||||
b'\x1d\x00\x01:\x83\xb2\x9a\x18\x01\xac\x92\xb2\x1b\n#p`p\x13\n* \xa3p'
|
||||
b'\xe2p\xff\xf7\xb1\xff!\x00\x04 \xff\xf7\xcb\xff\x01=\xb2\xb2U\x19'
|
||||
b'\xad\xb2\x12\n"p+ *\n\xa2pfp\xe5p\xff\xf7\xa0\xff!\x00\x04 \xff\xf7\xba\xff'
|
||||
b', \xff\xf7\x99\xffs\xbd\xa0#p\xb5\x10"\x08$\xdb\x05\x9aa\x9ca\x9ab'
|
||||
b'\xc0#\xce\xb2\xe1@\x00$\x0bJ[\x01\xa0B\x07\xdc\x91h\x19B\xfc\xd1\xa0#'
|
||||
b'\x10"\xdb\x05\x9aap\xbd\x95h\x1d@\x9dB\xfb\xd0\x16s\x95h\x1d@\x9dB'
|
||||
b'\xfb\xd0\x11s\x014\xe9\xe7\x000\x01@p\xb5\x1c\x00\x04\xab\x1e\x88'
|
||||
b'#\x00\x15\x00\xff\xf7\xa8\xff \x001\x00hC\xff\xf7\xcd\xffp\xbd'
|
||||
b'\x10\xb5\x8a\xb0\x1c"\x00!\x03\xa8\x00\xf09\xfb\xc0#\x1b\x02\x00\x93'
|
||||
b'\x82#[\x00\x01\x93\xe0#\xdb\x00\x02\x93\x80#\tLiF\x9b\x00 \x00\x05\x93'
|
||||
b'\x00\xf0\x92\xfa@#"h\x13C#`\x01#\x04J\x11x\x0bC\x13p\n\xb0\x10\xbd\xc0F'
|
||||
b'\x000\x01@<\x00\x00 \xf7\xb5\x16\x00\x08\xaa\x12x\x94F!(0\xdc\t).\xdc\x16%'
|
||||
b'\t"MCPC)\x00bF\x12$\xc7\x1d\x0f1\x00*\x00\xd1\t<\x00+.\xd1\x00.'
|
||||
b'\x1f\xd0\x1e\x00\x01#"\x008\x00\x00\x96\xff\xf7\xaa\xff)\x00\x01#"\x008\x00'
|
||||
b'$1\x105\x00\x96\xff\xf7\xa1\xff\x14#\x01")\x008\x00\x00\x96\xff\xf7\x9a\xff'
|
||||
b'\x14#\x01")\x008\x19\x018\x00\x96\xff\xf7\x92\xff\xf7\xbd\x08K"\x00\x00\x93'
|
||||
b'8\x00\x16#\xf6\xe7)\x00\x14#\xa2\x1e\x101\x080\x00\x96\xef\xe7\x00.\xf6\xd0'
|
||||
b'\x00N\xcf\xe7\xfd`\x00\x00\xf7\xb5\x1dKR!\x00\xaf\x9dDnF\x00"\x06$\x1aH\xff1'
|
||||
b'\x13\x00#@]BkA\x18M[B\x03@[\x19U\x00\x012sS\x8aB\xf2\xd1\x03#\xa0"\xed!'
|
||||
b'\x00 [BR\x00\xff\xf7\x0f\xff\x03$\x10M\xa0 +h\x80\x00{`\x0f#zh\x01<'
|
||||
b'\x99\x1aI\x00q\x18\xff\xf7\xe1\xfe\x00,\xf0\xd1{h\tJ\x013\x13@\x04\xd5'
|
||||
b'\x10"\x01;RB\x13C\x013\xbdF+`\xf7\xbdX\xfd\xff\xff\x03\x9f\xff\xff'
|
||||
b'\xfd`\x00\x00@\x00\x00 \x0f\x00\x00\x80\xf8\xb5\x14K\x00\xaf\x9dDlF\x80 '
|
||||
b'"\x00\x00!\x06\x00\x11K[\\\x03@\x1d\x00kBkA[B\x13\x80@\x08\x14\xd1\x011'
|
||||
b'()\x10\xd1\xa0"x#\xa0&R\x00\xff\xf7\xcc\xfex%\xb6\x00!\x000\x00\x01=\xff\xf7'
|
||||
b'\xa5\xfe\x00-\xf8\xd1\xbdF\xf8\xbd0\x00\x022\xde\xe7\x80\xfd\xff\xff'
|
||||
b'H\r\x00\x08\xf0\xb5\x89\xb0\x0c"\x00!\x05\xa8\x00\xf0Q\xfa\xa0 \x06#\x03%'
|
||||
b'\x02$\x02\xa9\xc0\x05\x02\x93\x03\x94\x04\x95\x00\xf0]\xf8\x18#\xa0 '
|
||||
b'\x02\x93\x17;\x03\x93\x00#\x02\xa9\xc0\x05\x06\x93\x05\x93\x07\x93\x04\x95'
|
||||
b'\x00\xf0O\xf8!N3x#B\x04\xd0\xff\xf7\xac\xff3x\xa3C3p3x\xdb\x07\x01\xd5'
|
||||
b'\xff\xf7^\xff\x0c#7x\x1fB"\xd0\x19M,h\x00,\x14\xd1\xbb\x06:\x07'
|
||||
b'\xff\x06\xff\x0f\xb1xpx\xdb\x0f\xd2\x0f\x00\x97\xff\xf7\xff\xfe\x01"'
|
||||
b'3x\x99\x06\xc9\x0f\x8aC !R\x01\x8bC\x13C3p\x0eJc\x1c\x13@\x04\xd5 "\x01;RB'
|
||||
b'\x13C\x013+`\x14"\x00!\x03\xa8\x00\xf0\xfe\xf9\xa0 \x1e#\x02\xa9\xc0\x05'
|
||||
b'\x02\x93\x00\xf0\x0e\xf8\t\xb0\xf0\xbd\xc0F<\x00\x00 8\x00\x00 '
|
||||
b'\x1f\x00\x00\x80\xfe\xe7\xfe\xe7pGpGpG\xf0\xb5\x87\xb0\x0bh\x02\x91\x1f"'
|
||||
b'\x01!\x01\x93\x05\x00\x01\x98[\x08\x00+\x1e\xd1\x90@ 3\x00(\x02\xd0\x00\xf0'
|
||||
b'\xb9\xf9\xc3\xb2\x03\x93\x02\x9b\x03\x9a[h\x04\x93\x01\x9b\xd3@\x16\xd1'
|
||||
b'\x04\x9b\x01;\x01+\x08\xd8kh\x01\x9a\x01\x99\x93C\x02\x9a\xd2hJC\x13Ck`\x00 '
|
||||
b'\x07\xb0\xf0\xbd\x1c\x00@\x00\x0c@ C\x01:[\x08\xd7\xe7\x01#\x03\x9a\x01\x9c'
|
||||
b'\x93@\x01\x9a\x1c@\x1aB\x00\xd1\xd3\xe0f\x08 \x003\x00\x1f"/h\x00+p\xd1\x90@'
|
||||
b' 3\x00(\x02\xd0\x00\xf0\x83\xf9\xc3\xb2\x03"[\x00\x9a@ \x00\x97C3\x00'
|
||||
b'\x1f"\x00+g\xd1\x90@ 3\x00(\x02\xd0\x00\xf0s\xf9\xc3\xb2\x04\x9a[\x00'
|
||||
b'\x9a@\x04\x9b\x17C\x01;/`\x01+$\xd8\x02\x9b \x00\x9bh\x1f"\x05\x933\x00\xafh'
|
||||
b'\x00+U\xd1\x90@ 3\x00(\x02\xd0\x00\xf0Z\xf9\xc3\xb2\x03"[\x00\x9a@ \x00\x97C'
|
||||
b'3\x00\x1f"\x00+L\xd1\x90@ 3\x00(\x02\xd0\x00\xf0J\xf9\xc3\xb2\x05\x9a'
|
||||
b'[\x00\x9a@\x17C\xaf`\x02\x9b \x00\x1bi\x1f"\x05\x933\x00\xefh\x00+>\xd1\x90@'
|
||||
b' 3\x00(\x02\xd0\x00\xf05\xf9\xc3\xb2\x03"[\x00\x9a@ \x00\x97C3\x00\x1f"\x00+'
|
||||
b'5\xd1\x90@ 3\x00(\x02\xd0\x00\xf0%\xf9\xc3\xb2\x05\x9a[\x00\x9a@\x04\x9b'
|
||||
b'\x17C\xef`\x02+_\xd1 \x003\x00\x1f"/\xe0\x01!@\x00\x19@\x08C\x01:[\x08'
|
||||
b'\x85\xe7\x01!@\x00\x19@\x08C\x01:[\x08\x8e\xe7\x01!@\x00\x19@\x08C\x01:[\x08'
|
||||
b'\xa0\xe7\x01!@\x00\x19@\x08C\x01:[\x08\xa9\xe7\x01!@\x00\x19@\x08C\x01:[\x08'
|
||||
b'\xb7\xe7\x01!@\x00\x19@\x08C\x01:[\x08\xc0\xe7\x01!@\x00\x19@\x08C\x01:[\x08'
|
||||
b'\x00+\xf7\xd1\x02\x9b\x90@[i\x04\x935\xd0\x00\xf0\xdf\xf8\x07(1\xdc \x00'
|
||||
b'3\x00\x1f"/j\x00+\x1d\xd1\x90@ 3\x00(\x02\xd0\x00\xf0\xd1\xf8\xc3\xb2'
|
||||
b'\x0f"\x9b\x00\x9a@\x1f#\x97C\x00.\x16\xd1 \x00\x98@ #\x00(\x02\xd0'
|
||||
b'\x00\xf0\xc2\xf8\xc3\xb2\x04\x9a\x9b\x00\x9a@\x17C/b\x03\x9b\x013'
|
||||
b'\x00\xe7\x01!@\x00\x19@\x08C\x01:[\x08\xd8\xe7\x01 d\x000@\x04C\x01;v\x08'
|
||||
b'\xdf\xe7&\nd\n0\x00#\x00\x1f"oj\x00+\x1b\xd1\x90@ 3\x00(\x02\xd0\x00\xf0'
|
||||
b'\x9d\xf8\xc3\xb2\x0f"\x9b\x00\x9a@\x1f#\x97C\x00,\x14\xd10\x00\x98@ #'
|
||||
b'\x00(\x02\xd0\x00\xf0\x8e\xf8\xc3\xb2\x04\x9a\x9b\x00\x9a@\x17Cob'
|
||||
b'\xca\xe7\x01!@\x00\x19@\x08C\x01:[\x08\xda\xe7\x01 v\x00 @\x06C\x01;d\x08'
|
||||
b'\xe1\xe7\x00\x00\x03h\x02\x00p\xb5\x01 [\x06,\xd4Nh\x0bhHi3C\xceh\x15h'
|
||||
b'3C\x0ei\x0cj3C\x8ei\x03C3C\xcei\x00\x0c3C\x10N#C5@+C\x13`Sh\x8dh\x0eN(C3@'
|
||||
@ -114,27 +137,15 @@ BINARY = (b'\x00\x18\x00 \t\x01\x00\x08\x99\x06\x00\x08\x9b\x06\x00\x08\x00\x00\
|
||||
b'\x04h+C\x14M,@#C\x03`Kh\x13L\x03a\x03h\ri\x1aC\x02`\x83h\x8ai#@\x83`\x83h'
|
||||
b'*C\xdb\n\xdb\x02\x1aC\x82`\x00-\x04\xd0\x80#\x82h\x1b\x02\x13C\x83`'
|
||||
b'\x02h\x08K\x1a@\x0bh\x1aC\x02`ChJi#@\x13CC`\x00 0\xbd\xc0F\xff\xe0\xff\xff'
|
||||
b'\xff\x7f\xff\xff\xff\xff\xcf\xff\xfa!\x10\xb5\x89\x00\x00\xf0\x11\xf8\x00"'
|
||||
b'\x03K\x018X`\x9a`\x052\x1a`\x10\xbd\xc0F\x10\xe0\x00\xe0\x01K\x18`pG\xc0F'
|
||||
b'\x00\x00\x00 \x00"C\x08\x8bBt\xd3\x03\t\x8bB_\xd3\x03\n\x8bBD\xd3'
|
||||
b'\x03\x0b\x8bB(\xd3\x03\x0c\x8bB\r\xd3\xff"\t\x02\x12\xba\x03\x0c'
|
||||
b'\x8bB\x02\xd3\x12\x12\t\x02e\xd0\x03\x0b\x8bB\x19\xd3\x00\xe0\t\n'
|
||||
b'\xc3\x0b\x8bB\x01\xd3\xcb\x03\xc0\x1aRA\x83\x0b\x8bB\x01\xd3\x8b\x03'
|
||||
b'\xc0\x1aRAC\x0b\x8bB\x01\xd3K\x03\xc0\x1aRA\x03\x0b\x8bB\x01\xd3\x0b\x03'
|
||||
b'\xc0\x1aRA\xc3\n\x8bB\x01\xd3\xcb\x02\xc0\x1aRA\x83\n\x8bB\x01\xd3\x8b\x02'
|
||||
b'\xc0\x1aRAC\n\x8bB\x01\xd3K\x02\xc0\x1aRA\x03\n\x8bB\x01\xd3\x0b\x02'
|
||||
b'\xc0\x1aRA\xcd\xd2\xc3\t\x8bB\x01\xd3\xcb\x01\xc0\x1aRA\x83\t\x8bB\x01\xd3'
|
||||
b'\x8b\x01\xc0\x1aRAC\t\x8bB\x01\xd3K\x01\xc0\x1aRA\x03\t\x8bB\x01\xd3'
|
||||
b'\x0b\x01\xc0\x1aRA\xc3\x08\x8bB\x01\xd3\xcb\x00\xc0\x1aRA\x83\x08'
|
||||
b'\x8bB\x01\xd3\x8b\x00\xc0\x1aRAC\x08\x8bB\x01\xd3K\x00\xc0\x1aRAA\x1a'
|
||||
b'\x00\xd2\x01FRA\x10FpG\xff\xe7\x01\xb5\x00 \x00\xf0\x06\xf8\x02\xbd\xc0F'
|
||||
b'\x00)\xf7\xd0v\xe7pGpG\xc0F\x1c!\x01#\x1b\x04\x98B\x01\xd3\x00\x0c'
|
||||
b'\xff\x7f\xff\xff\xff\xff\xcf\xff\x1c!\x01#\x1b\x04\x98B\x01\xd3\x00\x0c'
|
||||
b'\x109\x1b\n\x98B\x01\xd3\x00\n\x089\x1b\t\x98B\x01\xd3\x00\t\x049\x02\xa2'
|
||||
b'\x10\\@\x18pG\xc0F\x04\x03\x02\x02\x01\x01\x01\x01\x00\x00\x00\x00'
|
||||
b'\x00\x00\x00\x00\x03\x00\x82\x18\x93B\x00\xd1pG\x19p\x013\xf9\xe7\x00#\xc2\\'
|
||||
b'\x013\x00*\xfb\xd1X\x1epG\x00\x00\xf8\xb5\xc0F\xf8\xbc\x08\xbc\x9eFpG'
|
||||
b'\xf8\xb5\xc0F\xf8\xbc\x08\xbc\x9eFpG1.0.0\x00OK\x00Bad cmd?\x001.0.0 time'
|
||||
b'=20230728.120528 git=q1@d86d521 DEV=1\x00\x00\x00\x00\x00\x00\x00'
|
||||
b'\x00\x1b\xb7\x00\xe9\x00\x00\x08\xc1\x00\x00\x08')
|
||||
b'\xf8\xb5\xc0F\xf8\xbc\x08\xbc\x9eFpG1.1.0\x00OK\x00Bad cmd?\x00Bad args?\x00'
|
||||
b'\x00\x00\x00\x00\x00\x00\x00?\x1c\x0e\x00\x1f\x8e\x00\xe0\x0f'
|
||||
b'\xf8\xff\x8f\xc7\xe3\xfe?\xe3\xf1\xf8\xff\xf1\xf8\x03\xfe8\xfc\x00\x00\x00'
|
||||
b'\x00\x00\x00\x001.1.0 time=20230801.083144 git=q1@f6b50e1 DEV=1\x00'
|
||||
b'\x00\x00\x00\x00\xe9\x00\x00\x08\xc1\x00\x00\x08')
|
||||
|
||||
# EOF
|
||||
|
||||
161
misc/gpu/lcd.c
161
misc/gpu/lcd.c
@ -10,6 +10,7 @@
|
||||
#include "lcd.h"
|
||||
#include <string.h>
|
||||
#include "stm32c0xx_hal_gpio_ex.h"
|
||||
#include "barcode.h"
|
||||
|
||||
lcd_state_t lcd_state;
|
||||
|
||||
@ -20,7 +21,8 @@ const int NUM_PIXELS = (LCD_WIDTH*LCD_HEIGHT);
|
||||
// doing RGB565, but swab16
|
||||
const uint16_t COL_BLACK = 0;
|
||||
const uint16_t COL_WHITE = ~0;
|
||||
const uint16_t COL_FOREGROUND = 0x60fd; //SWAB16(0xfd60); // orange
|
||||
const uint16_t COL_RED = 0x00f8; //SWAP16(0xf800);
|
||||
const uint16_t COL_FOREGROUND = 0x60fd; //SWAB16(0xfd60); // brand orange
|
||||
|
||||
// progress bar specs
|
||||
const uint16_t PROG_HEIGHT = 3;
|
||||
@ -28,9 +30,7 @@ const uint16_t PROG_Y = LCD_HEIGHT - PROG_HEIGHT;
|
||||
|
||||
static const int NUM_PHASES = 16;
|
||||
|
||||
// forward refs
|
||||
void lcd_write_rows(int y, int num_rows, uint16_t *pixels);
|
||||
|
||||
#if 0
|
||||
// memset2()
|
||||
//
|
||||
static inline void
|
||||
@ -52,6 +52,7 @@ static inline void wait_vsync(void) {
|
||||
}
|
||||
//puts("TEAR timeout");
|
||||
}
|
||||
#endif
|
||||
|
||||
// write_byte()
|
||||
//
|
||||
@ -87,6 +88,31 @@ write_bytes(int len, const uint8_t *buf)
|
||||
}
|
||||
}
|
||||
|
||||
// write_uint16()
|
||||
//
|
||||
static inline void
|
||||
write_uint16(int count, uint16_t val)
|
||||
{
|
||||
uint8_t a = val & 0xff;
|
||||
uint8_t b = val >> 8;
|
||||
|
||||
for(int n=0; n<count; n++) {
|
||||
while(LL_SPI_GetTxFIFOLevel(SPI1) == LL_SPI_TX_FIFO_FULL) {
|
||||
// wait for space
|
||||
}
|
||||
LL_SPI_TransmitData8(SPI1, a);
|
||||
|
||||
while(LL_SPI_GetTxFIFOLevel(SPI1) == LL_SPI_TX_FIFO_FULL) {
|
||||
// wait for space
|
||||
}
|
||||
LL_SPI_TransmitData8(SPI1, b);
|
||||
}
|
||||
|
||||
while(LL_SPI_GetTxFIFOLevel(SPI1) != LL_SPI_TX_FIFO_EMPTY) {
|
||||
// wait for FIFO to drain completely
|
||||
}
|
||||
}
|
||||
|
||||
// lcd_write_cmd()
|
||||
//
|
||||
static void
|
||||
@ -117,6 +143,20 @@ lcd_write_data(int len, const uint8_t *pixels)
|
||||
LL_GPIO_SetOutputPin(GPIOA, PIN_CS);
|
||||
}
|
||||
|
||||
// lcd_write_constant()
|
||||
//
|
||||
void
|
||||
lcd_write_constant(int len, const uint16_t pixel)
|
||||
{
|
||||
LL_GPIO_SetOutputPin(GPIOA, PIN_CS);
|
||||
LL_GPIO_SetOutputPin(GPIOA, PIN_DATA_CMD);
|
||||
LL_GPIO_ResetOutputPin(GPIOA, PIN_CS);
|
||||
|
||||
write_uint16(len, pixel);
|
||||
|
||||
LL_GPIO_SetOutputPin(GPIOA, PIN_CS);
|
||||
}
|
||||
|
||||
// lcd_write_cmd4()
|
||||
//
|
||||
static void
|
||||
@ -161,19 +201,22 @@ lcd_setup(void)
|
||||
LL_SPI_Init(SPI1, &init);
|
||||
LL_SPI_Enable(SPI1);
|
||||
|
||||
// debug values?
|
||||
// usually want the busy bar
|
||||
lcd_state.activity_bar = true;
|
||||
|
||||
#if 0
|
||||
// debug values
|
||||
lcd_state.cursor_x = 9;
|
||||
lcd_state.cursor_y = 2;
|
||||
lcd_state.outline_cursor = true;
|
||||
#else
|
||||
#endif
|
||||
#if 0
|
||||
lcd_state.dbl_wide = true;
|
||||
lcd_state.cursor_x = 16;
|
||||
lcd_state.cursor_y = 4;
|
||||
lcd_state.solid_cursor = true;
|
||||
#endif
|
||||
//lcd_state.outline_cursor = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
// take_control()
|
||||
@ -244,11 +287,9 @@ send_window(int x, int y, int w, int h, const void *data)
|
||||
static void
|
||||
send_solid(int x, int y, int w, int h, uint16_t pixel)
|
||||
{
|
||||
// NOTE: stack size limit here
|
||||
uint16_t buf[w*h];
|
||||
memset2(buf, pixel, sizeof(buf));
|
||||
send_window(x, y, w, h, NULL);
|
||||
|
||||
send_window(x, y, w, h, buf);
|
||||
lcd_write_constant(w*h, pixel);
|
||||
}
|
||||
|
||||
// cursor_draw()
|
||||
@ -264,9 +305,9 @@ cursor_draw(int char_x, int char_y, bool outline, bool phase, bool dbl_wide)
|
||||
const int CELL_W = 9;
|
||||
const int CELL_H = 22;
|
||||
|
||||
ASSERT(char_x < CHARS_W);
|
||||
ASSERT(char_y < CHARS_H);
|
||||
STATIC_ASSERT(CELL_H > 2*CELL_W); // for dbl_wide case
|
||||
// no error reporting.. but dont die either
|
||||
if(char_x >= CHARS_W) return;
|
||||
if(char_y >= CHARS_H) return;
|
||||
|
||||
// top left corner, just on edge of character cell
|
||||
int x = LEFT_MARGIN + (char_x * CELL_W);
|
||||
@ -274,18 +315,16 @@ cursor_draw(int char_x, int char_y, bool outline, bool phase, bool dbl_wide)
|
||||
int cell_w = CELL_W + (dbl_wide?CELL_W:0);
|
||||
|
||||
// make some pixels big enough for either vert or horz lines
|
||||
uint16_t colour = phase ? COL_FOREGROUND : COL_BLACK;
|
||||
uint16_t row[CELL_H];
|
||||
memset2(row, colour, sizeof(row));
|
||||
uint16_t colour = phase ? COL_FOREGROUND : COL_BLACK;
|
||||
|
||||
if(outline) {
|
||||
// horz
|
||||
send_window(x,y, cell_w, 1, &row);
|
||||
send_window(x,y+CELL_H-1, cell_w, 1, &row);
|
||||
send_solid(x,y, cell_w, 1, colour);
|
||||
send_solid(x,y+CELL_H-1, cell_w, 1, colour);
|
||||
|
||||
// vert
|
||||
send_window(x, y+1, 1, CELL_H-2, &row);
|
||||
send_window(x+cell_w-1, y+1, 1, CELL_H-2, &row);
|
||||
send_solid(x, y+1, 1, CELL_H-2, colour);
|
||||
send_solid(x+cell_w-1, y+1, 1, CELL_H-2, colour);
|
||||
} else {
|
||||
if(!phase) {
|
||||
// solid fill -- draw first time
|
||||
@ -297,31 +336,14 @@ cursor_draw(int char_x, int char_y, bool outline, bool phase, bool dbl_wide)
|
||||
}
|
||||
}
|
||||
|
||||
// lcd_show_raw()
|
||||
//
|
||||
// No decompression. Just used for factory show. 1k bytes
|
||||
//
|
||||
void
|
||||
lcd_show_raw(uint32_t len, const uint8_t *pixels)
|
||||
{
|
||||
// 1024 / 2 = 512 / 320 = 1.6 => just one row!
|
||||
lcd_write_rows(LCD_HEIGHT-3, 1, (uint16_t *)pixels);
|
||||
lcd_write_rows(LCD_HEIGHT-2, 1, (uint16_t *)pixels);
|
||||
}
|
||||
|
||||
// lcd_fill_solid()
|
||||
//
|
||||
void
|
||||
lcd_fill_solid(uint16_t pattern)
|
||||
{
|
||||
// whole screen
|
||||
send_window(0, 0, LCD_WIDTH, LCD_HEIGHT, NULL);
|
||||
|
||||
uint16_t row[LCD_WIDTH];
|
||||
memset2(row, pattern, sizeof(row));
|
||||
|
||||
for(int y=0; y<LCD_HEIGHT; y++) {
|
||||
lcd_write_data(sizeof(row), (uint8_t *)&row);
|
||||
}
|
||||
lcd_write_constant(LCD_WIDTH*LCD_HEIGHT, pattern);
|
||||
}
|
||||
|
||||
// lcd_draw_progress()
|
||||
@ -331,18 +353,13 @@ lcd_draw_progress(void)
|
||||
{
|
||||
static int phase = 0;
|
||||
|
||||
uint16_t row[LCD_WIDTH + NUM_PHASES + 1];
|
||||
uint16_t row[LCD_WIDTH + NUM_PHASES + 1];
|
||||
|
||||
for(int i=0; i<numberof(row); i++) {
|
||||
row[i] = ((i % 8) < 2) ? COL_BLACK : COL_FOREGROUND;
|
||||
}
|
||||
|
||||
send_window(0, PROG_Y, LCD_WIDTH, PROG_Y-LCD_HEIGHT, NULL);
|
||||
#if 0
|
||||
lcd_write_cmd4(0x2a, 0, LCD_WIDTH-1); // CASET - Column address set range (x)
|
||||
lcd_write_cmd4(0x2b, PROG_Y, LCD_HEIGHT-1); // RASET - Row address set range (y)
|
||||
lcd_write_cmd(0x2c); // RAMWR - memory write
|
||||
#endif
|
||||
|
||||
for(int y=0; y<PROG_HEIGHT; y++) {
|
||||
lcd_write_data(LCD_WIDTH*2, (uint8_t *)(&row[NUM_PHASES - phase - 1]));
|
||||
@ -351,22 +368,6 @@ lcd_draw_progress(void)
|
||||
phase = (phase + 1) % NUM_PHASES;
|
||||
}
|
||||
|
||||
// lcd_write_rows()
|
||||
//
|
||||
void
|
||||
lcd_write_rows(int y, int num_rows, uint16_t *pixels)
|
||||
{
|
||||
send_window(0, y, LCD_WIDTH, num_rows, pixels);
|
||||
#if 0
|
||||
lcd_write_cmd4(0x2a, 0, LCD_WIDTH-1); // CASET - Column address set range (x)
|
||||
lcd_write_cmd4(0x2b, y, LCD_HEIGHT-1); // RASET - Row address set range (y) [wrong, works]
|
||||
lcd_write_cmd(0x2c); // RAMWR - memory write
|
||||
|
||||
lcd_write_data(num_rows * 2 * LCD_WIDTH, (uint8_t *)pixels);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// lcd_animate()
|
||||
//
|
||||
// Called at LCD frame rate, when we have control over LCD.
|
||||
@ -376,6 +377,11 @@ lcd_animate(void)
|
||||
{
|
||||
take_control();
|
||||
|
||||
if(lcd_state.test_pattern) {
|
||||
lcd_test_pattern();
|
||||
lcd_state.test_pattern = false;
|
||||
}
|
||||
|
||||
if(lcd_state.activity_bar) {
|
||||
lcd_draw_progress();
|
||||
}
|
||||
@ -386,6 +392,7 @@ lcd_animate(void)
|
||||
if(cur_phase == 0) {
|
||||
cursor_draw(lcd_state.cursor_x, lcd_state.cursor_y,
|
||||
lcd_state.outline_cursor, lcd_state.cur_flash, lcd_state.dbl_wide);
|
||||
|
||||
lcd_state.cur_flash = !lcd_state.cur_flash;
|
||||
}
|
||||
|
||||
@ -395,4 +402,34 @@ lcd_animate(void)
|
||||
release_control();
|
||||
}
|
||||
|
||||
// lcd_test_pattern()
|
||||
//
|
||||
void
|
||||
lcd_test_pattern(void)
|
||||
{
|
||||
// NOTE: this is very limited so it cannot be abused to show arbitrary things
|
||||
// - take packed pixels in (blk/white)
|
||||
// - draw them centered w/ red side border
|
||||
// - repeat same pattern bunch of times.
|
||||
// - used for a linear barcode in selftest process
|
||||
// - important: this cannot render a QR code, nor misleading text.
|
||||
// - LATER: let's just make fully static instead.
|
||||
|
||||
STATIC_ASSERT(sizeof(test_barcode) == LCD_WIDTH/8);
|
||||
|
||||
uint16_t row[LCD_WIDTH];
|
||||
for(int i=0, x=0; i<sizeof(test_barcode); i++) {
|
||||
for(uint8_t m=0x80; m; m >>= 1) {
|
||||
row[x++] = (test_barcode[i] & m) ? COL_BLACK : COL_WHITE;
|
||||
}
|
||||
}
|
||||
|
||||
const int y = 40, h = 120;
|
||||
send_window(0, y, LCD_WIDTH, h, NULL);
|
||||
|
||||
for(int i=0; i<h; i++) {
|
||||
lcd_write_data(sizeof(row), (uint8_t *)&row);
|
||||
}
|
||||
}
|
||||
|
||||
// EOF
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
|
||||
typedef struct {
|
||||
bool activity_bar:1;
|
||||
bool test_pattern:1; // self clearing
|
||||
|
||||
bool solid_cursor:1;
|
||||
bool outline_cursor:1;
|
||||
@ -18,5 +19,6 @@ extern lcd_state_t lcd_state;
|
||||
|
||||
void lcd_setup(void);
|
||||
void lcd_animate(void);
|
||||
void lcd_test_pattern(void);
|
||||
|
||||
// EOF
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
#include "version.h"
|
||||
#include <string.h>
|
||||
|
||||
// LL/HAL internal vars
|
||||
// LL/CMSIS internal vars
|
||||
uint32_t SystemCoreClock = 12000000UL;
|
||||
|
||||
#define MY_I2C_ADDR 0x65
|
||||
@ -97,7 +97,7 @@ i2c_setup(void)
|
||||
void
|
||||
enter_bootloader(void)
|
||||
{
|
||||
// prepare enter bootloader on next reset
|
||||
// Force entry into bootloader on next reset
|
||||
SET_BIT(FLASH->ACR, FLASH_ACR_PROGEMPTY);
|
||||
}
|
||||
|
||||
@ -136,13 +136,16 @@ i2c_poll(void)
|
||||
// - sending strings as zero-terminated
|
||||
// - for other responses, master will need to know true length of response
|
||||
if(!isRead) {
|
||||
respLen = 0;
|
||||
switch(cmd) {
|
||||
case 'V': // full version
|
||||
if(argLen != 0) goto bad_args;
|
||||
resp = version_string;
|
||||
respLen = strlen(version_string)+1;
|
||||
break;
|
||||
|
||||
case 'v': // short version
|
||||
if(argLen != 0) goto bad_args;
|
||||
resp = RELEASE_VERSION;
|
||||
respLen = strlen(RELEASE_VERSION)+1;
|
||||
break;
|
||||
@ -152,17 +155,46 @@ i2c_poll(void)
|
||||
respLen = argLen;
|
||||
break;
|
||||
|
||||
case 'b': // enter bootloader
|
||||
case 'b': // enter bootloader (follow w/ hard reset)
|
||||
if(argLen != 0) goto bad_args;
|
||||
enter_bootloader();
|
||||
resp = "OK";
|
||||
respLen = 3;
|
||||
break;
|
||||
|
||||
case 'c': // enable cursor: args=x,y,outline(else solid),dbl_wide
|
||||
if(argLen != 4) goto bad_args;
|
||||
lcd_state.activity_bar = false;
|
||||
lcd_state.cursor_x = args[0];
|
||||
lcd_state.cursor_y = args[1];
|
||||
lcd_state.outline_cursor = !args[2];
|
||||
lcd_state.solid_cursor = !!args[2];
|
||||
lcd_state.dbl_wide = !!args[3];
|
||||
lcd_state.cur_flash = false;
|
||||
break;
|
||||
|
||||
case 'a': // disable cursor (implied: enable activity bar)
|
||||
if(argLen != 0) goto bad_args;
|
||||
lcd_state.activity_bar = true;
|
||||
lcd_state.outline_cursor = false;
|
||||
lcd_state.solid_cursor = false;
|
||||
break;
|
||||
|
||||
case 't': // test feature: draw a single test pattern
|
||||
if(argLen != 0) goto bad_args;
|
||||
lcd_state.test_pattern = true;
|
||||
break;
|
||||
|
||||
case 0:
|
||||
default:
|
||||
resp = "Bad cmd?";
|
||||
respLen = strlen(resp);
|
||||
break;
|
||||
|
||||
bad_args:
|
||||
resp = "Bad args?";
|
||||
respLen = strlen(resp);
|
||||
break;
|
||||
}
|
||||
|
||||
// critical: flush old data
|
||||
@ -232,10 +264,16 @@ clock_setup(void)
|
||||
|
||||
// Set APB1 prescaler
|
||||
LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1);
|
||||
LL_Init1msTick(12000000);
|
||||
|
||||
// Update CMSIS variable (which can be updated also through SystemCoreClockUpdate function)
|
||||
LL_SetSystemCoreClock(12000000);
|
||||
// WAS:
|
||||
// LL_Init1msTick(12000000);
|
||||
// LL_SetSystemCoreClock(12000000);
|
||||
// but, this saves 296-324 bytes because it avoids a division that pulls in a math helper
|
||||
//SysTick->LOAD = (uint32_t)((12000000 / 1000) - 1UL); // set reload register
|
||||
SysTick->LOAD = 11999;
|
||||
SysTick->VAL = 0; // Load the SysTick Counter Value
|
||||
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
|
||||
SysTick_CTRL_ENABLE_Msk; // Enable the Systick Timer
|
||||
}
|
||||
|
||||
// mainloop()
|
||||
@ -249,7 +287,6 @@ mainloop(void)
|
||||
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SYSCFG | LL_APB2_GRP1_PERIPH_SPI1);
|
||||
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_PWR | LL_APB1_GRP1_PERIPH_I2C1);
|
||||
|
||||
|
||||
// Our setup code.
|
||||
gpio_setup();
|
||||
lcd_setup();
|
||||
@ -262,7 +299,7 @@ mainloop(void)
|
||||
while(1) {
|
||||
i2c_poll();
|
||||
|
||||
// G_CTRL must be low, and TEAR high, and if so we do progress bar
|
||||
// G_CTRL must be low, and TEAR high, and if so we can write to LCD.
|
||||
if(!LL_GPIO_IsInputPinSet(GPIOA, PIN_G_CTRL)
|
||||
&& LL_GPIO_IsInputPinSet(GPIOA, PIN_TEAR)
|
||||
) {
|
||||
@ -274,8 +311,6 @@ mainloop(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//return 0;
|
||||
}
|
||||
|
||||
// fatal_error()
|
||||
|
||||
91
misc/gpu/make_barcode.py
Normal file
91
misc/gpu/make_barcode.py
Normal file
@ -0,0 +1,91 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Render a little barcode we need for selftest process.
|
||||
#
|
||||
# - packed bytes
|
||||
import barcode
|
||||
from io import BytesIO
|
||||
from barcode import Code128
|
||||
from barcode.writer import ImageWriter
|
||||
|
||||
|
||||
class Packer(barcode.writer.BaseWriter):
|
||||
# api in <../../ENV/lib/python3.10/site-packages/barcode/writer.py>
|
||||
def __init__(self):
|
||||
super().__init__(initialize=self.do_init,
|
||||
paint_module=self.paint, paint_text=self.do_text, finish=self.do_fin)
|
||||
|
||||
def do_init(self, code):
|
||||
# the answer I want is given to init function: binary for black/white sections
|
||||
assert len(code) == 1, 'not a list?'
|
||||
code = code[0]
|
||||
|
||||
if len(code) % 2:
|
||||
code += '0'
|
||||
while (len(code) % 8) != 0:
|
||||
code = f'0{code}0'
|
||||
|
||||
#code = code.replace('0', '00').replace('1', '11') # double it up
|
||||
code = code.replace('0', '000').replace('1', '111') # 3X
|
||||
#code = code.replace('0', '0000').replace('1', '1111') # 4X
|
||||
|
||||
# pad to 320 pixels (div 8) (centered)
|
||||
while len(code) < 320:
|
||||
code = f'0000{code}0000'
|
||||
|
||||
# convert to bytes
|
||||
self.result = int(code, 2).to_bytes(len(code)//8, 'big')
|
||||
|
||||
def do_text(self, *unused):
|
||||
pass
|
||||
|
||||
def paint(self, xpos, ypos, width, color):
|
||||
#print(f'paint: pos={xpos},{ypos} w={width} c={color}')
|
||||
pass
|
||||
|
||||
def do_fin(self):
|
||||
return self.result
|
||||
|
||||
def doit(ofile='barcode.h'):
|
||||
|
||||
# contents of barcode
|
||||
if 0:
|
||||
# works, but overkill and reads better if simpler
|
||||
version = None
|
||||
with open('version.h') as fd:
|
||||
for ln in fd:
|
||||
if 'RELEASE_VERSION' in ln:
|
||||
version = eval(ln.split()[-1])
|
||||
break
|
||||
assert version
|
||||
msg = f'GPU={version}'
|
||||
msg = f'GPU'
|
||||
bc = Code128(msg, writer=Packer())
|
||||
rv = bc.render()
|
||||
|
||||
#bc2 = Code128(msg, writer=ImageWriter())
|
||||
#bc2.write('check.png')
|
||||
|
||||
#print(f'Result: {rv.hex()} len={len(rv)}')
|
||||
|
||||
assert len(rv) * 8 <= 320, 'too wide to fit on screen'
|
||||
assert len(rv) == 40, 'expected 320 pixels'
|
||||
|
||||
enc = rv.hex(' ', 1).replace(' ', ', 0x')
|
||||
|
||||
with open(ofile, 'wt') as fd:
|
||||
fd.write(f'''// autogen file, see make_barcode.py
|
||||
|
||||
// in python: {repr(rv)}
|
||||
static const uint8_t test_barcode[{len(rv)}] = {{
|
||||
0x{enc}
|
||||
}};
|
||||
|
||||
// EOF''')
|
||||
|
||||
print(f"Updated: {ofile}")
|
||||
|
||||
if __name__ == '__main__':
|
||||
doit()
|
||||
|
||||
# EOF
|
||||
2
misc/gpu/requirements.txt
Normal file
2
misc/gpu/requirements.txt
Normal file
@ -0,0 +1,2 @@
|
||||
# optional, unless you want to run make_barcode.py
|
||||
python-barcode==0.15.1
|
||||
@ -5,7 +5,7 @@
|
||||
#include <stdint.h>
|
||||
|
||||
// Public version number for humans. Lots more version data added by Makefile.
|
||||
#define RELEASE_VERSION "1.0.0"
|
||||
#define RELEASE_VERSION "1.1.1"
|
||||
|
||||
extern const char version_string[];
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user