Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:04

0001 /*
0002  *  LPC22XX/LPC21xx clock specific using the System Timer
0003  *
0004  *  Set the Time0 to generate click for RTEMS
0005  */
0006 
0007 /*
0008  *  Copyright (c) 2006 by Ray <rayx.cn@gmail.com>
0009  *
0010  *  The license and distribution terms for this file may be
0011  *  found in the file LICENSE in this distribution or at
0012  *  http://www.rtems.org/license/LICENSE.
0013  */
0014 
0015 #include <rtems.h>
0016 #include <bsp.h>
0017 #include <bsp/irq.h>
0018 #include <lpc22xx.h>
0019 #include <rtems/bspIo.h>  /* for printk */
0020 #include <rtems/timecounter.h>
0021 
0022 void Clock_isr(rtems_irq_hdl_param arg);
0023 static void clock_isr_on(const rtems_irq_connect_data *unused);
0024 static void clock_isr_off(const rtems_irq_connect_data *unused);
0025 static int clock_isr_is_on(const rtems_irq_connect_data *irq);
0026 
0027 static rtems_timecounter_simple lpc22xx_tc;
0028 
0029 static uint32_t lpc22xx_tc_get(rtems_timecounter_simple *tc)
0030 {
0031   return T0TC;
0032 }
0033 
0034 static bool lpc22xx_tc_is_pending(rtems_timecounter_simple *tc)
0035 {
0036   return (T0IR & 0x1) != 0;
0037 }
0038 
0039 static uint32_t lpc22xx_tc_get_timecount(struct timecounter *tc)
0040 {
0041   return rtems_timecounter_simple_upcounter_get(
0042     tc,
0043     lpc22xx_tc_get,
0044     lpc22xx_tc_is_pending
0045   );
0046 }
0047 
0048 /**
0049  * When we get the clock interrupt
0050  *    - clear the interrupt bit?
0051  *    - restart the timer?
0052  */
0053 static void lpc22xx_tc_at_tick(rtems_timecounter_simple *tc)
0054 {
0055   if (!(T0IR & 0x01))
0056     return;
0057   T0IR = 0x01;
0058   VICVectAddr = 0x00;
0059 }
0060 
0061 static void lpc22xx_tc_tick(void)
0062 {
0063   rtems_timecounter_simple_upcounter_tick(
0064     &lpc22xx_tc,
0065     lpc22xx_tc_get,
0066     lpc22xx_tc_at_tick
0067   );
0068 }
0069 
0070 /* Replace the first value with the clock's interrupt name. */
0071 rtems_irq_connect_data clock_isr_data = {
0072   .name   = LPC22xx_INTERRUPT_TIMER0,
0073   .hdl    = Clock_isr,
0074   .handle = NULL,
0075   .on     = clock_isr_on,
0076   .off    = clock_isr_off,
0077   .isOn   = clock_isr_is_on,
0078 };
0079 
0080 /* use the /shared/dev/clock/clockimpl.h code template */
0081 
0082 /**
0083  * Installs the clock ISR. You shouldn't need to change this.
0084  */
0085 #define Clock_driver_support_install_isr( _new ) \
0086   BSP_install_rtems_irq_handler(&clock_isr_data)
0087 
0088 /**
0089  * Initialize the hardware for the clock
0090  *   - Set the frequency
0091  *   - enable it
0092  *   - clear any pending interrupts
0093  *
0094  * Since you may want the clock always running, you can
0095  * enable interrupts here. If you do so, the clock_isr_on(),
0096  * clock_isr_off(), and clock_isr_is_on() functions can be
0097  * NOPs.
0098  * 
0099  * set timer to generate interrupt every
0100  * rtems_configuration_get_microseconds_per_tick()
0101  *     MR0/(LPC22xx_Fpclk/(PR0+1)) = 10/1000 = 0.01s
0102  */
0103 #define Clock_driver_support_initialize_hardware() \
0104   do { \
0105     /* disable and clear timer 0, set to  */ \
0106     T0TCR &= 0;                              \
0107     /* TC is incremented on every pclk.*/    \
0108     T0PC   = 0;                              \
0109     /* initialize the timer period and prescaler */  \
0110     T0MR0  = ((LPC22xx_Fpclk/1000 *          \
0111              rtems_configuration_get_microseconds_per_tick()) / 1000); \
0112     /* generate interrupt when T0MR0 match T0TC and Reset Timer Count*/ \
0113     T0MCR |= 0x03;          \
0114     /* No external match */ \
0115     T0EMR = 0;              \
0116     /* enable timer0 */     \
0117     T0TCR = 1;              \
0118     /* enable interrupt, skyeye will check this*/ \
0119     T0IR |= 0x01; \
0120     /* install timecounter */ \
0121     rtems_timecounter_simple_install( \
0122       &lpc22xx_tc, \
0123       LPC22xx_Fpclk, \
0124       T0MR0, \
0125       lpc22xx_tc_get_timecount \
0126     ); \
0127   } while (0)
0128 
0129 /**
0130  * Enables clock interrupt.
0131  *
0132  * If the interrupt is always on, this can be a NOP.
0133  */
0134 static void clock_isr_on(const rtems_irq_connect_data *unused)
0135 {
0136   T0IR&=0x01;
0137 }
0138 
0139 /**
0140  * Disables clock interrupts
0141  *
0142  * If the interrupt is always on, this can be a NOP.
0143  */
0144 static void clock_isr_off(const rtems_irq_connect_data *unused)
0145 {
0146   T0IR=0x00;
0147 }
0148 
0149 /**
0150  * Tests to see if clock interrupt is enabled, and returns 1 if so.
0151  * If interrupt is not enabled, returns 0.
0152  *
0153  * If the interrupt is always on, this always returns 1.
0154  */
0155 static int clock_isr_is_on(const rtems_irq_connect_data *irq)
0156 {
0157   return T0IR & 0x01;  /* MR0 mask */
0158 }
0159 
0160 #define Clock_driver_timecounter_tick(arg) lpc22xx_tc_tick()
0161 
0162 /* Make sure to include this, and only at the end of the file */
0163 #include "../../../shared/dev/clock/clockimpl.h"
0164