|
|
View previous topic :: View next topic |
Author |
Message |
benedictkim
Joined: 14 Nov 2019 Posts: 11
|
dsPIC30F6014A PCD Bootloader OK and App FW with No Interrupt |
Posted: Thu Nov 14, 2019 1:52 am |
|
|
I uploaded the boot loader FW and downloaded a simple application as shown below.
The result is that the normal functioning works fine, but the timer and RS232 receive interrupts do not.
Why not do interrupts?
Thank you for your help.
Please note that the bootloader code could not be attached due to many modifications.
Simple application code
Code: | #include <30F6014A.h>
/*-*-*-*-*-*-*-*-*-* preprocessor *-*-*-*-*-*-*-*-*-*-*-*-/
#fuses HS, NOWDT, NOPROTECT
#use delay(crystal = 30Mhz)
#use rs232(UART1, baud=115200, stop=1, parity=N, xmit=PIN_F3, rcv=PIN_F2, bits=8, stream=DBG_PINF3F2)
#use rs232(UART2, baud=115200, stop=1, parity=N, xmit=PIN_F5, rcv=PIN_F4, bits=8, stream=HMI_PINF5F4)
// "Same with LOADER_PAGES of bootloader FW"
#define LOADER_PAGES 81
#include <pcd_bootloader.h>
#define OP_LED PIN_D12
unsigned int32 HMIBuf_Num = 0;
unsigned int8 HMI_STX_Buf[200];
unsigned int32 Timer_100ms_Count = 0;
#INT_RDA2
void HMI_Uart2_Rx_isr(void)
{
HMI_STX_Buf[HMIBuf_Num] = getc(HMI_PINF5F4);
HMIBuf_Num++;
if (HMIBuf_Num >= 200) HMIBuf_Num = 0;
}
#INT_TIMER2
void TIMER2_isr(void)
{
Timer_100ms_Count++;
}
/*******************************************************
* Function: void main()
* Description: main
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-/
void main()
{
unsigned int32 ret = 0;
unsigned int32 tmp_Num = 5;
fprintf(DBG_PINF3F2, "\r\nSimpleApplication #1");
fprintf(DBG_PINF3F2, "\r\nSo enjoy!");
ret = getenv("PROGRAM_MEMORY");
fprintf(DBG_PINF3F2, "\r\nPROGRAM_MEMORY:0x%x", ret);
ret = getenv("FLASH_ERASE_SIZE");
fprintf(DBG_PINF3F2, "\r\nFLASH_ERASE_SIZE:0x%x", ret);
ret = getenv("FLASH_WRITE_SIZE");
fprintf(DBG_PINF3F2, "\r\nFLASH_WRITE_SIZE:0x%x", ret);
ret = getenv("READ_PROGRAM");
fprintf(DBG_PINF3F2, "\r\nREAD_PROGRAM:0x%x", ret);
fprintf(DBG_PINF3F2, "\r\nLOADER_END:0x%x", LOADER_END);
fprintf(DBG_PINF3F2, "\r\nLOADER_SIZE:0x%x", LOADER_SIZE);
fprintf(DBG_PINF3F2, "\r\nLOADER_ADDR:0x%x", LOADER_ADDR);
#ifdef BOOTLOADER_AT_START
fprintf(DBG_PINF3F2, "\r\nBOOTLOADER_AT_START defined");
#else
fprintf(DBG_PINF3F2, "\r\nBOOTLOADER_AT_START No defined");
#endif
setup_timer2(TMR_INTERNAL | TMR_DIV_BY_64, 11718);
enable_interrupts(INT_TIMER2);
enable_interrupts(INT_RDA2);
enable_interrupts(INTR_GLOBAL);
while(TRUE)
{
if (tmp_Num != HMIBuf_Num)
{
fprintf(DBG_PINF3F2, "Timer1:%u\r\n", Timer_100ms_Count);
tmp_Num = HMIBuf_Num;
Timer_100ms_Count = 0;
}
else if (Timer_100ms_Count > 10)
{
fprintf(DBG_PINF3F2, "Timer2:%u\r\n", Timer_100ms_Count);
if (HMIBuf_Num)
{
for (ret = 0; ret < HMIBuf_Num; ret++)
{
fprintf(DBG_PINF3F2, "Rx[%u]:0x%x\r\n", ret, HMI_STX_Buf[ret]);
}
}
Timer_100ms_Count = 0;
}
output_toggle(OP_LED);
}
} |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19520
|
|
Posted: Thu Nov 14, 2019 5:09 am |
|
|
The fault is almost certainly that your bootloader is not correctly re-vectoring
the interrupt handling. So it is the bootloader you need to post.... |
|
|
benedictkim
Joined: 14 Nov 2019 Posts: 11
|
|
Posted: Thu Nov 14, 2019 6:50 pm |
|
|
Below is the bootloader code.
The boot loader is very complicated.
However, the download is normal and the default operation is not abnormal except for interrupt.
Please treat me well.
Thank you.
Ttelmah! thank you.
Three bootloaders / application firmware / final firmware hex files were compared.
Vertor has detected a problem with the bootloader 0x0 address and the application firmware 0x0980 address.
PCB_Bootloader did not fix it.
Where is the problem?
Code: |
#include <30F6014A.h>
#include "main.h"
/******************** preprocessor ***********************/
//#fuses NOWRTB // OK
//#fuses HS, NOWDT, NOPROTECT, NOWRT // OK
//#use delay(crystal = 30Mhz)
#fuses HS, NOWDT, NOPROTECT // OK
#use delay(crystal = 30Mhz)
//#fuses NOWDT // OK
//#use delay(crystal = 30Mhz)
#use rs232(UART1, baud=115200, stop=1, parity=N, xmit=PIN_F3, rcv=PIN_F2, bits=8, stream=DBG_PINF3F2)
//#use rs232(UART1, baud=115200, stop=1, parity=N, xmit=PIN_F3, rcv=PIN_F2, bits=8, timeout=10000, stream=RS232_PINF3F2)
#use rs232(UART2, baud=115200, stop=1, parity=N, xmit=PIN_F5, rcv=PIN_F4, bits=8, stream=HMI_PINF5F4)
/********************** define ***************************/
#define READ_BOOT_INFO 1
#define ERASE_FLASH 2
#define PROGRAM_FLASH 3
#define READ_CRC 4
#define JMP_TO_APP 5
// Data EEPROM address 0x30 status value
#define TO_APP_FW_MODE 0x41 // to application FW
// IO pin
#define S_SW1 PIN_G13
// Don't touch - Fixed position
#define _bootloader
// "Same with LOADER_PAGES of application FW"
#define LOADER_PAGES 81
#include <pcd_bootloader.h>
#define APP_FLASH_BASE_ADDRESS (LOADER_PAGES * (getenv("FLASH_ERASE_SIZE")/2))
#define APP_FLASH_END_ADDRESS getenv("PROGRAM_MEMORY")
#define FLASH_PAGE_SIZE getenv("FLASH_ERASE_SIZE")
#define MAJOR_VERSION 1
#define MINOR_VERSION 0
/********************* global ****************************/
const unsigned int8 BootInfo[2] =
{
MAJOR_VERSION,
MINOR_VERSION
};
T_FRAME RxBuff;
T_FRAME TxBuff;
unsigned int32 Timer_100ms_Count = 0;
unsigned int1 RunApplication = FALSE;
unsigned int1 RxFrameValid = FALSE;
unsigned int16 Reply_Data_Length = 0;
/****************************************************************************
* Static table used for the table_driven implementation.
*****************************************************************************/
const unsigned int16 crc_table[16] =
{
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef
};
/*******************************************************
* Function: void isr(void)
* Description: interrupt service routine for jump
* to the Applicatoin IVT
********************************************************/
#int_default
void isr(void)
{
jump_to_isr(LOADER_END+5);
}
/*******************************************************
* Function: void main()
* Description: Jump to application FW
********************************************************/
#org LOADER_END+1,LOADER_END+5
void application(void)
{
while(TRUE);
}
/*******************************************************
* Function: unsigned int16 CalculateCrc(unsigned int8 *data, unsigned int32 len)
* Description: Calculates CRC for the given data and len
* Parameter: data pointer and data length
* Return: CRC
********************************************************/
unsigned int16 CalculateCrc(unsigned int8 *data, unsigned int32 len)
{
unsigned int32 i;
unsigned int16 crc = 0;
while(len--)
{
i = (crc >> 12) ^ ((unsigned int16)*data >> 4);
crc = crc_table[i & 0x0F] ^ (crc << 4);
i = (crc >> 12) ^ ((unsigned int16)*data >> 0);
crc = crc_table[i & 0x0F] ^ (crc << 4);
data++;
}
return (crc & 0xFFFF);
}
/*******************************************************
* Function: void EraseFlash(void)
* Description: Erases Flash (Block Erase).
********************************************************/
void EraseFlash(void)
{
unsigned int32 i;
for (i = 0; i <= ((APP_FLASH_END_ADDRESS - APP_FLASH_BASE_ADDRESS)/FLASH_PAGE_SIZE); i++)
{
erase_program_memory(APP_FLASH_BASE_ADDRESS + (i*FLASH_PAGE_SIZE));
}
}
/*******************************************************
* Function: unsigned int1 ExitFirmwareUpgradeMode(void)
* Description: This function returns true if firmware mode has to be exited.
********************************************************/
unsigned int1 ExitFirmwareUpgradeMode(void)
{
static unsigned int16 buff_len = 0;
if (buff_len != RxBuff.Len)
{
buff_len = RxBuff.Len;
Timer_100ms_Count = 0;
}
else if (Timer_100ms_Count > 100)
{
fprintf(DBG_PINF3F2, "RS232 Timeout\r\n");
RunApplication = TRUE;
}
return RunApplication;
}
/*******************************************************
* Function: void WriteHexRecord2Flash_UART(unsigned int8* HexRecord, unsigned int16 totalHexRecLen)
* Description: Writes hex record to flash.
* Parameter: HexRecord buffer.
********************************************************/
void WriteHexRecord2Flash_UART(unsigned int8* HexRecord, unsigned int16 totalHexRecLen)
{
static unsigned int16 h_addr = 0;
unsigned int32 addr;
unsigned int16 l_addr;
unsigned int16 data_count=0;
unsigned int16 total_count=0;
unsigned int16 checksum_index;
unsigned int8 data[32];
unsigned int8 checksum, line_type;
unsigned int8 dataidx, i;
while(totalHexRecLen>=5) // A hex record must be atleast 5 bytes. (1 Data Len byte + 1 rec type byte+ 2 address bytes + 1 crc)
{
data_count = HexRecord[0 + total_count]; // Get the number of bytes from the HexRecord
checksum_index = 1+ 2 + 1+ data_count;
// Get the lower 16 bits of address
l_addr = make16(HexRecord[1 + total_count], HexRecord[2 + total_count]);
line_type = HexRecord[3 + total_count];
addr = ((make32(h_addr,l_addr))/2);
checksum = 0; // Sum the bytes to find the check sum value
for (i=0; i<(checksum_index); i++) checksum += HexRecord[i + total_count];
checksum = 0xFF - checksum + 1;
if (checksum != HexRecord[checksum_index + total_count])
{
// Checksum error
}
else
{
// If the line type is 1, then data is done being sent
if (line_type == 1) return;
else if (line_type == 4) h_addr = make16(HexRecord[4 + total_count], HexRecord[5 + total_count]);
else if (line_type == 0)
{
if (((addr < LOADER_ADDR) || (addr > LOADER_END)) && addr < getenv("PROGRAM_MEMORY"))
{ // Loops through all of the data and stores it in data
// The last 2 bytes are the check sum, hence buffidx-3
for (i = 4,dataidx=0; i < checksum_index; i++)
{
data[dataidx++] = HexRecord[i + total_count];
}
write_program_memory(addr, data, data_count);
}
}
totalHexRecLen = totalHexRecLen - (data_count + 5);
total_count += data_count + 5;
}
}
}
/*******************************************************
* Function: void HandleCommand(void)
* Description: Process the received frame and take action depending on
the command received.
********************************************************/
void HandleCommand(void)
{
DWORD_VAL Address;
DWORD_VAL Length;
WORD_VAL crc;
unsigned int32 i;
unsigned int8 Cmd;
void* pFlash;
// First byte of the data field is command.
Cmd = RxBuff.Data[0];
// Partially build response frame. First byte in the data field carries command.
TxBuff.Data[0] = RxBuff.Data[0];
// Process the command.
switch(Cmd)
{
case READ_BOOT_INFO: // Read boot loader version info.
memcpy(&TxBuff.Data[1], BootInfo, 2);
//Set the transmit frame length.
Reply_Data_Length = 2 + 1; // Boot Info Fields + command
break;
case ERASE_FLASH:
pFlash = (void*)APP_FLASH_BASE_ADDRESS;
for( i = 0; i <= ((APP_FLASH_END_ADDRESS - APP_FLASH_BASE_ADDRESS)/FLASH_PAGE_SIZE); i++ )
{
erase_program_memory(APP_FLASH_BASE_ADDRESS + (i*FLASH_PAGE_SIZE));
}
//Set the transmit frame length.
Reply_Data_Length = 1; // Command
break;
case PROGRAM_FLASH:
WriteHexRecord2Flash_UART(&RxBuff.Data[1], RxBuff.Len-3); //Negate length of command and CRC RxBuff.Len.
//Set the transmit frame length.
Reply_Data_Length = 1; // Command
break;
case READ_CRC:
// Get address from the packet.
memcpy(&Address.v[0], &RxBuff.Data[1], sizeof(Address.Val));
memcpy(&Length.v[0], &RxBuff.Data[5], sizeof(Length.Val));
crc.Val = CalculateCrc((unsigned int8 *)Address.Val, Length.Val);
memcpy(&TxBuff.Data[1], &crc.v[0], 2);
//Set the transmit frame length.
Reply_Data_Length = 1 + 2; // Command + 2 bytes of CRC.
break;
case JMP_TO_APP:
write_eeprom(0x30, TO_APP_FW_MODE);
// Exit firmware upgrade mode.
RunApplication = TRUE;
break;
default:
// Nothing to do.
break;
}
}
/*******************************************************
* Function: void FrameWorkTask(void)
* Description: Process the command if there is a valid fame.
********************************************************/
void FrameWorkTask(void)
{
WORD_VAL crc;
if(RxFrameValid)
{
crc.bytes.LB = RxBuff.Data[RxBuff.Len-2];
crc.bytes.HB = RxBuff.Data[RxBuff.Len-1];
if((CalculateCrc(RxBuff.Data, (unsigned int32)(RxBuff.Len-2)) == crc.Val) && (RxBuff.Len > 2))
{
// CRC matches and frame received is valid.
}
else return;
// Valid frame received, process the command.
HandleCommand();
// Reset the flag.
RxFrameValid = FALSE;
}
}
/*******************************************************
* Function: void GetTransmitFrame(void)
* Description: Gets the complete transmit frame into the "Buff".
* Return: Length of the buffer.
* Parameter: Buffer pointer.
********************************************************/
void GetTransmitFrame(void)
{
WORD_VAL crc;
unsigned int8 tmp_buff[255];
unsigned int32 i;
//There is something to transmit.
// Calculate CRC of the frame.
crc.Val = CalculateCrc(TxBuff.Data, (unsigned int32)Reply_Data_Length);
TxBuff.Data[Reply_Data_Length++] = crc.bytes.LB;
TxBuff.Data[Reply_Data_Length++] = crc.bytes.HB;
memcpy(tmp_buff, TxBuff.Data, Reply_Data_Length);
// Insert SOH (Indicates beginning of the frame)
TxBuff.Data[TxBuff.Len++] = SOH;
// Insert Data Link Escape Character.
for(i = 0; i < Reply_Data_Length; i++)
{
if((tmp_buff[i] == EOT) || (tmp_buff[i] == SOH) || (tmp_buff[i] == DLE))
{
// EOT/SOH/DLE repeated in the data field, insert DLE.
TxBuff.Data[TxBuff.Len++] = DLE;
}
TxBuff.Data[TxBuff.Len++] = tmp_buff[i];
}
// Mark end of frame with EOT.
TxBuff.Data[TxBuff.Len++] = EOT;
Reply_Data_Length = 0; // Purge this buffer, no more required.
}
/*******************************************************
* Function: void HMI_Uart2_Tx_isr(void)
* Description: UART 2 Tx interrupt service routine for HMI
********************************************************/
#INT_TBE2
void HMI_Uart2_Tx_isr(void)
{
static unsigned int16 tx_index = 0;
putc(TxBuff.Data[tx_index++], HMI_PINF5F4);
if (tx_index >= TxBuff.Len)
{
tx_index = TxBuff.Len = 0;
disable_interrupts(INT_TBE2);
}
else enable_interrupts(INT_TBE2);
}
/*******************************************************
* Function: void UartTxTask(void)
* Description: Runs some UART routines like receive bytes and transmit bytes.
********************************************************/
void UartTxTask(void)
{
if(Reply_Data_Length)
{
// Get transmit frame from frame work.
GetTransmitFrame();
enable_interrupts(INT_TBE2);
}
}
/*******************************************************
* Function: void HMI_Uart2_Rx_isr(void)
* Description: interrupt service routine for jump
* to the Applicatoin IVT
********************************************************/
#INT_RDA2
void HMI_Uart2_Rx_isr(void)
{
static unsigned int1 Escape = FALSE;
unsigned int8 ch;
ch = getc(HMI_PINF5F4);
if(RxBuff.Len >= sizeof(RxBuff.Data)) RxBuff.Len = 0;
switch(ch)
{
case SOH: //Start of header
if(Escape)
{
// Received byte is not SOH, but data.
RxBuff.Data[RxBuff.Len++] = ch;
// Reset Escape Flag.
Escape = FALSE;
}
// Received byte is indeed a SOH which indicates start of new frame.
else RxBuff.Len = 0;
break;
case EOT: // End of transmission
if(Escape)
{
// Received byte is not EOT, but data.
RxBuff.Data[RxBuff.Len++] = ch;
// Reset Escape Flag.
Escape = FALSE;
}
else
{
// Received byte is indeed a EOT which indicates end of frame.
// Calculate CRC to check the validity of the frame.
if(RxBuff.Len > 1) RxFrameValid = TRUE;
}
break;
case DLE: // Escape character received.
if(Escape)
{
// Received byte is not ESC but data.
RxBuff.Data[RxBuff.Len++] = ch;
// Reset Escape Flag.
Escape = FALSE;
}
// Received byte is an escape character. Set Escape flag to escape next byte.
else Escape = TRUE;
break;
default: // Data field.
RxBuff.Data[RxBuff.Len++] = ch;
// Reset Escape Flag.
Escape = FALSE;
break;
}
}
/*******************************************************
* Function: void TIMER2_isr(void)
* Description: Timer 2 interrupt routine - 100ms
********************************************************/
#INT_TIMER2
void TIMER2_isr(void)
{
Timer_100ms_Count++;
}
/*******************************************************
* Function: void main()
* Description: main
********************************************************/
void main()
{
TxBuff.Len = 0;
RxBuff.Len = 0;
// fprintf(RS232_PINF3F2, "Start Bootloader\r\n");
// delay_ms(1000);
fprintf(DBG_PINF3F2, "Start Bootloader\r\n");
delay_ms(1000);
/*
ret = getenv("PROGRAM_MEMORY");
fprintf(DBG_RS232_F5F4, "PROGRAM_MEMORY:0x%x\r\n", ret);
ret = getenv("FLASH_ERASE_SIZE");
fprintf(DBG_RS232_F5F4, "FLASH_ERASE_SIZE:0x%x\r\n", ret);
ret = getenv("FLASH_WRITE_SIZE");
fprintf(DBG_RS232_F5F4, "FLASH_WRITE_SIZE:0x%x\r\n", ret);
ret = getenv("READ_PROGRAM");
fprintf(DBG_RS232_F5F4, "READ_PROGRAM:0x%x\r\n", ret);
fprintf(DBG_RS232_F5F4, "LOADER_END:0x%x\r\n", LOADER_END);
fprintf(DBG_RS232_F5F4, "LOADER_SIZE:0x%x\r\n", LOADER_SIZE);
fprintf(DBG_RS232_F5F4, "LOADER_ADDR:0x%x\r\n", LOADER_ADDR);
fprintf(DBG_RS232_F5F4, "APP_FLASH_BASE_ADDRESS:0x%x\r\n", APP_FLASH_BASE_ADDRESS);
fprintf(DBG_RS232_F5F4, "APP_FLASH_END_ADDRESS:0x%x\r\n", APP_FLASH_END_ADDRESS);
fprintf(DBG_RS232_F5F4, "FLASH_PAGE_SIZE:0x%x\r\n", FLASH_PAGE_SIZE);
#ifdef BOOTLOADER_AT_START
fprintf(DBG_RS232_F5F4, "BOOTLOADER_AT_START defined\r\n");
#else
fprintf(DBG_RS232_F5F4, "BOOTLOADER_AT_START No defined\r\n");
#endif
*/
setup_timer2(TMR_INTERNAL | TMR_DIV_BY_64, 11718);
enable_interrupts(INT_TIMER2);
enable_interrupts(INT_RDA2);
enable_interrupts(INTR_GLOBAL);
if (read_eeprom(0x30) == TO_APP_FW_MODE)
{
fprintf(DBG_PINF3F2, "Download JumpToApp#1\r\n");
fprintf(HMI_PINF5F4, "Download JumpToApp#1\r\n");
application();
}
fprintf(DBG_PINF3F2, "EEPROM 0x30: 0x%x\r\n", read_eeprom(0x30));
while(!ExitFirmwareUpgradeMode()) // Be in loop till framework recieves "run application" command from PC
{
// Enter firmware upgrade mode. Be in loop, looking for commands from PC
FrameWorkTask(); // Run frame work related tasks (Handling Rx frame, process frame and so on)
UartTxTask(); // Run Uart Tx tasks
}
fprintf(DBG_PINF3F2, "Download JumpToApp#2\r\n");
fprintf(HMI_PINF5F4, "Download JumpToApp#2\r\n");
application();
}
|
|
|
|
benedictkim
Joined: 14 Nov 2019 Posts: 11
|
|
Posted: Thu Nov 14, 2019 11:24 pm |
|
|
Interrupts were resolved by changing the order in the source phase.
Thank you. |
|
|
|
|
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
|