cancel
Showing results for 
Search instead for 
Did you mean: 

AN1753 - output compare mode for periodic delays - cannot work?!

jkn_stforum
Associate II
Posted on January 09, 2007 at 15:31

AN1753 - output compare mode for periodic delays - cannot work?!

3 REPLIES 3
jkn_stforum
Associate II
Posted on December 29, 2006 at 12:55

Hello everybody

I've been trying to get a software UART running using the 12-bit auto-reload counter, in a similar way to AN1753. That is written for an ST7FLITE0. I'm using an ST7FLITE29, which is very similar in this area.

I've seen in this forum that other people have had a lot of trouble with the output compare mode on this timer. I've read as many of those threads as I can find, and I've stripped down an assembly-language program until only the absolute basics are there.

I'm now at the point when I'm very suspicious that the method in this appnote can actually work. I will explain what I see and why I think this is wrong.

For Serial comms we require a periodic interrupt at the period of the bit rate. for instance, 417uSec for 2400 baud.

In output compare mode, with the Autoreload counter reload value set to zero, the counter will count up from zero until the value of the counter (CTR) equals the value of the Duty Cycle Register (DCRx). At that point a Output Compare Interrupt is generated.

The idea for this application is that the OPCMP interrupt does the work to put the next bit on the wire, and then sets up the next interrupt to occur after a delay equal to the required bit period. The algorithm in the app note does this by adding the period to the DCR registers.

But because these values are not transferred immediately to the actual registers, I don't think this can work.

Let's use some real values. I want a bit period of 1.5mSec @1MHz clock. So I set DCRx to be 1500.

- the counter counts from zero to 1500, and I get an OPCMP interrupt.

- my Interrupt handler does what it needs to to put my bit on the output pin.

- I now want to be interrupted again in 1.5msec. So I calculate DCR_new = DCR_current + 1500

- I store this new value in the DCR registers. Remember to set the TRANCR bit...

But this won't work! Because the new value of 1500+1500 = 3000, is less than the overflow count of 4095. And the new value of DRC will only be updated after an overflow. So the period I will get is

(time from now to overflow) + (time from zero to new value in DCRx)

= (4095-1500) + 3000

ie, the period will be 4095 counts late. The CTR will pass the value of 3000 without an interrupt because the DCR registers have not yet been loaded. This will occur each time the sum (DCR_new = DCR_old + delay) does not wrap round the overflow value.

Unless there is a way to immediately load the *actual* DCR registers from the Preload registers that we have access to (DCRxH, DCRxL), I don't see how this application note can work.

This also describes what I am seeing, and other messages in this forum when people have tried to get Output Compare mode to work.

Am I missing something? Has anyone actually got this to work? Is there a better way?

Thanks for your thoughts

jon N

pjr
Associate II
Posted on January 03, 2007 at 12:51

Jon,

While I have not worked with the FLITE group of processors I have implemented the code from AN1046 on a ST72F264. It employs a method similar to AN1753 and works well.

We would need to see your version of the code to be specific about why it is not working for you.

The following comments are my interpertations of the FLITE0 & FLITE29 datasheets only. Again I have not directly worked with the processors.

The TRANCR and loading of the DCRx registers into the shadow register are only applicable to the PWM function. For output capture they are not important. This is not really shown in the FLITE29 datasheet figure 34. From the description ( and appnote code ) I think the functionality is really more like what is shown in the ST7FLITE0x datasheet figure 33. Either the DCR0 pre-load register(s) or the shadow register(s) are used depending on the setting of the TRAN bit in TRANCR ( or maybe the enable of that pwm channel in PWMCR ).

The appnote uses DCR0 but I guess any of the four would work.

With the compare function ( pwm not enabled ) the DCR0 registers are directly used for the comparision, not the shadow resister ( which is loaded on overflow ).

When CNTR ( 12 bit auto-reload counter ) is equal to the value stored into the DCR0 registers, CMPF0 is set and an interrupt is generated. CNTR continues to increment.

The appnote isr for CMPF0 disables interrupts, adds the appropriate bit ( or half bit ) time values to the DCR0 registers, loads DCR0 with these new values and re-enables interrupts. Now when CNTR ( which has been continually incrementing ) equals the new value in DCR0 another interrupt will be generated. etc... Time for the next bit processing.

pjr

jkn_stforum
Associate II
Posted on January 09, 2007 at 15:31

Hi pjr

Thanks for your reply. I have since spoken to a ST expert and he has confirmed that my understanding of the modes is correct; the functionality has changed (you might argue for the worse ;-( ) from the FLITE0 to the FLITE 15 and FLITE29, which I am using. The update of the DCR 'preload' registers only occurs at overflow time.

There now exist 'B' versions of these devices (ST7FLITE15B and ST7FLITE19B) which have added a 'force' bit to the ATR timer. This bit makes the DCR preload registers load into the real registers immediately. I guess this is an acknowledgement from ST that there is a problem...

Since I am currently stuck with my current CPUs, I have had to compromise. On the transmit side, where the timing is constant and known, I have used the overflow interrupt, and set the reload value to (4096 - delayperiod). This gives me regular interrupts which I can use to step through the sequence of tranmitting a byte.

On the receive side I have had to use the LT2 timer. The problem then becomes how to synchronise the timer with the first transition - the start bit. I used a clever trick from 'EtaPhi' in this forum; I set the reload value to 0xff, with interrupts off. This means that the counter 'spins' at 0xff. With a bit of clever programming you can then update the ATR value for the next interrupt and expect only a minimal amount of 'jitter' to be present.

If you're interested in this, I recommend searching for the post 'I must reload IMMEDIATELY LTCSR2: can I?' in the ST7 forum. There is some code attached; it's commented in Italian but I was mostly able to work out what was happening.

Cheers

Jon N