⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ckinit.c

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 C
字号:
/* * This file contains the generic RTEMS clock driver the Hitachi SH 7750 * * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia * Author: Victor V. Vengerov <vvv@oktet.ru> * *  COPYRIGHT (c) 2001 *  On-Line Applications Research Corporation (OAR). * *  The license and distribution terms for this file may be *  found in the file LICENSE in this distribution or at *  http://www.rtems.com/license/LICENSE. * *  $Id: ckinit.c,v 1.2.4.1 2003/09/04 18:46:00 joel Exp $ */#include <rtems.h>#include <stdlib.h>#include <rtems/libio.h>#include <rtems/score/sh_io.h>#include <rtems/score/sh.h>#include <rtems/score/ispsh7750.h>#include <rtems/score/iosh7750.h>#ifndef CLOCKPRIO#define CLOCKPRIO 10#endif/* Clock timer prescaler division ratio */#define CLOCK_PRESCALER 4#define TCR0_TPSC       SH7750_TCR_TPSC_DIV4/* *  The interrupt vector number associated with the clock tick device *  driver. */#define CLOCK_VECTOR SH7750_EVT_TO_NUM(SH7750_EVT_TUNI0)/* *  Clock_driver_ticks is a monotonically increasing counter of the *  number of clock ticks since the driver was initialized. */volatile rtems_unsigned32 Clock_driver_ticks;static void Clock_exit( void );static rtems_isr Clock_isr( rtems_vector_number vector );/* * These are set by clock driver during its init */rtems_device_major_number rtems_clock_major = ~0;rtems_device_minor_number rtems_clock_minor;/* *  The previous ISR on this clock tick interrupt vector. */rtems_isr_entry  Old_ticker;/* *  Isr Handler *//* Clock_isr -- *     Clock interrupt handling routine. * * PARAMETERS: *     vector - interrupt vector number *  * RETURNS: *     none */rtems_isr Clock_isr(rtems_vector_number vector){    unsigned16 tcr;    /* reset the timer underflow flag */    tcr = read16(SH7750_TCR0);    write16(tcr & ~SH7750_TCR_UNF, SH7750_TCR0);    /* Increment the clock interrupt counter */    Clock_driver_ticks++ ;    /* Invoke rtems clock service routine */    rtems_clock_tick();}/* Install_clock -- *     Install a clock tick handler and reprograms the chip.  This *     is used to initially establish the clock tick. * * PARAMETERS: *     clock_isr - Clock interrupt stay routine * * RETURNS: *     none * * SIDE EFFECTS: *     Establish clock interrupt handler, configure Timer 0 hardware */void Install_clock(rtems_isr_entry clock_isr){    int cpudiv = 1; /* CPU frequency divider */    int tidiv = 1;  /* Timer input frequency divider */    unsigned32 timer_divider; /* Calculated Timer Divider value */    unsigned8 temp8;    unsigned16 temp16;      /*     *  Initialize the clock tick device driver variables     */    Clock_driver_ticks = 0;    /* Get CPU frequency divider from clock unit */    switch (read16(SH7750_FRQCR) & SH7750_FRQCR_IFC)    {        case SH7750_FRQCR_IFCDIV1:            cpudiv = 1;            break;                case SH7750_FRQCR_IFCDIV2:            cpudiv = 2;            break;                   case SH7750_FRQCR_IFCDIV3:            cpudiv = 3;            break;                case SH7750_FRQCR_IFCDIV4:            cpudiv = 4;            break;                case SH7750_FRQCR_IFCDIV6:            cpudiv = 6;            break;                case SH7750_FRQCR_IFCDIV8:            cpudiv = 8;            break;                default:            rtems_fatal_error_occurred( RTEMS_NOT_CONFIGURED);    }    /* Get peripheral module frequency divider from clock unit */    switch (read16(SH7750_FRQCR) & SH7750_FRQCR_PFC)    {        case SH7750_FRQCR_PFCDIV2:            tidiv = 2 * CLOCK_PRESCALER;            break;                   case SH7750_FRQCR_PFCDIV3:            tidiv = 3 * CLOCK_PRESCALER;            break;                case SH7750_FRQCR_PFCDIV4:            tidiv = 4 * CLOCK_PRESCALER;            break;                case SH7750_FRQCR_PFCDIV6:            tidiv = 6 * CLOCK_PRESCALER;            break;                case SH7750_FRQCR_PFCDIV8:            tidiv = 8 * CLOCK_PRESCALER;            break;                default:            rtems_fatal_error_occurred( RTEMS_NOT_CONFIGURED);    }    timer_divider =         (rtems_cpu_configuration_get_clicks_per_second() *          cpudiv / (tidiv*1000000)) *        rtems_configuration_get_microseconds_per_tick();    /*     *  Hardware specific initialization     */      /* Stop the Timer 0 */    temp8 = read8(SH7750_TSTR);    temp8 &= ~SH7750_TSTR_STR0;    write8(temp8, SH7750_TSTR);    /* Establish interrupt handler */    rtems_interrupt_catch( Clock_isr, CLOCK_VECTOR, &Old_ticker );    /* Reset counter */    write32(timer_divider, SH7750_TCNT0);    /* Load divider */    write32(timer_divider, SH7750_TCOR0);        write16(        SH7750_TCR_UNIE |        /* Enable Underflow Interrupt */        SH7750_TCR_CKEG_RAISE |  /* Count on rising edge */        TCR0_TPSC,               /* Timer prescaler ratio */        SH7750_TCR0);    /* Set clock interrupt priority */    temp16 = read16(SH7750_IPRA);    temp16 = (temp16 & ~SH7750_IPRA_TMU0) | (CLOCKPRIO << SH7750_IPRA_TMU0_S);    write16(temp16, SH7750_IPRA);    /* Start the Timer 0 */    temp8 = read8(SH7750_TSTR);    temp8 |= SH7750_TSTR_STR0;    write8(temp8, SH7750_TSTR);    /*     *  Schedule the clock cleanup routine to execute if the application exits.     */    atexit( Clock_exit );}/* Clock_exit -- *     Clean up before the application exits * * PARAMETERS: *     none * * RETURNS: *     none * * SIDE EFFECTS: *     Stop Timer 0 counting, set timer 0 interrupt priority level to 0. */void Clock_exit(void){    unsigned8 temp8 = 0;    unsigned16 temp16 = 0;    /* turn off the timer interrupts */    /* Stop the Timer 0 */    temp8 = read8(SH7750_TSTR);    temp8 &= ~SH7750_TSTR_STR0;    write8(temp8, SH7750_TSTR);    /* Lower timer interrupt priority to 0 */    temp16 = read16(SH7750_IPRA);    temp16 = (temp16 & ~SH7750_IPRA_TMU0) | (0 << SH7750_IPRA_TMU0_S);    write16(temp16, SH7750_IPRA);  /* old vector shall not be installed */}/* Clock_initialize -- *     Device driver entry point for clock tick driver initialization. * * PARAMETERS: *     major - clock major device number *     minor - clock minor device number *     pargp - driver initialize primitive argument, not used * * RETURNS: *     RTEMS_SUCCESSFUL */rtems_device_driver Clock_initialize(rtems_device_major_number major,                  rtems_device_minor_number minor,                 void *pargp){    Install_clock( Clock_isr );     /*     * make major/minor avail to others such as shared memory driver     */    rtems_clock_major = major;    rtems_clock_minor = minor;     return RTEMS_SUCCESSFUL;}/* Clock_control -- *     Device driver entry point for clock driver IOCTL functions. * * PARAMETERS: *     major - clock major device number *     minor - clock minor device number *     pargp - driver ioctl primitive argument, not used * * RETURNS: *     RTEMS_SUCCESSFUL */rtems_device_driver Clock_control(rtems_device_major_number major,              rtems_device_minor_number minor,              void *pargp){  rtems_unsigned32 isrlevel;  rtems_libio_ioctl_args_t *args = pargp;    if (args != 0)    {      /*       * This is hokey, but until we get a defined interface       * to do this, it will just be this simple...       */            if (args->command == rtems_build_name('I', 'S', 'R', ' '))	{	  Clock_isr(CLOCK_VECTOR);	}      else if (args->command == rtems_build_name('N', 'E', 'W', ' '))	{	  rtems_isr_entry	ignored ;	  rtems_interrupt_disable( isrlevel );	  rtems_interrupt_catch( args->buffer, CLOCK_VECTOR, &ignored );	  	  rtems_interrupt_enable( isrlevel );	}    }  return RTEMS_SUCCESSFUL;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -