source: buchla-emu/emu/tim.c@ 9e0cd12

Last change on this file since 9e0cd12 was 9e0cd12, checked in by Thomas Lopatic <thomas@…>, 7 years ago

Code review.

  • Property mode set to 100644
File size: 3.2 KB
Line 
1/*
2 * Copyright (C) 2017 The Contributors
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or (at
7 * your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * A copy of the GNU General Public License can be found in the file
15 * "gpl.txt" in the top directory of this repository.
16 */
17
18#include <all.h>
19
20#define ver(...) _ver(tim_verbose, 0, __VA_ARGS__)
21#define ver2(...) _ver(tim_verbose, 1, __VA_ARGS__)
22#define ver3(...) _ver(tim_verbose, 2, __VA_ARGS__)
23
24int32_t tim_verbose = 0;
25
26#define REG_CRX 0
27#define REG_CR2 1
28#define REG_T1H 2
29#define REG_T1L 3
30#define REG_T2H 4
31#define REG_T2L 5
32#define REG_T3H 6
33#define REG_T3L 7
34
35#define COUNT_1 32
36#define COUNT_2 3200
37#define COUNT_3 801
38
39typedef struct {
40 bool irq_e;
41 bool irq;
42 int32_t latch;
43 int32_t count;
44} state_timer;
45
46static state_timer timers[] = {
47 { .irq_e = false, .irq = false, .latch = COUNT_1, .count = COUNT_1 },
48 { .irq_e = false, .irq = false, .latch = COUNT_2, .count = COUNT_2 },
49 { .irq_e = false, .irq = false, .latch = COUNT_3, .count = COUNT_3 }
50};
51
52static bool wr_cr1 = false;
53static bool oper = false;
54
55void tim_init(void)
56{
57 ver("tim init");
58}
59
60void tim_quit(void)
61{
62 ver("tim quit");
63}
64
65bool tim_exec(void)
66{
67 if (oper) {
68 for (int32_t i = 0; i < ARRAY_COUNT(timers); ++i) {
69 --timers[i].count;
70
71 if (timers[i].count == 0) {
72 ver2("tim %d zero", i + 1);
73 timers[i].count = timers[i].latch;
74
75 if (timers[i].irq_e) {
76 ver2("tim %d irq", i + 1);
77 timers[i].irq = true;
78 }
79 }
80 }
81 }
82
83 return timers[0].irq || timers[1].irq || timers[2].irq;
84}
85
86uint32_t tim_read(uint32_t off, int32_t sz)
87{
88 ver2("tim rd %u:%d", off, sz * 8);
89
90 if (sz != 1 || off > 7) {
91 fail("invalid tim rd %u:%d", off, sz * 8);
92 }
93
94 uint32_t rv = 0x00;
95
96 switch (off) {
97 case REG_CR2:
98 rv |= (uint32_t)timers[0].irq << 0;
99 rv |= (uint32_t)timers[1].irq << 1;
100 rv |= (uint32_t)timers[2].irq << 2;
101
102 ver2("tim irqs %u %u %u",
103 (uint32_t)timers[0].irq, (uint32_t)timers[1].irq, (uint32_t)timers[2].irq);
104 break;
105
106 case REG_T1L:
107 if (timers[0].irq) {
108 ver2("tim 1 !irq");
109 timers[0].irq = false;
110 }
111
112 break;
113
114 case REG_T2L:
115 if (timers[1].irq) {
116 ver2("tim 2 !irq");
117 timers[1].irq = false;
118 }
119
120 break;
121
122 case REG_T3L:
123 if (timers[2].irq) {
124 ver2("tim 3 !irq");
125 timers[2].irq = false;
126 }
127
128 break;
129
130 default:
131 break;
132 }
133
134 return rv;
135}
136
137void tim_write(uint32_t off, int32_t sz, uint32_t val)
138{
139 ver2("tim wr %u:%d 0x%0*x", off, sz * 8, sz * 2, val);
140
141 if (sz != 1 || off > 7) {
142 fail("invalid tim wr %u:%d", off, sz * 8);
143 }
144
145 switch (off) {
146 case REG_CRX:
147 if (wr_cr1) {
148 if ((val & 0x01) == 0) {
149 ver2("tim start");
150 oper = true;
151 }
152
153 timers[0].irq_e = (val & 0x40) != 0;
154 }
155 else {
156 timers[2].irq_e = (val & 0x40) != 0;
157 }
158
159 break;
160
161 case REG_CR2:
162 wr_cr1 = (val & 0x01) != 0;
163 timers[1].irq_e = (val & 0x40) != 0;
164 break;
165
166 default:
167 break;
168 }
169}
Note: See TracBrowser for help on using the repository browser.