Mercurial > public > hwos_code
diff src/adc_lightsensor.asm @ 623:c40025d8e750
3.03 beta released
author | heinrichsweikamp |
---|---|
date | Mon, 03 Jun 2019 14:01:48 +0200 |
parents | b87f23fae743 |
children | cd58f7fc86db |
line wrap: on
line diff
--- a/src/adc_lightsensor.asm Wed Apr 10 10:51:07 2019 +0200 +++ b/src/adc_lightsensor.asm Mon Jun 03 14:01:48 2019 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File adc.asm V2.99e +; File adc_lightsensor.asm combined next generation V3.03.2 ; ; ; Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved. @@ -14,16 +14,13 @@ #include "eeprom_rs232.inc" #include "i2c.inc" - extern reset_battery_internal_only -adc_light CODE +adc_light CODE ;============================================================================= -wait_adc: +wait_adc: ; bank-safe movwf ADCON0 - nop - nop nop bsf ADCON0,1 ; start ADC wait_adc2: @@ -32,47 +29,42 @@ return global get_battery_voltage -get_battery_voltage: ; starts ADC and waits until finished - btfss battery_gauge_available - bra get_battery_voltage1 ; normal ostc3 hardware - - call lt2942_get_accumulated_charge - call lt2942_get_voltage - call lt2942_get_temperature - - tstfsz batt_voltage+1 ; < 256 mV ? - bra get_battery_voltage_noretry ; NO - - ; Retry - call lt2942_get_accumulated_charge - call lt2942_get_voltage - call lt2942_get_temperature +get_battery_voltage: ; start ADC and wait until finished + btfss battery_gauge_available ; battery gauge IC available? + bra get_battery_voltage_2 ; NO - OSTC hardware without gauge IC + call lt2942_get_accumulated_charge ; YES - read coulomb counter + call lt2942_get_voltage ; - read battery voltage + call lt2942_get_temperature ; - read battery temperature + tstfsz batt_voltage+1 ; - read voltage < 256 mV ? + bra get_battery_voltage_1 ; NO - proceed + call lt2942_get_accumulated_charge ; YES - re-read coulomb counter + call lt2942_get_voltage ; - re-read battery voltage + call lt2942_get_temperature ; - re-read battery temperature + ;bra get_battery_voltage_1 ; - proceed -get_battery_voltage_noretry: - btfsc divemode - return ; not in divemode - - bcf cv_active - bcf cc_active - bcf LEDr - bcf TRISJ,2 ; Chrg-Out output - bsf CHRG_OUT +get_battery_voltage_1: + btfsc divemode ; in dive mode? + return ; YES - done - btfss CHRG_IN - bra charge_cc_active + bcf cv_active ; clear CV charing status by default + bcf cc_active ; clear CC charing status ny default + bcf LEDr ; switch off red LED + bcf TRISJ,2 ; activate Chrg-Out output + bsf CHRG_OUT ; start charger + btfss CHRG_IN ; charging? + bra charge_cc_active ; YES - charging in CC mode + bcf CHRG_OUT ; NO - stop charger + bsf TRISJ,2 ; - set Chrg-Out output to high impedance + WAITMS d'1' ; - wait 1 ms + btfsc CHRG_IN ; - still charging? + return ; NO - done + ;bra charge_cv_active ; YES - charging in CV mode - bcf CHRG_OUT - bsf TRISJ,2 ; Chrg-Out high impedance - - WAITMS d'1' - - btfsc CHRG_IN - return ; Not charging, done. charge_cv_active: decfsz get_bat_volt_counter,F return movlw .15 - cpfsgt batt_voltage+1 ; battery voltage >= 16*256mV (4,096V)? + cpfsgt batt_voltage+1 ; battery voltage >= 16*256mV (4.096V) ? bra charge_cc_active ; NO bsf cc_active bsf cv_active @@ -87,7 +79,7 @@ bsf cc_active bsf LEDr ; indicate charging bcf CHRG_OUT - bsf TRISJ,2 ; chrg-Out high impedance + bsf TRISJ,2 ; set chrg-Out output to high impedance movlw .15 cpfsgt batt_voltage+1 ; battery voltage >= 16*256mV (4.096 V)? bra charge_cc_active2 ; NO @@ -99,69 +91,59 @@ movwf get_bat_volt_counter return -get_battery_voltage1: - ; Additional disable in software - bsf charge_disable - bcf TRISE,2 - bsf adc_running ; =1: The ADC is in use +get_battery_voltage_2: ; no gauge IC available, use ADC to measure battery voltage + ; additional charging disable in software + bsf charge_disable ; set charging-inhibit signal + bcf charge_enable ; activate charging-inhibit signal - movlw b'00100000' ; 2.048V Vref+ -> 1LSB = 500µV + bsf adc_is_running ; =1: the ADC is in use + movlw b'00100000' ; 2.048 Volt Vref+ -> 1 LSB = 500 µV movwf ADCON1 movlw b'00011001' ; power on ADC, select AN6 rcall wait_adc - movff ADRESH,batt_voltage+1 ; store value - movff ADRESL,batt_voltage+0 ; store value + MOVII ADRESL,batt_voltage ; store value bcf ADCON0,0 ; power off ADC ; Multiply with 2.006 to be exact here... ; bcf STATUS,C ; rlcf xA+0,F -; ; rlcf xA+1,F ; x2 +; MOVII xA,batt_voltage ; store value -; movff xA+0,batt_voltage+0 ; store value -; movff xA+1,batt_voltage+1 + bcf battery_is_36v ; by default assume it is a 1.5 battery + MOVII batt_voltage,sub_b ; load measured battery voltage - movlw LOW lithium_36v_low - movwf sub_a+0 - movlw HIGH lithium_36v_low - movwf sub_a+1 - movff batt_voltage+0,sub_b+0 - movff batt_voltage+1,sub_b+1 - call subU16 ; sub_c = sub_a - sub_b - ; Battery is 3.6V (> lithium_36v_low?) - btfss neg_flag - bra get_battery_voltage4 ; NO - use 1.5V - bsf battery_is_36v ; YES - set flag (Cleared in power-on reset only!) + ; Check if the battery is a 3.6V lithium + MOVLI lithium_36v_low,sub_a ; load threshold for 3.6 Volt lithium battery + call cmpU16 ; sub_a - sub_b + btfss neg_flag ; battery voltage > 3.6 V lithium threshold ? + bra get_battery_voltage_9 ; NO - keep assumption of 1.5V battery + bsf battery_is_36v ; YES - set flag ; Check if the battery is near-dead already - movlw LOW lithium_36v_empty - movwf sub_a+0 - movlw HIGH lithium_36v_empty - movwf sub_a+1 - call subU16 ; sub_c = sub_a - sub_b - ; Battery is not dead yet (> lithium_36v_empty)? - btfsc neg_flag - bra get_battery_voltage2 ; YES - battery is still ok + MOVLI lithium_36v_empty,sub_a ; load threshold for near-dead lithium battery + call cmpU16 ; sub_a - sub_b + btfsc neg_flag ; battery voltage > dead-battery threshold ? + bra get_battery_voltage_3 ; YES - battery is still ok + movlw .128 ; NO - battery is probably dead very soon, set ">=24Ah used" + movff WREG,battery_gauge+5 ; - into battery gauge registers - ; Battery is probably dead very soon - ; Set ">=24Ah used" into battery gauge registers - movlw .128 - movff WREG,battery_gauge+5 - -get_battery_voltage2: - ; Use 3.6V battery gauging mode +get_battery_voltage_3: ; 3.6V battery gauge mode + ; SMOVFF "by hand" as the macro does not work with arguments that have a '+something' with them + bcf trigger_isr_updates ; clear flag, it will be set by the ISR in case it had kicked in movff battery_gauge+5,xC+3 movff battery_gauge+4,xC+2 movff battery_gauge+3,xC+1 movff battery_gauge+2,xC+0 + btfsc trigger_isr_updates ; did the ISR kicked in since we cleared the flag? + bra get_battery_voltage_3 ; YES - retry copy + ; battery_gauge: 6 is nAs ; divide through 65536 ; divide through battery_capacity:2 ; result is in percent - movff internal_battery_capacity+0,xB+0 - movff internal_battery_capacity+1,xB+1 + MOVII battery_capacity_internal,xB call div32x16 ; xC:4 = xC:4 / xB:2 with xA as remainder movff xC+0,lo ; limit to 100 @@ -172,124 +154,102 @@ movf lo,W sublw .100 movwf lo -get_battery_voltage3: - movlw .100 - cpfslt lo - movwf lo +get_battery_voltage_4: + movlw .100 ; start with default of 100% + cpfslt lo ; > 100% + movwf lo ; YES - limit to 100% ; lo will be between 100 (full) and 0 (empty) - ; use 3.6V battery sensing based on 50 mA load - ; 75% - movff batt_voltage+0,sub_b+0 - movff batt_voltage+1,sub_b+1 - movlw LOW lithium_36v_75 - movwf sub_a+0 - movlw HIGH lithium_36v_75 - movwf sub_a+1 - call subU16 ; sub_c = sub_a - sub_b - btfsc neg_flag - bra get_battery_voltage3a - movlw .75 + MOVLI lithium_36v_75,sub_a ; load threshold for > 75% + call cmpU16 ; sub_a - sub_b + btfsc neg_flag ; battery voltage above 75% level? + bra get_battery_voltage_5 ; YES + movlw .75 ; NO - set to 75% movwf lo -get_battery_voltage3a: -; 50% - movlw LOW lithium_36v_50 - movwf sub_a+0 - movlw HIGH lithium_36v_50 - movwf sub_a+1 - call subU16 ; sub_c = sub_a - sub_b - btfsc neg_flag - bra get_battery_voltage3b - movlw .50 +get_battery_voltage_5: + ; 50% + MOVLI lithium_36v_50,sub_a ; load threshold for > 50% + call cmpU16 ; sub_a - sub_b + btfsc neg_flag ; battery voltage above 75% level? + bra get_battery_voltage_6 ; YES + movlw .50 ; NO - set to 50% movwf lo -get_battery_voltage3b: +get_battery_voltage_6: ; 25% - movlw LOW lithium_36v_25 - movwf sub_a+0 - movlw HIGH lithium_36v_25 - movwf sub_a+1 - call subU16 ; sub_c = sub_a - sub_b - btfsc neg_flag - bra get_battery_voltage3c - movlw .25 + MOVLI lithium_36v_25,sub_a ; load threshold for > 25% + call cmpU16 ; sub_a - sub_b + btfsc neg_flag ; battery voltage above 25% level? + bra get_battery_voltage_7 ; YES + movlw .25 ; NO - set to 25% movwf lo -get_battery_voltage3c: +get_battery_voltage_7: ; 10% - movlw LOW lithium_36v_10 - movwf sub_a+0 - movlw HIGH lithium_36v_10 - movwf sub_a+1 - call subU16 ; sub_c = sub_a - sub_b - btfsc neg_flag - bra get_battery_voltage3d - movlw .10 + MOVLI lithium_36v_10,sub_a ; load threshold for > 10% + call cmpU16 ; sub_a - sub_b + btfsc neg_flag ; battery voltage above 10% level? + bra get_battery_voltage_8 ; YES + movlw .10 ; NO - set to 10% movwf lo -get_battery_voltage3d: - movlw .100 - cpfslt lo - movwf lo - ; lo will be between 100 (full) and 0 (empty) - movf batt_percent,W - cpfsgt lo ; keep batt_percent on the lowest value found - movff lo,batt_percent ; store value - btfsc battery_is_36v ; but always use computed value for 3.6V battery - movff lo,batt_percent ; store value - bcf adc_running ; =1: the ADC is in use +get_battery_voltage_8: + movlw .100 ; maximum is 100 (%) + cpfslt lo ; > 100% ? + movwf lo ; YES - limit to 100% + movf batt_percent,W ; get last battery percentage + cpfsgt lo ; current battery % < last battery % ? + movff lo,batt_percent ; YES - take new value (keep batt_percent on the lowest value found) + btfsc battery_is_36v ; using a 3.6 volt battery? + movff lo,batt_percent ; YES - take new value (always use computed value for 3.6V battery) + bcf adc_is_running ; done with ADC return -get_battery_voltage4: +get_battery_voltage_9: ; use 1.5V battery voltage mode - ; use approximation (batt_voltage:2-aa_15v_low)/4 = lo - movff batt_voltage+0,sub_a+0 - movff batt_voltage+1,sub_a+1 - movlw LOW aa_15v_low - movwf sub_b+0 - movlw HIGH aa_15v_low - movwf sub_b+1 + ; use approximation (batt_voltage-aa_15v_low)/4 = lo + MOVII batt_voltage,sub_a ; load battery voltage + MOVLI aa_15v_low, sub_b ; load offset call subU16 ; sub_c = sub_a - sub_b - bcf STATUS,C + bcf STATUS,C ; shift right to divide / 2 rrcf sub_c+1 - rrcf sub_c+0 ; /2 - bcf STATUS,C + rrcf sub_c+0 + bcf STATUS,C ; another shift right to divide / 4 rrcf sub_c+1 - rrcf sub_c+0 ; /4 - movff sub_c+0,lo - bra get_battery_voltage3d ; check limits and return + rrcf sub_c+0 + movff sub_c+0,lo ; store result + bra get_battery_voltage_8 ; check limits and return - global get_ambient_level + + global get_ambient_level ; called from ISR only, in context bank isr_backup get_ambient_level: ; starts ADC and waits until finished - btfsc adc_running ; ADC in use? - return ; YES - return - - btfsc ambient_sensor - bra get_ambient_level1 ; normal OSTC3 hardware + btfsc sleepmode ; in sleep mode? + return ; YES - done + btfsc adc_is_running ; NO - ADC in use? + return ; YES - return + banksel HW_descriptor ; NO - select bank where hardware descriptor is stored + btfsc ambient_sensor ; - ambient sensor available? + bra get_ambient_level1 ; YES - use sensor + banksel isr_backup ; NO - back to ISR default bank + movff opt_brightness,isr_lo ; - get brightness selection + incf isr_lo,F ; - 0-2 -> 1-3 + movlw ambient_light_max_high_cr ; - default selection to brightest setting + dcfsnz isr_lo,F ; - level 0 (eco) selected? + movlw ambient_light_max_eco ; YES - select eco brightness + dcfsnz isr_lo,F ; - level 1 (medium) selected? + movlw ambient_light_max_medium ; YES - select medium brightness + movwf ambient_light+0 ; - store selection + movwf max_CCPR1L ; - store value for dimming in TMR7 interrupt + return ; - done - banksel isr_backup ; back to bank0 ISR data - movff opt_brightness,isr1_temp - incf isr1_temp,F ; adjust 0-2 to 1-3 - movlw ambient_light_max_high_cr ; cR and 2 hardware brightest setting - dcfsnz isr1_temp,F - movlw ambient_light_max_eco ; brightest setting - dcfsnz isr1_temp,F - movlw ambient_light_max_medium ; brightest setting - - movff WREG,ambient_light+0 ; set to max. - movff ambient_light+0,max_CCPR1L ; store value for dimming in TMR7 interrupt - return - -get_ambient_level1: +get_ambient_level1: ; using ambient sensor + banksel isr_backup ; back to ISR default bank movlw b'00000000' ; Vref+ = Vdd movwf ADCON1 movlw b'00011101' ; power on ADC, select AN7 rcall wait_adc - - movff ADRESH,ambient_light+1 - movff ADRESL,ambient_light+0 + MOVII ADRESL,ambient_light bcf ADCON0,0 ; power off ADC ; ambient_light:2 is between 4096 (direct sunlight) and about 200 (darkness) ; first: divide by 16 - banksel ambient_light bcf STATUS,C rrcf ambient_light+1 rrcf ambient_light+0 @@ -321,162 +281,155 @@ ; btfsc STATUS,N ; movwf ambient_light+0 ; avoid clipping - banksel isr_backup ; back to bank0 ISR data - movff opt_brightness,isr1_temp + movff opt_brightness,isr_lo ; get brightness setting btfsc RCSTA1,7 ; UART module on? - clrf isr1_temp ; YES - set temporally to eco mode + clrf isr_lo ; YES - set temporary to eco mode + incf isr_lo,F ; adjust 0-2 to 1-3 - incf isr1_temp,F ; adjust 0-2 to 1-3 + movlw ambient_light_max_high_cr ; cR and 2 hardware brightest setting - banksel common ; flag is in bank1 - movlw ambient_light_max_high_cr ; cR and 2 hardware brightest setting + banksel HW_descriptor ; select bank where hardware descriptor and model variant is stored btfss battery_gauge_available movlw ambient_light_max_high_15V ; 1.5V battery brightest setting btfsc battery_is_36v ; 3.6V battery in use? movlw ambient_light_max_high_36V ; YES - 3.6V battery brightest setting - banksel isr_backup ; back to bank0 ISR data + banksel isr_backup ; back to ISR default bank - dcfsnz isr1_temp,F - movlw ambient_light_max_eco ; brightest setting - dcfsnz isr1_temp,F + dcfsnz isr_lo,F + movlw ambient_light_max_eco ; eco setting + dcfsnz isr_lo,F movlw ambient_light_max_medium ; brightest setting - banksel ambient_light incf ambient_light+0,F ; +1 cpfslt ambient_light+0 ; smaller than WREG? movwf ambient_light+0 ; NO - set to max. - banksel isr_backup ; back to bank0 ISR data - movff opt_brightness,isr1_temp - incf isr1_temp,F ; adjust 0-2 to 1-3 + movff opt_brightness,isr_lo + incf isr_lo,F ; adjust 0-2 to 1-3 + movlw ambient_light_min_high ; darkest setting + dcfsnz isr_lo,F + movlw ambient_light_min_eco ; darkest setting + dcfsnz isr_lo,F + movlw ambient_light_min_medium ; darkest setting + dcfsnz isr_lo,F movlw ambient_light_min_high ; darkest setting - dcfsnz isr1_temp,F - movlw ambient_light_min_eco ; darkest setting - dcfsnz isr1_temp,F - movlw ambient_light_min_medium ; darkest setting - dcfsnz isr1_temp,F - movlw ambient_light_min_high ; darkest setting - - banksel ambient_light cpfsgt ambient_light+0 ; bigger than WREG? movwf ambient_light+0 ; NO - set to min - banksel common movff ambient_light+0,max_CCPR1L ; store value for dimming in TMR7 interrupt return - global get_analog_inputs + +;============================================================================= +; routines for reading analog-attached external sensors +; + IFDEF _external_sensor + + global get_analog_inputs ; called from outside ISR only get_analog_inputs: ; start ADC and wait until finished - bsf adc_running ; =1: The ADC is in use + bsf adc_is_running ; =1: the ADC is in use btfsc TFT_PWM bra get_analog_inputs ; wait for PWM low movlw b'00100000' ; 2.048V Vref+ -> 1 LSB = 500 µV movwf ADCON1 + banksel sensor1_mv ; select bank where sensor1_mv is stored + ; Sensor 1 movlw b'00100001' ; power on ADC, select AN8 rcall wait_adc bcf STATUS,C rrcf ADRESH,F ; /2 rrcf ADRESL,W - ; add to o2_mv_sensor1:2 - addwf o2_mv_sensor1+0,F + addwf sensor1_mv+0,F ; add to sensor1_mv:2 movf ADRESH,W - addwfc o2_mv_sensor1+1,F - ; divide by 2 + addwfc sensor1_mv+1,F bcf STATUS,C - rrcf o2_mv_sensor1+1,F ; /2 - rrcf o2_mv_sensor1+0,F - + rrcf sensor1_mv+1,F ; divide /2 + rrcf sensor1_mv+0,F movlw HIGH ignore_mv - cpfsgt o2_mv_sensor1+1 ; > ignore_mv ? - bra get_analog_inputs2a ; NO - ; YES - ignore this reading - clrf o2_mv_sensor1+1 - clrf o2_mv_sensor1+0 -get_analog_inputs2a: - ; ignore 1.9 mV noise for not-connected inputs - tstfsz o2_mv_sensor1+1 ; > 25.5mV ? + cpfsgt sensor1_mv+1 ; > ignore_mv ? + bra get_analog_inputs1a ; NO + CLRI sensor1_mv ; YES - ignore this reading +get_analog_inputs1a: ; ignore 1.9 mV noise for not-connected inputs + tstfsz sensor1_mv+1 ; > 25.5 mV ? bra get_analog_inputs2 ; YES - skip here movlw .19 - cpfsgt o2_mv_sensor1+0 ; > 1.9mV ? - clrf o2_mv_sensor1+0 ; NO - clear result + cpfsgt sensor1_mv+0 ; > 1.9 mV ? + clrf sensor1_mv+0 ; NO - clear result + get_analog_inputs2: + ; Sensor 2 movlw b'00100101' ; power on ADC, select AN9 rcall wait_adc bcf STATUS,C rrcf ADRESH,F ; /2 rrcf ADRESL,W - ; add to o2_mv_sensor2:2 - addwf o2_mv_sensor2+0,F + addwf sensor2_mv+0,F ; add to sensor2_mv:2 movf ADRESH,W - addwfc o2_mv_sensor2+1,F - ; divide by 2 + addwfc sensor2_mv+1,F bcf STATUS,C - rrcf o2_mv_sensor2+1,F ; /2 - rrcf o2_mv_sensor2+0,F - + rrcf sensor2_mv+1,F ; divide /2 + rrcf sensor2_mv+0,F movlw HIGH ignore_mv - cpfsgt o2_mv_sensor2+1 ; > ignore_mv ? - bra get_analog_inputs3a ; NO - ; YES - ignore this reading - clrf o2_mv_sensor2+1 - clrf o2_mv_sensor2+0 -get_analog_inputs3a: - ; ignore 1.9 mV noise for not-connected inputs - tstfsz o2_mv_sensor2+1 ; > 25.5 mV ? + cpfsgt sensor2_mv+1 ; > ignore_mv ? + bra get_analog_inputs2a ; NO + CLRI sensor2_mv ; YES - ignore this reading +get_analog_inputs2a: ; ignore 1.9 mV noise for not-connected inputs + tstfsz sensor2_mv+1 ; > 25.5 mV ? bra get_analog_inputs3 ; YES - skip here movlw .19 - cpfsgt o2_mv_sensor2+0 ; > 1.9 mV ? - clrf o2_mv_sensor2+0 ; NO - clear result + cpfsgt sensor2_mv+0 ; > 1.9 mV ? + clrf sensor2_mv+0 ; NO - clear result + get_analog_inputs3: + ; Sensor 3 movlw b'00101001' ; power on ADC, select AN10 rcall wait_adc bcf STATUS,C rrcf ADRESH,F ; /2 rrcf ADRESL,W - ; add to o2_mv_sensor3:2 - addwf o2_mv_sensor3+0,F + addwf sensor3_mv+0,F ; add to sensor3_mv:2 movf ADRESH,W - addwfc o2_mv_sensor3+1,F - ; divide by 2 + addwfc sensor3_mv+1,F bcf STATUS,C - rrcf o2_mv_sensor3+1,F ; /2 - rrcf o2_mv_sensor3+0,F - + rrcf sensor3_mv+1,F ; divide /2 + rrcf sensor3_mv+0,F movlw HIGH ignore_mv - cpfsgt o2_mv_sensor3+1 ; > ignore_mv ? - bra get_analog_inputs4a ; NO - ; YES - ignore this reading - clrf o2_mv_sensor3+1 - clrf o2_mv_sensor3+0 -get_analog_inputs4a: - ; ignore 1.9mV noise for not-connected inputs - tstfsz o2_mv_sensor3+1 ; > 25.5 mV ? + cpfsgt sensor3_mv+1 ; > ignore_mv ? + bra get_analog_inputs3a ; NO + CLRI sensor3_mv ; YES - ignore this reading +get_analog_inputs3a: ; ignore 1.9 mV noise for not-connected inputs + tstfsz sensor3_mv+1 ; > 25.5 mV ? bra get_analog_inputs4 ; YES - skip here movlw .19 - cpfsgt o2_mv_sensor3+0 ; > 1.9 mV ? - clrf o2_mv_sensor3+0 ; NO - clear result + cpfsgt sensor3_mv+0 ; > 1.9 mV ? + clrf sensor3_mv+0 ; NO - clear result get_analog_inputs4: + banksel common ; back to bank common bcf ADCON0,0 ; power off ADC - bcf adc_running ; =1: the ADC is in use + bcf adc_is_running ; done with ADC return - global piezo_config ; set up piezo sensitivity of heinrichs weikamp piezo buttons (~30ms) -piezo_config: ; settings between 20 and 200 - clrf TMR5H - clrf TMR5L ; ~2sec - bcf PIR5,TMR5IF ; clear flag - bcf switch_right - bcf switch_left + ENDIF ; _external_sensor + +;============================================================================= + + global piezo_config ; called from outside ISR only +piezo_config: ; set up sensitivity of heinrichsweikamp piezo buttons (~30ms) + clrf TMR5H ; clear TMR5H first + clrf TMR5L ; clear TMR5L thereafter + bcf PIR5,TMR5IF ; clear timer 5 overrun flag, will take ~ 2 seconds to overrun after reset + bcf switch_right ; clear left-over button events + bcf switch_left ; ... piezo_config0: - btfsc switch_right - bra piezo_config - btfsc switch_left - bra piezo_config ; restart on button press + btfsc switch_right ; user still pressing the right button? + bra piezo_config ; YES - loop to wait for release + btfsc switch_left ; user still pressing the left button? + bra piezo_config ; YES - loop to wait for release - btfss PIR5,TMR5IF - bra piezo_config0 ; wait loop + btfss PIR5,TMR5IF ; timeout? + bra piezo_config0 ; NO - not yet, loop bcf INTCON,GIE @@ -518,50 +471,48 @@ return piezo_config_wait_bit: - setf TMR5H - movlw .255-.26 ; 26 x 31,5µs = 819us - movwf TMR5L - bcf PIR5,TMR5IF ; clear flag + setf TMR5H ; set TMR5H first (to 255) + movlw .255-.26 ; 26 x 31.5 µs = 819 us + movwf TMR5L ; set TMR5L thereafter + bcf PIR5,TMR5IF ; clear timer 5 overrun flag piezo_config_wait_bit3: - btfss PIR5,TMR5IF - bra piezo_config_wait_bit3 ; wait loop - return - - global reset_battery_pointer -reset_battery_pointer: ; reset battery pointer 0x07-0x0C and battery_gauge:5 - extern lt2942_charge_done - btfsc battery_gauge_available ; something to reset? - call lt2942_charge_done ; YES - reset accumulating registers to 0xFFFF - goto reset_battery_internal_only ; and return + btfss PIR5,TMR5IF ; timeout? + bra piezo_config_wait_bit3 ; NO - loop + return ; YES - done - global get_analog_switches + global get_analog_switches ; called from ISR and from sleep mode, returns in bank common get_analog_switches: ; start ADC and wait until finished + banksel HW_variants ; switch to bank where OSTC model variant is stored btfsc analog_switches ; does the OSTC have analog switches? - bra get_analog_switches2 ; YES - ; NO - bcf analog_sw1_pressed ; NO - clear flag for analog switch 1 + bra get_analog_switches_1 ; YES + banksel common ; NO - back to bank common + bcf analog_sw1_pressed ; - clear flag for analog switch 1 bcf analog_sw2_pressed ; - clear flag for analog switch 2 return ; - done -get_analog_switches2: - btfsc adc_running ; ADC in use? + +get_analog_switches_1: + banksel common ; back to bank common + btfsc adc_is_running ; ADC in use? return ; YES - abort - ; NO + ;bra get_analog_switches_2 ; NO - read switches + +get_analog_switches_2: movlw b'00001001' ; left justified movwf ADCON2 ; movlw b'00000000' ; Vref+ = Vdd clrf ADCON1 movlw b'00100101' ; power on ADC, select AN9 rcall wait_adc - banksel analog_counter + + banksel isr_backup ; select bank ISR data movff ADRESH,WREG addwf analog_sw2_raw+0 movlw .0 addwfc analog_sw2_raw+1 decfsz analog_counter,F ; continue averaging? - bra get_analog_switches2a ; YES - ; NO - done, compute average - bcf STATUS,C + bra get_analog_switches_2a ; YES + bcf STATUS,C ; NO - done, compute average rrcf analog_sw2_raw+1 rrcf analog_sw2_raw+0 ; /2 bcf STATUS,C @@ -578,9 +529,9 @@ clrf analog_sw2_raw+0 ; reset average registers ; movlw .16 ; movwf analog_counter ; only once... -get_analog_switches2a: - banksel common - bcf analog_sw2_pressed + +get_analog_switches_2a: + bcf analog_sw2_pressed ; default to not pressed movff opt_cR_button_left,WREG ; 20-100 bcf STATUS,C rrcf WREG ; /2 -> 10-50 @@ -589,34 +540,32 @@ decf WREG,W ; -1 decf WREG,W ; -1 decf WREG,W ; -1 -> 2-22 - banksel analog_sw2 btfss button_polarity,1 ; (1= normal, 0=inverted) - bra sw2_inverted + bra get_analog_switches_sw2_inv addwf analog_sw2,W ; average (~128) - cpfsgt ADRESH - bra get_analog_sw1 - banksel common - bsf analog_sw2_pressed ; left button normal - bra get_analog_sw1 -sw2_inverted: + cpfsgt ADRESH ; pressed? + bra get_analog_switches_3 ; NO + bra get_analog_switches_sw2_pressed ; YES (left button normal) + +get_analog_switches_sw2_inv: subwf analog_sw2,W ; average (~128) - cpfslt ADRESH - bra get_analog_sw1 - banksel common - bsf analog_sw2_pressed ; left button inverted -get_analog_sw1: - banksel common + cpfslt ADRESH ; pressed? + bra get_analog_switches_3 ; NO + ;bra get_analog_switches_sw2_pressed ; YES (left button inverted) + +get_analog_switches_sw2_pressed: + bsf analog_sw2_pressed ; set left button as pressed + +get_analog_switches_3: movlw b'00101001' ; power on ADC, select AN10 rcall wait_adc - banksel analog_counter movff ADRESH,WREG addwf analog_sw1_raw+0 movlw .0 addwfc analog_sw1_raw+1 tstfsz analog_counter ; continue averaging? - bra get_analog_switches1a ; YES - ; NO - done, compute average - bcf STATUS,C + bra get_analog_switches_3a ; YES + bcf STATUS,C ; NO - done, compute average rrcf analog_sw1_raw+1 rrcf analog_sw1_raw+0 ; /2 bcf STATUS,C @@ -633,9 +582,9 @@ clrf analog_sw1_raw+0 ; reset average registers movlw .16 movwf analog_counter ; only once... -get_analog_switches1a: - banksel common - bcf analog_sw1_pressed + +get_analog_switches_3a: + bcf analog_sw1_pressed ; default to not pressed movff opt_cR_button_right,WREG ; 20-100 bcf STATUS,C rrcf WREG ; /2 -> 10-50 @@ -644,30 +593,32 @@ decf WREG,W ; -1 decf WREG,W ; -1 decf WREG,W ; -1 -> 2-22 - banksel analog_sw1 btfss button_polarity,0 ; (1= normal, 0=inverted) - bra sw1_inverted + bra get_analog_switches_sw1_inv addwf analog_sw1,W ; average (~128) - cpfsgt ADRESH - bra get_analog_sw_done - banksel common - bsf analog_sw1_pressed ; right button normal - bra get_analog_sw_done -sw1_inverted: + cpfsgt ADRESH ; pressed? + bra get_analog_switches_4 ; NO + bra get_analog_switches_sw1_pressed ; YES (right button normal) + +get_analog_switches_sw1_inv: subwf analog_sw1,W ; average (~128) - cpfslt ADRESH - bra get_analog_sw_done - banksel common - bsf analog_sw1_pressed ; right button inverted -get_analog_sw_done: - banksel common + cpfslt ADRESH ; pressed? + bra get_analog_switches_4 ; NO + ;bra get_analog_switches_sw1_pressed ; YES (right button inverted) + +get_analog_switches_sw1_pressed: + bsf analog_sw1_pressed ; set right button as pressed + +get_analog_switches_4: movlw b'10001101' ; restore to right justified movwf ADCON2 - btfsc analog_sw1_pressed - return - btfsc analog_sw2_pressed - return - setf TMR1H ; no button pressed, enhance timer1 to overflow quickly + + banksel common ; back to bank common + btfsc analog_sw1_pressed ; right button pressed? + return ; YES - done + btfsc analog_sw2_pressed ; left button pressed? + return ; YES - done + setf TMR1H ; NO to both - no button pressed, set timer1 to overflow quickly return END \ No newline at end of file