|
|
View previous topic :: View next topic |
Author |
Message |
adrian
Joined: 08 Sep 2003 Posts: 92 Location: Glasgow, UK
|
updated setup_wdt() function: |
Posted: Wed Sep 21, 2005 7:38 am |
|
|
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
|
|
Posted: Wed Sep 21, 2005 12:26 pm |
|
|
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
|
the saga continues.... |
Posted: Thu Sep 22, 2005 3:42 am |
|
|
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
|
more thoughts |
Posted: Thu Sep 22, 2005 10:29 am |
|
|
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
|
|
Posted: Thu Sep 22, 2005 11:11 am |
|
|
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
|
|
Posted: Thu Sep 22, 2005 11:41 am |
|
|
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
|
sorted! |
Posted: Fri Sep 23, 2005 7:53 am |
|
|
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. |
|
|
|
|
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
|