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 #include <rtems.h>
0018
0019 #include <stdlib.h>
0020
0021 #include <rtems/clockdrv.h>
0022 #include <rtems/score/sh_io.h>
0023 #include <rtems/score/sh.h>
0024 #include <rtems/score/ispsh7750.h>
0025 #include <rtems/score/iosh7750.h>
0026
0027 static void Clock_exit( void );
0028
0029 extern uint32_t bsp_clicks_per_second;
0030
0031 #ifndef CLOCKPRIO
0032 #define CLOCKPRIO 10
0033 #endif
0034
0035
0036 #define CLOCK_PRESCALER 4
0037 #define TCR0_TPSC SH7750_TCR_TPSC_DIV4
0038
0039
0040
0041
0042
0043 #define CLOCK_VECTOR SH7750_EVT_TO_NUM(SH7750_EVT_TUNI0)
0044
0045
0046
0047
0048
0049 volatile uint32_t Clock_driver_ticks;
0050
0051 static rtems_isr Clock_isr( rtems_vector_number vector );
0052
0053
0054
0055
0056 rtems_isr_entry Old_ticker;
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067 static rtems_isr Clock_isr(rtems_vector_number vector)
0068 {
0069 uint16_t tcr;
0070
0071
0072 tcr = read16(SH7750_TCR0);
0073 write16(tcr & ~SH7750_TCR_UNF, SH7750_TCR0);
0074
0075
0076 Clock_driver_ticks++ ;
0077
0078
0079 rtems_clock_tick();
0080 }
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091 static void Install_clock(rtems_isr_entry clock_isr)
0092 {
0093 int cpudiv = 1;
0094 int tidiv = 1;
0095 uint32_t timer_divider;
0096 uint8_t temp8;
0097 uint16_t temp16;
0098
0099
0100
0101
0102
0103 Clock_driver_ticks = 0;
0104
0105
0106 switch (read16(SH7750_FRQCR) & SH7750_FRQCR_IFC) {
0107 case SH7750_FRQCR_IFCDIV1:
0108 cpudiv = 1;
0109 break;
0110
0111 case SH7750_FRQCR_IFCDIV2:
0112 cpudiv = 2;
0113 break;
0114
0115 case SH7750_FRQCR_IFCDIV3:
0116 cpudiv = 3;
0117 break;
0118
0119 case SH7750_FRQCR_IFCDIV4:
0120 cpudiv = 4;
0121 break;
0122
0123 case SH7750_FRQCR_IFCDIV6:
0124 cpudiv = 6;
0125 break;
0126
0127 case SH7750_FRQCR_IFCDIV8:
0128 cpudiv = 8;
0129 break;
0130
0131 default:
0132 rtems_fatal_error_occurred( RTEMS_NOT_CONFIGURED);
0133 }
0134
0135
0136 switch (read16(SH7750_FRQCR) & SH7750_FRQCR_PFC) {
0137 case SH7750_FRQCR_PFCDIV2:
0138 tidiv = 2 * CLOCK_PRESCALER;
0139 break;
0140
0141 case SH7750_FRQCR_PFCDIV3:
0142 tidiv = 3 * CLOCK_PRESCALER;
0143 break;
0144
0145 case SH7750_FRQCR_PFCDIV4:
0146 tidiv = 4 * CLOCK_PRESCALER;
0147 break;
0148
0149 case SH7750_FRQCR_PFCDIV6:
0150 tidiv = 6 * CLOCK_PRESCALER;
0151 break;
0152
0153 case SH7750_FRQCR_PFCDIV8:
0154 tidiv = 8 * CLOCK_PRESCALER;
0155 break;
0156
0157 default:
0158 rtems_fatal_error_occurred( RTEMS_NOT_CONFIGURED);
0159 }
0160 timer_divider =
0161 (bsp_clicks_per_second * cpudiv / (tidiv*1000000)) *
0162 rtems_configuration_get_microseconds_per_tick();
0163
0164
0165
0166
0167
0168
0169 temp8 = read8(SH7750_TSTR);
0170 temp8 &= ~SH7750_TSTR_STR0;
0171 write8(temp8, SH7750_TSTR);
0172
0173
0174 rtems_interrupt_catch( Clock_isr, CLOCK_VECTOR, &Old_ticker );
0175
0176
0177 write32(timer_divider, SH7750_TCNT0);
0178
0179
0180 write32(timer_divider, SH7750_TCOR0);
0181
0182 write16(
0183 SH7750_TCR_UNIE |
0184 SH7750_TCR_CKEG_RAISE |
0185 TCR0_TPSC,
0186 SH7750_TCR0);
0187
0188
0189 temp16 = read16(SH7750_IPRA);
0190 temp16 = (temp16 & ~SH7750_IPRA_TMU0) | (CLOCKPRIO << SH7750_IPRA_TMU0_S);
0191 write16(temp16, SH7750_IPRA);
0192
0193
0194 temp8 = read8(SH7750_TSTR);
0195 temp8 |= SH7750_TSTR_STR0;
0196 write8(temp8, SH7750_TSTR);
0197
0198
0199
0200
0201 atexit( Clock_exit );
0202 }
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212 void
0213 Clock_exit(void)
0214 {
0215 uint8_t temp8 = 0;
0216 uint16_t temp16 = 0;
0217
0218
0219
0220 temp8 = read8(SH7750_TSTR);
0221 temp8 &= ~SH7750_TSTR_STR0;
0222 write8(temp8, SH7750_TSTR);
0223
0224
0225 temp16 = read16(SH7750_IPRA);
0226 temp16 = (temp16 & ~SH7750_IPRA_TMU0) | (0 << SH7750_IPRA_TMU0_S);
0227 write16(temp16, SH7750_IPRA);
0228
0229
0230 }
0231
0232 void _Clock_Initialize( void )
0233 {
0234 Install_clock( Clock_isr );
0235 }