Advertisement
Guest User

Untitled

a guest
Apr 28th, 2018
120
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
ARM 13.18 KB | None | 0 0
  1.     AREA    GPIO, CODE, READWRITE
  2.     EXPORT uart_init
  3.     EXPORT pin_connect_block_setup
  4.     EXPORT read_from_push_btns
  5.     EXPORT illuminate_RGB_LED
  6.     EXPORT illuminate_LEDs
  7.     EXPORT write_to_7_segs
  8.     EXPORT read_character
  9.     EXPORT output_character
  10.     EXPORT output_string
  11.     EXPORT read_string
  12.     EXPORT div_and_mod
  13.  
  14. U0LSR EQU 0x14
  15. null_char EQU 0x0 ; Null character (\0)
  16.    
  17. button_result = "The number you input is: ",0
  18.  
  19.     ALIGN
  20.  
  21. digits_SET
  22. clear   DCD 0x0000B780
  23. char0   DCD 0x00003780  ; 0
  24. char1   DCD 0x00000300  ; 1
  25. char2   DCD 0x00009580  ; 2
  26. char3   DCD 0x00008780  ; 3
  27. char4   DCD 0x0000A300  ; 4
  28. char5   DCD 0x0000A680  ; 5
  29. char6   DCD 0x0000B680  ; 6
  30. char7   DCD 0x00000380  ; 7
  31. char8   DCD 0x0000B780  ; 8
  32. char9   DCD 0x0000A380  ; 9
  33. charA   DCD 0x0000B380  ; A
  34. charB   DCD 0x0000B600  ; B
  35. charC   DCD 0x00003480  ; C
  36. charD   DCD 0x00009700  ; D
  37. charE   DCD 0x0000B480  ; E
  38. charF   DCD 0x0000B080  ; F
  39.    
  40.     ALIGN
  41.  
  42.  
  43. uart_init
  44.     STMFD sp!, {r0, r1, r2, lr}
  45.     LDR r0, =0xE000C00C         ; UART0 Line Control Register Address (U0LCR)
  46.     LDRB r2, [r0]               ; Load U0LCR into r2
  47.     MOV r2, #131                ; Enable Divisor Latch Access Bit (DLAB)
  48.     STRB r2, [r0]
  49.  
  50.     SUB r0, r0, #0xC            ; Base Address of Lower Divisor Latch is 0xE000C000 (U0DLL)
  51.     LDRB r1, [r0]
  52.     MOV r1, #120
  53.     STRB r1, [r0]               ; Store LSB value for 9,600 Baud in U0DLL
  54.  
  55.     ADD r0, r0, #0x4            ; Base Address of Upper Divisor Latch is 0xE000C004 (U0DLM)
  56.     LDRB r1, [r0]
  57.     MOV r1, #0
  58.     STRB r1, [r0]               ; Store MSB value for 9,600 Baud in U0DLM
  59.  
  60.     ADD r0, r0, #8              ; UART0 Line Control Register Address (U0LCR)
  61.     MOV r2, #3                  ; 8-bit word length, 1 stop bit, no parity
  62.     STRB r2, [r0]               ; disable break control, disable divisor latch access
  63.     LDMFD sp!, {r0, r1, r2, lr}
  64.     BX lr
  65.  
  66.  
  67.     ; (DIGIT) P0.2-P0.5
  68.     ; (7-SEG) P0.7-P0.10, P0.12, P0.13
  69.     ; (RGB LED) P0.17, P0.18, P0.21
  70. pin_connect_block_setup    ; Conserves r0, r1, r2 and sets GPIO directions
  71.     STMFD sp!, {r0, r1-r2}
  72.     LDR r0, =0xE002C000         ; PINSEL0
  73.     LDR r1, [r0]                ; (DIGIT) P0.2-P0.5 & (7-SEG) P0.7-P0.10,  P0.12, P0.13, P0.15
  74.     LDR r2, =0xCF3FCFFA
  75.     BIC r1, r1, r2              ; Clear DIGIT & 7-SEG (00 = GPIO)
  76.     ORR r1, r1, #5              ; (UART0) P0.0, P0.1 (01 = UART0)
  77.     STR r1, [r0]
  78.     LDR r0, =0xE002C004         ; PINSEL1
  79.     LDR r1, [r0]                ; (RGB LED) P0.17, P0.18, P0.21
  80.     LDR r2, =0x00000C3C
  81.     BIC r1, r1, r2              ; Clear P0.17, P0.18, P0.21 (00 = GPIO)
  82.     STR r1, [r0]
  83.  
  84.     LDR r0, =0xE0028008         ; IO0DIR Set pin directions
  85.     LDR r1, [r0]                ; Output (set to 1) P0.2-P0.5, P0.7-P0.10,P0.12,
  86.     LDR r2, =0x0026B7BC
  87.     ORR r1, r1, r2              ;           P0.13, P0.15, P0.17, P0.18, P0.21
  88.     STR r1, [r0]
  89.  
  90.     LDR r0, =0xE0028018     ; IO1DIR Set pin directions Do we need this? Yes
  91.     LDR r1, [r0]
  92.     LDR r2, =0x000F0000
  93.     ORR r1, r1, r2
  94.     STR r1, [r0]
  95.     LDMFD sp!, {r0, r1, r2}
  96.     BX lr
  97.  
  98.  
  99. read_from_push_btns     ; Reads push buttons, returns value in r0. Conserves registers
  100.     STMFD sp!, {lr, r0-r4}
  101.     BL read_character
  102.     CMP r0, #0x20            ; Check if character is Space
  103.     LDR r1, =0xE0028010     ; Address of Port 1 Pin Value Register
  104.     BNE read_from_push_btns
  105.     LDREQ r2, [r1]          ; Load Pin Value Register
  106.     LDR r3, = 0x00F00000    ; Load Mask
  107.     AND r2, r2, r3          ; Mask Pin Values to extract button values
  108.     EOR r2, r2, r3
  109.     MOV r0, r2, LSR #20     ; Shift button values to bits 0-3
  110.  
  111.     ; Reverse bits
  112.     MOV r3, #0                                          ; Clear register for running sum
  113.     AND r1, r0, #1                                  ;
  114.     MOV r1, r1, LSL #3                          ; Mask to extract bit 0 and move to bit 3
  115.     ADD r3, r3, r1                                  ; Add to running sum
  116.     AND r1, r0, #2                                  ;
  117.     MOV r1, r1, LSL #1                          ; Mask to extract bit 1 and move to bit 2
  118.     ADD r3, r3, r1                                  ; Add to running sum
  119.     AND r1, r0, #4                                  ;
  120.     MOV r1, r1, LSR #1                          ; Mask to extract bit 2 and move to bit 1
  121.     ADD r3, r3, r1                                  ; Add to running sum
  122.     AND r1, r0, #8                                  ;
  123.     MOV r1, r1, LSR #3                          ; Mask to extract bit 3 and move to bit 0
  124.     ADD r3, r3, r1                                  ; Add to running sum
  125.     MOV r0, r3                                          ; Move running sum back for display
  126.  
  127.    
  128.     LDR r4, =button_result
  129.     BL output_string
  130.     CMP r0, #10                     ;
  131.     BGE greater_than_ten
  132.     ADD r0, r0, #0x30             ;
  133.     BL output_character           ; Display digit if less than 10
  134.     B done
  135.  
  136. greater_than_ten
  137.     MOV r1, r0
  138.     MOV r0, #0x31                  ;
  139.     BL output_character            ; Display 1 if digit is greater than 10
  140.     SUB r0, r1, #10               ;
  141.     ADD r0, r0, #0x30             ;
  142.     BL output_character            ; Then display value mod 10 if greater than 10
  143.  
  144. done
  145.     MOV r0, #0x0A                       ;
  146.     BL output_character             ;
  147.     BL output_character
  148.     MOV r0, #0x0D                       ;
  149.     BL output_character             ; New line for formatting
  150.     LDMFD sp!, {lr, r0-r4}
  151.     BX LR
  152.  
  153. illuminate_RGB_LED      ; Desired colour passed in r0, Conserves registers r0-r4 + lr
  154.     STMFD sp!, {lr, r0-r4}
  155.     LDR r1, =0xE0028004     ; IO0SET
  156.     LDR r2, =0xE002800C     ; IO0CLR
  157.     LDR r3, [r2]
  158.     LDR r4, [r1]
  159.     AND r3, r3, #0x0        ; Reset Output Register
  160.     AND r4, r4, #0x00260000 ; IO0CLR, turn off all LEDS (17. 18, 21) first
  161.     STR r4, [r1]            ; Store reset Clear register
  162.     ; On is 0, not 1?
  163.  
  164.     CMP r0, #0x6F               ; ascii o for off
  165.     ORREQ r4, r4, #0x00260000
  166.     STREQ r4, [r1]
  167.     BEQ RGB_DONE
  168.  
  169.     CMP r0, #0x72               ; ascii r for red
  170.     ORREQ r3, r3, #0x00020000   ; Output red (17)
  171.     BEQ RGB_DONE
  172.  
  173.     CMP r0, #0x67               ; ascii g for green
  174.     ORREQ r3, r3, #0x00200000   ; Output green (21)
  175.     BEQ RGB_DONE
  176.  
  177.     CMP r0, #0x62               ; ascii b for blue
  178.     ORREQ r3, r3, #0x00040000   ; Output blue (18)
  179.     BEQ RGB_DONE
  180.  
  181.     CMP r0, #0x70               ; ascii p for purple
  182.     ORREQ r3, r3, #0x00060000   ; Output purple (17 + 18)
  183.     BEQ RGB_DONE
  184.  
  185.     CMP r0, #0x79               ; ascii y for yellow
  186.     ORREQ r3, r3, #0x00220000   ; Output yellow (17 + 21)
  187.     BEQ RGB_DONE
  188.  
  189.     CMP r0, #0x77               ; ascii w for white
  190.     ORREQ r3, r3, #0x00260000   ; Output white (17 + 18 + 21)
  191.     BEQ RGB_DONE
  192.  
  193. RGB_DONE
  194.     STR r3, [r2]                ; Store colour combo in IO0SET
  195.     LDMFD sp!, {lr, r0-r4}
  196.     BX LR
  197.  
  198.  
  199. illuminate_LEDs                             ; conserves registers r0-r3, pattern in r0
  200.     STMFD sp!, {lr, r0-r3}
  201.     LDR r1, =0xE0028014                     ; Address of Output Set Register
  202.     LDR r2, =0xE002801C                     ; Address of Output Clear Register
  203.     MOV r3, #0xF                            ;
  204.     MOV r3, r3, LSL #16                     ; Shift pattern to correct pins
  205.     STR r3, [r1]                            ; Clear LEDs
  206.  
  207.  
  208.     ; Reverse bits
  209.     MOV r3, #0                                          ; Clear register for running sum
  210.     AND r1, r0, #1                                  ;
  211.     MOV r1, r1, LSL #3                          ; Mask to extract bit 0 and move to bit 3
  212.     ADD r3, r3, r1                                  ; Add to running sum
  213.     AND r1, r0, #2                                  ;
  214.     MOV r1, r1, LSL #1                          ; Mask to extract bit 1 and move to bit 2
  215.     ADD r3, r3, r1                                  ; Add to running sum
  216.     AND r1, r0, #4                                  ;
  217.     MOV r1, r1, LSR #1                          ; Mask to extract bit 2 and move to bit 1
  218.     ADD r3, r3, r1                                  ; Add to running sum
  219.     AND r1, r0, #8                                  ;
  220.     MOV r1, r1, LSR #3                          ; Mask to extract bit 3 and move to bit 0
  221.     ADD r3, r3, r1                                  ; Add to running sum
  222.     MOV r0, r3                                          ; Move running sum back for display
  223.  
  224.  
  225.    
  226.     MOV r0, r0, LSL #16                     ; Shift pattern to correct pins
  227.     STR r0, [r2]                            ; Illuminate LEDs
  228.     LDMFD sp!, {lr, r0-r3}
  229.     BX LR
  230.  
  231.  
  232. write_to_7_segs
  233.     STMFD sp!, {lr, r0-r5}                  ; Store link register and gp registers to stack
  234.     LDR r2, =0xE0028004                         ; Address of Output Set Register
  235.     LDR r3, =0xE002800C                         ; Address of Output Clear Register
  236.  
  237.     LDR r4, =0x3C
  238.     STR r4, [r2]
  239.     CMP r1, #0x30
  240.     LDREQ r4, =0x04
  241.     CMP r1, #0x31
  242.     LDREQ r4, =0x08
  243.     CMP r1, #0x32
  244.     LDREQ r4, =0x10
  245.     CMP r1, #0x33
  246.     LDREQ r4, =0x20
  247.     STR r4, [r3]
  248.  
  249.     CMP r0, #0x30                                   ; Check if character is 0
  250.     LDREQ r4, char0                                 ; Store seg values for 0 in r4
  251.     CMP r0, #0x31                                   ; Check if character is 1
  252.     LDREQ r4, char1                                 ; Store seg values for 1 in r4
  253.     CMP r0, #0x32                                   ; Check if character is 2
  254.     LDREQ r4, char2                                 ; Store seg values for 2 in r4
  255.     CMP r0, #0x33                                   ; Check if character is 3
  256.     LDREQ r4, char3                                 ; Store seg values for 3 in r4
  257.     CMP r0, #0x34                                   ; Check if character is 4
  258.     LDREQ r4, char4                                 ; Store seg values for 4 in r4
  259.     CMP r0, #0x35                                   ; Check if character is 5
  260.     LDREQ r4, char5                                 ; Store seg values for 5 in r4
  261.     CMP r0, #0x36                                   ; Check if character is 6
  262.     LDREQ r4, char6                                 ; Store seg values for 6 in r4
  263.     CMP r0, #0x37                                   ; Check if character is 7
  264.     LDREQ r4, char7                                 ; Store seg values for 7 in r4
  265.     CMP r0, #0x38                                   ; Check if character is 8
  266.     LDREQ r4, char8                                 ; Store seg values for 8 in r4
  267.     CMP r0, #0x39                                   ; Check if character is 9
  268.     LDREQ r4, char9                                 ; Store seg values for 9 in r4
  269.     CMP r0, #0x61                                   ; Check if character is a
  270.     LDREQ r4, charA                                 ; Store seg values for a in r4
  271.     CMP r0, #0x62                                   ; Check if character is b
  272.     LDREQ r4, charB                                 ; Store seg values for b in r4
  273.     CMP r0, #0x63                                   ; Check if character is c
  274.     LDREQ r4, charC                                 ; Store seg values for c in r4
  275.     CMP r0, #0x64                                   ; Check if character is d
  276.     LDREQ r4, charD                                 ; Store seg values for d in r4
  277.     CMP r0, #0x65                                   ; Check if character is e
  278.     LDREQ r4, charE                                 ; Store seg values for e in r4
  279.     CMP r0, #0x66                                   ; Check if character is f
  280.     LDREQ r4, charF                                 ; Store seg values for f in r4
  281.     LDR r5, clear                                   ;
  282.     STR r5, [r3]                                    ; Clear segments
  283.     STR r4, [r2]                                    ; Set segs to value
  284.     LDMFD sp!, {lr, r0-r5}
  285.     BX lr
  286.  
  287.  
  288. read_character                  ; RETURNS character in r0
  289.     STMFD sp!, {lr, r1-r3}
  290.     LDR r0, =0xE000C014         ; Load line status address into r0
  291. POLL
  292.     LDRB r1, [r0]               ; Load in UART0 Line Status Register
  293.     AND r1, r1, #0x00000001     ;
  294.     CMP r1, #0x00000001         ; Check U0LSR RSR Bit (Bit 0)
  295.     BNE POLL                    ; If RDR is not set, continue polling, else store byte
  296.  
  297.     SUB r0, r0, #U0LSR          ; U0RBR location = (UART0 Base + U0LSR) - U0LSR
  298.     LDRB r0, [r0]               ; Load received byte to r0, to be transmitted
  299.     LDMFD sp!, {lr, r1-r3}
  300.     BX lr
  301.  
  302.  
  303. read_string
  304.     STMFD sp!, {r0, r1, r4, lr}
  305. read_loop
  306.     BL read_character
  307.         BL output_character
  308.     STRB r0, [r4]                  ; Store character in memory
  309.     ADD r4, r4, #1                 ; Increment memory address
  310.     CMP r0, #13                    ; Check for Enter
  311.     BNE read_loop                  ; Continue reading characters until Enter
  312.  
  313.     SUB r4, r4, #1                 ;
  314.     MOV r0, #null_char             ;
  315.     STRB r0, [r4]                  ; Store null character at end of string
  316.  
  317.     LDMFD sp!, {r0, r1, r4, lr}
  318.     BX  lr
  319.  
  320.  
  321. output_character                ; Character PASSED in r0
  322.         STMFD sp!, {lr, r1-r3}
  323.         LDR r1, =0xE000C014         ; Load line status address into r1
  324. loop
  325.         LDRB r2, [r1]               ; Load status register into r2
  326.         AND r3, r2, #32             ; Clear all but bit 5 (32)
  327.         CMP r3, #32                 ;
  328.         BNE loop                    ; Loop back if THRE is 0
  329.         SUB r1, r1, #0x14           ; Adjust r1 to address for transmit reg
  330.         STRB r0, [r1]               ; Store byte (r0) in transmit reg
  331.         LDMFD sp!, {lr, r1-r3}
  332.         BX lr
  333.  
  334.  
  335. output_string                   ; Base address of string PASSED in r4
  336.     STMFD sp!, {r0-r3, r5, lr}  ; Store registers on stack, r2 and r3 are from output_character
  337.     MOV r5, #0                  ; r5 is offset for string in [r4], incremented by 1?
  338.     LDRB r0, [r4]               ; Store first character in r0 for output_character
  339. string_loop
  340.     BL output_character         ; Subroutine stores character byte in UART0 transmit reg
  341.     ADD r5, r5, #1              ; Increment offset (r2) by 1 (next byte)
  342.     LDRB r0, [r4, r5]           ; Store first character in r0 for output_character
  343.     CMP r0, #null_char          ; Check every r4+ and transmit, until null
  344.     BNE string_loop
  345.     LDMFD sp!, {r0-r3, r5, lr}  ; Load lr from stack, and used registers
  346.     BX lr
  347.  
  348.  
  349. div_and_mod
  350.     STMFD sp!, {r2-r6, lr}
  351.                           ; The dividend is passed in r10 and the divisor in r9.
  352.                           ; The quotient is returned in r10 and the remainder in r9.
  353.     MOV r5, #0            ; Initialize flag register to use for negating quotient
  354.     MVN r6, #0            ; Set r6 to 0xFFFFFFFF for use in sign change
  355.     CMP r10, #0           ; Check sign of r10
  356.     EORLT r10, r10, r6    ; Take one's complement if r10 is negative
  357.     ADDLT r10, r10, #1    ; Add one for two's complement
  358.     EORLT r5, r5, #1      ; Flip flag register if negative
  359.     CMP r9, #0            ; Check sign of r9
  360.     EORLT r9, r9, r6      ; One's complement if r9 is negative
  361.     ADDLT r9, r9, #1      ; Add one for two's complement
  362.     EORLT r5, r5, #1      ; Flip flag register if negative
  363.     MOV r2, #16           ; Initialize counter
  364.     MOV r3, #0            ; Initialize quotient to 0
  365.     MOV r9, r9, LSL #15   ; Shift divisor 15 places
  366.     MOV r4, r10           ; Initialize remainder to dividend
  367.  
  368. divide_loop
  369.     SUB r2, r2, #1        ; Decrement counter
  370.     SUB r4, r4, r9        ; Subtract divisor from remainder
  371.     CMP r4, #0            ;
  372.     BLT divide_negative   ; Branch if remainder is negative
  373.     MOV r3, r3, LSL #1    ;
  374.     ADD r3, r3, #1        ; Shift 1 into LSB of quotient
  375.     B next                ; Branch to next
  376.  
  377. divide_negative
  378.     ADD r4, r4, r9        ; Reset remainder by re-adding divisor
  379.     MOV r3, r3, LSL #1    ; Shift 0 into LSB
  380.  
  381. next
  382.     MOV r9, r9, LSR #1    ; Shift divisor to next bit
  383.     CMP r2, #0            ;
  384.     BGT divide_loop       ; Loop if counter is not 0
  385.     MOV r10, r3           ; Move quotient to r10
  386.     MOV r9, r4            ; Move remainder to r9
  387.     CMP r5, #1            ; Check flag register
  388.     EOREQ r10, r10, r6    ; One's complement if flag is 1
  389.     ADDEQ r10, r10, #1    ; Add one for two's complement
  390.  
  391.     LDMFD sp!, {r2-r6, lr}
  392.     BX lr                 ; Return to the C program
  393.  
  394.  
  395.  
  396.  
  397.     END
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement