| View previous topic :: View next topic | 
	
	
		| Author | Message | 
	
		| starfire151 
 
 
 Joined: 01 Apr 2007
 Posts: 203
 
 
 
			    
 
 | 
			
				| problem with WDT in 16LF1825 |  
				|  Posted: Mon May 10, 2021 10:47 am |   |  
				| 
 |  
				| First, the basics: Windows 10 x64
 PCWHD 5.071
 
 I'm trying to get a PIC16LF1825 to run in a low power mode by using the WDT and an external interrupt.  As a test case, I have the WDT set for 2 seconds (I plan to use 128 seconds in the final version).  I loop a total of 10 times, restarting the WDT for the full 2 second count and then going to to sleep.  When the final loop is done, I'm trying to turn off the WDT so I can do some activity, which will take longer than the watchdog time.  In this test case, I'm using a couple of pins to monitor status.
 
 I see the background timeouts work correctly.  I see the peripheral output pin get turned on after the loops.  ...but... I see the peripheral get turned off after one watchdog period (2 seconds) instead of waiting for the 10 second peripheral period.  It's as if the setup_wdt(WDT_OFF) command is not being recognized.
 
 I put the PIN_C2 on a scope and I see the voltage go from low to high and stay high for 2 seconds and then start to decay off.  It decays from +3.3VDC to about 0.5VDC in about 40ms then shoots up to +3.3VDC again briefly (around 10us) before decaying off to 0VDC again.
 
 I'm including the test code below:
 
  	  | Code: |  	  | #include <16LF1825.h>
 
 #device adc=10       // 10-bit ADC => 1024 steps
 #device *=16
 
 #FUSES NODEBUG       // No Debug mode for ICD
 #FUSES WDT           // Watch Dog Timer
 #FUSES HS            // High speed osc
 #FUSES NOPROTECT     // Code not protected from reading
 #FUSES IESO          // Internal External Switch Over mode enabled
 #FUSES NOBROWNOUT    // No brownout reset
 #FUSES STVREN        // Stack full/underflow will cause reset
 #FUSES NOLVP         // No low volt prgm, B3(PIC16) or B5(PIC18) used for I/O
 #FUSES MCLR          // Master Clear pin enabled
 
 #define clk_freq 16000000
 #use delay(internal=clk_freq)
 
 #define PA_TRIS 0b11001111
 #define PA_DEF 0b11011111
 #define PC_TRIS 0b11100000
 #define PC_DEF 0b11100000
 
 typedef unsigned int8 uint8;
 typedef unsigned int16 uint16;
 typedef unsigned int32 uint32;
 
 int1 extIntFlag;     // TRUE=external int seen
 int1 wdFlag;         // TRUE=doing WDT loops
 
 uint16 loopCntr;     // current WDT loop count
 uint16 bgLoopCntr;   // background loop count for peripheral acitvity
 
 
 // ---- external interrupt service ----
 //  if ext int seen from light sensor, set flag for background
 #int_EXT
 void ExtISR(void)
 {
 extIntFlag = TRUE;
 }
 
 
 // ---- main background routine ----
 #zero_ram
 void main(void)
 {
 set_tris_a(PA_TRIS);
 set_tris_c(PC_TRIS);
 
 set_rtcc(0);
 setup_timer_0(RTCC_INTERNAL | RTCC_DIV_256 | RTCC_8_BIT);
 setup_timer_1(T1_DISABLED);
 setup_timer_2(T2_DISABLED, 0, 1);
 
 setup_comparator(NC_NC_NC_NC);
 setup_vref(FALSE);
 
 output_a(PA_DEF);
 output_c(PC_DEF);
 extIntFlag = FALSE;
 wdFlag = TRUE;
 bgLoopCntr = 0;   // reset background loop counter
 
 delay_ms(100);                // system stability time
 
 ext_int_edge(L_TO_H);   // external int from light sensor through 74AHC14
 clear_interrupt(INT_EXT);        // clear any pending interrupt
 enable_interrupts(INT_EXT);      // enalbe external interrupts
 enable_interrupts(GLOBAL);       // global activation of enabled ints
 
 setup_wdt(WDT_ON | WDT_2S);   // enable WDT and set for 2 second timeout
 
 while(TRUE) // background
 {
 if(wdFlag)
 {
 loopCntr = 0;  // reset loop counter
 while((loopCntr < 10) && (extIntFlag == FALSE))
 {
 restart_wdt(); // restart WDT to get full 2 second delay time
 
 sleep();       // go to sleep now
 
 output_high(PIN_A5);  // flash test pin to show awake now
 delay_ms(100);
 output_low(PIN_A5);
 
 loopCntr++;    // if no ext int, just increment loop counter
 }
 
 // enable an output pin to show active now
 output_high(PIN_C2); // turn peripheral power on
 
 setup_wdt(WDT_OFF);  // turn off WDT
 wdFlag = FALSE;      // don't do WDT loops until done with activity
 
 output_high(PIN_A5); // flash test pin to show it got to here
 delay_ms(50);
 output_low(PIN_A5);
 delay_ms(50);
 output_high(PIN_A5);
 delay_ms(50);
 output_low(PIN_A5);
 
 extIntFlag = FALSE;  // verify ext int flag reset, if it was set
 }
 
 delay_ms(1);
 
 if(++bgLoopCntr == 10000)   // delay to allow background activity
 {
 bgLoopCntr = 0;      // reset for next time
 
 // disable 3V and 6V supplies and turn off LEDs now
 output_low(PIN_C2);       // turn peripheral power off
 
 setup_wdt(WDT_ON | WDT_2S);
 restart_wdt();
 
 wdFlag = TRUE;    // tell the WDT to loop again
 }
 }
 }
 
 | 
 
 Does anyone have any idea what's happening?
 
 Thanks for any help.
 |  | 
	
		|  | 
	
		| PCM programmer 
 
 
 Joined: 06 Sep 2003
 Posts: 21708
 
 
 
			    
 
 | 
			
				| Re: problem with WDT in 16LF1825 |  
				|  Posted: Mon May 10, 2021 2:22 pm |   |  
				| 
 |  
				|  	  | starfire151 wrote: |  	  | It's as if the setup_wdt(WDT_OFF) command is not being recognized. 
 
 #FUSES NODEBUG       // No Debug mode for ICD
 #FUSES WDT           // Watch Dog Timer
 #FUSES HS            // High speed osc
 #FUSES NOPROTECT     // Code not protected from reading
 #FUSES IESO          // Internal External Switch Over mode enabled
 #FUSES NOBROWNOUT    // No brownout reset
 #FUSES STVREN        // Stack full/underflow will cause reset
 #FUSES NOLVP         // No low volt prgm, B3(PIC16) or B5(PIC18) used for I/O
 #FUSES MCLR          // Master Clear pin enabled
 
 | 
 On page 569 of the CCS manual, in the section on setup_wdt(), it says:
 
  	  | Quote: |  	  | Note: For PCH parts and PCM parts with software controlled WDT, setup_wdt( ) would enable/disable watchdog timer only if NOWDT fuse is set. If WDT fuse is set, watchdog timer is always enabled.
 | 
 You need to change your fuse to NOWDT.
 |  | 
	
		|  | 
	
		| starfire151 
 
 
 Joined: 01 Apr 2007
 Posts: 203
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Mon May 10, 2021 2:44 pm |   |  
				| 
 |  
				| Hi PCM programmer.  Thanks for responding so quickly. 
 I changed the #FUSES WDT to #FUSES NOWDT and tried it again.  I don't even see the loops counting now on the PIN_A5 output.
 
 When I activate the external interrupt, though, it turns on the peripheral pin on PIN_C2 and it stays active for 10 seconds, like its supposed to. It appears the setup_wdt(WDT_OFF) is working now  ...progress...
 
 Why wouldn't the PIN_A5 output work in the loop now, though?  Shouldn't program execution continue after the sleep() command when the WDT times out?
 
 Thanks for your help.
 |  | 
	
		|  | 
	
		| PCM programmer 
 
 
 Joined: 06 Sep 2003
 Posts: 21708
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Tue May 11, 2021 12:47 am |   |  
				| 
 |  
				| Did you put the IDE into Debug mode ?  That would disable the WDT. |  | 
	
		|  | 
	
		| Ttelmah 
 
 
 Joined: 11 Mar 2010
 Posts: 19966
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Tue May 11, 2021 2:18 am |   |  
				| 
 |  
				| One little change that may affect things: 
 
  	  | Code: |  	  | sleep();       // go to sleep now
 delay_cycles(1);
 output_high(PIN_A5);  // flash test pin to show awake now
 
 | 
 The instruction _after_ the sleep, is 'prefetched' when you go to sleep.
 As a result, it may not actually execute correctly when you wake.
 Hence this instruction should always be a NOP. delay_cycles(1) codes
 as a NOP.
 It may affect how the code behaves when it wakes.
 
 You don't actually need the restart_wdt when entering sleep. The act of
 entering the sleep mode always restarts the WDT.
 |  | 
	
		|  | 
	
		| starfire151 
 
 
 Joined: 01 Apr 2007
 Posts: 203
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Tue May 11, 2021 8:33 am |   |  
				| 
 |  
				| Hi PCM programmer - 
 I included the #FUSES NODEBUG so I think the WDT should be enabled?
 
 Hi Ttelmah -
 
 I included the delay_cycles(1); after the sleep() command.  This didn't appear to make any difference.  It's as if it's not being awakened by the WDT timeout.  I removed the restart_wdt() before going to sleep(), also.  Thanks for that info.
 
 One question on how to start the WDT.  I've tried setup_wdt(WDT_ON | WDT_2S), setup_wdt(WDT_2S), and both setup_wdt(WDT_2S) then setup_wdt(WDT_ON).  All three conditions give the same result.  What is the correct method.  The documentation is kind of vague about this.
 
 In all three cases, though, when I trigger the external interrupt, the code after the sleep() statement all works correctly.  I see the flashes to the PIN_A5, the PIN_C2 turns on and stays on for the expected 10 seconds before turning off the PIN_C2 and returning to the loop.
 
 Thanks for your continued help in resolving this issue.
 |  | 
	
		|  | 
	
		| temtronic 
 
 
 Joined: 01 Jul 2010
 Posts: 9588
 Location: Greensville,Ontario
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Tue May 11, 2021 9:47 am |   |  
				| 
 |  
				| re: I included the #FUSES NODEBUG so I think the WDT should be enabled? 
 NOT necessarily if you're using an IDE. IDEs can overwrite the pgm code setups....
 
 Also, if you're using MPLAB, you must compiler in 'release' mode not 'debug' mode......
 so... is the hardware totally 'standalone'? IE burn the PIC then test in the 'real World' ??
 |  | 
	
		|  | 
	
		| PCM programmer 
 
 
 Joined: 06 Sep 2003
 Posts: 21708
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Tue May 11, 2021 10:06 am |   |  
				| 
 |  
				|  	  | starfire151 wrote: |  	  | Hi PCM programmer - 
 I included the #FUSES NODEBUG so I think the WDT should be enabled?
 
 | 
 Temtronics answered the question, but here is some more:
 
 Using MPLAB vs. 8.92, I set the Release/Debug drop-down box
 to DEBUG, and compiled your program.  I then looked at the bottom
 of the .LST file to see the fuses set by the compiler:
 
  	  | Quote: |  	  | Configuration Fuses: Word  1: 19E4   INTRC_IO NOWDT NOPUT MCLR NOPROTECT NOCPD NOBROWNOUT NOCLKOUT IESO NOFCMEN
 Word  2: 0EFF   NOWRT PLL_SW STVREN BORV19 DEBUG NOLVP
 
 Some fuses have been forced to be compatible with the ICD debugger.
 
 | 
 Note that the drop-down box setting has over-ridden the NODEBUG
 in your program.
 
 That's why I mentioned it.  What IDE are you using and is it
 accidentally set for DEBUG mode ?
 |  | 
	
		|  | 
	
		| starfire151 
 
 
 Joined: 01 Apr 2007
 Posts: 203
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Tue May 11, 2021 5:20 pm |   |  
				| 
 |  
				| Hi PCM programmer and temtronic 
 I checked the bottom of the .lst file and get this:
 
 Configuration Fuses:
 Word  1: 39C4   INTRC_IO NOWDT PUT MCLR NOPROTECT NOCPD NOBROWNOUT NOCLKOUT IESO FCMEN
 Word  2: 1EFF   NOWRT PLL_SW STVREN BORV19 NODEBUG NOLVP
 
 It appears I am not in debug mode.
 
 I'm using V5.071 of the compiler.  I'm using the ICD-USB module to program the PIC.  I use the "Build and Run" option from the menu.  It compiles and downloads the program to the PIC and then starts operation.  Since this test case isn't using the PClk or PDat lines, the program runs OK.  I have also disconnected the ICD-USB module from the PIC and done a reset to the system but it still responds the same way.
 
 As an aside, I also just compiled the program and loaded it to the PIC with the ccsload program but that also showed the same results.  The WDT appears to not be working but the EXT interrupt still works.
 |  | 
	
		|  | 
	
		| newguy 
 
 
 Joined: 24 Jun 2004
 Posts: 1924
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Tue May 11, 2021 6:06 pm |   |  
				| 
 |  
				| Have you read the errata for that processor? 
 Item 1.1: LFINTOSC, Item summary: Wake from sleep. Revision A0 affected.
 
 Item 1.2: Clock switching, Item summary: clock switching can cause a single corrupted instruction. Revision A0 affected.
 
 Item 1.3: Oscillator start-up timer, Item summary: OSTS bit remains set. Revisions A0 and A2 affected.
 
 These are, to my mind, 3 possibilities in terms of your troubles.
 
 Use CCSLoad to read the HW rev of your processor.
 |  | 
	
		|  | 
	
		| newguy 
 
 
 Joined: 24 Jun 2004
 Posts: 1924
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Tue May 11, 2021 6:15 pm |   |  
				| 
 |  
				|  	  | starfire151 wrote: |  	  | Hi PCM programmer and temtronic 
 I checked the bottom of the .lst file and get this:
 
 Configuration Fuses:
 Word  1: 39C4   INTRC_IO NOWDT PUT MCLR NOPROTECT NOCPD NOBROWNOUT NOCLKOUT IESO FCMEN
 Word  2: 1EFF   NOWRT PLL_SW STVREN BORV19 NODEBUG NOLVP
 
 It appears I am not in debug mode.
 | 
 
 Your WDT is completely disabled. It cannot function in SW controlled mode because it's off. From the data sheet, chapter 4, page 48:
 
 WDTE bits (4:3): 00 = watchdog disabled.
 
 You want 01 = WDT controlled by the SWDTEN bit in the WDTCON register.
 |  | 
	
		|  | 
	
		| PCM programmer 
 
 
 Joined: 06 Sep 2003
 Posts: 21708
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Tue May 11, 2021 7:35 pm |   |  
				| 
 |  
				| On page 569 of the CCS manual, in the section on setup_wdt(), it says: 
  	  | Quote: |  	  | Note: For PCH parts and PCM parts with software controlled WDT, setup_wdt( ) would enable/disable watchdog timer only if NOWDT fuse is set. If WDT fuse is set, watchdog timer is always enabled.
 | 
 |  | 
	
		|  | 
	
		| newguy 
 
 
 Joined: 24 Jun 2004
 Posts: 1924
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Tue May 11, 2021 8:32 pm |   |  
				| 
 |  
				| Manual appears to be wrong. 
 Test program:
 
  	  | Code: |  	  | #include <16LF1825.h> #device ADC=10
 
 #FUSES PUT                      //Power Up Timer
 #FUSES NOBROWNOUT               //No brownout reset
 #fuses WDT_SW         //No Watch Dog Timer, enabled in Software
 #fuses INTRC_IO       //Internal RC Osc, no CLKOUT
 
 #use delay(internal=4000000)
 
 void main(void) {
 setup_wdt(WDT_ON | WDT_512MS);
 
 while(TRUE) {
 
 }
 }
 | 
 
 List file:
 
  	  | Code: |  	  | CCS PCM C Compiler, Version 5.093, 46949               11-May-21 20:21 
 Filename:   C:\temp\main.lst
 
 ROM used:   19 words (0%)
 Largest free fragment is 2048
 RAM used:   5 (0%) at main() level
 16 (2%) worst case
 Stack used: 0 locations
 Stack size: 16
 
 0000:  MOVLP  00
 0001:  GOTO   main
 0002:  NOP
 .................... #include <16LF1825.h>
 .................... //////////// Standard Header file for the PIC16LF1825 device ////////////////
 .................... ///////////////////////////////////////////////////////////////////////////
 .................... ////        (C) Copyright 1996, 2014 Custom Computer Services          ////
 .................... //// This source code may only be used by licensed users of the CCS C  ////
 .................... //// compiler.  This source code may only be distributed to other      ////
 .................... //// licensed users of the CCS C compiler.  No other use, reproduction ////
 .................... //// or distribution is permitted without written permission.          ////
 .................... //// Derivative programs created using this software in object code    ////
 .................... //// form are not restricted in any way.                               ////
 .................... ///////////////////////////////////////////////////////////////////////////
 .................... #device PIC16LF1825
 ....................
 .................... #list
 ....................
 .................... #device ADC=10
 ....................
 .................... #FUSES PUT                      //Power Up Timer
 .................... #FUSES NOBROWNOUT               //No brownout reset
 .................... #fuses WDT_SW         //No Watch Dog Timer, enabled in Software
 .................... #fuses INTRC_IO       //Internal RC Osc, no CLKOUT
 ....................
 .................... #use delay(internal=4000000)
 ....................
 .................... void main(void) {
 0003:  MOVLW  6A
 0004:  MOVLB  01
 0005:  MOVWF  OSCCON
 0006:  MOVLB  03
 0007:  CLRF   ANSELA
 0008:  CLRF   ANSELC
 0009:  MOVLB  02
 000A:  CLRF   CM1CON1
 000B:  CLRF   CM1CON0
 000C:  CLRF   CM2CON1
 000D:  CLRF   CM2CON0
 ....................    setup_wdt(WDT_ON | WDT_512MS);
 000E:  MOVLW  13
 000F:  MOVLB  01
 0010:  MOVWF  WDTCON // this is correct
 ....................
 ....................    while(TRUE) {
 0011:  GOTO   011
 ....................
 ....................    }
 .................... }
 0012:  SLEEP
 
 Configuration Fuses:
 Word  1: 39CC   INTRC_IO WDT_SW PUT MCLR NOPROTECT NOCPD NOBROWNOUT NOCLKOUT IESO FCMEN // correct
 Word  2: 1EFF   NOWRT PLL_SW STVREN BORV19 NODEBUG NOLVP
 | 
 
 If the WDT fuse is changed to disable it:
 
  	  | Code: |  	  | CCS PCM C Compiler, Version 5.093, 46949               11-May-21 20:26 
 Filename:   C:\temp\main.lst
 
 ROM used:   19 words (0%)
 Largest free fragment is 2048
 RAM used:   5 (0%) at main() level
 16 (2%) worst case
 Stack used: 0 locations
 Stack size: 16
 
 0000:  MOVLP  00
 0001:  GOTO   main
 0002:  NOP
 .................... #include <16LF1825.h>
 .................... //////////// Standard Header file for the PIC16LF1825 device ////////////////
 .................... ///////////////////////////////////////////////////////////////////////////
 .................... ////        (C) Copyright 1996, 2014 Custom Computer Services          ////
 .................... //// This source code may only be used by licensed users of the CCS C  ////
 .................... //// compiler.  This source code may only be distributed to other      ////
 .................... //// licensed users of the CCS C compiler.  No other use, reproduction ////
 .................... //// or distribution is permitted without written permission.          ////
 .................... //// Derivative programs created using this software in object code    ////
 .................... //// form are not restricted in any way.                               ////
 .................... ///////////////////////////////////////////////////////////////////////////
 .................... #device PIC16LF1825
 ....................
 .................... #list
 ....................
 .................... #device ADC=10
 ....................
 .................... #FUSES PUT                      //Power Up Timer
 .................... #FUSES NOBROWNOUT               //No brownout reset
 .................... #fuses NOWDT          //No Watch Dog Timer
 .................... #fuses INTRC_IO       //Internal RC Osc, no CLKOUT
 ....................
 .................... #use delay(internal=4000000)
 ....................
 .................... void main(void) {
 0003:  MOVLW  6A
 0004:  MOVLB  01
 0005:  MOVWF  OSCCON
 0006:  MOVLB  03
 0007:  CLRF   ANSELA
 0008:  CLRF   ANSELC
 0009:  MOVLB  02
 000A:  CLRF   CM1CON1
 000B:  CLRF   CM1CON0
 000C:  CLRF   CM2CON1
 000D:  CLRF   CM2CON0
 ....................    setup_wdt(WDT_ON | WDT_512MS);
 000E:  MOVLW  13
 000F:  MOVLB  01
 0010:  MOVWF  WDTCON // same as before
 ....................
 ....................    while(TRUE) {
 0011:  GOTO   011
 ....................
 ....................    }
 .................... }
 0012:  SLEEP
 
 Configuration Fuses:
 Word  1: 39C4   INTRC_IO NOWDT PUT MCLR NOPROTECT NOCPD NOBROWNOUT NOCLKOUT IESO FCMEN // setup_wdt() doesn't change the fuse - the WDT is killed
 Word  2: 1EFF   NOWRT PLL_SW STVREN BORV19 NODEBUG NOLVP
 
 | 
 |  | 
	
		|  | 
	
		| Ttelmah 
 
 
 Joined: 11 Mar 2010
 Posts: 19966
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Tue May 11, 2021 11:40 pm |   |  
				| 
 |  
				| No, the manual is right, except it dates from older chips that only had WDT and NOWDT fuses. This chip has WDT, NOWDT, WDT_NOSL, and
 WDT_SW options.
 
 You have to look at and understand what the fuses actually 'do' (data sheet).
 
 For this chip it says:
 
  	  | Quote: |  	  | bit 4-3 WDTE<1:0>: Watchdog Timer Enable bit
 11 = WDT enabled
 10 = WDT enabled while running and disabled in Sleep
 01 = WDT controlled by the SWDTEN bit in the WDTCON register
 00 = WDT disabled
 
 | 
 
 Note that only the third (which is WDT_SW), allows the SWDTEN bit to
 control the watchdog.
 
 On the earlier chips, you had:
 
  	  | Quote: |  	  | bit 3 WDTE: Watchdog Timer Enable bit
 1 = WDT enabled
 0 = WDT disabled and can be enabled by SWDTEN bit (WDTCON<0>)
 
 | 
 
 So to use the SWDTEN, you simply had to disable the WDT in the fuses.
 The manual has not been updated for these later chips.
 
 The key thing always is to look at the data sheet.
 |  | 
	
		|  | 
	
		| starfire151 
 
 
 Joined: 01 Apr 2007
 Posts: 203
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Wed May 12, 2021 8:32 am |   |  
				| 
 |  
				| Hi Ttelmah, newguy, and PCM programmer - 
 GREAT HELP EVERYBODY!  I changed the #FUSES NOWDT line to #FUSES WDT_SW, recompiled, and loaded it.  It worked right off the bat completely correctly!
 
 I'm seeing the 100ms pulse every 2 seconds on PIN_A5 during the WDT counting loop, I see the PIN_C2 get enabled after the end of the counting loop, I see the background operation run correctly for 10 seconds with no WDT timeout, I see the PIN_C2 get disabled at the end of the 10 second background operation, and I see the PIN_A5 100ms pulse every 2 seconds from the WDT for another 10 loops, etc.
 
 I didn't see WDT_SW as a fuse option in the device file.  It worked great!
 
 
 Thanks, again, everyone!
 
 I'm off to the races...
  |  | 
	
		|  | 
	
		|  |