OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [sim/] [mips/] [dv-tx3904tmr.c] - Blame information for rev 1771

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/*  This file is part of the program GDB, the GNU debugger.
2
 
3
    Copyright (C) 1998 Free Software Foundation, Inc.
4
    Contributed by Cygnus Solutions.
5
 
6
    This program is free software; you can redistribute it and/or modify
7
    it under the terms of the GNU General Public License as published by
8
    the Free Software Foundation; either version 2 of the License, or
9
    (at your option) any later version.
10
 
11
    This program is distributed in the hope that it will be useful,
12
    but WITHOUT ANY WARRANTY; without even the implied warranty of
13
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
    GNU General Public License for more details.
15
 
16
    You should have received a copy of the GNU General Public License
17
    along with this program; if not, write to the Free Software
18
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
 
20
    */
21
 
22
 
23
#include "sim-main.h"
24
#include "hw-main.h"
25
 
26
 
27
/* DEVICE
28
 
29
 
30
   tx3904tmr - tx3904 timer
31
 
32
 
33
   DESCRIPTION
34
 
35
 
36
   Implements one tx3904 timer/counter described in the tx3904
37
   user guide.  Three instances are required for TMR0, TMR1, and
38
   TMR3 within the tx3904, at different base addresses.
39
 
40
   Both internal and system clocks are synthesized as divided versions
41
   of the simulator clock.
42
 
43
   There is no support for:
44
    - edge sensitivity of external clock
45
    - different mode restrictions for TMR0..2
46
    - level interrupts (interrupts are treated as events that occur at edges)
47
 
48
 
49
 
50
   PROPERTIES
51
 
52
 
53
   reg <base> <length>
54
 
55
   Base of TMR control register bank.  <length> must equal 0x100.
56
   Register offsets:       0: TCR: timer control  register
57
                           4: TISR: timer interrupt status register
58
                           8: CPRA: compare register A
59
                          12: CPRB: compare register B
60
                          16: ITMR: interval timer mode register
61
                          32: CCDR: divider register
62
                          48: PMGR: pulse generator mode register
63
                          64: WTMR: watchdog timer mode register
64
                         240: TRR: timer read register
65
 
66
 
67
   clock <ticks>
68
 
69
   Rate of timer clock signal.  This number is the number of simulator
70
   ticks per clock signal tick.  Default 1.
71
 
72
 
73
   ext <ticks>
74
 
75
   Rate of "external input clock signal", the other clock input of the
76
   timer.  It uses the same scale as above.  Default 100.
77
 
78
 
79
 
80
   PORTS
81
 
82
 
83
   int (output)
84
 
85
   Interrupt port.  An event is generated when a timer interrupt
86
   occurs.
87
 
88
 
89
   ff (output)
90
 
91
   Flip-flop output, corresponds to the TMFFOUT port.  An event is
92
   generated when flip-flop changes value.  The integer associated
93
   with the event is 1/0 according to flip-flop value.
94
 
95
 
96
   reset (input)
97
 
98
   Reset port.
99
 
100
   */
101
 
102
 
103
 
104
/* static functions */
105
 
106
static void deliver_tx3904tmr_tick (struct hw *me, void *data);
107
 
108
 
109
/* register numbers; each is one word long */
110
enum
111
{
112
  TCR_REG = 0,
113
  TISR_REG = 1,
114
  CPRA_REG = 2,
115
  CPRB_REG = 3,
116
  ITMR_REG = 4,
117
  CCDR_REG = 8,
118
  PMGR_REG = 12,
119
  WTMR_REG = 16,
120
  TRR_REG = 60
121
};
122
 
123
 
124
 
125
/* port ID's */
126
 
127
enum
128
 {
129
  RESET_PORT,
130
  INT_PORT,
131
  FF_PORT
132
};
133
 
134
 
135
static const struct hw_port_descriptor tx3904tmr_ports[] =
136
{
137
  { "int", INT_PORT, 0, output_port, },
138
  { "ff", FF_PORT, 0, output_port, },
139
  { "reset", RESET_PORT, 0, input_port, },
140
  { NULL, },
141
};
142
 
143
 
144
 
145
/* The timer/counter register internal state.  Note that we store
146
   state using the control register images, in host endian order. */
147
 
148
struct tx3904tmr {
149
  address_word base_address; /* control register base */
150
  unsigned_4 clock_ticks, ext_ticks; /* clock frequencies */
151
  signed_8 last_ticks; /* time at last deliver_*_tick call */
152
  signed_8 roundoff_ticks; /* sim ticks unprocessed during last tick call */
153
  int ff; /* pulse generator flip-flop value: 1/0 */
154
  struct hw_event* event; /* last scheduled event */
155
 
156
  unsigned_4 tcr;
157
#define GET_TCR_TCE(c)      (((c)->tcr & 0x80) >> 7)
158
#define GET_TCR_CCDE(c)     (((c)->tcr & 0x40) >> 6)
159
#define GET_TCR_CRE(c)      (((c)->tcr & 0x20) >> 5)
160
#define GET_TCR_CCS(c)      (((c)->tcr & 0x04) >> 2)
161
#define GET_TCR_TMODE(c)    (((c)->tcr & 0x03) >> 0)
162
  unsigned_4 tisr;
163
#define SET_TISR_TWIS(c)    ((c)->tisr |= 0x08)
164
#define SET_TISR_TPIBS(c)   ((c)->tisr |= 0x04)
165
#define SET_TISR_TPIAS(c)   ((c)->tisr |= 0x02)
166
#define SET_TISR_TIIS(c)    ((c)->tisr |= 0x01)
167
  unsigned_4 cpra;
168
  unsigned_4 cprb;
169
  unsigned_4 itmr;
170
#define GET_ITMR_TIIE(c)    (((c)->itmr & 0x8000) >> 15)
171
#define SET_ITMR_TIIE(c,v)  BLIT32((c)->itmr, 15, (v) ? 1 : 0)
172
#define GET_ITMR_TZCE(c)    (((c)->itmr & 0x0001) >> 0)
173
#define SET_ITMR_TZCE(c,v)  BLIT32((c)->itmr, 0, (v) ? 1 : 0)
174
  unsigned_4 ccdr;
175
#define GET_CCDR_CDR(c)     (((c)->ccdr & 0x07) >> 0)
176
  unsigned_4 pmgr;
177
#define GET_PMGR_TPIBE(c)   (((c)->pmgr & 0x8000) >> 15)
178
#define SET_PMGR_TPIBE(c,v) BLIT32((c)->pmgr, 15, (v) ? 1 : 0)
179
#define GET_PMGR_TPIAE(c)   (((c)->pmgr & 0x4000) >> 14)
180
#define SET_PMGR_TPIAE(c,v) BLIT32((c)->pmgr, 14, (v) ? 1 : 0)
181
#define GET_PMGR_FFI(c)     (((c)->pmgr & 0x0001) >> 0)
182
#define SET_PMGR_FFI(c,v)   BLIT32((c)->pmgr, 0, (v) ? 1 : 0)
183
  unsigned_4 wtmr;
184
#define GET_WTMR_TWIE(c)    (((c)->wtmr & 0x8000) >> 15)
185
#define SET_WTMR_TWIE(c,v)  BLIT32((c)->wtmr, 15, (v) ? 1 : 0)
186
#define GET_WTMR_WDIS(c)    (((c)->wtmr & 0x0080) >> 7)
187
#define SET_WTMR_WDIS(c,v)  BLIT32((c)->wtmr, 7, (v) ? 1 : 0)
188
#define GET_WTMR_TWC(c)     (((c)->wtmr & 0x0001) >> 0)
189
#define SET_WTMR_TWC(c,v)   BLIT32((c)->wtmr, 0, (v) ? 1 : 0)
190
  unsigned_4 trr;
191
};
192
 
193
 
194
 
195
/* Finish off the partially created hw device.  Attach our local
196
   callbacks.  Wire up our port names etc */
197
 
198
static hw_io_read_buffer_method tx3904tmr_io_read_buffer;
199
static hw_io_write_buffer_method tx3904tmr_io_write_buffer;
200
static hw_port_event_method tx3904tmr_port_event;
201
 
202
static void
203
attach_tx3904tmr_regs (struct hw *me,
204
                      struct tx3904tmr *controller)
205
{
206
  unsigned_word attach_address;
207
  int attach_space;
208
  unsigned attach_size;
209
  reg_property_spec reg;
210
 
211
  if (hw_find_property (me, "reg") == NULL)
212
    hw_abort (me, "Missing \"reg\" property");
213
 
214
  if (!hw_find_reg_array_property (me, "reg", 0, &reg))
215
    hw_abort (me, "\"reg\" property must contain one addr/size entry");
216
 
217
  hw_unit_address_to_attach_address (hw_parent (me),
218
                                     &reg.address,
219
                                     &attach_space,
220
                                     &attach_address,
221
                                     me);
222
  hw_unit_size_to_attach_size (hw_parent (me),
223
                               &reg.size,
224
                               &attach_size, me);
225
 
226
  hw_attach_address (hw_parent (me), 0,
227
                     attach_space, attach_address, attach_size,
228
                     me);
229
 
230
  if(hw_find_property(me, "clock") != NULL)
231
    controller->clock_ticks = (unsigned_4) hw_find_integer_property(me, "clock");
232
 
233
  if(hw_find_property(me, "ext") != NULL)
234
    controller->ext_ticks = (unsigned_4) hw_find_integer_property(me, "ext");
235
 
236
  controller->base_address = attach_address;
237
}
238
 
239
 
240
static void
241
tx3904tmr_finish (struct hw *me)
242
{
243
  struct tx3904tmr *controller;
244
 
245
  controller = HW_ZALLOC (me, struct tx3904tmr);
246
  set_hw_data (me, controller);
247
  set_hw_io_read_buffer (me, tx3904tmr_io_read_buffer);
248
  set_hw_io_write_buffer (me, tx3904tmr_io_write_buffer);
249
  set_hw_ports (me, tx3904tmr_ports);
250
  set_hw_port_event (me, tx3904tmr_port_event);
251
 
252
  /* Preset clock dividers */
253
  controller->clock_ticks = 1;
254
  controller->ext_ticks = 100;
255
 
256
  /* Attach ourself to our parent bus */
257
  attach_tx3904tmr_regs (me, controller);
258
 
259
  /* Initialize to reset state */
260
  controller->tcr =
261
    controller->itmr =
262
    controller->ccdr =
263
    controller->pmgr =
264
    controller->wtmr =
265
    controller->tisr =
266
    controller->trr = 0;
267
  controller->cpra = controller->cprb = 0x00FFFFFF;
268
  controller->ff = 0;
269
  controller->last_ticks = controller->roundoff_ticks = 0;
270
  controller->event = NULL;
271
}
272
 
273
 
274
 
275
/* An event arrives on an interrupt port */
276
 
277
static void
278
tx3904tmr_port_event (struct hw *me,
279
                     int my_port,
280
                     struct hw *source,
281
                     int source_port,
282
                     int level)
283
{
284
  struct tx3904tmr *controller = hw_data (me);
285
 
286
  switch (my_port)
287
    {
288
    case RESET_PORT:
289
      {
290
        HW_TRACE ((me, "reset"));
291
 
292
        /* preset flip-flop to FFI value */
293
        controller->ff = GET_PMGR_FFI(controller);
294
 
295
        controller->tcr =
296
          controller->itmr =
297
          controller->ccdr =
298
          controller->pmgr =
299
          controller->wtmr =
300
          controller->tisr =
301
          controller->trr = 0;
302
        controller->cpra = controller->cprb = 0x00FFFFFF;
303
        controller->last_ticks = controller->roundoff_ticks = 0;
304
        if(controller->event != NULL)
305
          hw_event_queue_deschedule(me, controller->event);
306
        controller->event = NULL;
307
        break;
308
      }
309
 
310
    default:
311
      hw_abort (me, "Event on unknown port %d", my_port);
312
      break;
313
    }
314
}
315
 
316
 
317
/* generic read/write */
318
 
319
static unsigned
320
tx3904tmr_io_read_buffer (struct hw *me,
321
                         void *dest,
322
                         int space,
323
                         unsigned_word base,
324
                         unsigned nr_bytes)
325
{
326
  struct tx3904tmr *controller = hw_data (me);
327
  unsigned byte;
328
 
329
  HW_TRACE ((me, "read 0x%08lx %d", (long) base, (int) nr_bytes));
330
  for (byte = 0; byte < nr_bytes; byte++)
331
    {
332
      address_word address = base + byte;
333
      int reg_number = (address - controller->base_address) / 4;
334
      int reg_offset = 3 - (address - controller->base_address) % 4;
335
      unsigned_4 register_value; /* in target byte order */
336
 
337
      /* fill in entire register_value word */
338
      switch (reg_number)
339
        {
340
        case TCR_REG: register_value = controller->tcr; break;
341
        case TISR_REG: register_value = controller->tisr; break;
342
        case CPRA_REG: register_value = controller->cpra; break;
343
        case CPRB_REG: register_value = controller->cprb; break;
344
        case ITMR_REG: register_value = controller->itmr; break;
345
        case CCDR_REG: register_value = controller->ccdr; break;
346
        case PMGR_REG: register_value = controller->pmgr; break;
347
        case WTMR_REG: register_value = controller->wtmr; break;
348
        case TRR_REG: register_value = controller->trr; break;
349
        default: register_value = 0;
350
        }
351
 
352
      /* write requested byte out */
353
      memcpy ((char*) dest + byte, ((char*)& register_value)+reg_offset, 1);
354
    }
355
 
356
  return nr_bytes;
357
}
358
 
359
 
360
 
361
static unsigned
362
tx3904tmr_io_write_buffer (struct hw *me,
363
                          const void *source,
364
                          int space,
365
                          unsigned_word base,
366
                          unsigned nr_bytes)
367
{
368
  struct tx3904tmr *controller = hw_data (me);
369
  unsigned byte;
370
 
371
  HW_TRACE ((me, "write 0x%08lx %d", (long) base, (int) nr_bytes));
372
  for (byte = 0; byte < nr_bytes; byte++)
373
    {
374
      address_word address = base + byte;
375
      unsigned_1 write_byte = ((const char*) source)[byte];
376
      int reg_number = (address - controller->base_address) / 4;
377
      int reg_offset = 3 - (address - controller->base_address) % 4;
378
 
379
      /* fill in entire register_value word */
380
      switch (reg_number)
381
        {
382
        case TCR_REG:
383
          if(reg_offset == 0) /* first byte */
384
            {
385
              /* update register, but mask out NOP bits */
386
              controller->tcr = (unsigned_4) (write_byte & 0xef);
387
 
388
              /* Reset counter value if timer suspended and CRE is set. */
389
              if(GET_TCR_TCE(controller) == 0 &&
390
                 GET_TCR_CRE(controller) == 1)
391
                controller->trr = 0;
392
            }
393
          /* HW_TRACE ((me, "tcr: %08lx", (long) controller->tcr)); */
394
          break;
395
 
396
        case ITMR_REG:
397
          if(reg_offset == 1) /* second byte */
398
            {
399
              SET_ITMR_TIIE(controller, write_byte & 0x80);
400
            }
401
          else if(reg_offset == 0) /* first byte */
402
            {
403
              SET_ITMR_TZCE(controller, write_byte & 0x01);
404
            }
405
          /* HW_TRACE ((me, "itmr: %08lx", (long) controller->itmr)); */
406
          break;
407
 
408
        case CCDR_REG:
409
          if(reg_offset == 0) /* first byte */
410
            {
411
              controller->ccdr = write_byte & 0x07;
412
            }
413
          /* HW_TRACE ((me, "ccdr: %08lx", (long) controller->ccdr)); */
414
          break;
415
 
416
        case PMGR_REG:
417
          if(reg_offset == 1) /* second byte */
418
            {
419
              SET_PMGR_TPIBE(controller, write_byte & 0x80);
420
              SET_PMGR_TPIAE(controller, write_byte & 0x40);
421
            }
422
          else if(reg_offset == 0) /* first byte */
423
            {
424
              SET_PMGR_FFI(controller, write_byte & 0x01);
425
            }
426
          /* HW_TRACE ((me, "pmgr: %08lx", (long) controller->pmgr)); */
427
          break;
428
 
429
        case WTMR_REG:
430
          if(reg_offset == 1) /* second byte */
431
            {
432
              SET_WTMR_TWIE(controller, write_byte & 0x80);
433
            }
434
          else if(reg_offset == 0) /* first byte */
435
            {
436
              SET_WTMR_WDIS(controller, write_byte & 0x80);
437
              SET_WTMR_TWC(controller, write_byte & 0x01);
438
            }
439
          /* HW_TRACE ((me, "wtmr: %08lx", (long) controller->wtmr)); */
440
          break;
441
 
442
        case TISR_REG:
443
          if(reg_offset == 0) /* first byte */
444
            {
445
              /* All bits must be zero in given byte, according to
446
                 spec. */
447
 
448
              /* Send an "interrupt off" event on the interrupt port */
449
              if(controller->tisr != 0) /* any interrupts active? */
450
                {
451
                  hw_port_event(me, INT_PORT, 0);
452
                }
453
 
454
              /* clear interrupt status register */
455
              controller->tisr = 0;
456
            }
457
          /* HW_TRACE ((me, "tisr: %08lx", (long) controller->tisr)); */
458
          break;
459
 
460
        case CPRA_REG:
461
          if(reg_offset < 3) /* first, second, or third byte */
462
            {
463
              MBLIT32(controller->cpra, (reg_offset*8)+7, (reg_offset*8), write_byte);
464
            }
465
          /* HW_TRACE ((me, "cpra: %08lx", (long) controller->cpra)); */
466
          break;
467
 
468
        case CPRB_REG:
469
          if(reg_offset < 3) /* first, second, or third byte */
470
            {
471
              MBLIT32(controller->cprb, (reg_offset*8)+7, (reg_offset*8), write_byte);
472
            }
473
          /* HW_TRACE ((me, "cprb: %08lx", (long) controller->cprb)); */
474
          break;
475
 
476
        default:
477
          HW_TRACE ((me, "write to illegal register %d", reg_number));
478
        }
479
    } /* loop over bytes */
480
 
481
  /* Schedule a timer event in near future, so we can increment or
482
     stop the counter, to respond to register updates. */
483
  hw_event_queue_schedule(me, 1, deliver_tx3904tmr_tick, NULL);
484
 
485
  return nr_bytes;
486
}
487
 
488
 
489
 
490
/* Deliver a clock tick to the counter. */
491
static void
492
deliver_tx3904tmr_tick (struct hw *me,
493
                        void *data)
494
{
495
  struct tx3904tmr *controller = hw_data (me);
496
  SIM_DESC sd = hw_system (me);
497
  signed_8 this_ticks = sim_events_time(sd);
498
 
499
  signed_8 warp;
500
  signed_8 divisor;
501
  signed_8 quotient, remainder;
502
 
503
  /* compute simulation ticks between last tick and this tick */
504
  if(controller->last_ticks != 0)
505
    warp = this_ticks - controller->last_ticks + controller->roundoff_ticks;
506
  else
507
    {
508
      controller->last_ticks = this_ticks; /* initialize */
509
      warp = controller->roundoff_ticks;
510
    }
511
 
512
  if(controller->event != NULL)
513
    hw_event_queue_deschedule(me, controller->event);
514
  controller->event = NULL;
515
 
516
  /* Check whether the timer ticking is enabled at this moment.  This
517
     largely a function of the TCE bit, but is also slightly
518
     mode-dependent. */
519
  switch((int) GET_TCR_TMODE(controller))
520
    {
521
    case 0: /* interval */
522
      /* do not advance counter if TCE = 0 or if holding at count = CPRA */
523
      if(GET_TCR_TCE(controller) == 0 ||
524
         controller->trr == controller->cpra)
525
        return;
526
      break;
527
 
528
    case 1: /* pulse generator */
529
      /* do not advance counter if TCE = 0 */
530
      if(GET_TCR_TCE(controller) == 0)
531
        return;
532
      break;
533
 
534
    case 2: /* watchdog */
535
      /* do not advance counter if TCE = 0 and WDIS = 1 */
536
      if(GET_TCR_TCE(controller) == 0 &&
537
         GET_WTMR_WDIS(controller) == 1)
538
        return;
539
      break;
540
 
541
    case 3: /* disabled */
542
      /* regardless of TCE, do not advance counter */
543
      return;
544
    }
545
 
546
  /* In any of the above cases that return, a subsequent register
547
     write will be needed to restart the timer.  A tick event is
548
     scheduled by any register write, so it is more efficient not to
549
     reschedule dummy events here. */
550
 
551
 
552
  /* find appropriate divisor etc. */
553
  if(GET_TCR_CCS(controller) == 0) /* internal system clock */
554
    {
555
      /* apply internal clock divider */
556
      if(GET_TCR_CCDE(controller)) /* divisor circuit enabled? */
557
        divisor = controller->clock_ticks * (1 << (1 + GET_CCDR_CDR(controller)));
558
      else
559
        divisor = controller->clock_ticks;
560
    }
561
  else
562
    {
563
      divisor = controller->ext_ticks;
564
    }
565
 
566
  /* how many times to increase counter? */
567
  quotient = warp / divisor;
568
  remainder = warp % divisor;
569
 
570
  /* NOTE: If the event rescheduling code works properly, the quotient
571
     should never be larger than 1.  That is, we should receive events
572
     here at least as frequently as the simulated counter is supposed
573
     to decrement.  So the remainder (-> roundoff_ticks) will slowly
574
     accumulate, with the quotient == 0.  Once in a while, quotient
575
     will equal 1. */
576
 
577
  controller->roundoff_ticks = remainder;
578
  controller->last_ticks = this_ticks;
579
  while(quotient > 0) /* Is it time to increment counter? */
580
    {
581
      /* next 24-bit counter value */
582
      unsigned_4 next_trr = (controller->trr + 1) % (1 << 24);
583
      quotient --;
584
 
585
      switch((int) GET_TCR_TMODE(controller))
586
        {
587
        case 0: /* interval timer mode */
588
          {
589
            /* Current or next counter value matches CPRA value?  The
590
               first case covers counter holding at maximum before
591
               reset.  The second case covers normal counting
592
               behavior. */
593
            if(controller->trr == controller->cpra ||
594
               next_trr == controller->cpra)
595
              {
596
                /* likely hold CPRA value */
597
                if(controller->trr == controller->cpra)
598
                  next_trr = controller->cpra;
599
 
600
                SET_TISR_TIIS(controller);
601
 
602
                /* Signal an interrupt if it is enabled with TIIE,
603
                   and if we just arrived at CPRA.  Don't repeatedly
604
                   interrupt if holding due to TZCE=0 */
605
                if(GET_ITMR_TIIE(controller) &&
606
                   next_trr != controller->trr)
607
                  {
608
                    hw_port_event(me, INT_PORT, 1);
609
                  }
610
 
611
                /* Reset counter? */
612
                if(GET_ITMR_TZCE(controller))
613
                  {
614
                    next_trr = 0;
615
                  }
616
              }
617
          }
618
        break;
619
 
620
        case 1: /* pulse generator mode */
621
          {
622
            /* first trip point */
623
            if(next_trr == controller->cpra)
624
              {
625
                /* flip flip-flop & report */
626
                controller->ff ^= 1;
627
                hw_port_event(me, FF_PORT, controller->ff);
628
                SET_TISR_TPIAS(controller);
629
 
630
                /* signal interrupt */
631
                if(GET_PMGR_TPIAE(controller))
632
                  {
633
                    hw_port_event(me, INT_PORT, 1);
634
                  }
635
 
636
              }
637
            /* second trip point */
638
            else if(next_trr == controller->cprb)
639
              {
640
                /* flip flip-flop & report */
641
                controller->ff ^= 1;
642
                hw_port_event(me, FF_PORT, controller->ff);
643
                SET_TISR_TPIBS(controller);
644
 
645
                /* signal interrupt */
646
                if(GET_PMGR_TPIBE(controller))
647
                  {
648
                    hw_port_event(me, INT_PORT, 1);
649
                  }
650
 
651
                /* clear counter */
652
                next_trr = 0;
653
              }
654
          }
655
        break;
656
 
657
        case 2: /* watchdog timer mode */
658
          {
659
            /* watchdog timer expiry */
660
            if(next_trr == controller->cpra)
661
              {
662
                SET_TISR_TWIS(controller);
663
 
664
                /* signal interrupt */
665
                if(GET_WTMR_TWIE(controller))
666
                  {
667
                    hw_port_event(me, INT_PORT, 1);
668
                  }
669
 
670
                /* clear counter */
671
                next_trr = 0;
672
              }
673
          }
674
        break;
675
 
676
        case 3: /* disabled */
677
        default:
678
        }
679
 
680
      /* update counter and report */
681
      controller->trr = next_trr;
682
      /* HW_TRACE ((me, "counter trr %ld tisr %lx",
683
         (long) controller->trr, (long) controller->tisr)); */
684
    } /* end quotient loop */
685
 
686
  /* Reschedule a timer event in near future, so we can increment the
687
     counter again.  Set the event about 75% of divisor time away, so
688
     we will experience roughly 1.3 events per counter increment. */
689
  controller->event = hw_event_queue_schedule(me, divisor*3/4, deliver_tx3904tmr_tick, NULL);
690
}
691
 
692
 
693
 
694
 
695
const struct hw_descriptor dv_tx3904tmr_descriptor[] = {
696
  { "tx3904tmr", tx3904tmr_finish, },
697
  { NULL },
698
};

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.