/*! \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) { //Simplelink_UDMADeInit(); #ifdef SL_PLATFORM_MULTI_THREADED osi_InterruptDeRegister(INT_LSPI); osi_MsgQDelete(&DMAMsgQ); #else SPIIntUnregister(ulBase); g_cDummy = 0; #endif SPIFIFODisable(ulBase,SPI_RX_FIFO); SPIFIFODisable(ulBase,SPI_TX_FIFO); SPIDmaDisable(ulBase,SPI_RX_DMA); SPIDmaDisable(ulBase,SPI_TX_DMA); } //Disable Chip Select SPICSDisable(LSPI_BASE); //Disable SPI Channel SPIDisable(ulBase); // Reset SPI SPIReset(ulBase); // Enable SPI Peripheral PRCMPeripheralClkDisable(PRCM_LSPI,PRCM_RUN_MODE_CLK|PRCM_SLP_MODE_CLK); return 0; }
//***************************************************************************** // //! DMA SPI interrupt handler //! //! \param None //! //! This function //! 1. Invoked when SPI Transaction Completes //! //! \return None. // //***************************************************************************** void DmaSpiSwIntHandler() { SPIIntClear(LSPI_BASE,SPI_INT_EOW); SPICSDisable(LSPI_BASE); #if defined(SL_PLATFORM_MULTI_THREADED) osi_MsgQWrite(&DMAMsgQ,g_cDummy,OSI_NO_WAIT); #else g_cDummy = 0x1; #endif }
// Distinguishing write data, DC (GPIOA2_BASE) set to high void writeData(unsigned char c) { unsigned long ulDummy; GPIOPinWrite(GPIOA2_BASE, 0x40, 0x40); SPICSEnable(GSPI_BASE); SPIDataPut(GSPI_BASE, c); SPIDataGet(GSPI_BASE, &ulDummy); SPICSDisable(GSPI_BASE); }
/*! \brief attempts to write up to len bytes to the 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 write size. Otherwise, -1 shall be returned \sa spi_Read_CPU , spi_Write_CPU \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_CPU(unsigned char *pBuff, int len) { unsigned long ulCnt; unsigned long ulStatusReg; unsigned long *ulDataOut; unsigned long ulDataIn; unsigned long ulTxReg; unsigned long ulRxReg; //Enable Chip Select //HWREG(0x44022128)&=~1; SPICSEnable(LSPI_BASE); // // Initialize local variable. // ulDataOut = (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; // // Writing Loop // while(ulCnt--) { while(!( HWREG(ulStatusReg)& MCSPI_CH0STAT_TXS )); HWREG(ulTxReg) = *ulDataOut; while(!( HWREG(ulStatusReg)& MCSPI_CH0STAT_RXS )); ulDataIn = HWREG(ulRxReg); ulDataOut++; } //Disable Chip Select //HWREG(0x44022128)|= 1; SPICSDisable(LSPI_BASE); UNUSED(ulDataIn); return len; }
/*! \brief open spi communication port to be used for communicating with a SimpleLink device Given an interface name and option flags, this function opens the spi communication port and creates a file descriptor. This file descriptor can be used afterwards to read and write data from and to this specific spi channel. The SPI speed, clock polarity, clock phase, chip select and all other attributes are all set to hardcoded values in this function. \param ifName - points to the interface name/path. The interface name is an optional attributes that the simple link driver receives on opening the device. in systems that the spi channel is not implemented as part of the os device drivers, this parameter could be NULL. \param flags - option flags \return upon successful completion, the function shall open the spi channel and return a non-negative integer representing the file descriptor. Otherwise, -1 shall be returned \sa spi_Close , spi_Read , spi_Write \note \warning */ Fd_t spi_Open(char *ifName, unsigned long flags) { unsigned long ulBase; //NWP master interface ulBase = LSPI_BASE; //Enable MCSPIA2 PRCMPeripheralClkEnable(PRCM_LSPI,PRCM_RUN_MODE_CLK|PRCM_SLP_MODE_CLK); //Disable Chip Select SPICSDisable(ulBase); //Disable SPI Channel SPIDisable(ulBase); // Reset SPI SPIReset(ulBase); // // Configure SPI interface // SPIConfigSetExpClk(ulBase,PRCMPeripheralClockGet(PRCM_LSPI), SPI_IF_BIT_RATE,SPI_MODE_MASTER,SPI_SUB_MODE_0, (SPI_SW_CTRL_CS | SPI_4PIN_MODE | SPI_TURBO_OFF | SPI_CS_ACTIVEHIGH | SPI_WL_32)); if(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)); //g_ucDout[0]=0xFF; //Simplelink_UDMAInit(); // Set DMA channel cc_UDMAChannelSelect(UDMA_CH12_LSPI_RX); cc_UDMAChannelSelect(UDMA_CH13_LSPI_TX); SPIFIFOEnable(ulBase,SPI_RX_FIFO); SPIFIFOEnable(ulBase,SPI_TX_FIFO); SPIDmaEnable(ulBase,SPI_RX_DMA); SPIDmaEnable(ulBase,SPI_TX_DMA); SPIFIFOLevelSet(ulBase,1,1); #if defined(SL_PLATFORM_MULTI_THREADED) osi_InterruptRegister(INT_LSPI, (P_OSI_INTR_ENTRY)DmaSpiSwIntHandler,INT_PRIORITY_LVL_1); SPIIntEnable(ulBase,SPI_INT_EOW); osi_MsgQCreate(&DMAMsgQ,"DMAQueue",sizeof(int),1); #else IntRegister(INT_LSPI,(void(*)(void))DmaSpiSwIntHandler); IntPrioritySet(INT_LSPI, INT_PRIORITY_LVL_1); IntEnable(INT_LSPI); SPIIntEnable(ulBase,SPI_INT_EOW); g_cDummy = 0x0; #endif } SPIEnable(ulBase); g_SpiFd = 1; return g_SpiFd; }