//! 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; }
//! 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; }
/* * LPLD_SPI_Master_WriteRead * K60主机SPI向从机写数据,并读取从机数据 * * 参数: * spix--SPI选择 * |__SPI0 -选择SPI0模块 * |__SPI1 -选择SPI1模块 * |__SPI2 -选择SPI2模块 * data--要发送数据 * |__单位为一个字节,8位 * pcsx--CS片选端口号 * |__SPI_PCS0 -0号片选(SPI0、SPI1、SPI2含有) * |__SPI_PCS1 -1号片选(SPI0、SPI1、SPI2含有) * |__SPI_PCS2 -2号片选(SPI0、SPI1含有) * |__SPI_PCS3 -3号片选(SPI0、SPI1含有) * |__SPI_PCS4 -4号片选(SPI0含有) * |__SPI_PCS5 -5号片选(SPI0含有) * pcs_state--一帧数据传输完成后CS的状态 * |__SPI_PCS_ASSERTED -保持片选有效,PCS信号保持为低电平 * |__SPI_PCS_INACTIVE -片选无效,PCS信号变为高电平 * 输出: * 读取从机8位的数据 */ uint8 LPLD_SPI_Master_WriteRead(SPI_MemMapPtr spix,uint8 data,uint8 pcsx,uint8 pcs_state) { uint8 temp = 0; //PUSHR - DSPI PUSH Tx FIFO register In Master mode //CONT continuos peripheral chip select enable //CONT = 1 return inactive //CONT = 0 kepp ASSERT spix->PUSHR = (((uint32_t)(((uint32_t)(pcs_state))<<SPI_PUSHR_CONT_SHIFT))&SPI_PUSHR_CONT_MASK) |SPI_PUSHR_CTAS(0) |SPI_PUSHR_PCS(pcsx) |data; if (!pcs_state) spix->PUSHR |= SPI_PUSHR_EOQ_MASK; //直到传输完成 while(!(spix->SR & SPI_SR_TCF_MASK)); spix->SR |= SPI_SR_TCF_MASK ; while(!(spix->SR & SPI_SR_RFDF_MASK)); //read date temp = (uint8)(spix->POPR & 0xff); spix->SR |= SPI_SR_RFDF_MASK; 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; }
/********************************************************* * 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*/
/*********************************************************************************************** 功能: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; }
/* * LPLD_SPI_Master_Write * K60主机SPI向从机写数据 * * 参数: * spix--SPI选择 * |__SPI0 -选择SPI0模块 * |__SPI1 -选择SPI1模块 * |__SPI2 -选择SPI2模块 * data--要发送数据 * |__单位为一个字节,8位 * pcsx--CS片选端口号 * |__SPI_PCS0 -0号片选(SPI0、SPI1、SPI2含有) * |__SPI_PCS1 -1号片选(SPI0、SPI1、SPI2含有) * |__SPI_PCS2 -2号片选(SPI0、SPI1含有) * |__SPI_PCS3 -3号片选(SPI0、SPI1含有) * |__SPI_PCS4 -4号片选(SPI0含有) * |__SPI_PCS5 -5号片选(SPI0含有) * pcs_state--一帧数据传输完成后CS的状态 * |__SPI_PCS_ASSERTED -保持片选有效,PCS信号保持为低电平 * |__SPI_PCS_INACTIVE -片选无效,PCS信号变为高电平 */ void LPLD_SPI_Master_Write(SPI_MemMapPtr spix,uint8 data,uint8 pcsx,uint8 pcs_state) { spix->PUSHR = (((uint32_t)(((uint32_t)(pcs_state))<<SPI_PUSHR_CONT_SHIFT)) & SPI_PUSHR_CONT_MASK) |SPI_PUSHR_CTAS(0) |SPI_PUSHR_PCS(pcsx) |data; if (!pcs_state) spix->PUSHR |= SPI_PUSHR_EOQ_MASK; while(!(spix->SR & SPI_SR_TCF_MASK)); spix->SR |= SPI_SR_TCF_MASK ; }
//----------------------------------------------------------------------------- // 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; }
/** * @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 }
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; }
/** * @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; }
// Write buffer to SPI FIFO void SPI_write( uint8_t *buffer, uint8_t len ) { for ( uint8_t byte = 0; byte < len; byte++ ) { // Wait for SPI TxFIFO to have 4 or fewer entries while ( !( SPI0_SR & SPI_SR_TFFF ) ) delayMicroseconds(10); // Write byte to TxFIFO // CS0, CTAR0 SPI0_PUSHR = ( buffer[ byte ] & 0xff ) | SPI_PUSHR_PCS(1); // Indicate transfer has completed while ( !( SPI0_SR & SPI_SR_TCF ) ); SPI0_SR |= SPI_SR_TCF; } }
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*/
/*FUNCTION**************************************************************** * * Function Name : _dspi_polled_deinit * Returned Value : MQX error code * Comments : * This function de-initializes the SPI module * *END*********************************************************************/ static uint_32 _dspi_polled_deinit ( /* [IN] the initialization information for the device being opened */ IO_SPI_POLLED_DEVICE_STRUCT_PTR io_dev_ptr, /* [IN] the address of the device specific information */ DSPI_INFO_STRUCT_PTR io_info_ptr ) { SPI_MemMapPtr dspi_ptr; uint_32 index; if ((NULL == io_info_ptr) || (NULL == io_dev_ptr)) { return SPI_ERROR_DEINIT_FAILED; } /* Disable the SPI */ dspi_ptr = io_info_ptr->DSPI_PTR; dspi_ptr->MCR |= SPI_MCR_HALT_MASK; /* Disable all chip selects */ if (dspi_ptr->MCR & SPI_MCR_MSTR_MASK) { for (index = 0; index < DSPI_CS_COUNT; index++) { if ((NULL != io_info_ptr->CS_CALLBACK[index]) && (0 != (io_info_ptr->CS_ACTIVE & (1 << index)))) { io_info_ptr->CS_CALLBACK[index] (SPI_PUSHR_PCS(1 << index), 1, io_info_ptr->CS_USERDATA[index]); } } io_info_ptr->CS_ACTIVE = 0; } _mem_free(io_dev_ptr->DEV_INFO_PTR); io_dev_ptr->DEV_INFO_PTR = NULL; return SPI_OK; }
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)); }
/*lint -save -e970 Disable MISRA rule (6.3) checking. */ int main(void) /*lint -restore Enable MISRA rule (6.3) checking. */ { /*GPIO Initialization on GPIOA4 set to output*/ /* Write your local variable definition here */ LDD_TDeviceDataPtr SpiTxDmaLDD; LDD_TDeviceDataPtr SpiRxDmaLDD; /*** Processor Expert internal initialization. DON'T REMOVE THIS CODE!!! ***/ PE_low_level_init(); /*** End of Processor Expert internal initialization. ***/ //GPIO Initialization for testing switching timing SIM_SCGC5 |= (1<<12); PORTD_PCR7 |= (1<<8); GPIOD_PDDR |= (1<<7);//test //------------------------------------------------- /* Write your code here */ SpiTxDmaLDD = DMACH1_Init(NULL); SpiRxDmaLDD = DMACH2_Init(NULL); //Pull test pin low GPIOD_PCOR = (1<<7);//test // Enable the module in processor expert internally DMA1_Enable(SpiTxDmaLDD); DMA1_Enable(SpiRxDmaLDD); // DumpDmaRx(SpiRxDmaLDD); SpiRxDmaComplete = 0; SpiTxDmaComplete = 0; //Command will be read n registers starting at address r // This is a command to talk to the S25FL032P Flash part SpiDmaTxBuffer[0] = SPI_PUSHR_PCS(1) | SPI_PUSHR_CONT_MASK | ADS_CMD_SDATAC; // Read Device ID (READ_ID) and following 4 registers SpiDmaTxBuffer[1] = SPI_PUSHR_PCS(1) | SPI_PUSHR_CONT_MASK | 0X20; // All zero low byte of 24 bit address SpiDmaTxBuffer[2] = SPI_PUSHR_PCS(1) | SPI_PUSHR_CONT_MASK | 0X03; // Transmit an empty byte to clock in the RX byte SpiDmaTxBuffer[3] = SPI_PUSHR_PCS(1) | SPI_PUSHR_CONT_MASK | 0X00; SpiDmaTxBuffer[4] = SPI_PUSHR_PCS(1) | SPI_PUSHR_CONT_MASK | 0X00; SpiDmaTxBuffer[5] = SPI_PUSHR_PCS(1) | SPI_PUSHR_CONT_MASK | 0X00; SpiDmaTxBuffer[6] = SPI_PUSHR_PCS(1) | SPI_PUSHR_EOQ_MASK | 0x00; // Transmit an empty byte to clock in the RX byte DMACH1_SetSourceAddress(SpiTxDmaLDD, &SpiDmaTxBuffer[0]); DMACH1_SetDestinationAddress(SpiTxDmaLDD, &SPI2_PUSHR); DMACH2_SetSourceAddress(SpiRxDmaLDD, &SPI2_POPR); DMACH2_SetDestinationAddress(SpiRxDmaLDD, &SpiDmaRxBuffer[0]); //added a SetTransactionCount API from ProcessorExpert. Set to one DMACH1_SetTransactionCount(SpiTxDmaLDD,1); DMACH2_SetTransactionCount(SpiRxDmaLDD,1); DMACH1_SetRequestCount(SpiTxDmaLDD, 1); DMACH2_SetRequestCount(SpiRxDmaLDD, 1); // We care about 2 bytes, but we are going to get a receive for every // transmit byte //Enable requests for Tx and Rx DMA1_EnableRequest(SpiRxDmaLDD); DMA1_EnableRequest(SpiTxDmaLDD); while(!SpiRxDmaComplete | !SpiTxDmaComplete); /*** Don't write any code pass this line, or it will be deleted during code generation. ***/ /*** RTOS startup code. Macro PEX_RTOS_START is defined by the RTOS component. DON'T MODIFY THIS CODE!!! ***/ #ifdef PEX_RTOS_START PEX_RTOS_START(); /* Startup of the selected RTOS. Macro is defined by the RTOS component. */ #endif /*** End of RTOS startup code. ***/ /*** Processor Expert end of main routine. DON'T MODIFY THIS CODE!!! ***/ for(;;){} /*** Processor Expert end of main routine. DON'T WRITE CODE BELOW!!! ***/ } /*** End of main routine. DO NOT MODIFY THIS TEXT!!! ***/
/*FUNCTION**************************************************************** * * Function Name : _dspi_polled_ioctl * Returned Value : MQX error code * Comments : * This function performs miscellaneous services for * the SPI I/O device. * *END*********************************************************************/ uint_32 _dspi_polled_ioctl ( /* [IN] The address of the device specific information */ DSPI_INFO_STRUCT_PTR io_info_ptr, /* [IN] The command to perform */ uint_32 cmd, /* [IN] Parameters for the command */ uint_32_ptr param_ptr, /* [IN] Opening flags */ uint_32 flags ) { SPI_MemMapPtr dspi_ptr; SPI_CS_CALLBACK_STRUCT_PTR callbacks; uint_32 val, num, size, command; uint_32 result = SPI_OK; SPI_READ_WRITE_STRUCT_PTR rw_ptr; uchar_ptr input, output; dspi_ptr = io_info_ptr->DSPI_PTR; switch (cmd) { case IO_IOCTL_SPI_GET_BAUD: if (NULL == param_ptr) { result = SPI_ERROR_INVALID_PARAMETER; } else { val = dspi_ptr->CTAR[0]; val = BAUDRATE_PRESCALER[SPI_CTAR_PBR_GET(val)] * BAUDRATE_SCALER[SPI_CTAR_BR_GET(val)]; *param_ptr = (uint_32)((io_info_ptr->INIT.CLOCK_SPEED) / val); } break; case IO_IOCTL_SPI_SET_BAUD: if (NULL == param_ptr) { result = SPI_ERROR_INVALID_PARAMETER; } else if (0 == (*param_ptr)) { result = SPI_ERROR_BAUD_RATE_INVALID; } else { val = _dspi_find_baudrate (io_info_ptr->INIT.CLOCK_SPEED, *param_ptr); /* Disable SPI module */ dspi_ptr->MCR |= SPI_MCR_HALT_MASK; /* Set the frequency divider */ dspi_ptr->CTAR[0] &= (~ (SPI_CTAR_PBR(0x0F) | SPI_CTAR_BR(0x0F))); dspi_ptr->CTAR[0] |= val; /* Enable SPI module */ dspi_ptr->MCR &= (~ SPI_MCR_HALT_MASK); } break; case IO_IOCTL_SPI_DEVICE_DISABLE: dspi_ptr->MCR |= SPI_MCR_HALT_MASK; break; case IO_IOCTL_SPI_DEVICE_ENABLE: dspi_ptr->MCR &= (~ SPI_MCR_HALT_MASK); break; case IO_IOCTL_SPI_GET_MODE: if (NULL == param_ptr) { result = SPI_ERROR_INVALID_PARAMETER; } else { if (dspi_ptr->CTAR[0] & SPI_CTAR_CPOL_MASK) { if (dspi_ptr->CTAR[0] & SPI_CTAR_CPHA_MASK) { *param_ptr = SPI_CLK_POL_PHA_MODE3; } else { *param_ptr = SPI_CLK_POL_PHA_MODE2; } } else { if (dspi_ptr->CTAR[0] & SPI_CTAR_CPHA_MASK) { *param_ptr = SPI_CLK_POL_PHA_MODE1; } else { *param_ptr = SPI_CLK_POL_PHA_MODE0; } } } break; case IO_IOCTL_SPI_SET_MODE: if (NULL == param_ptr) { result = SPI_ERROR_INVALID_PARAMETER; } else { /* Disable SPI module */ dspi_ptr->MCR |= SPI_MCR_HALT_MASK; switch (*param_ptr) { case (SPI_CLK_POL_PHA_MODE0): /* Inactive state of SPI_CLK = logic 0 */ dspi_ptr->CTAR[0] &= (~ SPI_CTAR_CPOL_MASK); /* SPI_CLK transitions middle of bit timing */ dspi_ptr->CTAR[0] &= (~ SPI_CTAR_CPHA_MASK); break; case (SPI_CLK_POL_PHA_MODE1): /* Inactive state of SPI_CLK = logic 0 */ dspi_ptr->CTAR[0] &= (~ SPI_CTAR_CPOL_MASK); /* SPI_CLK transitions begining of bit timing */ dspi_ptr->CTAR[0] |= SPI_CTAR_CPHA_MASK; break; case (SPI_CLK_POL_PHA_MODE2): /* Inactive state of SPI_CLK = logic 1 */ dspi_ptr->CTAR[0] |= SPI_CTAR_CPOL_MASK; /* SPI_CLK transitions middle of bit timing */ dspi_ptr->CTAR[0] &= (~ SPI_CTAR_CPHA_MASK); break; case (SPI_CLK_POL_PHA_MODE3): /* Inactive state of SPI_CLK = logic 1 */ dspi_ptr->CTAR[0] |= SPI_CTAR_CPOL_MASK; /* SPI_CLK transitions begining of bit timing */ dspi_ptr->CTAR[0] |= SPI_CTAR_CPHA_MASK; break; default: result = SPI_ERROR_MODE_INVALID; break; } /* Enable SPI module */ dspi_ptr->MCR &= (~ SPI_MCR_HALT_MASK); } break; case IO_IOCTL_SPI_GET_TRANSFER_MODE: if (NULL == param_ptr) { result = SPI_ERROR_INVALID_PARAMETER; } else { if (dspi_ptr->MCR & SPI_MCR_MSTR_MASK) { *param_ptr = SPI_DEVICE_MASTER_MODE; } else { *param_ptr = SPI_DEVICE_SLAVE_MODE; } } break; case IO_IOCTL_SPI_SET_TRANSFER_MODE: if (NULL == param_ptr) { result = SPI_ERROR_INVALID_PARAMETER; } else { /* Disable SPI module */ dspi_ptr->MCR |= SPI_MCR_HALT_MASK; /* Set transfer mode */ if (*param_ptr == SPI_DEVICE_SLAVE_MODE) { dspi_ptr->MCR &= (~ SPI_MCR_MSTR_MASK); } else if (*param_ptr == SPI_DEVICE_MASTER_MODE) { dspi_ptr->MCR |= SPI_MCR_MSTR_MASK; } else { result = SPI_ERROR_TRANSFER_MODE_INVALID; } /* Enable SPI module */ dspi_ptr->MCR &= (~ SPI_MCR_HALT_MASK); } break; case IO_IOCTL_SPI_GET_ENDIAN: if (NULL == param_ptr) { result = SPI_ERROR_INVALID_PARAMETER; } else if (dspi_ptr->CTAR[0] & SPI_CTAR_LSBFE_MASK) { *param_ptr = SPI_DEVICE_LITTLE_ENDIAN; } else { *param_ptr = SPI_DEVICE_BIG_ENDIAN; } break; case IO_IOCTL_SPI_SET_ENDIAN: if (NULL == param_ptr) { result = SPI_ERROR_INVALID_PARAMETER; } else if (! (dspi_ptr->MCR & SPI_MCR_MSTR_MASK)) { result = SPI_ERROR_ENDIAN_INVALID; } else if (*param_ptr == SPI_DEVICE_LITTLE_ENDIAN) { dspi_ptr->CTAR[0] |= SPI_CTAR_LSBFE_MASK; } else if (*param_ptr == SPI_DEVICE_BIG_ENDIAN) { dspi_ptr->CTAR[0] &= (~ SPI_CTAR_LSBFE_MASK); } else { result = SPI_ERROR_ENDIAN_INVALID; } break; case IO_IOCTL_SPI_GET_STATS: if (NULL == param_ptr) { result = SPI_ERROR_INVALID_PARAMETER; } else { *((SPI_STATISTICS_STRUCT_PTR)param_ptr) = io_info_ptr->STATS; } break; case IO_IOCTL_SPI_CLEAR_STATS: io_info_ptr->STATS.INTERRUPTS = 0; io_info_ptr->STATS.RX_PACKETS = 0; io_info_ptr->STATS.RX_OVERFLOWS = 0; io_info_ptr->STATS.TX_PACKETS = 0; io_info_ptr->STATS.TX_ABORTS = 0; io_info_ptr->STATS.TX_UNDERFLOWS= 0; break; case IO_IOCTL_FLUSH_OUTPUT: case IO_IOCTL_SPI_FLUSH_DEASSERT_CS: while ((0 != io_info_ptr->RECEIVING) || (0 != io_info_ptr->ONTHEWAY) || (dspi_ptr->RSER & SPI_RSER_TFFF_RE_MASK)) {}; // waiting for completion if ((0 == (flags & SPI_FLAG_NO_DEASSERT_ON_FLUSH)) || (IO_IOCTL_SPI_FLUSH_DEASSERT_CS == cmd)) { /* Deassert all chip selects */ if (dspi_ptr->MCR & SPI_MCR_MSTR_MASK) { for (num = 0; num < DSPI_CS_COUNT; num++) { if ((NULL != io_info_ptr->CS_CALLBACK[num]) && (0 != (io_info_ptr->CS_ACTIVE & (1 << num)))) { io_info_ptr->CS_CALLBACK[num] (SPI_PUSHR_PCS(1 << num), 1, io_info_ptr->CS_USERDATA[num]); } } io_info_ptr->CS_ACTIVE = 0; dspi_ptr->RSER &= (~ SPI_RSER_RFDF_RE_MASK); val = (uint_32)-1; _dspi_polled_tx_rx (io_info_ptr, (uchar_ptr)&val, TRUE, 0); dspi_ptr->RSER |= SPI_RSER_RFDF_RE_MASK; } } break; case IO_IOCTL_SPI_GET_FRAMESIZE: if (NULL == param_ptr) { result = SPI_ERROR_INVALID_PARAMETER; } else { *param_ptr = SPI_CTAR_FMSZ_GET(dspi_ptr->CTAR[0]) + 1; } break; case IO_IOCTL_SPI_SET_FRAMESIZE: if (NULL == param_ptr) { result = SPI_ERROR_INVALID_PARAMETER; } else { /* Disable SPI module */ dspi_ptr->MCR |= SPI_MCR_HALT_MASK; dspi_ptr->CTAR[0] &= (~ (SPI_CTAR_FMSZ(0x0F))); dspi_ptr->CTAR[0] |= SPI_CTAR_FMSZ(*param_ptr - 1); /* Enable SPI module */ dspi_ptr->MCR &= (~ SPI_MCR_HALT_MASK); } break; case IO_IOCTL_SPI_GET_CS: if (NULL == param_ptr) { result = SPI_ERROR_INVALID_PARAMETER; } else { *param_ptr = SPI_PUSHR_PCS(io_info_ptr->CS); } break; case IO_IOCTL_SPI_SET_CS: if (NULL == param_ptr) { result = SPI_ERROR_INVALID_PARAMETER; } else { io_info_ptr->CS = SPI_PUSHR_PCS_GET(*param_ptr); } break; case IO_IOCTL_SPI_ENABLE_MODF: result = MQX_IO_OPERATION_NOT_AVAILABLE; break; case IO_IOCTL_SPI_DISABLE_MODF: break; case IO_IOCTL_SPI_SET_CS_CALLBACK: if (NULL == param_ptr) { result = SPI_ERROR_INVALID_PARAMETER; } else { callbacks = (SPI_CS_CALLBACK_STRUCT_PTR)(param_ptr); for (num = 0; num < DSPI_CS_COUNT; num++) { if (0 != (callbacks->MASK & (SPI_PUSHR_PCS(1 << num)))) { io_info_ptr->CS_CALLBACK[num] = callbacks->CALLBACK; io_info_ptr->CS_USERDATA[num] = callbacks->USERDATA; } } } break; case IO_IOCTL_SPI_READ_WRITE: if (NULL == param_ptr) { result = SPI_ERROR_INVALID_PARAMETER; } else { rw_ptr = (SPI_READ_WRITE_STRUCT_PTR)param_ptr; command = SPI_PUSHR_CONT_MASK | SPI_PUSHR_PCS(io_info_ptr->CS); size = rw_ptr->BUFFER_LENGTH; input = (uchar_ptr)rw_ptr->WRITE_BUFFER; output = (uchar_ptr)rw_ptr->READ_BUFFER; for (num = 0; num < size; num++) { val = _dspi_polled_tx_rx (io_info_ptr, input, TRUE, command); if (SPI_CTAR_FMSZ_GET(dspi_ptr->CTAR[0]) > 7) { output[0] = (uint_8)(val >> 8); output++; input++; } output[0] = (uint_8)val; output++; input++; io_info_ptr->STATS.RX_PACKETS++; io_info_ptr->STATS.TX_PACKETS++; } } break; case IO_IOCTL_SPI_KEEP_QSPI_CS_ACTIVE: result = MQX_IO_OPERATION_NOT_AVAILABLE; break; default: result = IO_ERROR_INVALID_IOCTL_CMD; break; }
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 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; }
void SetDigitalPot(BYTE Val) { SPI1_PUSHR = Val | SPI_PUSHR_PCS(0x02); }