Initial version
Tested: - UART debug output works at 115200 baud (pad S15) - Jumps to bootloader on watchdog timeout - Jumps to bootloader when Return is held while plugging in USB - Jumps to bootloader when UTX/URX lines are shorted - Measured max GPIO toggling speed is 3MHz
This commit is contained in:
@@ -35,6 +35,7 @@
|
|||||||
*.i*86
|
*.i*86
|
||||||
*.x86_64
|
*.x86_64
|
||||||
*.hex
|
*.hex
|
||||||
|
*.bin
|
||||||
|
|
||||||
# Debug files
|
# Debug files
|
||||||
*.dSYM/
|
*.dSYM/
|
||||||
|
|||||||
@@ -0,0 +1,176 @@
|
|||||||
|
CHIP SN8F2288
|
||||||
|
|
||||||
|
//{{SONIX_CODE_OPTION
|
||||||
|
; Options for Lenovo Compact Keyboard
|
||||||
|
.Code_Option Fcpu "Fosc/4"
|
||||||
|
.Code_Option Fslow "Flosc/2"
|
||||||
|
.Code_Option High_CLK "12M_X'tal"
|
||||||
|
.Code_Option LVD "LVD_M"
|
||||||
|
.Code_Option Reset_Pin "P07"
|
||||||
|
.Code_Option Rst_Length "No"
|
||||||
|
.Code_Option Security "Enable"
|
||||||
|
.Code_Option Watch_Dog "Enable"
|
||||||
|
//}}SONIX_CODE_OPTION
|
||||||
|
|
||||||
|
.DATA
|
||||||
|
_canary_check EQU 0x2880
|
||||||
|
_flasher EQU 0x2890
|
||||||
|
UTX EQU P0.6 ; S15
|
||||||
|
UTTXIRQ EQU INTRQ1.3
|
||||||
|
URX EQU P0.5 ; S10
|
||||||
|
S10 EQU P0.5
|
||||||
|
R6 EQU P1.5
|
||||||
|
|
||||||
|
.CODE
|
||||||
|
ORG 0x0 ; Reset vector
|
||||||
|
; Jump to bootloader, checks canary and continues execution at 0x10 if found
|
||||||
|
JMP _canary_check
|
||||||
|
|
||||||
|
ORG 0x8 ; Interrupt vector
|
||||||
|
JMP _flasher
|
||||||
|
|
||||||
|
ORG 0x10 ; Bootloader jumps here on successful canary check, start of payload execution
|
||||||
|
_start:
|
||||||
|
; Set stack pointer and disable interrupts
|
||||||
|
MOV A, #7
|
||||||
|
B0MOV STKP, A
|
||||||
|
|
||||||
|
MOV A, #0
|
||||||
|
B0MOV RBANK, A
|
||||||
|
|
||||||
|
; Jump into bootloader if watchdog triggered or undefined reset source
|
||||||
|
B0BTS1 FNT0
|
||||||
|
JMP _flasher ; NT0 == 0 => watchdog reset or undefined reason
|
||||||
|
|
||||||
|
; Light up the power LED (P5.3/PWM0)
|
||||||
|
B0BCLR P5.3 ; Set to low level to light up
|
||||||
|
B0BSET P5M.3 ; Set to output
|
||||||
|
|
||||||
|
; DS indicates watchdog may start running before CPU
|
||||||
|
; Tickle it once so we have a well-defined time left
|
||||||
|
MOV A, #0x5a
|
||||||
|
B0MOV WDTR, A
|
||||||
|
|
||||||
|
; Set up P0.6/UTX (UART TX)
|
||||||
|
B0BSET P0UR.6 ; Enable pull-up (UART idle is high)
|
||||||
|
B0BCLR P0M.6 ; Set to input (TXEN will override to output)
|
||||||
|
MOV A, #0x60 ; Baud 115200
|
||||||
|
B0MOV URBRC, A
|
||||||
|
MOV A, #0x90 ; 24MHz clock, TX enabled, 8n1, 1-byte mode
|
||||||
|
B0MOV URTX, A
|
||||||
|
|
||||||
|
; Send a message that we are alive
|
||||||
|
MOV A, #'H'
|
||||||
|
CALL _uart_tx
|
||||||
|
MOV A, #'i'
|
||||||
|
CALL _uart_tx
|
||||||
|
MOV A, #'!'
|
||||||
|
CALL _uart_tx
|
||||||
|
MOV A, #13
|
||||||
|
CALL _uart_tx
|
||||||
|
MOV A, #10
|
||||||
|
CALL _uart_tx
|
||||||
|
|
||||||
|
; Jump into bootloader if "Return" key (S10/R6) is held
|
||||||
|
B0BSET P0M.5 ; Set S10 to output
|
||||||
|
B0BCLR P1M.5 ; Set R6 to input
|
||||||
|
B0BSET P1UR.5 ; Enable pull-up on R6
|
||||||
|
|
||||||
|
B0BSET S10 ; Set S10 high
|
||||||
|
CALL _delayshort
|
||||||
|
B0BTS1 R6 ; Jump if R6 is low
|
||||||
|
JMP @F
|
||||||
|
B0BCLR S10 ; Set S10 low
|
||||||
|
CALL _delayshort
|
||||||
|
B0BTS1 R6 ; Jump if R6 is low
|
||||||
|
JMP _return_held
|
||||||
|
@@:
|
||||||
|
|
||||||
|
; Jump into bootloader if P0.5/P0.6 are shorted (URX/UTX)
|
||||||
|
B0BCLR 0xa9.4 ; Switch UTX back to GPIO
|
||||||
|
B0BSET P0M.6 ; Set UTX to output
|
||||||
|
B0BCLR P0M.5 ; Set URX to input
|
||||||
|
B0BSET P0UR.5 ; Enable pull-up on URX
|
||||||
|
|
||||||
|
B0BSET UTX ; Set P0.6/UTX high
|
||||||
|
CALL _delayshort
|
||||||
|
B0BTS1 URX ; Jump if P0.5/URX is low
|
||||||
|
JMP @F
|
||||||
|
B0BCLR UTX ; Set P0.6/UTX low
|
||||||
|
CALL _delayshort
|
||||||
|
B0BTS1 URX ; Jump if P0.5/URX is low
|
||||||
|
JMP _uart_shorted
|
||||||
|
@@:
|
||||||
|
B0BSET 0xa9.4 ; Switch UTX back to UART
|
||||||
|
|
||||||
|
|
||||||
|
; Reset either from undervoltage (power-on) or external reset
|
||||||
|
; Cold reset state per datasheet:
|
||||||
|
; - Clock is 12MHz PLL synced to external oscillator
|
||||||
|
; - IOs set to input
|
||||||
|
|
||||||
|
MOV A, #0
|
||||||
|
B0MOV Y, A
|
||||||
|
@@:
|
||||||
|
MOV A, Y
|
||||||
|
CALL _uart_hex
|
||||||
|
INCMS Y
|
||||||
|
NOP
|
||||||
|
JMP @B
|
||||||
|
|
||||||
|
JMP _flasher
|
||||||
|
|
||||||
|
_return_held:
|
||||||
|
MOV A, #'E'
|
||||||
|
CALL _uart_tx
|
||||||
|
MOV A, #'r'
|
||||||
|
CALL _uart_tx
|
||||||
|
JMP _flasher
|
||||||
|
|
||||||
|
_uart_shorted:
|
||||||
|
B0BSET 0xa9.4 ; Switch UTX back to UART
|
||||||
|
MOV A, #'E'
|
||||||
|
CALL _uart_tx
|
||||||
|
MOV A, #'s'
|
||||||
|
CALL _uart_tx
|
||||||
|
JMP _flasher
|
||||||
|
|
||||||
|
_uart_hex:
|
||||||
|
MOV R, A
|
||||||
|
SWAP R
|
||||||
|
CALL _uart_nibble
|
||||||
|
MOV A, R
|
||||||
|
; fall-through
|
||||||
|
|
||||||
|
_uart_nibble:
|
||||||
|
AND A, #0xf
|
||||||
|
ADD A, #0xf6 ; -0xa
|
||||||
|
B0BTS0 FC ; Skip next insn if carry unset
|
||||||
|
ADD A, #0x27 ; 'a' - '0' - 0xa
|
||||||
|
ADD A, #0x3a ; '0' + 0xa
|
||||||
|
; fall-through
|
||||||
|
|
||||||
|
_uart_tx:
|
||||||
|
B0MOV URTXD1, A
|
||||||
|
@@:
|
||||||
|
B0BTS1 FUTTXIRQ ; Check if TX is done
|
||||||
|
JMP @B
|
||||||
|
B0BCLR FUTTXIRQ
|
||||||
|
RET
|
||||||
|
|
||||||
|
_delayshort:
|
||||||
|
MOV A, #0
|
||||||
|
B0MOV R, A
|
||||||
|
@@:
|
||||||
|
DECMS R
|
||||||
|
JMP @B
|
||||||
|
RET
|
||||||
|
|
||||||
|
ORG 0x27ff
|
||||||
|
DW 0xaaaa ; canary
|
||||||
|
|
||||||
|
ORG _canary_check
|
||||||
|
JMP _start
|
||||||
|
|
||||||
|
ORG _flasher
|
||||||
|
JMP $
|
||||||
+86
@@ -0,0 +1,86 @@
|
|||||||
|
PIN1/P1.2: R2
|
||||||
|
PIN2/P1.1/SDA: R3
|
||||||
|
PIN3/P1.0/SCL: R0
|
||||||
|
PIN4/P0.0/INT0: ?NC?
|
||||||
|
PIN5/P0.1/INT1: ?NC?
|
||||||
|
PIN6/P0.2: ?NC?
|
||||||
|
[PIN7/VDD]
|
||||||
|
PIN8/P4.0/AIN0: S2
|
||||||
|
PIN9/P4.1/AIN1: S4
|
||||||
|
PIN10/P4.2/AIN2: S7
|
||||||
|
PIN11/P4.3/AIN3: S8
|
||||||
|
PIN12/P4.4/AIN4: S6
|
||||||
|
[corner]
|
||||||
|
PIN13/P4.5/AIN5: S3
|
||||||
|
PIN14/P4.6/AIN6: S12
|
||||||
|
PIN15/P4.7/AIN7: S13
|
||||||
|
[PIN16/VSS]
|
||||||
|
PIN17/P0.3: S14
|
||||||
|
PIN18/P0.4: S11
|
||||||
|
PIN19/P0.5/URX: S10/KSO10
|
||||||
|
PIN20/P0.6/UTX: S15/KSO15
|
||||||
|
PIN21/P0.7/RST
|
||||||
|
[PIN22/XIN]
|
||||||
|
[PIN23/XOUT]
|
||||||
|
[PIN24/VREG25]
|
||||||
|
[corner]
|
||||||
|
[PIN25/VSS]
|
||||||
|
[PIN26/D+]
|
||||||
|
[PIN27/D-]
|
||||||
|
[PIN28/VREG33]
|
||||||
|
[PIN29/VDD]
|
||||||
|
PIN30/P2.0/SCK: S1
|
||||||
|
PIN31/P2.1/SDO: S5
|
||||||
|
PIN32/P2.2/SDI: S0
|
||||||
|
PIN33/P2.3: S9
|
||||||
|
PIN34/P2.4: trackpoint SCL
|
||||||
|
PIN35/P2.5: trackpoint SDA
|
||||||
|
PIN36/P2.6: trackpoint IRQ
|
||||||
|
[corner]
|
||||||
|
PIN37/P2.7: ?NC?
|
||||||
|
PIN38/P5.0: ?NC?
|
||||||
|
PIN39/P5.1: ?NC?
|
||||||
|
PIN40/P5.2: ?NC?
|
||||||
|
PIN41/P5.3/PWM0: LED D1
|
||||||
|
PIN42/P5.4/PWM1 ?NC?
|
||||||
|
PIN43/P5.5/PWM2 ?NC?
|
||||||
|
PIN44/P1.7 R1
|
||||||
|
PIN45/P1.6 R7
|
||||||
|
PIN46/P1.5 R6
|
||||||
|
PIN47/P1.4: R4
|
||||||
|
PIN48/P1.3: R5
|
||||||
|
|
||||||
|
Keyboard connector (PCB labels):
|
||||||
|
R1 R6 R4 S0 R3 S1 S2 S7 S6 S12 S14 S10 MG MM
|
||||||
|
R7 S9 R5 R2 S5 R0 S4 S8 S3 S13 S11 S15 ML MR
|
||||||
|
|
||||||
|
Alternative names (S230U schematic):
|
||||||
|
KSI1 KSI6 KSI4 KSO0 KSI3 KSO1 KSO2 KSO7 KSO6 KSO12 KSO14 KSO10 GND IPD_MIDDLE
|
||||||
|
KSI7 KSO9 KSI5 KSI2 KSO5 KSI0 KSO4 KSO8 KSO3 KSO13 KSO11 KSO15 IPD_LEFT IPD_RIGHT
|
||||||
|
|
||||||
|
Pin1: KSI1
|
||||||
|
Pin2: KSI7
|
||||||
|
[...]
|
||||||
|
Pin27: IPD_MIDDLE
|
||||||
|
Pin28: IPD_RIGHT
|
||||||
|
|
||||||
|
Keyboard matrix (annotated ku1255_sim.py output):
|
||||||
|
P1.0 P1.1 P1.2 P1.3 P1.4 P1.5 P1.6 P1.7
|
||||||
|
R0 R3 R2 R5 R4 R6 R7 R1
|
||||||
|
|
||||||
|
UP (none) (none) END (none) PAUSE LEFT KP_MEMSTORE P0.3/S14
|
||||||
|
(none) HOME (none) F11 (none) (none) DOWN (none) P0.4/S11
|
||||||
|
F5 F9 INTERNATIONAL3 F10 BACKSLASH RETURN SPACE BACKSPACE P0.5/S10
|
||||||
|
(none) DELETE (none) INSERT PRINTSCREEN PAGEUP PAGEDOWN (none) P0.6/S15
|
||||||
|
F4 F2 E 3 D C (none) F3 P2.0/S1
|
||||||
|
H 6 U 7 J M N Y P2.1/S5
|
||||||
|
ESCAPE GRAVE Q 1 A Z INTERNATIONAL5 TAB P2.2/S0
|
||||||
|
(none) (none) (none) (none) (none) RSHIFT (none) LSHIFT P2.3/S9
|
||||||
|
NONUSBACKSLASH F1 W 2 S X (none) CAPSLOCK P4.0/S2
|
||||||
|
G 5 R 4 F V B T P4.1/S4
|
||||||
|
INTERNATIONAL4 F8 O 9 L PERIOD INTERNATIONAL2 F7 P4.2/S7
|
||||||
|
APOSTROPHE MINUS P 0 SEMICOLON NONUSHASH SLASH LEFTBRACKET P4.3/S8
|
||||||
|
F6 EQUALS I 8 K COMMA INTERNATIONAL1 RIGHTBRACKET P4.4/S6
|
||||||
|
(none) LCTRL (none) (none) (none) RCTRL (none) (none) P4.5/S3
|
||||||
|
LALT KP_MEMSUBTRACT (none) (none) (none) (none) RALT (none) P4.6/S12
|
||||||
|
(none) (none) KP_MEMCLEAR F12 (none) (none) RIGHT LGUI P4.7/S13
|
||||||
Reference in New Issue
Block a user