MC9S12XEP100 Timer TIM Module Debug mode issue.

cancel
Showing results for 
Search instead for 
Did you mean: 

MC9S12XEP100 Timer TIM Module Debug mode issue.

Jump to solution
366 Views
Al_M
Contributor I

Hello,

This is my first post on this forums so I will try to make it as short as possible.
I am trying to use the Timer TIM module on the MC9S12XEP100 MCU. However, it seems to be working perfectly during debug mode only, as soon as I disconnect my debugger and run it by using the MCU only, it doesn't work as expected, instead it runs much faster ruining my timing completely.
I am using the timer to generate a 1 wire communication protocol between the MCU and a 1-wire temperature sensor.
Please help me know what do I need to do to setup the TIM timer module correctly to work outside of debug mode. Like I said, it is perfectly fine when the debugger is connected ONLY. The OVF vector and all work perfectly, as soon as I run it without the debugger it doesn't work as expected.
Sincerely,
Al.
Labels (1)
0 Kudos
1 Solution
49 Views
kef
Specialist I
  • My question is, What if, TCNT is near its overflow value, and you give it a "ticks_to_go" that causes TCx to overflow, then how would that work exactly?

It will work perfectly well. Say you are at TCNT = 0xF000 and add 0x2000. 0xF000+0x2000 overflows to 0x1000. From 0xF000 to 0x10000 you have 0x1000 ticks. Another 0x1000 ticks are from 0(0x10000) to 0x1000. Still some problems with this?

 

  • If you don't know the value of TCNT when you are doing the above operation? To me it seems that using an INT instead of TCx will make this work better. Is that true? And can you elaborate on the last line "TCx will happen N ticks past TCy"?

What is INT? By TCx and TCy I meant timer compare or timer capture registers. TCx = TCy + ticks_to_go - means you can (and often should) setup next timer compare event relative to previous timer compare or capture event. For example to generate squarewave you can setup timer compare to toggle pin, then in timer compare interrupt you do two things: set up next compare TCx += ticks_to_go and clear interrupt flag. Generated waveform will be rock solid and jitterless. TCx = TCNT + ticks_to_go will be not so nice. Just try it.

 

 

  • Sorry of my lack of understanding, I've used the timer in the C32 module before and it was very easy to reset it back to 0, but it seems this controller is designed a little bit different.

No, TCNT is not writeable in normal modes even on S12C32.

View solution in original post

0 Kudos
7 Replies
49 Views
kef
Specialist I

Debuggers usually boot MCU in special single chip mode. There are some write once registers, which you can write only once after reset into normal mode. In special modes you can write them as many times as you need. As you should know, bits are not addressable. To set some bit, processor has to read whole register, manipulate your bit in memory, then write whoe byte back to register. This means if you set/clear one bit in write once register, then you won't be able to manipulate others. Instead you should write whole bits pattern in one write operation.

TCNT is not writeable in normal modes.

0 Kudos
49 Views
Al_M
Contributor I

Thank you very much for your reply, I have changed all my write commands to write entire registers at a time instead of 1 bit as you suggested in your post. It still works in debugger only. Is there any way to make the chip run in special mode without the debugger? 

 

When you say that you cannot write to TCNT during normal mode. How do I zero the timer then? I thought you can write to TCNT as long as the timer is OFF.

 

Sincerely,

Al.

0 Kudos
49 Views
kef
Specialist I
  •  I have changed all my write commands to write entire registers at a time instead of 1 bit as you suggested in your post.

Sorry, bad memory. I thought timer prescaler bits are write once, and this could bite you. There's no need to do what you did for all registers, only for those ones, which have write once bits. For example look at IRQCR register description. It is said that IRQE bit is write once. This means that first write to IRQCR will lock contents of IRQE. So if you do first

 

IRQCR_IRQEN = 0; // or =1

 

then write

 

IRQCR_IRQE = 1;

 

^^ this will be ignored and IRQE will stay in its reset default state = 0.

 

 

 

  • It still works in debugger only. Is there any way to make the chip run in special mode without the debugger? 

No, it's not possible. You can boot MCU in special single chip mode, but it will be halted until you command it to GO using BDM interface.

  

 

  • When you say that you cannot write to TCNT during normal mode. How do I zero the timer then? I thought you can write to TCNT as long as the timer is OFF.

You can't zero TCNT in normal mode. Manual says this about TCNT "Write: Has no meaning or effect in the normal mode; only writable in special modes (test_mode = 1).".

Instead of resetting timer counter, you should setup new timer events relative to the old events:

 

 TCx = TCNT + ticks_to_go; // TCx will happen N ticks later

  

 TCx = TCy + ticks_to_go; // TCx will happen N ticks past TCy

 

Having free running counter you have (almost) 8 independent timers. Resetting counter you have only one timer.

0 Kudos
49 Views
Al_M
Contributor I


Thank you for a prompt reply. You have been very helpful and have helped me understand this timer module much better. I still have a few questions before I start implementing this in code, which will require changing my code quite a bit really.

 

You said:


TCx = TCNT + ticks_to_go; // TCx will happen N ticks later

 

TCx = TCy + ticks_to_go; // TCx will happen N ticks past TCy


My question is, What if, TCNT is near its overflow value, and you give it a "ticks_to_go" that causes TCx to overflow, then how would that work exactly? If you don't know the value of TCNT when you are doing the above operation? To me it seems that using an INT instead of TCx will make this work better. Is that true? And can you elaborate on the last line "TCx will happen N ticks past TCy"?

 

Sorry of my lack of understanding, I've used the timer in the C32 module before and it was very easy to reset it back to 0, but it seems this controller is designed a little bit different.

 

Sincerely,

Al.

 

PS. Would really appreciate it if you share a code example with me.

0 Kudos
50 Views
kef
Specialist I
  • My question is, What if, TCNT is near its overflow value, and you give it a "ticks_to_go" that causes TCx to overflow, then how would that work exactly?

It will work perfectly well. Say you are at TCNT = 0xF000 and add 0x2000. 0xF000+0x2000 overflows to 0x1000. From 0xF000 to 0x10000 you have 0x1000 ticks. Another 0x1000 ticks are from 0(0x10000) to 0x1000. Still some problems with this?

 

  • If you don't know the value of TCNT when you are doing the above operation? To me it seems that using an INT instead of TCx will make this work better. Is that true? And can you elaborate on the last line "TCx will happen N ticks past TCy"?

What is INT? By TCx and TCy I meant timer compare or timer capture registers. TCx = TCy + ticks_to_go - means you can (and often should) setup next timer compare event relative to previous timer compare or capture event. For example to generate squarewave you can setup timer compare to toggle pin, then in timer compare interrupt you do two things: set up next compare TCx += ticks_to_go and clear interrupt flag. Generated waveform will be rock solid and jitterless. TCx = TCNT + ticks_to_go will be not so nice. Just try it.

 

 

  • Sorry of my lack of understanding, I've used the timer in the C32 module before and it was very easy to reset it back to 0, but it seems this controller is designed a little bit different.

No, TCNT is not writeable in normal modes even on S12C32.

View solution in original post

0 Kudos
49 Views
Al_M
Contributor I

Thank you very much for your help. It works now... I have the following function for timer delay based on a 40MHz E Clock.

 

void TimerDelay (unsigned int time){ // input time in us. 
    int ix = 0;
    time -= 4;  // from scope reading offset determined
    
    TIM_TSCR1 = 0x90; /* enable TCNT and fast timer flag clear */
    TIM_TSCR2 = 0x00; /* disable timer interrupt, set prescaler to default */
    TIM_TIOS |= TIM_TIOS_IOS0_MASK; /* enable OC0 */
    TIM_TC0 = TIM_TCNT + 40;
 
    for (ix = 0; ix <= time; ix++) {
    while(!(TIM_TFLG1 & TIM_TFLG1_C0F_MASK));
    TIM_TC0 += 40;
    }
    TIM_TIOS &= ~TIM_TIOS_IOS0_MASK; /* disable OC0 */
    TimerOff;
    return;
}
Much appreciated for all your help, now my one wire communication is working with no further problems even outside of debug mode.
Sincerely,
Al.

 

0 Kudos
49 Views
kef
Specialist I

For software delays you should not waste timer compare channels. All you need is TCNT register.

 

void TimerDelay (unsigned int time){ // input time in us. 
    int ix = 0;
   short t0;
    time -= 4;  // from scope reading offset determined
    
    TIM_TSCR1 |= TIM_TSCR1_TEN_MASK; /* enable TIM */
 
    t0 = TCNT + 40;      
    for (ix = 0; ix <= time; ix++) {
       while( (signed short)(t0 - TCNT) >= 0 ){}
       t0 += 40;
    }
    TimerOff;
    return;
}
0 Kudos