⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 universedmavme_dy4.c

📁 Curtiss-Wright Controls Embedded Computing公司的cw183板bsp源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
     */    sem_result = semGive( vmeDmaMutexSem );    if( sem_result != OK )    {      logMsg ("sysVmeDmaLock: Cannot give Mutex semaphore\n",                  0, 0, 0, 0, 0, 0);      return( ERROR );    }    return( status );}/****************************************************************************** sysVmeDmaUnlock - unlock VME DMA transfer operation** This routine unlocks the VME DMA operation, if the calling task* has the lock. If <forceUnlock> is true, an unlock can be forced even* if the calling task does not possess the lock.** RETURNS: OK, or ERROR if unlock failed.** SEE ALSO: sysVmeDmaLock(), sysVmeDmaCopy(), sysVmeDmaSet(), sysVmeDmaClr()*/STATUS sysVmeDmaUnlock ( BOOL   forceUnlock ){    STATUS      status = ERROR;    STATUS      sem_result;    /*     * Check if the driver is initialised.     */    if( !vmeDmaInitialised )    {      if( universeDmaDebug )      {        logMsg( "VMEBus DMA not initialized!\n", 0, 0, 0, 0, 0, 0 );      }      return( ERROR );    }    /*     * Ensure that only one task is in this critical section at     * any one time.     */    sem_result = semTake( vmeDmaMutexSem, WAIT_FOREVER );    if( sem_result != OK )    {      logMsg ("sysVmeDmaUnlock: Cannot take Mutex semaphore\n",                  0, 0, 0, 0, 0, 0);      return( ERROR );    }    /*     * If either we own the lock (via the ID) or we are asking the lock to     * be forced, unlock the DMA.     */    if( forceUnlock || (vmeDmaLockId == taskIdSelf()) )    {      vmeDmaLockId = 0;      status = OK;    }    /*     * Give back the mutex to release other tasks to enter these critical     * sections.     */    sem_result = semGive( vmeDmaMutexSem );    if( sem_result != OK )    {      logMsg ("sysVmeDmaUnlock: Cannot give Mutex semaphore\n",                  0, 0, 0, 0, 0, 0);      return( ERROR );    }    return( status );}/****************************************************************************** sysVmeDmaCopy - copy blocks across the VMEbus using the DMA** This routine is used to copy blocks to or from VMEbus using the DMA. This* is a blocking DMA copy which waits for the DMA copy to complete before* returning to the calling task.** RETURNS: ERROR, or OK if data is transferred correctly.** SEE ALSO: sysVmeDmaSet(), sysVmeDmaGet(), sysVmeDmaLock()*/STATUS sysVmeDmaCopy  (                      char *      local_addr,     /* Local Address */                      char *      vme_addr,       /* VMEbus Address */                      UINT32      xfer_size,      /* transfersize in bytes */                      BOOL        to_vme          /* direction */                      ){    STATUS      status = ERROR;    STATUS      sem_result;    UINT32      temp;    /*     * Check if the driver is initialised.     */    if( !vmeDmaInitialised )    {      if( universeDmaDebug )        logMsg( "VMEBus DMA not initialized!\n", 0, 0, 0, 0, 0, 0 );      return( ERROR );    }    /*     * Ensure that only one task is in this critical section at     * any one time.     */    sem_result = semTake( vmeDmaMutexSem, WAIT_FOREVER );    if( sem_result != OK )    {      logMsg ("sysVmeDmaCopy: Cannot take Mutex semaphore\n",                  0, 0, 0, 0, 0, 0);      return( ERROR );    }    /*     * Ensure that the calling task owns the lock or there is no lock in     * place before continuing. An unowned lock is signified by the ID     * being 0.     */    if( (vmeDmaLockId != taskIdSelf()) &&        (vmeDmaLockId != 0) )    {      if( universeDmaDebug )        logMsg( "VMEBus DMA locked by another task!\n",                  0, 0, 0, 0, 0, 0 );      sem_result = semGive( vmeDmaMutexSem );      if( sem_result != OK )      {        logMsg ("sysVmeDmaCopy: Cannot give Mutex semaphore\n",                    0, 0, 0, 0, 0, 0);      }      return( ERROR );    }    /*     * Check to see if the size requested is within range.     */    if( xfer_size > 0x1000000 )    {      if( universeDmaDebug )        logMsg( "Requested VMEbus DMA transfer size too large!\n",                  0, 0, 0, 0, 0, 0 );      sem_result = semGive( vmeDmaMutexSem );      if( sem_result != OK )      {        logMsg ("sysVmeDmaCopy: Cannot give Mutex semaphore\n",                    0, 0, 0, 0, 0, 0);      }      return( ERROR );    }    /*     * Check the source and destination addresses are aligned to the same     * oct-byte boundary.     */    if( ((UINT32)local_addr & 0x7) != ((UINT32)vme_addr & 0x7) )    {      if( universeDmaDebug )        logMsg( "Src/Dest VMEbus DMA oct-byte boundaries not equal!\n",                  0, 0, 0, 0, 0, 0);      sem_result = semGive( vmeDmaMutexSem );      if( sem_result != OK )      {        logMsg ("sysVmeDmaCopy: Cannot give Mutex semaphore\n",                    0, 0, 0, 0, 0, 0);      }      return( ERROR );    }    /*     * Set local (PCI) Address.     */    *UNIVERSE_DLA = LONGSWAP( (UINT32)local_addr );    /*     * Set VME Address.     */    *UNIVERSE_DVA = LONGSWAP( (UINT32)vme_addr );    /*     * Set transfer size.     */    *UNIVERSE_DTBC = LONGSWAP( xfer_size );    /*     * Set transfer direction.     */    temp = LONGSWAP( *UNIVERSE_DCTL );    temp = (temp & ~DCTL_L2V) | ((to_vme ? 1 : 0) << 31);    *UNIVERSE_DCTL = LONGSWAP( temp );    /*     * If debug is enabled, tell the world what we are doing.     */    if( universeDmaDebug )    {      logMsg( "VMEBus DMA started\n", 0, 0, 0, 0, 0, 0 );      logMsg( "Local address   : %08x\n", (UINT32)local_addr, 0, 0, 0, 0, 0 );      logMsg( "VMEBus address  : %08x\n", (UINT32)vme_addr, 0, 0, 0, 0, 0 );      logMsg( "Transfer length : %08x\n", xfer_size, 0, 0, 0, 0, 0 );    }    /*     * Clear all status bits and start transfer.     */    temp = LONGSWAP( *UNIVERSE_DGCS );    temp = ( temp      |             DGCS_GO   |             DGCS_STOP |             DGCS_HALT |             DGCS_DONE |             DGCS_LERR |             DGCS_VERR |             DGCS_P_ERR );    *UNIVERSE_DGCS = LONGSWAP( temp );    /*     * The ISR reports the DMA interrupt has fired by returning this     * semaphore. If we get the semaphore back in time, it means that     * some portion of the DMA triggered an interrupt (good or bad).     */    if( semTake( vmeDmaSyncSem,                (MAX_SECONDS_FOR_DMA_COMPLETION * sysClkRateGet())) == ERROR )    {      /*       * Whoops!! There was no response from the DMA interrupt. We       * have timeout out! Kill the DMA transaction by setting the       * STOP_REQ bit.       */      temp = LONGSWAP( *UNIVERSE_DGCS );      temp = (temp | DGCS_STOP_REQ);      *UNIVERSE_DGCS = LONGSWAP( temp );      if( universeDmaDebug )      {        logMsg( "VMEBus DMA aborted due to timeout!\n", 0, 0, 0, 0, 0, 0 );      }      status = ERROR;    }    /*     * We got a DMA interrupt and now we must process the DMA status     * register for the results.     */    else    {      temp = LONGSWAP( *UNIVERSE_DGCS );      /*       * See if the DMA DONE bit is set. This indicates that a       * successfull transaction occured.       */      if( (temp & DGCS_DONE) == DGCS_DONE )      {        if( universeDmaDebug )        {          logMsg( "VMEBus DMA termination ok!\n", 0, 0, 0, 0, 0, 0 );        }        status = OK;      }      /*       * See if the LERR bit is set indicating a local (PCI) bus error.       */      if( (temp & DGCS_LERR) == DGCS_LERR )      {        if( universeDmaDebug )        {          logMsg( "VMEBus DMA error on PCI!\n", 0, 0, 0, 0, 0, 0 );        }        status = ERROR;      }      /*       * See if the VERR bit is set indicating a VMEbus error.       */      if( (temp & DGCS_VERR) == DGCS_VERR )      {        if( universeDmaDebug )        {          logMsg( "VMEBus DMA error on VME!\n", 0, 0, 0, 0, 0, 0 );        }        status = ERROR;      }      /*       * Check if DMA P_ERR bit is set indicating a ??? error.       */      if( (temp & DGCS_P_ERR) == DGCS_P_ERR )      {        if( universeDmaDebug )        {          logMsg( "VMEBus DMA error, misaligned transfer!\n",                    0, 0, 0, 0, 0, 0 );        }        status = ERROR;      }    }    /*     * Give back the mutex to release other tasks to enter these critical     * sections.     */    sem_result = semGive( vmeDmaMutexSem );    if( sem_result != OK )    {      logMsg ("sysVmeDmaCopy: Cannot give Mutex semaphore\n",                  0, 0, 0, 0, 0, 0);      return( ERROR );    }    return( status );}/****************************************************************************** sysVmeDmaConnect - connect a function to the DMA interrupt rountine.** The routine installs a terminal interrupt routine to the DMA interrupt* service routine. This is intended for use with the asynchronous DMA* function async_sysVmeDmaCopy().*** !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!* NOTE NOTE NOTE: The mixed use of blocking and non-blocking* DMA functions is NOT RECOMMENDED. If this is required, the* task using non-block calls MUST DISCONNECT the sysVmeDmaRoutine* after DMA use by connecting a NULL vector using the* sysVmeDmaConnect() function. This MUST be done BEFORE a* blocking call is used.* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!** !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!* NOTE NOTE NOTE: Since the user function is executing at* interrupt level, the user should be aware that this function* might have a significant impact on interrupt performance. It* is advisable to execute as little as possible in the user* function.* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!** RETURNS: OK** SEE ALSO: async_sysVmeDmaCopy(), async_sysVmeDmaExampleISR()*/STATUS sysVmeDmaConnect ( FUNCPTR routine ){    STATUS      sem_result;    /*     * Check if the driver is initialised.     */    if( !vmeDmaInitialised )    {      if( universeDmaDebug )        logMsg( "VMEBus DMA not initialized!\n", 0, 0, 0, 0, 0, 0 );      return( ERROR );    }    /*     * Ensure that only one task is in this critical section at     * any one time.     */    sem_result = semTake( vmeDmaMutexSem, WAIT_FOREVER );    if( sem_result != OK )    {      logMsg ("sysVmeDmaConnect: Cannot take Mutex semaphore\n",                  0, 0, 0, 0, 0, 0);      return( ERROR );    }    /*     * Ensure that the calling task owns the lock or there is no lock in     * place before continuing. An unowned lock is signified by the ID     * being 0.     */    if( (vmeDmaLockId != taskIdSelf()) &&        (vmeDmaLockId != 0) )    {      if( universeDmaDebug )        logMsg( "VMEBus DMA locked by another task!\n",                  0, 0, 0, 0, 0, 0 );      sem_result = semGive( vmeDmaMutexSem );      if( sem_result != OK )      {        logMsg ("sysVmeDmaConnect: Cannot give Mutex semaphore\n",                    0, 0, 0, 0, 0, 0);      }      return( ERROR );    }    /*     * Set the user defined ISR routine address.     */    sysVmeDmaRoutine = routine;    /*     * Give back the mutex to release other tasks to enter these critical     * sections.     */    sem_result = semGive( vmeDmaMutexSem );    if( sem_result != OK )    {      logMsg ("sysVmeDmaConnect: Cannot give Mutex semaphore\n",                  0, 0, 0, 0, 0, 0);      return( ERROR );    }    return (OK);}/****************************************************************************

⌨️ 快捷键说明

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