Advertisement
Guest User

Untitled

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