nmeyer
Joined: 09 Jul 2004 Posts: 70
|
Bootloader for loading External Memory (18F8722) |
Posted: Fri Jan 09, 2009 9:21 am |
|
|
I have posted some other posts about the PIC18F8722 and extended memory. I have been having issues with this, but through seaching the forum and some support from CCS I have made some progress. However, now I feel I understand what i have to do, but i am having issues. I was trying to load the program into external memory with the ICD, but support from CCS informed me that is not possible for the ICD. So the suggestion was to use a bootloader. Which I have takedn the CCS bootloader and i have been trying to modify it to work so that it will bootload the PIC flash first and then switch over to the external flash. I am prototyping this on the 18F8722 demo board from CCS. CCS's suggestion was to modify the bootload code so that in the areas which it call for write_program_memory() i needed to add in a decision point to determine whether it was internal memory or external and then add in wirite functions for the external. I have done this using the at1029.c include file for the write_ext_flash_memory() functions. All portions of this program seem to work fine seperately, bootloader, writing to external flash and main program. However, when i try to fully implement this with the switch over between internal and external my bootloader then hangs and times out. I am not sure why.
I have a new device called 18F8722EX that has 131072 for memory and a new 18F8722EX.h file that has the device called out as 18F8722EX.
Here is my Bootloader_ex.c
Code: |
#if defined(__PCM__)
#include <16F877.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7,RESTART_WDT,ERRORS) // Jumpers: 8 to 11, 7 to 12
#elif defined(__PCH__)
#include <18F8722EX.h>
#FUSES WDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES HS //High speed Osc (> 4mhz)
#FUSES NOPROTECT //Code not protected from reading
//#FUSES NOBROWNOUT //No brownout reset
#FUSES BROWNOUT //BROWN OUT ON
#FUSES BORV27 //RESET VOLTAGE AT 2.7V
//#FUSES BORV42 //RESET VOLTAGE AT 4.2V
//#FUSES BORV25 //Brownout reset at 2.5V
#FUSES NOPUT //No Power Up Timer
#FUSES NOCPD //No EE protection
#FUSES STVREN //Stack full/underflow will cause reset
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOWRT //Program memory not write protected
#FUSES NOWRTD //Data EEPROM not write protected
#FUSES IESO //Internal External Switch Over mode enabled
#FUSES FCMEN //Fail-safe clock monitor enabled
//#FUSES PBADEN //PORTB pins are configured as analog input channels on RESET
#FUSES NOWRTC //configuration not registers write protected
#FUSES NOWRTB //Boot block not write protected
#FUSES NOEBTR //Memory not protected from table reads
#FUSES NOEBTRB //Boot block not protected from table reads
#FUSES NOCPB //No Boot Block code protection
//#FUSES LPT1OSC //Timer1 configured for low-power operation
#FUSES MCLR //Master Clear pin enabled
#FUSES NOXINST //Extended set extension and Indexed Addressing mode enabled
#FUSES EMCU
#FUSES ABW20
#FUSES BW16
#use delay(clock=20000000,RESTART_WDT)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,RESTART_WDT,ERRORS)
#endif
#define _bootloader
//#include <bootloader.h>
//#include <loader.c>
#include "Z:\Projects\132-Rawson\07-012 AccurateII\Code\Extended Memory\bootloader.h"
#include "Z:\Projects\132-Rawson\07-012 AccurateII\Code\Extended Memory\loader_ext.c"
#if defined(__PCM__)
#org LOADER_END+1,LOADER_END+10
#elif defined(__PCH__)
#org LOADER_END+2,LOADER_END+20
#endif
void application(void) {
while(TRUE);
}
#if defined(__PCH__)
#org 0x40,0x7F
#else
#org 0x20,0x3F
#endif
void main(void) {
if(!input(PIN_A4))
{
load_program();
}
application();
}
#ORG default
#int_global
void isr(void) {
jump_to_isr(LOADER_END+5*(getenv("BITS_PER_INSTRUCTION")/8));
}
|
minor adjustments to CCS bootloaer.c
This is the loader_ext.c i have modified this to have the decision point for internal and external.
Code: |
#ifndef LOADER_END
#define LOADER_END getenv("PROGRAM_MEMORY")-1
#if defined(__PCM__)
#define LOADER_SIZE 0x17F
#elif defined(__PCH__)
#define LOADER_SIZE 0x3FF
#endif
#endif
#include "Z:\Projects\132-Rawson\07-012 AccurateII\Code\Extended Memory\ext_flash.c"
#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
#SEPARATE
unsigned int atoi_b16(char *s);
#ORG LOADER_ADDR+10, LOADER_END auto=0 default
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];
init_ext_flash_memory();
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 {
buffer[buffidx] = getc();
} while ( (buffer[buffidx++] != 0x0D) && (buffidx <= BUFFER_LEN_LOD) );
putchar (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 defined(__PCM__) // PIC16 uses word addresses
addr /= 2;
#endif
// If the line type is 1, then data is done being sent
if (line_type == 1) {
done = TRUE;
#if defined(__PCM__)
} else if ((addr < LOADER_ADDR || addr > LOADER_END) && addr < 0x2000){
#elif defined(__PCH__)
} else if ((addr < LOADER_ADDR || addr > LOADER_END) && addr < 0x300000){
#endif
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 defined(__PCM__)
if ((addr!=next_addr)&&(addr&(getenv("FLASH_ERASE_SIZE")-1)!=0))
#else
if ((addr!=next_addr)&&(addr&(getenv("FLASH_ERASE_SIZE")/2-1)!=0))
#endif
erase_program_eeprom(addr);
next_addr = addr + 1;
#endif
if (addr<=0x1FFFF)//this is my modification
write_program_memory(addr, data, count);
else
write_ext_flash_memory(addr-0x20000, data, count);//to here
}
else if (line_type == 4)
h_addr = make16(atoi_b16(&buffer[9]), atoi_b16(&buffer[11]));
}
}
}
if (do_ACKLOD)
putchar (ACKLOD);
putchar(XON);
}
putchar (ACKLOD);
putchar(XON);
#ifndef _bootloader
reset_cpu();
#endif
}
unsigned int atoi_b16(char *s) { // Convert two hex characters to a int8
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);
}
#ORG default
#ORG LOADER_ADDR, LOADER_ADDR+9
void load_program(void)
{
real_load_program();
} |
the ext_flash.c is the same as at29C1024.c file included with the compiler except for this change
Code: |
void write_ext_flash_memory(long address,long value, long count)
{
write_external_memory(START_ADDRESS+((int32)2*address),&value,count);
while(read_ext_flash_memory(address)!=value);
} |
Does any one see any reason why my decision point is causing it to time out?
Thanks |
|