FC3000
找出LCD的初始化資料
目前量測出來的屏腳位
腳位 | 訊號 | F1C100S |
---|---|---|
1 | VDD | |
2 | GND | |
3 | LEDA | PE6 |
4 | RST | PE11 |
5 | CS | PD21 |
6 | RS | PD19 |
7 | WR | PD18 |
8 | VDD | |
9 | DB11 | PD13 |
10 | DB12 | PD14 |
11 | DB13 | PD15 |
12 | DB14 | PD16 |
13 | DB15 | PD17 |
14 | DB5 | PD6 |
15 | DB6 | PD7 |
16 | DB7 | PD8 |
17 | DB8 | PD10 |
18 | DB9 | PD11 |
19 | DB10 | PD12 |
20 | DB0 | PD1 |
21 | DB1 | PD2 |
22 | DB2 | PD3 |
23 | DB3 | PD4 |
24 | DB4 | PD5 |
基本上,可以使用如下幾種方式,把屏的初始化資料找出來:
1. 使用J-Link Debug官方韌體程式
2. 使用QEMU跑官方韌體程式,然後把存取暫存器的內容Dump出來
3. 使用邏輯分析儀
雖然第一種方式是司徒覺得最好的方式,可惜那個山寨J-Link在Debug官方韌體程式時,常常跑飛,所以目前只能先放棄第一種方式,至於第二種方式,看似簡單,不過需要花一些時間,雖然司徒在最新版QEMU有找到支援Orangipc-PC開發板(Allwinner H3),不過要改成F1C100S還是需要一點點時間,所以司徒接下來想測試一下邏輯分析儀的部份,不過司徒手上剛好沒有專用的邏輯分析儀,因此,司徒想使用芒果派F1C200S來當作分析儀使用,於是開始製作過程
括除焊點
勇敢的芒果派站了出來
腳位
腳位 | 訊號 | F1C100S | 芒果派 |
---|---|---|---|
1 | VDD | ||
2 | GND | ||
3 | LEDA | PE6 | |
4 | RST | PE11 | |
5 | CS | PD21 | |
6 | RS | PD19 | PD12 |
7 | WR | PD18 | PD0 |
8 | VDD | ||
9 | DB11 | PD13 | PE11 |
10 | DB12 | PD14 | PA0 |
11 | DB13 | PD15 | PA1 |
12 | DB14 | PD16 | PA2 |
13 | DB15 | PD17 | PA3 |
14 | DB5 | PD6 | PE5 |
15 | DB6 | PD7 | PE6 |
16 | DB7 | PD8 | PE7 |
17 | DB8 | PD10 | PE8 |
18 | DB9 | PD11 | PE9 |
19 | DB10 | PD12 | PE10 |
20 | DB0 | PD1 | PE0 |
21 | DB1 | PD2 | PE1 |
22 | DB2 | PD3 | PE2 |
23 | DB3 | PD4 | PE3 |
24 | DB4 | PD5 | PE4 |
跳線
測試程式
.global _start .equiv CCU_BASE, 0x01c20000 .equiv GPIO_BASE, 0x01c20800 .equiv UART1_BASE, 0x01c25400 .equiv PLL_PERIPH_CTRL_REG, 0x0028 .equiv AHB_APB_HCLKC_CFG_REG, 0x0054 .equiv BUS_CLK_GATING_REG2, 0x0068 .equiv BUS_SOFT_RST_REG2, 0x02d0 .equiv PA, (0x24 * 0) .equiv PB, (0x24 * 1) .equiv PC, (0x24 * 2) .equiv PD, (0x24 * 3) .equiv PE, (0x24 * 4) .equiv PORT_CFG0, 0x00 .equiv PORT_CFG1, 0x04 .equiv PORT_CFG2, 0x08 .equiv PORT_DATA, 0x10 .equiv PORT_PUL0, 0x1c .equiv PORT_PUL1, 0x20 .equiv UART_RBR, 0x00 .equiv UART_DLL, 0x00 .equiv UART_DLH, 0x04 .equiv UART_IER, 0x04 .equiv UART_IIR, 0x08 .equiv UART_LCR, 0x0c .equiv UART_MCR, 0x10 .equiv UART_USR, 0x7c .arm .text _start: .long 0xea000016 .byte 'e', 'G', 'O', 'N', '.', 'B', 'T', '0' .long 0, __spl_size .byte 'S', 'P', 'L', 2 .long 0, 0 .long 0, 0, 0, 0, 0, 0, 0, 0 .long 0, 0, 0, 0, 0, 0, 0, 0 _vector: b reset b . b . b . b . b . b . b . reset: ldr r0, =CCU_BASE ldr r1, =0x80041800 str r1, [r0, #PLL_PERIPH_CTRL_REG] ldr r1, =0x00003180 str r1, [r0, #AHB_APB_HCLKC_CFG_REG] ldr r4, =GPIO_BASE mov r1, #0x00000000 str r1, [r4, #(PA + PORT_CFG0)] str r1, [r4, #(PC + PORT_CFG0)] str r1, [r4, #(PD + PORT_CFG0)] str r1, [r4, #(PD + PORT_CFG1)] str r1, [r4, #(PE + PORT_CFG0)] str r1, [r4, #(PE + PORT_CFG1)] ldr r1, =0x55555555 str r1, [r4, #(PD + PORT_PUL0)] str r1, [r4, #(PD + PORT_PUL1)] str r1, [r4, #(PE + PORT_PUL0)] str r1, [r4, #(PE + PORT_PUL1)] ldr r5, =0x4000 ldr r6, =64 mov r1, #0 mov r2, r5 mov r3, r6 0: str r1, [r2] add r2, #4 subs r3, #4 bne 0b ldr r4, =GPIO_BASE 0: ldr r1, [r4, #(PD + PORT_DATA)] ands r1, #(1 << 0) bne 0b mov r1, #0 ldr r2, [r4, #(PD + PORT_DATA)] and r2, #(1 << 12) lsl r2, #20 orr r1, r2 ldr r2, [r4, #(PA + PORT_DATA)] and r2, #0x07 lsl r2, #12 orr r1, r2 ldr r2, [r4, #(PE + PORT_DATA)] ldr r3, =0x7ff and r2, r3 orr r1, r2 str r1, [r5] 1: ldr r1, [r4, #(PD + PORT_DATA)] ands r1, #(1 << 0) beq 1b add r5, #4 subs r6, #4 bne 0b bl uart_init ldr r0, =0x11223344 bl uart_4byte ldr r5, =0x4000 ldr r6, =64 0: ldr r0, [r5] bl uart_4byte ldr r0, =0xaa bl uart_byte add r5, #4 subs r6, #4 bne 0b b . uart_init: push {r4, lr} ldr r4, =CCU_BASE ldr r1, =(1 << 21) str r1, [r4, #BUS_CLK_GATING_REG2] str r1, [r4, #BUS_SOFT_RST_REG2] ldr r4, =GPIO_BASE ldr r1, =0x5500 str r1, [r4, #(PA + PORT_CFG0)] ldr r4, =UART1_BASE ldr r1, =0x00 str r1, [r4, #UART_IER] ldr r1, =0xf7 str r1, [r4, #UART_IIR] ldr r1, =0x00 str r1, [r4, #UART_MCR] ldr r1, [r4, #UART_LCR] orr r1, #(1 << 7) str r1, [r4, #UART_LCR] ldr r1, =54 str r1, [r4, #UART_DLL] ldr r1, =0x00 str r1, [r4, #UART_DLH] ldr r1, [r4, #UART_LCR] bic r1, #(1 << 7) str r1, [r4, #UART_LCR] ldr r1, [r4, #UART_LCR] bic r1, #0x1f orr r1, #0x03 str r1, [r4, #UART_LCR] pop {r4, pc} uart_byte: push {r4, lr} ldr r4, =UART1_BASE 1: ldr r1, [r4, #UART_USR] tst r1, #(1 << 1) beq 1b strb r0, [r4, #UART_RBR] pop {r4, pc} uart_4byte: push {r4, lr} mov r4, r0 lsr r0, #24 bl uart_byte mov r0, r4 lsr r0, #16 bl uart_byte mov r0, r4 lsr r0, #8 bl uart_byte mov r0, r4 bl uart_byte pop {r4, pc} .end
P.S. PA3先拔除
但是詭異的事情發生了,每次量測到的資料竟然都不一樣
於是,司徒寫了一個GPIO Toggle量測
F1C200S I/O速度只有2.8MHz
屏的LCD_WR速度則是4.7MHz,難怪取出來的資料每次都不一樣,因為,最低取樣頻率至少要是原生的兩倍...,不過,司徒突然對STM32的GPIO 50MHz相當感興趣,哈
接著司徒打算使用STM32F103來做邏輯分析儀,因為官方文件說,I/O Toggle可以達到18MHz,如果再超頻,那應該是夠用,因此,司徒找來STM32F103開發板
PLL 72MHz,可以達到12MHz
PLL 128MHz,可以達到21MHz
值得注意的是,使用eor指令做I/O Toggle時,速度比str指令來的慢,只有12MHz(PLL 128MHz)
重新跳線
接著開始測試,將LCD_WR接到PB1,經由負緣觸發中斷時,接著將PC的資料寫到RAM,讀取完64Bytes後,透過UART傳回電腦
STM32F103測試程式(PB0:LCD_RS, PB1:LCD_WR, PC:LCD_DB)
.thumb .cpu cortex-m3 .syntax unified .equiv NVIC_ISER0, 0xe000e100 .equiv AFIO_EXTICR1, 0x40010008 .equiv EXTI_IMR, 0x40010400 .equiv EXTI_EMR, 0x40010404 .equiv EXTI_RTSR, 0x40010408 .equiv EXTI_FTSR, 0x4001040c .equiv EXTI_SWIER, 0x40010410 .equiv EXTI_PR, 0x40010414 .equiv GPIOA_CRL, 0x40010800 .equiv GPIOA_CRH, 0x40010804 .equiv GPIOA_IDR, 0x40010808 .equiv GPIOA_ODR, 0x4001080c .equiv GPIOB_CRL, 0x40010c00 .equiv GPIOB_CRH, 0x40010c04 .equiv GPIOB_IDR, 0x40010c08 .equiv GPIOB_ODR, 0x40010c0c .equiv GPIOC_CRL, 0x40011000 .equiv GPIOC_CRH, 0x40011004 .equiv GPIOC_IDR, 0x40011008 .equiv GPIOC_ODR, 0x4001100c .equiv RCC_CR, 0x40021000 .equiv RCC_CFGR, 0x40021004 .equiv RCC_APB2ENR, 0x40021018 .equiv FLASH_ACR, 0x40022000 .equiv UART1_SR, 0x40013800 .equiv UART1_DR, 0x40013804 .equiv UART1_BRR, 0x40013808 .equiv UART1_CR1, 0x4001380c .equiv UART1_CR2, 0x40013810 .equiv UART1_CR3, 0x40013814 .equiv STACKINIT, 0x20005000 .global _start .section .text .org 0x0000 .word STACKINIT .word _start .org 0x005c .word _exti1 .org 0x0200 .align 2 .thumb_func _exti1: push {r4, lr} ldrh r1, [r7] strh r1, [r5, #2]! ldrh r2, [r8] strh r2, [r5, #2]! ldr r4, =EXTI_PR mov r1, #(1 << 1) str r1, [r4] pop {r4, pc} .align 2 .thumb_func _start: bl rcc_init bl flash_init bl uart_init ldr r4, =RCC_APB2ENR ldr r1, [r4] orr r1, #(1 << 4) | (1 << 3) | (1 << 2) str r1, [r4] ldr r4, =GPIOB_CRL ldr r1, =0x88888888 str r1, [r4] ldr r4, =GPIOB_CRH ldr r1, =0x88888888 str r1, [r4] ldr r4, =GPIOC_CRL ldr r1, =0x88888888 str r1, [r4] ldr r4, =GPIOC_CRH ldr r1, =0x88888888 str r1, [r4] ldr r4, =EXTI_IMR ldr r1, =(1 << 1) str r1, [r4] ldr r4, =EXTI_EMR ldr r1, =(1 << 1) str r1, [r4] ldr r4, =EXTI_FTSR ldr r1, =(1 << 1) str r1, [r4] ldr r4, =AFIO_EXTICR1 ldr r1, =(1 << 4) str r1, [r4] ldr r5, =buf ldr r6, =buf ldr r7, =GPIOB_IDR ldr r8, =GPIOC_IDR ldr r4, =NVIC_ISER0 ldr r1, =(1 << 7) str r1, [r4] add r6, #(64 * 2 * 2) 0: cmp r5, r6 bcc 0b ldr r4, =NVIC_ISER0 mov r1, #0 str r1, [r4] ldr r4, =AFIO_EXTICR1 mov r1, #0 str r1, [r4] ldr r5, =buf ldr r6, =64 0: ldrh r1, [r5, #2]! lsl r1, #31 eor r0, r0 ldrh r0, [r5, #2]! orr r0, r1 bl uart_4byte subs r6, #1 bne 0b ldr r0, =0x11223344 bl uart_4byte b . .align 2 .thumb_func uart_init: push {r4, lr} ldr r4, =RCC_APB2ENR ldr r1, [r4] ldr r2, =(1 << 14) | (1 << 2) | (1 << 0) orr r1, r2 str r1, [r4] ldr r4, =GPIOA_CRH ldr r1, [r4] bic r1, #0xff0 orr r1, #0x4b0 str r1, [r4] ldr r4, =UART1_BRR @ldr r1, =(39 << 4) | (1 << 0) @ 115200bps 72MHz ldr r1, =(69 << 4) | (7 << 0) @ 115200bps 128MHz str r1, [r4] ldr r4, =UART1_CR1 ldr r1, =(1 << 13) | (1 << 3) str r1, [r4] pop {r4, pc} .align 2 .thumb_func uart_byte: push {r4, lr} ldr r4, =UART1_SR 0: ldr r1, [r4] tst r1, #(1 << 7) beq 0b ldr r4, =UART1_DR str r0, [r4] pop {r4, pc} .align 2 .thumb_func uart_4byte: push {r4, lr} mov r4, r0 lsr r0, #24 bl uart_byte mov r0, r4 lsr r0, #16 bl uart_byte mov r0, r4 lsr r0, #8 bl uart_byte mov r0, r4 bl uart_byte pop {r4, pc} .align 2 .thumb_func rcc_init: push {r4, lr} ldr r4, =RCC_CR ldr r1, =(1 << 26) | (1 << 16) str r1, [r4] 0: ldr r1, [r4] tst r1, #(1 << 17) bne 0b ldr r4, =RCC_CFGR @mov r1, #(7 << 18) @ 72MHz mov r1, #(14 << 18) @ 128MHz orr r1, #(1 << 16) str r1, [r4] ldr r4, =RCC_CR ldr r1, [r4] orr r1, #(1 << 24) str r1, [r4] 0: ldr r1, [r4] tst r1, #(1 << 25) bne 0b ldr r4, =RCC_CFGR ldr r1, [r4] orr r1, #2 str r1, [r4] 0: ldr r1, [r4] tst r1, #(1 << 3) bne 0b pop {r4, pc} .align 2 .thumb_func flash_init: push {r4, lr} ldr r4, =FLASH_ACR mov r1, #0x32 str r1, [r4] pop {r4, pc} .data .align 2 buf: .skip (64 * 2 * 2) .end
測試後發現,資料還是會有不一致的狀況,因此,STM32F103目前無法勝任這個任務...
接著,司徒為了確定LCD輸出代碼是否有問題,因此,測試了一下Miyoo,確實是可以動作的
Q8掌機也是沒有問題
不過,將屏拿到Q8掌機測試,結果還是點不亮,共測試GC9300、GC9306、ST7789、HX8357C、R61520初始化程式,還是不行...
於是,司徒買一台山寨Saleae Logic 16,體積很迷你
不過,同時開啟16通道時,取樣率只有16MS/s...
在測試過16通道16MS/s取樣率後,司徒發現每次取的資料都有變動,資料不一致性有點大,這邏輯分析儀...,於是,司徒改成使用12通道25MS/s的取樣率
測試幾次後,發現資料不一致性還是有,不過已經好很多了,不過LCD是16Bits,在加上LCD_WR、LCD_RS,需要18通道才行,於是司徒分兩次擷取
低位元資料(取5次):LCD_RS、LCD_WR、LCD_DB0~LCD_DB9
高位元資料(取5次):LCD_RS、LCD_WR、LCD_DB6~LCD_DB15
擷取後,把高位元資料進行排列,假定這些多餘的資料為雜訊,手動濾掉
低位元資料進行排列,假定這些多餘的資料為雜訊,手動濾掉
再做合併時,發現低位元資料少一筆,這...,不過,仔細一看,資料都是一筆CMD、一筆DAT,然後LCD_DB6~LCD_DB9是疊加取樣,因此,交叉比對後,發現第一筆高位元資料是雜訊
合併後的初始化命令
CMD:0x800 DAT:0x100 CMD:0x1000 DAT:0x700 CMD:0x1800 DAT:0xc002 CMD:0x2000 DAT:0x0 CMD:0x4000 DAT:0x1200 CMD:0x4800 DAT:0x0 CMD:0x5000 DAT:0x0 CMD:0x6000 DAT:0x0 CMD:0x6800 DAT:0x0 CMD:0x7800 DAT:0x0 CMD:0x8000 DAT:0x0 CMD:0x8800 DAT:0x3800 CMD:0x9000 DAT:0x0 CMD:0x9800 DAT:0x0 CMD:0x3800 DAT:0x800 CMD:0x8000 DAT:0x8682 CMD:0x8800 DAT:0x3e60 CMD:0x9000 DAT:0xc080 CMD:0x9800 DAT:0x603 CMD:0x4820 DAT:0xf000 CMD:0x5820 DAT:0x7000 CMD:0x20 DAT:0x0 CMD:0x820 DAT:0x0 CMD:0x8020 DAT:0x0 CMD:0x8820 DAT:0x3d00 CMD:0x9020 DAT:0x2000 CMD:0xa820 DAT:0x2a00 CMD:0xb020 DAT:0x2000 CMD:0xb820 DAT:0x3b00 CMD:0xc020 DAT:0x1000 CMD:0xc820 DAT:0x3f00 CMD:0xe020 DAT:0x1500 CMD:0xe820 DAT:0x2000 CMD:0x8040 DAT:0x0 CMD:0x8840 DAT:0x78e0 CMD:0x9040 DAT:0x0 CMD:0x9840 DAT:0xf920 CMD:0x60 DAT:0x714 CMD:0x860 DAT:0x800 CMD:0x5060 DAT:0x0 CMD:0x80 DAT:0x0 CMD:0x880 DAT:0x0 CMD:0x1080 DAT:0x0 CMD:0x1880 DAT:0x0 CMD:0x2080 DAT:0x0 CMD:0x2880 DAT:0x0 CMD:0x8080 DAT:0x8000 CMD:0x9080 DAT:0x600 CMD:0x1800 DAT:0x4020 CMD:0x3800 DAT:0x9920 CMD:0x8040 DAT:0x0 CMD:0x8840 DAT:0x78e0 CMD:0x9040 DAT:0x0 CMD:0x9840 DAT:0xf920 CMD:0x20 DAT:0x78e0 CMD:0x820 DAT:0x0 CMD:0x1020 DAT:0x0
測試程式
.global _start .equiv PIO_BASE, 0x01c20800 .equiv PD, (0x24 * 3) .equiv PE, (0x24 * 4) .equiv PIO_CFG0, 0x00 .equiv PIO_CFG1, 0x04 .equiv PIO_CFG2, 0x08 .equiv PIO_DATA, 0x10 .equiv LCD_CS, (1 << 21) .equiv LCD_RD, (1 << 20) .equiv LCD_RS, (1 << 19) .equiv LCD_WR, (1 << 18) .equiv LCD_RST, (1 << 11) .equiv LCD_BL, (1 << 6) .arm .text _start: .long 0xea000016 .byte 'e', 'G', 'O', 'N', '.', 'B', 'T', '0' .long 0, __spl_size .byte 'S', 'P', 'L', 2 .long 0, 0 .long 0, 0, 0, 0, 0, 0, 0, 0 .long 0, 0, 0, 0, 0, 0, 0, 0 _vector: b reset b . b . b . b . b . b . b . reset: ldr r4, =PIO_BASE + PD ldr r1, =0x11111111 str r1, [r4, #PIO_CFG0] str r1, [r4, #PIO_CFG1] ldr r1, =0x00111111 str r1, [r4, #PIO_CFG2] ldr r4, =PIO_BASE + PE ldr r1, [r4, #PIO_CFG0] bic r1, #0xf000000 orr r1, #0x1000000 str r1, [r4, #PIO_CFG0] ldr r1, [r4, #PIO_CFG1] bic r1, #0xf000 orr r1, #0x1000 str r1, [r4, #PIO_CFG1] ldr r4, =PIO_BASE + PD ldr r1, =0xffffffff str r1, [r4, #PIO_DATA] ldr r4, =PIO_BASE + PE ldr r1, =0xffffffff str r1, [r4, #PIO_DATA] bl lcd_rst ldr r0, =0x800 bl lcd_cmd ldr r0, =0x100 bl lcd_dat ldr r0, =0x1000 bl lcd_cmd ldr r0, =0x700 bl lcd_dat ldr r0, =0x1800 bl lcd_cmd ldr r0, =0xc002 bl lcd_dat ldr r0, =0x2000 bl lcd_cmd ldr r0, =0x0 bl lcd_dat ldr r0, =0x4000 bl lcd_cmd ldr r0, =0x1200 bl lcd_dat ldr r0, =0x4800 bl lcd_cmd ldr r0, =0x0 bl lcd_dat ldr r0, =0x5000 bl lcd_cmd ldr r0, =0x0 bl lcd_dat ldr r0, =0x6000 bl lcd_cmd ldr r0, =0x0 bl lcd_dat ldr r0, =0x6800 bl lcd_cmd ldr r0, =0x0 bl lcd_dat ldr r0, =0x7800 bl lcd_cmd ldr r0, =0x0 bl lcd_dat ldr r0, =0x8000 bl lcd_cmd ldr r0, =0x0 bl lcd_dat ldr r0, =0x8800 bl lcd_cmd ldr r0, =0x3800 bl lcd_dat ldr r0, =0x9000 bl lcd_cmd ldr r0, =0x0 bl lcd_dat ldr r0, =0x9800 bl lcd_cmd ldr r0, =0x0 bl lcd_dat ldr r0, =0x3800 bl lcd_cmd ldr r0, =0x800 bl lcd_dat ldr r0, =0x8000 bl lcd_cmd ldr r0, =0x8682 bl lcd_dat ldr r0, =0x8800 bl lcd_cmd ldr r0, =0x3e60 bl lcd_dat ldr r0, =0x9000 bl lcd_cmd ldr r0, =0xc080 bl lcd_dat ldr r0, =0x9800 bl lcd_cmd ldr r0, =0x603 bl lcd_dat ldr r0, =0x4820 bl lcd_cmd ldr r0, =0xf000 bl lcd_dat ldr r0, =0x5820 bl lcd_cmd ldr r0, =0x7000 bl lcd_dat ldr r0, =0x20 bl lcd_cmd ldr r0, =0x0 bl lcd_dat ldr r0, =0x820 bl lcd_cmd ldr r0, =0x0 bl lcd_dat ldr r0, =0x8020 bl lcd_cmd ldr r0, =0x0 bl lcd_dat ldr r0, =0x8820 bl lcd_cmd ldr r0, =0x3d00 bl lcd_dat ldr r0, =0x9020 bl lcd_cmd ldr r0, =0x2000 bl lcd_dat ldr r0, =0xa820 bl lcd_cmd ldr r0, =0x2a00 bl lcd_dat ldr r0, =0xb020 bl lcd_cmd ldr r0, =0x2000 bl lcd_dat ldr r0, =0xb820 bl lcd_cmd ldr r0, =0x3b00 bl lcd_dat ldr r0, =0xc020 bl lcd_cmd ldr r0, =0x1000 bl lcd_dat ldr r0, =0xc820 bl lcd_cmd ldr r0, =0x3f00 bl lcd_dat ldr r0, =0xe020 bl lcd_cmd ldr r0, =0x1500 bl lcd_dat ldr r0, =0xe820 bl lcd_cmd ldr r0, =0x2000 bl lcd_dat ldr r0, =0x8040 bl lcd_cmd ldr r0, =0x0 bl lcd_dat ldr r0, =0x8840 bl lcd_cmd ldr r0, =0x78e0 bl lcd_dat ldr r0, =0x9040 bl lcd_cmd ldr r0, =0x0 bl lcd_dat ldr r0, =0x9840 bl lcd_cmd ldr r0, =0xf920 bl lcd_dat ldr r0, =0x60 bl lcd_cmd ldr r0, =0x714 bl lcd_dat ldr r0, =0x860 bl lcd_cmd ldr r0, =0x800 bl lcd_dat ldr r0, =0x5060 bl lcd_cmd ldr r0, =0x0 bl lcd_dat ldr r0, =0x80 bl lcd_cmd ldr r0, =0x0 bl lcd_dat ldr r0, =0x880 bl lcd_cmd ldr r0, =0x0 bl lcd_dat ldr r0, =0x1080 bl lcd_cmd ldr r0, =0x0 bl lcd_dat ldr r0, =0x1880 bl lcd_cmd ldr r0, =0x0 bl lcd_dat ldr r0, =0x2080 bl lcd_cmd ldr r0, =0x0 bl lcd_dat ldr r0, =0x2880 bl lcd_cmd ldr r0, =0x0 bl lcd_dat ldr r0, =0x8080 bl lcd_cmd ldr r0, =0x8000 bl lcd_dat ldr r0, =0x9080 bl lcd_cmd ldr r0, =0x600 bl lcd_dat ldr r0, =0x1800 bl lcd_cmd ldr r0, =0x4020 bl lcd_dat ldr r0, =0x3800 bl lcd_cmd ldr r0, =0x9920 bl lcd_dat ldr r0, =0x8040 bl lcd_cmd ldr r0, =0x0 bl lcd_dat ldr r0, =0x8840 bl lcd_cmd ldr r0, =0x78e0 bl lcd_dat ldr r0, =0x9040 bl lcd_cmd ldr r0, =0x0 bl lcd_dat ldr r0, =0x9840 bl lcd_cmd ldr r0, =0xf920 bl lcd_dat ldr r0, =0x20 bl lcd_cmd ldr r0, =0x78e0 bl lcd_dat ldr r0, =0x820 bl lcd_cmd ldr r0, =0x0 bl lcd_dat ldr r0, =0x1020 bl lcd_cmd ldr r4, =320*80 ldr r5, =0x1f 0: mov r0, r5 bl lcd_dat subs r4, #1 bne 0b ldr r4, =320*80 ldr r5, =0x7e0 0: mov r0, r5 bl lcd_dat subs r4, #1 bne 0b ldr r4, =320*80 ldr r5, =0xf800 0: mov r0, r5 bl lcd_dat subs r4, #1 bne 0b b . delay: push {lr} 0: subs r0, #1 bne 0b pop {pc} lcd_rst: push {r4, r5, lr} ldr r4, =PIO_BASE + PE ldr r5, =0xffffffff bic r5, #LCD_RST str r5, [r4, #PIO_DATA] ldr r0, =10000 bl delay orr r5, #LCD_RST str r5, [r4, #PIO_DATA] ldr r0, =10000 bl delay pop {r4, r5, pc} lcd_wr: push {r4, r5, lr} ldr r4, =PIO_BASE + PD and r2, r0, #0x00ff and r3, r0, #0xff00 lsl r2, #1 lsl r3, #2 eor r5, r5 orr r5, r1 orr r5, r2 orr r5, r3 orr r5, #LCD_RD str r5, [r4, #PIO_DATA] orr r5, #LCD_WR str r5, [r4, #PIO_DATA] pop {r4, r5, pc} lcd_dat: push {lr} mov r1, #LCD_RS bl lcd_wr pop {pc} lcd_cmd: push {lr} mov r1, #0 bl lcd_wr pop {pc} .end
感動的一刻
從觀察結果來看,R和B的資料似乎是故意被交換使用