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 sfr= uc->address_space(MEM_SFR_ID);
44 if (features & (t2_down|t2_clock_out))
46 register_cell(sfr, T2MOD, &cell_t2mod,
55 //cell_rcap2l= uc->mem(MEM_SFR)->get_cell(RCAP2L);
56 //cell_rcap2h= uc->mem(MEM_SFR)->get_cell(RCAP2H);
57 use_cell(sfr, RCAP2L, &cell_rcap2l, wtd_restore);
58 use_cell(sfr, RCAP2H, &cell_rcap2h, wtd_restore);
60 bit_t2ex= sfr->read(P1) & bmT2EX;
65 cl_timer2::added_to_uc(void)
67 uc->it_sources->add(new cl_it_src(bmET2, T2CON, bmTF2, 0x002b, false,
69 exf2it= new cl_it_src(bmET2, T2CON, bmEXF2, 0x002b, false,
71 uc->it_sources->add(exf2it);
75 cl_timer2::mem_cell_changed(class cl_mem *mem, t_addr addr)
77 class cl_mem *sfr= uc->mem(MEM_SFR);
80 if (mem && sfr && mem == sfr)
85 c= cell_tcon= sfr->get_cell(T2CON);
94 cell_tl= sfr->get_cell(addr_tl);
96 cell_th= sfr->get_cell(addr_th);
97 cell_rcap2l= sfr->get_cell(RCAP2L);
98 cell_rcap2h= sfr->get_cell(RCAP2H);
103 cl_timer2::added(class cl_hw *new_hw)
105 if (new_hw->cathegory == HW_UART)
106 hws_to_inform->add(new_hw);
110 cl_timer2::write(class cl_memory_cell *cell, t_mem *val)
117 if (cell == cell_tcon)
119 C_T = *val & mask_C_T;
121 RCLK= *val & mask_RCLK;
122 TCLK= *val & mask_TCLK;
123 CP_RL2= *val & mask_CP_RL2;
124 EXEN2 = *val & bmEXEN2;
125 if (!(RCLK || TCLK) &&
128 else if (!(RCLK || TCLK) &&
130 mode= T2MODE_CAPTURE;
131 else if (RCLK || TCLK)
132 mode= T2MODE_BAUDRATE;
136 inform_partners(EV_T2_MODE_CHANGED, val);
138 else if (cell == cell_t2mod)
140 bit_dcen= (*val & bmDCEN) != 0;
141 bit_t2oe= (*val & bmT2OE) != 0;
142 if ((features & t2_down) &&
144 mode == T2MODE_RELOAD)
148 exf2it->deactivate();
150 if ((features & t2_clock_out) &&
154 if (mode != oldmode ||
157 T_edge= t2ex_edge= 0;
161 cl_timer2::tick(int cycles)
165 case T2MODE_BAUDRATE:
169 do_t2_capture(cycles);
172 do_t2_reload(cycles);
178 do_t2_clock_out(cycles);
187 * Baud rate generator mode of Timer #2
191 cl_timer2::do_t2_baud(int cycles)
193 if (EXEN2 && t2ex_edge)
195 cell_tcon->set_bit1(bmEXF2);
203 (cycles= T_edge), T_edge= 0;
209 if (!cell_tl->add(1))
210 if (!cell_th->add(1))
212 cell_th->set(cell_rcap2h->get());
213 cell_tl->set(cell_rcap2l->get());
214 inform_partners(EV_OVERFLOW, 0);
222 * Capture function of Timer #2
226 cl_timer2::do_t2_capture(int cycles)
228 if (EXEN2 && t2ex_edge)
230 cell_tcon->set_bit1(bmEXF2);
231 cell_rcap2h->set(cell_th->get());
232 cell_rcap2l->set(cell_tl->get());
240 (cycles= T_edge), T_edge= 0;
242 if (!cell_tl->add(1))
244 if (!cell_th->add(1))
245 cell_tcon->set_bit1(bmTF2);
251 * Auto Reload mode of Timer #2, counting UP
255 cl_timer2::do_t2_reload(int cycles)
257 if (EXEN2 && t2ex_edge)
259 cell_tcon->set_bit1(bmEXF2);
260 cell_th->set(cell_rcap2h->get());
261 cell_tl->set(cell_rcap2l->get());
269 (cycles= T_edge), T_edge= 0;
271 if (!cell_tl->add(1))
273 if (!cell_th->add(1))
275 cell_tcon->set_bit1(mask_TF);
276 cell_th->set(cell_rcap2h->get());
277 cell_tl->set(cell_rcap2l->get());
283 cl_timer2::do_t2_down(int cycles)
285 bool toggle= DD_FALSE;
291 (cycles= T_edge), T_edge= 0;
296 if (!cell_tl->add(1))
298 if (!cell_th->add(1))
300 cell_tcon->set_bit1(mask_TF);
301 cell_th->set(cell_rcap2h->get());
302 cell_tl->set(cell_rcap2l->get());
311 if ((l= cell_tl->add(-1)) == 0xff)
315 if ((TYPE_UWORD)(h*256+l) <
316 (TYPE_UWORD)(cell_rcap2h->get()*256+cell_rcap2l->get()))
318 cell_tcon->set_bit1(mask_TF);
327 class cl_memory_cell *p1= sfr->get_cell(P1);
329 p1->set(p1->get() ^ bmEXF2);
334 cl_timer2::do_t2_clock_out(int cycles)
336 if (EXEN2 && t2ex_edge)
338 cell_tcon->set_bit1(bmEXF2);
346 (cycles= T_edge), T_edge= 0;
352 if (!cell_tl->add(1))
353 if (!cell_th->add(1))
355 cell_th->set(cell_rcap2h->get());
356 cell_tl->set(cell_rcap2l->get());
357 inform_partners(EV_OVERFLOW, 0);
362 class cl_memory_cell *p1= sfr->get_cell(P1);
364 p1->set(p1->get() ^ bmT2);
371 cl_timer2::happen(class cl_hw *where, enum hw_event he, void *params)
373 struct ev_port_changed *ep= (struct ev_port_changed *)params;
375 if (where->cathegory == HW_PORT &&
376 he == EV_PORT_CHANGED &&
379 t_mem p1n= ep->new_pins & ep->new_value;
380 t_mem p1o= ep->pins & ep->prev_value;
381 if (!(p1n & mask_T) &&
384 if (!(p1n & bmT2EX) &&
387 bit_t2ex= p1n & bmT2EX;
392 cl_timer2::print_info(class cl_console *con)
394 int t2con= cell_tcon->get();
396 con->dd_printf("%s[%d] 0x%04x", id_string, id,
397 256*cell_th->get()+cell_tl->get());
400 con->dd_printf(" baud");
402 con->dd_printf(" RCLK");
404 con->dd_printf(" TCLK");
407 con->dd_printf(" %s", (CP_RL2)?"capture":"reload");
408 con->dd_printf(" 0x%04x",
409 256*cell_rcap2h->get()+cell_rcap2l->get());
410 con->dd_printf(" %s", (C_T)?"counter":"timer");
411 con->dd_printf(" %s", (TR)?"ON":"OFF");
412 con->dd_printf(" irq=%c", (t2con&bmTF2)?'1':'0');
413 con->dd_printf(" %s", sfr?"?":((sfr->get(IE)&bmET2)?"en":"dis"));
414 con->dd_printf(" prio=%d", uc->it_priority(bmPT2));
415 con->dd_printf("\n");
419 /* End of s51.src/timer2.cc */