CPU "G:\PROGRAM FILES\CROSS-32 4.0\68HC11.TBL" HOF "MOT8" ;************************************************************************ ; * ; RTC_EXAMPLE_1 Version 1.00 for CPU_3A* series modules * ; * ;************************************************************************ ; INTRODUCTION ;************************************************************************ ; This is a simple example showing how to write to and read from the ; Holtek real time clock (RTC) in single byte and burst modes. ; There are 2 levels of subroutine: ; low level = I/O maipulation to read and write the RTC ; high level = initalise, read to RAM, write from RAM ; Initalise should be called once to get the RTC oscillator running. ; Read to RAM and Write from RAM are the useful bits. ; This code can be loaded into the CPU_3A2 using Buffalo. ; It loads to RAM at 2000H and uses 2200-220F for data. ; Enter the command "BF 2000 22FF 00" to clear some RAM. ; Load the program with "LOAD T" then send the file "rtc_example_2.hex" ; Run it with the command "GO 2000" ; View the RTC data in RAM with "MD 2200"; the 1st 7-bytes are from the RTC. ; add |<-----RTC data-------->| read 1-byte->|--| ; 2200 14 00 00 01 01 01 00 80 00 00 00 00 00 00 14 91 ; The one byte read is the the seconds from the RTC. 80H would ; indicate that the RTC oscillator was disabled and 00 secs. ; As it is it indicates 14-seconds. ; 80H at the end of the RTC data indicates that the Write Protect is ; enabled. ; As supplied it will enable the RTC clock only if it is not already ; enabled, read the seconds register into RAM and then read out all ; 8 RTC registers into RAM. ; You can use Buffalo to edit the values in 2200-2206 and then use the ; "Write from RAM" routine to save the data to the RTC. ; Just watch the clock inhibit bit etc. ; Please refer to the RTC data sheet for internal address and data ; information. ; NOTES: ; Adjust the comments in the main application area to run different ; functions (initalise, read, write). ; If a read immediately follows the initalisation, the seconds register ; returns 00 rather than the seconds; not sure why, maybe RTC settling. ; Not a problem once the RTC is initalised and running. ; The LED/Piezo on the development board pulse when this program runs. ; Some of the short NOP delays can probably be removed. They make ; debugging easier but the RTC should be fast enough to cope with full ; speed. ;************************************************************************ ;************************************************************************ ;************************************************************************ ;************************************************************************ ;************************************************************************ ;************************************************************************ ;************************************************************************ ;************************************************************************ ;************************************************************************ ;************************************************************************ ;************************************************************************ ; * ; EQUATES - SYSTEM - RAM - ROM - EEPROM * ; * ;************************************************************************ ; SYSTEM ; * ;************************************************************************ REGBS EQU 1000H ; START OF REGISTERS x000 to x05F CSIO1 EQU 1600H ; bank select address x600 to x7FF CSIO2 EQU 1800H ; external chip select x800 to xFFF RAM EQU 0000H ; START OF CPU RAM 0000 to 3FFF FLS_SA EQU 8000H ; START OF FLASH 8000 FLS_EA EQU 0FDFFH ; END OF FLASH FDFF EEP_SA EQU 0FE00H ; START OF EEPROM FE00 EEP_EA EQU 0FFFFH ; END OF EEPROM FFFF ;************************************************************************ ; REGISTER * * ;************************************************************************ PORTA EQU 00H ; PORT A DDRA EQU 01H ; PORT A DDR PORTG EQU 02H ; PORT G DDRG EQU 03H ; PORT G DDR PORTB EQU 04H ; PORT B PORTCL EQU 05H ; PROT C LATCHED DATA REG. DDRC EQU 07H ; DATA DIRECTION REGISTER C PORTD EQU 08H ; PORT D DDRD EQU 09H ; DATA DIRECTION REGISTER D PORTE EQU 0AH ; PORT E CFORC EQU 0BH ; TIMER COMPARE FORCE REG. OC1M EQU 0CH ; O/P COMPARE 1 MASK REG. OC1D EQU 0DH ; O/P COMPARE 1 DATA REG TCNT EQU 0EH ; TIMER COUNT H TCNTL EQU 0FH ; L TIC1 EQU 10H ; TIMER O/P COMPARE 1 H TIC1L EQU 11H ; 1 L TIC2 EQU 12H ; 2 H TIC2L EQU 13H ; 2 L TIC3 EQU 14H ; 3 H TIC3L EQU 15H ; 3 L TOC1 EQU 16H ; TIMER O/P COMPARE 1 H TOC1L EQU 17H ; 1 L TOC2 EQU 18H ; 2 H TOC2L EQU 19H ; 2 L TOC3 EQU 1AH ; 3 H TOC3L EQU 1BH ; 3 L TOC4 EQU 1CH ; 4 H TOC4L EQU 1DH ; 4 L TOC5 EQU 1EH ; 5 H TOC5L EQU 1FH ; 5 L TCTL1 EQU 20H ; TIMER CONTROL REG 1 TCTL2 EQU 21H ; TIMER CONTROL REG 2 TMSK1 EQU 22H ; TIMER MASK 1 TFLG1 EQU 23H ; TIMER FLAG 1 TMSK2 EQU 24H ; TIMER MASK 2 TFLG2 EQU 25H ; TIMER FLAG 2 PACTL EQU 26H ; PULSE ACCUMULATOR CONT. REG. PACNT EQU 27H ; PULSE ACCUMULATOR COUNT REG. SPCR EQU 28H ; SPSR EQU 29H ; SPDR EQU 2AH ; BAUD EQU 2BH ; SCI BAUD REG SCCR1 EQU 2CH ; SCI CONTROL 1 REG SCCR2 EQU 2DH ; SCI CONTROL 2 REG SCSR EQU 2EH ; SCI STATUS REG SCDR EQU 2FH ; SCI DATA REG ADCTL EQU 30H ; ADR1 EQU 31H ; ADR2 EQU 32H ; ADR3 EQU 33H ; ADR4 EQU 34H ; BPROT EQU 35H ; OPTION EQU 39H ; OPTION REG COPRST EQU 3AH ; COP RESET REG PPROG EQU REGBS+3BH ; EEPROM PROG REG HPRIO EQU 3CH ; HPRIO REG INIT EQU 3DH ; INIT CONFIG EQU 3FH ; CONFIG REG CSSTRH EQU 5CH ; CS CYCLE STRETCH CSCTL EQU 5DH ; CS CONTROL CSGADR EQU 5EH ; GENERAL PURPOSE CS (RAM) CSGSIZ EQU 5FH ; GENERAL PURPOSE CS SIZE BANKSR EQU 1600H ; BANK SELECT REGISTER ;************************************************************************ ; CONSTANTS * * ;************************************************************************ PIEZO EQU 00010000B ; EVB_3A piezo output (D4) RTC_CLK EQU 00000001B ; RTC clock line G0 RTC_RST EQU 00000010B ; RTC reset line G1 RTC_DAT EQU 00000100B ; RTC data line G2 ; MEMORY ; DFB " rtc_example_2.asm V1.00 01 January 2005 " ; DFB " (c) 2005 PMB " ; Variables RTC_RAM EQU 2200H ; RTC data in RAM RTC_BYT EQU 220EH ; RTC one byte read RTC_CMD EQU 220FH ; RTC command byte ;************************************************************************ ;************************************************************************ ;************************************************************************ ;************; P R O G R A M S T A R T S H E R E ******************** ;************; P R O G R A M S T A R T S H E R E ******************** ;************; P R O G R A M S T A R T S H E R E ******************** ;************************************************************************ ;************************************************************************ ;************************************************************************ ; INITIALISATION ROUTINE ; ********************** ORG 2000H ; code in RAM ;************ ; INITALISATION START LDX #REGBS ; register base address BSET DDRG,X,00000011B ; make RST & CLK = outputs BSET DDRD,X,PIEZO ; make piezo an output BSET PORTD,X,PIEZO ; turn piezo on ;************************************************************************ ;************************************************************************ ;************************************************************************ ; APPLICATION CORE ;************************************************************************ ;************************************************************************ ;************************************************************************ ;************ ; initalise the RTC MAIN JSR RTCINI ; enable the RTC clock ;************ ; read one byte from RTC (seconds) BSET PORTG,X,RTC_RST ; set reset high LDAA #10000001B ; get RTC command byte JSR RTCTX ; send command byte to RTC JSR RTCRX ; read one byte from RTC STAA RTC_BYT ; save byte BCLR PORTG,X,RTC_RST ; set reset low ;************ ; read or write RTC JSR RTC_RD ; byte ; read RTC to RAM (2000-2007) ; JSR RTC_BR ; burst ; read RTC to RAM (2000-2007) ; JSR RTC_WR ; byte ; write RAM to RTC (2000-2007) ; JSR RTC_BW ; burst ; write RAM to RTC (2000-2007) ;************ ; finished BCLR PORTD,X,PIEZO ; turn piezo off JMP 8000H ; return to Buffalo ;************************************************************************ ;************************************************************************ ;************************************************************************ ;************************************************************************ ;************************************************************************ ; RTC SUBROUTINES ;************************************************************************ ;************************************************************************ ;************************************************************************ ;************************************************************************ ;************************************************************************ ; Sequence = command byte then data byte. ; Bytes are sent and received LSB first. ; Command byte ; bit 0 = read/write ; bits 1,2,3 = register address ; bits 4,5 = 00 for single byte, 11 for burst mode ; bit 6 = always low ; bit 7 = always high ;****************************************************************************** ;****************************************************************************** ; RTC ROUTINES (high level) ;****************************************************************************** ;****************************************************************************** ;****************************************************************************** ; RTC Initalisation ; This routine first checks the RTC oscillator. If it's not already running ; it is enabled. It must be enabled for the RTC to run. RTCINI BSET DDRG,X,00000011B ; make RST & CLK = outputs ; does it need initalising ?? BSET PORTG,X,RTC_RST ; set reset high LDAA #10000001B ; get RTC command byte JSR RTCTX ; send command byte to RTC JSR RTCRX ; read one byte from RTC STAA RTC_BYT ; save byte BCLR PORTG,X,RTC_RST ; set reset low BITA #10000000B ; osc enable bit mask BEQ RTCINI9 ; no, skip ; write enable LDAA #10001110B ; command byte (111-write) BSET PORTG,X,RTC_RST ; set reset high JSR RTCTX ; send command byte LDAA #00000000B ; data byte JSR RTCTX ; send byte BCLR PORTG,X,RTC_RST ; set reset low ; enable osc. LDAA #10000000B ; command byte (000-write) BSET PORTG,X,RTC_RST ; set reset high JSR RTCTX ; send command byte LDAA #00000000B ; data byte (enable) JSR RTCTX ; send byte BCLR PORTG,X,RTC_RST ; set reset low ; write protect LDAA #10001110B ; command byte (111-write) BSET PORTG,X,RTC_RST ; set reset high JSR RTCTX ; send command byte LDAA #10000000B ; data byte JSR RTCTX ; send byte BCLR PORTG,X,RTC_RST ; set reset low ; finished RTCINI9 RTS ; finished ;****************************************************************************** ; read RTC to RAM in byte mode ; Reads 8 bytes from RTC to RAM ; setup RTC_RD LDY #RTC_RAM ; RAM target address LDAB #08D ; byte counter LDAA #10000001B ; initalise RTC command byte (000-read) STAA RTC_CMD ; save ; read RTC RTC_RD1 BSET PORTG,X,RTC_RST ; set reset high NOP ; delay NOP ; " LDAA RTC_CMD ; get RTC command byte JSR RTCTX ; send command byte to RTC JSR RTCRX ; read one byte from RTC STAA 0,Y ; save byte BCLR PORTG,X,RTC_RST ; set reset low ; loop LDAA RTC_CMD ; get command byte ADDA #00000010B ; increment address STAA RTC_CMD ; save command for next pass INY ; next target address DECB ; byte count -1 BNE RTC_RD1 ; next byte ; finished RTS ; return ;****************************************************************************** ; read RTC to RAM in burst mode ; Reads 8 bytes from RTC to RAM ; setup RTC_BR LDY #RTC_RAM ; RAM target address LDAB #08D ; byte counter ; command BSET PORTG,X,RTC_RST ; set reset high LDAA #10111111B ; RTC burst read command JSR RTCTX ; send command byte to RTC ; read RTC loop RTC_BR1 JSR RTCRX ; read one byte from RTC STAA 0,Y ; save byte INY ; next target address DECB ; byte count -1 BNE RTC_BR1 ; next byte ; finished BCLR PORTG,X,RTC_RST ; set reset low RTS ; return ;****************************************************************************** ; write RAM to RTC in byte mode ; Writes 7 bytes from RAM to RTC ; write enable RTC_WR LDAA #10001110B ; command byte (111-write) BSET PORTG,X,RTC_RST ; set reset high JSR RTCTX ; send command byte LDAA #00000000B ; data byte JSR RTCTX ; send byte BCLR PORTG,X,RTC_RST ; set reset low ; setup LDY #RTC_RAM ; RAM target address LDAB #07D ; byte counter LDAA #10000000B ; initalise RTC command byte (000-write) STAA RTC_CMD ; save ; write RTC RTC_WR1 NOP ; delay NOP ; " BSET PORTG,X,RTC_RST ; set reset high LDAA RTC_CMD ; get RTC command byte JSR RTCTX ; send command byte to RTC LDAA 0,Y ; get data byte JSR RTCTX ; send one byte to RTC BCLR PORTG,X,RTC_RST ; set reset low ; loop LDAA RTC_CMD ; get command byte ADDA #00000010B ; increment address STAA RTC_CMD ; save command for next pass INY ; next target address DECB ; byte count -1 BNE RTC_WR1 ; next byte ; finished RTS ; return ;****************************************************************************** ; write RAM to RTC in burst mode ; Writes 7 bytes from RAM to RTC ; write enable RTC_BW LDAA #10001110B ; command byte (111-write) BSET PORTG,X,RTC_RST ; set reset high JSR RTCTX ; send command byte LDAA #00000000B ; data byte JSR RTCTX ; send byte BCLR PORTG,X,RTC_RST ; set reset low ; setup LDY #RTC_RAM ; RAM target address LDAB #07D ; byte counter ; command BSET PORTG,X,RTC_RST ; set reset high LDAA #10111110B ; RTC burst write command JSR RTCTX ; send command byte to RTC ; write RTC loop RTC_BW1 LDAA 0,Y ; get data byte JSR RTCTX ; send one byte to RTC INY ; next target address DECB ; byte count -1 BNE RTC_BW1 ; next byte ; finished BCLR PORTG,X,RTC_RST ; set reset low RTS ; return ;****************************************************************************** ;****************************************************************************** ; RTC ROUTINES (low level) ;****************************************************************************** ;****************************************************************************** ; These subroutines handle communications with the RTC device. ; RESET line (RTC_RST) is always an output ; CLOCK line (RTC_CLK) is always an output ; DATA line (RTC_DAT) . ; These are the low level routines. ; RTCRX receive byte from slave (returned in "RXDAT") ; RTCTX transmit byte to slave (from "W") ;************************************************************************ ; SEND DATA BYTE IN "A" TO RTC ; Single byte transmission to RTC (LSB first) ; The data is changed while the clock is low, the clock is then ; pulsed high. ; This routine does not include taking the RTC reset line high during ; data transfer. RTCTX PSHB ; save B BSET DDRG,X,RTC_DAT ; data line = output LDAB #08D ; bit counter ; write RTCTX1 RORA ; move bit to carry BCC RTCTX2 ; BSET PORTG,X,RTC_DAT ; data = 1 BRA RTCTX3 ; RTCTX2 BCLR PORTG,X,RTC_DAT ; data = 0 RTCTX3 NOP ; bit delay NOP ; " BSET PORTG,X,RTC_CLK ; set clock bit NOP ; bit delay NOP ; " BCLR PORTG,X,RTC_CLK ; clear clock bit DECB ; decrement bit counter BNE RTCTX1 ; next bit ; finished BCLR PORTG,X,RTC_DAT ; data = 0 BCLR DDRG,X,RTC_DAT ; data line = input PULB ; restore B RTS ; finished ;************ ; RECEIVE DATA BYTE TO "A" ; Single byte reception from RTC (LSB first) returned in "A" ; Data from the RTC is valid following the falling edge of the clock. ; Data should be read on the rising edge of the clock. RTCRX PSHB ; save B BCLR DDRG,X,RTC_DAT ; data line = input LDAB #08D ; bit counter ; read RTCRX1 BSET PORTG,X,RTC_CLK ; set clock bit NOP ; bit delay NOP ; " PSHA ; save data byte LDAA PORTG,X ; read data ANDA #RTC_DAT ; test data bit BNE RTCRX2 ; high = set carry CLC ; clear the carry BRA RTCRX3 ; RTCRX2 SEC ; set the carry RTCRX3 PULA ; restore data byte RORA ; move data in from carry BCLR PORTG,X,RTC_CLK ; clear clock bit NOP ; bit delay NOP ; " DECB ; decrement bit counter BNE RTCRX1 ; next bit ; finished PULB ; restore B RTS ; finished ;************************************************************************ ;************************************************************************ ;************************************************************************ ;************************************************************************ ;************************************************************************ ; OTHER SUBROUTINES ;************************************************************************ ;************************************************************************ ;************************************************************************ ;************************************************************************ ;************************************************************************ ; Finished, pulse the PIEZO fast TESTB LDX #1000H ; register base address TSTB1 BRSET PORTD,X,PIEZO,TSTB2 ; check PIEZO BSET PORTD,X,PIEZO ; PIEZO = on BRA TSTB3 TSTB2 BCLR PORTD,X,PIEZO ; PIEZO = off TSTB3 LDY #0FFFFH ; delay TSTB4 DEY BNE TSTB4 ; delay loop RTS ; return ;************************************************************************ ;************************************************************************ ;************************************************************************ ;************************************************************************ ;************************************************************************ END