avr_timer16.c (18079B)
1/* 2 * AVR 16-bit timer 3 * 4 * Copyright (c) 2018 University of Kent 5 * Author: Ed Robbins 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this library; if not, see 19 * <http://www.gnu.org/licenses/lgpl-2.1.html> 20 */ 21 22/* 23 * Driver for 16 bit timers on 8 bit AVR devices. 24 * Note: 25 * ATmega640/V-1280/V-1281/V-2560/V-2561/V timers 1, 3, 4 and 5 are 16 bit 26 */ 27 28/* 29 * XXX TODO: Power Reduction Register support 30 * prescaler pause support 31 * PWM modes, GPIO, output capture pins, input compare pin 32 */ 33 34#include "qemu/osdep.h" 35#include "qapi/error.h" 36#include "qemu/log.h" 37#include "hw/irq.h" 38#include "hw/qdev-properties.h" 39#include "hw/timer/avr_timer16.h" 40#include "trace.h" 41 42/* Register offsets */ 43#define T16_CRA 0x0 44#define T16_CRB 0x1 45#define T16_CRC 0x2 46#define T16_CNTL 0x4 47#define T16_CNTH 0x5 48#define T16_ICRL 0x6 49#define T16_ICRH 0x7 50#define T16_OCRAL 0x8 51#define T16_OCRAH 0x9 52#define T16_OCRBL 0xa 53#define T16_OCRBH 0xb 54#define T16_OCRCL 0xc 55#define T16_OCRCH 0xd 56 57/* Field masks */ 58#define T16_CRA_WGM01 0x3 59#define T16_CRA_COMC 0xc 60#define T16_CRA_COMB 0x30 61#define T16_CRA_COMA 0xc0 62#define T16_CRA_OC_CONF \ 63 (T16_CRA_COMA | T16_CRA_COMB | T16_CRA_COMC) 64 65#define T16_CRB_CS 0x7 66#define T16_CRB_WGM23 0x18 67#define T16_CRB_ICES 0x40 68#define T16_CRB_ICNC 0x80 69 70#define T16_CRC_FOCC 0x20 71#define T16_CRC_FOCB 0x40 72#define T16_CRC_FOCA 0x80 73 74/* Fields masks both TIMSK and TIFR (interrupt mask/flag registers) */ 75#define T16_INT_TOV 0x1 /* Timer overflow */ 76#define T16_INT_OCA 0x2 /* Output compare A */ 77#define T16_INT_OCB 0x4 /* Output compare B */ 78#define T16_INT_OCC 0x8 /* Output compare C */ 79#define T16_INT_IC 0x20 /* Input capture */ 80 81/* Clock source values */ 82#define T16_CLKSRC_STOPPED 0 83#define T16_CLKSRC_DIV1 1 84#define T16_CLKSRC_DIV8 2 85#define T16_CLKSRC_DIV64 3 86#define T16_CLKSRC_DIV256 4 87#define T16_CLKSRC_DIV1024 5 88#define T16_CLKSRC_EXT_FALLING 6 89#define T16_CLKSRC_EXT_RISING 7 90 91/* Timer mode values (not including PWM modes) */ 92#define T16_MODE_NORMAL 0 93#define T16_MODE_CTC_OCRA 4 94#define T16_MODE_CTC_ICR 12 95 96/* Accessors */ 97#define CLKSRC(t16) (t16->crb & T16_CRB_CS) 98#define MODE(t16) (((t16->crb & T16_CRB_WGM23) >> 1) | \ 99 (t16->cra & T16_CRA_WGM01)) 100#define CNT(t16) VAL16(t16->cntl, t16->cnth) 101#define OCRA(t16) VAL16(t16->ocral, t16->ocrah) 102#define OCRB(t16) VAL16(t16->ocrbl, t16->ocrbh) 103#define OCRC(t16) VAL16(t16->ocrcl, t16->ocrch) 104#define ICR(t16) VAL16(t16->icrl, t16->icrh) 105 106/* Helper macros */ 107#define VAL16(l, h) ((h << 8) | l) 108#define DB_PRINT(fmt, args...) /* Nothing */ 109 110static inline int64_t avr_timer16_ns_to_ticks(AVRTimer16State *t16, int64_t t) 111{ 112 if (t16->period_ns == 0) { 113 return 0; 114 } 115 return t / t16->period_ns; 116} 117 118static void avr_timer16_update_cnt(AVRTimer16State *t16) 119{ 120 uint16_t cnt; 121 cnt = avr_timer16_ns_to_ticks(t16, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - 122 t16->reset_time_ns); 123 t16->cntl = (uint8_t)(cnt & 0xff); 124 t16->cnth = (uint8_t)((cnt & 0xff00) >> 8); 125} 126 127static inline void avr_timer16_recalc_reset_time(AVRTimer16State *t16) 128{ 129 t16->reset_time_ns = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - 130 CNT(t16) * t16->period_ns; 131} 132 133static void avr_timer16_clock_reset(AVRTimer16State *t16) 134{ 135 t16->cntl = 0; 136 t16->cnth = 0; 137 t16->reset_time_ns = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); 138} 139 140static void avr_timer16_clksrc_update(AVRTimer16State *t16) 141{ 142 uint16_t divider = 0; 143 switch (CLKSRC(t16)) { 144 case T16_CLKSRC_EXT_FALLING: 145 case T16_CLKSRC_EXT_RISING: 146 qemu_log_mask(LOG_UNIMP, "%s: external clock source unsupported\n", 147 __func__); 148 break; 149 case T16_CLKSRC_STOPPED: 150 break; 151 case T16_CLKSRC_DIV1: 152 divider = 1; 153 break; 154 case T16_CLKSRC_DIV8: 155 divider = 8; 156 break; 157 case T16_CLKSRC_DIV64: 158 divider = 64; 159 break; 160 case T16_CLKSRC_DIV256: 161 divider = 256; 162 break; 163 case T16_CLKSRC_DIV1024: 164 divider = 1024; 165 break; 166 default: 167 break; 168 } 169 if (divider) { 170 t16->freq_hz = t16->cpu_freq_hz / divider; 171 t16->period_ns = NANOSECONDS_PER_SECOND / t16->freq_hz; 172 trace_avr_timer16_clksrc_update(t16->freq_hz, t16->period_ns, 173 (uint64_t)(1e6 / t16->freq_hz)); 174 } 175} 176 177static void avr_timer16_set_alarm(AVRTimer16State *t16) 178{ 179 if (CLKSRC(t16) == T16_CLKSRC_EXT_FALLING || 180 CLKSRC(t16) == T16_CLKSRC_EXT_RISING || 181 CLKSRC(t16) == T16_CLKSRC_STOPPED) { 182 /* Timer is disabled or set to external clock source (unsupported) */ 183 return; 184 } 185 186 uint64_t alarm_offset = 0xffff; 187 enum NextInterrupt next_interrupt = OVERFLOW; 188 189 switch (MODE(t16)) { 190 case T16_MODE_NORMAL: 191 /* Normal mode */ 192 if (OCRA(t16) < alarm_offset && OCRA(t16) > CNT(t16) && 193 (t16->imsk & T16_INT_OCA)) { 194 alarm_offset = OCRA(t16); 195 next_interrupt = COMPA; 196 } 197 break; 198 case T16_MODE_CTC_OCRA: 199 /* CTC mode, top = ocra */ 200 if (OCRA(t16) < alarm_offset && OCRA(t16) > CNT(t16)) { 201 alarm_offset = OCRA(t16); 202 next_interrupt = COMPA; 203 } 204 break; 205 case T16_MODE_CTC_ICR: 206 /* CTC mode, top = icr */ 207 if (ICR(t16) < alarm_offset && ICR(t16) > CNT(t16)) { 208 alarm_offset = ICR(t16); 209 next_interrupt = CAPT; 210 } 211 if (OCRA(t16) < alarm_offset && OCRA(t16) > CNT(t16) && 212 (t16->imsk & T16_INT_OCA)) { 213 alarm_offset = OCRA(t16); 214 next_interrupt = COMPA; 215 } 216 break; 217 default: 218 qemu_log_mask(LOG_UNIMP, "%s: pwm modes are unsupported\n", 219 __func__); 220 return; 221 } 222 if (OCRB(t16) < alarm_offset && OCRB(t16) > CNT(t16) && 223 (t16->imsk & T16_INT_OCB)) { 224 alarm_offset = OCRB(t16); 225 next_interrupt = COMPB; 226 } 227 if (OCRC(t16) < alarm_offset && OCRB(t16) > CNT(t16) && 228 (t16->imsk & T16_INT_OCC)) { 229 alarm_offset = OCRB(t16); 230 next_interrupt = COMPC; 231 } 232 alarm_offset -= CNT(t16); 233 234 t16->next_interrupt = next_interrupt; 235 uint64_t alarm_ns = 236 t16->reset_time_ns + ((CNT(t16) + alarm_offset) * t16->period_ns); 237 timer_mod(t16->timer, alarm_ns); 238 239 trace_avr_timer16_next_alarm(alarm_offset * t16->period_ns); 240} 241 242static void avr_timer16_interrupt(void *opaque) 243{ 244 AVRTimer16State *t16 = opaque; 245 uint8_t mode = MODE(t16); 246 247 avr_timer16_update_cnt(t16); 248 249 if (CLKSRC(t16) == T16_CLKSRC_EXT_FALLING || 250 CLKSRC(t16) == T16_CLKSRC_EXT_RISING || 251 CLKSRC(t16) == T16_CLKSRC_STOPPED) { 252 /* Timer is disabled or set to external clock source (unsupported) */ 253 return; 254 } 255 256 trace_avr_timer16_interrupt_count(CNT(t16)); 257 258 /* Counter overflow */ 259 if (t16->next_interrupt == OVERFLOW) { 260 trace_avr_timer16_interrupt_overflow("counter 0xffff"); 261 avr_timer16_clock_reset(t16); 262 if (t16->imsk & T16_INT_TOV) { 263 t16->ifr |= T16_INT_TOV; 264 qemu_set_irq(t16->ovf_irq, 1); 265 } 266 } 267 /* Check for ocra overflow in CTC mode */ 268 if (mode == T16_MODE_CTC_OCRA && t16->next_interrupt == COMPA) { 269 trace_avr_timer16_interrupt_overflow("CTC OCRA"); 270 avr_timer16_clock_reset(t16); 271 } 272 /* Check for icr overflow in CTC mode */ 273 if (mode == T16_MODE_CTC_ICR && t16->next_interrupt == CAPT) { 274 trace_avr_timer16_interrupt_overflow("CTC ICR"); 275 avr_timer16_clock_reset(t16); 276 if (t16->imsk & T16_INT_IC) { 277 t16->ifr |= T16_INT_IC; 278 qemu_set_irq(t16->capt_irq, 1); 279 } 280 } 281 /* Check for output compare interrupts */ 282 if (t16->imsk & T16_INT_OCA && t16->next_interrupt == COMPA) { 283 t16->ifr |= T16_INT_OCA; 284 qemu_set_irq(t16->compa_irq, 1); 285 } 286 if (t16->imsk & T16_INT_OCB && t16->next_interrupt == COMPB) { 287 t16->ifr |= T16_INT_OCB; 288 qemu_set_irq(t16->compb_irq, 1); 289 } 290 if (t16->imsk & T16_INT_OCC && t16->next_interrupt == COMPC) { 291 t16->ifr |= T16_INT_OCC; 292 qemu_set_irq(t16->compc_irq, 1); 293 } 294 avr_timer16_set_alarm(t16); 295} 296 297static void avr_timer16_reset(DeviceState *dev) 298{ 299 AVRTimer16State *t16 = AVR_TIMER16(dev); 300 301 avr_timer16_clock_reset(t16); 302 avr_timer16_clksrc_update(t16); 303 avr_timer16_set_alarm(t16); 304 305 qemu_set_irq(t16->capt_irq, 0); 306 qemu_set_irq(t16->compa_irq, 0); 307 qemu_set_irq(t16->compb_irq, 0); 308 qemu_set_irq(t16->compc_irq, 0); 309 qemu_set_irq(t16->ovf_irq, 0); 310} 311 312static uint64_t avr_timer16_read(void *opaque, hwaddr offset, unsigned size) 313{ 314 assert(size == 1); 315 AVRTimer16State *t16 = opaque; 316 uint8_t retval = 0; 317 318 switch (offset) { 319 case T16_CRA: 320 retval = t16->cra; 321 break; 322 case T16_CRB: 323 retval = t16->crb; 324 break; 325 case T16_CRC: 326 retval = t16->crc; 327 break; 328 case T16_CNTL: 329 avr_timer16_update_cnt(t16); 330 t16->rtmp = t16->cnth; 331 retval = t16->cntl; 332 break; 333 case T16_CNTH: 334 retval = t16->rtmp; 335 break; 336 case T16_ICRL: 337 /* 338 * The timer copies cnt to icr when the input capture pin changes 339 * state or when the analog comparator has a match. We don't 340 * emulate this behaviour. We do support it's use for defining a 341 * TOP value in T16_MODE_CTC_ICR 342 */ 343 t16->rtmp = t16->icrh; 344 retval = t16->icrl; 345 break; 346 case T16_ICRH: 347 retval = t16->rtmp; 348 break; 349 case T16_OCRAL: 350 retval = t16->ocral; 351 break; 352 case T16_OCRAH: 353 retval = t16->ocrah; 354 break; 355 case T16_OCRBL: 356 retval = t16->ocrbl; 357 break; 358 case T16_OCRBH: 359 retval = t16->ocrbh; 360 break; 361 case T16_OCRCL: 362 retval = t16->ocrcl; 363 break; 364 case T16_OCRCH: 365 retval = t16->ocrch; 366 break; 367 default: 368 break; 369 } 370 trace_avr_timer16_read(offset, retval); 371 372 return (uint64_t)retval; 373} 374 375static void avr_timer16_write(void *opaque, hwaddr offset, 376 uint64_t val64, unsigned size) 377{ 378 assert(size == 1); 379 AVRTimer16State *t16 = opaque; 380 uint8_t val8 = (uint8_t)val64; 381 uint8_t prev_clk_src = CLKSRC(t16); 382 383 trace_avr_timer16_write(offset, val8); 384 385 switch (offset) { 386 case T16_CRA: 387 t16->cra = val8; 388 if (t16->cra & T16_CRA_OC_CONF) { 389 qemu_log_mask(LOG_UNIMP, "%s: output compare pins unsupported\n", 390 __func__); 391 } 392 break; 393 case T16_CRB: 394 t16->crb = val8; 395 if (t16->crb & T16_CRB_ICNC) { 396 qemu_log_mask(LOG_UNIMP, 397 "%s: input capture noise canceller unsupported\n", 398 __func__); 399 } 400 if (t16->crb & T16_CRB_ICES) { 401 qemu_log_mask(LOG_UNIMP, "%s: input capture unsupported\n", 402 __func__); 403 } 404 if (CLKSRC(t16) != prev_clk_src) { 405 avr_timer16_clksrc_update(t16); 406 if (prev_clk_src == T16_CLKSRC_STOPPED) { 407 t16->reset_time_ns = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); 408 } 409 } 410 break; 411 case T16_CRC: 412 t16->crc = val8; 413 qemu_log_mask(LOG_UNIMP, "%s: output compare pins unsupported\n", 414 __func__); 415 break; 416 case T16_CNTL: 417 /* 418 * CNT is the 16-bit counter value, it must be read/written via 419 * a temporary register (rtmp) to make the read/write atomic. 420 */ 421 /* ICR also has this behaviour, and shares rtmp */ 422 /* 423 * Writing CNT blocks compare matches for one clock cycle. 424 * Writing CNT to TOP or to an OCR value (if in use) will 425 * skip the relevant interrupt 426 */ 427 t16->cntl = val8; 428 t16->cnth = t16->rtmp; 429 avr_timer16_recalc_reset_time(t16); 430 break; 431 case T16_CNTH: 432 t16->rtmp = val8; 433 break; 434 case T16_ICRL: 435 /* ICR can only be written in mode T16_MODE_CTC_ICR */ 436 if (MODE(t16) == T16_MODE_CTC_ICR) { 437 t16->icrl = val8; 438 t16->icrh = t16->rtmp; 439 } 440 break; 441 case T16_ICRH: 442 if (MODE(t16) == T16_MODE_CTC_ICR) { 443 t16->rtmp = val8; 444 } 445 break; 446 case T16_OCRAL: 447 /* 448 * OCRn cause the relevant output compare flag to be raised, and 449 * trigger an interrupt, when CNT is equal to the value here 450 */ 451 t16->ocral = val8; 452 break; 453 case T16_OCRAH: 454 t16->ocrah = val8; 455 break; 456 case T16_OCRBL: 457 t16->ocrbl = val8; 458 break; 459 case T16_OCRBH: 460 t16->ocrbh = val8; 461 break; 462 case T16_OCRCL: 463 t16->ocrcl = val8; 464 break; 465 case T16_OCRCH: 466 t16->ocrch = val8; 467 break; 468 default: 469 break; 470 } 471 avr_timer16_set_alarm(t16); 472} 473 474static uint64_t avr_timer16_imsk_read(void *opaque, 475 hwaddr offset, 476 unsigned size) 477{ 478 assert(size == 1); 479 AVRTimer16State *t16 = opaque; 480 trace_avr_timer16_read_imsk(offset ? 0 : t16->imsk); 481 if (offset != 0) { 482 return 0; 483 } 484 return t16->imsk; 485} 486 487static void avr_timer16_imsk_write(void *opaque, hwaddr offset, 488 uint64_t val64, unsigned size) 489{ 490 assert(size == 1); 491 AVRTimer16State *t16 = opaque; 492 trace_avr_timer16_write_imsk(val64); 493 if (offset != 0) { 494 return; 495 } 496 t16->imsk = (uint8_t)val64; 497} 498 499static uint64_t avr_timer16_ifr_read(void *opaque, 500 hwaddr offset, 501 unsigned size) 502{ 503 assert(size == 1); 504 AVRTimer16State *t16 = opaque; 505 trace_avr_timer16_read_ifr(offset ? 0 : t16->ifr); 506 if (offset != 0) { 507 return 0; 508 } 509 return t16->ifr; 510} 511 512static void avr_timer16_ifr_write(void *opaque, hwaddr offset, 513 uint64_t val64, unsigned size) 514{ 515 assert(size == 1); 516 AVRTimer16State *t16 = opaque; 517 trace_avr_timer16_write_imsk(val64); 518 if (offset != 0) { 519 return; 520 } 521 t16->ifr = (uint8_t)val64; 522} 523 524static const MemoryRegionOps avr_timer16_ops = { 525 .read = avr_timer16_read, 526 .write = avr_timer16_write, 527 .endianness = DEVICE_NATIVE_ENDIAN, 528 .impl = {.max_access_size = 1} 529}; 530 531static const MemoryRegionOps avr_timer16_imsk_ops = { 532 .read = avr_timer16_imsk_read, 533 .write = avr_timer16_imsk_write, 534 .endianness = DEVICE_NATIVE_ENDIAN, 535 .impl = {.max_access_size = 1} 536}; 537 538static const MemoryRegionOps avr_timer16_ifr_ops = { 539 .read = avr_timer16_ifr_read, 540 .write = avr_timer16_ifr_write, 541 .endianness = DEVICE_NATIVE_ENDIAN, 542 .impl = {.max_access_size = 1} 543}; 544 545static Property avr_timer16_properties[] = { 546 DEFINE_PROP_UINT8("id", struct AVRTimer16State, id, 0), 547 DEFINE_PROP_UINT64("cpu-frequency-hz", struct AVRTimer16State, 548 cpu_freq_hz, 0), 549 DEFINE_PROP_END_OF_LIST(), 550}; 551 552static void avr_timer16_pr(void *opaque, int irq, int level) 553{ 554 AVRTimer16State *s = AVR_TIMER16(opaque); 555 556 s->enabled = !level; 557 558 if (!s->enabled) { 559 avr_timer16_reset(DEVICE(s)); 560 } 561} 562 563static void avr_timer16_init(Object *obj) 564{ 565 AVRTimer16State *s = AVR_TIMER16(obj); 566 567 sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->capt_irq); 568 sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->compa_irq); 569 sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->compb_irq); 570 sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->compc_irq); 571 sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->ovf_irq); 572 573 memory_region_init_io(&s->iomem, obj, &avr_timer16_ops, 574 s, "avr-timer16", 0xe); 575 memory_region_init_io(&s->imsk_iomem, obj, &avr_timer16_imsk_ops, 576 s, "avr-timer16-intmask", 0x1); 577 memory_region_init_io(&s->ifr_iomem, obj, &avr_timer16_ifr_ops, 578 s, "avr-timer16-intflag", 0x1); 579 580 sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->iomem); 581 sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->imsk_iomem); 582 sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->ifr_iomem); 583 qdev_init_gpio_in(DEVICE(s), avr_timer16_pr, 1); 584} 585 586static void avr_timer16_realize(DeviceState *dev, Error **errp) 587{ 588 AVRTimer16State *s = AVR_TIMER16(dev); 589 590 if (s->cpu_freq_hz == 0) { 591 error_setg(errp, "AVR timer16: cpu-frequency-hz property must be set"); 592 return; 593 } 594 595 s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, avr_timer16_interrupt, s); 596 s->enabled = true; 597} 598 599static void avr_timer16_class_init(ObjectClass *klass, void *data) 600{ 601 DeviceClass *dc = DEVICE_CLASS(klass); 602 603 dc->reset = avr_timer16_reset; 604 dc->realize = avr_timer16_realize; 605 device_class_set_props(dc, avr_timer16_properties); 606} 607 608static const TypeInfo avr_timer16_info = { 609 .name = TYPE_AVR_TIMER16, 610 .parent = TYPE_SYS_BUS_DEVICE, 611 .instance_size = sizeof(AVRTimer16State), 612 .instance_init = avr_timer16_init, 613 .class_init = avr_timer16_class_init, 614}; 615 616static void avr_timer16_register_types(void) 617{ 618 type_register_static(&avr_timer16_info); 619} 620 621type_init(avr_timer16_register_types)