Difference between revisions of "84PCE:Ports:D000"

From WikiTI
Jump to: navigation, search
m (Some comments.)
(Link to the LCD controller page for command descriptions)
 
(26 intermediate revisions by 4 users not shown)
Line 7: Line 7:
 
'''Function:''' LCD Interface
 
'''Function:''' LCD Interface
  
This appears to be an SPI controller that interfaces with the LCD.  Non-extended commands from [https://cdn-shop.adafruit.com/datasheets/ILI9340.pdf] appear to work, but there's plenty of unknown commands used by the boot code.
+
This appears to be an FTSSP010 or compatible SPI controller that interfaces with the [[84PCE:LCD Controller|LCD Controller]].
 +
 
 +
Note that the SPI controller may also be configured to interface with the ARM coprocessor on Python models, via some ports in the 00xx range. The state of this configuration should be considered unknown when starting a program in TI-OS. In order to reliably use the LCD interface, the _boot_InitializeHardware routine should be called at the start of a program to select the LCD interface and reset its configuration to the default.
  
  
Line 17: Line 19:
 
|-
 
|-
 
|D000<br/>F80000
 
|D000<br/>F80000
|
+
|0000182B
|0000F38C
+
|0000FFFF
|Boot code writes 180B/09 before/after turning on/off the lcd.<br/>Bits 0-2 could be transfer size.
+
|CR0: Bits 12-15 indicate the protocol, set the value to 1 for SPI.<br/>The selected protocol determines the read mask; the effective mask for SPI is F8EF.<br/>Boot code writes 180B/09 before/after turning on/off the lcd.  
 
|-
 
|-
 
|D004<br/>F80004
 
|D004<br/>F80004
|0000182B
+
|0002000B
 
|007FFFFF
 
|007FFFFF
|Boot code initializes to 02000B.
+
|CR1: Bits 0-15 are clock divider - 1, bits 16-22 are FIFO entry data length in bits - 1.<br/>According to some drivers, bits 24-31 are padding length, but on this controller it's non-writable and seems to have no effect on transfers or timing.<br/>Base clock is 24 MHz (unconfirmed whether this changes with CPU speed).<br/>Sending with a clock divider of 1 to the LCD has been empirically unreliable across models, but a divider of 2 seems safe. According to LCD controller specs, receiving may require a larger divider.
 
|-
 
|-
 
|D008<br/>F80008
 
|D008<br/>F80008
|0002000B
+
|0000010C
|00000F8F
+
|00000FCF
|Boot code initializes to 010C.<br/>Bit 0 is set to transfer data.<br/>Bit 7 is set/reset for reading/writing.
+
|CR2: Bit 0 is set to transfer data and activate the SPI chip select signal.<br/>Bit 1 is set for data output enable according to some drivers, but this has no effect on LCD sends.<br/>Writing a 1 to Bit 2 clears the receive FIFO and writing a 1 to Bit 3 clears the send FIFO. Writing a 1 to Bit 6 resets the SPI controller.<br/>Bit 7 is set to enable receiving, Bit 8 is set to enable sending.<br/>Bits 9-11 are used for chip select, according to some drivers. Set to 0 for LCD sends.
 
|-
 
|-
 
|D00C<br/>F8000C
 
|D00C<br/>F8000C
|
+
|00000002
|000004F2
+
|0001F1F7
|Status bits.<br/>Boot code waits for bits 4-7 and 10 to be 0 before/after reading/writing.
+
|Status bits (read-only).<br/>Bit 0 is set if the receive FIFO is full, and Bit 1 is set if the send FIFO is <i>not</i> full (can accept more writes).<br/>Bit 2 is set if data is being sent or received, bits 4-8 are the number of queued receive FIFO entries, and bits 12-16 are the number of queued send FIFO entries.<br/>Boot code waits for bits 12-15 and bit 2 to be 0 (in that order) before/after reading/writing.<br/>Receiving seems to stop after 15 FIFO entries are full, unless the send FIFO is non-empty. Conversely, receiving does not stop before 15 FIFO entries are full, even if the send FIFO is empty.<br/>It's unclear what data is sent when this occurs, so it's best to disable the transfer when the send FIFO underruns.
 
|-
 
|-
 
|D010<br/>F80010
 
|D010<br/>F80010
|00002100
+
|00000021
|
+
|0001FFBF
|Unknown
+
|Interrupt control. Masked with interrupt status to generate interrupts.<br/>Bit 0: Receive FIFO overrun interrupt enable.<br/>Bit 1: Send FIFO underrun interrupt enable.<br/>Bit 2: Receive FIFO threshold interrupt enable.<br/>Bit 3: Send FIFO threshold interrupt enable.<br/>Bits 7-11: Receive FIFO threshold. The interrupt status bit is set if and only if the receive FIFO has this many queued entries or more. Ignored when set to 0.<br/>Bits 12-16: Send FIFO threshold. The interrupt status bit is set if and only if the send FIFO has this many queued entries or fewer. Ignored when set to 0.
 
|-
 
|-
 
|D014<br/>F80014
 
|D014<br/>F80014
|00000008
 
 
|
 
|
|Unknown
+
|0000000F
 +
|Interrupt status (read-only). Non-threshold bits are cleared after read.<br/>Bit 0: Receive FIFO overrun according to some drivers; however, it seems the transfer simply stops before an overrun can happen.<br/>Bit 1: Send FIFO underrun (set only when both sending and receiving).<br/>Bit 2: Receive FIFO threshold. Cleared only when the condition becomes false.<br/>Bit 3: Send FIFO threshold. Cleared only when the condition becomes false.
 
|-
 
|-
|D018<br/>F80014
+
|D018<br/>F80018
|
+
 
|
 
|
|FIFO in/out.
+
|FFFFFFFF
 +
|FIFO in/out. Writes push to the send FIFO, and reads pop from the receive FIFO.<br/>Supports up to a 32-bit data length, but when working with more than 8 bits, the low byte access must come last because it causes the push/pop of the entire entry.<br/>The upper 24 bits are latched when written to, but seem to be undefined after pushing a FIFO entry. These bits should not be written to while the FIFO is full.<br/>Any read bits when the FIFO is empty or outside of the receive's configured bit length are undefined, and should be ignored/masked out.
 
|-
 
|-
 
|D01C<br/>F8001C
 
|D01C<br/>F8001C
 
|0E0F0F1F
 
|0E0F0F1F
 
|
 
|
|Constant, could be an ID or status.
+
|Inside reserved range. Appears to be a copy of the feature register at D064.
 
|-
 
|-
 
|D060<br/>F80060
 
|D060<br/>F80060
 
|00012100
 
|00012100
 
|
 
|
|Constant, could be an ID or status.
+
|Revision (read-only)
 
|-
 
|-
 
|D064<br/>F80064
 
|D064<br/>F80064
 
|0E0F0F1F
 
|0E0F0F1F
 
|
 
|
|Constant, could be an ID or status.
+
|Features (read-only): 32-bit data width, 16-entry send/receive FIFOs, list of extra protocols supported.
 
|}
 
|}
 +
 +
== Known Commands ==
 +
See the [[84PCE:LCD_Controller#Command_List|Command List]] on the LCD Controller page for the protocol description and list of commands. Note that TI configures the FIFO to 3 bits per entry by default for the 9-bit protocol; this configuration is assumed for the below example code.
  
 
== Example ==
 
== Example ==
Line 135: Line 140:
 
  ld a,(hl) ; dummy read
 
  ld a,(hl) ; dummy read
 
  ld a,(hl)
 
  ld a,(hl)
 +
ld a,(hl) ; Why is there no wait after dummy read?
 
  ld a,(hl)
 
  ld a,(hl)
  xor a,a
+
  rla
  ld bc,00300h
+
rla
spiReadLoop:
+
rla
 +
rla
 +
rla
 +
and a,0E0h
 +
  ld c,a
 
  ld a,(hl)
 
  ld a,(hl)
  and a,3
+
  rla
  add a,a
+
  rla
  add a,a
+
  and a,01Ch
add a,a
+
 
  or a,c
 
  or a,c
 
  ld c,a
 
  ld c,a
  djnz spiReadLoop
+
  ld a,(hl)
 +
rra ; why are we throwing away the lsb instead of the msb
 +
and a,003h
 +
or a,c
 
  ret</nowiki>
 
  ret</nowiki>

Latest revision as of 12:32, 30 May 2024

Synopsis

Port Number: D000

Memory-mapped Address: F80000

Function: LCD Interface

This appears to be an FTSSP010 or compatible SPI controller that interfaces with the LCD Controller.

Note that the SPI controller may also be configured to interface with the ARM coprocessor on Python models, via some ports in the 00xx range. The state of this configuration should be considered unknown when starting a program in TI-OS. In order to reliably use the LCD interface, the _boot_InitializeHardware routine should be called at the start of a program to select the LCD interface and reset its configuration to the default.


Port    Default    Bits    Information   
D000
F80000
0000182B 0000FFFF CR0: Bits 12-15 indicate the protocol, set the value to 1 for SPI.
The selected protocol determines the read mask; the effective mask for SPI is F8EF.
Boot code writes 180B/09 before/after turning on/off the lcd.
D004
F80004
0002000B 007FFFFF CR1: Bits 0-15 are clock divider - 1, bits 16-22 are FIFO entry data length in bits - 1.
According to some drivers, bits 24-31 are padding length, but on this controller it's non-writable and seems to have no effect on transfers or timing.
Base clock is 24 MHz (unconfirmed whether this changes with CPU speed).
Sending with a clock divider of 1 to the LCD has been empirically unreliable across models, but a divider of 2 seems safe. According to LCD controller specs, receiving may require a larger divider.
D008
F80008
0000010C 00000FCF CR2: Bit 0 is set to transfer data and activate the SPI chip select signal.
Bit 1 is set for data output enable according to some drivers, but this has no effect on LCD sends.
Writing a 1 to Bit 2 clears the receive FIFO and writing a 1 to Bit 3 clears the send FIFO. Writing a 1 to Bit 6 resets the SPI controller.
Bit 7 is set to enable receiving, Bit 8 is set to enable sending.
Bits 9-11 are used for chip select, according to some drivers. Set to 0 for LCD sends.
D00C
F8000C
00000002 0001F1F7 Status bits (read-only).
Bit 0 is set if the receive FIFO is full, and Bit 1 is set if the send FIFO is not full (can accept more writes).
Bit 2 is set if data is being sent or received, bits 4-8 are the number of queued receive FIFO entries, and bits 12-16 are the number of queued send FIFO entries.
Boot code waits for bits 12-15 and bit 2 to be 0 (in that order) before/after reading/writing.
Receiving seems to stop after 15 FIFO entries are full, unless the send FIFO is non-empty. Conversely, receiving does not stop before 15 FIFO entries are full, even if the send FIFO is empty.
It's unclear what data is sent when this occurs, so it's best to disable the transfer when the send FIFO underruns.
D010
F80010
00000021 0001FFBF Interrupt control. Masked with interrupt status to generate interrupts.
Bit 0: Receive FIFO overrun interrupt enable.
Bit 1: Send FIFO underrun interrupt enable.
Bit 2: Receive FIFO threshold interrupt enable.
Bit 3: Send FIFO threshold interrupt enable.
Bits 7-11: Receive FIFO threshold. The interrupt status bit is set if and only if the receive FIFO has this many queued entries or more. Ignored when set to 0.
Bits 12-16: Send FIFO threshold. The interrupt status bit is set if and only if the send FIFO has this many queued entries or fewer. Ignored when set to 0.
D014
F80014
0000000F Interrupt status (read-only). Non-threshold bits are cleared after read.
Bit 0: Receive FIFO overrun according to some drivers; however, it seems the transfer simply stops before an overrun can happen.
Bit 1: Send FIFO underrun (set only when both sending and receiving).
Bit 2: Receive FIFO threshold. Cleared only when the condition becomes false.
Bit 3: Send FIFO threshold. Cleared only when the condition becomes false.
D018
F80018
FFFFFFFF FIFO in/out. Writes push to the send FIFO, and reads pop from the receive FIFO.
Supports up to a 32-bit data length, but when working with more than 8 bits, the low byte access must come last because it causes the push/pop of the entire entry.
The upper 24 bits are latched when written to, but seem to be undefined after pushing a FIFO entry. These bits should not be written to while the FIFO is full.
Any read bits when the FIFO is empty or outside of the receive's configured bit length are undefined, and should be ignored/masked out.
D01C
F8001C
0E0F0F1F Inside reserved range. Appears to be a copy of the feature register at D064.
D060
F80060
00012100 Revision (read-only)
D064
F80064
0E0F0F1F Features (read-only): 32-bit data width, 16-entry send/receive FIFOs, list of extra protocols supported.

Known Commands

See the Command List on the LCD Controller page for the protocol description and list of commands. Note that TI configures the FIFO to 3 bits per entry by default for the 9-bit protocol; this configuration is assumed for the below example code.

Example

Sending

 ld a,036h ; Flips the lcd horizontally, vertically, and swaps the b and r components
 call spiCmd
 ld a,0C0h
 call spiParam

 ld a,002h ; Resetting the lcd on exit
 call spiCmd
 jp boot_InitializeHardware

; Input: A = parameter
spiParam:
 scf ; First bit is set for data
 .db 030h ; jr nc,? ; skips over one byte
; Input: A = command
spiCmd:
 or a,a ; First bit is clear for commands
 ld hl,0F80818h
 call spiWrite
 ld l,h
 ld (hl),001h
spiWait:
 ld l,00Dh
spiWait1:
 ld a,(hl)
 and a,0F0h
 jr nz,spiWait1
 dec l
spiWait2:
 bit 2,(hl)
 jr nz,spiWait2
 ld l,h
 ld (hl),a
 ret
spiWrite:
 ld b,3
spiWriteLoop:
 rla
 rla
 rla
 ld (hl),a ; send 3 bits
 djnz spiWriteLoop
 ret

Receiving

This does not appear to work, always returning 0 on the calcs I've tested, due to either a TI bug or hardware issue.

; Input: A = command
; Ouput: A = data
spiRead:
 ld hl,0F80808
 ld (hl),00Ch
 ld l,018h
 or a,a
 call spiWrite
 xor a,a ; not sure what this is for
 call spiWrite
 ld l,009h
 ld (hl),001h
 dec l
 ld (hl),081h
 call spiWait
 ld l,$18
 ld a,(hl) ; dummy read
 ld a,(hl)
 ld a,(hl) ; Why is there no wait after dummy read?
 ld a,(hl)
 rla
 rla
 rla
 rla
 rla
 and a,0E0h
 ld c,a
 ld a,(hl)
 rla
 rla
 and a,01Ch
 or a,c
 ld c,a
 ld a,(hl)
 rra ; why are we throwing away the lsb instead of the msb
 and a,003h
 or a,c
 ret