[3aac2db] | 1 | /* |
---|
| 2 | * Use the last periodic interval timer (PIT2) as the system clock. |
---|
| 3 | */ |
---|
| 4 | |
---|
| 5 | #include <rtems.h> |
---|
[75acd9e] | 6 | #include <rtems/timecounter.h> |
---|
[3aac2db] | 7 | #include <bsp.h> |
---|
| 8 | |
---|
| 9 | /* |
---|
| 10 | * Use INTC0 base |
---|
| 11 | */ |
---|
| 12 | #define CLOCK_VECTOR (64+56) |
---|
| 13 | |
---|
[75acd9e] | 14 | static rtems_timecounter_simple mcf52235_tc; |
---|
[3aac2db] | 15 | |
---|
[75acd9e] | 16 | static uint32_t mcf52235_tc_get(rtems_timecounter_simple *tc) |
---|
[3aac2db] | 17 | { |
---|
[75acd9e] | 18 | return MCF_PIT1_PCNTR; |
---|
| 19 | } |
---|
[9374e9b0] | 20 | |
---|
[75acd9e] | 21 | static bool mcf52235_tc_is_pending(rtems_timecounter_simple *tc) |
---|
| 22 | { |
---|
| 23 | return (MCF_PIT1_PCSR & MCF_PIT_PCSR_PIF) != 0; |
---|
[3aac2db] | 24 | } |
---|
| 25 | |
---|
[75acd9e] | 26 | static uint32_t mcf52235_tc_get_timecount(struct timecounter *tc) |
---|
| 27 | { |
---|
| 28 | return rtems_timecounter_simple_downcounter_get( |
---|
| 29 | tc, |
---|
| 30 | mcf52235_tc_get, |
---|
| 31 | mcf52235_tc_is_pending |
---|
| 32 | ); |
---|
| 33 | } |
---|
| 34 | |
---|
[76ac1ee3] | 35 | static void mcf52235_tc_at_tick(rtems_timecounter_simple *tc) |
---|
[75acd9e] | 36 | { |
---|
[76ac1ee3] | 37 | MCF_PIT1_PCSR |= MCF_PIT_PCSR_PIF; |
---|
[75acd9e] | 38 | } |
---|
[3aac2db] | 39 | |
---|
[76ac1ee3] | 40 | static void mcf52235_tc_tick(void) |
---|
| 41 | { |
---|
| 42 | rtems_timecounter_simple_downcounter_tick( |
---|
| 43 | &mcf52235_tc, |
---|
| 44 | mcf52235_tc_get, |
---|
| 45 | mcf52235_tc_at_tick |
---|
| 46 | ); |
---|
| 47 | } |
---|
[3aac2db] | 48 | |
---|
| 49 | /* |
---|
| 50 | * Attach clock interrupt handler |
---|
| 51 | */ |
---|
[f3b29236] | 52 | #define Clock_driver_support_install_isr( _new ) \ |
---|
| 53 | set_vector(_new, CLOCK_VECTOR, 1) |
---|
[3aac2db] | 54 | |
---|
| 55 | /* |
---|
| 56 | * Set up the clock hardware |
---|
| 57 | * |
---|
[5e86086] | 58 | * We need to have 1 interrupt every rtems_configuration_get_microseconds_per_tick() |
---|
[3aac2db] | 59 | */ |
---|
[a840853] | 60 | static void Clock_driver_support_initialize_hardware(void) |
---|
[3aac2db] | 61 | { |
---|
[9374e9b0] | 62 | int level; |
---|
| 63 | uint32_t pmr; |
---|
| 64 | uint32_t preScaleCode = 0; |
---|
| 65 | uint32_t clk = bsp_get_CPU_clock_speed() >> 1; |
---|
[5e86086] | 66 | uint32_t tps = 1000000 / rtems_configuration_get_microseconds_per_tick(); |
---|
[9374e9b0] | 67 | |
---|
| 68 | while (preScaleCode < 15) { |
---|
| 69 | pmr = (clk >> preScaleCode) / tps; |
---|
| 70 | if (pmr < (1 << 15)) |
---|
| 71 | break; |
---|
| 72 | preScaleCode++; |
---|
| 73 | } |
---|
[3aac2db] | 74 | |
---|
[9374e9b0] | 75 | MCF_INTC0_ICR56 = MCF_INTC_ICR_IL(PIT3_IRQ_LEVEL) | |
---|
| 76 | MCF_INTC_ICR_IP(PIT3_IRQ_PRIORITY); |
---|
| 77 | rtems_interrupt_disable(level); |
---|
| 78 | MCF_INTC0_IMRH &= ~MCF_INTC_IMRH_MASK56; |
---|
| 79 | MCF_PIT1_PCSR &= ~MCF_PIT_PCSR_EN; |
---|
| 80 | rtems_interrupt_enable(level); |
---|
[3aac2db] | 81 | |
---|
[9374e9b0] | 82 | MCF_PIT1_PCSR = MCF_PIT_PCSR_PRE(preScaleCode) | |
---|
| 83 | MCF_PIT_PCSR_OVW | MCF_PIT_PCSR_PIE | MCF_PIT_PCSR_RLD; |
---|
| 84 | MCF_PIT1_PMR = pmr; |
---|
| 85 | MCF_PIT1_PCSR = MCF_PIT_PCSR_PRE(preScaleCode) | |
---|
| 86 | MCF_PIT_PCSR_PIE | MCF_PIT_PCSR_RLD | MCF_PIT_PCSR_EN; |
---|
[75acd9e] | 87 | |
---|
| 88 | rtems_timecounter_simple_install( |
---|
| 89 | &mcf52235_tc, |
---|
| 90 | clk >> preScaleCode, |
---|
| 91 | pmr, |
---|
| 92 | mcf52235_tc_get_timecount |
---|
| 93 | ); |
---|
[3aac2db] | 94 | } |
---|
| 95 | |
---|
[1eed6f8] | 96 | #define Clock_driver_timecounter_tick(arg) mcf52235_tc_tick() |
---|
[75acd9e] | 97 | |
---|
[7632906] | 98 | #include "../../../shared/dev/clock/clockimpl.h" |
---|