Mercurial > public > hwos_code
diff src/eeprom_rs232.asm @ 634:4050675965ea
3.10 stable release
author | heinrichsweikamp |
---|---|
date | Tue, 28 Apr 2020 17:34:31 +0200 |
parents | 185ba2f91f59 |
children | 8c1f1f334275 |
line wrap: on
line diff
--- a/src/eeprom_rs232.asm Thu Mar 05 15:06:14 2020 +0100 +++ b/src/eeprom_rs232.asm Tue Apr 28 17:34:31 2020 +0200 @@ -1,6 +1,6 @@ ;============================================================================= ; -; File eeprom_rs232.asm combined next generation V3.08.8 +; File eeprom_rs232.asm * combined next generation V3.09.4n ; ; Internal EEPROM, RS232 ; @@ -21,20 +21,20 @@ extern lt2942_charge_done + +;============================================================================= +eeprom CODE +;============================================================================= + ;----------------------------------------------------------------------------- ; -; for EEPROM Macros and Memory Map, see eeprom_rs232.inc +; EEPROM Functions - for EEPROM Macros and Memory Map, see eeprom_rs232.inc ; ;----------------------------------------------------------------------------- -ee_rs232 CODE - -;============================================================================= -; EEPROM Functions -;============================================================================= ;----------------------------------------------------------------------------- -; read from internal EEPROM +; Read from internal EEPROM ; ; Input: EEADRH:EEADR = EEPROM address ; Output: EEDATA @@ -42,13 +42,14 @@ ; global read_eeprom read_eeprom: - bcf EECON1,EEPGD ; - bcf EECON1,CFGS ; - bsf EECON1,RD ; - return + bcf EECON1,EEPGD ; access data EEPROM + bcf EECON1,CFGS ; ... + bsf EECON1,RD ; initiate reading + return ; done + ;----------------------------------------------------------------------------- -; write into internal EEPROM +; Write into internal EEPROM ; ; Input: EEADRH:EEADR = EEPROM address ; EEDATA = byte to write @@ -56,10 +57,10 @@ ; global write_eeprom write_eeprom: - bcf EECON1,EEPGD ; - bcf EECON1,CFGS ; - bsf EECON1,WREN ; - bcf INTCON,GIE ; disable interrupts for the next 5 instructions + bcf EECON1,EEPGD ; access data EEPROM + bcf EECON1,CFGS ; ... + bsf EECON1,WREN ; enable writing + bcf INTCON,GIE ; disable interrupts movlw 0x55 ; unlock sequence movwf EECON2 ; ... movlw 0xAA ; ... @@ -67,13 +68,14 @@ bsf EECON1,WR ; start write operation write_eeprom_loop: btfsc EECON1,WR ; write completed? - bra write_eeprom_loop ; NO - loop waiting - bcf EECON1,WREN ; - bsf INTCON,GIE ; ...but the flag for the ISR routines were still set, so they will interrupt now! - return + bra write_eeprom_loop ; NO - loop waiting + bcf EECON1,WREN ; YES - disable writing + bsf INTCON,GIE ; - re-enable interrupts + return ; - done + ;----------------------------------------------------------------------------- -; these 2 functions are meant to be used through the macros, see eeprom_rs232! +; EEPROM read and write Functions to be used via Macros ; global eeprom_read_common eeprom_read_common: @@ -97,44 +99,46 @@ bra eeprom_write_common_loop ; NO - loop return ; YES - done + ;----------------------------------------------------------------------------- -; REad OSTC serial number +; Read OSTC Serial Number ; global eeprom_serial_number_read eeprom_serial_number_read: - EEPROM_II_READ eeprom_ostc_serial,mpr - return + EEPROM_II_READ eeprom_ostc_serial,mpr ; read serial number + return ; done + ;----------------------------------------------------------------------------- -; Read and write dive number offset +; Read and Write Dive Number Offset ; global eeprom_log_offset_read eeprom_log_offset_read: - EEPROM_II_READ eeprom_log_offset,mpr - return + EEPROM_II_READ eeprom_log_offset,mpr ; read log offset + return ; done global eeprom_log_offset_write eeprom_log_offset_write: - EEPROM_II_WRITE mpr,eeprom_log_offset - return + EEPROM_II_WRITE mpr,eeprom_log_offset ; write log-offset + return ; done ;----------------------------------------------------------------------------- -; Read and write total number of dives +; Read and Write total Number of Dives ; global eeprom_total_dives_read eeprom_total_dives_read: - EEPROM_II_READ eeprom_num_dives,mpr - return + EEPROM_II_READ eeprom_num_dives,mpr ; read total dives + return ; done global eeprom_total_dives_write eeprom_total_dives_write: - EEPROM_II_WRITE mpr,eeprom_num_dives - return + EEPROM_II_WRITE mpr,eeprom_num_dives ; write total dives + return ; done ;----------------------------------------------------------------------------- -; Read and write the battery gauge and type +; Read and Write the Battery Type and Gauge Reading ; global eeprom_battery_gauge_read eeprom_battery_gauge_read: @@ -143,7 +147,7 @@ EEPROM_CC_READ eeprom_battery_type, battery_type ; 1 byte read from EEPROM EEPROM_RR_READ eeprom_battery_gauge,battery_gauge,.6 ; 6 byte read from EEPROM bcf block_battery_gauge ; allow ISR to access the battery gauge again - return + return ; done global eeprom_battery_gauge_write eeprom_battery_gauge_write: @@ -152,16 +156,28 @@ update_battery_gauge: EEPROM_RR_WRITE battery_gauge,eeprom_battery_gauge,.6 ; 6 byte write to EEPROM bcf block_battery_gauge ; allow ISR to access the battery gauge again - return + return ; done ;----------------------------------------------------------------------------- -; Read and write the deco status +; Memorize the Checksum of the Firmware in the update Storage +; + global eeprom_memorize_fw_checksum +eeprom_memorize_fw_checksum: + EXT_FLASH_ADDR 0x3E000D ; address firmware ID at 0x3E000D + FLASH_CW_READ_0x40 ; read firmware ID to WREG + movff WREG,buffer+.5 ; append firmware ID to checksum + EEPROM_RR_WRITE buffer,eeprom_fw_chksum_current,.6 ; do a 6 byte write to EEPROM + return ; done + + +;----------------------------------------------------------------------------- +; Read and Write the Deco Status ; global eeprom_deco_data_read eeprom_deco_data_read: - btfsc RCON,POR ; was there a power outage ? + btfsc RCON,POR ; was there a power outage? bra eeprom_deco_data_read_1 ; NO - RTC is up-to-date EEPROM_RR_READ eeprom_deco_data_timestamp,rtc_latched_year,.6 ; 6 byte read from EEPROM @@ -220,98 +236,115 @@ return ; done - ;============================================================================= -; RS232 Functions +rs232 CODE ;============================================================================= - global disable_ir_s8 -disable_ir_s8: - banksel TXSTA2 ; select bank for IO register access - clrf TXSTA2 - clrf RCSTA2 - banksel common ; back to bank common - bcf PIE3,RC2IE ; disable RC2 INT - bcf ir_power ; IR off - bcf mcp_power ; power-down instrumentation amp - bsf s8_npower ; power-down S8 digital interface - bcf s8_digital_avail ; digital S8 interface not available - return +;----------------------------------------------------------------------------- +; +; RS232 Functions +; +;----------------------------------------------------------------------------- - global enable_ir_s8 -enable_ir_s8: +;----------------------------------------------------------------------------- +; Switch-On the IR/S8 Port +; + global enable_ir_s8_analog +enable_ir_s8_analog: ;initialize serial port2 (TRISG2) - btfsc analog_o2_input ; do we have an analog input? - bra enable_s8 ; YES - search for S8 digital input - ; NO - start IR digital input - banksel BAUDCON2 ; - select bank for IO register access - movlw b'00100000' ; - BRG16=0, inverted for IR - movwf BAUDCON2 - movlw b'00100000' ; - BRGH=0, SYNC=0 - movwf TXSTA2 - movlw .102 ; - SPBRGH:SPBRG = .102 : 2403 BAUD @ 16 MHz - movwf SPBRG2 - clrf SPBRGH2 - movlw b'10010000' - movwf RCSTA2 - banksel common ; - back to bank common - bsf ir_power ; - power-up IR - btfss ir_power ; - power-up confirmed? - bra $-6 ; NO - loop and wait - bsf PIE3,RC2IE ; - enable RC2 INT - return ; - done + btfsc ext_input_s8_ana ; do we have an S8/analog input? + bra enable_s8_analog ; YES - enable S8/analog input + ;bra enable_ir ; NO - enable IR digital input -enable_s8: +enable_ir: + banksel BAUDCON2 ; select bank for IO register access + movlw b'00100000' ; speed generator configuration: BRG16=0, inverted for IR + movwf BAUDCON2 ; ... + movlw b'00100000' ; TX configuration: BRGH=0, SYNC=0 + movwf TXSTA2 ; ... + movlw .102 ; speed configuration: SPBRGH:SPBRG = .102 : 2403 BAUD @ 16 MHz + movwf SPBRG2 ; ... + clrf SPBRGH2 ; ... + movlw b'10010000' ; RX configuration + movwf RCSTA2 ; ... + banksel common ; back to bank common + bsf ir_power ; power-up IR + btfss ir_power ; power-up confirmed? + bra $-6 ; NO - loop and wait + bsf PIE3,RC2IE ; enable RC2 INT + return ; done + +enable_s8_analog: banksel TXSTA2 ; select bank for IO register access clrf TXSTA2 ; reset UART 2 TX function clrf RCSTA2 ; reset UART 2 RX function banksel common ; back to bank common - bsf mcp_power ; power-up instrumentation amp (for analog AND digital) + bsf mcp_power ; power-up instrumentation amp (used by S8 and analog input) btfss mcp_power ; power-up completed? bra $-4 ; NO - loop - ; toggle for digital/analog + ; branch according to S8 / analog selection TSTOSS opt_s8_mode ; =0: analog, =1: digital RS232 - bra enable_s8_analog ; -> analog + bra enable_analog ; -> analog ; configure S8 digital interface bcf s8_npower ; power S8 HUD (inverted via P-MOS transistor) WAITMS d'30' ; NO - wait 30 ms banksel BAUDCON2 ; select bank for IO register access - movlw b'00000000' ; BRG16=0, normal for S8 - movwf BAUDCON2 - movlw b'00100000' ; BRGH=0, SYNC=0 - movwf TXSTA2 - movlw .25 ; SPBRGH:SPBRG = .25 : 9615 BAUD @ 16 MHz - movwf SPBRG2 - movlw b'10010000' - movwf RCSTA2 + movlw b'00000000' ; speed generator configuration: BRG16=0, normal for S8 + movwf BAUDCON2 ; ... + movlw b'00100000' ; TX configuration: BRGH=0, SYNC=0 + movwf TXSTA2 ; ... + movlw .25 ; speed configuration: SPBRGH:SPBRG = .25 : 9615 BAUD @ 16 MHz + movwf SPBRG2 ; ... + movlw b'10010000' ; RX configuration + movwf RCSTA2 ; ... banksel common ; back to bank common bsf PIE3,RC2IE ; enable RC2 INT - bsf s8_digital_avail ; digital S8 interface available return -enable_s8_analog: +enable_analog: ; S8 analog interface bcf PIE3,RC2IE ; disable RC2 INT - bsf s8_npower ; power-down S8 HUD - bcf s8_digital_avail ; digital S8 interface not available - return + bsf s8_npower ; power-down S8 digital interface + return ; done - global ir_s8_wait_tx -ir_s8_wait_tx: +;----------------------------------------------------------------------------- +; Shut-Down the IR/S8 Port +; + global disable_ir_s8_analog +disable_ir_s8_analog: banksel TXSTA2 ; select bank for IO register access -rs232_wait_tx2_loop: - btfss TXSTA2,TRMT ; RS232 busy? - bra rs232_wait_tx2_loop ; YES - wait... - banksel common ; NO - back to bank common + clrf TXSTA2 ; shut down TX function + clrf RCSTA2 ; shut down RX function + banksel common ; back to bank common + bcf PIE3,RC2IE ; disable RC2 INT + bcf ir_power ; power down IR receiver + bcf mcp_power ; power-down instrumentation amp + bsf s8_npower ; power-down S8 digital interface + return ; done + + +;----------------------------------------------------------------------------- +; Send Byte in WREG via the IR/S8 Port +; + global ir_s8_tx_single +ir_s8_tx_single: + banksel TXSTA2 ; UART 2 is outside of the access RAM + movwf TXREG2 ; transmit byte +ir_s8_tx_single_loop: + btfss TXSTA2,TRMT ; TX completed? + bra ir_s8_tx_single_loop ; NO - wait... + banksel common ; YES - back to bank common return ; - done + ;----------------------------------------------------------------------------- - +; Switch-On USB/BT Port +; global enable_rs232 enable_rs232: call request_speed_normal ; request CPU speed change to normal speed @@ -324,21 +357,44 @@ movwf TXSTA1 ; - ... movlw b'10010000' ; - RX configuration: port enabled, RX enabled movwf RCSTA1 ; - ... - movlw HIGH(.65536-rx_timeout*.32) ; - define TMR5H initialization value for RX timeout - movwf rx_timoeut_tmr5h_load ; - store for later use + IFNDEF _comm_debug + movlw HIGH(.65536-rx_timeout*.32) ; - define TMR5H initialization value for RX timeout (rx_timeout defined in hwos.inc) + ELSE + include "math.inc" + movff opt_comm_timeout,xA+0 ; - get timeout setting in multiples of 10 ms (opt_comm_timeout: 10 .. 200 x 10 ms) + clrf xA+1 ; - ... + MOVLI .320,xB ; - multiply with 10 to get timeout in ms and 32 because tmr5 ticks 32x per ms + call mult16x16 ; - xC = xA * xB = timer ticks to go until timeout + MOVII xC,sub_b ; - multiplication result is max. 64000 + MOVLI .65535,sub_a ; - timer wraps around after 65535 + call subU16 ; - sub_c = sub_a - sub_b = start value for timer + + movlw .244 ; safety maximum value for rx_timeout_tmr5h_load (minimum timeout interval) + cpfslt sub_c+1 ; result > safety value? + movwf sub_c+1 ; YES - revert to safety value + + movf sub_c+1,W ; - keep only the upper byte as TMR5H initialization value for RX timeout + ENDIF + movwf rx_timeout_tmr5h_load ; - store for later use return ; - done +;----------------------------------------------------------------------------- +; Shut-Down USB/BT Port +; global disable_rs232 disable_rs232: clrf RCSTA1 ; disable RX clrf TXSTA1 ; disable TX bcf PORTC,6 ; switch TX pin hard to GND - bsf PORTE,0 ; stop comm + bsf PORTE,0 ; power down BT chip bcf PORTJ,2 ; /Reset (required for very old OSTC sport) return +;----------------------------------------------------------------------------- +; Wait for last Byte to be sent out of USB/BT Port +; global rs232_wait_tx ; ++++ do not touch WREG here! ++++ rs232_wait_tx: btfss TXSTA1,TRMT ; last byte completely shifted out on TX pin? @@ -350,36 +406,47 @@ return ; YES - done - ; ++++ make this code as fast as possible! ++++ - global rs232_get_byte ; ++++ do not touch WREG here! ++++ -rs232_get_byte: +;----------------------------------------------------------------------------- +; Receive one Byte via the USB/BT Port +; +; ++++ make this code as fast as possible! ++++ +; ++++ do not touch WREG here! ++++ +; + global serial_rx_single +serial_rx_single: bcf rs232_rx_timeout ; clear timeout flag - btfsc PIR1,RCIF ; received a data byte? (bit is set on RX complete and reset on reading RCREG1) - return ; YES - done, received a byte (fast path) - movff rx_timoeut_tmr5h_load,TMR5H ; - load TMR5 high with timeout value + btfsc PIR1,RCIF ; received a data byte? (bit is set on RX completion and reset on reading RCREG1) + return ; YES - done (fast path) + movff rx_timeout_tmr5h_load,TMR5H ; NO - load TMR5 high with timeout value clrf TMR5L ; - load TMR5 low with a zero, writing low starts the timer bcf PIR5,TMR5IF ; - clear timer overflow flag -rs232_get_byte_loop: +serial_rx_single_loop: btfsc PIR1,RCIF ; received a data byte? - return ; YES - done, received a byte + return ; YES - done btfss PIR5,TMR5IF ; NO - timer overflow (timeout)? - bra rs232_get_byte_loop ; NO - continue looping - ;bra rs232_rx_get_timeout ; YES - give up - -rs232_rx_get_timeout: - bsf rs232_rx_timeout ; set timeout flag - bcf RCSTA1,CREN ; clear receiver status by toggling CREN - bsf RCSTA1,CREN ; ... - return ; done, given up + bra serial_rx_single_loop ; NO - continue waiting + ;bra serial_rx_timeout ; YES - timeout ;----------------------------------------------------------------------------- -; Send and Receive functions to be used through the macros +; Helper Function: Timeout in serial_rx_single / serial_tx_steam +; +serial_rx_timeout: + bsf rs232_rx_timeout ; set timeout flag + bcf RCSTA1,CREN ; clear receiver status: disable RX, + bsf RCSTA1,CREN ; ... enable again RX + return ; done + -; send a range of 1-256 bytes from memory to the RS232 interface +;----------------------------------------------------------------------------- +; Send and Receive Functions to be used via Macros +;----------------------------------------------------------------------------- + +;----------------------------------------------------------------------------- +; Send a Range of 1-256 Bytes from Memory via the USB/BT Port ; - global serial_tx_ram -serial_tx_ram: + global serial_tx_steam +serial_tx_steam: movwf eeprom_loop ; initialize loop counter (eeprom variable used here) serial_tx_ram_loop: rcall rs232_wait_tx ; wait for completion of last transmit @@ -389,37 +456,36 @@ return ; YES - done -; receive a range of 1-256 byte from the RS232 interface and write them to memory +;----------------------------------------------------------------------------- +; Receive a Range of 1-256 Byte via the USB/BT Port and write them to Memory +; ++++ make this code as fast as possible! ++++ ; - global serial_rx_stream_ram ; ++++ make this code as fast as possible! ++++ -serial_rx_stream_ram: + global serial_rx_stream +serial_rx_stream: movwf eeprom_loop ; initialize loop counter (eeprom variable used here) -serial_rx_stream_ram_loop_1: +serial_rx_stream_loop: btfss PIR1,RCIF ; received a data byte? (bit is set on RX complete and reset on reading RCREG1) - bra serial_rx_stream_ram_tmr ; NO - enter loop with timeout - movff RCREG1,POSTINC2 ; YES - copy received byte to memory - decfsz eeprom_loop,F ; - decrement loop counter, became zero? - bra serial_rx_stream_ram_loop_1 ; NO - loop - bcf rs232_rx_timeout ; YES - clear timeout flag - return ; - all bytes received, done -serial_rx_stream_ram_tmr: - movff rx_timoeut_tmr5h_load,TMR5H ; load TMR5 high with timeout value - clrf TMR5L ; load TMR5 low with a zero, writing low starts the timer + bra serial_rx_stream_tmr ; NO - enter receive loop with timeout + ;bra serial_rx_stream_received ; YES - copy to memory, tick counter, ... + +serial_rx_stream_received: + movff RCREG1,POSTINC2 ; copy received byte to memory + decfsz eeprom_loop,F ; decrement loop counter, became zero? + bra serial_rx_stream_loop ; NO - await next byte + bcf rs232_rx_timeout ; YES - clear timeout flag + return ; - all bytes received, done + +serial_rx_stream_tmr: + movff rx_timeout_tmr5h_load,TMR5H ; load TMR5 high with timeout value + clrf TMR5L ; load TMR5 low with a zero, writing to low starts the timer bcf PIR5,TMR5IF ; clear timer overflow flag -serial_rx_stream_ram_loop_2a: - clrf TMR5L ; restart timer (see above) -serial_rx_stream_ram_loop_2b: - btfss PIR1,RCIF ; received a data byte? (bit is set on RX complete and reset on reading RCREG1) - bra serial_rx_stream_ram_chk ; NO - check timeout - movff RCREG1,POSTINC2 ; YES - copy received byte to memory - decfsz eeprom_loop,F ; - decrement loop counter, became zero? - bra serial_rx_stream_ram_loop_2a; NO - loop - bcf rs232_rx_timeout ; YES - clear timeout flag - return ; - all bytes received, done -serial_rx_stream_ram_chk: - btfss PIR5,TMR5IF ; timer overflow (timeout)? - bra serial_rx_stream_ram_loop_2b; NO - continue looping - bra rs232_rx_get_timeout ; YES - give up +serial_rx_stream_tmr_loop: + btfsc PIR1,RCIF ; received a data byte? (bit is set on RX complete and reset on reading RCREG1) + bra serial_rx_stream_received ; YES - copy to memory, tick counter, ... + btfss PIR5,TMR5IF ; NO - timer overflow (timeout)? + bra serial_rx_stream_tmr_loop ; NO - continue waiting + bra serial_rx_timeout ; YES - timeout ;----------------------------------------------------------------------------- + END