You are on page 1of 4

/*

Bootloader USB HID para microcontroladores PIC18F4550 e PIC18F2550


Clock: 48MHz ( ? MHz + PLL ativado )
Compilador: MikroC PRO PIC
Autor: Tiago
Blog: microcontrolandos.blogspot.com.br
*/
#include <Built_in.h>
/* Comandos */
enum Cmd { cmdNONE, cmdINFO, cmdSTART, cmdWRITE, cmdERASE };
enum McuType { PIC16 = 1, PIC18, PIC18FJ, PIC24, DSPIC = 10, PIC32 = 20 };
enum Cmd CmdCode = cmdNONE;
const STX = 0x0F;
/* Calcula o endereo inicial do bootloader */
const unsigned long BOOTLOADER_SIZE
= 7432;
const unsigned long BOOTLOADER_START = (( __FLASH_SIZE - BOOTLOADER_SIZE) /
_FLASH_ERASE) * _FLASH_ERASE;
const unsigned char RESET_VECTOR_SIZE = 4;
/* Fornece informaes sobre o MCU */
typedef struct
{
char McuType; //Tipo
unsigned long FlashSize; //Tamanho da Flash
unsigned EraseBlock; //Numero de blocos para apagar
unsigned WriteBlock; //Numeros de blocos de escrita
unsigned long BootStart; //Endereo inicial do bootloader
unsigned EepromSize; //Tamanho da Eeprom
char Device[19]; //Nome do microcontrolador
}BootInfo;
/* Cria a variavel com as informaes */
const BootInfo mcuBootInfo = { PIC18,
__FLASH_SIZE,
_FLASH_ERASE,
_FLASH_WRITE_LATCH,
BOOTLOADER_START,
256,
"PIC18F4550"
};
unsigned Address = 0;
unsigned EraseBlockSize at Address;
/* Endereo da USB RAM */
unsigned char HidReadBuff[64] absolute 0x500;
unsigned char HidWriteBuff[64] absolute 0x540;
unsigned char Reserve4thBankForUSB[256] absolute 0x400;

char flags = 0;
sbit WriteData at flags.B0;
/* Envia uma resposta ao PC */
void Ack( char cmd )
{
HidWriteBuff[0] = STX;
//Start
HidWriteBuff[1] = cmd;
//Comando
while( !HID_Write( &HidWriteBuff, 64) ); //envia 64 bytes para o PC
}
/* Verifica um comando recebido */
void CheckCmd()
{
if( CmdCode == cmdNONE )
{
if( HidReadBuff[0] != STX )
return;
CmdCode = HIDReadBuff[1]; //Comando
Hi(Address) = HidReadBuff[2]; //Address
Lo(Address) = HidReadBuff[3]; //Address
}
}
/* Aguarda a conexo com o software */
char EnterBootloader()
{
unsigned timer = 7000; //Tempo que permanece esperando a conexo
while( timer-- )
{
USB_Polling_Proc();
if( HID_Read() ) //Byte(s) recebido(s)
{
CheckCmd(); //verifica o comando recebido
/* Foi requisitado para enviar as inoformaes ao PC */
if( CmdCode == cmdINFO )
{
//Carrega a variavel 'mcuBootInfo' em 'HidWriteBuff'
*(BootInfo*)( &HidWriteBuff+2) = mcuBootInfo;
Ack( cmdINFO ); //Envia a resposta
CmdCode = cmdNONE;
return 1; //OK
}
}
Delay_ms(1);
}
return 0; //Tempo esgotado
}
/* Inicia a comunicao com o software */

void StartBootloader()
{
while(1)
{
USB_Polling_Proc();
if( HID_Read() )
{
CheckCmd();
if( CmdCode == cmdWRITE ) //Escrever na Flash
{
if( !WriteData )
{
WriteData = 1;
}
else
{
if( Address < BOOTLOADER_START )
Flash_Write_32( Address, &HidReadBuff[4] );
}
Ack( cmdWRITE );
CmdCode = cmdNONE;
}
else if( CmdCode == cmdERASE ) //Apagar Flash
{
unsigned EraseBlocks;
unsigned long blockAddress;
for( EraseBlocks = 0; EraseBlocks < EraseBlockSize; EraseBlocks++ )
{
blockAddress = EraseBlocks * _FLASH_ERASE;
if( blockAddress < BOOTLOADER_START )
Flash_Erase_64( blockAddress );
}
Ack( cmdERASE );
CmdCode = cmdNONE;
}
else if( CmdCode == cmdSTART ) //Encerra a rotina
{
Ack( cmdSTART );
return;
}
}
}
}
void StartProgram()
{
asm sleep;
}
void main()
{

/* configura o inicio do codigo e define o endereo das funes */


OrgAll( BOOTLOADER_START - RESET_VECTOR_SIZE );
FuncOrg( main, BOOTLOADER_START );
FuncOrg( StartProgram, BOOTLOADER_START - RESET_VECTOR_SIZE );
if ( Reserve4thBankForUSB );
HID_Enable(

&HidReadBuff,

&HidWriteBuff ); //Habilita a comunicao USB

if( EnterBootloader() ) //Aguarda a conexo...Conectou!!!


StartBootloader();
Hid_Disable(); //Desabilita a USB
Delay_ms( 10 );
StartProgram(); //Inicia o programa do usurio
}

You might also like