View previous topic :: View next topic |
Author |
Message |
RickDaystorm
Joined: 01 Jul 2012 Posts: 12
|
Problems with PCWH v4.137 (Latest) |
Posted: Mon Oct 15, 2012 9:51 pm |
|
|
I upgraded from v4.083 to v4.137 today.
However, my bootloader and application code that worked perfectly well yesterday with the previous compiler version no longer work today with the latest compiler version. The bootloader portion "seems" to work fine as it allows the SIOW to load in the application, but the application never runs.
The ONLY difference between the two instances of code is the BORV fuse which had to be updated for the new version - v4.083 used BORV42 which is now undefined in v4.137 and had to be changed to BORV45.
Comparing the HEX files generated by the two compiler versions I'd discovered that the ones created with v4.137 are missing the very first line that appears in the HEX files created with v4.083.
I think that may be the root of my problem. Does anyone have any suggestions on what could be causing this or what could be done to fix it (other than re-installing my older version of PCWH).
I am using a PIC18F6722 running at 40MHz clocked from an external oscillator. VDD is 5V and I have a 47K between MCLR and VDD although I have disabled the MCLR pin. I am also not using the debugger.
The bootloader code is the standard CCS example tweaked to use an FTDI 245RL USB-Serial converter. I have been loading the PIC with the compiled bootloader HEX using the ICD, and then using the CCS SIOW application to load in my Application.hex file.
Here is my code:
bootloader.h
Code: | #define LOADER_END 0x7FF
#define LOADER_SIZE 0x4FF
#ifndef _bootloader
#build(reset=LOADER_END+1, interrupt=LOADER_END+9)
#org 0, LOADER_END {}
#endif |
bootloader.c
Code: | #include <18F6722.h>
#device adc=10
#fuses HS,PROTECT,PUT,NOLVP,NOWDT,CPD,NOWRTD,CPB,EBTRB
#fuses BROWNOUT,BORV45
#fuses NOMCLR,STVREN
#use delay(clock=40000000)
#define _bootloader
#include <bootloader.h>
#serialize(dataee=0x02,binary=4,listfile="serial_source.txt",log="serial_log.txt")
#define LOAD_VIA_USB // Comment this line out if you want to load in via RS232
#ifndef LOAD_VIA_USB
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,ERRORS)
#endif
#define BOOT_MODE_SEL PIN_A4 //When HIGH in BOOT Mode
#define LOADER_ADDR LOADER_END-LOADER_SIZE
#define BUFFER_LEN_LOD 64
int buffidx;
char buffer[BUFFER_LEN_LOD];
#define ACKLOD 0x06
#define XON 0x11
#define XOFF 0x13
//USB defines
#define FT_PWRN PIN_E5 // PIC Input: LOW when FT Chip is configured by the host
#define FT_RD PIN_E6 // PIC Output: Pull LOW and FT Chip presents its data... Pull HIGH to tristate FT's data bus
#define FT_WR PIN_E7 // PIC Output: Toggle HIGH->LOW and FT Chip reads its data bus and sends it to PC
#define FT_TXE PIN_E4 // PIC Input: When HIGH FT Chip's 384-byte TX buffer is full - Don't write when HIGH
#define FT_RXF PIN_E3 // PIC Input: LOW when FT Chip has at least one byte in the buffer. HIGH when empty
#SEPARATE
unsigned int atoi_b16(char *s);
//USB Functions
#SEPARATE
void setup_usb();
#SEPARATE
void send_USB_byte(int data);
#SEPARATE
int get_USB_byte();
#ORG LOADER_ADDR+10, LOADER_END auto=0 default //Original - DON'T TOUCH
void real_load_program (void)
{
int1 do_ACKLOD, done=FALSE;
int8 checksum, line_type;
int16 l_addr,h_addr=0;
int32 addr;
#if getenv("FLASH_ERASE_SIZE")>2
int32 next_addr;
#endif
int8 dataidx, i, count;
int8 data[32];
setup_usb();
while (!done) // Loop until the entire program is downloaded
{
buffidx = 0; // Read into the buffer until 0x0D ('\r') is received or the buffer is full
do
{
#ifdef LOAD_VIA_USB
while(input(FT_RXF)) delay_cycles(1); // Sit here and do nothing until FT245 tells us there is data in its buffer.
buffer[buffidx] = get_USB_byte();
#else
buffer[buffidx] = getc();
#endif
} while ( (buffer[buffidx++] != 0x0D) && (buffidx <= BUFFER_LEN_LOD) );
#ifdef LOAD_VIA_USB
send_USB_byte(XOFF); // Suspend sender
#else
putchar(XOFF); // Suspend sender
#endif
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 < LOADER_ADDR || addr > LOADER_END) && addr < 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]);
#if getenv("FLASH_ERASE_SIZE") > getenv("FLASH_WRITE_SIZE")
if ((addr!=next_addr)&&(addr&(getenv("FLASH_ERASE_SIZE")/2-1)!=0))
erase_program_eeprom(addr);
next_addr = addr + 1;
#endif
write_program_memory(addr, data, count);
}
else if (line_type == 4) h_addr = make16(atoi_b16(&buffer[9]), atoi_b16(&buffer[11]));
}
}
}
if (do_ACKLOD)
{
#ifdef LOAD_VIA_USB
send_USB_byte(ACKLOD); // Suspend sender
#else
putchar(ACKLOD); // Suspend sender
#endif
}
#ifdef LOAD_VIA_USB
send_USB_byte(XON); // Suspend sender
#else
putchar(XON); // Suspend sender
#endif
}
#ifdef LOAD_VIA_USB
send_USB_byte(ACKLOD); // Suspend sender
#else
putchar(ACKLOD); // Suspend sender
#endif
#ifdef LOAD_VIA_USB
send_USB_byte(XON); // Suspend sender
#else
putchar(XON); // Suspend sender
#endif
#ifndef _bootloader
reset_cpu();
#endif
}
// Convert two hex characters to a int8
unsigned int atoi_b16(char *s)
{
unsigned int result = 0;
int i;
for (i=0; i<2; i++,s++)
{
if (*s >= 'A') result = 16*result + (*s) - 'A' + 10;
else result = 16*result + (*s) - '0';
}
return(result);
}
//USB
void setup_usb()
{
int h=0;
input(FT_PWRN); // Ensure E0 (PWR_ENABLE) is set up as an input
set_tris_d(0xFF); // Configure Port D as an input
output_high(FT_RD); // Make sure FT tristates its output
output_high(FT_WR); // Make sure FT's Write input is high
for(h=0;h<255;h++) // Make sure FTDI's Buffer is empty by performing 130 reads
{
get_USB_byte();
}
}
void send_USB_byte (int data)
{
output_high(FT_RD); // Make sure FT tristates its output
output_high(FT_WR); // Make sure FT's Write input is high
while (input(FT_TXE)==1)
{
delay_cycles(1); // Do nothing until FT empties its buffer
}
output_d(data); // Place data on Port D
output_low(FT_WR); // Toggle FT's WR pin LOW so it reads in port data
delay_cycles(2);
output_high(FT_WR); // Return FT's Write input HIGH
set_tris_d(0xFF); // Configure Port D as an input
}
int get_USB_byte()
{
int data = 0;
output_high(FT_RD); // Make sure FT tristates its output
output_high(FT_WR); // Make sure FT's Write input is high
output_low(FT_RD);
delay_cycles(2);
data = input_d();
output_high(FT_RD);
set_tris_d(0xFF); // Configure Port D as an input
return (data);
}
#ORG default
#ORG LOADER_ADDR, LOADER_ADDR+9 //Original - DON'T TOUCH
void load_program(void)
{
real_load_program();
}
#org LOADER_END+2,LOADER_END+20 //Original - DON'T TOUCH
void application(void)
{
while(TRUE);
}
//#org 0x40,0x7F //Original
#org 0x40,0x1EC //New
void main(void)
{
int usb_byte = 0;
setup_usb();
//Original CCS Code
if(input(BOOT_MODE_SEL))
{
load_program();
}
application();
}
#ORG default
#int_global
void isr(void)
{
//jump_to_isr(LOADER_END+5*(getenv("BITS_PER_INSTRUCTION")/8)); //original
jump_to_isr(LOADER_END+9); //Ttelmah's suggestion
} |
HEX generated by v4.083
Code: | :020000040000FA
:0400000020EF00F0FD
:0800080004EF04F00000000009
:0E00100000000000000000000CEF04F01000E3
:10004000F86AD09EEA6AE96AC150C00B0F09C16E16
:10005000070EB46E476A6BD9928880A801D050D938
:04006000CFDB0300EF
:040300009CD8000C79
:06030A007C6B969C8D8CBB
:10031000969E8D8E969C8D9C00D0FF0E956E83CF01 |
HEX generated by v4.137
Code: | :0400000020EF00F0FD
:0800080004EF04F00000000009
:0E00100000000000000000000CEF04F01000E3
:10004000F86AD09EEA6AE96AC150C00B0F09C16E16
:10005000070EB46E476A6BD9928880A801D050D938
:04006000CFDB0300EF
:040300009CD8120073
:06030A007C6B969C8D8CBB
:10031000969E8D8E969C8D9C00D0956883CF7CF0A8 |
Application.c
Code: | #include <18F6722.h>
#device adc=10
#fuses HS,PROTECT,PUT,NOLVP,NOWDT,CPD,NOWRTD,CPB,EBTRB // Matches Bootloader
#fuses BROWNOUT,BORV45
#fuses NOMCLR,STVREN
#use delay(clock=40000000)
#include "bootloader.h"
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,ERRORS)
//************************
#define MAJ_VERSION 0x00
#define MIN_VERSION 0x32
...
|
HEX generated by v4.083
Code: | :020000040000FA
:040800002DEF2DF0BB
:08080800056ED8CF06F0E0CF29
:1008100007F00001E9CF0DF0EACF08F0E1CF09F0D1
:10082000E2CF0AF0D9CF0BF0DACF0CF0F3CF14F00F
:10083000F4CF15F0FACF16F0FBCF17F000C00FF091
:1008400001C010F002C011F003C012F004C013F098 |
HEX generated by v4.137
Code: | :04080000F6EF2CF0F3
:08080800046ED8CF05F0E0CF2B
:1008100006F00001E9CF0CF0EACF07F0E1CF08F0D5
:10082000E2CF09F0D9CF0AF0DACF0BF0F3CF12F014
:10083000F4CF13F0FACF14F0F5CF15F0F6CF16F091
:10084000F7CF17F0F8CF18F0FBCF19F000C00EF07B |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
RickDaystorm
Joined: 01 Jul 2012 Posts: 12
|
|
Posted: Tue Oct 16, 2012 5:40 am |
|
|
As always, thanks for the lightning fast response PCM. I completely missed those posts.
In one of them FvM says:
Quote: | As explained in the linked post, you only need to initialize the extended address part in your bootloader to make it work without patching the *.hex files. |
but I can't figure out exactly how to initialize the extended address part in my bootloader.
I looked for clues in the latest bootloader.h and ex_bootloader.c files that came with v4.137 but I can't find any new statements in the code that weren't there in the previous versions.
Is this perhaps a compiler setting that needs to be changed? |
|
|
thefloyd
Joined: 02 Sep 2009 Posts: 46
|
|
Posted: Tue Oct 16, 2012 3:24 pm |
|
|
RickDaystorm wrote: | As always, thanks for the lightning fast response PCM. I completely missed those posts.
In one of them FvM says:
Quote: | As explained in the linked post, you only need to initialize the extended address part in your bootloader to make it work without patching the *.hex files. |
but I can't figure out exactly how to initialize the extended address part in my bootloader.
I looked for clues in the latest bootloader.h and ex_bootloader.c files that came with v4.137 but I can't find any new statements in the code that weren't there in the previous versions.
Is this perhaps a compiler setting that needs to be changed? |
You didn't follow the links all the way through.
I don't use bootloaders (yet) so I can't vouch for the solution but it's documented in the post that's linked from the post PCM Programmer gave:
http://www.ccsinfo.com/forum/viewtopic.php?t=38874
Quote: |
For usage with the Microchip HID bootloader, the most simple solution is to initialize the extended Address part in the PC software.
Change
Code: |
unsigned long extendedAddress;
|
to
Code: |
unsigned long extendedAddress = 0;
|
|
|
|
|
RickDaystorm
Joined: 01 Jul 2012 Posts: 12
|
|
Posted: Tue Oct 16, 2012 4:56 pm |
|
|
I saw that post, but didn't understand any of the information contained within:
1. What is the PC Software the post was referring to;
2. What is the Microchip HID bootloader (I'm assuming it's a bootloader for PICs with built-in USB hardware);
3. Where to find the following declaration and change it:
Code: |
//FROM:
unsigned long extendedAddress;
//TO:
unsigned long extendedAddress = 0; |
4. Where btn_OpenHexFile_Click in Form1.h is located and what is it.
If someone could please get out the sock puppets and large crayons and explain in simple terms how the beloved SIOW bootloader scheme is supposed to work with this new line of CCS compiler versions I would be ever so grateful.
Thanks,
Rick |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Oct 16, 2012 5:47 pm |
|
|
He's referring to this:
Quote: | Microchip Libraries of Applications v2012-08-22 Windows | which can be downloaded here (237 MB):
http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=2680&dDocName=en547784
After downloading, I ran the installer. I only selected the tickbox
for USB Demos.
Then doing a text search for this:
Quote: | unsigned long extendedAddress;
|
gives this file:
Quote: | c:\microchip solutions v2012-08-22\usb\device - bootloaders\hid\software - windows\form1.h |
which is part of a Windows application written in C++.
When compiled, it creates this executable file:
Quote: | c:\microchip solutions v2012-08-22\usb\device - bootloaders\hid\hidbootloader (windows).exe |
Here is a screenshot of the Windows app:
http://i44.tinypic.com/24lmz3d.jpg
The version number in the screenshot there is old. It builds a newer version.
But you're not using a USB bootloader Windows app. You said in your
original post that you're doing this:
Quote: | using the CCS SIOW application to load in my Application.hex file. |
So I doubt if any of this discussion will fix that problem.
Read this guy's webpage. He may have some tips for you:
http://www.picprojects.net/usbbootloader/index.html |
|
|
RickDaystorm
Joined: 01 Jul 2012 Posts: 12
|
|
Posted: Tue Oct 16, 2012 7:07 pm |
|
|
Would it be safe to say then that the only way around this issue is to manually edit the application HEX file by adding in that first line or even revert back to an older PCW version that generates the "proper" hex files?
Why would CCS do something like this?
Rick |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Oct 16, 2012 7:41 pm |
|
|
The reason is explained in this thread:
http://www.ccsinfo.com/forum/viewtopic.php?t=38874
Why don't you email CCS and ask them to add a #device statement
or some other option which will allow that line to be put back in the Hex file. |
|
|
RickDaystorm
Joined: 01 Jul 2012 Posts: 12
|
|
Posted: Wed Oct 17, 2012 4:49 pm |
|
|
From CCS Support:
Quote: |
This would be a problem with SIOW not the compiler.
What is the date of your SIOW.EXE file?
Try the stand-alone bootloader program on our software download page. |
If there is one thing I've never had a problem with over the past 10 years of tinkering with PICs, that's been the trusty SIOW.EXE. |
|
|
asmallri
Joined: 12 Aug 2004 Posts: 1634 Location: Perth, Australia
|
|
Posted: Wed Oct 17, 2012 5:22 pm |
|
|
The proper way to fix this problem is to have CCS remove the bug because that is what it is. All hex files produced by the compiler should include the initial type 4 record. _________________ Regards, Andrew
http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!! |
|
|
jeremiah
Joined: 20 Jul 2010 Posts: 1346
|
|
Posted: Wed Oct 17, 2012 8:30 pm |
|
|
According to the hard copy of the spec I have here, they are within spec, so I would hesitate to call it a bug on their part. If anything SIOW.exe is not fully compatible with the specification for Intel hex file format.
In the extended address section:
Quote: |
When an Extended Linear Address Record defines the value of LBA, it may appear anywhere within a
32-bit hexadecimal object file. This value remains in effect until another Extended Linear Address
Record is encountered. The LBA defaults to zero until an Extended Linear Address Record is
encountered.
|
Now it certainly is not good form to change how something works like that, but both methods appear to be in spec unless a new revised version of the specification is saying otherwise (my hard copy is dated 1988). |
|
|
RickDaystorm
Joined: 01 Jul 2012 Posts: 12
|
|
Posted: Thu Oct 18, 2012 8:56 am |
|
|
New Reply from CCS Support:
Quote: | Sorry, I was wrong about SIOW. The problem would have to do with the bootloader loaded in the
PIC. If you based your code on our example program make sure your declaration of h_addr looks
like the following line. You need to initialize h_addr to 0 before starting the download.
Code: | int16 l_addr,h_addr=0; |
|
Then later on this one:
Quote: | The Intel hex file specification indicates the high address obtained from type 4 records
is asumed to be zero at the start of a file so the type 4 record with zero is not needed.
If your bootloader sets the high address to zero you should be covered.
There may be some other problem perhaps related to a corruption of the first line
transmitted. Try adding a comment line to the start of the file and see if that also works. |
Is there something that could be changed in the real_load_program() function in CCS' loader.c example in order to work around this? |
|
|
technomation
Joined: 27 Oct 2012 Posts: 8 Location: united kingdom
|
|
Posted: Sat Oct 27, 2012 7:20 am |
|
|
I'm pretty sure the issue is the compiled size of the bootloader.c application and that the loading of the main application is overwriting the last part of the loader file so the processor doesn't know to start your main application.
This is because the compiler produces a larger file in the newer versions of the hex file. I use the ccs bootloader with a 16f1938 and when I upgraded I had a similar problem. The solution I'm using still (as I haven't sat down to really solve it) is I have compiled the bootloader.c in the old version and load the hex file normally using my ICSP link, then use the SIOW program to load my application (having compiled it with the bootloader.h file included). This has worked well so far for me!
If anyone more clever than me does know what line needs changing to solve it though I'd be very interested.
regards
graham |
|
|
|