int spi_Read(Fd_t fd, unsigned char *pBuff, int len) { int read_size = 0; unsigned int pBuffAddr = (unsigned int)pBuff; if(fd!=1 || g_SpiFd!=1) return -1; if(len>DMA_BUFF_SIZE_MIN && g_ucDMAEnabled && ((pBuffAddr % 4) == 0)) { #if defined(SL_PLATFORM_MULTI_THREADED) char temp[4]; #endif while (len>0) { if( len < MAX_DMA_RECV_TRANSACTION_SIZE) { SetupDMAReceive(&pBuff[read_size],len); MAP_SPICSEnable(LSPI_BASE); #if defined(SL_PLATFORM_MULTI_THREADED) osi_MsgQRead(&DMAMsgQ,temp,OSI_WAIT_FOREVER); #else while(g_cDummy != 0x1); g_cDummy = 0x0; #endif read_size += len; len = 0; } else { SetupDMAReceive(&pBuff[read_size],MAX_DMA_RECV_TRANSACTION_SIZE); MAP_SPICSEnable(LSPI_BASE); #if defined(SL_PLATFORM_MULTI_THREADED) osi_MsgQRead(&DMAMsgQ,temp,OSI_WAIT_FOREVER); #else while(g_cDummy != 0x1); g_cDummy = 0x0; #endif read_size += MAX_DMA_RECV_TRANSACTION_SIZE; len -= MAX_DMA_RECV_TRANSACTION_SIZE; } } } else { read_size += spi_Read_CPU(pBuff,len); } return read_size; }
/*! \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; }
/*! \brief attempts to write up to len bytes to the SPI channel \param fd - file descriptor of an opened SPI channel \param pBuff - points to first location to start getting the data from \param len - number of bytes to write to the SPI channel \return upon successful completion, the function shall return 0. Otherwise, -1 shall be returned \sa spi_Open , spi_Read \note This function could be implemented as zero copy and return only upon successful completion of writing the whole buffer, but in cases that memory allocation is not too tight, the function could copy the data to internal buffer, return back and complete the write in parallel to other activities as long as the other SPI activities would be blocked untill the entire buffer write would be completed \warning */ int spi_Write(Fd_t fd, unsigned char *pBuff, int len) { int write_size = 0; unsigned int pBuffAddr = (unsigned int)pBuff; if(fd!=1 || g_SpiFd!=1) return -1; if(len>DMA_BUFF_SIZE_MIN && g_ucDMAEnabled && ((pBuffAddr % 4) == 0)) { #if defined(SL_PLATFORM_MULTI_THREADED) char temp[4]; #endif SetupDMASend(pBuff,len); MAP_SPICSEnable(LSPI_BASE); #if defined(SL_PLATFORM_MULTI_THREADED) osi_MsgQRead(&DMAMsgQ,temp,OSI_WAIT_FOREVER); #else while(g_cDummy != 0x1); g_cDummy = 0x0; #endif write_size += len; } else { write_size += spi_Write_CPU(pBuff,len); } return write_size; }
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); }
void SampleInit(void) { /* //UDMAInit(); // Reset SPI //MAP_SPIReset(GSPI_BASE); MAP_SPIConfigSetExpClk(GSPI_BASE,MAP_PRCMPeripheralClockGet(PRCM_GSPI), SPI_IF_BIT_RATE,SPI_MODE_MASTER,SPI_SUB_MODE_3, (SPI_HW_CTRL_CS | SPI_4PIN_MODE | SPI_TURBO_ON| SPI_CS_ACTIVELOW | SPI_WL_8)); MAP_SPIEnable(GSPI_BASE); MAP_SPICSEnable(GSPI_BASE); MAP_SPIFIFOEnable(GSPI_BASE,SPI_RX_FIFO); MAP_SPIFIFOEnable(GSPI_BASE,SPI_TX_FIFO); SPIFIFOLevelSet(GSPI_BASE,1,1); MAP_SPIIntEnable(GSPI_BASE,SPI_INT_DMARX|SPI_INT_DMATX); //MAP_SPIIntEnable(GSPI_BASE,SPI_INT_DMATX); //MAP_SPIIntRegister(GSPI_BASE,DMAIntHandler); osi_InterruptRegister(INT_GSPI, DMAIntHandler, 32); */ UDMAInit(); MAP_SPIConfigSetExpClk(GSPI_BASE,MAP_PRCMPeripheralClockGet(PRCM_GSPI), SPI_IF_BIT_RATE,SPI_MODE_MASTER,SPI_SUB_MODE_3, (SPI_HW_CTRL_CS | SPI_4PIN_MODE | SPI_TURBO_ON| SPI_CS_ACTIVEHIGH | SPI_WL_8)); MAP_SPIEnable(GSPI_BASE); MAP_SPICSEnable(GSPI_BASE); MAP_SPIFIFOEnable(GSPI_BASE,SPI_RX_FIFO); MAP_SPIFIFOEnable(GSPI_BASE,SPI_TX_FIFO); SPIFIFOLevelSet(GSPI_BASE,1,1); MAP_SPIIntEnable(GSPI_BASE,SPI_INT_DMARX); //MAP_SPIIntEnable(GSPI_BASE,SPI_INT_DMATX); //MAP_SPIIntRegister(GSPI_BASE,DMAIntHandler); osi_InterruptRegister(INT_GSPI, DMAIntHandler, 32); }
/* * ======== 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); }
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(); }