Exemplo n.º 1
0
//*****************************************************************************
//
//! Does the actual Memory transfer
//!
//! \param ulChannel. DMA Channel to be used
//! \param ulMode. DMA Mode to be used
//! \param ulItemCount. Items to be transfered in DMA Transfer
//! \param ulArbSize. Arbitration Size to be set
//! \param pvSrcBuf. Pointer to the source Buffer
//! \param ulSrcInc. Source Increment
//! \param pvDstBuf. Pointer to the Destination Buffer
//! \param ulDstInc. Destination Increment
//!
//! This function
//!        1. Sets up the uDMA registers to perform the actual transfer
//!
//! \return None.
//
//*****************************************************************************
void SetupTransfer(unsigned long ulChannel,
                   unsigned long ulMode,
                   unsigned long ulItemCount,
                   unsigned long ulItemSize,
                   unsigned long ulArbSize,
                   void *pvSrcBuf,
                   unsigned long ulSrcInc,
                   void *pvDstBuf,
                   unsigned long ulDstInc)
{

    MAP_uDMAChannelControlSet(ulChannel,
                              ulItemSize | ulSrcInc | ulDstInc | ulArbSize);

    MAP_uDMAChannelAttributeEnable(ulChannel,UDMA_ATTR_USEBURST);

    MAP_uDMAChannelTransferSet(ulChannel, ulMode,
                               pvSrcBuf, pvDstBuf, ulItemCount);

    MAP_uDMAChannelEnable(ulChannel);

}
/*
 *  ======== CameraCC3200DMA_hwiIntFxn ========
 *  Hwi function that processes Camera interrupts.
 *
 *  The Frame end,DMA interrupts is enabled for the camera.
 *  The DMA interrupt is triggered for every 64 elements.
 *  The ISR will check for Frame end interrupt to trigger the callback
 *  in the non-blocking mode/post a semaphore in the blocking mode to
 *  indicate capture complete.
 *
 *  @param(arg)         The Camera_Handle for this Hwi.
 */
static void CameraCC3200DMA_hwiIntFxn(uintptr_t arg)
{
    uint32_t                     status;
    CameraCC3200DMA_Object        *object = ((Camera_Handle)arg)->object;
    CameraCC3200DMA_HWAttrs const *hwAttrs = ((Camera_Handle)arg)->hwAttrs;
    unsigned long **bufferPtr = (unsigned long**)&object->captureBuf;

    status = MAP_CameraIntStatus(hwAttrs->baseAddr);
    if ((object->cameraDMAxIntrRcvd > 1) && (status & (CAM_INT_FE))) {
        DebugP_log2("Camera:(%p) Interrupt with mask 0x%x",
               hwAttrs->baseAddr,status);

        MAP_CameraIntClear(hwAttrs->baseAddr, CAM_INT_FE);
        object->captureCallback((Camera_Handle)arg, *bufferPtr,
                                 object->frameLength);
        DebugP_log2("Camera:(%p) capture finished, %d bytes written",
                hwAttrs->baseAddr, object->frameLength);
        object->inUse = 0;

        MAP_CameraCaptureStop(hwAttrs->baseAddr, true);

        Power_releaseConstraint(PowerCC3200_DISALLOW_DEEPSLEEP);
    }

    if (status & CAM_INT_DMA) {
        // Camera DMA Done clear
        MAP_CameraIntClear(hwAttrs->baseAddr, CAM_INT_DMA);

        object->cameraDMAxIntrRcvd++;

        object->frameLength +=
         (CameraCC3200DMA_DMA_TRANSFER_SIZE*sizeof(unsigned long));
        if (object->frameLength < object->bufferlength) {
             if (object->cameraDMA_PingPongMode == 0) {
                MAP_uDMAChannelControlSet(hwAttrs->channelIndex,
                UDMA_SIZE_32 | UDMA_SRC_INC_32 | UDMA_DST_INC_32 | UDMA_ARB_8);

                MAP_uDMAChannelAttributeEnable(hwAttrs->channelIndex,
                                                 UDMA_ATTR_USEBURST);
                MAP_uDMAChannelTransferSet(hwAttrs->channelIndex,
                                           UDMA_MODE_PINGPONG,
                                           (void *)CAM_BUFFER_ADDR,
                                           (void *)*bufferPtr,
                                           CameraCC3200DMA_DMA_TRANSFER_SIZE);
                MAP_uDMAChannelEnable(hwAttrs->channelIndex);
                *bufferPtr += CameraCC3200DMA_DMA_TRANSFER_SIZE;
                object->cameraDMA_PingPongMode = 1;
            }
            else {
                MAP_uDMAChannelControlSet(hwAttrs->channelIndex | UDMA_ALT_SELECT,
                  UDMA_SIZE_32 | UDMA_SRC_INC_32 | UDMA_DST_INC_32 | UDMA_ARB_8);

                MAP_uDMAChannelAttributeEnable(
                    hwAttrs->channelIndex | UDMA_ALT_SELECT,
                    UDMA_ATTR_USEBURST);
                MAP_uDMAChannelTransferSet(
                    hwAttrs->channelIndex | UDMA_ALT_SELECT,
                    UDMA_MODE_PINGPONG,
                    (void *)CAM_BUFFER_ADDR, (void *)*bufferPtr,
                    CameraCC3200DMA_DMA_TRANSFER_SIZE);
                MAP_uDMAChannelEnable(hwAttrs->channelIndex | UDMA_ALT_SELECT);
                *bufferPtr += CameraCC3200DMA_DMA_TRANSFER_SIZE;
                object->cameraDMA_PingPongMode = 0;
            }
        }
        else {
            // Disable DMA
            MAP_UtilsDelay(20000);
            MAP_uDMAChannelDisable(hwAttrs->channelIndex);
            MAP_CameraIntDisable(hwAttrs->baseAddr, CAM_INT_DMA);
            object->cameraDMA_PingPongMode = 0;
            object->captureCallback((Camera_Handle)arg, *bufferPtr,
                                     object->frameLength);
            DebugP_log2("Camera:(%p) capture finished, %d bytes written",
                    hwAttrs->baseAddr, object->frameLength);

            MAP_CameraCaptureStop(hwAttrs->baseAddr, true);

            Power_releaseConstraint(PowerCC3200_DISALLOW_DEEPSLEEP);
        }
    }
}
/*
 *  ======== SPICC3200DMA_configDMA ========
 *  This functions configures the transmit and receive DMA channels for a given
 *  SPI_Handle and SPI_Transaction
 *
 *  @pre    Function assumes that the handle and transaction is not NULL
 */
static void SPICC3200DMA_configDMA(SPI_Handle handle, SPI_Transaction *transaction)
{
    uintptr_t                   key;
    SPIDataType                 dummy;
    void                       *buf;
    uint32_t                    channelControlOptions;
    SPICC3200DMA_Object        *object = handle->object;
    SPICC3200DMA_HWAttrs const *hwAttrs = handle->hwAttrs;

    /* Clear out the FIFO */
    while (MAP_SPIDataGetNonBlocking(hwAttrs->baseAddr, &dummy)) {}

    /* Configure DMA for RX */
    MAP_uDMAChannelAssign(hwAttrs->rxChannelIndex);
    MAP_uDMAChannelAttributeDisable(hwAttrs->rxChannelIndex, UDMA_ATTR_ALTSELECT);

    if (transaction->rxBuf) {
        channelControlOptions = dmaRxConfig[object->frameSize];
        buf = transaction->rxBuf;
    }
    else {
        channelControlOptions = dmaNullConfig[object->frameSize];
        buf = hwAttrs->scratchBufPtr;
    }
    MAP_uDMAChannelControlSet(hwAttrs->rxChannelIndex | UDMA_PRI_SELECT,
                              channelControlOptions);
    MAP_uDMAChannelTransferSet(hwAttrs->rxChannelIndex | UDMA_PRI_SELECT,
                               UDMA_MODE_BASIC,
                               (void *)(hwAttrs->baseAddr + MCSPI_O_RX0),
                               buf,
                               transaction->count);

    /* Configure DMA for TX */
    MAP_uDMAChannelAssign(hwAttrs->txChannelIndex);
    MAP_uDMAChannelAttributeDisable(hwAttrs->txChannelIndex, UDMA_ATTR_ALTSELECT);

    if (transaction->txBuf) {
        channelControlOptions = dmaTxConfig[object->frameSize];
        buf = transaction->txBuf;
    }
    else {
        channelControlOptions = dmaNullConfig[object->frameSize];
        *hwAttrs->scratchBufPtr = hwAttrs->defaultTxBufValue;
        buf = hwAttrs->scratchBufPtr;
    }
    MAP_uDMAChannelControlSet(hwAttrs->txChannelIndex | UDMA_PRI_SELECT,
                              channelControlOptions);
    MAP_uDMAChannelTransferSet(hwAttrs->txChannelIndex | UDMA_PRI_SELECT,
                               UDMA_MODE_BASIC,
                               buf,
                               (void *)(hwAttrs->baseAddr + MCSPI_O_TX0),
                               transaction->count);

    DebugP_log1("SPI:(%p) DMA transfer enabled", hwAttrs->baseAddr);
    DebugP_log4("SPI:   DMA transaction: %p, rxBuf: %p; txBuf: %p; Count: %d",
                (uintptr_t)transaction, (uintptr_t)transaction->rxBuf,
                (uintptr_t)transaction->txBuf, (uintptr_t)transaction->count);

    key = HwiP_disable();
    MAP_uDMAChannelEnable(hwAttrs->rxChannelIndex);
    MAP_uDMAChannelEnable(hwAttrs->txChannelIndex);
    HwiP_restore(key);

    MAP_SPIWordCountSet(hwAttrs->baseAddr, transaction->count);
}