Advertisement
Guest User

Untitled

a guest
Oct 31st, 2014
154
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.29 KB | None | 0 0
  1. ;*----------------------------------------------------------------------------
  2. ;* Name: Lab_2_program.s
  3. ;* Purpose: This code template is for Lab 2
  4. ;* Author: Eric Praetzel and Rasoul Keshavarzi
  5. ;* Lab 2 code added by: Jobair Hassan, Maaz Ali
  6. ;*----------------------------------------------------------------------------*/
  7. THUMB ; Declare THUMB instruction set
  8. AREA My_code, CODE, READONLY ;
  9. EXPORT __MAIN ; Label __MAIN is used externally q
  10. ENTRY
  11. __MAIN
  12. ; The following lines are similar to Lab-1 but use an address, in r4, to make it easier.
  13. ; Note that one still needs to use the offsets of 0x20 and 0x40 to access the ports
  14. ;
  15. ; Turn off all LEDs
  16. MOV R2, #0xC000 ; move 0xC000 into R2
  17. MOV R3, #0xB0000000 ; This value, when stored in the addresses for ports, will turn off the LED
  18. MOV R4, #0x0
  19. MOVT R4, #0x2009
  20. ADD R4, R4, R2 ; 0x2009C000 - the base address for dealing with the ports
  21. STR R3, [r4, #0x20] ; Turn off the three LEDs on port 1
  22. MOV R3, #0x0000007C
  23. STR R3, [R4, #0x40] ; Turn off five LEDs on port 2
  24.  
  25. ResetLUT
  26. LDR R5, =InputLUT ; assign R5 to the address at label LUT. This address contains the word for which we will flash the morse code of.
  27.  
  28. ;;;;;;;;;;;;;;;;;
  29. ; Gets the next character and converts it into morse code sequence, and stores this into R1.
  30. ;;;;;;;;;;;;;;;;;
  31.  
  32. NextChar
  33.  
  34. LDRB R0, [R5] ; Read a character to convert to Morse
  35. ADD R5, #1 ; point to next value for number of delays, jump by 1 byte
  36. TEQ R0, #0 ; If we hit 0 (null at end of the string) then reset to the start of lookup table
  37. BNE ProcessChar ; If we have a character process it
  38.  
  39. MOV R0, #4 ; delay 4 extra spaces (7 total) between words
  40. BL DELAY
  41. BEQ ResetLUT
  42.  
  43. ProcessChar BL CHAR2MORSE ; convert ASCII to Morse pattern in R1
  44.  
  45. ; First - loop until we have a 1 bit to send
  46. ;
  47. ; This is confusing as we're shifting a 32-bit value left, but the data is ONLY in the lowest 16 bits, so test starting at bit 15 for 1 or 0
  48. ; Then loop thru all of the data bits:
  49. ;
  50.  
  51. ;;;;;;;;;;;;;;;;;;;;;;;;
  52. ; This is the main section of the program. What it essentially does is call methods like LED_ON, LED_OFF and DELAY
  53. ; and converts the morse code bits found in R1 into blinking LEDS depending on the bit sequence (1 or 0)
  54. ;;;;;;;;;;;;;;;;;;;;;;;;
  55.  
  56. ; We're going to assign 15 to R9 and let it count down to 0 (16 bits which is a half word, so it'll go through all of the relevant bits in R1
  57. MOV R9, #0xF
  58.  
  59. ; R8 is used is a flag (to skip the first n 0 bits)
  60. MOV R8, #0x0
  61.  
  62. morseCodeToLED
  63.  
  64.  
  65. ; This is our check, if we see that the counter has
  66. ; reached 0, we should stop processing the current character
  67. ; cause we're done, and move on to the next one.
  68. CMP R9, #0
  69. BLT goToNextChar
  70.  
  71. ; Decrementing the counter, we do this
  72. ; after checking the counter because we
  73. ; want to include the 0th bit as well
  74. SUB R9, R9, #1
  75.  
  76. ; We're basically initializing R6 to contain a bit sequence
  77. ; where the 15th bit is a 1 (00...001...000)
  78. ; then we'll do a bit wise and to check if the 15th bit of
  79. ; the morse code sequence is a 1 or a 0, depending on the result
  80. ; we'll either turn on the LED, or turn off the led
  81. ; Just before that, we make sure we do a left shift on the R1 register
  82. ; so the next time we go through the loop, we check the current 14th bit
  83. ; which will be the 15th bit after the shift.
  84. MOV R6, #0x8000 ; Init R6 with the value for the bit, 15th, which we wish to test
  85. ANDS R7, R1, R6 ; R7 gets R1 AND R6, Zero bit gets set telling us if the bit is 0 or 1
  86. LSL R1, R1, #1 ; shift R1 left by 1, store in R1
  87.  
  88. BEQ turnLEDOFF; branch somewhere it's zero
  89. BNE turnLEDON; branch somewhere - it's not zero
  90.  
  91. turnLEDOFF
  92. ; We want to skip the first
  93. ; n 0 bits, so if the first 1
  94. ; bit hasn't been encountered
  95. ; then go back to the starting of
  96. ; the loop
  97. CMP R8, #0x0
  98. BEQ morseCodeToLED
  99.  
  100.  
  101. ; Call the LED_OFF function
  102. ; to turn the LED_OFF
  103. BL LED_OFF
  104.  
  105. ; Set a delay of 500ms (LED_OFF for 500ms)
  106. MOV R0, #1
  107. BL DELAY
  108. B restartLoop
  109.  
  110. turnLEDON
  111.  
  112. ; turn the LED ON
  113. BL LED_ON
  114.  
  115. ; Since we've encountered a 1 bit
  116. ; we can set the flag to 1 so now if
  117. ; 0 bits are encountered, they will
  118. ; turn the LED_OFF for 500ms
  119. MOV R8, #0x1
  120.  
  121. ; Set a delay for 500ms
  122. MOV R0, #1
  123. BL DELAY
  124.  
  125.  
  126.  
  127. restartLoop
  128. ; Simply restart the loop
  129. ; the checks to exit will be
  130. ; done there
  131. B morseCodeToLED ; Process next char
  132.  
  133. goToNextChar
  134. ; We're done processing the character
  135. ; we want to set a 1.5s delay before we
  136. ; start processing the next character
  137. BL LED_OFF
  138. MOV R0, #3
  139. BL DELAY
  140. B NextChar
  141.  
  142.  
  143.  
  144. ENDLOOP B ENDLOOP ; This is the end of the main program
  145.  
  146.  
  147. ; Subroutines
  148. ;
  149. ; convert ASCII character to Morse pattern
  150. ; pass ASCII character in R0, output in R1
  151. ; index into MorseLuT must be by steps of 2 bytes
  152. CHAR2MORSE STMFD R13!,{R2, R14} ; push Link Register (return address) on stack
  153. ; Subtract 41 to get the index so we can use it for MorseLUT
  154. SUB R0, R0, #0x41
  155.  
  156. ; Grab the address of MorseLUT into R2
  157. LDR R2, =MorseLUT
  158.  
  159. ; Get the morse of sequence of the character into R1
  160. LDRH R1, [R2, R0, LSL #1]
  161.  
  162. LDMFD R13!,{R2, R15} ; restore LR to R15 the Program Counter to return
  163.  
  164.  
  165. ; Turn the LED on, but deal with the stack in a simpler way
  166. ; NOTE: This method of returning from subroutine (BX LR) does NOT work if subroutines are nested!!
  167. ;
  168. LED_ON push {r2-r4} ; preserve R3 and R4 on the R13 stack
  169.  
  170.  
  171. ; MOV R2, #0xC000
  172. ; MOV R3, #0xB0000000
  173. ; MOV R4, #0x0
  174. ; MOVT R4, #0x2009
  175. ; ADD R4, R4, R2 ; 0x2009C000 - the base address for dealing with the ports
  176.  
  177. ; Turn on address for LED on Port 1
  178. MOV R3, #0x0
  179. MOVT R3, #0xA000
  180. STR R3, [r4, #0x20] ; Turn ON the LED on port 1
  181.  
  182. pop {r2-r4}
  183. BX LR ; branch to the address in the Link Register. Ie return to the caller
  184.  
  185. ; Turn the LED off, but deal with the stack in the proper way
  186. ; the Link register gets pushed onto the stack so that subroutines can be nested
  187. ;
  188. LED_OFF STMFD R13!,{R3, R14} ; push R3 and Link Register (return address) on stack
  189.  
  190. ; Turn off address for LED on Port 1
  191. MOV R3, #0x0
  192. MOVT R3, #0xB000
  193. STR R3, [R4, #0x20] ; Turn off the LED on port 1
  194.  
  195.  
  196. LDMFD R13!,{R3, R15} ; restore R3 and LR to R15 the Program Counter to return
  197.  
  198. ; Delay 500ms * R0 times
  199. ; Use the delay loop from Lab-1 but loop R0 times around
  200. ;
  201. DELAY STMFD R13!,{R2, R4, R14}
  202. MultipleDelay TEQ R0, #0 ; test R0 to see if it's 0 - set Zero flag so you can use BEQ, BNE
  203.  
  204. BEQ exitDelay
  205.  
  206. ; This is likely about 1s, so we need to
  207. ; measure this to be around 500ms
  208. MOV R4, #0x0000
  209. MOVT R4, #0x000B ; 0x000577FF
  210.  
  211. delayLoopR4Times
  212.  
  213. SUBS R4, R4, #1
  214. BNE delayLoopR4Times
  215.  
  216. SUBS R0, R0, #1
  217. BNE MultipleDelay
  218.  
  219.  
  220.  
  221.  
  222. exitDelay LDMFD R13!,{R2, R4, R15}
  223.  
  224. ; We most likely don't need this
  225. ;BX LR
  226.  
  227.  
  228. ;
  229. ; Data used in the program
  230. ; DCB is Define Constant Byte size
  231. ; DCW is Define Constant Word (16-bit) size
  232. ; EQU is EQUate or assign a value. This takes no memory but instead of typing the same address in many places one can just use an EQU
  233. ;
  234. ALIGN ; make sure things fall on word addresses
  235.  
  236. ; One way to provide a data to convert to Morse code is to use a string in memory.
  237. ; Simply read bytes of the string until the NULL or "0" is hit. This makes it very easy to loop until done.
  238. ;
  239. InputLUT DCB "SOS", 0 ; strings must be stored, and read, as BYTES
  240.  
  241. ALIGN ; make sure things fall on word addresses
  242. MorseLUT
  243. DCW 0x17, 0x1D5, 0x75D, 0x75 ; A, B, C, D
  244. DCW 0x1, 0x15D, 0x1DD, 0x55 ; E, F, G, H
  245. DCW 0x5, 0x1777, 0x1D7, 0x175 ; I, J, K, L
  246. DCW 0x77, 0x1D, 0x777, 0x5DD ; M, N, O, P
  247. DCW 0x1DD7, 0x5D, 0x15, 0x7 ; Q, R, S, T
  248. DCW 0x57, 0x157, 0x177, 0x757 ; U, V, W, X
  249. DCW 0x1D77, 0x775 ; Y, Z
  250.  
  251. ; One can also define an address using the EQUate directive
  252. ;
  253. LED_PORT_ADR EQU 0x2009c000 ; Base address of the memory that controls I/O like LEDs
  254.  
  255. END
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement