Advertisement
Guest User

Untitled

a guest
Nov 14th, 2018
163
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
ARM 10.99 KB | None | 0 0
  1.     PRESERVE8
  2.     AREA MyCode,CODE,READONLY
  3.     EXPORT config
  4.     EXPORT asm_pit1_irq
  5. PIT1_IRQHandler EQU asm_pit1_irq+1
  6.     EXPORT PIT1_IRQHandler      ;the vector table must contain odd addresses        for the Cortex processor
  7. PDB0_IRQHandler EQU asm_PDB0_irq+1
  8.     EXPORT PDB0_IRQHandler
  9. ADC0_IRQHandler EQU asm_ADC0_irq+1 ;the vector table must contain odd addresses for the Cortex processor
  10.     EXPORT ADC0_IRQHandler
  11. my_SIM_SCGC5 EQU    0x40048038      ;Address for SIM_SCGC5
  12. my_GPIOC_clken EQU  0x00000800      ;Clock gate enable for port A
  13. my_PORTC_PCR0 EQU   0x4004B000
  14. PORTC_PCR_VAL EQU   0x00000140
  15. my_GPIOC_PDDR EQU   0x400FF094
  16. my_GPIOC_PDOR EQU   0x400FF080
  17. my_GPIOC_PCOR EQU   0x400FF088
  18. my_GPIOC_PSOR EQU   0x400FF084
  19. GPIOC_PDDR_VAL EQU  0x000007FF
  20. my_SIM_SCGC6 EQU    0x4004803C
  21. my_SCGC6_value EQU  0x00800000
  22.    
  23. my_PIT_MCR EQU      0x40037000
  24. my_PIT_LDVAL1 EQU   0x40037110
  25. my_LDVAL1_value EQU 0x0000C34F
  26. my_PIT_TFLG1 EQU    0x4003711C
  27. my_PIT_TCTRL1 EQU   0x40037118
  28.    
  29. my_NVIC_addr EQU    0xE000E108
  30. my_NVIC_value EQU   0x00000020
  31. config
  32.  
  33. ;write 1 to bit {11} of SIM_SCGC5, enable Port C clock gate
  34.     LDR     r2, =my_SIM_SCGC5       ;0x40048038
  35.     LDR     r1, =my_GPIOC_clken     ;0x00000800
  36.     LDR     r3, [r2]
  37.     ORR     r3, r3, r1
  38.     STR     r3, [r2]                ;enable GPIO_PORTC
  39.  
  40. ;For PortC PCR0-PCR10:
  41. ;write 1 to bit {6}, DSE, high drive strength
  42. ;write 001 to bits {8-10}, MUX, alternative 1 GPIO
  43.     MOV     r4, #0
  44.     LDR     r2, =my_PORTC_PCR0      ;0x4004B000 address PortC PCR0
  45.     LDR     r1, =PORTC_PCR_VAL      ;0x00000140
  46. next_portc
  47.     STR r1,[r2], #4
  48.     ADD r4,r4,#1
  49.     CMP r4,#11
  50.     BNE next_portc
  51.    
  52. ;set PDDR PCR bits 0-10 to logic 1 - set them as outputs
  53. ;bits 0-10 set to 1 (= 0x07ff)
  54.     LDR     r2, =my_GPIOC_PDDR      ;0x4000FF094
  55.     LDR     r1, =GPIOC_PDDR_VAL     ;0x0000007FF
  56.     STR     r1, [r2]
  57.    
  58. ;initializing off at reset
  59.     LDR r2, =my_GPIOC_PDOR
  60.     LDR r5, =0x000000FF
  61.     STR r5,[r2]
  62.    
  63. ;Set PIT by writing 1 to bit {23} of SIM_SCGC6
  64.     LDR      r2,=my_SIM_SCGC6       ;0x4004803C
  65.     LDR      r1,=my_SCGC6_value     ;0x00800000
  66.     LDR      r0,[r2]
  67.     ORR      r0,r0,r1
  68.     STR      r0,[r2]                ;enable clock to PIT1
  69.  
  70. ;enable the PIT module (0 to bits {0-1} of the MCR)
  71.     LDR      r2,=my_PIT_MCR         ;0x40037000, memory address for PCR
  72.     MOV      r0,#0
  73.     STR      r0,[r2]                ;stores 0x0 into PCR
  74.    
  75. ;sets the timer to interrupt every 2s by writing LDVAL1
  76.     LDR      r2,=my_PIT_LDVAL1      ;0x40037110, memory address for PIT_LDVAL1
  77. ;want it to trigger every 1ms
  78. ;1ms/20ns - 1 =50e3 - 1 =0xC34F
  79.     LDR      r1,=my_LDVAL1_value    ;0xC34F
  80.     STR      r1,[r2]                ;load the count value to generate interrupt periodically
  81.  
  82. ;store 1 in bits {0,1} of TCTRL1, enable timer and interrupts
  83.     LDR      r2,=my_PIT_TCTRL1      ;0x40037118, memory address for PIT_TCTRL1
  84.     MOV      r0,#0x3
  85.     STR      r0,[r2]                ;set TIE and TEN bits
  86.  
  87. ;NVIC CONVIG
  88. ;69/32 = 2, write NVIC_ISER2
  89. ;69 mod 32 = 5, write 1 to bit {5} of NVIC_ISER2
  90.     LDR      r2,=my_NVIC_value      ;0x00000020 sets IRQ 69
  91.     LDR      r1,=my_NVIC_addr       ;0xE000E108
  92.     STR      r2, [r1]
  93.    
  94.    
  95.     LDR      r5, =value             ;loads address of value for 7seg
  96.    
  97. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  98.  
  99. ;Configure ADC port clock:
  100.      LDR  r2, =0x4004803C ;mem address for SIM_SCGC6
  101.      LDR  r3,=0x08400000  ;here we enable clock for PDB and ADC0
  102.      LDR  r4,[r2]
  103.      ORR  r4,r4,r3
  104.      STR  r4,[r2]
  105.      
  106. ;Configure DAC port clock:
  107.      LDR r2,=0x4004802C ;mem address for SIM_SCGC2
  108.      LDR r3,=0x00001000 ;enable clock for DAC0
  109.      LDR r4,[r2]
  110.      ORR r4,r4,r3
  111.      STR r4,[r2]
  112.      
  113. ;Activate PDB0
  114.      LDR  r2,=0x40048018 ;SIM_SOPT7
  115.      LDR  r3,=0x00000000 ;PDB selected for triggering ADC0
  116.      STR  r3,[r2]
  117.      
  118. ;Set PA7 as input for ADC10
  119.      LDR r2,=0x4004901C  ;PORTA_PCR7
  120.      LDR r3, =0x00000000 ;set as analog input
  121.      STR r3,[r2]
  122.      NOP
  123.      NOP
  124.      
  125. ;Configure programmable delay block
  126. ;PDB0_MOD specifies period of the counter
  127. ;Resets to 0 when it reaches this value
  128.     LDR r2,=0x40036004 ;PDB0_MOD
  129.     LDR r3,=0x1000     ;PDB0_MODmin
  130.     STR r3,[r2]
  131. ;PDB0_IDLY specifies the delay value to schedule the PDB interrupt
  132.     LDR r2,=0x4003600C ;PDB0_IDLY
  133.     LDR r3,=0x0        ;PDB0_IDLYvalue
  134.     STR r3,[r2]
  135. ;Write PDB0_CH0C1
  136. ;Select and enable pretrigger for ADC0 (1 to bits {0,8})
  137.     LDR r2,=0x40036010 ;PDB0_CH0C1
  138.     LDR r3,=0x00000101 ;CH0 pretrigger output is selected and enabled
  139.     STR r3,[r2]
  140. ;Write PDB0_POEN
  141. ;Enable pulse out for ADC0 (1 to bit {0})
  142.     LDR r2,=0x40036190 ;PDB0_POEN
  143.     LDR r3,=0x01       ;PDB pulse out enabled
  144.     STR r3,[r2]
  145. ;Write PDB0_PO0DLY
  146.     LDR r2,=0x40036194 ;PDB0_PO0DLY
  147.     LDR r3,=0x01001000 ;sets pulse output to 1 after 0x100 pulses and to 0 after 0x1000 pulses
  148.     STR r3,[r2]
  149. ;Write PDB0_SC
  150. ;LOADOK by writing 1 to bit {0}
  151. ;Continuous mode (1 to bit {1})
  152. ;MULT factor of 1 (00 to  bits {2-3})
  153. ;Enable software trigger (1111 to bits {8-11})
  154. ;Prescaler to 0 -> use MULT of 1 (000 to bits {12-14})
  155.     LDR r2,=0x40036000 ;PDB0_SC
  156.     LDR r3,=0x00000F83 ;set prescaler to 0 and MULT to 1
  157.     STR r3,[r2]
  158.  
  159. ;Configure ADC
  160. ;Write ADC0_CRFG1:
  161. ;Select bus clock/2 as input clock (01 to bits {0-1})
  162. ;Select single ended 16-bit conversion (11 to bit {2-3})
  163. ;Select long sample time (1 to bit {4})
  164. ;Select divide ratio of 8 and clock rate of input clock/8 (11 to bits {5-6})
  165.     LDR r2,=0x4003B008 ;ADC0_CFG1
  166.     LDR r3,=0x0000007D ;divide ratio 8, long sample time, single ended 16bit, bus_clock/2
  167.     STR r3,[r2]
  168. ;Write ADC0_CFG2
  169.     LDR r2,=0x4003B00C ;ADC0_CFG2
  170.     LDR r3,=0x0        ;ADxxa channels are selected, default longest sample time
  171.     STR r3,[r2]
  172. ;Write ADC0_SC2
  173.     LDR r2,=0x4003B020 ;ADC0_SC2
  174.     LDR r3,=0x00000040 ;set the hardware trigger PDB (1 to bit {6})
  175.     STR r3,[r2]
  176. ;Write ADC0_SC3
  177. ;Average 32 samples to create ADC average result (11 to bits {0-1})
  178.     LDR r2,=0x4003B024 ;ADC0_SC3
  179.     LDR r3,=0x0000000C ;Hardware average function enabled with continuous conversion
  180.     STR r3,[r2]
  181. ;need to initiate the ADC module before the PDB module, writing ADC0_SC1A will start the module
  182.     LDR r2,=0x4003B000 ;ADC0_SC1A      
  183.     LDR r3,=0x0000004A ;Interrupt enabled, ADC10 selected as single ended, input from primary connector B40 pin
  184.     STR r3,[r2]
  185.    
  186.     LDR r2,=0x40036000 ;PDB0_SC
  187.     LDR r3,=0x00010000 ;write bit 16 to start counting
  188.     LDR r4,[r2]
  189.     ORR r3,r3,r4
  190.     STR r3,[r2]  ;trigger the PDB0 channel
  191.  
  192. ;activate ADC0_IRQ57
  193. ;57/32 = 1, write NVIC_ISER1
  194. ;57 mod 32 = 25, write bit {25} in NVIC_ISER1
  195.     LDR r2,=0xE000E104 ;NVIC_ISER1
  196.     LDR r3,=0x02000000 ;sets bit 25 in NVIC_ISER1 for ADC0 interrupt IRQ#57
  197.     LDR r4,[r2]
  198.     ORR r4,r4,r3
  199.     STR r3,[r2]
  200.  
  201. ;activate PDB0_IRQ72
  202. ;72/32 = 2, write NVIC_ISER2
  203. ;72 mod 32 = 8, write bit {8} in NVIC_ISER2
  204.     LDR r2,=0xE000E108 ;NVIC_ISER2
  205.     LDR r3,=0x00000100 ;set bit 8 in NVIC_ISER2 for PDB0 interrupt IRQ#72
  206.     LDR r4,[r2]
  207.     ORR r3,r3,r4
  208.     STR r3,[r2]
  209.    
  210. loop B loop
  211.  
  212. asm_ADC0_irq
  213. ;COCO is set in ADC0_SC1A when the conversion is done
  214. ;this also triggers the interrupt
  215. ;see pp 826 in K60 Sub Family Reference Manual
  216.     CPSID i             ;disable interrupts
  217.     PUSH {lr}           ;store LR, to know how to return from irq
  218.     ;PUSH {r2-r5}       ;dont think this is needed
  219. ;next read the result register
  220.     LDR r2,=0x4003B010  ;ADC0_RA
  221.     LDR r0,[r2]         ;loads the adc voltage value into r0
  222. ;next transfer this value to DAC0
  223.     MOV r3,r0,LSR #4    ;divide by 16
  224.     LDR r2,=0x400CC000  ;DAC0_DAT0L
  225.     STRB r3,[r2],#1     ;should store the 8 lsb bits to DAC0, update mem address
  226.     LSR r3,r3,#8        ;divide by 256
  227.     STRB r3,[r2]        ;store in DAC0_DATH
  228.  
  229. ;Code for req3:
  230. ;//
  231.     ;LDR r2,=adc0counter    ;load base mem address of adc0counter
  232.     ;LDR r3,[r2]            ;load value of adc0counter
  233.     ;ADD r3,r3,#1       ;increment counter
  234.     ;str r3, [r2] ;new
  235.     ;CMP r3,#0x01000    ;I am waiting for 2^12 ADC conversions
  236.     B adc0tovolts
  237.     ;BEQ next0
  238.     ;STR r3,[r2],#4     ;store counter value in adc0counter, inc mem address
  239.     ;LDR r4,[r2]            ;load value from adc0counter+4
  240.     ;ADD r4,r4,r0       ;make the sum for average
  241.     ;STR r4,[r2]            ;store sum in adc0counter+4
  242.     ;B outofdac0
  243. ;next0
  244.     ;MOV r3,#0x1            ;reset counter
  245.     ;push {r0}
  246.     ;bl volts_valuef
  247.     ;pop {r0}
  248.     ;STR r3,[r2],#4     ;store 0x1 in adc0counter
  249.     ;LDR r4,[r2]            ;load value from adc0counter+4
  250.     ;LSR r4,r4,#12          ;here I am dividing by 2^12 -> get average
  251.     ;STR r4,[r2]            ;store average adc value into adc0counter+4
  252.     ;MOV r0,r4          ;move average into r0
  253.     ;B adc0tovolts      ;convert average to volts
  254. ;//
  255. outofdac0
  256.     CPSIE i
  257.     ;POP {r2-r5}
  258.     POP {pc}
  259.    
  260. vrange EQU 330
  261. bindiv EQU 0xFFFF
  262. ten EQU 10
  263. adc0tovolts
  264.     LDR r3,=vrange
  265.     LDR r4,=bindiv
  266.     MUL r3,r3,r0        ;r3 = 330 * avg adc value
  267.     UDIV r3,r3,r4       ;r3 = (330 * avg adc value)/((2^16)-1)
  268. ;we apply Volts value = (r0*3.30)/(2^16-1)
  269. ;next convert to BCD by dividing by 10 and keeping the remainders
  270.     LDR r2,=volts_value+2  ;set to the last digit
  271.     MOV r4,#0xA          ;the conversion base
  272. over
  273.     UDIV r5,r3,r4       ;divide voltage  by 10
  274.     MUL r6,r5,r4        ;multiply by 10
  275.     SUB r6,r3,r6        ;subtract original value
  276.     STRB r6,[r2],#-1    ;store into memory
  277.     CMP r5,r4      
  278.     BLT done_conv       ;done if divided value <10
  279.     MOV r3,r5           ;next iteration
  280.     B over
  281. done_conv
  282.     STRB r5,[r2];,#-1
  283.     LDR r4,=volts_value
  284. fillzero
  285.     CMP r2,r4
  286.     BEQ outofdac0
  287.     MOV r5,#0
  288.     STRB r5,[r2];,#-1
  289.     B fillzero
  290.  
  291. asm_PDB0_irq
  292.     PUSH {lr}   ;store LR, to know how to return from irq
  293.     PUSH {r2-r5}
  294.     LDR r2,=0x40036000 ;=myPDB0_SC      ;
  295.     LDR r3,=0xFFFFFFBF ;=myPDB0_PDBIF       ;  to clear PDBIF
  296.     LDR r4,[r2]
  297.     AND r4,r4,r3
  298.     STR r4,[r2]
  299.     LDR r2,=0x40036014 ;=myPDB0_CH0S        ;
  300.     LDR r3,=0x0 ;=myPDB0_CH0Svalue      ;
  301.     STR r3,[r2]
  302.     POP {r2-r5}
  303.     POP {pc}            ;return from interrupt
  304.  
  305.    
  306. asm_pit1_irq
  307.     PUSH     {lr}                   ;store LR
  308.     LDR      r4,=my_PIT_TFLG1       ;load memory address of TFLG1
  309.     MOV      r3,#0x01               ;1 to clear flag
  310.     STR      r3,[r4]                ;store 1 to the memory to clear flags
  311.     LDR      r1, =irqcounter        ;load memory address of counter
  312.     LDRB     r3,[r1]                ;loads value from counter into r3
  313.     B        sevSeg
  314.  
  315. sevSeg
  316.     ldr r12, =volts_value
  317.     LDR      r7, =sevSegTable       ;loads address of lookup table
  318.     add      r12, r12, r3
  319.     LDRB     r6, [r12]              ;loads value to be printed
  320.     LSL      r6, r6, #2             ;multiply value by 4
  321.     ADD      r6, r6, r7             ;add shift value to memory address
  322.     LDR      r8, [r6]               ;load value from lookup table
  323.     LDR      R9, =my_GPIOC_PDOR     ;load PDOR address to output
  324.     CMP      r3, #1                 ;branch to correct digit #
  325.     BEQ      dig_one
  326.     BGT      dig_two
  327.    
  328. dig_zero
  329.     ADD      r3,#1                  ;increment counter 
  330.     STRB     r3,[r1]                ;updating counter in memory
  331.     add      r8, r8, #0x400         ;0x400 turns on MS digit PTC10
  332.     sub      r8, r8, #0x80
  333.     str      r8, [r9]               ;store value in PDOR
  334.     pop      {pc}                   ;restore program
  335.    
  336. dig_one
  337.     ADD      r3,#1                  ;increment counter 
  338.     STRB     r3,[r1]                ;updating counter in memory
  339.     add      r8, r8, #0x200         ;0x200 turns on middle digit PTC9
  340.     str      r8, [r9]               ;store value in PDOR
  341.     POP      {pc}                   ;restore program
  342. dig_two
  343.     mov      r3, #0x0               ;reset counter (limit between 0 and 2)
  344.     strb     r3, [r1]               ;store 0 in counter memory
  345.     add      r8, r8, #0x100         ;0x100 turns on LS digit PTC8
  346.     STR      r8, [r9]               ;store value in PDOR
  347.     POP      {pc}                   ;restore program
  348.    
  349.  
  350.    
  351.     ALIGN
  352.     AREA MyData, DATA, READWRITE
  353. irqcounter  DCD 0x00
  354. value       DCD 0x04
  355.             DCD 0x02
  356.             DCD 0x00
  357. sevSegTable DCD 0xC0
  358.             DCD 0xF9
  359.             DCD 0xA4
  360.             DCD 0xB0
  361.             DCD 0x99
  362.             DCD 0x92
  363.             DCD 0x82
  364.             DCD 0xF8
  365.             DCD 0x98
  366.             DCD 0xFF    ;period
  367. adc0counter DCD 0x0
  368.             DCD 0x0
  369. volts_value DCD 0x0
  370.             DCD 0x0
  371.             DCD 0x0
  372.  
  373.     END
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement