File indexing completed on 2025-05-11 08:24:01
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #include <rtems.h>
0019 #include <rtems/btimer.h>
0020
0021 #include <rtems/score/sh_io.h>
0022 #include <rtems/score/iosh7750.h>
0023
0024 extern uint32_t bsp_clicks_per_second;
0025
0026 #ifndef TIMER_PRIO
0027 #define TIMER_PRIO 15
0028 #endif
0029
0030
0031 #define TIMER_PRESCALER 4
0032 #define TCR1_TPSC SH7750_TCR_TPSC_DIV4
0033
0034 #define TIMER_VECTOR SH7750_EVT_TO_NUM(SH7750_EVT_TUNI1)
0035
0036 extern rtems_isr timerisr(void);
0037
0038 static uint32_t Timer_interrupts;
0039
0040
0041 static uint32_t microseconds_divider;
0042
0043
0044 static uint32_t microseconds_per_int;
0045
0046 bool benchmark_timer_find_average_overhead;
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061 void
0062 benchmark_timer_initialize(void)
0063 {
0064 uint8_t temp8;
0065 uint16_t temp16;
0066 rtems_interrupt_level level;
0067 rtems_isr *ignored;
0068 int cpudiv = 1;
0069 int tidiv = 1;
0070
0071 Timer_interrupts = 0;
0072 rtems_interrupt_disable(level);
0073
0074
0075 switch (read16(SH7750_FRQCR) & SH7750_FRQCR_IFC)
0076 {
0077 case SH7750_FRQCR_IFCDIV1:
0078 cpudiv = 1;
0079 break;
0080
0081 case SH7750_FRQCR_IFCDIV2:
0082 cpudiv = 2;
0083 break;
0084
0085 case SH7750_FRQCR_IFCDIV3:
0086 cpudiv = 3;
0087 break;
0088
0089 case SH7750_FRQCR_IFCDIV4:
0090 cpudiv = 4;
0091 break;
0092
0093 case SH7750_FRQCR_IFCDIV6:
0094 cpudiv = 6;
0095 break;
0096
0097 case SH7750_FRQCR_IFCDIV8:
0098 cpudiv = 8;
0099 break;
0100
0101 default:
0102 rtems_fatal_error_occurred( RTEMS_NOT_CONFIGURED);
0103 }
0104
0105
0106 switch (read16(SH7750_FRQCR) & SH7750_FRQCR_PFC)
0107 {
0108 case SH7750_FRQCR_PFCDIV2:
0109 tidiv = 2 * TIMER_PRESCALER;
0110 break;
0111
0112 case SH7750_FRQCR_PFCDIV3:
0113 tidiv = 3 * TIMER_PRESCALER;
0114 break;
0115
0116 case SH7750_FRQCR_PFCDIV4:
0117 tidiv = 4 * TIMER_PRESCALER;
0118 break;
0119
0120 case SH7750_FRQCR_PFCDIV6:
0121 tidiv = 6 * TIMER_PRESCALER;
0122 break;
0123
0124 case SH7750_FRQCR_PFCDIV8:
0125 tidiv = 8 * TIMER_PRESCALER;
0126 break;
0127
0128 default:
0129 rtems_fatal_error_occurred( RTEMS_NOT_CONFIGURED);
0130 }
0131
0132 microseconds_divider = bsp_clicks_per_second * cpudiv / (tidiv * 1000000);
0133 microseconds_per_int = 0xFFFFFFFF / microseconds_divider;
0134
0135
0136
0137
0138
0139
0140 temp8 = read8(SH7750_TSTR);
0141 temp8 &= ~SH7750_TSTR_STR1;
0142 write8(temp8, SH7750_TSTR);
0143
0144
0145 _CPU_ISR_install_raw_handler( TIMER_VECTOR, timerisr, &ignored );
0146
0147
0148 write32(0xFFFFFFFF, SH7750_TCOR1);
0149 write32(0xFFFFFFFF, SH7750_TCNT1);
0150
0151
0152 write16(
0153 SH7750_TCR_UNIE |
0154 SH7750_TCR_CKEG_RAISE |
0155 TCR1_TPSC,
0156 SH7750_TCR1);
0157
0158
0159 temp16 = read16(SH7750_IPRA);
0160 temp16 = (temp16 & ~SH7750_IPRA_TMU1) | (TIMER_PRIO << SH7750_IPRA_TMU1_S);
0161 write16(temp16, SH7750_IPRA);
0162
0163
0164 rtems_interrupt_enable(level);
0165
0166
0167 temp8 = read8(SH7750_TSTR);
0168 temp8 |= SH7750_TSTR_STR1;
0169 write8(temp8, SH7750_TSTR);
0170
0171 }
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183 #define AVG_OVERHEAD 0
0184
0185
0186 #define LEAST_VALID 0
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197 benchmark_timer_t
0198 benchmark_timer_read(void)
0199 {
0200 uint32_t clicks;
0201 uint32_t ints;
0202 uint32_t total;
0203 rtems_interrupt_level level;
0204 uint32_t tcr;
0205
0206
0207 rtems_interrupt_disable(level);
0208
0209 clicks = 0xFFFFFFFF - read32(SH7750_TCNT1);
0210 tcr = read32(SH7750_TCR1);
0211 ints = Timer_interrupts;
0212
0213 rtems_interrupt_enable(level);
0214
0215
0216 if ((clicks > 0xFF000000) && ((tcr & SH7750_TCR_UNF) != 0))
0217 {
0218 ints++;
0219 }
0220
0221 total = microseconds_per_int * ints + (clicks / microseconds_divider);
0222
0223 if ( benchmark_timer_find_average_overhead )
0224 return total;
0225 else
0226 {
0227 if ( total < LEAST_VALID )
0228 return 0;
0229
0230
0231
0232 return (total - AVG_OVERHEAD) ;
0233 }
0234 }
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247
0248 void
0249 benchmark_timer_disable_subtracting_average_overhead(bool find_flag)
0250 {
0251 benchmark_timer_find_average_overhead = find_flag;
0252 }
0253
0254
0255
0256
0257
0258
0259 void
0260 timerisr(void)
0261 {
0262 uint8_t temp8;
0263
0264
0265 temp8 = read8(SH7750_TCR1) & ~SH7750_TCR_UNF;
0266 write8(temp8, SH7750_TCR1);
0267
0268 Timer_interrupts += 1;
0269 }