|
|
View previous topic :: View next topic |
Author |
Message |
mecbb
Joined: 16 May 2014 Posts: 4
|
PIC18f4550 bootloader - Siow.exe and Teraterm.exe. [SOLVED] |
Posted: Fri May 16, 2014 5:54 pm |
|
|
Hello Everyone,
I´m trying to put to work the example of CCS “ex_usb_bootloader.c” with 18F4550, “siow.exe” and “teraterm.exe". I have spent three days under this and I don’t know how to put things to work, as mentioned for others members.
It seems to be related to the memory map, but I don’t have any idea about what I have to change.
I will describe everything I did, and post entire code. If anybody could give me some directions, it would be great and I would be thankful.
1 – Everything looks ok, just the application don’t run after send from siow.exe or teraterm.exe.
2 – Using PCWHD version 4.134. Mplab version 8.91. Siow version 4. Teraterm version 4.73. The schematic that I used was:
[img]
http://www.hobbielektronika.hu/forum/getfile.php?id=3688
[/img] (alt+p)
3 – I’ve follow the ex_usb_bootloader.c. I didn’t change anything on this code. I've only changed the code “ex_usb_common.h” for change the pins of Leds and comment the usb sense and ADC stuffs. This part is called at the beginning of “ex_usb_bootloader.c”.
ex_usb_bootloader.c
Code: |
#if !defined(__PCH__)
#error This bootloader written for PIC18
#endif
#include <ex_usb_common.h> // I’VE CHANGE INSIDE THIS CODE
#define LOADER_ISR 0x28
#build(interrupt=LOADER_ISR)
/*
Configure, then load the bootloader definitions
*/
#define _bootloader
#include <usb_bootloader.h>
// Includes all USB code and interrupts, as well as the CDC API
#include <usb_cdc.h>
/*
Goto the interrupt vector of the application.
*/
#org 0x08,0x17
void high_isr(void)
{
if (bit_test(g_InBootloader,0))
{
#ASM
goto LOADER_ISR
#ENDASM
}
else
{
#ASM
goto APPLICATION_ISR
#ENDASM
}
}
#org 0x18,0x27
void low_isr(void)
{
if (bit_test(g_InBootloader,0))
{
#ASM
goto LOADER_ISR+0x10
#ENDASM
}
else
{
#ASM
goto APPLICATION_ISR+0x10
#ENDASM
}
}
#define ROM_BLOCK_INVALID -1
int32 rom_block_start = ROM_BLOCK_INVALID;
#define EEPROM_ERASE_SIZE getenv("FLASH_ERASE_SIZE")
int8 rom_block[EEPROM_ERASE_SIZE];
// see rom_w() documentation. performs the flushing
void rom_w_flush(void)
{
if (rom_block_start != ROM_BLOCK_INVALID)
{
erase_program_eeprom(rom_block_start); //erase entire block
write_program_memory(rom_block_start, rom_block, sizeof(rom_block)); //write modified block
rom_block_start = ROM_BLOCK_INVALID;
}
}
// see rom_w() documentation. performs the writing
void rom_w_block(int32 location, char *src, int16 size)
{
int32 block_start;
int16 i,num;
block_start = location & (~((int32)EEPROM_ERASE_SIZE-1));
i = location - block_start;
while (size)
{
if (block_start != rom_block_start)
{
rom_w_flush();
rom_block_start = block_start;
read_program_memory(block_start, rom_block, sizeof(rom_block)); //read entire block to ram buffer
}
if (size>(EEPROM_ERASE_SIZE-i)) {num=EEPROM_ERASE_SIZE-i;} else {num=size;}
memcpy(&rom_block[i], src, num); //modify ram buffer
src += num;
block_start += EEPROM_ERASE_SIZE;
i = 0;
size -= num;
}
}
// Write to Flash ROM.
//
// location - flash program memory address
// src - pointer to data to write
// size - number of bytes to write to flash
//
// Here is the sequence of events:
// 1.) Goes to the beginning of the first erase block for this address
// 2.) Reads n records to ram, where n is the PIC's flash erase size
// 3.) Erases block in flash
// 4.) Modifies block in RAM
// 5.) Writes changed block back to FLASH. Writes in chunks defined by PIC's flash write size
// 6.) Goes back to step1 if there is still more data to be written
void rom_w(int32 location, char *src, int16 size)
{
rom_w_block(location, src, size);
rom_w_flush();
}
#define BUFFER_LEN_LOD 64
#define ACKLOD 0x06
#define XON 0x11
#define XOFF 0x13
// Convert two hex characters to a int8
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);
}
void load_program(void)
{
int1 do_ACKLOD, done=FALSE;
int8 checksum, line_type;
int16 l_addr,h_addr=0;
int8 to;
int32 addr;
int8 dataidx, i, count;
int8 data[32];
int buffidx;
char buffer[BUFFER_LEN_LOD];
while (!done) // Loop until the entire program is downloaded
{
usb_task();
output_toggle(LED1);
output_toggle(pin_c0);
if (!usb_cdc_kbhit())
continue;
buffidx = 0; // Read into the buffer until 0x0D ('\r') is received or the buffer is full
to = 250; //250 milliseconds
do
{
if (!usb_cdc_kbhit())
{
delay_ms(1);
to--;
if (!to)
break;
}
else
to = 250;
i = usb_cdc_getc();
buffer[buffidx++] = i;
} while ( (i != 0x0D) && (i != 0x0A) && (buffidx <= BUFFER_LEN_LOD) );
if (!to)
continue;
usb_cdc_putc(XOFF); // Suspend sender
do_ACKLOD = TRUE;
// Only process data blocks that start with ':'
if (buffer[0] == ':')
{
count = atoi_b16 (&buffer[1]); // Get the number of bytes from the buffer
// Get the lower 16 bits of address
l_addr = make16(atoi_b16(&buffer[3]),atoi_b16(&buffer[5]));
line_type = atoi_b16 (&buffer[7]);
addr = make32(h_addr,l_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-3]))
do_ACKLOD = FALSE;
else
{
// If the line type is 1, then data is done being sent
if (line_type == 1)
done = TRUE;
else if (line_type == 4)
h_addr = make16(atoi_b16(&buffer[9]), atoi_b16(&buffer[11]));
else if ((line_type == 0) && (addr >= (int32)APPLICATION_START) && (addr < ((int32)APPLICATION_END)))
{
// Loops through all of the data and stores it in data
// The last 2 bytes are the check sum, hence buffidx-3
for (i = 9,dataidx=0; i < buffidx-3; i += 2)
data[dataidx++]=atoi_b16(&buffer[i]);
rom_w_block(addr, data, count);
// write_program_memory(addr, data, count);
}
}
}
if (do_ACKLOD)
usb_cdc_putc (ACKLOD);
usb_cdc_putc(XON);
}
rom_w_flush();
usb_cdc_putc (ACKLOD);
usb_cdc_putc(XON);
delay_ms(2000); //give time for packet to flush
reset_cpu();
}
void main(void)
{
#if (defined(__USB_87J50__) && (getenv("FUSE_SET:H4_SW")))
#byte OSCTUNE = 0xF9B
#bit PLLEN=OSCTUNE.6
PLLEN = TRUE;
delay_ms(250);
#endif
HW_INIT();
//we use a button as an event to determine if we should start the USB CDC
//bootloader. if button is not pressed then goto the application, else if
//button is pressed then do the bootloader.
if(BUTTON_PRESSED())
{
g_InBootloader = TRUE;
usb_cdc_init();
usb_init();
while(!usb_enumerated());
load_program();
}
g_InBootloader = FALSE;
#ASM
goto APPLICATION_START
#ENDASM
}
|
ex_common.h
Code: |
ex_usb_common.h
////// Begin User Configuration
//#define USB_HW_CCS_PIC16C765 //CCS ACEKit with USB Addon and PIC16C765
//#define USB_HW_CCS_USBN9604 //CCS National USBN9604 USB development kit (external USB peripheral)
//#define USB_HW_MCHP_18F14K50 //Microchip low-pin count USB development kit (PIC18F14K50)
#define USB_HW_CCS_PIC18F4550 //CCS PIC18F4550 USB Development kit
//#define USB_HW_MCHP_18F46J50 //Microchip USB PIM Demo Board (PIC18F46J50)
//#define USB_HW_GENERIC_18F67J50 //Generic 18F67J50 example
//#define USB_HW_GENERIC_18F27J53 //Generic 18F27J53 example
//#define USB_HW_CCS_PIC24F //CCS 24FJ256GB206 USB Development kit
//#define USB_HW_MCHP_EXPLORER16_24F //Microchip Explorer16 with USB OTG PICTail+ & 24FJ256GB110
//#define USB_HW_MCHP_EXPLORER16_24E //Microchip Explorer16 with USB OTG PICTail+
// Optional configuration.
// Defining USB_ISR_POLLING will have USB library not use ISRs. Instead you
// must periodically call usb_task().
//#define USB_ISR_POLLING
////// End User Configuration
#ifndef __EX_USB_COMMON_H__
#define __EX_USB_COMMON_H__
#if defined(USB_HW_CCS_PIC16C765)
#include <16C765.h>
#device *=16
#fuses HS,NOWDT,NOPROTECT
#use delay(clock=24000000)
#define LED1 PIN_A5
#define LED2 PIN_B4
#define LED3 PIN_B5
#define BUTTON_PRESSED() !input(PIN_A4)
#define HW_ADC_CONFIG ADC_CLOCK_INTERNAL
#define HW_ADC_CHANNEL 0
#define HW_ADC_PORTS AN0_AN1_AN3
#endif
#if defined(USB_HW_CCS_PIC18F4550)
#include <18F4550.h>
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN, MCLR
#use delay(clock=48000000)
//#use rs232(BAUD=115200, parity=N, BITS=8, XMIT=pin_c6, RCV=pin_c7,ERRORS) //I tried to put this rs232 because my application use this. Don’t make difference. Here I have a doubt: the establishment of rs232 should be considering like fuses? I have to put this like I put in my application? As I read in others posts, we can’t change the fuses when using bootloader.
//leds ordered from bottom to top
#define LED1 pin_b7 // CHANGED
#define LED2 pin_b6 // CHANGED
#define LED3 pin_b5 // CHANGED
#define BUTTON_PRESSED() !input(pin_b4) // CHANGED
//see section below labeled USB_CABLE_IS_ATTACHED
// #define PIN_USB_SENSE PIN_B2
//#define HW_ADC_CONFIG ADC_CLOCK_INTERNAL
//#define HW_ADC_CHANNEL 0
//#define HW_ADC_PORTS AN0
#endif
#if defined(USB_HW_MCHP_EXPLORER16_24E)
#include <24EP512GU810.h>
#device ADC=8
#fuses NOWDT, NOIESO
//8MHz clock is scaled to 48mhz for usb clock.
//8mhz clock is scaled to 120mhz for cpu operation.
#use delay(crystal=8Mhz, clock=120Mhz, AUX:clock=48Mhz)
// no pin select compatible.
#pin_select U1TX = PIN_F5
#pin_select U1RX = PIN_F4
#define PIN_UART1_RTS PIN_F13 //out to PC
#define PIN_UART1_CTS PIN_F12 //in to PIC
// led's ordered from right to left
#define LED1 PIN_A0 //D3
#define LED2 PIN_A1 //D4
#define LED3 PIN_A2 //D5
#define LED_ON(x) output_high(x)
#define LED_OFF(x) output_low(x)
#define BUTTON_PRESSED() !input(PIN_D6) //s3
#define HW_ADC_PORTS sAN5
#define HW_ADC_CHANNEL 5
#define HW_ADC_CONFIG ADC_CLOCK_INTERNAL | ADC_TAD_MUL_31
/*
#byte ACLKCON3=getenv("SFR:ACLKCON3")
#byte ACLKDIV3=getenv("SFR:ACLKDIV3")
#bit ACLKCON3_APLLCK=ACLKCON3.14
#bit ACLKCON3_ENAPLL=ACLKCON3.15
//#define HW_INIT() while(!ACLKCON3_APLLCK)
#define HW_INIT() APllInit()
void ApllInit(void)
{
ACLKCON3 = 0x24C1;
ACLKDIV3 = 0x7;
ACLKCON3_ENAPLL = 1;
while(!ACLKCON3_APLLCK);
}
*/
#endif
#if defined(USB_HW_MCHP_EXPLORER16_24F)
#include <24FJ256GB110.h>
#device ADC=8
#fuses HS,PR_PLL,NOWDT,DISUVREG,ICSP2
#use delay(clock=32M) //8MHz clock is 4x because of PLL
#fuses PLL2 //Divide 8MHz by 2 to get the 4MHz required for USB
#pin_select U1TX = PIN_F5
#pin_select U1RX = PIN_F4
#define PIN_UART1_RTS PIN_F13 //out to PC
#define PIN_UART1_CTS PIN_F12 //in to PIC
// led's ordered from left to right
#define LED1 PIN_A7
#define LED2 PIN_A6
#define LED3 PIN_A5
#define LED4 PIN_A4
#define LED5 PIN_A3
#define LED6 PIN_A2
#define LED7 PIN_A1
#define LED8 PIN_A0
#define LED_ON(x) output_high(x)
#define LED_OFF(x) output_low(x)
#define BUTTON_PRESSED() !input(PIN_D6)
#define HW_ADC_PORTS sAN5
#define HW_ADC_CHANNEL 5
#define HW_ADC_CONFIG ADC_CLOCK_INTERNAL | ADC_TAD_MUL_31
#endif
#if defined(USB_HW_CCS_PIC24F)
#include <24FJ256GB206.h>
#device ADC=8
#fuses HS,PR_PLL,NOWDT,ICSP2,PLL5,SOSC_DIG
#use delay(clock=32M)
#pin_select U1TX = PIN_D5
#pin_select U1RX = PIN_D4
#pin_select SDI2 = PIN_F5
#pin_select SDO2 = PIN_B15
#pin_select SCK2OUT = PIN_F4
#define LED1 PIN_B9 //green
#define LED2 PIN_B10 //yellow
#define LED3 PIN_B11 //red
#define LED_ON(x) output_high(x)
#define LED_OFF(x) output_low(x)
#define BUTTON_PRESSED() !input(PIN_F0)
#define HW_ADC_PORTS sAN2|sAN5
#define HW_ADC_CHANNEL 5
#define HW_ADC_CONFIG ADC_CLOCK_INTERNAL | ADC_TAD_MUL_31
#define LCD_ENABLE_PIN PIN_D0
#define LCD_RS_PIN PIN_D1
#define LCD_RW_PIN PIN_D2
#define LCD_DATA4 PIN_E6
#define LCD_DATA5 PIN_E7
#define LCD_DATA6 PIN_D6
#define LCD_DATA7 PIN_D7
#endif
#if defined(USB_HW_CCS_USBN9604)
#include <18F452.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#define __USB_PIC_PERIF__ 0
#DEFINE LED1 PIN_B3
#define LED2 PIN_B4
#define LED3 PIN_B5
#define BUTTON_PRESSED() !input(PIN_A4)
#define HW_ADC_CONFIG ADC_CLOCK_INTERNAL
#define HW_ADC_CHANNEL 0
#define HW_ADC_PORTS AN0
#endif
#if defined(USB_HW_MCHP_18F14K50)
#include <18F14K50.h>
#fuses NOIESO
#fuses NOFCMEN
#fuses PCLKEN
#fuses NOPUT
#fuses NOBROWNOUT
#fuses NOWDT
#fuses NOMCLR
#fuses NOHFOFST
#fuses NOLVP
#fuses NOXINST
// configure 12MHz clock for USB operation and 48Mhz CPU operation
#fuses HS
#fuses PLLEN //enable pll, we can now use CPUDIVx fuses
#fuses CPUDIV1 //CPU clock set to 48MHz
#fuses USBDIV2 //when using low speed USB, need to divide 12MHz by 2. this fuse has no effect when using full speed.
#use delay(clock=48000000)
//leds are ordered left to right
#define LED1 PIN_C3
#define LED2 PIN_C2
#define LED3 PIN_C1
#define LED4 PIN_C0
#define LED_ON(x) output_high(x)
#define LED_OFF(x) output_low(x)
#define BUTTON_PRESSED() !input(PIN_A3)
#define HW_ADC_CONFIG ADC_CLOCK_INTERNAL
#define HW_ADC_CHANNEL 10
#define HW_ADC_PORTS sAN10
#endif
#if defined(USB_HW_MCHP_18F46J50)
#include <18F46J50.h>
#fuses NOWDT
#fuses NOXINST
#fuses NODEBUG
#fuses NOPROTECT
#fuses HSPLL
#fuses PLL3 //set usb pll clock to 4MHz (from 12Mhz input)
#fuses NOCPUDIV //set cpu clock to 48MHz
#use delay(clock=48MHz)
#DEFINE LED1 PIN_E0
#define LED2 PIN_E1
#define LED3 PIN_D7 //requires PIC18 Explorer
#define LED_ON(x) output_high(x)
#define LED_OFF(x) output_low(x)
#define BUTTON_PRESSED() !input(PIN_B2)
// pot is on PIC18 Explorer
#define HW_ADC_PORTS sAN0
#define HW_ADC_CHANNEL 0
#define HW_ADC_CONFIG ADC_CLOCK_INTERNAL
// uart/rs232 requires PIC18 Explorer
//#define PIN_USB_SENSE PIN_C2 //Jumper JP2 needs to short 'R' to 'U' position for this to be valid.
#define HW_INIT() setup_oscillator(OSC_PLL_ON); delay_ms(50)
#endif
#if defined(USB_HW_GENERIC_18F67J50)
#include <18F67J50.h>
#fuses NOWDT
#fuses NOXINST
//8Mhz clock configured for USB operation and 48MHz CPU operation
#fuses HSPLL
#fuses PLL2
#fuses NOCPUDIV
#use delay(clock=48M)
#DEFINE LED1 PIN_E4
#define LED2 PIN_E5
#define LED3 PIN_E6
#define BUTTON_PRESSED() FALSE //no push button on this hardware
#define HW_ADC_PORTS sAN0
#define HW_ADC_CHANNEL 0
#define HW_ADC_CONFIG ADC_CLOCK_INTERNAL
#define PIN_USB_SENSE PIN_B2
#byte OSCTUNE = 0xF9B
#bit PLLEN=OSCTUNE.6
#define HW_INIT() PLLEN=TRUE; delay_ms(50)
#endif
#if defined(USB_HW_GENERIC_18F27J53)
#include <18F27J53.h>
#fuses NOWDT
#fuses NOXINST
//12Mhz clock configured for USB operation and 48MHz CPU operation
#fuses HSPLL
#fuses PLLEN
#fuses PLL3
#fuses NOCPUDIV
#use delay(clock=48M)
#DEFINE LED1 PIN_B5
#define LED2 PIN_B4
#define LED3 PIN_C7
#define BUTTON_PRESSED() (!input(PIN_B0))
#define PIN_USB_SENSE PIN_A3
#define __NO_UART__
#define HW_ADC_PORTS sAN0|sAN1|sAN2
#define HW_ADC_CHANNEL 0
#define HW_ADC_CONFIG ADC_CLOCK_INTERNAL
#byte OSCTUNE = 0xF9B
#bit PLLEN=OSCTUNE.6
#define HW_INIT() output_low(PIN_C0); output_low(PIN_C1); output_high(PIN_C2); output_high(PIN_B2); PLLEN=TRUE; delay_ms(50)
#endif
#if defined(__NO_UART__)
#define uart_putc(c)
#define uart_getc() (0)
#define uart_kbhit() (FALSE)
#define uart_printf(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z) { }
#define uart_task()
#else
#if defined(PIN_UART_TX)
#use rs232(baud=9600, xmit=PIN_UART_TX, rcv=PIN_UART_RX, errors)
#else
#use rs232(baud=115200, UART1, errors)
#endif
#define uart_getc getc
#define uart_kbhit kbhit
#define uart_printf printf
#if defined(UART_USE_TX_BUFFER)
char tbeBuffer[2750];
unsigned int16 tbeIn=0, tbeOut=0, tbeCount=0;
void uart_putc(char c)
{
if (tbeCount < sizeof(tbeBuffer))
{
tbeCount++;
tbeBuffer[tbeIn++] = c;
if (tbeIn >= sizeof(tbeBuffer))
tbeIn = 0;
}
}
void uart_task(void)
{
char c;
if (tbeCount)
{
tbeCount--;
c = tbeBuffer[tbeOut++];
if (tbeOut >= sizeof(tbeBuffer))
tbeOut = 0;
putc(c);
}
}
#else
void uart_putc(char c) {putc(c);}
#define uart_task()
#endif
#endif
/////////////////////////////////////////////////////////////////////////////
//
// Required macro: USB_CABLE_IS_ATTACHED()
//
// This macro provides configuration to the library to detect if a
// USB cable is attached or not. This is only relevant if the PIC is acting
// as a slave device.
//
// If you are using a USB connection sense method or pin, define this
// macro here. If you are not using connection sense, comment out this line.
// Without connection sense you will not know if the device gets disconnected.
//
// If you are using a PIC24/33 with the internal USB peripheral, you can connect
// the Vbus (5V) line from the USB to the Vbus pin on the PIC - you
// can then look at the SFR bit U1OTGSTAT.SESVD to determine if USB is
// connected.
//
// If you are not using the internal USB peripheral of a PIC24, you can connect
// Vbus to a GPIO to detect connection sense.
//
// For both methods (connecting to Vbus pin or GPIO pin), a pull-down resistor
// (around 150K) and capacitor (1uF) should also be placed on the Vbus pin.
//
/////////////////////////////////////////////////////////////////////////////
#if defined(PIN_USB_SENSE)
#define USB_CABLE_IS_ATTACHED() input(PIN_USB_SENSE)
#elif defined(__PCD__)
#bit U1OTGSTAT_SESVD=getenv("BIT:SESVD")
#define USB_CABLE_IS_ATTACHED() (U1OTGSTAT_SESVD)
//#define USB_CABLE_IS_ATTACHED() bit_test(*0x484,3) //24fj/33fj support only, won't work with 24ep/33ep
#endif
#ifndef LED_ON
#define LED_ON(x) output_low(x)
#endif
#ifndef LED_OFF
#define LED_OFF(x) output_high(x)
#endif
#ifndef HW_INIT
#define HW_INIT()
#endif
#ifndef __USB_PIC_PERIF__
#define __USB_PIC_PERIF__ 1
#endif
/*
#if defined(__PCD__)
#word W0REG=0
#word W1REG=2
#word W2REG=4
#word W3REG=6
#word W4REG=8
#word W5REG=10
#word W6REG=12
#word W7REG=14
#word W8REG=16
#word W9REG=18
#word W10REG=20
#word W11REG=22
#word W12REG=24
#word W13REG=26
#word W14REG=28
#word W15REG=30
#int_addrerr FAST
void handle_addrerr(void)
{
int16 w[16];
int16 h,l;
int32 val;
#asm
POP h;
POP l;
#endasm
w[0] = W0REG;
w[1] = W1REG;
w[2] = W2REG;
w[3] = W3REG;
w[4] = W4REG;
w[5] = W5REG;
w[6] = W6REG;
w[7] = W7REG;
w[8] = W8REG;
w[9] = W9REG;
w[10] = W10REG;
w[11] = W11REG;
w[12] = W12REG;
w[13] = W13REG;
w[14] = W14REG;
w[15] = W15REG;
h &= 0x00FF;
val = make32(h, l);
val -= 2;
// this address might be off by 2 bytes
printf("\r\n\nADDRESS FAULT 0x%LX ", val);
for (l=0;l<16;l++)
{
printf("W%U:%LX ", l, w[l]);
}
printf("\r\n");
while(TRUE);
}
#int_stackerr FAST
void handle_stackerr(void)
{
int16 w[16];
int16 h,l;
int32 val;
#asm
POP h;
POP l;
#endasm
w[0] = W0REG;
w[1] = W1REG;
w[2] = W2REG;
w[3] = W3REG;
w[4] = W4REG;
w[5] = W5REG;
w[6] = W6REG;
w[7] = W7REG;
w[8] = W8REG;
w[9] = W9REG;
w[10] = W10REG;
w[11] = W11REG;
w[12] = W12REG;
w[13] = W13REG;
w[14] = W14REG;
w[15] = W15REG;
h &= 0x00FF;
val = make32(h, l);
val -= 2;
// this address might be off by 2 bytes
printf("\r\n\nSTACK FAULT 0x%LX ", val);
for (l=0;l<16;l++)
{
printf("W%U:%LX ", l, w[l]);
}
printf("\r\n");
while(TRUE);
}
#endif //defined(__PCD__)
*/
#endif
|
4 – I Compiled the code with Mplab and everything was ok. No errors. I’ve used the Pickit3 to load the bootloader on PIC and ok.
5 – My application is very simple, just blink a Led.
Code: |
// My application
#include <18F4550.h>
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN, MCLR
#use delay(clock=48000000)
//#use rs232(BAUD=115200, parity=N, BITS=8, XMIT=pin_c6, RCV=pin_c7,ERRORS)
#define _bootloader
#include <usb_bootloader.h>
//#include <usb_cdc.h>
//#build(reset= 0x800, interrupt = 0x808)
//#org 0x0000, 0x07ff {}
#include <stdio.h>
#include <math.h> //para log(), log10().
static boolean led;
long int cont;
//---------------------------------------------------------------------------
#int_timer0
void MyTimer()
{
cont++;
if(cont == 47000)
{
cont = 0;
led = !led;
output_bit(pin_b7, led);
}
}
//---------------------------------------------------------------------------
void main()
{
setup_timer_0(RTCC_INTERNAL | RTCC_DIV_1 | RTCC_8_BIT);
enable_interrupts(int_timer0);
enable_interrupts(GLOBAL);
cont = 0;
while( true )
{
//output_toggle(pin_c0);
}
}
|
6 – After generate the .HEX from my application, I tried to use Siow.exe to load the application using the USB. I tried all speeds and nothing works. I press B4 pin, after the reset pin and the pic start the bootload mode. The siow recognize the pic and looks like everything is all right. I select download, choose the .hex and Siow apparently sent it to the PIC. The PIC restart and the application don’t run.
I’ve tested the application alone, programming with pickit3 and everything works fine.
7 – I also tried the teraterm software. But works the same as Siow.
8 – Now I really don’t know what to do. Please, anybody could give some help?
Best Regards!
Last edited by mecbb on Mon May 19, 2014 7:00 am; edited 1 time in total |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Sat May 17, 2014 3:03 am |
|
|
Key line leaping out at me in your application program, is:
#define _bootloader
This _must_ only be defined in the code that is the actual bootloader....
It is what switches bootloader.h, between setting things up for the bootloader itself, and setting things up for the loaded application.
Look at ex_bootload.c, and you will see this is _not_ defined. Then look at ex_bootloader.c, and here you will see it is..... |
|
|
mecbb
Joined: 16 May 2014 Posts: 4
|
|
Posted: Sat May 17, 2014 5:05 am |
|
|
Ttelmah,
I don’t have enough words to thank you. It works perfectly.
Thank you very much!
Eternally grateful
Best wishes |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Mon May 19, 2014 1:21 am |
|
|
You might want to flag the thread as 'solved'.
The documentation is unfortunately 'poor' for things like this, unless you go and study bootloader.h, and realise what this does.
Glad it worked. |
|
|
mecbb
Joined: 16 May 2014 Posts: 4
|
|
Posted: Mon May 19, 2014 6:47 am |
|
|
Ttelmah,
How can I flag as "Solved"?
Thanks |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Mon May 19, 2014 6:57 am |
|
|
You edit the subject line, and add [Solved].
Only the original poster, or moderator can do it. |
|
|
mecbb
Joined: 16 May 2014 Posts: 4
|
|
Posted: Mon May 19, 2014 7:03 am |
|
|
The Edit option was not available because I was not logged on. Very easy.
Thank you so much again |
|
|
SubhamayS
Joined: 07 Mar 2012 Posts: 34 Location: jalpaiguri, India
|
Does "ex_usb_bootloader.c" work with PIC18F2550 ? |
Posted: Wed Jan 27, 2016 12:01 pm |
|
|
Ttelmah wrote: | Key line leaping out at me in your application program, is:
#define _bootloader
This _must_ only be defined in the code that is the actual bootloader....
It is what switches bootloader.h, between setting things up for the bootloader itself, and setting things up for the loaded application.
Look at ex_bootload.c, and you will see this is _not_ defined. Then look at ex_bootloader.c, and here you will see it is..... |
I have followed the post and did whatever mentioned. The code is compiling fine. I have also loaded the program in to PIC18F2550 using PICkit 3. But tera term doesn't show any activity.. Plz help.. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Wed Jan 27, 2016 12:07 pm |
|
|
If you load the code with the PicKit, you destroy the bootloader.
You load the bootloader _only_ with the programmer.
Then compile the main code to use the bootloader, and load this with the terminal program. |
|
|
SubhamayS
Joined: 07 Mar 2012 Posts: 34 Location: jalpaiguri, India
|
Issue with CDC Bootloader |
Posted: Fri Jan 29, 2016 4:00 am |
|
|
Ttelmah wrote: | If you load the code with the PicKit, you destroy the bootloader.
You load the bootloader _only_ with the programmer.
Then compile the main code to use the bootloader, and load this with the terminal program. |
Thanks for the reply..
I am using 18F2550. Does the bootloader work with 18F2550 ?? The bootloader code I am using is given below. I am not using "ex_usb_common.h" I have loaded the "ex_usb_bootloader.c" using the programmer, but unable to load the application program using tera term. The USB is detected but windows 7 is unable to install the driver. I have mentioned the address of "cdc_NTXPVista78.inf", still windows is not detecting the driver. I am using CCS C compiler version 5.015. Do I need to modify the inf file ? Please Help..
Code: | #define __USB_PIC_PERIF__ 1
#if !defined(__PCH__)
#error USB CDC Library requires PIC18
#endif
#if __USB_PIC_PERIF__
#include <18F2550.h>
//configure a 20MHz crystal to operate at 48MHz
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN
#use delay(clock=48000000)
#else //use the National USBN960x peripheral
#include <18F452.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#endif //endif check to see which peripheral to use
/////////////////////////////////////////////////////////////////////////////
//
// If you are using a USB connection sense pin, define it here. If you are
// not using connection sense, comment out this line. Without connection
// sense you will not know if the device gets disconnected.
// (connection sense should look like this:
// 100k
// VBUS-----+----/\/\/\/\/\----- (I/O PIN ON PIC)
// |
// +----/\/\/\/\/\-----GND
// 100k
// (where VBUS is pin1 of the USB connector)
//
/////////////////////////////////////////////////////////////////////////////
///only ccs's 18F4550 development kit has this pin
/*
#if __USB_PIC_PERIF__ && defined(__PCH__)
#define USB_CON_SENSE_PIN PIN_B2
#endif
*/
/*
Configure, then load the bootloader definitions
*/
#define _bootloader
#include <usb_bootloader.h>
#define LOADER_ISR 0x28
#build(interrupt=LOADER_ISR)
// Includes all USB code and interrupts, as well as the CDC API
#include <usb_cdc.h>
/*
Goto the interrupt vector of the application.
*/
#org 0x08,0x17
void high_isr(void)
{
if (bit_test(g_InBootloader,0))
{
#ASM
goto LOADER_ISR
#ENDASM
}
else
{
#ASM
goto APPLICATION_ISR
#ENDASM
}
}
#org 0x18,0x27
void low_isr(void)
{
if (bit_test(g_InBootloader,0))
{
#ASM
goto LOADER_ISR+0x10
#ENDASM
}
else
{
#ASM
goto APPLICATION_ISR+0x10
#ENDASM
}
}
//Write to Flash ROM.
//
// location - flash program memory address
// src - pointer to data to write
// size - number of bytes to write to flash
//
// Here is the sequence of events:
// 1.) Goes to the beginning of the first erase block for this address
// 2.) Reads n records to ram, where n is the PIC's flash erase size
// 3.) Erases block in flash
// 4.) Modifies block in RAM
// 5.) Writes changed block back to FLASH. Writes in chunks defined by PIC's flash write size
// 6.) Goes back to step1 if there is still more data to be written
void rom_w(int32 location, char *src, int16 size)
{
#define EEPROM_ERASE_SIZE getenv("FLASH_ERASE_SIZE")
#define EEPROM_WRITE_SIZE getenv("FLASH_WRITE_SIZE")
int8 block[EEPROM_ERASE_SIZE];
int32 block_start;
int8 i;
int8 num;
block_start = location & (~((int32)EEPROM_ERASE_SIZE-1));
i=location-block_start;
while (size)
{
read_program_memory(block_start, block, sizeof(block)); //read entire block to ram buffer
if (size>(EEPROM_ERASE_SIZE-i)) {num=EEPROM_ERASE_SIZE-i;} else {num=size;}
memcpy(&block[i],src,num); //modify ram buffer
erase_program_eeprom(block_start); //erase entire block
write_program_memory(block_start, block, sizeof(block)); //write modified block
src+=num;
block_start+=EEPROM_ERASE_SIZE;
i=0;
size-=num;
}
}
#define BUFFER_LEN_LOD 64
#define ACKLOD 0x06
#define XON 0x11
#define XOFF 0x13
// Convert two hex characters to a int8
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);
}
void load_program(void)
{
int1 do_ACKLOD, done=FALSE;
int8 checksum, line_type;
int16 l_addr,h_addr=0;
int8 to;
int32 addr;
int8 dataidx, i, count;
int8 data[32];
int buffidx;
char buffer[BUFFER_LEN_LOD];
while (!done) // Loop until the entire program is downloaded
{
usb_task();
if (!usb_cdc_kbhit())
continue;
buffidx = 0; // Read into the buffer until 0x0D ('\r') is received or the buffer is full
to = 250; //250 milliseconds
do
{
if (!usb_cdc_kbhit())
{
delay_ms(1);
to--;
if (!to)
break;
}
else
to = 250;
i = usb_cdc_getc();
buffer[buffidx++] = i;
} while ( (i != 0x0D) && (i != 0x0A) && (buffidx <= BUFFER_LEN_LOD) );
if (!to)
continue;
usb_cdc_putc(XOFF); // Suspend sender
do_ACKLOD = TRUE;
// Only process data blocks that start with ':'
if (buffer[0] == ':') {
count = atoi_b16 (&buffer[1]); // Get the number of bytes from the buffer
// Get the lower 16 bits of address
l_addr = make16(atoi_b16(&buffer[3]),atoi_b16(&buffer[5]));
line_type = atoi_b16 (&buffer[7]);
addr = make32(h_addr,l_addr);
// If the line type is 1, then data is done being sent
if (line_type == 1)
{
done = TRUE;
}
else if ((addr >= (int32)APPLICATION_START) && (addr < ((int32)0x300000)))
{
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-3]))
do_ACKLOD = FALSE;
else
{
if (line_type == 0) {
// Loops through all of the data and stores it in data
// The last 2 bytes are the check sum, hence buffidx-3
for (i = 9,dataidx=0; i < buffidx-3; i += 2)
data[dataidx++]=atoi_b16(&buffer[i]);
rom_w(addr, data, count);
}
else if (line_type == 4)
h_addr = make16(atoi_b16(&buffer[9]), atoi_b16(&buffer[11]));
}
}
}
if (do_ACKLOD)
usb_cdc_putc (ACKLOD);
usb_cdc_putc(XON);
}
usb_cdc_putc (ACKLOD);
usb_cdc_putc(XON);
delay_ms(2000); //give time for packet to flush
reset_cpu();
}
void main(void)
{
//we use PIN_A4 as an event to determine if we should start the USB CDC
//bootloader. if it is not low (button is not pressed) then goto the
//application, else if is low (button is pressed) then do the bootloader.
if(!input(PIN_A4))
{
g_InBootloader = TRUE;
usb_cdc_init();
usb_init();
while(!usb_enumerated());
load_program();
}
g_InBootloader = FALSE;
#ASM
goto APPLICATION_START
#ENDASM
}
|
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Fri Jan 29, 2016 5:19 am |
|
|
The USB bootloader will work fine on your chip.
Study it. It does not use interrupts.
You are trying to bodge the interrupt handler to route interrupts to two different targets. This can be done, but 'why bother' It is much safer (and a little quicker) to use the USB as the example bootloader does with the interrupt polled.
You then have the interrupts set up to be used by the USB (which will therefore assume these are used), but you never enable the global interrupt (study the examples, _you_ have to do this if you are using the USB interrupt driven). So your code won't work... |
|
|
SubhamayS
Joined: 07 Mar 2012 Posts: 34 Location: jalpaiguri, India
|
|
Posted: Mon Feb 01, 2016 12:22 am |
|
|
Ttelmah wrote: | The USB bootloader will work fine on your chip.
Study it. It does not use interrupts.
You are trying to bodge the interrupt handler to route interrupts to two different targets. This can be done, but 'why bother' It is much safer (and a little quicker) to use the USB as the example bootloader does with the interrupt polled.
You then have the interrupts set up to be used by the USB (which will therefore assume these are used), but you never enable the global interrupt (study the examples, _you_ have to do this if you are using the USB interrupt driven). So your code won't work... |
I have tried using the CCS example bootloader, (without interrupts) but still the problem prevails. Windows is saying CSC BOOTLOADER not found. Contact manufacturer support section of your device for the driver. I have also tried searching the driver online but no driver is available. selecting the .inf file is also not working. The CDC diver is not present in the windows drivers list. I am using Lenovo Thinkpad T420, Windows 7 Professional 64-bit. Please Help ! :( |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Mon Feb 01, 2016 2:40 am |
|
|
The driver is in your PIC directory.
In the drivers sub-directory. "NT,2000,XP,VISTA,7,8,10", then the file "cdc_NTXPVista_7_8_10.inf" |
|
|
SubhamayS
Joined: 07 Mar 2012 Posts: 34 Location: jalpaiguri, India
|
|
Posted: Mon Feb 01, 2016 9:06 am |
|
|
Ttelmah wrote: | The driver is in your PIC directory.
In the drivers sub-directory. "NT,2000,XP,VISTA,7,8,10", then the file "cdc_NTXPVista_7_8_10.inf" |
Did it as you have suggested. But the problem prevails. Another fact is that, the USB serial communication is working fine on my board with 18F2550. The driver is also recognized easily. I was looking at the cdc_NTXPVista_7_8_10.inf file.
Code: | ;%CCS_CDC%=Reader, USB\VID_0461&PID_0033 this was removed for WHQL certification since it's not CCS's VID
;%CCS_CDCBOOT%=Reader, USB\VID_0461&PID_0034 this was removed for WHQL certification since it's not CCS's VID |
The above lines are commented. Is that an issue !!!! |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Mon Feb 01, 2016 9:34 am |
|
|
No. The VID should be 2405, and the PID should be 000c for the bootloader if you are compiling the example with the current settings. This is half a dozen lines further down in the file as CCS_CDCBOOT2.
If the device has VID 0461 listed, then you are using an old file in the compile. This is MicroChip's VID that was used at one time when the CCS code was a translation of the MicroChip code, and hence had to be removed. |
|
|
|
|
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
|