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

📄 universedmavme_dy4.c

📁 Curtiss-Wright Controls Embedded Computing公司的cw183板bsp源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
** async_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 non-blocking DMA copy which does not wait for the DMA copy to complete* before returning to the calling task.*** !!! NOTE --- NOTE --- NOTE --- NOTE --- NOTE --- NOTE --- NOTE !!!** The user MUST install a user defined DMA interrupt handler via the* sysVmeDmaConnect() function in order for this function to work* properly.** !!! NOTE --- NOTE --- NOTE --- NOTE --- NOTE --- NOTE --- NOTE !!!** !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!* 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: ERROR, or OK if data is transferred correctly.** SEE ALSO: sysVmeDmaSet(), sysVmeDmaGet(), sysVmeDmaLock(),*           sysVmeDmaConnect(), async_sysVmeDmaExampleISR()*/STATUS async_sysVmeDmaCopy  (                      char *      local_addr,     /* Local Address */                      char *      vme_addr,       /* VMEbus Address */                      UINT32      xfer_size,      /* transfersize in bytes */                      BOOL        to_vme          /* direction */                      ){    UINT32      temp;    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 );    }    /*     * Check that the user has actually attached a return function.     * If not, clear out with an error.     */    if (sysVmeDmaRoutine == NULL)    {      if( universeDmaDebug )        logMsg ("No VMEbus DMA interrupt function connected\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 ("async_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 ("async_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 ("async_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 ("async_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 );    /*     * DMA should be running.     */    return (OK);}/****************************************************************************** async_sysVmeDmaExampleISR - default VMEbus DMA interrupt function for async** This function is an example of how an asynchronous DMA ISR function* might look. It uses the global variable sysVmeDmaLastAsyncStatus to record* the status of the last asynchronous transfer. This global status word can* be accessed using the sysVmeDmaGetLastAsyncStatus() function.** This routine may be connected to the async DMA function using the* sysVmeDmaConnect().*** RETURNS: none** SEE ALSO: async_sysVmeDmaCopy(), sysVmeDmaConnect(),*           sysVmeDmaGetLastAsyncStatus()*/void async_sysVmeDmaExampleISR ( void ){    UINT32      temp;    temp = LONGSWAP( *UNIVERSE_DGCS );    /*     * See if the DMA DONE bit is set. This indicates that a     * successfull transaction has occured.     */    if( (temp & DGCS_DONE) == DGCS_DONE )    {      if( universeDmaDebug )      {        logMsg( "VMEBus DMA termination ok!\n", 0, 0, 0, 0, 0, 0 );      }      sysVmeDmaSetLastAsyncStatus( 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 );      }      sysVmeDmaSetLastAsyncStatus( 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 );      }      sysVmeDmaSetLastAsyncStatus( 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 );      }      sysVmeDmaSetLastAsyncStatus( ERROR );    }}/****************************************************************************** sysVmeDmaGetLastAsyncStatus - get the status of the last async DMA transfer*** RETURNS: STATUS of last async DMA transfer** NOMANUAL*/STATUS sysVmeDmaGetLastAsyncStatus ( void ){    return( sysVmeDmaLastAsyncStatus );}/****************************************************************************** sysVmeDmaSetLastAsyncStatus - set the status of the last async DMA transfer*** RETURNS: STATUS of last async DMA transfer** NOMANUAL*/STATUS sysVmeDmaSetLastAsyncStatus ( STATUS last_status ){    sysVmeDmaLastAsyncStatus = last_status;    return( sysVmeDmaLastAsyncStatus );}/****************************************************************************** sysVmeDmaIsAsyncDone - check to see if an asynchronous DMA transfer has*                        completed.** Timeout value is in seconds.** If timeout is set to 0, the function tests the semaphore immediately* with no waiting. This can be used to poll the result.** RETURNS: OK or ERROR** NOMANUAL*/STATUS sysVmeDmaIsAsyncDone( UINT32 timeout  ){    STATUS    sem_result;    UINT32    temp;    /*     * Wait for the DMA to finish. If timeout is set to 0, don't wait.     * This is intended to be used as a poll operation.     */    if( timeout == 0 )      sem_result = semTake( vmeDmaSyncSem, NO_WAIT );    else      sem_result = semTake( vmeDmaSyncSem, (timeout * sysClkRateGet()) );    /*     * Check on the results of trying to get the semaphore. It could be     * either a timeout or a real error.     */    if( sem_result != OK )    {      /*       * Check for a polled "not done" condition. Currently, don't do       * anything when this is detected.       */      if( errno == S_objLib_OBJ_UNAVAILABLE )      {        /* logMsg ("sysVmeDmaIsAsyncDone: Polled 'not done'\n",                    0, 0, 0, 0, 0, 0); */      }      /*       * We did not get an OK (indicating completion) and we did       * not get S_objLib_OBJ_UNAVAILABLE (indicating not completed).       * Therefore, something serious happened and we must see what.       * We should release the mutex in this case.       */      else      {        /*         * Check for a time out. If so and the debug flag is active, print         * a message.         */        if( errno == S_objLib_OBJ_TIMEOUT )        {          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 );          }        }        /*         * If it was not a timeout or a poll "not done", we must not have been         * able to get the binary semaphore. Report this error.         */        else        {          logMsg ("sysVmeDmaIsAsyncDone: Cannot take Binary semaphore\n",                      0, 0, 0, 0, 0, 0);        }        /*         * We have an irreconcilable problem. Give back the mutex to release         * other tasks to enter these critical sections.         */        sem_result = semGive( vmeDmaMutexSem );        if( sem_result != OK )        {          logMsg ("sysVmeDmaIsAsyncDone: Cannot give Mutex semaphore\n",                      0, 0, 0, 0, 0, 0);        }        /* DEBUG */        /* logMsg ("sysVmeDmaIsAsyncDone: Released Mutex semaphore (error condition)\n",                    0, 0, 0, 0, 0, 0); */      }      return( ERROR );    }    /*     * If we got here, the DMA operation has finished.     */    /*     * Give back the mutex to release other tasks to enter these critical     * sections.     */    sem_result = semGive( vmeDmaMutexSem );    if( sem_result != OK )    {      logMsg ("sysVmeDmaIsAsyncDone: Cannot give Mutex semaphore\n",                  0, 0, 0, 0, 0, 0);      return( ERROR );    }    /* DEBUG */    /* logMsg ("sysVmeDmaIsAsyncDone: Released Mutex semaphore\n",                0, 0, 0, 0, 0, 0); */    return( OK );}

⌨️ 快捷键说明

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