Changeset 9fab016 in rtems
- Timestamp:
- 10/12/14 20:37:34 (9 years ago)
- Branches:
- 4.11, 5, master
- Children:
- e827199
- Parents:
- 4172cf1b
- git-author:
- Joel Sherrill <joel.sherrill@…> (10/12/14 20:37:34)
- git-committer:
- Joel Sherrill <joel.sherrill@…> (10/13/14 15:33:34)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
c/src/lib/libcpu/sh/sh7750/clock/ckinit.c
r4172cf1b r9fab016 1 1 /* 2 2 * This file contains the generic RTEMS clock driver the Hitachi SH 7750 3 * 3 */ 4 5 /* 4 6 * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia 5 7 * Author: Victor V. Vengerov <vvv@oktet.ru> … … 17 19 #include <stdlib.h> 18 20 19 #include <rtems/ libio.h>21 #include <rtems/clockdrv.h> 20 22 #include <rtems/score/sh_io.h> 21 23 #include <rtems/score/sh.h> … … 37 39 * driver. 38 40 */ 39 40 41 #define CLOCK_VECTOR SH7750_EVT_TO_NUM(SH7750_EVT_TUNI0) 41 42 … … 44 45 * number of clock ticks since the driver was initialized. 45 46 */ 46 47 47 volatile uint32_t Clock_driver_ticks; 48 48 49 static void Clock_exit( void );50 49 static rtems_isr Clock_isr( rtems_vector_number vector ); 51 50 52 51 /* 53 * These are set by clock driver during its init54 */55 rtems_device_major_number rtems_clock_major = ~0;56 rtems_device_minor_number rtems_clock_minor;57 58 /*59 52 * The previous ISR on this clock tick interrupt vector. 60 53 */ 61 62 54 rtems_isr_entry Old_ticker; 63 55 … … 66 58 */ 67 59 68 /* Clock_isr -- 69 * Clock interrupt handling routine. 70 * 71 * PARAMETERS: 72 * vector - interrupt vector number 73 * 74 * RETURNS: 75 * none 76 */ 77 rtems_isr 78 Clock_isr(rtems_vector_number vector) 79 { 80 uint16_t tcr; 81 82 /* reset the timer underflow flag */ 83 tcr = read16(SH7750_TCR0); 84 write16(tcr & ~SH7750_TCR_UNF, SH7750_TCR0); 85 86 /* Increment the clock interrupt counter */ 87 Clock_driver_ticks++ ; 88 89 /* Invoke rtems clock service routine */ 60 /* 61 * Clock_isr 62 * 63 * Clock interrupt handling routine. 64 */ 65 static rtems_isr Clock_isr(rtems_vector_number vector) 66 { 67 uint16_t tcr; 68 69 /* reset the timer underflow flag */ 70 tcr = read16(SH7750_TCR0); 71 write16(tcr & ~SH7750_TCR_UNF, SH7750_TCR0); 72 73 /* Increment the clock interrupt counter */ 74 Clock_driver_ticks++ ; 75 76 /* Invoke rtems clock service routine */ 90 77 rtems_clock_tick(); 91 78 } 92 79 93 /* Install_clock -- 94 * Install a clock tick handler and reprograms the chip. This 95 * is used to initially establish the clock tick. 96 * 97 * PARAMETERS: 98 * clock_isr - Clock interrupt stay routine 99 * 100 * RETURNS: 101 * none 80 /* 81 * Install_clock 82 * 83 * Install a clock tick handler and reprograms the chip. This 84 * is used to initially establish the clock tick. 102 85 * 103 86 * SIDE EFFECTS: 104 87 * Establish clock interrupt handler, configure Timer 0 hardware 105 88 */ 106 void 107 Install_clock(rtems_isr_entry clock_isr) 108 { 109 int cpudiv = 1; /* CPU frequency divider */ 110 int tidiv = 1; /* Timer input frequency divider */ 111 uint32_t timer_divider; /* Calculated Timer Divider value */ 112 uint8_t temp8; 113 uint16_t temp16; 114 115 /* 116 * Initialize the clock tick device driver variables 117 */ 118 119 Clock_driver_ticks = 0; 120 121 /* Get CPU frequency divider from clock unit */ 122 switch (read16(SH7750_FRQCR) & SH7750_FRQCR_IFC) 123 { 124 case SH7750_FRQCR_IFCDIV1: 125 cpudiv = 1; 126 break; 127 128 case SH7750_FRQCR_IFCDIV2: 129 cpudiv = 2; 130 break; 131 132 case SH7750_FRQCR_IFCDIV3: 133 cpudiv = 3; 134 break; 135 136 case SH7750_FRQCR_IFCDIV4: 137 cpudiv = 4; 138 break; 139 140 case SH7750_FRQCR_IFCDIV6: 141 cpudiv = 6; 142 break; 143 144 case SH7750_FRQCR_IFCDIV8: 145 cpudiv = 8; 146 break; 147 148 default: 149 rtems_fatal_error_occurred( RTEMS_NOT_CONFIGURED); 150 } 151 152 /* Get peripheral module frequency divider from clock unit */ 153 switch (read16(SH7750_FRQCR) & SH7750_FRQCR_PFC) 154 { 155 case SH7750_FRQCR_PFCDIV2: 156 tidiv = 2 * CLOCK_PRESCALER; 157 break; 158 159 case SH7750_FRQCR_PFCDIV3: 160 tidiv = 3 * CLOCK_PRESCALER; 161 break; 162 163 case SH7750_FRQCR_PFCDIV4: 164 tidiv = 4 * CLOCK_PRESCALER; 165 break; 166 167 case SH7750_FRQCR_PFCDIV6: 168 tidiv = 6 * CLOCK_PRESCALER; 169 break; 170 171 case SH7750_FRQCR_PFCDIV8: 172 tidiv = 8 * CLOCK_PRESCALER; 173 break; 174 175 default: 176 rtems_fatal_error_occurred( RTEMS_NOT_CONFIGURED); 177 } 178 timer_divider = 179 (bsp_clicks_per_second * cpudiv / (tidiv*1000000)) * 180 rtems_configuration_get_microseconds_per_tick(); 181 182 /* 183 * Hardware specific initialization 184 */ 185 186 /* Stop the Timer 0 */ 187 temp8 = read8(SH7750_TSTR); 188 temp8 &= ~SH7750_TSTR_STR0; 189 write8(temp8, SH7750_TSTR); 190 191 /* Establish interrupt handler */ 192 rtems_interrupt_catch( Clock_isr, CLOCK_VECTOR, &Old_ticker ); 193 194 /* Reset counter */ 195 write32(timer_divider, SH7750_TCNT0); 196 197 /* Load divider */ 198 write32(timer_divider, SH7750_TCOR0); 199 200 write16( 201 SH7750_TCR_UNIE | /* Enable Underflow Interrupt */ 202 SH7750_TCR_CKEG_RAISE | /* Count on rising edge */ 203 TCR0_TPSC, /* Timer prescaler ratio */ 204 SH7750_TCR0); 205 206 /* Set clock interrupt priority */ 207 temp16 = read16(SH7750_IPRA); 208 temp16 = (temp16 & ~SH7750_IPRA_TMU0) | (CLOCKPRIO << SH7750_IPRA_TMU0_S); 209 write16(temp16, SH7750_IPRA); 210 211 /* Start the Timer 0 */ 212 temp8 = read8(SH7750_TSTR); 213 temp8 |= SH7750_TSTR_STR0; 214 write8(temp8, SH7750_TSTR); 215 216 /* 217 * Schedule the clock cleanup routine to execute if the application exits. 218 */ 219 220 atexit( Clock_exit ); 221 } 222 223 /* Clock_exit -- 224 * Clean up before the application exits 225 * 226 * PARAMETERS: 227 * none 228 * 229 * RETURNS: 230 * none 89 static void Install_clock(rtems_isr_entry clock_isr) 90 { 91 int cpudiv = 1; /* CPU frequency divider */ 92 int tidiv = 1; /* Timer input frequency divider */ 93 uint32_t timer_divider; /* Calculated Timer Divider value */ 94 uint8_t temp8; 95 uint16_t temp16; 96 97 /* 98 * Initialize the clock tick device driver variables 99 */ 100 101 Clock_driver_ticks = 0; 102 103 /* Get CPU frequency divider from clock unit */ 104 switch (read16(SH7750_FRQCR) & SH7750_FRQCR_IFC) { 105 case SH7750_FRQCR_IFCDIV1: 106 cpudiv = 1; 107 break; 108 109 case SH7750_FRQCR_IFCDIV2: 110 cpudiv = 2; 111 break; 112 113 case SH7750_FRQCR_IFCDIV3: 114 cpudiv = 3; 115 break; 116 117 case SH7750_FRQCR_IFCDIV4: 118 cpudiv = 4; 119 break; 120 121 case SH7750_FRQCR_IFCDIV6: 122 cpudiv = 6; 123 break; 124 125 case SH7750_FRQCR_IFCDIV8: 126 cpudiv = 8; 127 break; 128 129 default: 130 rtems_fatal_error_occurred( RTEMS_NOT_CONFIGURED); 131 } 132 133 /* Get peripheral module frequency divider from clock unit */ 134 switch (read16(SH7750_FRQCR) & SH7750_FRQCR_PFC) { 135 case SH7750_FRQCR_PFCDIV2: 136 tidiv = 2 * CLOCK_PRESCALER; 137 break; 138 139 case SH7750_FRQCR_PFCDIV3: 140 tidiv = 3 * CLOCK_PRESCALER; 141 break; 142 143 case SH7750_FRQCR_PFCDIV4: 144 tidiv = 4 * CLOCK_PRESCALER; 145 break; 146 147 case SH7750_FRQCR_PFCDIV6: 148 tidiv = 6 * CLOCK_PRESCALER; 149 break; 150 151 case SH7750_FRQCR_PFCDIV8: 152 tidiv = 8 * CLOCK_PRESCALER; 153 break; 154 155 default: 156 rtems_fatal_error_occurred( RTEMS_NOT_CONFIGURED); 157 } 158 timer_divider = 159 (bsp_clicks_per_second * cpudiv / (tidiv*1000000)) * 160 rtems_configuration_get_microseconds_per_tick(); 161 162 /* 163 * Hardware specific initialization 164 */ 165 166 /* Stop the Timer 0 */ 167 temp8 = read8(SH7750_TSTR); 168 temp8 &= ~SH7750_TSTR_STR0; 169 write8(temp8, SH7750_TSTR); 170 171 /* Establish interrupt handler */ 172 rtems_interrupt_catch( Clock_isr, CLOCK_VECTOR, &Old_ticker ); 173 174 /* Reset counter */ 175 write32(timer_divider, SH7750_TCNT0); 176 177 /* Load divider */ 178 write32(timer_divider, SH7750_TCOR0); 179 180 write16( 181 SH7750_TCR_UNIE | /* Enable Underflow Interrupt */ 182 SH7750_TCR_CKEG_RAISE | /* Count on rising edge */ 183 TCR0_TPSC, /* Timer prescaler ratio */ 184 SH7750_TCR0); 185 186 /* Set clock interrupt priority */ 187 temp16 = read16(SH7750_IPRA); 188 temp16 = (temp16 & ~SH7750_IPRA_TMU0) | (CLOCKPRIO << SH7750_IPRA_TMU0_S); 189 write16(temp16, SH7750_IPRA); 190 191 /* Start the Timer 0 */ 192 temp8 = read8(SH7750_TSTR); 193 temp8 |= SH7750_TSTR_STR0; 194 write8(temp8, SH7750_TSTR); 195 196 /* 197 * Schedule the clock cleanup routine to execute if the application exits. 198 */ 199 atexit( Clock_exit ); 200 } 201 202 /* 203 * Clock_exit 204 * 205 * Clean up before the application exits 231 206 * 232 207 * SIDE EFFECTS: … … 236 211 Clock_exit(void) 237 212 { 238 239 240 241 242 243 244 245 246 247 248 249 250 213 uint8_t temp8 = 0; 214 uint16_t temp16 = 0; 215 216 /* turn off the timer interrupts */ 217 /* Stop the Timer 0 */ 218 temp8 = read8(SH7750_TSTR); 219 temp8 &= ~SH7750_TSTR_STR0; 220 write8(temp8, SH7750_TSTR); 221 222 /* Lower timer interrupt priority to 0 */ 223 temp16 = read16(SH7750_IPRA); 224 temp16 = (temp16 & ~SH7750_IPRA_TMU0) | (0 << SH7750_IPRA_TMU0_S); 225 write16(temp16, SH7750_IPRA); 251 226 252 227 /* old vector shall not be installed */ 253 228 } 254 229 255 /* Clock_initialize -- 256 * Device driver entry point for clock tick driver initialization. 257 * 258 * PARAMETERS: 259 * major - clock major device number 260 * minor - clock minor device number 261 * pargp - driver initialize primitive argument, not used 262 * 263 * RETURNS: 264 * RTEMS_SUCCESSFUL 265 */ 266 rtems_device_driver 267 Clock_initialize(rtems_device_major_number major, 268 rtems_device_minor_number minor, 269 void *pargp) 230 /* 231 * Clock_initialize 232 * 233 * Device driver entry point for clock tick driver initialization. 234 */ 235 rtems_device_driver Clock_initialize( 236 rtems_device_major_number major, 237 rtems_device_minor_number minor, 238 void *pargp 239 ) 270 240 { 271 241 Install_clock( Clock_isr ); 272 242 273 /*274 * make major/minor avail to others such as shared memory driver275 */276 rtems_clock_major = major;277 rtems_clock_minor = minor;278 279 243 return RTEMS_SUCCESSFUL; 280 244 }
Note: See TracChangeset
for help on using the changeset viewer.