hal_diag.c

来自「eCos操作系统源码」· C语言 代码 · 共 549 行 · 第 1/2 页

C
549
字号
/*=============================================================================////      hal_diag.c////      HAL diagnostic output code////=============================================================================//####ECOSGPLCOPYRIGHTBEGIN####// -------------------------------------------// This file is part of eCos, the Embedded Configurable Operating System.// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.//// 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):   gthomas// Contributors:nickg, gthomas, dmoseley//              Travis C. Furrer <furrer@mit.edu>// Date:        2000-05-08// Purpose:     HAL diagnostic output// Description: Implementations of HAL diagnostic output support.////####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_arch.h>           // basic machine info#include <cyg/hal/hal_intr.h>           // interrupt macros#include <cyg/hal/hal_io.h>             // IO macros#include <cyg/hal/hal_if.h>             // Calling interface definitions#include <cyg/hal/hal_diag.h>#include <cyg/hal/drv_api.h>            // cyg_drv_interrupt_acknowledge#include <cyg/hal/hal_misc.h>           // Helper functions#include <cyg/hal/hal_sa11x0.h>         // Hardware definitionsstruct sa11x0_serial {  volatile cyg_uint32 utcr0;  volatile cyg_uint32 utcr1;  volatile cyg_uint32 utcr2;  volatile cyg_uint32 utcr3;  volatile cyg_uint32 pad0010;  volatile cyg_uint32 utdr;  volatile cyg_uint32 pad0018;  volatile cyg_uint32 utsr0;  volatile cyg_uint32 utsr1;};//-----------------------------------------------------------------------------typedef struct {    volatile struct sa11x0_serial* base;    cyg_int32 msec_timeout;    int isr_vector;    int baud_rate;} channel_data_t;/*---------------------------------------------------------------------------*/// SA11x0 Serial Port (UARTx) for Debugstatic voidinit_channel(channel_data_t* __ch_data){    volatile struct sa11x0_serial* base = __ch_data->base;    cyg_uint32 brd;    // Disable Receiver and Transmitter (clears FIFOs)    base->utcr3 = SA11X0_UART_RX_DISABLED | SA11X0_UART_TX_DISABLED;    // Clear sticky (writable) status bits.    base->utsr0 = SA11X0_UART_RX_IDLE | SA11X0_UART_RX_BEGIN_OF_BREAK |                  SA11X0_UART_RX_END_OF_BREAK;#if defined(CYGPKG_HAL_ARM_SA11X0_SA1100MM) || defined(CYGPKG_HAL_ARM_SA11X0_BRUTUS)   // This setup is specific to only a few boards.   if (SA11X0_UART1_BASE == (volatile unsigned long *)base) {        cyg_uint32 pdr, afr, par;        HAL_READ_UINT32(SA11X0_GPIO_PIN_DIRECTION, pdr);        HAL_READ_UINT32(SA11X0_GPIO_ALTERNATE_FUNCTION, afr);        HAL_READ_UINT32(SA11X0_PPC_PIN_ASSIGNMENT, par);        //Set pin 14 as an output (Tx) and pin 15 as in input (Rx).        HAL_WRITE_UINT32(SA11X0_GPIO_PIN_DIRECTION, ((pdr | SA11X0_GPIO_PIN_14) & ~SA11X0_GPIO_PIN_15));        // Use GPIO 14 & 15 pins for serial port 1.        HAL_WRITE_UINT32(SA11X0_GPIO_ALTERNATE_FUNCTION, afr | SA11X0_GPIO_PIN_14 | SA11X0_GPIO_PIN_15);        // Pin reassignment for serial port 1.        HAL_WRITE_UINT32(SA11X0_PPC_PIN_ASSIGNMENT, par | SA11X0_PPC_UART_PIN_REASSIGNMENT_MASK);    }#endif    // Set UART to 8N1 (8 data bits, no partity, 1 stop bit)    base->utcr0 = SA11X0_UART_PARITY_DISABLED | SA11X0_UART_STOP_BITS_1 |                  SA11X0_UART_DATA_BITS_8;    // Set the desired baud rate.    brd = SA11X0_UART_BAUD_RATE_DIVISOR(__ch_data->baud_rate);    base->utcr1 = (brd >> 8) & SA11X0_UART_H_BAUD_RATE_DIVISOR_MASK;    base->utcr2 = brd & SA11X0_UART_L_BAUD_RATE_DIVISOR_MASK;    // Enable the receiver and the transmitter.    base->utcr3 = SA11X0_UART_RX_ENABLED | SA11X0_UART_TX_ENABLED;    // All done}voidcyg_hal_plf_serial_putc(void *__ch_data, char c){    volatile struct sa11x0_serial* base = ((channel_data_t*)__ch_data)->base;    CYGARC_HAL_SAVE_GP();    // Wait for Tx FIFO not full    while ((base->utsr1 & SA11X0_UART_TX_FIFO_NOT_FULL) == 0)        ;    base->utdr = c;    CYGARC_HAL_RESTORE_GP();}// FIXME: shouldn't we check for PARITY_ERROR, FRAMING_ERROR, or// RECEIVE_FIFO_OVERRUN_ERROR in the received data?  This// means check the appropriate bits in UTSR1.static cyg_boolcyg_hal_plf_serial_getc_nonblock(void* __ch_data, cyg_uint8* ch){    volatile struct sa11x0_serial* base = ((channel_data_t*)__ch_data)->base;    // If receive fifo is empty, return false    if ((base->utsr1 & SA11X0_UART_RX_FIFO_NOT_EMPTY) == 0)        return false;    *ch = (char)base->utdr;    // Clear receiver idle status bit, to allow another interrupt to    // occur in the case where the receive fifo is almost empty.    base->utsr0 = SA11X0_UART_RX_IDLE;    return true;}cyg_uint8cyg_hal_plf_serial_getc(void* __ch_data){    cyg_uint8 ch;    CYGARC_HAL_SAVE_GP();    while(!cyg_hal_plf_serial_getc_nonblock(__ch_data, &ch));    CYGARC_HAL_RESTORE_GP();    return ch;}static channel_data_t ser_channels[] = {#if CYGHWR_HAL_ARM_SA11X0_UART1 != 0    { (volatile struct sa11x0_serial*)SA11X0_UART1_BASE, 1000,       CYGNUM_HAL_INTERRUPT_UART1, CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD },#endif#if CYGHWR_HAL_ARM_SA11X0_UART3 != 0    { (volatile struct sa11x0_serial*)SA11X0_UART3_BASE, 1000,       CYGNUM_HAL_INTERRUPT_UART3, CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD },#endif};static voidcyg_hal_plf_serial_write(void* __ch_data, const cyg_uint8* __buf,                          cyg_uint32 __len){    CYGARC_HAL_SAVE_GP();    while(__len-- > 0)        cyg_hal_plf_serial_putc(__ch_data, *__buf++);    CYGARC_HAL_RESTORE_GP();}static voidcyg_hal_plf_serial_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len){    CYGARC_HAL_SAVE_GP();    while(__len-- > 0)        *__buf++ = cyg_hal_plf_serial_getc(__ch_data);    CYGARC_HAL_RESTORE_GP();}cyg_boolcyg_hal_plf_serial_getc_timeout(void* __ch_data, cyg_uint8* ch){    int delay_count;    channel_data_t* chan = (channel_data_t*)__ch_data;    cyg_bool res;    CYGARC_HAL_SAVE_GP();    delay_count = chan->msec_timeout * 10; // delay in .1 ms steps    for(;;) {        res = cyg_hal_plf_serial_getc_nonblock(__ch_data, ch);        if (res || 0 == delay_count--)            break;                CYGACC_CALL_IF_DELAY_US(100);    }    CYGARC_HAL_RESTORE_GP();    return res;}static intcyg_hal_plf_serial_control(void *__ch_data, __comm_control_cmd_t __func, ...){    static int irq_state = 0;    channel_data_t* chan = (channel_data_t*)__ch_data;    int ret = -1;    va_list ap;    CYGARC_HAL_SAVE_GP();    va_start(ap, __func);    switch (__func) {    case __COMMCTL_GETBAUD:        ret = chan->baud_rate;        break;    case __COMMCTL_SETBAUD:        chan->baud_rate = va_arg(ap, cyg_int32);        // Should we verify this value here?        init_channel(chan);        ret = 0;        break;    case __COMMCTL_IRQ_ENABLE:        irq_state = 1;        chan->base->utcr3 |= SA11X0_UART_RX_FIFO_INT_ENABLED;        HAL_INTERRUPT_UNMASK(chan->isr_vector);        break;    case __COMMCTL_IRQ_DISABLE:        ret = irq_state;

⌨️ 快捷键说明

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