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
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.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 *
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.





Bookmarks