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
|
||||
*.x86_64
|
||||
*.hex
|
||||
*.bin
|
||||
|
||||
# Debug files
|
||||
*.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