📄 z85230drv.c
字号:
/* z85230Drv.c - Z85230 SCC Sync/Async Serial Driver *//* Copyright 2000-2002 Dy 4 Systems, Inc. *//*modification history--------------------01d 07jun05,dle support 183 Serial IPM V201c,12aug02,aak use generic gtDmaIntxxx interface01b,27apr01, co - Fill in header - Modify the order of includes to fix the compile problems (P/T 670, Task 2577)01a,20jun01, co - Modify z85230DrvInitialize for the interrupt callback pointers to be assigned BEFORE intConnect/intEnable for same interrupts (P/T 669, Task 2571)*//*The Dy 4 sync/async serial driver is a standard VxWorks character driver thatallows an application to exercise the EIA-422 serial channels (3 and 4)available on the target board (implemented with the Zilog Z85230 SerialCommunications Controller device). In general terms, it allows an applicationto transfer data to a compatible serial device via serial channels 3 and 4,simultaneously and independently.The driver supports asynchronous and synchronous raw HDLC (High-LevelData Link Control) and LAPB (Link Access Protocol Balanced) data transfermodes with full DMA support as well as configuration capabilities (e.g.,character size) required for each mode.This file contains the generic utilities for all modesof the driver (including macro definitions and global defs). It contains the following: z85230RebootHook z85230DrvProtocolSet z85230DrvInitialize z85230DrvShutdown z85230DrvOpen z85230DrvClose z85230DrvIoctl z85230DrvRead z85230DrvWrite z85230Drv z85230DrvRemove z85230DevCreat z85230DevRemove z85230DrvDmaRxInt z85230DrvDmaTxInt z85230DrvInt*//* Dependencies on BSP/OS files: vxWorks.h rebootLib.h string.h stdlib.h svme179.h intLib.h iv.h usrLib.h BSP Driver Dependencies: gt64260.h *//* includes */#include "vxWorks.h"#include "rebootLib.h"#include <string.h>#include <stdlib.h>/* Task 2577, P/T 670 *//* Move dy4181.h include after z85230Drv.h include*/#include "h/drv/sio/z85230Drv.h"#include "intLib.h"#include "iv.h"#include "usrLib.h"#ifdef VME_181#include "h/drv/sio/z85230Dma.h"#include "dy4181.h" #include "h/drv/pciBridge/gt64260_dy4.h"#include "h/drv/discovery/gtTimer_dy4.h"/* preprocessor macros */#define GT64260_BASE_ADRS (SVME181_PPC_DISCOVERY_ADRS) #endif#ifdef VME_183#include "intCtrl183.h"#endif/* fail is given a non-existant channel */#define Z85230_CHECK_CHANNEL(A) if( ((A) < 0) || ((A) >= Z85230_NUM_CHANNELS) ) { return Z85230_ERR_INVALID_PARAM; }/* return ERROR if (A)->error != Z85230_OK */#define Z85230_CHECK_ERR(A) \ if ((A)->error != Z85230_OK) \ {errno = (A)->error; (A)->error = 0; return ERROR;}/* return ERROR if (A)->error != Z85230_OK or (B) != Z85230_OK */#define Z85230_CHECK(A, B) \ if ((A)->error != Z85230_OK) \ {errno = (A)->error; (A)->error = 0; return ERROR;} \ else if ((B) != Z85230_OK) \ {errno = (B); (B) = 0; return ERROR;}/* globals */#ifdef VME_181extern GT64260_VARS gt;#endifshort gZ85230DrvNum = ERROR;UINT gZ85230Errno = 0;Z85230_DEV gZ85230Devices[ Z85230_NUM_CHANNELS ];Z85230_CHAN * gZ85230Channels[ Z85230_NUM_CHANNELS ];void * gZ85230Base;void * gZ85230Gt64130Base;int gZ85230IntCount = 0;int gZ85230TXAIntCount = 0;int gZ85230TXBIntCount = 0;int gZ85230RXAIntCount = 0;int gZ85230RXBIntCount = 0;int gZ85230EXAIntCount = 0;int gZ85230EXBIntCount = 0;int gZ85230DmaTxBIntCount = 0;int gZ85230DmaRxBIntCount = 0;#if TRUE int gZ85230DmaTxAIntCount = 0;int gZ85230DmaRxAIntCount = 0;#else /* STP test only */int gZ85230DmaTxIntCount = 0;int gZ85230DmaRxIntCount = 0;#define gZ85230DmaTxAIntCount gZ85230DmaTxIntCount#define gZ85230DmaRxAIntCount gZ85230DmaRxIntCount#endifint gZ85230RXAFpgaCount = 0, gZ85230RXBFpgaCount = 0;int gZ85230TXAFpgaCount = 0, gZ85230TXBFpgaCount = 0;/* incremented with each DMA interrupt handled by z85230DrvDmaInt */int gNumDmaInts = 0;/* local functions */LOCAL void z85230DrvInt( int );LOCAL void z85230RebootHook(int );#ifdef VME_181LOCAL void z85230DrvDmaRxAInt( int );LOCAL void z85230DrvDmaTxAInt( int );LOCAL void z85230DrvDmaRxBInt( int );LOCAL void z85230DrvDmaTxBInt( int );IMPORT void z85230AsyncFpgaInt( struct _Z85230_CHAN * channel );#elseIMPORT void z85230AsyncTxFpgaInt( struct _Z85230_CHAN * channel );IMPORT void z85230AsyncRxFpgaInt( struct _Z85230_CHAN * channel );IMPORT void z85230AsyncTimeoutFpgaInt( struct _Z85230_CHAN * channel );#endifIMPORT void z85230RHDLCfpgaInt( struct _Z85230_CHAN * channel );/* local variables */LOCAL BOOL gRebootHookAdded = FALSE ;/*************************************************************************** * z85230RebootHook - clen up the driver in the event of a reboot or * control X event * * RETURNS * N/A */LOCAL void z85230RebootHook(int dummy){ int oldLevel; volatile UINT8* cr; Z85230_CHAN * channel;#ifdef _Z85230_DEBUG_ int i ; for(i=0; i<30; i++) { sysToggleLed(1); taskDelay(30); }#endif if( gZ85230DrvNum != ERROR ) {#ifdef VME_181 /* turn off the timer */ gtTmrDisable(SCC_TMR); gtTmrIntDisable(SCC_TMR_INT);#endif channel = gZ85230Channels[0] ; /* channel A */ cr = channel->hw.cr ; oldLevel = intLock(); /* disable interrupts */ REG_8530_WRITE( cr, SCC_WR0_SEL_WR1 ); REG_8530_WRITE( cr, 0 ); /* Reset */ REG_8530_WRITE(cr, SCC_WR0_SEL_WR9); REG_8530_WRITE( cr,SCC_WR9_HDWR_RST ); Z8530_RESET_DELAY; /* ensure the DMA semaphores are released *** commented aak semGive( gt.dmaQueueSem[ SCC_RXA_DMA_CHAN ] ); semGive( gt.dmaQueueSem[ SCC_TXA_DMA_CHAN ] ); */ intUnlock( oldLevel ); }}/*************************************************************************** * z85230DrvProtocolSet - set current protocol as specified * * RETURNS * N/A */static int z85230DrvProtocolSet( Z85230_CHAN * channel, int protocol ) { /* check protocol */ switch ( protocol ) { case Z85230_PROTOCOL_ASYNC: channel->protocol.protocol = protocol; channel->protocol.open = z85230AsyncOpen; channel->protocol.close = z85230AsyncClose; channel->protocol.read = z85230AsyncRead; channel->protocol.write = z85230AsyncWrite; channel->protocol.ioctl = z85230AsyncIoctl; channel->protocol.txInt = z85230AsyncTxInt; channel->protocol.rxInt = z85230AsyncRxInt; channel->protocol.exInt = z85230AsyncExInt;#ifdef VME_181 channel->protocol.rxDmaInt = z85230AsyncRxDmaInt; channel->protocol.txDmaInt = z85230AsyncTxDmaInt; channel->protocol.rxFpgaInt = z85230AsyncFpgaInt; channel->protocol.txFpgaInt = NULL; #else channel->protocol.rxFpgaInt = z85230AsyncRxFpgaInt; channel->protocol.txFpgaInt = z85230AsyncTxFpgaInt;#endif break; case Z85230_PROTOCOL_RHDLC: channel->protocol.protocol = protocol; channel->protocol.open = z85230RHDLCOpen; channel->protocol.close = z85230RHDLCClose; channel->protocol.read = z85230RHDLCRead; channel->protocol.write = z85230RHDLCWrite; channel->protocol.ioctl = z85230RHDLCIoctl; channel->protocol.txInt = z85230RHDLCTxInt; channel->protocol.rxInt = z85230RHDLCRxInt; channel->protocol.exInt = z85230RHDLCExInt; channel->protocol.rxDmaInt = z85230RHDLCRxDmaInt; /* dummy routine */ channel->protocol.txDmaInt = z85230RHDLCRxDmaInt; /* was z85230RHDLCTxDmaInt */ channel->protocol.rxFpgaInt = z85230RHDLCfpgaInt; channel->protocol.txFpgaInt = z85230RHDLCTxDmaInt; break;#ifdef INCLUDE_LAPB_Z8530 /* * LAPB protocol is not supported in the current release of the BSP */ case Z85230_PROTOCOL_LAPB: channel->protocol.protocol = protocol; channel->protocol.open = z85230LAPBOpen; channel->protocol.close = z85230LAPBClose; channel->protocol.read = z85230LAPBRead; channel->protocol.write = z85230LAPBWrite; channel->protocol.ioctl = z85230LAPBIoctl; channel->protocol.txInt = z85230LAPBTxInt; channel->protocol.rxInt = z85230LAPBRxInt; channel->protocol.exInt = z85230LAPBExInt; channel->protocol.rxDmaInt = z85230LAPBRxDmaInt; channel->protocol.txDmaInt = z85230LAPBTxDmaInt; break;#endif default: return Z85230_ERR_INVALID_PARAM; } return Z85230_OK; }/*************************************************************************** * z85230DrvInitialize - initialize driver * * RETURNS * N/A */LOCAL void z85230DrvInitialize( void * z85230BaseAddr, void * gtBaseAddr, Z85230_CHAN * chanA, Z85230_CHAN * chanB ) { int i;#ifndef VME_181 int size;#endif /* Initialize variables */ gZ85230Channels[ 0 ] = chanA; gZ85230Channels[ 1 ] = chanB; gZ85230Base = z85230BaseAddr; gZ85230Gt64130Base = gtBaseAddr; #ifndef VME_181 /* FPGA: Disable the FPGA ESCC facility */ sysOutLong ((UINT32)FPGA_SCC_CNTRL, 0x00); sysOutLong ((UINT32)FPGA_SCC_INT_CNTRL, 0x00); size = max(Z85230ASYNC_DEFAULT_BUFFERSIZE, Z85230RHDLC_DEFAULT_BUFFERSIZE); /* Allocate TX & RX buffers */ for (i = 0; i < Z85230_MAX_DESC; i++) { chanA->hw.txBuf[i] = (unsigned char *)cacheDmaMalloc(size); chanA->hw.rxBuf[i] = (unsigned char *)cacheDmaMalloc(size); chanB->hw.txBuf[i] = (unsigned char *)cacheDmaMalloc(size); chanB->hw.rxBuf[i] = (unsigned char *)cacheDmaMalloc(size); }#else /* FPGA: Disable the FPGA ESCC facility */ sysOutByte ((UINT32)FPGA_SCC_INT_CNTRL, 0x00 ); /* * Arbiter control register value * should be updated here sometime (aak) * gtDmaUpdateArbiter4_7() */ /* * Install interrupt handlers for the DMA engines * Note: interrupt priorities are currently defaults to 0 */ gtDmaIntConnect( SCC_RXA_DMA_INT, z85230DrvDmaRxAInt, SCC_RXA_DMA_INT, 0); gtDmaIntConnect( SCC_TXA_DMA_INT, z85230DrvDmaTxAInt, SCC_TXA_DMA_INT, 0); gtDmaIntConnect( SCC_RXB_DMA_INT, z85230DrvDmaRxBInt, SCC_RXB_DMA_INT, 0); gtDmaIntConnect( SCC_TXB_DMA_INT, z85230DrvDmaTxBInt, SCC_TXB_DMA_INT, 0);#endif /* Initialize z85230 */ for ( i = 0; i < Z85230_NUM_CHANNELS; i++ ) { Z85230_CHAN * channel = gZ85230Channels[ i ]; channel->hw.baudFreq = SBC_Z8530_CLK_FREQ; channel->hw.writeReg11 = SCC_WR11_RX_BR_GEN | SCC_WR11_TX_BR_GEN | SCC_WR11_OUT_BR_GEN; channel->hw.writeReg14 = SCC_WR14_BR_EN | SCC_WR14_BR_SRC | SCC_WR14_SRC_BR;#ifdef VME_181 channel->hw.intVec = INT_VEC_SCC;#else channel->hw.intVec = INT_SRC_SCC;#endif channel->hw.intType = SBC_Z8530_VEC_TYPE; channel->readSem = semCCreate( SEM_Q_FIFO, SEM_EMPTY ); Z85230_ASSERT( channel->readSem != NULL ); channel->writeSem = semCCreate( SEM_Q_FIFO, SEM_EMPTY ); Z85230_ASSERT( channel->writeSem != NULL ); }#ifdef VME_181 chanA->hw.dr = (char *)SBC_Z8530_A_DATA_REG; chanA->hw.cr = (char *)SBC_Z8530_A_CTRL_REG; chanA->hw.txfpga = (char *)FPGA_SCC_TXA_DATA; chanA->hw.rxfpga = (char *)FPGA_SCC_RXA_DATA; chanB->hw.dr = (char *)SBC_Z8530_B_DATA_REG; chanB->hw.cr = (char *)SBC_Z8530_B_CTRL_REG; chanB->hw.txfpga = (char *)FPGA_SCC_TXB_DATA; chanB->hw.rxfpga = (char *)FPGA_SCC_RXB_DATA;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -