Advertisement
Guest User

Untitled

a guest
Nov 26th, 2014
142
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.97 KB | None | 0 0
  1. ;*-------------------------------------------------------------------
  2. ;* Name: lab_4_program.s
  3. ;* Purpose: A sample style for lab-4
  4. ;* Term: Winter 2013
  5. ;*-------------------------------------------------------------------
  6. THUMB ; Declare THUMB instruction set
  7. AREA My_code, CODE, READONLY ;
  8. EXPORT __MAIN ; Label __MAIN is used externally
  9. EXPORT EINT3_IRQHandler ; We do this to override the default behaviour
  10. ENTRY
  11.  
  12. __MAIN
  13.  
  14.  
  15. ; The following lines are similar to previous labs.
  16. ; They just turn off all LEDs
  17. LDR R10, =LED_BASE_ADR ; R10 is a pointer to the base address for the LEDs
  18. MOV R3, #0xB0000000
  19. STR R3, [r10, #0x20] ; Turn off three LEDs on port 1
  20. MOV R3, #0x0000007C
  21. STR R3, [R10, #0x40] ; Turn off five LEDs on port 2
  22. ; This line is very important in your main program
  23. ; Initializes R11 to a 16-bit non-zero value and NOTHING else can write to R11 !!
  24. MOV R11, #0xABCD ; Init the random number generator with a non-zero number
  25. ; Generate a 16 bit random number
  26. BL RNG
  27.  
  28. ; R11 has a random number 16 bits in length. We store that in r0.
  29. MOV R0, R11
  30. ; We will use these values later.
  31. MOV R8, #0x64 ; 100
  32. MOV R12, #0x7A ; 122
  33. ; roundabout way of getting the the randomly generated 16 bits. We shift them 16 bits to the left to get rid of the garbage top 16 bits, then we shift back to the
  34. ; right to get the proper 16 bit number back.
  35. LSL R0, R0, #16
  36. LSR R0, R0, #16
  37. ; Now, the max number that can be generated from the random number generator is 2^16 - 1, i.e 65535. Now, first, we want to generate
  38. ; a 0 - 8 second delay, so we want to scale 65535 to 80000, which is why we multiply the value in r0 by 122.
  39. ; Then we divide by a 100, becayuse we want to scale the number
  40. ; up by a factor of 1.22 as the max value is 65535 to 80,000. This value, when passed to the delay method, will
  41. ; generate a 0 - 8 second delay
  42. MUL R0, R12
  43. UDIV R0, R8
  44. ; we move 20000 into r1
  45. MOV R1, #0x4e20
  46. ; offsets the delay 2 by adding 20000 to r0, so our delay will be from 2 - 10 seconds.
  47. ADD R0, R0, R1 ; 20000 in hex (2 seconds)
  48. ; R5 will count up to R0 and we'll be done it'll increment by 2500
  49. MOV R5, #0x9C4
  50. ; and R5 will count up to R7 so we'll move R0
  51. MOV R7, R0
  52.  
  53. ; Now we want to turn LEDs 3 on port 1 ON and then 4 on port 2 off and switch
  54. loopLEDSOnAndOff
  55.  
  56. ; ; we need the 3 leds on port 1 on first so 31, 29, 28 bits need to be 0 while the rest are 1
  57. ; ; that ends up being 0x4FFFFFFF
  58.  
  59. MOV R4, #0x000F
  60.  
  61. BL DISPLAY_NUM
  62.  
  63.  
  64. ; ; we need a delay of 0.25s which is 250ms which means 2500*0.1ms = 250ms
  65. MOV R0, #0x9C4 ; this 2500 in hex
  66. BL DELAY
  67.  
  68. ; Let's decrement by 2500
  69. SUBS R7, R7, R5
  70. BLE randomNumberDone
  71.  
  72.  
  73. MOV R4, #0x00F0
  74. BL DISPLAY_NUM
  75.  
  76.  
  77. ; we'll also delay for another 0.25 seconds before looping again
  78. MOV R0, #0x9C4 ; this is 2500 in hex
  79. BL DELAY
  80.  
  81. SUBS R7, R7, R5
  82. BLE randomNumberDone
  83.  
  84. B loopLEDSOnAndOff
  85.  
  86.  
  87. randomNumberDone
  88.  
  89.  
  90.  
  91. ; initialize R6 to 1, and later on check
  92. LDR R9, =ISER0 ;
  93. MOV R8, #0x200000
  94. STR R8, [R9] ; This will set the twenty first bit as 1
  95. LDR R9, =IO2IntEnf ; Pointer to GPIO Interrupt Enable for port 2 Falling Edge
  96. LDR R8, [R9]
  97. ORR R8, #0x400 ; This number, in binary, has its tenth bit as 1.
  98. STR R8, [R9] ; This will set the tenth bit as 1.
  99.  
  100. ; increment this counter with a 0.1 delay and poll for INT0
  101. ; we'll reset out counter (R4) to 0 before we start
  102. ; the loop
  103. MOV R4, #0x0
  104.  
  105. ; We only want to delay by 1ms, so we move 1 into r0.
  106. MOV R0, #0x10
  107.  
  108. ; R5 and R7 will be used for the LEDS
  109. MOV R7, #0xFF
  110. ; R6 is initalized with 1
  111. MOV R6, #0x1
  112. flashLedsAndCount
  113.  
  114. ; we need to flip the bits so we can use eors
  115. EOR R7, #0xFF ; flips port 2 leds
  116. MOV R5, R4
  117. MOV R4, R7
  118. BL DISPLAY_NUM
  119. MOV R4, R5
  120. ; we'll use R8 to basically count up to some frequency
  121. ; while also incrementing R4 (which is the elapsed time)
  122. MOV R8, #0x64 ; this is 100
  123. loopCountDelay
  124. ; for 1ms
  125. MOV R0, #0x10
  126.  
  127. ; we start by delaying for 0.1ms.
  128. BL DELAY
  129.  
  130. ; after the delay, we increment the counter.
  131. ADD R4, R4, #1
  132. ; we'll do a check in the middle of the inner loop
  133. ; just incase if the isr was called in here and we
  134. ; need to handle R6's 0 value
  135. CMP R6, #0x0
  136. BEQ displayTheNumber
  137. SUBS R8, R8, #0x1
  138.  
  139. BNE loopCountDelay
  140. ; we should check if the ISR basically set R6 to 0 or not
  141. CMP R6, #0x0
  142. BEQ displayTheNumber
  143.  
  144. B flashLedsAndCount
  145. displayTheNumber
  146.  
  147.  
  148. ; now we can display the number
  149. BL DISPLAY_NUM
  150.  
  151. MOV R0, #0xc350 ; about 5 seconds delay, before we display the number again.
  152.  
  153. BL DELAY
  154. B displayTheNumber
  155. ;*-------------------------------------------------------------------
  156. ; Subroutine RNG ... Generates a pseudo-Random Number in R11
  157. ;*-------------------------------------------------------------------
  158. ; R11 holds a random number as per the Linear feedback shift register (Fibonacci) on WikiPedia
  159. ; R11 MUST be initialized to a non-zero 16-bit value at the start of the program
  160. ; R11 can be read anywhere in the code but must only be written to by this subroutine
  161. RNG STMFD R13!,{R1-R3, R14} ; Random Number Generator
  162. AND R1, R11, #0x8000
  163. AND R2, R11, #0x2000
  164. LSL R2, #2
  165. EOR R3, R1, R2
  166. AND R1, R11, #0x1000
  167. LSL R1, #3
  168. EOR R3, R3, R1
  169. AND R1, R11, #0x0400
  170. LSL R1, #5
  171. EOR R3, R3, R1 ; The new bit to go into the LSB is present
  172. LSR R3, #15
  173. LSL R11, #1
  174. ORR R11, R11, R3
  175. LDMFD R13!,{R1-R3, R15}
  176.  
  177. ;*-------------------------------------------------------------------
  178. ; Subroutine DELAY ... Causes a delay of 1ms * R0 times
  179. ;*-------------------------------------------------------------------
  180. ; aim for better than 10% accuracy
  181. DELAY STMFD R13!,{R4, R14}
  182. MultipleDelay TEQ R0, #0 ; test R0 to see if it's 0 - set Zero flag so you can use BEQ, BNE
  183. BEQ exitDelay
  184. ; About 0.1ms
  185. MOV R4, #0x80
  186. delayLoopR4Times
  187. SUBS R4, R4, #1
  188. BNE delayLoopR4Times
  189. SUBS R0, R0, #1
  190. BNE MultipleDelay
  191. exitDelay LDMFD R13!,{R4, R15}
  192.  
  193.  
  194. ; This procedure Displays the number in R4 onto the 8 LEDs
  195.  
  196. ; We start by storing the registers we modify on the stack
  197. DISPLAY_NUM STMFD R13!,{R2, R3, R4, R5, R6, R7, R14}
  198. displayAgainLoop
  199.  
  200. MOV R2, #0x0 ; This will hold the bit values for the port 1 LEDs
  201. MOV R3, #0x0 ; This will hold the bit values for the port 2 LEDs
  202. MOV R5, R4
  203. LSL R5, #24
  204. LSR R5, #24
  205. ; reverse the bits
  206. RBIT R5, R5
  207. LSR R5, #24
  208. EOR R5, R5, #0xFF
  209. ; grabs the last 2 bits and stores them in R6
  210. LSL R6, R5, #30
  211. ; r6 has the bits in 31 and 30 we move it down to 29 and 28
  212. LSR R6, R6, #2
  213. ; grabs the third last bit
  214. AND R7, R5, #0x4
  215. ; we move it into it`s position
  216. LSL R7, R7, #29
  217. ORR R6, R7, R6
  218. ; r6 now has the proper stuff for port1
  219. STR R6, [R10, #0x20]
  220. LSR R7, R5, #1
  221. AND R7, R7, #0x7C
  222. STR R7, [R10, #0x40]
  223.  
  224. LSR R4, R4, #8 ; When we've displayed the first 8 bits, we'll remove them from the register
  225. CMP R4, #0 ; We compare if r4 is zero. If it is, then we are done. Otherwise, we go back and do the same for the next 8 bits.
  226.  
  227. BEQ endDisplayLoop
  228.  
  229. ; We need to wait 2 seconds
  230. ; and display the next 8 bits
  231. ; depending on if they exist
  232. MOV R0, #20000
  233. BL DELAY
  234. B displayAgainLoop
  235.  
  236. endDisplayLoop
  237. ; restore the values from the stack.
  238. LDMFD R13!,{R2, R3, R4, R5, R6, R7, R15}
  239.  
  240. ; The Interrupt Service Routine MUST be in the startup file for simulation
  241. ; to work correctly. Add it where there is the label "EINT3_IRQHandler
  242. ;
  243. ;*-------------------------------------------------------------------
  244. ; Interrupt Service Routine (ISR) for EINT3_IRQHandler
  245. ;*-------------------------------------------------------------------
  246. ; This ISR handles the interrupt triggered when the INT0 push-button is pressed
  247. ; with the assumption that the interrupt activation is done in the main program
  248. EINT3_IRQHandler
  249. STMFD R13!,{R8, R9, R14} ; Use this command if you need it
  250.  
  251. ; Lets basically just set R6 to 0
  252. MOV R6, #0x0
  253. LDR R9, =IO2IntClr ; Pointer to GPIO Interrupt Enable for port 2 Falling Edge
  254. LDR R8, [R9]
  255. ORR R8, R8, #0x400 ; This number, in binary, has its tenth bit as 1
  256. STR R8, [R9] ; This will set the tenth bit as 1.
  257.  
  258. ; For debugging
  259. ;MOV R0, #0xc350
  260. ;BL DELAY
  261.  
  262. LDMFD R13!,{R8, R9, R15} ; Use this command if you used STMFD (otherwise use BX LR)
  263.  
  264.  
  265. ;*-------------------------------------------------------------------
  266. ; Below is a list of useful registers with their respective memory addresses.
  267. ;*-------------------------------------------------------------------
  268. LED_BASE_ADR EQU 0x2009c000 ; Base address of the memory that controls the LEDs
  269. PINSEL3 EQU 0x4002C00C ; Pin Select Register 3 for P1[31:16]
  270. PINSEL4 EQU 0x4002C010 ; Pin Select Register 4 for P2[15:0]
  271. FIO1DIR EQU 0x2009C020 ; Fast Input Output Direction Register for Port 1
  272. FIO2DIR EQU 0x2009C040 ; Fast Input Output Direction Register for Port 2
  273. FIO1SET EQU 0x2009C038 ; Fast Input Output Set Register for Port 1
  274. FIO2SET EQU 0x2009C058 ; Fast Input Output Set Register for Port 2
  275. FIO1CLR EQU 0x2009C03C ; Fast Input Output Clear Register for Port 1
  276. FIO2CLR EQU 0x2009C05C ; Fast Input Output Clear Register for Port 2
  277. IO2IntEnf EQU 0x400280B4 ; GPIO Interrupt Enable for port 2 Falling Edge
  278. ISER0 EQU 0xE000E100 ; Interrupt Set-Enable Register 0
  279. IO2IntClr EQU 0x400280AC ; GPIO Interrupt Clear register for port 0
  280. ALIGN
  281.  
  282. END
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement