4 #include "ImplementationException.h"
7 bit_CS0
= 0, /* timer/counter clock select bit 0 */
13 mask_CS0
= 1 << bit_CS0
,
14 mask_CS1
= 1 << bit_CS1
,
15 mask_CS2
= 1 << bit_CS2
,
16 mask_CS
= (mask_CS0
| mask_CS1
| mask_CS2
),
20 CS_STOP
= 0x00, /* Stop, the Timer/Counter is stopped */
21 CS_CK
= 0x01, /* CK */
22 CS_CK_8
= 0x02, /* CK/8 */
23 CS_CK_64
= 0x03, /* CK/64 */
24 CS_CK_256
= 0x04, /* CK/256 */
25 CS_CK_1024
= 0x05, /* CK/1024 */
26 CS_EXT_FALL
= 0x06, /* External Pin Tn, falling edge */
27 CS_EXT_RISE
= 0x07, /* External Pin Tn, rising edge */
44 mask_WGM
= (WGM1
|WGM0
),
45 mask_COM
= (COM1
|COM0
),
52 MODE_FASTPWM
= (WGM0
|WGM1
)
64 #define overflow() *tifr |= tovmask
65 #define compareMatch() *tifr |= ocfmask
67 bool Timer8::attachReg(const char *name
, IORegister
*reg
) {
68 if( strcmp(name
, "tcnt") == 0 ) {
70 reg
->registerHW(this);
71 } else if( strcmp(name
, "tccr") == 0 ) {
73 reg
->registerHW(this);
74 } else if( strcmp(name
, "ocr") == 0 ) {
76 reg
->registerHW(this);
77 } else if( strcmp(name
, "tifr") == 0 )
85 void Timer8::regChanged( IORegister
*reg
) {
87 unsigned char val
= tccr
->get();
90 unsigned char timerModeNew
= val
& mask_WGM
;
91 if( timerMode
!= timerModeNew
)
93 timerMode
= timerModeNew
;
95 compareMode
= val
& mask_COM
;
99 } else if( reg
== tcnt
) {
100 blockCompareMatch
= true;
101 } else if( reg
== ocr
) {
102 if( (timerMode
== MODE_NORMAL
) || (timerMode
== MODE_CTC
) )
107 void Timer8::setClock(unsigned char tccr
) {
108 byte clk
= tccr
& mask_CS
;
111 bus
.clearBreak(this);
136 throw util::ImplementationException(
137 "external timer/counter sources not implemented" );
140 bus
.setBreakDelta(period
, this);
143 void Timer8::forceOutputCompare() {
144 compareMatchOutput( tcnt
->get() );
147 void Timer8::compareMatchOutput(unsigned char tcnt
) {
148 // the non-PWM modes are NORMAL and CTC
149 // under NORMAL, there is no pin action for a compare match
150 // under CTC, the action is to clear the pin.
151 if( tcnt
== ocrBuf
) {
152 switch( compareMode
) {
157 //outputComparePin.toggle();
161 //outputComparePin.low();
165 //outputComparePin.high();
176 void Timer8::step() {
177 byte tcntVal
= tcnt
->get();
178 byte tcntSave
= tcntVal
;
181 switch( timerMode
) {
183 if( tcntVal
== TOP
) {
190 if( tcntVal
== ocrBuf
) {
197 if( (tcntVal
== TOP
) && (direction
== +1) ) {
200 } else if( (tcntVal
== BOTTOM
) && (direction
== -1) ) {
207 if( tcntVal
== TOP
) {
217 tcntVal
+= direction
;
219 if( ! blockCompareMatch
)
220 compareMatchOutput(tcntSave
);
221 blockCompareMatch
= false;
223 tcnt
->set( tcntVal
);
224 bus
.setBreakDelta(period
, this);