00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include <config.h>
00034
00035 #include <stdio.h>
00036 #include <stdlib.h>
00037 #include <string.h>
00038
00039 #include "avrerror.h"
00040 #include "avrmalloc.h"
00041 #include "avrclass.h"
00042 #include "utils.h"
00043 #include "callback.h"
00044 #include "op_names.h"
00045
00046 #include "storage.h"
00047 #include "flash.h"
00048
00049 #include "vdevs.h"
00050 #include "memory.h"
00051 #include "stack.h"
00052 #include "register.h"
00053 #include "sram.h"
00054 #include "eeprom.h"
00055 #include "timers.h"
00056 #include "ports.h"
00057
00058 #include "avrcore.h"
00059
00060 #include "intvects.h"
00061
00062 #ifndef DOXYGEN
00063
00064
00065
00066 Timer16Def global_timer16_defs[] = {
00067 {
00068 .timer_name = "Timer1",
00069 .tcnth_name = "TCNT1H",
00070 .tcntl_name = "TCNT1L",
00071 .tccra_name = "TCCR1A",
00072 .tccrb_name = "TCCR1B",
00073 .base = 0x4c,
00074 .tof = bit_TOV1,
00075 .ocf_a = bit_OCF1A,
00076 .ocf_b = bit_OCF1B,
00077 .ocf_c = 8
00078 }
00079 };
00080
00081 OCReg16Def global_ocreg16_defs[] = {
00082 {
00083 .ocrdev_name = "OCR1A",
00084 .ocrl_name = "OCR1AL",
00085 .ocrh_name = "OCR1AH",
00086 .base = 0x4a
00087 },
00088 {
00089 .ocrdev_name = "OCR1B",
00090 .ocrl_name = "OCR1BL",
00091 .ocrh_name = "OCR1BH",
00092 .base = 0x48
00093 },
00094 {
00095 .ocrdev_name = "OCR1C",
00096 .ocrl_name = "OCR1CL",
00097 .ocrh_name = "OCR1CH",
00098 .base = 0x78},
00099 {
00100 .ocrdev_name = "OCR3A",
00101 .ocrl_name = "OCR3AL",
00102 .ocrh_name = "OCR3A",
00103 .base = 0x86
00104 },
00105 {
00106 .ocrdev_name = "OCR3B",
00107 .ocrl_name = "OCR3BL",
00108 .ocrh_name = "OCR3BH",
00109 .base = 0x84
00110 },
00111 {
00112 .ocrdev_name = "OCR3C",
00113 .ocrl_name = "OCR3CL",
00114 .ocrh_name = "OCR3CH",
00115 .base = 0x82
00116 }
00117 };
00118
00119
00120 #endif
00121
00122
00123
00124
00125
00126
00127
00128 static void timer_iadd_addr (VDevice *vdev, int addr, char *name,
00129 int rel_addr, void *data);
00130 static uint8_t timer_intr_read (VDevice *dev, int addr);
00131 static void timer_intr_write (VDevice *dev, int addr, uint8_t val);
00132 static void timer_intr_reset (VDevice *dev);
00133 static int timer_intr_cb (uint64_t time, AvrClass *data);
00134
00135
00136
00137 VDevice *
00138 timer_int_create (int addr, char *name, int rel_addr, void *data)
00139 {
00140 uint8_t *func_mask = (uint8_t *) data;
00141 if (data)
00142 return (VDevice *)timer_intr_new (addr, name, *func_mask);
00143 else
00144 avr_error ("Attempted timer interrupt create with NULL data pointer");
00145 return 0;
00146 }
00147
00148 TimerIntr_T *
00149 timer_intr_new (int addr, char *name, uint8_t func_mask)
00150 {
00151 TimerIntr_T *ti;
00152
00153 ti = avr_new (TimerIntr_T, 1);
00154 timer_intr_construct (ti, addr, name, func_mask);
00155 class_overload_destroy ((AvrClass *)ti, timer_intr_destroy);
00156
00157 return ti;
00158 }
00159
00160
00161
00162 void
00163 timer_intr_construct (TimerIntr_T *ti, int addr, char *name,
00164 uint8_t func_mask)
00165 {
00166 if (ti == NULL)
00167 avr_error ("passed null ptr");
00168
00169 vdev_construct ((VDevice *)ti, timer_intr_read, timer_intr_write,
00170 timer_intr_reset, timer_iadd_addr);
00171
00172 ti->func_mask = func_mask;
00173
00174 timer_iadd_addr ((VDevice *)ti, addr, name, 0, NULL);
00175
00176 timer_intr_reset ((VDevice *)ti);
00177 }
00178
00179 static void
00180 timer_iadd_addr (VDevice *vdev, int addr, char *name, int rel_addr,
00181 void *data)
00182 {
00183 TimerIntr_T *ti = (TimerIntr_T *)vdev;
00184
00185 if (strncmp ("TIFR", name, 4) == 0)
00186 {
00187 ti->tifr_addr = addr;
00188 }
00189
00190 else if (strncmp ("TIMSK", name, 5) == 0)
00191 {
00192 ti->timsk_addr = addr;
00193 }
00194
00195 else
00196 {
00197 avr_error ("invalid Timer Interrupt register name: '%s' @ 0x%04x",
00198 name, addr);
00199 }
00200 }
00201
00202
00203
00204 void
00205 timer_intr_destroy (void *ti)
00206 {
00207 if (ti == NULL)
00208 return;
00209
00210 vdev_destroy (ti);
00211 }
00212
00213 static uint8_t
00214 timer_intr_read (VDevice *dev, int addr)
00215 {
00216 TimerIntr_T *ti = (TimerIntr_T *)dev;
00217
00218 if (addr == ti->timsk_addr)
00219 {
00220 return (ti->timsk & ti->func_mask);
00221 }
00222
00223 else if (addr == ti->tifr_addr)
00224 {
00225 return (ti->tifr & ti->func_mask);
00226 }
00227
00228 else
00229 {
00230 avr_error ("Bad address: 0x%04x", addr);
00231 }
00232
00233 return 0;
00234 }
00235
00236 static void
00237 timer_intr_write (VDevice *dev, int addr, uint8_t val)
00238 {
00239 TimerIntr_T *ti = (TimerIntr_T *)dev;
00240 CallBack *cb;
00241
00242 if (addr == ti->timsk_addr)
00243 {
00244 ti->timsk = (val & ti->func_mask);
00245 if (ti->timsk == 0)
00246 {
00247 ti->intr_cb = NULL;
00248
00249 }
00250 else if (ti->intr_cb == NULL)
00251 {
00252
00253 cb = callback_new (timer_intr_cb, (AvrClass *)ti);
00254 ti->intr_cb = cb;
00255 avr_core_async_cb_add ((AvrCore *)vdev_get_core (dev), cb);
00256 }
00257 }
00258
00259 else if (addr == ti->tifr_addr)
00260 {
00261 ti->tifr &= ~(val & ti->func_mask);
00262 }
00263
00264 else
00265 {
00266 avr_error ("Bad address: 0x%04x", addr);
00267 }
00268 }
00269
00270 static void
00271 timer_intr_reset (VDevice *dev)
00272 {
00273 TimerIntr_T *ti = (TimerIntr_T *)dev;
00274
00275 ti->intr_cb = NULL;
00276
00277 ti->timsk = 0;
00278 ti->tifr = 0;
00279 }
00280
00281 static int
00282 timer_intr_cb (uint64_t time, AvrClass *data)
00283 {
00284 TimerIntr_T *ti = (TimerIntr_T *)data;
00285 uint8_t intrs = ti->timsk & ti->tifr & ti->func_mask;
00286
00287 if (ti->intr_cb == NULL)
00288 return CB_RET_REMOVE;
00289
00290 if (intrs)
00291 {
00292 AvrCore *core = (AvrCore *)vdev_get_core ((VDevice *)ti);
00293
00294
00295
00296
00297
00298
00299
00300 if (intrs & mask_TOV0)
00301 {
00302 avr_core_irq_raise (core, irq_vect_table_index (TIMER0_OVF));
00303 ti->tifr &= ~mask_TOV0;
00304 }
00305 else if (intrs & mask_ICF1)
00306 {
00307 avr_core_irq_raise (core, irq_vect_table_index (TIMER1_CAPT));
00308 ti->tifr &= ~mask_ICF1;
00309 }
00310 else if (intrs & mask_OCF1B)
00311 {
00312 avr_core_irq_raise (core, irq_vect_table_index (TIMER1_COMPB));
00313 ti->tifr &= ~mask_OCF1B;
00314 }
00315 else if (intrs & mask_OCF1A)
00316 {
00317 avr_core_irq_raise (core, irq_vect_table_index (TIMER1_COMPA));
00318 ti->tifr &= ~mask_OCF1A;
00319 }
00320 else if (intrs & mask_TOV1)
00321 {
00322 avr_core_irq_raise (core, irq_vect_table_index (TIMER1_OVF));
00323 ti->tifr &= ~mask_TOV1;
00324 }
00325 else
00326 {
00327 avr_error ("An invalid interrupt was flagged");
00328 }
00329 }
00330
00331 return CB_RET_RETAIN;
00332 }
00333
00334
00335
00336
00337
00338
00339
00340 static void timer0_add_addr (VDevice *vdev, int addr, char *name,
00341 int rel_addr, void *data);
00342 static uint8_t timer0_read (VDevice *dev, int addr);
00343 static void timer0_write (VDevice *dev, int addr, uint8_t val);
00344 static void timer0_reset (VDevice *dev);
00345 static int timer0_clk_incr_cb (uint64_t ck, AvrClass *data);
00346
00347
00348
00349 VDevice *
00350 timer0_create (int addr, char *name, int rel_addr, void *data)
00351 {
00352 return (VDevice *)timer0_new (addr, name, rel_addr);
00353 }
00354
00355 Timer0_T *
00356 timer0_new (int addr, char *name, int rel_addr)
00357 {
00358 Timer0_T *timer;
00359
00360 timer = avr_new (Timer0_T, 1);
00361 timer0_construct (timer, addr, name, rel_addr);
00362 class_overload_destroy ((AvrClass *)timer, timer0_destroy);
00363
00364 return timer;
00365 }
00366
00367
00368
00369 void
00370 timer0_construct (Timer0_T *timer, int addr, char *name, int rel_addr)
00371 {
00372 if (timer == NULL)
00373 avr_error ("passed null ptr");
00374
00375 vdev_construct ((VDevice *)timer, timer0_read, timer0_write, timer0_reset,
00376 timer0_add_addr);
00377
00378 timer0_add_addr ((VDevice *)timer, addr, name, 0, NULL);
00379 if (rel_addr)
00380 timer->related_addr = rel_addr;
00381 timer0_reset ((VDevice *)timer);
00382 }
00383
00384
00385
00386 void
00387 timer0_destroy (void *timer)
00388 {
00389 if (timer == NULL)
00390 return;
00391
00392 vdev_destroy (timer);
00393 }
00394
00395 static void
00396 timer0_add_addr (VDevice *vdev, int addr, char *name, int rel_addr,
00397 void *data)
00398 {
00399 Timer0_T *ti = (Timer0_T *)vdev;
00400
00401 if (strncmp ("TCNT", name, 4) == 0)
00402 {
00403 ti->tcnt_addr = addr;
00404 }
00405
00406 else if (strncmp ("TCCR", name, 4) == 0)
00407 {
00408 ti->tccr_addr = addr;
00409 }
00410
00411 else
00412 {
00413 avr_error ("invalid Timer register name: '%s' @ 0x%04x", name, addr);
00414 }
00415 }
00416
00417 static uint8_t
00418 timer0_read (VDevice *dev, int addr)
00419 {
00420 Timer0_T *timer = (Timer0_T *)dev;
00421
00422 if (addr == timer->tcnt_addr)
00423 return timer->tcnt;
00424
00425 else if (addr == timer->tccr_addr)
00426 return timer->tccr;
00427
00428 else
00429 {
00430 avr_error ("Bad address: 0x%04x", addr);
00431 }
00432
00433 return 0;
00434 }
00435
00436 static void
00437 timer0_write (VDevice *dev, int addr, uint8_t val)
00438 {
00439 Timer0_T *timer = (Timer0_T *)dev;
00440 CallBack *cb;
00441
00442 if (addr == timer->tcnt_addr)
00443 {
00444 timer->tcnt = val;
00445 }
00446
00447 else if (addr == timer->tccr_addr)
00448 {
00449
00450
00451
00452
00453
00454
00455
00456
00457 timer->tccr = val & mask_CS;
00458
00459 switch (timer->tccr)
00460 {
00461 case CS_STOP:
00462
00463 timer->clk_cb = timer->ext_cb = NULL;
00464 timer->divisor = 0;
00465 return;
00466 case CS_EXT_FALL:
00467 case CS_EXT_RISE:
00468
00469 avr_error ("external timer/counter sources is not implemented"
00470 " yet");
00471 return;
00472 case CS_CK:
00473 timer->divisor = 1;
00474 break;
00475 case CS_CK_8:
00476 timer->divisor = 8;
00477 break;
00478 case CS_CK_64:
00479 timer->divisor = 64;
00480 break;
00481 case CS_CK_256:
00482 timer->divisor = 256;
00483 break;
00484 case CS_CK_1024:
00485 timer->divisor = 1024;
00486 break;
00487 default:
00488 avr_error ("The impossible happened!");
00489 }
00490
00491 if (timer->ext_cb)
00492 timer->ext_cb = NULL;
00493
00494
00495 if (timer->clk_cb == NULL)
00496 {
00497 cb = callback_new (timer0_clk_incr_cb, (AvrClass *)timer);
00498 timer->clk_cb = cb;
00499 avr_core_clk_cb_add ((AvrCore *)vdev_get_core ((VDevice *)timer),
00500 cb);
00501 }
00502 }
00503
00504 else
00505 {
00506 avr_error ("Bad address: 0x%04x", addr);
00507 }
00508 }
00509
00510 static void
00511 timer0_reset (VDevice *dev)
00512 {
00513 Timer0_T *timer = (Timer0_T *)dev;
00514
00515 timer->clk_cb = NULL;
00516 timer->ext_cb = NULL;
00517
00518 timer->tccr = 0;
00519 timer->tcnt = 0;
00520
00521 timer->divisor = 0;
00522 }
00523
00524 static int
00525 timer0_clk_incr_cb (uint64_t ck, AvrClass *data)
00526 {
00527 Timer0_T *timer = (Timer0_T *)data;
00528 uint8_t last = timer->tcnt;
00529 TimerIntr_T *ti;
00530
00531 ti = (TimerIntr_T *)avr_core_get_vdev_by_addr ((AvrCore *)
00532 vdev_get_core ((VDevice *)
00533 timer),
00534 timer->related_addr);
00535
00536 if (timer->clk_cb == NULL)
00537 return CB_RET_REMOVE;
00538
00539 if (timer->divisor <= 0)
00540 avr_error ("Bad divisor value: %d", timer->divisor);
00541
00542
00543
00544
00545 timer->tcnt += ((ck & (timer->divisor - 1)) == 0);
00546
00547
00548
00549
00550
00551
00552
00553
00554 if ((timer->tcnt == 0) && (timer->tcnt != last))
00555 ti->tifr |= mask_TOV0;
00556
00557 return CB_RET_RETAIN;
00558 }
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570 static void timer16_add_addr (VDevice *vdev, int addr, char *name,
00571 int rel_addr, void *data);
00572 static void timer16_destroy (void *timer);
00573 static uint8_t timer16_read (VDevice *dev, int addr);
00574 static void timer16_write (VDevice *dev, int addr, uint8_t val);
00575 static void timer16_reset (VDevice *dev);
00576 static int timer16_clk_incr_cb (uint64_t time, AvrClass *data);
00577 static void timer16_handle_tccr_write (Timer16_T *timer);
00578
00579
00580
00581 VDevice *
00582 timer16_create (int addr, char *name, int rel_addr, void *data)
00583 {
00584 uint8_t *def_data = (uint8_t *) data;
00585 if (data)
00586 return (VDevice *)timer16_new (addr, name, rel_addr,
00587 global_timer16_defs[*def_data]);
00588 else
00589 avr_error ("Attempted timer 16 create with NULL data pointer");
00590 return 0;
00591 }
00592
00593 Timer16_T *
00594 timer16_new (int addr, char *name, int rel_addr, Timer16Def timerdef)
00595 {
00596 Timer16_T *timer;
00597
00598 timer = avr_new (Timer16_T, 1);
00599 timer16_construct (timer, addr, name, rel_addr, timerdef);
00600 class_overload_destroy ((AvrClass *)timer, timer16_destroy);
00601
00602 return timer;
00603 }
00604
00605
00606
00607 void
00608 timer16_construct (Timer16_T *timer, int addr, char *name, int rel_addr,
00609 Timer16Def timerdef)
00610 {
00611 if (timer == NULL)
00612 avr_error ("passed null ptr");
00613
00614 vdev_construct ((VDevice *)timer, timer16_read, timer16_write,
00615 timer16_reset, timer16_add_addr);
00616
00617 timer->timerdef = timerdef;
00618
00619 timer16_add_addr ((VDevice *)timer, addr, name, 0, NULL);
00620 if (rel_addr)
00621 timer->related_addr = rel_addr;
00622 timer16_reset ((VDevice *)timer);
00623 }
00624
00625 static void
00626 timer16_add_addr (VDevice *vdev, int addr, char *name, int rel_addr,
00627 void *data)
00628 {
00629 Timer16_T *ti = (Timer16_T *)vdev;
00630
00631 if (strncmp ("TCNTL", name, 5) == 0)
00632 {
00633 ti->tcntl_addr = addr;
00634 }
00635
00636 else if (strncmp ("TCNTH", name, 5) == 0)
00637 {
00638 ti->tcnth_addr = addr;
00639 }
00640
00641 else if (strncmp ("TCCRA", name, 5) == 0)
00642 {
00643 ti->tccra_addr = addr;
00644 }
00645
00646 else if (strncmp ("TCCRB", name, 5) == 0)
00647 {
00648 ti->tccrb_addr = addr;
00649 }
00650
00651 else if (strncmp ("TCCRC", name, 5) == 0)
00652 {
00653 ti->tccrc_addr = addr;
00654 }
00655
00656 else
00657 {
00658 avr_error ("invalid Timer16 register name: '%s' @ 0x%04x", name,
00659 addr);
00660 }
00661 }
00662
00663 static void
00664 timer16_destroy (void *timer)
00665 {
00666 if (timer == NULL)
00667 return;
00668
00669 vdev_destroy (timer);
00670 }
00671
00672 static uint8_t
00673 timer16_read (VDevice *dev, int addr)
00674 {
00675 Timer16_T *timer = (Timer16_T *)dev;
00676
00677 if (addr == timer->tcntl_addr)
00678 {
00679 timer->TEMP = (uint8_t) ((timer->tcnt) >> 8);
00680 return (timer->tcnt) & 0xFF;
00681 }
00682
00683 else if (addr == timer->tcnth_addr)
00684 {
00685 return timer->TEMP;
00686 }
00687
00688 else if (addr == timer->tccra_addr)
00689 {
00690 return timer->tccra;
00691 }
00692
00693 else if (addr == timer->tccrb_addr)
00694 {
00695 return timer->tccrb;
00696 }
00697
00698 else if (addr == timer->tccrc_addr)
00699 {
00700 return timer->tccrc;
00701 }
00702
00703 else
00704 {
00705 avr_error ("Bad address: 0x%04x", addr);
00706 }
00707
00708 return 0;
00709 }
00710
00711 static void
00712 timer16_write (VDevice *dev, int addr, uint8_t val)
00713 {
00714 Timer16_T *timer = (Timer16_T *)dev;
00715
00716 if (addr == timer->tcntl_addr)
00717 {
00718 timer->tcnt = (((timer->TEMP) << 8) & 0xFF00) | val;
00719 }
00720
00721 else if (addr == timer->tcnth_addr)
00722 {
00723 timer->TEMP = val;
00724 }
00725
00726 else if (addr == timer->tccra_addr)
00727 {
00728 timer->tccra = val;
00729 timer16_handle_tccr_write (timer);
00730 }
00731
00732 else if (addr == timer->tccrb_addr)
00733 {
00734 timer->tccrb = val;
00735 timer16_handle_tccr_write (timer);
00736 }
00737
00738 else if (addr == timer->tccrc_addr)
00739 {
00740 timer->tccrc = val;
00741 timer16_handle_tccr_write (timer);
00742 }
00743
00744 else
00745 {
00746 avr_error ("Bad address: 0x%04x", addr);
00747 }
00748 }
00749
00750 static void
00751 timer16_reset (VDevice *dev)
00752 {
00753 Timer16_T *timer = (Timer16_T *)dev;
00754
00755 timer->clk_cb = NULL;
00756 timer->ext_cb = NULL;
00757
00758 timer->tccra = 0;
00759 timer->tccrb = 0;
00760 timer->tccrc = 0;
00761 timer->tcnt = 0;
00762
00763 timer->divisor = 0;
00764 }
00765
00766 static void
00767 timer_intr_set_flag (TimerIntr_T *ti, uint8_t bitnr)
00768 {
00769 ti->tifr |= bitnr;
00770 }
00771
00772 static int
00773 timer16_clk_incr_cb (uint64_t ck, AvrClass *data)
00774 {
00775 Timer16_T *timer = (Timer16_T *)data;
00776 uint16_t last = timer->tcnt;
00777
00778 if (!timer->ti)
00779 timer->ti =
00780 (TimerIntr_T *)avr_core_get_vdev_by_addr ((AvrCore *)
00781 vdev_get_core ((VDevice
00782 *)
00783 timer),
00784 timer->related_addr);
00785
00786 if (timer->clk_cb == NULL)
00787 return CB_RET_REMOVE;
00788
00789
00790
00791
00792 timer->tcnt += ((ck & (timer->divisor - 1)) == 0);
00793
00794 if (timer->divisor <= 0)
00795 avr_error ("Bad divisor value: %d", timer->divisor);
00796
00797
00798
00799 if (timer->tcnt != last)
00800 {
00801
00802 if (timer->tcnt == 0)
00803 timer_intr_set_flag (timer->ti, mask_TOV1);
00804
00805
00806 if (timer->ocra && (timer->tcnt == timer->ocra->ocr))
00807 {
00808 timer_intr_set_flag (timer->ti, mask_OCF1A);
00809 }
00810
00811 if (timer->ocrb && (timer->tcnt == timer->ocrb->ocr))
00812 {
00813 timer_intr_set_flag (timer->ti, mask_OCF1B);
00814 }
00815 }
00816 return CB_RET_RETAIN;
00817 }
00818
00819 #if 0
00820 static void
00821 timer_intr_clear_flag (TimerIntr_T *ti, uint8_t bitnr)
00822 {
00823 ti->tifr &= ~(bitnr);
00824 }
00825 #endif
00826
00827 static void
00828 timer16_handle_tccr_write (Timer16_T *timer)
00829 {
00830 int cs;
00831 CallBack *cb;
00832
00833
00834
00835
00836
00837
00838
00839 cs = timer->tccrb & 0x07;
00840
00841 switch (cs)
00842 {
00843 case CS_STOP:
00844
00845 timer->clk_cb = timer->ext_cb = NULL;
00846 timer->divisor = 0;
00847 return;
00848 case CS_EXT_FALL:
00849 case CS_EXT_RISE:
00850
00851 avr_error ("external timer/counter sources is not implemented"
00852 "yet");
00853 return;
00854 case CS_CK:
00855 timer->divisor = 1;
00856 break;
00857 case CS_CK_8:
00858 timer->divisor = 8;
00859 break;
00860 case CS_CK_64:
00861 timer->divisor = 64;
00862 break;
00863 case CS_CK_256:
00864 timer->divisor = 256;
00865 break;
00866 case CS_CK_1024:
00867 timer->divisor = 1024;
00868 break;
00869 default:
00870 avr_error ("The impossible happened!");
00871 }
00872
00873 if (timer->ext_cb)
00874 timer->ext_cb = NULL;
00875
00876
00877 if (timer->clk_cb == NULL)
00878 {
00879 cb = callback_new (timer16_clk_incr_cb, (AvrClass *)timer);
00880 timer->clk_cb = cb;
00881 avr_core_clk_cb_add ((AvrCore *)vdev_get_core ((VDevice *)timer), cb);
00882 }
00883 }
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897 static void ocr_add_addr (VDevice *vdev, int addr, char *name, int rel_addr,
00898 void *data);
00899 static void ocreg16_destroy (void *ocr);
00900 static uint8_t ocreg16_read (VDevice *dev, int addr);
00901 static void ocreg16_write (VDevice *dev, int addr, uint8_t val);
00902 static void ocreg16_reset (VDevice *dev);
00903
00904
00905
00906
00907
00908 VDevice *
00909 ocreg16_create (int addr, char *name, int rel_addr, void *data)
00910 {
00911 uint8_t *def_data = (uint8_t *) data;
00912 if (data)
00913 return (VDevice *)ocreg16_new (addr, name,
00914 global_ocreg16_defs[*def_data]);
00915 else
00916 avr_error ("Attempted OCReg create with NULL data pointer");
00917 return 0;
00918 }
00919
00920 OCReg16_T *
00921 ocreg16_new (int addr, char *name, OCReg16Def ocrdef)
00922 {
00923 OCReg16_T *ocreg;
00924
00925 ocreg = avr_new (OCReg16_T, 1);
00926 ocreg16_construct (ocreg, addr, name, ocrdef);
00927 class_overload_destroy ((AvrClass *)ocreg, ocreg16_destroy);
00928
00929 return ocreg;
00930 }
00931
00932
00933
00934 void
00935 ocreg16_construct (OCReg16_T *ocreg, int addr, char *name, OCReg16Def ocrdef)
00936 {
00937 if (ocreg == NULL)
00938 avr_error ("passed null ptr");
00939
00940 vdev_construct ((VDevice *)ocreg, ocreg16_read, ocreg16_write,
00941 ocreg16_reset, ocr_add_addr);
00942
00943 ocreg->ocrdef = ocrdef;
00944
00945 ocr_add_addr ((VDevice *)ocreg, addr, name, 0, NULL);
00946 ocreg16_reset ((VDevice *)ocreg);
00947 }
00948
00949 static void
00950 ocr_add_addr (VDevice *vdev, int addr, char *name, int rel_addr, void *data)
00951 {
00952 OCReg16_T *ocreg = (OCReg16_T *)vdev;
00953
00954 if ((strncmp ("OCRAL", name, 5) == 0) || (strncmp ("OCRBL", name, 5) == 0)
00955 || (strncmp ("OCRCL", name, 5) == 0))
00956 {
00957 ocreg->ocrl_addr = addr;
00958 }
00959
00960 else if ((strncmp ("OCRAH", name, 5) == 0)
00961 || (strncmp ("OCRBH", name, 5) == 0)
00962 || (strncmp ("OCRCH", name, 5) == 0))
00963
00964 {
00965 ocreg->ocrh_addr = addr;
00966 }
00967
00968 else
00969 {
00970 avr_error ("invalid Timer16 register name: '%s' @ 0x%04x", name,
00971 addr);
00972 }
00973 }
00974
00975 static void
00976 ocreg16_destroy (void *ocreg)
00977 {
00978 if (ocreg == NULL)
00979 return;
00980
00981 vdev_destroy (ocreg);
00982 }
00983
00984 static uint8_t
00985 ocreg16_read (VDevice *dev, int addr)
00986 {
00987 OCReg16_T *ocreg = (OCReg16_T *)dev;
00988
00989 if (addr == ocreg->ocrl_addr)
00990 {
00991 return (ocreg->ocr) & 0xFF;
00992 }
00993
00994 else if (addr == ocreg->ocrh_addr)
00995 {
00996 return (ocreg->ocr) >> 8;
00997 }
00998
00999 else
01000 {
01001 avr_error ("Bad address: 0x%04x", addr);
01002 }
01003
01004 return 0;
01005 }
01006
01007 static void
01008 ocreg16_write (VDevice *dev, int addr, uint8_t val)
01009 {
01010 OCReg16_T *ocreg = (OCReg16_T *)dev;
01011
01012 if (addr == ocreg->ocrl_addr)
01013 {
01014 ocreg->ocr = (((ocreg->TEMP) << 8) & 0xFF00) | val;
01015 }
01016
01017 else if (addr == ocreg->ocrh_addr)
01018 {
01019 ocreg->TEMP = val;
01020 }
01021
01022 else
01023 {
01024 avr_error ("Bad address: 0x%04x", addr);
01025 }
01026 }
01027
01028 static void
01029 ocreg16_reset (VDevice *dev)
01030 {
01031 OCReg16_T *ocreg = (OCReg16_T *)dev;
01032
01033 ocreg->ocr = 0;
01034 }
01035
01036