diff options
| author | Jan Sucan <sucanjan@fit.cvut.cz> | 2019-09-22 21:16:27 +0200 |
|---|---|---|
| committer | Jan Sucan <sucanjan@fit.cvut.cz> | 2019-09-22 21:16:27 +0200 |
| commit | 1715cc7f241a236372eed03aa8279b9ed864e4b0 (patch) | |
| tree | d9e182d2da722c035648a21721d2e10d664a8764 | |
Initial commit
| -rw-r--r-- | firmware.asm | 722 |
1 files changed, 722 insertions, 0 deletions
diff --git a/firmware.asm b/firmware.asm new file mode 100644 index 0000000..05efb2a --- /dev/null +++ b/firmware.asm @@ -0,0 +1,722 @@ +; Zdrojove kody mozete pouzivat k akemukolvek ucelu. +; Za mozne sposobene skody nenesiem zodpovednost. +; +; You can use the source codes for anything you want. +; I am not responsible for any damages. + +; Firmware prevodniku pre programovanie mikrokontrolerov +; Vykonava prevod medzi seriovymi signalmi pre programovanie +; mikrokontroleru AT89S51 a paralelnymi signalmi pre programovanie +; mikrokontroleru AT89C1051, AT89C2051 alebo AT89C4051. + + +; ---------------------------------------------------------------------- +; hardware +; ---------------------------------------------------------------------- +green equ p3.6 ; zelena led +red equ p3.5 ; cervena led +up equ p3.7 ; upload led +down equ p3.4 ; download led + ; definice paralelneho rozhrania +rstsw equ p2.1 ; spinac rst signalu +vccsw equ p2.0 ; spinac napajacieho napatia +pdata equ p0 ; paralelne data +xtal equ p2.6 ; xtal +prog equ p2.5 ; prog +m0 equ p2.4 ; prvy bit modu +m1 equ p2.3 ; druhy bit modu +m2 equ p2.2 ; treti a stvrty bit modu + ; definicie fram +frwp equ p1.0 ; write protect +frscl equ p1.1 ; hodinovy signal +frsda equ p1.2 ; datovy signal + ; signaly serioveho rozhrania +mosi equ p1.5 ; master in slave out +miso equ p1.6 ; master out slave in +sck equ p1.7 ; hodinovy signal +rst equ p3.2 ; resetovaci signal +btn equ p3.3 ; ovladacie tlacitko +; ---------------------------------------------------------------------- +; premenne a konstanty +; ---------------------------------------------------------------------- + bseg at 20h +lock: dbit 1 ; zamok modelu +spe: dbit 1 ; vlajka serial programming enabled +taskerr:dbit 1 ; vlajka chyby ulohy + + dseg at 30h + ; premenne modelu +vlocks: ds 1 ; lock bity +vsign: ds 3 ; bajty signatury +vchange:ds 1 ; bity zmeny + ; 0. bit - chip erase + ; 1. bit - write program memory + ; 2. bit - write lock bits + ; premenne fram +frct: ds 1 ; pocitadlo pre fram podprogramy +frerr: ds 1 ; pocet opakovani pri chybe prenosu +frtmp: ds 1 ; docasne ulozenie dat fram + + ; pwm konstanty +volt equ 30 ; trvanie aktivnej casti periody pwm +period equ 2200 ; trvanie periody pwm + +vmargin equ 08h ; velkost pamate programu at89cx051 mcu + ; velkost pamate v bajtoch je ziskana + ; vynasobenim tohoto cisla cislom 256 + ; 04h je pre at89c1051 + ; 08h je pre at89c2051 + ; 10h je pre at89c4051 +; ---------------------------------------------------------------------- +; kod programu +; ---------------------------------------------------------------------- + cseg + + org 00h + ajmp main ; skok na zaciatok programu + + org 03h + ajmp serial ; obsluha serioveho programatoru + + org 0bh + ajmp rstpwm ; obsluha pwm kanalu + + org 13h + ajmp button ; obsluha ovladacieho tlacitka +; ---------------------------------------------------------------------- +; hlavny program +; ---------------------------------------------------------------------- +main: clr green ; zasviet vsetky led + clr red + clr up + clr down ; ok + + setb frwp ; signaly fram do kludoveho stavu + setb frscl + setb frsda ; ok + + anl tmod,#0fh ; 16 bitovy casovac 1 + orl tmod,#10h + setb tr1 ; spust + ; signaly paralelneho rozhrania do + acall poff ; kludoveho stavu + + anl tmod,#0f0h ; 16 bitovy casovac 0 + orl tmod,#01h + setb tr0 ; spust + setb pt0 ; vysoka priorita + + mov a,#0 ; vychodzie hodnoty premennych modelu + mov vlocks,a ; deaktivovane lock bity + mov a,#1eh ; platna signatura at89s51 + mov vsign,a + mov a,#51h + mov vsign+1,a + mov a,#06h + mov vsign+2,a ; ok + mov vchange,a ; ziadne zmeny + + clr it0 ; int0 citlive na log. 0 + setb ex0 + + clr it1 ; int1 citlive na zostupnu hranu + setb ex1 + + setb red ; led do pohotovostneho stavu + setb green + setb down + clr up ; ok + setb ea ; povolene vsetky prerusenia + +task: clr lock ; odomkni pamat + mov r0,#100 ; cakaj 2 s +task_wait: + clr tf1 + mov tl1,#low (65535 - 40000) + mov th1,#high (65535 - 40000) + jnb tf1,$ + djnz r0,task_wait + setb lock ; zamkni pamat a detekuj zmenu + mov a,vchange + jz task ; ak nie je zmena, odomkni a cakaj + clr green ; je zmena, zasviet oranzovu led + clr red + clr taskerr ; zhod priznak zmeny +task_select: + mov a,vchange ; zisti kde je zmena + jb acc.0,task_perasechip + jb acc.1,task_pcodewrite + jb acc.2,task_plockwrite + jb taskerr,task_error + setb red ; nie je chyba, zasviet zelenu led + clr green + ajmp task ; cakaj na dalsie zmeny +task_error: + setb green ; je chyba, zasviet cervenu led + clr red + mov vchange,#0 ; zrus vsetky zmeny + ajmp task ; cakaj na dalsie zmeny +task_perasechip: + acall perasechip ; zmaz at89cx8051 + mov a,vchange ; zhod priznak zmeny + clr acc.0 + mov vchange,a ; ok + ajmp task_select ; pokracuj dalsou ulohou +task_pcodewrite: + acall pcodewrite ; zapis pamat programu at89cx051 + mov taskerr,c ; nastav vlajku chyby + mov a,vchange ; nie je chyba, zhod priznak zmeny + clr acc.1 + mov vchange,a ; ok + ajmp task_select ; pokracuj dalsou ulohou +task_plockwrite: + acall plockwrite ; zapis lock bity at89cx501 + mov a,vchange ; zhod priznak zmeny + clr acc.2 + mov vchange,a ; ok + ajmp task_select ; pokracuj dalsou ulohou + +; ---------------------------------------------------------------------- +; obsluzne procedury +; ---------------------------------------------------------------------- + ; obsluha serioveho rozhrania +serial: jnb lock,$+4 ; skontroluj zamok + reti + clr spe ; zhod vlajku programming enable +sdecode: + acall srcv ; prijmi 1. bajt + cjne a,#0ach,$+5 ; a dekoduj ho + ajmp sdecode_l0 + cjne a,#20h,$+5 + ajmp sbyteread + cjne a,#40h,$+5 + ajmp sbytewrite + cjne a,#24h,$+5 + ajmp slockread + cjne a,#28h,$+5 + ajmp ssignread + cjne a,#30h,$+5 + ajmp spageread + cjne a,#50h,$+5 + ajmp spagewrite + ajmp sterm ; nebol rozpoznany, skonci +sdecode_l0: + acall srcv ; prijmi 2. bajt + mov r0,a ; a zalohuj ho, moze obsahovat data + cjne a,#53h,$+5 + ajmp senableprog + anl a,#11111100b + cjne a,#0e0h,$+5 + ajmp slockwrite + anl a,#11100000b + cjne a,#80h,$+5 + ajmp serasechip + ajmp sterm ; nebol rozpoznany, skonci +sterm_p2: + pop acc ; zahod 2 bajty navratovej adresy + pop acc +sterm: pop acc + pop acc + mov a,#low task + push acc + mov a,#high task + push acc + setb green ; zhasni zelenu a cervenu led + setb red + reti + +senableprog: ; programming enable + setb spe ; nastav priznak programming enable + acall srcv ; prijmi 3. bajt + mov a,#01101001b + acall ssend ; posli 4. bajt + ajmp sdecode + +serasechip: ; chip erase + jb spe,$+5 ; skontroluj programming enable + ajmp sterm + clr green ; zasviet cervenu led a zelenu led + clr red + acall srcv ; prijmi 3. + acall srcv ; a 4. bajt + mov dptr,#0 ; zmaz 4 kib fram + acall vwrite_open ; otvor model +serasechip_l0: + mov a,#0ffh ; vymazany bajt + acall vwrite_byte ; zapis bajt do modelu + inc dptr ; inkrementuj adresu + mov a,dph + cjne a,#10h,serasechip_l0 + acall vwrite_close ; zatvor model + mov a,vchange ; zaznamenaj zmenu + setb acc.0 + mov vchange,a + ajmp sdecode + +sbyteread: ; read program memory (byte mode) + jb spe,$+5 ; skontroluj programming enable + ajmp sterm + acall srcv ; prijmi 2. bajt (upper address byte) + anl a,#0fh ; vymaskuj nahodne bity + mov dph,a + acall srcv ; prijmi 3. bajt (lower address byte) + mov dpl,a + acall vread + acall ssend ; posli 4. bajt (data) + ajmp sdecode + +sbytewrite: ; write program memory (byte mode) + jb spe,$+5 ; skontroluj programming enable + ajmp sterm + clr green ; zasviet cervenu led a zelenu led + clr red + acall srcv ; prijmi 2. bajt (upper address byte) + anl a,#0fh ; vymaskuj nahodne bity + mov dph,a + acall srcv ; prijmi 3. bajt (lower address byte) + mov dpl,a + acall srcv ; prijmi 4. bajt (data) + acall vwrite + mov a,vchange ; zaznamenaj zmenu + setb acc.1 + mov vchange,a + ajmp sdecode + +slockwrite: ; write lock bits + jb spe,$+5 ; skontroluj programming enable + ajmp sterm + clr green ; zasviet cervenu led a zelenu led + clr red + acall srcv ; prijmi 3. + acall srcv ; a 4. bajt + mov a,r0 ; vyber 2. bajt zo zalohy + anl a,#03h ; vymaskuj nahodne bity + mov r0,a + mov a,vlocks ; nastav prislusny lock bit + cjne r0,#1,$+5 + setb acc.2 + cjne r0,#2,$+5 + setb acc.3 + cjne r0,#3,$+5 + setb acc.4 + mov vlocks,a + mov a,vchange ; zaznamenaj zmenu + setb acc.2 + mov vchange,a + ajmp sdecode + +slockread: ; read lock bits + jb spe,$+5 ; skontroluj programming enable + ajmp sterm + acall srcv ; prijmi 2. + acall srcv ; a 3. bajt + mov a,vlocks + acall ssend ; posli 4. bajt (lock bits) + ajmp sdecode + +ssignread: ; read signature bytes + jb spe,$+5 ; skontroluj programming enable + ajmp sterm + acall srcv ; prijmi 2. bajt (upper address) + mov r0,a + acall srcv ; prijmi 3. bajt (lower address) + jnz ssignread_l0 ; ak nie je 0, ignoruj upper address + mov a,r0 + anl a,#0fh + mov dptr,#vsign + movc a,@a+dptr +ssignread_l0: + acall ssend ; posli 4. bajt (signature byte) + ajmp sdecode + +spageread: ; read program memory (page mode) + jb spe,$+5 ; skontroluj programming enable + ajmp sterm + acall srcv ; prijmi 2. bajt (upper address) + anl a,#0fh ; vymaskuj nahodne bity + mov dph,a + mov dpl,#0 +spageread_l0: + acall vread + acall ssend ; posli 0. az 255. datovy bajt + inc dpl + mov a,dpl + cjne a,#0,spageread_l0 + ajmp sdecode + +spagewrite: ; write program memory (page mode) + jb spe,$+5 ; skontroluj programming enable + ajmp sterm + clr green ; zasviet cervenu led a zelenu led + clr red + acall srcv ; prijmi 2. bajt (upper address) + anl a,#0fh ; vymaskuj nahodne bity + mov dph,a + mov dpl,#0 +spagewrite_l0: + acall srcv ; prijmi 0. az 255. datovy bajt + acall vwrite + inc dpl + mov a,dpl + cjne a,#0,spagewrite_l0 + mov a,vchange ; zaznamenaj zmenu + setb acc.1 + mov vchange,a + ajmp sdecode + + ; prijem bajtu od programatoru +srcv: mov r1,#8 ; prijmi 8 bitov +srcv_l0: + jnb rst,$+5 ; kontroluj rst + ajmp sterm_p2 + jb sck,$-5 ; cakaj na sck = 0 + jnb rst,$+5 + ajmp sterm_p2 + jnb sck,$-5 ; cakaj na sck = 1 + mov c,mosi ; prijmi bit + rlc a + jnb rst,$+5 + ajmp sterm_p2 + jb sck,$-5 ; cakaj na sck = 0 + djnz r1,srcv_l0 + ret + + ; odoslanie bajtu programatoru +ssend: mov r1,#8 ; posli 8 bitov +ssend_l0: + jnb rst,$+5 + ajmp sterm_p2 + jb sck,$-5 ; cakaj na sck = 0 + jnb rst,$+5 + ajmp sterm_p2 + jnb sck,$-5 ; cakaj na sck = 1 + rlc a + mov miso,c ; posli bit + jnb rst,$+5 + ajmp sterm_p2 + jb sck,$-5 ; cakaj na sck = 0 + djnz r1,ssend_l0 + ret + +; ---------------------------------------------------------------------- + ; obsluha casovaca 0 pre pwm +rstpwm: jb rstsw,rstpwm_low + setb rstsw ; rst = 12 v + mov tl0,#low (0ffffh - volt) + mov th0,#high (0ffffh - volt) + reti +rstpwm_low: + clr rstsw ; rst = 0 v + mov tl0,#low (0ffffh - period + volt) + mov th0,#high (0ffffh - period + volt) + reti + + ; rst = 0 v +rst0v: clr et0 ; zakaz prerusenie od casovaca 0 + clr rstsw ; rst = 0 v + jmp rstv_exit + ; rst = 5 v +rst5v: setb et0 ; povol prerusenie od casovaca 0 + setb tf0 ; vyvolaj obsluhu casovaca 0 + ;ajmp $ ; nekonecne cakanie pre odladenie generovania + ; napatia 5 v + jmp rstv_exit + ; rst = 12 v +rst12v: clr et0 ; zakaz prerusenie od casovaca 0 + setb rstsw ; rst = 12 v +rstv_exit: ; cakaj na ustalenie rst napatia + mov r2,#20 +rstv_exit_loop: + clr tf1 + mov tl1,#0 + mov th1,#0 + jnb tf1,$ ; ok + djnz r2,rstv_exit_loop + ret + +; ---------------------------------------------------------------------- +button: jnb lock,$+4 ; skontroluj zamok + reti + setb lock ; zamkni model + mov r0,#3 ; zober 3 vzorky +button_noise: + clr tf1 ; po 5 ms + mov tl1,#low (65535 - 10000) + mov th1,#high (65535 - 10000) + jnb tf1,$ + jnb btn,$+6 + clr lock + reti + djnz r0,button_noise + mov r0,#30 ; hranicny cas 700 ms +button_wait: + clr tf1 + mov tl1,#low (65535 - 50000) + mov th1,#high (65535 - 50000) + ; detekovane kratke stlacenie + jb btn,button_short + jnb tf1,$-3 + djnz r0,button_wait + ajmp button_long ; detekovane dlhe stlacenie + +button_short: ; kratke stlacenie + cpl up ; prepni smer synchronizacie + cpl down + ajmp button_exit ; skonci + +button_long: ; dlhe stlacenie + ; reaguj podla smeru synchronizacie + jnb up,button_upload + jnb down,button_download +button_upload: ; at89cx501 do prevodniku + clr green ; led do aktivneho stavu + clr red + acall pcoderead ; precitaj pamat programu + setb red ; zasviet zelenu led + ajmp button_exit ; skonci +button_download: ; prevodnik do at89cx501 + clr green ; led do aktivneho stavu + clr red + acall perasechip ; zamaz at89cx501 + acall pcodewrite ; zapis data + jnc button_download_l0 + setb green ; zapis neuspesny, zasviet cervenu led + ajmp button_exit ; a skonci +button_download_l0: + acall plockwrite ; zapis lock bity + setb red ; zapis uspesny, zasviet zelenu led + ajmp button_exit ; a skonci + +button_exit: ; cakaj na pustenie tlacidla + mov r0,#10 ; zober 10 vzoriek +button_exit_l0: + clr tf1 ; po 5 ms + mov tl1,#low (65535 - 10000) + mov th1,#high (65535 - 10000) + jnb tf1,$ + jnb btn,button_exit ; ak je detekovane stlacenie, znovu + djnz r0,button_exit_l0 + clr lock ; odomkni model + reti + +; ---------------------------------------------------------------------- + ; vypinacia sekvencia +poff: clr xtal ; xtal = 0 v + acall rst0v ; rst = 0 v + clr vccsw ; vypni napajanie + ret + +pcodewrite: ; naprogramovanie pamate at89cx051 + setb vccsw ; zapni napajanie + setb prog ; prog = 5 v + acall rst5v ; rst = 5 v + clr m0 ; mod + setb m1 + setb m2 ; ok + mov dptr,#0 ; nastav fram adresu + clr f0 ; nabeh rst na 12 v len pre 1. bajt +pcodewrite_l0: + acall vread ; precitaj bajt z modelu + mov pdata,a ; posli bajt at89cx051 + jb f0,$+7 + acall rst12v ; rst = 12 v + setb f0 ; len pre prvy bajt + clr prog ; 1 us prog pulz + nop + setb prog ; ok + clr tf1 ; cakaj 2 ms na skoncenie zapisu + mov tl1,#low (65535 - 4000) + mov th1,#high (65535 - 4000) + jnb tf1,$ + setb xtal ; zvys adresu at89cx501 + clr xtal + inc dptr ; zvys adresu modelu + mov a,dph ; skontroluj adresu + cjne a,#vmargin,pcodewrite_l0 +pcodeverify: ; kontrola pamate at89cx051 + acall rst5v ; rst = 5 v + setb prog ; prog = 5 v + clr m0 ; mod + clr m1 + setb m2 ; ok + mov dptr,#0 ; zaklad adresy modelu +pcodeverify_l0: + acall vread ; precitaj byte z modelu + xrl a,pdata ; a porovnaj z at89cx501 + ; ak acc != 0, chyba + jnz pcodeverify_error + setb xtal ; zvys adresu at89cx501 + clr xtal + inc dptr ; zvys adresu modelu + mov a,dph ; skontroluj adresu + cjne a,#vmargin,pcodeverify_l0 + acall poff ; vypinacia sekvencia + clr c ; zhod vlajku chyby + ret +pcodeverify_error: + acall poff ; vypinacia sekvencia + setb c ; nastav vlajku chyby + ret + +pcoderead: ; citanie pamate at89cx051 + mov dptr,#0 ; zmaz 4 kib fram + acall vwrite_open ; otvor model +pcoderead_l1: + mov a,#0ffh ; vymazany bajt + acall vwrite_byte ; zapis bajt do modelu + inc dptr ; inkrementuj adresu + mov a,dph + cjne a,#10h,pcoderead_l1 + acall vwrite_close ; zatvor model + setb vccsw ; zapni napajanie + acall rst5v ; rst = 5 v + setb prog ; prog = 5 v + mov pdata,#0ffh ; pdata ako vstupy + clr m0 ; mod + clr m1 + setb m2 ; ok + mov dptr,#0 ; zaklad adresy modelu +pcoderead_l0: + mov a,pdata ; precitaj data + acall vwrite ; zapis do modelu + setb xtal ; zvys adresu at89cx501 + clr xtal + inc dptr ; zvys adresu modelu + mov a,dph ; skontroluj adresu + cjne a,#vmargin,pcoderead_l0 + acall poff ; vypinacia sekvencia + ret + +plockwrite: ; zapis lock bitov at89cx501 + mov a,vlocks + jnb acc.2,$+7 ; test 1. lock bitu + setb m2 ; nastav prislusny mod + acall plockwrite_l0 ; a zapis + jnb acc.3,$+7 ; test 2. lock bitu + clr m2 ; nastav prislusny mod + acall plockwrite_l0 ; a zapis + ret +plockwrite_l0: + setb vccsw ; zapni napajanie + setb prog ; prog = 5 v + acall rst5v ; rst = 5 v + setb m0 ; mod + setb m1 + acall rst12v ; rst = 12 v + clr prog ; 1 us prog pulz + nop + setb prog ; ok + clr tf1 ; cakaj na skoncenie zapisu + mov tl1,#low (65535 - 4000) + mov th1,#high (65535 - 4000) + jnb tf1,$ + acall poff ; vypinacia sekvencia + ret + +perasechip: ; zmazanie pamate at89cx501 + setb vccsw ; zapni napajanie + acall rst5v ; rst = 5 v + setb prog ; prog = 5 v + setb m0 ; nastav mod + clr m1 + clr m2 ; ok + acall rst12v ; rst = 12 v + clr prog ; prog pulz 10 ms + clr tf1 + mov tl1,#low (65535 - 20000) + mov th1,#high (65535 - 20000) + jnb tf1,$ + setb prog ; ok + acall poff ; vypinacia sekvencia + ret + +; ---------------------------------------------------------------------- +vwrite: mov b,a ; zapis 1 bajt do fram + acall vwrite_open + mov a,b + acall vwrite_byte + acall vwrite_close ; ok + ret + +vwrite_open: ; otvorenie fram pre zapis + clr frwp ; povol zapis + clr frsda ; start + clr frscl ; adresa zariadenia + mov a,#10100000b + acall frsend + mov a,dph ; vrchny bajt adresy + acall frsend + mov a,dpl ; spodny bajt adresy + acall frsend + ret +vwrite_byte: ; zapis bajtu do fram + acall frsend + ret +vwrite_close: ; zatvorenie fram + setb frscl ; stop + setb frsda + setb frwp ; zakaz zapis + ret + +frsend: mov frerr,#2 ; pocet opakovani pri chybe + mov frct,#8 ; posli 8 bitov + mov frtmp,a ; zalohuj data +frsend_l0: + rlc a + mov frsda,c ; acc.7 na sda + setb frscl ; zapis + clr frscl + djnz frct,frsend_l0 ; dalsi bit + setb frsda ; ack + setb frscl + mov c,frsda ; precitaj ack + clr frscl + jc frsend_retry ; vyhodnot ack + ret ; zapis prebehol uspesne, skonci +frsend_retry: ; chyba zapisu + djnz frerr,$+5 + ajmp fatal ; pocet pokusov vycerpany, fatalna chyba + mov frct,#8 ; posli 8 bitov + mov a,frtmp ; obnov data zo zalohy + ajmp frsend_l0 ; a znovu + +vread: acall vwrite_open ; precitaj 1 bajt z fram + setb frwp ; zakaz zapis + setb frscl ; start + clr frsda + clr frscl + mov a,#10100001b ; adresa zariadenia + acall frsend + mov frct,#8 ; prijmi 8 bitov +vread_l0: + mov c,frsda ; zober bit z sda + rlc a + setb frscl ; vypytaj dalsi bit + clr frscl + djnz frct,vread_l0 + setb frsda ; no ack + setb frscl + clr frscl ; ok + setb frscl ; stop + setb frsda + ret + +; ---------------------------------------------------------------------- + ; neopravitelna chyba +fatal: clr ea ; zakaz vsetky prerusenia + setb green ; zhasni vsetky led + setb up + setb down + setb red +fatal_blink: + mov r0,#25 ; blikaj cervenou led s periodou 0.5 s + cpl red +fatal_wait: + clr tf1 + mov tl1,#low (65535 - 40000) + mov th1,#high (65535 - 40000) + jnb tf1,$ + djnz r0,fatal_wait + ajmp fatal_blink ; cakaj do resetu + + end |
