 |
 |
| View previous topic :: View next topic |
| Author |
Message |
allenhuffman
Joined: 17 Jun 2019 Posts: 669 Location: Des Moines, Iowa, USA
|
| [Solved] ICD debugger printf output corrupted by timer? |
Posted: Mon Jun 08, 2026 7:38 am |
|
|
PIC24: 24FJ64GA002
EDIT: Further testing shows it is not timer2, specifically, but some combination. See attached code.
Our firmware was developed without the aid of debugging output (an impressive feat). When I inherited the code, I got printf output going to help me learn how things worked.
On one of our projects, using a 24FJ64GA002, using timer2 corrupts the debug printf via the ICD debugger console.
To work around this, I just called that function from timer3, which seemed to work fine.
Does anyone know why this would be? Compiler? Hardware design issue? PIC24 flaw? I did not see anything obvious in the errata when I looked into this years ago.
Cheers,
| Code: | #include <24FJ64GA002.h>
#device ICSP=1
#use delay(clock=32MHz,crystal=8MHz)
#FUSES NOWDT //No Watch Dog Timer
#FUSES CKSFSM //Clock Switching is enabled, fail Safe clock monitor is enabled
#define DEBUGGER_ON 0 // Set both debugger #defines to use printf ().
#define DEBUGGER_WITH_PRINTF 1 // Set both debugger #defines to use printf ().
// Sets the debugger to ON
#if DEBUGGER_ON == 1
// Allows DEBUGGER
#device ICD=TRUE
#endif
// Allows both the debugger and the printf ()
#if DEBUGGER_WITH_PRINTF == 1
// Turn on the RS-232 functionality.
#use rs232 (ICD)
#define DEBUG_PRINTF printf
#else
#define DEBUG_PRINTF(...)
#endif
#define LED_OK PIN_B6 // LED2 enable
#define DIGITAL_IN2_ESTOP PIN_B5 // Digital input #2 - E-Stop
// Timer constants
#define TIME_1_MS 0x07D1 // A one millisecond timer period.
#define TIME_10_MS 0x4E21 // A ten millisecond timer period.
#define TIME_1_SEC 0xF425 // A one second timer period.
#define MOD_VALUE 60000
#define USE_TIMER1
#define USE_TIMER2
#define USE_TIMER3
//#define USE_TIMER4
//#define USE_TIMER5
#include <stdint.h>
/*--------------------------------------------------------------------------*/
// Globals
/*--------------------------------------------------------------------------*/
volatile uint32_t g_Tick1 = 0;
volatile uint32_t g_Tick2 = 0;
volatile uint32_t g_Tick3 = 0;
volatile uint32_t g_Tick4 = 0;
volatile uint32_t g_Tick5 = 0;
/*--------------------------------------------------------------------------*/
// Timer ISRs
/*--------------------------------------------------------------------------*/
#INT_TIMER1 LEVEL=6
void timer1_isr (void)
{
g_tick1++;
}
#INT_TIMER2 LEVEL=6
void timer2_isr (void)
{
g_tick2++;
}
#INT_TIMER3 LEVEL=6
void timer3_isr (void)
{
g_tick3++;
}
#INT_TIMER4 LEVEL=6
void timer4_isr (void)
{
g_tick4++;
}
#INT_TIMER5 LEVEL=6
void timer5_isr (void)
{
g_tick5++;
}
/*--------------------------------------------------------------------------*/
// Main
/*--------------------------------------------------------------------------*/
void main()
{
DEBUG_PRINTF ("\nUniversal test: "__DATE__" "__TIME__"\r");
// Setup and initialize each timer to 1ms.
#ifdef USE_TIMER1
setup_timer1 (TMR_INTERNAL | TMR_DIV_BY_8, TIME_1_MS);
enable_interrupts (INT_TIMER1);
#endif
// This messes up debug output for some reason, so it will now be handled
// inside the TIMER3 ISR.
#ifdef USE_TIMER2
setup_timer2 (TMR_INTERNAL | TMR_DIV_BY_8, TIME_1_MS);
enable_interrupts (INT_TIMER2);
#endif
#ifdef USE_TIMER3
setup_timer3 (TMR_INTERNAL | TMR_DIV_BY_8, TIME_1_MS);
enable_interrupts (INT_TIMER3);
#endif
#ifdef USE_TIMER4
setup_timer4 (TMR_INTERNAL | TMR_DIV_BY_8, TIME_1_MS);
enable_interrupts (INT_TIMER4);
#endif
#ifdef USE_TIMER5
setup_timer5 (TMR_INTERNAL | TMR_DIV_BY_8, TIME_1_MS);
enable_interrupts (INT_TIMER5);
#endif
while(TRUE)
{
disable_interrupts (GLOBAL);
uint32_t tick1 = g_tick1;
uint32_t tick2 = g_tick2;
uint32_t tick3 = g_tick3;
uint32_t tick4 = g_tick4;
uint32_t tick5 = g_tick5;
enable_interrupts (GLOBAL);
#ifdef USE_TIMER1
if (tick1 % MOD_VALUE == 0) { printf ("\n1: %lu\r", g_tick1); }
#endif
#ifdef USE_TIMER2
if (tick2 % MOD_VALUE == 0) { printf ("\n2: %lu\r", g_tick2); }
#endif
#ifdef USE_TIMER3
if (tick3 % MOD_VALUE == 0) { printf ("\n3: %lu\r", g_tick3); }
#endif
#ifdef USE_TIMER4
if (tick4 % MOD_VALUE == 0) { printf ("\n4: %lu\r", g_tick4); }
#endif
#ifdef USE_TIMER5
if (tick5 % MOD_VALUE == 0) { printf ("\n5: %lu\r", g_tick5); }
#endif
}
}
// End of file.
|
_________________ Allen C. Huffman, Sub-Etha Software (est. 1990) http://www.subethasoftware.com
Embedded C, Arduino, MSP430, ESP8266/32, and PIC24 programmer.
http://www.whywouldyouwanttodothat.com ?
Using: 24FJ256GA106, 24EP256GP202, 24FJ64GA002 and 24FJ1024GA606.
Last edited by allenhuffman on Mon Jun 08, 2026 12:00 pm; edited 1 time in total |
|
 |
jeremiah
Joined: 20 Jul 2010 Posts: 1417
|
|
Posted: Mon Jun 08, 2026 11:19 am |
|
|
It's a software serial port so you'll want to disable interrupts for the stream:
| Code: |
#use rs232 (ICD, DISABLE_INTS, stream=DEBUG_STREAM)
|
|
|
 |
allenhuffman
Joined: 17 Jun 2019 Posts: 669 Location: Des Moines, Iowa, USA
|
|
Posted: Mon Jun 08, 2026 11:56 am |
|
|
| jeremiah wrote: | It's a software serial port so you'll want to disable interrupts for the stream:
| Code: |
#use rs232 (ICD, DISABLE_INTS, stream=DEBUG_STREAM)
|
|
Wow, wish I knew this years ago. I had no idea interrupts were being enabled when using something that did not need interrupts.
Thank you! _________________ Allen C. Huffman, Sub-Etha Software (est. 1990) http://www.subethasoftware.com
Embedded C, Arduino, MSP430, ESP8266/32, and PIC24 programmer.
http://www.whywouldyouwanttodothat.com ?
Using: 24FJ256GA106, 24EP256GP202, 24FJ64GA002 and 24FJ1024GA606. |
|
 |
jeremiah
Joined: 20 Jul 2010 Posts: 1417
|
|
Posted: Mon Jun 08, 2026 3:25 pm |
|
|
| allenhuffman wrote: | | jeremiah wrote: | It's a software serial port so you'll want to disable interrupts for the stream:
| Code: |
#use rs232 (ICD, DISABLE_INTS, stream=DEBUG_STREAM)
|
|
Wow, wish I knew this years ago. I had no idea interrupts were being enabled when using something that did not need interrupts.
Thank you! |
They are not being enabled for things that do not need interrupts. Your code enabled interrupts:
| Code: |
enable_interrupts (INT_TIMER2);
|
DISABLE_INTS just turns off all of your interrupts temporarily while a software UART operation is being performed.
Hopefully that helps explain it better! |
|
 |
allenhuffman
Joined: 17 Jun 2019 Posts: 669 Location: Des Moines, Iowa, USA
|
|
Posted: Mon Jun 08, 2026 3:27 pm |
|
|
| jeremiah wrote: |
They are not being enabled for things that do not need interrupts. Your code enabled interrupts:
| Code: |
enable_interrupts (INT_TIMER2);
|
DISABLE_INTS just turns off all of your interrupts temporarily while a software UART operation is being performed.
Hopefully that helps explain it better! |
That is a clear explanation. By default, it will not mask interrupts, but if you are using other IRQs, you can tell it to mask. Makes perfect sense. _________________ Allen C. Huffman, Sub-Etha Software (est. 1990) http://www.subethasoftware.com
Embedded C, Arduino, MSP430, ESP8266/32, and PIC24 programmer.
http://www.whywouldyouwanttodothat.com ?
Using: 24FJ256GA106, 24EP256GP202, 24FJ64GA002 and 24FJ1024GA606. |
|
 |
|
|
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
|