FC3000

找出LCD的初始化資料


目前量測出來的屏腳位

腳位訊號F1C100S
1VDD
2GND
3LEDAPE6
4RSTPE11
5CSPD21
6RSPD19
7WRPD18
8VDD
9DB11PD13
10DB12PD14
11DB13PD15
12DB14PD16
13DB15PD17
14DB5PD6
15DB6PD7
16DB7PD8
17DB8PD10
18DB9PD11
19DB10PD12
20DB0PD1
21DB1PD2
22DB2PD3
23DB3PD4
24DB4PD5

基本上,可以使用如下幾種方式,把屏的初始化資料找出來:
1. 使用J-Link Debug官方韌體程式
2. 使用QEMU跑官方韌體程式,然後把存取暫存器的內容Dump出來
3. 使用邏輯分析儀

雖然第一種方式是司徒覺得最好的方式,可惜那個山寨J-Link在Debug官方韌體程式時,常常跑飛,所以目前只能先放棄第一種方式,至於第二種方式,看似簡單,不過需要花一些時間,雖然司徒在最新版QEMU有找到支援Orangipc-PC開發板(Allwinner H3),不過要改成F1C100S還是需要一點點時間,所以司徒接下來想測試一下邏輯分析儀的部份,不過司徒手上剛好沒有專用的邏輯分析儀,因此,司徒想使用芒果派F1C200S來當作分析儀使用,於是開始製作過程

括除焊點


勇敢的芒果派站了出來


腳位

腳位訊號F1C100S芒果派
1VDD
2GND
3LEDAPE6
4RSTPE11
5CSPD21
6RSPD19PD12
7WRPD18PD0
8VDD
9DB11PD13PE11
10DB12PD14PA0
11DB13PD15PA1
12DB14PD16PA2
13DB15PD17PA3
14DB5PD6PE5
15DB6PD7PE6
16DB7PD8PE7
17DB8PD10PE8
18DB9PD11PE9
19DB10PD12PE10
20DB0PD1PE0
21DB1PD2PE1
22DB2PD3PE2
23DB3PD4PE3
24DB4PD5PE4

跳線



測試程式

  .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的資料似乎是故意被交換使用


返回上一頁