View previous topic :: View next topic |
Author |
Message |
hillcraft
Joined: 22 Sep 2003 Posts: 101 Location: Cape Town (South africa)
|
18F458 bootloader CCS Ver 3.202 |
Posted: Mon Jun 14, 2004 2:56 pm |
|
|
I have done the proper thing and renewed my Maintenance contract so as to obtain the bootloader examples from ver 3.202.
The bootloader certainly works much better - but I still have a problem with getc() within the application if the loader resets the processor.
I can reset the processor within the app and switch back to the bootloader and getc() continues to work. (I do set a hell of a lot of register states back to their boot state before the reset_cpu() is issued) - Doing this does not work when the loader reboots the processor and goes to the app.
I have found that if I put a getc() inside the bootloader just before the app is started from the loader then the getc works inside the app after the loader has rebooted the processor.
If I reboot the processor manually then getc() is a-ok.
I have tried various options of resetting registers to their start up values and I have also tried setting the UART registers to their proper settings before the reboot. I have also tried the ERRORS statement and also to move the #USE RS232 ... from the bootloader.c to loader.c
I just cannot see the answer - Any Ideas?
#include <18F458.h>
// used to reset to power-up defaults for bootloader reentry.
#fuses HS,NOPUT,NOBROWNOUT,NOWDT,NOLVP,PROTECT,CPB,WRTB
#use delay(clock=20000000)
// defines required to reset the serial uart after reboot
#byte TRISC = 0xF94
#bit trisc7 = TRISC.7
#bit trisc6 = TRISC.6
#byte TXSTA = 0xFAC
#bit sync = TXSTA.4
#bit brgh = TXSTA.2
#bit txen = TXSTA.5
#byte SPBRG = 0xFAF
#byte RCSTA = 0xFAB
#bit spen = RCSTA.7
#bit cren = RCSTA.4
#define _bootloader
#use rs232(baud=19200, xmit=PIN_C6, rcv=PIN_C7,ERRORS,STREAM=PORT_PC)
#define AddrLoadLoader 0x01
#include <bootloader.h>
#include "loader.c"
#org LOADER_END+2,LOADER_END+20
void application(void) {
while(TRUE);
}
#org 0x40,0xB6 // 0xB6 will be too low if the getc() is included
// if the first EE address is 'L' then we must run the bootloader
void main(void) {
byte LoadLoader;
LoadLoader = read_eeprom(AddrLoadLoader);
// go into the bootolar the first time the bootloader is installed
// or if the register is set to 'L'
if ((LoadLoader==0xFF) || (LoadLoader==0x00) || (LoadLoader=='L')) {
// output white
output_low(PIN_E0); // red
output_low(PIN_E1); // green
output_low(PIN_E2); // blue
load_program();
trisc6 = 1; // make tx (term 25 an input)
trisc7 = 1; // rx (term 26) input
sync = 0; // asynchronous
brgh = 1 ; // baud rate generator high speed
SPBRG = 64; // 19200 @ 20.0 MHz clock
spen = 1; // serial port enabled
txen = 1; // as appropriate
cren = 1;
// output yellow by dimming out blue
output_high(PIN_E2); // blue
/* i have tried to set the following here (This does not work either)
#ASM
MOVLW 0
MOVWF PCLATH
RESET
#ENDASM
*/
reset_cpu();
}
else {
// getc(); here seems to do the trick for some reason
application();
}
}
#ORG default
#if defined(__PCM__)
#int_global
void isr(void) {
#asm
goto LOADER_END+5
#endasm
}
#elif defined(__PCH__)
#int_global
void isr(void) {
#asm
goto LOADER_END+7
nop
nop
nop
nop
nop
nop
goto LOADER_END+0x17
#endasm
}
#endif |
|
|
Neutone
Joined: 08 Sep 2003 Posts: 839 Location: Houston
|
|
Posted: Mon Jun 14, 2004 3:35 pm |
|
|
Why do you have this,
Code: | sync = 0; // asynchronous
brgh = 1 ; // baud rate generator high speed
SPBRG = 64; // 19200 @ 20.0 MHz clock
|
It's my understanding that the USART can be configured with brgh equal 1 or 0 and still keep the same baud rate. Your mixing function calls with low level access of the hardware. Maybe you problem is related to this. |
|
|
hillcraft
Joined: 22 Sep 2003 Posts: 101 Location: Cape Town (South africa)
|
A matter of trying everything |
Posted: Mon Jun 14, 2004 3:49 pm |
|
|
Those lines come from PHAnderson's Serial initialization routine. They were put in purely to try and see if they correct the problem that I am experiencing.
The same result occurs if those lines are not in the app.
I have read through the posts regarding this problem and they all come back to the fact that the bootloader leaves some registers in an improper state when the device is rebooted inside the bootloader.
I have gone as far a declaring every single special register and setting it to its expected cold boot value - (with no improvement)
I have also tried to clear out any garbage in the recieve register.
I must say that I have not tried to analize exactly how getc() works - maybe the answer is to be found inside assembler code of this function. |
|
|
Guest
|
|
Posted: Mon Jun 14, 2004 7:31 pm |
|
|
try adding this:
CREN=0; delay_us(2); // clear RS232 receive error
the following is my code to reset RS232
Code: | #bit OERR = RCSTA.1 // overrun
#bit CREN = RCSTA.4 // enable
void check_and_reset_HW_RS232(void)
{
if ( OERR ) // RS232 receiver buffer full !
{
CREN=0; delay_us(2); // clear RS232 receive error
CREN=1; // restart RS232, clear buffer!
}
}
|
|
|
|
|