CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

[Solved] ICD debugger printf output corrupted by timer?

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
allenhuffman



Joined: 17 Jun 2019
Posts: 669
Location: Des Moines, Iowa, USA

View user's profile Send private message Visit poster's website

[Solved] ICD debugger printf output corrupted by timer?
PostPosted: Mon Jun 08, 2026 7:38 am     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Jun 08, 2026 11:19 am     Reply with quote

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

View user's profile Send private message Visit poster's website

PostPosted: Mon Jun 08, 2026 11:56 am     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Jun 08, 2026 3:25 pm     Reply with quote

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

View user's profile Send private message Visit poster's website

PostPosted: Mon Jun 08, 2026 3:27 pm     Reply with quote

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.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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