Hello, I am using the C6713 DSP from TI. I'm trying to implement a timer. I use Timer1 by manually programming it (not inside the DSP-BIOS, but with a timer handle). The only thing I insert into the DSP-BIOS is the Timer function (At HWI 15, I insert the function that the timer shall enter after it finishes to count). I enabled to use the dispatcher with "self" for the interrupt mask. The problem is now: At its first run, the timer enters issues an interrupt after the right period, but the next time it enters the function is only about 900 clock cycles later but not at the value in the period register that I entered. To solve that, I tried to set the counter value to zero every time it enters the function (by using the function Timer_setCount, but not even the value of the counter is set. Can you help me? The code i use is the following: #include "bios.h" #include <csl.h> [...] static TIMER_Handle hTimer1; static Uint32 TimerEventId; [...] /*----------------------------------------------------------------------------*/ static Uint32 TimerControl = TIMER_CTL_RMK( /* Timer control register (CTL)*/ TIMER_CTL_INVINP_NO, /* TINP inverter control(INVINP). Only affects operation if CLKSRC =0. TIMER_CTL_INVINP_NO - Uninverted TINP drives timer TIMER_CTL_INVINP_YES - inverted TINP drives timer */ TIMER_CTL_CLKSRC_CPUOVR4,/* Timer input clock source (CLKSRC) TIMER_CTL_CLKSRC_CPUOVR4 - CPU clock /4*/ TIMER_CTL_CP_CLOCK, /* Clock/pulse mode(CP) TIMER_CTL_CP_PULSE - Pulse mode.TSTAT is active one CPU clock after the timer reaches the timer period.PWID determines when it goes inactive.*/ TIMER_CTL_HLD_YES, /* Hold(HLD). Counter may be read or written regardless of HLD value. TIMER_CTL_HLD_YES - Counter is disabled and held in current value. TIMER_CTL_HLD_NO - COunter is allowed to count. */ TIMER_CTL_GO_NO, /* Go bit(GO). Resets and starts the timer counter. TIMER_CTL_GO_NO - No effects on the timer. TIMER_CTL_GO_YES - if HLD =1, the counter register is zeroed and begins counting on next clock. */ TIMER_CTL_PWID_ONE, /* Pulse width(PWID). Only used in pulse mode. TIMER_CTL_PWID_ONE - TSTAT goes inactive one timer input clock cycle after the timer counter value equals the timer period value. TIMER_CTL_PWID_TWO - TSTAT goes inactive one timer input clock cycle after the timer counter value equals the timer period value.*/ TIMER_CTL_DATOUT_0, /* Data output (DATOUT). TIMER_CTL_DATOUT_0 - If FUNC =0,the DATOUT is driven on TOUT. TIMER_CTL_DATOUT_1 - If FUNC =1,The DATOUT is driven on TOUT after inversion by INVOUT. */ TIMER_CTL_INVOUT_NO, /* TOUT inverter control (INVOUT) TIMER_CTL_INVOUT_NO - Uninverted TSTAT drives TOUT TIMER_CTL_INVOUT_YES - Inverted TSTAT drives TOUT.*/ TIMER_CTL_FUNC_GPIO /* Function of TOUT pin(FUNC). TIMER_CTL_FUNC_GPIO - TOU is a general purpose output pin TIMER_CTL_FUNC_TOUT - TOUT is a timer output pin */ ); void DDS_Timer(void) { //TIMER_setCount(hTimer1,0x0); [....]function to be done count++; } void main(void) { init_module(0); EMIF_config(&emifCfg0); set_module_cfg (CFG_CPLD_nRESET); CSL_init(); /* Open TIMER1 device, and reset them to power-on default state */ hTimer1 = TIMER_open(TIMER_DEV1, TIMER_OPEN_RESET); /* Obtain the event ID for the timer device */ TimerEventId = TIMER_getEventId(hTimer1); //IRQ_setVecs(vectors); /* point to the IRQ vector table */ IRQ_globalEnable(); /* Globally enable interrupts */ IRQ_nmiEnable(); /* Enable NMI interrupt */ /* Map TIMER events to physical interrupt number */ IRQ_map(TimerEventId, 15); /* Reset the timer events */ IRQ_reset(TimerEventId); /* Enable the timer events(events are disabled while resetting) */ IRQ_enable(TimerEventId); [....] T=((double)rate*(double)nstep/(double)nsample); //seconds /* Configure the timer devices */ TIMER_configArgs(hTimer1, TimerControl, /* use predefined control value */ (unsigned int)(T*56250000.), /* set period */ 0x00000000 /* start count value at zero */ ); TIMER_start(hTimer1); }
C6713 Timer problem
Started by ●February 10, 2005
Reply by ●February 10, 20052005-02-10
"Simone Winkler" <simone.winkler@gmx.at> wrote in news:420b743f$0$11094$3b214f66@aconews.univie.ac.at: Hi Simone: I never had any problems with the Timer functionality for either the 6711 or the 6713. I pretty much developed that Timer handling code straight from the TI CSL documentation. I'm not really sure what you are doing here, but I'll just show you a small snippet of what I did - and it sure seems to work. /* The configuration structure for the Timer.. */ TIMER_Config timerCfg0 = { // // This a bit of a pain in the butt - we need to // make sure that the clock is set to internal (CPU) source.. // I'm not crazy about wading thru all of these bits.. TIMER_CTL_RMK( TIMER_CTL_INVINP_DEFAULT, TIMER_CTL_CLKSRC_CPUOVR4, // Internal clock... TIMER_CTL_CP_DEFAULT, TIMER_CTL_HLD_DEFAULT, TIMER_CTL_GO_DEFAULT, TIMER_CTL_PWID_DEFAULT, TIMER_CTL_DATOUT_DEFAULT, TIMER_CTL_INVOUT_DEFAULT, TIMER_CTL_FUNC_DEFAULT ), /* Period Register (PRD) */ (BTIMER_NUM_MSEC_PER_TICK * ( SYSTEM_CLOCK / 1000UL )) / 4UL, 0x00000000, /* Counter Register (CNT) */ }; if( bTimerOpened == TRUE ) { // We've already opened the timer.. return 1; } // // The CSL version... // hTimer0 = TIMER_open( TIMER_DEV0, TIMER_OPEN_RESET ); if( hTimer0 == INV ) { // The open function returned a bad result.. return -1; } TIMER_config( hTimer0, &timerCfg0 ); // // Set up the interrupts for Timer 0 // IRQ_nmiEnable(); IRQ_globalEnable(); // Clear the Timer0 flag in ICR, clears the IER // corresponding flag.. IRQ_reset(IRQ_EVT_TINT0); // The following 2 macros seem redundant... included here // bacause that's what the TI docs suggest... IRQ_disable(IRQ_EVT_TINT0); // Clear the Timer0 flag // in IER // (it returns what was //set in IER).. IRQ_clear(IRQ_EVT_TINT0); // Clear the Timer0 flag // in ICR.. IRQ_enable(IRQ_EVT_TINT0); /* Clear the timer flag (bTimerIntFlag). */ bTimerIntFlag = FALSE; // Kick off the timer... // The HLD of the ctl register is released, and the GO // bit is set.. TIMER_start( hTimer0 ); bTimerOpened = TRUE; return 0; Offhand, one of the differences I see is that I use the CSL define for the Timer event (IRQ_EVT_TINT0), whereas you use Event ID obtained from the TIMER_getEventID() call (and I am using DEV0, not DEV1, BTW). Outside of that, I don't know. I do know that the section of code I had did come mostly from the CSL manual, and it never gave me any problems. Hope this helps.. George> Hello, > > I am using the C6713 DSP from TI. I'm trying to implement a timer. > I use Timer1 by manually programming it (not inside the DSP-BIOS, but > with a timer handle). > The only thing I insert into the DSP-BIOS is the Timer function (At > HWI 15, I insert the function that the timer shall enter after it > finishes to count). I enabled to use the dispatcher with "self" for > the interrupt mask. >
Reply by ●February 10, 20052005-02-10
Simone, I suspect you may be doing something wrong such as writing to the CNT register while it is actually running in which case you can end up with an indeterminate state for CNT and maybe get the results you're seeing. How are you measuring this in order to know that it is wrong? Please post your intended period along with the actual period(s) you are seeing. Also, if you're modifying any of the registers at run-time you could put that code here too. Brad "Simone Winkler" <simone.winkler@gmx.at> wrote in message news:420b743f$0$11094$3b214f66@aconews.univie.ac.at...> Hello, > > I am using the C6713 DSP from TI. I'm trying to implement a timer. > I use Timer1 by manually programming it (not inside the DSP-BIOS, but with > a timer handle). > The only thing I insert into the DSP-BIOS is the Timer function (At HWI > 15, I insert the function that the timer shall enter after it finishes to > count). I enabled to use the dispatcher with "self" for the interrupt > mask. > > The problem is now: > At its first run, the timer enters issues an interrupt after the right > period, but the next time it enters the function is only about 900 clock > cycles later but not at the value in the period register that I entered. > To solve that, I tried to set the counter value to zero every time it > enters the function (by using the function Timer_setCount, but not even > the value of the counter is set. > > Can you help me? > > The code i use is the following: > > #include "bios.h" > #include <csl.h> > [...] > > static TIMER_Handle hTimer1; > static Uint32 TimerEventId; > [...] > > /*----------------------------------------------------------------------------*/ > static Uint32 TimerControl = TIMER_CTL_RMK( /* Timer control register > (CTL)*/ > TIMER_CTL_INVINP_NO, /* TINP inverter control(INVINP). Only affects > operation > if CLKSRC =0. > TIMER_CTL_INVINP_NO - Uninverted TINP drives timer > TIMER_CTL_INVINP_YES - inverted TINP drives timer */ > > TIMER_CTL_CLKSRC_CPUOVR4,/* Timer input clock source (CLKSRC) > TIMER_CTL_CLKSRC_CPUOVR4 - CPU clock /4*/ > > TIMER_CTL_CP_CLOCK, /* Clock/pulse mode(CP) > TIMER_CTL_CP_PULSE - Pulse mode.TSTAT is active one > CPU clock after the timer reaches the timer > period.PWID determines when it goes inactive.*/ > > TIMER_CTL_HLD_YES, /* Hold(HLD). Counter may be read or written > regardless of > HLD value. > TIMER_CTL_HLD_YES - Counter is disabled and held in > current value. > TIMER_CTL_HLD_NO - COunter is allowed to count. */ > > TIMER_CTL_GO_NO, /* Go bit(GO). Resets and starts the timer counter. > TIMER_CTL_GO_NO - No effects on the timer. > TIMER_CTL_GO_YES - if HLD =1, the counter register > is zeroed and begins counting on next clock. */ > TIMER_CTL_PWID_ONE, /* Pulse width(PWID). Only used in pulse mode. > TIMER_CTL_PWID_ONE - TSTAT goes inactive one timer > input clock cycle after the timer counter value > equals the timer period value. > TIMER_CTL_PWID_TWO - TSTAT goes inactive one timer > input clock cycle after the timer counter value > equals the timer period value.*/ > > TIMER_CTL_DATOUT_0, /* Data output (DATOUT). > TIMER_CTL_DATOUT_0 - If FUNC =0,the DATOUT is > driven on TOUT. > TIMER_CTL_DATOUT_1 - If FUNC =1,The DATOUT is driven > on TOUT after inversion by INVOUT. */ > > TIMER_CTL_INVOUT_NO, /* TOUT inverter control (INVOUT) > TIMER_CTL_INVOUT_NO - Uninverted TSTAT drives TOUT > TIMER_CTL_INVOUT_YES - Inverted TSTAT drives TOUT.*/ > TIMER_CTL_FUNC_GPIO /* Function of TOUT pin(FUNC). > TIMER_CTL_FUNC_GPIO - TOU is a general purpose > output pin > TIMER_CTL_FUNC_TOUT - TOUT is a timer output pin */ > > ); > > void DDS_Timer(void) { > > //TIMER_setCount(hTimer1,0x0); > > [....]function to be done > > count++; > } > > void main(void) { > > init_module(0); > EMIF_config(&emifCfg0); > set_module_cfg (CFG_CPLD_nRESET); > > CSL_init(); > > /* Open TIMER1 device, and reset them to power-on default state */ > hTimer1 = TIMER_open(TIMER_DEV1, TIMER_OPEN_RESET); > > /* Obtain the event ID for the timer device */ > TimerEventId = TIMER_getEventId(hTimer1); > > //IRQ_setVecs(vectors); /* point to the IRQ vector table */ > IRQ_globalEnable(); /* Globally enable interrupts */ > IRQ_nmiEnable(); /* Enable NMI interrupt */ > > /* Map TIMER events to physical interrupt number */ > IRQ_map(TimerEventId, 15); > > /* Reset the timer events */ > IRQ_reset(TimerEventId); > > > /* Enable the timer events(events are disabled while resetting) */ > IRQ_enable(TimerEventId); > > [....] > > > T=((double)rate*(double)nstep/(double)nsample); //seconds > > /* Configure the timer devices */ > TIMER_configArgs(hTimer1, > TimerControl, /* use predefined control value */ > (unsigned int)(T*56250000.), /* set period */ > 0x00000000 /* start count value at zero */ > ); > > TIMER_start(hTimer1); > > } >
Reply by ●February 11, 20052005-02-11
Reply by ●February 11, 20052005-02-11
> I suspect you may be doing something wrong such as writing to the CNT > register while it is actually running in which case you can end up with an > indeterminate state for CNT and maybe get the results you're seeing.Actually I don't write to the CNT register. I once tried to reset it to zero with every entering into the timer function, but that did not work.> > How are you measuring this in order to know that it is wrong?with the profiler. It works for the first timer period, but then its only a maximum period of 1000 clock cycles that the timer counts. I can also watch the registers, and I can see, that the cnt register is not at zero or at FFFF... when I enter the function.> Please post your intended period along with the actual period(s) you are > seeing. Also, if you're modifying any of the registers at run-time you > could put that code here too.I don't modify any registers at run-time...except that I'm using the EMIF. My intended period is programmable, at the moment I try to implement about 340 ms (19327352 clock cycles at 225 MHz). What i get is a number of clock cycles that is always smaller than 1000. As I said, it WORKS FINE for one period, but not for more than one. :( Where's the problem?? I'm already quite in a hurry, because it's one of the last details that does not work. :((( Simone Thank you for every suggestion!
Reply by ●February 11, 20052005-02-11
"Simone Winkler" <simone.winkler@gmx.at> wrote in message news:420cadf0$0$11352$3b214f66@aconews.univie.ac.at...>> How are you measuring this in order to know that it is wrong? > > with the profiler. It works for the first timer period, but then its only > a maximum period of 1000 clock cycles that the timer counts. > I can also watch the registers, and I can see, that the cnt register is > not at zero or at FFFF... when I enter the function.I wouldn't use the profiler to do this. It puts in a bunch of breakpoints behind the scene to stop and start the CPU core at all the functions you're profiling. The timer, however, keeps on running (i.e. it doesn't halt at breakpoints). What you may be seeing is that the timer is actually firing off periods at the proper rate but it looks wrong in the profiler because the CPU keeps being stopped and started. Bottom line, don't use the profiler to do this. The best way to measure this is using a scope. Either probe the timer output pin or else toggle a GPIO pin every time you get into the your ISR. I imagine you'll find it's already working right. It's probably just the way you're using the profiler that's making it look like it's not working right. Brad
Reply by ●February 11, 20052005-02-11
"Simone Winkler" <simone.winkler@gmx.at> wrote in news:420cac6c$0$11868 $3b214f66@aconews.univie.ac.at: Hi Simone: I'm stumped then, sorry.. The only thing I'd ask you to try or check on is: (1). Somewhere at the start of main(), you should be doing: CSL_init(); IRQ_setVecs(vectors); [BTW, I noticed that in your original example, you had the IRQ_setVecs(vectors) statement commented out. Was there a problem with it?] (2). Check to see if there aren't any other places in the code path where you could be inadvertently calling IRQ_globalDisable() or IRQ_disable(IRQ_EVT_TINT0) or TIMER_close(hTimer0) (3). Just for sanity sake, and I've done this before, try writing a small program that <ONLY> handles the timer interrupt. By narrowing down the scope, I can usually find my problem with a particular component easier than with a program a program that does more than one thing. Well, that's about it - the other things I'd suggest, but you've probably also tried, is to take a look at TI's web site, look for all of their application reports related to handling the Timer through CSL. In the meantime, you might also want to place a call to your TI field application engineer - they may not know precisely where to look, but they might be able to steer you to another apps engineer at TI who does know. I sincerely hope this helps. Keep me posted. George> Hi, > > I tried to use your code... no changes. :( > > Simone > >
Reply by ●February 15, 20052005-02-15
"Simone Winkler" <simone.winkler@gmx.at> writes:> Hello, > > I am using the C6713 DSP from TI. I'm trying to implement a timer. > I use Timer1 by manually programming it (not inside the DSP-BIOS, but with a > timer handle). > The only thing I insert into the DSP-BIOS is the Timer function (At HWI 15, > I insert the function that the timer shall enter after it finishes to > count). I enabled to use the dispatcher with "self" for the interrupt mask. >If you have DSP-BIOS "installed" with your app, it does tend to mess with one of the timers IIRC. Can you use the other one? Cheers, Martin -- martin.j.thompson@trw.com TRW Conekt, Solihull, UK http://www.trw.com/conekt
Reply by ●February 16, 20052005-02-16
> The best way to measure this is using a scope. Either probe the timer > output pin or else toggle a GPIO pin every time you get into the your ISR. > I imagine you'll find it's already working right. It's probably just the > way you're using the profiler that's making it look like it's not working > right.You were right, it gave the right time interval.....:) If only always the problems were that easy... Simone