int spi_Read(Fd_t fd, unsigned char *pBuff, int len) { int read_size = 0; if(fd!=1 || g_SpiFd!=1) return -1; g_len = len; if(len>DMA_BUFF_SIZE_MIN && g_ucDMAEnabled) { #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); 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); 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 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; if(fd!=1 || g_SpiFd!=1) return -1; if(len>DMA_BUFF_SIZE_MIN && g_ucDMAEnabled) { #if defined(SL_PLATFORM_MULTI_THREADED) char temp[4]; #endif SetupDMASend(pBuff,len); 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; }
// 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; }