File indexing completed on 2025-05-11 08:23:03
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022 #include <stdio.h>
0023 #include <rtems/status-checks.h>
0024 #include <bsp.h>
0025 #include <bsp/irq.h>
0026 #include <bsp/io.h>
0027 #include <bsp/timer.h>
0028
0029
0030
0031
0032 const lpc176x_timer timers[ LPC176X_TIMER_COUNT ] =
0033 {
0034 {
0035 .device = (lpc176x_timer_device *) LPC176X_TMR0_BASE_ADDR,
0036 .module = LPC176X_MODULE_TIMER_0,
0037 .pinselcap = LPC176X_TIMER0_CAPTURE_PORTS,
0038 .pinselemat = LPC176X_TIMER0_EMATCH_PORTS,
0039 },
0040 {
0041 .device = (lpc176x_timer_device *) LPC176X_TMR1_BASE_ADDR,
0042 .module = LPC176X_MODULE_TIMER_1,
0043 .pinselcap = LPC176X_TIMER1_CAPTURE_PORTS,
0044 .pinselemat = LPC176X_TIMER1_EMATCH_PORTS,
0045 },
0046 {
0047 .device = (lpc176x_timer_device *) LPC176X_TMR2_BASE_ADDR,
0048 .module = LPC176X_MODULE_TIMER_2,
0049 .pinselcap = LPC176X_TIMER2_CAPTURE_PORTS,
0050 .pinselemat = LPC176X_TIMER2_EMATCH_PORTS,
0051 },
0052 {
0053 .device = (lpc176x_timer_device *) LPC176X_TMR3_BASE_ADDR,
0054 .module = LPC176X_MODULE_TIMER_3,
0055 .pinselcap = LPC176X_TIMER3_CAPTURE_PORTS,
0056 .pinselemat = LPC176X_TIMER3_EMATCH_PORTS,
0057 }
0058 };
0059
0060
0061
0062
0063 lpc176x_timer_functions functions_vector[ LPC176X_TIMER_COUNT ] =
0064 {
0065 {
0066 .funct_vector = NULL
0067 },
0068 {
0069 .funct_vector = NULL
0070 },
0071 {
0072 .funct_vector = NULL
0073 },
0074 {
0075 .funct_vector = NULL
0076 }
0077 };
0078
0079
0080
0081
0082
0083
0084
0085
0086 static inline void lpc176x_call_desired_isr(
0087 const lpc176x_timer_number number,
0088 const lpc176x_isr_function interruptfunction
0089 )
0090 {
0091 if ( ( *functions_vector[ number ].funct_vector )[ interruptfunction ] !=
0092 NULL ) {
0093 ( *functions_vector[ number ].funct_vector )[ interruptfunction ]( number );
0094 }
0095
0096
0097
0098 }
0099
0100
0101
0102
0103
0104
0105
0106
0107 static inline bool lpc176x_timer_interrupt_is_pending(
0108 const lpc176x_timer_number tnumber,
0109 const lpc176x_isr_function function
0110 )
0111 {
0112 assert( ( tnumber < LPC176X_TIMER_COUNT )
0113 && ( function < LPC176X_ISR_FUNCTIONS_COUNT ) );
0114
0115 return ( timers[ tnumber ].device->IR &
0116 LPC176X_TIMER_INTERRUPT_SOURCE_BIT( function ) );
0117 }
0118
0119
0120
0121
0122
0123
0124
0125 static inline void lpc176x_timer_reset_interrupt(
0126 const lpc176x_timer_number tnumber,
0127 const lpc176x_isr_function function
0128 )
0129 {
0130 assert( ( tnumber < LPC176X_TIMER_COUNT )
0131 && ( function < LPC176X_ISR_FUNCTIONS_COUNT ) );
0132 timers[ tnumber ].device->IR =
0133 LPC176X_TIMER_INTERRUPT_SOURCE_BIT( function );
0134 }
0135
0136 inline rtems_status_code lpc176x_timer_reset(
0137 const lpc176x_timer_number tnumber )
0138 {
0139 rtems_status_code status_code = RTEMS_INVALID_NUMBER;
0140
0141 if ( tnumber < LPC176X_TIMER_COUNT ) {
0142 timers[ tnumber ].device->TCR = LPC176X_TIMER_RESET;
0143 status_code = RTEMS_SUCCESSFUL;
0144 }
0145
0146
0147
0148
0149 return status_code;
0150 }
0151
0152 inline rtems_status_code lpc176x_timer_set_mode(
0153 const lpc176x_timer_number tnumber,
0154 const lpc176x_timer_mode mode
0155 )
0156 {
0157 rtems_status_code status_code = RTEMS_INVALID_NUMBER;
0158
0159 if ( tnumber < LPC176X_TIMER_COUNT ) {
0160 timers[ tnumber ].device->CTCR = mode;
0161 status_code = RTEMS_SUCCESSFUL;
0162 }
0163
0164
0165
0166
0167 return status_code;
0168 }
0169
0170 inline rtems_status_code lpc176x_timer_start(
0171 const lpc176x_timer_number tnumber )
0172 {
0173 rtems_status_code status_code = RTEMS_INVALID_NUMBER;
0174
0175 if ( tnumber < LPC176X_TIMER_COUNT ) {
0176 timers[ tnumber ].device->TCR = LPC176X_TIMER_START;
0177 status_code = RTEMS_SUCCESSFUL;
0178 }
0179
0180
0181
0182
0183 return status_code;
0184 }
0185
0186 inline rtems_status_code lpc176x_timer_is_started(
0187 const lpc176x_timer_number tnumber,
0188 bool *is_started
0189 )
0190 {
0191 rtems_status_code status_code = RTEMS_INVALID_NUMBER;
0192
0193 if ( tnumber < LPC176X_TIMER_COUNT ) {
0194 *is_started = ( timers[ tnumber ].device->TCR & LPC176X_TIMER_START ) ==
0195 LPC176X_TIMER_START;
0196 status_code = RTEMS_SUCCESSFUL;
0197 }
0198
0199
0200
0201
0202 return status_code;
0203 }
0204
0205 inline rtems_status_code lpc176x_timer_set_resolution(
0206 const lpc176x_timer_number tnumber,
0207 const lpc176x_microseconds resolution
0208 )
0209 {
0210 rtems_status_code status_code = RTEMS_INVALID_NUMBER;
0211
0212 if ( tnumber < LPC176X_TIMER_COUNT ) {
0213 timers[ tnumber ].device->PR = ( LPC176X_CCLK /
0214 LPC176X_TIMER_PRESCALER_DIVISOR ) *
0215 resolution;
0216 status_code = RTEMS_SUCCESSFUL;
0217 }
0218
0219
0220
0221
0222 return status_code;
0223 }
0224
0225 rtems_status_code lpc176x_timer_match_config(
0226 const lpc176x_timer_number tnumber,
0227 const lpc176x_match_port match_port,
0228 const lpc176x_match_function function,
0229 const uint32_t match_value
0230 )
0231 {
0232 rtems_status_code status_code = RTEMS_INVALID_NUMBER;
0233
0234 if ( ( tnumber < LPC176X_TIMER_COUNT )
0235 && ( match_port < LPC176X_EMATCH_PORTS_COUNT )
0236 && ( function < LPC176X_TIMER_MATCH_FUNCTION_COUNT ) ) {
0237 timers[ tnumber ].device->MCR =
0238 LPC176X_SET_MCR( timers[ tnumber ].device->MCR,
0239 match_port, function );
0240 timers[ tnumber ].device->MR[ match_port ] = match_value;
0241 status_code = RTEMS_SUCCESSFUL;
0242 }
0243
0244
0245
0246
0247 return status_code;
0248 }
0249
0250 inline rtems_status_code lpc176x_timer_capture_config(
0251 const lpc176x_timer_number tnumber,
0252 const lpc176x_capture_port capture_port,
0253 const lpc176x_capture_function function
0254 )
0255 {
0256 rtems_status_code status_code = RTEMS_INVALID_NUMBER;
0257
0258 if ( ( tnumber < LPC176X_TIMER_COUNT )
0259 && ( capture_port < LPC176X_CAPTURE_PORTS_COUNT )
0260 && ( function < LPC176X_TIMER_CAPTURE_FUNCTION_COUNT ) ) {
0261 timers[ tnumber ].device->CCR =
0262 LPC176X_SET_CCR( timers[ tnumber ].device->CCR,
0263 capture_port, function );
0264 lpc176x_pin_select( timers[ tnumber ].pinselcap[ capture_port ],
0265 LPC176X_PIN_FUNCTION_11 );
0266 }
0267
0268
0269
0270
0271 return status_code;
0272 }
0273
0274 inline rtems_status_code lpc176x_timer_external_match_config(
0275 const lpc176x_timer_number number,
0276 const lpc176x_match_port match_port,
0277 const lpc176x_ext_match_function function
0278 )
0279 {
0280 rtems_status_code status_code = RTEMS_INVALID_NUMBER;
0281
0282 if ( ( number < LPC176X_TIMER_COUNT )
0283 && ( match_port < LPC176X_EMATCH_PORTS_COUNT ) ) {
0284 timers[ number ].device->EMR =
0285 LPC176X_SET_EMR( timers[ number ].device->EMR,
0286 match_port, function );
0287 lpc176x_pin_select( timers[ number ].pinselemat[ match_port ],
0288 LPC176X_PIN_FUNCTION_11 );
0289 status_code = RTEMS_SUCCESSFUL;
0290 }
0291
0292
0293
0294
0295 return status_code;
0296 }
0297
0298 inline uint32_t lpc176x_timer_get_capvalue(
0299 const lpc176x_timer_number number,
0300 const lpc176x_capture_port capture_port
0301 )
0302 {
0303 assert( ( number < LPC176X_TIMER_COUNT )
0304 && ( capture_port < LPC176X_CAPTURE_PORTS_COUNT ) );
0305
0306 return timers[ number ].device->CR[ capture_port ];
0307 }
0308
0309 inline uint32_t lpc176x_timer_get_timer_value(
0310 const lpc176x_timer_number tnumber )
0311 {
0312 assert( tnumber < LPC176X_TIMER_COUNT );
0313
0314 return timers[ tnumber ].device->TC;
0315 }
0316
0317 inline rtems_status_code lpc176x_timer_set_timer_value(
0318 const lpc176x_timer_number tnumber,
0319 const uint32_t timer_value
0320 )
0321 {
0322 rtems_status_code status_code = RTEMS_INVALID_NUMBER;
0323
0324 if ( tnumber < LPC176X_TIMER_COUNT ) {
0325 timers[ tnumber ].device->TC = timer_value;
0326 status_code = RTEMS_SUCCESSFUL;
0327 }
0328
0329
0330
0331
0332 return status_code;
0333 }
0334
0335 void lpc176x_timer_isr( void *arg )
0336 {
0337 const lpc176x_timer_number tnumber = (lpc176x_timer_number) arg;
0338
0339 if ( tnumber < LPC176X_TIMER_COUNT ) {
0340 lpc176x_isr_function i;
0341
0342 for ( i = 0; i < LPC176X_ISR_FUNCTIONS_COUNT; ++i ) {
0343 if ( lpc176x_timer_interrupt_is_pending( tnumber, i ) ) {
0344 lpc176x_call_desired_isr( tnumber, i );
0345 lpc176x_timer_reset_interrupt( tnumber, i );
0346 }
0347
0348
0349
0350 }
0351 }
0352
0353
0354
0355 }
0356
0357 rtems_status_code lpc176x_timer_init( const lpc176x_timer_number tnumber )
0358 {
0359 rtems_status_code status_code = RTEMS_INVALID_NUMBER;
0360
0361 if ( tnumber < LPC176X_TIMER_COUNT ) {
0362 status_code = lpc176x_module_enable( timers[ tnumber ].module,
0363 LPC176X_MODULE_PCLK_DEFAULT );
0364 RTEMS_CHECK_SC( status_code, "Enabling the timer module." );
0365
0366 status_code = lpc176x_timer_reset( tnumber );
0367 status_code = lpc176x_timer_set_mode( tnumber,
0368 LPC176X_TIMER_MODE_TIMER );
0369 status_code = lpc176x_timer_set_resolution( tnumber,
0370 LPC176X_TIMER_DEFAULT_RESOLUTION );
0371
0372 timers[ tnumber ].device->MCR = LPC176X_TIMER_CLEAR_FUNCTION;
0373 timers[ tnumber ].device->CCR = LPC176X_TIMER_CLEAR_FUNCTION;
0374 timers[ tnumber ].device->EMR = LPC176X_TIMER_CLEAR_FUNCTION;
0375 }
0376
0377
0378
0379
0380 return status_code;
0381 }
0382
0383 rtems_status_code lpc176x_timer_init_with_interrupt(
0384 const lpc176x_timer_number tnumber,
0385 const lpc176x_isr_funct_vector *const vector
0386 )
0387 {
0388 rtems_status_code status_code = RTEMS_INVALID_NUMBER;
0389
0390 char isrname[ LPC176X_ISR_NAME_STRING_SIZE ];
0391
0392 snprintf( isrname, LPC176X_ISR_NAME_STRING_SIZE, "TimerIsr%d", tnumber );
0393
0394 if ( tnumber < LPC176X_TIMER_COUNT && vector != NULL ) {
0395 functions_vector[ tnumber ].funct_vector = vector;
0396
0397 status_code = lpc176x_timer_init( tnumber );
0398 status_code = rtems_interrupt_handler_install(
0399 LPC176X_TIMER_VECTOR_NUMBER( tnumber ),
0400 isrname,
0401 RTEMS_INTERRUPT_UNIQUE,
0402 lpc176x_timer_isr,
0403 (void *) tnumber );
0404 }
0405
0406 return status_code;
0407 }