Esempio n. 1
0
//! 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;
}
Esempio n. 2
0
//! 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;
}
Esempio n. 3
0
/*
 * 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;
}
Esempio n. 4
0
/*
 * 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;
  
}
Esempio n. 5
0
//! 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;
}
Esempio n. 6
0
/*********************************************************
* 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*/
Esempio n. 7
0
/***********************************************************************************************
 功能: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;
}
Esempio n. 8
0
/*
 * 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 ;            
}
Esempio n. 9
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
  }
Esempio n. 10
0
/**
  * @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;
}
Esempio n. 11
0
/**
 * @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;
}
Esempio n. 12
0
/*
 * 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
}
Esempio n. 13
0
/*
 * 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
}
Esempio n. 14
0
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;
}
Esempio n. 15
0
/**
 * @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;
}
Esempio n. 16
0
// 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;
	}
}
Esempio n. 17
0
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);
}
Esempio n. 18
0
/*********************************************************
* 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*/
Esempio n. 19
0
/*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;
}
Esempio n. 20
0
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));
}
Esempio n. 21
0
/*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!!! ***/
Esempio n. 22
0
/*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);
}
Esempio n. 24
0
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);
}
Esempio n. 25
0
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;
}
Esempio n. 26
0
void SetDigitalPot(BYTE Val)
{
	SPI1_PUSHR = Val | SPI_PUSHR_PCS(0x02);
}