Difference between revisions of "84PCE:Ports:A000"
(→Synopsis) |
Calc84maniac (Talk | contribs) (→Registers: Document mask register) |
||
(17 intermediate revisions by 3 users not shown) | |||
Line 1: | Line 1: | ||
[[Category:84PCE:Ports:By_Address|4000 - LCD Controller]] [[Category:84PCE:Ports:By_Name|LCD Controller]] | [[Category:84PCE:Ports:By_Address|4000 - LCD Controller]] [[Category:84PCE:Ports:By_Name|LCD Controller]] | ||
[[Category:84PCE:Ports:By_Address|A000 - Keyboard]] [[Category:84PCE:Ports:By_Name|Keyboard]] | [[Category:84PCE:Ports:By_Address|A000 - Keyboard]] [[Category:84PCE:Ports:By_Name|Keyboard]] | ||
+ | [[Category:84PCE:Ports:By_Address|A000 - Keyboard]] [[Category:84PCE:Ports:By_Name|Keyboard]] | ||
== Synopsis == | == Synopsis == | ||
'''Port Number:''' A000-? | '''Port Number:''' A000-? | ||
Line 6: | Line 7: | ||
'''Memory-mapped address:''' F50000-? | '''Memory-mapped address:''' F50000-? | ||
− | '''Function:''' | + | '''Function:''' Keypad Controller |
− | + | ||
− | + | ||
+ | == Registers == | ||
* F50000 (R/W): | * F50000 (R/W): | ||
** Bits 0-1: Scan mode | ** Bits 0-1: Scan mode | ||
*** Mode 0: Idle. | *** Mode 0: Idle. | ||
− | *** Mode 1: Indiscriminate key detection. Data registers are | + | *** Mode 1: Indiscriminate key detection. Data registers of all enabled rows are set to the bitwise OR of those rows, and whenever any key is pressed, interrupt bit 2 is set (and cannot be cleared until the key is released). |
*** Mode 2: Single scan. The keypad is scanned once, and then the mode returns to 0. | *** Mode 2: Single scan. The keypad is scanned once, and then the mode returns to 0. | ||
*** Mode 3: Continuous scan. When scanning completes, it just starts over again after a delay. | *** Mode 3: Continuous scan. When scanning completes, it just starts over again after a delay. | ||
− | ** Bits 2-15: Number of APB cycles to wait before scanning each row | + | ** Bits 2-15: Number of APB (6MHz) cycles to wait before scanning each row (default value is 03C0h; bits 2-7 are 0 so the mode can be written directly to F50000) |
− | ** Bits 16-31: Number of APB cycles to wait between scans | + | ** Bits 16-31: Number of APB (6MHz) cycles to wait between scans (default value is 0F00h) |
* F50004 (R/W): | * F50004 (R/W): | ||
** Bits 0-7: Number of rows to read (later rows are not updated in F50010-F5002F, and just read as whatever they were before being disabled) | ** Bits 0-7: Number of rows to read (later rows are not updated in F50010-F5002F, and just read as whatever they were before being disabled) | ||
− | ** Bits 8-15: Number of columns to read (later column bits in a row are set to | + | ** Bits 8-15: Number of columns to read (later column bits in a row are set to 0 when it is updated) |
+ | ** Bits 16-31: Mask of rows to scan in mode 1. Rows corresponding to "1" bits are included in the scan. Strangely, this mask also determines which columns can set interrupt bit 2, despite not being masked out in the data registers. | ||
* F50008 (R/W): Keypad interrupt status/acknowledge (3-bit). Write "1" bits to acknowledge. | * F50008 (R/W): Keypad interrupt status/acknowledge (3-bit). Write "1" bits to acknowledge. | ||
** Bit 0: Keypad scan complete | ** Bit 0: Keypad scan complete | ||
Line 33: | Line 34: | ||
* F50030-F5003F (R/W): Keypad GPIOs. Each register is 20 bits, with one bit per GPIO. The role of each register is unknown. | * F50030-F5003F (R/W): Keypad GPIOs. Each register is 20 bits, with one bit per GPIO. The role of each register is unknown. | ||
− | + | == Using the keypad == | |
− | + | * This is the layout of what the keypad looks like according to the controller: | |
− | + | {|border="1" cellspacing="0" cellpadding="5" | |
− | + | |- | |
− | + | ! Address | |
− | + | ! Bit 0 | |
− | + | ! Bit 1 | |
− | + | ! Bit 2 | |
− | + | ! Bit 3 | |
− | + | ! Bit 4 | |
− | + | ! Bit 5 | |
− | ld | + | ! Bit 6 |
− | + | ! Bit 7 | |
− | + | |- | |
− | + | | F50010 | |
− | + | | bgcolor=lightgray | | |
− | + | | bgcolor=lightgray | | |
− | + | | bgcolor=lightgray | | |
− | + | | bgcolor=lightgray | | |
− | < | + | | bgcolor=lightgray | |
− | xor a | + | | bgcolor=lightgray | |
− | ld ( | + | | bgcolor=lightgray | |
− | inc | + | | bgcolor=lightgray | |
− | + | |- | |
− | ld ( | + | | F50012 |
− | inc | + | | graph |
+ | | trace | ||
+ | | zoom | ||
+ | | wind | ||
+ | | y= | ||
+ | | 2nd | ||
+ | | mode | ||
+ | | del | ||
+ | |- | ||
+ | | F50014 | ||
+ | | bgcolor=lightgray | | ||
+ | | sto | ||
+ | | ln | ||
+ | | log | ||
+ | | x^2 | ||
+ | | x^-1 | ||
+ | | math | ||
+ | | alpha | ||
+ | |- | ||
+ | | F50016 | ||
+ | | 0 | ||
+ | | 1 | ||
+ | | 4 | ||
+ | | 7 | ||
+ | | , | ||
+ | | sin | ||
+ | | apps | ||
+ | | X | ||
+ | |- | ||
+ | | F50018 | ||
+ | | . | ||
+ | | 2 | ||
+ | | 5 | ||
+ | | 8 | ||
+ | | ( | ||
+ | | cos | ||
+ | | prgm | ||
+ | | stat | ||
+ | |- | ||
+ | | F5001A | ||
+ | | (-) | ||
+ | | 3 | ||
+ | | 6 | ||
+ | | 9 | ||
+ | | ) | ||
+ | | tan | ||
+ | | vars | ||
+ | | bgcolor=lightgray | | ||
+ | |- | ||
+ | | F5001C | ||
+ | | enter | ||
+ | | + | ||
+ | | - | ||
+ | | * | ||
+ | | / | ||
+ | | ^ | ||
+ | | clear | ||
+ | | bgcolor=lightgray | | ||
+ | |- | ||
+ | | F5001E | ||
+ | | down | ||
+ | | left | ||
+ | | right | ||
+ | | up | ||
+ | | bgcolor=lightgray | | ||
+ | | bgcolor=lightgray | | ||
+ | | bgcolor=lightgray | | ||
+ | | bgcolor=lightgray | | ||
+ | |} | ||
+ | * '''Note:''' Group F5001A Bit 0 is NEGATE, not to be confused with SUBTRACT. | ||
+ | * '''Note:''' Group F50014 Bit 0 would be ON, but the ON key is tested elsewhere. | ||
+ | |||
+ | The controller works by scanning multiple rows into data registers; rather than manually selecting rows like previous versions. | ||
+ | |||
+ | For example, if you set the controller to scan 3 rows, it will affect only the data in F00010h, F00012h, F00014h, and leave the others alone. There's not really a reason to set anything other than 8 rows, though. | ||
+ | |||
+ | You will want to disable interrupts when performing your own scans, as OS interrupts will modify the controller's state. | ||
+ | |||
+ | Alternatively, if you want to make use of the OS's scans, you will want to first check the scan mode to ensure the data registers are valid. The OS leaves the controller in mode 1 when no keys are pressed, which renders the data registers useless. | ||
+ | |||
+ | == Comments == | ||
+ | The CE appears to use the same keypad controller as the TI-Nspire series. | ||
+ | |||
+ | == Example == | ||
+ | |||
+ | === Scanning the Keypad === | ||
+ | <nowiki> di ; Disable OS interrupts | ||
+ | ld hl,0F50000h | ||
+ | ld (hl),2 ; Set Single Scan mode | ||
+ | |||
+ | xor a,a | ||
+ | scan_wait: | ||
+ | cp a,(hl) ; Wait for Idle mode | ||
+ | jr nz,scan_wait | ||
+ | |||
+ | ; Read data registers here as needed | ||
+ | |||
+ | ei ; Enable OS interrupts</nowiki> | ||
+ | |||
+ | It is generally a good idea to reset the keypad controller back before exiting your program, in case you have modified timings and such. | ||
+ | |||
+ | === Reset the Keypad === | ||
+ | <nowiki>RestoreKeyboard: | ||
+ | ld hl,0F50000h | ||
+ | xor a ; Mode 0 | ||
+ | ld (hl),a | ||
+ | inc l ; 0F50001h | ||
+ | ld (hl),15 ; Wait 15*256 APB cycles before scanning each row | ||
+ | inc l ; 0F50002h | ||
xor a | xor a | ||
− | ld ( | + | ld (hl),a |
− | inc | + | inc l ; 0F50003h |
− | + | ld (hl),15 ; Wait 15 APB cycles before each scan | |
− | ld ( | + | inc l ; 0F50004h |
− | inc | + | ld a,8 ; Number of rows to scan |
− | ld a,8 | + | ld (hl),a |
− | ld ( | + | inc l ; 0F50005h |
− | inc | + | ld (hl),a ; Number of columns to scan |
− | ld ( | + | ret</nowiki> |
Latest revision as of 10:02, 21 September 2024
Contents
Synopsis
Port Number: A000-?
Memory-mapped address: F50000-?
Function: Keypad Controller
Registers
- F50000 (R/W):
- Bits 0-1: Scan mode
- Mode 0: Idle.
- Mode 1: Indiscriminate key detection. Data registers of all enabled rows are set to the bitwise OR of those rows, and whenever any key is pressed, interrupt bit 2 is set (and cannot be cleared until the key is released).
- Mode 2: Single scan. The keypad is scanned once, and then the mode returns to 0.
- Mode 3: Continuous scan. When scanning completes, it just starts over again after a delay.
- Bits 2-15: Number of APB (6MHz) cycles to wait before scanning each row (default value is 03C0h; bits 2-7 are 0 so the mode can be written directly to F50000)
- Bits 16-31: Number of APB (6MHz) cycles to wait between scans (default value is 0F00h)
- Bits 0-1: Scan mode
- F50004 (R/W):
- Bits 0-7: Number of rows to read (later rows are not updated in F50010-F5002F, and just read as whatever they were before being disabled)
- Bits 8-15: Number of columns to read (later column bits in a row are set to 0 when it is updated)
- Bits 16-31: Mask of rows to scan in mode 1. Rows corresponding to "1" bits are included in the scan. Strangely, this mask also determines which columns can set interrupt bit 2, despite not being masked out in the data registers.
- F50008 (R/W): Keypad interrupt status/acknowledge (3-bit). Write "1" bits to acknowledge.
- Bit 0: Keypad scan complete
- Bit 1: Keypad data register changed
- Bit 2: Key pressed in mode 1
- F5000C (R/W): Keypad interrupt mask (3-bit). Set each bit to 1 if the corresponding event in [F50008] should cause an interrupt.
- F50010-F5002F (R): Keypad data, one halfword per row.
- F50030-F5003F (R/W): Keypad GPIOs. Each register is 20 bits, with one bit per GPIO. The role of each register is unknown.
Using the keypad
- This is the layout of what the keypad looks like according to the controller:
Address | Bit 0 | Bit 1 | Bit 2 | Bit 3 | Bit 4 | Bit 5 | Bit 6 | Bit 7 |
---|---|---|---|---|---|---|---|---|
F50010 | ||||||||
F50012 | graph | trace | zoom | wind | y= | 2nd | mode | del |
F50014 | sto | ln | log | x^2 | x^-1 | math | alpha | |
F50016 | 0 | 1 | 4 | 7 | , | sin | apps | X |
F50018 | . | 2 | 5 | 8 | ( | cos | prgm | stat |
F5001A | (-) | 3 | 6 | 9 | ) | tan | vars | |
F5001C | enter | + | - | * | / | ^ | clear | |
F5001E | down | left | right | up |
- Note: Group F5001A Bit 0 is NEGATE, not to be confused with SUBTRACT.
- Note: Group F50014 Bit 0 would be ON, but the ON key is tested elsewhere.
The controller works by scanning multiple rows into data registers; rather than manually selecting rows like previous versions.
For example, if you set the controller to scan 3 rows, it will affect only the data in F00010h, F00012h, F00014h, and leave the others alone. There's not really a reason to set anything other than 8 rows, though.
You will want to disable interrupts when performing your own scans, as OS interrupts will modify the controller's state.
Alternatively, if you want to make use of the OS's scans, you will want to first check the scan mode to ensure the data registers are valid. The OS leaves the controller in mode 1 when no keys are pressed, which renders the data registers useless.
Comments
The CE appears to use the same keypad controller as the TI-Nspire series.
Example
Scanning the Keypad
di ; Disable OS interrupts ld hl,0F50000h ld (hl),2 ; Set Single Scan mode xor a,a scan_wait: cp a,(hl) ; Wait for Idle mode jr nz,scan_wait ; Read data registers here as needed ei ; Enable OS interrupts
It is generally a good idea to reset the keypad controller back before exiting your program, in case you have modified timings and such.
Reset the Keypad
RestoreKeyboard: ld hl,0F50000h xor a ; Mode 0 ld (hl),a inc l ; 0F50001h ld (hl),15 ; Wait 15*256 APB cycles before scanning each row inc l ; 0F50002h xor a ld (hl),a inc l ; 0F50003h ld (hl),15 ; Wait 15 APB cycles before each scan inc l ; 0F50004h ld a,8 ; Number of rows to scan ld (hl),a inc l ; 0F50005h ld (hl),a ; Number of columns to scan ret