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