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

Problem with PIC18F4685 Bootloader

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



Joined: 31 Oct 2008
Posts: 17

View user's profile Send private message

Problem with PIC18F4685 Bootloader
PostPosted: Sat Nov 14, 2009 7:05 pm     Reply with quote

Hello,

I am trying to use the bootloader functionality for the first time, but I am having little luck with it.

Since I couldn't make heads or tails of the ex_bootloader.c / ex_bootload.c in the "examples" folder, I used the Wizard to create the attached code.

One minor change I made is to place the PIC into bootloader mode when RC0 is HIGH - I have a PB switch on my board that is pulls RC0 high when pressed (otherwise C0 is low via a 10K resistor)

The problem I'm having is that when I run the code below, the PIC either freezes, or I get a message from SIOW - "Timeout while downloading".

I looked through the forums for similar posts and found only one but the solution turned out to be replacing a bad MAX232 IC - my MAX232 was thoroughly tested in both directions and works fine.

If I comment out the
#include "C:\boot_test\boot_test_bootloader.h"
the PIC starts up OK.

Commenting out
//real_load_program();
does not prevent PIC freezing

I am using a PIC18F4685
with PCH 4.083
Running at 5Vdc at 40MHz (Via external oscillator)

boot_test.c (Main File)
Code:

#include "C:\boot_test\boot_test.h"
#include "C:\boot_test\boot_test_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

// NOTE - User must include PROJECTNAME_bootloader.C in his final Application program

void main()
{// Enter Bootloader if Pin B5 is low after a RESET
   if(input(PIN_C0))
   {
      real_load_program();
   }

   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_wdt(WDT_OFF);
   setup_timer_0(RTCC_INTERNAL);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
//Setup_Oscillator parameter not selected from Intr Oscillator Config tab

   while(TRUE)
  {
   output_high(PIN_B4); //LED ON
   delay_ms(50);
   output_high(PIN_B4); //LED OFF
   delay_ms(50);
  }

   // TODO: USER CODE!!

}


boot_test.h
Code:

#include <18F4685.h>
#device adc=8

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES WDT128                   //Watch Dog Timer uses 1:128 Postscale
#FUSES HS                       //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOBROWNOUT               //No brownout reset
#FUSES BORV20                   //Brownout reset at 2.0V
#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 NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOWRT                    //Program memory not write protected
#FUSES NOWRTD                   //Data EEPROM not write protected
#FUSES IESO                     //Internal External Switch Over mode enabled
#FUSES FCMEN                    //Fail-safe clock monitor enabled
#FUSES PBADEN                   //PORTB pins are configured as analog input channels on RESET
#FUSES BBSIZ4K                  //4K words Boot Block size
#FUSES NOWRTC                   //configuration not registers write protected
#FUSES NOWRTB                   //Boot block not write protected
#FUSES NOEBTR                   //Memory not protected from table reads
#FUSES NOEBTRB                  //Boot block not protected from table reads
#FUSES NOCPB                    //No Boot Block code protection
#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)

#use delay(clock=40000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)


boot_test_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();
      } while ( (buffer[buffidx++] != 0x0D) && (buffidx <= BUFFER_LEN_LOD) );

      putchar (XOFF);  // 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);

      putchar(XON);
   }

   putchar (ACKLOD);
   putchar(XON);
   #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);
}
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