 |
 |
View previous topic :: View next topic |
Author |
Message |
Marco27293
Joined: 09 May 2020 Posts: 128
|
DSPIC33EP512GP502 -- PCD v5.115 compiler - Bootloader issue |
Posted: Thu Feb 20, 2025 1:55 pm |
|
|
Hi,
I'm using this bootloader code. It seems to work fine.
Code: |
///////////////////////////////////////////////////////////////////////////
//// EX_PCD_BOOTLOADER.C ////
//// ////
//// This program is an example standalone bootloader. ////
//// ////
//// This program must be loaded into a target chip using a device ////
//// programmer. Afterwards this program may be used to load new ////
//// versions of the application program. ////
//// ////
//// This bootloader is designed to detect a pushbutton low on reset. ////
//// It will then use the RS232 link to download a new program. ////
//// Otherwise the application program is started. ////
//// ////
//// Use an RS232 link and the SIOW.EXE program to load a new HEX ////
//// file into the target chip. See example EX_PCD_BOOTLOAD.C. ////
//// ////
//// Uncomment the define BOOTLOADER_MODE2X to use an alternate ////
//// bootloader that receives each line in the hex file twice and ////
//// compares them before acknowledging the line and writing it to ////
//// the target chip's memory. This mode only works with the ////
//// CCS_BOOTLOADER.exe program, add MODE2X to the command line to ////
//// use this mode. ////
//// ////
//// The config bits will be write protected, in software, by the ////
//// rom_modify() function. To allow config bits to change then ////
//// you need to #define ROM_WRITE_CAN_MODIFY_CONFIG_BITS ////
//// ////
//// Depending on the PIC the bootloader is being built for or if ////
//// changes are made to the code the bootloader may not fit in the ////
//// program memory set a side for it by default for this example. ////
//// If that happens the size set aside for the bootloader can be ////
//// changed by defining LOADER_PAGES to the number of erase pages ////
//// to set aside for it before the pcd_bootloader.h is included, ////
//// this define must be made in both the bootloader and application ////
//// programs for the bootloader to work correctly. ////
//// ////
//// This example will work with the PCD compiler. Change the ////
//// device, clock, push button, and RS232 pins for your hardware if ////
//// needed. ////
///////////////////////////////////////////////////////////////////////////
//// (C) Copyright 1996,2021 Custom Computer Services ////
//// This source code may only be used by licensed users of the CCS ////
//// C compiler. This source code may only be distributed to other ////
//// licensed users of the CCS C compiler. No other use, ////
//// reproduction or distribution is permitted without written ////
//// permission. Derivative programs created using this software ////
//// in object code form are not restricted in any way. ////
//// ////
//// http://www.ccsinfo.com ////
///////////////////////////////////////////////////////////////////////////
// see explanation above
//#define ROM_WRITE_CAN_MODIFY_CONFIG_BITS
#include <33EP512GP502.h>
#FUSES NOPROTECT // Allow a Programmer device (eg. Pickit) to read Microcontroller firmware
#FUSES NOIOL1WAY // Used to enable peripheral deselection (useful to reduce power-consumption )
#use delay(internal=20MHz,clock_out)
#define UART_2_TX PIN_B11 // DsPIC UART2 TX
#define UART_2_RX PIN_B12 // DsPIC UART2 RX
#PIN_SELECT U2TX=UART_2_TX
#PIN_SELECT U2RX=UART_2_RX
#use rs232(uart2,baud=115200,PARITY=N, BITS=8, ERRORS, stream=SPECTRUM)
#define _bootloader
#define BOOTLOADER_MODE2X
#define BOOTLOADER_STREAM SPECTRUM
#define LOADER_PAGES 5
#include <pcd_bootloader.h>
#include <loader_pcd.c>
void main(void)
{
delay_ms(140); // wait for PLL
char ans='0';
do
{
ans=fgetc(SPECTRUM);
}
while(ans!='A'&&ans!='K'&&ans!='!');
if(ans=='!')
{
fputc('!',SPECTRUM);
load_program();
}
else if(ans=='K')
{
fputc('K',SPECTRUM);
}
goto_address(APPLICATION_START); // Salta all'applicazione se non deve entrare in modalità bootloader
}
#int_default
void isr(void)
{
jump_to_isr(APPLICATION_ISR_START);
}
|
It seems to work fine, it loads correctly an application but I'm experiencing a strange issue related to INT_EXT1:
Code: |
#INT_EXT1
void MCP346_manager()
{
switch(sample_num)
{
case 16384:
{
disable_interrupts(INT_EXT1);
clear_interrupt(INT_EXT1);
sample_num++;
}
break;
default:
{
clear_interrupt(INT_EXT1);
// 1. SPI Read ADC
input_buffer[shift] = make16(spi_read(0xFF),spi_read(0xFF));
// 2. Aggiorna l'indice del buffer circolare (utilizzando maschera per efficienza)
shift = (shift + 1) & TAP_MASK;
// 3. Aggiorna la somma parziale per il passo corrente
switch(sample_num&7)
{
case 0:
{
acc_sum += _mul(fir[0], input_buffer[(shift - 0) & TAP_MASK ]);
acc_sum += _mul(fir[1], input_buffer[(shift - 1) & TAP_MASK ]);
acc_sum += _mul(fir[2], input_buffer[(shift - 2) & TAP_MASK ]);
acc_sum += _mul(fir[3], input_buffer[(shift - 3) & TAP_MASK ]);
}
break;
case 1:
{
acc_sum += _mul(fir[4], input_buffer[(shift - 4) & TAP_MASK ]);
acc_sum += _mul(fir[5], input_buffer[(shift - 5) & TAP_MASK ]);
acc_sum += _mul(fir[6], input_buffer[(shift - 6) & TAP_MASK ]);
acc_sum += _mul(fir[7], input_buffer[(shift - 7) & TAP_MASK ]);
}
break;
case 2:
{
acc_sum += _mul(fir[8], input_buffer[(shift - 8) & TAP_MASK ]);
acc_sum += _mul(fir[9], input_buffer[(shift - 9) & TAP_MASK ]);
acc_sum += _mul(fir[10], input_buffer[(shift - 10)& TAP_MASK ]);
acc_sum += _mul(fir[11], input_buffer[(shift - 11)& TAP_MASK]);
}
break;
case 3:
{
acc_sum += _mul(fir[12], input_buffer[(shift - 12)& TAP_MASK ]);
acc_sum += _mul(fir[13], input_buffer[(shift - 13)& TAP_MASK ]);
acc_sum += _mul(fir[14], input_buffer[(shift - 14)& TAP_MASK ]);
acc_sum += _mul(fir[15], input_buffer[(shift - 15)& TAP_MASK ]);
}
break;
case 4:
{
acc_sum += _mul(fir[16], input_buffer[(shift - 16)& TAP_MASK ]);
acc_sum += _mul(fir[17], input_buffer[(shift - 17)& TAP_MASK ]);
acc_sum += _mul(fir[18], input_buffer[(shift - 18)& TAP_MASK ]);
acc_sum += _mul(fir[19], input_buffer[(shift - 19)& TAP_MASK ]);
}
break;
case 5:
{
acc_sum += _mul(fir[20], input_buffer[(shift - 20)& TAP_MASK ]);
acc_sum += _mul(fir[21], input_buffer[(shift - 21)& TAP_MASK ]);
acc_sum += _mul(fir[22], input_buffer[(shift - 22)& TAP_MASK ]);
acc_sum += _mul(fir[23], input_buffer[(shift - 23)& TAP_MASK ]);
}
break;
case 6:
{
acc_sum += _mul(fir[24], input_buffer[(shift - 24)& TAP_MASK ]);
acc_sum += _mul(fir[25], input_buffer[(shift - 25)& TAP_MASK ]);
acc_sum += _mul(fir[26], input_buffer[(shift - 26)& TAP_MASK ]);
acc_sum += _mul(fir[27], input_buffer[(shift - 27)& TAP_MASK ]);
}
break;
case 7:
{
acc_sum += _mul(fir[28], input_buffer[(shift - 28)& TAP_MASK ]);
acc_sum += _mul(fir[29], input_buffer[(shift - 29)& TAP_MASK ]);
acc_sum += _mul(fir[30], input_buffer[(shift - 30)& TAP_MASK ]);
acc_sum += _mul(fir[31], input_buffer[(shift - 31)& TAP_MASK ]);
samples32[sample_num>>3] =(acc_sum);
acc_sum = 0;
}
break;
}
// 4. Incrementa il contatore dei campioni acquisiti
sample_num++;
}
break;
}
}
|
This ISR is defined in the application.
It is used to sample and filter data from ADC connected to DSPIC via SPI1.
The problem is: when I execute the standalone application without bootloader all is fine and I'am able to sample data at the required Fsampling.
When the application is embedded with the bootloader part the isr still works but I reach exactly Fsampling/2.
The Fuses and clock for bootloader and application are the same:
Code: |
#use delay(internal=20MHz,clock_out)
//From LST:
Configuration Fuses:
Word 3L: FFCF ICSP1 NOJTAG NODEBUG
H: 0000
Word 4L: FFFF NOALTI2C1 NOALTI2C2 WDTWIN_25%
H: 0000
Word 5L: FF7F WPOSTS16 WPRES128 PLLWAIT WINDIS NOWDT
H: 0000
Word 6L: FFDF NOPR NOOSCIO NOIOL1WAY
H: 0000
Word 7L: FFF9 FRC_PLL IESO
H: 0000
Word 8L: FFFF NOWRT NOPROTECT
H: 0000
Word 9L: FFFF
H: 0000
Word 10L: FFFF
H: 0000
|
Could you help me to find the problem cause ?
The ADC is configured by this driver:
Code: |
//-----------------------------MCP346x Driver.C-------------------------------//
#ifndef __MCP346_C
#define __MCP346_C
#include "MCP346.h"
//-----------------------------Foos Definitions-------------------------------//
//MCP346 Utility implemented via SPI
unsigned int16 MCP346_Spi_Util(unsigned int8 mode)
{
unsigned int8 MSB=0,LSB=0,LOCK=0,ADC_REG_CHECK=0,ADC_SETTING_SUM=0;
output_bit(SPI1_PIN_SELECT,1);
output_bit(SPI1_PIN_SELECT,0);
switch(mode){
case _full_reset:
spi_read(0b01111000); //full reset
break;
case _start_adc:
spi_read(0b01101000); //start conversion
break;
case _single_read:
spi_read(0b01000001); //Static Read ADCDATA register
MSB=spi_read(0xFF);
LSB=spi_read(0xFF);
output_bit(SPI1_PIN_SELECT,1);
return make16(MSB,LSB);
break;
case _read_lock:
spi_read(0b01110101); //read lock
LOCK=spi_read(0xFF);
output_bit(SPI1_PIN_SELECT,1);
return (unsigned int16)(LOCK);
break;
case _config_lock:
spi_read(0b01110110); //Incremental write lock register
spi_read(0xA5);
break;
case _config_adc:
spi_read(0b01000110); //Incremental write starting at 0x01 config0
spi_read(0b11000010); //Config0 external clock without output,Standby mode
spi_read(0b00001000); //Config1 MCLK
spi_read(0b10101011); //Config2
spi_read(0b11000000); //Config3, 16 bit format data
spi_read(0b01110010); //IRQ
spi_read(0b00010000); //MUX select channel CH1 - CH0
break;
case _read_adc:
spi_read(0b01000111); //Incremental read starting at 0x01 config0
ADC_REG_CHECK=spi_read(0xFF); //Config0 external clock without output,Conversion mode
ADC_REG_CHECK ^= 0b11000010;
ADC_SETTING_SUM+=ADC_REG_CHECK;
ADC_REG_CHECK=spi_read(0xFF); //Config1 MCLK
ADC_REG_CHECK ^= 0b00001000;
ADC_SETTING_SUM+=ADC_REG_CHECK;
ADC_REG_CHECK=spi_read(0xFF); //Config2
ADC_REG_CHECK ^= 0b10101011;
ADC_SETTING_SUM+=ADC_REG_CHECK;
ADC_REG_CHECK=spi_read(0xFF); //Config3, 16 bit format data
ADC_REG_CHECK ^= 0b11000000;
ADC_SETTING_SUM+=ADC_REG_CHECK;
ADC_REG_CHECK=spi_read(0xFF); //IRQ
ADC_REG_CHECK ^= 0b01110010;
ADC_SETTING_SUM+=ADC_REG_CHECK;
ADC_REG_CHECK=spi_read(0xFF); //MUX select channel CH1 - CH0
ADC_REG_CHECK ^= 0b00010000;
ADC_SETTING_SUM+=ADC_REG_CHECK;
output_bit(SPI1_PIN_SELECT,1);
if(ADC_SETTING_SUM==0)
return MCP_SUCCESS;
else
return MCP_FAILURE;
break;
}
output_bit(SPI1_PIN_SELECT,1);
return MCP_SUCCESS;
}
//MCP346 Restart
void MCP346_Restart()
{
delay_ms(50);
MCP346_Spi_Util(_full_reset);
delay_ms(50);
do
{
MCP346_Spi_Util(_config_lock);
delay_ms(50);
}
while(MCP346_Spi_Util(_read_lock) != MCP_LOCK);
delay_ms(50);
do
{
MCP346_Spi_Util(_config_adc);
delay_ms(50);
}
while(MCP346_Spi_Util(_read_adc) != MCP_SUCCESS);
delay_ms(50);
MCP346_Spi_Util(_start_adc);
}
#endif
|
Changing driver options I'am able to reach correct Fsampling, but WHY must be a mismatch in registers configurations between application standalone and Boootloader+application ?
Nothing changes in my code except for application:
#define LOADER_PAGES 5
#include <pcd_bootloader.h>
they are commented in standalone project... |
|
 |
Ttelmah
Joined: 11 Mar 2010 Posts: 19700
|
|
Posted: Fri Feb 21, 2025 3:53 am |
|
|
Hmm.
That is odd.
One comment, you don't need the clear_interrupt lines in your interrupt
handler. Unless you compile an interrupt with the setting 'NOCLEAR', the
interrupt is always cleared when the handler exits. So you are potentially
clearing the interrupt twice.
Your remark on the NOIOL1WAY setting is wrong. This is what allows
your main code to have #PIN_SELECT lines that work. The power control
options are separate to this.
Using the bootloader, adds a tiny extra delay in handling the interrupts.
This can be avoided on chips that support the alternate interrupt vector
table, by using this. Look at the AIVT bootloader and boatload examples.
Check that the fuse settings given by the compile when boot loading, match
those you get from the bootloader. You show one set, but not the other.
Are there any other interrupts in use?.
Just a silly thing to try. Compile both the bootloader and the application
with #OPT 0
There was a problem around your compiler version with the default
optimisation making some interrupts not work properly. I'm wondering
if you might be experiencing this. |
|
 |
Marco27293
Joined: 09 May 2020 Posts: 128
|
|
Posted: Fri Feb 21, 2025 6:16 am |
|
|
Thank you Ttelmah,
I'll try #OPT 0 ASAP.
Meanwhile some clarifications:
- Fuses match between bootloader and application (No change)
- No other interrupt required or used
I looked AIVT bootloader and bootload examples in pcd compiler folder.
But seems that chip dspic33ep512gp502 I'm using dors not supporto the required Fuses...
How can I use alternate interrupt Vector on this chip ?
Any workaround or fix ? |
|
 |
Ttelmah
Joined: 11 Mar 2010 Posts: 19700
|
|
Posted: Fri Feb 21, 2025 7:39 am |
|
|
Unfortunately it looks like your chip does not support this.
As a coment, the interrupt handling with the bootloader present will have
one extra ijump instruction before being handled. Now you have several things
that could be optimised better, so these might make the difference.
Don't use a switch for handling the single first test. Just test if and else for
the other code. Get rid of the clear interrupts as already mentioned and
the handling speed will probably be as good. |
|
 |
|
|
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
|