|
|
View previous topic :: View next topic |
Author |
Message |
ntgcp_08
Joined: 21 Feb 2008 Posts: 24
|
CCS Bootloader Problem |
Posted: Thu Sep 18, 2008 3:44 pm |
|
|
I'm using processor 18LF6722
Clock is 4MHz
compiler version is PCH V4.066
I'm trying to implement a bootloader in my project but I've had little luck so far. The program just doesn't run. When I take the bootload stuff out, things function.
Here is my program stripped down as much as possible:
Main program - bootloader.c
Code: |
#include "C:\Documents and Settings\kerrj\My Documents\Firmware\Bootloader\bootloader.h"
#include "C:\Documents and Settings\kerrj\My Documents\Firmware\Bootloader\bootloader_bootloader.h"
//BOOTLOADER AT START - Include Bootloader.h in your application - See sample application Ex_Bootload.c
//BOOTLOADER AT END - Always include the projectname_bootloader.h file in future versions of the project
void application(void) {
while(TRUE){
fprintf(DEBUG232, "Version 1.00\r\n");
delay_ms(1000);
if(!input(PushButton)){
write_eeprom(EE_ENTER_BOOTLOADER, 0xAA);
reset_CPU();
}
}
}
void main()
{
setup_adc_ports(NO_ANALOGS|VSS_VDD);
setup_adc(ADC_OFF|ADC_TAD_MUL_0);
setup_psp(PSP_DISABLED);
setup_spi(SPI_SS_DISABLED);
setup_spi2(SPI_SS_DISABLED);
setup_wdt(WDT_OFF);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_8); // 524mS /tick
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
setup_timer_4(T4_DIV_BY_16,240,13); //50.1 mS timer
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
setup_low_volt_detect(FALSE);
setup_oscillator(false);
SET_TRIS_A(TRIS_A_SETTING);
SET_TRIS_B(TRIS_B_SETTING);
SET_TRIS_C(TRIS_C_SETTING);
SET_TRIS_D(TRIS_D_SETTING);
SET_TRIS_E(TRIS_E_SETTING);
SET_TRIS_F(TRIS_F_SETTING);
SET_TRIS_G(TRIS_G_SETTING);
enable_interrupts(GLOBAL);
ext_int_edge( 2, H_TO_L);
ext_int_edge( 3, H_TO_L);
output_bit(XMIT_PWR_ON,1); // xmitter on
output_bit(LED1_ON,1); // xmitter on
delay_ms(2000);
if(read_eeprom(EE_ENTER_BOOTLOADER) == 0xAA)
{
output_bit(LED1_ON,0); // xmitter on
fprintf(DEBUG232, "Bootloader!!!\r\n");
real_load_program();
}
application();
}
|
bootloader.h
Code: |
#include <18F6722.h>
#device adc=10
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES HS //High speed Osc (> 4mhz)
#FUSES NOPROTECT //Code not protected from reading
#FUSES IESO //Internal External Switch Over mode enabled
#FUSES BROWNOUT //Reset when brownout detected
#FUSES BORV25 //Brownout reset at 2.5V
#FUSES NOPUT //No Power Up Timer
#FUSES NOCPD //No EE protection
#FUSES STVREN //Stack full/underflow will cause reset
#FUSES NODEBUG //No Debug mode for ICD
#FUSES LVP //Low Voltage Programming on B3(PIC16) or B5(PIC18)
#FUSES NOWRT //Program memory not write protected
#FUSES NOCPB //No Boot Block code protection
#FUSES NOEBTRB //Boot block not protected from table reads
#FUSES NOEBTR //Memory not protected from table reads
#FUSES NOWRTD //Data EEPROM not write protected
#FUSES NOWRTC //configuration not registers write protected
#FUSES NOWRTB //Boot block not write protected
#FUSES FCMEN //Fail-safe clock monitor enabled
#FUSES LPT1OSC //Timer1 configured for low-power operation
#FUSES MCLR //Master Clear pin enabled
#FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#FUSES BBSIZ1K //1K words Boot Block size
#use delay(clock=4000000)
#define EE_ENTER_BOOTLOADER 357
#define TRIS_A_SETTING 0xcF
#define TRIS_B_SETTING 0x7F
#define TRIS_C_SETTING 0x90
#define TRIS_D_SETTING 0x08
#define TRIS_E_SETTING 0x18
#define TRIS_F_SETTING 0x00
#define TRIS_G_SETTING 0x24
#define PushButton PIN_B4 // input 1
#define MESH_TX PIN_C6 // output 0
#define MESH_RX PIN_C7 // input 1
#define SATGSM_TX PIN_G1 // input 0
#define SATGSM_RX PIN_G2 // input 1
#define DEBUG_TX PIN_E2 // output 0
#define DEBUG_RX PIN_E3 // input 1
#define XMIT_PWR_ON PIN_D1 // output 0
#define LED1_ON PIN_F3 // output 0
#use rs232(baud=9600,parity=N,xmit=MESH_TX,rcv=MESH_RX,bits=8,restart_wdt,STREAM=MESH232,errors)
#use rs232(baud=9600,parity=N,xmit=SATGSM_TX,rcv=SATGSM_RX,bits=8,restart_wdt,STREAM=SATGSM232,errors)
#use rs232(baud=9600,parity=N,xmit=DEBUG_TX,rcv=DEBUG_RX,bits=8,restart_wdt,STREAM=DEBUG232, DISABLE_INTS)
|
bootloader_bootloader.h
Code: |
//bootloader code
// APPLICATION_ISR_VECTOR - Where the compiler is going to put the ISR
#define FIRMWARE_UPGRADE_VECTOR 0 // Bootloader at Start of memory
#define MAX_UPGRADE_AREA (0x500) // Space required by bootloader
#define MIN_FIRMWARE_UPGRADE_MEMORY_AREA (0x20) // Start of bootloder code
#define MAX_FIRMWARE_UPGRADE_MEMORY_AREA (MAX_UPGRADE_AREA-1) // End of bootloder code
#define APPLICATION_RESET_VECTOR 0x500 // New RESET Vector
#define APPLICATION_ISR_VECTOR 0x508 // New Interrupt Vector
// Re-vectored RESET vector from 0x0000 to 0x0500
// Re-vectored Interrupt vector from 0x0008 to 0x0508
#build(reset=APPLICATION_RESET_VECTOR, interrupt=APPLICATION_ISR_VECTOR)
#define LOADER_END MAX_UPGRADE_AREA -1
#define LOADER_ADDR MIN_FIRMWARE_UPGRADE_MEMORY_AREA
#define BUFFER_LEN_LOD 64
int buffidx;
char buffer[BUFFER_LEN_LOD];
#define ACKLOD 0x06
#define XON 0x11
#define XOFF 0x13
#SEPARATE
unsigned int atoi_b16(char *s);
#ORG LOADER_ADDR+10, LOADER_END auto=0 default
void real_load_program (void)
{
int1 do_ACKLOD, done=FALSE;
int8 checksum, line_type;
int16 l_addr,h_addr=0;
int32 addr;
#if getenv("FLASH_ERASE_SIZE")>2
int32 next_addr;
#endif
int8 dataidx, i, count;
int8 data[32];
while (!done) // Loop until the entire program is downloaded
{
buffidx = 0; // Read into the buffer until 0x0D ('\r') is received or the buffer is full
do {
buffer[buffidx] = getc(SATGSM232);
} while ( (buffer[buffidx++] != 0x0D) && (buffidx <= BUFFER_LEN_LOD) );
putchar (XOFF, SATGSM232); // Suspend sender
do_ACKLOD = TRUE;
// Only process data blocks that start with ':'
if (buffer[0] == ':') {
count = atoi_b16 (&buffer[1]); // Get the number of bytes from the buffer
// Get the lower 16 bits of address
l_addr = make16(atoi_b16(&buffer[3]),atoi_b16(&buffer[5]));
line_type = atoi_b16 (&buffer[7]);
addr = make32(h_addr,l_addr);
#if defined(__PCM__) // PIC16 uses word addresses
addr /= 2;
#endif
// If the line type is 1, then data is done being sent
if (line_type == 1) {
done = TRUE;
#if defined(__PCM__)
} else if ((addr < LOADER_ADDR || addr > LOADER_END) && addr < 0x2000){
#elif defined(__PCH__)
} else if ((addr < LOADER_ADDR || addr > LOADER_END) && addr < 0x300000){
#endif
checksum = 0; // Sum the bytes to find the check sum value
for (i=1; i<(buffidx-3); i+=2)
checksum += atoi_b16 (&buffer[i]);
checksum = 0xFF - checksum + 1;
if (checksum != atoi_b16 (&buffer[buffidx-3]))
do_ACKLOD = FALSE;
else {
if (line_type == 0) {
// Loops through all of the data and stores it in data
// The last 2 bytes are the check sum, hence buffidx-3
for (i = 9,dataidx=0; i < buffidx-3; i += 2)
data[dataidx++]=atoi_b16(&buffer[i]);
#if getenv("FLASH_ERASE_SIZE") > getenv("FLASH_WRITE_SIZE")
#if defined(__PCM__)
if ((addr!=next_addr)&&(addr&(getenv("FLASH_ERASE_SIZE")-1)!=0))
#else
if ((addr!=next_addr)&&(addr&(getenv("FLASH_ERASE_SIZE")/2-1)!=0))
#endif
erase_program_eeprom(addr);
next_addr = addr + 1;
#endif
write_program_memory(addr, data, count);
}
else if (line_type == 4)
h_addr = make16(atoi_b16(&buffer[9]), atoi_b16(&buffer[11]));
}
}
}
if (do_ACKLOD)
putchar (ACKLOD, SATGSM232);
putchar(XON, SATGSM232);
}
putchar (ACKLOD, SATGSM232);
putchar(XON, SATGSM232);
write_eeprom(EE_ENTER_BOOTLOADER, 0x00);
#ifndef _bootloader
reset_cpu();
#endif
}
unsigned int atoi_b16(char *s) { // Convert two hex characters to a int8
unsigned int result = 0;
int i;
for (i=0; i<2; i++,s++) {
if (*s >= 'A')
result = 16*result + (*s) - 'A' + 10;
else
result = 16*result + (*s) - '0';
}
return(result);
}
|
I assume the issue is how I have the RESET vector and the Interrupt vector "re-vectored". The bootload portion of the code came directly from the CCS PIC Wizard. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Sep 18, 2008 4:12 pm |
|
|
I didn't look at your code in detail, but the line above will cause problems.
Change it to NOLVP. |
|
|
ntgcp_08
Joined: 21 Feb 2008 Posts: 24
|
|
Posted: Thu Sep 18, 2008 4:19 pm |
|
|
Oops, somehow my #fuses changed... here is what I'm using. The program still does not function
Code: |
#FUSES HS //External Oscillator using HS
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOIESO //Internal External Switch Over mode enabled
#FUSES BROWNOUT //Reset when brownout detected
#FUSES BORV25 //Brownout reset at 2.0V
#FUSES PUT //Power Up Timer
#FUSES NOCPD //No EE protection
#FUSES STVREN //Stack full/underflow will cause reset
#FUSES NODEBUG
#FUSES NOLVP //Low Voltage Programming on B3(PIC16) or B5(PIC18)
#FUSES NOWRT //Program memory not write protected
#FUSES NOCPB //No Boot Block code protection
#FUSES NOEBTRB //Boot block not protected from table reads
#FUSES NOEBTR //Memory not protected from table reads
#FUSES NOWRTD //Data EEPROM not write protected
#FUSES NOWRTC //configuration registers not write protected
#FUSES NOWRTB //Boot block not write protected
#FUSES NOFCMEN //Fail-safe clock monitor enabled
#FUSES NOLPT1OSC //Timer1 configured for low-power operation
#FUSES MCLR //Master Clear pin enabled
#FUSES NOXINST //Extended set extension and Indexed Addressing mode enabled
#FUSES BBSIZ1K |
|
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Thu Sep 18, 2008 6:37 pm |
|
|
Your code has only one line with #org in it. There is at least a second #org required to mark the end of the bootloader section.
I don't have time to look into it now but if you compare the original generated code to what you have now you should easily spot the now missing '#org', or '#org default'. |
|
|
ntgcp_08
Joined: 21 Feb 2008 Posts: 24
|
|
Posted: Fri Sep 19, 2008 8:34 am |
|
|
Using the PIC Wizard the #ORG that is in bootloader_bootloader.h is the only #ORG that was added.
I went through ex_bootloader.c to see where it has #ORG statements.
My bootloader.c now looks like this:
Code: |
#ORG 0x0640, 0xFFFF
void application(void) {
while(TRUE){
fprintf(DEBUG232, "Version 1.00\r\n");
delay_ms(1000);
if(!input(PushButton)){
write_eeprom(EE_ENTER_BOOTLOADER, 0xAA);
reset_CPU();
}
}
}
#org 0x528, 0x63F
void main()
{
setup_adc_ports(NO_ANALOGS|VSS_VDD);
setup_adc(ADC_OFF|ADC_TAD_MUL_0);
setup_psp(PSP_DISABLED);
setup_spi(SPI_SS_DISABLED);
setup_spi2(SPI_SS_DISABLED);
setup_wdt(WDT_OFF);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_8); // 524mS /tick
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
setup_timer_4(T4_DIV_BY_16,240,13); //50.1 mS timer
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
setup_low_volt_detect(FALSE);
setup_oscillator(false);
SET_TRIS_A(TRIS_A_SETTING);
SET_TRIS_B(TRIS_B_SETTING);
SET_TRIS_C(TRIS_C_SETTING);
SET_TRIS_D(TRIS_D_SETTING);
SET_TRIS_E(TRIS_E_SETTING);
SET_TRIS_F(TRIS_F_SETTING);
SET_TRIS_G(TRIS_G_SETTING);
enable_interrupts(GLOBAL);
ext_int_edge( 2, H_TO_L);
ext_int_edge( 3, H_TO_L);
output_bit(XMIT_PWR_ON,1); // 5V Power On
output_bit(LED1_ON,1); // LED on
delay_ms(2000);
if(read_eeprom(EE_ENTER_BOOTLOADER) == 0xAA)
{
output_bit(LED1_ON,0); // LED off
fprintf(DEBUG232, "Bootloader!!!\r\n");
real_load_program();
}
application();
}
#ORG default |
I also added an #ORG Default to the end of bootloader_bootloader.h
However, I still have no luck.
So now, I believe my memory map looks like the following... correct?
0x0000 to 0x0029 - Nothing
0x002A to 0x04FF - Bootloader
0x0500 to 0x0507 - Reset Vector
0x0508 to 0x0527 - Interrupt Service Routine
0x0528 to 0x063F - Main
0x0640 to 0xFFFF - Application |
|
|
ntgcp_08
Joined: 21 Feb 2008 Posts: 24
|
|
Posted: Fri Sep 19, 2008 10:33 am |
|
|
OK, I've got it working...
How I got it working??? I followed the ex_bootloader.c exacty how it was written. I didn't try using the PIC Wizard. |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Thu Sep 25, 2008 1:28 am |
|
|
As a late comment:
Code: | 0x0000 to 0x0029 - Nothing |
can't be correct. The region has to hold the primary reset and interrupt handler. |
|
|
|
|
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
|