//! Transmit a 32-bit word with the target //! //! @param send - data to send //! //! @return BDM_RC_OK => success //! uint8_t spi_tx32(const uint8_t *data) { SPI0_PUSHR = SPI_PUSHR_CTAS(ctas_8bit)|SPI_PUSHR_PCS(0x1)|SPI_PUSHR_CONT_MASK|SPI_PUSHR_TXDATA(*data++); SPI0_PUSHR = SPI_PUSHR_CTAS(ctas_8bit)|SPI_PUSHR_PCS(0x1)|SPI_PUSHR_CONT_MASK|SPI_PUSHR_TXDATA(*data++); SPI0_PUSHR = SPI_PUSHR_CTAS(ctas_8bit)|SPI_PUSHR_PCS(0x1)|SPI_PUSHR_CONT_MASK|SPI_PUSHR_TXDATA(*data++); SPI0_PUSHR = SPI_PUSHR_CTAS(ctas_8bit)|SPI_PUSHR_PCS(0x1)|SPI_PUSHR_CONT_MASK|SPI_PUSHR_TXDATA(*data++)|SPI_PUSHR_EOQ_MASK; while ((SPI0_SR & SPI_SR_EOQF_MASK) == 0) { } SPI0_SR = SPI_SR_EOQF_MASK; return BDM_RC_OK; }
//========================================================================= //函数名称: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; }
//! Receive a 32-bit word from the target //! //! @param receive - data received //! //! @return BDM_RC_OK => success //! uint8_t spi_rx32(uint8_t *receive) { SPI0_PUSHR = SPI_PUSHR_CTAS(ctas_8bit)|SPI_PUSHR_PCS(0x1)|SPI_PUSHR_CONT_MASK|SPI_PUSHR_TXDATA(0); SPI0_PUSHR = SPI_PUSHR_CTAS(ctas_8bit)|SPI_PUSHR_PCS(0x1)|SPI_PUSHR_CONT_MASK|SPI_PUSHR_TXDATA(0); SPI0_PUSHR = SPI_PUSHR_CTAS(ctas_8bit)|SPI_PUSHR_PCS(0x1)|SPI_PUSHR_CONT_MASK|SPI_PUSHR_TXDATA(0); SPI0_PUSHR = SPI_PUSHR_CTAS(ctas_8bit)|SPI_PUSHR_PCS(0x1)|SPI_PUSHR_CONT_MASK|SPI_PUSHR_TXDATA(0)|SPI_PUSHR_EOQ_MASK; while ((SPI0_SR & SPI_SR_EOQF_MASK) == 0) { } SPI0_SR = SPI_SR_EOQF_MASK; *receive++ = SPI0_POPR; *receive++ = SPI0_POPR; *receive++ = SPI0_POPR; *receive++ = SPI0_POPR; return BDM_RC_OK; }
/* * To read data from a LCD register, this function sets the register index, * and then sends out 0x73 and wait for reply */ static unsigned short SpiReadDataWord(unsigned char reg) { unsigned short value, data; unsigned short data2; //Set register pointer data=0x7000 | reg; // wait write buffer not full flag while (!(SPI2_SR & SPI_SR_TFFF_MASK)){}; // Assert CS0, Use config 0 SPI2_PUSHR = SPI_PUSHR_PCS(1 << (0)) | SPI_PUSHR_CTAS(0) | SPI_PUSHR_TXDATA((unsigned short)data); while (!(SPI2_SR & SPI_SR_TCF_MASK)){};// while shift-out complete SPI2_SR = SPI_SR_TCF_MASK; // clear flag //Tell it to do a read by sending out 0x73 data=0x7300; data2=0x0000; //Halt SPI from sending out anything SPI2_MCR |= SPI_MCR_HALT_MASK; // wait write buffer not full flag while (!(SPI2_SR & SPI_SR_TFFF_MASK)){}; // Assert CS0, Use config 0, write two words at once to have CW low long enough // to let data be recieved. SPI2_PUSHR = SPI_PUSHR_CONT_MASK | SPI_PUSHR_PCS(1 << (0)) | SPI_PUSHR_CTAS(0) | SPI_PUSHR_TXDATA((unsigned short)data); SPI2_PUSHR = SPI_PUSHR_PCS(1 << (0)) | SPI_PUSHR_CTAS(0) | SPI_PUSHR_TXDATA((unsigned short)data2); //Send out both data words back to back using the FIFO SPI2_MCR &= (~ SPI_MCR_HALT_MASK); while (!(SPI2_SR & SPI_SR_TCF_MASK)){};// while shift-out complete //while (!(SPI2_SR & SPI_SR_RCF_MASK)){};// while shift-out complete SPI2_SR = SPI_SR_TCF_MASK; // clear flag time_delay_ms(5); //Data returned from LCD should be in POPR now value = SPI2_POPR ; //garbage value = SPI2_POPR ; //good data return value; }
/*********************************************************************************************** 功能:SPI 读写一次数据 形参:SPICSMap SPI 片选通道定义 @arg SPI0_PCS0_PA14: SPI0通道 PCS0 PA14引脚 @arg ... Data: 需要发送的数据 PCS_State: 片选信号状态 @arg SPI_PCS_Asserted: 发送完数据后 片选信号拉高 @arg SPI_PCS_Inactive: 发送完数据后 片选信号保持低电平 返回:接收到的数据 详解:0 ************************************************************************************************/ uint16_t SPI_ReadWriteByte(uint32_t SPICSMap,uint16_t Data,uint16_t PCS_State) { uint32_t temp = 0; SPI_Type *SPIx = NULL; SPI_CSMapTypeDef *pSPI_CSMap = (SPI_CSMapTypeDef*)&(SPICSMap); //参数检查 assert_param(IS_SPI_PCS_STATE(PCS_State)); assert_param(IS_SPI_PCS_CHL(SPICSMap)); //找出SPI端口 switch(pSPI_CSMap->SPI_Index) { case 0: SPIx = SPI0; break; case 1: SPIx = SPI1; break; case 2: SPIx = SPI2; break; default:break; } while((SPIx->SR & SPI_SR_TFFF_MASK) == 0){}; //等待发送缓冲区有空位 SPIx->PUSHR = (((uint32_t)(((uint32_t)(PCS_State))<<SPI_PUSHR_CONT_SHIFT))&SPI_PUSHR_CONT_MASK) //是否拉起CS | SPI_PUSHR_CTAS(1) | SPI_PUSHR_PCS(1<<(pSPI_CSMap->SPI_PCS_CH_Index))//使能信号 | SPI_PUSHR_TXDATA(Data); //写数据 while(!(SPIx->SR & SPI_SR_TCF_MASK)){}; //等待发送完成 SPIx->SR |= SPI_SR_TCF_MASK ; //清除发送缓冲标志位 //使接收缓冲器为空 while((SPIx->SR & SPI_SR_RFDF_MASK) == 0){}; //RX FIFO 未接收到数据则一直等待 temp = SPIx->POPR; //数据以32位形式存在POPR中,转化格式 while((SPIx->SR & SPI_SR_RFDF_MASK) == 0){}; //RX FIFO 未接收到数据则一直等待 return temp; }
//! Transmit a 8-bit word with the target //! //! @param send - data to send //! //! @return BDM_RC_OK => success //! uint8_t spi_tx8(uint8_t data) { SPI0_PUSHR = SPI_PUSHR_CTAS(ctas_8bit)|SPI_PUSHR_EOQ_MASK|SPI_PUSHR_PCS(0x1)|SPI_PUSHR_TXDATA(data); while ((SPI0_SR & SPI_SR_EOQF_MASK) == 0) { } SPI0_SR = SPI_SR_EOQF_MASK; return BDM_RC_OK; }
static inline uint8_t spi_transfer_internal(SPI_Type *spi_dev, uint32_t flags, uint8_t byte_out) { /* Wait until there is space in the TXFIFO */ while (!(spi_dev->SR & SPI_SR_TFFF_MASK)); #if KINETIS_SPI_USE_HW_CS spi_dev->PUSHR = flags | SPI_PUSHR_TXDATA(byte_out) | SPI_PUSHR_PCS(1); #else spi_dev->PUSHR = flags | SPI_PUSHR_TXDATA(byte_out); #endif /* Wait until we have received a byte */ while (!(spi_dev->SR & SPI_SR_RXCTR_MASK)); return (uint8_t)spi_dev->POPR; }
/********************************************************* * Name: SPI_Send_byte * Desc: Send one byte * Parameter: The byte to be sent * Return: None **********************************************************/ void SPI_Send_byte(uint_8 u8Data) { /*Body*/ /* Check the status flag */ if(SPI1_SR & SPI_SR_EOQF_MASK) { /* Clear the EOQF by writting a 1 to it */ SPI1_SR |= SPI_SR_EOQF_MASK; }/*Endif*/ /* Write the DSPI_PUSHR register */ SPI1_PUSHR = ( SPI_PUSHR_CTAS(0) | SPI_PUSHR_EOQ_MASK | SPI_PUSHR_CTCNT_MASK | SPI_PUSHR_PCS(1) | SPI_PUSHR_TXDATA(u8Data)); /* Write the clock and transfer attributes: master clock and frame size (8 bits) */ SPI1_CTAR0 = ( SPI_CTAR_SLAVE_FMSZ(7) | gSPI_BeforeTransfDelay | gSPI_AfterTransfDelay | gSPI_InterTransfDelay | gSPI_BaudRate); /* Start the transfer */ SPI1_MCR &= ~SPI_MCR_HALT_MASK; /* Wait until the transfer has been finished */ while(!(SPI1_SR & SPI_SR_EOQF_MASK)) { Watchdog_Reset(); }/*EndWhile*/ /* Clear the EOQF by writting a 1 to it */ SPI1_SR |= SPI_SR_EOQF_MASK; }/*EndBody*/
int spi_master_write(spi_t *obj, int value) { // wait tx buffer empty while(!spi_writeable(obj)); obj->spi->PUSHR = SPI_PUSHR_TXDATA(value & 0xff); // wait rx buffer full while (!spi_readable(obj)); return obj->spi->POPR; }
int spi_master_write(spi_t *obj, int value) { //clear RX buffer flag obj->spi->SR |= SPI_SR_RFDF_MASK; // wait tx buffer empty while(!spi_writeable(obj)); obj->spi->PUSHR = SPI_PUSHR_TXDATA(value & 0xffff) /*| SPI_PUSHR_EOQ_MASK*/; // wait rx buffer full while (!spi_readable(obj)); return obj->spi->POPR; }
/** * @brief get two ad7687 conver data, * @param None * @retval None */ void AD7687_GetConverData (uint16_t *ad) { _AD7687_Send_aclock (); while((AD7687_SPI->SR & SPI_SR_TFFF_MASK) == 0){}; AD7687_SPI->PUSHR = SPI_PUSHR_CTAS(1) | SPI_PUSHR_TXDATA(0); while(!(AD7687_SPI->SR & SPI_SR_TCF_MASK)){}; AD7687_SPI->SR |= SPI_SR_TCF_MASK; while((AD7687_SPI->SR & SPI_SR_RFDF_MASK) == 0); //RX FIFO 未接收到数据则一直等待 ad[0] = AD7687_SPI->POPR; //B通道 交流电流 正极电压 while((AD7687_SPI->SR & SPI_SR_RFDF_MASK) == 0){}; //RX FIFO 未接收到数据则一直等待 while((AD7687_SPI->SR & SPI_SR_TFFF_MASK) == 0){}; AD7687_SPI->PUSHR = SPI_PUSHR_CTAS(1) | SPI_PUSHR_TXDATA(0); while(!(AD7687_SPI->SR & SPI_SR_TCF_MASK)){}; AD7687_SPI->SR |= SPI_SR_TCF_MASK; while((AD7687_SPI->SR & SPI_SR_RFDF_MASK) == 0){}; ad[1] = AD7687_SPI->POPR; ////A通道 交流电压 负极电压 while((AD7687_SPI->SR & SPI_SR_RFDF_MASK) == 0){}; //RX FIFO 未接收到数据则一直等待 }
/** * @brief . * @param None * @retval None */ void _ILI_SendDummyData (void) { uint16_t receive; while (ILI_SPI->SR & SPI_SR_TFFF_MASK == 0); ILI_SPI->PUSHR = (SPI_PUSHR_CTAS(0) |SPI_PUSHR_TXDATA(0x1ff)); while (!(ILI_SPI->SR&SPI_SR_TCF_MASK)); ILI_SPI->SR |= SPI_SR_TCF_MASK; while ((ILI_SPI->SR & SPI_SR_RFDF_MASK)==0); receive = ILI_SPI->POPR; while ((ILI_SPI->SR & SPI_SR_RFDF_MASK) == 0); }
//----------------------------------------------------------------------------- // FUNCTION: D4DLCDHW_SendDataWord_Kinetis_Spi // SCOPE: Low Level Driver API function // DESCRIPTION: The function send the one 16 bit variable into LCD // // PARAMETERS: unsigned short value variable to send // // RETURNS: none //----------------------------------------------------------------------------- static void D4DLCDHW_SendDataWord_Kinetis_Spi(unsigned short value) { // wait write buffer not full flag while (!(D4DLCD_SPI_SR & SPI_SR_TFFF_MASK)){}; // Assert CS0, Use config 0 D4DLCD_SPI_PUSHR = SPI_PUSHR_PCS(1 << (D4DLCD_SPI_PCS_ID)) | SPI_PUSHR_CTAS(0) | SPI_PUSHR_TXDATA((unsigned short)value); while (!(D4DLCD_SPI_SR & SPI_SR_TCF_MASK)){};// while shift-out complete D4DLCD_SPI_SR = SPI_SR_TCF_MASK; // clear flag }
/** * @brief . * @param None * @retval None */ uint16_t ILI_SendReceiveNcont (uint16_t data) { uint16_t receive; while (ILI_SPI->SR & SPI_SR_TFFF_MASK == 0); ILI_SPI->PUSHR = (SPI_PUSHR_CTAS(0) |SPI_PUSHR_PCS(1<<1) |SPI_PUSHR_TXDATA(data)); while (!(ILI_SPI->SR&SPI_SR_TCF_MASK)); ILI_SPI->SR |= SPI_SR_TCF_MASK; while ((ILI_SPI->SR & SPI_SR_RFDF_MASK)==0); receive = ILI_SPI->POPR; while ((ILI_SPI->SR & SPI_SR_RFDF_MASK) == 0); return receive; }
static inline void irq_handler_transfer(SPI_Type *spi, spi_t dev) { if (spi->SR & SPI_SR_RFDF_MASK) { char data; data = (char)spi->POPR; data = spi_config[dev].cb(data); spi->PUSHR = SPI_PUSHR_CTAS(0) | SPI_PUSHR_EOQ_MASK | SPI_PUSHR_TXDATA(data); } /* see if a thread with higher priority wants to run now */ cortexm_isr_end(); }
/** * @brief SPI发送数据 * * @param spino SPI通道号 * @param data[] 需要发送的数据 * @param len 需要发送的数据 */ void spi_snd(uint8_t spino, uint8_t data[], uint32_t len) { uint32_t i = 0; SPI_MemMapPtr base_addr = spi_get_base_address(spino); 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 TX FIFO */ | SPI_MCR_CLR_RXF_MASK; /* Clears the RX Counter */ for (i = 0; i < len; i++) { if (i == (len - 1)) { SPI_PUSHR_REG(base_addr) = 0 | SPI_PUSHR_CTAS(0) /* Clock and Transfer Attributes Select */ | SPI_PUSHR_EOQ_MASK /* End Of Queue */ | SPI_PUSHR_TXDATA(data[i]); /* Transmit Data */ } else { SPI_PUSHR_REG(base_addr) = 0 | SPI_PUSHR_CONT_MASK | SPI_PUSHR_CTAS(0) | SPI_PUSHR_TXDATA(data[i]); } } /* 等待数据发送完毕 */ while((SPI_SR_REG(base_addr) & SPI_SR_TCF_MASK)==0); SPI_SR_REG(base_addr) |= SPI_SR_TCF_MASK; }
/** * @brief SPI读写一字节数据 * @code * //使用SPI的1模块的1片选信号写一字节的数据0x55,片选信号最后为选中状态 * SPI_ReadWriteByte(HW_SPI1, HW_CTAR0, 0x55, 1, kSPI_PCS_ReturnInactive); * @endcode * @param[in] instance 芯片SPI端口 * @arg HW_SPI0 芯片的SPI0端口 * @arg HW_SPI1 芯片的SPI1端口 * @arg HW_SPI2 芯片的SPI2端口 * @param[in] ctar SPI通信通道选择 * @arg HW_CTAR0 0配置寄存器 * @arg HW_CTAR1 1配置寄存器 * @param[in] data 要发送的一字节数据 * @param[in] CSn 片选信号端口选择 * @param[in] csState 片选信号最后的状态 * @arg kSPI_PCS_ReturnInactive 最后处于选中状态 * @arg kSPI_PCS_KeepAsserted 最后保持未选中状态 * @return 读取到的数据 */ uint16_t SPI_ReadWriteByte(uint32_t instance, uint32_t ctar, uint16_t data, uint16_t CSn, SPI_PCS_Type csState) { SPI_InstanceTable[instance]->PUSHR = (((uint32_t)(((csState))<<SPI_PUSHR_CONT_SHIFT))&SPI_PUSHR_CONT_MASK) | SPI_PUSHR_CTAS(ctar) | SPI_PUSHR_PCS(1<<CSn) | SPI_PUSHR_TXDATA(data); /* waitting for complete */ if(!(SPI_InstanceTable[instance]->RSER & SPI_RSER_TCF_RE_MASK)) /* if it is polling mode */ { while(!(SPI_InstanceTable[instance]->SR & SPI_SR_TCF_MASK)); SPI_InstanceTable[instance]->SR |= SPI_SR_TCF_MASK; } return (uint16_t)SPI_InstanceTable[instance]->POPR; }
/* * To set the LCD register to read/write, send out 0x70 and then the register # */ static void SpiRegSet(unsigned char reg) { unsigned short data; //Set the data to write out by concatenating 0x70 with the register value. data=0x7000 | reg; // wait write buffer not full flag while (!(SPI2_SR & SPI_SR_TFFF_MASK)){}; // Assert CS0, Use config 0, and send out on MISO SPI2_PUSHR = SPI_PUSHR_PCS(1 << (0)) | SPI_PUSHR_CTAS(0) | SPI_PUSHR_TXDATA((unsigned short)data); while (!(SPI2_SR & SPI_SR_TCF_MASK)){};// while shift-out complete SPI2_SR = SPI_SR_TCF_MASK; // clear flag }
/* * To write data to a LCD register, send out 0x72 and then value * Make sure to set the register index first via SpiRegSet() */ static void SpiSendDataWord(unsigned char value) { unsigned short data; //Set the data to write out by concatenating 0x72 with the data to write data=0x7200 | value; // wait write buffer not full flag while (!(SPI2_SR & SPI_SR_TFFF_MASK)){}; // Assert CS0, Use config 0 SPI2_PUSHR = SPI_PUSHR_PCS(1 << (0)) | SPI_PUSHR_CTAS(0) | SPI_PUSHR_TXDATA((unsigned short)data); while (!(SPI2_SR & SPI_SR_TCF_MASK)){};// while shift-out complete SPI2_SR = SPI_SR_TCF_MASK; // clear flag }
/** * @brief SPI读写一字节数据 * @code * //使用SPI的1模块的1片选信号写一字节的数据0x55,片选信号最后为选中状态 * SPI_ReadWriteByte(HW_SPI1, HW_CTAR0, 0x55, 1, kSPI_PCS_ReturnInactive); * @endcode * @param instance :SPI通信模块号 HW_SPI0~2 * @param ctar :SPI通信通道选择 * @arg HW_CTAR0 :0通道 * @arg HW_CTAR1 :1通道 * @param data : 要发送的一字节数据 * @param CSn : 片选信号端口选择 * @param csState : 片选信号最后的状态 * @arg kSPI_PCS_ReturnInactive :最后处于选中状态 * @arg kSPI_PCS_KeepAsserted :最后保持未选中状态 * @retval 读取到的数据 */ uint16_t SPI_ReadWriteByte(uint32_t instance,uint32_t ctar, uint16_t data, uint16_t CSn, uint16_t csState) { uint16_t read_data; SPI_InstanceTable[instance]->PUSHR = (((uint32_t)(((csState))<<SPI_PUSHR_CONT_SHIFT))&SPI_PUSHR_CONT_MASK) | SPI_PUSHR_CTAS(ctar) | SPI_PUSHR_PCS(1<<CSn) | SPI_PUSHR_TXDATA(data); if(!(SPI_InstanceTable[instance]->RSER & SPI_RSER_TCF_RE_MASK)) // if it is polling mode { /* wait for transfer complete */ while(!(SPI_InstanceTable[instance]->SR & SPI_SR_TCF_MASK)){}; /* clear flag */ SPI_InstanceTable[instance]->SR |= SPI_SR_TCF_MASK; } read_data = (uint16_t)SPI_InstanceTable[instance]->POPR; return read_data; }
INT8U SPI_SendReceive ( SPI_Type *SPIx, INT8U tx_dat ) { SPIx->SR = (SPI_SR_EOQF_MASK | SPI_SR_TFFF_MASK | SPI_SR_TFUF_MASK | SPI_SR_RFDF_MASK | SPI_SR_RFOF_MASK ); SPIx->MCR |= (SPI_MCR_CLR_RXF_MASK| SPI_MCR_CLR_TXF_MASK); SPIx->PUSHR = (SPI_PUSHR_CTAS(0) | SPI_PUSHR_EOQ_MASK | SPI_PUSHR_PCS(1) | /*SPI Flash cs Conflict with lcd_en(pcs1) spiflash need comment this statement*/ SPI_PUSHR_TXDATA(tx_dat)); while((SPIx->SR & SPI_SR_TCF_MASK) == 0); SPIx->SR |= SPI_SR_TCF_MASK; return (SPIx->POPR); }
/********************************************************* * Name: SPI_Receive_byte * Desc: The byte received by SPI * Parameter: None * Return: Received byte **********************************************************/ uint_8 SPI_Receive_byte(void) { uint_16 u8Data; /*Body*/ /* Check the status flag */ if(SPI1_SR & SPI_SR_EOQF_MASK) { /* Clear the EOQF by writting a 1 to it */ SPI1_SR |= SPI_SR_EOQF_MASK; }/*EndIf*/ /* Write the DSPI_PUSHR register */ SPI1_PUSHR = ( SPI_PUSHR_CTAS(0) | SPI_PUSHR_EOQ_MASK | SPI_PUSHR_CTCNT_MASK | SPI_PUSHR_PCS(1) | SPI_PUSHR_TXDATA(0xFF)); /* Write the clock and transfer attributes: master clock and frame size (8 bits) */ SPI1_CTAR0 = ( SPI_CTAR_FMSZ(7) | gSPI_BeforeTransfDelay | gSPI_AfterTransfDelay | gSPI_InterTransfDelay | gSPI_BaudRate); /* Start the transfer */ SPI1_MCR &= ~SPI_MCR_HALT_MASK; /* Wait until the transfer has been finished */ while(!(SPI1_SR & SPI_SR_EOQF_MASK)) { Watchdog_Reset(); }/*EndWhile*/ /* Clear the EOQF by writting a 1 to it */ SPI1_SR |= SPI_SR_EOQF_MASK; /* Read the byte form the DSPI_POPR register */ u8Data = (uint_16)SPI_RXFR0_RXDATA(SPI1_POPR); return((uint_8)u8Data); }/*EndBody*/
void spi_transmission_begin(spi_t dev, char reset_val) { switch (dev) { #if SPI_0_EN case SPI_0: SPI_0_DEV->PUSHR = SPI_PUSHR_CTAS(SPI_0_CTAS) | SPI_PUSHR_EOQ_MASK | SPI_PUSHR_TXDATA(reset_val); break; #endif #if SPI_1_EN case SPI_1: SPI_1_DEV->PUSHR = SPI_PUSHR_CTAS(SPI_1_CTAS) | SPI_PUSHR_EOQ_MASK | SPI_PUSHR_TXDATA(reset_val); break; #endif #if SPI_2_EN case SPI_2: SPI_2_DEV->PUSHR = SPI_PUSHR_CTAS(SPI_2_CTAS) | SPI_PUSHR_EOQ_MASK | SPI_PUSHR_TXDATA(reset_val); break; #endif #if SPI_3_EN case SPI_3: SPI_3_DEV->PUSHR = SPI_PUSHR_CTAS(SPI_3_CTAS) | SPI_PUSHR_EOQ_MASK | SPI_PUSHR_TXDATA(reset_val); break; #endif #if SPI_4_EN case SPI_4: SPI_4_DEV->PUSHR = SPI_PUSHR_CTAS(SPI_4_CTAS) | SPI_PUSHR_EOQ_MASK | SPI_PUSHR_TXDATA(reset_val); break; #endif #if SPI_5_EN case SPI_5: SPI_5_DEV->PUSHR = SPI_PUSHR_CTAS(SPI_5_CTAS) | SPI_PUSHR_EOQ_MASK | SPI_PUSHR_TXDATA(reset_val); break; #endif #if SPI_6_EN case SPI_6: SPI_6_DEV->PUSHR = SPI_PUSHR_CTAS(SPI_6_CTAS) | SPI_PUSHR_EOQ_MASK | SPI_PUSHR_TXDATA(reset_val); break; #endif #if SPI_7_EN case SPI_7: SPI_7_DEV->PUSHR = SPI_PUSHR_CTAS(SPI_7_CTAS) | SPI_PUSHR_EOQ_MASK | SPI_PUSHR_TXDATA(reset_val); break; #endif } }
void Spi::put_data (uint16_t data, CS_number cs, CTAR_number ctar, State cont) { SPI0->PUSHR = SPI_PUSHR_PCS(1<<(uint8_t)cs)|SPI_PUSHR_TXDATA(data)|SPI_PUSHR_CTAS(ctar)|SPI_PUSHR_CONT(cont); }
int spi_transfer_blocking(const spi_bus_t spi_num, const uint8_t ctas, const uint32_t cs, const spi_transfer_flag_t cont, const uint8_t *data_out, uint8_t *data_in, size_t count_out, size_t count_in) { SPI_Type *spi_dev = SPI[spi_num]; /* Frame size in bits */ unsigned short frame_size = ((SPI[spi_num]->CTAR[ctas] & SPI_CTAR_FMSZ_MASK) >> SPI_CTAR_FMSZ_SHIFT) + 1; /* Array stride in bytes */ /* unsigned int stride = (frame_size / 8) + 1; */ uint32_t common_flags = SPI_PUSHR_CTAS(ctas) | SPI_PUSHR_PCS(cs); uint32_t spi_pushr; /* this may yield unaligned memory accesses because of uint8_t* casted to * uint16_t*. Using the DMA module will avoid this. */ if (frame_size > 8) { /* Error! not implemented yet */ DEBUGGER_BREAK(BREAK_INVALID_PARAM); while(1); } while (count_out > 0) { spi_pushr = common_flags; spi_pushr |= SPI_PUSHR_TXDATA(*data_out); ++data_out; /* or += stride */ --count_out; /* See if we are at the end yet */ if((count_out > 0) || (count_in > 0) || (cont == SPI_TRANSFER_CONT)) { spi_pushr |= SPI_PUSHR_CONT_MASK; } /* Clear transfer complete flag */ spi_dev->SR |= SPI_SR_TCF_MASK; /* Set waiting flag */ spi_waiting_flag[spi_num] = 1; /* Shift a frame out/in */ spi_dev->PUSHR = spi_pushr; /* Wait for transfer complete */ COND_WAIT(spi_waiting_flag[spi_num] != 0); /* Do a dummy read in order to allow for the next byte to be read */ uint8_t tmp = spi_dev->POPR; (void)tmp; /* Suppress warning about unused value. */ } /* Prepare read */ spi_pushr = common_flags; spi_pushr |= SPI_PUSHR_TXDATA(SPI_IDLE_DATA); spi_pushr |= SPI_PUSHR_CONT_MASK; /* Do a number of reads */ while (count_in > 0) { --count_in; /* See if we are at the end yet */ if((count_in < 1) && (cont != SPI_TRANSFER_CONT)) { /* Disable CS line after the next transfer */ spi_pushr &= ~(SPI_PUSHR_CONT_MASK); } /* Clear transfer complete flag */ spi_dev->SR |= SPI_SR_TCF_MASK; /* Set waiting flag */ spi_waiting_flag[spi_num] = 1; /* Shift a frame out/in */ spi_dev->PUSHR = spi_pushr; /* Wait for transfer complete */ COND_WAIT(spi_waiting_flag[spi_num] != 0); (*data_in) = spi_dev->POPR; ++data_in; /* or += stride */ } return 0; }
static int dspi_transfer_write(struct fsl_dspi *dspi) { int tx_count = 0; int tx_word; u16 d16; u8 d8; u32 dspi_pushr = 0; int first = 1; tx_word = is_double_byte_mode(dspi); /* If we are in word mode, but only have a single byte to transfer * then switch to byte mode temporarily. Will switch back at the * end of the transfer. */ if (tx_word && (dspi->len == 1)) { dspi->dataflags |= TRAN_STATE_WORD_ODD_NUM; set_bit_mode(dspi, 8); tx_word = 0; } while (dspi->len && (tx_count < DSPI_FIFO_SIZE)) { if (tx_word) { if (dspi->len == 1) break; if (!(dspi->dataflags & TRAN_STATE_TX_VOID)) { d16 = *(u16 *)dspi->tx; dspi->tx += 2; } else { d16 = dspi->void_write_data; } dspi_pushr = SPI_PUSHR_TXDATA(d16) | SPI_PUSHR_PCS(dspi->cs) | SPI_PUSHR_CTAS(dspi->cs) | SPI_PUSHR_CONT; dspi->len -= 2; } else { if (!(dspi->dataflags & TRAN_STATE_TX_VOID)) { d8 = *(u8 *)dspi->tx; dspi->tx++; } else { d8 = (u8)dspi->void_write_data; } dspi_pushr = SPI_PUSHR_TXDATA(d8) | SPI_PUSHR_PCS(dspi->cs) | SPI_PUSHR_CTAS(dspi->cs) | SPI_PUSHR_CONT; dspi->len--; } if (dspi->len == 0 || tx_count == DSPI_FIFO_SIZE - 1) { /* last transfer in the transfer */ dspi_pushr |= SPI_PUSHR_EOQ; } else if (tx_word && (dspi->len == 1)) dspi_pushr |= SPI_PUSHR_EOQ; if (first) { first = 0; dspi_pushr |= SPI_PUSHR_CTCNT; /* clear counter */ } writel(dspi_pushr, dspi->base + SPI_PUSHR); tx_count++; } return tx_count * (tx_word + 1); }
void spi1_transmit (uint8_t data) { while(!(SPI1->SR &SPI_SR_TFFF_MASK)); SPI1->PUSHR =SPI_PUSHR_PCS(1 << 1)| SPI_PUSHR_CTAS(0)|SPI_PUSHR_TXDATA(data); while(!(SPI1->SR &SPI_SR_TCF_MASK)); }