Trouble with Async Timer setup

Go To Last Post
10 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi Everyone,

 

I'm having trouble getting my Asynchronous timer working on my ATMEGA328p. I've had this code working before, but now I'm finding that it's getting stuck on waiting for the various "busy" register bits to clear. My understanding (from the datasheet) is that the TC2UB2, TCR2BUB, and OCR2BUB are all cleared by hardware when the registers are done being written to, but it's just hanging on for reasons I can't figure. Is there anything wrong with my setup here? Is there something that might be blocking it in my circuit?

void setupRTC() {
  //Timer2 Async setup.

  //clear interrupt flags
  TIMSK2 |= ((1 << TOIE2) | (1 << OCIE2B));

  //enable async clock
  ASSR |= (1 << AS2);

  //Set Timer2 Prescaler to 128
  TCCR2B |= (1 << CS22) | (1 << CS20); 

  // Write new starting value for TCNT2, and OCR2B;
  TCNT2 = 0;
  OCR2B = 0;
  //wait for async registers to start up
  while(ASSR & ((1 << TCN2UB) | (1 << TCR2BUB) | (1 << OCR2BUB)))
  {
    // printBinaryByte(ASSR);
    // printString("|");
    // printBinaryByte((1 << TCN2UB) | (1 << TCR2BUB) | (1 << OCR2BUB));
    // printString("\n");
  }

  //clear interrupt flag on timer2
  TIFR2 = (1 << TOV2);

  TIMSK2 = (1 << TOIE2);

  //enable global interrupts
  sei();  
}

The printString and printBinaryByte are helper methods from Elliot Williams "Make:AVR" while they're commented out here, I've used them to find the problem, and debug in general.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Have used M329P a lot,  but never those bits. I use Timer2 as a simple async down-counter to generate clock ticks so I never pay attention to those bits.

 

I wonder if the timer needs to be running asynchronously for those to operate correctly? I think you have it set up that way, but ...

 

I also wonder whether or not there is just one "temporary register" and that you need to write one, and wait until its UpdateBusy bit is cleared, then write the next, and wait for that one to clear, and so forth. Just a guess.

 

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well, I think I've found one error in my code. I had written this:

 TIMSK2 |= ((1 << TOIE2) | (1 << OCIE2B));

But the data sheet says that these bits (interrupt mask bits) need to be cleared. I think I had misunderstood them to be like the TIFR (Timer Interrupt Flag Register) where you set them to clear them. Following the example code from AVR134 , I was missing a ~, to NOT the values against TIMSK2. That said, it had been working up until that point, and it's not clear why it stopped. The fixed code looks like this:

  TIMSK2 &= ~((1 << TOIE2) | (1 << OCIE2A) | (1 << OCIE2B));

 

So I fixed that but no change in the running program. It was still stuck on the while loop waiting for the busy bits to be updated. I added a Macro into my code to check register values:

#define OUT(VAR) printString(#VAR);\
printBinaryByte((VAR));\
printString("\n");\

and put it after setting the AS2 bit on ASSR and now it's working again, but I don't really know why. I don't feel like the Macro is associated with the fix. I can remove the NOT operator from the TIMSK2 setting with no change in the (now working) program.

I'm glad the program's working now, but it bothers me that I don't know the source of the problem, nor how to fix it in the future.

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you for the suggestions Jim. I tried writing the bits to the register independently and waiting for each one, without any change. It just gets stuck on the first one.

Per your first thought, The data sheet does state:

When writing to one of the registers TCNT2, OCR2x, or TCCR2x, the value is transferred to a temporary register, and latched after two positive edges on TOSC1. The user should not write a new value before the contents of the temporary register have been transferred to its destination.

Which makes me wonder if something is wrong with my crystal setup - that is, the AS2 bit is being set, but the async clock isn't doing those two cycles for some reason. The crystal I have seems fine (Though I haven't tested it on a scope)

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That strongly suggests two things: (1) that you should write each one and wait for that one to complete before doing the next and (2) the crystal oscillator may not be running.

 

I missed that reference. It says a lot more about what the underlying hardware actually does.

 

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

My circuit is back to not working. I'm having a hard time understanding where it's failing.

 

It looks like I was wrong about the single register (Page 151 of the ATMega328P):

When writing to one of the registers TCNT2, OCR2x, or TCCR2x, the value is transferred to a temporary register, and latched after two positive edges on TOSC1. The user should not write a new value before the contents of the temporary register have been transferred to its destination. Each of the five mentioned registers have their individual temporary register, which means that e.g. writing to TCNT2 does not disturb an OCR2x write in progress. To detect that a transfer to the destination register has taken place, the Asynchronous Status Register – ASSR has been implemented.

Something is preventing the Busy bits from being updated. My first suspicion was the Crystal itself. As mentioned above, the registers are updated from the temporary registers after 2 positive edges on TOSC1, so maybe my Crystal is bad... I tried 3 crystals (32.768Khz, 12.5pF) None of them worked.

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Do you have a way (oscilloscope, for example) to detect a clock signal at the oscillator output pin?

 

What happens if you set the timer overflow to change an output pin without writing to those registers you are waiting for. Is there a signal on the output (at half the overflow rate)? That should tell you if the timer is being clocked. Maybe do it in overflow interrupt and just toggle an arbitrary pin.

 

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

Last Edited: Tue. Jan 2, 2018 - 06:10 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I tried connecting the TOSC2 pin to my Oscope last night, and did not see a signal like I expected. Looking at the data sheet, it appears I need 8pF and 18pF capacitors on the TOSC pins with a watch Crystal attached. I wonder if the capacitance has been "just right" occasionally to make it work, but it won't now. Does that seem reasonable? AVR134 (written for the ATMEGA128) states that it doesn't need any other discrete components, but other devices might. This may be a silly question, but are the capacitors critical to operation of the Async timer?

 

I can try the overflow suggestion tonight.

Last Edited: Wed. Jan 3, 2018 - 07:37 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

sircastor wrote:
but are the capacitors critical to operation of the Async timer?

It depends on your watch crystal [IME].

 

We have several apps in that model family without caps on 32kHz crystal.

 

See e.g. app note 512 and others with similar information to below.  How do your specs add up?

...

 

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks Theusch,

 

Your positing on the app note and data sheets made me go check the crystal I was using and found that it was out of spec. My 12.5pF Load Capacitance Crystal has a max ESR of 35kOhm. That may explain why it might work sometimes and not others (though I really can't say if that's the case.) Additionally, with a 12.5pf LC, I need capacitors on the TOSC pins. If my math is right, they should be 7pF and 17pF.

C = 2 * Cl - Cs

C = 2 * 12.5 - 18 = 25 -18 = 7

C = 2 * 12.5 - 8 = 25 - 7 = 17
 

The only thing that's not obvious here to me is that the datasheet says that Cs "is the total stray capacitance for one TOSC pin".  I'm assuming the stray capacitance is the load capacitance for the pin listed on the sheet. If it's not, I don't really know how to determine that value.

 

Another way of looking at it though: If I go with a 6pF LC or smaller crystal, I can skip the capacitors altogether.

 

A question on all of this though: This section of the data sheet is written towards using the Crystal as the system clock by selecting the Low-Frequency Crystal Oscillator. Does it apply to my use of using the Asynchronous mode of Timer2?

 

To your question of whether or not the timer is overflowing Jim, I'm pretty sure it's failing to run. Even if I drop waiting for the busy bits to clear, I never receive any notification of the ISR overflow occurring - I have a serial message in there that should be sent when it happens. Likewise, my PORTB and PORTC get updated on every overflow - I will grant that I haven't cut it down to something as simple as toggling the port or pin.