This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TMS320F28032: First 6 pulses of CPU Timer 2 lost when Clock Source Configured as External Oscillator.

Part Number: TMS320F28032
Other Parts Discussed in Thread: TMS320F28035

We are using CPU timer 2 as a sort of external pulse counter.

So far we have used the following code to configure CPU timer 2:

EALLOW;

SysCtrlRegs.PCLKCR3.bit.CPUTIMER2ENCLK = 1; //Enable CPU timer 2

SysCtrlRegs.CLKCTL.bit.TMR2CLKSRCSEL = 1; //Set the input clock of timer 2 to use the external pin

SysCtrlRegs.CLKCTL.bit.TMR2CLKPRESCALE = 0; //Set the prescaler of the input clock source to /1

SysCtrlRegs.XCLK.bit.XCLKINSEL = 1; //Set the external clock source pin as GPIO19

EDIS;

Everything works fine except on a power-on reset, the first 6 pulses from GPIO19 do not cause CpuTimer2Regs.TIM to count down. After the 6th pulse, the CpuTimer counts down normally.

It seems that this problem is time-independant and frequency-independant. I could wait several minutes after power up and the first 6 pulses would be lost no matter what. I could also send pulses several seconds apart and they would also be lost until the 7th pulse. 

I another thing that I have tried is to set TMR2CLKSRCSEL = 0 (SYSCLKOUT), wait a few microseconds, then switch back to TMR2CLKSRCSEL = 1. Using the debugger, I observed that CpuTimer2Regs.TIM had decremented while the clock source was SYSCLKOUT, but right after switching to the external clock source, the first 6 pulses were lost again.

Any idea what I am doing wrong?

  • Cneshi,

    This is an interesting issue being that it's time and frequency independent.


    I have a few questions to ask you to better understand the situation:

    1. What are you using as an external clock source?

    2. Have you tried setting XTALOSCOFF to 1? TMS320x2803x Piccolo System Control and Interrupts Reference Guide (Rev. C)
    states it much be set to 1 if XCLKIN is used.


    Some things you could try below:

    1. You could try setting Qualification at 3 or 6 samples to filter signal noise. Use the GPACTRL register.
    (set GPAQSEL2 registers to 01 for 3 samples or 10 for 6 samples)

    2. Also try setting the Crystal Oscillator Off manually by setting CLKCTL[XTALOSCOFF] to 1. This defaults to 0 on reset turning the OSC on.

    For more information regarding these suggestions please look at the TMS320x2803x Piccolo System Control and Interrupts Reference Guide linked below.

    www.ti.com/.../sprugl8c.pdf

    Best,
    Kevin
  • Hi Kevin,

    Thanks for the reply:

    1. The external clock source is actually a optocoupler, the output of the optocoupler is passed through a logic inverter before being connected to GPIO19. We probed the signal using the scope and it is a very clean 3.3V square wave.

    2. The CLKCTL[XTALOSCOFF] = 1 is already present earlier in my code when I configure the system clock source:

    EALLOW;
    SysCtrlRegs.CLKCTL.bit.INTOSC1OFF = 0;
    SysCtrlRegs.CLKCTL.bit.OSCCLKSRCSEL = 0; // Clk Src = INTOSC1
    SysCtrlRegs.CLKCTL.bit.XTALOSCOFF = 1; // Turn off XTALOSC
    SysCtrlRegs.CLKCTL.bit.INTOSC2OFF = 1; // Turn off INTOSC2
    EDIS;

    3. I tried changing the qualification of GPIO19 to 3 and also 6 samples, there was no change in the behavior. On the other side of the optocoupler, we're using a PLC to send pulses with 1ms width - so there shouldn't be any signal bouncing.

  • Cneshi,

    I have some more questions:

    1. What frequency is the external clock source (optocoupler) running at?

    2. You said you're using CPU timer 2 to count the pulses of the external oscillator. What is your reason for this? Are you using it to drive an interrupt or something of that sort?

    One thing to verify is that all registers/bits that you have initialized are not changing during the main section of your code. You should be able to verify these values in CCS after debugging (You can run the code line by line and look for changes).

    Another thing that I would like to note is that this device has missing clock detection circuitry. There's a possibility that this could be going off when switching to your external clock source causing some discrepancies.

    This is just something I wanted to bring to your attention.

    Hope this helps,
    Kevin
  • Hi Kevin,

    To give you a simple overview of the system, we are developing a servo drive using the 28032 chip. The inputs to the drive are the traditional "Step", "Direction", "Enable" signals, which are isolated using the optocoupler. So the "clock" signal connected to CPU Timer 2 is really the "Step" input.

    In terms of frequency, it is not fixed and completely up to the end-user of the servo drive. We only limit the max frequency of the "Step" signal after 200kHz using an RC circuit. During our tests to debug the lost pulse issue, we were using far far lower frequencies. 

    Initially we simply had the "step" signal programmed to be an external interrupt. However, as you know, interrupts have a large overhead, and at higher frequencies, the CPU simply did not have time to service the frequency interrupts and perform servo computations at the same time. I know it is possible for us to configure the QEP module to accept step & direction signals, however there is only one QEP module and it is already being used to interface our incremental encoder. We finally came up with the idea of using the CPU timer 2 with external clock source to count steps for us. This solution has so far worked very well and freed up a tremendous amount of CPU resources for us. The only problem is with this mysterious loss of pulses on startup

    I am aware of the missing clock detection circuitry from reading SPRUGL8C, although I have to admit the whole section about that topic is a bit hard to follow. I checked the PLLSTS[MCLKSTS] bit after my own code has been initialized and it is always0. From what I understand, that indicates that the no abnormal clock condition was detected? To be honest, it's not clear to me what role CPU Timer 2 plays in the missing clock detection circuit. 

    Cheers,

    Dave

  • Dave,

    This seems like a good way to free up some computational power being that you are already using the QEP for something else. This is an interesting issue and I am not currently sure why the first 6 pulses are being ignored. I will have to look into this more.

    That is correct, If the PLLSTS[MCLKSTS] bit is showing 0 then missing clocks are not being witnessed and it shouldn't be an issue.

    I will post here when/if I discover anything new and related.

    Best,
    Kevin
  • Dave,

    Is there anything else running in your code when testing the CPU timer 2 pulse detection? Have you tried breaking it down to sourcing the external clock from just a GPIO pin rather than the optocoupler? I want to make sure there are no other functions going on while you test this that may be affecting it.

    I'm working on replicating your issue. It seems to be working as intended so far, but I have not tested the setup after a power-on-reset as of yet.

    Will keep you posted,
    Kevin
  • Hi Kevin,

    Thanks for taking the time to look into this issue. I don't believe the issue lies with hardware. When we were tracing the issue previously, we had used an oscilliscope to probe the GPIO pin directly - bypassing the optocoupler. We did not observe any lost pulses after a startup at all. 

    When I get the chance, I will try to setup a fresh project with the bare minimum amount of code to get this issue replicated. I'll share the code and my findings once I get it working. Thanks again!

  • Hi Dave,

    I was able to get my setup working after a POR using a GPIO pin (Or you could try a power supply, 3.3V). I did not witness the missing 6 pulses.

    I would suggest to make sure you are correctly running this from Flash and that you are not waiting for anything to be initialized through RAM. Check out this prior forum post related to this and how to correctly run/program your code from Flash.

    e2e.ti.com/.../839255

    Also be sure that your initial register bits that are set to use the external clock and CPU Timer 2 are not changing after a POR. I will include the initialization functions I used below...

    void
    ExtOscSel (void)
    {
    EALLOW;

    //
    // 1-GPIO19 = XCLKIN, 0-GPIO38 = XCLKIN
    //
    SysCtrlRegs.XCLK.bit.XCLKINSEL = 1; // Set external clock source pin as GPIO19

    SysCtrlRegs.CLKCTL.bit.XTALOSCOFF = 1; //Turn off XTALOSC, crystal oscillator
    SysCtrlRegs.CLKCTL.bit.XCLKINOFF = 0; //Turn on XCLKIN
    SysCtrlRegs.CLKCTL.bit.OSCCLKSRC2SEL = 0; //Switch to external clock

    //
    // Switch INTOSC1 to INTOSC2/ext clk
    //
    SysCtrlRegs.CLKCTL.bit.OSCCLKSRCSEL = 0; // Cneshi has as 0, run CPU off of internal clock

    SysCtrlRegs.CLKCTL.bit.WDCLKSRCSEL = 0; //Clock Watchdog off of INTOSC1
    SysCtrlRegs.CLKCTL.bit.INTOSC2OFF = 1; //Turn off INTOSC2
    SysCtrlRegs.CLKCTL.bit.INTOSC1OFF = 0; //Leave INTOSC1 on
    EDIS;
    }

    // Initialize CPU Timer 2
    void
    InitCPUTimer2(void)
    {
    EALLOW;

    SysCtrlRegs.PCLKCR3.bit.CPUTIMER2ENCLK = 1; //Enable CPU timer 2

    SysCtrlRegs.CLKCTL.bit.TMR2CLKSRCSEL = 1; //Set the input clock of timer 2 to use the external pin

    SysCtrlRegs.CLKCTL.bit.TMR2CLKPRESCALE = 0; //Set the prescaler of the input clock source to /1

    SysCtrlRegs.XCLK.bit.XCLKINSEL = 1; //Set the external clock source pin as GPIO19

    EDIS;
    }

    Hope this helps,
    Kevin
  • Hi Kevin,

    I tried out your code today and still no luck. In the main function, I commented out everything except for code to copy RAM functions from flash to RAM. Then I pasted in the code you shared. I am still seeing the same behavior: first 6 pulses are not received, all others are fine. I double checked the signals going into the MCU with a scope and there is no issue with it whatsoever. The signal is a very clean 3.3V square wave and lasts for exactly 1ms before changing back to 0V. Here's a photo:

    It doesn't matter whether the pulse is the first one from a POR or not, the shape of the pulse always looks the same on the scope. What is your hardware setup? is it the exact same chip? TMS320F28032?

  • Dave,

    You are toggling this signal on/off as desired, it is not continuously running at a 1ms period (1kHz) correct? Not sure how you would witness the 6 pulses being missed if it was.

    When you say "It doesn't matter whether the pulse is the first one from a POR or not" are you meaning the first 6 pulses are missed after first programming the MCU and also after turning on/off power?

    I am using a TMS320F28035 thinking that they wouldn't act differently in this matter. If I can get my hands on a 28032 I will try my same setup.

    My setup involves connecting a GPIO pin to CLKIN (GPIO19) and toggling it on/off as needed for the external oscillator. Watching registers CPUTIMER.TIMER2TIM and CpuTimer2Regs.TIM.all. Also I have a timer2 interrupt to set off an LED for debugging after a POR.

    I am running most of this program off of flash so that it will work after a POR, below is a portion of the .cmd to show this.

    SECTIONS
    {

    /* Allocate program areas: */
    .cinit : > FLASHA PAGE = 0
    .pinit : > FLASHA, PAGE = 0
    .text : > FLASHA PAGE = 0
    codestart : > BEGIN PAGE = 0
    ramfuncs : LOAD = FLASHD,
    RUN = RAML0,
    LOAD_START(_RamfuncsLoadStart),
    LOAD_SIZE(_RamfuncsLoadSize),
    RUN_START(_RamfuncsRunStart),
    PAGE = 0

    csmpasswds : > CSM_PWL_P0 PAGE = 0
    csm_rsvd : > CSM_RSVD PAGE = 0

    /* Allocate uninitalized data sections: */
    .stack : > RAMM0 PAGE = 1
    .ebss : > RAML2 PAGE = 1
    .esysmem : > RAML2 PAGE = 1

    Best,
    Kevin
  • Hi Kevin,

    Yes you are correct, I am toggling the signal on/off as desired. I am using a PLC to send fixed 1ms width pulses, but it only sends one pulse at a time when I press a button connected to it. I tried changing the width of the pulses today and it does not seem to make a difference. I also tried having the PLC send multiple pulses at a time. In the end, the observed number of missed pulses is the same.

    In terms of the missed pulses, yes, in both situations, POR and after programming the MCU, 6 missed pulses were observed. 

    By the way, the way you are verifying missed pulses is exactly the same as what I am doing. I am essentially observing changes to CpuTimer2Regs.TIM.all through debugging. 

    Today I took out a F28035 controlCARD that our company bought a while ago and programmed it with the same code. Interestingly, I also did not observe any missed pulses. I've arranged to have one of our PCBs to be converted to use a F28035 chip, Let's see if it really is a chip specific issue. 

  • Hi Dave,

    I am glad to hear that I am replicating your problem correctly. That is odd that your setup is working on the F28035 ControlCard and not the F28032 chip itself, they should act in the same way. I assume you are running the exact same program. Hopefully converting your PCB to the F28035 will make the difference. If I get a F28032 chip and test it at some point I will post my findings on here.

    Best of Luck,
    Kevin
  • Hi Kevin,
    We have a theory on why the pulses are missing on our own board but not the controlCARDs. We think it has to do with the fact that the controlCARD has a crystal oscillator while our board does not. If you take a look at the bottom left of FIG 18. in SPRUGL8C, the EXTCLK signal comes from the XCLKIN signal XORed with the crystal oscillator block (OSC). The OSC is enabled by default on reset. So my theory is the first 6 pulses are still lost on the controlCARD. However, these pulses come from the the crystal oscillator, so by the time we configure TIMER2 to use GPIO19 as the clock input, it will already accept pulses normally. Does that make sense? One way to verify is to remove the crystal oscillator from the controlCARD and try our code again. I strongly suspect that we will observe the missing pulses in this case.

    Anyway, even if my theory is correct, this still does not resolve the fundamental issue of the missing pulses. Is there anyone you could talk to at TI? Perhaps someone familiar with the silicon would have some insight into this?

    Cheers,
    Dave

    Update: I just tested out my theory. We took a 23035 controlCARD and desoldered the crystal oscillator, using the same code we were able to observe the missing pulses.

  • Hi Dave,

    This is an interesting theory. Just to clarify, when you say "we were able to observe the missing pulses" in your update you are meaning that the issue exists after removing the crystal? That the first 6 pulses are "lost".

    If this is what you mean, and the issue indeed still exits, I will try to get in contact with someone that can provide better understanding on this. Please let me know.

    Best,
    Kevin
  • Hi Kevin,
    Yes your interpretation is correct, the 6 pulses are lost after I removed the crystal oscillator.
  • Hi Dave,

    I tried the experiment on a ControlCARD that did not have a crystal oscillator. You are correct, the issue was present and the first 6 pulses were missed.

    I have forwarded this issue, and all related information, to our design team and will keep you updated.

    Best,
    Kevin
  • Hi Kevin,

    Glad to hear that you were able to replicate the issue and thank you for all your support so far. I await your update.

    Cheers,

    Dave

  • Hi Dave,

    I have received a response and explanation from the design team.

    When switching the input of CPU Timer 2 to the external oscillator pin (setting TMR2CLKSRCSEL = 1;) there will be a delay of a few cycles due to the glitch-free clock switching circuit. There are a number of flip-flops within this circuitry that need to be set and these first incoming pulses will not make it to the timer. This delay varies depending on the phase of the clocks and the clock ratio between INTOSC and EXTCLK. That is if the EXTCLK frequency is more than the INTOSC frequency, more edges will be missed. This being said, 6 pulses should be the maximum number of pulses missed, especially in your case where the incoming frequency is much lower than INTOSC. The missing pulses did not occur when a crystal oscillator was included since the generated pulses preset the glitch-free circuitry before switching to the external pin, GPIO19.

    We have come up with a tested method to work around this:

    1. If JTAG is being used (Emulator connected) you can add a delay in your code between setting TMR2CLKSRCSEL and XCLKINSEL to allow the JTAG TCK pulses going through GPIO38, which is also the default XCLKIN, to set the glitch-free circuitry. This will take care of the missing pulses during the time between setting CPU Timer 2 to use the external source as an input (TMR2CLKSRCSEL) and switching the external source pin to GPIO19 (XCLKINSEL). This will only work if the JTAG is in use. (Note: Delay may not need to be 100us that is used in example code below)

    2. If JTAG is not being used (Emulator not connected) you will have to toggle GPIO38 six (or more) times between setting TMR2CLKSRCSEL and XCLKINSEL to feed the glitch-free circuitry.

    I will provide some example code below that includes both these cases.

    void
    InitCPUTimer2(void)
    {
        int i = 0;
    
        EALLOW;
    
        SysCtrlRegs.PCLKCR3.bit.CPUTIMER2ENCLK = 1; //Enable CPU timer 2
    
        SysCtrlRegs.CLKCTL.bit.TMR2CLKSRCSEL = 1; //Set the input clock of timer 2 to use the external pin
    
        SysCtrlRegs.CLKCTL.bit.TMR2CLKPRESCALE = 0; //Set the prescaler of the input clock source to /1
    
        GpioCtrlRegs.GPBMUX1.bit.GPIO38 = 0;
        GpioCtrlRegs.GPBDIR.bit.GPIO38 = 1;     // Set GPIO38 as an output
    
    
        // Toggle on and off at least 6 times if emulator not in use
        for(i = 0; i < 6; i++){
            GpioDataRegs.GPBDAT.bit.GPIO38 = 1;
            DELAY_US(10);
            GpioDataRegs.GPBDAT.bit.GPIO38 = 0;
        }
    
        //DELAY_US(100); // Wait for pulses from JTAG TCK
    
        SysCtrlRegs.XCLK.bit.XCLKINSEL = 1; //Set the external clock source pin as GPIO19
    
        EDIS;
    }

    I hope all of this makes sense and that it helps.

    Best,

    Kevin

  • Hi Kevin,
    Thank you for all your help on this issue! I tested both your solutions on my side and they work perfectly. Hopefully our exchange can also help others who may encounter this in the future.