Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
12 years ago

Interval timer problem

Hello.

I’ve got a problem with simple interrupt from interval timer in uC/OS-II

System frequency is 75Mhz. There are PIO and timer. It makes strobe. Duration 10 ms. Here it is:


// global variablesint err; 
// handler
static void handle_timer(void* context)
{
    IOWR_ALTERA_AVALON_TIMER_CONTROL(timer_base, ALTERA_AVALON_TIMER_CONTROL_STOP_MSK); //disable interrupt
    IOWR_ALTERA_AVALON_TIMER_STATUS(timer_base, 0); //clear flag
    IOWR_ALTERA_AVALON_PIO_DATA(PIO_BASE, 1);
    timer_exit();
    err = 1;
    return;
}
// set handler
void timer_init(alt_u32 _base, alt_u32 _interrupt, alt_u32 _irq)
{
    timer_base = _base; 
    timer_interrupt = _interrupt;
    timer_irq = _irq;
    alt_ic_irq_disable (timer_interrupt, timer_irq);//disable interrupt
    alt_ic_isr_register(timer_interrupt, timer_irq, handle_timer, NULL, NULL); break;
    return;
}
// reset / set timeout 
void timer_set_period(alt_u32 timer_period)
{
    timer_period = HIGHT_RES_TIMER_LOAD_VALUE * timer_period;
    IOWR_ALTERA_AVALON_TIMER_PERIODL(timer_base, timer_period&ALTERA_AVALON_TIMER_PERIODL_MSK);            //write timer period l
    IOWR_ALTERA_AVALON_TIMER_PERIODH(timer_base, (timer_period>>16)&ALTERA_AVALON_TIMER_PERIODH_MSK);    //write timer period h
    return;
}
// start counting
void timer_start(void)
{
    IOWR_ALTERA_AVALON_TIMER_CONTROL(timer_base, ALTERA_AVALON_TIMER_CONTROL_STOP_MSK); //stop timer, disable interrupt
    IOWR_ALTERA_AVALON_TIMER_STATUS(timer_base, 0);                                     //clear flag
    IOWR_ALTERA_AVALON_TIMER_CONTROL(timer_base, (    ALTERA_AVALON_TIMER_CONTROL_ITO_MSK |
                                                    ALTERA_AVALON_TIMER_CONTROL_START_MSK)); //start timer, enable interrupt
    return;
}
// pause counting
void timer_stop(void)
{
    IOWR_ALTERA_AVALON_TIMER_CONTROL(timer_base, ALTERA_AVALON_TIMER_CONTROL_STOP_MSK); //stop timer, disable interrupt
    IOWR_ALTERA_AVALON_TIMER_STATUS(timer_base, 0);                                     //clear flag
    return;
}
// timer deactivation 
void timer_exit(void)
{
    IOWR_ALTERA_AVALON_TIMER_CONTROL(timer_base, ALTERA_AVALON_TIMER_CONTROL_STOP_MSK); //stop timer, disable interrupt
    IOWR_ALTERA_AVALON_TIMER_STATUS(timer_base, 0);                                     //clear flag
    alt_ic_irq_disable (timer_interrupt, timer_irq);//disable interrupt
    return;
}
// timer usage
int foo(void)
    {
        int nop; 
        err = 0;
        
/*A*/    IOWR_ALTERA_AVALON_PIO_DATA(PIO_BASE, 0);    //set PIO
/*B*/    timer_init(HIGHT_RES_TIMER_BASE, HIGHT_RES_TIMER_IRQ_INTERRUPT_CONTROLLER_ID, HIGHT_RES_TIMER_IRQ);
/*C*/    timer_set_period(10);
/*D*/    timer_start();
        while(err == 0)
        {nop=0;}        //waiting for timer
        timer_exit();
        return 1;
    }

Timer’s description from system.h

/*
 * hight_res_timer configuration
 *
 */# define ALT_MODULE_CLASS_hight_res_timer altera_avalon_timer# define HIGHT_RES_TIMER_ALWAYS_RUN 0# define HIGHT_RES_TIMER_BASE 0x1003520# define HIGHT_RES_TIMER_COUNTER_SIZE 32# define HIGHT_RES_TIMER_FIXED_PERIOD 0# define HIGHT_RES_TIMER_FREQ 75000000u# define HIGHT_RES_TIMER_IRQ 1# define HIGHT_RES_TIMER_IRQ_INTERRUPT_CONTROLLER_ID 0# define HIGHT_RES_TIMER_LOAD_VALUE 74ull# define HIGHT_RES_TIMER_MULT 1.0E-6# define HIGHT_RES_TIMER_NAME "/dev/hight_res_timer"# define HIGHT_RES_TIMER_PERIOD 1.0# define HIGHT_RES_TIMER_PERIOD_UNITS "us"# define HIGHT_RES_TIMER_RESET_OUTPUT 0# define HIGHT_RES_TIMER_SNAPSHOT 1# define HIGHT_RES_TIMER_SPAN 32# define HIGHT_RES_TIMER_TICKS_PER_SEC 1000000u# define HIGHT_RES_TIMER_TIMEOUT_PULSE_OUTPUT 0

I debugged this code and it works perfectly.

My project became more complicated and I had to use uC/OS-II.

This part of code is very simple and has no changes but it works very strange. Duration of strobe became about 30 ms!

After some manipulation with code I found out that functions of setting timer on are very slow.

I put line A between lines C and D. It makes duration of strobe about 16 ms.

why simple register’s writing become slow? what should i do to make it working faster?

11 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    To resume, you want to produce strobe with various durations.

    This strobe signal is on an OUTPUT FPGA pin (destination : other device)

    right ?

    If you want hard real time (I mean that durations are strictly constrained and if one time is missed then fatal error), I don't recommand using software interrupts, because of what you have seen.

    --- Quote Start ---

    It’s hard to realize this staff on FPGA logic because it works closely to other subprograms.

    --- Quote End ---

    To produce strobe at various duration is not hard. You can load the value to a external (but inside FPGA) counter which produce strobe.

    To load the value, just employ a PIO ins Qsys.

    could you describe more of your project ? could you give a basic algorithm and structure of this part of your project (moslty relation between strobe and (sub)program)?

    Not enough info to help you and still confusing.