What PWM mode to select and how?

Here is a guide how to include images: http://forum.arduino.cc/index.php?topic=519037.0

I am still confused. You say you are trying to decode data from DataIn signal but it seems you are trying to generate the CLK signal. Both makes sense because the chip you use has option to use external clock input instead of internal PLL and you claim the PLL is not working for some reason.

To decode the signal you cannot use the Timer alone, it needs a lot of help from software. To do so you will use the Timer “only” as a time reference but rest must be done in SW. There are more possibilities how to read the signal.

  1. Use a Timer to generate an interrupt in regular intervals. In ISR you read the DataIn signal, store the value and when you get a sample long enough you analyze it somehow. I think it is poor method but if the signal is noisy you may implement some noise filtering this way easily.
  2. Use a Pin Change interrupt on DataIn pin. When interrupt triggers read value in TCNTn and store it. By subtracting TCNTn value saved in last interrupt you can say how long it took for the signal to change level - if it was long time decoded value is 1, otherwise it is 0.
  3. Use Input Capture feature of Timer1. It works as 2) but you read ICR1 instead of TNCT1. Advantage is you avoid jitter from interrupt latency but not all AVRs have timer with this feature.

Since I believe method 3) is superior I will show you how I would do it. You must use Timer1 for it and apply DataIn on ICP1 pin (PB0 of ATMega328, Digital 8 of Arduino Uno). You want to measure time between two edges of the DataIn signal, the time should be between 16 or 32 CLK pulses. If CLK is about 125kHz it means one CLK pulse is about 16MHz/125kHz=128 Arduino clock cycles. You have two options
a) Clock the Timer1 from main clock prescaled down to some reasonable value, prescaler 256 (CS=4) is a good choice, Timer1 frequency will be 16MHz/256=62.5 kHz (about half of frequency of CLK). One edge to edge interval will be about 8 or 16 Timer1 ticks.
b) Clock the Timer1 from CLK (CLK = 6 or 7, I don’t think it does matter). In this case Timer1 frequency will be exactly CLK frequency and one edge to edge interval should take 16 or 32 Timer1 ticks. Downside is you need use pin T1 (PD5, Digital 5) as clock input for Timer1.
I think a) is better in many ways. In either case time between two events should be < 50 Timer1 ticks. Because of this it is better to use Timer1 as 8 bit timer - reducing associated values to single byte will make calculations faster. Fast PWM 8-bit mode (WGM1=5) can be used for this.
I think you need detect both rising and falling edge of DataIn. So you will enable Timer1 Capture Event interrupt and in the ISR you toggle Input Capture Edge Select bit. The code for this could be

ISR(TIMER1_CAPT_VECT) {
  TCCR1B^=1<<ICES1;
  static byte lastEdge;
  byte thisEdge=ICR1;
  byte difference=lastEdge - thisEdge;
  if (difference < someBoundary) TODO
  else TODO
  lastEdge=thisEdge;
}

setup () {
  TCCR1A=1<<WGM10;
  TCCR1B=(1<<ICNC1)|(1<<WGM12)|(1<<CS12);
  TIMSK1=1<<ICIE1;
}

Thank you so much for the clarification. I will definitely try them out and keep you posted of the progress.

Hey Smajdalf, I was revisiting this post. What's the boundary condition in the ISR?

Also the lastEdge, thisEdge - what are these values? Timer count values?

Best, A

Hey Smajdalf,

I am reaching out to see if you could help me out. Should I define the ICR1 as top in setup?

I don't remember what was going on in this topic but after a quick refresh: thisEdge and lastEdge are "remembered" values of Timer1 at the time of captured edge. lastEdge - thisEdge is time (in Timer1 ticks) of duration of the pulse. Depending on the time you want to do some action - it is up to you to decide what the action should be and what is the boundary. TOP of the timer must NOT be ICR1. The TOP should be a fixed value: 0xff if using the timer only in 8 bit mode (to make the calculations faster). Maybe using it in 16 bit mode with 0xffff to would be better (less chance for some strange overflow bug). In this case thisEdge, lastEdge and all related variables should be unsigned int instead of byte.