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 CCS Technical Support

updated setup_wdt() function:

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



Joined: 08 Sep 2003
Posts: 92
Location: Glasgow, UK

View user's profile Send private message

updated setup_wdt() function:
PostPosted: Wed Sep 21, 2005 7:38 am     Reply with quote

Can someone out there tell me which issue the setup_wdt changed from (WDT_xMS) to (WDT_DIV_x)? Both the manual and the online help still show the old way? And I couldn't see a reference in the change history?

In the good old days, if you enabled the watchdog in the fuses - but didn't use setup_wdt(), it defaulted to 18mS. I Don't know what is happening now with the new setup, but if I enable the watchdog fuse and dont use setup_wdt, it seems to default to a value of about a couple of seconds? And NORMAL_POWER_UP is reported by restart_cause()? If I do use setup_wdt(WDT_DIV_65536), the programme never seems to start?

I am using 16F913; PCM v3.234; MPLab v7.20.

If I look at the listing file I can see..
Code:
119:   SETUP_WDT(WDT_DIV_65536);
   12C    3017     MOVLW 0x17
   12D    0098     MOVWF 0x18

Now my knowledge of .asm is poor, but is this not trying to write to a register at address 0x18 - which just happens to be RCSTA which is a USART register and nothing to do with the watchdog timer?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Sep 21, 2005 12:26 pm     Reply with quote

Can you post a full test program (but a short one), with the #fuses
statement, etc., that demonstrates the problem ? Then I can install
your version of the compiler and look at the .LST file.
adrian



Joined: 08 Sep 2003
Posts: 92
Location: Glasgow, UK

View user's profile Send private message

the saga continues....
PostPosted: Thu Sep 22, 2005 3:42 am     Reply with quote

PCM many thanks for you offer of help. I feel as if I am constantly banging my head on a brick wall over this one - I don't know if it is the 16F913 chip I am trying to use, or v3.234 of the compiler or a combination of both.

This version seems to be paticularly buggy, these are the faults (which have been acknowledged by CCs) that I have found in v3.234 so far:
I have managed to crash the compiler, but could not repeat it to show CCS Tech support.
*** Error 44 "C:\Program Files\.....\GP.c" Line 97(0,1): Internal Error - Contact CCS

This message is a reply to CCS e-mail id: 5I....
> The setup_comparator() has been fixed for the next release.

This message is a reply to CCS e-mail id: 5I....
Error in #fuses INTRC, will not compile with out edit NEEDS FIXING FOR THE NEXT ISSUE.
> You also did not make the change (edit) requested in 16F913.H so that is
> why you got the error.

This message is a reply to CCS e-mail id: 5I....
A reported problem with interrupts....
> The INT_RAx, INT_RB0, INT_RB1, INT_RB2, INT_RB3 are all an error
> and will be removed in the next release.

This message is a reply to CCS e-mail id: 5I....
Problems reported with restart_cause()....
> I notice that part has an extra bit in PCON. Maybe that is causing your problem.
> In the next version we will mask it off.

May I appologise at this point for the size of the 'short' test programme. I originally started using it to experiment with the newly extended reporting of restart_cause() - where I got into difficulties with the Watchdog function. If anyone has previous working code that uses restart_cause(), can they try it on this version as I think its broken - see footnotes below.

OK here is the code.
Code:

//point to Compiler PIC header file
      #include   "16F913.H"

//-------------------------- CONFIGURATION FUSES -------------------------------------\\
//Configuration Fuses for 16F913:
   #fuses   noDEBUG            //debug DISABLED.    
   #fuses   noFCMEN            //Falesafe Clock Monitor DISABLED.
   #fuses   noIESO            //Internal External Switch Over DISABLED.
   #fuses   BROWNOUT         //brownout detector ENABLED.
   #fuses   noCPD            //EEPROM data protection DISABLED.
   #fuses   noPROTECT         //code protection DISABLED.
   #fuses   MCLR            //external reset.
   #fuses   PUT               //power up timer ENABLED.
//   #fuses   noWDT            //internal watchdog DISABLED.
   #fuses   WDT               //internal watchdog ENABLED.
//   #fuses   INTRC            //clock out on PA6; PA7 available as digital I/O.  *needs edit to 16F913.h*
   #fuses   INTRC_IO         //Uses internal 8Mhz oscillator circuit.
                        //PA6 & PA7 available as digital I/O.
                        
//------------------------- PORT C DIGITAL CONFIGURATION -----------------------------\\
#byte      PORTC=         0X07      //port address
#define      PORTC_DDR      0b10100000   //set I/O direction
#define      PORTC_OUT      0b11000000   //initialise output state

////////////////////////////// CLOCK \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
//Declare internal Oscillator Frequency - all timing derived from this value
//needed to boost internal 8Mhz oscillator to get 57600 baud - with 0% error
//   #use    Delay(Clock=8294400,restart_wdt)
   #use    Delay(Clock=8294400)
   
///////////////////////////// HARDWARE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
//set RS232 pin allocation using hardware USART comms parameters
   #use    rs232(baud=57600,xmit=PIN_C6,rcv=PIN_C7,restart_wdt)

////////////////////// define GLOBAL VARIABLES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
//message sent over RS232 - see sign_on() - at end of initialising the hardware
#define   PRODUCT      "\n\r\n\rGP Controller ",restart_wdt()
#define   VERSION      "Test Software Ver 0.0\n\r",restart_wdt()

//----------------------- #INT_RDA variables ------------------------------\\
boolean      quit      = FALSE;
   
//point to prototype functions
      #include   "protypes.c"

#INT_RDA
void   serial_isr()
{
   int   received   =0;         //RS232 data
   
   received = getch();         //get character from RS232 stream
   printf("%c\n\r",received);   //print character
   quit = TRUE;            //set exit flag
}

///////////////////////////////////MAIN STARTS HERE\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
   
void MAIN   (void)
{
   //findout cause of re-start
      start_check();
      
   //enable interrupts
   enable_interrupts(INT_RDA);            //enable RS232 interrupt
   enable_interrupts(GLOBAL);            //make it so!
   
   while   (FALSE == quit)
   {
      cycle_relays();
   }
   
   //if it is a 'Q' then its time to quit
   //first turn off any relay outputs that may have been left on   
      printf("sleep\n\r");      //sign off
      delay_mS(100);            //need this delay to get "bye" printed   
}
//end of MAIN programme

Code:

//----------------------------- [PROTYPES.C] ----------------------------------\\

//////////////////////////////// FUNCTIONS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

//------------------------ RS232 sign on message ------------------------------\\
void   sign_on()
{
   //send message over RS232 to show that system is alive

   //product identifier
      printf(PRODUCT);      //defined in GP.h
   //software version
      printf(VERSION);      //defined in GP.h
}

void   cycle_relays()   //various pins on Port C
{
   //energise each relay in turn - used to show non-initialisation of SETUP_LCD
   //this disables relays RL2,RL3,RL4 as the pin function remains VLCD1 -> 3.

   //relay 1 on Port C bit 3
      output_high(PIN_C3);
      delay_mS(1000);

   //relay 2 on Port C bit 2
      output_high(PIN_C2);
      delay_mS(1000);

   //relay 3 on Port C bit 1
      output_high(PIN_C1);
      delay_mS(1000);

   //relay 4 on Port C bit 0
      output_high(PIN_C0);
      delay_mS(1000);

   //relay 5 on Port C bit 4
      output_high(PIN_C4);
      delay_mS(1000);

   //turn them off again using brute force
      PORTC   =   0x00;

      printf("Relay Test OK\n\r");
}

//--------------------- initialisation routines --------------------------\\
void   set_clock_speed()
{
   //set clock to ~8.2944Mhz
      SETUP_OSCILLATOR(OSC_8MHZ, 0x04);
}

void   re_initialise_hardware()
{
   //During certain types of reset, the I/O is
   //re-initialised as ALL inputs by the hardware.
   //Need to reconfigure the required I/O direction.
      set_tris_c(PORTC_DDR);

   //Also need to turn the LCD stuff off, as it disables RL2, RL3 & RL4.
      SETUP_LCD(LCD_DISABLED);
}

void   initialise_hardware()
{
   //INITIALISATION SEQUENCE

   //configure PORTC for digital operation
      //set direction of I/O pins - see GP.h for details
         set_tris_c(PORTC_DDR);
      //set output pins to required state - see GP.h for details
         PORTC = PORTC_OUT;

      //configure timer 0 - Watchdog
         SETUP_WDT(WDT_DIV_65536);

   //LCD - not used - ENABLED on power up!
      //disable the LCD drivers - which effect RL2, RL3 & RL4
         SETUP_LCD(LCD_DISABLED);

   //sign-on message over RS232
      sign_on();
}

void   start_check()
{
   //check to find out why programme restarted
   
   //extended options in v3.234
   switch ( restart_cause())   //CCS Function
   {
      case WDT_FROM_SLEEP:   //should never happen - never put to sleep
                        //initialise hardware
                           set_clock_speed();
                        //debug - send message over RS232
                           printf("wdt from sleep\n\r");
                           break;

      case WDT_TIMEOUT:      //should never happen - watchdog never activated
                        //initialise hardware
                           set_clock_speed();
                        //debug - send message over RS232
                           printf("wdt\n\r");
                           break;
                           
      //this case is recognised by the compiler but does not act on it?
      case MCLR_FROM_RUN:      //using MCLR pushbutton
                        //initialise hardware
                           set_clock_speed();
                           initialise_hardware();
                        //debug - send message over RS232
                           printf("reset\n\r");
                           break;
                           
      //indeterminate operation in v3.234 with a value of 19?
           //correct operation in v3.234 with a value of 16?      
      case MCLR_FROM_SLEEP:   //should never happen - never put to sleep
                        //initialise hardware
                           set_clock_speed();
                           re_initialise_hardware();
                        //debug - send message over RS232
                           printf("mclr from sleep\n\r");
                           break;

      case NORMAL_POWER_UP:   //this should always happen
     //also MCLR pushbutton   //initialise hardware
                           set_clock_speed();
                           initialise_hardware();
                        //debug - send message over RS232
                           printf("restarted\n\r",restart_wdt());
                           break;

      case BROWNOUT_RESTART:   //this can happen
                        //initialise hardware
                           set_clock_speed();
                           re_initialise_hardware();
                        //debug - send message over RS232
                           printf("brownout\n\r");
                           break;      
   }
}
//end of PROTYPES.C

Results seen so far.
1)If I use #fuses noWDT, and don't use SETUP_WDT(WDT_DIV_65536), the code runs as expected.
2)If I use #fuses noWDT, and use SETUP_WDT(WDT_DIV_65536), the code appears to do nothing. There are no printf messages being generated, and the cycle_relays() function does not run.
3)If I use #fuses WDT, and don't use SETUP_WDT(WDT_DIV_65536), the code runs as you would expect. It resets about every 2 seconds or so. N.B. the only place that I have used restart_wdt() is in the printf routines as I want to make sure I can see what is going on! Interestingly when the code restarts, restart_cause() reports the message generated by NORMAL_POWER_UP. This is why I think the new extended reporting of restart_cause() is also broken!
4)If I use #fuses WDT, and use SETUP_WDT(WDT_DIV_65536), the code appears to do nothing as per #2 above. I don't think it even watchdogs - but that is hard to detect if the printf routines are knobbled, and you can't use ICD2 in debug mode!

Now if SETUP_WDT() does something to the USART, which I originally suspected from...
> If I look at the listing file I can see..
>
> 119: SETUP_WDT(WDT_DIV_65536);
> 12C 3017 MOVLW 0x17
> 12D 0098 MOVWF 0x18
>
> Now my knowledge of .asm is poor, but is this not trying to write to a
> register at address 0x18 - which just happens to be RCSTA which is a USART
> register and nothing to do with the watchdog timer?
It might explain why my printf statements are being knobbled.

Further footnotes:
The new extended function restart_cause() is giving me grief. Here is what I have found so far.
#define NORMAL_POWER_UP: is OK as the #define has not changed between v3.233 & v3.234 and works as expected.

#define MCLR_FROM_SLEEP: has changed value from 16 to 19, and does not work as I expect. If I change the value back to 16 (in the header file whilst using v3.234), it works as expected? With a value of 16, I get the I/O functioning correctly, and the printf statement is generated. If I use a value of 19, the I/O is not initialised (left in the same state as a reset) and the printf statement is not generated. I have to assume from that, that the MCLR_FROM_SLEEP state is not being detected, as the relevant hardware setup and printf functions are not being actioned.
#define MCLR_FROM_RUN: is a new addition, (which I assume is detecting the /MCLR reset whilst the code is running?) compiles but does not seem to do anything? I get the same result as a 'normal power up' - verified by the printf statement?

#define BROWNOUT_RESTART: is a new addition, compiles but does not seem to do anything? The 16F913 did not hold itself in reset, even when the power was reduced to 3V3. However, it may be my settings in #fuses that are at fault?

#define WDT_TIMEOUT, and WDT_FROM_SLEEP: this is where i originally started.
adrian



Joined: 08 Sep 2003
Posts: 92
Location: Glasgow, UK

View user's profile Send private message

more thoughts
PostPosted: Thu Sep 22, 2005 10:29 am     Reply with quote

I have had a bit more time to think about this.

The watchdog oscillator runs from the internal 31Khz clock, and after a reset the timebase is set to 16mS. Running the code through the simulator, shows that by the end of the first printf statement, the time lapse is 11.16mS. I do not know, at which point the restart_wdt kicks in when #use rs232(baud=57600,xmit=PIN_C6,rcv=PIN_C7,restart_wdt) is used. Is it after each character of the printf string, or is it at the end of the printf string? So in theory, the watchdog shold be kicked during the printf statement, and timeout during the cycle_relays() function - which seems to happen if SETUP_WDT(WDT_DIV_65536) is NOT used.

If the printf operation is getting knobbled by SETUP_WDT(WDT_DIV_65536), it might explain why I don't see anything happening as the restart_wdt is never called?

Anybody got any further thoughts ?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Sep 22, 2005 11:11 am     Reply with quote

Can you state your goal ? Post a short program, of just a few lines
(without all the diagnostic code) that shows what you want to do.
The program should be compilable, that is, it should have the #include
statement, #use statements, and #fuse statement.
adrian



Joined: 08 Sep 2003
Posts: 92
Location: Glasgow, UK

View user's profile Send private message

PostPosted: Thu Sep 22, 2005 11:41 am     Reply with quote

PCM programmer wrote:
Can you state your goal ?

OK I'll try.
First off I am sure that restart_cause() has been broken in v3.234. I was using this functions existing options before moving onto experimenting with the new options that v3.234 introduced. I know that MCLR_FROM_SLEEP no longer works, and was moving on to checkout the WDT_TIMEOUT, and WDT_FROM_SLEEP which are two of the existing options that should also work. Whilst investigating this I came across the problem with SETUP_WDT().

I am about to give up on v3.234 and revert back to v3.233 and see if that is any better.
adrian



Joined: 08 Sep 2003
Posts: 92
Location: Glasgow, UK

View user's profile Send private message

sorted!
PostPosted: Fri Sep 23, 2005 7:53 am     Reply with quote

I have finally worked out what is wrong! As I surmised, SETUP_WDT is wrong. This has been confirmed by CCS

This message is a reply to CCS e-mail id: 5I....
There is an error in the setup_wdt() function for the 9xx chips. It will be fixed in version 3.235.

I found that the WDTCON register was not being written to. I also tried to use SETUP_COUNTERS(), but could not find a method of assigning the prescaler to the watchdog, rather than Timer0. In the end I did it myself by writing to the OPTION_REG, to set the prescaler to maximum and assign it to the watchdog. Then wrote to WDTCON with the watchdog value.
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