File indexing completed on 2025-05-11 08:23:53
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033 #include <rtems/bspIo.h>
0034
0035 #include <mpc83xx/mpc83xx.h>
0036 #include <mpc83xx/gtm.h>
0037
0038 #define RTEMS_STATUS_CHECKS_USE_PRINTK
0039
0040 #include <rtems/status-checks.h>
0041
0042 #define MPC83XX_GTM_CHECK_INDEX( timer) \
0043 if (( timer) < 0 || ( timer) >= MPC83XX_GTM_NUMBER) { \
0044 return RTEMS_INVALID_NUMBER; \
0045 }
0046
0047 #define GTM_MODULE(timer) ((timer)/4)
0048 #define GTM_MODULE_TIMER(timer) ((timer)%4)
0049 #define GTM_HIGH(timer) (GTM_MODULE_TIMER(timer)/2)
0050 #define GTM_LOW(timer) (GTM_MODULE_TIMER(timer)%2)
0051
0052 #define MPC83XX_GTM_CLOCK_MASK MPC83XX_GTM_CLOCK_EXTERN
0053
0054 static const uint8_t mpc83xx_gmt_interrupt_vector_table [MPC83XX_GTM_NUMBER] = { 90, 78, 84, 72, 91, 79, 85, 73 };
0055
0056 rtems_status_code mpc83xx_gtm_initialize( int timer, int clock)
0057 {
0058 rtems_status_code sc = RTEMS_SUCCESSFUL;
0059 rtems_interrupt_level level;
0060
0061 unsigned mask = 0xfU << (GTM_LOW(timer) * 4);
0062 unsigned flags = 0x3U << (GTM_LOW(timer) * 4);
0063 uint8_t reg = 0;
0064
0065 MPC83XX_GTM_CHECK_INDEX( timer);
0066
0067 rtems_interrupt_disable( level);
0068
0069 reg = mpc83xx.gtm [GTM_MODULE(timer)].gtcfr [GTM_HIGH(timer)].reg;
0070 mpc83xx.gtm [GTM_MODULE(timer)].gtcfr [GTM_HIGH(timer)].reg =
0071 (uint8_t) ((reg & ~mask) | flags);
0072
0073 mpc83xx.gtm [GTM_MODULE(timer)]
0074 .gt_tim_regs [GTM_HIGH(timer)]
0075 .gtmdr [GTM_LOW(timer)] = 0;
0076
0077 rtems_interrupt_enable( level);
0078
0079 sc = mpc83xx_gtm_set_clock( timer, clock);
0080 RTEMS_CHECK_SC( sc, "Set clock");
0081
0082 sc = mpc83xx_gtm_set_value( timer, 0);
0083 RTEMS_CHECK_SC( sc, "Set value");
0084
0085 sc = mpc83xx_gtm_set_reference( timer, 0);
0086 RTEMS_CHECK_SC( sc, "Set reference");
0087
0088 sc = mpc83xx_gtm_set_prescale( timer, 0);
0089 RTEMS_CHECK_SC( sc, "Set prescale");
0090
0091 return RTEMS_SUCCESSFUL;
0092 }
0093
0094 rtems_status_code mpc83xx_gtm_enable_restart( int timer, bool enable)
0095 {
0096 rtems_interrupt_level level;
0097 MPC83XX_GTM_CHECK_INDEX( timer);
0098
0099 rtems_interrupt_disable( level);
0100
0101 if (enable) {
0102 mpc83xx.gtm [GTM_MODULE(timer)]
0103 .gt_tim_regs [GTM_HIGH(timer)]
0104 .gtmdr [GTM_LOW(timer)] |= 0x0008;
0105 } else {
0106 mpc83xx.gtm [GTM_MODULE(timer)]
0107 .gt_tim_regs [GTM_HIGH(timer)]
0108 .gtmdr [GTM_LOW(timer)] &= ~0x0008;
0109 }
0110
0111 rtems_interrupt_enable( level);
0112
0113 return RTEMS_SUCCESSFUL;
0114 }
0115
0116 rtems_status_code mpc83xx_gtm_set_clock( int timer, int clock)
0117 {
0118 rtems_interrupt_level level;
0119 uint16_t reg = 0;
0120
0121 MPC83XX_GTM_CHECK_INDEX( timer);
0122
0123 if (clock & ~MPC83XX_GTM_CLOCK_MASK) {
0124 return RTEMS_INVALID_CLOCK;
0125 }
0126
0127 rtems_interrupt_disable( level);
0128
0129 reg = mpc83xx.gtm [GTM_MODULE(timer)]
0130 .gt_tim_regs [GTM_HIGH(timer)]
0131 .gtmdr [GTM_LOW(timer)];
0132 mpc83xx.gtm [GTM_MODULE(timer)]
0133 .gt_tim_regs [GTM_HIGH(timer)]
0134 .gtmdr [GTM_LOW(timer)] = (reg & ~MPC83XX_GTM_CLOCK_MASK) | clock;
0135
0136 rtems_interrupt_enable( level);
0137
0138 return RTEMS_SUCCESSFUL;
0139 }
0140
0141 rtems_status_code mpc83xx_gtm_get_clock( int timer, int *clock)
0142 {
0143 MPC83XX_GTM_CHECK_INDEX( timer);
0144
0145 *clock = mpc83xx.gtm [GTM_MODULE(timer)]
0146 .gt_tim_regs [GTM_HIGH(timer)]
0147 .gtmdr [GTM_LOW(timer)] & MPC83XX_GTM_CLOCK_MASK;
0148
0149 return RTEMS_SUCCESSFUL;
0150 }
0151
0152 rtems_status_code mpc83xx_gtm_start( int timer)
0153 {
0154 rtems_interrupt_level level;
0155 uint8_t flags = 0x2 << (GTM_LOW(timer) * 4);
0156
0157 MPC83XX_GTM_CHECK_INDEX( timer);
0158
0159 rtems_interrupt_disable( level);
0160 mpc83xx.gtm [GTM_MODULE(timer)]
0161 .gtcfr [GTM_HIGH(timer)].reg &= ~flags;
0162 rtems_interrupt_enable( level);
0163
0164 return RTEMS_SUCCESSFUL;
0165 }
0166
0167 rtems_status_code mpc83xx_gtm_stop( int timer)
0168 {
0169 rtems_interrupt_level level;
0170 uint8_t flags = 0x2 << (GTM_LOW(timer) * 4);
0171
0172 MPC83XX_GTM_CHECK_INDEX( timer);
0173
0174 rtems_interrupt_disable( level);
0175 mpc83xx.gtm [GTM_MODULE(timer)].gtcfr [GTM_HIGH(timer)].reg |= flags;
0176 rtems_interrupt_enable( level);
0177
0178 return RTEMS_SUCCESSFUL;
0179 }
0180
0181 rtems_status_code mpc83xx_gtm_set_value( int timer, uint16_t value)
0182 {
0183 MPC83XX_GTM_CHECK_INDEX( timer);
0184
0185 mpc83xx.gtm [GTM_MODULE(timer)].gt_tim_regs [GTM_HIGH(timer)].gtcnr [GTM_LOW(timer)] = value;
0186
0187 return RTEMS_SUCCESSFUL;
0188 }
0189
0190 rtems_status_code mpc83xx_gtm_get_value( int timer, uint16_t *value)
0191 {
0192 MPC83XX_GTM_CHECK_INDEX( timer);
0193
0194 *value = mpc83xx.gtm [GTM_MODULE(timer)].gt_tim_regs [GTM_HIGH(timer)].gtcnr [GTM_LOW(timer)];
0195
0196 return RTEMS_SUCCESSFUL;
0197 }
0198
0199 rtems_status_code mpc83xx_gtm_set_reference( int timer, uint16_t reference)
0200 {
0201 MPC83XX_GTM_CHECK_INDEX( timer);
0202
0203 mpc83xx.gtm [GTM_MODULE(timer)].gt_tim_regs [GTM_HIGH(timer)].gtrfr [GTM_LOW(timer)] = reference;
0204
0205 return RTEMS_SUCCESSFUL;
0206 }
0207
0208 rtems_status_code mpc83xx_gtm_get_reference( int timer, uint16_t *reference)
0209 {
0210 MPC83XX_GTM_CHECK_INDEX( timer);
0211
0212 *reference = mpc83xx.gtm [GTM_MODULE(timer)].gt_tim_regs [GTM_HIGH(timer)].gtrfr [GTM_LOW(timer)];
0213
0214 return RTEMS_SUCCESSFUL;
0215 }
0216
0217 rtems_status_code mpc83xx_gtm_set_prescale( int timer, uint8_t prescale)
0218 {
0219 MPC83XX_GTM_CHECK_INDEX( timer);
0220
0221 mpc83xx.gtm [GTM_MODULE(timer)].gtpsr [GTM_MODULE_TIMER(timer)] = prescale;
0222
0223 return RTEMS_SUCCESSFUL;
0224 }
0225
0226 rtems_status_code mpc83xx_gtm_get_prescale( int timer, uint8_t *prescale)
0227 {
0228 MPC83XX_GTM_CHECK_INDEX( timer);
0229
0230 *prescale = mpc83xx.gtm [GTM_MODULE(timer)].gtpsr [GTM_MODULE_TIMER(timer)];
0231
0232 return RTEMS_SUCCESSFUL;
0233 }
0234
0235 rtems_status_code mpc83xx_gtm_interrupt_get_vector( int timer, rtems_vector_number *vector)
0236 {
0237 MPC83XX_GTM_CHECK_INDEX( timer);
0238
0239 *vector = mpc83xx_gmt_interrupt_vector_table [timer];
0240
0241 return RTEMS_SUCCESSFUL;
0242 }
0243
0244 rtems_status_code mpc83xx_gtm_interrupt_enable( int timer)
0245 {
0246 rtems_interrupt_level level;
0247 MPC83XX_GTM_CHECK_INDEX( timer);
0248
0249 rtems_interrupt_disable( level);
0250 mpc83xx.gtm [GTM_MODULE(timer)].gt_tim_regs [GTM_HIGH(timer)].gtmdr [GTM_LOW(timer)] |= 0x0010;
0251 rtems_interrupt_enable( level);
0252
0253 return RTEMS_SUCCESSFUL;
0254 }
0255
0256 rtems_status_code mpc83xx_gtm_interrupt_disable( int timer)
0257 {
0258 rtems_interrupt_level level;
0259 MPC83XX_GTM_CHECK_INDEX( timer);
0260
0261 rtems_interrupt_disable( level);
0262 mpc83xx.gtm [GTM_MODULE(timer)].gt_tim_regs [GTM_HIGH(timer)].gtmdr [GTM_LOW(timer)] &= ~0x0010;
0263 rtems_interrupt_enable( level);
0264
0265 return RTEMS_SUCCESSFUL;
0266 }
0267
0268 rtems_status_code mpc83xx_gtm_interrupt_clear( int timer)
0269 {
0270 MPC83XX_GTM_CHECK_INDEX( timer);
0271
0272 mpc83xx.gtm [GTM_MODULE(timer)].gtevr [GTM_MODULE_TIMER(timer)] = 0x0002;
0273
0274 return RTEMS_SUCCESSFUL;
0275 }