This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

delay milisecond

Hi all Iam using STR912FW44 based board and I want a delay function that should give the delay in milisecond I made a function


void delay_ms (unsigned long nCount){   /* Wait function                    */
  nCount=nCount+16000000L;

  while (nCount--);
}


when I call

delay_ms(10000);

it gives arround 10 second delay but when I call

delay_ms(20000);
it should give arround 20 second delay but it does not happen

but when I call

delay_ms(10000);
delay_ms(10000);

it gives arround 15 sec delay

please tell me exact way to build a delay function

regards
rupesh

Parents
  • /*
    ** Copyright (C) 2008 Tamir Michael
    **
    ** This program is free software; you can redistribute it and/or modify
    ** it under the terms of the GNU General Public License as published by
    ** the Free Software Foundation; either version 2 of the License, or
    ** (at your option) any later version.
    **
    ** This program is distributed in the hope that it will be useful,
    ** but WITHOUT ANY WARRANTY; without even the implied warranty of
    ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    ** GNU General Public License for more details.
    **
    ** You should have received a copy of the GNU General Public License
    ** along with this program; if not, write to the Free Software
    ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
    */
    
    #ifdef TIMER_MODULE
    
    #include "general_definitions.h"
    #include "timer.h"
    #include "config.h"
    #include "scheduler.h"
    #include "system_services.h"
    #include "system_notifications.h"
    
    // this module uses TIM2 to measure time intervals using polling with a flag indicating that
    // the desired time has elapsed, so that the interrupt line does not have to be disabled
    
    // avoid char and alike and use int instead. registers and stack are 32 bit wide anyway.
    // using a char for the index adds one instruction to its decrement.
    
    // making the size of arrays a multiple of 4 or 8 makes it easy to:
    // * fast calculate the index of the next element in a circular buffer ( index &= (size - 1) )
    // * east unroll of loops to reduce the 2 instruction overhead per loop iteration of the ARM
    
    // to add new timers, increase the value of 'USER_TIMER_SLOTS'. in addition, each task
    // has its own timer for delays.
    
    // note: the first MAX_TASKS timers are dedicated to wait timers of tasks
    // all timers beyond that are user timers.
    static timer_t  s_timers[1 + MAX_TASKS + USER_TIMER_SLOTS] ; // including the idle task
    static int32u   s_max_timers = (sizeof(s_timers) / sizeof(timer_t)) ;
    
    void timer_module_init(void)
    {
            int32u l_index, l_scheduler_state ;
    
            l_index = s_max_timers - 1 ;
    
            refuse_interrupt_context() ;
    
            scheduler_disable(&l_scheduler_state) ;
            system_timer_disable() ;
    
            do
            {
                    timer_t *lp_timer = s_timers + l_index ;
    
                    lp_timer->state = e_timer_not_ticking ;
                    lp_timer->deadline_countdown = 0 ;
                    lp_timer->late_counter = 0 ;
                    lp_timer->mode = e_timer_poll_mode ;
            }
            while ( (l_index--) != 0) ;
    
            system_timer_enable() ;
            scheduler_restore(l_scheduler_state) ;
    }
    
    // call 'timer_poll' repeatedly to wait for a certain time period to elapse.
    // a_timeout should be given using the defines in general_definitions.h. either way,
    // the unit is 10 milliseconds e.g giving this function '30' (or MILLISECONDS_X_10(30) )
    // will start incrementing the provided flag after 300 milliseconds.
    // note that calling this function results in the
    // timer restarting if it has expired, starting if it not started or resuming if the
    // deadline has not been reached yet. the reference point is set only if the timer
    // has expired or if it is not ticking as the time of the call.
    // the return value is the amount time that has elapsed
    // since the deadline has expired, or 0 if the timer is still ticking
    int32s timer_poll(int32s a_index, int32s a_timeout, int32s *a_ticks_left)
    {
            timer_t *lp_timer ;
            int32s   l_result = -1 ;
    
            if (a_timeout < 0)
            {
                    software_error("%d %s %d", ERR_INVALID_PARAMETER, __FILE__, __LINE__) ;
            }
    
            if ( (a_index < s_max_timers) && (a_index >= 0) )
            {
                    int32u l_scheduler_state, l_timer_state ;
    
                    scheduler_disable(&l_scheduler_state) ;
                    system_timer_disable() ;
    
                    lp_timer = s_timers + a_index ;
                    l_timer_state = lp_timer->state ;
    
                    system_timer_enable() ;
                    scheduler_restore(l_scheduler_state) ;
    
                    if (a_ticks_left)
                    {
                            *a_ticks_left = 0 ;
                    }
    
                    if (l_timer_state == e_timer_expired)
                    {
                            scheduler_disable(&l_scheduler_state) ;
    
                            lp_timer->deadline_countdown = a_timeout ; // reload the timer
                            l_result = lp_timer->late_counter ; // return how long before the call the deadline has expired
    
                            scheduler_restore(l_scheduler_state) ;
                    }
                    else if (lp_timer->state == e_timer_not_ticking)
                    {
                            scheduler_disable(&l_scheduler_state) ;
    
                            lp_timer->mode = e_timer_poll_mode ;
                            lp_timer->deadline_countdown = a_timeout ; // reload the timer
    
                            scheduler_restore(l_scheduler_state) ;
    
                            l_result = 0 ;
                    }
                    else
                    {
                            // lp_timer->deadline_countdown is not reloaded if timer is still ticking
                            l_result = 0 ;
                    }
    
                    scheduler_disable(&l_scheduler_state) ;
    
                    lp_timer->late_counter = 0 ;
                    lp_timer->state = e_timer_ticking ;
    
                    if (a_ticks_left)
                    {
                            *a_ticks_left = lp_timer->deadline_countdown ;
                    }
    
                    scheduler_restore(l_scheduler_state) ;
    
                    system_timer_enable() ;
            }
    
            return l_result ;
    }
    

Reply
  • /*
    ** Copyright (C) 2008 Tamir Michael
    **
    ** This program is free software; you can redistribute it and/or modify
    ** it under the terms of the GNU General Public License as published by
    ** the Free Software Foundation; either version 2 of the License, or
    ** (at your option) any later version.
    **
    ** This program is distributed in the hope that it will be useful,
    ** but WITHOUT ANY WARRANTY; without even the implied warranty of
    ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    ** GNU General Public License for more details.
    **
    ** You should have received a copy of the GNU General Public License
    ** along with this program; if not, write to the Free Software
    ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
    */
    
    #ifdef TIMER_MODULE
    
    #include "general_definitions.h"
    #include "timer.h"
    #include "config.h"
    #include "scheduler.h"
    #include "system_services.h"
    #include "system_notifications.h"
    
    // this module uses TIM2 to measure time intervals using polling with a flag indicating that
    // the desired time has elapsed, so that the interrupt line does not have to be disabled
    
    // avoid char and alike and use int instead. registers and stack are 32 bit wide anyway.
    // using a char for the index adds one instruction to its decrement.
    
    // making the size of arrays a multiple of 4 or 8 makes it easy to:
    // * fast calculate the index of the next element in a circular buffer ( index &= (size - 1) )
    // * east unroll of loops to reduce the 2 instruction overhead per loop iteration of the ARM
    
    // to add new timers, increase the value of 'USER_TIMER_SLOTS'. in addition, each task
    // has its own timer for delays.
    
    // note: the first MAX_TASKS timers are dedicated to wait timers of tasks
    // all timers beyond that are user timers.
    static timer_t  s_timers[1 + MAX_TASKS + USER_TIMER_SLOTS] ; // including the idle task
    static int32u   s_max_timers = (sizeof(s_timers) / sizeof(timer_t)) ;
    
    void timer_module_init(void)
    {
            int32u l_index, l_scheduler_state ;
    
            l_index = s_max_timers - 1 ;
    
            refuse_interrupt_context() ;
    
            scheduler_disable(&l_scheduler_state) ;
            system_timer_disable() ;
    
            do
            {
                    timer_t *lp_timer = s_timers + l_index ;
    
                    lp_timer->state = e_timer_not_ticking ;
                    lp_timer->deadline_countdown = 0 ;
                    lp_timer->late_counter = 0 ;
                    lp_timer->mode = e_timer_poll_mode ;
            }
            while ( (l_index--) != 0) ;
    
            system_timer_enable() ;
            scheduler_restore(l_scheduler_state) ;
    }
    
    // call 'timer_poll' repeatedly to wait for a certain time period to elapse.
    // a_timeout should be given using the defines in general_definitions.h. either way,
    // the unit is 10 milliseconds e.g giving this function '30' (or MILLISECONDS_X_10(30) )
    // will start incrementing the provided flag after 300 milliseconds.
    // note that calling this function results in the
    // timer restarting if it has expired, starting if it not started or resuming if the
    // deadline has not been reached yet. the reference point is set only if the timer
    // has expired or if it is not ticking as the time of the call.
    // the return value is the amount time that has elapsed
    // since the deadline has expired, or 0 if the timer is still ticking
    int32s timer_poll(int32s a_index, int32s a_timeout, int32s *a_ticks_left)
    {
            timer_t *lp_timer ;
            int32s   l_result = -1 ;
    
            if (a_timeout < 0)
            {
                    software_error("%d %s %d", ERR_INVALID_PARAMETER, __FILE__, __LINE__) ;
            }
    
            if ( (a_index < s_max_timers) && (a_index >= 0) )
            {
                    int32u l_scheduler_state, l_timer_state ;
    
                    scheduler_disable(&l_scheduler_state) ;
                    system_timer_disable() ;
    
                    lp_timer = s_timers + a_index ;
                    l_timer_state = lp_timer->state ;
    
                    system_timer_enable() ;
                    scheduler_restore(l_scheduler_state) ;
    
                    if (a_ticks_left)
                    {
                            *a_ticks_left = 0 ;
                    }
    
                    if (l_timer_state == e_timer_expired)
                    {
                            scheduler_disable(&l_scheduler_state) ;
    
                            lp_timer->deadline_countdown = a_timeout ; // reload the timer
                            l_result = lp_timer->late_counter ; // return how long before the call the deadline has expired
    
                            scheduler_restore(l_scheduler_state) ;
                    }
                    else if (lp_timer->state == e_timer_not_ticking)
                    {
                            scheduler_disable(&l_scheduler_state) ;
    
                            lp_timer->mode = e_timer_poll_mode ;
                            lp_timer->deadline_countdown = a_timeout ; // reload the timer
    
                            scheduler_restore(l_scheduler_state) ;
    
                            l_result = 0 ;
                    }
                    else
                    {
                            // lp_timer->deadline_countdown is not reloaded if timer is still ticking
                            l_result = 0 ;
                    }
    
                    scheduler_disable(&l_scheduler_state) ;
    
                    lp_timer->late_counter = 0 ;
                    lp_timer->state = e_timer_ticking ;
    
                    if (a_ticks_left)
                    {
                            *a_ticks_left = lp_timer->deadline_countdown ;
                    }
    
                    scheduler_restore(l_scheduler_state) ;
    
                    system_timer_enable() ;
            }
    
            return l_result ;
    }
    

Children
No data