📄 diofpga.c
字号:
checkbit = (dioMask & (1 << bitcount)) ? 1 : 0; if (checkbit == 1) { /* initialize the new handler */ lock = intLock (); intConnect ((void *)(FPGA_DIO0_INT_SRC+bitcount), (VOIDFUNCPTR) dioRoutine, arg); intUnlock (lock); } } return (OK); }/***************************************************************************** dioWrite - Write the specified DIO Data lines to the specified value ** This routine writes the data passed in as <value> out to the DIO lines* specified by the dioMask parameter.** RETURNS: OK.** SEE ALSO: dioRead()*/STATUS dioWrite ( UINT32 dioMask, UINT32 value /* Value to write to the specified DIO data lines */ ) { uint16 dataRead; /* data read in from dio lines */ while(cpuSemGet(DIO_SEM_ID) != BSP_OK); /* read in data from register and store in dataReg */ dataRead = sysInWordNoSwap((UINT32)FPGA_DIO_DATA); dataRead &= ~(dioMask & dioCpuConfig); /* mask out bits affected */ value &= (dioMask & dioCpuConfig); value |= dataRead; /* OR value with the existing contents */ /* Write the value back to the register */ sysOutWordNoSwap((UINT32)FPGA_DIO_DATA,value); cpuSemFree(DIO_SEM_ID); return (OK);} /***************************************************************************** dioRead - Read the DIO Data and store at location pointed to by parameter** This routine reads the DIO Data register and stores the value at the * location given by the passed in pointer. All data will be returned so it is * the user's responsibility to mask out any unneeded Data bits.** RETURNS: OK.** SEE ALSO: dioWrite()*/STATUS dioRead ( UINT32 *pValue /* pointer to returned data */ ) { while(cpuSemGet(DIO_SEM_ID) != BSP_OK); *pValue = sysInWordNoSwap ((UINT32)FPGA_DIO_DATA); cpuSemFree(DIO_SEM_ID); return (OK); }/***************************************************************************** dioDirectionSet - Sets the direction of the specified DIO lines** This routine sets the direction bit for each DIO line specified in the mask.* Direction is determined by the passed in flag dioDirection. It can be * either INPUT or OUTPUT. ** RETURNS: OK if successful, ERROR if dioDirection is invalid or if user* attempts to change direction of bits which are enabled for interrupts,* or if the lines are assigned to another CPU**/STATUS dioDirectionSet ( UINT32 dioMask, int dioDirection ) { UINT16 readReg; UINT32 dioIntEnableMask; int lock; /* check if attempting to change direction of different CPU */ if(0 != (dioMask & (~dioCpuConfig))) { logMsg("ERROR: attempting to change direction of another CPU's DIO lines!\n",0,0,0,0,0,0); return ERROR; } /* check if attempting to change direction of lines which interrupts are enabled */ /* get current dio int enable mask */ dioIntEnableMask = sysInWordNoSwap((UINT32)FPGA_DIO_MSB_INTENBL) ; /* check which of these DIO interrupts enabled to this CPU */ dioIntEnableMask &= getDioIntMask(); /* Make sure not to change direction of DIO bits which have interrupts enabled */ if (0 != (dioMask & dioIntEnableMask)) { logMsg("ERROR: attempting to change direction of DIO bits which have interrupts enabled!\n",0,0,0,0,0,0); return ERROR; } while(cpuSemGet(DIO_SEM_ID) != BSP_OK); lock = intLock (); switch (dioDirection) { case INPUT: /* Set direction to INPUT - bits go to 0's */ readReg = sysInWordNoSwap ((UINT32)FPGA_DIO_MODE); readReg &= ~(dioMask & dioCpuConfig); sysOutWordNoSwap ((UINT32)FPGA_DIO_MODE, (UINT16)readReg); break; case OUTPUT: /* Set direction to OUTPUT - bits go to 1's */ readReg = sysInWordNoSwap ((UINT32)FPGA_DIO_MODE); readReg |= (dioMask & dioCpuConfig); sysOutWordNoSwap ((UINT32)FPGA_DIO_MODE, (UINT16)readReg); break; default : intUnlock (lock); cpuSemFree(DIO_SEM_ID); return (ERROR); } /* Need to clear any interrupts genrated by changing the DIO mode */ /* Make sure to enable dio interrupts from the DIO_INT_ENBL register to get visibility to the DIO_INT_STAT register. Note that interrupts are still masked in the CPU mask level */ sysOutWordNoSwap((UINT32)FPGA_DIO_MSB_INTENBL, dioMask); /* Clear interrupts in the STAT register */ sysOutWordNoSwap((UINT32)FPGA_DIO_MSB_INTSTAT, dioMask); intUnlock (lock); cpuSemFree(DIO_SEM_ID); return (OK); }/***************************************************************************** dioEdgeSet - sets the interrupt triggering edge of specified DIO lines** This routine sets the edge which will trigger an interrupt for each* Discrete I/O (DIO) line whose bit is set in the mask. The dioEdge flag * can be either RISING or FALLING. ** RETURNS: OK if successful, ERROR if dioEdge parameter is invalid or if the user* attempts to change triggering edge of bits which are enabled for interrupts,* or if the lines are assigned to another CPU**/STATUS dioEdgeSet ( UINT32 dioMask, int dioEdge ) { UINT16 readReg; int lock; UINT32 dioIntEnableMask; STATUS stat = OK; /* check if attempting to change triggering edge of different CPU */ if(0 != (dioMask & (~dioCpuConfig))) { logMsg("ERROR: attempting to change triggering edge of another CPU's DIO lines!\n",0,0,0,0,0,0); return ERROR; } /* check if attempting to change triggering edge of lines which interrupts are enabled */ /* get current dio int enable mask */ dioIntEnableMask = sysInWordNoSwap((UINT32)FPGA_DIO_MSB_INTENBL) ; /* check which of these DIO interrupts enabled to this CPU */ dioIntEnableMask &= getDioIntMask(); /* Make sure not to change triggering edge of DIO bits which have interrupts enabled */ if (0 != (dioMask & dioIntEnableMask)) { logMsg("ERROR: attempting to change triggering edge of DIO bits which have interrupts enabled!\n",0,0,0,0,0,0); return ERROR; } while(cpuSemGet(DIO_SEM_ID) != BSP_OK); lock = intLock (); switch (dioEdge) { case RISING: /* Interrupt on rising edge - set register bits to 1 */ readReg = sysInWordNoSwap ((UINT32)FPGA_DIO_EDGE); readReg |= (dioMask & dioCpuConfig); sysOutWordNoSwap ((UINT32)FPGA_DIO_EDGE, (UINT16)readReg); break; case FALLING: /* Interrupt on falling edge - set 0's in register bits */ readReg = sysInWordNoSwap ((UINT32)FPGA_DIO_EDGE); readReg &= ~(dioMask & dioCpuConfig); sysOutWordNoSwap ((UINT32)FPGA_DIO_EDGE, (UINT16)readReg); break; default : stat = ERROR; /* invalid dioEdge parameter */ } /* Need to clear any interrupts genrated by changing the triggering edg */ /* Make sure to enable dio interrupts from the DIO_INT_ENBL register to get visibility to the DIO_INT_STAT register. Note that interrupts are still masked in the CPU mask level */ sysOutWordNoSwap((UINT32)FPGA_DIO_MSB_INTENBL, dioMask); /* Clear interrupts in the STAT register */ sysOutWordNoSwap((UINT32)FPGA_DIO_MSB_INTSTAT, dioMask); intUnlock (lock); cpuSemFree(DIO_SEM_ID); return (stat); }/******************************************************************************** fpgaTimerIntClear - Clear FPGA dio INT** DESCRIPTION: Clear the FPGA dio INT by clearing the FPGA_DIO_MSB_INTSTAT register bit** INPUT:** RETURN:**/void fpgaDioIntClear(int dio){ sysOutWordNoSwap((ULONG)FPGA_DIO_MSB_INTSTAT, 1 << dio);}/******************************************************************************** dioDefaultIsr - DIO default ISR** DESCRIPTION:** INPUT:** RETURN:** NOMANUAL*/LOCAL void dioDefaultIsr(int dio){ logMsg("No interrupt handler attached to dio %d\n",dio,2,3,4,5,6) ;}#ifdef INCLUDE_SHOW_ROUTINES /* * int getDioIntMask(void) * * Get the DIO (IOFPGA 1 - 14) interrupt mask * */unsigned int getDioIntMask(void){ UINT32 mask; if(sysProcId==0) mask = sysInWordNoSwap((UINT32)FPGA_CPU0_DIO_MSB_INTMSK); else mask = sysInWordNoSwap((UINT32)FPGA_CPU1_DIO_MSB_INTMSK); return mask;}void dioShow(void){ UINT16 value; printf("Interrupt Mask Register 0x%X\n", getDioIntMask()); value = sysInWordNoSwap((UINT32)FPGA_DIO_MSB_INTSTAT); printf("Interrupt Status Register 0x%X\n", value); value = sysInWordNoSwap((UINT32)FPGA_DIO_MODE); printf("Mode/Direction Register 0x%X\n", value); value = sysInWordNoSwap((UINT32)FPGA_DIO_DATA); printf("Data Register 0x%X\n", value); value = sysInWordNoSwap((UINT32)FPGA_DIO_EDGE); printf("Interrupt Edge Register 0x%X\n", value);}#endif#ifdef __cplusplus}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -