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

📄 sa11x0_misc.c

📁 移植到WLIT项目的redboot源代码
💻 C
字号:
//==========================================================================////      sa11x0_misc.c////      HAL misc board support code for StrongARM SA11x0////==========================================================================//####COPYRIGHTBEGIN####//// -------------------------------------------// The contents of this file are subject to the Red Hat eCos Public License// Version 1.1 (the "License"); you may not use this file except in// compliance with the License.  You may obtain a copy of the License at// http://www.redhat.com///// Software distributed under the License is distributed on an "AS IS"// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the// License for the specific language governing rights and limitations under// the License. //// The Original Code is eCos - Embedded Configurable Operating System,// released September 30, 1998.//// The Initial Developer of the Original Code is Red Hat.// Portions created by Red Hat are// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.// All Rights Reserved.// -------------------------------------------////####COPYRIGHTEND####//==========================================================================//#####DESCRIPTIONBEGIN####//// Author(s):    gthomas// Contributors: hmt//               Travis C. Furrer <furrer@mit.edu>// Date:         2000-05-08// Purpose:      HAL board support// Description:  Implementations of HAL board interfaces////####DESCRIPTIONEND####////========================================================================*/#include <pkgconf/hal.h>#include <pkgconf/system.h>#include CYGBLD_HAL_PLATFORM_H#include <cyg/infra/cyg_type.h>         // base types#include <cyg/infra/cyg_trac.h>         // tracing macros#include <cyg/infra/cyg_ass.h>          // assertion macros#include <cyg/hal/hal_io.h>             // IO macros#include <cyg/hal/hal_arch.h>           // Register state info#include <cyg/hal/hal_diag.h>#include <cyg/hal/hal_intr.h>           // Interrupt names#include <cyg/hal/hal_cache.h>#include <cyg/hal/hal_sa11x0.h>         // Hardware definitions#include <cyg/infra/diag.h>             // diag_printf// Most initialization has already been done before we get here.// All we do here is set up the interrupt environment.// FIXME: some of the stuff in hal_platform_setup could be moved here.externC void plf_hardware_init(void);void hal_hardware_init(void){    // Mask all interrupts    *SA11X0_ICMR = 0;         // Make all interrupts do IRQ and not FIQ    // FIXME: Change this if you use FIQs.    *SA11X0_ICLR = 0;         // Prevent masked interrupts from bringing us out of idle mode    *SA11X0_ICCR = 1;    // Disable all GPIO interrupt sources    *SA11X0_GPIO_RISING_EDGE_DETECT = 0;    *SA11X0_GPIO_FALLING_EDGE_DETECT = 0;    *SA11X0_GPIO_EDGE_DETECT_STATUS = 0x0FFFFFFF;    // Perform any platform specific initializations    plf_hardware_init();    // Let the "OS" counter run    *SA11X0_OSCR = 0;    *SA11X0_OSMR0 = 0;    // Set up eCos/ROM interfaces    hal_if_init();    // Enable caches    HAL_DCACHE_ENABLE();    HAL_ICACHE_ENABLE();}// -------------------------------------------------------------------------static cyg_uint32  clock_period;void hal_clock_initialize(cyg_uint32 period){    // Load match value    *SA11X0_OSMR0 = period;    clock_period = period;    // Start the counter    *SA11X0_OSCR = 0;    // Clear any pending interrupt    *SA11X0_OSSR = SA11X0_OSSR_TIMER0;    // Enable timer 0 interrupt        *SA11X0_OIER |= SA11X0_OIER_TIMER0;    // Unmask timer 0 interrupt    HAL_INTERRUPT_UNMASK( CYGNUM_HAL_INTERRUPT_TIMER0 );    // That's all.}// This routine is called during a clock interrupt.// Define this if you want to ensure that the clock is perfect (i.e. does// not drift).  One reason to leave it turned off is that it costs some// 1.5us per system clock interrupt for this maintenance.#undef COMPENSATE_FOR_CLOCK_DRIFTvoid hal_clock_reset(cyg_uint32 vector, cyg_uint32 period){#ifdef COMPENSATE_FOR_CLOCK_DRIFT    cyg_int32 ctr = (cyg_int32)*SA11X0_OSCR;    // Current value of the counter    ctr -= period;                              // Reset counter    if ((ctr < 0) || (ctr >= period)) ctr = 0;  // Adjust for missed interrupts    *SA11X0_OSCR = ctr;    clock_period = period;#else    *SA11X0_OSCR = 0;#endif    *SA11X0_OSMR0 = period;                     // Load new match value    *SA11X0_OSSR = SA11X0_OSSR_TIMER0;          // Clear any pending interrupt}// Read the current value of the clock, returning the number of hardware// "ticks" that have occurred (i.e. how far away the current value is from// the start)// Note: The "contract" for this function is that the value is the number// of hardware clocks that have happened since the last interrupt (i.e.// when it was reset).  This value is used to measure interrupt latencies.// However, since the hardware counter does not automatically reset, as// many do, the value may be larger than the system "tick" interval.// If this turns out to be the case, the result will be adjusted to be// within the interval [0..N-1], where N is the number of hardware clocks/tick.void hal_clock_read(cyg_uint32 *pvalue){    cyg_uint32 ctr = *SA11X0_OSCR;    if (ctr > clock_period) ctr -= clock_period;    *pvalue = ctr;}//// Delay for some number of micro-seconds//void hal_delay_us(cyg_int32 usecs){    int diff, diff2;    cyg_uint32 val1, val2;    while (usecs-- > 0) {        diff = 0;        while (diff < 3) {            val1 = *SA11X0_OSCR;            while ((val2 = *SA11X0_OSCR) == val1) ;            if (*SA11X0_OSMR0) {                // A kernel is running, the counter may get reset as we watch                diff2 = val2 - val1;                if (diff2 < 0) diff2 += *SA11X0_OSMR0;                diff += diff2;            } else {                diff += val2 - val1;            }        }    }}// -------------------------------------------------------------------------// This routine is called to respond to a hardware interrupt (IRQ).  It// should interrogate the hardware and return the IRQ vector number.int hal_IRQ_handler(void){    cyg_uint32 sources, index;#if 0 // test FIQ and print alert if active - really for debugging    sources = *SA11X0_ICFP;    if ( 0 != sources )        diag_printf( "FIQ source active!!! - fiqstatus %08x irqstatus %08x\n",                     sources, *SA11X0_ICIP );    else#endif // Scan FIQ sources also    sources = *SA11X0_ICIP;// FIXME// if we come to support FIQ properly...//    if ( 0 == sources )//        sources = *SA11X0_ICFP;    // Nothing wrong with scanning them in any order we choose...    // So here we try to make the serial devices steal fewer cycles.    // So, knowing this is an ARM:    if ( sources & 0xff0000 )        index = 16;    else if ( sources & 0xff00 )        index = 8;    else if ( sources & 0xff )        index = 0;    else // if ( sources & 0xff000000 )        index = 24;    do {        if ( (1 << index) & sources ) {            if (index == CYGNUM_HAL_INTERRUPT_GPIO) {                // Special case of GPIO cascade.  Search for lowest set bit                sources = *SA11X0_GPIO_EDGE_DETECT_STATUS & 0x0FFFF800;                index = 11;                do {                    if (sources & (1 << index)) {                        index += 32;                        break;                    }                    index++;                } while (index < 28);            }            return index;        }      index++;    } while ( index & 7 );        return CYGNUM_HAL_INTERRUPT_NONE; // This shouldn't happen!}//// Interrupt control//void hal_interrupt_mask(int vector){    // Non-GPIO interrupt sources can be masked separately.    // Note: masking any non-unique GPIO signal (31..11) results in    // all GPIO signals (31..11) being masked as only the "lump"    // source will be changed.    if (vector >= CYGNUM_HAL_INTERRUPT_GPIO11) {        vector = CYGNUM_HAL_INTERRUPT_GPIO;    }    *SA11X0_ICMR &= ~(1 << vector);}void hal_interrupt_unmask(int vector){    if (vector >= CYGNUM_HAL_INTERRUPT_GPIO11) {        vector = CYGNUM_HAL_INTERRUPT_GPIO;    }    *SA11X0_ICMR |= (1 << vector);}void hal_interrupt_acknowledge(int vector){    // GPIO interrupts are driven by an edge detection mechanism.  This    // is latching so these interrupts must be acknowledged directly.    // All other interrupts simply go away when the interrupting unit    // has been serviced by the ISR.    if ((vector < CYGNUM_HAL_INTERRUPT_GPIO) ||         (vector >= CYGNUM_HAL_INTERRUPT_GPIO11)) {        *SA11X0_GPIO_EDGE_DETECT_STATUS  = (1 << (vector & 0x1F));    } else {        // Not a GPIO interrupt        return;    }}void hal_interrupt_configure(int vector, int level, int up){    // This function can be used to configure the GPIO interrupts.  All    // of these pins can potentially generate an interrupt, but only    // 0..10 are unique.  Thus the discontinuity in the numbers.    // Also, if 'level' is true, then both edges are enabled if 'up' is    // true, otherwise they will be disabled.    // Non GPIO sources are ignored.    if ((vector < CYGNUM_HAL_INTERRUPT_GPIO) ||         (vector >= CYGNUM_HAL_INTERRUPT_GPIO11)) {        if (level) {            if (up) {                // Enable both edges                *SA11X0_GPIO_RISING_EDGE_DETECT |= (1 << (vector & 0x1F));                *SA11X0_GPIO_FALLING_EDGE_DETECT |= (1 << (vector & 0x1F));            } else {                // Disable both edges                *SA11X0_GPIO_RISING_EDGE_DETECT &= ~(1 << (vector & 0x1F));                *SA11X0_GPIO_FALLING_EDGE_DETECT &= ~(1 << (vector & 0x1F));            }        } else {            // Only interested in one edge            if (up) {                // Set rising edge detect and clear falling edge detect.                *SA11X0_GPIO_RISING_EDGE_DETECT |= (1 << (vector & 0x1F));                *SA11X0_GPIO_FALLING_EDGE_DETECT &= ~(1 << (vector & 0x1F));            } else {                // Set falling edge detect and clear rising edge detect.                *SA11X0_GPIO_FALLING_EDGE_DETECT |= (1 << (vector & 0x1F));                *SA11X0_GPIO_RISING_EDGE_DETECT &= ~(1 << (vector & 0x1F));            }        }    }}void hal_interrupt_set_level(int vector, int level){    // Interrupt priorities are not configurable on the SA11X0.}/*------------------------------------------------------------------------*/// EOF sa11x0_misc.c

⌨️ 快捷键说明

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