📄 diffdiofpga.c
字号:
/* diffDioFpga.c - Differential I/O driver for a fpga implementation *//************************************************************************** * * Copyright (c) 2005 Curtiss-Wright Controls, Inc. All rights * reserved. This Source Code is the Property of Curtiss-Wright * Controls, Inc. and can only be used in accordance with Source * Code License Agreement(s) of Curtiss-Wright Controls, Inc. or any * of its subsidiaries. * **************************************************************************//*modification history--------------------01d,08Nov05,tis -add support for SCP-124 -rename Discovery_II directory to Discovery_III CR#12835.01c,23Nov05,tis -added the function fpgaDifDioIntClear() to clear the DIFFDIO interrupts CR#12295. -updated the function difDioInit() to clear the pending interrupts properly and to return ERROR if the passed difSelect is zero or the passed DIFFIO lines belong to another CPU CR#12609. -updated the function difDioIntEnable() to prevent enabling Ints to uninitialized difDio lines CR#12609. -updated the function difDioIntDisable() to prevent disabling Ints to uninitialized difDio lines CR#12609. -updated the function difDioIntConnect() to return ERROR if the user attempt to connect an ISR to uninitialized difDio lines. or the passed ISR is NULL CR#12609. -updated the function difDioIntEdgeSet() to return error if the user attempts to set edge to uninitialized difDio lines or if the requested diffio bits which are enabled for interrupts CR#12609.01b,09Nov05,tis update the function difDioInit() with the right DIFFDIO macro CR#1228501a,01Mar05,rcd based difLib_dy4.c rev 01f. *//** DESCRIPTION** DIFIO for VME-183 & SCP-124 boards.* This module contains the subroutine library for the differential I/O.* The VME-183 provides 8 configurable differential input lines and* 8 configurable differential output lines. These signals are multiplexed* with the CH3, CH4, CH5, and CH6 SIO channels via software selection.* The HW imposes the constraint that the lines can only be configured* by groups of 2 input + 2 output lines (ie. one serial channel).** INCLUDE FILES: *//* BSP includes */#include "h/drv/dio/dio_dy4.h"#ifdef VME_183#include "fpga183.h"#endif#ifdef SCP_124#include "fpga124.h"#endif#if defined(SCP_124) || defined(VME_183) #include "h/drv/discovery_III/gtCore_dy4.h"#include "h/drv/discovery_III/gt644xx.h"#endif#ifdef __cplusplusextern "C" {#endif/* Local definitions */#define DIFFDIO_GROUP_ENABLE 0x3#define DIFFDIO_CHAN_ENABLE 0x1#define DIFFDIO_NUM_GROUPS 4#define DIFFDIO_GROUP_MASK 0x03/* globals *//* The DDIO lines that the user wants enabled (difDioInit) */uint8 ddioEnabled = 0;/* forward declarations */STATUS difDioIntDisable(UINT8);unsigned int getDifDioIntMask(void);LOCAL void difDioDefaultIsr(int diffio);/* external declarations*/IMPORT void bsm_wait(const UINT32 delay);/***************************************************************************** difDioInit - initialize the differential I/O device ** Description* This routine initializes the user specified differential I/O lines for use.** The VME-183 provides 8 differential input lines and 8 differential* output lines (each line consists of a 2 wire pair). The lines are grouped* into channels: 2 input + 2 output = 1 channel. These groups are multiplexed* with the CH3, CH4, CH5, and CH6 SIO channels via software selection.* The difSelect parameter specifies the bits user wants to use as* differential I/O pins the with constraint that the lines can only be configured* on a group by group basis.*** The groups of DIFF DIO lines are refered to as:** DIFF_DIO_GROUP1* DIFF_DIO_GROUP2* DIFF_DIO_GROUP3* DIFF_DIO_GROUP4** If group 1 is specified for DIFF DIO use then lines 0 & 1 will be configured and enabled.** INPUTS:* .iP <difSelect>* Differential IO Config Select parameter. Each bit represents a diff dio line.* 0 = Differential IO pairs are routed for serial communication devices.* 1 = Differential IO pairs are routed for DIFF IO.**======================================================================================================* Bits: | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0(Lsb)*------------------------------------------------------------------------------------------------------* Groups: | DIFF_DIO_GROUP4 | DIFF_DIO_GROUP3 | DIFF_DIO_GROUP2 | DIFF_DIO_GROUP1*------------------------------------------------------------------------------------------------------* Default: | 0 0 0 0 0 0 0 0*======================================================================================================** Examples:* To use the differential I/O pins from CH3 & CH4 make the following call in your application code:* difDioInit(DIFF_DIO_GROUP2 | DIFF_DIO_GROUP1)* Note that in this case CH3 & CH4 cannot be used for the serial * communication anymore.** To use all the differential I/O pins make the following call in your application code:* difDioInit(DIFF_DIO_GROUP4 | DIFF_DIO_GROUP3 | DIFF_DIO_GROUP2 | DIFF_DIO_GROUP1)* Note that in this case CH3 trough CH6 cannot be used for the serial * communication anymore.** RETURNS: OK if successful,otherwise returns ERROR if the passed difSelect is zero or the passed DIFFIO * lines belong to another CPU.**/STATUS difDioInit ( UINT8 difSelect /* diff. I/O group bits 0x3, 0xC, 0x30, 0xC0 */ ) { STATUS stat = ERROR; UINT8 readIntStat; UINT8 ddioCtrlNibble = 0; /* a nibble for the control register */ UINT8 tmp = 0; volatile int bitcount, checkbit; int lock,i; if( 0 == difSelect) { logMsg("ERROR: attempting to pass zero to difDioInit!\n",0,0,0,0,0,0); return(ERROR); } /* check if attempting to initialize DIFFIO lines not assigned for this CPU */ if(0 != (difSelect & (~ddioCpuConfig))) { logMsg("ERROR: attempting to initialize DIFFIO lines not assigned for this CPU!\n",0,0,0,0,0,0); return ERROR; } tmp = difSelect; for(i=0;i<DIFFDIO_NUM_GROUPS;i++) { if((tmp & DIFFDIO_GROUP_MASK) == DIFFDIO_GROUP_ENABLE) { /* the user wants this group enabled */ ddioEnabled |= (DIFFDIO_GROUP_ENABLE << (i*2)); ddioCtrlNibble |= (DIFFDIO_CHAN_ENABLE << i); } tmp = (tmp >> 2); } if (ddioEnabled > 0) stat = OK; else return ERROR; /* mask the interrupts from our CPU */ difDioIntDisable(ddioEnabled); lock = intLock(); /* Connect deafult DIFFIO ISR to all DIFFIO lines owned by this CPU*/ for (bitcount = 0; bitcount < DIF_LINES; bitcount++) { checkbit = (ddioEnabled & (1 << bitcount)) ? 1 : 0; if (checkbit == 1) { /* initialize the new handler */ intConnect ((void *)(FPGA_DIFFIO_0_INT_SRC + bitcount), (VOIDFUNCPTR) difDioDefaultIsr, bitcount); } } /* Clear all pending interrupts for fresh use by enabling the bits in the FPGA_DIFFDIO_INTENBL register * then writing 1 to each bit we use in the FPGA_DIFFDIO_INTSTAT register. Writing 0 has no effect */ sysOutByte((UINT32)FPGA_DIFFDIO_INTENBL, ddioEnabled ); sysOutByte ((UINT32)FPGA_DIFFDIO_INTSTAT, ddioEnabled ); readIntStat = sysInByte ((UINT32)FPGA_DIFFDIO_INTSTAT); /* check only our bits */ readIntStat &= ddioEnabled; if (readIntStat != 0) { logMsg ("difDioInit: Couldn't Clear Interrupts\n",0,0,0,0,0,0); intUnlock (lock); return (ERROR); } /* route the DIO lines in the FPGA */ tmp = sysInByte((UINT32)FPGA_DIFFDIO_ROUTE); tmp &= (~ddioEnabled); sysOutByte ((UINT32)FPGA_DIFFDIO_ROUTE, tmp); intUnlock (lock); /* enable diff dio output pairs and set interface to RS485 */ ddioCtrlNibble |= (ddioCtrlNibble << 4); /* Enable Diff DIO pair for each interface */ tmp = sysInByte((UINT32)FPGA_DIFFDIO_CTRL); tmp |= ddioCtrlNibble; sysOutByte ((UINT32)FPGA_DIFFDIO_CTRL, tmp); /* Allow HW to settle */ bsm_wait(10); /* Clear all pending interrupts generated by the routing process */ sysOutByte ((UINT32)FPGA_DIFFDIO_INTSTAT, ddioEnabled ); return(stat); }/***************************************************************************** difDioIntEnable - enable Differential I/O (Diff I/O) local interrupts** This routine enables the given Diff I/O interrupts by setting the* corresponding bits in the difMask register of the FPGA.** RETURNS: OK, or ERROR if the passed difMask contains uninitialized difDio lines.*** SEE ALSO: difDioIntDisable()**/STATUS difDioIntEnable ( UINT8 difMask /* interrupt bits 0..7 */ ) { int lock; int i; unsigned int stat; /* check if attempting to enable interrupts to uninitialized difDio lines on this CPU*/ if(0 != (difMask & (~ddioEnabled))) { logMsg("ERROR: attempting to enable interrupts to uninitialized difDio lines\n",0,0,0,0,0,0); return ERROR; } difMask &= ddioEnabled; lock = intLock (); for (i = 0; i < DIF_LINES; i++) { if (difMask & (1 << i)) stat = fpgaIntEnable(FPGA_DIFFIO_0_INT_SRC + i); } intUnlock (lock); return (OK); }/***************************************************************************** difDioIntDisable - disable Differential I/O (Diff I/O) local interrupts** This routine disables the given Differential I/O (Diff I/O) interrupts by clearing the* corresponding bits in the difMask register of the FPGA.** RETURNS: OK or ERROR if the passed difMask contains uninitialized difDio lines.** SEE ALSO: difDioIntEnable()*/STATUS difDioIntDisable ( UINT8 difMask /* interrupt bits 0..7 */ ) { int lock; int i; /* check if attempting to disable interrupts on DIFFIO lines not assigned for this CPU */ if(0 != (difMask & (~ddioEnabled))) { logMsg("ERROR: attempting to disable interrupts to uninitialized difDio lines\n",0,0,0,0,0,0); return ERROR; } difMask &= ddioEnabled; lock = intLock (); for (i = 0; i < DIF_LINES; i++) { if (difMask & (1 << i)) fpgaIntDisable(FPGA_DIFFIO_0_INT_SRC + i); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -