Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- PRESERVE8
- AREA MyCode,CODE,READONLY
- EXPORT config
- ;IMPORT my_fprint
- ;IMPORT volts_valuef
- EXPORT asm_pit1_irq
- PIT1_IRQHandler EQU asm_pit1_irq+1
- EXPORT PIT1_IRQHandler ;the vector table must contain odd addresses for the Cortex processor
- ADC0_IRQHandler EQU asm_ADC0_irq+1 ;the vector table must contain odd addresses for the Cortex processor
- EXPORT ADC0_IRQHandler
- my_SIM_SCGC5 EQU 0x40048038 ;Address for SIM_SCGC5
- my_GPIOC_clken EQU 0x00000800 ;Clock gate enable for port A
- my_PORTC_PCR0 EQU 0x4004B000
- PORTC_PCR_VAL EQU 0x00000140
- ;my_GPIOA_PDOR EQU 0x400FF000
- my_GPIOC_PDDR EQU 0x400FF094
- my_GPIOC_PDOR EQU 0x400FF080
- my_GPIOC_PCOR EQU 0x400FF088
- my_GPIOC_PSOR EQU 0x400FF084
- ;GPIOA_PDOR_VAL EQU 0x30000800
- GPIOC_PDDR_VAL EQU 0x000007FF
- ;my_GPIOA_PCOR EQU 0x400FF008
- ;my_GPIOA_PSOR EQU 0x400FF004
- my_SIM_SCGC6 EQU 0x4004803C
- my_SCGC6_value EQU 0x00800000
- my_PIT_MCR EQU 0x40037000
- my_PIT_LDVAL1 EQU 0x40037110
- my_LDVAL1_value EQU 0x0000C34F
- my_PIT_TFLG1 EQU 0x4003711C
- my_PIT_TCTRL1 EQU 0x40037118
- my_NVIC_addr EQU 0xE000E108
- my_NVIC_value EQU 0x00000020
- config
- ;write 1 to bit {11} of SIM_SCGC5, enable Port C clock gate
- LDR r2, =my_SIM_SCGC5 ;0x40048038
- LDR r1, =my_GPIOC_clken ;0x00000800
- LDR r3, [r2]
- ORR r3, r3, r1
- STR r3, [r2] ;enable GPIO_PORTC
- ;For PortC PCR0-PCR10:
- ;write 1 to bit {6}, DSE, high drive strength
- ;write 001 to bits {8-10}, MUX, alternative 1 GPIO
- MOV r4, #0
- LDR r2, =my_PORTC_PCR0 ;0x4004B000 address PortC PCR0
- LDR r1, =PORTC_PCR_VAL ;0x00000140
- next_portc
- STR r1,[r2], #4
- ADD r4,r4,#1
- CMP r4,#11
- BNE next_portc
- ;set PDDR PCR bits 0-10 to logic 1 - set them as outputs
- ;bits 0-10 set to 1 (= 0x07ff)
- LDR r2, =my_GPIOC_PDDR ;0x4000FF094
- LDR r1, =GPIOC_PDDR_VAL ;0x0000007FF
- STR r1, [r2]
- ;initializing off at reset
- LDR r2, =my_GPIOC_PDOR
- LDR r5, =0x000000FF
- STR r5,[r2]
- ;Set PIT by writing 1 to bit {23} of SIM_SCGC6
- LDR r2,=my_SIM_SCGC6 ;0x4004803C
- LDR r1,=my_SCGC6_value ;0x00800000
- LDR r0,[r2]
- ORR r0,r0,r1
- STR r0,[r2] ;enable clock to PIT1
- ;enable the PIT module (0 to bits {0-1} of the MCR)
- LDR r2,=my_PIT_MCR ;0x40037000, memory address for PCR
- MOV r0,#0
- STR r0,[r2] ;stores 0x0 into PCR
- ;sets the timer to interrupt every 2s by writing LDVAL1
- LDR r2,=my_PIT_LDVAL1 ;0x40037110, memory address for PIT_LDVAL1
- ;want it to trigger every 1ms
- ;1ms/20ns - 1 =50e3 - 1 =0xC34F
- LDR r1,=my_LDVAL1_value ;0xC34F
- STR r1,[r2] ;load the count value to generate interrupt periodically
- ;store 1 in bits {0,1} of TCTRL1, enable timer and interrupts
- LDR r2,=my_PIT_TCTRL1 ;0x40037118, memory address for PIT_TCTRL1
- MOV r0,#0x3
- STR r0,[r2] ;set TIE and TEN bits
- ;NVIC CONVIG
- ;69/32 = 2, write NVIC_ISER2
- ;69 mod 32 = 5, write 1 to bit {5} of NVIC_ISER2
- LDR r2,=my_NVIC_value ;0x00000020 sets IRQ 69
- LDR r1,=my_NVIC_addr ;0xE000E108
- STR r2, [r1]
- ;LDR r5, =value ;loads address of value for 7seg
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;Configure ADC port clock:
- LDR r2, =0x4004803C ;mem address for SIM_SCGC6
- LDR r3,=0x08400000 ;here we enable clock for PDB and ADC0
- LDR r4,[r2]
- ORR r4,r4,r3
- STR r4,[r2]
- ;Configure DAC port clock:
- LDR r2,=0x4004802C ;mem address for SIM_SCGC2
- LDR r3,=0x00001000 ;enable clock for DAC0
- LDR r4,[r2]
- ORR r4,r4,r3
- STR r4,[r2]
- LDR r2, =0x400CC000
- MOV r3,#0x0
- STRB r3,[r2],#1
- STRB r3,[r2] ;clear the DAT0 data values
- LDR r2,=0x400CC020
- STRB r3,[r2],#1 ;clear flags in SR
- STRB r3,[r2],#1 ;clear C0
- STRB r3,[r2],#1 ;clear C1
- MOV r3,#0x0F
- STRB r3,[r2],#-2 ;initialize C2
- LSL r3,r3,#4 ;set C0 values
- STRB r3,[r2] ;start the DAC0, software trigger, use DACREF_2
- ;Activate PDB0
- LDR r2,=0x40048018 ;SIM_SOPT7
- LDR r3,=0x00000000 ;PDB selected for triggering ADC0
- STR r3,[r2]
- ;Set PA7 as input for ADC10
- LDR r2,=0x4004901C ;PORTA_PCR7
- LDR r3, =0x00000000 ;set as analog input
- STR r3,[r2]
- NOP
- NOP
- ;Configure programmable delay block
- ;PDB0_MOD specifies period of the counter
- ;Resets to 0 when it reaches this value
- LDR r2,=0x40036004 ;PDB0_MOD
- LDR r3,=0x1000 ;PDB0_MODmin
- STR r3,[r2]
- ;PDB0_IDLY specifies the delay value to schedule the PDB interrupt
- LDR r2,=0x4003600C ;PDB0_IDLY
- LDR r3,=0x0 ;PDB0_IDLYvalue
- STR r3,[r2]
- ;Write PDB0_CH0C1
- ;Select and enable pretrigger for ADC0 (1 to bits {0,8})
- LDR r2,=0x40036010 ;PDB0_CH0C1
- LDR r3,=0x00000101 ;CH0 pretrigger output is selected and enabled
- STR r3,[r2]
- ;Write PDB0_POEN
- ;Enable pulse out for ADC0 (1 to bit {0})
- LDR r2,=0x40036190 ;PDB0_POEN
- LDR r3,=0x01 ;PDB pulse out enabled
- STR r3,[r2]
- ;Write PDB0_PO0DLY
- LDR r2,=0x40036194 ;PDB0_PO0DLY
- LDR r3,=0x01001000 ;sets pulse output to 1 after 0x100 pulses and to 0 after 0x1000 pulses
- STR r3,[r2]
- ;Write PDB0_SC
- ;LOADOK by writing 1 to bit {0}
- ;Continuous mode (1 to bit {1})
- ;MULT factor of 1 (00 to bits {2-3})
- ;Enable software trigger (1111 to bits {8-11})
- ;Prescaler to 0 -> use MULT of 1 (000 to bits {12-14})
- LDR r2,=0x40036000 ;PDB0_SC
- LDR r3,=0x00000F83 ;set prescaler to 0 and MULT to 1
- STR r3,[r2]
- ;Configure ADC
- ;Write ADC0_CRFG1:
- ;Select bus clock/2 as input clock (01 to bits {0-1})
- ;Select single ended 16-bit conversion (11 to bit {2-3})
- ;Select long sample time (1 to bit {4})
- ;Select divide ratio of 8 and clock rate of input clock/8 (11 to bits {5-6})
- LDR r2,=0x4003B008 ;ADC0_CFG1
- LDR r3,=0x0000007D ;divide ratio 8, long sample time, single ended 16bit, bus_clock/2
- STR r3,[r2]
- ;Write ADC0_CFG2
- LDR r2,=0x4003B00C ;ADC0_CFG2
- LDR r3,=0x0 ;ADxxa channels are selected, default longest sample time
- STR r3,[r2]
- ;Write ADC0_SC2
- LDR r2,=0x4003B020 ;ADC0_SC2
- LDR r3,=0x00000040 ;set the hardware trigger PDB (1 to bit {6})
- STR r3,[r2]
- ;Write ADC0_SC3
- ;Average 32 samples to create ADC average result (11 to bits {0-1})
- LDR r2,=0x4003B024 ;ADC0_SC3
- LDR r3,=0x0000000C ;Hardware average function enabled with continuous conversion
- STR r3,[r2]
- ;need to initiate the ADC module before the PDB module, writing ADC0_SC1A will start the module
- LDR r2,=0x4003B000 ;ADC0_SC1A
- LDR r3,=0x0000004A ;Interrupt enabled, ADC10 selected as single ended, input from primary connector B40 pin
- STR r3,[r2]
- LDR r2,=0x40036000 ;PDB0_SC
- LDR r3,=0x00010000 ;write bit 16 to start counting
- LDR r4,[r2]
- ORR r3,r3,r4
- STR r3,[r2] ;trigger the PDB0 channel
- ;activate ADC0_IRQ57
- ;57/32 = 1, write NVIC_ISER1
- ;57 mod 32 = 25, write bit {25} in NVIC_ISER1
- LDR r2,=0xE000E104 ;NVIC_ISER1
- LDR r3,=0x02000000 ;sets bit 25 in NVIC_ISER1 for ADC0 interrupt IRQ#57
- LDR r4,[r2]
- ORR r4,r4,r3
- STR r3,[r2]
- ;activate PDB0_IRQ72
- ;72/32 = 2, write NVIC_ISER2
- ;72 mod 32 = 8, write bit {8} in NVIC_ISER2
- LDR r2,=0xE000E108 ;NVIC_ISER2
- LDR r3,=0x00000100 ;set bit 8 in NVIC_ISER2 for PDB0 interrupt IRQ#72
- LDR r4,[r2]
- ORR r3,r3,r4
- STR r3,[r2]
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- loop B loop
- asm_ADC0_irq
- ;COCO is set in ADC0_SC1A when the conversion is done
- ;this also triggers the interrupt
- ;see pp 826 in K60 Sub Family Reference Manual
- CPSID i ;disable interrupts
- PUSH {lr} ;store LR, to know how to return from irq
- ;next read the result register
- LDR r2,=0x4003B010 ;ADC0_RA
- LDR r0,[r2] ;loads the adc voltage value into r0
- ;next transfer this value to DAC0
- MOV r3,r0,LSR #4 ;divide by 16 ->adc is 16 bit, dac is 12 bit
- LDR r2,=0x400CC000 ;DAC0_DAT0L
- STRB r3,[r2],#1 ;should store the 8 lsb bits to DAC0, update mem address
- LSR r3,r3,#8 ;divide by 256, store 8 msb to dath
- STRB r3,[r2] ;store in DAC0_DATH
- ;Code for req3:
- ;//
- LDR r2,=adc0counter ;load base mem address of adc0counter
- LDR r3,[r2] ;load value of adc0counter
- ADD r3,r3,#1 ;increment counter
- CMP r3,#0x01000 ;I am waiting for 2^12 ADC conversions
- BEQ next0
- STR r3,[r2],#4 ;store counter value in adc0counter, inc mem address
- LDR r4,[r2] ;load value from adc0counter+4
- ADD r4,r4,r0 ;make the sum for average
- STR r4,[r2] ;store sum in adc0counter+4
- B outofdac0
- next0
- MOV r3,#0x1 ;reset counter
- STR r3,[r2],#4 ;store 0x1 in adc0counter
- LDR r4,[r2] ;load value from adc0counter+4
- LSR r4,r4,#12 ;here I am dividing by 2^12 -> get average
- STR r4,[r2] ;store average adc value into adc0counter+4 ;maybe store 0 instead so we dont have running average
- MOV r0,r4 ;move average into r0
- B adc0tovolts ;convert average to volts
- ;//
- outofdac0
- CPSIE i ;enable interrupts
- POP {pc}
- vrange EQU 330
- bindiv EQU 0xFFFF
- ten EQU 10
- adc0tovolts
- LDR r3,=vrange
- LDR r4,=bindiv
- MUL r3,r3,r0 ;r3 = 330 * avg adc value
- UDIV r3,r3,r4 ;r3 = (330 * avg adc value)/((2^16)-1)
- ;we apply Volts value = (r0*3.30)/(2^16-1)
- ;next convert to BCD by dividing by 10 and keeping the remainders
- LDR r2,=volts_value+2 ;set to the last digit
- MOV r4,#0xA ;the conversion base
- over
- UDIV r5,r3,r4 ;divide voltage by 10
- MUL r6,r5,r4 ;multiply by 10
- SUB r6,r3,r6 ;subtract original value
- STRB r6,[r2],#-1 ;store into memory
- CMP r5,r4
- BLT done_conv ;done if divided value <10
- MOV r3,r5 ;next iteration
- B over
- done_conv
- STRB r5,[r2];,#-1
- LDR r4,=volts_value
- fillzero
- CMP r2,r4
- BEQ outofdac0
- MOV r5,#0
- STRB r5,[r2, #-1]!
- B fillzero
- asm_pit1_irq
- PUSH {lr} ;store LR
- LDR r4,=my_PIT_TFLG1 ;load memory address of TFLG1
- MOV r3,#0x01 ;1 to clear flag
- STR r3,[r4] ;store 1 to the memory to clear flags
- LDR r1, =irqcounter ;load memory address of counter
- LDRB r3,[r1] ;loads value from counter into r3
- B sevSeg
- sevSeg
- ldr r12, =volts_value
- LDR r7, =sevSegTable ;loads address of lookup table
- add r12, r12, r3
- LDRB r6, [r12] ;loads value to be printed
- LSL r6, r6, #2 ;multiply value by 4
- ADD r6, r6, r7 ;add shift value to memory address
- LDR r8, [r6] ;load value from lookup table
- LDR R9, =my_GPIOC_PDOR ;load PDOR address to output
- CMP r3, #1 ;branch to correct digit #
- BEQ dig_one
- BGT dig_two
- dig_zero
- ADD r3,#1 ;increment counter
- STRB r3,[r1] ;updating counter in memory
- add r8, r8, #0x400 ;0x400 turns on MS digit PTC10
- sub r8, r8, #0x80
- str r8, [r9] ;store value in PDOR
- pop {pc} ;restore program
- dig_one
- ADD r3,#1 ;increment counter
- STRB r3,[r1] ;updating counter in memory
- add r8, r8, #0x200 ;0x200 turns on middle digit PTC9
- str r8, [r9] ;store value in PDOR
- POP {pc} ;restore program
- dig_two
- mov r3, #0x0 ;reset counter (limit between 0 and 2)
- strb r3, [r1] ;store 0 in counter memory
- add r8, r8, #0x100 ;0x100 turns on LS digit PTC8
- STR r8, [r9] ;store value in PDOR
- POP {pc} ;restore program
- ALIGN
- AREA MyData, DATA, READWRITE
- irqcounter DCD 0x00
- sevSegTable DCD 0xC0
- DCD 0xF9
- DCD 0xA4
- DCD 0xB0
- DCD 0x99
- DCD 0x92
- DCD 0x82
- DCD 0xF8
- DCD 0x98
- DCD 0xFF ;period
- adc0counter DCD 0x0
- DCD 0x0
- volts_value DCD 0x0
- DCD 0x0
- DCD 0x0
- END
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement