[3aac2db] | 1 | /* |
---|
| 2 | * Use the last periodic interval timer (PIT2) as the system clock. |
---|
| 3 | * |
---|
| 4 | * $Id$ |
---|
| 5 | */ |
---|
| 6 | |
---|
| 7 | #include <rtems.h> |
---|
| 8 | #include <bsp.h> |
---|
| 9 | |
---|
| 10 | /* |
---|
| 11 | * Use INTC0 base |
---|
| 12 | */ |
---|
| 13 | #define CLOCK_VECTOR (64+56) |
---|
| 14 | |
---|
| 15 | static uint32_t s_pcntrAtTick = 0; |
---|
| 16 | static uint32_t s_nanoScale = 0; |
---|
| 17 | |
---|
| 18 | /* |
---|
| 19 | * Provide nanosecond extension |
---|
[9374e9b0] | 20 | * Interrupts are disabled when this is called |
---|
[3aac2db] | 21 | */ |
---|
| 22 | static uint32_t bsp_clock_nanoseconds_since_last_tick(void) |
---|
| 23 | { |
---|
[9374e9b0] | 24 | uint32_t i; |
---|
| 25 | |
---|
| 26 | if (MCF_PIT1_PCSR & MCF_PIT_PCSR_PIF) { |
---|
| 27 | i = s_pcntrAtTick + (MCF_PIT1_PMR - MCF_PIT1_PCNTR); |
---|
| 28 | } |
---|
| 29 | else { |
---|
| 30 | i = s_pcntrAtTick - MCF_PIT1_PCNTR; |
---|
| 31 | } |
---|
| 32 | return i * s_nanoScale; |
---|
[3aac2db] | 33 | } |
---|
| 34 | |
---|
| 35 | #define Clock_driver_nanoseconds_since_last_tick bsp_clock_nanoseconds_since_last_tick |
---|
| 36 | |
---|
| 37 | /* |
---|
| 38 | * Periodic interval timer interrupt handler |
---|
| 39 | */ |
---|
| 40 | #define Clock_driver_support_at_tick() \ |
---|
| 41 | do { \ |
---|
| 42 | s_pcntrAtTick = MCF_PIT1_PCNTR; \ |
---|
| 43 | MCF_PIT1_PCSR |= MCF_PIT_PCSR_PIF; \ |
---|
| 44 | } while (0) \ |
---|
| 45 | |
---|
| 46 | /* |
---|
| 47 | * Attach clock interrupt handler |
---|
| 48 | */ |
---|
| 49 | #define Clock_driver_support_install_isr( _new, _old ) \ |
---|
| 50 | do { \ |
---|
| 51 | _old = (rtems_isr_entry)set_vector(_new, CLOCK_VECTOR, 1); \ |
---|
| 52 | } while(0) |
---|
| 53 | |
---|
| 54 | /* |
---|
| 55 | * Turn off the clock |
---|
| 56 | */ |
---|
[9374e9b0] | 57 | static void Clock_driver_support_shutdown_hardware() |
---|
[3aac2db] | 58 | { |
---|
[9374e9b0] | 59 | MCF_PIT1_PCSR &= ~MCF_PIT_PCSR_EN; |
---|
[3aac2db] | 60 | } |
---|
| 61 | |
---|
| 62 | /* |
---|
| 63 | * Set up the clock hardware |
---|
| 64 | * |
---|
| 65 | * We need to have 1 interrupt every BSP_Configuration.microseconds_per_tick |
---|
| 66 | */ |
---|
| 67 | static void Clock_driver_support_initialize_hardware() |
---|
| 68 | { |
---|
[9374e9b0] | 69 | int level; |
---|
| 70 | uint32_t pmr; |
---|
| 71 | uint32_t preScaleCode = 0; |
---|
| 72 | uint32_t clk = bsp_get_CPU_clock_speed() >> 1; |
---|
| 73 | uint32_t tps = 1000000 / Configuration.microseconds_per_tick; |
---|
| 74 | |
---|
| 75 | while (preScaleCode < 15) { |
---|
| 76 | pmr = (clk >> preScaleCode) / tps; |
---|
| 77 | if (pmr < (1 << 15)) |
---|
| 78 | break; |
---|
| 79 | preScaleCode++; |
---|
| 80 | } |
---|
| 81 | s_nanoScale = 1000000000 / (clk >> preScaleCode); |
---|
[3aac2db] | 82 | |
---|
[9374e9b0] | 83 | MCF_INTC0_ICR56 = MCF_INTC_ICR_IL(PIT3_IRQ_LEVEL) | |
---|
| 84 | MCF_INTC_ICR_IP(PIT3_IRQ_PRIORITY); |
---|
| 85 | rtems_interrupt_disable(level); |
---|
| 86 | MCF_INTC0_IMRH &= ~MCF_INTC_IMRH_MASK56; |
---|
| 87 | MCF_PIT1_PCSR &= ~MCF_PIT_PCSR_EN; |
---|
| 88 | rtems_interrupt_enable(level); |
---|
[3aac2db] | 89 | |
---|
[9374e9b0] | 90 | MCF_PIT1_PCSR = MCF_PIT_PCSR_PRE(preScaleCode) | |
---|
| 91 | MCF_PIT_PCSR_OVW | MCF_PIT_PCSR_PIE | MCF_PIT_PCSR_RLD; |
---|
| 92 | MCF_PIT1_PMR = pmr; |
---|
| 93 | MCF_PIT1_PCSR = MCF_PIT_PCSR_PRE(preScaleCode) | |
---|
| 94 | MCF_PIT_PCSR_PIE | MCF_PIT_PCSR_RLD | MCF_PIT_PCSR_EN; |
---|
| 95 | s_pcntrAtTick = MCF_PIT1_PCNTR; |
---|
[3aac2db] | 96 | } |
---|
| 97 | |
---|
| 98 | #include "../../../shared/clockdrv_shell.c" |
---|