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

18LF46K22 with #fuses WDT sleeps for ever - solved

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



Joined: 14 May 2010
Posts: 20

View user's profile Send private message

18LF46K22 with #fuses WDT sleeps for ever - solved
PostPosted: Fri Dec 02, 2011 8:02 am     Reply with quote

I had many problems with the 18LF46K22:

The CTMU sometimes did not work while a PIN is set by PWM - the only solution was to check the PWM-timer if it will roll over and may wait with CTMU.
(Parasitic capacitances inside the chip?).

I am not able to activate PIN D4 for PWM. Datasheet says it is a alternative PWM PIN, but don´t tell me how to do = which register must be written.
CCS v.4.120 cant´t do anything too.


Now I am stupid (not many experience with sleep) or there is a bug too:
After sleep the CPU can only be waked up by a reset on MCLR.
I can do what I want or wait 10 Minutes:
After reset MCLR I see only one single peak=delay_cycles(10) on my scope.

Code:

#include <18LF46K22.h>
#fuses  WDT
//#fuses WDT_SW
#fuses  WDT1
#fuses  MCLR       
#fuses  INTRC
#FUSES  IESO       
void Main()
{  //SETUP_TIMER_1(T1_INTERNAL|T1_DIV_BY_1);
   //enable_interrupts(INT_TIMER1);
   //enable_interrupts(GLOBAL);
   //setup_wdt(wdt_on);
   //set_Tris_D(0);output_d(0);
while(1)
   { output_high(PIN_D5);delay_cycles(10);
     output_low (PIN_D5);
     sleep();
     output_high(PIN_D5);delay_cycles(200);
     output_low (PIN_D5);}
}

MPLAB v8.76 / CCS v.4.120


Last edited by buchtsucht on Sat Dec 03, 2011 4:55 am; edited 1 time in total
Ttelmah



Joined: 11 Mar 2010
Posts: 19363

View user's profile Send private message

PostPosted: Fri Dec 02, 2011 10:07 am     Reply with quote

The ECCP module, can produce a PWM output on this pin, but not by involving re-routing. It is the standard pin for it's second output, and you can connect a single pwm output to this with:

setup_CCP1(CCP_PWM_H_H | CCP_PULSE_STEERING_B);

Which selects it's 'B' output to be used.
You should check that CCS updates the TRIS when you do this. Generally they have a habit of forgetting to change the TRIS settings when alternative pins are selected....

Now, onto sleep. Your code as posted, has nothing setup to wake the chip from sleep, so 'of course' it stays asleep until you reset.
Any _asynchronous_ interrupt, can be set to wake the chip. So:
Code:

#include <18LF46K22.h>
#fuses  WDT
#fuses  WDT1
#fuses  MCLR       
#fuses  INTRC
//#FUSES  IESO       //unless you have a second oscillator, don't use
void Main(void) {
   portb_pullups(0b00000001); enable pullup on pin B0
   while(1) {
     output_high(PIN_D5);
     delay_cycles(10);
     output_low (PIN_D5);
     //Do not enable global interrupts, unless you have an interrupt handler
     //for int_ext
     disable_interrupts(GLOBAL);
     enable_interrupts(INT_EXT_H2L); //enable EXT interrupt on falling edge
     clear_interrupt(INT_EXT); //ensure interrupt is clear
     sleep();
     delay_cycles(1); //This instruction is prefetched when you sleep
     //Use a NOP here - delay_cycles(1) gives this.
     disable_interrupts(INT_EXT); //Disable here before you enable any
     //other interrupts.

     output_high(PIN_D5);
     delay_cycles(200);
     output_low (PIN_D5);
   }
}

Now, the chip will sleep, and it's clock will stop. This is why the interrupt source must be one that doesn't depend on a processor clock (asynchronous). If you pull down pin B0, the chip will start.

Basically, it'll wake, if any 'enabled' interrupt, gets it's interrupt flag set. Because the 'global' flag is _not_ set, it won't call a 'handler', but just wake up.

Best Wishes
Ttelmah



Joined: 11 Mar 2010
Posts: 19363

View user's profile Send private message

PostPosted: Fri Dec 02, 2011 3:53 pm     Reply with quote

On why the WDT doesn't wake it - you have stopped the WDT oscillator....
Look at section 2.7 in the data sheet.
You must set the oscillator to stay running in sleep if you want to use the WDT to wake - look at OSC_IDLE_MODE in the setup oscillator instruction.

Best Wishes
buchtsucht



Joined: 14 May 2010
Posts: 20

View user's profile Send private message

PostPosted: Fri Dec 02, 2011 11:41 pm     Reply with quote

Thanks, I forgot to say, I want to wake up the PIC by WDT. And I tried several settings for Interrupts / Timer1 / LFINTOSC - no success.
I read 2.2 / 2.7 / 3.3 in Datasheet, but maybe I understand something wrong.

Datsheet S 51: ......If the WDT is selected, the LFINTOSC source will continue to operate.....When a wake event occurs in Sleep mode (by interrupt, Reset or WDT time-out), the device will not be clocked
until the clock source selected by the SCS<1:0> bits becomes ready (see Figure 3-5), or it will be clocked from the internal oscillator block if either the Two-Speed Start-up or the Fail-Safe Clock Monitor are enabled.....

Following work at my other PICs but not here:


Code:

#include <18LF46K22.h>
#fuses  WDT
#fuses  WDT1
#fuses  MCLR       
#fuses  INTRC
#FUSES  IESO   
#FUSES  FCMEN 


// CPU-CLOCK
#byte OSCCON   = 0xFD3
#byte OSCCON2  = 0xFD2
#byte OSCTUNE  = 0xF9B

void Main(void) {
 OSCCON   = 0b00000010;        // needs <10 µA                              
 OSCCON2  = 0b00000000;        // needs <10 µA
 OSCTUNE  = 0b00000000;        // needs <10 µA
// setup_oscillator(OSC_31250);// needs 370µA!      
// setup_timer_1 (T1_INTERNAL | T1_DIV_BY_1);   

   while(1) {
     output_high(PIN_D5);
     delay_cycles(10);
     output_low (PIN_D5);

     disable_interrupts(GLOBAL);
     enable_interrupts(INT_TIMER1);
     enable_interrupts(GLOBAL);
     //clear_interrupt(INT_TIMER1);
     sleep();
     delay_cycles(1);
     //disable_interrupts(INT_TIMER1);
     output_high(PIN_D5);
     delay_cycles(200);
     output_low (PIN_D5);
   }
}



PIC18(L)F4XK22
Datasheet Page 25: D4 => Enhanced CCP2 PWM output.
Datasheet Page 178: CCP2MX=0 => B3 / CCP2MX=1 => C1
No comment about CCP2 / D4 anywhere else in the datasheet
CCS: ////////Fuses:.........CCP2B3,CCP2C1.......CCP2C0,CCP2D.........2CCP3E0,CCP3B5, but nothing with D4
Ttelmah



Joined: 11 Mar 2010
Posts: 19363

View user's profile Send private message

PostPosted: Sat Dec 03, 2011 3:43 am     Reply with quote

The point is that most watchdog have the watchdog automatically running if enabled. On this chip, it doesn't. The sleep mode is designed for _super_ low power, and defaults to stopping _everything_. As I said, look at 'OSC_IDLE_MODE' in the setup_oscillator instruction. You 'OR' this with the oscillator mode you select, and this enables the oscillator to stay running in idle mode. Then the WDT will run, but sleep draws a little more power.

Best Wishes
buchtsucht



Joined: 14 May 2010
Posts: 20

View user's profile Send private message

PostPosted: Sat Dec 03, 2011 4:54 am     Reply with quote

Thanks Ttelmah. I am not able to aktivate the WDT as I want, but it works very well like this:
(Current consumtion is about 1 µA or less while sleep)
Code:

#include <18LF46K22.h>
#fuses  NoWDT
#fuses  MCLR       
#fuses  INTRC

// CPU-CLOCK
#byte OSCCON   = 0xFD3
#byte OSCCON2  = 0xFD2
#byte OSCTUNE  = 0xF9B
// Voltage reference
#byte VREFCON0 = 0xF42

void Main(void) {
 setup_comparator(NC_NC_NC_NC);               
 setup_ADC(ADC_OFF);
 SETUP_DAC(DAC_OFF);
 SETUP_WDT(WDT_Off);
 SET_TIMER0(T0_OFF);
 SET_TIMER2(T2_DISABLED);
 SET_TIMER3(T3_DISABLED);
 SET_TIMER4(T4_DISABLED);
 SET_TIMER5(T5_DISABLED);
 SET_TIMER6(T6_DISABLED);
 SETUP_CCP1(CCP_OFF );
 SETUP_CCP2(CCP_OFF );
 SETUP_CCP3(CCP_OFF );
 SETUP_CCP4(CCP_OFF );
 SETUP_CCP5(CCP_OFF );
 SETUP_SPI(SPI_DISABLED);
 VREFCON0=0b00010000;
 set_Tris_A(0b00000000);output_a(0);
 set_Tris_B(0b00000000);output_b(0);
 set_Tris_C(0b00000000);output_c(0);
 set_Tris_D(0b00000000);output_d(0);
 set_Tris_E(0b00000000);output_e(0);
 setup_timer_1 (T1_INTERNAL | T1_DIV_BY_1);   
 OSCCON   = 0b10000011;               
 OSCCON2  = 0b00000000;
 OSCTUNE  = 0b00000000;
   while(1) {
     output_high(PIN_D5);
     delay_cycles(10);
     output_low (PIN_D5);
     disable_interrupts(GLOBAL);
     enable_interrupts(INT_TIMER1);
     clear_interrupt(INT_TIMER1);
     set_timer1(65000);
     sleep();
     delay_cycles(1);
     disable_interrupts(INT_TIMER1);
     output_high(PIN_D5);
     delay_cycles(20);
     output_low (PIN_D5);
   }
}


(Was it not the idea of the WDT, that I can programm the biggest rubbish, one thing is everytime certain: WDT makes a reset if not cleared erverytime. I can´t understand, that a WDT makes no reset if I write #fuses NoWDT)
Ttelmah



Joined: 11 Mar 2010
Posts: 19363

View user's profile Send private message

PostPosted: Sat Dec 03, 2011 5:12 am     Reply with quote

Code:

#include <18LF46K22.h>
#fuses  WDT1
#fuses  MCLR       
#fuses  INTRC_IO
#use delay(CLOCK=4000000);
void Main(void) {
   setup_oscillator(OSC_4MHZ);
   while(1) {
     output_high(PIN_D5);
     delay_cycles(10);
     output_low (PIN_D5);
     //Down to low speed oscillator, staying on when asleep
     setup_oscillator(OSC_31250 | OSC_INTRC | OSC_IDLE_MODE);
     sleep();
     delay_cycles(1); //This instruction is prefetched when you sleep
     //Use a NOP here - delay_cycles(1) gives this.
     
     //Back up to normal oscillator
     setup_oscillator(OSC_4MHZ);
     output_high(PIN_D5);
     delay_cycles(200);
     output_low (PIN_D5);
   }
}


Best Wishes
buchtsucht



Joined: 14 May 2010
Posts: 20

View user's profile Send private message

PostPosted: Sat Dec 03, 2011 10:34 pm     Reply with quote

This code gives me only one peak on skope, then sleeping for ever............
Ttelmah



Joined: 11 Mar 2010
Posts: 19363

View user's profile Send private message

PostPosted: Sun Dec 04, 2011 4:11 am     Reply with quote

With the idle enabled, it should work.
However some compilers do unnecessary fiddling with the bits.
So:
Code:

#include <18LF46K22.h>
#fuses  WDT1
#fuses  MCLR       
#fuses  INTRC_IO
#use delay(CLOCK=4000000);
#byte OSCTUNE = getenv("SFR:OSCTUNE")
#bit INTSRC=OSCTUNE.7

void Main(void) {
   setup_oscillator(OSC_4MHZ);
   while(1) {
     output_high(PIN_D5);
     delay_cycles(10);
     output_low (PIN_D5);
     //Down to low speed oscillator, staying on when asleep
     setup_oscillator(OSC_31250 | OSC_INTRC | OSC_IDLE_MODE);
     INTSRC=0; //select LFINTOSC
     sleep();
     delay_cycles(1); //This instruction is prefetched when you sleep
     //Use a NOP here - delay_cycles(1) gives this.
     
     //Back up to normal oscillator
     setup_oscillator(OSC_4MHZ);
     output_high(PIN_D5);
     delay_cycles(200);
     output_low (PIN_D5);
   }
}

Which forces the chip into running on the LF oscillator before switching.

That should work with all compiler versions.... Smile

It _should_ have worked for you, with 4.120, with just:

Code:

#include <18LF46K22.h>
#fuses  WDT1
#fuses  MCLR       
#fuses  INTRC_IO
#use delay(CLOCK=4000000);
void main()
{
   setup_oscillator(OSC_4MHZ | OSC_INTRC | OSC_IDLE_MODE);
   while(1) {
     output_high(PIN_D5);
     delay_cycles(10);
     output_low (PIN_D5);
     sleep();
     delay_cycles(1); //This instruction is prefetched when you sleep
     //Use a NOP here - delay_cycles(1) gives this.
     output_high(PIN_D5);
     delay_cycles(200);
     output_low (PIN_D5);
   }
}


Rather puzzled that it doesn't.....

You are testing directly on a hardware chip, and not an ICD?. Some simulators, and some ICD's don't support watchdog operation. Check the 'exclusions' list in their data, just in case.....

Best Wishes
buchtsucht



Joined: 14 May 2010
Posts: 20

View user's profile Send private message

PostPosted: Mon Dec 05, 2011 9:11 am     Reply with quote

Both give just one pulse on my scope.....
I am programming with Pickit3, remove it, connect power, (make a reset) and look on my scope.
I don´t understand those things. I tried hundreds of settings with no success.


I give up now.


Maybe the chip is not O.K. ( I don´t think so because a lot of protection circuits on board), there is a bug on chip and/ or a problem with reset.

Even I have a perfect reset circuit as told in Datasheet, just the µC, caps and ESD protection on board, it makes with some settings a difference in current consumption while sleep if I had made a reset with removing Ubat (120µ...240µA) or without (ca 1µA). The µC with its complex software behaves absolute same in both cases only difference in Power consumption while sleep. I can´t find the problem here too.

If I don´t write 500 times different values in the CCP2 register after reset before using ccp2, it sometimes did not work after reset and I am not the only one with those problems:
http://www.ccsinfo.com/forum/viewtopic.php?t=44564&highlight=18f45k22

I had never such problems with other chips (PIC18LF252,PIC18LF23K22...) before, I think, that this chip was not a good choice....
buchtsucht



Joined: 14 May 2010
Posts: 20

View user's profile Send private message

PostPosted: Mon Dec 05, 2011 11:18 pm     Reply with quote

And I forgot to to say:
Thanks for your help, Ttelmah
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