Hello all,

I've been stalking around this board for a couple months sucking knowledge from so many great minds. I wanted to do something I couldn't find, after I figured it out I thought I'd share my code. I wanted to use an EEPROM byte to control on boot if I should enter bootloader mode or jump up to Pic basic code.

I loaded the new MCHPFSUSB v2.3 (just release 6 weeks or so ago) and modified the HID Bootloader C code to do exactly what I want.

In my Pic I'm doing the following

Code:
    
If ProgramMe = 1 then   'Put the chip into programming mode via a ProgramMe variable i'm passing across the USB
        Write 1, 255  'Set eeprom byte 1 back to FF
        pause 250     'I small pause for no good reason, probably not needed
        @ Reset        'reset/reboot the PIC
ENDIF

I then modified the main.c in the "C:\Microchip Solutions\USB Device - Bootloaders\HID - Bootloader\HID Bootloader - Firmware for PIC18 Non-J Devices" to the following

Code:
/*********************************************************************
 *
 *   Microchip USB HID Bootloader for PIC18 (Non-J Family) USB Microcontrollers
 *
 *********************************************************************
 * FileName:        main.c
 * Dependencies:    See INCLUDES section below
 * Processor:       PIC18
 * Compiler:        C18 3.20+
 * Company:         Microchip Technology, Inc.
 *



/** I N C L U D E S **********************************************************/
#include <p18cxxx.h>
#include "typedefs.h"                   
#include "usb.h"                         
#include "io_cfg.h"                     
#include "BootPIC18NonJ.h"


#if defined(PIC18F4550_PICDEM_FS_USB)	
        #pragma config PLLDIV   = 5     
        #pragma config CPUDIV   = OSC1_PLL2	
        #pragma config USBDIV   = 2     
        #pragma config FOSC     = HSPLL_HS
        #pragma config FCMEN    = OFF
        #pragma config IESO     = OFF
        #pragma config PWRT     = OFF
        #pragma config BOR      = ON
        #pragma config BORV     = 3
        #pragma config VREGEN   = ON	
        #pragma config WDT      = OFF
        #pragma config WDTPS    = 32768
        #pragma config MCLRE    = ON
        #pragma config LPT1OSC  = OFF
        #pragma config PBADEN   = OFF		


        #pragma config STVREN   = ON
        #pragma config LVP      = OFF

        #pragma config XINST    = OFF       
        #pragma config CP0      = OFF
        #pragma config CP1      = OFF
        #pragma config CPB      = OFF

        #pragma config WRT0     = OFF
        #pragma config WRT1     = OFF
        #pragma config WRTB     = OFF       // Boot Block Write Protection
        #pragma config WRTC     = OFF

        #pragma config EBTR0    = OFF
        #pragma config EBTR1    = OFF
        #pragma config EBTRB    = OFF

#elif defined(LOW_PIN_COUNT_USB_DEVELOPMENT_KIT)
        //14K50
        #pragma config CPU_DIV = NoClkDiv, USB_LSCLK = OFF             
        #pragma config FOSC = HS, PLL_EN=ON, FCMEN = OFF, IESO = OFF   
        #pragma config PWRT = OFF, BOREN = OFF, BORV = 30, VREGEN = ON
        #pragma config WDTEN = OFF, WDTPS = 32768                     
        #pragma config MCLRE = OFF, HFOFST = OFF				      
        #pragma config STVREN = ON, LVP = OFF, XINST = OFF, BBSIZ=OFF
        #pragma config CP0 = OFF, CP1 = OFF						     
        #pragma config CPB = OFF                                    			    
        #pragma config WRT0 = OFF, WRT1 = OFF						                
        
        #pragma config WRTB = OFF, WRTC = OFF                            			
        #pragma config EBTR0 = OFF, EBTR1 = OFF							           	
        #pragma config EBTRB = OFF                                                  
        
        
        #ifdef __DEBUG
            #pragma config BKBUG = ON 
        #endif
        #ifndef __DEBUG
            #pragma config BKBUG = OFF
        #endif   
#else
	#error Not a supported board (yet), make sure the proper board is selected in usbcfg.h, and if so, set configuration bits in __FILE__, line __LINE__
#endif

/** V A R I A B L E S ********************************************************/
#pragma udata

/** P R I V A T E  P R O T O T Y P E S ***************************************/
static void InitializeSystem(void);
void USBTasks(void);
#if !defined(__18F14K50) && !defined(__18F13K50) && !defined(__18LF14K50) && !defined(__18LF13K50)
    void BlinkUSBStatus(void);
#else
    #define BlinkUSBStatus()
#endif

/** V E C T O R  R E M A P P I N G *******************************************/
#pragma code high_vector=0x08
void interrupt_at_high_vector(void)
{
    _asm goto 0x1008 _endasm
}
#pragma code low_vector=0x18
void interrupt_at_low_vector(void)
{
    _asm goto 0x1018 _endasm
}
#pragma code


/** D E C L A R A T I O N S **************************************************/
#pragma code
/******************************************************************************
 * Function:        void main(void)
 *
 * PreCondition:    None
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        Main program entry point.
 *
 * Note:            None
 *****************************************************************************/
void main(void)
{   
    
	//read the first byte store in var eepTemp
	signed char eepTemp;  	//setup a var to read the eep
	EEADR = 0x0001; 		//location to read, I'm useing eeprom address 1
	EECON1bits.EEPGD = 0; 
	EECON1bits.CFGS = 0; 
	EECON1bits.RD = 1; 
	eepTemp = EEDATA; 

	//write Byte "1" back to a 1, so no matter once bootloader code only enters once
    EEADR =0x0001; 
   	EEDATA =0x01;
   	Nop();
   	Nop();
    EECON1bits.EEPGD = 0;
   	EECON1bits.CFGS = 0;
   	EECON1bits.WREN = 1;
   	INTCONbits.GIE = 0;
   	EECON2 = 0x55;
   	EECON2 = 0xAA;
   	EECON1bits.WR = 1;
	while(EECON1bits.WR); 
   	INTCONbits.GIE = 1;
   	EECON1bits.WREN = 0;
	

    //Check Bootload Mode Entry Condition
	if(eepTemp == 0x01)	//Check the eepTemp and see if it's 0x01, if so boot to the PIC Basic code at 0x1000
	{
		_asm
		goto 0x1000			//If the user is not trying to enter the bootloader, go straight to the main application remapped "reset" vector.
		_endasm
	}
    InitializeSystem();
    while(1)
    {
		ClrWdt();	
	    USBTasks();         					// Need to call USBTasks() periodically
	    										// it handles SETUP packets needed for enumeration

		//BlinkUSBStatus();
		
	    if((usb_device_state == CONFIGURED_STATE) && (UCONbits.SUSPND != 1))
	    {
 	       ProcessIO();   // This is where all the actual bootloader related data transfer/self programming takes place
 	    }				  // see ProcessIO() function in the Boot87J50Family.c file.
    }//end while
}//end main

/******************************************************************************
 * Function:        static void InitializeSystem(void)
 *
 **/
static void InitializeSystem(void)
{

	#if defined(__18F87J50)||defined(__18F86J55)|| \
    	defined(__18F86J50)||defined(__18F85J50)|| \
    	defined(__18F67J50)||defined(__18F66J55)|| \
    	defined(__18F66J50)||defined(__18F65J50)

    unsigned int pll_startup_counter = 600;
    OSCTUNEbits.PLLEN = 1;  //Enable the PLL and wait 2+ms until the PLL locks before enabling USB module
    while(pll_startup_counter--);


    #else

    #endif

    #if defined(USE_USB_BUS_SENSE_IO)
    tris_usb_bus_sense = INPUT_PIN; // See io_cfg.h
    #endif
    #if defined(USE_SELF_POWER_SENSE_IO)
    tris_self_power = INPUT_PIN;
    #endif
    
    mInitializeUSBDriver();         // See usbdrv.h
    
    UserInit();                     // See user.c & .h

}//end InitializeSystem

/******************************************************************************
 * Function:        void USBTasks(void)
 */

void USBTasks(void)
{
    /*
     * Servicing Hardware
     */
    USBCheckBusStatus();                    // Must use polling method
    USBDriverService();              	    // Interrupt or polling method

}// end USBTasks


/******************************************************************************
 * Function:        void BlinkUSBStatus(void)
 * 
 * THIS FUNCTION WAS REMOVED TO MAKE ROOM FOR THE EEPROM READ AND WRITE CODE
 *
Basically every time the pic boots I check EEPROM Byte 1. If the PICBasic code has set byte 1 back to 0xFF then the c code sets it back to 0x01 and runs the bootloader code for that boot. I then run the microchip HID bootloader and update the Pic Basic code.

Upon reseting after upgrading Byte 1 has already been switched back to 0x01 so it bypasses the bootloader.

No Switches to press... very simple upgrades. I send a command down to the pic, it reboots, I run the HID Bootloader, reboot after loading my new code. The PicBasic code Executes.