|
|
View previous topic :: View next topic |
Author |
Message |
Guest
|
write_eeprom() hangs program when WDT is enabled |
Posted: Fri Nov 27, 2009 11:41 pm |
|
|
Hi All,
I am using PCML V4.095 with a PIC16F690.
Program I am working on is in final stages - passed all tests and debugging and I am in the process of enabling the watchdog for production - so the code before enabling the WDT works fine under all conditions.
I have a hard coded sleep() at the end of the main infinite loop as the chip spends most of its time asleep. I want the WDT to be on while the chip is awake and not when it is asleep - so from manuals and datasheets, easiest way seems to be to use software with setup_wdt().
All good so far - except the whole thing hangs when it hits a write_eeprom() function.
I have debugged this for hours and have managed to narrow it down to this function in a couple of spots - both in the main loop and inside an ISR. Put a setup_wdt(WDT_OFF) before the write_eeprom() and a setup_wdt(WDT_ON) after, and the program behaves.
So I guess, in a way I have fixed it - but my question to those with more experience with the CCS compiler is why??
Is this a bug, or am I configuring something wrong:
Code: | #fuses INTRC_IO, NOWDT, NOPROTECT |
when I enter main() is set wdt up with:
Code: | setup_wdt(WDT_2304MS); |
and at the top of the infinite loop:
Code: | setup_wdt(WDT_ON);
restart_wdt(); |
Some clarity from a greater mind than mine would be greatly appreciated.
Cheers,
Nigel |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Nov 28, 2009 2:00 am |
|
|
1. How do you know that it hangs on that line ? What method are you
using to determine that ?
2. Are you using a hardware debugger (ICD-U40 or ICD2, etc.) ?
If so, are you using the special 16F690-ICD header board ?
Are you single-stepping through the code or using breakpoints ?
3. Ideally, you would post a stripped-down (but compilable) program
that shows the problem, but with the smallest possible amount of code. |
|
|
Guest
|
|
Posted: Sat Nov 28, 2009 2:49 pm |
|
|
Thanks for getting back PCM Programmer,
I am using printf's each step through the code. Not using a hardware debugger.
Sunday here in Oz and She Who Must Be Obeyed has banned me from working.
After sleeping on it, I am sure I must be doing something wrong - it doesn't make sense otherwise - will write some test routines tomorrow to see if I can reproduce the problem with a small chunk of code.
Will get back to you with the results.
Thanks,
Nigel |
|
|
big_nige Guest
|
|
Posted: Mon Nov 30, 2009 3:41 am |
|
|
Hi PCM Programmer,
Here is the smallest compilable chunk of code that produces the error. Realise that I could OR the setup_wdt commands, but that is not how they will be used in my program as the WDT is turned on and off in the main routine.
#include <16F690.h>
#fuses INTRC_IO,NOWDT,NOPROTECT
#use delay(clock=4000000, RESTART_WDT)
#use rs232(uart1, baud=57600, ERRORS, RESTART_WDT)
#use i2c(i2c1, master, FAST=400000)
void main() {
printf("in main\r\n");
setup_wdt(WDT_2304MS);
setup_wdt(WDT_ON);
delay_ms(1000);
while (TRUE) {
printf("start main loop\r\n");
output_high(PIN_C1);
delay_ms(1500);
output_low(PIN_C1);
delay_ms(1500);
printf("end of flash\r\n");
restart_wdt();
write_eeprom(0x00, 0xAF);
printf("%x written to eeprom\r\n", read_eeprom(0x00));
}
}
If you comment out the WDT setup "AF written to eeprom" gets printed out. If you enable them (as shown), it prints:
in main
start main loop
end of flash
and then starts to repeat, without getting to the other side of the write_eeprom.
Sorry about the 'hangs' in the subject text, it is not actually hanging the program, it is just resetting without executing the write_eeprom.
I am using the Microchip low pin count protoboard - hence the outputs to C1. They are mainly to test that the config for delay_ms is working.
#include <16F690.h>
#fuses INTRC_IO,NOWDT,NOPROTECT
#use delay(clock=4000000, RESTART_WDT)
#use rs232(uart1, baud=57600, ERRORS, RESTART_WDT)
#use i2c(i2c1, master, FAST=400000)
void main() {
printf("in main\r\n");
setup_wdt(WDT_2304MS);
setup_wdt(WDT_ON);
delay_ms(1000);
while (TRUE) {
printf("start main loop\r\n");
output_high(PIN_C1);
delay_ms(1500);
output_low(PIN_C1);
delay_ms(1500);
printf("end of flash\r\n");
restart_wdt();
write_eeprom(0x00, 0xAF);
printf("%x written to eeprom\r\n", read_eeprom(0x00));
}
} |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Nov 30, 2009 2:30 pm |
|
|
Code: |
.................... setup_wdt(WDT_ON);
002F: MOVLW 01
0030: BSF 03.5
0031: MOVWF 17 // Set WDTCON = 0x01
0032: BTFSS 01.3 // Is PSA assigned to WDT ?
0033: GOTO 037
0034: BCF 01.0 // If so, set pre-scaler to 1:1
0035: BCF 01.1
0036: BCF 01.2
|
The problem is caused by using WDT_ON alone, as the parameter.
It sets both pre-scalers to the minimum value, which results in a
WDT timeout period of about 1 ms. The write_eeprom() operation
takes 4 or 5 ms. That's why it's doing a WDT reset. When you
use WDT_ON alone, it over-writes your previous setting of 2304 ms.
You should enable the WDT by doing this:
Code: | setup_wdt(WDT_2304MS); |
and turn it off by doing this:
Code: | setup_wdt(WDT_OFF); |
|
|
|
big_nige
Joined: 30 Nov 2009 Posts: 7
|
|
Posted: Tue Dec 01, 2009 12:21 am |
|
|
aaahh - It all becomes clear
Thanks for the advice - much appreciated.
Cheers,
Nigel |
|
|
|
|
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
|