CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Output compare not working when timer prescaler not 1

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
dluu13



Joined: 28 Sep 2018
Posts: 395
Location: Toronto, ON

View user's profile Send private message Visit poster's website

Output compare not working when timer prescaler not 1
PostPosted: Tue Feb 05, 2019 10:20 am     Reply with quote

Hi, I am having a problem with the output compare module on a
PIC24FJ128GA308 with compiler version 5.082.

When the timer source of the OC module has a prescaler of anything
other than 1, the OC pin does not pulse as I expect it to.

Here is my code:

Code:
#include <24FJ128GA308.h>
#DEVICE ADC=12
#case

#FUSES ICSP1, NOJTAG, NODEBUG, NOWRT, NOPROTECT, WPDIS, NOWPCFG
#FUSES NOBROWNOUT, NODSBOR, NOVBATBOR
#FUSES NOLVR, NOIOL1WAY, VREFNORM_CVREFNORM, NOIESO
#FUSES NOWDT
#FUSES FRC_PLL, NOOSCIO

#use delay(clock=32MHz)

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

#pin_select OC1=PIN_G6
#pin_select T4CK=PIN_E8

#word CLKDIV=getenv("SFR:CLKDIV")
struct
{
    unsigned : 8;
    unsigned RCDIV : 3;
    unsigned DOZEN : 1;
    unsigned DOZE : 3;
    unsigned ROI : 1;
} CLKDIVbits;
#word CLKDIVbits=CLKDIV

int main(void)
{
    CLKDIVbits.RCDIV = 0; // sets oscillator divider to 0

    setup_timer4(TMR_EXTERNAL | TMR_DIV_BY_1, 1);

/****************** PROBLEM IS HERE ******************/   
//    setup_timer5(TMR_INTERNAL | TMR_DIV_BY_1); // works
     setup_timer5(TMR_INTERNAL | TMR_DIV_BY_8); // does not work
   
    setup_compare(1, COMPARE_SINGLE_PULSE | COMPARE_TIMER5 | COMPARE_TRIGGER | COMPARE_TRIG_SYNC_TIMER4);
    set_compare_time(1, 200, 400);

    enable_interrupts(INTR_GLOBAL);
    enable_interrupts(INT_OC1);
    enable_interrupts(INTR_CN_PIN | PIN_E1);
   
    output_high(PIN_E2); // LED

   while(1)
   {

   }
   return 0;
}

#INT_OC1

void oc1_isr()
{
    setup_compare(1, COMPARE_SINGLE_PULSE | COMPARE_TIMER5 | COMPARE_TRIGGER | COMPARE_TRIG_SYNC_TIMER4);
    output_toggle(PIN_E2); // toggle my LED to show ISR is ran
}

#INT_CNI

void cni_isr() // gets triggered every time there is a change. this is the clock source to output into TMRCLK
{
    output_high(PIN_E7); // connect timer pulse to timer clk in
    output_low(PIN_E7);
    output_high(PIN_E7);
    output_low(PIN_E7);
}


What I am doing is using Timer 4 as a trigger source to the OC module,
by using a button hooked up as the clock source to Timer 4. Note that in
my circuit, I have shorted PIN_E7 to PIN_E8. I don't see anything wrong
in the errata of the chip. When I look at the LST file, the only difference in
setting for the timer 5 control register between prescaler 1 and 8 setting is
at the TCKPS bits, as expected.

I can set Timer 4 to run from an internal source, and it will behave the
same way. I have also tried to use different timers and OC modules, with
the same result.

Do you guys have any idea? Let me know if you want me to try anything.

I have done this exact configuration on the PIC24FJ128GA204 Curiosity
Dev board from Microchip with no problems.

Thanks in advance!


Last edited by dluu13 on Tue Feb 05, 2019 1:16 pm; edited 1 time in total
PrinceNai



Joined: 31 Oct 2016
Posts: 452
Location: Montenegro

View user's profile Send private message

PostPosted: Tue Feb 05, 2019 11:19 am     Reply with quote

Dear dluu,

for the price of being really stupid, I really don't have any experience with those chips. I don't get it exactly where are you pulsing the OC1 pin in your code? If you have anything on E7, isn't this a bit too fast to be visible at 32MHz?
Quote:

{
output_high(PIN_E7); // connect timer pulse to timer clk in
output_low(PIN_E7);
output_high(PIN_E7);
output_low(PIN_E7);
}

Not an answer, I know. I just ask for an explanation.
Regards,
Samo
dluu13



Joined: 28 Sep 2018
Posts: 395
Location: Toronto, ON

View user's profile Send private message Visit poster's website

PostPosted: Tue Feb 05, 2019 11:22 am     Reply with quote

PrinceNai wrote:
Dear dluu,

for the price of being really stupid, I really don't have any experience with those chips. I don't get it exactly where are you pulsing the OC1 pin in your code? If you have anything on E7, isn't this a bit too fast to be visible at 32MHz?
Quote:

{
output_high(PIN_E7); // connect timer pulse to timer clk in
output_low(PIN_E7);
output_high(PIN_E7);
output_low(PIN_E7);
}

Not an answer, I know. I just ask for an explanation.
Regards,
Samo


No problem, this is really a very convoluted workaround... Unfortunately,
the OC module on this chip doesn't have a dedicated trigger pin, but I can
trigger from timer. Basically what I am doing is when I receive CN
interrupt from my button, I pulse PIN_E7 as a clock source to Timer4
which will cause it to overflow and trigger the CCP module.

The OC1 pulsing comes from the set_compare_time earlier on in the
setup.
PrinceNai



Joined: 31 Oct 2016
Posts: 452
Location: Montenegro

View user's profile Send private message

PostPosted: Tue Feb 05, 2019 11:33 am     Reply with quote

Thanks for the explanation. Is it possible that the speed with which you change E7 makes a problem?
dluu13



Joined: 28 Sep 2018
Posts: 395
Location: Toronto, ON

View user's profile Send private message Visit poster's website

PostPosted: Tue Feb 05, 2019 11:46 am     Reply with quote

PrinceNai wrote:
Thanks for the explanation. Is it possible that the speed with which you change E7 makes a problem?


I doubt that is the case, since I have the same problem even if I set the
Timer4 to run from internal clock. Once I change the prescaler for Timer5 to
anything other than 1, then OC1 no longer pulses.

Besides, I feel that even if the E7 pulsing is too quick, I should be able to
simply press my button a couple more times and Timer4 should overflow from that anyway.
dluu13



Joined: 28 Sep 2018
Posts: 395
Location: Toronto, ON

View user's profile Send private message Visit poster's website

PostPosted: Tue Feb 05, 2019 12:19 pm     Reply with quote

UPDATE - I've made a discovery:

It appears that indeed there is a pulse when I use another prescaler value.
The difference is that for some reason, when I use a prescaler value other
than 1 for Timer5, my OC1 ISR does not get triggered.


I am still confused but this gives me direction at least.

EDIT: correction: it appears that the ISR is running, but only once. However,
it appears that this line does not have the intended effect after running in the
ISR:
Code:
setup_compare(1, COMPARE_SINGLE_PULSE | COMPARE_TIMER5 | COMPARE_TRIGGER | COMPARE_TRIG_SYNC_TIMER4);


I expected it to reset the OC module to prepare for another single pulse but it appears not to have reset. Or maybe it has, but somehow the Timer 5 prescaler not being 1 is messing it up.
Ttelmah



Joined: 11 Mar 2010
Posts: 19215

View user's profile Send private message

PostPosted: Tue Feb 05, 2019 1:50 pm     Reply with quote

I think the extra time involved with a prescaler, and whatever the clock rate
actually is on your timer4, means that the syncronisation does not occur
in time. This is listed as one of the special circumstances in this mode,
which results in the module not resetting.
dluu13



Joined: 28 Sep 2018
Posts: 395
Location: Toronto, ON

View user's profile Send private message Visit poster's website

PostPosted: Tue Feb 05, 2019 2:10 pm     Reply with quote

Ttelmah wrote:
I think the extra time involved with a prescaler, and whatever the clock rate
actually is on your timer4, means that the syncronisation does not occur
in time. This is listed as one of the special circumstances in this mode,
which results in the module not resetting.


But if it misses the current synchronisation, shouldn't it catch the next one?

Other than that, I still don't think it's the case that my trigger source is
running too fast for my timer5. If I run timer 4 like this:
Code:
setup_timer4(TMR_INTERNAL | TMR_DIV_BY_256, 65535);

I get around a 1Hz trigger. It is still the case that giving a prescaler to timer 5
will prevent it from triggering.

Let me know if you think my logic is flawed.
Right now, I am setting OCxR and OCxR to 5 and 20, and 20 counts in the
OC timer register, which I am understanding comes from Timer 5, lasts
only 1.25 us, for a prescaler of 1, and 10 us for a prescaler of 8. There
should be plenty of time for the module to reset itself.

EDIT: If by the "special condition", you mean this one, I actually get
something different. My OC module does drive the pin back down and fire
the interrupt. (Click on thumbnails of images to see full size)


For some extra info, here are a couple of oscilloscope traces of my
pulses:
With Timer5 prescaler 1 (works properly)


With Timer5 prescaler 8 (only pulses once, and does not reset)
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group