[3c7ed6b] | 1 | /** |
---|
| 2 | * @file timer.c |
---|
| 3 | * |
---|
| 4 | * GBA Timer driver. |
---|
| 5 | */ |
---|
| 6 | /* |
---|
| 7 | * RTEMS GBA BSP |
---|
| 8 | * |
---|
| 9 | * Copyright (c) 2002 by Jay Monkman <jtm@smoothsmoothie.com> |
---|
| 10 | * |
---|
| 11 | * Copyright (c) 2004 Markku Puro <markku.puro@kopteri.net> |
---|
| 12 | * |
---|
| 13 | * The license and distribution terms for this file may be |
---|
[15ca4e7] | 14 | * found in the file LICENSE in this distribution or at |
---|
[c499856] | 15 | * http://www.rtems.org/license/LICENSE. |
---|
[3c7ed6b] | 16 | * |
---|
| 17 | * |
---|
| 18 | * Notes: |
---|
| 19 | * This file manages the benchmark timer used by the RTEMS Timing Test |
---|
| 20 | * Suite. Each measured time period is demarcated by calls to |
---|
[89866d84] | 21 | * benchmark_timer_initialize() and benchmark_timer_read(). benchmark_timer_read() usually returns |
---|
| 22 | * the number of microseconds since benchmark_timer_initialize() exitted. |
---|
[3c7ed6b] | 23 | * |
---|
| 24 | * It is important that the timer start/stop overhead be determined |
---|
| 25 | * when porting or modifying this code. |
---|
| 26 | */ |
---|
| 27 | |
---|
| 28 | #include <rtems.h> |
---|
| 29 | #include <bsp.h> |
---|
[14102e1e] | 30 | #include <rtems/btimer.h> |
---|
[536f2d2b] | 31 | #include <bsp/irq.h> |
---|
[3c7ed6b] | 32 | #include <gba.h> |
---|
| 33 | |
---|
| 34 | /* |
---|
| 35 | * Set up the timer hardware |
---|
| 36 | * 1 / 16.78Mhz => 59.595 ns |
---|
| 37 | * 64 / 16.78Mhz => 3.814 us |
---|
| 38 | * 256 / 16.78Mhz => 15.256 us |
---|
| 39 | * 1024 / 16.78Mhz => 61.025 us |
---|
| 40 | */ |
---|
| 41 | #define __TimePreScaler 1 |
---|
| 42 | #define __TickTime_ns ((1000000000L/__ClockFrequency)*__TimePreScaler) |
---|
| 43 | #define __TickTime_us ((1000000L/__ClockFrequency)*__TimePreScaler) |
---|
| 44 | |
---|
| 45 | #if (__TimePreScaler==1) |
---|
| 46 | #define GBA_TM0CNT_PS 0x0000 |
---|
| 47 | #elif (__TimePreScaler==64) |
---|
| 48 | #define GBA_TM0CNT_PS 0x0001 |
---|
| 49 | #elif (__TimePreScaler==256) |
---|
| 50 | #define GBA_TM0CNT_PS 0x0002 |
---|
| 51 | #elif (__TimePreScaler==1024) |
---|
| 52 | #define GBA_TM0CNT_PS 0x0003 |
---|
| 53 | #else |
---|
| 54 | #define GBA_TM0CNT_PS 0x0003 |
---|
| 55 | #endif |
---|
| 56 | |
---|
[89866d84] | 57 | bool benchmark_timer_find_average_overhead; |
---|
[3c7ed6b] | 58 | |
---|
| 59 | /** |
---|
[89866d84] | 60 | * @brief benchmark_timer_initialize start TM0 and TM1 |
---|
[3c7ed6b] | 61 | * |
---|
| 62 | * @param None |
---|
| 63 | * @return None |
---|
| 64 | */ |
---|
[89866d84] | 65 | void benchmark_timer_initialize( void ) |
---|
[3c7ed6b] | 66 | { |
---|
| 67 | GBA_REG_TM1CNT = 0x0000; /* Stop Counters */ |
---|
| 68 | GBA_REG_TM0CNT = 0x0000; |
---|
| 69 | GBA_REG_TM1D = 0x0000; /* Reset Counters */ |
---|
| 70 | GBA_REG_TM0D = 0x0000; |
---|
| 71 | /* Start Counters */ |
---|
| 72 | GBA_REG_TM1CNT = 0x0084; /* Start Count Up timing */ |
---|
| 73 | GBA_REG_TM0CNT = (0x0080|GBA_TM0CNT_PS); /* Start Count */ |
---|
| 74 | } |
---|
| 75 | |
---|
| 76 | /* |
---|
[89866d84] | 77 | * The following controls the behavior of benchmark_timer_read(). |
---|
[3c7ed6b] | 78 | * |
---|
| 79 | * AVG_OVEREHAD is the overhead for starting and stopping the timer. It |
---|
| 80 | * is usually deducted from the number returned. |
---|
| 81 | * |
---|
| 82 | * LEAST_VALID is the lowest number this routine should trust. Numbers |
---|
| 83 | * below this are "noise" and zero is returned. |
---|
| 84 | */ |
---|
| 85 | |
---|
| 86 | #define AVG_OVERHEAD 3 /**< It typically takes 3 microseconds */ |
---|
| 87 | #define LEAST_VALID 1 /**< Don't trust a clicks value lower than this */ |
---|
| 88 | |
---|
| 89 | /** |
---|
[89866d84] | 90 | * @brief benchmark_timer_read return timer countervalue in microseconds. |
---|
[3c7ed6b] | 91 | * |
---|
| 92 | * Used in Timing Test Suite. |
---|
| 93 | * |
---|
| 94 | * @param None |
---|
| 95 | * @return Timer value in microseconds |
---|
| 96 | */ |
---|
[89866d84] | 97 | uint32_t benchmark_timer_read( void ) |
---|
[3c7ed6b] | 98 | { |
---|
| 99 | uint32_t ticks; |
---|
| 100 | uint32_t total; |
---|
| 101 | |
---|
| 102 | /* Stop Counters */ |
---|
| 103 | GBA_REG_TM0CNT = 0x0000; |
---|
| 104 | GBA_REG_TM1CNT = 0x0000; |
---|
| 105 | /* Read Counters */ |
---|
| 106 | ticks = (GBA_REG_TM1D<<16) | GBA_REG_TM0D; |
---|
| 107 | if ( ticks < LEAST_VALID ) { |
---|
| 108 | return 0; /* below timer resolution */ |
---|
| 109 | } |
---|
| 110 | /* convert to uS */ |
---|
| 111 | total = ((ticks * __TickTime_ns) / 1000); |
---|
[8b549aff] | 112 | if ( benchmark_timer_find_average_overhead == true ) { |
---|
[3c7ed6b] | 113 | return total; /* in microseconds */ |
---|
| 114 | } |
---|
| 115 | else { |
---|
| 116 | if ( total < AVG_OVERHEAD ) { |
---|
| 117 | return 0; |
---|
| 118 | } |
---|
| 119 | return (total - AVG_OVERHEAD); |
---|
| 120 | } |
---|
| 121 | } |
---|
| 122 | |
---|
| 123 | /** |
---|
[89866d84] | 124 | * @brief Set benchmark_timer_find_average_overhead flag. |
---|
[3c7ed6b] | 125 | * |
---|
| 126 | * Used in Timing Test Suite. |
---|
| 127 | * |
---|
[8b549aff] | 128 | * @param find_flag bool find_flag |
---|
[3c7ed6b] | 129 | * @return None |
---|
| 130 | */ |
---|
[89866d84] | 131 | void benchmark_timer_disable_subtracting_average_overhead(bool find_flag) |
---|
[3c7ed6b] | 132 | { |
---|
[89866d84] | 133 | benchmark_timer_find_average_overhead = find_flag; |
---|
[3c7ed6b] | 134 | } |
---|