Beispiel #1
0
/**
  * @brief  Initializes the SPIx peripheral according to the specified 
  *   parameters in the SPI_InitStruct.
  * @param  SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
  * @param  SPI_InitStruct: pointer to a SPI_InitTypeDef structure that
  *   contains the configuration information for the specified SPI peripheral.
  * @retval None
  */
void SPI_Init(SPI_TypeDef* SPIx, SPI_InitTypeDef* SPI_InitStruct)
{
  uint16_t tmpreg = 0;
  
  /* check the parameters */
  assert_param(IS_SPI_ALL_PERIPH(SPIx));   
  
  /* Check the SPI parameters */
  assert_param(IS_SPI_DIRECTION_MODE(SPI_InitStruct->SPI_Direction));
  assert_param(IS_SPI_MODE(SPI_InitStruct->SPI_Mode));
  assert_param(IS_SPI_DATASIZE(SPI_InitStruct->SPI_DataSize));
  assert_param(IS_SPI_CPOL(SPI_InitStruct->SPI_CPOL));
  assert_param(IS_SPI_CPHA(SPI_InitStruct->SPI_CPHA));
  assert_param(IS_SPI_NSS(SPI_InitStruct->SPI_NSS));
  assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_InitStruct->SPI_BaudRatePrescaler));
  assert_param(IS_SPI_FIRST_BIT(SPI_InitStruct->SPI_FirstBit));
  assert_param(IS_SPI_CRC_POLYNOMIAL(SPI_InitStruct->SPI_CRCPolynomial));

/*---------------------------- SPIx CR1 Configuration ------------------------*/
  /* Get the SPIx CR1 value */
  tmpreg = SPIx->CR1;
  /* Clear BIDIMode, BIDIOE, RxONLY, SSM, SSI, LSBFirst, BR, MSTR, CPOL and CPHA bits */
  tmpreg &= CR1_CLEAR_Mask;
  /* Configure SPIx: direction, NSS management, first transmitted bit, BaudRate prescaler
     master/salve mode, CPOL and CPHA */
  /* Set BIDImode, BIDIOE and RxONLY bits according to SPI_Direction value */
  /* Set SSM, SSI and MSTR bits according to SPI_Mode and SPI_NSS values */
  /* Set LSBFirst bit according to SPI_FirstBit value */
  /* Set BR bits according to SPI_BaudRatePrescaler value */
  /* Set CPOL bit according to SPI_CPOL value */
  /* Set CPHA bit according to SPI_CPHA value */
  tmpreg |= (uint16_t)((uint32_t)SPI_InitStruct->SPI_Direction | SPI_InitStruct->SPI_Mode |
                  SPI_InitStruct->SPI_DataSize | SPI_InitStruct->SPI_CPOL |  
                  SPI_InitStruct->SPI_CPHA | SPI_InitStruct->SPI_NSS |  
                  SPI_InitStruct->SPI_BaudRatePrescaler | SPI_InitStruct->SPI_FirstBit);
  /* Write to SPIx CR1 */
  SPIx->CR1 = tmpreg;
  
  /* Activate the SPI mode (Reset I2SMOD bit in I2SCFGR register) */
  SPIx->I2SCFGR &= SPI_Mode_Select;		

/*---------------------------- SPIx CRCPOLY Configuration --------------------*/
  /* Write to SPIx CRCPOLY */
  SPIx->CRCPR = SPI_InitStruct->SPI_CRCPolynomial;
}
Beispiel #2
0
/*******************************************************************************
* 函数名称: SPI_I2S_DMACmd
* 功能描述: 使能或禁止SPIx/I2Sx DMA接口.
* 输入参数: (1)SPIx: x可以是 :
*                         - 1, 2 或 3 在 SPI 模式 
*                         - 2 或 3 在 I2S 模式
*           (2)SPI_I2S_DMAReq: 指定的 SPI/I2S DMA 传输请求被使能或禁止。
*                    这个参数可以是下面任意值的组合:
*                       - SPI_I2S_DMAReq_Tx: 发送缓冲 DMA传输请求
*                       - SPI_I2S_DMAReq_Rx:  接收缓冲DMA 传输请求
*           (3)NewState:选择的 SPI/I2S DMA传输请求新状态 
*                    这个参数可以是: ENABLE 或DISABLE.
* 输出参数: 无
* 返回参数: 无
*******************************************************************************/
void SPI_I2S_DMACmd(SPI_TypeDef* SPIx, u16 SPI_I2S_DMAReq, FunctionalState NewState)
{
  /* Check the parameters [检查参数]*/
  assert_param(IS_SPI_ALL_PERIPH(SPIx));
  assert_param(IS_FUNCTIONAL_STATE(NewState));
  assert_param(IS_SPI_I2S_DMAREQ(SPI_I2S_DMAReq));

  if (NewState != DISABLE)
  {
    /* Enable the selected SPI/I2S DMA requests [使能选择的SPI/I2S DMA请求]*/
    SPIx->CR2 |= SPI_I2S_DMAReq;
  }
  else
  {
    /* Disable the selected SPI/I2S DMA requests [禁止选择的SPI/I2S DMA请求]*/
    SPIx->CR2 &= (u16)~SPI_I2S_DMAReq;
  }
}
/**
  * @brief  Enables or disables the SPIx/I2Sx DMA interface.
  * @param  SPIx: where x can be 1 or 2 in SPI mode or 1 in I2S mode to select 
  *         the SPI peripheral.
  * @param  SPI_I2S_DMAReq: specifies the SPI DMA transfer request to be enabled or disabled. 
  *          This parameter can be any combination of the following values:
  *            @arg SPI_I2S_DMAReq_Tx: Tx buffer DMA transfer request
  *            @arg SPI_I2S_DMAReq_Rx: Rx buffer DMA transfer request
  * @param  NewState: new state of the selected SPI DMA transfer request.
  *          This parameter can be: ENABLE or DISABLE.
  * @retval None
  */
void SPI_I2S_DMACmd(SPI_TypeDef* SPIx, uint16_t SPI_I2S_DMAReq, FunctionalState NewState)
{
  /* Check the parameters */
  assert_param(IS_SPI_ALL_PERIPH(SPIx));
  assert_param(IS_FUNCTIONAL_STATE(NewState));
  assert_param(IS_SPI_I2S_DMA_REQ(SPI_I2S_DMAReq));

  if (NewState != DISABLE)
  {
    /* Enable the selected SPI DMA requests */
    SPIx->CR2 |= SPI_I2S_DMAReq;
  }
  else
  {
    /* Disable the selected SPI DMA requests */
    SPIx->CR2 &= (uint16_t)~SPI_I2S_DMAReq;
  }
}
Beispiel #4
0
/***********************************************************************************************
 功能:SPI DMA命令
 形参:SPIx SPI 模块号
       @arg: SPI0 模块
			 @arg: SPI1 模块
       @arg: SPI2 模块
			 SPI_IT: 中断标志
			 @arg  SPI_DMAReq_TFFF: 发送队列结束标志
       @arg  SPI_DMAReq_RFDF: 接收缓冲区满
 返回:0
 详解:0
************************************************************************************************/
void SPI_DMACmd(SPI_Type* SPIx, uint16_t SPI_DMAReq, FunctionalState NewState)
{
	//参数检查
	assert_param(IS_SPI_ALL_PERIPH(SPIx));
	assert_param(SPI_DMAREQ(SPI_DMAReq));
	assert_param(IS_FUNCTIONAL_STATE(NewState));
	
	switch(SPI_DMAReq)
	{
		case SPI_DMAReq_TFFF:
			(ENABLE == NewState)?(SPIx->RSER |= SPI_RSER_TFFF_DIRS_MASK):(SPIx->RSER &= ~SPI_RSER_TFFF_DIRS_MASK);
			break;
		case SPI_DMAReq_RFDF:
			(ENABLE == NewState)?(SPIx->RSER |= SPI_RSER_RFDF_DIRS_MASK):(SPIx->RSER &= ~SPI_RSER_RFDF_DIRS_MASK);
			break;
		default:break;
	}
}
Beispiel #5
0
/**
  * @brief  Returns the transmit or the receive CRC register value for the specified SPI.
  * @param  SPIx: where x can be 1 or 2 to select the SPI peripheral.
  * @param  SPI_CRC: specifies the CRC register to be read.
  *   This parameter can be one of the following values:
  *     @arg SPI_CRC_Tx: Selects Tx CRC register
  *     @arg SPI_CRC_Rx: Selects Rx CRC register
  * @retval The selected CRC register value..
  */
uint16_t SPI_GetCRC(SPI_TypeDef* SPIx, uint8_t SPI_CRC)
{
    uint16_t crcreg = 0;
    /* Check the parameters */
    assert_param(IS_SPI_ALL_PERIPH(SPIx));
    assert_param(IS_SPI_CRC(SPI_CRC));

    if (SPI_CRC != SPI_CRC_Rx) {
        /* Get the Tx CRC register */
        crcreg = SPIx->TXCRCR;
    } else {
        /* Get the Rx CRC register */
        crcreg = SPIx->RXCRCR;
    }

    /* Return the selected CRC register */
    return crcreg;
}
Beispiel #6
0
/**
  * @brief  Deinitializes the SPIx peripheral registers to their default
  *         reset values.
  * @param  SPIx: where x can be 1 or 2 to select the SPI peripheral.
  * @retval None
  */
void SPI_I2S_DeInit(SPI_TypeDef* SPIx)
{
    /* Check the parameters */
    assert_param(IS_SPI_ALL_PERIPH(SPIx));

    if (SPIx == SPI1) {
        /* Enable SPI1 reset state */
        RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1, ENABLE);
        /* Release SPI1 from reset state */
        RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1, DISABLE);
    } else {
        if (SPIx == SPI2) {
            /* Enable SPI2 reset state */
            RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2, ENABLE);
            /* Release SPI2 from reset state */
            RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2, DISABLE);
        }
    }
}
Beispiel #7
0
/**
  * @brief  Checks whether the specified SPI flag is set or not.
  * @param  SPIx: where x can be 1 or 2 in SPI mode or 1 in I2S mode to select
  *   the SPI peripheral.
  * @param  SPI_I2S_FLAG: specifies the SPI flag to check.
  *   This parameter can be one of the following values:
  *     @arg SPI_I2S_FLAG_TXE: Transmit buffer empty flag.
  *     @arg SPI_I2S_FLAG_RXNE: Receive buffer not empty flag.
  *     @arg SPI_I2S_FLAG_BSY: Busy flag.
  *     @arg SPI_I2S_FLAG_OVR: Overrun flag.
  *     @arg SPI_I2S_FLAG_MODF: Mode Fault flag.
  *     @arg SPI_I2S_FLAG_CRCERR: CRC Error flag.
  *     @arg SPI_I2S_FLAG_FRE: TI frame format error flag.
  *     @arg I2S_FLAG_UDR: Underrun Error flag.
  *     @arg I2S_FLAG_CHSIDE: Channel Side flag.
  * @retval The new state of SPI_I2S_FLAG (SET or RESET).
  */
FlagStatus SPI_I2S_GetFlagStatus(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG)
{
    FlagStatus bitstatus = RESET;
    /* Check the parameters */
    assert_param(IS_SPI_ALL_PERIPH(SPIx));
    assert_param(IS_SPI_I2S_GET_FLAG(SPI_I2S_FLAG));

    /* Check the status of the specified SPI flag */
    if ((SPIx->SR & SPI_I2S_FLAG) != (uint16_t)RESET) {
        /* SPI_I2S_FLAG is set */
        bitstatus = SET;
    } else {
        /* SPI_I2S_FLAG is reset */
        bitstatus = RESET;
    }

    /* Return the SPI_I2S_FLAG status */
    return  bitstatus;
}
Beispiel #8
0
/*******************************************************************************
* 函数名称: SPI_I2S_GetFlagStatus
* 功能描述: 检查指定的SPI/I2S标记是否被置位.
* 输入参数: (1)- SPIx: x可以是 :
*                         - 1, 2 或 3 在 SPI 模式 
*                         - 2 或 3 在 I2S 模式
*           (2)检查指定的SPI/I2S标记是否被设置. 
*                    这个参数可以是下面的值之一:
*                       - SPI_I2S_FLAG_TXE: 传输缓冲为空标记.
*                       - SPI_I2S_FLAG_RXNE: 接收缓冲不空标记.
*                       - SPI_I2S_FLAG_BSY: 忙碌标记.
*                       - SPI_I2S_FLAG_OVR: 溢出标记.
*                       - SPI_FLAG_MODF: 模式错误标记.
*                       - SPI_FLAG_CRCERR: CRC校验错误标记.
*                       - I2S_FLAG_UDR: 空栈读出错标记. 
*                       - I2S_FLAG_CHSIDE: 通道边标志.
* 输出参数: 无
* 返回参数: SPI_I2S_FLAG标记的新状态  (SET or RESET).
*******************************************************************************/
FlagStatus SPI_I2S_GetFlagStatus(SPI_TypeDef* SPIx, u16 SPI_I2S_FLAG)
{
  FlagStatus bitstatus = RESET;

  /* Check the parameters [检查参数]*/
  assert_param(IS_SPI_ALL_PERIPH(SPIx));
  assert_param(IS_SPI_I2S_GET_FLAG(SPI_I2S_FLAG));

  /* Check the status of the specified SPI/I2S flag [检查指定的SPI/I2S标志状态]*/
  if ((SPIx->SR & SPI_I2S_FLAG) != (u16)RESET)
  {
    /* SPI_I2S_FLAG is set [置位SPI_I2S_FLAG]*/
    bitstatus = SET;
  }
  else
  {
    /* SPI_I2S_FLAG is reset [复位SPI_I2S_FLAG]*/
    bitstatus = RESET;
  }
  /* Return the SPI_I2S_FLAG status [返回SPI_I2S_FLAG状态]*/
  return  bitstatus;
}
Beispiel #9
0
/*******************************************************************************
* 函数名称: SPI_GetCRC
* 功能描述: 返回特定SPI外设传送或接收的CRC寄存器的值.
* 输入参数: (1)SPIx :x为1,2或3用于选定SPI外设。
*           (2)SPI_CRC:将被读取的CRC寄存器。
*                    这个参数可以是下面的值之一:
*                       - SPI_CRC_Tx: 选择Tx CRC寄存器
*                       - SPI_CRC_Rx: 选择Rx CRC寄存器
* 输出参数: 无
* 返回参数: 所选择的CRC寄存器的值。
*******************************************************************************/
u16 SPI_GetCRC(SPI_TypeDef* SPIx, u8 SPI_CRC)
{
  u16 crcreg = 0;

  /* Check the parameters [检查参数]*/
  assert_param(IS_SPI_ALL_PERIPH(SPIx));
  assert_param(IS_SPI_CRC(SPI_CRC));

  if (SPI_CRC != SPI_CRC_Rx)
  {
    /* Get the Tx CRC register [取得Tx CRC寄存器]*/
    crcreg = SPIx->TXCRCR;
  }
  else
  {
    /* Get the Rx CRC register [取得Rx CRC寄存器]*/
    crcreg = SPIx->RXCRCR;
  }

  /* Return the selected CRC register [返回选择的CRC寄存器]*/
  return crcreg;
}
/**
  * @brief  Enables or disables the specified SPI/I2S interrupts.
  * @param SPIx: where x can be :
  *   1, 2 or 3 in SPI mode 
  *   2 or 3 in I2S mode
  * @param SPI_I2S_IT: specifies the SPI/I2S interrupt source to be 
  *   enabled or disabled. 
  *   This parameter can be one of the following values:
  * @arg SPI_I2S_IT_TXE: Tx buffer empty interrupt mask
  * @arg SPI_I2S_IT_RXNE: Rx buffer not empty interrupt mask
  * @arg SPI_I2S_IT_ERR: Error interrupt mask
  * @param NewState: new state of the specified SPI/I2S interrupt.
  *   This parameter can be: ENABLE or DISABLE.
  * @retval : None
  */
void SPI_I2S_ITConfig(SPI_TypeDef* SPIx, uint8_t SPI_I2S_IT, FunctionalState NewState)
{
  uint16_t itpos = 0, itmask = 0 ;
  /* Check the parameters */
  assert_param(IS_SPI_ALL_PERIPH(SPIx));
  assert_param(IS_FUNCTIONAL_STATE(NewState));
  assert_param(IS_SPI_I2S_CONFIG_IT(SPI_I2S_IT));
  /* Get the SPI/I2S IT index */
  itpos = SPI_I2S_IT >> 4;
  /* Set the IT mask */
  itmask = (uint16_t)((uint16_t)1 << itpos);
  if (NewState != DISABLE)
  {
    /* Enable the selected SPI/I2S interrupt */
    SPIx->CR2 |= itmask;
  }
  else
  {
    /* Disable the selected SPI/I2S interrupt */
    SPIx->CR2 &= (uint16_t)~itmask;
  }
}
/**
  * @brief  Initializes the SPIx peripheral according to the specified 
  *         parameters in the I2S_InitStruct.
  * @param  SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
  * @param  I2S_InitStruct: pointer to an I2S_InitTypeDef structure that
  *         contains the configuration information for the specified SPI peripheral
  *         configured in I2S mode.
  * @note   This function calculates the optimal prescaler needed to obtain the most 
  *         accurate audio frequency (depending on the I2S clock source, the PLL values 
  *         and the product configuration). But in case the prescaler value is greater 
  *         than 511, the default value (0x02) will be configured instead.
  * @retval None
  */
void I2S_Init(SPI_TypeDef* SPIx, I2S_InitTypeDef* I2S_InitStruct)
{
  uint16_t tmpreg = 0, i2sdiv = 2, i2sodd = 0, packetlength = 1;
  uint32_t tmp = 0;
  RCC_ClocksTypeDef RCC_Clocks;
  uint32_t sourceclock = 0;

  /* Check the I2S parameters */
  assert_param(IS_SPI_ALL_PERIPH(SPIx));
  assert_param(IS_I2S_MODE(I2S_InitStruct->I2S_Mode));
  assert_param(IS_I2S_STANDARD(I2S_InitStruct->I2S_Standard));
  assert_param(IS_I2S_DATA_FORMAT(I2S_InitStruct->I2S_DataFormat));
  assert_param(IS_I2S_MCLK_OUTPUT(I2S_InitStruct->I2S_MCLKOutput));
  assert_param(IS_I2S_AUDIO_FREQ(I2S_InitStruct->I2S_AudioFreq));
  assert_param(IS_I2S_CPOL(I2S_InitStruct->I2S_CPOL));  

/*----------------------- SPIx I2SCFGR & I2SPR Configuration -----------------*/
  /* Clear I2SMOD, I2SE, I2SCFG, PCMSYNC, I2SSTD, CKPOL, DATLEN and CHLEN bits */
  SPIx->I2SCFGR &= I2SCFGR_CLEAR_Mask; 
  SPIx->I2SPR = 0x0002;

  /* Get the I2SCFGR register value */
  tmpreg = SPIx->I2SCFGR;

  /* If the default value has to be written, reinitialize i2sdiv and i2sodd*/
  if(I2S_InitStruct->I2S_AudioFreq == I2S_AudioFreq_Default)
  {
    i2sodd = (uint16_t)0;
    i2sdiv = (uint16_t)2;   
  }
  /* If the requested audio frequency is not the default, compute the prescaler */
  else
  {
    /* Check the frame length (For the Prescaler computing) */
    if(I2S_InitStruct->I2S_DataFormat == I2S_DataFormat_16b)
    {
      /* Packet length is 16 bits */
      packetlength = 1;
    }
    else
    {
      /* Packet length is 32 bits */
      packetlength = 2;
    }

    /* I2S Clock source is System clock: Get System Clock frequency */
    RCC_GetClocksFreq(&RCC_Clocks);      

    /* Get the source clock value: based on System Clock value */
    sourceclock = RCC_Clocks.SYSCLK_Frequency;    

    /* Compute the Real divider depending on the MCLK output state with a floating point */
    if(I2S_InitStruct->I2S_MCLKOutput == I2S_MCLKOutput_Enable)
    {
      /* MCLK output is enabled */
      tmp = (uint16_t)(((((sourceclock / 256) * 10) / I2S_InitStruct->I2S_AudioFreq)) + 5);
    }
    else
    {
      /* MCLK output is disabled */
      tmp = (uint16_t)(((((sourceclock / (32 * packetlength)) *10 ) / I2S_InitStruct->I2S_AudioFreq)) + 5);
    }
    
    /* Remove the floating point */
    tmp = tmp / 10;

    /* Check the parity of the divider */
    i2sodd = (uint16_t)(tmp & (uint16_t)0x0001);

    /* Compute the i2sdiv prescaler */
    i2sdiv = (uint16_t)((tmp - i2sodd) / 2);

    /* Get the Mask for the Odd bit (SPI_I2SPR[8]) register */
    i2sodd = (uint16_t) (i2sodd << 8);
  }

  /* Test if the divider is 1 or 0 or greater than 0xFF */
  if ((i2sdiv < 2) || (i2sdiv > 0xFF))
  {
    /* Set the default values */
    i2sdiv = 2;
    i2sodd = 0;
  }

  /* Write to SPIx I2SPR register the computed value */
  SPIx->I2SPR = (uint16_t)(i2sdiv | (uint16_t)(i2sodd | (uint16_t)I2S_InitStruct->I2S_MCLKOutput));

  /* Configure the I2S with the SPI_InitStruct values */
  tmpreg |= (uint16_t)(SPI_I2SCFGR_I2SMOD | (uint16_t)(I2S_InitStruct->I2S_Mode | \
                  (uint16_t)(I2S_InitStruct->I2S_Standard | (uint16_t)(I2S_InitStruct->I2S_DataFormat | \
                  (uint16_t)I2S_InitStruct->I2S_CPOL))));

  /* Write to SPIx I2SCFGR */
  SPIx->I2SCFGR = tmpreg;
}