📄 sitsang_misc.c
字号:
//==========================================================================//// sitsang_misc.c//// HAL misc board support code for XScale SITSANG////==========================================================================//####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, 2001 Red Hat, Inc. // All Rights Reserved. // ------------------------------------------- // //####COPYRIGHTEND####//==========================================================================//#####DESCRIPTIONBEGIN####//// Author(s): alvin// Contributors: alvin// Date: 2002-08-28// Purpose: HAL board support// Description: Implementations of HAL board interfaces////####DESCRIPTIONEND####////========================================================================*/#include <redboot.h>#include <pkgconf/hal.h>#include <pkgconf/system.h>#include CYGBLD_HAL_PLATFORM_H#include CYGHWR_MEMORY_LAYOUT_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_stub.h> // Stub macros#include <cyg/hal/hal_if.h> // calling interface API#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_sitsang.h> // Hardware definitions#include <cyg/hal/drv_api.h> // CYG_ISR_HANDLED#define CONSOLE_OUT(x) {x;}extern int printf(char *fmt, ...);// Some initialization has already been done before we get here.//// Set up the interrupt environment.// Set up the MMU so that we can use caches.// Enable caches.void coldstart(void){ *(unsigned long *)OSCR = 0; // initialize os timer counter *(unsigned long *)RCNR = 0; // initialize rtc counter *(unsigned long *)RTTR = 0x7FFF; // divide RTC to get 1hz output // // initialize interrupt registers *(unsigned long *)ICMR = 0; // Pending Interrupts are masked from becoming active *(unsigned long *)ICLR = 0; // Route all Interrupts to CPU IRQ (none to FIQ) *(unsigned long *)ICCR = 1; // Only enabled and unmasked interrupt bring core out of idle return ;}void hal_hardware_init(void){ unsigned long int gpioValue, bcrValue ; // enable FFUART clock gpioValue = *(volatile unsigned long *)CKEN ; gpioValue = gpioValue | (volatile unsigned long)0x40 ; //enable FFUART unit clock *(volatile unsigned long *)CKEN = gpioValue ; bcrValue = *(volatile unsigned long *)PCR_RW; bcrValue = bcrValue | (volatile unsigned long)(PCR_RS232_ON | PCR_PER_ON); *(volatile unsigned long *)PCR_RW = bcrValue; // Let the "OS" counter run coldstart() ; // Set up eCos/ROM interfaces hal_if_init(); //ecos, not platform, specifc. Common to all. Do not change. // Enable caches HAL_DCACHE_ENABLE(); HAL_ICACHE_ENABLE(); return ;}#include CYGHWR_MEMORY_LAYOUT_Htypedef void code_fun(void);void sitsang_program_new_stack(void *func){ register CYG_ADDRESS stack_ptr asm("sp"); register CYG_ADDRESS old_stack asm("r4"); register code_fun *new_func asm("r0"); old_stack = stack_ptr; stack_ptr = CYGMEM_REGION_ram + CYGMEM_REGION_ram_SIZE - sizeof(CYG_ADDRESS); new_func = (code_fun*)func; new_func(); stack_ptr = old_stack; return;}// -------------------------------------------------------------------------// Clock can come from the PMU or from an external timer.// The external timer is the preferred choice.#if CYGNUM_HAL_INTERRUPT_RTC == CYGNUM_HAL_INTERRUPT_PMU_CCNT_OVFL// Proper version that uses the clock counter in the PMU to do proper// interrupts that require acknowledgement and all that good stuff.static cyg_uint32 hal_clock_init_period; // The START value, it counts upvoid hal_clock_initialize(cyg_uint32 period){ // event types both zero; clear all 3 interrupts; // disable all 3 counter interrupts; // CCNT counts every processor cycle; reset all counters; // enable PMU. register cyg_uint32 init = 0x00000707; asm volatile ( "mcr p14,0,%0,c0,c0,0;" // write into PMNC : : "r"(init) /*:*/ ); // the CCNT in the PMU counts *up* then interrupts at overflow // ie. at 0x1_0000_0000 as it were. // So init to 0xffffffff - period + 1 to get the right answer. period = (~period) + 1; hal_clock_init_period = period; hal_clock_reset( 0, 0 );}// This routine is called during a clock interrupt.// (before acknowledging the interrupt)void hal_clock_reset(cyg_uint32 vector, cyg_uint32 period){ asm volatile ( "mrc p14,0,r0,c1,c0,0;" // read from CCNT - how long since OVFL "add %0, %0, r0;" // synchronize with previous overflow "mcr p14,0,%0,c1,c0,0;" // write into CCNT : : "r"(hal_clock_init_period) : "r0" );}// 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)void hal_clock_read(cyg_uint32 *pvalue){ register cyg_uint32 now; asm volatile ( "mrc p14,0,%0,c1,c0,0;" // read from CCNT : "=r"(now) : /*:*/ ); *pvalue = now - hal_clock_init_period;}// Delay for some usecs.void hal_delay_us(cyg_uint32 delay){ int i; // the loop is going to take 3 ticks. At 600 MHz, to give uS, multiply // by 600/3 = 200. No volatile is needed on i; gcc recognizes delay // loops and does NOT elide them. for ( i = 200 * delay; i ; i--) ;}#else // external timerstatic cyg_uint32 _period;void hal_clock_initialize(cyg_uint32 period){ //user specific code here if desired //This function is not necessary for Redboot operation }// This routine is called during a clock interrupt.void hal_clock_reset(cyg_uint32 vector, cyg_uint32 period){ //user specific code here if desired //This function is not necessary for Redboot operation}// Read and return the current value of the clockvoid hal_clock_read(cyg_uint32 *pvalue){ *pvalue = *(unsigned long *)OSCR ; return ;}// Delay for some usecs.void hal_delay_us(cyg_uint32 delay){ unsigned long delayCount; volatile unsigned long startCount; volatile long elapsedCount = 0 ; startCount = *(volatile unsigned long *)OSCR; delayCount = (unsigned long)(delay*3.6864); while (elapsedCount < delayCount) { if( (elapsedCount = (*(volatile unsigned *)OSCR - startCount)) < 0) { elapsedCount = 0xffffffff - startCount + *(volatile unsigned *)OSCR ;// printf("elapsed count = %d\n", elapsedCount) ; } } return;}unsigned long hal_elapsed_ticks(unsigned long *pStart){ long elapsedTicks = 0 ; unsigned long currTimerValue ; currTimerValue = *(unsigned long *)OSCR ; elapsedTicks = currTimerValue - *pStart ; if(elapsedTicks > 0) return elapsedTicks ; else return(0xffffffff - *pStart + currTimerValue) ;}#endif// -------------------------------------------------------------------------#define RTC_EQ_ALARM_REG 31 // Real-time clock 1 RTC equals alarm register.#define RTC_1HZ_TICK 30 // 1 One Hz clock TIC occurred.#define OSTIMER_EQ_MATCH_REG3 29 // OS timer equals match register 3.#define OSTIMER_EQ_MATCH_REG2 28 // OS timer equals match register 2.#define OSTIMER_EQ_MATCH_REG1 27 // OS timer equals match register 1.#define OSTIMER_EQ_MATCH_REG0 26 // OS timer equals match register 0.#define DMA_SERVICE_REQ 25 // DMA Channel service request.#define SSP_SERVICE_REQ 24 // SSP service request.#define MMC_STATUS 23 // MMC status / error detection#define FFUART_SERVICE_REQ 22 // x-mit, receive, error in FFUART.#define BTUART_SERVICE_REQ 21 // x-mit, receive, error in BTUART.#define STUART_SERVICE_REQ 20 // x-mit, receive, error in STUART.#define ICP_SERVICE_REQ 19 // x-mit, receive, error in ICP.#define I2C_SERVICE_REQ 18 // I2C service request.#define LCD_CTRL_SERVICE_REQ 17 // LCD controller service request.#define TOUCHSCREEN_INT 16 // Touch screen interrupt#define ADC_INT 15 // Analog to Digital converter interrupt#define AC97_INT 14 // AC97 interrupt#define I2S_INT 13 // I2S interrupt#define PMU_INT 12 // PMU (Performance Monitor) interrupt#define USB_INT 11 // USB interrupt#define GPIO_EDGE_DET_OR 10 // 揙R
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -