Ah, no. I actually started from the microchip bootloader and modified
it using your clockfreq, configbits (same one from the target program
so I don't have to rewrite it from the application's hex file), i2c,
serial, timer, uart, and util source files (not the ones from the
bootloader though). I did add in your MCLR and POR reset protections
though.
What I am doing is just going from the bootloader (on a reset or power
on) to the main program. The catch here is that my hex file is coming
in from a different communication protocol, so I have to catch it
using the UART (using the _U2RXInterrupt and _U2TXInterrupt). I also
use _T3Interrupt to catch the time, but I believe that I could find a
workaround for that one. So far I have not been successful in using
the linker script from the bully bootloader (after I modified the
addresses so they wouldn't collide with the bootloader's program
space) because the interrupts will not work when I use it. I have also
attempted to rename my interrupts to match up with the linker script.
Are they not working because (your version of) the bootloader linker
script it is lacking the extra code that (your version of) the
application's linker script uses to point between DefaultInterrupt and
the intended interrupt?
If this is the case, I believe I may have to use the application
linker script (from the bully bootloader) and remap the IVT to a
mutually unused page of program memory. Then I would have to write a
function at both the beginning of my bootloader and the beginning of
the application to rewrite the remapped IVT to point the interrupts to
the bootloader's / application's version of the interrupts. In that
case, I would need to know the address of the interrupt function I'm
pointing to, which I'll need to figure out.
I have added the code from main.c below. Is there a way to attach
files to the group?
Thanks!
Remy
/********************************************************************
* FileName: main.c
* Dependencies:
* Processor: PIC24H Family
* Hardware: Explorer 16
* Compiler: C30 2.01
* Company: Microchip Technology, Inc.
*
* Software License Agreement
*
* The software supplied herewith by Microchip Technology Incorporated
* (the “Company”) for its PICmicro® Microcontroller is intended and
* supplied to you, the Company’s customer, for use solely and
* exclusively on Microchip PICmicro Microcontroller products. The
* software is owned by the Company and/or its supplier, and is
* protected under applicable copyright laws. All rights are reserved.
* Any use in violation of the foregoing restrictions may subject the
* user to criminal sanctions under applicable laws, as well as to
* civil liability for the breach of the terms and conditions of this
* license.
*
* THIS SOFTWARE IS PROVIDED IN AN “AS IS” CONDITION. NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
* TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
* IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
*********************************************************************/
//#include "p24Hxxxx.h"
#include "pic24_all.h"
#include "pic24_delay.h"
#include "display.h"
#define EXT
#include "interrup.h"
#include "ram.h"
#undef EXT
#include "def.h"
//1.00a-004-boot-rme #define FCY 40000000
//1.00a-004-boot-rme #define BAUDRATE 9600
//1.00a-004-boot-rme #define BRGVAL ((FCY/BAUDRATE)/16)-1
// External Oscillator
//1.00a-004-boot-rme _FOSCSEL(FNOSC_PRIPLL); // Primary (XT,
HS, EC) Oscillator with PLL
//1.00a-004-boot-rme _FOSC(FCKSM_CSDCMD & OSCIOFNC_OFF &
POSCMD_XT); // Clock Switching and Fail Safe Clock Monitor is disabled
// OSC2 Pin Function: OSC2 is Clock Output
// Primary Oscillator Mode: XT Crystanl
//1.00a-005-boot-rme _FWDT(FWDTEN_OFF); // Watchdog
Timer Enabled/disabled by user software
// (LPRC can be disabled by clearing SWDTEN bit in RCON
register
//_FPOR(PWRTEN_OFF); // Turn off the power-up timers.
//_FGS(GCP_OFF); // Disable Code Protection
extern UWord32 ReadLatch(UWord16, UWord16);
void PutChar(unsigned char);
void GetChar(unsigned char *);
void WriteBuffer(unsigned char *, int);
void ReadPM(unsigned char *, uReg32);
void WritePM(unsigned char *, uReg32);
int main(void)
{
// initialize_interrupt_table();
configClock(); //1.00a-004-boot-rme
configI2C1(50); //1.00b-mag-002-rme //50MHz
configUART2(19200); // configure UART2 for 19200 //1.00a-004-boot-rme
//Initializes LCD Display and sends Micro-Mag title to display
DELAY_MS(45); //1.00b-mag-006-rme
display_init(); //1.00b-mag-005-rme //Initializes the LCD display
display_send_title(); //1.00b-mag-005-rme //Sends the title to the
LCD display
CONFIG_DIRECTION_PIN_2(); //1.00a-004-boot-rme
SET_DIRECTION_RECEIVE_2(); //1.00a-004-boot-rme
configOutputs();
mcsio_initialization_2(); //1.00a-004-boot-rme
interrupt_initialization(); //1.00a-004-boot-rme
// Configure Oscillator to operate the device at 40Mhz
// Fosc= Fin*M/(N1*N2), Fcy=Fosc/2
// Fosc= 8M*40(2*2)=80Mhz for 8M input clock
//1.00a-004-boot-rme PLLFBD=38; // M=40
//1.00a-004-boot-rme CLKDIVbits.PLLPOST=0; // N1=2
//1.00a-004-boot-rme CLKDIVbits.PLLPRE=0; // N2=2
//1.00a-004-boot-rme OSCTUN=0; // Tune FRC oscillator, if FRC is
used
//1.00a-005-boot-rme RCONbits.SWDTEN=0; /* Disable Watch
Dog Timer*/
while(OSCCONbits.LOCK!=1) {}; /* Wait for PLL to lock*/
//1.00a-003-rme SourceAddr.Val32 = 0xc00;
SourceAddr.Word.LW = 0x8600;
SourceAddr.Word.HW = 0x0000;
Delay.Val32 = ReadLatch(SourceAddr.Word.HW, SourceAddr.Word.LW);
if(Delay.Val[0] == 0 || (_POR==0 && _EXTR==0))
{
ResetDevice();
}
//1.00a-004-boot-rme T2CONbits.T32 = 1; /* to increment every
instruction cycle */
//1.00a-004-boot-rme IFS0bits.T3IF = 0; /* Clear the Timer3 Interrupt
Flag */
//1.00a-004-boot-rme IEC0bits.T3IE = 0; /* Disable Timer3 Interrup
Service Routine */
if((Delay.Val32 & 0x000000FF) != 0xFF)
{
/* Convert seconds into timer count value */
//Delay.Val32 = ((UWord32)(FCY)) * ((UWord32)(Delay.Val[0]));
// PR3 = Delay.Word.HW;
// PR2 = Delay.Word.LW;
// /* Enable Timer */
// T2CONbits.TON=1;
}
//1.00a-004-boot-rme U2BRG = BRGVAL ; /* BAUD Rate Setting of
Uart2 */
//1.00a-004-boot-rme U2MODE = 0x8000; /* Reset UART to 8-n-1, alt
pins, and enable */
//1.00a-004-boot-rme U2STA = 0x0400; /* Reset status register and
enable TX */
/***************************/
/* Config MCSIO structures */
/***************************/
sw_status.cfg_valid = FALSE; //1.00a-004-boot-rme
sw_status.cfg_download = TRUE; //1.00a-004-boot-rme
sw_status.cfg_download_timer = 125; //1.00a-004-boot-rme
sw_status.filler = 0xFF; //1.00a-004-boot-rme
sw_status.serial_numb = 0x0001; //1.00a-004-boot-rme
sw_status.sw_version[0] = 'M'; //1.00a-004-boot-rme
sw_status.sw_version[1] = 'I'; //1.00a-004-boot-rme
sw_status.sw_version[2] = 'C'; //1.00a-004-boot-rme
sw_status.sw_version[3] = 'R'; //1.00a-004-boot-rme
sw_status.sw_version[4] = 'O'; //1.00a-004-boot-rme
sw_status.sw_version[5] = '-'; //1.00a-004-boot-rme
sw_status.sw_version[6] = 'B'; //1.00a-004-boot-rme
sw_status.sw_version[7] = 'O'; //1.00a-004-boot-rme
sw_status.sw_version[8] = 'O'; //1.00a-004-boot-rme
sw_status.sw_version[9] = 'T'; //1.00a-004-boot-rme
sw_status.sw_version[10] = ' '; //1.00a-004-boot-rme
sw_status.sw_version[11] = ' '; //1.00a-004-boot-rme
sw_status.sw_version[12] = 0X00; //1.00a-004-boot-rme
//1.00a-004-boot-rme
version_numb.name[0] = 'B'; //1.00a-004-boot-rme
version_numb.name[1] = 'O'; //1.00a-004-boot-rme
version_numb.name[2] = 'O'; //1.00a-004-boot-rme
version_numb.name[3] = 'T'; //1.00a-004-boot-rme
version_numb.name[4] = 'L'; //1.00a-004-boot-rme
version_numb.name[5] = 'O'; //1.00a-004-boot-rme
version_numb.name[6] = 'A'; //1.00a-004-boot-rme
version_numb.name[7] = 'D'; //1.00a-004-boot-rme
version_numb.name[8] = 'E'; //1.00a-004-boot-rme
version_numb.name[9] = 'R'; //1.00a-004-boot-rme
version_numb.name[10] = ' '; //1.00a-004-boot-rme
version_numb.name[11] = '1'; //1.00a-004-boot-rme
version_numb.name[12] = '.'; //1.00a-004-boot-rme
version_numb.name[13] = '0'; //1.00a-004-boot-rme
version_numb.name[14] = '0'; //1.00a-004-boot-rme
version_numb.name[15] = 0x00; //1.00a-004-boot-rme
//1.00a-004-boot-rme
//1.00a-004-boot-rme
version_numb.co_name[0] = 'M'; //1.00a-004-boot-rme
version_numb.co_name[1] = 'C'; //1.00a-004-boot-rme
version_numb.co_name[2] = 'S'; //1.00a-004-boot-rme
version_numb.co_name[3] = ' '; //1.00a-004-boot-rme
version_numb.co_name[4] = ' '; //1.00a-004-boot-rme
version_numb.co_name[5] = ' '; //1.00a-004-boot-rme
version_numb.co_name[6] = ' '; //1.00a-004-boot-rme
version_numb.co_name[7] = ' '; //1.00a-004-boot-rme
version_numb.co_name[8] = ' '; //1.00a-004-boot-rme
version_numb.co_name[9] = ' '; //1.00a-004-boot-rme
version_numb.co_name[10] = ' '; //1.00a-004-boot-rme
version_numb.co_name[11] = ' '; //1.00a-004-boot-rme
version_numb.co_name[12] = ' '; //1.00a-004-boot-rme
version_numb.co_name[13] = ' '; //1.00a-004-boot-rme
version_numb.co_name[14] = ' '; //1.00a-004-boot-rme
version_numb.co_name[15] = 0X00; //1.00a-004-boot-rme
//1.00a-004-boot-rme
version_numb.model_name[0] = 'B'; //1.00a-004-boot-rme
version_numb.model_name[1] = 'O'; //1.00a-004-boot-rme
version_numb.model_name[2] = 'O'; //1.00a-004-boot-rme
version_numb.model_name[3] = 'T'; //1.00a-004-boot-rme
version_numb.model_name[4] = 'L'; //1.00a-004-boot-rme
version_numb.model_name[5] = 'O'; //1.00a-004-boot-rme
version_numb.model_name[6] = 'A'; //1.00a-004-boot-rme
version_numb.model_name[7] = 'D'; //1.00a-004-boot-rme
version_numb.model_name[8] = 'E'; //1.00a-004-boot-rme
version_numb.model_name[9] = 'R'; //1.00a-004-boot-rme
version_numb.model_name[10] = ' '; //1.00a-004-boot-rme
version_numb.model_name[11] = '1'; //1.00a-004-boot-rme
version_numb.model_name[12] = '.'; //1.00a-004-boot-rme
version_numb.model_name[13] = '0'; //1.00a-004-boot-rme
version_numb.model_name[14] = '0'; //1.00a-004-boot-rme
version_numb.model_name[15] = 0X00; //1.00a-004-boot-rme
//1.00a-004-boot-rme
version_numb.installed_date.MONTH = 8; //1.00a-004-boot-rme
version_numb.installed_date.DATE = 23; //1.00a-004-boot-rme
version_numb.installed_date.YEAR = 11; //1.00a-004-boot-rme
//1.00a-004-boot-rme
version_numb.serial_number[0] = 'V'; //1.00a-004-boot-rme
version_numb.serial_number[1] = 'E'; //1.00a-004-boot-rme
version_numb.serial_number[2] = 'R'; //1.00a-004-boot-rme
version_numb.serial_number[3] = 'S'; //1.00a-004-boot-rme
version_numb.serial_number[4] = 'I'; //1.00a-004-boot-rme
version_numb.serial_number[5] = 'O'; //1.00a-004-boot-rme
version_numb.serial_number[6] = 'N'; //1.00a-004-boot-rme
version_numb.serial_number[7] = ' '; //1.00a-004-boot-rme
version_numb.serial_number[8] = '1'; //1.00a-004-boot-rme
version_numb.serial_number[9] = '.'; //1.00a-004-boot-rme
version_numb.serial_number[10] = '0'; //1.00a-004-boot-rme
version_numb.serial_number[11] = '0'; //1.00a-004-boot-rme
version_numb.serial_number[12] = 'A'; //1.00a-004-boot-rme
version_numb.serial_number[13] = ' '; //1.00a-004-boot-rme
version_numb.serial_number[14] = ' '; //1.00a-004-boot-rme
version_numb.serial_number[15] = 0X00; //1.00a-004-boot-rme
//1.00a-004-boot-rme
version_numb.cfg_version = 'B'; //1.00a-004-boot-rme
version_numb.cfg_type = 'B'; //1.00a-004-boot-rme
version_numb.cfg_month = 8; //1.00a-004-boot-rme
version_numb.cfg_dom = 23; //1.00a-004-boot-rme
version_numb.cfg_year = 11; //1.00a-004-boot-rme
version_numb.cfg_hour = 12; //1.00a-004-boot-rme
version_numb.cfg_minute = 47; //1.00a-004-boot-rme
version_numb.load_month = 8; //1.00a-004-boot-rme
version_numb.load_dom = 23; //1.00a-004-boot-rme
version_numb.load_year = 11; //1.00a-004-boot-rme
version_numb.load_hour = 21; //1.00a-004-boot-rme
version_numb.load_minute = 47; //1.00a-004-boot-rme
version_numb.model_numb = 'u'; //1.00a-004-boot-rme
system_transmit_success =0;
system_transmit_completed =0;
system_firmware_receiving = 0;
while(1)
{
char Command;
/* //1.00a-004-boot-rme
GetChar(&Command);
switch(Command)
{
case COMMAND_READ_PM: //tested
{
uReg32 SourceAddr;
GetChar(&(SourceAddr.Val[0]));
GetChar(&(SourceAddr.Val[1]));
GetChar(&(SourceAddr.Val[2]));
SourceAddr.Val[3]=0;
ReadPM(Buffer, SourceAddr);
WriteBuffer(Buffer, PM_ROW_SIZE*3);
break;
}
case COMMAND_WRITE_PM: // tested
{
uReg32 SourceAddr;
int Size;
GetChar(&(SourceAddr.Val[0]));
GetChar(&(SourceAddr.Val[1]));
GetChar(&(SourceAddr.Val[2]));
SourceAddr.Val[3]=0;
for(Size = 0; Size < PM_ROW_SIZE*3; Size++)
{
GetChar(&(Buffer[Size]));
}
Erase(SourceAddr.Word.HW,SourceAddr.Word.LW,PM_ROW_ERASE);
WritePM(Buffer, SourceAddr); //program page
PutChar(COMMAND_ACK); //Send Acknowledgement
break;
}
case COMMAND_READ_ID:
{
uReg32 SourceAddr;
uReg32 Temp;
SourceAddr.Val32 = 0xFF0000;
Temp.Val32 = ReadLatch(SourceAddr.Word.HW, SourceAddr.Word.LW);
WriteBuffer(&(Temp.Val[0]), 4);
SourceAddr.Val32 = 0xFF0002;
Temp.Val32 = ReadLatch(SourceAddr.Word.HW, SourceAddr.Word.LW);
WriteBuffer(&(Temp.Val[0]), 4);
break;
}
case COMMAND_WRITE_CM:
{
int Size;
for(Size = 0; Size < CM_ROW_SIZE*3;)
{
GetChar(&(Buffer[Size++]));
GetChar(&(Buffer[Size++]));
GetChar(&(Buffer[Size++]));
PutChar(COMMAND_ACK); //Send Acknowledgement
}
break;
}
case COMMAND_RESET:
{
uReg32 SourceAddr;
int Size;
uReg32 Temp;
for(Size = 0, SourceAddr.Val32 = 0xF80000; Size < CM_ROW_SIZE*3;
Size +=3, SourceAddr.Val32 += 2)
{
if(Buffer[Size] == 0)
{
Temp.Val[0]=Buffer[Size+1];
Temp.Val[1]=Buffer[Size+2];
WriteLatch( SourceAddr.Word.HW,
SourceAddr.Word.LW,
Temp.Word.HW,
Temp.Word.LW);
WriteMem(CONFIG_WORD_WRITE);
}
}
ResetDevice();
break;
}
case COMMAND_NACK:
{
ResetDevice();
break;
}
default:
PutChar(COMMAND_NACK);
break;
}
*/ //1.00a-004-boot-rme
if (old_sec_ticker != sec_ticker)
{
if((unsigned char) Delay.Val[0] == 0xFF)
{
sec_ticker = 0;
}
old_sec_ticker = sec_ticker;
if((sec_ticker > (unsigned char) Delay.Val[0]) && ((unsigned char)
Delay.Val[0] != 0xFF))
{
sec_ticker = sec_ticker;
ResetDevice();
}
checkRxErrorUART2();
CLRWDT(); // Clear Watchdog timer //1.00a-005-boot-
rme
if(mcsio_2.uart_state == RS485_IDLE)
mcsio_reset_transceiver_2();
}
if (mcsio_2.uart_state == RS485_MESSAGE_RECEIVED)
{
if (mcsio_msg_valid_2())
{
sec_ticker = 0;
old_sec_ticker = 0;
mcsio_msg_response_2(); // mcsio response
}
else
mcsio_reset_transceiver_2(); // Reset mcsio channel
}
}
}
/
******************************************************************************/
void GetChar(unsigned char * ptrChar)
{
while(1)
{
// if timer expired, signal to application to jump to user code
if(IFS0bits.T3IF == 1)
{
* ptrChar = COMMAND_NACK;
break;
}
// check for receive errors
if(U2STAbits.FERR == 1)
{
continue;
}
// must clear the overrun error to keep uart receiving
if(U2STAbits.OERR == 1)
{
U2STAbits.OERR = 0;
continue;
}
// get the data
if(U2STAbits.URXDA == 1)
{
T2CONbits.TON=0; // Disable timer countdown
* ptrChar = U2RXREG;
break;
}
}
}
/
******************************************************************************/
void ReadPM(unsigned char * ptrData, uReg32 SourceAddr)
{
int Size;
uReg32 Temp;
for(Size = 0; Size < PM_ROW_SIZE; Size++)
{
Temp.Val32 = ReadLatch(SourceAddr.Word.HW, SourceAddr.Word.LW);
ptrData[0] = Temp.Val[2];;
ptrData[1] = Temp.Val[1];;
ptrData[2] = Temp.Val[0];;
ptrData = ptrData + 3;
SourceAddr.Val32 = SourceAddr.Val32 + 2;
}
}
/
******************************************************************************/
void VerifyPM(unsigned char * ptrData, uReg32 SourceAddr)
{
int Size;
uReg32 Temp;
for(Size = 0; Size < PM_ROW_SIZE; Size++)
{
if(hexfile_error)
{
hexfile_error = hexfile_error;
break;
}
Temp.Val32 = ReadLatch(SourceAddr.Word.HW, SourceAddr.Word.LW);
hexfile_error = (ptrData[0] == Temp.Val[0]) ? hexfile_error :
VERIFY_ERROR;
hexfile_error = (ptrData[1] == Temp.Val[1]) ? hexfile_error :
VERIFY_ERROR;
hexfile_error = (ptrData[2] == Temp.Val[2]) ? hexfile_error :
VERIFY_ERROR;
ptrData = ptrData + 3;
SourceAddr.Val32 = SourceAddr.Val32 + 2;
}
}
/
******************************************************************************/
void WriteBuffer(unsigned char * ptrData, int Size)
{
int DataCount;
for(DataCount = 0; DataCount < Size; DataCount++)
{
PutChar(ptrData[DataCount]);
}
}
/
******************************************************************************/
void PutChar(unsigned char Char)
{
while(!U2STAbits.TRMT);
U2TXREG = Char;
}
/
******************************************************************************/
void WritePM(unsigned char * ptrData, uReg32 SourceAddr)
{
int Size,Size1;
uReg32 Temp;
uReg32 TempAddr;
uReg32 TempData;
for(Size = 0,Size1=0; Size < PM_ROW_SIZE; Size++)
{
Temp.Val[0]=ptrData[Size1+0];
Temp.Val[1]=ptrData[Size1+1];
Temp.Val[2]=ptrData[Size1+2];
Temp.Val[3]=0;
Size1+=3;
WriteLatch(SourceAddr.Word.HW,
SourceAddr.Word.LW,Temp.Word.HW,Temp.Word.LW);
// Device ID errata workaround: Save data at any address that has
LSB 0x18
if((SourceAddr.Val32 & 0x0000001F) == 0x18)
{
TempAddr.Val32 = SourceAddr.Val32;
TempData.Val32 = Temp.Val32;
}
if((Size !=0) && (((Size + 1) % 64) == 0))
{
// Device ID errata workaround: Reload data at address with LSB of
0x18
WriteLatch(TempAddr.Word.HW,
TempAddr.Word.LW,TempData.Word.HW,TempData.Word.LW);
WriteMem(PM_ROW_WRITE);
}
SourceAddr.Val32 = SourceAddr.Val32 + 2;
}
}
/
******************************************************************************/
On Sep 13, 9:22 pm, Robert Reese <
rbrees...@gmail.com> wrote:
> I am assuming that you started from bootloader version 3 (look in the
> main.c, see if VERSION_MAJOR is 3). This is the version of the bootloader
> that uses a remapped IVT table so that the bootloader program area is never
> written during bootloading.
>
> If I understand correctly, what you want to do is for a normal program to
> detect that you want to bootload, then you invoke the bootloader from the
> main program (perhaps by just jumping to location 0x200 directly where the
> bootloader resides). I guess you have also modified the bootloader code so
> that when it is jumped to like this, it does the actual bootloading (right
> now, the bootloader will only bootload if it detects a MCLR reset or a
> power-on reset, so just jumping to it will not cause a bootload -- you have
> to change this check somehow).
>
> This is as far as I understand what you are trying to do. I don't understand
> your question about the ResetDevice function or interrupts (or which
> interrupts you are concerned about).
>
> If you could post the modified main.c of the bootloader, that would be
> helpful, or describe in more detail how you modified the bootloader to
> accomplish what you are trying to do.
>
> On Tue, Sep 13, 2011 at 10:11 AM, Remy Echavarria <
remy.echavar...@gmail.com