Created
August 21, 2022 04:39
-
-
Save rrbutani/1af0736a75ae07e0e9f5b2a43292d1d9 to your computer and use it in GitHub Desktop.
LC3 GPIO Test
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.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