|
|
View previous topic :: View next topic |
Author |
Message |
canero
Joined: 22 Apr 2018 Posts: 13
|
dsPic30F4011 Interrupts Stop after Bootload |
Posted: Sun Apr 22, 2018 2:54 am |
|
|
Hello.
I have a strange behaviour with dsPIC30f4011. I loaded the CCS supplied serial pcd-bootload code through PICKit2. After that, I downloaded my application through serial port with pcd_bootloader.h in the header included. At the first run, everything works perfect including I2C interrupts, but when I add a fprintf sentence (or any other modification) to the code and redownload the new application to my chip through serialbootload, I2C interrupts stop working.
CCS vers 5.015
Here is my code :
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. ////
//// ////
//// This example will work with the PCD compiler. The ////
//// following conditional compilation lines are used to include a ////
//// valid device for the compiler. Change the device, clock, ////
//// push button, and RS232 pins for your hardware if needed. ////
///////////////////////////////////////////////////////////////////////////
//// (C) Copyright 1996,2013 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. ////
///////////////////////////////////////////////////////////////////////////
//!
//!//Normalde reset vektoru 0x000da interrupt vektoru ise 0x0004te. kaydırma yaparken
//!//aralarında 4 fark olacak hep. rset atıyorum 0xA0 ise interrupt 0xA4 olmalı. Loaderend even olmalı. dikkat.
//!
//!//These defines control the chip family that this program will compile for.
//!//The setup for 4 different chips, one from each of these chip families,
//!//is listed below.
//!//#define DSPIC33FJ
//!#define DSPIC30F
//!#define PIC24FJ
//!//#define PIC24HJ
//!
//!#if defined(DSPIC33FJ)
//! #include <33FJ128GP706.h>
//! #fuses NOWDT
//! #use delay(crystal=12MHz)
//! #use rs232(BAUD=9600,UART2)
//! #define PUSH_BUTTON PIN_B2
//!#elif defined(DSPIC30F)
//! #include <30F4011.h>
//! #fuses NOWDT
//! #use delay(crystal=20M)
//! #use rs232(BAUD=9600,UART1)
//! #use rs232(BAUD=38400,UART1A)//c13 TX PIN15 - c14 RX-PIN16..........
//! // #use rs232(BAUD=9600,UART1A)//c13 TX PIN15 - c14 RX-PIN16..........
//! #use rs232(baud=153600, parity=N, xmit=PIN_C13, rcv=PIN_C14, bits=8, stop=1, errors)
//! #use rs232(BAUD=9600,UART2)
//! #define PUSH_BUTTON PIN_F0
//!#elif defined(PIC24FJ)
//! #include <24FJ128GA006.h>
//! #fuses NOWDT
//! #use delay(crystal=20MHz)
//! #use rs232(BAUD=9600,UART2)
//! #define PUSH_BUTTON PIN_F0
//!#elif defined(PIC24HJ)
//! #include <24HJ256GP610.h>
//! #fuses NOWDT
//! #use delay(crystal=20MHz)
//! #use rs232(Baud=9600,UART1)
//! #define PUSH_BUTTON PIN_A4
//!#endif
//!
//!#define _bootloader
//!
//!#include <pcd_bootloader_caner.h>
//!#include <pcd_bootloader.h>
//!#include <loader_pcd.c>
//!
//!#org LOADER_END+1,LOADER_END+5
//!
//!void application(void)
//!{
//! while(TRUE);
//!}
//!
//!void main(void)
//!{
//!
//! delay_ms(500);
//! output_high(pin_b8);
//! delay_ms(500);
//! output_low(pin_b8);
//! delay_ms(500);
//! output_high(pin_b8);
//! delay_ms(500);
//! output_low(pin_b8);
//!
//! if(!input(PUSH_BUTTON))
//! {
//! ////////////////////Bootload mode giriş///////////////////////////
//! printf("\r\nBootloader 30F\r\n");
//! output_high(pin_b8);
//! // Let the user know it is ready to accept a download
//! printf("\r\nWaiting for download...");
//!
//! // Load the program
//! load_program();
//! ////////////////////////////////////////////////////////////
//! }
//!
//! application();
//!}
//!
//!#int_default
//!void isr(void)
//!{
//! jump_to_isr(LOADER_END+5); //
//!}
//!
///////////////////////////////////////////////////////////////////////////
//// 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. ////
//// ////
//// This example will work with the PCD compiler. The ////
//// following conditional compilation lines are used to include a ////
//// valid device for the compiler. Change the device, clock, ////
//// push button, and RS232 pins for your hardware if needed. ////
///////////////////////////////////////////////////////////////////////////
//// (C) Copyright 1996,2013 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. ////
///////////////////////////////////////////////////////////////////////////
//These defines control the chip family that this program will compile for.
//The setup for 4 different chips, one from each of these chip families,
//is listed below.
//#define DSPIC33FJ
#define DSPIC30F
//!#define PIC24FJ
//#define PIC24HJ
#if defined(DSPIC30F)
#include <30F4011.h>
#device adc=10
#FUSES NOWDT //No Watch Dog Timer
#FUSES FRC_PLL16 //Internal Fast RC oscillator with 16X PLL
#FUSES NOCKSFSM //Clock Switching is disabled, fail Safe clock monitor is disabled
#FUSES NOPUT //No Power Up Timer
#FUSES BORV27 //
#FUSES BROWNOUT //brownout reset
#use delay(clock=117920000) //7.3728Mhz x16
//! #use delay(crystal=20Mhz, clock=20Mhz)
#use rs232(baud=115200, parity=N, xmit=PIN_C13, rcv=PIN_C14, bits=8, stop=1, errors)
//! #use rs232(BAUD=9600,UART1)
#define PUSH_BUTTON PIN_F0
#endif
#define _bootloader
//!#include <pcd_bootloader_caner.h>
#include <pcd_bootloader.h>
#include <loader_pcd.c>
#org LOADER_END+1,LOADER_END+5
void application(void)
{
while(TRUE);
}
void main(void)
{
//! delay_ms(500);
output_high(pin_b8);
delay_ms(500);
output_low(pin_b8);
delay_ms(500);
output_high(pin_b8);
//! delay_ms(500);
//! output_low(pin_b8);
if(!input(PUSH_BUTTON))
{
output_high(pin_b8);
//! printf("\r\nBootloader Caner\r\n");
// Let the user know it is ready to accept a download
printf("\r\nWaiting for download...");
// Load the program
load_program();
}
application();
}
#int_default
void isr(void)
{
jump_to_isr(LOADER_END+5); //same as build
}
|
Application
Code: |
#include <30F4011.h>
#device adc=10
#FUSES NOWDT //No Watch Dog Timer
#FUSES FRC_PLL16 //Internal Fast RC oscillator with 16X PLL
#FUSES NOCKSFSM //Clock Switching is disabled, fail Safe clock monitor is disabled
#FUSES NOPUT //No Power Up Timer
#FUSES BORV27 //
#FUSES BROWNOUT //brownout reset
#use delay(clock=117920000) //7.3728Mhz x16
#include <pcd_bootloader.h>
#use rs232(baud=115200, parity=N, xmit=PIN_C13, rcv=PIN_C14, bits=8, stop=1, errors, stream=iletisim_PIC)
#use i2c(SLAVE, SDA=PIN_f2, SCL=PIN_f3,FORCE_hW,address=0xb0)
int incoming1=0;
int incoming2=0;
int16 a=0;
int16 aa=0;
//I2c
BYTE state;
int8 incoming3,incoming4;
int8 writebuffer[8];
//!#int_rda
//!void RDA_isr(void)
//!{
//!//disable_interrupts(int_rda);
//!char e;
//!e=getch();
//!
//!
//!if (e=='a') output_toggle(pin_f1);
//!
//!}
//!
//!#INT_SI2C
//!void si2c_interrupt()
//!
//!{
//!
//!a++;
//!output_toggle(pin_b8);
//!}
#INT_SI2C
//!#int_ssp
void si2c_interrupt()
{
state = i2c_isr_state();
if(state==0) i2c_read(); //Address match received with R/W bit clear,
//!
if(state < 0x80) //Master is sending data
{
if(state == 1) //First received byte is address
{
incoming1 = i2c_read();
aa++;
fprintf (iletisim_PIC,"\ninc1 :%u",incoming1);
//! fprintf (iletisim_PIC,"\naa :%u",aa);
//! fprintf (iletisim_PIC,"\n");
}
//!
if(state == 2) //First received byte is address
{
incoming2 = i2c_read();
fprintf (iletisim_PIC,"\ninc2 :%u",incoming2);
}
}
output_toggle(pin_b8);
}
void main()
{
fprintf (iletisim_PIC,"\nPic is alive");
//! output_high(pin_b8);
enable_interrupts(INT_SI2C);
enable_interrupts(INTR_GLOBAL);
output_low(pin_b8);
delay_ms(1000);
while(TRUE)
{
delay_ms(500);
output_toggle(pin_b8);
//!
fprintf (iletisim_PIC,"\nabcds: %lu",getenv("PROGRAM_MEMORY"));
//! fprintf (iletisim_PIC,"\nu1sta: %lu",aa); //when I uncomment this, and reload the program through serial bootload, interrupts never work.
//! fprintf (iletisim_PIC,"\nPosDataReceivedMotor2: %u",incoming2);
}
}
|
Can anyone help me here? _________________ Regards;
Caner. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9242 Location: Greensville,Ontario
|
|
Posted: Sun Apr 22, 2018 5:05 am |
|
|
OK I don't use that PIC but just quickly looking at your code..
...this doesn't look 'correct'.
#INT_SI2C
//!#int_ssp
You commented out the official CCS PreProcessor directive name and replaced it with yours. I don't know if that's 'legal' to do. My manual doesn't say anything about being able to do that.
Hopefully a seasoned DSPIC programmers can shed light onto this. Maybe it's an option for that series of PICs?
Jay |
|
|
canero
Joined: 22 Apr 2018 Posts: 13
|
|
Posted: Sun Apr 22, 2018 5:12 am |
|
|
temtronic wrote: | OK I don't use that PIC but just quickly looking at your code..
...this doesn't look 'correct'.
#INT_SI2C
//!#int_ssp
You commented out the official CCS PreProcessor directive name and replaced it with yours. I don't know if that's 'legal' to do. My manual doesn't say anything about being able to do that.
Hopefully a seasoned DSPIC programmers can shed light onto this. Maybe it's an option for that series of PICs?
Jay |
Hello;
Yes int_ssp is not valid for this PIC type. Its been replaced with INT_SI2C for I2C interrupt handlers for dsPIC.
Caner. _________________ Regards;
Caner. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9242 Location: Greensville,Ontario
|
|
Posted: Sun Apr 22, 2018 6:21 am |
|
|
OK, so that's not it....
next idea...
Maybe you need to increase the 'stack' size ? I recall some of these 'high powered' PICs need you to increase the size of the stack. The more complicated the code, the more stack it needs
Might be worth a try ?
Jay |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19538
|
|
Posted: Sun Apr 22, 2018 7:48 am |
|
|
Yes. The default stack size was increased on later PCD releases. On 5.015, it is so small that a fprintf can run it out of stack. |
|
|
canero
Joined: 22 Apr 2018 Posts: 13
|
|
Posted: Sun Apr 22, 2018 1:20 pm |
|
|
temtronic wrote: | OK, so that's not it....
next idea...
Maybe you need to increase the 'stack' size ? I recall some of these 'high powered' PICs need you to increase the size of the stack. The more complicated the code, the more stack it needs
Might be worth a try ?
Jay |
How do you increase the stack size? Can you please give me an example?
Caner. _________________ Regards;
Caner. |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1909
|
|
Posted: Sun Apr 22, 2018 1:37 pm |
|
|
Code: | #BUILD (stack=1024) |
Put that line in your project's .h file, right after your processor include, fuses, and oscillator set up. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19538
|
|
Posted: Sun Apr 22, 2018 1:40 pm |
|
|
#BUILD STACK=0x200
That should be large enough for most normal use. |
|
|
canero
Joined: 22 Apr 2018 Posts: 13
|
|
Posted: Sun Apr 22, 2018 2:00 pm |
|
|
Ttelmah wrote: | #BUILD STACK=0x200
That should be large enough for most normal use. |
Hello.
I tried your suggestions, the RAM use increased to 26% but its still the same. The code normally runs but interrupts never fire .
Caner. _________________ Regards;
Caner. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9242 Location: Greensville,Ontario
|
|
Posted: Sun Apr 22, 2018 6:12 pm |
|
|
since this PIC is the slave, how do you know the Master is sending ? Does a scope confirm data IS being sent to the Slave ?? |
|
|
canero
Joined: 22 Apr 2018 Posts: 13
|
|
Posted: Mon Apr 23, 2018 1:10 am |
|
|
temtronic wrote: | since this PIC is the slave, how do you know the Master is sending ? Does a scope confirm data IS being sent to the Slave ?? |
Yes I am sure. I did 2 tests. First I checked with oscilloscope if I am really sending the data from SDA and SCL pins and its valid. Also, at the first run (so after bootloader program loaded through PickKit2 and a new program is loaded to the slave through serialbootloader for the first time) slave workes perfectly so I know that master is already working. while keeping the master program unchanged and running, I modify the program of the slave and send the new program through serial bootloader then the interrupt stops.
Also, this happens with INTR_RDA interrupts as well. Its not only limited with I2c interrupts. _________________ Regards;
Caner. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19538
|
|
Posted: Wed Apr 25, 2018 8:57 am |
|
|
OK.
Your last comment is interesting. Think about it. Interrupts imply a hardware 'call' to a specific memory address. If there is no code at this address this will almost certainly completely crash the system. For them 'not to work', implies that either they are not actually being enabled, or something is stopping the physical interrupt hardware from working.
Now you do get your 'PIC is alive' message OK?.
If so this implies you should be getting to the code to enable the interrupts, unless something else was happening like a watchdog timeout. Your code though shows NOWDT.
Now you obviously do have access to a programmer, so does the code work if you program it without the bootloader?.
Now there is a major problem with having fprintf both in the I2C routine and the main, since this implies the interrupts will be disabled in large lumps of the main code, which could cause problems, and the code will spend a lot longer in the I2C routine than it should, waiting to print, which could cause an error. It may be that it is the extra time with interrupts disabled, that is generated by uncommenting the fprintf, that is actually causing the problem. I'd suspect the I2C receive overflow bit is being set, since the handler doesn't get called, and results in the peripheral becoming locked. The same applies to the UART, since you don't have ERRORS enabled which will add the code to clear UART overflows. |
|
|
canero
Joined: 22 Apr 2018 Posts: 13
|
|
Posted: Wed Apr 25, 2018 2:15 pm |
|
|
Ttelmah wrote: | OK.
Your last comment is interesting. Think about it. Interrupts imply a hardware 'call' to a specific memory address. If there is no code at this address this will almost certainly completely crash the system. For them 'not to work', implies that either they are not actually being enabled, or something is stopping the physical interrupt hardware from working.
Now you do get your 'PIC is alive' message OK?.
If so this implies you should be getting to the code to enable the interrupts, unless something else was happening like a watchdog timeout. Your code though shows NOWDT.
Now you obviously do have access to a programmer, so does the code work if you program it without the bootloader?.
Now there is a major problem with having fprintf both in the I2C routine and the main, since this implies the interrupts will be disabled in large lumps of the main code, which could cause problems, and the code will spend a lot longer in the I2C routine than it should, waiting to print, which could cause an error. It may be that it is the extra time with interrupts disabled, that is generated by uncommenting the fprintf, that is actually causing the problem. I'd suspect the I2C receive overflow bit is being set, since the handler doesn't get called, and results in the peripheral becoming locked. The same applies to the UART, since you don't have ERRORS enabled which will add the code to clear UART overflows. |
Hello;
Very good point Ttelmah. I tested the code without the bootloader and it works perfect. I changed the code, added fprintf, redownloaded it and all the interrupts are working without the bootloader. This strange thing happens when I load the code with the bootload. I suspect there is some inconsistency in the bootloader code of CCS for dsPIC30F devices.
For the UART, I already introduced the errors as you can see in the code.
#use rs232(baud=115200, parity=N, xmit=PIN_C13, rcv=PIN_C14, bits=8, stop=1, errors, stream=iletisim_PIC)
Maybe there is a misunderstanding there. _________________ Regards;
Caner. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9242 Location: Greensville,Ontario
|
|
Posted: Wed Apr 25, 2018 5:46 pm |
|
|
Maybe recheck the 'FUSES' in both programs. They have to be the same. Perhaps in editting the code 'something' got changed by mistake ? Could the programmer 'override' your program's FUSE settings ?
just thinking of possible reasons...
Jay |
|
|
jeremiah
Joined: 20 Jul 2010 Posts: 1354
|
|
Posted: Wed Apr 25, 2018 6:02 pm |
|
|
You can try #FUSES NONE in your application since it shouldn't be setting fuses anyways.
Since adding code makes things break, that suggests that your application code may be overwriting some bootloader code. Have you checked both the boothloader HEX file and the application HEX file and made sure there are no overlapping addresses? A properly written application file will not overlap. I know some bootloaders are smart enough to ignore certain address ranges, but I don't off the top of my head remember if the PCD bootloader example does that or not. CCS allows for you to make sure that no addresses overlap between the two hex files.
Particularly if your #use rs232 code (which is only created once you start using printf) is in a region allocated for the bootloader or the application IVT, then that could mess things up. |
|
|
|
|
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
|