;rtc.asm ******************************************************************************* *REVISION HISTORY: * *DATE REV. NO. DESCRIPTION * *Oct 29, 1999 1.00 RTC clean up *Author: Exequiel Rarama ******************************************************************************* ; ; ---------------------------- ; ADAPT-912MX1 Flash Utilities ; ---------------------------- ; --------------------------- ; Clock RTC - RTC Routines ; --------------------------- ;clock modes status1 equ %10000011 ;clock control/status register status2 equ %00000011 ;clock control/status register status3 equ %00001011 ;clock control/status register ; read date and month directly. rtc_control_reg_address equ 0 millisecond_reg_address equ 1 seconds_reg_address equ 2 minutes_reg_address equ 3 hours_reg_address equ 4 year_date_reg_address equ 5 week_month_reg_address equ 6 timer_reg_address equ 7 alarm_cntrl_reg_address equ 8 rtc_read_address equ %10100011 ;address of rtc clock rtc_write_address equ %10100010 ;address of rtc clock SDA EQU %10000000 ;SERIAL DATA SCL EQU %01000000 ;SERIAL CLOCK FOR THE DATA ; ;Required Rams variables ;------------- ;RTC Variables ;------------- ;spi_read ds 1 ;spi_write ds 1 ;rtc_reg_address ds 1 ;read_write_flag ds 1 ;if bit 0 is 0 then write else read ;ack_flag ds 1 ;acknowledged flag ;time variables ;time_temp ;time_seconds_hundred ds 1 ;time_seconds ds 1 ;time_minutes ds 1 ;time_hours ds 1 ;time_days ds 1 ;time_months ds 1 ;leap_year ds 1 ;time_years ds 1 ;time_flag ds 1 ;date_flag ds 1 ; ;----------------------------------------------------------------------------- ; RTC_INIT clr time_flag ;clear flags for sci parsing clr date_flag rts clr time_seconds_hundred clr time_seconds clr time_minutes clr time_hours ; ;Initialize month and date to January 1 movb #%00000001,time_months ;January movb #%00000001,time_days ;1st ; movb #%00010001,time_days ;eg. shows 11th as the date. movb #%10011000,time_years ;98 and in this case the year 1998 bra TIME_INIT ; NEW_TIME_INIT clr time_seconds_hundred bra TIME_INIT NEW_DATE_INIT jsr READ_TIME_HR jsr READ_TIME_MIN jsr READ_TIME_SEC ; TIME_INIT movb #rtc_write_address,spi_write ;slave address movb #rtc_control_reg_address,rtc_reg_address ;slave control register jsr WRITE_MOD ; ;status ldab #8 ldaa #status1 ;dump status data into rtc jsr clock_bits jsr acknowledge ;get acknowledge signal from rtc ; ;------------------------------- ;Time are set to 00:00:00:00 in 24h format ;Date are set to Jan 1 and the year to 1. The actual year value (ie 1998) must ; set somewhere else. ; ;hundredths of a second ldab #8 ;the rtc is auto incremented ldaa time_seconds_hundred ;address 1 jsr clock_bits jsr acknowledge ;get acknowledge signal from rtc ;seconds ldab #8 ;the rtc is auto incremented ldaa time_seconds ;address 2 jsr clock_bits jsr acknowledge ;get acknowledge signal from rtc ;minutes ldab #8 ;the rtc is auto incremented ldaa time_minutes ;address 3 jsr clock_bits jsr acknowledge ;get acknowledge signal from rtc ;hours ldab #8 ;the rtc is auto incremented ldaa time_hours ;address 4 jsr clock_bits jsr acknowledge ;get acknowledge signal from rtc ldaa time_flag bne time_upx ;year/date ldab #8 ;the rtc is auto incremented ldaa time_days ;address 5 - set date to 1st jsr clock_bits ; and year to 1 jsr acknowledge ;get acknowledge signal from rtc ;weekday/month ldab #8 ;the rtc is auto incremented ldaa time_months ;address 6 - set month to 1st jsr clock_bits ; and weekday 0 jsr acknowledge ;get acknowledge signal from rtc time_upx jsr stop_condition ; jsr small_delay ; ;Update to new time and Initialize clock to start counting ; time_update clr read_write_flag movb #rtc_write_address,spi_write ;slave address movb #rtc_control_reg_address,rtc_reg_address ;slave control register jsr WRITE_MOD ;status ldab #8 ldaa #status2 ;dump status data into rtc jsr clock_bits jsr acknowledge ;get acknowledge signal from rtc jsr stop_condition ; clr time_flag clr date_flag rts ;----------------------------------------------------------------------------- GET_TIME ldx #M_CURRENT_TIME ;Send message jsr SendString jsr READ_TIME_HR ldaa time_hours jsr display_time ldaa #':' jsr SendByte jsr READ_TIME_MIN ldaa time_minutes jsr display_time ldaa #':' jsr SendByte jsr READ_TIME_SEC ldaa time_seconds jsr display_time jsr PutNewLine ldx #M_NEW_TIME ;Send message jsr SendString ; ;----------------------- ;get hour, minunte and second ; inc time_flag ;set flag to sci parsing clr date_flag ;get hour jsr get_time_char cmpa #CR ;cr beq time_ex cmpa #$30 blo GET_TIME cmpa #$32 bhi GET_TIME jsr SB1 ;Outchar before stripping suba #$30 ; jsr shift_a jsr get_time_char cmpa #$30 blo GET_TIME psha ldaa TEMP1 cmpa #$20 ;if first digit is 2 then bne NAN1 ; valid second digit range is 0 - 3 pula cmpa #$33 bra NAN2 NAN1: pula cmpa #$39 ;else valid range is 0 - 9 NAN2: bhi GET_TIME jsr SB1 ;Outchar before stripping anda #%00001111 ldab TEMP1 aba staa time_hours ldaa #':' jsr SendByte ;get minutes jsr get_time_char cmpa #CR ;cr beq time_hr_ex jsr get_minutes_second staa time_minutes ldaa #':' jsr SendByte ;get seconds jsr get_time_char cmpa #CR ;cr beq time_min_ex jsr get_minutes_second staa time_seconds time_hr_ex bra timex time_min_ex bra timex timex lbra NEW_TIME_INIT time_ex clr time_flag rts ; get_minutes_second cmpa #$30 lblo GET_TIME cmpa #$35 lbhi GET_TIME jsr SB1 ;Outchar before stripping suba #$30 jsr shift_a jsr get_time_char cmpa #$30 lblo GET_TIME cmpa #$39 lbhi GET_TIME jsr SB1 ;Outchar before stripping anda #%00001111 ldab TEMP1 aba rts shift_a anda #%00001111 asla ;Shift content 4 times asla asla asla staa TEMP1 rts display_time psha asra ;Shift contents 4 times to carry asra asra asra anda #%00001111 adda #$30 jsr SB1 ;Outchar pula anda #%00001111 adda #$30 jsr SB1 rts ;----------------------------------------------------------------------------- GET_DATE ldx #M_CURRENT_DATE ;Send message jsr SendString ldx #time_years jsr HTOD ; ldaa 0,x ;display first 2 digit ; bsr display_time ; ldaa 1,x ;display last 2 digit ; bsr display_time ldaa #'/' jsr SendByte jsr READ_TIME_MNTH ldaa time_months bsr display_time ldaa #'/' jsr SendByte jsr READ_TIME_DATE ldaa time_days bsr display_time jsr PutNewLine ldx #M_NEW_DATE ;Send message jsr SendString ; ;----------------------- ;get year, month and day ; clr time_flag ;set flag to sci parsing inc date_flag ;get the first 2 digit of the year ldx #time_years jsr get_time_char cmpa #CR ;cr lbeq date_ex cmpa #$30 blo GET_DATE cmpa #$39 bhi GET_DATE jsr SB1 ;Outchar before stripping suba #$30 ; jsr shift_a jsr get_time_char cmpa #$30 blo GET_DATE cmpa #$39 bhi GET_DATE jsr SB1 ;Outchar before stripping anda #%00001111 ldab TEMP1 aba staa 0,x ;time_years ;get the last 2 digit of the year; jsr get_time_char cmpa #CR ;check if cr lbeq date_ex ;yes, then exit, not a complete date cmpa #$30 blo GET_DATE cmpa #$39 lbhi GET_DATE jsr SB1 ;Outchar before stripping suba #$30 ; jsr shift_a jsr get_time_char cmpa #$30 lblo GET_DATE cmpa #$39 lbhi GET_DATE jsr SB1 ;Outchar before stripping anda #%00001111 ldab TEMP1 aba staa 1,x ;time_years ldaa #'/' jsr SendByte ;calculate for leap year condition jsr bcd_to_hex std time_years andb #%00000011 ;check last 2 nibbles aslb aslb aslb aslb aslb aslb stab leap_var ;get months jsr get_time_char cmpa #CR ;check if cr lbeq datex ;yes, go set date cmpa #$30 lblo GET_DATE cmpa #$31 lbhi GET_DATE jsr SB1 ;Outchar before stripping suba #$30 ; jsr shift_a jsr get_time_char cmpa #$30 lblo GET_DATE cmpa #$39 lbhi GET_DATE psha anda #%00001111 ldab TEMP1 aba cmpa #1 lblo GET_DATE cmpa #$12 lbhi GET_DATE staa time_months pula jsr SB1 ;Outchar before stripping ldaa #'/' jsr SendByte ;get days jsr get_time_char cmpa #CR ;check if cr lbeq datex ;yes, go set date cmpa #$30 lblo GET_DATE cmpa #$33 lbhi GET_DATE jsr SB1 ;Outchar before stripping suba #$30 ; jsr shift_a jsr get_time_char cmpa #$30 lblo GET_DATE cmpa #$39 lbhi GET_DATE psha anda #%00001111 ldab TEMP1 aba cmpa #1 lblo GET_DATE cmpa #$31 lbhi GET_DATE staa time_days ldaa leap_var ldab time_days aba staa time_days pula jsr SB1 ;Outchar before stripping datex ldaa leap_var ldx #leap_year staa 0,x lbra NEW_DATE_INIT date_ex clr time_flag clr date_flag rts ;----------------------------------------------------------------------------- READ_TIME_SEC movb #seconds_reg_address,rtc_reg_address ;slave control register jsr READ_TIME movb time_temp,time_seconds jsr stop_condition rts READ_TIME_MIN movb #minutes_reg_address,rtc_reg_address ;slave control register jsr READ_TIME movb time_temp,time_minutes jsr stop_condition rts READ_TIME_HR movb #hours_reg_address,rtc_reg_address ;slave control register jsr READ_TIME movb time_temp,time_hours jsr stop_condition rts READ_TIME_DATE movb #rtc_write_address,spi_write ;slave address movb #rtc_control_reg_address,rtc_reg_address ;slave control register jsr WRITE_MOD ;status ldab #8 ldaa #status3 ;dump status data into rtc jsr clock_bits jsr acknowledge ;get acknowledge signal from rtc nop nop nop nop jsr stop_condition movb #year_date_reg_address,rtc_reg_address ;slave control register bsr READ_TIME movb time_temp,time_days jsr stop_condition rts READ_TIME_WEEK movb #week_month_reg_address,rtc_reg_address ;slave control register bsr READ_TIME movb time_temp,time_hours jsr stop_condition rts READ_TIME_MNTH movb #rtc_write_address,spi_write ;slave address movb #rtc_control_reg_address,rtc_reg_address ;slave control register jsr WRITE_MOD ;status ldab #8 ldaa #status3 ;dump status data into rtc jsr clock_bits jsr acknowledge ;get acknowledge signal from rtc jsr stop_condition movb #week_month_reg_address,rtc_reg_address ;slave control register bsr READ_TIME movb time_temp,time_months jsr stop_condition rts READ_TIME_YR movb #year_date_reg_address,rtc_reg_address ;slave control register bsr READ_TIME movb time_temp,time_years jsr stop_condition rts READ_TIME ; ;set slave address and word address clr read_write_flag movb #rtc_write_address,spi_write ;slave address jsr WRITE_MOD jsr acknowledge ;get acknowledge signal from rtc movb #1,read_write_flag movb #rtc_read_address,spi_read jsr READ_CMD jsr acknowledge ;get acknowledge signal from rtc clr time_temp ldab #8 bsr SHIFT_BITS jsr acknowledge ;get acknowledge signal from rtc rts ;----------------------------------------------------------------------------- SHIFT_BITS bset PORTP,SCL ;Get data from RTC jsr small_delay ldaa PORTP ;read bit in jsr small_delay bclr PORTP,SCL jsr small_delay anda #SDA ;mask unwanted bits clc ;clear carry asla ;Shift content to carry rol time_temp ;store bit into mem decb ;decrement counter bne SHIFT_BITS ;clock bit again if not count down to zero rts ;function return with new time in time_second buff ;---------------------------------------- WRITE_MOD jsr small_delay ;do some delay bset PORTP,%11000000 ;make sure both SDA and SCL are high bset DDRP,%11000000 ;make sure bit 6, and 7 are output jsr small_delay ;do some delay jsr start_condition clr read_write_flag jsr WRITE_CMD ;go start sequence jsr acknowledge ;get acknowledge signal from rtc ldab #8 ldaa rtc_reg_address ;word address 0 jsr clock_bits jsr acknowledge ;get acknowledge signal from rtc rts ;---------------------------------------- READ_CMD jsr small_delay ;do some delay bset PORTP,%11000000 ;make sure both SDA and SCL are high bset DDRP,%11000000 ;make sure bit 6, and 7 are output jsr small_delay ;do some delay jsr start_condition ldab #8 ldaa spi_read ;get rtc address bra clock_bits ;---------------------------------------- WRITE_CMD ldab #8 ldaa spi_write ;get rtc address clock_bits clc ;clear carry bit asla ;move high bit into carry bcs clock_bit_high ;clock a high bit if carry is set bra clock_bit_low ;clock a low bit if carry is not set clock_bit_high bset PORTP,SDA ;set SDA hi jsr small_delay bset PORTP,SCL ;strobe SDA jsr small_delay bclr PORTP,SCL jsr small_delay decb ;decrement counter bne clock_bits ;clock bit again if not count down to zero rts clock_bit_low bclr PORTP,SDA ;set SDA lo jsr small_delay bset PORTP,SCL ;strobe SDA jsr small_delay bclr PORTP,SCL jsr small_delay decb ;decrement counter bne clock_bits ;clock bit again if not count down to zero rts start_condition bclr PORTP,SDA ;set SDA low to start process jsr small_delay bclr PORTP,SCL ;set SCL low to satisfy start process jsr small_delay rts stop_condition ; bclr PORTP,SDA ;set SDA lo jsr small_delay ;do some delay bset PORTP,SCL ;set SCL lo jsr small_delay ;do some delay bset PORTP,SDA ;set SDA hi jsr small_delay rts acknowledge bclr DDRP,SDA ;make SDA (bit 7 of PORTC) as input jsr small_delay ; ldab PORTP ; nop ; nop bset PORTP,SCL jsr small_delay ldab PORTP bclr PORTP,SCL jsr small_delay andb #SDA ;clear unwanted bits clc ;clear carry bit before shifting aslb ;Shift content to carry bcc yes_acknowledge ;check if carry is set no_acknowledge ;carry is not set. No acknowledge clr ack_flag ;no acknowledge and clear acknowledge flag rts yes_acknowledge ;carry is set. There is acknowledge inc ack_flag ;set acknowledge flag ldaa read_write_flag beq writing rts writing ;ready to send stop condition bclr PORTP,SDA ;set SDA lo bset DDRP,SDA ;make SDA (bit 7 of PORTP) as output rts ;----------------------------------------------------------------------------- delay pshy ldy #0 bra dly small_delay pshy ldy #10 dly dbne y,dly puly rts ;------------------------------------------------------------------------------ ;4 digit bcd to 16 bit hex conversion digit_1 fdb 1 digit_10 fdb 10 digit_100 fdb 100 digit_1000 fdb 1000 bcd_to_hex movw #0,result ;initialize variables movw #0,result+2 movw #0,TEMP1 ldab time_years bsr shift_b ldx #digit_1000 ldy #TEMP1 emacs result ldab time_years bsr shift_bb ldx #digit_100 ldy #TEMP1 emacs result ldab time_years+1 bsr shift_b ldx #digit_10 ldy #TEMP1 emacs result ldab time_years+1 bsr shift_bb ldy result+2 aby xgdy std TEMP1 rts shift_b lsrb ;Shift content 4 times lsrb lsrb lsrb shift_bb andb #%00001111 clra std TEMP1 rts ;----------------------------------------------------------------------------- ;HTOD-SUBROUTINE TO CONVERT A 16-BIT HEX NUMBER TO A 5 DIGIT DECIMAL ; HTOD LDD 0,X ;D=HEX VALUE TO BE CONVERTED LDX #10000 IDIV ;FREQ+10,000 ->X; REMAINDER->D XGDX ADDB #$30 STAB DBUFR XGDX LDX #1000 IDIV XGDX ADDB #$30 STAB DBUFR+1 XGDX LDX #100 IDIV XGDX ADDB #$30 STAB DBUFR+2 XGDX LDX #10 IDIV ADDB #$30 STAB DBUFR+4 XGDX ADDB #$30 STAB DBUFR+3 P5DEC LDX #DBUFR ;POINT AT DECIMAL LDAA #$30 ;CHECK FOR LEADING ZEROS CMPA 0,X ;CHECK FOR 10,000S DIGIT BNE P10K ;START AT 10K DIGIT BSR SKP1 ;INX AND PRINT A SPACE CMPA 0,X ;CHECK FOR 1,000S BNE P1K ;START AT 1K DIGIT BSR SKP1 BSR SKP1 DEX CMPA 0,X ;CHECK FOR 100S DIGIT BNE P100 ;START AT 100 DIGIT BSR SKP1 CMPA 0,X ;CHECK 10S DIGIT BNE P10 BSR SKP1 BRA P1 ;START AT 1S DIGIT P10K LDAA 0,X ;10,000 DIGIT PSHX jsr SB1 PULX INX P1K LDAA 0,X PSHX jsr SB1 PULX INX P100 LDAA 0,X PSHX jsr SB1 PULX INX P10 LDAA 0,X PSHX jsr SB1 PULX INX P1 LDAA 0,X jsr SB1 RTS SKP1 PSHA INX LDAA #$20 jsr SB1 PULA RTS