Compare commits
431 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
57623acc99 | ||
|
|
4f8d29d0b7 | ||
|
|
8eda2d805f | ||
|
|
432d4a4ffa | ||
|
|
539caf3d83 | ||
|
|
ce6926c36c | ||
|
|
8058d550ab | ||
|
|
9a21ff6976 | ||
|
|
1f4f41b6e6 | ||
|
|
a959196c2a | ||
|
|
3f22601022 | ||
|
|
a80a7ecba9 | ||
|
|
7c450f4a5f | ||
|
|
6316d3076d | ||
|
|
7181683d8e | ||
|
|
7d7134dd9e | ||
|
|
c29db97f73 | ||
|
|
05833bb38c | ||
|
|
253de81a6b | ||
|
|
21e6a0cf7e | ||
|
|
d0fefabad7 | ||
|
|
44db160ab1 | ||
|
|
cb633a8f32 | ||
|
|
66b7130641 | ||
|
|
80d9718770 | ||
|
|
dfbbca4c9f | ||
|
|
f4d08b2d9b | ||
|
|
588a834ae4 | ||
|
|
833dda7e7c | ||
|
|
6a4ab55930 | ||
|
|
d7ce2a81db | ||
|
|
4d90fa4830 | ||
|
|
501fdda138 | ||
|
|
678e8d34e3 | ||
|
|
07d1982abf | ||
|
|
fd05f83636 | ||
|
|
94e119fb51 | ||
|
|
c2ff4bf623 | ||
|
|
faf5651607 | ||
|
|
978e8344cf | ||
|
|
160d6eacc0 | ||
|
|
075d8e6393 | ||
|
|
28008ac7ac | ||
|
|
345d36287e | ||
|
|
edff6c551d | ||
|
|
d42a94f148 | ||
|
|
c01b8aa89c | ||
|
|
4958bd6a52 | ||
|
|
46038032a4 | ||
|
|
f66ddca100 | ||
|
|
6981c59de3 | ||
|
|
f21f13b15d | ||
|
|
ef5a01433d | ||
|
|
0e12d8545b | ||
|
|
9dbf745649 | ||
|
|
e8f73a42b8 | ||
|
|
dbe431095a | ||
|
|
513f77a2ad | ||
|
|
e8cf85bd65 | ||
|
|
be23d1fa15 | ||
|
|
4e7e5081a7 | ||
|
|
fff750e609 | ||
|
|
38ce46a158 | ||
|
|
7a27a7b3b5 | ||
|
|
c6ec175045 | ||
|
|
3b9ab66cf1 | ||
|
|
b6e458e97b | ||
|
|
c5152f6a9d | ||
|
|
e5689cfe57 | ||
|
|
f3f1d4d4f0 | ||
|
|
796b15a861 | ||
|
|
add351289a | ||
|
|
a4a056128a | ||
|
|
6e314933d9 | ||
|
|
a31bedda97 | ||
|
|
a25c82a8ce | ||
|
|
8ccc47dfa5 | ||
|
|
9de5a4ba66 | ||
|
|
84e437ae5b | ||
|
|
9e34c5995d | ||
|
|
497bbdf3cd | ||
|
|
8683a0ff58 | ||
|
|
874c801772 | ||
|
|
eea5463a5c | ||
|
|
af790aeaf8 | ||
|
|
a8a45b215a | ||
|
|
38f456a2ee | ||
|
|
a980eac647 | ||
|
|
ea83566fc9 | ||
|
|
0857d7ff0e | ||
|
|
48e98ab8c9 | ||
|
|
8cd438146d | ||
|
|
a80cc0ae2c | ||
|
|
2428736bfa | ||
|
|
a7bf8bf118 | ||
|
|
8038e1faa9 | ||
|
|
15a7e49dde | ||
|
|
8b30bd4b57 | ||
|
|
63d03303a2 | ||
|
|
0e40fef049 | ||
|
|
1a50425475 | ||
|
|
8fc5267110 | ||
|
|
f6a3b2c9ac | ||
|
|
7aa1e77642 | ||
|
|
2370ca0a44 | ||
|
|
abcf7f6f57 | ||
|
|
d1f0ea3de7 | ||
|
|
dbc8f4a4c2 | ||
|
|
c6c396ce2a | ||
|
|
74b91b0085 | ||
|
|
53c9ca8072 | ||
|
|
13e5216a4e | ||
|
|
147ccd3070 | ||
|
|
dc5c26e7c6 | ||
|
|
4914af1200 | ||
|
|
b57d26e99a | ||
|
|
f196b8bb0e | ||
|
|
7b460f7e56 | ||
|
|
9daa14abec | ||
|
|
bf8fd9a33b | ||
|
|
1f37b96359 | ||
|
|
46921aca22 | ||
|
|
41f96d4305 | ||
|
|
0959dc3a2d | ||
|
|
31baf3d19a | ||
|
|
f4696da0ef | ||
|
|
83ab79c51e | ||
|
|
745ac609d2 | ||
|
|
0f9aa51afe | ||
|
|
9fbb28e887 | ||
|
|
adf2045896 | ||
|
|
1a797bf93a | ||
|
|
1a9372b4ce | ||
|
|
87b91174ec | ||
|
|
26fff275ce | ||
|
|
53b44a525d | ||
|
|
8ce5d55eb8 | ||
|
|
afb749560a | ||
|
|
7a66e0298a | ||
|
|
e491a4cf57 | ||
|
|
b7789f1edb | ||
|
|
4949331f4c | ||
|
|
2c695e9a96 | ||
|
|
faaf801534 | ||
|
|
3fa775e3ad | ||
|
|
6663330de3 | ||
|
|
ed916360eb | ||
|
|
e4bc5c41ce | ||
|
|
d0d943c9c3 | ||
|
|
60b629e57f | ||
|
|
df80339060 | ||
|
|
cbbd427d3a | ||
|
|
dfcdb2e1e6 | ||
|
|
11ca6caf5f | ||
|
|
15afdf53e4 | ||
|
|
d15f958b48 | ||
|
|
5fd3bdede7 | ||
|
|
e2dd218f33 | ||
|
|
a85891ae00 | ||
|
|
2628044ba8 | ||
|
|
e620783a89 | ||
|
|
2fba9848ae | ||
|
|
52c65661d8 | ||
|
|
601c85c23e | ||
|
|
9d79f39897 | ||
|
|
2a7a3452ba | ||
|
|
f1386c60af | ||
|
|
b6ec217484 | ||
|
|
ad560b650e | ||
|
|
14a048a496 | ||
|
|
ba984d02eb | ||
|
|
fce59fba43 | ||
|
|
685663dcf6 | ||
|
|
cb61e856ad | ||
|
|
5b8fb9fb6b | ||
|
|
8249d9e1a2 | ||
|
|
4a152504cb | ||
|
|
b8eff953c6 | ||
|
|
cf1f94662c | ||
|
|
d4d6730c20 | ||
|
|
d287d40208 | ||
|
|
7e5e365f18 | ||
|
|
7bebec1304 | ||
|
|
2aa1ce5390 | ||
|
|
aaaf470dcf | ||
|
|
cf175fc00d | ||
|
|
c13eabcde8 | ||
|
|
8e45fcc069 | ||
|
|
d1e3a0fdff | ||
|
|
19ddff299a | ||
|
|
0954eb2b09 | ||
|
|
0a9931ddb3 | ||
|
|
0ccea3aa83 | ||
|
|
a1188505e8 | ||
|
|
2424ecc4f0 | ||
|
|
202540c7f7 | ||
|
|
1ceb380f6f | ||
|
|
da0cdf1bd0 | ||
|
|
708863358e | ||
|
|
a862b85a46 | ||
|
|
495907b8a4 | ||
|
|
f9a1935762 | ||
|
|
8ef9f888f6 | ||
|
|
9b3e9724b7 | ||
|
|
8880dfab24 | ||
|
|
5ffbbf40a5 | ||
|
|
a36fec5696 | ||
|
|
7acad84932 | ||
|
|
8d2230dc51 | ||
|
|
528ddbe12c | ||
|
|
e4c0756ded | ||
|
|
1c9efa327c | ||
|
|
fbbfeb2d1c | ||
|
|
ccaf49bece | ||
|
|
147fed39c8 | ||
|
|
d0a73bdc72 | ||
|
|
29dc122dd4 | ||
|
|
293c47774d | ||
|
|
795ed8aadc | ||
|
|
377825d4fb | ||
|
|
b89bb35054 | ||
|
|
caae685fab | ||
|
|
bd4517abab | ||
|
|
095b234fce | ||
|
|
b1c09f8a9c | ||
|
|
cabaa6cfb8 | ||
|
|
94486873c1 | ||
|
|
89a4eadab0 | ||
|
|
55395ea4fd | ||
|
|
4166a3c128 | ||
|
|
cabb8cd33a | ||
|
|
ab7a81081c | ||
|
|
8a352bdfe2 | ||
|
|
721e926a75 | ||
|
|
0b314d7f21 | ||
|
|
8305058cf5 | ||
|
|
6dddb968fa | ||
|
|
d3c318d0c9 | ||
|
|
604ec4416d | ||
|
|
c7fcea5f35 | ||
|
|
a84f1e5ee5 | ||
|
|
6a4161fdc4 | ||
|
|
e45ffab5d8 | ||
|
|
669e42960c | ||
|
|
55568b037f | ||
|
|
b5df428e43 | ||
|
|
1c19a69e35 | ||
|
|
67a03bbd85 | ||
|
|
32955380c7 | ||
|
|
93b4514343 | ||
|
|
68d57861cd | ||
|
|
485edb4883 | ||
|
|
bbc3f41493 | ||
|
|
5a6608dff4 | ||
|
|
8f222fd0bd | ||
|
|
1f5b371608 | ||
|
|
ce156ab4e7 | ||
|
|
94235dd005 | ||
|
|
cb471162d2 | ||
|
|
9d1c0ce308 | ||
|
|
27b1f0e843 | ||
|
|
dae7be8ec4 | ||
|
|
2f5b52223c | ||
|
|
bf222290b8 | ||
|
|
d825be5eb2 | ||
|
|
9da0e0358b | ||
|
|
216d97aada | ||
|
|
e3421fd44e | ||
|
|
85d43147ee | ||
|
|
e3e5dab0fc | ||
|
|
8b837dd81b | ||
|
|
8f7bdd45b1 | ||
|
|
0142ac1697 | ||
|
|
e8fb6624c0 | ||
|
|
bdb21ce3fd | ||
|
|
2ca4fb6d8f | ||
|
|
e7900b11b4 | ||
|
|
d71f6d0b99 | ||
|
|
926bd5d2fb | ||
|
|
461d14c39a | ||
|
|
6714cae498 | ||
|
|
b20a0e74c2 | ||
|
|
9686eaf3f1 | ||
|
|
7b03a24196 | ||
|
|
98555b24f8 | ||
|
|
3d05b58856 | ||
|
|
15b46ddb27 | ||
|
|
78c4e6510d | ||
|
|
cd76d5ac09 | ||
|
|
9c2a064817 | ||
|
|
db2da89f69 | ||
|
|
0652d6b3f1 | ||
|
|
1111125aab | ||
|
|
4fc420616d | ||
|
|
fb7c83a66c | ||
|
|
f021665089 | ||
|
|
6c887c15be | ||
|
|
2b7722da7d | ||
|
|
4f65697522 | ||
|
|
5140992a7b | ||
|
|
af0cd34f92 | ||
|
|
b8ca88ee0a | ||
|
|
fac1884a43 | ||
|
|
46fa330bdd | ||
|
|
adfa7c0780 | ||
|
|
11df6030f9 | ||
|
|
45ca2938f5 | ||
|
|
88fa4fa861 | ||
|
|
100d6cc4a5 | ||
|
|
32e58d2bb3 | ||
|
|
638a3909c5 | ||
|
|
82da1aaf2a | ||
|
|
3c2d86ef7b | ||
|
|
f559017aeb | ||
|
|
e158d9bc00 | ||
|
|
3ddd1c26ad | ||
|
|
ab5b59e10d | ||
|
|
1f67251331 | ||
|
|
4eecdfa553 | ||
|
|
80dd0f1580 | ||
|
|
4e0c70a402 | ||
|
|
ffd5a198f9 | ||
|
|
ddc89c9f49 | ||
|
|
9673d5524a | ||
|
|
3214fc2f93 | ||
|
|
3b0925b912 | ||
|
|
c5f032fcb2 | ||
|
|
98e05d941d | ||
|
|
90ab1e5656 | ||
|
|
564f36fc8b | ||
|
|
6159284be6 | ||
|
|
9afc6f0a4e | ||
|
|
f689bb253e | ||
|
|
0738c96867 | ||
|
|
edba8ca986 | ||
|
|
2aa9055fae | ||
|
|
1369d66043 | ||
|
|
9e48d64b27 | ||
|
|
d37fe213d7 | ||
|
|
029d66bd95 | ||
|
|
c73b4ad6ba | ||
|
|
6e256d29c7 | ||
|
|
185526d134 | ||
|
|
9b1c61fbcf | ||
|
|
ae7ef7d79a | ||
|
|
273f11cd59 | ||
|
|
f5092bc981 | ||
|
|
9489eca487 | ||
|
|
3aa195943d | ||
|
|
3c6c92aa9c | ||
|
|
c2160ae367 | ||
|
|
d607a8830b | ||
|
|
f7f99bddab | ||
|
|
4564db0b6d | ||
|
|
0a44a31f2c | ||
|
|
0692e4de8d | ||
|
|
92d013dd65 | ||
|
|
242bbdada5 | ||
|
|
d90f5b7e7c | ||
|
|
d95449c22d | ||
|
|
28f2fb1468 | ||
|
|
ad5a50ecd9 | ||
|
|
4d8dbe068d | ||
|
|
157e415636 | ||
|
|
48f84c5cf4 | ||
|
|
1d3d1c8454 | ||
|
|
bb2b339b54 | ||
|
|
5790c585f5 | ||
|
|
a2655912d4 | ||
|
|
e2c905e9b2 | ||
|
|
9619417b07 | ||
|
|
b0bcdeafac | ||
|
|
7b76015fd1 | ||
|
|
465955c8f5 | ||
|
|
90a759b98e | ||
|
|
0096b91146 | ||
|
|
125f000894 | ||
|
|
f9a0e6ce4f | ||
|
|
0d5a1416d0 | ||
|
|
43f3132069 | ||
|
|
3d00a1be21 | ||
|
|
87ce09f4b1 | ||
|
|
31f90a0a47 | ||
|
|
af30904624 | ||
|
|
f2f995af17 | ||
|
|
1c213d73c9 | ||
|
|
3dcd2ad15f | ||
|
|
accf226214 | ||
|
|
71df1e2da1 | ||
|
|
d49a40b0da | ||
|
|
75c6b01696 | ||
|
|
eb2c8a032f | ||
|
|
416db840ec | ||
|
|
b0c4cef077 | ||
|
|
58d12e5754 | ||
|
|
bcda64a5df | ||
|
|
ba77de3dc5 | ||
|
|
53325617bb | ||
|
|
8e836d958f | ||
|
|
fa72d1154d | ||
|
|
27926b0d55 | ||
|
|
8ce6bf82a9 | ||
|
|
36aeb36c90 | ||
|
|
780d17e61c | ||
|
|
c613acb31d | ||
|
|
21548545fc | ||
|
|
7dd3178d48 | ||
|
|
c9ee530205 | ||
|
|
cc54df87d7 | ||
|
|
9698cbc9d7 | ||
|
|
f085cbc4a4 | ||
|
|
d8b6aa3831 | ||
|
|
3e5ef39686 | ||
|
|
bc7c65447d | ||
|
|
a91378b9c1 | ||
|
|
7543234401 | ||
|
|
5b91c54936 | ||
|
|
322280757f | ||
|
|
b1636fbb96 | ||
|
|
cc18a7b146 | ||
|
|
5fe84a78ac | ||
|
|
822e0dcd98 | ||
|
|
a6be3714a3 | ||
|
|
f56d1bad04 | ||
|
|
c7ab404fc1 | ||
|
|
e8f41a03f3 | ||
|
|
8edc9971f9 | ||
|
|
54c36a7e46 | ||
|
|
afb820202d | ||
|
|
0ce973966f | ||
|
|
da8c040c08 |
4
.gitignore
vendored
4
.gitignore
vendored
@@ -2,3 +2,7 @@
|
||||
.vscode
|
||||
build/*
|
||||
output/*
|
||||
loader/payload_00.h
|
||||
loader/payload_01.h
|
||||
tools/bin2c/bin2c
|
||||
tools/lz/lz77
|
||||
|
||||
80
Makefile
80
Makefile
@@ -16,7 +16,10 @@ TARGET := hekate
|
||||
BUILDDIR := build
|
||||
OUTPUTDIR := output
|
||||
SOURCEDIR = bootloader
|
||||
BDKDIR := bdk
|
||||
BDKINC := -I./$(BDKDIR)
|
||||
VPATH = $(dir ./$(SOURCEDIR)/) $(dir $(wildcard ./$(SOURCEDIR)/*/)) $(dir $(wildcard ./$(SOURCEDIR)/*/*/))
|
||||
VPATH += $(dir $(wildcard ./$(BDKDIR)/)) $(dir $(wildcard ./$(BDKDIR)/*/)) $(dir $(wildcard ./$(BDKDIR)/*/*/))
|
||||
|
||||
# Main and graphics.
|
||||
OBJS = $(addprefix $(BUILDDIR)/$(TARGET)/, \
|
||||
@@ -28,8 +31,8 @@ OBJS = $(addprefix $(BUILDDIR)/$(TARGET)/, \
|
||||
|
||||
# Hardware.
|
||||
OBJS += $(addprefix $(BUILDDIR)/$(TARGET)/, \
|
||||
bpmp.o clock.o cluster.o di.o gpio.o i2c.o irq.o mc.o sdram.o \
|
||||
pinmux.o se.o smmu.o tsec.o uart.o \
|
||||
bpmp.o ccplex.o clock.o di.o gpio.o i2c.o irq.o mc.o sdram.o \
|
||||
pinmux.o pmc.o se.o smmu.o tsec.o uart.o \
|
||||
fuse.o kfuse.o minerva.o \
|
||||
sdmmc.o sdmmc_driver.o emummc.o nx_emmc.o nx_sd.o \
|
||||
bq24193.o max17050.o max7762x.o max77620-rtc.o \
|
||||
@@ -49,64 +52,99 @@ OBJS += $(addprefix $(BUILDDIR)/$(TARGET)/, \
|
||||
|
||||
# Libraries.
|
||||
OBJS += $(addprefix $(BUILDDIR)/$(TARGET)/, \
|
||||
lz.o blz.o \
|
||||
lz.o lz4.o blz.o \
|
||||
diskio.o ff.o ffunicode.o ffsystem.o \
|
||||
elfload.o elfreloc_arm.o \
|
||||
)
|
||||
|
||||
GFX_INC := '"../$(SOURCEDIR)/gfx/gfx.h"'
|
||||
FFCFG_INC := '"../$(SOURCEDIR)/libs/fatfs/ffconf.h"'
|
||||
|
||||
################################################################################
|
||||
|
||||
CUSTOMDEFINES := -DIPL_LOAD_ADDR=$(IPL_LOAD_ADDR) -DBL_MAGIC=$(IPL_MAGIC)
|
||||
CUSTOMDEFINES += -DBL_VER_MJ=$(BLVERSION_MAJOR) -DBL_VER_MN=$(BLVERSION_MINOR) -DBL_VER_HF=$(BLVERSION_HOTFX) -DBL_RESERVED=$(BLVERSION_RSVD)
|
||||
CUSTOMDEFINES += -DNYX_VER_MJ=$(NYXVERSION_MAJOR) -DNYX_VER_MN=$(NYXVERSION_MINOR) -DNYX_VER_HF=$(NYXVERSION_HOTFX) -DNYX_RESERVED=$(NYXVERSION_RSVD)
|
||||
#CUSTOMDEFINES += -DMENU_LOGO_ENABLE
|
||||
|
||||
# 0: UART_A, 1: UART_B.
|
||||
#CUSTOMDEFINES += -DDEBUG_UART_PORT=0
|
||||
CUSTOMDEFINES += -DGFX_INC=$(GFX_INC) -DFFCFG_INC=$(FFCFG_INC)
|
||||
|
||||
#CUSTOMDEFINES += -DDEBUG
|
||||
|
||||
# UART Logging: Max baudrate 12.5M.
|
||||
# DEBUG_UART_PORT - 0: UART_A, 1: UART_B, 2: UART_C.
|
||||
#CUSTOMDEFINES += -DDEBUG_UART_BAUDRATE=115200 -DDEBUG_UART_INVERT=0 -DDEBUG_UART_PORT=0
|
||||
|
||||
#TODO: Considering reinstating some of these when pointer warnings have been fixed.
|
||||
WARNINGS := -Wall -Wno-array-bounds -Wno-stringop-overread -Wno-stringop-overflow
|
||||
|
||||
ARCH := -march=armv4t -mtune=arm7tdmi -mthumb -mthumb-interwork
|
||||
CFLAGS = $(ARCH) -O2 -nostdlib -ffunction-sections -fdata-sections -fomit-frame-pointer -fno-inline -std=gnu11 -Wall $(CUSTOMDEFINES)
|
||||
CFLAGS = $(ARCH) -O2 -g -nostdlib -ffunction-sections -fdata-sections -fomit-frame-pointer -fno-inline -std=gnu11 $(WARNINGS) $(CUSTOMDEFINES)
|
||||
LDFLAGS = $(ARCH) -nostartfiles -lgcc -Wl,--nmagic,--gc-sections -Xlinker --defsym=IPL_LOAD_ADDR=$(IPL_LOAD_ADDR)
|
||||
|
||||
MODULEDIRS := $(wildcard modules/*)
|
||||
NYXDIR := $(wildcard nyx)
|
||||
LDRDIR := $(wildcard loader)
|
||||
TOOLSLZ := $(wildcard tools/lz)
|
||||
TOOLSB2C := $(wildcard tools/bin2c)
|
||||
TOOLS := $(TOOLSLZ) $(TOOLSB2C)
|
||||
|
||||
################################################################################
|
||||
|
||||
.PHONY: all clean $(MODULEDIRS) $(NYXDIR)
|
||||
.PHONY: all clean $(MODULEDIRS) $(NYXDIR) $(LDRDIR) $(TOOLS)
|
||||
|
||||
all: $(TARGET).bin
|
||||
@echo -n "Payload size is "
|
||||
all: $(TARGET).bin $(LDRDIR)
|
||||
@printf ICTC49 >> $(OUTPUTDIR)/$(TARGET).bin
|
||||
@echo "--------------------------------------"
|
||||
@echo -n "Uncompr size: "
|
||||
$(eval BIN_SIZE = $(shell wc -c < $(OUTPUTDIR)/$(TARGET)_unc.bin))
|
||||
@echo $(BIN_SIZE)" Bytes"
|
||||
@echo "Uncompr Max: 140288 Bytes + 3 KiB BSS"
|
||||
@if [ ${BIN_SIZE} -gt 140288 ]; then echo "\e[1;33mUncompr size exceeds limit!\e[0m"; fi
|
||||
@echo -n "Payload size: "
|
||||
$(eval BIN_SIZE = $(shell wc -c < $(OUTPUTDIR)/$(TARGET).bin))
|
||||
@echo $(BIN_SIZE)
|
||||
@echo "Max size is 126296 Bytes."
|
||||
@echo $(BIN_SIZE)" Bytes"
|
||||
@echo "Payload Max: 126296 Bytes"
|
||||
@if [ ${BIN_SIZE} -gt 126296 ]; then echo "\e[1;33mPayload size exceeds limit!\e[0m"; fi
|
||||
@echo "--------------------------------------"
|
||||
|
||||
clean:
|
||||
clean: $(TOOLS)
|
||||
@rm -rf $(OBJS)
|
||||
@rm -rf $(BUILDDIR)
|
||||
@rm -rf $(OUTPUTDIR)
|
||||
|
||||
$(MODULEDIRS):
|
||||
$(MAKE) -C $@ $(MAKECMDGOALS) -$(MAKEFLAGS)
|
||||
@$(MAKE) --no-print-directory -C $@ $(MAKECMDGOALS) -$(MAKEFLAGS)
|
||||
|
||||
$(NYXDIR):
|
||||
$(MAKE) -C $@ $(MAKECMDGOALS) -$(MAKEFLAGS)
|
||||
@$(MAKE) --no-print-directory -C $@ $(MAKECMDGOALS) -$(MAKEFLAGS)
|
||||
|
||||
$(TARGET).bin: $(BUILDDIR)/$(TARGET)/$(TARGET).elf $(MODULEDIRS) $(NYXDIR)
|
||||
$(LDRDIR): $(TARGET).bin
|
||||
@$(TOOLSLZ)/lz77 $(OUTPUTDIR)/$(TARGET).bin
|
||||
mv $(OUTPUTDIR)/$(TARGET).bin $(OUTPUTDIR)/$(TARGET)_unc.bin
|
||||
@mv $(OUTPUTDIR)/$(TARGET).bin.00.lz payload_00
|
||||
@mv $(OUTPUTDIR)/$(TARGET).bin.01.lz payload_01
|
||||
@$(TOOLSB2C)/bin2c payload_00 > $(LDRDIR)/payload_00.h
|
||||
@$(TOOLSB2C)/bin2c payload_01 > $(LDRDIR)/payload_01.h
|
||||
@rm payload_00
|
||||
@rm payload_01
|
||||
@$(MAKE) --no-print-directory -C $@ $(MAKECMDGOALS) -$(MAKEFLAGS) PAYLOAD_NAME=$(TARGET)
|
||||
|
||||
$(TOOLS):
|
||||
@$(MAKE) --no-print-directory -C $@ $(MAKECMDGOALS) -$(MAKEFLAGS)
|
||||
|
||||
$(TARGET).bin: $(BUILDDIR)/$(TARGET)/$(TARGET).elf $(MODULEDIRS) $(NYXDIR) $(TOOLS)
|
||||
$(OBJCOPY) -S -O binary $< $(OUTPUTDIR)/$@
|
||||
@printf ICTC49 >> $(OUTPUTDIR)/$@
|
||||
|
||||
$(BUILDDIR)/$(TARGET)/$(TARGET).elf: $(OBJS)
|
||||
$(CC) $(LDFLAGS) -T $(SOURCEDIR)/link.ld $^ -o $@
|
||||
@$(CC) $(LDFLAGS) -T $(SOURCEDIR)/link.ld $^ -o $@
|
||||
@echo "hekate was built with the following flags:\nCFLAGS: "$(CFLAGS)"\nLDFLAGS: "$(LDFLAGS)
|
||||
|
||||
$(BUILDDIR)/$(TARGET)/%.o: %.c
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
@echo Building $@
|
||||
@$(CC) $(CFLAGS) $(BDKINC) -c $< -o $@
|
||||
|
||||
$(BUILDDIR)/$(TARGET)/%.o: %.S
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
@echo Building $@
|
||||
@$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
$(OBJS): $(BUILDDIR)/$(TARGET)
|
||||
|
||||
|
||||
43
README.md
43
README.md
@@ -1,9 +1,9 @@
|
||||
# hekate - CTCaer mod
|
||||
# hekate - Nyx
|
||||
|
||||

|
||||
|
||||
|
||||
Custom Nintendo Switch bootloader, firmware patcher, and more.
|
||||
Custom Graphical Nintendo Switch bootloader, firmware patcher, tools, and many more.
|
||||
|
||||
|
||||
## Bootloader folders and files
|
||||
@@ -30,7 +30,7 @@ Custom Nintendo Switch bootloader, firmware patcher, and more.
|
||||
| bootloader/screenshots/ | Folder where Nyx screenshots are saved |
|
||||
| bootloader/payloads/ | For payloads. 'Payloads...' menu. Autoboot only supported by including them into an ini. All CFW bootloaders, tools, Linux payloads are supported. |
|
||||
| bootloader/libtools/ | Future reserved |
|
||||
| sept | Sept folder. This must be always get updated via the Atmosphère release zip. Needed for tools and booting HOS on 7.0.0 and up. Unused for booting HOS if `fss0=` key is defined. |
|
||||
| sept | Sept folder. This must always get updated via the Atmosphère release zip. Needed for tools and booting HOS on 7.0.0 and up. Unused for booting HOS if `fss0=` key is defined. |
|
||||
|
||||
**Note**: Sept files for booting 7.0.0 and up are expected at /sept folder at root of sd card.
|
||||
|
||||
@@ -55,6 +55,7 @@ You can find a template [Here](./res/hekate_ipl_template.ini)
|
||||
| bootwait=3 | 0: Disable (It also disables bootlogo. Having **VOL-** pressed since injection goes to menu.), #: Time to wait for **VOL-** to enter menu. |
|
||||
| autohosoff=1 | 0: Disable, 1: If woke up from HOS via an RTC alarm, shows logo, then powers off completely, 2: No logo, immediately powers off.|
|
||||
| autonogc=1 | 0: Disable, 1: Automatically applies nogc patch if unburnt fuses found and a >= 4.0.0 HOS is booted. |
|
||||
| bootprotect=0 | 0: Disable, 1: Protect bootloader folder from being corrupted by disallowing reading or editing in HOS. |
|
||||
| updater2p=0 | 0: Disable, 1: Force updates (if needed) the reboot2payload binary to be hekate. |
|
||||
| backlight=100 | Screen backlight level. 0-255. |
|
||||
|
||||
@@ -67,6 +68,9 @@ You can find a template [Here](./res/hekate_ipl_template.ini)
|
||||
| timeoff=100 | Sets time offset in HEX. Must be in HOS epoch format |
|
||||
| homescreen=0 | Sets home screen. 0: Home menu, 1: All configs (merges Launch and More configs), 2: Launch, 3: More Configs. |
|
||||
| verification=1 | 0: Disable Backup/Restore verification, 1: Sparse (block based, fast and mostly reliable), 2: Full (sha256 based, slow and 100% reliable). |
|
||||
| umsemmcrw=0 | 1: eMMC/emuMMC UMS will be mounted as writable by default. |
|
||||
| jcdisable=0 | 1: Disables Joycon driver completely. |
|
||||
| bpmpclock=1 | 0: Auto, 1: Faster, 2: Fast. Use 2 if Nyx hangs or some functions like UMS/Backup Verification fail. |
|
||||
|
||||
|
||||
### Boot entry key/value combinations:
|
||||
@@ -80,20 +84,30 @@ You can find a template [Here](./res/hekate_ipl_template.ini)
|
||||
| kip1={SD folder}/* | Loads every .kip/.kip1 inside a folder. Compatible with single kip1 keys. |
|
||||
| fss0={SD path} | Takes a fusee-secondary binary and `extracts` all needed parts from it. kips, exosphere, warmboot and sept. |
|
||||
| fss0experimental=1 | Enables loading of experimental content from a FSS0 storage |
|
||||
| exofatal={SD path} | Replaces the exosphere fatal binary for Mariko |
|
||||
| kip1patch=patchname | Enables a kip1 patch. Specify with multiple lines and/or as CSV. If not found, an error will show up |
|
||||
| fullsvcperm=1 | Disables SVC verification (full services permission) |
|
||||
| debugmode=1 | Enables Debug mode. Obsolete when used with exosphere as secmon. |
|
||||
| atmosphere=1 | Enables Atmosphère patching. |
|
||||
| atmosphere=1 | Enables Atmosphère patching. Not needed when `fss0` is used. |
|
||||
| emupath={SD folder} | Forces emuMMC to use the selected one. (=emuMMC/RAW1, =emuMMC/SD00, etc). emuMMC must be created by hekate because it uses the raw_based/file_based files. |
|
||||
| emummcforce=1 | Forces the use of emuMMC. If emummc.ini is disabled or not found, then it causes an error. |
|
||||
| emummc_force_disable=1 | Disables emuMMC if it's enabled. |
|
||||
| stock=1 | Disables unneeded kernel patching when running stock or semi-stock. `If emuMMC is enabled, emummc_force_disabled=1` is required. emuMMC is not supported on stock. If additional KIPs are needed other than OFW's, you can define them with `kip1` key. No kip should be used that relies on Atmosphère patching, because it will hang. If `NOGC` is needed, use `kip1patch=nogc`. |
|
||||
| emummc_force_disable=1 | Disables emuMMC, if it's enabled. |
|
||||
| stock=1 | Disables unneeded kernel patching and CFW kips when running stock or semi-stock. `If emuMMC is enabled, emummc_force_disabled=1` is required. emuMMC is not supported on stock. If additional KIPs are needed other than OFW's, you can define them with `kip1` key. No kip should be used that relies on Atmosphère patching, because it will hang. If `NOGC` is needed, use `kip1patch=nogc`. |
|
||||
| id=idname | Identifies boot entry for forced boot via id. Max 7 chars. |
|
||||
| payload={SD path} | Payload launching. Tools, Linux, CFW bootloaders, etc. |
|
||||
| logopath={SD path} | If no logopath, `bootloader/bootlogo.bmp` will be used if exists. If logopath exists, it will load the specified bitmap. |
|
||||
| icon={SD path} | Force Nyx to use the icon defined here. If this is not found, it will check for a bmp named as the boot entry ([Test 2] -> `bootloader/res/Test 2.bmp`). Otherwise default will be used. |
|
||||
|
||||
|
||||
**Note1**: When using the wildcard (`/*`) with `kip1` you can still use the normal `kip1` after that to load extra single kips.
|
||||
|
||||
**Note2**: When using FSS0 it parses exosphere, warmboot and all core kips. You can override the first 2 by using `secmon`/`warmboot` after defining `fss0`.
|
||||
You can define `kip1` to load an extra kip or many via the wildcard (`/*`) usage.
|
||||
|
||||
**Warning**: Careful when you define *fss0 core* kips when using `fss0` or the folder (when using `/*`) includes them.
|
||||
This is in case the kips are incompatible between them. If compatible, you can override `fss0` kips with no issues (useful for testing with intermediate kip changes).
|
||||
|
||||
|
||||
### Boot entry key/value Exosphère combinations:
|
||||
|
||||
| Config option | Description |
|
||||
@@ -102,15 +116,13 @@ You can find a template [Here](./res/hekate_ipl_template.ini)
|
||||
| userpmu=1 | Enables user access to PMU when paired with Exosphère. |
|
||||
| cal0blank=1 | Overrides Exosphère config `blank_prodinfo_{sys/emu}mmc`. If that key doesn't exist, `exosphere.ini` will be used. |
|
||||
| cal0writesys=1 | Overrides Exosphère config `allow_writing_to_cal_sysmmc`. If that key doesn't exist, `exosphere.ini` will be used. |
|
||||
| usb3force=1 | Overrides system settings mitm config `usb30_force_enabled`. If that key doesn't exist, `system_settings.ini` will be used. |
|
||||
|
||||
|
||||
**Note1**: When using the wildcard (`/*`) with `kip1` you can still use the normal `kip1` after that to load extra single kips.
|
||||
**Note**: `cal0blank`, `cal0writesys`, `usb3force`, as stated override the `exosphere.ini` or `system_settings.ini`. 0: Disable, 1: Enable, Key Missing: Use original value.
|
||||
|
||||
**Note2**: When using FSS0 it parses exosphere, warmboot and all core kips. You can override the first 2 by using `secmon`/`warmboot` after defining `fss0`.
|
||||
You can define `kip1` to load an extra kip or many via the wildcard (`/*`) usage.
|
||||
|
||||
**Warning**: Never define *fss0 core* kips when using `fss0` and make sure that the folder (when using `/*`), does not include them.
|
||||
This is in case the kips are incompatible between them. If compatible, you can override `fss0` kips with no issues (useful for testing with intermediate kip changes).
|
||||
**Note2**: `blank_prodinfo_{sys/emu}mmc`, `allow_writing_to_cal_sysmmc` and `usb30_force_enabled` in `exosphere.ini` and `system_settings.ini` respectively, are the only atmosphere config keys that can affect hekate booting configuration externally, **if** the equivalent keys in hekate config are missing.
|
||||
|
||||
|
||||
### Payload storage:
|
||||
@@ -119,11 +131,12 @@ hekate has a boot storage in the binary that helps it configure it outside of BP
|
||||
|
||||
| Offset / Name | Description |
|
||||
| ----------------------- | ----------------------------------------------------------------- |
|
||||
| '0x94' boot_cfg | bit0: `Force AutoBoot`, bit1: `Show launch log`, bit2: Boot from ID, bit3: `Boot to emuMMC`, bit7: `sept run`. |
|
||||
| '0x94' boot_cfg | bit0: `Force AutoBoot`, bit1: `Show launch log`, bit2: `Boot from ID`, bit3: `Boot to emuMMC`, bit7: `sept run`. |
|
||||
| '0x95' autoboot | If `Force AutoBoot`: 0: Force go to menu, else boot that entry. |
|
||||
| '0x96' autoboot_list | If `Force AutoBoot` and `autoboot` then it boots from ini folder. |
|
||||
| '0x97' extra_cfg | bit7: Force Nyx to run `Dump pkg1/2`. |
|
||||
| '0x97' extra_cfg | When menu is forced: bit5: `Run UMS`, bit7: `Run Dump pkg1/2`. |
|
||||
| '0x98' xt_str[128] | Depends on the set cfg bits. |
|
||||
| '0x98' ums[1] | When `Run UMS` is set, it will launch the selected UMS. 0: SD, 1: eMMC BOOT0, 2: eMMC BOOT1, 3: eMMC GPP, 4: emuMMC BOOT0, 5: emuMMC BOOT1, 6: emuMMC GPP, |
|
||||
| '0x98' id[8] | When `Boot from ID` is set, it will search all inis automatically and find the boot entry with that id and boot it. Must be NULL terminated. |
|
||||
| '0xA0' emummc_path[120] | When `Boot to emuMMC` is set, it will override the current emuMMC (boot entry or emummc.ini). Must be NULL terminated. |
|
||||
|
||||
@@ -133,9 +146,9 @@ If the main .ini is not found, it is created on the first hekate boot.
|
||||
|
||||
```
|
||||
hekate (c) 2018, naehrwert, st4rk.
|
||||
(c) 2018-2020, CTCaer.
|
||||
(c) 2018-2021, CTCaer.
|
||||
|
||||
Nyx GUI (c) 2019-2020, CTCaer.
|
||||
Nyx GUI (c) 2019-2021, CTCaer.
|
||||
|
||||
Thanks to: derrek, nedwill, plutoo, shuffle2, smea, thexyz, yellows8.
|
||||
Greetings to: fincs, hexkyz, SciresM, Shiny Quagsire, WinterMute.
|
||||
|
||||
10
Versions.inc
10
Versions.inc
@@ -1,11 +1,11 @@
|
||||
# IPL Version.
|
||||
BLVERSION_MAJOR := 5
|
||||
BLVERSION_MINOR := 2
|
||||
BLVERSION_HOTFX := 0
|
||||
BLVERSION_MINOR := 5
|
||||
BLVERSION_HOTFX := 7
|
||||
BLVERSION_RSVD := 0
|
||||
|
||||
# Nyx Version.
|
||||
NYXVERSION_MAJOR := 0
|
||||
NYXVERSION_MINOR := 9
|
||||
NYXVERSION_HOTFX := 0
|
||||
NYXVERSION_MAJOR := 1
|
||||
NYXVERSION_MINOR := 0
|
||||
NYXVERSION_HOTFX := 4
|
||||
NYXVERSION_RSVD := 0
|
||||
|
||||
752
bdk/display/di.c
Normal file
752
bdk/display/di.c
Normal file
@@ -0,0 +1,752 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2020 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "di.h"
|
||||
#include <power/max77620.h>
|
||||
#include <power/max7762x.h>
|
||||
#include <mem/heap.h>
|
||||
#include <soc/clock.h>
|
||||
#include <soc/gpio.h>
|
||||
#include <soc/hw_init.h>
|
||||
#include <soc/i2c.h>
|
||||
#include <soc/pinmux.h>
|
||||
#include <soc/pmc.h>
|
||||
#include <soc/t210.h>
|
||||
#include <utils/util.h>
|
||||
|
||||
#include "di.inl"
|
||||
|
||||
extern volatile nyx_storage_t *nyx_str;
|
||||
|
||||
static u32 _display_id = 0;
|
||||
|
||||
static void _display_panel_and_hw_end(bool no_panel_deinit);
|
||||
|
||||
static void _display_dsi_wait(u32 timeout, u32 off, u32 mask)
|
||||
{
|
||||
u32 end = get_tmr_us() + timeout;
|
||||
while (get_tmr_us() < end && DSI(off) & mask)
|
||||
;
|
||||
usleep(5);
|
||||
}
|
||||
|
||||
static void _display_dsi_send_cmd(u8 cmd, u32 param, u32 wait)
|
||||
{
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = (param << 8) | cmd;
|
||||
DSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST;
|
||||
|
||||
if (wait)
|
||||
usleep(wait);
|
||||
}
|
||||
|
||||
static void _display_dsi_read_rx_fifo(u32 *data)
|
||||
{
|
||||
u32 fifo_count = DSI(_DSIREG(DSI_STATUS)) & DSI_STATUS_RX_FIFO_SIZE;
|
||||
for (u32 i = 0; i < fifo_count; i++)
|
||||
{
|
||||
// Read or Drain RX FIFO.
|
||||
if (data)
|
||||
data[i] = DSI(_DSIREG(DSI_RD_DATA));
|
||||
else
|
||||
(void)DSI(_DSIREG(DSI_RD_DATA));
|
||||
}
|
||||
}
|
||||
|
||||
int display_dsi_read(u8 cmd, u32 len, void *data, bool video_enabled)
|
||||
{
|
||||
int res = 0;
|
||||
u32 host_control = 0;
|
||||
u32 cmd_timeout = video_enabled ? 0 : 250000;
|
||||
u32 fifo[DSI_STATUS_RX_FIFO_SIZE] = {0};
|
||||
|
||||
// Drain RX FIFO.
|
||||
_display_dsi_read_rx_fifo(NULL);
|
||||
|
||||
// Save host control and enable host cmd packets during video.
|
||||
if (video_enabled)
|
||||
{
|
||||
host_control = DSI(_DSIREG(DSI_HOST_CONTROL));
|
||||
|
||||
// Enable vblank interrupt.
|
||||
DISPLAY_A(_DIREG(DC_CMD_INT_ENABLE)) = DC_CMD_INT_FRAME_END_INT;
|
||||
|
||||
// Use the 4th line to transmit the host cmd packet.
|
||||
DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = DSI_CMD_PKT_VID_ENABLE | DSI_DSI_LINE_TYPE(4);
|
||||
|
||||
// Wait for vblank before starting the transfer.
|
||||
DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) = DC_CMD_INT_FRAME_END_INT; // Clear interrupt.
|
||||
while (DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) & DC_CMD_INT_FRAME_END_INT)
|
||||
;
|
||||
}
|
||||
|
||||
// Set reply size.
|
||||
_display_dsi_send_cmd(MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE, len, 0);
|
||||
_display_dsi_wait(cmd_timeout, _DSIREG(DSI_TRIGGER), DSI_TRIGGER_HOST | DSI_TRIGGER_VIDEO);
|
||||
|
||||
// Request register read.
|
||||
_display_dsi_send_cmd(MIPI_DSI_DCS_READ, cmd, 0);
|
||||
_display_dsi_wait(cmd_timeout, _DSIREG(DSI_TRIGGER), DSI_TRIGGER_HOST | DSI_TRIGGER_VIDEO);
|
||||
|
||||
// Transfer bus control to device for transmitting the reply.
|
||||
u32 high_speed = video_enabled ? DSI_HOST_CONTROL_HS : 0;
|
||||
DSI(_DSIREG(DSI_HOST_CONTROL)) = DSI_HOST_CONTROL_TX_TRIG_HOST | DSI_HOST_CONTROL_IMM_BTA | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC | high_speed;
|
||||
_display_dsi_wait(150000, _DSIREG(DSI_HOST_CONTROL), DSI_HOST_CONTROL_IMM_BTA);
|
||||
|
||||
// Wait a bit for the reply.
|
||||
usleep(5000);
|
||||
|
||||
// Read RX FIFO.
|
||||
_display_dsi_read_rx_fifo(fifo);
|
||||
|
||||
// Parse packet and copy over the data.
|
||||
if ((fifo[0] & 0xFF) == DSI_ESCAPE_CMD)
|
||||
{
|
||||
// Act based on reply type.
|
||||
switch (fifo[1] & 0xFF)
|
||||
{
|
||||
case GEN_LONG_RD_RES:
|
||||
case DCS_LONG_RD_RES:
|
||||
memcpy(data, &fifo[2], MIN((fifo[1] >> 8) & 0xFFFF, len));
|
||||
break;
|
||||
|
||||
case GEN_1_BYTE_SHORT_RD_RES:
|
||||
case DCS_1_BYTE_SHORT_RD_RES:
|
||||
memcpy(data, &fifo[2], 1);
|
||||
break;
|
||||
|
||||
case GEN_2_BYTE_SHORT_RD_RES:
|
||||
case DCS_2_BYTE_SHORT_RD_RES:
|
||||
memcpy(data, &fifo[2], 2);
|
||||
break;
|
||||
case ACK_ERROR_RES:
|
||||
default:
|
||||
res = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Disable host cmd packets during video and restore host control.
|
||||
if (video_enabled)
|
||||
{
|
||||
// Wait for vblank before reseting sync points.
|
||||
DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) = DC_CMD_INT_FRAME_END_INT; // Clear interrupt.
|
||||
while (DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) & DC_CMD_INT_FRAME_END_INT)
|
||||
;
|
||||
|
||||
// Reset all states of syncpt block.
|
||||
DSI(_DSIREG(DSI_INCR_SYNCPT_CNTRL)) = DSI_INCR_SYNCPT_SOFT_RESET;
|
||||
usleep(300); // Stabilization delay.
|
||||
|
||||
// Clear syncpt block reset.
|
||||
DSI(_DSIREG(DSI_INCR_SYNCPT_CNTRL)) = 0;
|
||||
usleep(300); // Stabilization delay.
|
||||
|
||||
// Restore video mode and host control.
|
||||
DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = 0;
|
||||
DSI(_DSIREG(DSI_HOST_CONTROL)) = host_control;
|
||||
|
||||
// Disable and clear vblank interrupt.
|
||||
DISPLAY_A(_DIREG(DC_CMD_INT_ENABLE)) = 0;
|
||||
DISPLAY_A(_DIREG(DC_CMD_INT_STATUS)) = DC_CMD_INT_FRAME_END_INT;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void display_dsi_write(u8 cmd, u32 len, void *data, bool video_enabled)
|
||||
{
|
||||
u8 *fifo8;
|
||||
u32 *fifo32;
|
||||
u32 host_control;
|
||||
|
||||
// Enable host cmd packets during video and save host control.
|
||||
if (video_enabled)
|
||||
DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = DSI_CMD_PKT_VID_ENABLE;
|
||||
host_control = DSI(_DSIREG(DSI_HOST_CONTROL));
|
||||
|
||||
// Enable host transfer trigger.
|
||||
DSI(_DSIREG(DSI_HOST_CONTROL)) |= DSI_HOST_CONTROL_TX_TRIG_HOST;
|
||||
|
||||
switch (len)
|
||||
{
|
||||
case 0:
|
||||
_display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE, cmd, 0);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
_display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE_PARAM, cmd | (*(u8 *)data << 8), 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
fifo32 = calloc(DSI_STATUS_RX_FIFO_SIZE * 8, 4);
|
||||
fifo8 = (u8 *)fifo32;
|
||||
fifo32[0] = (len << 8) | MIPI_DSI_DCS_LONG_WRITE;
|
||||
fifo8[4] = cmd;
|
||||
memcpy(&fifo8[5], data, len);
|
||||
len += 4 + 1; // Increase length by CMD/length word and DCS CMD.
|
||||
for (u32 i = 0; i < (ALIGN(len, 4) / 4); i++)
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = fifo32[i];
|
||||
DSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST;
|
||||
free(fifo32);
|
||||
break;
|
||||
}
|
||||
|
||||
// Wait for the write to happen.
|
||||
_display_dsi_wait(250000, _DSIREG(DSI_TRIGGER), DSI_TRIGGER_HOST);
|
||||
|
||||
// Disable host cmd packets during video and restore host control.
|
||||
if (video_enabled)
|
||||
DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = 0;
|
||||
DSI(_DSIREG(DSI_HOST_CONTROL)) = host_control;
|
||||
}
|
||||
|
||||
void display_init()
|
||||
{
|
||||
// Check if display is already initialized.
|
||||
if (CLOCK(CLK_RST_CONTROLLER_CLK_OUT_ENB_L) & BIT(CLK_L_DISP1))
|
||||
_display_panel_and_hw_end(true);
|
||||
|
||||
// Get Chip ID.
|
||||
bool tegra_t210 = hw_get_chip_id() == GP_HIDREV_MAJOR_T210;
|
||||
|
||||
// T210B01: Power on SD2 regulator for supplying LDO0.
|
||||
if (!tegra_t210)
|
||||
{
|
||||
// Set SD2 regulator voltage.
|
||||
max7762x_regulator_set_voltage(REGULATOR_SD2, 1325000);
|
||||
|
||||
// Set slew rate and enable SD2 regulator.
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_SD2_CFG, (1 << MAX77620_SD_SR_SHIFT) | MAX77620_SD_CFG1_FSRADE_SD_ENABLE);
|
||||
max7762x_regulator_enable(REGULATOR_SD2, true);
|
||||
|
||||
}
|
||||
|
||||
// Enable power to display panel controller.
|
||||
max7762x_regulator_set_voltage(REGULATOR_LDO0, 1200000);
|
||||
max7762x_regulator_enable(REGULATOR_LDO0, true);
|
||||
|
||||
if (tegra_t210)
|
||||
max77620_config_gpio(7, MAX77620_GPIO_OUTPUT_ENABLE); // T210: LD0 -> GPIO7 -> Display panel.
|
||||
|
||||
// Enable Display Interface specific clocks.
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_CLR) = BIT(CLK_H_MIPI_CAL) | BIT(CLK_H_DSI);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_SET) = BIT(CLK_H_MIPI_CAL) | BIT(CLK_H_DSI);
|
||||
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_CLR) = BIT(CLK_L_HOST1X) | BIT(CLK_L_DISP1);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_SET) = BIT(CLK_L_HOST1X) | BIT(CLK_L_DISP1);
|
||||
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_X_SET) = BIT(CLK_X_UART_FST_MIPI_CAL);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_UART_FST_MIPI_CAL) = 10; // Set PLLP_OUT3 and div 6 (17MHz).
|
||||
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_W_SET) = BIT(CLK_W_DSIA_LP);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_DSIA_LP) = 10; // Set PLLP_OUT and div 6 (68MHz).
|
||||
|
||||
// Bring every IO rail out of deep power down.
|
||||
PMC(APBDEV_PMC_IO_DPD_REQ) = PMC_IO_DPD_REQ_DPD_OFF;
|
||||
PMC(APBDEV_PMC_IO_DPD2_REQ) = PMC_IO_DPD_REQ_DPD_OFF;
|
||||
|
||||
// Configure LCD pins.
|
||||
PINMUX_AUX(PINMUX_AUX_NFC_EN) &= ~PINMUX_TRISTATE; // PULL_DOWN
|
||||
PINMUX_AUX(PINMUX_AUX_NFC_INT) &= ~PINMUX_TRISTATE; // PULL_DOWN
|
||||
PINMUX_AUX(PINMUX_AUX_LCD_RST) &= ~PINMUX_TRISTATE; // PULL_DOWN
|
||||
|
||||
// Configure Backlight pins.
|
||||
PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) &= ~PINMUX_TRISTATE; // PULL_DOWN | 1
|
||||
PINMUX_AUX(PINMUX_AUX_LCD_BL_EN) &= ~PINMUX_TRISTATE; // PULL_DOWN
|
||||
|
||||
// Set LCD +-5V pins mode and direction
|
||||
gpio_config(GPIO_PORT_I, GPIO_PIN_0 | GPIO_PIN_1, GPIO_MODE_GPIO);
|
||||
gpio_output_enable(GPIO_PORT_I, GPIO_PIN_0 | GPIO_PIN_1, GPIO_OUTPUT_ENABLE);
|
||||
|
||||
// Enable LCD power.
|
||||
gpio_write(GPIO_PORT_I, GPIO_PIN_0, GPIO_HIGH); // LCD +5V enable.
|
||||
usleep(10000);
|
||||
gpio_write(GPIO_PORT_I, GPIO_PIN_1, GPIO_HIGH); // LCD -5V enable.
|
||||
usleep(10000);
|
||||
|
||||
// Configure Backlight PWM/EN and LCD RST pins (BL PWM, BL EN, LCD RST).
|
||||
gpio_config(GPIO_PORT_V, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2, GPIO_MODE_GPIO);
|
||||
gpio_output_enable(GPIO_PORT_V, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2, GPIO_OUTPUT_ENABLE);
|
||||
|
||||
// Enable Backlight power.
|
||||
gpio_write(GPIO_PORT_V, GPIO_PIN_1, GPIO_HIGH);
|
||||
|
||||
// Power up supply regulator for display interface.
|
||||
MIPI_CAL(_DSIREG(MIPI_CAL_MIPI_BIAS_PAD_CFG2)) = 0;
|
||||
|
||||
if (!tegra_t210)
|
||||
{
|
||||
MIPI_CAL(_DSIREG(MIPI_CAL_MIPI_BIAS_PAD_CFG0)) = 0;
|
||||
APB_MISC(APB_MISC_GP_DSI_PAD_CONTROL) = 0;
|
||||
}
|
||||
|
||||
// Set DISP1 clock source and parent clock.
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_DISP1) = 0x40000000; // PLLD_OUT.
|
||||
u32 plld_div = (3 << 20) | (20 << 11) | 1; // DIVM: 1, DIVN: 20, DIVP: 3. PLLD_OUT: 768 MHz, PLLD_OUT0 (DSI): 97.5 MHz (offset).
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLD_BASE) = PLLCX_BASE_ENABLE | PLLCX_BASE_LOCK | plld_div;
|
||||
|
||||
if (tegra_t210)
|
||||
{
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLD_MISC1) = 0x20; // PLLD_SETUP.
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLD_MISC) = 0x2D0AAA; // PLLD_ENABLE_CLK.
|
||||
}
|
||||
else
|
||||
{
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLD_MISC1) = 0;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLD_MISC) = 0x2DFC00; // PLLD_ENABLE_CLK.
|
||||
}
|
||||
|
||||
// Setup Display Interface initial window configuration.
|
||||
exec_cfg((u32 *)DISPLAY_A_BASE, _display_dc_setup_win_config, 94);
|
||||
|
||||
// Setup display communication interfaces.
|
||||
exec_cfg((u32 *)DSI_BASE, _display_dsi_init_config_part1, 8);
|
||||
if (tegra_t210)
|
||||
DSI(_DSIREG(DSI_INIT_SEQ_DATA_15)) = 0;
|
||||
else
|
||||
DSI(_DSIREG(DSI_INIT_SEQ_DATA_15_B01)) = 0;
|
||||
exec_cfg((u32 *)DSI_BASE, _display_dsi_init_config_part2, 14);
|
||||
if (!tegra_t210)
|
||||
exec_cfg((u32 *)DSI_BASE, _display_dsi_init_config_part3_t210b01, 7);
|
||||
exec_cfg((u32 *)DSI_BASE, _display_dsi_init_config_part4, 10);
|
||||
DSI(_DSIREG(DSI_PHY_TIMING_0)) = tegra_t210 ? 0x6070601 : 0x6070603;
|
||||
exec_cfg((u32 *)DSI_BASE, _display_dsi_init_config_part5, 12);
|
||||
DSI(_DSIREG(DSI_PHY_TIMING_0)) = tegra_t210 ? 0x6070601 : 0x6070603;
|
||||
exec_cfg((u32 *)DSI_BASE, _display_dsi_init_config_part6, 14);
|
||||
usleep(10000);
|
||||
|
||||
// Enable LCD Reset.
|
||||
gpio_write(GPIO_PORT_V, GPIO_PIN_2, GPIO_HIGH);
|
||||
usleep(60000);
|
||||
|
||||
// Setup DSI device takeover timeout.
|
||||
DSI(_DSIREG(DSI_BTA_TIMING)) = 0x50204;
|
||||
|
||||
#if 0
|
||||
// Get Display ID.
|
||||
_display_id = 0xCCCCCC; // Set initial value. 4th byte cleared.
|
||||
display_dsi_read(MIPI_DCS_GET_DISPLAY_ID, 3, &_display_id, DSI_VIDEO_DISABLED);
|
||||
#else
|
||||
// Drain RX FIFO.
|
||||
_display_dsi_read_rx_fifo(NULL);
|
||||
|
||||
// Set reply size.
|
||||
_display_dsi_send_cmd(MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE, 3, 0);
|
||||
_display_dsi_wait(250000, _DSIREG(DSI_TRIGGER), DSI_TRIGGER_HOST | DSI_TRIGGER_VIDEO);
|
||||
|
||||
// Request register read.
|
||||
_display_dsi_send_cmd(MIPI_DSI_DCS_READ, MIPI_DCS_GET_DISPLAY_ID, 0);
|
||||
_display_dsi_wait(250000, _DSIREG(DSI_TRIGGER), DSI_TRIGGER_HOST | DSI_TRIGGER_VIDEO);
|
||||
|
||||
// Transfer bus control to device for transmitting the reply.
|
||||
DSI(_DSIREG(DSI_HOST_CONTROL)) = DSI_HOST_CONTROL_TX_TRIG_HOST | DSI_HOST_CONTROL_IMM_BTA | DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC;
|
||||
_display_dsi_wait(150000, _DSIREG(DSI_HOST_CONTROL), DSI_HOST_CONTROL_IMM_BTA);
|
||||
|
||||
// Wait a bit for the reply.
|
||||
usleep(5000);
|
||||
|
||||
// MIPI_DCS_GET_DISPLAY_ID reply is a long read, size 3 x u32.
|
||||
for (u32 i = 0; i < 3; i++)
|
||||
_display_id = DSI(_DSIREG(DSI_RD_DATA)) & 0xFFFFFF; // Skip ack and msg type info and get the payload (display id).
|
||||
#endif
|
||||
// Save raw Display ID to Nyx storage.
|
||||
nyx_str->info.disp_id = _display_id;
|
||||
|
||||
// Decode Display ID.
|
||||
_display_id = ((_display_id >> 8) & 0xFF00) | (_display_id & 0xFF);
|
||||
|
||||
if ((_display_id & 0xFF) == PANEL_JDI_XXX062M)
|
||||
_display_id = PANEL_JDI_XXX062M;
|
||||
|
||||
// Initialize display panel.
|
||||
switch (_display_id)
|
||||
{
|
||||
case PANEL_JDI_XXX062M:
|
||||
exec_cfg((u32 *)DSI_BASE, _display_init_config_jdi, 43);
|
||||
_display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE, MIPI_DCS_EXIT_SLEEP_MODE, 180000);
|
||||
break;
|
||||
|
||||
case PANEL_INL_P062CCA_AZ1:
|
||||
case PANEL_AUO_A062TAN01:
|
||||
_display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE, MIPI_DCS_EXIT_SLEEP_MODE, 180000);
|
||||
|
||||
// Unlock extension cmds.
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = 0x439; // MIPI_DSI_DCS_LONG_WRITE: 4 bytes.
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = 0x9483FFB9; // MIPI_DCS_PRIV_SET_EXTC. (Pass: FF 83 94).
|
||||
DSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST;
|
||||
usleep(5000);
|
||||
|
||||
// Set Power control.
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = 0x739; // MIPI_DSI_DCS_LONG_WRITE: 7 bytes.
|
||||
if (_display_id == PANEL_INL_P062CCA_AZ1)
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = 0x751548B1; // MIPI_DCS_PRIV_SET_POWER_CONTROL. (Not deep standby, BT5 / XDK, VRH gamma volt adj 53 / x40).
|
||||
else // PANEL_AUO_A062TAN01.
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = 0x711148B1; // MIPI_DCS_PRIV_SET_POWER_CONTROL. (Not deep standby, BT1 / XDK, VRH gamma volt adj 49 / x40).
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = 0x143209; // (NVRH gamma volt adj 9, Amplifier current small / x30, FS0 freq Fosc/80 / FS1 freq Fosc/32).
|
||||
DSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST;
|
||||
usleep(5000);
|
||||
break;
|
||||
|
||||
case PANEL_INL_2J055IA_27A:
|
||||
case PANEL_AUO_A055TAN01:
|
||||
case PANEL_V40_55_UNK:
|
||||
default: // Allow spare part displays to work.
|
||||
_display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE, MIPI_DCS_EXIT_SLEEP_MODE, 120000);
|
||||
break;
|
||||
}
|
||||
|
||||
// Unblank display.
|
||||
_display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE, MIPI_DCS_SET_DISPLAY_ON, 20000);
|
||||
|
||||
// Configure PLLD for DISP1.
|
||||
plld_div = (1 << 20) | (24 << 11) | 1; // DIVM: 1, DIVN: 24, DIVP: 1. PLLD_OUT: 768 MHz, PLLD_OUT0 (DSI): 234 MHz (offset).
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLD_BASE) = PLLCX_BASE_ENABLE | PLLCX_BASE_LOCK | plld_div;
|
||||
|
||||
if (tegra_t210)
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLD_MISC1) = 0x20; // PLLD_SETUP.
|
||||
else
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLD_MISC1) = 0;
|
||||
CLOCK(CLK_RST_CONTROLLER_PLLD_MISC) = 0x2DFC00; // Use new PLLD_SDM_DIN.
|
||||
|
||||
// Finalize DSI configuration.
|
||||
DSI(_DSIREG(DSI_PAD_CONTROL_1)) = 0;
|
||||
DSI(_DSIREG(DSI_PHY_TIMING_0)) = tegra_t210 ? 0x6070601 : 0x6070603;
|
||||
exec_cfg((u32 *)DSI_BASE, _display_dsi_packet_config, 19);
|
||||
// Set pixel clock dividers: 234 / 3 / 1 = 78 MHz (offset) for 60 Hz.
|
||||
DISPLAY_A(_DIREG(DC_DISP_DISP_CLOCK_CONTROL)) = PIXEL_CLK_DIVIDER_PCD1 | SHIFT_CLK_DIVIDER(4); // 4: div3.
|
||||
exec_cfg((u32 *)DSI_BASE, _display_dsi_mode_config, 10);
|
||||
usleep(10000);
|
||||
|
||||
// Calibrate display communication pads.
|
||||
u32 loops = tegra_t210 ? 1 : 2; // Find out why this is done 2 times on Mariko.
|
||||
exec_cfg((u32 *)MIPI_CAL_BASE, _display_mipi_pad_cal_config, 4);
|
||||
for (u32 i = 0; i < loops; i++)
|
||||
{
|
||||
// Set MIPI bias pad config.
|
||||
MIPI_CAL(_DSIREG(MIPI_CAL_MIPI_BIAS_PAD_CFG2)) = 0x10010;
|
||||
MIPI_CAL(_DSIREG(MIPI_CAL_MIPI_BIAS_PAD_CFG1)) = tegra_t210 ? 0x300 : 0;
|
||||
|
||||
// Set pad trimmers and set MIPI DSI cal offsets.
|
||||
if (tegra_t210)
|
||||
{
|
||||
exec_cfg((u32 *)DSI_BASE, _display_dsi_pad_cal_config_t210, 4);
|
||||
exec_cfg((u32 *)MIPI_CAL_BASE, _display_mipi_dsi_cal_offsets_config_t210, 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
exec_cfg((u32 *)DSI_BASE, _display_dsi_pad_cal_config_t210b01, 7);
|
||||
exec_cfg((u32 *)MIPI_CAL_BASE, _display_mipi_dsi_cal_offsets_config_t210b01, 4);
|
||||
}
|
||||
|
||||
// Set the rest of MIPI cal offsets and apply calibration.
|
||||
exec_cfg((u32 *)MIPI_CAL_BASE, _display_mipi_apply_dsi_cal_config, 12);
|
||||
}
|
||||
usleep(10000);
|
||||
|
||||
// Enable video display controller.
|
||||
exec_cfg((u32 *)DISPLAY_A_BASE, _display_video_disp_controller_enable_config, 113);
|
||||
}
|
||||
|
||||
void display_backlight_pwm_init()
|
||||
{
|
||||
clock_enable_pwm();
|
||||
|
||||
PWM(PWM_CONTROLLER_PWM_CSR_0) = PWM_CSR_EN; // Enable PWM and set it to 25KHz PFM. 29.5KHz is stock.
|
||||
|
||||
PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) = (PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) & ~PINMUX_FUNC_MASK) | 1; // Set PWM0 mode.
|
||||
gpio_config(GPIO_PORT_V, GPIO_PIN_0, GPIO_MODE_SPIO); // Backlight power mode.
|
||||
}
|
||||
|
||||
void display_backlight(bool enable)
|
||||
{
|
||||
gpio_write(GPIO_PORT_V, GPIO_PIN_0, enable ? GPIO_HIGH : GPIO_LOW); // Backlight PWM GPIO.
|
||||
}
|
||||
|
||||
void display_backlight_brightness(u32 brightness, u32 step_delay)
|
||||
{
|
||||
u32 old_value = (PWM(PWM_CONTROLLER_PWM_CSR_0) >> 16) & 0xFF;
|
||||
if (brightness == old_value)
|
||||
return;
|
||||
|
||||
if (brightness > 255)
|
||||
brightness = 255;
|
||||
|
||||
if (old_value < brightness)
|
||||
{
|
||||
for (u32 i = old_value; i < brightness + 1; i++)
|
||||
{
|
||||
PWM(PWM_CONTROLLER_PWM_CSR_0) = PWM_CSR_EN | (i << 16); // Enable PWM and set it to 25KHz PFM.
|
||||
usleep(step_delay);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (u32 i = old_value; i > brightness; i--)
|
||||
{
|
||||
PWM(PWM_CONTROLLER_PWM_CSR_0) = PWM_CSR_EN | (i << 16); // Enable PWM and set it to 25KHz PFM.
|
||||
usleep(step_delay);
|
||||
}
|
||||
}
|
||||
if (!brightness)
|
||||
PWM(PWM_CONTROLLER_PWM_CSR_0) = 0;
|
||||
}
|
||||
|
||||
u32 display_get_backlight_brightness()
|
||||
{
|
||||
return ((PWM(PWM_CONTROLLER_PWM_CSR_0) >> 16) & 0xFF);
|
||||
}
|
||||
|
||||
static void _display_panel_and_hw_end(bool no_panel_deinit)
|
||||
{
|
||||
if (no_panel_deinit)
|
||||
goto skip_panel_deinit;
|
||||
|
||||
display_backlight_brightness(0, 1000);
|
||||
|
||||
// Enable host cmd packets during video.
|
||||
DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = DSI_CMD_PKT_VID_ENABLE;
|
||||
|
||||
// Blank display.
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = (MIPI_DCS_SET_DISPLAY_OFF << 8) | MIPI_DSI_DCS_SHORT_WRITE;
|
||||
|
||||
// Propagate changes to all register buffers and disable host cmd packets during video.
|
||||
DISPLAY_A(_DIREG(DC_CMD_STATE_ACCESS)) = READ_MUX | WRITE_MUX;
|
||||
DSI(_DSIREG(DSI_VIDEO_MODE_CONTROL)) = 0;
|
||||
|
||||
// De-initialize video controller.
|
||||
exec_cfg((u32 *)DISPLAY_A_BASE, _display_video_disp_controller_disable_config, 17);
|
||||
exec_cfg((u32 *)DSI_BASE, _display_dsi_timing_deinit_config, 16);
|
||||
usleep(10000);
|
||||
|
||||
// De-initialize display panel.
|
||||
switch (_display_id)
|
||||
{
|
||||
case PANEL_JDI_XXX062M:
|
||||
exec_cfg((u32 *)DSI_BASE, _display_deinit_config_jdi, 22);
|
||||
break;
|
||||
|
||||
case PANEL_AUO_A062TAN01:
|
||||
exec_cfg((u32 *)DSI_BASE, _display_deinit_config_auo, 37);
|
||||
break;
|
||||
|
||||
case PANEL_INL_2J055IA_27A:
|
||||
case PANEL_AUO_A055TAN01:
|
||||
case PANEL_V40_55_UNK:
|
||||
// Unlock extension cmds.
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = 0x439; // MIPI_DSI_DCS_LONG_WRITE: 4 bytes.
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = 0x9483FFB9; // MIPI_DCS_PRIV_SET_EXTC. (Pass: FF 83 94).
|
||||
DSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST;
|
||||
usleep(5000);
|
||||
|
||||
// Set Power control.
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = 0xB39; // MIPI_DSI_DCS_LONG_WRITE: 11 bytes.
|
||||
if (_display_id == PANEL_INL_2J055IA_27A)
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = 0x751548B1; // MIPI_DCS_PRIV_SET_POWER_CONTROL. (Not deep standby, BT5 / XDK, VRH gamma volt adj 53 / x40).
|
||||
else if (_display_id == PANEL_AUO_A055TAN01)
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = 0x711148B1; // MIPI_DCS_PRIV_SET_POWER_CONTROL. (Not deep standby, BT1 / XDK, VRH gamma volt adj 49 / x40).
|
||||
else // PANEL_V40_55_UNK.
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = 0x731348B1; // MIPI_DCS_PRIV_SET_POWER_CONTROL. (Not deep standby, BT3 / XDK, VRH gamma volt adj 51 / x40).
|
||||
if (_display_id == PANEL_INL_2J055IA_27A || _display_id == PANEL_AUO_A055TAN01)
|
||||
{
|
||||
// (NVRH gamma volt adj 9, Amplifier current small / x30, FS0 freq Fosc/80 / FS1 freq Fosc/32, Enter standby / PON / VCOMG).
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = 0x71143209;
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = 0x114D31; // (Unknown).
|
||||
}
|
||||
else // PANEL_V40_55_UNK.
|
||||
{
|
||||
// (NVRH gamma volt adj 9, Amplifier current small / x30, FS0 freq Fosc/80 / FS1 freq Fosc/48, Enter standby / PON / VCOMG).
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = 0x71243209;
|
||||
DSI(_DSIREG(DSI_WR_DATA)) = 0x004C31; // (Unknown).
|
||||
}
|
||||
DSI(_DSIREG(DSI_TRIGGER)) = DSI_TRIGGER_HOST;
|
||||
usleep(5000);
|
||||
break;
|
||||
|
||||
case PANEL_INL_P062CCA_AZ1:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Blank - powerdown.
|
||||
_display_dsi_send_cmd(MIPI_DSI_DCS_SHORT_WRITE, MIPI_DCS_ENTER_SLEEP_MODE, 50000);
|
||||
|
||||
skip_panel_deinit:
|
||||
// Disable LCD power pins.
|
||||
gpio_write(GPIO_PORT_V, GPIO_PIN_2, GPIO_LOW); // LCD Reset disable.
|
||||
usleep(10000);
|
||||
gpio_write(GPIO_PORT_I, GPIO_PIN_1, GPIO_LOW); // LCD -5V disable.
|
||||
usleep(10000);
|
||||
gpio_write(GPIO_PORT_I, GPIO_PIN_0, GPIO_LOW); // LCD +5V disable.
|
||||
usleep(10000);
|
||||
|
||||
// Disable Display Interface specific clocks.
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_H_SET) = BIT(CLK_H_MIPI_CAL) | BIT(CLK_H_DSI);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_H_CLR) = BIT(CLK_H_MIPI_CAL) | BIT(CLK_H_DSI);
|
||||
CLOCK(CLK_RST_CONTROLLER_RST_DEV_L_SET) = BIT(CLK_L_HOST1X) | BIT(CLK_L_DISP1);
|
||||
CLOCK(CLK_RST_CONTROLLER_CLK_ENB_L_CLR) = BIT(CLK_L_HOST1X) | BIT(CLK_L_DISP1);
|
||||
|
||||
// Power down pads.
|
||||
DSI(_DSIREG(DSI_PAD_CONTROL_0)) = DSI_PAD_CONTROL_VS1_PULLDN_CLK | DSI_PAD_CONTROL_VS1_PULLDN(0xF) | DSI_PAD_CONTROL_VS1_PDIO_CLK | DSI_PAD_CONTROL_VS1_PDIO(0xF);
|
||||
DSI(_DSIREG(DSI_POWER_CONTROL)) = 0;
|
||||
|
||||
// Switch LCD PWM backlight pin to special function mode and enable PWM0 mode.
|
||||
gpio_config(GPIO_PORT_V, GPIO_PIN_0, GPIO_MODE_SPIO); // Backlight PWM.
|
||||
PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) = (PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) & ~PINMUX_TRISTATE) | PINMUX_TRISTATE;
|
||||
PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) = (PINMUX_AUX(PINMUX_AUX_LCD_BL_PWM) & ~PINMUX_FUNC_MASK) | 1; // Set PWM0 mode.
|
||||
}
|
||||
|
||||
void display_end() { _display_panel_and_hw_end(false); };
|
||||
|
||||
u16 display_get_decoded_panel_id()
|
||||
{
|
||||
return _display_id;
|
||||
}
|
||||
|
||||
void display_set_decoded_panel_id(u32 id)
|
||||
{
|
||||
// Decode Display ID.
|
||||
_display_id = ((id >> 8) & 0xFF00) | (id & 0xFF);
|
||||
|
||||
if ((_display_id & 0xFF) == PANEL_JDI_XXX062M)
|
||||
_display_id = PANEL_JDI_XXX062M;
|
||||
}
|
||||
|
||||
void display_color_screen(u32 color)
|
||||
{
|
||||
exec_cfg((u32 *)DISPLAY_A_BASE, cfg_display_one_color, 8);
|
||||
|
||||
// Configure display to show single color.
|
||||
DISPLAY_A(_DIREG(DC_WIN_AD_WIN_OPTIONS)) = 0;
|
||||
DISPLAY_A(_DIREG(DC_WIN_BD_WIN_OPTIONS)) = 0;
|
||||
DISPLAY_A(_DIREG(DC_WIN_CD_WIN_OPTIONS)) = 0;
|
||||
DISPLAY_A(_DIREG(DC_DISP_BLEND_BACKGROUND_COLOR)) = color;
|
||||
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = (DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) & 0xFFFFFFFE) | GENERAL_ACT_REQ;
|
||||
usleep(35000);
|
||||
|
||||
display_backlight(true);
|
||||
}
|
||||
|
||||
u32 *display_init_framebuffer_pitch()
|
||||
{
|
||||
// Sanitize framebuffer area.
|
||||
memset((u32 *)IPL_FB_ADDRESS, 0, 0x3C0000);
|
||||
|
||||
// This configures the framebuffer @ IPL_FB_ADDRESS with a resolution of 1280x720 (line stride 720).
|
||||
exec_cfg((u32 *)DISPLAY_A_BASE, cfg_display_framebuffer_pitch, 32);
|
||||
usleep(35000);
|
||||
|
||||
return (u32 *)IPL_FB_ADDRESS;
|
||||
}
|
||||
|
||||
u32 *display_init_framebuffer_pitch_inv()
|
||||
{
|
||||
// This configures the framebuffer @ NYX_FB_ADDRESS with a resolution of 1280x720 (line stride 720).
|
||||
exec_cfg((u32 *)DISPLAY_A_BASE, cfg_display_framebuffer_pitch_inv, 34);
|
||||
|
||||
usleep(35000);
|
||||
|
||||
return (u32 *)NYX_FB_ADDRESS;
|
||||
}
|
||||
|
||||
u32 *display_init_framebuffer_block()
|
||||
{
|
||||
// This configures the framebuffer @ NYX_FB_ADDRESS with a resolution of 1280x720 (line stride 720).
|
||||
exec_cfg((u32 *)DISPLAY_A_BASE, cfg_display_framebuffer_block, 34);
|
||||
|
||||
usleep(35000);
|
||||
|
||||
return (u32 *)NYX_FB_ADDRESS;
|
||||
}
|
||||
|
||||
u32 *display_init_framebuffer_log()
|
||||
{
|
||||
// This configures the framebuffer @ LOG_FB_ADDRESS with a resolution of 1280x720 (line stride 720).
|
||||
exec_cfg((u32 *)DISPLAY_A_BASE, cfg_display_framebuffer_log, 20);
|
||||
|
||||
return (u32 *)LOG_FB_ADDRESS;
|
||||
}
|
||||
|
||||
void display_activate_console()
|
||||
{
|
||||
DISPLAY_A(_DIREG(DC_CMD_DISPLAY_WINDOW_HEADER)) = WINDOW_D_SELECT; // Select window D.
|
||||
DISPLAY_A(_DIREG(DC_WIN_WIN_OPTIONS)) = WIN_ENABLE; // Enable window DD.
|
||||
DISPLAY_A(_DIREG(DC_WIN_POSITION)) = 0xFF80;
|
||||
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | WIN_D_UPDATE;
|
||||
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | WIN_D_ACT_REQ;
|
||||
|
||||
for (u32 i = 0xFF80; i < 0x10000; i++)
|
||||
{
|
||||
DISPLAY_A(_DIREG(DC_WIN_POSITION)) = i & 0xFFFF;
|
||||
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | WIN_D_UPDATE;
|
||||
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | WIN_D_ACT_REQ;
|
||||
usleep(1000);
|
||||
}
|
||||
|
||||
DISPLAY_A(_DIREG(DC_WIN_POSITION)) = 0;
|
||||
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | WIN_D_UPDATE;
|
||||
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | WIN_D_ACT_REQ;
|
||||
}
|
||||
|
||||
void display_deactivate_console()
|
||||
{
|
||||
DISPLAY_A(_DIREG(DC_CMD_DISPLAY_WINDOW_HEADER)) = WINDOW_D_SELECT; // Select window D.
|
||||
|
||||
for (u32 i = 0xFFFF; i > 0xFF7F; i--)
|
||||
{
|
||||
DISPLAY_A(_DIREG(DC_WIN_POSITION)) = i & 0xFFFF;
|
||||
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | WIN_D_UPDATE;
|
||||
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | WIN_D_ACT_REQ;
|
||||
usleep(500);
|
||||
}
|
||||
|
||||
DISPLAY_A(_DIREG(DC_WIN_POSITION)) = 0;
|
||||
DISPLAY_A(_DIREG(DC_WIN_WIN_OPTIONS)) = 0; // Disable window DD.
|
||||
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | WIN_D_UPDATE;
|
||||
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | WIN_D_ACT_REQ;
|
||||
}
|
||||
|
||||
void display_init_cursor(void *crs_fb, u32 size)
|
||||
{
|
||||
// Setup cursor.
|
||||
DISPLAY_A(_DIREG(DC_DISP_CURSOR_START_ADDR)) = CURSOR_CLIPPING(CURSOR_CLIP_WIN_A) | size | ((u32)crs_fb >> 10);
|
||||
DISPLAY_A(_DIREG(DC_DISP_BLEND_CURSOR_CONTROL)) =
|
||||
CURSOR_BLEND_R8G8B8A8 | CURSOR_BLEND_DST_FACTOR(CURSOR_BLEND_K1) | CURSOR_BLEND_SRC_FACTOR(CURSOR_BLEND_K1) | 0xFF;
|
||||
|
||||
DISPLAY_A(_DIREG(DC_DISP_DISP_WIN_OPTIONS)) |= CURSOR_ENABLE;
|
||||
|
||||
// Arm and activate changes.
|
||||
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | CURSOR_UPDATE;
|
||||
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | CURSOR_ACT_REQ;
|
||||
}
|
||||
|
||||
void display_set_pos_cursor(u32 x, u32 y)
|
||||
{
|
||||
DISPLAY_A(_DIREG(DC_DISP_CURSOR_POSITION)) = x | (y << 16);
|
||||
|
||||
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | CURSOR_UPDATE;
|
||||
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | CURSOR_ACT_REQ;
|
||||
}
|
||||
|
||||
void display_deinit_cursor()
|
||||
{
|
||||
DISPLAY_A(_DIREG(DC_DISP_BLEND_CURSOR_CONTROL)) = 0;
|
||||
DISPLAY_A(_DIREG(DC_DISP_DISP_WIN_OPTIONS)) &= ~CURSOR_ENABLE;
|
||||
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_UPDATE | CURSOR_UPDATE;
|
||||
DISPLAY_A(_DIREG(DC_CMD_STATE_CONTROL)) = GENERAL_ACT_REQ | CURSOR_ACT_REQ;
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2019 CTCaer
|
||||
* Copyright (c) 2018-2020 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -18,8 +18,11 @@
|
||||
#ifndef _DI_H_
|
||||
#define _DI_H_
|
||||
|
||||
#include "../../../common/memory_map.h"
|
||||
#include "../utils/types.h"
|
||||
#include <memory_map.h>
|
||||
#include <utils/types.h>
|
||||
|
||||
#define DSI_VIDEO_DISABLED 0
|
||||
#define DSI_VIDEO_ENABLED 1
|
||||
|
||||
/*! Display registers. */
|
||||
#define _DIREG(reg) ((reg) * 4)
|
||||
@@ -42,11 +45,11 @@
|
||||
#define DC_CMD_GENERAL_INCR_SYNCPT 0x00
|
||||
|
||||
#define DC_CMD_GENERAL_INCR_SYNCPT_CNTRL 0x01
|
||||
#define SYNCPT_CNTRL_NO_STALL (1 << 8)
|
||||
#define SYNCPT_CNTRL_SOFT_RESET (1 << 0)
|
||||
#define SYNCPT_CNTRL_SOFT_RESET BIT(0)
|
||||
#define SYNCPT_CNTRL_NO_STALL BIT(8)
|
||||
|
||||
#define DC_CMD_CONT_SYNCPT_VSYNC 0x28
|
||||
#define SYNCPT_VSYNC_ENABLE (1 << 8)
|
||||
#define SYNCPT_VSYNC_ENABLE BIT(8)
|
||||
|
||||
#define DC_CMD_DISPLAY_COMMAND_OPTION0 0x031
|
||||
|
||||
@@ -57,42 +60,43 @@
|
||||
#define DISP_CTRL_MODE_MASK (3 << 5)
|
||||
|
||||
#define DC_CMD_DISPLAY_POWER_CONTROL 0x36
|
||||
#define PW0_ENABLE (1 << 0)
|
||||
#define PW1_ENABLE (1 << 2)
|
||||
#define PW2_ENABLE (1 << 4)
|
||||
#define PW3_ENABLE (1 << 6)
|
||||
#define PW4_ENABLE (1 << 8)
|
||||
#define PM0_ENABLE (1 << 16)
|
||||
#define PM1_ENABLE (1 << 18)
|
||||
#define PW0_ENABLE BIT(0)
|
||||
#define PW1_ENABLE BIT(2)
|
||||
#define PW2_ENABLE BIT(4)
|
||||
#define PW3_ENABLE BIT(6)
|
||||
#define PW4_ENABLE BIT(8)
|
||||
#define PM0_ENABLE BIT(16)
|
||||
#define PM1_ENABLE BIT(18)
|
||||
|
||||
#define DC_CMD_INT_STATUS 0x37
|
||||
#define DC_CMD_INT_MASK 0x38
|
||||
#define DC_CMD_INT_ENABLE 0x39
|
||||
#define DC_CMD_INT_FRAME_END_INT BIT(1)
|
||||
|
||||
#define DC_CMD_STATE_ACCESS 0x40
|
||||
#define READ_MUX (1 << 0)
|
||||
#define WRITE_MUX (1 << 2)
|
||||
#define READ_MUX BIT(0)
|
||||
#define WRITE_MUX BIT(2)
|
||||
|
||||
#define DC_CMD_STATE_CONTROL 0x41
|
||||
#define GENERAL_ACT_REQ (1 << 0)
|
||||
#define WIN_A_ACT_REQ (1 << 1)
|
||||
#define WIN_B_ACT_REQ (1 << 2)
|
||||
#define WIN_C_ACT_REQ (1 << 3)
|
||||
#define WIN_D_ACT_REQ (1 << 4)
|
||||
#define CURSOR_ACT_REQ (1 << 7)
|
||||
#define GENERAL_UPDATE (1 << 8)
|
||||
#define WIN_A_UPDATE (1 << 9)
|
||||
#define WIN_B_UPDATE (1 << 10)
|
||||
#define WIN_C_UPDATE (1 << 11)
|
||||
#define WIN_D_UPDATE (1 << 12)
|
||||
#define CURSOR_UPDATE (1 << 15)
|
||||
#define NC_HOST_TRIG (1 << 24)
|
||||
#define GENERAL_ACT_REQ BIT(0)
|
||||
#define WIN_A_ACT_REQ BIT(1)
|
||||
#define WIN_B_ACT_REQ BIT(2)
|
||||
#define WIN_C_ACT_REQ BIT(3)
|
||||
#define WIN_D_ACT_REQ BIT(4)
|
||||
#define CURSOR_ACT_REQ BIT(7)
|
||||
#define GENERAL_UPDATE BIT(8)
|
||||
#define WIN_A_UPDATE BIT(9)
|
||||
#define WIN_B_UPDATE BIT(10)
|
||||
#define WIN_C_UPDATE BIT(11)
|
||||
#define WIN_D_UPDATE BIT(12)
|
||||
#define CURSOR_UPDATE BIT(15)
|
||||
#define NC_HOST_TRIG BIT(24)
|
||||
|
||||
#define DC_CMD_DISPLAY_WINDOW_HEADER 0x42
|
||||
#define WINDOW_A_SELECT (1 << 4)
|
||||
#define WINDOW_B_SELECT (1 << 5)
|
||||
#define WINDOW_C_SELECT (1 << 6)
|
||||
#define WINDOW_D_SELECT (1 << 7)
|
||||
#define WINDOW_A_SELECT BIT(4)
|
||||
#define WINDOW_B_SELECT BIT(5)
|
||||
#define WINDOW_C_SELECT BIT(6)
|
||||
#define WINDOW_D_SELECT BIT(7)
|
||||
|
||||
#define DC_CMD_REG_ACT_CONTROL 0x043
|
||||
|
||||
@@ -125,12 +129,13 @@
|
||||
|
||||
// DC_DISP shadowed registers.
|
||||
#define DC_DISP_DISP_WIN_OPTIONS 0x402
|
||||
#define HDMI_ENABLE (1 << 30)
|
||||
#define DSI_ENABLE (1 << 29)
|
||||
#define SOR1_TIMING_CYA (1 << 27)
|
||||
#define SOR1_ENABLE (1 << 26)
|
||||
#define SOR_ENABLE (1 << 25)
|
||||
#define CURSOR_ENABLE (1 << 16)
|
||||
#define CURSOR_ENABLE BIT(16)
|
||||
#define SOR_ENABLE BIT(25)
|
||||
#define SOR1_ENABLE BIT(26)
|
||||
#define SOR1_TIMING_CYA BIT(27)
|
||||
#define DSI_ENABLE BIT(29)
|
||||
#define HDMI_ENABLE BIT(30)
|
||||
|
||||
|
||||
#define DC_DISP_DISP_MEM_HIGH_PRIORITY 0x403
|
||||
#define DC_DISP_DISP_MEM_HIGH_PRIORITY_TIMER 0x404
|
||||
@@ -142,6 +147,7 @@
|
||||
#define DC_DISP_FRONT_PORCH 0x40A
|
||||
|
||||
#define DC_DISP_DISP_CLOCK_CONTROL 0x42E
|
||||
#define SHIFT_CLK_DIVIDER(x) ((x) & 0xff)
|
||||
#define PIXEL_CLK_DIVIDER_PCD1 (0 << 8)
|
||||
#define PIXEL_CLK_DIVIDER_PCD1H (1 << 8)
|
||||
#define PIXEL_CLK_DIVIDER_PCD2 (2 << 8)
|
||||
@@ -155,7 +161,6 @@
|
||||
#define PIXEL_CLK_DIVIDER_PCD18 (10 << 8)
|
||||
#define PIXEL_CLK_DIVIDER_PCD24 (11 << 8)
|
||||
#define PIXEL_CLK_DIVIDER_PCD13 (12 << 8)
|
||||
#define SHIFT_CLK_DIVIDER(x) ((x) & 0xff)
|
||||
|
||||
#define DC_DISP_DISP_INTERFACE_CONTROL 0x42F
|
||||
#define DISP_DATA_FORMAT_DF1P1C (0 << 0)
|
||||
@@ -189,8 +194,8 @@
|
||||
#define BASE_COLOR_SIZE_888 (8 << 0)
|
||||
|
||||
#define DC_DISP_SHIFT_CLOCK_OPTIONS 0x431
|
||||
#define SC1_H_QUALIFIER_NONE (1 << 16)
|
||||
#define SC0_H_QUALIFIER_NONE (1 << 0)
|
||||
#define SC0_H_QUALIFIER_NONE BIT(0)
|
||||
#define SC1_H_QUALIFIER_NONE BIT(16)
|
||||
|
||||
#define DC_DISP_DATA_ENABLE_OPTIONS 0x432
|
||||
#define DE_SELECT_ACTIVE_BLANK (0 << 0)
|
||||
@@ -217,6 +222,7 @@
|
||||
#define CURSOR_SIZE_128 (2 << 24)
|
||||
#define CURSOR_SIZE_256 (3 << 24)
|
||||
#define DC_DISP_CURSOR_POSITION 0x440
|
||||
#define DC_DISP_BLEND_BACKGROUND_COLOR 0x4E4
|
||||
#define DC_DISP_CURSOR_START_ADDR_HI 0x4EC
|
||||
#define DC_DISP_BLEND_CURSOR_CONTROL 0x4F1
|
||||
#define CURSOR_BLEND_2BIT (0 << 24)
|
||||
@@ -247,12 +253,12 @@
|
||||
|
||||
// The following registers are A/B/C shadows of the 0xB80/0xD80/0xF80 registers (see DISPLAY_WINDOW_HEADER).
|
||||
#define DC_WIN_WIN_OPTIONS 0x700
|
||||
#define H_DIRECTION (1 << 0)
|
||||
#define V_DIRECTION (1 << 2)
|
||||
#define SCAN_COLUMN (1 << 4)
|
||||
#define COLOR_EXPAND (1 << 6)
|
||||
#define CSC_ENABLE (1 << 18)
|
||||
#define WIN_ENABLE (1 << 30)
|
||||
#define H_DIRECTION BIT(0)
|
||||
#define V_DIRECTION BIT(2)
|
||||
#define SCAN_COLUMN BIT(4)
|
||||
#define COLOR_EXPAND BIT(6)
|
||||
#define CSC_ENABLE BIT(18)
|
||||
#define WIN_ENABLE BIT(30)
|
||||
|
||||
#define DC_WIN_BUFFER_CONTROL 0x702
|
||||
#define BUFFER_CONTROL_HOST 0
|
||||
@@ -358,6 +364,10 @@
|
||||
/*! Display serial interface registers. */
|
||||
#define _DSIREG(reg) ((reg) * 4)
|
||||
|
||||
#define DSI_INCR_SYNCPT_CNTRL 0x1
|
||||
#define DSI_INCR_SYNCPT_SOFT_RESET BIT(0)
|
||||
#define DSI_INCR_SYNCPT_NO_STALL BIT(8)
|
||||
|
||||
#define DSI_RD_DATA 0x9
|
||||
#define DSI_WR_DATA 0xA
|
||||
|
||||
@@ -369,39 +379,42 @@
|
||||
#define DSI_INT_MASK 0xE
|
||||
|
||||
#define DSI_HOST_CONTROL 0xF
|
||||
#define DSI_HOST_CONTROL_FIFO_RESET (1 << 21)
|
||||
#define DSI_HOST_CONTROL_CRC_RESET (1 << 20)
|
||||
#define DSI_HOST_CONTROL_ECC BIT(0)
|
||||
#define DSI_HOST_CONTROL_CS BIT(1)
|
||||
#define DSI_HOST_CONTROL_PKT_BTA BIT(2)
|
||||
#define DSI_HOST_CONTROL_IMM_BTA BIT(3)
|
||||
#define DSI_HOST_CONTROL_FIFO_SEL BIT(4)
|
||||
#define DSI_HOST_CONTROL_HS BIT(5)
|
||||
#define DSI_HOST_CONTROL_RAW BIT(6)
|
||||
#define DSI_HOST_CONTROL_TX_TRIG_SOL (0 << 12)
|
||||
#define DSI_HOST_CONTROL_TX_TRIG_FIFO (1 << 12)
|
||||
#define DSI_HOST_CONTROL_TX_TRIG_HOST (2 << 12)
|
||||
#define DSI_HOST_CONTROL_RAW (1 << 6)
|
||||
#define DSI_HOST_CONTROL_HS (1 << 5)
|
||||
#define DSI_HOST_CONTROL_FIFO_SEL (1 << 4)
|
||||
#define DSI_HOST_CONTROL_IMM_BTA (1 << 3)
|
||||
#define DSI_HOST_CONTROL_PKT_BTA (1 << 2)
|
||||
#define DSI_HOST_CONTROL_CS (1 << 1)
|
||||
#define DSI_HOST_CONTROL_ECC (1 << 0)
|
||||
#define DSI_HOST_CONTROL_CRC_RESET BIT(20)
|
||||
#define DSI_HOST_CONTROL_FIFO_RESET BIT(21)
|
||||
|
||||
#define DSI_CONTROL 0x10
|
||||
#define DSI_CONTROL_HS_CLK_CTRL (1 << 20)
|
||||
#define DSI_CONTROL_CHANNEL(c) (((c) & 0x3) << 16)
|
||||
#define DSI_CONTROL_FORMAT(f) (((f) & 0x3) << 12)
|
||||
#define DSI_CONTROL_TX_TRIG(x) (((x) & 0x3) << 8)
|
||||
#define DSI_CONTROL_LANES(n) (((n) & 0x3) << 4)
|
||||
#define DSI_CONTROL_DCS_ENABLE (1 << 3)
|
||||
#define DSI_CONTROL_HOST_ENABLE BIT(0)
|
||||
#define DSI_CONTROL_VIDEO_ENABLE BIT(1)
|
||||
#define DSI_CONTROL_SOURCE(s) (((s) & 0x1) << 2)
|
||||
#define DSI_CONTROL_VIDEO_ENABLE (1 << 1)
|
||||
#define DSI_CONTROL_HOST_ENABLE (1 << 0)
|
||||
#define DSI_CONTROL_DCS_ENABLE BIT(3)
|
||||
#define DSI_CONTROL_LANES(n) (((n) & 0x3) << 4)
|
||||
#define DSI_CONTROL_TX_TRIG(x) (((x) & 0x3) << 8)
|
||||
#define DSI_CONTROL_FORMAT(f) (((f) & 0x3) << 12)
|
||||
#define DSI_CONTROL_CHANNEL(c) (((c) & 0x3) << 16)
|
||||
#define DSI_CONTROL_HS_CLK_CTRL BIT(20)
|
||||
|
||||
#define DSI_SOL_DELAY 0x11
|
||||
#define DSI_MAX_THRESHOLD 0x12
|
||||
|
||||
#define DSI_TRIGGER 0x13
|
||||
#define DSI_TRIGGER_HOST (1 << 1)
|
||||
#define DSI_TRIGGER_VIDEO (1 << 0)
|
||||
#define DSI_TRIGGER_VIDEO BIT(0)
|
||||
#define DSI_TRIGGER_HOST BIT(1)
|
||||
|
||||
#define DSI_TX_CRC 0x14
|
||||
|
||||
#define DSI_STATUS 0x15
|
||||
#define DSI_STATUS_RX_FIFO_SIZE 0x1F
|
||||
|
||||
#define DSI_INIT_SEQ_CONTROL 0x1A
|
||||
#define DSI_INIT_SEQ_DATA_0 0x1B
|
||||
#define DSI_INIT_SEQ_DATA_1 0x1C
|
||||
@@ -430,36 +443,53 @@
|
||||
#define DSI_BTA_TIMING 0x3F
|
||||
|
||||
#define DSI_TIMEOUT_0 0x44
|
||||
#define DSI_TIMEOUT_LRX(x) (((x) & 0xffff) << 16)
|
||||
#define DSI_TIMEOUT_HTX(x) (((x) & 0xffff) << 0)
|
||||
#define DSI_TIMEOUT_LRX(x) (((x) & 0xffff) << 16)
|
||||
|
||||
#define DSI_TIMEOUT_1 0x45
|
||||
#define DSI_TIMEOUT_PR(x) (((x) & 0xffff) << 16)
|
||||
#define DSI_TIMEOUT_TA(x) (((x) & 0xffff) << 0)
|
||||
#define DSI_TIMEOUT_PR(x) (((x) & 0xffff) << 16)
|
||||
|
||||
#define DSI_TO_TALLY 0x46
|
||||
|
||||
#define DSI_PAD_CONTROL_0 0x4B
|
||||
#define DSI_PAD_CONTROL_VS1_PULLDN_CLK (1 << 24)
|
||||
#define DSI_PAD_CONTROL_VS1_PULLDN(x) (((x) & 0xf) << 16)
|
||||
#define DSI_PAD_CONTROL_VS1_PDIO_CLK (1 << 8)
|
||||
#define DSI_PAD_CONTROL_VS1_PDIO_CLK BIT(8)
|
||||
#define DSI_PAD_CONTROL_VS1_PDIO(x) (((x) & 0xf) << 0)
|
||||
#define DSI_PAD_CONTROL_VS1_PULLDN_CLK BIT(24)
|
||||
#define DSI_PAD_CONTROL_VS1_PULLDN(x) (((x) & 0xf) << 16)
|
||||
|
||||
#define DSI_PAD_CONTROL_CD 0x4C
|
||||
#define DSI_VIDEO_MODE_CONTROL 0x4E
|
||||
#define DSI_CMD_PKT_VID_ENABLE 1
|
||||
#define DSI_DSI_LINE_TYPE(x) ((x) << 1)
|
||||
|
||||
#define DSI_PAD_CONTROL_1 0x4F
|
||||
#define DSI_PAD_CONTROL_2 0x50
|
||||
|
||||
#define DSI_PAD_CONTROL_3 0x51
|
||||
#define DSI_PAD_PREEMP_PD_CLK(x) (((x) & 0x3) << 12)
|
||||
#define DSI_PAD_PREEMP_PU_CLK(x) (((x) & 0x3) << 8)
|
||||
#define DSI_PAD_PREEMP_PD(x) (((x) & 0x3) << 4)
|
||||
#define DSI_PAD_PREEMP_PU(x) (((x) & 0x3) << 0)
|
||||
#define DSI_PAD_PREEMP_PD(x) (((x) & 0x3) << 4)
|
||||
#define DSI_PAD_PREEMP_PU_CLK(x) (((x) & 0x3) << 8)
|
||||
#define DSI_PAD_PREEMP_PD_CLK(x) (((x) & 0x3) << 12)
|
||||
|
||||
#define DSI_PAD_CONTROL_4 0x52
|
||||
#define DSI_PAD_CONTROL_5_B01 0x53
|
||||
#define DSI_PAD_CONTROL_6_B01 0x54
|
||||
#define DSI_PAD_CONTROL_7_B01 0x55
|
||||
#define DSI_INIT_SEQ_DATA_15 0x5F
|
||||
#define DSI_INIT_SEQ_DATA_15_B01 0x62
|
||||
|
||||
/*! DSI packet defines */
|
||||
#define DSI_ESCAPE_CMD 0x87
|
||||
#define DSI_ACK_NO_ERR 0x84
|
||||
|
||||
#define ACK_ERROR_RES 0x02
|
||||
#define GEN_LONG_RD_RES 0x1A
|
||||
#define DCS_LONG_RD_RES 0x1C
|
||||
#define GEN_1_BYTE_SHORT_RD_RES 0x11
|
||||
#define DCS_1_BYTE_SHORT_RD_RES 0x21
|
||||
#define GEN_2_BYTE_SHORT_RD_RES 0x12
|
||||
#define DCS_2_BYTE_SHORT_RD_RES 0x22
|
||||
|
||||
/*! MIPI registers. */
|
||||
#define MIPI_CAL_MIPI_CAL_CTRL (0x00 / 0x4)
|
||||
@@ -483,51 +513,205 @@
|
||||
#define MIPI_CAL_DSID_MIPI_CAL_CONFIG_2 (0x74 / 0x4)
|
||||
|
||||
/*! MIPI CMDs. */
|
||||
#define MIPI_DSI_DCS_SHORT_WRITE 0x05
|
||||
#define MIPI_DSI_DCS_READ 0x06
|
||||
#define MIPI_DSI_DCS_SHORT_WRITE_PARAM 0x15
|
||||
#define MIPI_DSI_V_SYNC_START 0x01
|
||||
#define MIPI_DSI_COLOR_MODE_OFF 0x02
|
||||
#define MIPI_DSI_END_OF_TRANSMISSION 0x08
|
||||
#define MIPI_DSI_NULL_PACKET 0x09
|
||||
#define MIPI_DSI_V_SYNC_END 0x11
|
||||
#define MIPI_DSI_COLOR_MODE_ON 0x12
|
||||
#define MIPI_DSI_BLANKING_PACKET 0x19
|
||||
#define MIPI_DSI_H_SYNC_START 0x21
|
||||
#define MIPI_DSI_SHUTDOWN_PERIPHERAL 0x22
|
||||
#define MIPI_DSI_H_SYNC_END 0x31
|
||||
#define MIPI_DSI_TURN_ON_PERIPHERAL 0x32
|
||||
#define MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE 0x37
|
||||
#define MIPI_DSI_DCS_LONG_WRITE 0x39
|
||||
|
||||
#define MIPI_DSI_DCS_SHORT_WRITE 0x05
|
||||
#define MIPI_DSI_DCS_READ 0x06
|
||||
#define MIPI_DSI_DCS_SHORT_WRITE_PARAM 0x15
|
||||
#define MIPI_DSI_DCS_LONG_WRITE 0x39
|
||||
|
||||
#define MIPI_DSI_GENERIC_LONG_WRITE 0x29
|
||||
#define MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM 0x03
|
||||
#define MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM 0x13
|
||||
#define MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM 0x23
|
||||
#define MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM 0x04
|
||||
#define MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM 0x14
|
||||
#define MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM 0x24
|
||||
|
||||
/*! MIPI DCS CMDs. */
|
||||
#define MIPI_DCS_GET_DISPLAY_ID 0x04
|
||||
#define MIPI_DCS_ENTER_SLEEP_MODE 0x10
|
||||
#define MIPI_DCS_EXIT_SLEEP_MODE 0x11
|
||||
#define MIPI_DCS_SET_DISPLAY_ON 0x29
|
||||
#define MIPI_DCS_NOP 0x00
|
||||
#define MIPI_DCS_SOFT_RESET 0x01
|
||||
#define MIPI_DCS_GET_COMPRESSION_MODE 0x03
|
||||
#define MIPI_DCS_GET_DISPLAY_ID 0x04
|
||||
#define MIPI_DCS_GET_DISPLAY_ID1 0xDA // GET_DISPLAY_ID Byte0, Module Manufacturer ID.
|
||||
#define MIPI_DCS_GET_DISPLAY_ID2 0xDB // GET_DISPLAY_ID Byte1, Module/Driver Version ID.
|
||||
#define MIPI_DCS_GET_DISPLAY_ID3 0xDC // GET_DISPLAY_ID Byte2, Module/Driver ID.
|
||||
#define MIPI_DCS_GET_NUM_ERRORS 0x05
|
||||
#define MIPI_DCS_GET_RED_CHANNEL 0x06
|
||||
#define MIPI_DCS_GET_GREEN_CHANNEL 0x07
|
||||
#define MIPI_DCS_GET_BLUE_CHANNEL 0x08
|
||||
#define MIPI_DCS_GET_DISPLAY_STATUS 0x09
|
||||
#define MIPI_DCS_GET_POWER_MODE 0x0A
|
||||
#define MIPI_DCS_GET_ADDRESS_MODE 0x0B
|
||||
#define MIPI_DCS_GET_PIXEL_FORMAT 0x0C
|
||||
#define MIPI_DCS_GET_DISPLAY_MODE 0x0D
|
||||
#define MIPI_DCS_GET_SIGNAL_MODE 0x0E
|
||||
#define MIPI_DCS_GET_DIAGNOSTIC_RESULT 0x0F
|
||||
#define MIPI_DCS_ENTER_SLEEP_MODE 0x10
|
||||
#define MIPI_DCS_EXIT_SLEEP_MODE 0x11
|
||||
#define MIPI_DCS_ENTER_PARTIAL_MODE 0x12
|
||||
#define MIPI_DCS_ENTER_NORMAL_MODE 0x13
|
||||
#define MIPI_DCS_EXIT_INVERT_MODE 0x20
|
||||
#define MIPI_DCS_ENTER_INVERT_MODE 0x21
|
||||
#define MIPI_DCS_ALL_PIXELS_OFF 0x22
|
||||
#define MIPI_DCS_ALL_PIXELS_ON 0x23
|
||||
#define MIPI_DCS_SET_CONTRAST 0x25 // VCON in 40mV steps. 7-bit integer.
|
||||
#define MIPI_DCS_SET_GAMMA_CURVE 0x26
|
||||
#define MIPI_DCS_SET_DISPLAY_OFF 0x28
|
||||
#define MIPI_DCS_SET_DISPLAY_ON 0x29
|
||||
#define MIPI_DCS_SET_COLUMN_ADDRESS 0x2A
|
||||
#define MIPI_DCS_SET_PAGE_ADDRESS 0x2B
|
||||
#define MIPI_DCS_WRITE_MEMORY_START 0x2C
|
||||
#define MIPI_DCS_WRITE_LUT 0x2D // 24-bit: 192 bytes.
|
||||
#define MIPI_DCS_READ_MEMORY_START 0x2E
|
||||
#define MIPI_DCS_SET_PARTIAL_ROWS 0x30
|
||||
#define MIPI_DCS_SET_PARTIAL_COLUMNS 0x31
|
||||
#define MIPI_DCS_SET_SCROLL_AREA 0x33
|
||||
#define MIPI_DCS_SET_TEAR_OFF 0x34
|
||||
#define MIPI_DCS_SET_TEAR_ON 0x35
|
||||
#define MIPI_DCS_SET_ADDRESS_MODE 0x36
|
||||
#define MIPI_DCS_SET_SCROLL_START 0x37
|
||||
#define MIPI_DCS_EXIT_IDLE_MODE 0x38
|
||||
#define MIPI_DCS_ENTER_IDLE_MODE 0x39
|
||||
#define MIPI_DCS_SET_PIXEL_FORMAT 0x3A
|
||||
#define MIPI_DCS_WRITE_MEMORY_CONTINUE 0x3C
|
||||
#define MIPI_DCS_READ_MEMORY_CONTINUE 0x3E
|
||||
#define MIPI_DCS_GET_3D_CONTROL 0x3F
|
||||
#define MIPI_DCS_SET_VSYNC_TIMING 0x40
|
||||
#define MIPI_DCS_SET_TEAR_SCANLINE 0x44
|
||||
#define MIPI_DCS_GET_SCANLINE 0x45
|
||||
#define MIPI_DCS_SET_TEAR_SCANLINE_WIDTH 0x46
|
||||
#define MIPI_DCS_GET_SCANLINE_WIDTH 0x47
|
||||
#define MIPI_DCS_SET_BRIGHTNESS 0x51 // DCS_CONTROL_DISPLAY_BRIGHTNESS_CTRL.
|
||||
#define MIPI_DCS_GET_BRIGHTNESS 0x52
|
||||
#define MIPI_DCS_SET_CONTROL_DISPLAY 0x53
|
||||
#define MIPI_DCS_GET_CONTROL_DISPLAY 0x54
|
||||
#define MIPI_DCS_SET_CABC_VALUE 0x55
|
||||
#define MIPI_DCS_GET_CABC_VALUE 0x56
|
||||
#define MIPI_DCS_SET_CABC_MIN_BRI 0x5E
|
||||
#define MIPI_DCS_GET_CABC_MIN_BRI 0x5F
|
||||
#define MIPI_DCS_READ_DDB_START 0xA1
|
||||
#define MIPI_DCS_READ_DDB_CONTINUE 0xA8
|
||||
|
||||
/*! MIPI DCS Panel Private CMDs. */
|
||||
#define MIPI_DCS_PRIV_UNK_A0 0xA0
|
||||
#define MIPI_DCS_PRIV_SET_POWER_CONTROL 0xB1
|
||||
#define MIPI_DCS_PRIV_SET_EXTC 0xB9
|
||||
#define MIPI_DCS_PRIV_UNK_BD 0xBD
|
||||
#define MIPI_DCS_PRIV_UNK_D5 0xD5
|
||||
#define MIPI_DCS_PRIV_UNK_D6 0xD6
|
||||
#define MIPI_DCS_PRIV_UNK_D8 0xD8
|
||||
#define MIPI_DCS_PRIV_UNK_D9 0xD9
|
||||
|
||||
/*! MIPI DCS CMD Defines. */
|
||||
#define DCS_POWER_MODE_DISPLAY_ON BIT(2)
|
||||
#define DCS_POWER_MODE_NORMAL_MODE BIT(3)
|
||||
#define DCS_POWER_MODE_SLEEP_MODE BIT(4)
|
||||
#define DCS_POWER_MODE_PARTIAL_MODE BIT(5)
|
||||
#define DCS_POWER_MODE_IDLE_MODE BIT(6)
|
||||
|
||||
#define DCS_ADDRESS_MODE_V_FLIP BIT(0)
|
||||
#define DCS_ADDRESS_MODE_H_FLIP BIT(1)
|
||||
#define DCS_ADDRESS_MODE_LATCH_RL BIT(2) // Latch Data Order.
|
||||
#define DCS_ADDRESS_MODE_BGR_COLOR BIT(3)
|
||||
#define DCS_ADDRESS_MODE_LINE_ORDER BIT(4) // Line Refresh Order.
|
||||
#define DCS_ADDRESS_MODE_SWAP_XY BIT(5) // Page/Column Addressing Reverse Order.
|
||||
#define DCS_ADDRESS_MODE_MIRROR_X BIT(6) // Column Address Order.
|
||||
#define DCS_ADDRESS_MODE_MIRROR_Y BIT(7) // Page Address Order.
|
||||
#define DCS_ADDRESS_MODE_ROTATION_MASK (0xF << 4)
|
||||
#define DCS_ADDRESS_MODE_ROTATION_90 (DCS_ADDRESS_MODE_SWAP_XY | DCS_ADDRESS_MODE_LINE_ORDER)
|
||||
#define DCS_ADDRESS_MODE_ROTATION_180 (DCS_ADDRESS_MODE_MIRROR_X | DCS_ADDRESS_MODE_LINE_ORDER)
|
||||
#define DCS_ADDRESS_MODE_ROTATION_270 (DCS_ADDRESS_MODE_SWAP_XY)
|
||||
|
||||
#define DCS_GAMMA_CURVE_NONE 0
|
||||
#define DCS_GAMMA_CURVE_GC0_1_8 BIT(0)
|
||||
#define DCS_GAMMA_CURVE_GC1_2_5 BIT(1)
|
||||
#define DCS_GAMMA_CURVE_GC2_1_0 BIT(2)
|
||||
#define DCS_GAMMA_CURVE_GC3_1_0 BIT(3) // Are there more?
|
||||
|
||||
#define DCS_CONTROL_DISPLAY_BACKLIGHT_CTRL BIT(2)
|
||||
#define DCS_CONTROL_DISPLAY_DIMMING_CTRL BIT(3)
|
||||
#define DCS_CONTROL_DISPLAY_BRIGHTNESS_CTRL BIT(5)
|
||||
|
||||
/* Switch Panels:
|
||||
*
|
||||
* 6.2" panels for Icosa and Iowa skus:
|
||||
* [10] 81 [26]: JDI LPM062M326A
|
||||
* [10] 96 [09]: JDI LAM062M109A
|
||||
* [20] 93 [0F]: InnoLux P062CCA-AZ1 (Rev A1)
|
||||
* [20] XX [10]: InnoLux P062CCA-AZ2 [UNCONFIRMED ID]
|
||||
* [20] 95 [0F]: InnoLux P062CCA-AZ2 (Rev B1)
|
||||
* [20] 96 [0F]: InnoLux P062CCA-AZ3 [UNCONFIRMED MODEL REV]
|
||||
* [20] 98 [0F]: InnoLux P062CCA-??? [UNCONFIRMED MODEL REV]
|
||||
* [30] 94 [0F]: AUO A062TAN01 (59.06A33.001)
|
||||
* [30] XX [10]: AUO A062TAN02 (59.06A33.002) [UNCONFIRMED ID]
|
||||
* [30] 95 [0F]: AUO A062TAN02 (59.06A33.002)
|
||||
*
|
||||
* 5.5" panels for Hoag skus:
|
||||
* [20] 94 [10]: InnoLux 2J055IA-27A (Rev B1)
|
||||
* [30] XX [10]: AUO A055TAN01 (59.05A30.001) [UNCONFIRMED ID]
|
||||
* [40] XX [10]: Vendor 40 [UNCONFIRMED ID]
|
||||
*/
|
||||
|
||||
/* Display ID Decoding:
|
||||
*
|
||||
* byte0: Vendor
|
||||
* byte1: Model
|
||||
* byte2: Board
|
||||
*
|
||||
* Vendors:
|
||||
* 10h: Japan Display Inc.
|
||||
* 20h: InnoLux Corporation
|
||||
* 30h: AU Optronics
|
||||
* 40h: Unknown1
|
||||
* 50h: Unknown2 (OLED? Samsung? LG?)
|
||||
*
|
||||
* Boards, Panel Size:
|
||||
* 0Fh: Icosa/Iowa, 6.2"
|
||||
* 10h: Hoag, 5.5"
|
||||
* 20h: Unknown, x.x"
|
||||
*/
|
||||
|
||||
enum
|
||||
{
|
||||
PANEL_JDI_LPM062M = 0x10,
|
||||
PANEL_JDI_XXX062M = 0x10,
|
||||
PANEL_JDI_LAM062M109A = 0x0910,
|
||||
PANEL_JDI_LPM062M326A = 0x2610,
|
||||
PANEL_INL_P062CCA_AZ1 = 0x0F20,
|
||||
PANEL_AUO_A062TAN01 = 0x0F30,
|
||||
PANEL_INL_P062CCA_AZ2 = 0x1020,
|
||||
PANEL_AUO_A062TAN02 = 0x1030
|
||||
PANEL_INL_2J055IA_27A = 0x1020,
|
||||
PANEL_AUO_A055TAN01 = 0x1030,
|
||||
PANEL_V40_55_UNK = 0x1040
|
||||
};
|
||||
|
||||
void display_init();
|
||||
void display_backlight_pwm_init();
|
||||
void display_end();
|
||||
|
||||
/*! Get/Set Display panel ID. */
|
||||
u16 display_get_decoded_panel_id();
|
||||
void display_set_decoded_panel_id(u32 id);
|
||||
|
||||
/*! Show one single color on the display. */
|
||||
void display_color_screen(u32 color);
|
||||
|
||||
/*! Switches screen backlight ON/OFF. */
|
||||
void display_backlight(bool enable);
|
||||
void display_backlight_brightness(u32 brightness, u32 step_delay);
|
||||
u32 display_get_backlight_brightness();
|
||||
|
||||
/*! Init display in full 1280x720 resolution (B8G8R8A8, line stride 768, framebuffer size = 1280*768*4 bytes). */
|
||||
u32 *display_init_framebuffer_pitch();
|
||||
u32 *display_init_framebuffer_pitch_inv();
|
||||
u32 *display_init_framebuffer_block();
|
||||
u32 *display_init_framebuffer_log();
|
||||
void display_activate_console();
|
||||
@@ -536,4 +720,7 @@ void display_init_cursor(void *crs_fb, u32 size);
|
||||
void display_set_pos_cursor(u32 x, u32 y);
|
||||
void display_deinit_cursor();
|
||||
|
||||
void display_dsi_write(u8 cmd, u32 len, void *data, bool video_enabled);
|
||||
int display_dsi_read(u8 cmd, u32 len, void *data, bool video_enabled);
|
||||
|
||||
#endif
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2019 CTCaer
|
||||
* Copyright (c) 2018-2020 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -20,7 +20,7 @@ static const cfg_op_t _display_dc_setup_win_config[94] = {
|
||||
{DC_CMD_STATE_ACCESS, 0},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
|
||||
{DC_CMD_REG_ACT_CONTROL, 0x54},
|
||||
{DC_CMD_REG_ACT_CONTROL, 0x54}, // Select H counter for win A/B/C.
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
@@ -96,16 +96,16 @@ static const cfg_op_t _display_dc_setup_win_config[94] = {
|
||||
{DC_DISP_DISP_INTERFACE_CONTROL, DISP_DATA_FORMAT_DF1P1C},
|
||||
{DC_COM_PIN_OUTPUT_POLARITY(1), 0x1000000},
|
||||
{DC_COM_PIN_OUTPUT_POLARITY(3), 0},
|
||||
{0x4E4, 0},
|
||||
{DC_DISP_BLEND_BACKGROUND_COLOR, 0},
|
||||
{DC_COM_CRC_CONTROL, 0},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{0x716, 0x10000FF},
|
||||
{DC_WINBUF_BLEND_LAYER_CONTROL, 0x10000FF},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{0x716, 0x10000FF},
|
||||
{DC_WINBUF_BLEND_LAYER_CONTROL, 0x10000FF},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{0x716, 0x10000FF},
|
||||
{DC_WINBUF_BLEND_LAYER_CONTROL, 0x10000FF},
|
||||
{DC_CMD_DISPLAY_COMMAND_OPTION0, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
@@ -120,7 +120,7 @@ static const cfg_op_t _display_dc_setup_win_config[94] = {
|
||||
};
|
||||
|
||||
//DSI Init config.
|
||||
static const cfg_op_t _display_dsi_init_config[61] = {
|
||||
static const cfg_op_t _display_dsi_init_config_part1[8] = {
|
||||
{DSI_WR_DATA, 0},
|
||||
{DSI_INT_ENABLE, 0},
|
||||
{DSI_INT_STATUS, 0},
|
||||
@@ -128,8 +128,9 @@ static const cfg_op_t _display_dsi_init_config[61] = {
|
||||
{DSI_INIT_SEQ_DATA_0, 0},
|
||||
{DSI_INIT_SEQ_DATA_1, 0},
|
||||
{DSI_INIT_SEQ_DATA_2, 0},
|
||||
{DSI_INIT_SEQ_DATA_3, 0},
|
||||
{DSI_INIT_SEQ_DATA_15, 0},
|
||||
{DSI_INIT_SEQ_DATA_3, 0}
|
||||
};
|
||||
static const cfg_op_t _display_dsi_init_config_part2[14] = {
|
||||
{DSI_DCS_CMDS, 0},
|
||||
{DSI_PKT_SEQ_0_LO, 0},
|
||||
{DSI_PKT_SEQ_1_LO, 0},
|
||||
@@ -143,7 +144,18 @@ static const cfg_op_t _display_dsi_init_config[61] = {
|
||||
{DSI_PKT_SEQ_3_HI, 0},
|
||||
{DSI_PKT_SEQ_4_HI, 0},
|
||||
{DSI_PKT_SEQ_5_HI, 0},
|
||||
{DSI_CONTROL, 0},
|
||||
{DSI_CONTROL, 0}
|
||||
};
|
||||
static const cfg_op_t _display_dsi_init_config_part3_t210b01[7] = {
|
||||
{DSI_PAD_CONTROL_1, 0},
|
||||
{DSI_PAD_CONTROL_2, 0},
|
||||
{DSI_PAD_CONTROL_3, 0},
|
||||
{DSI_PAD_CONTROL_4, 0},
|
||||
{DSI_PAD_CONTROL_5_B01, 0},
|
||||
{DSI_PAD_CONTROL_6_B01, 0},
|
||||
{DSI_PAD_CONTROL_7_B01, 0}
|
||||
};
|
||||
static const cfg_op_t _display_dsi_init_config_part4[10] = {
|
||||
{DSI_PAD_CONTROL_CD, 0},
|
||||
{DSI_SOL_DELAY, 0x18},
|
||||
{DSI_MAX_THRESHOLD, 0x1E0},
|
||||
@@ -153,8 +165,9 @@ static const cfg_op_t _display_dsi_init_config[61] = {
|
||||
{DSI_PKT_LEN_2_3, 0},
|
||||
{DSI_PKT_LEN_4_5, 0},
|
||||
{DSI_PKT_LEN_6_7, 0},
|
||||
{DSI_PAD_CONTROL_1, 0},
|
||||
{DSI_PHY_TIMING_0, 0x6070601},
|
||||
{DSI_PAD_CONTROL_1, 0}
|
||||
};
|
||||
static const cfg_op_t _display_dsi_init_config_part5[12] = {
|
||||
{DSI_PHY_TIMING_1, 0x40A0E05},
|
||||
{DSI_PHY_TIMING_2, 0x30109},
|
||||
{DSI_BTA_TIMING, 0x190A14},
|
||||
@@ -166,8 +179,9 @@ static const cfg_op_t _display_dsi_init_config[61] = {
|
||||
{DSI_POWER_CONTROL, DSI_POWER_CONTROL_ENABLE},
|
||||
{DSI_POWER_CONTROL, 0},
|
||||
{DSI_POWER_CONTROL, 0},
|
||||
{DSI_PAD_CONTROL_1, 0},
|
||||
{DSI_PHY_TIMING_0, 0x6070601},
|
||||
{DSI_PAD_CONTROL_1, 0}
|
||||
};
|
||||
static const cfg_op_t _display_dsi_init_config_part6[14] = {
|
||||
{DSI_PHY_TIMING_1, 0x40A0E05},
|
||||
{DSI_PHY_TIMING_2, 0x30118},
|
||||
{DSI_BTA_TIMING, 0x190A14},
|
||||
@@ -187,12 +201,12 @@ static const cfg_op_t _display_dsi_init_config[61] = {
|
||||
//DSI panel config.
|
||||
static const cfg_op_t _display_init_config_jdi[43] = {
|
||||
{DSI_WR_DATA, 0x439}, // MIPI_DSI_DCS_LONG_WRITE: 4 bytes.
|
||||
{DSI_WR_DATA, 0x9483FFB9}, // Enable extension cmd. (Pass: FF 83 94).
|
||||
{DSI_WR_DATA, 0x9483FFB9}, // MIPI_DCS_PRIV_SET_EXTC. (Pass: FF 83 94).
|
||||
{DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
{DSI_WR_DATA, 0x00BD15}, // MIPI_DSI_DCS_SHORT_WRITE_PARAM: 0x0BD.
|
||||
{DSI_WR_DATA, 0x00BD15}, // MIPI_DSI_DCS_SHORT_WRITE_PARAM: 0 to 0xBD.
|
||||
{DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
{DSI_WR_DATA, 0x1939}, // MIPI_DSI_DCS_LONG_WRITE: 25 bytes.
|
||||
{DSI_WR_DATA, 0xAAAAAAD8},
|
||||
{DSI_WR_DATA, 0xAAAAAAD8}, // Register: 0xD8.
|
||||
{DSI_WR_DATA, 0xAAAAAAEB},
|
||||
{DSI_WR_DATA, 0xAAEBAAAA},
|
||||
{DSI_WR_DATA, 0xAAAAAAAA},
|
||||
@@ -200,10 +214,10 @@ static const cfg_op_t _display_init_config_jdi[43] = {
|
||||
{DSI_WR_DATA, 0xAAEBAAAA},
|
||||
{DSI_WR_DATA, 0xAA},
|
||||
{DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
{DSI_WR_DATA, 0x01BD15}, // MIPI_DSI_DCS_SHORT_WRITE_PARAM: 0x1BD.
|
||||
{DSI_WR_DATA, 0x01BD15}, // MIPI_DSI_DCS_SHORT_WRITE_PARAM: 1 to 0xBD.
|
||||
{DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
{DSI_WR_DATA, 0x2739}, // MIPI_DSI_DCS_LONG_WRITE: 39 bytes.
|
||||
{DSI_WR_DATA, 0xFFFFFFD8},
|
||||
{DSI_WR_DATA, 0xFFFFFFD8}, // Register: 0xD8.
|
||||
{DSI_WR_DATA, 0xFFFFFFFF},
|
||||
{DSI_WR_DATA, 0xFFFFFFFF},
|
||||
{DSI_WR_DATA, 0xFFFFFFFF},
|
||||
@@ -214,27 +228,25 @@ static const cfg_op_t _display_init_config_jdi[43] = {
|
||||
{DSI_WR_DATA, 0xFFFFFFFF},
|
||||
{DSI_WR_DATA, 0xFFFFFF},
|
||||
{DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
{DSI_WR_DATA, 0x02BD15}, // MIPI_DSI_DCS_SHORT_WRITE_PARAM: 0x2BD.
|
||||
{DSI_WR_DATA, 0x02BD15}, // MIPI_DSI_DCS_SHORT_WRITE_PARAM: 2 to 0xBD.
|
||||
{DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
{DSI_WR_DATA, 0xF39}, // MIPI_DSI_DCS_LONG_WRITE: 15 bytes.
|
||||
{DSI_WR_DATA, 0xFFFFFFD8},
|
||||
{DSI_WR_DATA, 0xFFFFFFD8}, // Register: 0xD8.
|
||||
{DSI_WR_DATA, 0xFFFFFFFF},
|
||||
{DSI_WR_DATA, 0xFFFFFFFF},
|
||||
{DSI_WR_DATA, 0xFFFFFF},
|
||||
{DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
{DSI_WR_DATA, 0x00BD15}, // MIPI_DSI_DCS_SHORT_WRITE_PARAM: 0x0BD.
|
||||
{DSI_WR_DATA, 0x00BD15}, // MIPI_DSI_DCS_SHORT_WRITE_PARAM: 0 to 0xBD.
|
||||
{DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
{DSI_WR_DATA, 0x06D915}, // MIPI_DSI_DCS_SHORT_WRITE_PARAM: 0x6D9.
|
||||
{DSI_WR_DATA, 0x06D915}, // MIPI_DSI_DCS_SHORT_WRITE_PARAM: 6 to 0xD9.
|
||||
{DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
{DSI_WR_DATA, 0x439}, // MIPI_DSI_DCS_LONG_WRITE: 4 bytes.
|
||||
{DSI_WR_DATA, 0x000000B9}, // Disable extension cmd.
|
||||
{DSI_WR_DATA, 0x000000B9}, // MIPI_DCS_PRIV_SET_EXTC. Disable.
|
||||
{DSI_TRIGGER, DSI_TRIGGER_HOST}
|
||||
};
|
||||
|
||||
//DSI packet config.
|
||||
static const cfg_op_t _display_dsi_packet_config[21] = {
|
||||
{DSI_PAD_CONTROL_1, 0},
|
||||
{DSI_PHY_TIMING_0, 0x6070601},
|
||||
static const cfg_op_t _display_dsi_packet_config[19] = {
|
||||
{DSI_PHY_TIMING_1, 0x40A0E05},
|
||||
{DSI_PHY_TIMING_2, 0x30172},
|
||||
{DSI_BTA_TIMING, 0x190A14},
|
||||
@@ -253,7 +265,7 @@ static const cfg_op_t _display_dsi_packet_config[21] = {
|
||||
{DSI_PKT_LEN_2_3, 0x87001A2},
|
||||
{DSI_PKT_LEN_4_5, 0x190},
|
||||
{DSI_PKT_LEN_6_7, 0x190},
|
||||
{DSI_HOST_CONTROL, 0},
|
||||
{DSI_HOST_CONTROL, 0}
|
||||
};
|
||||
|
||||
//DSI mode config.
|
||||
@@ -271,29 +283,44 @@ static const cfg_op_t _display_dsi_mode_config[10] = {
|
||||
};
|
||||
|
||||
//MIPI CAL config.
|
||||
static const cfg_op_t _display_mipi_pad_cal_config[6] = {
|
||||
static const cfg_op_t _display_mipi_pad_cal_config[4] = {
|
||||
{MIPI_CAL_MIPI_BIAS_PAD_CFG2, 0},
|
||||
{MIPI_CAL_CIL_MIPI_CAL_STATUS, 0xF3F10000},
|
||||
{MIPI_CAL_MIPI_BIAS_PAD_CFG0, 0},
|
||||
{MIPI_CAL_MIPI_BIAS_PAD_CFG2, 0},
|
||||
{MIPI_CAL_MIPI_BIAS_PAD_CFG2, 0x10010},
|
||||
{MIPI_CAL_MIPI_BIAS_PAD_CFG1, 0x300}
|
||||
{MIPI_CAL_MIPI_BIAS_PAD_CFG2, 0}
|
||||
};
|
||||
|
||||
//DSI config.
|
||||
static const cfg_op_t _display_dsi_pad_cal_config[4] = {
|
||||
static const cfg_op_t _display_dsi_pad_cal_config_t210[4] = {
|
||||
{DSI_PAD_CONTROL_1, 0},
|
||||
{DSI_PAD_CONTROL_2, 0},
|
||||
{DSI_PAD_CONTROL_3, DSI_PAD_PREEMP_PD_CLK(0x3) | DSI_PAD_PREEMP_PU_CLK(0x3) | DSI_PAD_PREEMP_PD(0x03) | DSI_PAD_PREEMP_PU(0x3)},
|
||||
{DSI_PAD_CONTROL_4, 0}
|
||||
};
|
||||
static const cfg_op_t _display_dsi_pad_cal_config_t210b01[7] = {
|
||||
{DSI_PAD_CONTROL_1, 0},
|
||||
{DSI_PAD_CONTROL_2, 0},
|
||||
{DSI_PAD_CONTROL_3, 0},
|
||||
{DSI_PAD_CONTROL_4, 0x77777},
|
||||
{DSI_PAD_CONTROL_5_B01, 0x77777},
|
||||
{DSI_PAD_CONTROL_6_B01, 0x1111},
|
||||
{DSI_PAD_CONTROL_7_B01, 0}
|
||||
};
|
||||
|
||||
//MIPI CAL config.
|
||||
static const cfg_op_t _display_mipi_apply_dsi_cal_config[16] = {
|
||||
static const cfg_op_t _display_mipi_dsi_cal_offsets_config_t210[4] = {
|
||||
{MIPI_CAL_DSIA_MIPI_CAL_CONFIG, 0x200200},
|
||||
{MIPI_CAL_DSIB_MIPI_CAL_CONFIG, 0x200200},
|
||||
{MIPI_CAL_DSIA_MIPI_CAL_CONFIG_2, 0x200002},
|
||||
{MIPI_CAL_DSIB_MIPI_CAL_CONFIG_2, 0x200002},
|
||||
{MIPI_CAL_DSIB_MIPI_CAL_CONFIG_2, 0x200002}
|
||||
};
|
||||
static const cfg_op_t _display_mipi_dsi_cal_offsets_config_t210b01[4] = {
|
||||
{MIPI_CAL_DSIA_MIPI_CAL_CONFIG, 0x200006},
|
||||
{MIPI_CAL_DSIB_MIPI_CAL_CONFIG, 0x200006},
|
||||
{MIPI_CAL_DSIA_MIPI_CAL_CONFIG_2, 0x260000},
|
||||
{MIPI_CAL_DSIB_MIPI_CAL_CONFIG_2, 0x260000}
|
||||
};
|
||||
static const cfg_op_t _display_mipi_apply_dsi_cal_config[12] = {
|
||||
{MIPI_CAL_CILA_MIPI_CAL_CONFIG, 0},
|
||||
{MIPI_CAL_CILB_MIPI_CAL_CONFIG, 0},
|
||||
{MIPI_CAL_CILC_MIPI_CAL_CONFIG, 0},
|
||||
@@ -372,16 +399,16 @@ static const cfg_op_t _display_video_disp_controller_enable_config[113] = {
|
||||
{DC_DISP_DISP_INTERFACE_CONTROL, DISP_DATA_FORMAT_DF1P1C},
|
||||
{DC_COM_PIN_OUTPUT_POLARITY(1), 0x1000000},
|
||||
{DC_COM_PIN_OUTPUT_POLARITY(3), 0},
|
||||
{0x4E4, 0},
|
||||
{DC_DISP_BLEND_BACKGROUND_COLOR, 0},
|
||||
{DC_COM_CRC_CONTROL, 0},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{0x716, 0x10000FF},
|
||||
{DC_WINBUF_BLEND_LAYER_CONTROL, 0x10000FF},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{0x716, 0x10000FF},
|
||||
{DC_WINBUF_BLEND_LAYER_CONTROL, 0x10000FF},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{0x716, 0x10000FF},
|
||||
{DC_WINBUF_BLEND_LAYER_CONTROL, 0x10000FF},
|
||||
{DC_CMD_DISPLAY_COMMAND_OPTION0, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
@@ -394,14 +421,37 @@ static const cfg_op_t _display_video_disp_controller_enable_config[113] = {
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE | WIN_B_UPDATE | WIN_C_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ | WIN_B_ACT_REQ | WIN_C_ACT_REQ},
|
||||
{DC_CMD_STATE_ACCESS, 0},
|
||||
/* Set Display timings */
|
||||
|
||||
/* Set Display timings
|
||||
*
|
||||
* DC_DISP_REF_TO_SYNC:
|
||||
* V_REF_TO_SYNC - 1
|
||||
* H_REF_TO_SYNC - 0
|
||||
*
|
||||
* DC_DISP_SYNC_WIDTH:
|
||||
* V_SYNC_WIDTH - 1
|
||||
* H_SYNC_WIDTH - 72
|
||||
*
|
||||
* DC_DISP_BACK_PORCH:
|
||||
* V_BACK_PORCH - 9
|
||||
* H_BACK_PORCH - 72
|
||||
*
|
||||
* DC_DISP_ACTIVE:
|
||||
* V_DISP_ACTIVE - 1280
|
||||
* H_DISP_ACTIVE - 720
|
||||
*
|
||||
* DC_DISP_FRONT_PORCH:
|
||||
* V_FRONT_PORCH - 10
|
||||
* H_FRONT_PORCH - 136
|
||||
*/
|
||||
{DC_DISP_DISP_TIMING_OPTIONS, 0},
|
||||
{DC_DISP_REF_TO_SYNC, (1 << 16)}, // h_ref_to_sync = 0, v_ref_to_sync = 1.
|
||||
{DC_DISP_REF_TO_SYNC, 0x10000},
|
||||
{DC_DISP_SYNC_WIDTH, 0x10048},
|
||||
{DC_DISP_BACK_PORCH, 0x90048},
|
||||
{DC_DISP_ACTIVE, 0x50002D0},
|
||||
{DC_DISP_FRONT_PORCH, 0xA0088}, // Sources say that this should be above the DC_DISP_ACTIVE cmd.
|
||||
{DC_DISP_FRONT_PORCH, 0xA0088}, // Sources say that this should happen before DC_DISP_ACTIVE cmd.
|
||||
/* End of Display timings */
|
||||
|
||||
{DC_DISP_SHIFT_CLOCK_OPTIONS, SC1_H_QUALIFIER_NONE | SC0_H_QUALIFIER_NONE},
|
||||
{DC_COM_PIN_OUTPUT_ENABLE(1), 0},
|
||||
{DC_DISP_DATA_ENABLE_OPTIONS, DE_SELECT_ACTIVE | DE_CONTROL_NORMAL},
|
||||
@@ -477,10 +527,10 @@ static const cfg_op_t _display_dsi_timing_deinit_config[16] = {
|
||||
//DSI config (if ver == 0x10).
|
||||
static const cfg_op_t _display_deinit_config_jdi[22] = {
|
||||
{DSI_WR_DATA, 0x439}, // MIPI_DSI_DCS_LONG_WRITE: 4 bytes.
|
||||
{DSI_WR_DATA, 0x9483FFB9}, // Enable extension cmd. (Pass: FF 83 94).
|
||||
{DSI_WR_DATA, 0x9483FFB9}, // MIPI_DCS_PRIV_SET_EXTC. (Pass: FF 83 94).
|
||||
{DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
{DSI_WR_DATA, 0x2139}, // MIPI_DSI_DCS_LONG_WRITE: 33 bytes.
|
||||
{DSI_WR_DATA, 0x191919D5},
|
||||
{DSI_WR_DATA, 0x191919D5}, // Register: 0xD5.
|
||||
{DSI_WR_DATA, 0x19191919},
|
||||
{DSI_WR_DATA, 0x19191919},
|
||||
{DSI_WR_DATA, 0x19191919},
|
||||
@@ -491,21 +541,21 @@ static const cfg_op_t _display_deinit_config_jdi[22] = {
|
||||
{DSI_WR_DATA, 0x19},
|
||||
{DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
{DSI_WR_DATA, 0xB39}, // MIPI_DSI_DCS_LONG_WRITE: 11 bytes.
|
||||
{DSI_WR_DATA, 0x4F0F41B1}, // Set Power control.
|
||||
{DSI_WR_DATA, 0x4F0F41B1}, // MIPI_DCS_PRIV_SET_POWER_CONTROL.
|
||||
{DSI_WR_DATA, 0xF179A433},
|
||||
{DSI_WR_DATA, 0x002D81},
|
||||
{DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
{DSI_WR_DATA, 0x439}, // MIPI_DSI_DCS_LONG_WRITE: 4 bytes.
|
||||
{DSI_WR_DATA, 0x000000B9}, // Disable extension cmd.
|
||||
{DSI_WR_DATA, 0x000000B9}, // MIPI_DCS_PRIV_SET_EXTC. Disable.
|
||||
{DSI_TRIGGER, DSI_TRIGGER_HOST}
|
||||
};
|
||||
|
||||
static const cfg_op_t _display_deinit_config_auo[37] = {
|
||||
{DSI_WR_DATA, 0x439}, // MIPI_DSI_DCS_LONG_WRITE: 4 bytes.
|
||||
{DSI_WR_DATA, 0x9483FFB9}, // Enable extension cmd. (Pass: FF 83 94).
|
||||
{DSI_WR_DATA, 0x9483FFB9}, // MIPI_DCS_PRIV_SET_EXTC. (Pass: FF 83 94).
|
||||
{DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
{DSI_WR_DATA, 0x2C39}, // MIPI_DSI_DCS_LONG_WRITE: 44 bytes.
|
||||
{DSI_WR_DATA, 0x191919D5},
|
||||
{DSI_WR_DATA, 0x191919D5}, // Register: 0xD5.
|
||||
{DSI_WR_DATA, 0x19191919},
|
||||
{DSI_WR_DATA, 0x19191919},
|
||||
{DSI_WR_DATA, 0x19191919},
|
||||
@@ -518,7 +568,7 @@ static const cfg_op_t _display_deinit_config_auo[37] = {
|
||||
{DSI_WR_DATA, 0x19191919},
|
||||
{DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
{DSI_WR_DATA, 0x2C39}, // MIPI_DSI_DCS_LONG_WRITE: 44 bytes.
|
||||
{DSI_WR_DATA, 0x191919D6},
|
||||
{DSI_WR_DATA, 0x191919D6}, // Register: 0xD6.
|
||||
{DSI_WR_DATA, 0x19191919},
|
||||
{DSI_WR_DATA, 0x19191919},
|
||||
{DSI_WR_DATA, 0x19191919},
|
||||
@@ -531,13 +581,13 @@ static const cfg_op_t _display_deinit_config_auo[37] = {
|
||||
{DSI_WR_DATA, 0x19191919},
|
||||
{DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
{DSI_WR_DATA, 0xB39}, // MIPI_DSI_DCS_LONG_WRITE: 11 bytes.
|
||||
{DSI_WR_DATA, 0x711148B1}, // Set Power control. (Not deep standby, BT1 / XDK, VRH gamma volt adj 49 / x40).
|
||||
// Set Power control. (NVRH gamma volt adj 9, Amplifier current small / x30, FS0 freq Fosc/80 / FS1 freq Fosc/32, Enter standby / PON / VCOMG).
|
||||
{DSI_WR_DATA, 0x711148B1}, // MIPI_DCS_PRIV_SET_POWER_CONTROL. (Not deep standby, BT1 / XDK, VRH gamma volt adj 49 / x40).
|
||||
// (NVRH gamma volt adj 9, Amplifier current small / x30, FS0 freq Fosc/80 / FS1 freq Fosc/32, Enter standby / PON / VCOMG).
|
||||
{DSI_WR_DATA, 0x71143209},
|
||||
{DSI_WR_DATA, 0x114D31}, // Set Power control. (Unknown).
|
||||
{DSI_WR_DATA, 0x114D31}, // (Unknown).
|
||||
{DSI_TRIGGER, DSI_TRIGGER_HOST},
|
||||
{DSI_WR_DATA, 0x439}, // MIPI_DSI_DCS_LONG_WRITE: 4 bytes.
|
||||
{DSI_WR_DATA, 0x000000B9}, // Disable extension cmd.
|
||||
{DSI_WR_DATA, 0x000000B9}, // MIPI_DCS_PRIV_SET_EXTC. Disable.
|
||||
{DSI_TRIGGER, DSI_TRIGGER_HOST}
|
||||
};
|
||||
|
||||
@@ -559,8 +609,44 @@ static const cfg_op_t cfg_display_one_color[8] = {
|
||||
{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY} // Continuous display.
|
||||
};
|
||||
|
||||
//Display A config pitch.
|
||||
static const cfg_op_t cfg_display_framebuffer_pitch[34] = {
|
||||
//Display A config linear pitch.
|
||||
static const cfg_op_t cfg_display_framebuffer_pitch[32] = {
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_B_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_A_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
|
||||
{DC_WIN_COLOR_DEPTH, WIN_COLOR_DEPTH_B8G8R8A8}, // NX Default: T_A8B8G8R8, WIN_COLOR_DEPTH_R8G8B8A8.
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_WIN_POSITION, 0}, //(0,0)
|
||||
{DC_WIN_H_INITIAL_DDA, 0},
|
||||
{DC_WIN_V_INITIAL_DDA, 0},
|
||||
{DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(720 * 4)},
|
||||
{DC_WIN_DDA_INC, V_DDA_INC(0x1000) | H_DDA_INC(0x1000)}, // 1.0x.
|
||||
{DC_WIN_SIZE, V_SIZE(1280) | H_SIZE(720)},
|
||||
{DC_WIN_LINE_STRIDE, UV_LINE_STRIDE(720 * 2) | LINE_STRIDE(720 * 4)}, // 720*2x720*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements.
|
||||
{DC_WIN_BUFFER_CONTROL, BUFFER_CONTROL_HOST},
|
||||
{DC_WINBUF_SURFACE_KIND, PITCH},
|
||||
{DC_WINBUF_START_ADDR, IPL_FB_ADDRESS}, // Framebuffer address.
|
||||
{DC_WINBUF_ADDR_H_OFFSET, 0},
|
||||
{DC_WINBUF_ADDR_V_OFFSET, 0},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_DISP_DISP_WIN_OPTIONS, DSI_ENABLE},
|
||||
{DC_WIN_WIN_OPTIONS, WIN_ENABLE}, // Enable window AD.
|
||||
{DC_CMD_DISPLAY_COMMAND, DISP_CTRL_MODE_C_DISPLAY}, // Continuous display.
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_UPDATE | WIN_A_UPDATE},
|
||||
{DC_CMD_STATE_CONTROL, GENERAL_ACT_REQ | WIN_A_ACT_REQ}
|
||||
};
|
||||
|
||||
//Display A config linear pitch inverse + Win D support.
|
||||
static const cfg_op_t cfg_display_framebuffer_pitch_inv[34] = {
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_D_SELECT},
|
||||
{DC_WIN_WIN_OPTIONS, 0},
|
||||
{DC_CMD_DISPLAY_WINDOW_HEADER, WINDOW_C_SELECT},
|
||||
@@ -576,7 +662,7 @@ static const cfg_op_t cfg_display_framebuffer_pitch[34] = {
|
||||
{DC_WIN_POSITION, 0}, //(0,0)
|
||||
{DC_WIN_H_INITIAL_DDA, 0},
|
||||
{DC_WIN_V_INITIAL_DDA, 0},
|
||||
{DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(2880)},
|
||||
{DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(720 * 4)},
|
||||
{DC_WIN_DDA_INC, V_DDA_INC(0x1000) | H_DDA_INC(0x1000)}, // 1.0x.
|
||||
{DC_WIN_SIZE, V_SIZE(1280) | H_SIZE(720)},
|
||||
{DC_WIN_LINE_STRIDE, UV_LINE_STRIDE(720 * 2) | LINE_STRIDE(720 * 4)}, // 720*2x720*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements.
|
||||
@@ -614,7 +700,7 @@ static const cfg_op_t cfg_display_framebuffer_block[34] = {
|
||||
{DC_WIN_POSITION, 0}, //(0,0)
|
||||
{DC_WIN_H_INITIAL_DDA, 0},
|
||||
{DC_WIN_V_INITIAL_DDA, 0},
|
||||
{DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(2880)},
|
||||
{DC_WIN_PRESCALED_SIZE, V_PRESCALED_SIZE(1280) | H_PRESCALED_SIZE(720 * 4)},
|
||||
{DC_WIN_DDA_INC, V_DDA_INC(0x1000) | H_DDA_INC(0x1000)}, // 1.0x.
|
||||
{DC_WIN_SIZE, V_SIZE(1280) | H_SIZE(720)},
|
||||
{DC_WIN_LINE_STRIDE, UV_LINE_STRIDE(1280 * 2) | LINE_STRIDE(1280 * 4)}, //720*2x720*4 (= 0x600 x 0xC00) bytes, see TRM for alignment requirements.
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2020 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -14,11 +14,11 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _CLUSTER_H_
|
||||
#define _CLUSTER_H_
|
||||
#ifndef _FATFS_CFG_H_
|
||||
#define _FATFS_CFG_H_
|
||||
|
||||
#include "../utils/types.h"
|
||||
|
||||
void cluster_boot_cpu0(u32 entry);
|
||||
#ifdef FFCFG_INC
|
||||
#include FFCFG_INC
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018 CTCaer
|
||||
* Copyright (c) 2020 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -14,6 +14,11 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "../utils/types.h"
|
||||
#ifndef _GFX_UTILS_H_
|
||||
#define _GFX_UTILS_H_
|
||||
|
||||
char *dirlist(const char *directory, const char *pattern, bool includeHiddenFiles);
|
||||
#ifdef GFX_INC
|
||||
#include GFX_INC
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -22,10 +22,10 @@
|
||||
#include "elfarch.h"
|
||||
#include "elf.h"
|
||||
|
||||
#include "../../utils/types.h"
|
||||
#include <utils/types.h>
|
||||
|
||||
#ifdef DEBUG
|
||||
#include "../../gfx/gfx.h"
|
||||
#include <gfx_utils.h>
|
||||
#define EL_DEBUG(format, ...) \
|
||||
gfx_printf(format __VA_OPT__(, ) __VA_ARGS__)
|
||||
#else
|
||||
@@ -18,12 +18,14 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "ianos.h"
|
||||
#include "../../common/common_module.h"
|
||||
#include "../gfx/gfx.h"
|
||||
#include "../libs/elfload/elfload.h"
|
||||
#include "../mem/heap.h"
|
||||
#include "../storage/nx_sd.h"
|
||||
#include "../utils/types.h"
|
||||
#include "elfload/elfload.h"
|
||||
#include <module.h>
|
||||
#include <mem/heap.h>
|
||||
#include <power/max7762x.h>
|
||||
#include <storage/nx_sd.h>
|
||||
#include <utils/types.h>
|
||||
|
||||
#include <gfx_utils.h>
|
||||
|
||||
#define IRAM_LIB_ADDR 0x4002B000
|
||||
#define DRAM_LIB_ADDR 0xE0000000
|
||||
@@ -36,12 +38,16 @@ void *fileBuf = NULL;
|
||||
static void _ianos_call_ep(moduleEntrypoint_t entrypoint, void *moduleConfig)
|
||||
{
|
||||
bdkParams_t bdkParameters = (bdkParams_t)malloc(sizeof(struct _bdkParams_t));
|
||||
bdkParameters->gfxCon = &gfx_con;
|
||||
bdkParameters->gfxCtx = &gfx_ctxt;
|
||||
bdkParameters->gfxCon = (void *)&gfx_con;
|
||||
bdkParameters->gfxCtx = (void *)&gfx_ctxt;
|
||||
bdkParameters->memcpy = (memcpy_t)&memcpy;
|
||||
bdkParameters->memset = (memset_t)&memset;
|
||||
bdkParameters->sharedHeap = &_heap;
|
||||
|
||||
// Extra functions.
|
||||
bdkParameters->extension_magic = IANOS_EXT0;
|
||||
bdkParameters->reg_voltage_set = (reg_voltage_set_t)&max7762x_regulator_set_voltage;
|
||||
|
||||
entrypoint(moduleConfig, bdkParameters);
|
||||
}
|
||||
|
||||
@@ -63,26 +69,20 @@ static bool _ianos_read_cb(el_ctx *ctx, void *dest, size_t numberBytes, size_t o
|
||||
}
|
||||
|
||||
//TODO: Support shared libraries.
|
||||
uintptr_t ianos_loader(bool sdmount, char *path, elfType_t type, void *moduleConfig)
|
||||
uintptr_t ianos_loader(char *path, elfType_t type, void *moduleConfig)
|
||||
{
|
||||
el_ctx ctx;
|
||||
uintptr_t epaddr = 0;
|
||||
|
||||
if (sdmount)
|
||||
{
|
||||
if (!sd_mount())
|
||||
goto elfLoadFinalOut;
|
||||
}
|
||||
if (!sd_mount())
|
||||
goto elfLoadFinalOut;
|
||||
|
||||
// Read library.
|
||||
fileBuf = sd_file_read(path, NULL);
|
||||
|
||||
if (sdmount)
|
||||
sd_unmount();
|
||||
|
||||
if (!fileBuf)
|
||||
goto elfLoadFinalOut;
|
||||
|
||||
|
||||
el_ctx ctx;
|
||||
ctx.pread = _ianos_read_cb;
|
||||
|
||||
if (el_init(&ctx))
|
||||
@@ -94,7 +94,6 @@ uintptr_t ianos_loader(bool sdmount, char *path, elfType_t type, void *moduleCon
|
||||
case EXEC_ELF:
|
||||
case AR64_ELF:
|
||||
elfBuf = (void *)DRAM_LIB_ADDR;
|
||||
sd_unmount();
|
||||
break;
|
||||
default:
|
||||
elfBuf = malloc(ctx.memsz); // Aligned to 0x10 by default.
|
||||
@@ -123,6 +122,5 @@ elfFreeOut:
|
||||
fileBuf = NULL;
|
||||
|
||||
elfLoadFinalOut:
|
||||
|
||||
return epaddr;
|
||||
}
|
||||
@@ -18,7 +18,7 @@
|
||||
#ifndef IANOS_H
|
||||
#define IANOS_H
|
||||
|
||||
#include "../utils/types.h"
|
||||
#include <utils/types.h>
|
||||
|
||||
typedef enum
|
||||
{
|
||||
@@ -29,6 +29,6 @@ typedef enum
|
||||
KEEP_IN_RAM = (1 << 31) // Shared library mask.
|
||||
} elfType_t;
|
||||
|
||||
uintptr_t ianos_loader(bool sdmount, char *path, elfType_t type, void* config);
|
||||
uintptr_t ianos_loader(char *path, elfType_t type, void* config);
|
||||
|
||||
#endif
|
||||
156
bdk/input/als.c
Normal file
156
bdk/input/als.c
Normal file
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* Ambient light sensor driver for Nintendo Switch's Rohm BH1730
|
||||
*
|
||||
* Copyright (c) 2018 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "als.h"
|
||||
#include <power/max7762x.h>
|
||||
#include <soc/clock.h>
|
||||
#include <soc/i2c.h>
|
||||
#include <soc/pinmux.h>
|
||||
#include <utils/util.h>
|
||||
|
||||
#define BH1730_DEFAULT_GAIN BH1730_GAIN_64X
|
||||
#define BH1730_DEFAULT_ICYCLE 38
|
||||
|
||||
#define BH1730_INTERNAL_CLOCK_NS 2800
|
||||
#define BH1730_ADC_CALC_DELAY_US 2000 /* BH1730_INTERNAL_CLOCK_MS * 714 */
|
||||
#define BH1730_ITIME_CYCLE_TO_US 2700 /* BH1730_INTERNAL_CLOCK_MS * 964 */
|
||||
|
||||
#define BH1730_DEFAULT_ITIME_MS 100
|
||||
|
||||
#define BH1730_LUX_MULTIPLIER 3600
|
||||
#define BH1730_LUX_MULTIPLIER_AULA 1410
|
||||
|
||||
#define BH1730_LUX_MAX 100000
|
||||
|
||||
typedef struct _opt_win_cal_t
|
||||
{
|
||||
u32 rc;
|
||||
u32 cv;
|
||||
u32 ci;
|
||||
} opt_win_cal_t;
|
||||
|
||||
// Nintendo Switch Icosa/Iowa Optical Window calibration.
|
||||
const opt_win_cal_t opt_win_cal_default[] = {
|
||||
{ 500, 5002, 7502 },
|
||||
{ 754, 2250, 2000 },
|
||||
{ 1029, 1999, 1667 },
|
||||
{ 1373, 884, 583 },
|
||||
{ 1879, 309, 165 }
|
||||
};
|
||||
|
||||
// Nintendo Switch Aula Optical Window calibration.
|
||||
const opt_win_cal_t opt_win_cal_aula[] = {
|
||||
{ 231, 9697, 30300 },
|
||||
{ 993, 3333, 2778 },
|
||||
{ 1478, 1621, 1053 },
|
||||
{ 7500, 81, 10 }
|
||||
};
|
||||
|
||||
const u32 als_gain_idx_tbl[4] = { 1, 2, 64, 128 };
|
||||
|
||||
void set_als_cfg(als_ctxt_t *als_ctxt, u8 gain, u8 cycle)
|
||||
{
|
||||
if (gain > BH1730_GAIN_128X)
|
||||
gain = BH1730_GAIN_128X;
|
||||
|
||||
if (!cycle)
|
||||
cycle = 1;
|
||||
else if (cycle > 255)
|
||||
cycle = 255;
|
||||
|
||||
i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_GAIN_REG), gain);
|
||||
i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_TIMING_REG), (256 - cycle));
|
||||
|
||||
als_ctxt->gain = gain;
|
||||
als_ctxt->cycle = cycle;
|
||||
}
|
||||
|
||||
void get_als_lux(als_ctxt_t *als_ctxt)
|
||||
{
|
||||
u32 data[2];
|
||||
u32 visible_light;
|
||||
u32 ir_light;
|
||||
u64 lux = 0;
|
||||
u32 itime_us = BH1730_ITIME_CYCLE_TO_US * als_ctxt->cycle;
|
||||
|
||||
// Get visible and ir light raw data. Mode is continuous so waiting for new values doesn't matter.
|
||||
data[0] = i2c_recv_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_DATA0LOW_REG)) +
|
||||
(i2c_recv_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_DATA0HIGH_REG)) << 8);
|
||||
data[1] = i2c_recv_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_DATA1LOW_REG)) +
|
||||
(i2c_recv_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_DATA1HIGH_REG)) << 8);
|
||||
|
||||
visible_light = data[0];
|
||||
ir_light = data[1];
|
||||
|
||||
als_ctxt->over_limit = visible_light > 65534 || ir_light > 65534;
|
||||
als_ctxt->vi_light = visible_light;
|
||||
als_ctxt->ir_light = ir_light;
|
||||
|
||||
if (!visible_light)
|
||||
{
|
||||
als_ctxt->lux = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Set calibration parameters.
|
||||
u32 lux_multiplier = BH1730_LUX_MULTIPLIER;
|
||||
u32 opt_win_cal_count = ARRAY_SIZE(opt_win_cal_default);
|
||||
const opt_win_cal_t *opt_win_cal = opt_win_cal_default;
|
||||
|
||||
// Apply optical window calibration coefficients.
|
||||
for (u32 i = 0; i < opt_win_cal_count; i++)
|
||||
{
|
||||
if (1000 * ir_light / visible_light < opt_win_cal[i].rc)
|
||||
{
|
||||
lux = ((u64)opt_win_cal[i].cv * data[0]) - (opt_win_cal[i].ci * data[1]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
lux *= BH1730_DEFAULT_ITIME_MS * lux_multiplier;
|
||||
lux /= als_gain_idx_tbl[als_ctxt->gain] * itime_us;
|
||||
lux /= 1000;
|
||||
|
||||
if (lux > BH1730_LUX_MAX)
|
||||
lux = BH1730_LUX_MAX;
|
||||
|
||||
als_ctxt->lux = lux;
|
||||
}
|
||||
|
||||
u8 als_power_on(als_ctxt_t *als_ctxt)
|
||||
{
|
||||
// Enable power to ALS IC.
|
||||
max7762x_regulator_set_voltage(REGULATOR_LDO6, 2900000);
|
||||
max7762x_regulator_enable(REGULATOR_LDO6, true);
|
||||
|
||||
// Init I2C2.
|
||||
pinmux_config_i2c(I2C_2);
|
||||
clock_enable_i2c(I2C_2);
|
||||
i2c_init(I2C_2);
|
||||
|
||||
// Initialize ALS.
|
||||
u8 id = i2c_recv_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(0x12));
|
||||
i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_SPEC(BH1730_SPECCMD_RESET), 0);
|
||||
|
||||
set_als_cfg(als_ctxt, BH1730_DEFAULT_GAIN, BH1730_DEFAULT_ICYCLE);
|
||||
|
||||
i2c_send_byte(I2C_2, BH1730_I2C_ADDR, BH1730_ADDR(BH1730_CONTROL_REG), BH1730_CTL_POWER_ON | BH1730_CTL_ADC_EN);
|
||||
|
||||
return id;
|
||||
}
|
||||
@@ -19,7 +19,7 @@
|
||||
#ifndef __ALS_H_
|
||||
#define __ALS_H_
|
||||
|
||||
#include "../utils/types.h"
|
||||
#include <utils/types.h>
|
||||
|
||||
#define BH1730_I2C_ADDR 0x29
|
||||
|
||||
@@ -45,21 +45,21 @@
|
||||
#define BH1730_DATA1LOW_REG 0x16
|
||||
#define BH1730_DATA1HIGH_REG 0x17
|
||||
|
||||
#define BH1730_ADDR(reg) (BH1730_CMD_MAGIC | BH1730_CMD_SETADDR | reg)
|
||||
#define BH1730_SPEC(cmd) (BH1730_CMD_MAGIC | BH1730_CMD_SPECCMD | cmd)
|
||||
#define BH1730_ADDR(reg) (BH1730_CMD_MAGIC | BH1730_CMD_SETADDR | (reg))
|
||||
#define BH1730_SPEC(cmd) (BH1730_CMD_MAGIC | BH1730_CMD_SPECCMD | (cmd))
|
||||
|
||||
typedef struct _als_table_t
|
||||
typedef struct _als_ctxt_t
|
||||
{
|
||||
float lux;
|
||||
u32 lux;
|
||||
bool over_limit;
|
||||
u32 vi_light;
|
||||
u32 ir_light;
|
||||
u8 gain;
|
||||
u8 itime;
|
||||
} als_table_t;
|
||||
u32 vi_light;
|
||||
u32 ir_light;
|
||||
u8 gain;
|
||||
u8 cycle;
|
||||
} als_ctxt_t;
|
||||
|
||||
void set_als_cfg(als_table_t *als_val, u8 gain, u8 itime);
|
||||
void get_als_lux(als_table_t *als_val);
|
||||
u8 als_init(als_table_t *als_val);
|
||||
void set_als_cfg(als_ctxt_t *als_ctxt, u8 gain, u8 cycle);
|
||||
void get_als_lux(als_ctxt_t *als_ctxt);
|
||||
u8 als_power_on(als_ctxt_t *als_ctxt);
|
||||
|
||||
#endif /* __ALS_H_ */
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Joy-Con UART driver for Nintendo Switch
|
||||
*
|
||||
* Copyright (c) 2019 CTCaer
|
||||
* Copyright (c) 2019-2021 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -19,48 +19,57 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "joycon.h"
|
||||
#include "../gfx/gfx.h"
|
||||
#include "../power/max17050.h"
|
||||
#include "../power/regulator_5v.h"
|
||||
#include "../soc/bpmp.h"
|
||||
#include "../soc/clock.h"
|
||||
#include "../soc/gpio.h"
|
||||
#include "../soc/pinmux.h"
|
||||
#include "../soc/uart.h"
|
||||
#include "../soc/t210.h"
|
||||
#include "../utils/util.h"
|
||||
#include <gfx_utils.h>
|
||||
#include <power/max17050.h>
|
||||
#include <power/regulator_5v.h>
|
||||
#include <soc/bpmp.h>
|
||||
#include <soc/clock.h>
|
||||
#include <soc/fuse.h>
|
||||
#include <soc/gpio.h>
|
||||
#include <soc/pinmux.h>
|
||||
#include <soc/uart.h>
|
||||
#include <soc/t210.h>
|
||||
#include <utils/util.h>
|
||||
|
||||
// For disabling driver when logging is enabled.
|
||||
#include "../libs/lvgl/lvgl.h"
|
||||
#include <libs/lv_conf.h>
|
||||
|
||||
#define JC_WIRED_CMD 0x91
|
||||
#define JC_WIRED_HID 0x92
|
||||
#define JC_WIRED_INIT_REPLY 0x94
|
||||
#define JC_INIT_HANDSHAKE 0xA5
|
||||
#define JC_WIRED_CMD 0x91
|
||||
#define JC_WIRED_HID 0x92
|
||||
#define JC_WIRED_INIT_REPLY 0x94
|
||||
#define JC_INIT_HANDSHAKE 0xA5
|
||||
|
||||
#define JC_WIRED_CMD_MAC 0x01
|
||||
#define JC_WIRED_CMD_10 0x10
|
||||
#define JC_HORI_INPUT_RPT_CMD 0x9A
|
||||
#define JC_HORI_INPUT_RPT 0x00
|
||||
|
||||
#define JC_HID_OUTPUT_RPT 0x01
|
||||
#define JC_HID_RUMBLE_RPT 0x10
|
||||
#define JC_WIRED_CMD_MAC 0x01
|
||||
#define JC_WIRED_CMD_10 0x10
|
||||
|
||||
#define JC_HID_INPUT_RPT 0x30
|
||||
#define JC_HID_SUBMCD_RPT 0x21
|
||||
#define JC_HID_OUTPUT_RPT 0x01
|
||||
#define JC_HID_RUMBLE_RPT 0x10
|
||||
|
||||
#define JC_HID_INPUT_RPT 0x30
|
||||
#define JC_HID_SUBMCD_RPT 0x21
|
||||
|
||||
#define JC_HID_SUBCMD_HCI_STATE 0x06
|
||||
#define HCI_STATE_SLEEP 0x00
|
||||
#define HCI_STATE_RECONNECT 0x01
|
||||
#define HCI_STATE_PAIR 0x02
|
||||
#define HCI_STATE_HOME 0x04
|
||||
#define HCI_STATE_SLEEP 0x00
|
||||
#define HCI_STATE_RECONNECT 0x01
|
||||
#define HCI_STATE_PAIR 0x02
|
||||
#define HCI_STATE_HOME 0x04
|
||||
#define JC_HID_SUBCMD_SPI_READ 0x10
|
||||
#define SPI_READ_OFFSET 0x20
|
||||
#define JC_HID_SUBCMD_RUMBLE_CTL 0x48
|
||||
#define JC_HID_SUBCMD_SND_RUMBLE 0xFF
|
||||
|
||||
#define JC_BTN_MASK_L 0xFF2900 // 0xFFE900: with charge status.
|
||||
#define JC_BTN_MASK_R 0x76FF
|
||||
#define JC_BTN_MASK_R 0x0056FF
|
||||
|
||||
#define JC_ID_L 1
|
||||
#define JC_ID_R 2
|
||||
#define JC_ID_L 0x01
|
||||
#define JC_ID_R 0x02
|
||||
#define JC_ID_HORI 0x20
|
||||
|
||||
#define JC_CRC8_INIT 0x00
|
||||
#define JC_CRC8_POLY 0x8D
|
||||
|
||||
enum
|
||||
{
|
||||
@@ -78,25 +87,31 @@ static const u8 init_jc[] = {
|
||||
static const u8 init_handshake[] = {
|
||||
0x19, 0x01, 0x03, 0x07, 0x00, // Uart header.
|
||||
JC_INIT_HANDSHAKE, 0x02, // Wired cmd and wired subcmd.
|
||||
0x01, 0x7E, 0x00, 0x00, 0x00 // Wired subcmd data.
|
||||
0x01, 0x7E, 0x00, 0x00, 0x00 // Wired subcmd data and crc.
|
||||
};
|
||||
|
||||
static const u8 init_get_info[] = {
|
||||
0x19, 0x01, 0x03, 0x07, 0x00, // Uart header.
|
||||
JC_WIRED_CMD, JC_WIRED_CMD_MAC, // Wired cmd and subcmd.
|
||||
0x00, 0x00, 0x00, 0x00, 0x24 // Wired subcmd data.
|
||||
0x00, 0x00, 0x00, 0x00, 0x24 // Wired subcmd data and crc.
|
||||
};
|
||||
|
||||
static const u8 init_finilize[] = {
|
||||
static const u8 init_finalize[] = {
|
||||
0x19, 0x01, 0x03, 0x07, 0x00, // Uart header.
|
||||
JC_WIRED_CMD, JC_WIRED_CMD_10, // Wired cmd and subcmd.
|
||||
0x00, 0x00, 0x00, 0x00, 0x3D // Wired subcmd data.
|
||||
0x00, 0x00, 0x00, 0x00, 0x3D // Wired subcmd data and crc.
|
||||
};
|
||||
|
||||
static const u8 nx_pad_status[] = {
|
||||
0x19, 0x01, 0x03, 0x08, 0x00, // Uart header.
|
||||
JC_WIRED_HID, 0x00, // Wired cmd and hid cmd.
|
||||
0x01, 0x00, 0x00, 0x69, 0x2D, 0x1F // hid data.
|
||||
0x01, 0x00, 0x00, 0x69, 0x2D, 0x1F // hid data and crc.
|
||||
};
|
||||
|
||||
static const u8 hori_pad_status[] = {
|
||||
0x19, 0x01, 0x03, 0x07, 0x00, // Uart header.
|
||||
JC_HORI_INPUT_RPT_CMD, 0x01, // Hori cmd and hori subcmd.
|
||||
0x00, 0x00, 0x00, 0x00, 0x48 // Hori cmd data and crc.
|
||||
};
|
||||
|
||||
typedef struct _jc_uart_hdr_t
|
||||
@@ -183,8 +198,8 @@ typedef struct _joycon_ctxt_t
|
||||
u8 connected;
|
||||
} joycon_ctxt_t;
|
||||
|
||||
static joycon_ctxt_t jc_l;
|
||||
static joycon_ctxt_t jc_r;
|
||||
static joycon_ctxt_t jc_l = {0};
|
||||
static joycon_ctxt_t jc_r = {0};
|
||||
|
||||
static bool jc_init_done = false;
|
||||
static u32 hid_pkt_inc = 0;
|
||||
@@ -193,33 +208,49 @@ static jc_gamepad_rpt_t jc_gamepad;
|
||||
|
||||
void jc_power_supply(u8 uart, bool enable);
|
||||
|
||||
static u8 jc_crc(u8 *data, u16 len)
|
||||
{
|
||||
u8 crc = JC_CRC8_INIT;
|
||||
u16 i, j;
|
||||
for (i = 0; i < len; i++) {
|
||||
crc ^= data[i];
|
||||
for (j = 0; j < 8; j++) {
|
||||
if ((crc & 0x80) != 0)
|
||||
crc = (u8)((crc << 1) ^ JC_CRC8_POLY);
|
||||
else
|
||||
crc <<= 1;
|
||||
}
|
||||
}
|
||||
return crc;
|
||||
}
|
||||
|
||||
void joycon_send_raw(u8 uart_port, const u8 *buf, u16 size)
|
||||
{
|
||||
uart_send(uart_port, buf, size);
|
||||
uart_wait_idle(uart_port, UART_TX_IDLE);
|
||||
}
|
||||
|
||||
static u16 jc_packet_add_uart_hdr(jc_wired_hdr_t *out, u8 wired_cmd, u8 *data, u16 size)
|
||||
static u16 jc_packet_add_uart_hdr(jc_wired_hdr_t *out, u8 wired_cmd, u8 *data, u16 size, bool crc)
|
||||
{
|
||||
out->uart_hdr.magic[0] = 0x19;
|
||||
out->uart_hdr.magic[1] = 0x01;
|
||||
out->uart_hdr.magic[2] = 0x3;
|
||||
|
||||
out->uart_hdr.total_size_lsb = 7;
|
||||
out->uart_hdr.total_size_lsb = sizeof(jc_wired_hdr_t) - sizeof(jc_uart_hdr_t);
|
||||
out->uart_hdr.total_size_msb = 0;
|
||||
out->cmd = wired_cmd;
|
||||
|
||||
if (data)
|
||||
memcpy(out->data, data, size);
|
||||
|
||||
out->crc = 0; // wired crc8ccit can be skipped.
|
||||
out->crc = crc ? jc_crc(&out->uart_hdr.total_size_msb, sizeof(out->uart_hdr.total_size_msb) + sizeof(out->cmd) + sizeof(out->data)) : 0;
|
||||
|
||||
return sizeof(jc_wired_hdr_t);
|
||||
}
|
||||
|
||||
static u16 jc_hid_output_rpt_craft(jc_wired_hdr_t *rpt, u8 *payload, u16 size)
|
||||
static u16 jc_hid_output_rpt_craft(jc_wired_hdr_t *rpt, u8 *payload, u16 size, bool crc)
|
||||
{
|
||||
u16 pkt_size = jc_packet_add_uart_hdr(rpt, JC_WIRED_HID, NULL, 0);
|
||||
u16 pkt_size = jc_packet_add_uart_hdr(rpt, JC_WIRED_HID, NULL, 0, crc);
|
||||
pkt_size += size;
|
||||
|
||||
rpt->uart_hdr.total_size_lsb += size;
|
||||
@@ -232,12 +263,12 @@ static u16 jc_hid_output_rpt_craft(jc_wired_hdr_t *rpt, u8 *payload, u16 size)
|
||||
return pkt_size;
|
||||
}
|
||||
|
||||
void jc_send_hid_output_rpt(u8 uart, u8 *payload, u16 size)
|
||||
void jc_send_hid_output_rpt(u8 uart, u8 *payload, u16 size, bool crc)
|
||||
{
|
||||
u8 rpt[0x50];
|
||||
memset(rpt, 0, sizeof(rpt));
|
||||
|
||||
u32 rpt_size = jc_hid_output_rpt_craft((jc_wired_hdr_t *)rpt, payload, size);
|
||||
u32 rpt_size = jc_hid_output_rpt_craft((jc_wired_hdr_t *)rpt, payload, size, crc);
|
||||
|
||||
joycon_send_raw(uart, rpt, rpt_size);
|
||||
}
|
||||
@@ -273,18 +304,18 @@ void jc_send_hid_cmd(u8 uart, u8 subcmd, u8 *data, u16 size)
|
||||
hid_pkt->subcmd = JC_HID_SUBCMD_RUMBLE_CTL;
|
||||
hid_pkt->subcmd_data[0] = 1;
|
||||
if (send_r_rumble)
|
||||
jc_send_hid_output_rpt(UART_B, (u8 *)hid_pkt, 0x10);
|
||||
jc_send_hid_output_rpt(UART_B, (u8 *)hid_pkt, 0x10, false);
|
||||
if (send_l_rumble)
|
||||
jc_send_hid_output_rpt(UART_C, (u8 *)hid_pkt, 0x10);
|
||||
jc_send_hid_output_rpt(UART_C, (u8 *)hid_pkt, 0x10, false);
|
||||
|
||||
// Send rumble.
|
||||
hid_pkt->cmd = JC_HID_RUMBLE_RPT;
|
||||
hid_pkt->pkt_id = jc_hid_pkt_id_incr();
|
||||
memcpy(hid_pkt->rumble, rumble_init, sizeof(rumble_init));
|
||||
if (send_r_rumble)
|
||||
jc_send_hid_output_rpt(UART_B, (u8 *)hid_pkt, 10);
|
||||
jc_send_hid_output_rpt(UART_B, (u8 *)hid_pkt, 10, false);
|
||||
if (send_l_rumble)
|
||||
jc_send_hid_output_rpt(UART_C, (u8 *)hid_pkt, 10);
|
||||
jc_send_hid_output_rpt(UART_C, (u8 *)hid_pkt, 10, false);
|
||||
|
||||
msleep(15);
|
||||
|
||||
@@ -295,27 +326,21 @@ void jc_send_hid_cmd(u8 uart, u8 subcmd, u8 *data, u16 size)
|
||||
hid_pkt->subcmd_data[0] = 0;
|
||||
memcpy(hid_pkt->rumble, rumble_neutral, sizeof(rumble_neutral));
|
||||
if (send_r_rumble)
|
||||
jc_send_hid_output_rpt(UART_B, (u8 *)hid_pkt, 0x10);
|
||||
jc_send_hid_output_rpt(UART_B, (u8 *)hid_pkt, 0x10, false);
|
||||
if (send_l_rumble)
|
||||
jc_send_hid_output_rpt(UART_C, (u8 *)hid_pkt, 0x10);
|
||||
jc_send_hid_output_rpt(UART_C, (u8 *)hid_pkt, 0x10, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
bool crc_needed = (jc_l.uart == uart) ? (jc_l.type & JC_ID_HORI) : (jc_r.type & JC_ID_HORI);
|
||||
|
||||
hid_pkt->cmd = JC_HID_OUTPUT_RPT;
|
||||
hid_pkt->pkt_id = jc_hid_pkt_id_incr();
|
||||
hid_pkt->subcmd = subcmd;
|
||||
if (data)
|
||||
memcpy(hid_pkt->subcmd_data, data, size);
|
||||
|
||||
u8 pkt_size = sizeof(jc_hid_out_rpt_t) + size;
|
||||
|
||||
if (subcmd != JC_HID_SUBCMD_SPI_READ)
|
||||
jc_send_hid_output_rpt(uart, (u8 *)hid_pkt, pkt_size);
|
||||
else
|
||||
{
|
||||
jc_send_hid_output_rpt(UART_B, (u8 *)hid_pkt, pkt_size);
|
||||
jc_send_hid_output_rpt(UART_C, (u8 *)hid_pkt, pkt_size);
|
||||
}
|
||||
jc_send_hid_output_rpt(uart, (u8 *)hid_pkt, sizeof(jc_hid_out_rpt_t) + size, crc_needed);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -337,6 +362,7 @@ static void jc_parse_wired_hid(joycon_ctxt_t *jc, const u8* packet, u32 size)
|
||||
|
||||
switch (hid_pkt->cmd)
|
||||
{
|
||||
case JC_HORI_INPUT_RPT:
|
||||
case JC_HID_INPUT_RPT:
|
||||
btn_tmp = hid_pkt->btn_right | hid_pkt->btn_shared << 8 | hid_pkt->btn_left << 16;
|
||||
|
||||
@@ -380,7 +406,7 @@ static void jc_parse_wired_hid(joycon_ctxt_t *jc, const u8* packet, u32 size)
|
||||
jc_hid_in_pair_data_t *pair_data = (jc_hid_in_pair_data_t *)spi_info->data;
|
||||
|
||||
// Check if we reply is pairing info.
|
||||
if (spi_info->addr == 0x2000 && spi_info->size == 0x1A && pair_data->magic == 0x95)
|
||||
if (spi_info->size == 0x1A && pair_data->magic == 0x95 && pair_data->size == 0x22)
|
||||
{
|
||||
bt_conn->type = jc->type;
|
||||
|
||||
@@ -416,6 +442,7 @@ static void jc_uart_pkt_parse(joycon_ctxt_t *jc, const u8* packet, size_t size)
|
||||
jc_wired_hdr_t *pkt = (jc_wired_hdr_t *)packet;
|
||||
switch (pkt->cmd)
|
||||
{
|
||||
case JC_HORI_INPUT_RPT_CMD:
|
||||
case JC_WIRED_HID:
|
||||
jc_parse_wired_hid(jc, pkt->payload, (pkt->data[0] << 8) | pkt->data[1]);
|
||||
break;
|
||||
@@ -436,10 +463,10 @@ static void jc_rcv_pkt(joycon_ctxt_t *jc)
|
||||
|
||||
// Check if device stopped sending data.
|
||||
u32 uart_irq = uart_get_IIR(jc->uart);
|
||||
if ((uart_irq & 0x8) != 0x8)
|
||||
if (uart_irq != UART_IIR_REDI)
|
||||
return;
|
||||
|
||||
u32 len = uart_recv(jc->uart, (u8 *)jc->buf, 0);
|
||||
u32 len = uart_recv(jc->uart, (u8 *)jc->buf, 0x100);
|
||||
|
||||
// Check valid size and uart reply magic.
|
||||
if (len > 7 && !memcmp(jc->buf, "\x19\x81\x03", 3))
|
||||
@@ -478,10 +505,15 @@ static bool jc_send_init_rumble(joycon_ctxt_t *jc)
|
||||
|
||||
static void jc_req_nx_pad_status(joycon_ctxt_t *jc)
|
||||
{
|
||||
bool sent_rumble = jc_send_init_rumble(jc);
|
||||
bool is_nxpad = !(jc->type & JC_ID_HORI);
|
||||
|
||||
if (sent_rumble)
|
||||
return;
|
||||
if (is_nxpad)
|
||||
{
|
||||
bool sent_rumble = jc_send_init_rumble(jc);
|
||||
|
||||
if (sent_rumble)
|
||||
return;
|
||||
}
|
||||
|
||||
if (jc->last_status_req_time > get_tmr_ms() || !jc->connected)
|
||||
return;
|
||||
@@ -492,7 +524,10 @@ static void jc_req_nx_pad_status(joycon_ctxt_t *jc)
|
||||
else
|
||||
gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_SPIO);
|
||||
|
||||
joycon_send_raw(jc->uart, nx_pad_status, sizeof(nx_pad_status));
|
||||
if (is_nxpad)
|
||||
joycon_send_raw(jc->uart, nx_pad_status, sizeof(nx_pad_status));
|
||||
else
|
||||
joycon_send_raw(jc->uart, hori_pad_status, sizeof(hori_pad_status));
|
||||
|
||||
// Turn Joy-Con detect on.
|
||||
if (jc->uart == UART_B)
|
||||
@@ -503,11 +538,34 @@ static void jc_req_nx_pad_status(joycon_ctxt_t *jc)
|
||||
jc->last_status_req_time = get_tmr_ms() + 15;
|
||||
}
|
||||
|
||||
jc_gamepad_rpt_t *jc_get_bt_pairing_info()
|
||||
static bool _jc_validate_pairing_info(u8 *buf, bool *is_hos)
|
||||
{
|
||||
u8 crc = 0;
|
||||
for (u32 i = 0; i < 0x22; i++)
|
||||
crc += buf[4 + i];
|
||||
|
||||
crc += 0x68; // Host is Switch.
|
||||
|
||||
if ((crc ^ 0x55) == buf[2])
|
||||
*is_hos = true;
|
||||
|
||||
crc -= 0x68;
|
||||
crc += 0x08; // Host is PC.
|
||||
|
||||
if (*is_hos || (crc ^ 0x55) == buf[2])
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
jc_gamepad_rpt_t *jc_get_bt_pairing_info(bool *is_l_hos, bool *is_r_hos)
|
||||
{
|
||||
u8 retries;
|
||||
jc_bt_conn_t *bt_conn;
|
||||
|
||||
if (!jc_init_done)
|
||||
return NULL;
|
||||
|
||||
bt_conn = &jc_gamepad.bt_conn_l;
|
||||
memset(bt_conn->host_mac, 0, 6);
|
||||
memset(bt_conn->ltk, 0, 16);
|
||||
@@ -522,9 +580,13 @@ jc_gamepad_rpt_t *jc_get_bt_pairing_info()
|
||||
jc_rcv_pkt(&jc_l);
|
||||
}
|
||||
|
||||
jc_hid_in_spi_read_t subcmd_data;
|
||||
subcmd_data.addr = 0x2000;
|
||||
subcmd_data.size = 0x1A;
|
||||
jc_hid_in_spi_read_t subcmd_data_l;
|
||||
subcmd_data_l.addr = 0x2000;
|
||||
subcmd_data_l.size = 0x1A;
|
||||
|
||||
jc_hid_in_spi_read_t subcmd_data_r;
|
||||
subcmd_data_r.addr = 0x2000;
|
||||
subcmd_data_r.size = 0x1A;
|
||||
|
||||
// Turn off Joy-Con detect.
|
||||
gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_SPIO);
|
||||
@@ -533,46 +595,94 @@ jc_gamepad_rpt_t *jc_get_bt_pairing_info()
|
||||
bool jc_r_found = jc_r.connected ? false : true;
|
||||
bool jc_l_found = jc_l.connected ? false : true;
|
||||
|
||||
u32 total_retries = 5;
|
||||
u32 total_retries = 10;
|
||||
retry:
|
||||
retries = 10;
|
||||
while (retries)
|
||||
{
|
||||
if (jc_l.last_status_req_time < get_tmr_ms())
|
||||
u32 time_now = get_tmr_ms();
|
||||
if ((!jc_l_found && jc_l.last_status_req_time < time_now) || (!jc_r_found && jc_r.last_status_req_time < time_now))
|
||||
{
|
||||
jc_send_hid_cmd(0, JC_HID_SUBCMD_SPI_READ, (u8 *)&subcmd_data, 5);
|
||||
jc_l.last_status_req_time = get_tmr_ms() + 15;
|
||||
jc_r.last_status_req_time = get_tmr_ms() + 15;
|
||||
retries--;
|
||||
}
|
||||
if (!jc_l_found)
|
||||
{
|
||||
jc_send_hid_cmd(jc_l.uart, JC_HID_SUBCMD_SPI_READ, (u8 *)&subcmd_data_l, 5);
|
||||
jc_l.last_status_req_time = get_tmr_ms() + 15;
|
||||
}
|
||||
|
||||
if (!jc_r_found)
|
||||
{
|
||||
memset(jc_r.buf, 0, 0x100);
|
||||
jc_rcv_pkt(&jc_r);
|
||||
if (!jc_r_found)
|
||||
{
|
||||
jc_send_hid_cmd(jc_r.uart, JC_HID_SUBCMD_SPI_READ, (u8 *)&subcmd_data_r, 5);
|
||||
jc_r.last_status_req_time = get_tmr_ms() + 15;
|
||||
}
|
||||
|
||||
retries--;
|
||||
}
|
||||
|
||||
if (!jc_l_found)
|
||||
{
|
||||
memset(jc_l.buf, 0, 0x100);
|
||||
jc_rcv_pkt(&jc_l);
|
||||
|
||||
bool is_hos = false;
|
||||
if (_jc_validate_pairing_info(&jc_l.buf[SPI_READ_OFFSET], &is_hos))
|
||||
{
|
||||
bool is_active = jc_l.buf[SPI_READ_OFFSET] == 0x95;
|
||||
|
||||
if (!is_active)
|
||||
subcmd_data_l.addr += 0x26; // Get next slot.
|
||||
else
|
||||
jc_l_found = true; // Entry is active.
|
||||
|
||||
if (jc_l_found && is_hos)
|
||||
*is_l_hos = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!jc_r_found)
|
||||
{
|
||||
memset(jc_r.buf, 0, 0x100);
|
||||
jc_rcv_pkt(&jc_r);
|
||||
|
||||
bool is_hos = false;
|
||||
if (_jc_validate_pairing_info(&jc_r.buf[SPI_READ_OFFSET], &is_hos))
|
||||
{
|
||||
bool is_active = jc_r.buf[SPI_READ_OFFSET] == 0x95;
|
||||
|
||||
if (!is_active)
|
||||
subcmd_data_r.addr += 0x26; // Get next slot.
|
||||
else
|
||||
jc_r_found = true; // Entry is active.
|
||||
|
||||
if (jc_r_found && is_hos)
|
||||
*is_r_hos = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (jc_l_found && jc_r_found)
|
||||
break;
|
||||
}
|
||||
|
||||
if (jc_l.connected &&
|
||||
memcmp(&jc_gamepad.bt_conn_l.ltk[0], "\x00\x00\x00\x00", 4) &&
|
||||
memcmp(&jc_gamepad.bt_conn_l.ltk[8], "\x00\x00\x00\x00", 4))
|
||||
jc_l_found = true;
|
||||
|
||||
if (jc_r.connected &&
|
||||
memcmp(&jc_gamepad.bt_conn_r.ltk[0], "\x00\x00\x00\x00", 4) &&
|
||||
memcmp(&jc_gamepad.bt_conn_r.ltk[8], "\x00\x00\x00\x00", 4))
|
||||
jc_r_found = true;
|
||||
|
||||
if (total_retries && (!jc_l_found || !jc_r_found))
|
||||
if (!jc_l_found || !jc_r_found)
|
||||
{
|
||||
total_retries--;
|
||||
goto retry;
|
||||
if (total_retries)
|
||||
{
|
||||
total_retries--;
|
||||
goto retry;
|
||||
}
|
||||
|
||||
if (!jc_l_found)
|
||||
{
|
||||
bt_conn = &jc_gamepad.bt_conn_l;
|
||||
memset(bt_conn->host_mac, 0, 6);
|
||||
memset(bt_conn->ltk, 0, 16);
|
||||
}
|
||||
|
||||
if (!jc_r_found)
|
||||
{
|
||||
bt_conn = &jc_gamepad.bt_conn_r;
|
||||
memset(bt_conn->host_mac, 0, 6);
|
||||
memset(bt_conn->ltk, 0, 16);
|
||||
}
|
||||
}
|
||||
|
||||
// Turn Joy-Con detect on.
|
||||
@@ -584,26 +694,31 @@ retry:
|
||||
|
||||
void jc_deinit()
|
||||
{
|
||||
// Disable power.
|
||||
jc_power_supply(UART_B, false);
|
||||
jc_power_supply(UART_C, false);
|
||||
|
||||
// Turn off Joy-Con detect.
|
||||
gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_SPIO);
|
||||
gpio_config(GPIO_PORT_D, GPIO_PIN_1, GPIO_MODE_SPIO);
|
||||
|
||||
// Send sleep command.
|
||||
u8 data = HCI_STATE_SLEEP;
|
||||
|
||||
if (jc_r.connected)
|
||||
if (jc_r.connected && !(jc_r.type & JC_ID_HORI))
|
||||
{
|
||||
jc_send_hid_cmd(UART_B, JC_HID_SUBCMD_HCI_STATE, &data, 1);
|
||||
msleep(1);
|
||||
jc_rcv_pkt(&jc_r);
|
||||
}
|
||||
if (jc_l.connected)
|
||||
if (jc_l.connected && !(jc_l.type & JC_ID_HORI))
|
||||
{
|
||||
jc_send_hid_cmd(UART_C, JC_HID_SUBCMD_HCI_STATE, &data, 1);
|
||||
msleep(1);
|
||||
jc_rcv_pkt(&jc_l);
|
||||
}
|
||||
|
||||
jc_power_supply(UART_B, false);
|
||||
jc_power_supply(UART_C, false);
|
||||
// Disable UART B and C clocks.
|
||||
clock_disable_uart(UART_B);
|
||||
clock_disable_uart(UART_C);
|
||||
}
|
||||
|
||||
static void jc_init_conn(joycon_ctxt_t *jc)
|
||||
@@ -640,9 +755,12 @@ static void jc_init_conn(joycon_ctxt_t *jc)
|
||||
msleep(5);
|
||||
jc_rcv_pkt(jc);
|
||||
|
||||
joycon_send_raw(jc->uart, init_finilize, sizeof(init_finilize));
|
||||
msleep(5);
|
||||
jc_rcv_pkt(jc);
|
||||
if (!(jc->type & JC_ID_HORI))
|
||||
{
|
||||
joycon_send_raw(jc->uart, init_finalize, sizeof(init_finalize));
|
||||
msleep(5);
|
||||
jc_rcv_pkt(jc);
|
||||
}
|
||||
|
||||
// Turn Joy-Con detect on.
|
||||
if (jc->uart == UART_B)
|
||||
@@ -697,10 +815,10 @@ void jc_power_supply(u8 uart, bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
if (regulator_get_5v_dev_enabled(1 << uart))
|
||||
if (regulator_5v_get_dev_enabled(1 << uart))
|
||||
return;
|
||||
|
||||
regulator_enable_5v(1 << uart);
|
||||
regulator_5v_enable(1 << uart);
|
||||
|
||||
if (jc_init_done)
|
||||
{
|
||||
@@ -730,10 +848,10 @@ void jc_power_supply(u8 uart, bool enable)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!regulator_get_5v_dev_enabled(1 << uart))
|
||||
if (!regulator_5v_get_dev_enabled(1 << uart))
|
||||
return;
|
||||
|
||||
regulator_disable_5v(1 << uart);
|
||||
regulator_5v_disable(1 << uart);
|
||||
|
||||
if (uart == UART_C)
|
||||
gpio_write(GPIO_PORT_CC, GPIO_PIN_3, GPIO_LOW);
|
||||
@@ -747,7 +865,10 @@ void jc_init_hw()
|
||||
jc_l.uart = UART_C;
|
||||
jc_r.uart = UART_B;
|
||||
|
||||
#if (LV_LOG_PRINTF != 1)
|
||||
#if !defined(DEBUG_UART_PORT) || !(DEBUG_UART_PORT)
|
||||
if (fuse_read_hw_type() == FUSE_NX_HW_TYPE_HOAG)
|
||||
return;
|
||||
|
||||
jc_power_supply(UART_C, true);
|
||||
jc_power_supply(UART_B, true);
|
||||
|
||||
@@ -764,14 +885,14 @@ void jc_init_hw()
|
||||
pinmux_config_uart(UART_C);
|
||||
|
||||
// Ease the stress to APB.
|
||||
bpmp_clk_rate_set(BPMP_CLK_NORMAL);
|
||||
bpmp_freq_t prev_fid = bpmp_clk_rate_set(BPMP_CLK_NORMAL);
|
||||
|
||||
// Enable UART B and C clocks.
|
||||
clock_enable_uart(UART_B);
|
||||
clock_enable_uart(UART_C);
|
||||
|
||||
// Restore OC.
|
||||
bpmp_clk_rate_set(BPMP_CLK_DEFAULT_BOOST);
|
||||
bpmp_clk_rate_set(prev_fid);
|
||||
|
||||
// Turn Joy-Con detect on.
|
||||
gpio_config(GPIO_PORT_G, GPIO_PIN_0, GPIO_MODE_GPIO);
|
||||
@@ -19,7 +19,7 @@
|
||||
#ifndef __JOYCON_H_
|
||||
#define __JOYCON_H_
|
||||
|
||||
#include "../utils/types.h"
|
||||
#include <utils/types.h>
|
||||
|
||||
#define JC_BTNS_DIRECTION_PAD 0xF0000
|
||||
#define JC_BTNS_PREV_NEXT 0x800080
|
||||
@@ -93,6 +93,6 @@ void jc_power_supply(u8 uart, bool enable);
|
||||
void jc_init_hw();
|
||||
void jc_deinit();
|
||||
jc_gamepad_rpt_t *joycon_poll();
|
||||
jc_gamepad_rpt_t *jc_get_bt_pairing_info();
|
||||
jc_gamepad_rpt_t *jc_get_bt_pairing_info(bool *is_l_hos, bool *is_r_hos);
|
||||
|
||||
#endif
|
||||
@@ -19,21 +19,30 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "../soc/clock.h"
|
||||
#include "../soc/i2c.h"
|
||||
#include "../soc/pinmux.h"
|
||||
#include "../power/max7762x.h"
|
||||
#include "../power/max77620.h"
|
||||
#include "../soc/gpio.h"
|
||||
#include "../soc/t210.h"
|
||||
#include "../utils/btn.h"
|
||||
#include "../utils/util.h"
|
||||
#include <soc/clock.h>
|
||||
#include <soc/i2c.h>
|
||||
#include <soc/pinmux.h>
|
||||
#include <power/max7762x.h>
|
||||
#include <soc/gpio.h>
|
||||
#include <soc/t210.h>
|
||||
#include <utils/btn.h>
|
||||
#include <utils/util.h>
|
||||
#include "touch.h"
|
||||
|
||||
|
||||
#include "../gfx/gfx.h"
|
||||
#include <gfx_utils.h>
|
||||
#define DPRINTF(...) gfx_printf(__VA_ARGS__)
|
||||
|
||||
static touch_panel_info_t _panels[] =
|
||||
{
|
||||
{ 0, 1, 1, 1, "NISSHA NFT-K12D" },
|
||||
{ 1, 0, 1, 1, "GiS GGM6 B2X" },
|
||||
{ 2, 0, 0, 0, "NISSHA NBF-K9A" },
|
||||
{ 3, 1, 0, 0, "GiS 5.5\"" },
|
||||
{ 4, 0, 0, 1, "Unknown" },
|
||||
{ -1, 1, 0, 1, "GiS VA 6.2\"" }
|
||||
};
|
||||
|
||||
static int touch_command(u8 cmd, u8 *buf, u8 size)
|
||||
{
|
||||
int res = i2c_send_buf_small(I2C_3, STMFTS_I2C_ADDR, cmd, buf, size);
|
||||
@@ -53,7 +62,7 @@ static int touch_read_reg(u8 *cmd, u32 csize, u8 *buf, u32 size)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int touch_wait_event(u8 event, u8 status, u32 timeout)
|
||||
static int touch_wait_event(u8 event, u8 status, u32 timeout, u8 *buf)
|
||||
{
|
||||
u32 timer = get_tmr_ms() + timeout;
|
||||
while (true)
|
||||
@@ -61,7 +70,11 @@ static int touch_wait_event(u8 event, u8 status, u32 timeout)
|
||||
u8 tmp[8] = {0};
|
||||
i2c_recv_buf_small(tmp, 8, I2C_3, STMFTS_I2C_ADDR, STMFTS_READ_ONE_EVENT);
|
||||
if (tmp[1] == event && tmp[2] == status)
|
||||
{
|
||||
if (buf)
|
||||
memcpy(buf, &tmp[3], 5);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (get_tmr_ms() > timer)
|
||||
return 1;
|
||||
@@ -147,10 +160,10 @@ static void _touch_parse_event(touch_event *event)
|
||||
event->type = STMFTS_EV_MULTI_TOUCH_LEAVE;
|
||||
}
|
||||
|
||||
// gfx_con_setpos(&gfx_con, 0, 300);
|
||||
// gfx_con_setpos(0, 300);
|
||||
// DPRINTF("x = %d \ny = %d \nz = %d \n", event->x, event->y, event->z);
|
||||
// DPRINTF("0 = %02X\n1 = %02x\n2 = %02x\n3 = %02x\n", event->raw[0], event->raw[1], event->raw[2], event->raw[3]);
|
||||
// DPRINTF("4 = %02X\n5 = %02x\n6 = %02x\n7 = %02x\n", event->raw[4], event->raw[5], event->raw[6], event->raw[7]);
|
||||
// DPRINTF("0 = %02X\n1 = %02X\n2 = %02X\n3 = %02X\n", event->raw[0], event->raw[1], event->raw[2], event->raw[3]);
|
||||
// DPRINTF("4 = %02X\n5 = %02X\n6 = %02X\n7 = %02X\n", event->raw[4], event->raw[5], event->raw[6], event->raw[7]);
|
||||
}
|
||||
|
||||
void touch_poll(touch_event *event)
|
||||
@@ -183,16 +196,45 @@ touch_info touch_get_info()
|
||||
info.config_id = buf[4];
|
||||
info.config_ver = buf[5];
|
||||
|
||||
//DPRINTF("ID: %04X, FW Ver: %d.%02d\nCfg ID: %02x, Cfg Ver: %d\n",
|
||||
//DPRINTF("ID: %04X, FW Ver: %d.%02d\nCfg ID: %02X, Cfg Ver: %d\n",
|
||||
// info.chip_id, info.fw_ver >> 8, info.fw_ver & 0xFF, info.config_id, info.config_ver);
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
touch_panel_info_t *touch_get_panel_vendor()
|
||||
{
|
||||
u8 buf[5] = {0};
|
||||
u8 cmd = STMFTS_VENDOR_GPIO_STATE;
|
||||
static touch_panel_info_t panel_info = { -2, 0, 0, 0, ""};
|
||||
|
||||
if (touch_command(STMFTS_VENDOR, &cmd, 1))
|
||||
return NULL;
|
||||
|
||||
if (touch_wait_event(STMFTS_EV_VENDOR, STMFTS_VENDOR_GPIO_STATE, 2000, buf))
|
||||
return NULL;
|
||||
|
||||
for (u32 i = 0; i < ARRAY_SIZE(_panels); i++)
|
||||
{
|
||||
touch_panel_info_t *panel = &_panels[i];
|
||||
if (buf[0] == panel->gpio0 && buf[1] == panel->gpio1 && buf[2] == panel->gpio2)
|
||||
return panel;
|
||||
}
|
||||
|
||||
// Touch panel not found, return current gpios.
|
||||
panel_info.gpio0 = buf[0];
|
||||
panel_info.gpio1 = buf[1];
|
||||
panel_info.gpio2 = buf[2];
|
||||
|
||||
return &panel_info;
|
||||
}
|
||||
|
||||
int touch_get_fw_info(touch_fw_info_t *fw)
|
||||
{
|
||||
u8 buf[8] = {0};
|
||||
|
||||
memset(fw, 0, sizeof(touch_fw_info_t));
|
||||
|
||||
// Get fw address info.
|
||||
u8 cmd[3] = { STMFTS_RW_FRAMEBUFFER_REG, 0, 0x60 };
|
||||
int res = touch_read_reg(cmd, 3, buf, 3);
|
||||
@@ -227,7 +269,7 @@ int touch_sys_reset()
|
||||
continue;
|
||||
}
|
||||
msleep(10);
|
||||
if (touch_wait_event(STMFTS_EV_CONTROLLER_READY, 0, 20))
|
||||
if (touch_wait_event(STMFTS_EV_CONTROLLER_READY, 0, 20, NULL))
|
||||
continue;
|
||||
else
|
||||
return 0;
|
||||
@@ -284,7 +326,7 @@ int touch_get_fb_info(u8 *buf)
|
||||
int res = 0;
|
||||
|
||||
|
||||
for (u32 i = 0; i < 0x10000; i+=4)
|
||||
for (u32 i = 0; i < 0x10000; i += 4)
|
||||
{
|
||||
if (!res)
|
||||
{
|
||||
@@ -301,9 +343,9 @@ int touch_get_fb_info(u8 *buf)
|
||||
|
||||
int touch_sense_enable()
|
||||
{
|
||||
// Enable auto tuning calibration and multi-touch sensing.
|
||||
u8 cmd = 1;
|
||||
if (touch_command(STMFTS_AUTO_CALIBRATION, &cmd, 1))
|
||||
// Switch sense mode and enable multi-touch sensing.
|
||||
u8 cmd = STMFTS_FINGER_MODE;
|
||||
if (touch_command(STMFTS_SWITCH_SENSE_MODE, &cmd, 1))
|
||||
return 0;
|
||||
|
||||
if (touch_command(STMFTS_MS_MT_SENSE_ON, NULL, 0))
|
||||
@@ -329,19 +371,19 @@ int touch_execute_autotune()
|
||||
// Apply Mutual Sense Compensation tuning.
|
||||
if (touch_command(STMFTS_MS_CX_TUNING, NULL, 0))
|
||||
return 0;
|
||||
if (touch_wait_event(STMFTS_EV_STATUS, STMFTS_EV_STATUS_MS_CX_TUNING_DONE, 2000))
|
||||
if (touch_wait_event(STMFTS_EV_STATUS, STMFTS_EV_STATUS_MS_CX_TUNING_DONE, 2000, NULL))
|
||||
return 0;
|
||||
|
||||
// Apply Self Sense Compensation tuning.
|
||||
if (touch_command(STMFTS_SS_CX_TUNING, NULL, 0))
|
||||
return 0;
|
||||
if (touch_wait_event(STMFTS_EV_STATUS, STMFTS_EV_STATUS_SS_CX_TUNING_DONE, 2000))
|
||||
if (touch_wait_event(STMFTS_EV_STATUS, STMFTS_EV_STATUS_SS_CX_TUNING_DONE, 2000, NULL))
|
||||
return 0;
|
||||
|
||||
// Save Compensation data to EEPROM.
|
||||
if (touch_command(STMFTS_SAVE_CX_TUNING, NULL, 0))
|
||||
return 0;
|
||||
if (touch_wait_event(STMFTS_EV_STATUS, STMFTS_EV_STATUS_WRITE_CX_TUNE_DONE, 2000))
|
||||
if (touch_wait_event(STMFTS_EV_STATUS, STMFTS_EV_STATUS_WRITE_CX_TUNE_DONE, 2000, NULL))
|
||||
return 0;
|
||||
|
||||
return touch_sense_enable();
|
||||
@@ -358,12 +400,11 @@ static int touch_init()
|
||||
|
||||
int touch_power_on()
|
||||
{
|
||||
// Enables LDO6 for touchscreen VDD/AVDD supply
|
||||
max77620_regulator_set_volt_and_flags(REGULATOR_LDO6, 2900000, MAX77620_POWER_MODE_NORMAL);
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_LDO6_CFG2,
|
||||
MAX77620_LDO_CFG2_ADE_ENABLE | (3 << 3) | (MAX77620_POWER_MODE_NORMAL << MAX77620_LDO_POWER_MODE_SHIFT));
|
||||
// Enable LDO6 for touchscreen AVDD supply.
|
||||
max7762x_regulator_set_voltage(REGULATOR_LDO6, 2900000);
|
||||
max7762x_regulator_enable(REGULATOR_LDO6, true);
|
||||
|
||||
// Configure touchscreen GPIO.
|
||||
// Configure touchscreen VDD GPIO.
|
||||
PINMUX_AUX(PINMUX_AUX_DAP4_SCLK) = PINMUX_PULL_DOWN | 1;
|
||||
gpio_config(GPIO_PORT_J, GPIO_PIN_7, GPIO_MODE_GPIO);
|
||||
gpio_output_enable(GPIO_PORT_J, GPIO_PIN_7, GPIO_OUTPUT_ENABLE);
|
||||
@@ -377,7 +418,7 @@ int touch_power_on()
|
||||
// Configure Touscreen and GCAsic shared GPIO.
|
||||
PINMUX_AUX(PINMUX_AUX_CAM_I2C_SDA) = PINMUX_LPDR | PINMUX_INPUT_ENABLE | PINMUX_TRISTATE | PINMUX_PULL_UP | 2;
|
||||
PINMUX_AUX(PINMUX_AUX_CAM_I2C_SCL) = PINMUX_IO_HV | PINMUX_LPDR | PINMUX_TRISTATE | PINMUX_PULL_DOWN | 2;
|
||||
gpio_config(GPIO_PORT_S, GPIO_PIN_3, GPIO_MODE_GPIO);
|
||||
gpio_config(GPIO_PORT_S, GPIO_PIN_3, GPIO_MODE_GPIO); // GC detect.
|
||||
|
||||
// Initialize I2C3.
|
||||
pinmux_config_i2c(I2C_3);
|
||||
@@ -385,7 +426,7 @@ int touch_power_on()
|
||||
i2c_init(I2C_3);
|
||||
|
||||
// Wait for the touchscreen module to get ready.
|
||||
touch_wait_event(STMFTS_EV_CONTROLLER_READY, 0, 20);
|
||||
touch_wait_event(STMFTS_EV_CONTROLLER_READY, 0, 20, NULL);
|
||||
|
||||
// Check for forced boot time calibration.
|
||||
if (btn_read_vol() == (BTN_VOL_UP | BTN_VOL_DOWN))
|
||||
@@ -414,9 +455,7 @@ void touch_power_off()
|
||||
gpio_write(GPIO_PORT_J, GPIO_PIN_7, GPIO_LOW);
|
||||
|
||||
// Disables LDO6 for touchscreen VDD, AVDD supply
|
||||
max77620_regulator_enable(REGULATOR_LDO6, 0);
|
||||
i2c_send_byte(I2C_5, MAX77620_I2C_ADDR, MAX77620_REG_LDO6_CFG2,
|
||||
MAX77620_LDO_CFG2_ADE_ENABLE | (2 << 3) | (MAX77620_POWER_MODE_NORMAL << MAX77620_LDO_POWER_MODE_SHIFT));
|
||||
max7762x_regulator_enable(REGULATOR_LDO6, false);
|
||||
|
||||
clock_disable_i2c(I2C_3);
|
||||
}
|
||||
@@ -20,7 +20,7 @@
|
||||
#ifndef __TOUCH_H_
|
||||
#define __TOUCH_H_
|
||||
|
||||
#include "../utils/types.h"
|
||||
#include <utils/types.h>
|
||||
|
||||
#define STMFTS_I2C_ADDR 0x49
|
||||
|
||||
@@ -47,19 +47,26 @@
|
||||
#define STMFTS_ITO_CHECK 0xA7
|
||||
#define STMFTS_RELEASEINFO 0xAA
|
||||
#define STMFTS_WRITE_REG 0xB6
|
||||
#define STMFTS_AUTO_CALIBRATION 0xC3
|
||||
#define STMFTS_SWITCH_SENSE_MODE 0xC3
|
||||
#define STMFTS_NOISE_WRITE 0xC7
|
||||
#define STMFTS_NOISE_READ 0xC8
|
||||
#define STMFTS_RW_FRAMEBUFFER_REG 0xD0
|
||||
#define STMFTS_SAVE_CX_TUNING 0xFC
|
||||
|
||||
#define STMFTS_UNK0 0xB8 //Request compensation
|
||||
#define STMFTS_UNK1 0xCF
|
||||
#define STMFTS_UNK2 0xF7
|
||||
#define STMFTS_UNK3 0xFA
|
||||
#define STMFTS_UNK4 0xF9
|
||||
#define STMFTS_REQU_COMP_DATA 0xB8
|
||||
#define STMFTS_VENDOR 0xCF
|
||||
#define STMFTS_FLASH_UNLOCK 0xF7
|
||||
#define STMFTS_FLASH_WRITE_64K 0xF8
|
||||
#define STMFTS_FLASH_STATUS 0xF9
|
||||
#define STMFTS_FLASH_OP 0xFA
|
||||
#define STMFTS_UNK5 0x62
|
||||
|
||||
/* cmd parameters */
|
||||
#define STMFTS_VENDOR_GPIO_STATE 0x01
|
||||
#define STMFTS_VENDOR_SENSE_MODE 0x02
|
||||
#define STMFTS_STYLUS_MODE 0x00
|
||||
#define STMFTS_FINGER_MODE 0x01
|
||||
#define STMFTS_HOVER_MODE 0x02
|
||||
|
||||
/* events */
|
||||
#define STMFTS_EV_NO_EVENT 0x00
|
||||
@@ -74,6 +81,7 @@
|
||||
#define STMFTS_EV_ERROR 0x0f
|
||||
#define STMFTS_EV_NOISE_READ 0x17
|
||||
#define STMFTS_EV_NOISE_WRITE 0x18
|
||||
#define STMFTS_EV_VENDOR 0x20
|
||||
|
||||
#define STMFTS_EV_CONTROLLER_READY 0x10
|
||||
#define STMFTS_EV_STATUS 0x16
|
||||
@@ -131,6 +139,15 @@ typedef struct _touch_event {
|
||||
bool touch;
|
||||
} touch_event;
|
||||
|
||||
typedef struct _touch_panel_info_t
|
||||
{
|
||||
u8 idx;
|
||||
u8 gpio0;
|
||||
u8 gpio1;
|
||||
u8 gpio2;
|
||||
char *vendor;
|
||||
} touch_panel_info_t;
|
||||
|
||||
typedef struct _touch_info {
|
||||
u16 chip_id;
|
||||
u16 fw_ver;
|
||||
@@ -146,6 +163,7 @@ typedef struct _touch_fw_info_t {
|
||||
|
||||
void touch_poll(touch_event *event);
|
||||
touch_event touch_poll_wait();
|
||||
touch_panel_info_t *touch_get_panel_vendor();
|
||||
int touch_get_fw_info(touch_fw_info_t *fw);
|
||||
touch_info touch_get_info();
|
||||
int touch_panel_ito_test(u8 *err);
|
||||
@@ -17,7 +17,7 @@
|
||||
#ifndef _BLZ_H_
|
||||
#define _BLZ_H_
|
||||
|
||||
#include "../../utils/types.h"
|
||||
#include <utils/types.h>
|
||||
|
||||
typedef struct _blz_footer
|
||||
{
|
||||
@@ -125,7 +125,7 @@ static int _LZ_ReadVarSize( unsigned int * x, const unsigned char * buf )
|
||||
* insize - Number of input bytes.
|
||||
*************************************************************************/
|
||||
|
||||
void LZ_Uncompress( const unsigned char *in, unsigned char *out,
|
||||
unsigned int LZ_Uncompress( const unsigned char *in, unsigned char *out,
|
||||
unsigned int insize )
|
||||
{
|
||||
unsigned char marker, symbol;
|
||||
@@ -134,7 +134,7 @@ void LZ_Uncompress( const unsigned char *in, unsigned char *out,
|
||||
/* Do we have anything to uncompress? */
|
||||
if( insize < 1 )
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Get marker symbol from input stream */
|
||||
@@ -176,4 +176,6 @@ void LZ_Uncompress( const unsigned char *in, unsigned char *out,
|
||||
}
|
||||
}
|
||||
while( inpos < insize );
|
||||
|
||||
return outpos;
|
||||
}
|
||||
@@ -41,7 +41,7 @@ extern "C" {
|
||||
* Function prototypes
|
||||
*************************************************************************/
|
||||
|
||||
void LZ_Uncompress( const unsigned char *in, unsigned char *out,
|
||||
unsigned int LZ_Uncompress( const unsigned char *in, unsigned char *out,
|
||||
unsigned int insize );
|
||||
|
||||
|
||||
1681
bdk/libs/compr/lz4.c
Normal file
1681
bdk/libs/compr/lz4.c
Normal file
File diff suppressed because it is too large
Load Diff
569
bdk/libs/compr/lz4.h
Normal file
569
bdk/libs/compr/lz4.h
Normal file
@@ -0,0 +1,569 @@
|
||||
/*
|
||||
* LZ4 - Fast LZ compression algorithm
|
||||
* Header File
|
||||
* Copyright (C) 2011-2017, Yann Collet.
|
||||
|
||||
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
You can contact the author at :
|
||||
- LZ4 homepage : http://www.lz4.org
|
||||
- LZ4 source repository : https://github.com/lz4/lz4
|
||||
*/
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef LZ4_H_2983827168210
|
||||
#define LZ4_H_2983827168210
|
||||
|
||||
/* --- Dependency --- */
|
||||
#include <stddef.h> /* size_t */
|
||||
|
||||
|
||||
/**
|
||||
Introduction
|
||||
|
||||
LZ4 is lossless compression algorithm, providing compression speed at 400 MB/s per core,
|
||||
scalable with multi-cores CPU. It features an extremely fast decoder, with speed in
|
||||
multiple GB/s per core, typically reaching RAM speed limits on multi-core systems.
|
||||
|
||||
The LZ4 compression library provides in-memory compression and decompression functions.
|
||||
Compression can be done in:
|
||||
- a single step (described as Simple Functions)
|
||||
- a single step, reusing a context (described in Advanced Functions)
|
||||
- unbounded multiple steps (described as Streaming compression)
|
||||
|
||||
lz4.h provides block compression functions. It gives full buffer control to user.
|
||||
Decompressing an lz4-compressed block also requires metadata (such as compressed size).
|
||||
Each application is free to encode such metadata in whichever way it wants.
|
||||
|
||||
An additional format, called LZ4 frame specification (doc/lz4_Frame_format.md),
|
||||
take care of encoding standard metadata alongside LZ4-compressed blocks.
|
||||
If your application requires interoperability, it's recommended to use it.
|
||||
A library is provided to take care of it, see lz4frame.h.
|
||||
*/
|
||||
|
||||
/*^***************************************************************
|
||||
* Export parameters
|
||||
*****************************************************************/
|
||||
/*
|
||||
* LZ4_DLL_EXPORT :
|
||||
* Enable exporting of functions when building a Windows DLL
|
||||
* LZ4LIB_VISIBILITY :
|
||||
* Control library symbols visibility.
|
||||
*/
|
||||
#ifndef LZ4LIB_VISIBILITY
|
||||
# if defined(__GNUC__) && (__GNUC__ >= 4)
|
||||
# define LZ4LIB_VISIBILITY __attribute__ ((visibility ("default")))
|
||||
# else
|
||||
# define LZ4LIB_VISIBILITY
|
||||
# endif
|
||||
#endif
|
||||
#if defined(LZ4_DLL_EXPORT) && (LZ4_DLL_EXPORT==1)
|
||||
# define LZ4LIB_API __declspec(dllexport) LZ4LIB_VISIBILITY
|
||||
#elif defined(LZ4_DLL_IMPORT) && (LZ4_DLL_IMPORT==1)
|
||||
# define LZ4LIB_API __declspec(dllimport) LZ4LIB_VISIBILITY /* It isn't required but allows to generate better code, saving a function pointer load from the IAT and an indirect jump.*/
|
||||
#else
|
||||
# define LZ4LIB_API LZ4LIB_VISIBILITY
|
||||
#endif
|
||||
|
||||
/*------ Version ------*/
|
||||
#define LZ4_VERSION_MAJOR 1 /* for breaking interface changes */
|
||||
#define LZ4_VERSION_MINOR 8 /* for new (non-breaking) interface capabilities */
|
||||
#define LZ4_VERSION_RELEASE 2 /* for tweaks, bug-fixes, or development */
|
||||
|
||||
#define LZ4_VERSION_NUMBER (LZ4_VERSION_MAJOR *100*100 + LZ4_VERSION_MINOR *100 + LZ4_VERSION_RELEASE)
|
||||
|
||||
#define LZ4_LIB_VERSION LZ4_VERSION_MAJOR.LZ4_VERSION_MINOR.LZ4_VERSION_RELEASE
|
||||
#define LZ4_QUOTE(str) #str
|
||||
#define LZ4_EXPAND_AND_QUOTE(str) LZ4_QUOTE(str)
|
||||
#define LZ4_VERSION_STRING LZ4_EXPAND_AND_QUOTE(LZ4_LIB_VERSION)
|
||||
|
||||
LZ4LIB_API int LZ4_versionNumber (void); /**< library version number; useful to check dll version */
|
||||
LZ4LIB_API const char* LZ4_versionString (void); /**< library version string; unseful to check dll version */
|
||||
|
||||
|
||||
/*-************************************
|
||||
* Tuning parameter
|
||||
**************************************/
|
||||
/*!
|
||||
* LZ4_MEMORY_USAGE :
|
||||
* Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; etc.)
|
||||
* Increasing memory usage improves compression ratio
|
||||
* Reduced memory usage may improve speed, thanks to cache effect
|
||||
* Default value is 14, for 16KB, which nicely fits into Intel x86 L1 cache
|
||||
*/
|
||||
#ifndef LZ4_MEMORY_USAGE
|
||||
# define LZ4_MEMORY_USAGE 14
|
||||
#endif
|
||||
|
||||
/*-************************************
|
||||
* Simple Functions
|
||||
**************************************/
|
||||
/*! LZ4_compress_default() :
|
||||
Compresses 'srcSize' bytes from buffer 'src'
|
||||
into already allocated 'dst' buffer of size 'dstCapacity'.
|
||||
Compression is guaranteed to succeed if 'dstCapacity' >= LZ4_compressBound(srcSize).
|
||||
It also runs faster, so it's a recommended setting.
|
||||
If the function cannot compress 'src' into a more limited 'dst' budget,
|
||||
compression stops *immediately*, and the function result is zero.
|
||||
Note : as a consequence, 'dst' content is not valid.
|
||||
Note 2 : This function is protected against buffer overflow scenarios (never writes outside 'dst' buffer, nor read outside 'source' buffer).
|
||||
srcSize : max supported value is LZ4_MAX_INPUT_SIZE.
|
||||
dstCapacity : size of buffer 'dst' (which must be already allocated)
|
||||
return : the number of bytes written into buffer 'dst' (necessarily <= dstCapacity)
|
||||
or 0 if compression fails */
|
||||
LZ4LIB_API int LZ4_compress_default(const char* src, char* dst, int srcSize, int dstCapacity);
|
||||
|
||||
/*! LZ4_decompress_safe() :
|
||||
compressedSize : is the exact complete size of the compressed block.
|
||||
dstCapacity : is the size of destination buffer, which must be already allocated.
|
||||
return : the number of bytes decompressed into destination buffer (necessarily <= dstCapacity)
|
||||
If destination buffer is not large enough, decoding will stop and output an error code (negative value).
|
||||
If the source stream is detected malformed, the function will stop decoding and return a negative result.
|
||||
This function is protected against malicious data packets.
|
||||
*/
|
||||
LZ4LIB_API int LZ4_decompress_safe (const char* src, char* dst, int compressedSize, int dstCapacity);
|
||||
|
||||
|
||||
/*-************************************
|
||||
* Advanced Functions
|
||||
**************************************/
|
||||
#define LZ4_MAX_INPUT_SIZE 0x7E000000 /* 2 113 929 216 bytes */
|
||||
#define LZ4_COMPRESSBOUND(isize) ((unsigned)(isize) > (unsigned)LZ4_MAX_INPUT_SIZE ? 0 : (isize) + ((isize)/255) + 16)
|
||||
|
||||
/*!
|
||||
LZ4_compressBound() :
|
||||
Provides the maximum size that LZ4 compression may output in a "worst case" scenario (input data not compressible)
|
||||
This function is primarily useful for memory allocation purposes (destination buffer size).
|
||||
Macro LZ4_COMPRESSBOUND() is also provided for compilation-time evaluation (stack memory allocation for example).
|
||||
Note that LZ4_compress_default() compresses faster when dstCapacity is >= LZ4_compressBound(srcSize)
|
||||
inputSize : max supported value is LZ4_MAX_INPUT_SIZE
|
||||
return : maximum output size in a "worst case" scenario
|
||||
or 0, if input size is incorrect (too large or negative)
|
||||
*/
|
||||
LZ4LIB_API int LZ4_compressBound(int inputSize);
|
||||
|
||||
/*!
|
||||
LZ4_compress_fast() :
|
||||
Same as LZ4_compress_default(), but allows selection of "acceleration" factor.
|
||||
The larger the acceleration value, the faster the algorithm, but also the lesser the compression.
|
||||
It's a trade-off. It can be fine tuned, with each successive value providing roughly +~3% to speed.
|
||||
An acceleration value of "1" is the same as regular LZ4_compress_default()
|
||||
Values <= 0 will be replaced by ACCELERATION_DEFAULT (currently == 1, see lz4.c).
|
||||
*/
|
||||
LZ4LIB_API int LZ4_compress_fast (const char* src, char* dst, int srcSize, int dstCapacity, int acceleration);
|
||||
|
||||
|
||||
/*!
|
||||
LZ4_compress_fast_extState() :
|
||||
Same compression function, just using an externally allocated memory space to store compression state.
|
||||
Use LZ4_sizeofState() to know how much memory must be allocated,
|
||||
and allocate it on 8-bytes boundaries (using malloc() typically).
|
||||
Then, provide it as 'void* state' to compression function.
|
||||
*/
|
||||
LZ4LIB_API int LZ4_sizeofState(void);
|
||||
LZ4LIB_API int LZ4_compress_fast_extState (void* state, const char* src, char* dst, int srcSize, int dstCapacity, int acceleration);
|
||||
|
||||
|
||||
/*!
|
||||
LZ4_compress_destSize() :
|
||||
Reverse the logic : compresses as much data as possible from 'src' buffer
|
||||
into already allocated buffer 'dst' of size 'targetDestSize'.
|
||||
This function either compresses the entire 'src' content into 'dst' if it's large enough,
|
||||
or fill 'dst' buffer completely with as much data as possible from 'src'.
|
||||
*srcSizePtr : will be modified to indicate how many bytes where read from 'src' to fill 'dst'.
|
||||
New value is necessarily <= old value.
|
||||
return : Nb bytes written into 'dst' (necessarily <= targetDestSize)
|
||||
or 0 if compression fails
|
||||
*/
|
||||
LZ4LIB_API int LZ4_compress_destSize (const char* src, char* dst, int* srcSizePtr, int targetDstSize);
|
||||
|
||||
|
||||
/*!
|
||||
LZ4_decompress_fast() : **unsafe!**
|
||||
This function is a bit faster than LZ4_decompress_safe(),
|
||||
but doesn't provide any security guarantee.
|
||||
originalSize : is the uncompressed size to regenerate
|
||||
Destination buffer must be already allocated, and its size must be >= 'originalSize' bytes.
|
||||
return : number of bytes read from source buffer (== compressed size).
|
||||
If the source stream is detected malformed, the function stops decoding and return a negative result.
|
||||
note : This function respects memory boundaries for *properly formed* compressed data.
|
||||
However, it does not provide any protection against malicious input.
|
||||
It also doesn't know 'src' size, and implies it's >= compressed size.
|
||||
Use this function in trusted environment **only**.
|
||||
*/
|
||||
LZ4LIB_API int LZ4_decompress_fast (const char* src, char* dst, int originalSize);
|
||||
|
||||
/*!
|
||||
LZ4_decompress_safe_partial() :
|
||||
This function decompress a compressed block of size 'srcSize' at position 'src'
|
||||
into destination buffer 'dst' of size 'dstCapacity'.
|
||||
The function will decompress a minimum of 'targetOutputSize' bytes, and stop after that.
|
||||
However, it's not accurate, and may write more than 'targetOutputSize' (but always <= dstCapacity).
|
||||
@return : the number of bytes decoded in the destination buffer (necessarily <= dstCapacity)
|
||||
Note : this number can also be < targetOutputSize, if compressed block contains less data.
|
||||
Therefore, always control how many bytes were decoded.
|
||||
If source stream is detected malformed, function returns a negative result.
|
||||
This function is protected against malicious data packets.
|
||||
*/
|
||||
LZ4LIB_API int LZ4_decompress_safe_partial (const char* src, char* dst, int srcSize, int targetOutputSize, int dstCapacity);
|
||||
|
||||
|
||||
/*-*********************************************
|
||||
* Streaming Compression Functions
|
||||
***********************************************/
|
||||
typedef union LZ4_stream_u LZ4_stream_t; /* incomplete type (defined later) */
|
||||
|
||||
/*! LZ4_createStream() and LZ4_freeStream() :
|
||||
* LZ4_createStream() will allocate and initialize an `LZ4_stream_t` structure.
|
||||
* LZ4_freeStream() releases its memory.
|
||||
*/
|
||||
LZ4LIB_API LZ4_stream_t* LZ4_createStream(void);
|
||||
LZ4LIB_API int LZ4_freeStream (LZ4_stream_t* streamPtr);
|
||||
|
||||
/*! LZ4_resetStream() :
|
||||
* An LZ4_stream_t structure can be allocated once and re-used multiple times.
|
||||
* Use this function to start compressing a new stream.
|
||||
*/
|
||||
LZ4LIB_API void LZ4_resetStream (LZ4_stream_t* streamPtr);
|
||||
|
||||
/*! LZ4_loadDict() :
|
||||
* Use this function to load a static dictionary into LZ4_stream_t.
|
||||
* Any previous data will be forgotten, only 'dictionary' will remain in memory.
|
||||
* Loading a size of 0 is allowed, and is the same as reset.
|
||||
* @return : dictionary size, in bytes (necessarily <= 64 KB)
|
||||
*/
|
||||
LZ4LIB_API int LZ4_loadDict (LZ4_stream_t* streamPtr, const char* dictionary, int dictSize);
|
||||
|
||||
/*! LZ4_compress_fast_continue() :
|
||||
* Compress 'src' content using data from previously compressed blocks, for better compression ratio.
|
||||
* 'dst' buffer must be already allocated.
|
||||
* If dstCapacity >= LZ4_compressBound(srcSize), compression is guaranteed to succeed, and runs faster.
|
||||
*
|
||||
* Important : The previous 64KB of compressed data is assumed to remain present and unmodified in memory!
|
||||
*
|
||||
* Special 1 : When input is a double-buffer, they can have any size, including < 64 KB.
|
||||
* Make sure that buffers are separated by at least one byte.
|
||||
* This way, each block only depends on previous block.
|
||||
* Special 2 : If input buffer is a ring-buffer, it can have any size, including < 64 KB.
|
||||
*
|
||||
* @return : size of compressed block
|
||||
* or 0 if there is an error (typically, cannot fit into 'dst').
|
||||
* After an error, the stream status is invalid, it can only be reset or freed.
|
||||
*/
|
||||
LZ4LIB_API int LZ4_compress_fast_continue (LZ4_stream_t* streamPtr, const char* src, char* dst, int srcSize, int dstCapacity, int acceleration);
|
||||
|
||||
/*! LZ4_saveDict() :
|
||||
* If last 64KB data cannot be guaranteed to remain available at its current memory location,
|
||||
* save it into a safer place (char* safeBuffer).
|
||||
* This is schematically equivalent to a memcpy() followed by LZ4_loadDict(),
|
||||
* but is much faster, because LZ4_saveDict() doesn't need to rebuild tables.
|
||||
* @return : saved dictionary size in bytes (necessarily <= maxDictSize), or 0 if error.
|
||||
*/
|
||||
LZ4LIB_API int LZ4_saveDict (LZ4_stream_t* streamPtr, char* safeBuffer, int maxDictSize);
|
||||
|
||||
|
||||
/*-**********************************************
|
||||
* Streaming Decompression Functions
|
||||
* Bufferless synchronous API
|
||||
************************************************/
|
||||
typedef union LZ4_streamDecode_u LZ4_streamDecode_t; /* incomplete type (defined later) */
|
||||
|
||||
/*! LZ4_createStreamDecode() and LZ4_freeStreamDecode() :
|
||||
* creation / destruction of streaming decompression tracking structure.
|
||||
* A tracking structure can be re-used multiple times sequentially. */
|
||||
LZ4LIB_API LZ4_streamDecode_t* LZ4_createStreamDecode(void);
|
||||
LZ4LIB_API int LZ4_freeStreamDecode (LZ4_streamDecode_t* LZ4_stream);
|
||||
|
||||
/*! LZ4_setStreamDecode() :
|
||||
* An LZ4_streamDecode_t structure can be allocated once and re-used multiple times.
|
||||
* Use this function to start decompression of a new stream of blocks.
|
||||
* A dictionary can optionnally be set. Use NULL or size 0 for a reset order.
|
||||
* @return : 1 if OK, 0 if error
|
||||
*/
|
||||
LZ4LIB_API int LZ4_setStreamDecode (LZ4_streamDecode_t* LZ4_streamDecode, const char* dictionary, int dictSize);
|
||||
|
||||
/*! LZ4_decompress_*_continue() :
|
||||
* These decoding functions allow decompression of consecutive blocks in "streaming" mode.
|
||||
* A block is an unsplittable entity, it must be presented entirely to a decompression function.
|
||||
* Decompression functions only accept one block at a time.
|
||||
* The last 64KB of previously decoded data *must* remain available and unmodified at the memory position where they were decoded.
|
||||
* If less than 64KB of data has been decoded all the data must be present.
|
||||
*
|
||||
* Special : if application sets a ring buffer for decompression, it must respect one of the following conditions :
|
||||
* - Exactly same size as encoding buffer, with same update rule (block boundaries at same positions)
|
||||
* In which case, the decoding & encoding ring buffer can have any size, including very small ones ( < 64 KB).
|
||||
* - Larger than encoding buffer, by a minimum of maxBlockSize more bytes.
|
||||
* maxBlockSize is implementation dependent. It's the maximum size of any single block.
|
||||
* In which case, encoding and decoding buffers do not need to be synchronized,
|
||||
* and encoding ring buffer can have any size, including small ones ( < 64 KB).
|
||||
* - _At least_ 64 KB + 8 bytes + maxBlockSize.
|
||||
* In which case, encoding and decoding buffers do not need to be synchronized,
|
||||
* and encoding ring buffer can have any size, including larger than decoding buffer.
|
||||
* Whenever these conditions are not possible, save the last 64KB of decoded data into a safe buffer,
|
||||
* and indicate where it is saved using LZ4_setStreamDecode() before decompressing next block.
|
||||
*/
|
||||
LZ4LIB_API int LZ4_decompress_safe_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* src, char* dst, int srcSize, int dstCapacity);
|
||||
LZ4LIB_API int LZ4_decompress_fast_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* src, char* dst, int originalSize);
|
||||
|
||||
|
||||
/*! LZ4_decompress_*_usingDict() :
|
||||
* These decoding functions work the same as
|
||||
* a combination of LZ4_setStreamDecode() followed by LZ4_decompress_*_continue()
|
||||
* They are stand-alone, and don't need an LZ4_streamDecode_t structure.
|
||||
*/
|
||||
LZ4LIB_API int LZ4_decompress_safe_usingDict (const char* src, char* dst, int srcSize, int dstCapcity, const char* dictStart, int dictSize);
|
||||
LZ4LIB_API int LZ4_decompress_fast_usingDict (const char* src, char* dst, int originalSize, const char* dictStart, int dictSize);
|
||||
|
||||
|
||||
/*^**********************************************
|
||||
* !!!!!! STATIC LINKING ONLY !!!!!!
|
||||
***********************************************/
|
||||
|
||||
/*-************************************
|
||||
* Unstable declarations
|
||||
**************************************
|
||||
* Declarations in this section should be considered unstable.
|
||||
* Use at your own peril, etc., etc.
|
||||
* They may be removed in the future.
|
||||
* Their signatures may change.
|
||||
**************************************/
|
||||
|
||||
#ifdef LZ4_STATIC_LINKING_ONLY
|
||||
|
||||
/*! LZ4_resetStream_fast() :
|
||||
* When an LZ4_stream_t is known to be in a internally coherent state,
|
||||
* it can often be prepared for a new compression with almost no work, only
|
||||
* sometimes falling back to the full, expensive reset that is always required
|
||||
* when the stream is in an indeterminate state (i.e., the reset performed by
|
||||
* LZ4_resetStream()).
|
||||
*
|
||||
* LZ4_streams are guaranteed to be in a valid state when:
|
||||
* - returned from LZ4_createStream()
|
||||
* - reset by LZ4_resetStream()
|
||||
* - memset(stream, 0, sizeof(LZ4_stream_t))
|
||||
* - the stream was in a valid state and was reset by LZ4_resetStream_fast()
|
||||
* - the stream was in a valid state and was then used in any compression call
|
||||
* that returned success
|
||||
* - the stream was in an indeterminate state and was used in a compression
|
||||
* call that fully reset the state (LZ4_compress_fast_extState()) and that
|
||||
* returned success
|
||||
*/
|
||||
LZ4LIB_API void LZ4_resetStream_fast (LZ4_stream_t* streamPtr);
|
||||
|
||||
/*! LZ4_compress_fast_extState_fastReset() :
|
||||
* A variant of LZ4_compress_fast_extState().
|
||||
*
|
||||
* Using this variant avoids an expensive initialization step. It is only safe
|
||||
* to call if the state buffer is known to be correctly initialized already
|
||||
* (see above comment on LZ4_resetStream_fast() for a definition of "correctly
|
||||
* initialized"). From a high level, the difference is that this function
|
||||
* initializes the provided state with a call to LZ4_resetStream_fast() while
|
||||
* LZ4_compress_fast_extState() starts with a call to LZ4_resetStream().
|
||||
*/
|
||||
LZ4LIB_API int LZ4_compress_fast_extState_fastReset (void* state, const char* src, char* dst, int srcSize, int dstCapacity, int acceleration);
|
||||
|
||||
/*! LZ4_attach_dictionary() :
|
||||
* This is an experimental API that allows for the efficient use of a
|
||||
* static dictionary many times.
|
||||
*
|
||||
* Rather than re-loading the dictionary buffer into a working context before
|
||||
* each compression, or copying a pre-loaded dictionary's LZ4_stream_t into a
|
||||
* working LZ4_stream_t, this function introduces a no-copy setup mechanism,
|
||||
* in which the working stream references the dictionary stream in-place.
|
||||
*
|
||||
* Several assumptions are made about the state of the dictionary stream.
|
||||
* Currently, only streams which have been prepared by LZ4_loadDict() should
|
||||
* be expected to work.
|
||||
*
|
||||
* Alternatively, the provided dictionary stream pointer may be NULL, in which
|
||||
* case any existing dictionary stream is unset.
|
||||
*
|
||||
* If a dictionary is provided, it replaces any pre-existing stream history.
|
||||
* The dictionary contents are the only history that can be referenced and
|
||||
* logically immediately precede the data compressed in the first subsequent
|
||||
* compression call.
|
||||
*
|
||||
* The dictionary will only remain attached to the working stream through the
|
||||
* first compression call, at the end of which it is cleared. The dictionary
|
||||
* stream (and source buffer) must remain in-place / accessible / unchanged
|
||||
* through the completion of the first compression call on the stream.
|
||||
*/
|
||||
LZ4LIB_API void LZ4_attach_dictionary(LZ4_stream_t *working_stream, const LZ4_stream_t *dictionary_stream);
|
||||
|
||||
#endif
|
||||
|
||||
/*-************************************
|
||||
* Private definitions
|
||||
**************************************
|
||||
* Do not use these definitions.
|
||||
* They are exposed to allow static allocation of `LZ4_stream_t` and `LZ4_streamDecode_t`.
|
||||
* Using these definitions will expose code to API and/or ABI break in future versions of the library.
|
||||
**************************************/
|
||||
#define LZ4_HASHLOG (LZ4_MEMORY_USAGE-2)
|
||||
#define LZ4_HASHTABLESIZE (1 << LZ4_MEMORY_USAGE)
|
||||
#define LZ4_HASH_SIZE_U32 (1 << LZ4_HASHLOG) /* required as macro for static allocation */
|
||||
|
||||
#if defined(__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct LZ4_stream_t_internal LZ4_stream_t_internal;
|
||||
struct LZ4_stream_t_internal {
|
||||
uint32_t hashTable[LZ4_HASH_SIZE_U32];
|
||||
uint32_t currentOffset;
|
||||
uint16_t initCheck;
|
||||
uint16_t tableType;
|
||||
const uint8_t* dictionary;
|
||||
const LZ4_stream_t_internal* dictCtx;
|
||||
uint32_t dictSize;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
const uint8_t* externalDict;
|
||||
size_t extDictSize;
|
||||
const uint8_t* prefixEnd;
|
||||
size_t prefixSize;
|
||||
} LZ4_streamDecode_t_internal;
|
||||
|
||||
#else
|
||||
|
||||
typedef struct LZ4_stream_t_internal LZ4_stream_t_internal;
|
||||
struct LZ4_stream_t_internal {
|
||||
unsigned int hashTable[LZ4_HASH_SIZE_U32];
|
||||
unsigned int currentOffset;
|
||||
unsigned short initCheck;
|
||||
unsigned short tableType;
|
||||
const unsigned char* dictionary;
|
||||
const LZ4_stream_t_internal* dictCtx;
|
||||
unsigned int dictSize;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
const unsigned char* externalDict;
|
||||
size_t extDictSize;
|
||||
const unsigned char* prefixEnd;
|
||||
size_t prefixSize;
|
||||
} LZ4_streamDecode_t_internal;
|
||||
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* LZ4_stream_t :
|
||||
* information structure to track an LZ4 stream.
|
||||
* init this structure before first use.
|
||||
* note : only use in association with static linking !
|
||||
* this definition is not API/ABI safe,
|
||||
* it may change in a future version !
|
||||
*/
|
||||
#define LZ4_STREAMSIZE_U64 ((1 << (LZ4_MEMORY_USAGE-3)) + 4)
|
||||
#define LZ4_STREAMSIZE (LZ4_STREAMSIZE_U64 * sizeof(unsigned long long))
|
||||
union LZ4_stream_u {
|
||||
unsigned long long table[LZ4_STREAMSIZE_U64];
|
||||
LZ4_stream_t_internal internal_donotuse;
|
||||
} ; /* previously typedef'd to LZ4_stream_t */
|
||||
|
||||
|
||||
/*!
|
||||
* LZ4_streamDecode_t :
|
||||
* information structure to track an LZ4 stream during decompression.
|
||||
* init this structure using LZ4_setStreamDecode (or memset()) before first use
|
||||
* note : only use in association with static linking !
|
||||
* this definition is not API/ABI safe,
|
||||
* and may change in a future version !
|
||||
*/
|
||||
#define LZ4_STREAMDECODESIZE_U64 4
|
||||
#define LZ4_STREAMDECODESIZE (LZ4_STREAMDECODESIZE_U64 * sizeof(unsigned long long))
|
||||
union LZ4_streamDecode_u {
|
||||
unsigned long long table[LZ4_STREAMDECODESIZE_U64];
|
||||
LZ4_streamDecode_t_internal internal_donotuse;
|
||||
} ; /* previously typedef'd to LZ4_streamDecode_t */
|
||||
|
||||
|
||||
/*-************************************
|
||||
* Obsolete Functions
|
||||
**************************************/
|
||||
|
||||
/*! Deprecation warnings
|
||||
Should deprecation warnings be a problem,
|
||||
it is generally possible to disable them,
|
||||
typically with -Wno-deprecated-declarations for gcc
|
||||
or _CRT_SECURE_NO_WARNINGS in Visual.
|
||||
Otherwise, it's also possible to define LZ4_DISABLE_DEPRECATE_WARNINGS */
|
||||
#ifdef LZ4_DISABLE_DEPRECATE_WARNINGS
|
||||
# define LZ4_DEPRECATED(message) /* disable deprecation warnings */
|
||||
#else
|
||||
# define LZ4_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
|
||||
# if defined (__cplusplus) && (__cplusplus >= 201402) /* C++14 or greater */
|
||||
# define LZ4_DEPRECATED(message) [[deprecated(message)]]
|
||||
# elif (LZ4_GCC_VERSION >= 405) || defined(__clang__)
|
||||
# define LZ4_DEPRECATED(message) __attribute__((deprecated(message)))
|
||||
# elif (LZ4_GCC_VERSION >= 301)
|
||||
# define LZ4_DEPRECATED(message) __attribute__((deprecated))
|
||||
# elif defined(_MSC_VER)
|
||||
# define LZ4_DEPRECATED(message) __declspec(deprecated(message))
|
||||
# else
|
||||
# pragma message("WARNING: You need to implement LZ4_DEPRECATED for this compiler")
|
||||
# define LZ4_DEPRECATED(message)
|
||||
# endif
|
||||
#endif /* LZ4_DISABLE_DEPRECATE_WARNINGS */
|
||||
|
||||
/* Obsolete compression functions */
|
||||
LZ4_DEPRECATED("use LZ4_compress_default() instead") LZ4LIB_API int LZ4_compress (const char* source, char* dest, int sourceSize);
|
||||
LZ4_DEPRECATED("use LZ4_compress_default() instead") LZ4LIB_API int LZ4_compress_limitedOutput (const char* source, char* dest, int sourceSize, int maxOutputSize);
|
||||
LZ4_DEPRECATED("use LZ4_compress_fast_extState() instead") LZ4LIB_API int LZ4_compress_withState (void* state, const char* source, char* dest, int inputSize);
|
||||
LZ4_DEPRECATED("use LZ4_compress_fast_extState() instead") LZ4LIB_API int LZ4_compress_limitedOutput_withState (void* state, const char* source, char* dest, int inputSize, int maxOutputSize);
|
||||
LZ4_DEPRECATED("use LZ4_compress_fast_continue() instead") LZ4LIB_API int LZ4_compress_continue (LZ4_stream_t* LZ4_streamPtr, const char* source, char* dest, int inputSize);
|
||||
LZ4_DEPRECATED("use LZ4_compress_fast_continue() instead") LZ4LIB_API int LZ4_compress_limitedOutput_continue (LZ4_stream_t* LZ4_streamPtr, const char* source, char* dest, int inputSize, int maxOutputSize);
|
||||
|
||||
/* Obsolete decompression functions */
|
||||
LZ4_DEPRECATED("use LZ4_decompress_fast() instead") LZ4LIB_API int LZ4_uncompress (const char* source, char* dest, int outputSize);
|
||||
LZ4_DEPRECATED("use LZ4_decompress_safe() instead") LZ4LIB_API int LZ4_uncompress_unknownOutputSize (const char* source, char* dest, int isize, int maxOutputSize);
|
||||
|
||||
/* Obsolete streaming functions; degraded functionality; do not use!
|
||||
*
|
||||
* In order to perform streaming compression, these functions depended on data
|
||||
* that is no longer tracked in the state. They have been preserved as well as
|
||||
* possible: using them will still produce a correct output. However, they don't
|
||||
* actually retain any history between compression calls. The compression ratio
|
||||
* achieved will therefore be no better than compressing each chunk
|
||||
* independently.
|
||||
*/
|
||||
LZ4_DEPRECATED("Use LZ4_createStream() instead") LZ4LIB_API void* LZ4_create (char* inputBuffer);
|
||||
LZ4_DEPRECATED("Use LZ4_createStream() instead") LZ4LIB_API int LZ4_sizeofStreamState(void);
|
||||
LZ4_DEPRECATED("Use LZ4_resetStream() instead") LZ4LIB_API int LZ4_resetStreamState(void* state, char* inputBuffer);
|
||||
LZ4_DEPRECATED("Use LZ4_saveDict() instead") LZ4LIB_API char* LZ4_slideInputBuffer (void* state);
|
||||
|
||||
/* Obsolete streaming decoding functions */
|
||||
LZ4_DEPRECATED("use LZ4_decompress_safe_usingDict() instead") LZ4LIB_API int LZ4_decompress_safe_withPrefix64k (const char* src, char* dst, int compressedSize, int maxDstSize);
|
||||
LZ4_DEPRECATED("use LZ4_decompress_fast_usingDict() instead") LZ4LIB_API int LZ4_decompress_fast_withPrefix64k (const char* src, char* dst, int originalSize);
|
||||
|
||||
#endif /* LZ4_H_2983827168210 */
|
||||
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
@@ -9,7 +9,7 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "../../utils/types.h"
|
||||
#include <utils/types.h>
|
||||
|
||||
/* Status of Disk Functions */
|
||||
typedef BYTE DSTATUS;
|
||||
@@ -27,7 +27,8 @@ typedef enum {
|
||||
DRIVE_SD = 0,
|
||||
DRIVE_RAM = 1,
|
||||
DRIVE_EMMC = 2,
|
||||
DRIVE_BIS = 3
|
||||
DRIVE_BIS = 3,
|
||||
DRIVE_EMU = 4
|
||||
} DDRIVE;
|
||||
|
||||
|
||||
@@ -59,6 +60,7 @@ DRESULT disk_set_info (BYTE pdrv, BYTE cmd, void *buff);
|
||||
#define GET_SECTOR_SIZE 2 /* Get sector size (needed at FF_MAX_SS != FF_MIN_SS) */
|
||||
#define GET_BLOCK_SIZE 3 /* Get erase block size (needed at FF_USE_MKFS == 1) */
|
||||
#define CTRL_TRIM 4 /* Inform device that the data on the block of sectors is no longer used (needed at FF_USE_TRIM == 1) */
|
||||
#define SET_SECTOR_OFFSET 5 /* Set media logical offset */
|
||||
|
||||
/* Generic command (Not used by FatFs) */
|
||||
#define CTRL_POWER 5 /* Get/Set power status */
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2018 naehrwert
|
||||
* Copyright (c) 2018-2019 CTCaer
|
||||
* Copyright (c) 2018-2021 CTCaer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
@@ -38,7 +38,8 @@
|
||||
|
||||
#include "ff.h" /* Declarations of FatFs API */
|
||||
#include "diskio.h" /* Declarations of device I/O functions */
|
||||
#include "../../gfx/gfx.h"
|
||||
#include <storage/mbr_gpt.h>
|
||||
#include <gfx_utils.h>
|
||||
|
||||
#define EFSPRINTF(text, ...) print_error(); gfx_printf("%k"text"%k\n", 0xFFFFFF00, 0xFFFFFFFF);
|
||||
//#define EFSPRINTF(...)
|
||||
@@ -3284,6 +3285,7 @@ static FRESULT find_volume ( /* FR_OK(0): successful, !=0: an error occurred */
|
||||
/* Following code attempts to mount the volume. (analyze BPB and initialize the filesystem object) */
|
||||
|
||||
fs->fs_type = 0; /* Clear the filesystem object */
|
||||
fs->part_type = 0; /* Clear the Partition object */
|
||||
fs->pdrv = LD2PD(vol); /* Bind the logical drive and a physical drive */
|
||||
stat = disk_initialize(fs->pdrv); /* Initialize the physical drive */
|
||||
if (stat & STA_NOINIT) { /* Check if the initialization succeeded */
|
||||
@@ -3318,6 +3320,20 @@ static FRESULT find_volume ( /* FR_OK(0): successful, !=0: an error occurred */
|
||||
EFSPRINTF("BRNL");
|
||||
return FR_DISK_ERR; /* An error occured in the disk I/O layer */
|
||||
}
|
||||
#if FF_SIMPLE_GPT
|
||||
if (fmt >= 2) {
|
||||
/* If GPT Check the first partition */
|
||||
gpt_header_t *gpt_header = (gpt_header_t *)fs->win;
|
||||
if (move_window(fs, 1) != FR_OK) return FR_DISK_ERR;
|
||||
if (!mem_cmp(&gpt_header->signature, "EFI PART", 8)) {
|
||||
if (move_window(fs, gpt_header->part_ent_lba) != FR_OK) return FR_DISK_ERR;
|
||||
gpt_entry_t *gpt_entry = (gpt_entry_t *)fs->win;
|
||||
fs->part_type = 1;
|
||||
bsect = gpt_entry->lba_start;
|
||||
fmt = bsect ? check_fs(fs, bsect) : 3; /* Check the partition */
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (fmt >= 2) {
|
||||
EFSPRINTF("NOFAT");
|
||||
return FR_NO_FILESYSTEM; /* No FAT volume is found */
|
||||
@@ -3906,11 +3922,11 @@ FRESULT f_read (
|
||||
|
||||
|
||||
|
||||
#ifdef FF_FASTFS
|
||||
#if FF_FASTFS && FF_USE_FASTSEEK
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Fast Read Aligned Sized File Without a Cache */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
#if FF_USE_FASTSEEK
|
||||
|
||||
FRESULT f_read_fast (
|
||||
FIL* fp, /* Pointer to the file object */
|
||||
const void* buff, /* Pointer to the data to be written */
|
||||
@@ -3988,7 +4004,6 @@ FRESULT f_read_fast (
|
||||
LEAVE_FF(fs, FR_OK);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -4132,11 +4147,11 @@ FRESULT f_write (
|
||||
|
||||
|
||||
|
||||
#ifdef FF_FASTFS
|
||||
#if FF_FASTFS && FF_USE_FASTSEEK
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Fast Write Aligned Sized File Without a Cache */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
#if FF_USE_FASTSEEK
|
||||
|
||||
FRESULT f_write_fast (
|
||||
FIL* fp, /* Pointer to the file object */
|
||||
const void* buff, /* Pointer to the data to be written */
|
||||
@@ -4219,7 +4234,6 @@ FRESULT f_write_fast (
|
||||
LEAVE_FF(fs, FR_OK);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -4680,8 +4694,7 @@ FRESULT f_lseek (
|
||||
|
||||
|
||||
|
||||
#ifdef FF_FASTFS
|
||||
#if FF_USE_FASTSEEK
|
||||
#if FF_FASTFS && FF_USE_FASTSEEK
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Seek File Read/Write Pointer */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
@@ -4708,7 +4721,6 @@ DWORD *f_expand_cltbl (
|
||||
return fp->cltbl;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -5842,7 +5854,7 @@ FRESULT f_mkfs (
|
||||
UINT len /* Size of working buffer [byte] */
|
||||
)
|
||||
{
|
||||
const UINT n_fats = 1; /* Number of FATs for FAT/FAT32 volume (1 or 2) */
|
||||
const UINT n_fats = 2; /* Number of FATs for FAT/FAT32 volume (1 or 2) */
|
||||
const UINT n_rootdir = 512; /* Number of root directory entries for FAT volume */
|
||||
static const WORD cst[] = {1, 4, 16, 64, 256, 512, 0}; /* Cluster size boundary for FAT volume (4Ks unit) */
|
||||
static const WORD cst32[] = {1, 2, 4, 8, 16, 32, 0}; /* Cluster size boundary for FAT32 volume (128Ks unit) */
|
||||
@@ -6130,6 +6142,9 @@ FRESULT f_mkfs (
|
||||
if (fmt == FS_FAT32) { /* FAT32: Move FAT base */
|
||||
sz_rsv += n; b_fat += n;
|
||||
} else { /* FAT: Expand FAT size */
|
||||
if (n % n_fats) { /* Adjust fractional error if needed */
|
||||
n--; sz_rsv++; b_fat++;
|
||||
}
|
||||
sz_fat += n / n_fats;
|
||||
}
|
||||
|
||||
@@ -6170,7 +6185,9 @@ FRESULT f_mkfs (
|
||||
#endif
|
||||
/* Create FAT VBR */
|
||||
mem_set(buf, 0, ss);
|
||||
mem_cpy(buf + BS_JmpBoot, "\xEB\xFE\x90" "MSDOS5.0", 11);/* Boot jump code (x86), OEM name */
|
||||
/* Boot jump code (x86), OEM name */
|
||||
if (!(opt & FM_PRF2)) mem_cpy(buf + BS_JmpBoot, "\xEB\xFE\x90" "NYX1.0.0", 11);
|
||||
else mem_cpy(buf + BS_JmpBoot, "\xEB\xE9\x90\x00\x00\x00\x00\x00\x00\x00\x00", 11);
|
||||
st_word(buf + BPB_BytsPerSec, ss); /* Sector size [byte] */
|
||||
buf[BPB_SecPerClus] = (BYTE)pau; /* Cluster size [sector] */
|
||||
st_word(buf + BPB_RsvdSecCnt, (WORD)sz_rsv); /* Size of reserved area */
|
||||
@@ -6183,23 +6200,27 @@ FRESULT f_mkfs (
|
||||
}
|
||||
buf[BPB_Media] = 0xF8; /* Media descriptor byte */
|
||||
st_word(buf + BPB_SecPerTrk, 63); /* Number of sectors per track (for int13) */
|
||||
st_word(buf + BPB_NumHeads, 255); /* Number of heads (for int13) */
|
||||
st_word(buf + BPB_NumHeads, (opt & FM_PRF2) ? 16 : 255); /* Number of heads (for int13) */
|
||||
st_dword(buf + BPB_HiddSec, b_vol); /* Volume offset in the physical drive [sector] */
|
||||
if (fmt == FS_FAT32) {
|
||||
st_dword(buf + BS_VolID32, GET_FATTIME()); /* VSN */
|
||||
st_dword(buf + BS_VolID32, (opt & FM_PRF2) ? 0 : GET_FATTIME()); /* VSN */
|
||||
st_dword(buf + BPB_FATSz32, sz_fat); /* FAT size [sector] */
|
||||
st_dword(buf + BPB_RootClus32, 2); /* Root directory cluster # (2) */
|
||||
st_word(buf + BPB_FSInfo32, 1); /* Offset of FSINFO sector (VBR + 1) */
|
||||
st_word(buf + BPB_BkBootSec32, 6); /* Offset of backup VBR (VBR + 6) */
|
||||
buf[BS_DrvNum32] = 0x80; /* Drive number (for int13) */
|
||||
buf[BS_BootSig32] = 0x29; /* Extended boot signature */
|
||||
mem_cpy(buf + BS_VolLab32, "SWITCH SD " "FAT32 ", 19); /* Volume label, FAT signature */
|
||||
/* Volume label, FAT signature */
|
||||
if (!(opt & FM_PRF2)) mem_cpy(buf + BS_VolLab32, FF_MKFS_LABEL "FAT32 ", 19);
|
||||
else mem_cpy(buf + BS_VolLab32, "NO NAME " "FAT32 ", 19);
|
||||
} else {
|
||||
st_dword(buf + BS_VolID, GET_FATTIME()); /* VSN */
|
||||
st_word(buf + BPB_FATSz16, (WORD)sz_fat); /* FAT size [sector] */
|
||||
buf[BS_DrvNum] = 0x80; /* Drive number (for int13) */
|
||||
buf[BS_BootSig] = 0x29; /* Extended boot signature */
|
||||
mem_cpy(buf + BS_VolLab, "SWITCH SD " "FAT ", 19); /* Volume label, FAT signature */
|
||||
/* Volume label, FAT signature */
|
||||
if (!(opt & FM_PRF2)) mem_cpy(buf + BS_VolLab, FF_MKFS_LABEL "FAT ", 19);
|
||||
else mem_cpy(buf + BS_VolLab, "NO NAME " "FAT ", 19);
|
||||
}
|
||||
st_word(buf + BS_55AA, 0xAA55); /* Signature (offset is fixed here regardless of sector size) */
|
||||
if (disk_write(pdrv, buf, b_vol, 1) != RES_OK) LEAVE_MKFS(FR_DISK_ERR); /* Write it to the VBR sector */
|
||||
@@ -6217,6 +6238,16 @@ FRESULT f_mkfs (
|
||||
disk_write(pdrv, buf, b_vol + 1, 1); /* Write original FSINFO (VBR + 1) */
|
||||
}
|
||||
|
||||
/* Create PRF2SAFE info */
|
||||
if (fmt == FS_FAT32 && opt & FM_PRF2) {
|
||||
mem_set(buf, 0, ss);
|
||||
buf[16] = 0x64; /* Record type */
|
||||
st_dword(buf + 32, 0x03); /* Unknown. SYSTEM: 0x3F00. USER: 0x03. Volatile. */
|
||||
st_dword(buf + 36, 25); /* Entries. SYSTEM: 22. USER: 25.Static? */
|
||||
st_dword(buf + 508, 0x517BBFE0); /* Custom CRC32. SYSTEM: 0x6B673904. USER: 0x517BBFE0. */
|
||||
disk_write(pdrv, buf, b_vol + 3, 1); /* Write PRF2SAFE info (VBR + 3) */
|
||||
}
|
||||
|
||||
/* Initialize FAT area */
|
||||
mem_set(buf, 0, (UINT)szb_buf);
|
||||
sect = b_fat; /* FAT start sector */
|
||||
@@ -26,8 +26,8 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "../../utils/types.h" /* Basic integer types */
|
||||
#include "ffconf.h" /* FatFs configuration options */
|
||||
#include <utils/types.h> /* Basic integer types */
|
||||
#include <fatfs_cfg.h> /* FatFs configuration options */
|
||||
|
||||
#if FF_DEFINED != FFCONF_DEF
|
||||
#error Wrong configuration file (ffconf.h).
|
||||
@@ -95,8 +95,8 @@ typedef DWORD FSIZE_t;
|
||||
/* Filesystem object structure (FATFS) */
|
||||
|
||||
typedef struct {
|
||||
BYTE win[FF_MAX_SS]; /* Disk access window for Directory, FAT (and file data at tiny cfg) */
|
||||
BYTE fs_type; /* Filesystem type (0:not mounted) */
|
||||
BYTE part_type; /* Partition type (0:MBR, 1:GPT) */
|
||||
BYTE pdrv; /* Associated physical drive */
|
||||
BYTE n_fats; /* Number of FATs (1 or 2) */
|
||||
BYTE wflag; /* win[] flag (b0:dirty) */
|
||||
@@ -138,6 +138,7 @@ typedef struct {
|
||||
DWORD bitbase; /* Allocation bitmap base sector */
|
||||
#endif
|
||||
DWORD winsect; /* Current sector appearing in the win[] */
|
||||
BYTE win[FF_MAX_SS] __attribute__((aligned(8))); /* Disk access window for Directory, FAT (and file data at tiny cfg). DMA aligned. */
|
||||
} FATFS;
|
||||
|
||||
|
||||
@@ -168,9 +169,6 @@ typedef struct {
|
||||
/* File object structure (FIL) */
|
||||
|
||||
typedef struct {
|
||||
#if !FF_FS_TINY
|
||||
BYTE buf[FF_MAX_SS]; /* File private data read/write window */
|
||||
#endif
|
||||
FFOBJID obj; /* Object identifier (must be the 1st member to detect invalid object pointer) */
|
||||
BYTE flag; /* File status flags */
|
||||
BYTE err; /* Abort flag (error code) */
|
||||
@@ -184,6 +182,9 @@ typedef struct {
|
||||
#if FF_USE_FASTSEEK
|
||||
DWORD* cltbl; /* Pointer to the cluster link map table (nulled on open, set by application) */
|
||||
#endif
|
||||
#if !FF_FS_TINY
|
||||
BYTE buf[FF_MAX_SS] __attribute__((aligned(8))); /* File private data read/write window. DMA aligned. */
|
||||
#endif
|
||||
} FIL;
|
||||
|
||||
|
||||
@@ -246,7 +247,7 @@ typedef enum {
|
||||
FR_LOCKED, /* (16) The operation is rejected according to the file sharing policy */
|
||||
FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */
|
||||
FR_TOO_MANY_OPEN_FILES, /* (18) Number of open files > FF_FS_LOCK */
|
||||
#ifdef FF_FASTFS
|
||||
#if FF_FASTFS
|
||||
FR_INVALID_PARAMETER, /* (19) Given parameter is invalid */
|
||||
FR_CLTBL_NO_INIT /* (20) The cluster table for fast seek/read/write was not created */
|
||||
#else
|
||||
@@ -263,10 +264,8 @@ FRESULT f_open (FIL* fp, const TCHAR* path, BYTE mode); /* Open or create a f
|
||||
FRESULT f_close (FIL* fp); /* Close an open file object */
|
||||
FRESULT f_read (FIL* fp, void* buff, UINT btr, UINT* br); /* Read data from the file */
|
||||
FRESULT f_write (FIL* fp, const void* buff, UINT btw, UINT* bw); /* Write data to the file */
|
||||
#ifdef FF_FASTFS
|
||||
FRESULT f_read_fast (FIL* fp, const void* buff, UINT btr); /* Fast read data from the file */
|
||||
FRESULT f_write_fast (FIL* fp, const void* buff, UINT btw); /* Fast write data to the file */
|
||||
#endif
|
||||
FRESULT f_lseek (FIL* fp, FSIZE_t ofs); /* Move file pointer of the file object */
|
||||
FRESULT f_truncate (FIL* fp); /* Truncate the file */
|
||||
FRESULT f_sync (FIL* fp); /* Flush cached data of the writing file */
|
||||
@@ -288,9 +287,7 @@ FRESULT f_getfree (const TCHAR* path, DWORD* nclst, FATFS** fatfs); /* Get numbe
|
||||
FRESULT f_getlabel (const TCHAR* path, TCHAR* label, DWORD* vsn); /* Get volume label */
|
||||
FRESULT f_setlabel (const TCHAR* label); /* Set volume label */
|
||||
FRESULT f_forward (FIL* fp, UINT(*func)(const BYTE*,UINT), UINT btf, UINT* bf); /* Forward data to the stream */
|
||||
#ifdef FF_FASTFS
|
||||
DWORD *f_expand_cltbl (FIL* fp, UINT tblsz, FSIZE_t ofs); /* Expand file and populate cluster table */
|
||||
#endif
|
||||
FRESULT f_expand (FIL* fp, FSIZE_t fsz, BYTE opt); /* Allocate a contiguous block to the file */
|
||||
FRESULT f_mount (FATFS* fs, const TCHAR* path, BYTE opt); /* Mount/Unmount a logical drive */
|
||||
FRESULT f_mkfs (const TCHAR* path, BYTE opt, DWORD au, void* work, UINT len); /* Create a FAT volume */
|
||||
@@ -369,6 +366,7 @@ int ff_del_syncobj (FF_SYNC_t sobj); /* Delete a sync object */
|
||||
#define FM_EXFAT 0x04
|
||||
#define FM_ANY 0x07
|
||||
#define FM_SFD 0x08
|
||||
#define FM_PRF2 0x10
|
||||
|
||||
/* Filesystem type (FATFS.fs_type) */
|
||||
#define FS_FAT12 1
|
||||
@@ -17,8 +17,8 @@
|
||||
#ifndef LV_CONF_H
|
||||
#define LV_CONF_H
|
||||
|
||||
#include "../utils/types.h"
|
||||
#include "../../../common/memory_map.h"
|
||||
#include <utils/types.h>
|
||||
#include <memory_map.h>
|
||||
/*===================
|
||||
Dynamic memory
|
||||
*===================*/
|
||||
@@ -32,7 +32,7 @@
|
||||
# define LV_MEM_ADR NYX_LV_MEM_ADR /*Set an address for memory pool instead of allocation it as an array. Can be in external SRAM too.*/
|
||||
# define LV_MEM_AUTO_DEFRAG 1 /*Automatically defrag on free*/
|
||||
#else /*LV_MEM_CUSTOM*/
|
||||
# define LV_MEM_CUSTOM_INCLUDE "../../../mem/heap.h" /*Header for the dynamic memory function*/
|
||||
# define LV_MEM_CUSTOM_INCLUDE <mem/heap.h> /*Header for the dynamic memory function*/
|
||||
# define LV_MEM_CUSTOM_ALLOC malloc /*Wrapper to malloc*/
|
||||
# define LV_MEM_CUSTOM_FREE free /*Wrapper to free*/
|
||||
#endif /*LV_MEM_CUSTOM*/
|
||||
@@ -149,13 +149,17 @@
|
||||
/*HAL settings*/
|
||||
#define LV_TICK_CUSTOM 1 /*1: use a custom tick source (removing the need to manually update the tick with `lv_tick_inc`) */
|
||||
#if LV_TICK_CUSTOM == 1
|
||||
#define LV_TICK_CUSTOM_INCLUDE "../../../utils/util.h" /*Header for the sys time function*/
|
||||
#define LV_TICK_CUSTOM_INCLUDE <utils/util.h> /*Header for the sys time function*/
|
||||
#define LV_TICK_CUSTOM_SYS_TIME_EXPR (get_tmr_ms()) /*Expression evaluating to current systime in ms*/
|
||||
#endif /*LV_TICK_CUSTOM*/
|
||||
|
||||
|
||||
/*Log settings*/
|
||||
#define USE_LV_LOG 0 /*Enable/disable the log module*/
|
||||
#ifdef DEBUG_UART_LV_LOG
|
||||
# define USE_LV_LOG 1 /*Enable/disable the log module*/
|
||||
#else
|
||||
# define USE_LV_LOG 0 /*Enable/disable the log module*/
|
||||
#endif
|
||||
#if USE_LV_LOG
|
||||
/* How important log should be added:
|
||||
* LV_LOG_LEVEL_TRACE A lot of logs to give detailed information
|
||||
@@ -336,7 +340,7 @@
|
||||
#define USE_LV_BTNM 1
|
||||
|
||||
/*Keyboard (dependencies: lv_btnm)*/
|
||||
#define USE_LV_KB 1
|
||||
#define USE_LV_KB 0
|
||||
|
||||
/*Check box (dependencies: lv_btn, lv_label)*/
|
||||
#define USE_LV_CB 1
|
||||
@@ -357,7 +357,10 @@ static void indev_pointer_proc(lv_indev_t * i, lv_indev_data_t * data)
|
||||
if(i->cursor != NULL &&
|
||||
(i->proc.last_point.x != data->point.x ||
|
||||
i->proc.last_point.y != data->point.y)) {
|
||||
lv_obj_set_pos(i->cursor, data->point.x, data->point.y);
|
||||
/*Use cursor's center as pointer*/
|
||||
uint32_t off_x = lv_obj_get_width(i->cursor) >> 1;
|
||||
uint32_t off_y = lv_obj_get_height(i->cursor) >> 1;
|
||||
lv_obj_set_pos(i->cursor, data->point.x - off_x, data->point.y - off_y);
|
||||
}
|
||||
|
||||
i->proc.act_point.x = data->point.x;
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
#include "../lv_misc/lv_font.h"
|
||||
|
||||
#include "../../../../../common/memory_map.h"
|
||||
#include <memory_map.h>
|
||||
|
||||
#if USE_HEKATE_SYMBOL_120 != 0 /*Can be enabled in lv_conf.h*/
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
#include "../lv_misc/lv_font.h"
|
||||
|
||||
#include "../../../../../common/memory_map.h"
|
||||
#include <memory_map.h>
|
||||
|
||||
#if USE_HEKATE_SYMBOL_20 != 0 /*Can be enabled in lv_conf.h*/
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
#include "../lv_misc/lv_font.h"
|
||||
|
||||
#include "../../../../../common/memory_map.h"
|
||||
#include <memory_map.h>
|
||||
|
||||
#if USE_HEKATE_SYMBOL_30 != 0 /*Can be enabled in lv_conf.h*/
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
#include "../lv_misc/lv_font.h"
|
||||
|
||||
#include "../../../../../common/memory_map.h"
|
||||
#include <memory_map.h>
|
||||
|
||||
#if USE_INTERUI_20 != 0 /*Can be enabled in lv_conf.h*/
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
#include "../lv_misc/lv_font.h"
|
||||
|
||||
#include "../../../../../common/memory_map.h"
|
||||
#include <memory_map.h>
|
||||
|
||||
#if USE_INTERUI_30 != 0 /*Can be enabled in lv_conf.h*/
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
#include "../lv_misc/lv_font.h"
|
||||
|
||||
#include "../../../../../common/memory_map.h"
|
||||
#include <memory_map.h>
|
||||
|
||||
#if USE_UBUNTU_MONO != 0 /*Can be enabled in lv_conf.h*/
|
||||
|
||||
@@ -17,7 +17,7 @@ extern "C" {
|
||||
*********************/
|
||||
#include <stdint.h>
|
||||
#include "lv_hal.h"
|
||||
#include "../../../utils/types.h"
|
||||
#include <utils/types.h>
|
||||
#include "../lv_misc/lv_area.h"
|
||||
#include "../lv_core/lv_obj.h"
|
||||
|
||||
@@ -15,7 +15,7 @@ extern "C" {
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include <string.h>
|
||||
#include "../../../utils/types.h"
|
||||
#include <utils/types.h>
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
@@ -16,7 +16,7 @@ extern "C" {
|
||||
*********************/
|
||||
#include <stddef.h>
|
||||
#include "lv_area.h"
|
||||
#include "../../../utils/types.h"
|
||||
#include <utils/types.h>
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user