FireBLE/Timer driver

来自Firefly wiki
跳转至: 导航搜索

Introduction

The timer supplies lots of convenient operations and accurate beats of time for system as the most basic driver in the development of MCU.QN902x has 4 timers,among them the TIMER0/1 is the 32-bit timer,TIMER2/3 is the 16-bit timer.The functions of timer includes timing,counting,capturing,comparing and so on.

Initialization

System initialization、GPIO initialization and timer pin configuration

    SystemInit();
 
    /* Initialize GPIO (sets up clock) */
    gpio_init(NULL);
    /* Set all pin to output */
    gpio_set_direction_field(LED_PINS, (uint32_t)GPIO_OUTPUT);
    gpio_write_pin_field(LED_PINS, (uint32_t)GPIO_HIGH);
 
 
    // Timer io configurate
    timer_io_config();

The IO of system initialization,because of considering packaging volume,the IO of QN9021 are cut in a degree and the pin configuration has some diffrence with QN9020’s.

void timer_io_config(void)
{
    // pin mux
    syscon_SetPMCR0(QN_SYSCON, P07_SW_CLK_PIN_CTRL       
                             | P06_SW_DAT_PIN_CTRL
                             | P00_UART0_TXD_PIN_CTRL      
                             | P17_UART0_RXD_PIN_CTRL   
                             | P03_TIMER0_ECLK_PIN_CTRL //P0.3 timer0, used for pwm and caputure
                             | P10_TIMER2_ECLK_PIN_CTRL //P1.0 timer2, used for pwm and caputure
                             | P11_TIMER1_ICP0_PIN_CTRL //P1.1 timer1, used for pwm and caputure
                             );
    syscon_SetPMCR1(QN_SYSCON, P23_TIMER3_ICP0_PIN_CTRL //P2.3 timer3, used for pwm and caputure      
                             );
// pin pull ( 00 : High-Z,  01 : Pull-down,  10 : Pull-up,  11 : Reserved )
    syscon_SetPPCR0(QN_SYSCON, 0xAAAA5AAA);
    syscon_SetPPCR1(QN_SYSCON, 0x2AAAAAAA);
}

Example of timer

There are interruption experiment,PWM output experiment,capturing event-time experiment,capturing event-counting experiment and capturing event experiment.

Timer's interruption experiment

This experiment set different initial value for different timesrs separately.when the timer triggers the interruption after the time reaches ,lighting LED up and out in contrast to previous state at the callback function,and making the 4 LED flashing with different frequence. As a 32-bit timer,the timer0/1 has the higher degree of accuracy,lower degree of time interval,smaller value of frequence division coefficient.

    timer_init(QN_TIMER0, led0_link);
    timer_config(QN_TIMER0, TIMER_PSCAL_DIV, TIMER_COUNT_US(1000, TIMER_PSCAL_DIV));
    timer_enable(QN_TIMER0, MASK_ENABLE);
 
    timer_init(QN_TIMER1, led1_link);
    timer_config(QN_TIMER1, TIMER_PSCAL_DIV, TIMER_COUNT_US(2000, TIMER_PSCAL_DIV));
    timer_enable(QN_TIMER1, MASK_ENABLE);

As a 16-bit timer,the timer2/3 has lower degree of accuracy,higher degree of timer interval,larger value of frequence division coefficient.

    timer_init(QN_TIMER2, led2_link);
    timer_config(QN_TIMER2, 10, TIMER_COUNT_MS(3, 10));
    timer_enable(QN_TIMER2, MASK_ENABLE);
 
    timer_init(QN_TIMER3, led3_link);
    timer_config(QN_TIMER3, 10, TIMER_COUNT_MS(4, 10));
    timer_enable(QN_TIMER3, MASK_ENABLE);

Timer's PWM output experiment

This experiment is for PWM output using timer,the configuration parameters are same to PWM’s.

    //P0.3 will output pwm wave with period for 1000us and pulse for 500us 
    timer_init(QN_TIMER0, NULL);
    timer_pwm_config(QN_TIMER0, TIMER_PSCAL_DIV, TIMER_COUNT_US(1000, TIMER_PSCAL_DIV), TIMER_COUNT_US(500, TIMER_PSCAL_DIV));
    timer_enable(QN_TIMER0, MASK_ENABLE);
 
    //P1.1 will output pwm wave with period for 2000us and pulse for 1000us
    timer_init(QN_TIMER1, NULL);
    timer_pwm_config(QN_TIMER1, TIMER_PSCAL_DIV, TIMER_COUNT_US(2000, TIMER_PSCAL_DIV), TIMER_COUNT_US(1000, TIMER_PSCAL_DIV));
    timer_enable(QN_TIMER1, MASK_ENABLE);
 
    //P2.6 will output pwm wave with period for 4ms and pulse for 2ms
    timer_init(QN_TIMER2, NULL);
    timer_pwm_config(QN_TIMER2, 10, TIMER_COUNT_MS(4, 10),  TIMER_COUNT_MS(2, 10));
    timer_enable(QN_TIMER2, MASK_ENABLE);
 
    //P2.3 will output pwm wave with period for 6ms and pulse for 3ms
    timer_init(QN_TIMER3, NULL);
    timer_pwm_config(QN_TIMER3, 10, TIMER_COUNT_MS(6, 10),  TIMER_COUNT_MS(3, 10));
    timer_enable(QN_TIMER3, MASK_ENABLE);

Timer's capturing event-time experiment

Timer’s capture mode is a little complex,fiirst of all it need to initial the TIMERx and set the callback fuction to record the time when the event happends,setting the timer capture mode-INCAP_TIMER_MOD for timer,at the moment,the timer will trigger interruption and count time at the rising edge of P0.3.(the falling edge need to get into the funtion timer_capture_config to set up), then keeping the value of counting-time in the callback function when every risig edge comes.therefore, it can get the time interval between 2 events in the callback function,which adapts to the occurrence time of pattern.

    /*
     * Capture timer mode is to capture trigger event, and record the time-stamp.
     *
     * Make sure the macro TIMER0_CAP_MODE is INCAP_TIMER_MOD. 
     *
     * Timer0 will capture the P0.3 rising edge, and each rising edge will trigger 
     * the callback function, as the same time the counter value will transmit to 
     * timer0_env.count.
     * 
     * Other timers are similar to this.
     */
    timer_init(QN_TIMER0, timer0_callback);
    timer_capture_config(QN_TIMER0, INCAP_TIMER_MOD, 0, 0, 0);
    timer_enable(QN_TIMER0, MASK_ENABLE);

Timer's capturing event-counting experiment

It sets the time-capturing mode INCAP_COUNTER_MOD for timer in this experiment,and triggers interruption and records counting numbers after every five rising edge coming at P0.3.
    /*
     * Capture event mode is to calculate the time of happened specified event with 
     * specified numbers.
     *
     * Make sure the macro TIMER0_CAP_MODE is INCAP_COUNTER_MOD. 
     *
     * Timer0 will count the time during 5 times rising edge of P0.3. After that, the 
     * callback function will be called, as the same time the time value will transmit to 
     * timer0_env.count.
     * 
     * Other timers are similar to this.
     */
    timer_init(QN_TIMER0, timer0_callback);
    timer_capture_config(QN_TIMER0, INCAP_COUNTER_MOD, 100, 0, 5);
    timer_enable(QN_TIMER0, MASK_ENABLE);

Timer's event-capturing experiment

It sets the event-capturing mod INCAP_COUNTER_MOD for timer in the experiment.in the mod,counting the numbers of the rising edge of P0.3 within 1000ms,after 1000ms the interruption being triggered,then taking out the value of times events happen in callback function.

    /*
     * Capture conter mode is used to count the numbers of a special event during a specified period.
     * 
     * Make sure the macro TIMER0_CAP_MODE is INCAP_EVENT_MOD. 
     *
     * Timer0 will count the numbers of rising edge during 1000ms with P0.3, and each rising 
     * edge will trigger the callback function, as the same time the counter value will transmit 
     * to timer0_env.count.
     * 
     * Other timers are similar to this.
     */
    timer_init(QN_TIMER0, timer0_callback);
    timer_capture_config(QN_TIMER0, INCAP_EVENT_MOD, 100, TIMER_COUNT_MS(1000, 100), 0);
    timer_enable(QN_TIMER0, MASK_ENABLE);