예제 #1
0
파일: cc_pal.c 프로젝트: Cherduke/Energia
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;
}
예제 #2
0
/*!
    \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;
}
예제 #3
0
파일: cc_pal.c 프로젝트: Cherduke/Energia
/*!
    \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;
}
예제 #4
0
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();
}