avr: optimized cny70 module (not tested, yet).

This commit is contained in:
Martin Preuss
2024-09-09 15:49:58 +02:00
parent e70c294d9b
commit 9bd376464a

View File

@@ -19,16 +19,11 @@
.equ CNY70_FLAGS_ADC_STARTED = 0x01
.equ CNY70_FLAGS_ADC_FINISHED = 0x02
.equ CNY70_FLAGS_ADC_VALID = 0x04
.equ CNY70_TIMER_100MS = 20 ; every 2s
.equ CNY70_FLAGS_ADC_UPDATED = 0x02
cny70DataBegin:
cny70Flags: .byte 1
cny70LastData: .byte 1
cny70TimerCounter: .byte 1
cny70DataEnd:
@@ -60,13 +55,16 @@ CNY70_Init:
; setup pins and interrupts
sbi CNY70_DDR_LED, CNY70_PINNUM_LED ; set DATA port as output
cbi CNY70_PORT_LED, CNY70_PINNUM_LED ; LED off
sbi CNY70_PORT_LED, CNY70_PINNUM_LED ; LED off
cbi CNY70_PORT_ADC, CNY70_PINNUM_ADC ; disable internal pullup for ADC
cbi CNY70_DDR_ADC, CNY70_PINNUM_ADC ; set ADC port as input
ldi r16, (1<<ADLAR) | (1<<CNY70_ADCSRB_ADC) ; "8 bit" mode, disable digital pin input buffer
ldi r16, (1 << CNY70_MUX_ADC) ; select input pin, use Vcc as reference voltage
out ADMUX, r16
sbi ADCSRB, ADLAR ; left shift result for 8-bit representation in ADCH
ldi r16, (1 << ADEN) | (1 << ADPS1) | (1 << ADPS0) ; enable, prescaler 8
out ADCSRB, r16
sec
ret
@@ -79,92 +77,56 @@ CNY70_Fini:
CNY70_Run:
ret ; DEBUG (doesn't change things)
lds r16, cny70Flags
andi r16, CNY70_FLAGS_ADC_UPDATED ; new value?
breq CNY70_Run_done ; nope, jump
rcall CNY70_SendAdc ; send value
brcc CNY70_Run_done ; jump on error
lds r16, cny70Flags ; value sent, clear flag
andi r16, ~CNY70_FLAGS_ADC_UPDATED
sts cny70Flags, r16
CNY70_Run_done:
clc
ret
CNY70_Every100ms:
push r15
in r15, SREG
cli
lds r16, cny70Flags
andi r16, CNY70_FLAGS_ADC_STARTED
brne CNY70_Every100ms_done
lds r16, cny70TimerCounter
inc r16
cpi r16, CNY70_TIMER_100MS
brcc CNY70_Every100ms_startConversion
sts cny70TimerCounter, r16
rjmp CNY70_Every100ms_done
CNY70_Every100ms_startConversion:
clr r16
sts cny70TimerCounter, r16
rcall cny70StartConversion
CNY70_Every100ms_done:
out SREG, r15
pop r15
CNY70_OnTimer:
lds r16, cny70Flags
andi r16, CNY70_FLAGS_ADC_STARTED
breq CNY70_OnTimer_startConversion
; conversion is running, complete?
sbis ADCSRA, ADSC
ret ; only if bit clear
; conversion complete, read value, set flags
lds r16, cny70Flags
andi r16, ~CNY70_FLAGS_ADC_STARTED
ori r16, CNY70_FLAGS_ADC_UPDATED
sts cny70Flags, r16
in r16, ADCH ; read value from ADC
sts cny70LastData, r16
sbi CNY70_PORT_LED, CNY70_PINNUM_LED ; LED off
nop
nop
nop
ret
cny70StartConversion:
sbi CNY70_PORT_LED, CNY70_PINNUM_LED ; LED on
CNY70_OnTimer_startConversion:
lds r16, cny70Flags
ori r16, CNY70_FLAGS_ADC_STARTED
sts cny70Flags, r16
cbi CNY70_PORT_LED, CNY70_PINNUM_LED ; LED on
nop
nop
nop
; setup adc
ldi r16, CNY70_MUX_ADC
out ADMUX, r16
; enable adc, enable irq, clear irq, select prescaler 8 (125kHz)
ldi r16, (1<<ADEN) | (1<<ADIE) | (1<<ADIF) | (1<<ADPS1) | (1<<ADPS0)
out ADCSRA, r16
sbic ADCSRA, ADSC ; start conversion
push r15
in r15, SREG
cli
lds r16, cny70Flags
ori r16, CNY70_FLAGS_ADC_STARTED
andi r16, ~CNY70_FLAGS_ADC_FINISHED
sts cny70Flags, r16
out SREG, r15
pop r15
ret
cny70Isr:
push r15
in r15, SREG
push r16
cbi CNY70_PORT_LED, CNY70_PINNUM_LED ; LED off
in r16, ADCH
sts cny70LastData, r16 ; store value
clr r16 ; disable ADC
out ADCSRA, r16
lds r16, cny70Flags
ori r16, CNY70_FLAGS_ADC_FINISHED | CNY70_FLAGS_ADC_VALID
andi r16, ~CNY70_FLAGS_ADC_STARTED
sts cny70Flags, r16
pop r16
out SREG, r15
pop r15
reti
CNY70_SendAdc:
lds r16, cny70Flags
andi r16, CNY70_FLAGS_ADC_VALID
brne CNY70_SendAdc_haveValue
sec
ret
CNY70_SendAdc_haveValue:
ldi r16, 0xff ; destination address
ldi r17, VALUE_ID_ADC ; value id
ldi r22, AQHOME_VALUETYPE_UNKNOWN