2 * Simulator of microcontrollers (timer2.cc)
4 * Copyright (C) 1999,99 Drotos Daniel, Talker Bt.
6 * To contact author send email to drdani@mazsola.iit.uni-miskolc.hu
10 /* This file is part of microcontroller simulator: ucsim.
12 UCSIM is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
17 UCSIM is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
22 You should have received a copy of the GNU General Public License
23 along with UCSIM; see the file COPYING. If not, write to the Free
24 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
33 cl_timer2::cl_timer2(class cl_uc *auc, int aid, char *aid_string,
35 cl_timer0(auc, /*2*/aid, /*"timer2"*/aid_string)
41 mask_CP_RL2= bmCP_RL2;
42 make_partner(HW_UART, 0);
43 if (features & (t2_down|t2_clock_out))
44 register_cell(uc->mem(MEM_SFR), T2MOD, &cell_t2mod, wtd_restore_write);
51 //cell_rcap2l= uc->mem(MEM_SFR)->get_cell(RCAP2L);
52 //cell_rcap2h= uc->mem(MEM_SFR)->get_cell(RCAP2H);
53 use_cell(uc->mem(MEM_SFR), RCAP2L, &cell_rcap2l, wtd_restore);
54 use_cell(uc->mem(MEM_SFR), RCAP2H, &cell_rcap2h, wtd_restore);
55 bit_t2ex= uc->read_mem(MEM_SFR, P1) & bmT2EX;
60 cl_timer2::added_to_uc(void)
62 uc->it_sources->add(new cl_it_src(bmET2, T2CON, bmTF2, 0x002b, false,
64 exf2it= new cl_it_src(bmET2, T2CON, bmEXF2, 0x002b, false,
66 uc->it_sources->add(exf2it);
70 cl_timer2::mem_cell_changed(class cl_mem *mem, t_addr addr)
72 class cl_mem *sfr= uc->mem(MEM_SFR);
75 if (mem && sfr && mem == sfr)
80 c= cell_tcon= sfr->get_cell(T2CON);
89 cell_tl= sfr->get_cell(addr_tl);
91 cell_th= sfr->get_cell(addr_th);
92 cell_rcap2l= sfr->get_cell(RCAP2L);
93 cell_rcap2h= sfr->get_cell(RCAP2H);
98 cl_timer2::added(class cl_hw *new_hw)
100 if (new_hw->cathegory == HW_UART)
101 hws_to_inform->add(new_hw);
105 cl_timer2::write(class cl_cell *cell, t_mem *val)
112 if (cell == cell_tcon)
114 C_T = *val & mask_C_T;
116 RCLK= *val & mask_RCLK;
117 TCLK= *val & mask_TCLK;
118 CP_RL2= *val & mask_CP_RL2;
119 EXEN2 = *val & bmEXEN2;
120 if (!(RCLK || TCLK) &&
123 else if (!(RCLK || TCLK) &&
125 mode= T2MODE_CAPTURE;
126 else if (RCLK || TCLK)
127 mode= T2MODE_BAUDRATE;
131 inform_partners(EV_T2_MODE_CHANGED, val);
133 else if (cell == cell_t2mod)
135 bit_dcen= (*val & bmDCEN) != 0;
136 bit_t2oe= (*val & bmT2OE) != 0;
137 if ((features & t2_down) &&
139 mode == T2MODE_RELOAD)
143 exf2it->deactivate();
145 if ((features & t2_clock_out) &&
149 if (mode != oldmode ||
152 T_edge= t2ex_edge= 0;
156 cl_timer2::tick(int cycles)
160 case T2MODE_BAUDRATE:
164 do_t2_capture(cycles);
167 do_t2_reload(cycles);
173 do_t2_clock_out(cycles);
182 * Baud rate generator mode of Timer #2
186 cl_timer2::do_t2_baud(int cycles)
188 if (EXEN2 && t2ex_edge)
190 cell_tcon->set_bit1(bmEXF2);
198 (cycles= T_edge), T_edge= 0;
204 if (!cell_tl->add(1))
205 if (!cell_th->add(1))
207 cell_th->set(cell_rcap2h->get());
208 cell_tl->set(cell_rcap2l->get());
209 inform_partners(EV_OVERFLOW, 0);
217 * Capture function of Timer #2
221 cl_timer2::do_t2_capture(int cycles)
223 if (EXEN2 && t2ex_edge)
225 cell_tcon->set_bit1(bmEXF2);
226 cell_rcap2h->set(cell_th->get());
227 cell_rcap2l->set(cell_tl->get());
235 (cycles= T_edge), T_edge= 0;
237 if (!cell_tl->add(1))
239 if (!cell_th->add(1))
240 cell_tcon->set_bit1(bmTF2);
246 * Auto Reload mode of Timer #2, counting UP
250 cl_timer2::do_t2_reload(int cycles)
252 if (EXEN2 && t2ex_edge)
254 cell_tcon->set_bit1(bmEXF2);
255 cell_th->set(cell_rcap2h->get());
256 cell_tl->set(cell_rcap2l->get());
264 (cycles= T_edge), T_edge= 0;
266 if (!cell_tl->add(1))
268 if (!cell_th->add(1))
270 cell_tcon->set_bit1(mask_TF);
271 cell_th->set(cell_rcap2h->get());
272 cell_tl->set(cell_rcap2l->get());
278 cl_timer2::do_t2_down(int cycles)
280 bool toggle= DD_FALSE;
286 (cycles= T_edge), T_edge= 0;
291 if (!cell_tl->add(1))
293 if (!cell_th->add(1))
295 cell_tcon->set_bit1(mask_TF);
296 cell_th->set(cell_rcap2h->get());
297 cell_tl->set(cell_rcap2l->get());
306 if ((l= cell_tl->add(-1)) == 0xff)
310 if ((TYPE_UWORD)(h*256+l) <
311 (TYPE_UWORD)(cell_rcap2h->get()*256+cell_rcap2l->get()))
313 cell_tcon->set_bit1(mask_TF);
321 class cl_cell *p1= uc->mem(MEM_SFR)->get_cell(P1);
322 p1->set(p1->get() ^ bmEXF2);
327 cl_timer2::do_t2_clock_out(int cycles)
329 if (EXEN2 && t2ex_edge)
331 cell_tcon->set_bit1(bmEXF2);
339 (cycles= T_edge), T_edge= 0;
345 if (!cell_tl->add(1))
346 if (!cell_th->add(1))
348 cell_th->set(cell_rcap2h->get());
349 cell_tl->set(cell_rcap2l->get());
350 inform_partners(EV_OVERFLOW, 0);
354 class cl_cell *p1= uc->mem(MEM_SFR)->get_cell(P1);
355 p1->set(p1->get() ^ bmT2);
362 cl_timer2::happen(class cl_hw *where, enum hw_event he, void *params)
364 struct ev_port_changed *ep= (struct ev_port_changed *)params;
366 if (where->cathegory == HW_PORT &&
367 he == EV_PORT_CHANGED &&
370 t_mem p1n= ep->new_pins & ep->new_value;
371 t_mem p1o= ep->pins & ep->prev_value;
372 if (!(p1n & mask_T) &&
375 if (!(p1n & bmT2EX) &&
378 bit_t2ex= p1n & bmT2EX;
383 cl_timer2::print_info(class cl_console *con)
385 int t2con= cell_tcon->get();
387 con->dd_printf("%s[%d] 0x%04x", id_string, id,
388 256*cell_th->get()+cell_tl->get());
391 con->dd_printf(" baud");
393 con->dd_printf(" RCLK");
395 con->dd_printf(" TCLK");
398 con->dd_printf(" %s", (CP_RL2)?"capture":"reload");
399 con->dd_printf(" 0x%04x",
400 256*cell_rcap2h->get()+cell_rcap2l->get());
401 con->dd_printf(" %s", (C_T)?"counter":"timer");
402 con->dd_printf(" %s", (TR)?"ON":"OFF");
403 con->dd_printf(" irq=%c", (t2con&bmTF2)?'1':'0');
404 con->dd_printf(" %s", (uc->get_mem(MEM_SFR, IE)&bmET2)?"en":"dis");
405 con->dd_printf(" prio=%d", uc->it_priority(bmPT2));
406 con->dd_printf("\n");
410 /* End of s51.src/timer2.cc */