File indexing completed on 2025-05-11 08:23:49
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #include <rtems.h>
0017 #include <rtems/timecounter.h>
0018 #include <bsp.h>
0019 #include <mcf5282/mcf5282.h>
0020
0021
0022
0023
0024
0025 #define IDLE_COUNTER __SRAMBASE.idle_counter
0026 #define FILTERED_IDLE __SRAMBASE.filtered_idle
0027 #define MAX_IDLE_COUNT __SRAMBASE.max_idle_count
0028 #define PITC_PER_TICK __SRAMBASE.pitc_per_tick
0029 #define NSEC_PER_PITC __SRAMBASE.nsec_per_pitc
0030 #define FILTER_SHIFT 6
0031
0032
0033
0034
0035 #define CLOCK_VECTOR (64+58)
0036
0037 static rtems_timecounter_simple uC5282_tc;
0038
0039 static uint32_t uC5282_tc_get(rtems_timecounter_simple *tc)
0040 {
0041 return MCF5282_PIT3_PCNTR;
0042 }
0043
0044 static bool uC5282_tc_is_pending(rtems_timecounter_simple *tc)
0045 {
0046 return (MCF5282_PIT3_PCSR & MCF5282_PIT_PCSR_PIF) != 0;
0047 }
0048
0049 static uint32_t uC5282_tc_get_timecount(struct timecounter *tc)
0050 {
0051 return rtems_timecounter_simple_downcounter_get(
0052 tc,
0053 uC5282_tc_get,
0054 uC5282_tc_is_pending
0055 );
0056 }
0057
0058 static void uC5282_tc_at_tick(rtems_timecounter_simple *tc)
0059 {
0060 unsigned idle = IDLE_COUNTER;
0061 IDLE_COUNTER = 0;
0062 if (idle > MAX_IDLE_COUNT)
0063 MAX_IDLE_COUNT = idle;
0064 FILTERED_IDLE = idle + FILTERED_IDLE - (FILTERED_IDLE>>FILTER_SHIFT);
0065 MCF5282_PIT3_PCSR |= MCF5282_PIT_PCSR_PIF;
0066 }
0067
0068 static void uC5282_tc_tick(void)
0069 {
0070 rtems_timecounter_simple_downcounter_tick(
0071 &uC5282_tc,
0072 uC5282_tc_get,
0073 uC5282_tc_at_tick
0074 );
0075 }
0076
0077
0078
0079
0080 #define Clock_driver_support_install_isr( _new ) \
0081 set_vector(_new, CLOCK_VECTOR, 1)
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093 #define Clock_driver_support_initialize_hardware() \
0094 do { \
0095 unsigned long long N; \
0096 int level; \
0097 int preScaleCode = 0; \
0098 N = bsp_get_CPU_clock_speed(); \
0099 N *= rtems_configuration_get_microseconds_per_tick(); \
0100 N /= 2*1000000; \
0101 while ( N > 0x10000 ) { \
0102 preScaleCode++; \
0103 N >>= 1; \
0104 } \
0105 PITC_PER_TICK = N; \
0106 N = 2000000000ULL << preScaleCode; \
0107 N /= bsp_get_CPU_clock_speed(); \
0108 NSEC_PER_PITC = N; \
0109 IDLE_COUNTER = 0; \
0110 FILTERED_IDLE = 0; \
0111 MAX_IDLE_COUNT = 0; \
0112 bsp_allocate_interrupt(PIT3_IRQ_LEVEL, PIT3_IRQ_PRIORITY); \
0113 MCF5282_INTC0_ICR58 = MCF5282_INTC_ICR_IL(PIT3_IRQ_LEVEL) | \
0114 MCF5282_INTC_ICR_IP(PIT3_IRQ_PRIORITY); \
0115 rtems_interrupt_disable( level ); \
0116 MCF5282_INTC0_IMRH &= ~MCF5282_INTC_IMRH_INT58; \
0117 MCF5282_PIT3_PCSR &= ~MCF5282_PIT_PCSR_EN; \
0118 rtems_interrupt_enable( level ); \
0119 MCF5282_PIT3_PCSR = MCF5282_PIT_PCSR_PRE(preScaleCode) | \
0120 MCF5282_PIT_PCSR_OVW | \
0121 MCF5282_PIT_PCSR_PIE | \
0122 MCF5282_PIT_PCSR_RLD; \
0123 MCF5282_PIT3_PMR = PITC_PER_TICK - 1; \
0124 MCF5282_PIT3_PCSR = MCF5282_PIT_PCSR_PRE(preScaleCode) | \
0125 MCF5282_PIT_PCSR_PIE | \
0126 MCF5282_PIT_PCSR_RLD | \
0127 MCF5282_PIT_PCSR_EN; \
0128 rtems_timecounter_simple_install( \
0129 &uC5282_tc, \
0130 bsp_get_CPU_clock_speed() >> (preScaleCode + 1), \
0131 PITC_PER_TICK, \
0132 uC5282_tc_get_timecount \
0133 ); \
0134 } while (0)
0135
0136
0137
0138
0139 void * bsp_idle_thread(uintptr_t ignored)
0140 {
0141
0142 for(;;)
0143 __asm__ volatile ("addq.l #1,%0"::"m"(IDLE_COUNTER));
0144 }
0145
0146 int bsp_cpu_load_percentage(void)
0147 {
0148 return MAX_IDLE_COUNT ?
0149 (100 - ((100 * (FILTERED_IDLE >> FILTER_SHIFT)) / MAX_IDLE_COUNT)) :
0150 0;
0151 }
0152
0153 #define Clock_driver_timecounter_tick(arg) uC5282_tc_tick()
0154
0155 #include "../../../shared/dev/clock/clockimpl.h"