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 support@ccsinfo.com

#INT_TBE not working with Bootloader
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
RickDaystorm



Joined: 01 Jul 2012
Posts: 12

View user's profile Send private message

#INT_TBE not working with Bootloader
PostPosted: Sun Jul 01, 2012 5:08 pm     Reply with quote

Hello,

I’m having a problem with an interrupt not working in a boot-loaded program.

In my main program I have a routine that continuously sends out a 17-byte message to an LCD screen using RS485. When I compile the main program without the #include usb_bootloader.h and load it directly onto the target using the ICD (using the ICD button set up with "\ccsload.exe" "-T%H" "%D") everything works perfectly fine. However, when I recompile it with the start offset and load it in using the bootloader , the #INT_TBE interrupt never fires, but everything else works perfectly.

I can’t figure out what is so special about this interrupt when all the other interrupts work fine in either case.

I am using a PIC18F6722 running at 40MHz clocked from an external oscillator and I am using CCS PCH C Compiler, Version 4.083. VDD is 5V and I have a 47K between MCLR and VDD. I am not set up for using the debugger.

The bootloader code is the standard CCS example that I modified to work with an FTDI 245RL converter. After I load the PIC with the compiled bootloader using the ICD, I use the CCS SIOW application to load in the Main_Program.hex file. The bootloading seems to work very well, although I've never figured out if the fuse settings need to be identical in the bootloader and in the program being loaded. I've also never figured out how to correctly determine and set up various memory segments in the bootloader code. I wonder if either the fuse settings being different in the two files or my "guesstimating" the memory segments is the root of the problem.

If anyone has any suggestions please let me know - I've nearly worn out the FLASH on this PIC trying to fix this Smile

Thanks,
Rick

Here is my bootloader code:

bootloader.c
Code:

//usb_bootloader.c

#include <18F6722.h>
#fuses HS,PROTECT,NOLVP,NOWDT,CPD,NOWRTD,CPB,EBTRB
#use delay(clock=40000000)

...
#ORG default

#ORG LOADER_ADDR, LOADER_ADDR+9  //Original - DON'T TOUCH
void load_program(void)
{
   real_load_program();
}


#org LOADER_END+2,LOADER_END+20  //Original - DON'T TOUCH
void application(void)
{
  while(TRUE);
}

#org 0x40,0x1EC //Works but why?
void main(void)

   int usb_byte = 0;
   
   setup_usb();
   
   //Original CCS Code
   
   if(input(BOOT_MODE_SEL))
   {
      load_program();
   }

   application();
   
}

#ORG default

#int_global
void isr(void)
{
   jump_to_isr(LOADER_END+5*(getenv("BITS_PER_INSTRUCTION")/8));
}


bootloader.h
Code:

//usb_bootloader.h

#define LOADER_END   0x7FF
#define LOADER_SIZE   0x4FF

#ifndef _bootloader
#build(reset=LOADER_END+1, interrupt=LOADER_END+9)
#org 0, LOADER_END {}
#endif


The LST file for the compiled Bootloader starts off with:

Code:

ROM used: 858 bytes (1%)
                         Largest free fragment is 65536
               RAM used: 72 (2%) at main() level
                         134 (3%) worst case
               Stack:    5 worst case (4 in main + 1 for interrupts)

*
00000:  GOTO   0040


My Main Program looks like this:

main_program.c
Code:

#include <18F6722.h>
#device adc=10
#fuses HS,PROTECT,NOLVP,NOWDT,NOCPD,NOWRTD

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

***


The LST file for the compiled Main Program starts off with:

Code:

ROM used: 22730 bytes (17%)
                         Largest free fragment is 65536
               RAM used: 1879 (49%) at main() level
                         2005 (52%) worst case
               Stack:    7 worst case (5 in main + 2 for interrupts)

*
00000:  GOTO   50EA
*


Last edited by RickDaystorm on Mon Oct 29, 2012 8:54 pm; edited 2 times in total
temtronic



Joined: 01 Jul 2010
Posts: 9174
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sun Jul 01, 2012 7:23 pm     Reply with quote

quick comments...
1) 47K on MCLR seems a lot to me, 4k7 or 10k is what I usually use on 5 volt PICs.

2) whenever you have 'use rs232(....) always add 'errors' to the options.It will keep the UART from 'locking up' , 'stalling' 'freezing', whatever you want to call it.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Jul 01, 2012 8:33 pm     Reply with quote

47K comes from the CCS FAQ on their ICD:
http://www.ccsinfo.com/faq.php?page=connect_icd
Look in the MCLR section and at the schematic.


My advice is to get rid of 90% of your code and just test the #int_tbe
issue only.
bkamen



Joined: 07 Jan 2004
Posts: 1611
Location: Central Illinois, USA

View user's profile Send private message

PostPosted: Sun Jul 01, 2012 10:46 pm     Reply with quote

temtronic wrote:
quick comments...
1) 47K on MCLR seems a lot to me, 4k7 or 10k is what I usually use on 5 volt PICs.



Ehh, I use 100K (with a 0.1uF to ground) as shown on a lot of MCHP docs controlling the part coming out of reset.

47K is probably ok.

-Ben
_________________
Dazed and confused? I don't think so. Just "plain lost" will do. :D
RickDaystorm



Joined: 01 Jul 2012
Posts: 12

View user's profile Send private message

PostPosted: Sun Jul 01, 2012 11:23 pm     Reply with quote

I'll try PCM's suggestion and strip out everything except the #INT_TBD ISR and the associated send routine and I'll also add "errors" to the use rs232 directive and a 0.1uF cap between MCLR and DGND.

Do you guys know if the fuse settings in the bootloader and the main program have to match? Are they even necessary in the main program given that they are applied when the bootloader HEX is loaded in using the ICD?

Do you have any comments on the memory segmentation in my modified CCS bootloader code? Is there a good tutorial somewhere on how to properly divide up the available memory between the bootloader and the main program depending on their compiled sizes and the resources of the target PIC?

Thanks,
Rick
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Jul 01, 2012 11:30 pm     Reply with quote

The two operative questions are, does the PIC allow writing of its Config
Bits under control of its internal program, and does the bootloader
support this ? You can research this.
bkamen



Joined: 07 Jan 2004
Posts: 1611
Location: Central Illinois, USA

View user's profile Send private message

PostPosted: Mon Jul 02, 2012 1:29 am     Reply with quote

RickDaystorm wrote:
Do you guys know if the fuse settings in the bootloader and the main program have to match? Are they even necessary in the main program given that they are applied when the bootloader HEX is loaded in using the ICD?


PCM, I didn't interpret this question the same. It's not "can I write the config bits via the bootloader but more of "do the config bits need to match between the bootloader and the main app".

Yes, he should still research it - but the quick answer is:

No. They don't have to match -- but I would then pose the question of, what might break if your Application assumes different settings than what the bootloader got programmed with

AND

Do you think it's a good idea to allow an Application's HEX to include config bits which could conflict with the bootloaders expectations?

It's always a good idea in the bootloader to BLOCK or at a MINUMUM filter any config bits that come through the Application's .HEX stream.

An example is code-space copy protection bits.
_________________
Dazed and confused? I don't think so. Just "plain lost" will do. :D
RickDaystorm



Joined: 01 Jul 2012
Posts: 12

View user's profile Send private message

PostPosted: Mon Jul 02, 2012 7:45 am     Reply with quote

Ben,

Not knowing how to block of filter the configuration bits that come through the application hex, I would guess the safest approach woukd be to ensure they are the same.
bkamen



Joined: 07 Jan 2004
Posts: 1611
Location: Central Illinois, USA

View user's profile Send private message

PostPosted: Mon Jul 02, 2012 10:42 pm     Reply with quote

RickDaystorm wrote:
Ben,

Not knowing how to block of filter the configuration bits that come through the application hex, I would guess the safest approach woukd be to ensure they are the same.


I strongly recommend then that you learn (unless this is a hobby and you don't care since this project is only for yourself.)

A: Find and download Intel's HEX record documentation. Also found on Wiki.
B: Study the memory map for the PIC you're using. Learn were the config bits are.
C: correlate that with the HEX output of a simple C project compiled.

It's really that easy.

Cheers,

-Ben
_________________
Dazed and confused? I don't think so. Just "plain lost" will do. :D
Ttelmah



Joined: 11 Mar 2010
Posts: 19369

View user's profile Send private message

PostPosted: Tue Jul 03, 2012 8:51 am     Reply with quote

Looking at the code, there is one thing that 'leaps out'.

In the main code, bootloader.h file, is loaded after the driver file for the RS232, and stdlib.

_Always_ when using a bootloader, the bootloader.h file, _must_ be the first file loaded. It carries the relocation code, to locate the subsequent code into the locations it has to occupy, with the bootloader present. The build instructions to say 'where; the code must sit.
This is being applied after the drivers to talk to the FTDI chip have been loaded, so these will be left in the wrong place in memory. These won't then be loaded (the bootloader should not load code that overlaps itself).

The bootloader used, looks as if it does ignore the fuses:

addr > LOADER_END) && addr < 0x300000

Best Wishes
Bill24



Joined: 30 Jun 2012
Posts: 45

View user's profile Send private message

PostPosted: Tue Jul 03, 2012 11:25 am     Reply with quote

RickDaystorm wrote:
Ben,

Not knowing how to block of filter the configuration bits that come through the application hex, I would guess the safest approach woukd be to ensure they are the same.


I have been having a crazy discussion with CCS support over this.

Are the fuses eg #FUSES PLL5 the configuration word ?

CCS seem to say no. I have been asking CCS as I have programmed a boot loader that is working with interrupts RS232 comms baud rates all working.

The only problem is that a test application runs slower. I,E the LEDS flash at a different rate than when the test program is flashed directly.If any one has a fix then please post it.

I believe the problem is with the CCS delay function being buggy.


THe interrupt problem was solve by the boot loader using the PIC alternate interrupt vector table.


The follow post is the code of a working RS232 boot loader. I have adapted it to use USB. If any one wants that code ill post it as well.
Bill24



Joined: 30 Jun 2012
Posts: 45

View user's profile Send private message

PostPosted: Tue Jul 03, 2012 11:31 am     Reply with quote

[quote="Bill24"]
RickDaystorm wrote:
Ben,


Working RS232 Boot loader.
N


Note - This boot loader download programs and a data table. So there is some code that can be stripped out by anybody who wants to copy this.

Code:

#include "includes\24FJ256GB108.h"
#ORG 0x020000, 0x28000  default
#build(ALT_INTERRUPT)

#include "includes\stdio.h"
#include "includes\main.h"

//Forward declarations for private functions.
void check_for_usb_data (void);
void send_USB_response(unsigned int8 command, unsigned int8 result);
void clear_input_buffer(void);

unsigned int8 load_firmware (void);
unsigned int8 atoi_b16(char *s) ;
unsigned int8 flash_erased = FALSE;
unsigned int8 erase_in_progress = FALSE;

// Reserve 4 words (16 bytes) for read buffer
unsigned int32 app_flag[FLAG_SIZE] = {0x00,0x00,0x00,0x00};

// Late mod 18 June 2012 - Data tables are to be embedded in application.
//unsigned int32 data_table_flag[FLAG_SIZE] = {0x00,0x00,0x00,0x00};
unsigned int32 valid[4] = {0x0000A5A5,0x00000000,0x00000000,0x00000000};
unsigned int32 dead[4] = {0x0000DEAD,0x00000000,0x00000000,0x00000000};

// Used to hold applications reset vector
unsigned int32 boot_ld_version=0x01;  //int32 neaded to read/write flash

unsigned INT8 usb_rcv_data[128]; /// incoming data in ascii
unsigned INT8 data_bytes[128];
unsigned INT8 usb_tx_data[64];

//------------------------------------------------------------------------------


void main(void)
{   
    unsigned int16 count = 0 ;

    // Write bootloader version number to flash for use by application
    write_program_memory (0x02A000, &boot_ld_version, 4);

 
    set_tris_d(0x7300);
    g_ccm_byte_count = 0;
    INTCON1 = 0x0000;   // Enable interrupt nesting 
    INTCON2 = 0x0000;
    IEC1    = 0x0000;   // Dissable CCM to Channel serial comms interrupt 
    IFS0    = 0x0000;   // clear interrupts
    IFS1    = 0x0000;   // clear interrupts
    IEC1    = 0x4000;   // Enable CCM to Channel serial comms interrupt 
    IPC7    = 0x0100;   // Set CCM to Channel serial comms interrupt to level 1 

    clear_input_buffer();
    flash_erased = FALSE;
    erase_in_progress = FALSE;

    // Boot loader uses alternate IVT to avoid clash with Application
    enable_interrupts(INTR_ALTERNATE);

    WHILE (TRUE)
    {
        count ++;

        if ( (count > 2000)  ) 
        {
            count = 0 ;

            // Check for existing application.
            read_program_memory (0x029000, app_flag, 4);
            if ( app_flag[0] == 0x0000A5A5) 
            {
                // Jumping to the application so use IVT 1
                 goto_address ( 0x0200);
            }
       }

        delay_ms (1);

        // Check for incoming packets.
        check_for_usb_data();
    }
}

/*==============================================================================
Function          : check_for_usb_data ()

Purpose           : Decode  USB packet and handle command.

Inputs            : None

Outputs           : None

Status returned   : None

Special           : None
==============================================================================*/
void check_for_usb_data (void)
{
    unsigned int8 result;
    Int32 e_address;

    IF (g_ccm_byte_count > 0)   // If RS232 data packet received
    {     
        switch (usb_rcv_data[0])
      {   
            case DATA_TABLE_UPGRADE_REQUEST: // USB Buffer = [ 0x01,0x03, Ch, 2 bytes for Num Pkts ]
            case CHANNEL_UPGRADE_REQUEST:    // USB Buffer = [ 0x07,0x03, Ch, 2 bytes for Num Pkts ]
            // FALL THROUGH

                if (usb_rcv_data[0] == DATA_TABLE_UPGRADE_REQUEST)
                {
                    // Erase data table memory.
                    for ( e_address = 0x1C600; e_address<0x1F600; e_address += 0x400)
                    {
                        erase_program_memory(e_address);
                    }
                }
                else
                {
                     // Erase application
                     for ( e_address = 0x400; e_address<0x1D000; e_address += 0x400)
                     {
                         erase_program_memory(e_address);
                     }
                } 

 
                send_USB_response(usb_rcv_data[0], READY);
                break;             
                           
            case DATA_TABLE_UPGRADE_DATA : // USB Buffer = [ 0x02, size, data ]
            case CHANNEL_UPGRADE_DATA :    // USB Buffer = USB Buffer = [ 0x08, size, data ]
            // FALL THROUGH
                // Received a line from a HEX File to be flashed in datbytes[]
                result = load_firmware();

                send_USB_response(usb_rcv_data[0], result); 
                if (result == STOP_SENDING)
                {

                    if ( usb_rcv_data[0] == DATA_TABLE_UPGRADE_DATA )
                    {   
                        // Set DATA_TABLE_VALID flag in non volatile memory
                        write_program_memory (0x028000, valid, 4);
                    }
                    else
                    {
                        // Set APP_LOADED_FLAG flag in non volatile memory
                        write_program_memory (0x029000, valid, 4);
                    }
   
             
               goto_address ( 0x0200);

                }
                break;

             default:
                break;
         }   
      }
}

/*==============================================================================
Function          : send_USB_response()

Purpose           : Returns result of USB packet back to the CCM

Inputs            : result of transcation

Outputs           : None

Status returned   : None

Special           : None
==============================================================================*/
void send_USB_response(unsigned int8 command, unsigned int8 result)
{
    unsigned int i;
    unsigned int8 chksum = 0;

    usb_tx_data[0]  = command;
    usb_tx_data[1]  = 0x01;    // length of data in packet
    usb_tx_data[2]  = result;

    // Add 1 byte checksum to fourth byte (  b1+b2........+bn )
    for (i = 0 ; i < 3 ; i++ )
    {
        chksum += usb_tx_data[i];
    }
    usb_tx_data[3]  = chksum;

    // Send response to CCM
   fputc(usb_tx_data[0],ccm);
   fputc(usb_tx_data[1],ccm);
   fputc(usb_tx_data[2],ccm);
   fputc(usb_tx_data[3],ccm);

    clear_input_buffer();
}

/*==============================================================================
Function          : atoi_b16 ()

Purpose           : Convert two hex characters to a int8

Inputs            : Pointer to char.

Outputs           : unsigned int8

Status returned   : None

Special           : None
==============================================================================*/
unsigned int8 atoi_b16(char *s)

    char c;
    unsigned int8 result = 0;
    int i;

    for (i=0; i<2; i++,s++) 
    {
        c = *s;
        if (c >= 'A')
            result = 16*result + c - 'A' + 10;
        else
            result = 16*result + c - '0';         
   }
   return(result);
}

/*==============================================================================
Function          : init_flash_page_0 ()

Purpose           : Initiialise flash page 0 protecting boot loader reset vector 
               and IVT

Inputs            : None. Uses common USB input buffer.

Outputs           : Indicates if program has been flashed and verified.

Status returned   : None

Special           : None
==============================================================================*/
void init_flash_page_0(void)
{
    /*
    The boot loader must protect its reset and USB ISR vector from being corrupted.
    When a downloaded  application sets an interrupt vector in page 0, writing to flash it is
    only possible to change a '1' to a '0'. For the PIC24F,  write_program_memory() will only
    erase the flash page if it attempts to write to the start address of a page, e.g  0,
    0x400, 0x400, 0xC00 etc. The erase_program_memory() function will erase the entire
    page that the address passed to it is in. E.g any address from 0 to 0x3FE passed to it
    will cause all addresses in that range to be erased. There is no way to erase specific
    addresses in a page.
    */
    unsigned int32 reset_vector_low;
    unsigned int32 reset_vector_high;
    unsigned int32 uart2_isr_vector;

    read_program_memory(0x0000, &reset_vector_low, 4);
    read_program_memory(0x0002, &reset_vector_high, 4);
    read_program_memory(0x0150, &uart2_isr_vector, 4);   //Boot loader uses PIC24's alternate IVT

    write_program_memory (0x0000, &reset_vector_low, 4);   // Page 0, 0x0000 to 0x0400 is now erased
    write_program_memory (0x0002, &reset_vector_high, 4);
    write_program_memory(0x0150, &uart2_isr_vector, 4);
}

/*==============================================================================
Function          : load_firmware ()

Purpose           : Check line of HEX file and programs data into flash

Inputs            : None. Uses common USB input buffer.

Outputs           : Indicates if program has been flashed and verified.

Status returned   : None

Special           : None
==============================================================================*/
unsigned int8 load_firmware (void)
{
    // Hex File format codes
    #define end_of_file 1
    #define data_record 0
    #define line_type_field 7
    #define low_address_byte 3
    #define high_address_byte 5

    unsigned int8  checksum, line_type;
    unsigned int16 l_addr;
    static unsigned h_addr=0; // h_addr must retain its value on exit of this function.
    unsigned int32 addr;
    unsigned int8  dataidx, i;
    unsigned int16 count=0;
    unsigned int8  data[32];
    unsigned int8  check_data[32];
    unsigned int8  buffidx= 0;
    unsigned int8  buffer[BUFFER_LEN_LOD];
    unsigned int8  bufx;
    unsigned int8  result;
//=========
    unsigned int32 next_erase_addr;
//=========

    // NOTE - multiple returns are used to prevent and excess of nested if/else blocks.

    // Set APP_LOADED_FLAG flag in non volatile memory
    //write_program_memory (APP_LOADED_FLAG, dead, 4); //Symbol does not appear to work
    write_program_memory (0x029000, dead, 4);
      
    // Copy from byte 2 of received HEX file
    FOR (buffidx = 0; buffidx <= BUFFER_LEN_LOD; buffidx++)
    {
        bufx = data_bytes[buffidx+2];
        buffer[buffidx] = bufx;
        if ( bufx == 0x0D)
        {
            // buffidx will point to the last data byte in the HEX line.
            // leave loop
            break;
        }
    }

    // Only process data blocks that start with ':'
    if (buffer[0] == ':')
    {
        // Get the number of bytes from the buffer
        count = atoi_b16 (&buffer[1]); 

        // Get the address of of Flash to be programmed.
        l_addr = make16(atoi_b16(&buffer[low_address_byte]),atoi_b16(&buffer[high_address_byte]));
        addr = make32(h_addr,l_addr);
        addr /= 2;

        // Get the 'line type' of the line in the .HEX File
        line_type = atoi_b16 (&buffer[line_type_field]);

        // If the line type is 1, then data is done being sent
        if (line_type == end_of_file)
        {
            return (STOP_SENDING);
        }
        else if ((addr < LOADER_ADDR ))
        {
            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-2]))
            {
               // printf(" Bad checksum  \r\n");
                return (ABORT);
            }
            else   
            {
                //-------------------------------------------------------------------------
                // Capture downloaded reset vector. This must not changed by the boot loader.
                if ((line_type == data_record) && (addr <= 0x000003) )
                {
                    // save page 0 of flash and reprogram to ensure
                    // Flash 0x200 to 0x400 is clean.
                    init_flash_page_0();
                    next_erase_addr = 0x400;
            }
                  else if ((line_type == data_record) &&
                    (addr >= 0x00004) &&               
                    (addr < ((int32)APPLICATION_END))
               )
               {
                    // Loops through all of the data and stores it in data array
                    // The last 2 bytes are the check sum, hence buffidx-2
                    // The data starts at the 10th character (9 zero based)
                    //for (i = 9,dataidx=0; i < buffidx-3; i += 2)
                    for (i = 9,dataidx=0; i < buffidx-2; i += 2)
               {
                        data[dataidx++]=atoi_b16(&buffer[i]);
                    }
                 
                    write_program_memory(addr, data, count);
                    delay_us(10);   
                    read_program_memory(addr, check_data, count);

                    result = 0;
                    for (i = 0; i < count; i++)
                    {
                        if ( data[i] != check_data[i])
                        {
                            result ++; // count errors for debug purpose
                        }
                    }

                    if ( result != 0)
                    {
                        // printf("write_program_memory falure \r\n");
                        return ABORT;
                    }               
                }  // if (line_type == data_record)
                else if (line_type == 4)
                {
                    h_addr = make16(atoi_b16(&buffer[9]), atoi_b16(&buffer[11]));
                }
             }// (checksum != atoi_b16 (&buffer[buffidx-3]))
          }// else if ((addr < LOADER_ADDR ))
    }//if (buffer[0] == ':')
     return(SEND_MORE_DATA);
}

/*========================================================================================
Function          :  uart2_isr()

Purpose           :  Receives a data packet of upto 64 bytes from the CCM

Inputs            : None

Outputs           : None

Status returned   : None

Special           : None
========================================================================================*/
#int_rda2
void rda2_isr()
{
    unsigned int8 i = 0;
    unsigned int8 index = 0;
    unsigned int32 timeout = 0;

    // Get first data byte
    g_ccm_byte_count = 0;       
    index = 0;
    data_bytes[index++] = getc();
   
    // Timeout of 1200 chosen to ensure 64 byte packet can be received with a safe margin.
    timeout = 0;
    while( (index < 64) && (timeout++ < 10000 ))
    {
        if(bit_test(U2STA, 0))
        {
            data_bytes[index++] = getc();
        }
    }

    // Convert bytes from ascii to hex
    for(i= 0; i <= index; i++)
    {
        if ( data_bytes[i] >= 0x30 && data_bytes[i] < 0x3A)  // convert ASCII to Hex for 1-9
        {
             usb_rcv_data[i] = data_bytes[i] - 0x30;
        }

        if ( data_bytes[i] >= 0x61 && data_bytes[i] < 0x67)  // convert ASCII to Hex for a-f
        {
             usb_rcv_data[i] = data_bytes[i] - 0x57;
        }
    }
 
    // Store number of bytes in this packet.
    g_ccm_byte_count = index;
}

/*========================================================================================
Function          : clear_input_buffer()

Purpose           : Zeros Rx buffer and count before. Called before next packet is requested.

Inputs            : None

Outputs           : None

Status returned   : None

Special           : None
========================================================================================*/
void clear_input_buffer(void)
{
    g_ccm_byte_count = 0;
    unsigned index= 0;

    for(index = 0; index < 64; index++)
    {
        usb_rcv_data[index] = 0;
    }

}
Bill24



Joined: 30 Jun 2012
Posts: 45

View user's profile Send private message

PostPosted: Tue Jul 03, 2012 11:34 am     Reply with quote

Main .h for the boot loader


// BEWARE -BOTH APPLICATION AND BOOT LOADER MUST bE SAME FUSES AND CLOCKS ETC NOT SURE IF THIS IS TRUE. THIS CODE DOES WORK BUT A SUGGESTION WAS FOR THE BOOT LOADER TO HAVE NO FUSE STATEMENTS>
Code:

//
#ifndef __MAIN_H__
#define __MAIN_H__

#define IRDA_RCV        PIN_D14
#define IRDA_XMIT       PIN_D15
#define TEST_RCV        PIN_D12
#define TEST_XMIT       PIN_D8

// Uart status register bit positions
#define  UTXBF    9  //transmit shift register empty flag
#define  TRMT     8  //transmit buffer full flag
#define  PERR     3  //receive parity error flag
#define  FERR     2  //receive framing error flag
#define  OERR     1  //receive buffer overrun error flag
#define  URXDA   0  //Receive buffer data available flag

#define APPLICATION_START    0x0200
#define APPLICATION_END    0x10000
#define ROM_BLOCK_INVALID    -1
#define LOADER_ADDR       0x020000
#define LOADER_END          0x028000
#define APP_LOADED_FLAG    0x029000
#define FLAG_SIZE           4
#define BUFFER_LEN_LOD      64

#define DATA_TABLE_UPGRADE_REQUEST              0x01
#define DATA_TABLE_UPGRADE_DATA                 0x02
#define CHANNEL_UPGRADE_REQUEST                 0x07
#define CHANNEL_UPGRADE_DATA                    0x08
#define NOT_READY                               0x01
#define READY                                   0x02
#define SEND_MORE_DATA                          0x01
#define RESEND_LAST_PACKET                      0x02
#define ABORT                                   0x03
#define STOP_SENDING                            0x04

#use delay(clock=20000000)
#FUSES   WPOSTS9              //Watch Dog Timer PostScaler 1:256
#FUSES   NOWDT               
#FUSES   NOWRT                //Program memory not to be write protected
#FUSES   NOJTAG               //JTAG disabled
#FUSES   HS                   //High speed osc (>4MHz for PCM/PCH) (>10MHz for PCD)
#FUSES   CKSFSM               //Clock switching is enabled,
#FUSES   PR                   //Primary Oscillator
#FUSES   PLL5                 //Divide by 5 (20MHz oscillator input)
#FUSES   ICSP3                 

// Holds number of bytes in RS232 input buffer
unsigned int8  g_ccm_byte_count;
#byte g_ccm_byte_count = 0x0808   

// Maps UART1 and UART2 RX and TX to pins D14, D15, D12 and D8 respectively*/
#pin_select U1TX = IRDA_XMIT
#pin_select U1RX = IRDA_RCV
#pin_select U2TX = TEST_XMIT
#pin_select U2RX = TEST_RCV

#use standard_io(A)
#use standard_io(B)
#use standard_io(C)
#use standard_io(D)
#use standard_io(E)
#use standard_io(F)
#use standard_io(G)

#use rs232(UART1, stream = ccm, baud=28800, xmit=TEST_XMIT, rcv=TEST_RCV, BRGH1OK, parity=E, bits=8)
#use rs232(UART2, baud=28800, PARITY=E,BITS =8, STOP=1,  RESTART_WDT)

//uart 1 registers
#word u1mode      =  0x0220
#word u1sta       =  0x0222
#word u1txreg     =  0x0224
#word u1rxreg     =  0x0226
#word u1brg       =  0x0228

//uary t registers
#word u2mode      =  0x0230
#word u2sta       =  0x0232
#word u2txreg     =  0x0234
#word u2rxreg     =  0x0236
#word u2brg       =  0x0238

//interrupt registers
#word IFS0        =  0x0084
#word IFS1        =  0x0086
#word INTCON1     =  0x0080
#word INTCON2     =  0x0082
#word IPC0        =  0x00A4
#word IPC7        =  0x00B2
#word IFS0        =  0x0084
#word IEC0        =  0x0094
#word IEC1        =  0x0096

//port addresses
#word porta       =  0x02C2
#word portb       =  0x02CA
#word portc       =  0x02D2
#word portd       =  0x02DA
#word porte       =  0x02E2
#word portf       =  0x02EA
#word portg       =  0x02F2

#ENDIF //__MAIN_H__
Bill24



Joined: 30 Jun 2012
Posts: 45

View user's profile Send private message

PostPosted: Tue Jul 03, 2012 11:52 am     Reply with quote

bkamen wrote:
RickDaystorm wrote:
Ben,

Not knowing how to block of filter the configuration bits that come through the application hex, I would guess the safest approach woukd be to ensure they are the same.


I strongly recommend then that you learn (unless this is a hobby and you don't care since this project is only for yourself.)

<snip.

-Ben



IMO CCS examples are a bit weak since many people, myself included, start with the CCS examples and then resort to forums like this to fill in missing information. Hence so many threads on boot loader problems.

FWIW MikroC are far better in this area as they have tutorials included with their examples. Saves a lot of time searching the internet.
temtronic



Joined: 01 Jul 2010
Posts: 9174
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue Jul 03, 2012 12:55 pm     Reply with quote

Maybe..I haven't looked at the MikroC stuff, but CCS does provide lots of examples covering almost every aspect of the PIC and their implementation of C. That allows a reasonably good programmer a good 'leg up' in developing their project. Been here since 1998.
It takes a tremendous amount of time to support any ONE product and CCS has hundreds of 'subPICs' to support as well as this forum ,new R&D, legacy stuff, etc. Last time I checked there's still just 24 hours in a day but fewer as you grow older ! Perhaps you'ld like to offer your time/knowledge and create a 'how-to-it' forum here, so students of all ages can learn?
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
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