Skip to content

Instantly share code, notes, and snippets.

@rrbutani
Created August 21, 2022 04:39
Show Gist options
  • Save rrbutani/1af0736a75ae07e0e9f5b2a43292d1d9 to your computer and use it in GitHub Desktop.
Save rrbutani/1af0736a75ae07e0e9f5b2a43292d1d9 to your computer and use it in GitHub Desktop.
LC3 GPIO Test
.orig 0x3000
; Set the stack pointer
LD R6, STARTING_SP
; Set up the loop:
LD R1, NUM_GPIO_PINS
NOT R1, R1
ADD R1, R1, #1
AND R0, R0, #0
LD R3, PIN_MAP_PTR
; Iterate over the 24 pins:
GPIO_PIN_LOOP
; do:
; Print the message:
ADD R2, R0, #0
LEA R0, TEST_START_STR_1
PUTS
LEA R0, TEST_START_STR_2
PUTS
ADD R0, R2, #0
JSR PRINT_PIN_NAME
LEA R0, TEST_START_STR_3
PUTS
LEA R0, TEST_START_STR_4
PUTS
ADD R4, R3, R2
LDR R0, R4, #0
PUTS
LEA R0, TEST_START_STR_5
PUTS
ADD R0, R2, #0
; Do the test:
JSR TEST_GPIO_PIN
ADD R0, R0, #1
; while (R0 - 24) != 0;
ADD R2, R1, R0
BRnp GPIO_PIN_LOOP
LEA R0, FIN
PUTS
HALT
TEST_START_STR_1 .fill x1B
.stringz "[37mTesting pin "
TEST_START_STR_2 .fill x1B
.stringz "[32mG"
TEST_START_STR_3 .fill x1B
.stringz "[30m ("
TEST_START_STR_4 .fill x1B
.stringz "[35m"
TEST_START_STR_5 .fill x1B
.stringz "[30m):\n"
FIN .stringz "Success!"
ASCII_A .fill #65
ASCII_0 .fill #48
NUM_GPIO_PINS .fill #24
STARTING_SP .fill 0x3400
PIN_MAP_PTR .fill PIN_MAP
;; R0: pin number
PRINT_PIN_NAME
; Need to extract the bank:
; 0b----0_0xxx -> 0x07
; 0b00001_1000 -> 0x18
; prologue
ADD R6, R6, #-4
STR R0, R6, #0
STR R1, R6, #1
STR R2, R6, #2
STR R3, R6, #3
; move R0 to R2; we need R0 for `PUTC`
ADD R2, R0, #0
; extract the bank:
LD R0, ASCII_A
LD R1, BANK_MASK
AND R1, R1, R2
; if R1 & BIT_3:
LD R3, BIT_3
AND R3, R1, R3
BRz SKIP_BIT3
ADD R0, R0, #1
; if R1 & BIT_4:
SKIP_BIT3
LD R3, BIT_4
AND R3, R1, R3
BRz SKIP_BIT4
ADD R0, R0, #2
SKIP_BIT4
; print the bank
OUT
; extract the pin:
LD R1, PIN_MASK
AND R1, R1, R2
LD R0, ASCII_0
ADD R0, R0, R1
OUT
; epilogue
LDR R3, R6, #3
LDR R2, R6, #2
LDR R1, R6, #1
LDR R0, R6, #0
ADD R6, R6, #4
RET
PIN_MASK .fill 0x07
BANK_MASK .fill 0x18
BIT_3 .fill 0x08
BIT_4 .fill 0x10
SUCCESS .fill x1B
.stringz "[96m success!\n" ; TODO: colors!
DELAY_1S
; prologue
ADD R6, R6, #-2
STR R0, R6, #0
STR R1, R6, #1
TRAP x71
ADD R1, R0, #0
; R1 is the starting time plus 1000, negated
;
; R0 - R1 > 1000
; -> R0 - (R1 + 1000) > 0
LD R0, ONE_SECOND_IN_MS
ADD R1, R0, R1
NOT R1, R1
ADD R1, R1, #1
; Spin while not positive:
TRAP x71
ADD R0, R1, R0
BRnz #-3
; epilogue
LDR R1, R6, #1
LDR R0, R6, #0
ADD R6, R6, #2
RET
ONE_SECOND_IN_MS .fill #1000
;; R0: pin number
TEST_GPIO_PIN
; prologue
ADD R6, R6, #-5
STR R0, R6, #0
STR R1, R6, #1
STR R2, R6, #2
STR R3, R6, #3
STR R7, R6, #4
; Copy R0 to R2:
ADD R2, R0, #0
;;;;;;;;;;;; Output Checks:
; Put pin in output mode:
TRAP x31
; Check output: 0
AND R1, R1, #0
TRAP x35
LEA R0, CHECK_OUTPUT_LO
PUTS
; GETC
LEA R0, SUCCESS
PUTS
; Check output: 1
ADD R0, R2, #0
ADD R1, R1, #1
TRAP x35
LEA R0, CHECK_OUTPUT_HI
PUTS
GETC
LEA R0, SUCCESS
PUTS
; Write 0 to pin again:
ADD R0, R2, #0
AND R1, R1, #0
TRAP x35
LEA R0, CHECK_OUTPUT_LO
PUTS
GETC
LEA R0, SUCCESS
PUTS
; Write 1 to pin and then disable pin; verify that it's low:
ADD R0, R2, #0
AND R1, R1, #1
TRAP x35
TRAP x33
LEA R0, CHECK_OUTPUT_LO
PUTS
GETC
LEA R0, SUCCESS
PUTS
;;;;;;;;;;;; Input Checks:
; Put pin in input mode:
ADD R0, R2, #0
TRAP x30
; Check input: 1
LEA R0, WAITING_FOR_INPUT_HI
PUTS
ADD R0, R2, #0
TRAP x36
ADD R0, R0, #0
BRz #-4 ; Spin until reading is 1
LEA R0, SUCCESS
PUTS
; Check input: 0
LEA R0, WAITING_FOR_INPUT_LO
PUTS
ADD R0, R2, #0
TRAP x36
ADD R0, R0, #0
BRnp #-4 ; Spin until reading is 0
LEA R0, SUCCESS
PUTS
;;;;;;;;;;;; Interrupt Checks:
; Pause:
JSR DELAY_1S
; Set INT_TRIGGERED (used to communicate with the ISR):
AND R0, R0, #0
ADD R0, R0, #-3 ; we want 3 interrupts!
ST R0, INT_TRIGGERED
; Put the pin in interrupt mode:
ADD R0, R2, #0
LD R1, GPIO_TEST_ISR_PTR
TRAP x32
; Wait for interrupt:
LEA R0, WAITING_FOR_INTERRUPT
PUTS
; Spin while `INT_TRIGGERED` is negative:
LD R0, INT_TRIGGERED
BRn #-2
LEA R0, SUCCESS
PUTS
; Fin:
LEA R0, NEWL
PUTS
PUTS
LEA R0, CLEAR
PUTS
; Disable pin:
ADD R0, R2, #0
TRAP x33
; epilogue
LDR R7, R6, #4
LDR R3, R6, #3
LDR R2, R6, #2
LDR R1, R6, #1
LDR R0, R6, #0
ADD R6, R6, #5
RET
INT_TRIGGERED .fill #0
GPIO_TEST_ISR_PTR .fill GPIO_TEST_ISR
CHECK_OUTPUT_LO .fill x1B
.stringz "[30m is the pin low? (type to continue) "
CHECK_OUTPUT_HI .fill x1B
.stringz "[30m is the pin high? (type to continue) "
WAITING_FOR_INPUT_LO .fill x1B
.stringz "[30m waiting for input pin to go low... "
WAITING_FOR_INPUT_HI .fill x1B
.stringz "[30m waiting for input pin to go high... "
WAITING_FOR_INTERRUPT .fill x1B
.stringz "[30m waiting for 3 interrupts on pin... "
NEWL .stringz "\n"
CLEAR .fill x1B
.stringz "[30m"
GPIO_TEST_ISR
; prologue
ADD R6, R6, #-1
STR R0, R6, #0
LD R0, INT_TRIGGERED
ADD R0, R0, #1
ST R0, INT_TRIGGERED
; epilogue
LDR R0, R6, #0
ADD R6, R6, #1
RTI
;;;;;;;;;;;;;;;;;;;;;;;; PIN MAP ;;;;;;;;;;;;;;;;;;;;;;;;
GA0 .stringz "PF1"
GA1 .stringz "PF2"
GA2 .stringz "PF3"
GA3 .stringz "PF0"
GA4 .stringz "PF4"
GA5 .stringz "PC4"
GA6 .stringz "PC5"
GA7 .stringz "PD1"
GB0 .stringz "PD2"
GB1 .stringz "PD3"
GB2 .stringz "PA2"
GB3 .stringz "PA3"
GB4 .stringz "PA4"
GB5 .stringz "PA5"
GB6 .stringz "PA6"
GB7 .stringz "PA7"
GC0 .stringz "PB0"
GC1 .stringz "PB1"
GC2 .stringz "PB2"
GC3 .stringz "PB3"
GC4 .stringz "PB4"
GC5 .stringz "PB5"
GC6 .stringz "PB6"
GC7 .stringz "PB7"
PIN_MAP
.fill GA0
.fill GA1
.fill GA2
.fill GA3
.fill GA4
.fill GA5
.fill GA6
.fill GA7
.fill GB0
.fill GB1
.fill GB2
.fill GB3
.fill GB4
.fill GB5
.fill GB6
.fill GB7
.fill GC0
.fill GC1
.fill GC2
.fill GC3
.fill GC4
.fill GC5
.fill GC6
.fill GC7
.end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment