;FLASH LOADER FOR WINBOND UC 32KB/64KB VERSION, ;AUTOBAUD FEATURE ONLY FOR 9600 bps !!! ;PDW MARTHEL, WWW.MARTHEL.PL ;autor: Mariusz £acina ; ;version date: 16.09.2005 ;ASSEMBLER AS31.EXE ;******************************************************************************* ;* PORTS DEFINITIONS * ;******************************************************************************* .equ P1_0, 090H .equ P1_1, 091H .equ P1_2, 092H .equ P1_3, 093H .equ P1_4, 094H .equ P1_5, 095H .equ P1_6, 096H .equ P1_7, 097H .equ P0_0, 080H .equ P0_1, 081H .equ P0_2, 082H .equ P0_3, 083H .equ P0_4, 084H .equ P0_5, 085H .equ P0_6, 086H .equ P0_7, 087H .equ P2_0, 0A0H .equ P2_1, 0A1H .equ P2_2, 0A2H .equ P2_3, 0A3H .equ P2_4, 0A4H .equ P2_5, 0A5H .equ P2_6, 0A6H .equ P2_7, 0A7H .equ P3_0, 0B0H .equ P3_1, 0B1H .equ P3_2, 0B2H .equ P3_3, 0B3H .equ P3_4, 0B4H .equ P3_5, 0B5H .equ P3_6, 0B6H .equ P3_7, 0B7H ;******************************************************************************* ;* EXTERNAL WATCHDOG DEFINITION * ;******************************************************************************* .equ Watchdog, P1_7 ;IF YOU ARE NOT USING EXTERNAL WATCHDOG, SELECT ADRESS OF ANY FREE BIT ;******************************************************************************* ;* EXTRA SFR DEFINITIONS * ;******************************************************************************* ;ISP: .equ SFRAL, 0C4H .equ SFRAH, 0C5H .equ SFRFD, 0C6H .equ SFRCN, 0C7H .equ CHPCON, 0BFH .equ CHPENR, 0F6H ;******************************************************************************* ;* FLASH APROM MEMORY SIZE * ;******************************************************************************* ;FOR 32KB: .equ MAXADRL, 0FFH ;32kB version .equ MAXADRH, 07FH ;FOR 64KB: ;.equ MAXADRL, 0FFH ;64kB version ;.equ MAXADRH, 0FFH ;SELECT FLASH SIZE ;******************************************************************************* ;* CONSTANT DEFINITIONS * ;******************************************************************************* .equ RS_TIM_INIT, 0x03 ;serial transmision timeout 3 * 10 ms ;******************************************************************************* ;* FRAMES TO PC * ;******************************************************************************* .equ OK, 01H ;ACKNOWLEDGE TO THE PC .equ ADRES_ERR, 02H ;ADRESS ERROR .equ CRC_ERR, 03H ;CRC_ERR .equ PROG_TEST, 06H ;CALCULATIONS TEST .equ PROG_ERR, 07H ;PROGRAMMING ERROR .equ ERA_ERR, 08H ;ERASING ERROR .equ BLANK_OK, 09H ;BLANK CHECK OK .equ BLANK_ER, 0AH ;BLANK CHECK ERROR .equ WERYF_ERR, 0CH ;VERIFICATION ERROR ;******************************************************************************* ;* FRAMES FROM PC * ;******************************************************************************* .equ PROGRAM, 01H ;NEXT FRAME TO FLASH .equ WERYFIKUJ, 02H ;VERIFICATION FRAME .equ KASUJ, 06H ;ERASE .equ RESET, 07H ;RESET .equ TEST, 08H ;TEST .equ BLANK, 09H ;BLANK CHECK ;******************************************************************************* ;* IDATA < 0X80 * ;******************************************************************************* ;DATA SEGMENT .equ POM1H, 77H ;AUTOBAUD RESULT .equ POM1L, 76H .equ SREDNL, 75H ;9600 BPS BIT TIME .equ SREDNH, 74H .equ RS_TIMEOUT, 73H ;SERIAL PORT TIMEOUT COUNTER .equ BUF_POINT, 72H ;RECEIVE BUFFER POINTER .equ LICZ_ODEB, 71H ;RECEIVE BYTES COUNTER .equ LICZ_DOODB, 70H ;BYTES TO RECEIVE (FRAME LENGTH) .equ KOD, 6FH ;FRAME TYPE .equ ADRHH, 6EH ;FLASH ADRES POINTER (UPPER) .equ ADRHL, 6DH ;FLASH ADRES POINTER (HIGH) .equ ADRLL, 6CH ;FLASH ADRESS POINTER (LOW) .equ CRC16H, 6BH ;CRC16 HIGH OF RECEIVED FRAME .equ CRC16L, 6AH ;CRC16 LOW OF RECEIVED FRAME .equ WYKONAJ, 69H ;FRAME RECEIVED FLAG .equ TH1INIT, 68H ;RELOAD VALUE FOR T1 COUNTER - TIMEOUT 10 MS GENERATION .equ TL1INIT, 67H ;RELOAD VALUE FOR T1 COUNTER - TIMEOUT 10 MS GENERATION .equ ER_TIM_H, 66H ;ERASING TIME H .equ ER_TIM_L, 65H ;ERASING TIME L .equ PR_TIM_H, 64H ;PROGRAMMING TIME H .equ PR_TIM_L, 63H ;PROGRAMMING TIME L .equ READ_T_L, 61H ;READING TIME L .equ READ_T_H, 60H ;READING TIME H .equ CRC_BUFF, 5FH ;BUFFER FOR CRC CALCULATION .equ CRCHI, 5EH ;-"- .equ CRCLO, 5DH ;-"- .equ ILOSC, 5CH ;LENGTH OF FRAME TO SEND .equ PC_KOD, 5BH ;TYPE OF FRAME TO SEND .equ BLAD, 5AH ;0 - NO ERRORS ;1 - PROGRAMMING ;2 - ADRESS ERROR ;3 - ERASING ERROR ;4 - BLANK CHECK ERROR .equ DATA, 59H ;DATA BUFFER .equ RS_SYNCHRO, 58H ;0XFF - not synchronized ;0x55 - synchronized .equ DIVID_H, 57H ;DIVIDING PROCEDURE .equ DIVID_L, 56H .equ DIV_QUOT, 55H .equ DIV_REMAIN, 54H .equ DIVIDE_COUNTER, 53H .equ DIVISOR, 52H ;segmenty kodu: ;------------------------------------------------------------------ .org 0 LJMP MAIN ;TO PROGRAM START .org 03H RETI .org 0BH RETI .org 013H RETI .org 01BH LJMP T1_SERVIS ;T1 INTERRUPT RETI .org 023H ;SERIAL PORT INTERRUPT LJMP RS_SERVIS .org 02BH RETI .org 03BH RETI .org 043H RETI .org 04BH RETI .org 053H RETI .org 05BH RETI .org 063H RETI .org 06BH RETI .org 073H RETI MAIN: MOV IE,#0H ;INTERRUPTS SWITCHED OFF MOV BUF_POINT,#80H ;SERIAL RECEIVER DATA POINTER MOV RS_TIMEOUT,#RS_TIM_INIT ;SERIAL PORT TIMEOUT COUNTER MOV LICZ_ODEB,#00H ;RECEIVED BYTES COUNTER MOV LICZ_DOODB,#087H ;BYTES TO RECEIVE COUNTER MOV WYKONAJ,#00H ;FRAME RECEIVED FLAG MOV BLAD,#0H ;ERROR TYPE MOV RS_SYNCHRO,#0XFF ;SERIAL PORT SYNCHRONISATION ;FLAG ;******************************************************************************* ;* SERIAL PORT CONFIGURATION * ;******************************************************************************* MOV SCON,#60H ;STOP RECEIVING SETB P3_0 SETB P3_1 ;ALL INPUTS ;******************************************************************************* ;* TIMERS CONFIGURATION * ;******************************************************************************* ;T0, T1 - 16 b LENGTH MOV TCON,#00H ;COUNTERS STOPPED MOV TMOD,#011H ;16 BITS COUNTERS ;T2 - BAUD GENERATION MOV T2CON,#30H ;0011 0000B - STOPPED MOV RCAP2L,#0H MOV RCAP2H,#0H MOV TL2,#0H ;T2 CLEARED MOV TH2,#0H ;******************************************************************************* ;* AUTOBAUD MEASURING FOR 9600 bps * ;******************************************************************************* ;RESULT IN: POM1H:POM1L ;YOU CAN USE FIXED BAUD RATE FOR SELECTED QUARZ ; ;IN SUCH CASE, YOU SHOULD MANUALLY SETUP THE FOLLOWING VARIABLES: ; ;RCAP2H:RCAP2L - FOR BUAD RATE OF SERIAL PORT ; ;TH1INIT:TL1INIT - FOR 10 MS INTERRUPT PERIOD OF T1 COUNTER (16 BIT MODE) - IT'S NOT CRITICAL ; ;ER_TIM_H:ER_TIM_H - FOR 16.5 MS ERASE TIME (T0 COUNTER IN 16 BIT MODE) - IMPORTANT ; ;PR_TIM_H:PR_TIM_L - FOR 55USEK PROGRAMMING TIME (T0 COUNTER IN 16 BIT MODE) - IMPORTANT ; ;READ_T_H:READ_T_L - FOR 25 USEK READ TIME (T0 COUNTER IN 16 BIT MODE) - IT'S NOT CRITICALL ; ;AND JUMP TO: ; LJMP F04BOOT_TEST LCALL IMPULS ;T2 IS COUNTING QCLK/2 !!! ;******************************************************************************* ;* CALCULATION OF BIT DURATION IN 9600 SERIAL TRANSMISSION * ;******************************************************************************* ;RESULT IN: SREDNH:SREDNL ; ;SREDNH:SREDNL = (POM1H:POM1L)/8 IS GIVING 0.625 MSEK FOR QCLK/12 ; MOV R2,POM1L ;RESULT TO R3:R2 MOV R3,POM1H MOV R4,#0 ;REMAINDER MOV R6,#03H ;LOOP COUNTER DZIEL8: ;DIVIDE BY 8 LOOP CLR C MOV A,R3 ;HIGH BYTE RRC A MOV R3,A MOV A,R2 ;LOW BYTE RRC A MOV R2,A MOV A,R4 ;REMAINDER RRC A MOV R4,A DJNZ R6,DZIEL8 ;SHIFT 3 POSITIONS TO RIGHT ;CHECKING THE REMAINDER MOV R6,#05H ;SHIFTING TO LOWEST BIT POSITION MOV A,R4 KORRESZT: RR A DJNZ R6,KORRESZT CJNE A,#04H,KORTEST KORTEST: JC BEZKOR ;IF REMAINDER >= 4, ADD 1 TO THE RESULT MOV A,R2 ;INCREMENTING THE RESULT BY 1 ADD A,#01H MOV R2,A MOV A,R3 ADDC A,#0H MOV R3,A BEZKOR: MOV SREDNH,R3 ;BIT DURATION IN SREDBH:SREDNL MOV SREDNL,R2 ;******************************************************************************* ;* CALCULATION OF T2 RELOAD REGISTERS FOR 9600 SERIAL TRANSMISSION * ;******************************************************************************* ;RESULT IN RCAP2H:RCAP2L = [ 0X10000 - (SREDNH:SREDNL)/16 ] MOV R4,#0H ;REMAINDER MOV R6,#04H ;DIVIDE LOOP COUNTER DZIEL16: ;DIVIDE BY 16 CLR C MOV A,R3 ;HIGH BYTE RRC A MOV R3,A MOV A,R2 ;LOW BYTE RRC A MOV R2,A MOV A,R4 ;REMAINDER RRC A MOV R4,A DJNZ R6,DZIEL16 ;SHIFT 4 POSITIONS TO RIGHT MOV R6,#04H ;REMAINDER CORRECTION MOV A,R4 ;SHIFT 4 POSITIONS TO RIGHT KORRESZTY: RR A DJNZ R6,KORRESZTY CJNE A,#08H,DZTEST16 ;IF REMAINDER >= 8, ADD 1 TO THE RESULT DZTEST16: JC BKOR16 ;JUMP IF NOT MOV A,R2 ;CORRECT RESULT BY ADDING 1 ADD A,#01H MOV R2,A MOV A,R3 ADDC A,#0H MOV R3,A MOV A,R4 ADDC A,#0H MOV R4,A BKOR16: ;R3:R2 = (SREDNH:SREDNL)/16, BUT BECAUSE COUNTER IS COUNTING UP, ; WE NEED [ 0X10000 - (SREDNH:SREDNL)/16 ] MOV R5,#0FFH MOV R6,#0FFH MOV A,R5 ;R5:R6 =[ 0XFFFF - (SREDNH:SREDNL)/16] CLR C SUBB A,R2 MOV R5,A MOV A,R6 SUBB A,R3 MOV R6,A MOV A,R5 ;R5:R6 = R5:R6 + 1 ADD A,#01H MOV R5,A MOV A,R6 ADDC A,#0H MOV R6,A MOV TL2,R5 ;RESULT IN RCAP2H:RCAP2L MOV RCAP2L,R5 MOV TH2,R6 MOV RCAP2H,R6 ;******************************************************************************* ;* CALCULATION OF T1 RELOAD REGISTERS FOR 10MSEK INTERRUPT * ;******************************************************************************* ;TH1:TL1 = [ 0X10000 - (SREDNH:SREDNL)*16 ] (0.625MS * 16 = 10 MS) CPL Watchdog MOV R2,SREDNL MOV R3,SREDNH ;R3:R2 = SREDNH:SREDNL MOV R4,#04H ;LOOP COUNTER MNOZ16: CLR C ;MULTIPLY BY 16 MOV A,R2 RLC A MOV R2,A MOV A,R3 RLC A MOV R3,A DJNZ R4,MNOZ16 ;SHIFT TO LEFT BY 4 POSITIONS ;T1 = 0X10000-R3:R2 MOV R5,#0FFH MOV R6,#0FFH MOV A,R5 CLR C SUBB A,R2 ;R3:R2 = 0XFFFF-R3:R2 MOV R5,A MOV A,R6 SUBB A,R3 MOV R6,A MOV A,R5 ;R3:R2 = R3:R2+1 ADD A,#01H MOV R5,A MOV A,R6 ADDC A,#0H MOV R6,A MOV TL1INIT,R5 ;COUNTER T1 VALUE FOR 10MSEK PERIOD MOV TH1INIT,R6 MOV TL1,TL1INIT ;T1 INITIALISATION MOV TH1,TH1INIT ORL IE,#08H ;T1 INTERRUPT ENABLED SETB TR1 ;T1 START ;******************************************************************************* ;* ERASING TIME 16.25 MS CALCULATION * ;******************************************************************************* ;T0_ERASE_TIME = 0X10000-[SREDNH:SREDNL*16 + SREDNH:SREDNL*8 + SREDNH:SREDNL*2] ;FOR 9600 BPS: ; T0_ERASE_TIME=16.25 MSEK (0.625MS*26 = 16.25 MS) MOV R2,SREDNL MOV R3,SREDNH ;R3:R2 = SREDNH:SREDNL ;R6:R5 = RESULT MOV R1,#04H ;LOOP COUNTER MNOZ161: CLR C MOV A,R2 RLC A MOV R2,A MOV A,R3 RLC A MOV R3,A DJNZ R1,MNOZ161 ;MULTIPLY BY 16 LOOP MOV A,R2 MOV R5,A MOV A,R3 MOV R6,A ;R6:R5 = SREDNH:SREDNL*16 MOV R2,SREDNL MOV R3,SREDNH ;R3:R2 = SREDNH:SREDNL MOV R1,#03H ;LOOP COUNTER MNOZ81: CLR C MOV A,R2 RLC A MOV R2,A MOV A,R3 RLC A MOV R3,A DJNZ R1,MNOZ81 ;MULTIPLY BY 8 LOOP MOV A,R5 ADD A,R2 MOV R5,A MOV A,R6 ADDC A,R3 MOV R6,A ;R6:R5 = R6:R5+[SREDNH:SREDNHL*8] MOV R2,SREDNL MOV R3,SREDNH ;R3:R2 = SREDNH:SREDNL CLR C ;MULTIPLY BY 2 MOV A,R2 ;SHIFT TO LEFT BY 1 POSITION RLC A MOV R2,A MOV A,R3 RLC A MOV R3,A MOV A,R5 ADD A,R2 MOV R5,A MOV A,R6 ADDC A,R3 MOV R6,A ;R6:R5 = R6:R5+[SREDNH:SREDNHL*2] MOV R2,#0FFH ;R6:R5 = 0X10000-R6:R5 MOV R3,#0FFH MOV A,R2 CLR C SUBB A,R5 MOV R5,A MOV A,R3 SUBB A,R6 MOV R6,A ;R6:R5 = 0XFFFF - R6:R5 MOV A,R5 ADD A,#01H MOV R5,A MOV A,R6 ADDC A,#0H MOV R6,A ;R6:R5 = R6:R5 + 1 ;ER_TIM_L = 0X10000-[SREDNH:SREDNL*16 + SREDNH:SREDNL*8 + SREDNH:SREDNL*2] MOV ER_TIM_L,R5 MOV ER_TIM_H,R6 ;******************************************************************************* ;* PROGRAMMING TIME 52 us CALCULATION * ;******************************************************************************* ; PROGRAMMING TIME = 0.625MS / 12 = 52 us MOV DIVID_H,SREDNH MOV DIVID_L,SREDNL MOV DIVISOR,#0X0C LCALL DIVIDE MOV A,DIV_REMAIN CJNE A,#06H,DZ161 ;IF REMAINDER >= 6, ADD 1 TO THE RESULT DZ161: JC BK161 ;JUMP IF NOT INC DIV_QUOT BK161: MOV PR_TIM_H,#0X00 ;RESULT MOV PR_TIM_L,DIV_QUOT MOV A,#0FFH CLR C SUBB A,PR_TIM_L ;RESULT = 0X10000-RESULT MOV PR_TIM_L,A MOV A,#0FFH SUBB A,PR_TIM_H MOV PR_TIM_H,A MOV A,PR_TIM_L ADD A,#01H MOV PR_TIM_L,A MOV A,PR_TIM_H ADDC A,#0H MOV PR_TIM_H,A ;******************************************************************************* ;* READING TIME = PROGRAMMING TIME / 2 * ;******************************************************************************* MOV A,DIV_QUOT CLR C RRC A ;/2 MOV READ_T_L,A MOV READ_T_H,#0X00 MOV A,#0FFH ;RESULT = 0X10000 - RESULT CLR C SUBB A,READ_T_L ;L MOV READ_T_L,A MOV A,#0FFH SUBB A,READ_T_H ;H MOV READ_T_H,A ;RESULT = 0XFFFF - RESULT MOV A,READ_T_L ADD A,#01H MOV READ_T_L,A MOV A,READ_T_H ADDC A,#0H MOV READ_T_H,A ;RESULT = RESULT + 1 ;******************************************************************************* ;* F04BOOT MODE TESTING * ;******************************************************************************* F04BOOT_TEST: CLR TR0 CLR TR1 MOV IE,#0H ;INTERRUPTS DISABLED MOV TL0,READ_T_L MOV TH0,READ_T_H MOV CHPENR,#87H MOV CHPENR,#59H ;CHPCON ENABLED MOV CHPCON,#03H MOV IE,#82H ;INTERRUPTS ENABLED SETB TR0 CPL Watchdog MOV PCON,#01H ;IDLE MOV CHPENR,#0H ;CHPCON DISABLED CLR TR0 ;T0 STOP SETB TR1 MOV IE,#98H ;INTERRUPTS ENABLED ORL T2CON,#04H ;START T2 SETB REN ;START RECEIVING CLR TI CLR RI ;CLEARING SERIAL PORT FLAGS ;******************************************************************************* ;* MAIN LOOP * ;******************************************************************************* PETLA: MOV A,WYKONAJ ;IF RS FRAME RECEIVED, WYKONAJ=1 JZ PETLA MOV RS_SYNCHRO,#0XFF ;SERIAL NOT SYNCHRONIZED, NEXT FRAME RECEIVED MOV WYKONAJ,#0X00 ;******************************************************************************* ;* FRAME RECEIVED * ;******************************************************************************* LCALL CHECK_CRC16 ;CRC16 TEST JZ CRC_OK ;JUMP IF CRC16 OK CRC_ERROR: MOV PC_KOD,#CRC_ERR LCALL POTW_RAMKE ;SENDING CRC ERROR TO PC SETB REN MOV IE,#98H ;INTERRUPTS FROM SERIAL PORT AND T1 LJMP PETLA ;******************************************************************************* ;* FRAME TYPE DECODING * ;******************************************************************************* CRC_OK: MOV A,KOD CJNE A,#TEST,POL_SK002 ;FOR TESTING ONLY, CALCULATED TIMES MOV PC_KOD,#PROG_TEST LCALL SEND_CALCULATIONS LJMP POL_INIT ;******************************************************************************* ;* PROGRAMMING * ;******************************************************************************* POL_SK002: CJNE A,#PROGRAM,POL_SK003 LCALL PROGRAMUJ MOV A,BLAD JNZ POL_BLEDY MOV PC_KOD,#OK LCALL POTW_RAMKE LJMP POL_INIT ;******************************************************************************* ;* ERASING * ;******************************************************************************* POL_SK003: CJNE A,#KASUJ,POL_SK004 LCALL KASOWANIE MOV A,BLAD JNZ POL_BLEDY MOV PC_KOD,#OK LCALL POTW_RAMKE LJMP POL_INIT ;******************************************************************************* ;* VERIFICATION * ;******************************************************************************* POL_SK004: CJNE A,#WERYFIKUJ,POL_SK005 LCALL ODCZYTUJ MOV A,BLAD JNZ POL_BLEDY MOV PC_KOD,#OK LCALL POTW_RAMKE LJMP POL_INIT ;******************************************************************************* ;* BLANK CHECK * ;******************************************************************************* POL_SK005: CJNE A,#BLANK,POL_SK006 LCALL BLANK_CHECK MOV A,BLAD JNZ POL_BLEDY MOV PC_KOD,#BLANK_OK LCALL POTW_RAMKE LJMP POL_INIT ;******************************************************************************* ;* SOFTWARE RESET * ;******************************************************************************* POL_SK006: CJNE A,#RESET,POL_SK007 LCALL RESETUJ LJMP POL_INIT POL_SK007: LJMP POL_INIT ;******************************************************************************* ;* ERRORS SERVIS * ;******************************************************************************* POL_BLEDY: CJNE A,#01H,POL_B02 MOV BLAD,#0H MOV PC_KOD,#PROG_ERR ;PROGRAMMING ERROR LCALL POTW_RAMKE LJMP POL_INIT POL_B02: CJNE A,#02H,POL_B03 MOV BLAD,#0H MOV PC_KOD,#ADRES_ERR ;ADRESS ERROR LCALL POTW_RAMKE LJMP POL_INIT POL_B03: CJNE A,#03H,POL_B04 MOV BLAD,#0H MOV PC_KOD,#ERA_ERR ;ERASE ERROR LCALL POTW_RAMKE LCALL POL_INIT POL_B04: CJNE A,#04H,POL_B05 MOV BLAD,#0H ;BLANK CHECK ERROR MOV PC_KOD,#BLANK_ER ;DEVICE NOT BLANK LCALL POTW_RAMKE LCALL POL_INIT POL_B05: CJNE A,#05H,POL_B06 MOV BLAD,#0H MOV PC_KOD,#WERYF_ERR ;VERIFICATION ERROR LCALL POTW_RAMKE LCALL POL_INIT POL_B06: LJMP POL_INIT ;******************************************************************************* ;* RESTART FOR NEW SERIAL FRAME * ;******************************************************************************* POL_INIT: MOV KOD,#0H CLR RI SETB REN MOV IE,#98H ;INTERRUPT CONFIG LJMP PETLA ;******************************************************************************* ;* T1 SERVICE, EVERY 10 msek * ;******************************************************************************* T1_SERVIS: PUSH ACC PUSH PSW MOV TH1,TH1INIT MOV TL1,TL1INIT CPL Watchdog ;******************************************************************************* ;* SERIAL PORT RECEIVE TIMEOUT * ;******************************************************************************* MOV A,RS_TIMEOUT ;CHECK TIMEOUT ONLY NOT ZERO JZ T1_S_S001 DEC RS_TIMEOUT MOV A,RS_TIMEOUT JNZ T1_S_S001 ;TIMEOUT TEST MOV RS_SYNCHRO,#0XFF ;RECEIVER RESYNCHRONISATION NEEDED MOV IE,#98H ;INTERRUPTS CONFIG REFRESHED T1_S_S001: T1_SERV_EXIT: POP PSW POP ACC RETI ;******************************************************************************* ;* SERIAL PORT RECEIVER INTERRUPT SERVICE * ;******************************************************************************* ;LICZ_ODEB - RECEIVE COUNTER ;LICZ_DOODB - FRAME LENGTH ;RS_TIMEOUT - RECEIVE TIMEOUT ; ;FRAME FORMAT: ; ; 0X55 - AUTOBAUD BYTE ; 0XFF - RS HARDWARE SYNCHRO ; 0XFF - RS HARDWARE SYNCHRO ; 0X99 - FRAME SYNCHRO ; LENGHT - FRAME LENGTH ; TYPE - FRAME TYPE ; ADRU - UPPER ADRESS BYTE ; ADRH - HIGH ADRESS BYTE ; ADRL - LOW ADRESS BYTE ; DATA_BUF[128] - DATA BUFFER -> IDATA[0X80,0XFF] ; CRCH - CRC16 HIGH BYTE ; CRCL - CRC16 LOW BYTE RS_SERVIS: JNB RI,RS_NO_RECEIVER ;ONLY INTERRUPTS FROM RECEICER CLR RI ;CLEAR RECEIVE FLAG PUSH 0 ;R0,R1,ACC,PSW ON THE STACK PUSH 1 PUSH ACC PUSH PSW MOV RS_TIMEOUT,#RS_TIM_INIT ;RECEIVE TIMEOUT REFRESH MOV A,RS_SYNCHRO ;CHECKING SERIAL PORT SYNCHRO STATUS CJNE A,#0X55,RS_WAIT_FOR_SYNCHRO ;JUMP, IF NOT SYNCHRONIZED AJMP RS_SK000 RS_NO_RECEIVER: RETI RS_WAIT_FOR_SYNCHRO: MOV A,SBUF CJNE A,#099H,RS_WAIT_NOT_SYNCHRO ;WAITING FOR FRAME SYNCHRO BYTE MOV RS_SYNCHRO,#0X55 MOV BUF_POINT,#80H ;INITIALIZE BUFFER POINTER MOV LICZ_ODEB,#00H ;INITIALIZE COUNTERS MOV LICZ_DOODB,#087H ;MAX 135 BYTES IN FRAME RS_WAIT_NOT_SYNCHRO: AJMP RS_EXIT RS_SK000: ;RECEIVING BYTES MOV R0,SBUF RS_SK001: INC LICZ_ODEB ;COUNTER OF RECEIVED BYTES DEC LICZ_DOODB ;COUNTER OF BYTES TO END MOV A,LICZ_ODEB ;TEST OF RECEIVE COUNTER CJNE A,#01H,RS_SK002 ;IF 1, THERE IS LENGTH OF FRAME MOV LICZ_DOODB,R0 MOV ILOSC,R0 DEC LICZ_DOODB ;COUNTER OF BYTES TO END = LENGTH-1 AJMP RS_EXIT RS_SK002: CJNE A,#02H,RS_SK003 ;IF LICZ_ODEB==2, FRAME TYPE RECEIVED MOV KOD,R0 AJMP RS_EXIT RS_SK003: CJNE A,#03H,RS_SK004 ;IF LICZ_ODEB==3, UPPER ADRESS BYTE RECEIVED MOV ADRHH,R0 AJMP RS_EXIT RS_SK004: CJNE A,#04H,RS_SK005 ;HIGH ADRESS BYTE RECEIVED MOV ADRHL,R0 AJMP RS_EXIT RS_SK005: CJNE A,#05H,RS_SK006 ;LOW ADRESS BYTE RECEIVED MOV ADRLL,R0 AJMP RS_EXIT RS_SK006: MOV A,LICZ_DOODB ;ONE BYTE TO END = CRC16 HIGH BYTE CJNE A,#01H,RS_SK007 MOV CRC16H,R0 AJMP RS_EXIT RS_SK007: CJNE A,#00H,RS_SK008 ;END OF FRAME -> CRC16 LOW BYTE MOV CRC16L,R0 MOV IE,#00H ;FRAME RECEIVED MOV WYKONAJ,#01H ;SETTING RECEIVE FLAG ANL RS_TIMEOUT,#0X00 ;CLEARING RECEIVE TIMEOUT CLR REN ;STOP RECEIVER AJMP RS_EXIT ;EXIT RS_SK008: MOV R1,BUF_POINT ;RECEIVING BYTES TO IDATA BUFFER MOV A,R0 MOV @R1,A INC BUF_POINT ;INCREMENT POINTER TO DATA BUFFER RS_EXIT: POP PSW ;RESTORING PSW,ACC,R1,R0 POP ACC POP 1 POP 0 RETI ;******************************************************************************* ;* AUTOBAUD DETECTION * ;******************************************************************************* ;WARNING: Following transmission parameters should be used: ; - start bit; ; - 9600 bps; ; - 8 bit data; ; - no parity; ; - 1 stop bit; ; ; ;Procedure is measuring used quarz frequency with TIMER2, which is switched ;by external 9600 bps serial input byte: 0x55. ;T2 is configured for serial baud rate generation. ;T2 start counting oscillator frequency/2 at first rising edge on RX and ;stopping at fith rising edge on RX. ;Measuring window = 0.833 msek ; ;Measured quarz frequency: 2*[[T2H:T2L]/(0.833 msek)] IMPULS: MOV TL2,#0H MOV TH2,#0H IMPUL_1: CPL Watchdog JB P3_0,IMPUL_1 ;WAITING FOR START BIT IMP_1: CPL Watchdog JNB P3_0,IMP_1 ;WAITING FOR FIFST RISING EDGE ORL T2CON,#04H ;START MEASURING T2-ON IMP_2: CPL Watchdog JB P3_0,IMP_2 IMP_3: CPL Watchdog JNB P3_0,IMP_3 ;WAITING FOR SECOND RISING EDGE IMP_4: CPL Watchdog JB P3_0,IMP_4 IMP_5: CPL Watchdog JNB P3_0,IMP_5 ;WAITING FOR THIRD RISING EDGE IMP_6: CPL Watchdog JB P3_0,IMP_6 IMP_7: CPL Watchdog JNB P3_0,IMP_7 ;WAITING FOR FOURTH RISING EDGE IMP_8: CPL Watchdog JB P3_0,IMP_8 IMPULS_KON: CPL Watchdog JNB P3_0,IMPULS_KON ;WAITING FOR FITH RISING EDGE ANL T2CON,#0FBH ;T2 - STOP MOV POM1H,TH2 ;POM1 = MEASURING RESULT MOV POM1L,TL2 RET ;******************************************************************************* ;* CRC16 Table for High byte * ;******************************************************************************* CRC16TableHigh: .db 0, 0x80, 0x80, 0 .db 0x80, 0, 0, 0x80 .db 0x80, 0, 0, 0x80 .db 0, 0x80, 0x80, 0 .db 0x80, 0, 0, 0x80 .db 0, 0x80, 0x80, 0 .db 0, 0x80, 0x80, 0 .db 0x80, 0, 0, 0x80 .db 0x80, 0, 0, 0x80 .db 0, 0x80, 0x80, 0 .db 0, 0x80, 0x80, 0 .db 0x80, 0, 0, 0x80 .db 0, 0x80, 0x80, 0 .db 0x80, 0, 0, 0x80 .db 0x80, 0, 0, 0x80 .db 0, 0x80, 0x80, 0 .db 0x81, 0x1, 0x1, 0x81 .db 0x1, 0x81, 0x81, 0x1 .db 0x1, 0x81, 0x81, 0x1 .db 0x81, 0x1, 0x1, 0x81 .db 0x1, 0x81, 0x81, 0x1 .db 0x81, 0x1, 0x1, 0x81 .db 0x81, 0x1, 0x1, 0x81 .db 0x1, 0x81, 0x81, 0x1 .db 0x1, 0x81, 0x81, 0x1 .db 0x81, 0x1, 0x1, 0x81 .db 0x81, 0x1, 0x1, 0x81 .db 0x1, 0x81, 0x81, 0x1 .db 0x81, 0x1, 0x1, 0x81 .db 0x1, 0x81, 0x81, 0x1 .db 0x1, 0x81, 0x81, 0x1 .db 0x81, 0x1, 0x1, 0x81 .db 0x83, 0x3, 0x3, 0x83 .db 0x3, 0x83, 0x83, 0x3 .db 0x3, 0x83, 0x83, 0x3 .db 0x83, 0x3, 0x3, 0x83 .db 0x3, 0x83, 0x83, 0x3 .db 0x83, 0x3, 0x3, 0x83 .db 0x83, 0x3, 0x3, 0x83 .db 0x3, 0x83, 0x83, 0x3 .db 0x3, 0x83, 0x83, 0x3 .db 0x83, 0x3, 0x3, 0x83 .db 0x83, 0x3, 0x3, 0x83 .db 0x3, 0x83, 0x83, 0x3 .db 0x83, 0x3, 0x3, 0x83 .db 0x3, 0x83, 0x83, 0x3 .db 0x3, 0x83, 0x83, 0x3 .db 0x83, 0x3, 0x3, 0x83 .db 0x2, 0x82, 0x82, 0x2 .db 0x82, 0x2, 0x2, 0x82 .db 0x82, 0x2, 0x2, 0x82 .db 0x2, 0x82, 0x82, 0x2 .db 0x82, 0x2, 0x2, 0x82 .db 0x2, 0x82, 0x82, 0x2 .db 0x2, 0x82, 0x82, 0x2 .db 0x82, 0x2, 0x2, 0x82 .db 0x82, 0x2, 0x2, 0x82 .db 0x2, 0x82, 0x82, 0x2 .db 0x2, 0x82, 0x82, 0x2 .db 0x82, 0x2, 0x2, 0x82 .db 0x2, 0x82, 0x82, 0x2 .db 0x82, 0x2, 0x2, 0x82 .db 0x82, 0x2, 0x2, 0x82 .db 0x2, 0x82, 0x82, 0x2 ;******************************************************************************* ;* CRC16 Table for low byte * ;******************************************************************************* CRC16TableLow: .db 0X00, 0x5, 0xf, 0xa .db 0x1b, 0x1e, 0x14, 0x11 .db 0x33, 0x36, 0x3c, 0x39 .db 0x28, 0x2d, 0x27, 0x22 .db 0x63, 0x66, 0x6c, 0x69 .db 0x78, 0x7d, 0x77, 0x72 .db 0x50, 0x55, 0x5f, 0x5a .db 0x4b, 0x4e, 0x44, 0x41 .db 0xc3, 0xc6, 0xcc, 0xc9 .db 0xd8, 0xdd, 0xd7, 0xd2 .db 0xf0, 0xf5, 0xff, 0xfa .db 0xeb, 0xee, 0xe4, 0xe1 .db 0xa0, 0xa5, 0xaf, 0xaa .db 0xbb, 0xbe, 0xb4, 0xb1 .db 0x93, 0x96, 0x9c, 0x99 .db 0x88, 0x8d, 0x87, 0x82 .db 0x83, 0x86, 0x8c, 0x89 .db 0x98, 0x9d, 0x97, 0x92 .db 0xb0, 0xb5, 0xbf, 0xba .db 0xab, 0xae, 0xa4, 0xa1 .db 0xe0, 0xe5, 0xef, 0xea .db 0xfb, 0xfe, 0xf4, 0xf1 .db 0xd3, 0xd6, 0xdc, 0xd9 .db 0xc8, 0xcd, 0xc7, 0xc2 .db 0x40, 0x45, 0x4f, 0x4a .db 0x5b, 0x5e, 0x54, 0x51 .db 0x73, 0x76, 0x7c, 0x79 .db 0x68, 0x6d, 0x67, 0x62 .db 0x23, 0x26, 0x2c, 0x29 .db 0x38, 0x3d, 0x37, 0x32 .db 0x10, 0x15, 0x1f, 0x1a .db 0xb, 0xe, 0x4, 0x1 .db 0x3, 0x6, 0xc, 0x9 .db 0x18, 0x1d, 0x17, 0x12 .db 0x30, 0x35, 0x3f, 0x3a .db 0x2b, 0x2e, 0x24, 0x21 .db 0x60, 0x65, 0x6f, 0x6a .db 0x7b, 0x7e, 0x74, 0x71 .db 0x53, 0x56, 0x5c, 0x59 .db 0x48, 0x4d, 0x47, 0x42 .db 0xc0, 0xc5, 0xcf, 0xca .db 0xdb, 0xde, 0xd4, 0xd1 .db 0xf3, 0xf6, 0xfc, 0xf9 .db 0xe8, 0xed, 0xe7, 0xe2 .db 0xa3, 0xa6, 0xac, 0xa9 .db 0xb8, 0xbd, 0xb7, 0xb2 .db 0x90, 0x95, 0x9f, 0x9a .db 0x8b, 0x8e, 0x84, 0x81 .db 0x80, 0x85, 0x8f, 0x8a .db 0x9b, 0x9e, 0x94, 0x91 .db 0xb3, 0xb6, 0xbc, 0xb9 .db 0xa8, 0xad, 0xa7, 0xa2 .db 0xe3, 0xe6, 0xec, 0xe9 .db 0xf8, 0xfd, 0xf7, 0xf2 .db 0xd0, 0xd5, 0xdf, 0xda .db 0xcb, 0xce, 0xc4, 0xc1 .db 0x43, 0x46, 0x4c, 0x49 .db 0x58, 0x5d, 0x57, 0x52 .db 0x70, 0x75, 0x7f, 0x7a .db 0x6b, 0x6e, 0x64, 0x61 .db 0x20, 0x25, 0x2f, 0x2a .db 0x3b, 0x3e, 0x34, 0x31 .db 0x13, 0x16, 0x1c, 0x19 .db 0x8, 0xd, 0x7, 0x2 ; ****************************************************************************** ; * CALCULATION OF CRC 16 FOR DATA BUFFER ; ****************************************************************************** CALCULATE_CRC: MOV R0,#0X80 ;POINTER TO DATA BUFFER MOV A,@R0 MOV R1,A ;BUFFER LENGTH DEC R1 DEC R1 ;TWO LAST BYTES FOR CRC LCALL CRC_INIT LCALL CALCULATE_FOR_NEXT_BYTE DATABYTES_COUNTER: LCALL CRC_SHIFT ;NEXT BYTE LCALL CALCULATE_FOR_NEXT_BYTE DJNZ R1,DATABYTES_COUNTER LCALL CRC_ZERO_SHIFT ;0 TO CRC LCALL CALCULATE_FOR_NEXT_BYTE LCALL CRC_ZERO_SHIFT ;0 TO CRC LCALL CALCULATE_FOR_NEXT_BYTE RET ; ******************************************************************************* ; * NEXT BYTE TO CRC *; ; ******************************************************************************* Reload: LCALL CRC_SHIFT AJMP DATABYTES_COUNTER CRC_SHIFT: MOV CRC_BUFF,CRCHI MOV CRCHI,CRCLO MOV CRCLO,@R0 ;NEXT BYTE TO CRC INC R0 RET CRC_ZERO_SHIFT: MOV CRC_BUFF,CRCHI MOV CRCHI,CRCLO MOV CRCLO,#0X0 ;0 TO CRC RET ; ****************************************************************************** ; * CRC CALCULATION FOR NEXT BYTE * ; ****************************************************************************** CALCULATE_FOR_NEXT_BYTE: MOV DPTR,#CRC16TableHigh MOV A,CRC_BUFF MOVC A,@A+DPTR XRL A,CRCHI XCH A,CRCHI ; XOR table element with high byte MOV DPTR,#CRC16TableLow MOV A,CRC_BUFF MOVC A,@A+DPTR XRL A,CRCLO XCH A,CRCLO ; XOR table element with low byte RET ; ****************************************************************************** ; * INITIALIZATION OF CRC BUFFERS * ; ****************************************************************************** CRC_INIT: MOV CRC_BUFF,#0XAA ;INITIALIZATION OF CRC REGISTERS MOV CRCHI,#0XAA MOV CRCLO,#0XAA RET ; ******************************************************************************* ; * CRC CHECKING OF RECEIVED FRAME *; ; ******************************************************************************* ; DATABYTES: ILOSC, KOD, ADRHH, ADRHL, ADRLL ; IDATA BUFFER: [80H - BUF_POINT] ; IF CRC OK, RETURNS 0 ; IF CRC BAD, RETURNS 0XFF CHECK_CRC16: LCALL CRC_INIT LCALL CALCULATE_FOR_NEXT_BYTE MOV R0,#ILOSC LCALL CRC_SHIFT LCALL CALCULATE_FOR_NEXT_BYTE MOV R0,#KOD LCALL CRC_SHIFT LCALL CALCULATE_FOR_NEXT_BYTE MOV R0,#ADRHH LCALL CRC_SHIFT LCALL CALCULATE_FOR_NEXT_BYTE MOV R0,#ADRHL LCALL CRC_SHIFT LCALL CALCULATE_FOR_NEXT_BYTE MOV R0,#ADRLL LCALL CRC_SHIFT LCALL CALCULATE_FOR_NEXT_BYTE DEC BUF_POINT ;POINTING LAST BYTE IN RECEIVE BUFFER MOV A,BUF_POINT CLR C SUBB A,#07FH MOV R1,A ;DATABYTES COUNTER MOV R0,#80H ;DATABYTES POINTER CHECK_CRC_LOOP: LCALL CRC_SHIFT LCALL CALCULATE_FOR_NEXT_BYTE DJNZ R1,CHECK_CRC_LOOP LCALL CRC_ZERO_SHIFT ;ADD 0 TO CRC LCALL CALCULATE_FOR_NEXT_BYTE LCALL CRC_ZERO_SHIFT ;ADD 0 TO CRC LCALL CALCULATE_FOR_NEXT_BYTE MOV A,CRC16H CJNE A,CRCHI,CHECK_CRC_ERROR MOV A,CRC16L CJNE A,CRCLO,CHECK_CRC_ERROR MOV A,#0X0 ;CRC OK RET CHECK_CRC_ERROR: MOV A,#0XFF ;BAD CRC RET ;******************************************************************************* ;* SENDING CALCULATED TIMES TO PC * ;******************************************************************************* SEND_CALCULATIONS: MOV R0,#80H ;POINTER TO DATA BUFFER MOV @R0,#0X0E ;FRAME LENGTH = 14 INC R0 MOV @R0,#PROG_TEST ;TEST FRAME INC R0 MOV @R0,TH1INIT ;T1 10 MS TIME INC R0 MOV @R0,TL1INIT INC R0 MOV @R0,ER_TIM_H ;ERASE TIME INC R0 MOV @R0,ER_TIM_L INC R0 MOV @R0,PR_TIM_H ;PROGRAMM TIME INC R0 MOV @R0,PR_TIM_L INC R0 MOV @R0,READ_T_H ;READ TIME INC R0 MOV @R0,READ_T_L INC R0 MOV @R0,RCAP2H ;SERIAL PORT BAUD GENERATOR INC R0 MOV @R0,RCAP2L LCALL CALCULATE_CRC ;CALCULATING CRC FOR NEW FRAME MOV @R0,CRCHI ;CRC TO BUFFER INC R0 MOV @R0,CRCLO AJMP SEND_FRAME ;******************************************************************************* ;* ACKNOWLEDGE TO THE PC * ;******************************************************************************* ;FRAME FORMAT: ; 0X55 - SYNCHRO ; LENGTH - LENGTH (WITHOUT SYNCHRO BYTE) ; TYPE - FRAME TYPE ; DATAS ; ... ; CRCHI - CALCULATED FROM LENGTH TO LAST DATA BYTE ; CRCLOW ;FRAME IS LOCKATED AT 0X80 IDATA, WITHOUT SYNCHRO BYTE POTW_RAMKE: MOV R0,#80H ;POINTER TO DATA BUFFER MOV @R0,#0X07 ;FRAME LENGTH = 7 INC R0 MOV @R0,PC_KOD ;FRAME TYPE = PC_KOD INC R0 MOV @R0,ADRHH ;VALUE OF APROM FLASH MEMORY POINTER INC R0 MOV @R0,ADRHL INC R0 MOV @R0,ADRLL LCALL CALCULATE_CRC ;CALCULATING CRC FOR NEW FRAME MOV @R0,CRCHI ;CRC TO BUFFER INC R0 MOV @R0,CRCLO ;******************************************************************************* ;* SENDING FRAME TO RS * ;******************************************************************************* SEND_FRAME: CLR TI MOV SBUF,#0X55 ;SYNCHRO BYTE JNB TI,* CLR TI MOV R0,#80H ;POINTER TO FRAME MOV A,@R0 MOV R1,A ;DATA COUNTER SEND_FRAME_LOOP: CPL WATCHDOG ;SENDING FRAME MOV SBUF,@R0 JNB TI,* CLR TI INC R0 ;NEXT BYTE DJNZ R1,SEND_FRAME_LOOP ;COUNTER RET ;------------------------------------------------------------------------------- ; FLASH PROGRAMMING ;------------------------------------------------------------------------------- ;DATA BUFFER: <0X80;BUF_POINT> PROGRAMUJ: MOV IE,#82H ;T0 INTERRUPT ENABLED CLR TR0 ;T0 STOP MOV R4,#0FH ;ERROR COUNTER MOV DPL,ADRLL ;START ADRESS MOV DPH,ADRHL MOV A,ADRHH ;MAX ADRESS CHECKING JNZ PROG_AERR CLR C MOV A,#MAXADRL SUBB A,ADRLL MOV A,#MAXADRH SUBB A,ADRHL JC PROG_AERR ;JUMP, IF ADRESS TOO HIGH PROG_SK001: MOV A,BUF_POINT ;CALCULATING DATA BUFFER SIZE CLR C SUBB A,#7FH MOV R2,A ;BUFFER SIZE IN R2 MOV R0,#80H ;POINTER TO DATA BUFFER PROG_PETLA: ;PROGRAMMING LOOP CLR C MOV A,#MAXADRL SUBB A,DPL MOV A,#MAXADRH SUBB A,DPH JC PROG_AERR ;JUMP IF ADRESS TOO HIGH MOV SFRAL,DPL MOV SFRAH,DPH ;ADRESS POINTER PROG_POWT: MOV SFRFD,@R0 ;NEXT BYTE MOV SFRCN,#21H ;PROGRAMMING MODE MOV TH0,PR_TIM_H ;PROGRAMMING TIME H MOV TL0,PR_TIM_L ;PROGRAMMING TIME L CPL Watchdog SETB TR0 ;START PROGRAMMING TIMER MOV PCON,#01H ;START PROGRAMMING CLR TR0 ;STOP PROGRAMMING TIMER ;VERIFICATION: MOV SFRCN,#0H MOV TH0,READ_T_H ;READ TIME H MOV TL0,READ_T_L ;READ TIME L SETB TR0 MOV PCON,#01H ;READ MODE CLR TR0 MOV A,SFRFD MOV DATA,@R0 CJNE A,DATA,PR_ERR ;COMPARE WITH BUFFER, JUMP IF DIFFERENT MOV R4,#0AH ;PROGRAMMING ERROR COUNTER INC DPTR ;NEXT ADRESS INC R0 ;NEXT DATA BYTE DJNZ R2,PROG_PETLA ;PROGRAMMING LOOP MOV ADRLL,DPL ;SUCCESS MOV ADRHL,DPH ;DPTR = ADRESS + 1 MOV A,ADRLL CLR C SUBB A,#01H MOV ADRLL,A MOV A,ADRHL SUBB A,#0H ;ADRESS=ADRESS-1 MOV ADRHL,A MOV BLAD,#0H ;NO ERRORS RET ;EXIT PROG_AERR: MOV ADRLL,DPL MOV ADRHL,DPH MOV BLAD,#02H ;MAX ADRESS ERROR RET PR_ERR: DJNZ R4,PROG_POWT ;REPEATING 10 TIMES, IF PROGRAMMING ERROR MOV ADRLL,DPL ;POINTER TO ERROR ADRESS MOV ADRHL,DPH MOV BLAD,#01H ;PROGRAMMING ERROR RET ;EXIT ;------------------------------------------------------------------------------- ; CHIP ERASING ;------------------------------------------------------------------------------- KASOWANIE: MOV R4,#0FH ;ERROR COUNTER KAS_START: MOV IE,#82H ;INTERRUPTS FROM T0 CLR TR0 ;T0 STOP MOV TH0,ER_TIM_H ;ERASING TIME H MOV TL0,ER_TIM_L ;ERASING TIME L MOV SFRCN,#22H ;CHIP ERASING CPL Watchdog ;EXT WATCHDOG SETB TR0 MOV PCON,#01H ;START ERASING CLR TR0 MOV DPL,#0H ;BLANK CHECK MOV DPH,#0H ;START FROM 0X0000 MOV SFRCN,#0H KAS_BL: MOV SFRAL,DPL ;MEMORY ADRESS MOV SFRAH,DPH MOV TH0,READ_T_H ;READ TIME H MOV TL0,READ_T_L ;READ TIME L CPL Watchdog SETB TR0 MOV PCON,#01H ;MEMORY READ CLR TR0 MOV A,SFRFD CJNE A,#0FFH,KAS_ERR ;DEVICE NOT ERASED MOV A,DPL CJNE A,#MAXADRL,KAS_NEXT_ADRES MOV A,DPH CJNE A,#MAXADRH,KAS_NEXT_ADRES MOV BLAD,#0H RET ;SUCCESS KAS_NEXT_ADRES: INC DPTR ;NEXT ADRESS AJMP KAS_BL KAS_ERR: DJNZ R4,KAS_START ;REPEATING ERASING MOV ADRLL,DPL MOV ADRHL,DPH ;ERROR WITH MEMORY ADRESS MOV BLAD,#03H ;ERASING ERROR RET ;------------------------------------------------------------------------------- ; READING FOR VERIFICATION ;------------------------------------------------------------------------------- ODCZYTUJ: MOV IE,#82H ;T0 INTERRUPT CLR TR0 ;T0 STOP MOV R4,#0AH ;ERRORS COUNTER MOV R1,#80H ;BUFFER SIZE 128 B MOV DPL,ADRLL ;START ADRESS MOV DPH,ADRHL MOV A,ADRHH ;MAX ADRESS CHECKING JNZ ODCZ_AERR ;ADRESS TOO HIGH CLR C MOV A,#MAXADRL SUBB A,ADRLL MOV A,#MAXADRH SUBB A,ADRHL JC ODCZ_AERR ;ADRES TOO HIGH MOV SFRCN,#0H MOV R0,#80H ;POINTER TO DATA BUFFER ODCZ_PETLA: ;READ LOOP MOV SFRAL,DPL ;READ ADRESS MOV SFRAH,DPH MOV TH0,READ_T_H ;READ TIME H MOV TL0,READ_T_L ;READ TIME L CPL Watchdog ;EXT WATCHDOG SETB TR0 ;READ TIME (T0) MOV PCON,#01H ;READING CLR TR0 MOV A,SFRFD MOV DATA,@R0 CJNE A,DATA,ODCZ_WERR ;VERIFICATION ERROR INC DPTR ;NEXT ADRESS INC R0 ;NEXT DATA BYTE CLR C MOV A,#MAXADRL ;MAX ADRESS CHECKING SUBB A,DPL MOV A,#MAXADRH SUBB A,DPH JC ODCZ_WYJ ;JUMP, IF ADRESS TOO HIGH DJNZ R1,ODCZ_PETLA ;DATA COUNTER ODCZ_WYJ: MOV BLAD,#0H ;SUCCESS RET ODCZ_AERR: MOV ADRLL,#0H MOV ADRHL,#0H MOV ADRHH,#0H MOV BLAD,#02H ;ADRESS TOO HIGH ERROR RET ODCZ_WERR: MOV ADRLL,#0H MOV ADRHL,#0H MOV ADRHH,#0H MOV BLAD,#05H ;VERIFICATION ERROR RET ;------------------------------------------------------------------------------- ; BLANK CHECK ;------------------------------------------------------------------------------- BLANK_CHECK: MOV BLAD,#0H MOV IE,#82H ;INTERRUPTS FROM T0 CLR TR0 MOV DPL,#0H ;START FROM ADRESS 0X0000 MOV DPH,#0H MOV SFRCN,#0H BLANK_PETLA: MOV SFRAL,DPL MOV SFRAH,DPH MOV TH0,READ_T_H ;READ TIME H MOV TL0,READ_T_L ;READ TIME L CPL Watchdog SETB TR0 MOV PCON,#01H ;READ FLASH CLR TR0 ;T0 STOP MOV A,SFRFD CJNE A,#0FFH,BL_ERROR ;BLANK CHECK MOV A,DPL CJNE A,#MAXADRL,BLANK_NEXT_ADRES MOV A,DPH CJNE A,#MAXADRH,BLANK_NEXT_ADRES RET BLANK_NEXT_ADRES: INC DPTR AJMP BLANK_PETLA BL_ERROR: MOV BLAD,#04H MOV ADRLL,DPL ;ERROR ADRES MOV ADRHL,DPH RET ;------------------------------------------------------------------------------- ; SOFTWARE RESET ;------------------------------------------------------------------------------- RESETUJ: MOV IE,#0H CLR TR0 CLR TR1 ANL T2CON,#0FBH MOV CHPENR,#87H MOV CHPENR,#59H MOV CHPCON,#80H ;RESET STOP: AJMP STOP ;******************************************************************************* ;* DIVIDING * ;******************************************************************************* ;DZIELNA_H:DZIELNA_L ;DZIELNIK ;WYNIK ;RESZTA DIVIDE: MOV DIVIDE_COUNTER,#0X08 ;LOOP COUNTER DIVIDE_LOOP: CLR C XCH A,DIVID_L RLC A XCH A,DIVID_L XCH A,DIVID_H RLC A XCH A,DIVID_H CLR C MOV A,DIVID_H SUBB A,DIVISOR JC SKIP_1 MOV DIVID_H,A SKIP_1: JC SKIP_2 ORL DIVID_L,#0X01 SKIP_2: DJNZ DIVIDE_COUNTER,DIVIDE_LOOP MOV DIV_QUOT,DIVID_L MOV DIV_REMAIN,DIVID_H RET