quicc2_diag.c
来自「eCos操作系统源码」· C语言 代码 · 共 558 行 · 第 1/2 页
C
558 行
//=============================================================================//// quicc2_diag.c//// HAL diagnostic I/O support routines for MPC8xxx/QUICC2////=============================================================================//####ECOSGPLCOPYRIGHTBEGIN####// -------------------------------------------// This file is part of eCos, the Embedded Configurable Operating System.// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.// Copyright (C) 2002, 2003 Gary Thomas//// eCos is free software; you can redistribute it and/or modify it under// the terms of the GNU General Public License as published by the Free// Software Foundation; either version 2 or (at your option) any later version.//// eCos is distributed in the hope that it will be useful, but WITHOUT ANY// WARRANTY; without even the implied warranty of MERCHANTABILITY or// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License// for more details.//// You should have received a copy of the GNU General Public License along// with eCos; if not, write to the Free Software Foundation, Inc.,// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.//// As a special exception, if other files instantiate templates or use macros// or inline functions from this file, or you compile this file and link it// with other works to produce a work based on this file, this file does not// by itself cause the resulting work to be covered by the GNU General Public// License. However the source code for this file must still be made available// in accordance with section (3) of the GNU General Public License.//// This exception does not invalidate any other reasons why a work based on// this file might be covered by the GNU General Public License.//// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.// at http://sources.redhat.com/ecos/ecos-license/// -------------------------------------------//####ECOSGPLCOPYRIGHTEND####//=============================================================================//#####DESCRIPTIONBEGIN####//// Author(s): hmt// Contributors:hmt, gthomas// Date: 1999-06-08// Purpose: HAL diagnostics I/O support// Description: ////####DESCRIPTIONEND####////=============================================================================#include <pkgconf/hal.h>#include <cyg/hal/hal_mem.h> // HAL memory definitions#include <cyg/infra/cyg_type.h>#include <cyg/hal/hal_if.h> // hal_if_init#include <cyg/hal/hal_io.h> // hal_if_init#include <cyg/hal/hal_misc.h> // cyg_hal_is_break#include <cyg/hal/drv_api.h> // CYG_ISR_HANDLED#include <cyg/hal/hal_intr.h>#include <cyg/hal/hal_cache.h>#include <cyg/hal/mpc8xxx.h> // Needed for IMMR structure#define PORT_IS_SMC 1#define PORT_IS_SCC 0#define NUM(t) sizeof(t)/sizeof(t[0])struct port_info { short Txnum; // Number of Tx buffers short Rxnum; // Number of Rx buffers short intnum; // Interrupt bit short is_smc; // 1 => SMC, 0=> SCC int cpm_page; int timeout; // Timeout in msec int pram; // [Pointer] to PRAM data int regs; // [Pointer] to control registers int brg; // Baud rate generator volatile struct cp_bufdesc *next_rxbd; int irq_state;// Interrupt state int init; // Has port been initialized?};static struct port_info ports[] = {#if CYGNUM_HAL_MPC8XXX_SMC1 > 0 { 1, 4, CYGNUM_HAL_INTERRUPT_SMC1, PORT_IS_SMC, SMC1_PAGE_SUBBLOCK, 1000, DPRAM_SMC1_OFFSET, (int)&((t_PQ2IMM *)0)->smc_regs[SMC1], (int)&((t_PQ2IMM *)0)->brgs_brgc7 }, #endif#if CYGNUM_HAL_MPC8XXX_SCC1 > 0 { 1, 4, CYGNUM_HAL_INTERRUPT_SCC1, PORT_IS_SCC, SCC1_PAGE_SUBBLOCK, 1000, (int)&((t_PQ2IMM *)0)->pram.serials.scc_pram[SCC1], (int)&((t_PQ2IMM *)0)->scc_regs[SCC1], (int)&((t_PQ2IMM *)0)->brgs_brgc1 }, #endif};// For Baud Rate Calculation, see MPC8260 PowerQUICC II User's Manual// 16.3 UART Baud Rate Examples, page 16-5.#define UART_BIT_RATE(n) \ ((((int)(((CYGHWR_HAL_POWERPC_CPM_SPEED*2)*1000000)/16))/(n * 16))-1)#define UART_BAUD_RATE CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD// Function prototypesstatic cyg_uint8 cyg_hal_plf_serial_getc(void* __ch_data);static cyg_bool cyg_hal_plf_serial_getc_nonblock(void* __ch_data, cyg_uint8* ch);static cyg_bool cyg_hal_plf_serial_getc_timeout(void* __ch_data, cyg_uint8* ch);static void cyg_hal_plf_serial_putc(void* __ch_data, cyg_uint8 ch);static void cyg_hal_plf_serial_write(void* __ch_data, const cyg_uint8* __buf, cyg_uint32 __len);static void cyg_hal_plf_serial_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len);static void cyg_hal_plf_smcx_init_channel(struct port_info *info, int page);static void cyg_hal_plf_sccx_init_channel(struct port_info *info, int page);static int cyg_hal_plf_smcx_isr(void *__ch_data, int* __ctrlc, CYG_ADDRWORD __vector, CYG_ADDRWORD __data);static int cyg_hal_plf_sccx_isr(void *__ch_data, int* __ctrlc, CYG_ADDRWORD __vector, CYG_ADDRWORD __data);static int cyg_hal_plf_serial_control(void *__ch_data, __comm_control_cmd_t __func, ...);static int cyg_hal_plf_sccx_isr(void *__ch_data, int* __ctrlc, CYG_ADDRWORD __vector, CYG_ADDRWORD __data){ struct port_info *info = (struct port_info *)__ch_data; volatile struct scc_regs_8260 *regs = (volatile struct scc_regs_8260*)((char *)IMM + info->regs); volatile t_Scc_Pram *pram = (volatile t_Scc_Pram *)((char *)IMM + info->pram); char ch; int res = 0; volatile struct cp_bufdesc *bd; *__ctrlc = 0; if (regs->scce & SCCE_Rx) { regs->scce = SMCE_Rx; /* rx buffer descriptors */ bd = info->next_rxbd; if ((bd->ctrl & _BD_CTL_Ready) == 0) { // then there be a character waiting ch = bd->buffer[0]; bd->length = 1; bd->ctrl |= _BD_CTL_Ready | _BD_CTL_Int; if (bd->ctrl & _BD_CTL_Wrap) { bd = (struct cp_bufdesc *)((char *)IMM + pram->rbase); } else { bd++; } info->next_rxbd = bd; if( cyg_hal_is_break( &ch , 1 ) ) *__ctrlc = 1; } // Interrupt handled. Acknowledge it. HAL_INTERRUPT_ACKNOWLEDGE(info->intnum); res = CYG_ISR_HANDLED; } return res;}static int cyg_hal_plf_smcx_isr(void *__ch_data, int* __ctrlc, CYG_ADDRWORD __vector, CYG_ADDRWORD __data){ struct port_info *info = (struct port_info *)__ch_data; volatile struct smc_regs_8260 *regs = (volatile struct smc_regs_8260*)((char *)IMM + info->regs); t_Smc_Pram *pram = (t_Smc_Pram *)((char *)IMM + info->pram); char ch; int res = 0; volatile struct cp_bufdesc *bd; *__ctrlc = 0; if (regs->smc_smce & SMCE_Rx) { regs->smc_smce = SMCE_Rx; /* rx buffer descriptors */ bd = info->next_rxbd; if ((bd->ctrl & _BD_CTL_Ready) == 0) { // then there be a character waiting ch = bd->buffer[0]; bd->length = 1; bd->ctrl |= _BD_CTL_Ready | _BD_CTL_Int; if (bd->ctrl & _BD_CTL_Wrap) { bd = (struct cp_bufdesc *)((char *)IMM + pram->rbase); } else { bd++; } info->next_rxbd = bd; if( cyg_hal_is_break( &ch , 1 ) ) *__ctrlc = 1; } // Interrupt handled. Acknowledge it. HAL_INTERRUPT_ACKNOWLEDGE(info->intnum); res = CYG_ISR_HANDLED; } return res;}/* Early initialization of comm channels. */voidcyg_hal_plf_serial_init(void){ hal_virtual_comm_table_t* comm; int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT); int chan = 0; struct port_info *port; static int init = 0; if (init) return; init++; // Setup procs in the vector table for (port = ports, chan = 0; chan < NUM(ports); chan++, port++) { CYGACC_CALL_IF_SET_CONSOLE_COMM(chan); comm = CYGACC_CALL_IF_CONSOLE_PROCS(); CYGACC_COMM_IF_CH_DATA_SET(*comm, port); CYGACC_COMM_IF_WRITE_SET(*comm, cyg_hal_plf_serial_write); CYGACC_COMM_IF_READ_SET(*comm, cyg_hal_plf_serial_read); CYGACC_COMM_IF_PUTC_SET(*comm, cyg_hal_plf_serial_putc); CYGACC_COMM_IF_GETC_SET(*comm, cyg_hal_plf_serial_getc); CYGACC_COMM_IF_CONTROL_SET(*comm, cyg_hal_plf_serial_control); CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, cyg_hal_plf_serial_getc_timeout); if (port->is_smc) { cyg_hal_plf_smcx_init_channel(port, port->cpm_page); CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_smcx_isr); } else { cyg_hal_plf_sccx_init_channel(port, port->cpm_page); CYGACC_COMM_IF_DBG_ISR_SET(*comm, cyg_hal_plf_sccx_isr); } } // Restore original console CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);}static voidcyg_hal_plf_sccx_init_channel(struct port_info *info, int cpm_page){ unsigned int rxbase, txbase; int i; struct cp_bufdesc *rxbd, *txbd; volatile struct scc_regs_8260 *regs = (volatile struct scc_regs_8260*)((char *)IMM + info->regs); volatile t_Scc_Pram *pram = (volatile t_Scc_Pram *)((char *)IMM + info->pram); if (info->init) return; info->init = 1; // Make sure device is stopped regs->gsmr_l &= DISABLE_TX_RX; while ((IMM->cpm_cpcr & CPCR_FLG) != READY_TO_RX_CMD); IMM->cpm_cpcr = cpm_page | CPCR_STOP_TX | CPCR_FLG; /* ISSUE COMMAND */ while ((IMM->cpm_cpcr & CPCR_FLG) != READY_TO_RX_CMD); // Allocate buffer descriptors + buffers (adjacent to descriptors) rxbase = _mpc8xxx_allocBd(sizeof(struct cp_bufdesc)*info->Rxnum + info->Rxnum); txbase = _mpc8xxx_allocBd(sizeof(struct cp_bufdesc)*info->Txnum + info->Txnum); // setup RX buffer descriptors rxbd = (struct cp_bufdesc *)((char *)IMM + rxbase); info->next_rxbd = rxbd; for (i = 0; i < info->Rxnum; i++) { rxbd->length = 0; rxbd->buffer = ((char *)IMM + (rxbase+(info->Rxnum*sizeof(struct cp_bufdesc))))+i; rxbd->ctrl = _BD_CTL_Ready | _BD_CTL_Int; rxbd++;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?