//========================================================================= //函数名称:spi_send //函数参数:spin:SPI通道号。 // data[]:需要发送的数据。 // len:数据长度。 //函数返回:无 //功能概要:SPI发送数据。 //========================================================================= void spi_send(SPIn spin,u8 data[],u32 len) { u32 i = 0; u8 temp; SPI_TX_WAIT(spin); do { /************* 清标志位 ***************/ SPI_SR_REG(SPIN[spin]) = (SPI_SR_EOQF_MASK | SPI_SR_TFUF_MASK | SPI_SR_TFFF_MASK | SPI_SR_RFOF_MASK | SPI_SR_RFDF_MASK ); /************** 清FIFO计数器 **************/ SPI_MCR_REG(SPIN[spin]) |= (SPI_MCR_CLR_TXF_MASK //Clear TX FIFO.写1清 Tx FIFO counter |SPI_MCR_CLR_RXF_MASK //Clear RX FIFO. 写1清 the Rx FIFO counter. ); //SPI_SR_REG(SPIN[spin]) |= SPI_SR_RFDF_MASK; }while( (SPI_SR_REG(SPIN[spin]) & SPI_SR_RFDF_MASK)); //如果 Rx FIFO 非空,则清FIFO. /***************** 发送len-1个数据 *******************/ ; for(i = 0;i < (len-1);i++) { //DELAY_MS(1); SPI_PUSHR_REG(SPIN[spin]) = 0 | SPI_PUSHR_CONT_MASK //Continuous Peripheral Chip Select Enable,1为 传输期间保持PCSn信号 ,即继续传输数据 | SPI_PUSHR_CTAS(0) | SPI_PUSHR_TXDATA(data[i]); //要传输的数据 while( !(SPI_SR_REG(SPIN[spin]) & SPI_SR_RFDF_MASK)); //RFDF为1,Rx FIFO is not empty. temp = (u8)SPI_POPR_REG(SPIN[spin]); //读取一次接收的数据 SPI_SR_REG(SPIN[spin]) |= SPI_SR_RFDF_MASK; } /***************** 发送最后一个数据 *******************/ SPI_PUSHR_REG(SPIN[spin]) = 0 | SPI_PUSHR_CTAS(0) | SPI_PUSHR_EOQ_MASK //End Of Queue,1为 传输SPI最后的数据 | SPI_PUSHR_TXDATA(data[i]); SPI_EOQF_WAIT(spin); //要及时把RX FIFO的东西清掉,不然这里就无限等待 while( !(SPI_SR_REG(SPIN[spin]) & SPI_SR_RFDF_MASK)); //RFDF为1,Rx FIFO is not empty. temp = (u8)SPI_POPR_REG(SPIN[spin]); //读取一次接收的数据 //SPI_SR_REG(SPIN[spin]) |= SPI_SR_RFDF_MASK; }
//========================================================================= //函数名称:spi_re //函数参数:spin:SPI通道号。 // data[]:需要接收的数据。 //函数返回:返回接收到字节的长度 //功能概要:SPI接收数据。 //========================================================================= u32 spi_re(SPIn spin,u8 data[]) { u32 n=0; while(SPI_SR_REG(SPIN[spin]) & SPI_SR_RFDF_MASK) //RFDF为1,Rx FIFO is not empty. { data[n++] = (u8)SPI_POPR_REG(SPIN[spin]); //保存接收到的数据 SPI_SR_REG(SPIN[spin]) |= SPI_SR_RFDF_MASK; } /************* 清标志位 ***************/ SPI_SR_REG(SPIN[spin]) = (SPI_SR_EOQF_MASK | SPI_SR_TFUF_MASK | SPI_SR_TFFF_MASK | SPI_SR_RFOF_MASK | SPI_SR_RFDF_MASK ); /************** 清FIFO计数器 **************/ SPI_MCR_REG(SPIN[spin]) |= (SPI_MCR_CLR_TXF_MASK //Clear the Tx FIFO counter. |SPI_MCR_CLR_RXF_MASK //Clear the Rx FIFO counter. ); return n; //n为0,则没接收到数据 }
/* ******************************************************************************* *uint8_t Spi0MasteTxRxByte( SPI_MemMapPtr base, uint8_t tx_byte) ******************************************************************************* * Input : character to send * Output : received byte * Description : Wait for space in the SPI0 Tx FIFO and then send a character * Check if character is available in RX FIFO and return it ******************************************************************************** */ uint8_t SpiMasterTxRxByte( SPI_MemMapPtr base, uint8_t tx_byte) { uint8_t recv_byte = 0; //wait till TX FIFO is Empty. while((SPI_SR_REG(base) & SPI_SR_TFFF_MASK) != TX_FIFO_EMPTY); // Transmit Byte on SPI SPI_PUSHR_REG(base) = (uint32_t)tx_byte; //--> Wait till transmit complete while (((SPI_SR_REG(base) & SPI_SR_TCF_MASK)) != SPI_SR_TCF_MASK); //--> Clear Transmit Flag. SPI_SR_REG(base) |= (uint32_t)SPI_SR_TFFF_MASK; //wait till RX_FIFO is full while((SPI_SR_REG(base) & SPI_SR_RFDF_MASK) != RX_FIFO_EMPTY); //Read character from receiver recv_byte = (uint8_t)SPI_POPR_REG(base); //-->Clear the RX FIFO Drain Flag SPI_SR_REG(base) |= (uint32_t)SPI_SR_RFDF_MASK; return(recv_byte); }// End of Spi0MasteTxRxByte
/** * @brief SPI接收数据 * * @param spino SPI通道号 * @param data[] 需要发送的数据 * * @return 1 成功 * @return 0 失败 */ uint8_t spi_rcv(uint8_t spino, uint8_t data[]) { SPI_MemMapPtr base_addr = spi_get_base_address(spino); if(SPI_SR_REG(base_addr) & SPI_SR_RFDF_MASK) /* Rx FIFO is not empty */ { data[0] = (uint8_t)SPI_POPR_REG(base_addr); /* Received Data */ SPI_SR_REG(base_addr) |= SPI_SR_RFDF_MASK; /* The RFDF bit can be cleared by writing 1 */ return 1; } SPI_SR_REG(base_addr) = (SPI_SR_EOQF_MASK | SPI_SR_TFUF_MASK | SPI_SR_TFFF_MASK | SPI_SR_RFOF_MASK | SPI_SR_RFDF_MASK); SPI_MCR_REG(base_addr) |= SPI_MCR_CLR_TXF_MASK /* Clear the Tx FIFO counter. */ | SPI_MCR_CLR_RXF_MASK; /* Clear the Rx FIFO counter. */ return 0; }
OSStatus spi_transfer( spi_driver_t* spi_driver, const uint8_t* data_out, uint8_t* data_in, uint32_t size ) { uint32_t loop_count = MAX_LOOP_COUNT; clear_spi_fifos( spi_driver->spi_peripheral ); if(spi_driver->use_dma) { return spi_dma_transfer(data_out,data_in,size); } while ( size > 0 ) { /* Push frame to TX FIFO */ //SPI_PUSHR_REG( spi_driver->spi_peripheral ) = (uint32_t) ( *data_out++ | SPI_PUSHR_PCS( 1 << spi_driver->chip_select ) | ( ( size != 1 ) ? SPI_PUSHR_CONT_MASK : 0 ) ); SPI_PUSHR_REG( spi_driver->spi_peripheral ) = (uint32_t) ( *data_out++); /* Wait until RX FIFO is not empty */ while ( ( SPI_SR_RXCTR_MASK & SPI_SR_REG( spi_driver->spi_peripheral ) ) == 0 && loop_count > 0 ) { loop_count--; } if ( loop_count == 0 ) { return kTimeoutErr; } /* Pop frame from RX FIFO */ *data_in++ = (uint8_t)SPI_POPR_REG( spi_driver->spi_peripheral ); size--; } return kNoErr; }