📄 timer0.cc
字号:
/* * Simulator of microcontrollers (timer0.cc) * * Copyright (C) 1999,99 Drotos Daniel, Talker Bt. * * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu * *//* This file is part of microcontroller simulator: ucsim.UCSIM is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2 of the License, or(at your option) any later version.UCSIM is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with UCSIM; see the file COPYING. If not, write to the FreeSoftware Foundation, 59 Temple Place - Suite 330, Boston, MA02111-1307, USA. *//*@1@*/#include "timer0cl.h"#include "regs51.h"#include "types51.h"cl_timer0::cl_timer0(class cl_uc *auc, int aid, char *aid_string): cl_hw(auc, HW_TIMER, aid, aid_string){ cell_tmod= cell_tcon= 0; if (aid == 0) { mask_M0 = bmM00; mask_M1 = bmM10; mask_C_T = bmC_T0; mask_GATE= bmGATE0; mask_TR = bmTR0; mask_INT = bm_INT0; mask_TF = bmTF0; mask_T = bmT0; addr_tl = TL0; addr_th = TH0; } else if (aid == 1) { mask_M0 = bmM01; mask_M1 = bmM11; mask_C_T = bmC_T1; mask_GATE= bmGATE1; mask_TR = bmTR1; mask_INT = bm_INT1; mask_TF = bmTF1; mask_T = bmT1; addr_tl = TL1; addr_th = TH1; } else if (aid == 2) { addr_tl = TL2; addr_th = TH2; mask_T = bmT2; mask_C_T = bmC_T2; mask_TR = bmTR2; mask_TF = bmTF2; mask_M0= mask_M1= mask_GATE= mask_INT= 0; } else {} make_partner(HW_PCA, 0); make_partner(HW_PCA, 1); make_partner(HW_PCA, 2); make_partner(HW_PCA, 3); make_partner(HW_PCA, 4);}intcl_timer0::init(void){ class cl_mem *sfr= uc->mem(MEM_SFR); if (sfr) { //t_mem d; if (id == 0 || id == 1) { //cell_tmod= sfr->register_hw(TMOD, this, 0); register_cell(sfr, TMOD, &cell_tmod, wtd_restore_write); //d= cell_tmod->get(); write(cell_tmod, &d); //cell_tcon= sfr->register_hw(TCON, this, 0); register_cell(sfr, TCON, &cell_tcon, wtd_restore_write); //d= cell_tcon->get(); write(cell_tcon, &d); INT= sfr->read(P3) & mask_INT; } else if (id == 2) { cell_tmod= 0; //cell_tcon= sfr->register_hw(T2CON, this, 0); register_cell(sfr, T2CON, &cell_tcon, wtd_restore_write); //d= cell_tcon->get(); write(cell_tcon, &d); } //cell_tl= sfr->get_cell(addr_tl); //cell_th= sfr->get_cell(addr_th); use_cell(sfr, addr_tl, &cell_tl, wtd_restore); use_cell(sfr, addr_th, &cell_th, wtd_restore); } return(0);}voidcl_timer0::added_to_uc(void){ if (id == 0) uc->it_sources->add(new cl_it_src(bmET0, TCON, bmTF0, 0x000b, true, "timer #0", 2)); else if (id == 1) uc->it_sources->add(new cl_it_src(bmET1, TCON, bmTF1, 0x001b, true, "timer #1", 4));}/*t_memcl_timer0::read(class cl_cell *cell){ return(cell->get());}*/voidcl_timer0::write(class cl_cell *cell, t_mem *val){ if (cell == cell_tmod) { t_mem md= *val & (mask_M0|mask_M1); if (md == mask_M0) mode= 1; else if (md == mask_M1) mode= 2; else if (md == (mask_M0|mask_M1)) mode= 3; else mode= 0; GATE= *val & mask_GATE; C_T = *val & mask_C_T; T_edge= 0; } else if (cell == cell_tcon) { TR= *val & mask_TR; T_edge= 0; }}/*voidcl_timer0::mem_cell_changed(class cl_mem *mem, t_addr addr){ //class cl_mem *sfr= uc->mem(MEM_SFR); //t_mem d; cl_hw::mem_cell_changed(mem, addr); //d= cell_tmod->get(); //write(cell_tmod, &d); //d= cell_tcon->get(); //write(cell_tcon, &d); //if (addr == addr_tl) cell_tl= sfr->get_cell(addr_tl); //if (addr == addr_th) cell_th= sfr->get_cell(addr_th);}*/intcl_timer0::tick(int cycles){ switch (mode) { case 0: do_mode0(cycles); break; case 1: do_mode1(cycles); break; case 2: do_mode2(cycles); break; case 3: do_mode3(cycles); break; } return(resGO);}intcl_timer0::do_mode0(int cycles){ if (!TR) return(0); //t_mem p3= uc->mem(MEM_SFR)->get(P3); if (GATE) { if ((/*p3 & mask_*/INT) == 0) return(0); } if (C_T) { /*cycles= 0; if ((uc51->prev_p3 & mask_T) && !(p3 & uc51->port_pins[3] & mask_T)) cycles= 1;*/ cycles= T_edge; T_edge= 0; } while (cycles--) { // mod 0, TH= 8 bit t/c, TL= 5 bit precounter t_mem tl= cell_tl->add(1); if ((tl & 0x1f) == 0) { cell_tl->set(0); if (!cell_th->add(1)) { cell_tcon->set_bit1(mask_TF); overflow(); } } } return(0);}intcl_timer0::do_mode1(int cycles){ if (!TR) return(0); //t_mem p3= uc->mem(MEM_SFR)->get(P3); if (GATE) { if ((/*p3 & mask_*/INT) == 0) return(0); } if (C_T) { /*cycles= 0; if ((uc51->prev_p3 & mask_T) && !(p3 & uc51->port_pins[3] & mask_T)) cycles= 1;*/ cycles= T_edge; T_edge= 0; } while (cycles--) { // mod 1 TH+TL= 16 bit t/c if (!cell_tl->add(1)) { if (!cell_th->add(1)) { cell_tcon->set_bit1(mask_TF); overflow(); } } } return(0);}intcl_timer0::do_mode2(int cycles){ if (!TR) return(0); //t_mem p3= uc->mem(MEM_SFR)->get(P3); if (GATE) { if ((/*p3 & mask_*/INT) == 0) return(0); } if (C_T) { /*cycles= 0; if ((uc51->prev_p3 & mask_T) && !(p3 & uc51->port_pins[3] & mask_T)) cycles= 1;*/ cycles= T_edge; T_edge= 0; } //unsigned long startt= uc->ticks->ticks-(cycles*12);int i=0; while (cycles--) { // mod 2 TL= 8 bit t/c auto reload from TH if (!cell_tl->add(1)) { cell_tl->set(cell_th->get()); cell_tcon->set_bit1(mask_TF); //printf("timer%d overflow %d (%d) %d\n",id,uc->ticks->ticks,i,startt+(i*12)); overflow(); } //i++; } return(0);}intcl_timer0::do_mode3(int cycles){ int cyc= cycles; //t_mem p3= uc->mem(MEM_SFR)->get(P3); if (!TR) goto do_th; if (GATE) { if ((/*p3 & mask_*/INT) == 0) goto do_th; } if (C_T) { /*cycles= 0; if ((uc51->prev_p3 & mask_T) && !(p3 & uc51->port_pins[3] & mask_T)) cycles= 1;*/ cycles= T_edge; T_edge= 0; } while (cycles--) { if (!cell_tl->add(1)) { cell_tcon->set_bit1(mask_TF); overflow(); } } do_th: if ((cell_tcon->get() & bmTR1) != 0) while (cyc--) { if (!cell_th->add(1)) cell_tcon->set_bit1(bmTF1); } return(0);}voidcl_timer0::overflow(void){ inform_partners(EV_OVERFLOW, 0);}voidcl_timer0::happen(class cl_hw *where, enum hw_event he, void *params){ struct ev_port_changed *ep= (struct ev_port_changed *)params; if (where->cathegory == HW_PORT && he == EV_PORT_CHANGED && ep->id == 3) { t_mem p3n= ep->new_pins & ep->new_value; t_mem p3o= ep->pins & ep->prev_value; if ((p3n & mask_T) && !(p3o & mask_T)) T_edge++; INT= p3n & mask_INT; //printf("timer%d p%dchanged (%02x,%02x->%02x,%02x) INT=%d(%02x) edge=%d(%02x)\n",id,where->id,ep->prev_value,ep->pins,ep->new_value,ep->new_pins,INT,mask_INT,T_edge,mask_T); }}voidcl_timer0::print_info(class cl_console *con){ char *modes[]= { "13 bit", "16 bit", "8 bit autoreload", "2x8 bit" }; //t_mem tmod= cell_tmod->get(); int on; con->dd_printf("%s[%d] 0x%04x", id_string, id, 256*cell_th->get()+cell_tl->get()); //int mode= tmod & (bmM00|bmM10); con->dd_printf(" %s", modes[mode]); con->dd_printf(" %s", (/*tmod&bm*/C_T/*0*/)?"counter":"timer"); if (/*tmod&bm*/GATE/*0*/) { con->dd_printf(" gated"); on= /*uc->get_mem(MEM_SFR, P3) & uc->port_pins[3] & mask_*/INT/*bm_INT0*/; } else on= TR/*cell_tcon->get(TCON) & mask_TR*/; con->dd_printf(" %s", on?"ON":"OFF"); con->dd_printf(" irq=%c", (cell_tcon->get()&mask_TF)?'1':'0'); con->dd_printf(" %s", (uc->get_mem(MEM_SFR, IE)&bmET0)?"en":"dis"); con->dd_printf(" prio=%d", uc->it_priority(bmPT0)); con->dd_printf("\n");}/* End of s51.src/timer0.cc */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -