Output system clock ATTinyx4

With the ATTinyx4 the system clock can be output on PB2 - but I can't figure out how to enable/disable it (note that I want to be able to turn it on and off in code).

Thanks!

You need to use a Programmer (that access the SPI pins) to set a fuse to output the system clock. Doesn't look to be sketch controllable:
6.4 Clock Output Buffer
The device can output the system clock on the CKOUT pin. To enable the output, the CKOUT
fuse has to be programmed. This mode is suitable when the chip clock is used to drive other circuits
on the system. Note that the clock will not be output during reset and that the normal
operation of the I/O pin will be overridden when the fuse is programmed. Any clock source,
including the internal RC Oscillator, can be selected when the clock is output on CKOUT. If the
System Clock Prescaler is used, it is the divided system clock that is output.

Thanks CrossRoads.

I think it is possible to do this within a sketch though, as well as setting in permanently via the fuses. I've been able to turn it on using this code:

void setup() {
    TCCR0A = 0; //reset timer1 configuration
    TCCR0B = 0;

    TCCR0A |= _BV(COM0B1);  //Clear OC0B on Compare Match when up-counting. Set OC0B on Compare Match when down-counting.
    TCCR0A |= _BV(WGM00);   //PWM, Phase Correct, 8-bit 
    TCCR0B |= _BV(CS00);    //start timer
  
    DDRB |= _BV(PB2);   //sqare wave output
    PORTB &= ~_BV(PB2);

    CLKPR = _BV(CLKPCE);
    CLKPR = _BV(CLKPS1); //clock speed = clk/4 = 2Mhz
}

void startClock() {
  TCCR0A = _BV(COM0A0) |  //Toggle OC0A on Compare Match
      _BV(WGM01);
}

Calling startClock() will start outputting the expected 1MHz square wave... but I can't stop it.

The best you can get fromnoutput compare on a timer is 1/2 the system clock (except on a tiny85/861, which can run timer1 at 64mhz, hence output 32mhz)

Thanks DrAzzy, that's what I'm doing with the following code, it outputs half the system clock on PB2. But as I said, I can't make it stop. The startClock() function gets it going, but the stopClock() doesn't. It's odd because surely TCCR0A = 0; and TCCR0B = 0; should reset the timer status... but on the scope I can see the output continues. Any thoughts?

void setup() {
    TCCR0A = 0; //reset timer1 configuration
    TCCR0B = 0;

    TCCR0A |= _BV(COM0B1);  //Clear OC0B on Compare Match when up-counting. Set OC0B on Compare Match when down-counting.
    TCCR0A |= _BV(WGM00);   //PWM, Phase Correct, 8-bit 
    TCCR0B |= _BV(CS00);    //start timer
  
    DDRB |= _BV(PB2);   //sqare wave output
    PORTB &= ~_BV(PB2);
}

void loop() {
  delay(100000);
  startExcitationSignal();
  delay(100000);
  stopExcitationSignal();
  delay(100000);
}

void startClock() {
  TCCR0A = _BV(COM0A0) |  //Toggle OC0A on Compare Match
      _BV(WGM01);
}

void stopClock() {  
  TCCR0A = 0;
  TCCR0B = 0;
}

Show minimal (non-)working code. The code in your last post shows only parts of the code. The bug is likely hidden in the parts you did not show.

Indeed. My guess is either stopExcitationSignal(); isn't calling stopClock(), or startExcitationSignal() is barfing some time after calling startClock() and code execution isn't getting out of there.

I had actually missed that the functions you call are start/stopExcitationSignal, while the functions shown are start/stopClock...

This is why you should NEVER POST SNIPPETS. The very fact that you need to ask for help instead of knowing how to fix it yourself is evidence enough that you can't rely on your ability to recognize where the problem is. I would say >90% of the time, when someone posts only part of a sketch, the problem isn't in the part they posted.

You're right that I had made a small mistake in the code I posted, that's because I originally got this working bit from an old open source project - however this is the complete code. I had changed the names from 'ExcitationSignal' to 'Clock'. Anyhow, this is the verbatim copy from my source:

There is no other code, no other functions, this is my proof of concept - or lack of...

void setup() {
    TCCR0A = 0; //reset timer1 configuration
    TCCR0B = 0;

    TCCR0A |= _BV(COM0B1);  //Clear OC0B on Compare Match when up-counting. Set OC0B on Compare Match when down-counting.
    TCCR0A |= _BV(WGM00);   //PWM, Phase Correct, 8-bit 
    TCCR0B |= _BV(CS00);    //start timer
  
    DDRB |= _BV(PB2);   //sqare wave output
    PORTB &= ~_BV(PB2);
}

void loop() {
  delay(100000);
  startClock();
  delay(100000);
  stopClock();
  delay(100000);
}

void startClock() {
  TCCR0A = _BV(COM0A0) |  //Toggle OC0A on Compare Match
      _BV(WGM01);
}

void stopClock() {  
  TCCR0A = 0;
  TCCR0B = 0;
}

Oh! I should have spotted that sooner.

You're reconfiguring timer0, and then trying to use delay().

Timer0 is used for delay, millis, and micros, and if you reconfigure it, these timing functions won't work any more (in your case, they never increment at all).

Use Timer1, and leave timer0 untouched so it can be used for the builtin timing functions.

Bingo! Thanks DrAzzy.

I knew that millis() would be out (hence my very long delays), but I didn't figure out that that it wouldn't increment at all - in hindsight, I should have.

Thanks a lot for the help!