/*! \brief attempts to read up to len bytes from SPI channel into a buffer starting at pBuff. \param pBuff - points to first location to start writing the data \param len - number of bytes to read from the SPI channel \return upon successful completion, the function shall return Read Size. Otherwise, -1 shall be returned \sa spi_Read_CPU , spi_Write_CPU \note \warning */ int spi_Read_CPU(unsigned char *pBuff, int len) { unsigned long ulCnt; unsigned long ulStatusReg; unsigned long *ulDataIn; unsigned long ulTxReg; unsigned long ulRxReg; MAP_SPICSEnable(LSPI_BASE); // // Initialize local variable. // ulDataIn = (unsigned long *)pBuff; ulCnt = (len + 3) >> 2; ulStatusReg = LSPI_BASE+MCSPI_O_CH0STAT; ulTxReg = LSPI_BASE + MCSPI_O_TX0; ulRxReg = LSPI_BASE + MCSPI_O_RX0; // // Reading loop // while(ulCnt--) { while(!( HWREG(ulStatusReg)& MCSPI_CH0STAT_TXS )); HWREG(ulTxReg) = 0xFFFFFFFF; while(!( HWREG(ulStatusReg)& MCSPI_CH0STAT_RXS )); *ulDataIn = HWREG(ulRxReg); ulDataIn++; } MAP_SPICSDisable(LSPI_BASE); return len; }
/* * ======== SPICC3200DMA_close ======== * @pre Function assumes that the handle is not NULL */ void SPICC3200DMA_close(SPI_Handle handle) { uintptr_t key; SPICC3200DMA_Object *object = handle->object; SPICC3200DMA_HWAttrs const *hwAttrs = handle->hwAttrs; MAP_SPIDisable(hwAttrs->baseAddr); MAP_SPICSDisable(hwAttrs->baseAddr); MAP_SPIDmaDisable(hwAttrs->baseAddr, SPI_RX_DMA | SPI_TX_DMA); MAP_SPIFIFODisable(hwAttrs->baseAddr, SPI_RX_FIFO | SPI_TX_FIFO); /* Release power dependency on SPI. */ Power_releaseDependency(getPowerMgrId(hwAttrs->baseAddr)); Power_releaseDependency(PowerCC3200_PERIPH_UDMA); Power_unregisterNotify(&(object->notifyObj)); if (object->hwiHandle) { HwiP_delete(object->hwiHandle); } if (object->transferComplete) { SemaphoreP_delete(object->transferComplete); } DebugP_log1("SPI:(%p) closed", hwAttrs->baseAddr); key = HwiP_disable(); object->isOpen = false; HwiP_restore(key); }
/* * ======== SPICC3200DMA_initHw ======== */ static void SPICC3200DMA_initHw(SPI_Handle handle) { SPICC3200DMA_Object *object = handle->object; SPICC3200DMA_HWAttrs const *hwAttrs = handle->hwAttrs; /* Configure the SPI peripheral */ MAP_SPICSDisable(hwAttrs->baseAddr); MAP_SPIDisable(hwAttrs->baseAddr); MAP_SPIReset(hwAttrs->baseAddr); /* * To support 4-32 bit lengths, object->dataSize must be formatted to meet * hardware requirement. */ MAP_SPIConfigSetExpClk(hwAttrs->baseAddr, MAP_PRCMPeripheralClockGet(hwAttrs->spiPRCM), object->bitRate, mode[object->spiMode], frameFormat[object->frameFormat], (hwAttrs->csControl | hwAttrs->pinMode | hwAttrs->turboMode | hwAttrs->csPolarity | ((object->dataSize - 1) << 7))); /* Enable FIFOs, DMA, & interrupts */ MAP_SPIFIFOEnable(hwAttrs->baseAddr, SPI_RX_FIFO | SPI_TX_FIFO); MAP_SPIDmaEnable(hwAttrs->baseAddr, SPI_RX_DMA | SPI_TX_DMA); MAP_SPIFIFOLevelSet(hwAttrs->baseAddr, object->txFifoTrigger, object->rxFifoTrigger); }
void CC3200Helpers_HibernateNowFor(unsigned long dwSeconds, char flStopSL) { unsigned long long qwTicks = dwSeconds; qwTicks *= SLOW_CLK_FREQ; MAP_PRCMHibernateIntervalSet(qwTicks); MAP_PRCMHibernateWakeupSourceEnable(PRCM_HIB_SLOW_CLK_CTR); MAP_UtilsDelay(80000); if ( flStopSL ) { sl_WlanDisconnect(); sl_Stop(0); } MAP_SPICSDisable(SSPI_BASE); MAP_SPICSEnable(SSPI_BASE); MAP_SPIDataPut(SSPI_BASE, 0xB9); // deep power down MAP_SPICSDisable(SSPI_BASE); MAP_PRCMHibernateEnter(); }
STATIC void pyb_sleep_flash_powerdown (void) { uint32_t status; // Enable clock for SSPI module MAP_PRCMPeripheralClkEnable(PRCM_SSPI, PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK); // Reset SSPI at PRCM level and wait for reset to complete MAP_PRCMPeripheralReset(PRCM_SSPI); while(!MAP_PRCMPeripheralStatusGet(PRCM_SSPI)); // Reset SSPI at module level MAP_SPIReset(SSPI_BASE); // Configure SSPI module MAP_SPIConfigSetExpClk (SSPI_BASE, PRCMPeripheralClockGet(PRCM_SSPI), 20000000, SPI_MODE_MASTER,SPI_SUB_MODE_0, (SPI_SW_CTRL_CS | SPI_4PIN_MODE | SPI_TURBO_OFF | SPI_CS_ACTIVELOW | SPI_WL_8)); // Enable SSPI module MAP_SPIEnable(SSPI_BASE); // Enable chip select for the spi flash. MAP_SPICSEnable(SSPI_BASE); // Wait for the spi flash do { // Send the status register read instruction and read back a dummy byte. MAP_SPIDataPut(SSPI_BASE, SPIFLASH_INSTR_READ_STATUS); MAP_SPIDataGet(SSPI_BASE, &status); // Write a dummy byte then read back the actual status. MAP_SPIDataPut(SSPI_BASE, 0xFF); MAP_SPIDataGet(SSPI_BASE, &status); } while ((status & 0xFF) == SPIFLASH_STATUS_BUSY); // Disable chip select for the spi flash. MAP_SPICSDisable(SSPI_BASE); // Start another CS enable sequence for Power down command. MAP_SPICSEnable(SSPI_BASE); // Send Deep Power Down command to spi flash MAP_SPIDataPut(SSPI_BASE, SPIFLASH_INSTR_DEEP_POWER_DOWN); // Disable chip select for the spi flash. MAP_SPICSDisable(SSPI_BASE); }
/* * ======== 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); }
/*! \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 }
/*! \brief closes an opened spi communication port \param fd - file descriptor of an opened SPI channel \return upon successful completion, the function shall return 0. Otherwise, -1 shall be returned \sa spi_Open \note \warning */ int spi_Close(Fd_t fd) { unsigned long ulBase = LSPI_BASE; g_SpiFd = 0; //Disable Chip Select MAP_SPICSDisable(LSPI_BASE); //Disable SPI Channel MAP_SPIDisable(ulBase); // Reset SPI MAP_SPIReset(ulBase); // Disable SPI Peripheral MAP_PRCMPeripheralClkDisable(PRCM_LSPI,PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK); return 0; }
Fd_t spi_Open(char *ifName, unsigned long flags) { unsigned long ulBase; unsigned long ulSpiBitRate = SPI_RATE_20M; //NWP master interface ulBase = LSPI_BASE; //Enable MCSPIA2 MAP_PRCMPeripheralClkEnable(PRCM_LSPI,PRCM_RUN_MODE_CLK | PRCM_SLP_MODE_CLK); //Disable Chip Select MAP_SPICSDisable(ulBase); //Disable SPI Channel MAP_SPIDisable(ulBase); // Reset SPI MAP_SPIReset(ulBase); // // Configure SPI interface // MAP_SPIConfigSetExpClk(ulBase,MAP_PRCMPeripheralClockGet(PRCM_LSPI), ulSpiBitRate,SPI_MODE_MASTER,SPI_SUB_MODE_0, (SPI_SW_CTRL_CS | SPI_4PIN_MODE | SPI_TURBO_OFF | SPI_CS_ACTIVEHIGH | SPI_WL_32)); MAP_SPIEnable(ulBase); g_SpiFd = 1; return g_SpiFd; }
/*! \brief closes an opened spi communication port \param fd - file descriptor of an opened SPI channel \return upon successful completion, the function shall return 0. Otherwise, -1 shall be returned \sa spi_Open \note \warning */ int spi_Close(Fd_t fd) { unsigned long ulBase = LSPI_BASE; g_SpiFd = 0; if(g_ucDMAEnabled) { #ifdef SL_PLATFORM_MULTI_THREADED osi_InterruptDeRegister(INT_LSPI); osi_MsgQDelete(&DMAMsgQ); #else MAP_SPIIntUnregister(ulBase); g_cDummy = 0; #endif MAP_SPIFIFODisable(ulBase,SPI_RX_FIFO); MAP_SPIFIFODisable(ulBase,SPI_TX_FIFO); MAP_SPIDmaDisable(ulBase,SPI_RX_DMA); MAP_SPIDmaDisable(ulBase,SPI_TX_DMA); } //Disable Chip Select MAP_SPICSDisable(LSPI_BASE); //Disable SPI Channel MAP_SPIDisable(ulBase); // Reset SPI MAP_SPIReset(ulBase); // Enable SPI Peripheral MAP_PRCMPeripheralClkDisable(PRCM_LSPI,PRCM_RUN_MODE_CLK|PRCM_SLP_MODE_CLK); return 0; }
Fd_t spi_Open(char *ifName, unsigned long flags) { unsigned long ulBase; unsigned long ulSpiBitRate; tROMVersion* pRomVersion = (tROMVersion *)(ROM_VERSION_ADDR); //NWP master interface ulBase = LSPI_BASE; //Enable MCSPIA2 MAP_PRCMPeripheralClkEnable(PRCM_LSPI,PRCM_RUN_MODE_CLK|PRCM_SLP_MODE_CLK); //Disable Chip Select MAP_SPICSDisable(ulBase); //Disable SPI Channel MAP_SPIDisable(ulBase); // Reset SPI MAP_SPIReset(ulBase); // // Configure SPI interface // if(pRomVersion->ucMinorVerNum == ROM_VER_PG1_21 ) { ulSpiBitRate = SPI_RATE_13M; } else if(pRomVersion->ucMinorVerNum == ROM_VER_PG1_32) { ulSpiBitRate = SPI_RATE_13M; } else if(pRomVersion->ucMinorVerNum >= ROM_VER_PG1_33) { ulSpiBitRate = SPI_RATE_20M; } MAP_SPIConfigSetExpClk(ulBase,MAP_PRCMPeripheralClockGet(PRCM_LSPI), ulSpiBitRate,SPI_MODE_MASTER,SPI_SUB_MODE_0, (SPI_SW_CTRL_CS | SPI_4PIN_MODE | SPI_TURBO_OFF | SPI_CS_ACTIVEHIGH | SPI_WL_32)); if(MAP_PRCMPeripheralStatusGet(PRCM_UDMA)) { g_ucDMAEnabled = (HWREG(UDMA_BASE + UDMA_O_CTLBASE) != 0x0) ? 1 : 0; } else { g_ucDMAEnabled = 0; } #ifdef SL_CPU_MODE g_ucDMAEnabled = 0; #endif if(g_ucDMAEnabled) { memset(g_ucDinDout,0xFF,sizeof(g_ucDinDout)); // Set DMA channel cc_UDMAChannelSelect(UDMA_CH12_LSPI_RX); cc_UDMAChannelSelect(UDMA_CH13_LSPI_TX); MAP_SPIFIFOEnable(ulBase,SPI_RX_FIFO); MAP_SPIFIFOEnable(ulBase,SPI_TX_FIFO); MAP_SPIDmaEnable(ulBase,SPI_RX_DMA); MAP_SPIDmaEnable(ulBase,SPI_TX_DMA); MAP_SPIFIFOLevelSet(ulBase,1,1); #if defined(SL_PLATFORM_MULTI_THREADED) osi_InterruptRegister(INT_LSPI, (P_OSI_INTR_ENTRY)DmaSpiSwIntHandler,INT_PRIORITY_LVL_1); MAP_SPIIntEnable(ulBase,SPI_INT_EOW); osi_MsgQCreate(&DMAMsgQ,"DMAQueue",sizeof(int),1); #else MAP_IntRegister(INT_LSPI,(void(*)(void))DmaSpiSwIntHandler); MAP_IntPrioritySet(INT_LSPI, INT_PRIORITY_LVL_1); MAP_IntEnable(INT_LSPI); MAP_SPIIntEnable(ulBase,SPI_INT_EOW); g_cDummy = 0x0; #endif } MAP_SPIEnable(ulBase); g_SpiFd = 1; return g_SpiFd; }