/* * ======== SPICC3200DMA_hwiFxn ======== * ISR for the SPI when we use the DMA is used. */ void SPICC3200DMA_hwiFxn(uintptr_t arg) { SPI_Transaction *msg; SPICC3200DMA_Object *object = ((SPI_Handle)arg)->object; SPICC3200DMA_HWAttrs const *hwAttrs = ((SPI_Handle)arg)->hwAttrs; uint32_t intCode = 0; DebugP_log1("SPI:(%p) interrupt context start", hwAttrs->baseAddr); intCode = MAP_SPIIntStatus(hwAttrs->baseAddr, false); if (intCode & SPI_INT_DMATX) { /* DMA finished transfering; clear & disable interrupt */ MAP_SPIIntDisable(hwAttrs->baseAddr, SPI_INT_DMATX); MAP_SPIIntClear(hwAttrs->baseAddr, SPI_INT_DMATX); } /* Determine if the TX & RX DMA channels have completed */ if ((object->transaction) && (MAP_uDMAChannelIsEnabled(hwAttrs->rxChannelIndex) == false) && (MAP_uDMAIntStatus() & (1 << hwAttrs->rxChannelIndex))) { MAP_SPIDisable(hwAttrs->baseAddr); MAP_SPICSDisable(hwAttrs->baseAddr); MAP_SPIIntDisable(hwAttrs->baseAddr, SPI_INT_DMARX); MAP_SPIIntClear(hwAttrs->baseAddr, SPI_INT_DMARX); MAP_SPIIntClear(hwAttrs->baseAddr, SPI_INT_EOW); /* * Clear any pending interrupt * As the TX DMA channel interrupt gets service, it may be possible * that the RX DMA channel finished in the meantime, which means * the IRQ for RX DMA channel is still pending... */ HwiP_clearInterrupt(hwAttrs->intNum); /* * Use a temporary transaction pointer in case the callback function * attempts to perform another SPI_transfer call */ msg = object->transaction; /* Indicate we are done with this transfer */ object->transaction = NULL; /* Release constraint since transaction is done */ Power_releaseConstraint(PowerCC3200_DISALLOW_DEEPSLEEP); DebugP_log2("SPI:(%p) DMA transaction: %p complete", hwAttrs->baseAddr, (uintptr_t)msg); object->transferCallbackFxn((SPI_Handle)arg, msg); } DebugP_log1("SPI:(%p) interrupt context end", hwAttrs->baseAddr); }
static void interrupt_handler() { uint32_t status = MAP_SPIIntStatus(GSPI_BASE,true); MAP_SPIIntClear(GSPI_BASE,SPI_INT_EOW); transfer_counter = (transfer_counter + DMA_SIZE) % BUFFER_SIZE; if(transfer_counter == 0) { transfer_mode = !transfer_mode; } if(transfer_mode == RX) { spi_transfer(tx_buffer,data_buffer + transfer_counter); } if(transfer_mode == TX) { spi_transfer(data_buffer + transfer_counter,rx_buffer); } if(!(status & SPI_INT_EOW)) { Message("Error: Unexpected SPI interrupt!\n\r"); while(1){}; } }
static void interrupt_handler() { uint32_t recv_data; uint32_t status; status = MAP_SPIIntStatus(GSPI_BASE,true); MAP_SPIIntClear(GSPI_BASE,SPI_INT_RX_FULL|SPI_INT_TX_EMPTY); if(status & SPI_INT_TX_EMPTY) { MAP_SPIDataPut(GSPI_BASE,tx_buffer[tx_count % TR_BUFF_SIZE]); tx_count++; } if(status & SPI_INT_RX_FULL) { MAP_SPIDataGetNonBlocking(GSPI_BASE,&recv_data); rx_buffer[rx_count % TR_BUFF_SIZE] = recv_data; rx_count++; } interrupt_count++; if(interrupt_count % (TR_BUFF_SIZE * 2) == 0 && interrupt_count > 0) { transfer_count++; } }
// ------------------------------------------------- // // 采样的控制 // // ------------------------------------------------- static void DMAIntHandler(void) { MAP_SPIIntClear(GSPI_BASE,SPI_INT_DMATX|SPI_INT_DMARX); //MAP_SPIDmaDisable(GSPI_BASE, SPI_RX_DMA | SPI_TX_DMA); unsigned long ulMode; ulMode = MAP_uDMAChannelModeGet(UDMA_CH30_GSPI_RX | UDMA_PRI_SELECT); if(ulMode == UDMA_MODE_STOP) { //MAP_SPIDmaDisable(GSPI_BASE, SPI_RX_DMA ); if (!s_bRxDone) { s_bRxDone = true; // 发送同步脉冲 READ_FROM_SPI; WRITE_TO_SPI; READ_FROM_SPI; // 发送最后一根线 if (s_nSampleIndex >= 129) { ISR_LineSend(s_ucFrame,127,s_pucRxRcv,512); } } } ulMode = MAP_uDMAChannelModeGet(UDMA_CH31_GSPI_TX | UDMA_PRI_SELECT); if(ulMode == UDMA_MODE_STOP) { //MAP_SPIDmaDisable(GSPI_BASE, SPI_TX_DMA ); } }
/*! \brief DMA SPI interrupt handler \param None \return None \note This function 1. Invoked when SPI Transaction Completes \warning */ void DmaSpiSwIntHandler() { MAP_SPIIntClear(LSPI_BASE,SPI_INT_EOW); MAP_SPICSDisable(LSPI_BASE); #if defined(SL_PLATFORM_MULTI_THREADED) osi_MsgQWrite(&DMAMsgQ,g_cDummy,OSI_NO_WAIT); #else g_cDummy = 0x1; #endif }
/* * ======== SPICC3200DMA_transfer ======== * @pre Function assumes that handle and transaction is not NULL */ bool SPICC3200DMA_transfer(SPI_Handle handle, SPI_Transaction *transaction) { uintptr_t key; SPICC3200DMA_Object *object = handle->object; SPICC3200DMA_HWAttrs const *hwAttrs = handle->hwAttrs; /* This is a limitation by the micro DMA controller */ if ((transaction->count == 0) || (transaction->count > 1024) || !(transaction->rxBuf || transaction->txBuf) || (!(transaction->rxBuf && transaction->txBuf) && !hwAttrs->scratchBufPtr)) { return (false); } /* Check if a transfer is in progress */ key = HwiP_disable(); if (object->transaction) { HwiP_restore(key); DebugP_log1("SPI:(%p) ERROR! Transaction still in progress", ((SPICC3200DMA_HWAttrs const *)(handle->hwAttrs))->baseAddr); return (false); } else { object->transaction = transaction; HwiP_restore(key); } /* Set constraints to guarantee transaction */ Power_setConstraint(PowerCC3200_DISALLOW_DEEPSLEEP); SPICC3200DMA_configDMA(handle, transaction); MAP_SPIIntClear(hwAttrs->baseAddr, SPI_INT_DMARX | SPI_INT_DMATX | SPI_INT_EOW); MAP_SPIIntEnable(hwAttrs->baseAddr, SPI_INT_DMARX | SPI_INT_DMATX | SPI_INT_EOW); MAP_SPIEnable(hwAttrs->baseAddr); MAP_SPICSEnable(hwAttrs->baseAddr); if (object->transferMode == SPI_MODE_BLOCKING) { DebugP_log1("SPI:(%p) transfer pending on transferComplete semaphore", ((SPICC3200DMA_HWAttrs const *)(handle->hwAttrs))->baseAddr); SemaphoreP_pend(object->transferComplete, SemaphoreP_WAIT_FOREVER); } return (true); }