It is currently 23 Apr 2019 21:51

All times are UTC + 1 hour




Post new topic Reply to topic  [ 7 posts ] 
Author Message
PostPosted: 11 Jan 2019 17:44 
Offline

Joined: 26 Dec 2004 23:10
Posts: 751
Location: Matthews, NC, USA
If I understand the section 9 Watch Dog Timer correctly, it appears there is a way to resume code execution after a "Wait" command if the Osccon is set correctly. This "return" requires code to do a check of RCON to determine whether a WDT interrupt occurred and whether the MCU was in "Sleep" or "Idle" mode. They give an excellent example of how to do this in Section 9 page 9 code example 9-2

Here is an extract of Section 9 supporting that approach

Quote:
9.4.2 Watchdog Timer NMI
When the WDT module expires in Sleep or Idle, a NMI is generated. The NMI causes the CPU
code execution to jump to the device reset vector. Although the NMI shares the same vector as
a device Reset, registers and peripherals are not reset.
To detect a wake from a power-saving mode by the WDT, the WDTO bit (RCON<4>), SLEEP bit
(RCON<3>) and IDLE bit (WDTCON<2>) must be tested. If the WDTO bit is a ‘1’, the event was
caused by a WDT time-out. The SLEEP and IDLE bits can then be tested to determine if the WDT
event occurred in Sleep or Idle modes.

To cause a WDT time-out in Sleep mode to act like an interrupt, a return from interrupt instruction
(RETFIE) may be used in the start-up code after the event was determined to be a WDT
wake-up. This will cause code execution to continue with the opcode following the
WAIT
instruction that put the device into the power-saving mode. Refer to Example 9-2.]


So attempting to follow example 9-2 and translate in to Pascal I came up the following code. It appears to do everything expected with a WDT in sleep or idle mode except resume the code after a WDTO. I have two loops one where the LED blinks slowly and a following loop with a Fast blink loop.
The "Wait" command is inserted between the two loops. I would have expected that after a WDTO that the IF RCON code would return execution immediately after the "Wait" command there cause the fast blink loop to be executed, but that does not happen.

I do not know whether my code is flawed implementing this "return" or my example simply is not suitable to show it is actually occurring. Here is my code modeled after the example 9-2.

If anyone has a working example I would greatly appreciate it if you would share your approach or equally if you spot errors in the code I attempted to duplicate in pascal.


program WatchDog_Timer;
// Based on Sample Code Example 9.2 page 9 Section 9. Watchdog Timer ands Power Up Timer
// for PIC32MX795f512L family
// With OSC in sleep or idle mode the WDT set for approx 8 sec should wake up and resume the code
//  execution immediately after the "Wait" cmd in the main code IF the MCU was in "Sleep" or "Idle" mode


var i:byte;

begin  //Main

  AD1PCFG := 0xFFFF;  // Configure AN pins as digital

  TRISB.RB13 := 0 ; // output mode for LED
  LATB.RB13  := 1; // Turn on LED

  // Unlock  OSCON Register
  SYSKEY    := 0x12345678;
  SYSKEY    := 0xAA996655;
  SYSKEY    := 0x556699AA;
  //OSCON Now Unlocked
//  OSCCONSET := 0x10; // set Power-Saving mode to Sleep mode when a "Wait" is encountered in main
 // in sleep mode  the LEDs will NOT blink because the Oscillator
 // is turned off and no code is executing.
 
  OSCCONSET := 0x00; // set Power-Saving mode to idle mode.  When in "Idle" mode and with  no  "Wait"
  // command in main code the slow LEDs loop will blink until the "wait" is encountered because Oscillator is still running  and
  // Program Counter is still stepping through the code causing the LEDs to blink
 // OSCCON.SLPEN := 1; // enable sleep mode (SLPEN) Will enter sleep Mode when a "Wait" instruction
       // is executed
  SYSKEY    := 0x12345678; // relock OSCCON
  //WDTCONCLR := 0x0002; // Disable WDT window mode
  WDTCONSET := 0x8000; // Enable WDT

   while 1 do   // endless while loop
      begin

 // Code restarts here but if in sleep or idle mode
 // The IF RCON code should cause it to resume after a
 // "Wait" in main loop - again IF in Sleep or Idle mode.

   //Start Up Code Area with WDT interrupt check and return code
    if (RCON AND 0x18) then  // wake from sleep mode (both WDTO and SLEEP bits set
         begin

            asm
               eret ; volatile
               nop
            end;
         RCON := 0; // clear for next attempt
         end;

     if (RCON AND 0x14) then   // if idle mode (both WDTO and IDLE bits set)
         begin
            asm
               eret  //; volatile
               nop
            end;
            RCON := 0; // clear for next attempt
         end;

  if (RCON AND 0x10) then
      begin

        // WDT Time out - may have been in Sleep or Idle mode
         RCON := 0; // clear for next attempt
      end;
   
    //. . . user code . . .
   
   // Two LED blink loops (one slow and one fast) with "Wait" command between the two
   // Should cause WDT to occur after Slow blink loop but before fast blink loop
   // the IF RCON AND 0x..bit command should return execution after the WDTO to
   // code right after the "Wait" Command and the fast blink should execute
   
      LATB.RB13 := 1; // Turn  LED ON
      i := 0;
      // SLOW BLINK LOOP
      repeat     // Slow Blink Loop LED blinks only if OSCCON.SLPEN = 0 (idle mode)
         LATB.RB13 := NOT(LATB.RB13);
         Delay_ms(250);
         i := i + 1;
      until i >= {11}21;
     
      delay_ms(500);

     WDTCONSET := 0x01; // Service the WDT - with this in loop WDT0 occurs after approx 16 sec with only
    // SLOW BLINK begin executed as the code hits the "WAIT" command before the FAST BLINK loop.
    // With WDTCSONSET commented out of the code
    // SLOW BLINK occurs then WDTO after approx 8 seconds and FAST BLINK again does not execute
    // This all occurs because after a WDTO code execution starts at the beginning.
    // Now if in sleep or idle mode and with the IF RCON AND 0xNN set is at the code start up then
    // according to the documentation, the code should jump to immediately after the "WAIT" commd, but
    // does not do that for me.
   
      // With Wait at this location fast blink loop should execute after a WDTO if in Sleep or Idle mode
     
      asm
         wait  // without this "wait" cmd, LEDs blink in both loops if OSCCON <> 0x10 not in sleep mode
              // with Wait 1st repeat loop blinks LED but not second loop
              // when OSCCON is in idle mode
         nop
      end;
     
      // . . . user Code . . .
      delay_ms(500);
     // code resumption should start here after interrupt from sleep or idle modes
     // and fast blink LED loop should execute
     // FAST BLINK LOOP
      i:=0;
      repeat  // Fast Blink Loop
         LATB.RB13 := NOT(LATB.RB13);
         delay_ms(70);
         i := i + 1;
      until i = 12;
 end; // while
end.

_________________
Rotary_Ed
Matthews, NC USA
Rv-6A N494BW Rotary Powered


Top
 Profile  
 
PostPosted: 14 Jan 2019 17:03 
Offline

Joined: 26 Dec 2004 23:10
Posts: 751
Location: Matthews, NC, USA
Well, some success after many attempts, but not yet what I wanted.

This code does reset after WDTO and then using a "goto" label command does jump past the "Wait" command in the code and resumes code execution. The SLOW Blink occurs then the "Wait" command holds the PC until a WDT reset occurs then the code resumes at the goto Label in the code and the FAST blink occurs.

However, looking at all the examples it would appear that the "erie" ASM command should cause the code to jump to a point after the "Wait" without a "goto" and label. But, I have been unable to make that happen.

My tentative conclusion is that the "erie" command may not work in Pascal and I am unaware of a subsitute

Does anyone successfully use 'erie' command in pascal??


program WatchDog_Timer;
// Based on Sample Code Example 9.2 page 9 Section 9. Watchdog Timer ands Power Up Timer
// for PIC32MX795f512L family
// With OSC in sleep or idle mode the WDT set for approx 8 sec should wake up and resume the code
//  execution immediately after the "Wait" cmd in the main code IF the MCU was in "Sleep" or "Idle" mode


// ***** IMPORTANT BOTH THE BOOTLOADER (if used) WDT DELAY AND THE PROGRAM CODE DELAY MUST BE THE SAME
// ***** OR THE DELAY IN THE BOOTLOADER WILL DOMINATE

var i:byte;
    ReStartHere:dword;
   
label GoHere;

begin  //Main

  AD1PCFG := 0xFFFF;  // Configure AN pins as digital

  TRISB.RB13 := 0 ; // output mode for LED - set for your own LED
  LATB.RB13  := 1; // Turnon for LED

 // WDT_Sleep_Mode_Enable
       syskey := 0x0;
       syskey := 0xAA996655;
       syskey := 0x556699AA;
       OSCCONSET := 0x10; // enable sleep mode
       syskey := 0x0;  //relock register
 
  if RCON AND 0x10 then  // Check and see if WDTO occured
    begin
      if RCON AND 0x18 then // if WDTO was MCU in Sleep Mode?
         begin

           {asm  // Could not get any ASM code to return to WDT interrput point
             //  jr ra
             //  eret ; volatile ??????????
               nop
            end;}
            RCONCLR := 0x1C;  // clear WDTO, Sleep and Idle bits
         goto GoHere; // Jumps to this point but asm code should cause PC to  jump automatically to code immediately past "WAIT"
         end;
  end;

  WDTCONCLR := 0x0002; // Disable WDT window mode
 // WDTCONSET := 0x0002; //enable WDT Window mode
  WDTCONSET := 0x8000; // Enable WDT
 
   while 1 do   // endless while loop
      begin

      WDTCONSET := 0x8000; // Enable WDT  placement here made it work
      //otherwise the code would only WDT reset twice and then stop.  Why only two times?


   // Two LED blink loops follow = one slow and one fast with "Wait" command between the two

      LATB.RB13 := 1; // Turn  LED ON
      i := 0;

      // SLOW BLINK LOOP
      repeat     // Slow Blink Loop LED
     
         LATB.RB13 := NOT(LATB.RB13);
         Delay_ms(250);
         i := i + 1;
         
      until i >= 21;

      delay_ms(500);
      // code waits here until WDT Reset
      asm
        wait; volatile
        nop
      end;
     
      delay_ms(500);
  //goto here after WDT reset
GoHere:  // Only jumps here due to GOTO command in RCON IF statement, but should not be needed
    // if working correctly
     // code resumption should start here after interrupt from sleep or idle modes
     // and fast blink LED loop should execute

     // FAST BLINK LOOP
      i:=0;
      repeat  // Fast Blink Loop
         LATB.RB13 := NOT(LATB.RB13);
         delay_ms(70);
         i := i + 1;
      until i = 13;

     delay_ms(500);

 end; // while
end.

_________________
Rotary_Ed
Matthews, NC USA
Rv-6A N494BW Rotary Powered


Top
 Profile  
 
PostPosted: 14 Jan 2019 17:28 
Offline
User avatar

Joined: 05 Mar 2018 09:44
Posts: 607
Location: Belgrade
Hi Ed,
I'll look into this.
Kind regards,
Petar


Top
 Profile  
 
PostPosted: 14 Jan 2019 17:52 
Offline

Joined: 26 Dec 2004 23:10
Posts: 751
Location: Matthews, NC, USA
Many thanks, Petar

As I mentioned, it all appears to work except the resumption of code execution after the "Wait" command. Since the IF RCON code in the example is straight forward it would seem the only thing to question is whether the "eret" command works in Pascal.

Ed

_________________
Rotary_Ed
Matthews, NC USA
Rv-6A N494BW Rotary Powered


Top
 Profile  
 
PostPosted: 14 Jan 2019 20:47 
Offline

Joined: 26 Dec 2004 23:10
Posts: 751
Location: Matthews, NC, USA
Hi Petar,

Just realized that when talking about the return I referred to 'erie' as the return cmd when I should have typed 'eret". That embarrassment :oops: aside, my code did have it correct as "eret' and that code did not work.

Sorry bout that

Ed

_________________
Rotary_Ed
Matthews, NC USA
Rv-6A N494BW Rotary Powered


Top
 Profile  
 
PostPosted: 15 Jan 2019 14:40 
Offline
User avatar

Joined: 05 Mar 2018 09:44
Posts: 607
Location: Belgrade
Hi Ed,
eret should work in Pascal without any issues.
I believe my college Filip has answered your question on helpdesk.

Kind regards,
Petar


Top
 Profile  
 
PostPosted: 15 Jan 2019 15:28 
Offline

Joined: 26 Dec 2004 23:10
Posts: 751
Location: Matthews, NC, USA
Hi Petar,

Yes, heard from Filip who repeated that eret does work. Unfortunately, I can not get the code to resume after the wait command using the eret. The fast blink LED code never appears to be executed as it simply burns stead and even the slow blink never operates again. That indicates to me that whatever the eret command does do, at least in my code, it does not appear to resume the code execution after the 'wait" command in the code. My goto function does appear to cause the WDT tp do exactly what I am looking for and that is to resume the code after Wait. However, that does require me to create a goto label and place it in the code. If my understanding of the WDT resume from sleep was correct (and assuming my code is) that is what I would expect the eret command to do. But, alas, I can not make it happen.

But, given that you and Filip assures me the eret function works properly in pascal, it must be my understanding and/or my code that is flawed. :(

I do thank you for your reponses.

Ed

_________________
Rotary_Ed
Matthews, NC USA
Rv-6A N494BW Rotary Powered


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 7 posts ] 

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 1 guest


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 post attachments in this forum

Search for:
Jump to: