Memory-mapped I/O ports on CX II and Keypads: Difference between pages

From Hackspire
(Difference between pages)
Jump to navigation Jump to search
(Add back 90050000 - I2C controller)
 
(Add capTIvate protocol)
 
Line 1: Line 1:
Not all parts have been discovered and researched yet, so the information on this page is not complete.
==Key maps==


==00000000 - Boot1 ROM==
Each bit in the 900E0010-900E001F registers represents a key. Only bits 0 to 10 are used in each halfword. The mapping depends on the currently used keypad.


128kB of on-chip ROM.
'''Clickpad keypad map:'''


==10000000 - SDRAM==
If the bit is cleared, the key is being pressed.


64 MiB, managed by 0x90120000.
{|border="1" cellspacing="0" cellpadding="5"
|-
! offset
! bit 0
! bit 1
! bit 2
! bit 3
! bit 4
! bit 5
! bit 6
! bit 7
! bit 8
! bit 9
! bit 10
|-
| 0010
| ret
| enter
| space
| (-)
| Z
| .
| Y
| 0
| X
| on
| theta
|-
| 0012
| ,
| +
| W
| 3
| V
| 2
| U
| 1
| T
| e^x
| pi
|-
| 0014
| ?
| -
| S
| 6
| R
| 5
| Q
| 4
| P
| 10^x
| EE
|-
| 0016
| :
| *
| O
| 9
| N
| 8
| M
| 7
| L
| x^2
| i
|-
| 0018
| "
| /
| K
| tan
| J
| cos
| I
| sin
| H
| ^
| >
|-
| 001A
| '
| cat
| G
| )
| F
| (
| E
| var
| D
| shift
| <
|-
| 001C
| flag
| click
| C
| home
| B
| menu
| A
| esc
| &#124;
| tab
| bgcolor=lightgray |
|-
| 001E
| up
| u+r
| right
| r+d
| down
| d+l
| left
| l+u
| del
| ctrl
| =
|}


==90000000 - General Purpose I/O (GPIO)==
'''TI-84+ keypad map:'''


See [[GPIO Pins]]
If the bit is cleared, the key is being pressed.


==90010000 - Fast timer==
{|border="1" cellspacing="0" cellpadding="5"
|-
! offset
! bit 0
! bit 1
! bit 2
! bit 3
! bit 4
! bit 5
! bit 6
! bit 7
! bit 8
! bit 9
! bit 10
|-
| 0010
| down
| left
| right
| up
| bgcolor=lightgray |
| bgcolor=lightgray |
| bgcolor=lightgray |
| bgcolor=lightgray |
| bgcolor=lightgray |
| bgcolor=lightgray |
| bgcolor=lightgray |
|-
| 0012
| enter
| +
| -
| *
| /
| ^
| clear
| bgcolor=lightgray |
| bgcolor=lightgray |
| bgcolor=lightgray |
| bgcolor=lightgray |
|-
| 0014
| (-)
| 3
| 6
| 9
| )
| tan
| vars
| bgcolor=lightgray |
| bgcolor=lightgray |
| bgcolor=lightgray |
| bgcolor=lightgray |
|-
| 0016
| .
| 2
| 5
| 8
| (
| cos
| prgm
| stat
| bgcolor=lightgray |
| bgcolor=lightgray |
| bgcolor=lightgray |
|-
| 0018
| 0
| 1
| 4
| 7
| ,
| sin
| apps
| X
| bgcolor=lightgray |
| bgcolor=lightgray |
| bgcolor=lightgray |
|-
| 001A
| on
| sto
| ln
| log
| x^2
| x^-1
| math
| alpha
| bgcolor=lightgray |
| bgcolor=lightgray |
| bgcolor=lightgray |
|-
| 001C
| graph
| trace
| zoom
| wind
| y=
| 2nd
| mode
| del
| bgcolor=lightgray |
| bgcolor=lightgray |
| bgcolor=lightgray |
|-
| 001E
| bgcolor=lightgray |
| bgcolor=lightgray |
| bgcolor=lightgray |
| bgcolor=lightgray |
| bgcolor=lightgray |
| bgcolor=lightgray |
| bgcolor=lightgray |
| bgcolor=lightgray |
| bgcolor=lightgray |
| bgcolor=lightgray |
| bgcolor=lightgray |
|}


The same interface as 900C0000/900D0000, see [[#900D0000 - Second timer|Second timer]].
'''Touchpad/CX/CM/CX II keypad map:'''


==90020000 - Serial UART==
If the bit is set, the key is being pressed.


[http://infocenter.arm.com/help/topic/com.arm.doc.ddi0183f/DDI0183.pdf PL011].
{|border="1" cellspacing="0" cellpadding="5"
|-
! offset
! bit 0
! bit 1
! bit 2
! bit 3
! bit 4
! bit 5
! bit 6
! bit 7
! bit 8
! bit 9
! bit 10
|-
| 0010
| ret
| enter
| bgcolor=lightgray |
| (-)
| space
| Z
| Y
| 0
| ?!
| on
| bgcolor=lightgray |
|-
| 0012
| X
| W
| V
| 3
| U
| T
| S
| 1
| pi
| trig
| 10^x
|-
| 0014
| R
| Q
| P
| 6
| O
| N
| M
| 4
| EE
| x^2
| bgcolor=lightgray |
|-
| 0016
| L
| K
| J
| 9
| I
| H
| G
| 7
| /
| e^x
| bgcolor=lightgray |
|-
| 0018
| F
| E
| D
| bgcolor=lightgray |
| C
| B
| A
| =
| *
| ^
| bgcolor=lightgray |
|-
| 001A
| bgcolor=lightgray |
| var
| -
| )
| .
| (
| 5
| cat
| frac
| del
| scratch
|-
| 001C
| flag
| bgcolor=lightgray |
| +
| doc
| 2
| menu
| 8
| esc
| bgcolor=lightgray |
| tab
| bgcolor=lightgray |
|-
| 001E
| bgcolor=lightgray |
| bgcolor=lightgray |
| bgcolor=lightgray |
| bgcolor=lightgray |
| bgcolor=lightgray |
| bgcolor=lightgray |
| bgcolor=lightgray |
| bgcolor=lightgray |
| shift
| ctrl
| ,
|}


==90030000 - Fastboot RAM==
==Touchpad I²C==


4KiB of RAM, not cleared on resets/reboots.
Communication with the actual touchpad is done with the [http://en.wikipedia.org/wiki/I%C2%B2C I²C] protocol.


Only the lower 12 bits of the address are used, so the content aliases at 0x1000 and so on.
On the original Touchpad models, the I2C protocol is bitbanged through the GPIO: GPIO 1 is the Serial Clock (SCL) and GPIO 3 is the Serial Data Line (SDA). On the CX and CX II models, there is a dedicated [[Memory-mapped_I/O_ports#90050000_-_I2C_controller|I2C controller]] for accessing it.


The OS uses that to store some data which is used during boot to restore the previous state of the device.
Calculators before the CX II HW rev. AK use the Synaptics protocol, but later versions (indicated by bit 0 of the [[NAND_Memory_Layout#Manuf_Format|HW flags]]) use a custom touchpad and protocol called "CapTIvate".


The installer images use the area at 0x200 to store some variables for tracking the progress.
===Synaptics protocol===


==90040000 - SPI controller==
The touchpad seems to be a [http://read.pudn.com/downloads64/doc/fileformat/229278/510-501-rev4-tm603.pdf TM-603].
[http://lxr.free-electrons.com/source/drivers/input/mouse/synaptics_i2c.c The linux driver] is a good source for documentation.


FTSSP010 SPI controller connected to the LCD.
it responds to messages with address 0x20. A write message consists of the first port to write to, followed by the values to write: the port number auto-increments, so a message of <tt>00 de ad</tt> writes <tt>de</tt> to port <tt>00</tt> and <tt>ad</tt> to port <tt>01</tt>. A read message reads from whatever port was set by the previous write message, so it generally has to be preceded by an empty write to set the port.


==90050000 - I2C controller==
A list of some of the touchpad's ports follows. All 16-bit numbers are big-endian.


The Touchpad on the CX II is accessed through this controller. See [[Keypads#Touchpad I²C]] for protocol details. It seems to be a Synopsys Designware I2C adapter.
* Any page:
** FF: Page number
* Page 04 (default):
** 00: Contact (usually is 01 if proximity >= 0x2F, 00 otherwise)
** 01: Proximity
** 02-03: X position
** 04-05: Y position
** 06: relative X
** 07: relative Y (both refresh on irq)
** 0A: 1 if touchpad pressed down, 0 if not
** 0B: Status (reading this clears the low bits)
*** Bit 0 (0x01): Set when proximity is nonzero
*** Bit 1 (0x02): Set when velocity bytes are nonzero
*** Bit 2 (0x04): Set when unknown byte at 08 is nonzero
*** Bit 3 (0x08): Set when pressed byte has changed
*** Bit 6 (0x40): Set when the touchpad is configured
*** Bit 7 (0x80): Set when an error occured
** E4-E7: Firmware version
* Page 10:
** 04-05: Maximum X coordinate (0x0918)
** 06-07: Maximum Y coordinate (0x069B)


* 90050000 (R/W): Control register?
===CapTIvate protocol===
* 90050004 (?): ?
* 90050010 (R/W): Data/command register
* 90050014 (R/W): Speed divider for high period (standard speed) OS: 0x9c
* 90050018 (R/W): Speed divider for low period (standard speed) OS: 0xea
* 9005001c (R/W): Speed divider for high period (high speed) OS: 0x3b
* 90050020 (R/W): Speed divider for low period (high speed) OS: 0x2b
* 9005002c (R/W?): Interrupt status
* 90050030 (R/W): Interrupt mask
* 90050040 (R/W): Interrupt clear. Write 1 bits to clear
* 9005006c (R/W): Enable register
* 90050070 (R): Status register
* 90050074 (R?/W): TX FIFO?
* 90050078 (R?/W): RX FIFO?
* 900500f4 (?): ?
* 90050080 (?): ?


==90060000 - Watchdog timer==
The captivate touchpad seems to use an entirely custom protocol with less capabilities. It has a simpler structure: The first byte is a command byte, then data is either read or written, depending on the command.
Unlike the synaptics protocol, multi-byte values are little-endian.


Possibly an [http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0270b/index.html ARM SP805] or compatible. Runs at the APB clock frequency.
====01: Read "WHY_BOTHER_ME"====


==90070000 - Second Serial UART==
* Byte 0: 0/Unknown
* Byte 1: Flag byte
** Bit 0: Set if touchpad pressed
** Bit 1: Set if touchpad touched
** Bit 2: Clear if touchpad touched (?)
** Bit 3: Set if something changed after the last read
* Byte 2+3: X position
* Byte 4+5: Y position


[http://infocenter.arm.com/help/topic/com.arm.doc.ddi0183f/DDI0183.pdf PL011].
====03: Write unknown====


==90080000 - Cradle SPI Controller==
The OS writes a single byte here.


An FTSSP010 for communicating with the EEPROM in the cradle.
====06: Read status====


==90090000 - Real-Time Clock (RTC)==
* Byte 0: 0/Unknown
* Byte 1: Whether the touchpad is configured
* Byte 2-5: Unknown


Similar to the [http://infocenter.arm.com/help/topic/com.arm.doc.ddi0224b/index.html ARM PrimeCell PL031], but interrupt registers are different.
====07: Read size====


* 90090000 (R): Current time, increments by 1 every second.
* Byte 0: 0/Unknown
* 90090004 (R/W): Alarm value. When the time passes this, interrupt becomes active.
* Byte 1: 0/Unknown
* 90090008 (R/W): Sets the value of 90090000 (clock will not read new time until a couple seconds later). Reads last value written.
* Byte 2+3: Width
* 9009000C (R/W): Interrupt mask (1-bit)
* Byte 4+5: Height
* 90090010 (R/W): Masked interrupt status, reads 1 if interrupt active and mask bit is set. Write 1 to acknowledge.
* 90090014 (R): Status
** Bit 0: Time setting in progress
** Bit 1: Alarm setting in progress
** Bit 2: Interrupt acknowledgment in progress
** Bit 3: Interrupt mask setting in progress


==900A0000 - Miscellaneous==
====08: Read firmware version====


Seems to be similar to CX and Classic, except for the model ID at 900A0000 which is now 0x202.
    0, 0, 1, 0, 0, 4


==900B0000 - ADC==
====0A: Read unknown====


A Faraday FTADCC010.
Six unknown bytes.


==900C0000 - First timer==
====0C: Write unknown====


Same port structure as [[#900D0000 - Second timer|Second timer]].
The OS writes a single byte here.


==900D0000 - Second timer==
==Keypad Connector==
The Connector joining the keypads to the nspire itself has a very basic design concept: There are a bunch of GPIO pins, VCC, and GND. The OS memory-maps the pins to the bit chart seen above, using half as input, half as output. The same pins the touchpad uses for its I2C connection are used for buttons on the clickpad.


Timer is a [http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0271d/Babehiha.html SP804].
The pins are as follows:
1. Ground
2. Vcc
3-30. GPIO pins, alternating Column-Row-Column-Row


==900E0000 - Keypad controller==
On the 84+ Pad:
Pin 23 = Link port wire 1
Pin 25 = Link port wire 2


See also [[Keypads]] for information about the keypads themselves.


* 900E0000 (R/W):
The OS is constantly doing iskeypressed() on all the keys, so the pins end up looking like a square wave if read by a 'scope. Input pins only show the wave if one of their buttons is pressed, but output pins show the whole wave regardless.
** Bits 0-1: Scan mode
*** Mode 0: Idle.
*** Mode 1: Indiscriminate key detection. Data registers are not updated, but 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 cycles to wait before scanning each row
** Bits 16-31: Number of APB cycles to wait between scans
* 900E0004 (R/W):
** Bits 0-7: Number of rows to read (later rows are not updated in 900E0010-900E002F, 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 1 when it is updated)
* 900E0008 (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
* 900E000C (R/W): Keypad interrupt mask (3-bit). Set each bit to 1 if the corresponding event in [900E0008] should cause an interrupt.
* 900E0010-900E002F (R): Keypad data, one halfword per row.
* 900E0030-900E003F (R/W): Keypad GPIOs. Each register is 20 bits, with one bit per GPIO. The role of each register is unknown.
* 900E0040 (R/W): Interrupt enable. Bits unknown but seems to be related to touchpad. Causes interrupt on touchpad touched.
* 900E0044 (R/W): Interrupt status. Bits unknown. Write 1s to acknowledge.
* 900E0048 (R/W): Unknown


==90120000 - SDRAM Controller==
If you can't envision how the keys actually work yet, this might help:
All the buttons have 2 connectors, that get shorted when they are pressed.
The bits in the table above represent columns of buttons. It's not layed out perfectly because it has more than 8 buttons per column, so it gets offset strangely.
The bits in the offsets (the rows) represent rows of buttons.


An FTDDR3030.
The columns are each hooked to one Input pin.
The rows are each hooked to one output pin.
The calculator turns on ''One'' output pin, and looks for any signals on the inputs. If there are any, it records the button that matches the input pin and that column.
It then repeats this process for all the other columns, and the iskeypressed() process is complete.


==90130000 - Unknown Controller for the LCD Backlight==
If this doesn't make any sense still, email me (willrandship at gmail dot com) and I'll see if I can help.
 
--[[User:Willrandship|William Shipley]] 05:38, 16 September 2011 (CEST)
The OS controls the LCD backlight by writing to 90130018.
 
==90140000 - Power management==
 
A new "Aladdin PMU" unit. Not much known.
 
* 90140000 (R/?): Reason for waking up from low-power mode.
* 90140050 (R/W): Disable bus access to peripherals. Reads will just return the last word read from anywhere in the address range, and writes will be ignored.
** Bit 9: [[#C8010000 - Triple DES encryption]]
** Bit 10: [[#CC000000 - SHA-256 hash generator]]
** Bit 13: [[#90060000 - Watchdog timer]] (?)
** Bit 26: [[#90050000 - I2C controller]] (?)
* 90140050 (R/W): Disable bus access to peripherals. Reads will just return the last word read from anywhere in the address range, and writes will be ignored.
 
==A0000000 - Boot1 ROM again==
 
Mirror of the ROM at 0.
 
==A4000000 - Internal SRAM==
 
0x40000 bytes SRAM, managed by the controller at ?.
 
==A8000000 - Magic VRAM==
 
0x25800 bytes SRAM for an LCD framebuffer.
 
It is wired up in a way that the written data is X-Y swapped and rotated, so that writing a 320x240 image with (0/0) at the top left results in a 320x320 image in the right orientation for the LCD.
This means that it can't be used as generic RAM. How this mechanism works isn't known yet.
 
==B0000000 - USB OTG/Host/Device controller (top)==
 
An FOTG210 connected to the top USB port.
 
==B4000000 - USB OTG/Host/Device controller (bottom)==
 
An FOTG210 connected to the bottom USB port (dock connector).
 
==B8000000 - SPI NAND controller==
 
An FTSPI020 with a MICRON 1Gb flash at CS 1.
 
==BC000000 - DMA controller==
 
An FTDMAC020 with main SDRAM and LCD RAM (everything?) connected to AHB1. The OS uses this to copy the framebuffer into LCD RAM.
 
==C0000000 - LCD controller==
 
A [http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0293c/index.html PL111].
 
==C8010000 - Triple DES encryption==
 
Implements the [http://en.wikipedia.org/wiki/Triple_DES Triple DES encryption algorithm].
 
* C8010000 (R/W): Right half of block
* C8010004 (R/W): Left half of block. Writing this causes the block to be encrypted/decrypted.
* C8010008 (R/W): Right 32 bits of key 1
* C801000C (R/W):
** Bits 0-23: Left 24 bits of key 1
** Bit 30: Set to 0 to encrypt, 1 to decrypt
* C8010010 (R/W): Right 32 bits of key 2
* C8010014 (R/W): Left 24 bits of key 2
* C8010018 (R/W): Right 32 bits of key 3
* C801001C (R/W): Left 24 bits of key 3
 
==CC000000 - SHA-256 hash generator==
 
Implements the [http://en.wikipedia.org/wiki/SHA_hash_functions SHA-256 hash algorithm], which is used in cryptographic signatures.
 
* CC000000 (R): Busy if bit 0 set
* CC000000 (W): Write 0x10 and then 0x0 to initialize. Write 0xA to process first block, 0xE to process subsequent blocks
* CC000008 (R/W): Some sort of bus write-allow register? If a bit is set, it allows R/W access to the registers of the peripheral, if clear, R/O access only. Don't know what it's doing here, but it's here anyway.
** Bit 8: [[#CC000000 - SHA-256 hash generator]]
** Bit 10: ?
* CC000010-CC00004F (R/W): 512-bit block
* CC000060-CC00007F (R): 256-bit state
 
==DC000000 - Interrupt controller==
See [[Interrupts]]. The controller is a [http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0181e/index.html PL190].

Revision as of 18:03, 30 September 2020

Key maps

Each bit in the 900E0010-900E001F registers represents a key. Only bits 0 to 10 are used in each halfword. The mapping depends on the currently used keypad.

Clickpad keypad map:

If the bit is cleared, the key is being pressed.

offset bit 0 bit 1 bit 2 bit 3 bit 4 bit 5 bit 6 bit 7 bit 8 bit 9 bit 10
0010 ret enter space (-) Z . Y 0 X on theta
0012 , + W 3 V 2 U 1 T e^x pi
0014 ? - S 6 R 5 Q 4 P 10^x EE
0016 : * O 9 N 8 M 7 L x^2 i
0018 " / K tan J cos I sin H ^ >
001A ' cat G ) F ( E var D shift <
001C flag click C home B menu A esc | tab
001E up u+r right r+d down d+l left l+u del ctrl =

TI-84+ keypad map:

If the bit is cleared, the key is being pressed.

offset bit 0 bit 1 bit 2 bit 3 bit 4 bit 5 bit 6 bit 7 bit 8 bit 9 bit 10
0010 down left right up
0012 enter + - * / ^ clear
0014 (-) 3 6 9 ) tan vars
0016 . 2 5 8 ( cos prgm stat
0018 0 1 4 7 , sin apps X
001A on sto ln log x^2 x^-1 math alpha
001C graph trace zoom wind y= 2nd mode del
001E

Touchpad/CX/CM/CX II keypad map:

If the bit is set, the key is being pressed.

offset bit 0 bit 1 bit 2 bit 3 bit 4 bit 5 bit 6 bit 7 bit 8 bit 9 bit 10
0010 ret enter (-) space Z Y 0 ?! on
0012 X W V 3 U T S 1 pi trig 10^x
0014 R Q P 6 O N M 4 EE x^2
0016 L K J 9 I H G 7 / e^x
0018 F E D C B A = * ^
001A var - ) . ( 5 cat frac del scratch
001C flag + doc 2 menu 8 esc tab
001E shift ctrl ,

Touchpad I²C

Communication with the actual touchpad is done with the I²C protocol.

On the original Touchpad models, the I2C protocol is bitbanged through the GPIO: GPIO 1 is the Serial Clock (SCL) and GPIO 3 is the Serial Data Line (SDA). On the CX and CX II models, there is a dedicated I2C controller for accessing it.

Calculators before the CX II HW rev. AK use the Synaptics protocol, but later versions (indicated by bit 0 of the HW flags) use a custom touchpad and protocol called "CapTIvate".

Synaptics protocol

The touchpad seems to be a TM-603. The linux driver is a good source for documentation.

it responds to messages with address 0x20. A write message consists of the first port to write to, followed by the values to write: the port number auto-increments, so a message of 00 de ad writes de to port 00 and ad to port 01. A read message reads from whatever port was set by the previous write message, so it generally has to be preceded by an empty write to set the port.

A list of some of the touchpad's ports follows. All 16-bit numbers are big-endian.

  • Any page:
    • FF: Page number
  • Page 04 (default):
    • 00: Contact (usually is 01 if proximity >= 0x2F, 00 otherwise)
    • 01: Proximity
    • 02-03: X position
    • 04-05: Y position
    • 06: relative X
    • 07: relative Y (both refresh on irq)
    • 0A: 1 if touchpad pressed down, 0 if not
    • 0B: Status (reading this clears the low bits)
      • Bit 0 (0x01): Set when proximity is nonzero
      • Bit 1 (0x02): Set when velocity bytes are nonzero
      • Bit 2 (0x04): Set when unknown byte at 08 is nonzero
      • Bit 3 (0x08): Set when pressed byte has changed
      • Bit 6 (0x40): Set when the touchpad is configured
      • Bit 7 (0x80): Set when an error occured
    • E4-E7: Firmware version
  • Page 10:
    • 04-05: Maximum X coordinate (0x0918)
    • 06-07: Maximum Y coordinate (0x069B)

CapTIvate protocol

The captivate touchpad seems to use an entirely custom protocol with less capabilities. It has a simpler structure: The first byte is a command byte, then data is either read or written, depending on the command. Unlike the synaptics protocol, multi-byte values are little-endian.

01: Read "WHY_BOTHER_ME"

  • Byte 0: 0/Unknown
  • Byte 1: Flag byte
    • Bit 0: Set if touchpad pressed
    • Bit 1: Set if touchpad touched
    • Bit 2: Clear if touchpad touched (?)
    • Bit 3: Set if something changed after the last read
  • Byte 2+3: X position
  • Byte 4+5: Y position

03: Write unknown

The OS writes a single byte here.

06: Read status

  • Byte 0: 0/Unknown
  • Byte 1: Whether the touchpad is configured
  • Byte 2-5: Unknown

07: Read size

  • Byte 0: 0/Unknown
  • Byte 1: 0/Unknown
  • Byte 2+3: Width
  • Byte 4+5: Height

08: Read firmware version

   0, 0, 1, 0, 0, 4

0A: Read unknown

Six unknown bytes.

0C: Write unknown

The OS writes a single byte here.

Keypad Connector

The Connector joining the keypads to the nspire itself has a very basic design concept: There are a bunch of GPIO pins, VCC, and GND. The OS memory-maps the pins to the bit chart seen above, using half as input, half as output. The same pins the touchpad uses for its I2C connection are used for buttons on the clickpad.

The pins are as follows: 1. Ground 2. Vcc 3-30. GPIO pins, alternating Column-Row-Column-Row

On the 84+ Pad: Pin 23 = Link port wire 1 Pin 25 = Link port wire 2


The OS is constantly doing iskeypressed() on all the keys, so the pins end up looking like a square wave if read by a 'scope. Input pins only show the wave if one of their buttons is pressed, but output pins show the whole wave regardless.

If you can't envision how the keys actually work yet, this might help: All the buttons have 2 connectors, that get shorted when they are pressed. The bits in the table above represent columns of buttons. It's not layed out perfectly because it has more than 8 buttons per column, so it gets offset strangely. The bits in the offsets (the rows) represent rows of buttons.

The columns are each hooked to one Input pin. The rows are each hooked to one output pin. The calculator turns on One output pin, and looks for any signals on the inputs. If there are any, it records the button that matches the input pin and that column. It then repeats this process for all the other columns, and the iskeypressed() process is complete.

If this doesn't make any sense still, email me (willrandship at gmail dot com) and I'll see if I can help. --William Shipley 05:38, 16 September 2011 (CEST)