STM32F10x_StdPeriph_Examples/I2S/SPI_I2S_Switch/main.c

Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    I2S/SPI_I2S_Switch/main.c 
00004   * @author  MCD Application Team
00005   * @version V3.4.0
00006   * @date    10/15/2010
00007   * @brief   Main program body
00008   ******************************************************************************
00009   * @copy
00010   *
00011   * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
00012   * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
00013   * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
00014   * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
00015   * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
00016   * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
00017   *
00018   * <h2><center>&copy; COPYRIGHT 2010 STMicroelectronics</center></h2>
00019   */ 
00020 
00021 /* Includes ------------------------------------------------------------------*/
00022 #include "stm32f10x.h"
00023 
00024 /* Local includes ------------------------------------------------------------*/
00025 
00026 /** @addtogroup STM32F10x_StdPeriph_Examples
00027   * @{
00028   */
00029 
00030 /** @addtogroup I2S_SPI_I2S_Switch
00031   * @{
00032   */ 
00033 
00034 /* Private typedef -----------------------------------------------------------*/
00035 typedef enum {FAILED = 0, PASSED = !FAILED} TestStatus;
00036 
00037 /* Private define ------------------------------------------------------------*/
00038 #define BufferSize   32
00039 
00040 /* Private macro -------------------------------------------------------------*/
00041 /* Private variables ---------------------------------------------------------*/
00042 I2S_InitTypeDef I2S_InitStructure;
00043 SPI_InitTypeDef SPI_InitStructure;
00044 uint16_t I2S3_Buffer_Tx[BufferSize] = {0x0102, 0x0304, 0x0506, 0x0708, 0x090A, 0x0B0C,
00045                                   0x0D0E, 0x0F10, 0x1112, 0x1314, 0x1516, 0x1718,
00046                                   0x191A, 0x1B1C, 0x1D1E, 0x1F20, 0x2122, 0x2324,
00047                                   0x2526, 0x2728, 0x292A, 0x2B2C, 0x2D2E, 0x2F30,
00048                                   0x3132, 0x3334, 0x3536, 0x3738, 0x393A, 0x3B3C,
00049                                   0x3D3E, 0x3F40};
00050 
00051 uint16_t SPI3_Buffer_Tx[BufferSize] = {0x5152, 0x5354, 0x5556, 0x5758, 0x595A, 0x5B5C,
00052                                   0x5D5E, 0x5F60, 0x6162, 0x6364, 0x6566, 0x6768,
00053                                   0x696A, 0x6B6C, 0x6D6E, 0x6F70, 0x7172, 0x7374,
00054                                   0x7576, 0x7778, 0x797A, 0x7B7C, 0x7D7E, 0x7F80,
00055                                   0x8182, 0x8384, 0x8586, 0x8788, 0x898A, 0x8B8C,
00056                                   0x8D8E, 0x8F90};
00057 
00058 __IO uint16_t I2S2_Buffer_Rx[BufferSize];
00059 __IO uint16_t SPI2_Buffer_Rx[BufferSize];
00060 __IO uint8_t TxIdx = 0, RxIdx = 0;
00061 volatile TestStatus TransferStatus1 = FAILED, TransferStatus2 = FAILED;
00062 volatile TestStatus TransferStatus3 = FAILED;
00063 ErrorStatus HSEStartUpStatus;
00064 
00065 /* Private functions ---------------------------------------------------------*/
00066 void RCC_Configuration(void);
00067 void GPIO_Configuration(void);
00068 TestStatus Buffercmp(uint16_t* pBuffer1, uint16_t* pBuffer2, uint16_t BufferLength);
00069 
00070 /**
00071   * @brief   Main program
00072   * @param  None
00073   * @retval None
00074   */
00075 int main(void)
00076 {
00077   /*!< At this stage the microcontroller clock setting is already configured, 
00078        this is done through SystemInit() function which is called from startup
00079        file (startup_stm32f10x_xx.s) before to branch to application main.
00080        To reconfigure the default setting of SystemInit() function, refer to
00081        system_stm32f10x.c file
00082      */     
00083        
00084   /* System clocks configuration ---------------------------------------------*/
00085   RCC_Configuration();
00086 
00087   /* GPIO configuration ------------------------------------------------------*/
00088   GPIO_Configuration();
00089  
00090   /* Deinitializes the SPI2 and SPI3 peripheral registers --------------------*/
00091   SPI_I2S_DeInit(SPI2);
00092   SPI_I2S_DeInit(SPI3);
00093   
00094   /* I2S peripheral configuration */
00095   I2S_InitStructure.I2S_Standard = I2S_Standard_Phillips;
00096   I2S_InitStructure.I2S_DataFormat = I2S_DataFormat_16bextended;
00097   I2S_InitStructure.I2S_MCLKOutput = I2S_MCLKOutput_Disable;
00098   I2S_InitStructure.I2S_AudioFreq = I2S_AudioFreq_48k;
00099   I2S_InitStructure.I2S_CPOL = I2S_CPOL_Low;
00100 
00101   /* I2S3 Master Transmitter to I2S2 Slave Receiver communication ------------*/
00102   /* I2S3 configuration */
00103   I2S_InitStructure.I2S_Mode = I2S_Mode_MasterTx;
00104   I2S_Init(SPI3, &I2S_InitStructure);
00105 
00106   /* I2S2 configuration */
00107   I2S_InitStructure.I2S_Mode = I2S_Mode_SlaveRx;
00108   I2S_Init(SPI2, &I2S_InitStructure);
00109 
00110   /* Enable the I2S2 */
00111   I2S_Cmd(SPI2, ENABLE);
00112 
00113   /* Enable the I2S3 */
00114   I2S_Cmd(SPI3, ENABLE);
00115 
00116   /* Begin the communication in I2S mode */
00117   while (RxIdx < BufferSize)
00118   {
00119     /* Wait the Tx buffer to be empty */
00120     while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE) == RESET)
00121     {}
00122     /* Send a data from I2S3 */
00123     SPI_I2S_SendData(SPI3, I2S3_Buffer_Tx[TxIdx++]);
00124 
00125     /* Wait the Rx buffer to be full */
00126     while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET)
00127     {}
00128     /* Store the I2S2 received data in the relative data table */
00129     I2S2_Buffer_Rx[RxIdx++] = SPI_I2S_ReceiveData(SPI2);
00130   }
00131 
00132   TransferStatus1 = Buffercmp((uint16_t *)I2S2_Buffer_Rx, I2S3_Buffer_Tx, BufferSize);
00133   /* TransferStatus1 = PASSED, if the data transmitted from I2S3 and received by
00134                                I2S2 are the same 
00135      TransferStatus1 = FAILED, if the data transmitted from I2S3 and received by
00136                                I2S2 are different */
00137 
00138   /* Reset TxIdx, RxIdx indexes */
00139   TxIdx = 0;
00140   RxIdx = 0;
00141   
00142   /* Switch to SPI mode communication ----------------------------------------*/
00143   /* SPI3 configuration */
00144   SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx;
00145   SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
00146   SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;
00147   SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
00148   SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
00149   SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
00150   SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
00151   SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
00152   SPI_InitStructure.SPI_CRCPolynomial = 7;
00153   SPI_Init(SPI3, &SPI_InitStructure);
00154 
00155   /* SPI2 configuration ------------------------------------------------------*/
00156   SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_RxOnly;
00157   SPI_InitStructure.SPI_Mode = SPI_Mode_Slave;
00158   SPI_Init(SPI2, &SPI_InitStructure);
00159 
00160   /* Enable SPI2 */
00161   SPI_Cmd(SPI2, ENABLE);
00162   /* Enable SPI3 */
00163   SPI_Cmd(SPI3, ENABLE);
00164 
00165   /* Begin the communication in SPI mode */
00166   while (RxIdx < BufferSize)
00167   {
00168     /* Wait the Tx buffer to be empty */
00169     while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE) == RESET)
00170     {}
00171     /* Send a data from SPI3 */
00172     SPI_I2S_SendData(SPI3, SPI3_Buffer_Tx[TxIdx++]);
00173 
00174     /* Wait the Rx buffer to be full */
00175     while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET)
00176     {}
00177     /* Store the SPI2 received data in the relative data table */
00178     SPI2_Buffer_Rx[RxIdx++] = SPI_I2S_ReceiveData(SPI2);
00179   }
00180 
00181   TransferStatus2 = Buffercmp((uint16_t *)SPI2_Buffer_Rx, SPI3_Buffer_Tx, BufferSize);
00182   /* TransferStatus2 = PASSED, if the data transmitted from SPI3 and received by
00183                                SPI2 are the same
00184      TransferStatus2 = FAILED, if the data transmitted from SPI3 and received by
00185                                SPI2 are different */
00186 
00187   /* Reset TxIdx, RxIdx indexes and receive table values */
00188   for (TxIdx = 0; TxIdx < BufferSize; TxIdx++)
00189   {
00190     I2S2_Buffer_Rx[TxIdx] = 0;
00191   }
00192   
00193   TxIdx = 0;
00194   RxIdx = 0;
00195       
00196   /* I2S3 Slave Transmitter to I2S2 Master Receiver communication ------------*/
00197   /* I2S3 configuration */
00198   I2S_InitStructure.I2S_Mode = I2S_Mode_SlaveTx;
00199   I2S_Init(SPI3, &I2S_InitStructure);
00200 
00201   /* I2S2 configuration */
00202   I2S_InitStructure.I2S_Mode = I2S_Mode_MasterRx;
00203   I2S_Init(SPI2, &I2S_InitStructure);
00204 
00205   /* Wait the Tx buffer to be empty */
00206   while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE) == RESET)
00207   {}
00208   /* Prepare the first data to be sent from the slave */
00209   SPI_I2S_SendData(SPI3, I2S3_Buffer_Tx[TxIdx++]);
00210 
00211   /* Enable the I2S3 */
00212   I2S_Cmd(SPI3, ENABLE);
00213 
00214   /* Enable the I2S2 */
00215   I2S_Cmd(SPI2, ENABLE);
00216 
00217   /* Begin the communication in I2S mode */
00218   while (RxIdx < BufferSize)
00219   {
00220     /* Wait the Rx buffer to be full */
00221     while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET)
00222     {}
00223     /* Store the I2S2 received data in the relative data table */
00224     I2S2_Buffer_Rx[RxIdx++] = SPI_I2S_ReceiveData(SPI2);
00225 
00226     /* Wait the Tx buffer to be empty */
00227     while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE) == RESET)
00228     {}
00229     /* Send a data from I2S3 */
00230     SPI_I2S_SendData(SPI3, I2S3_Buffer_Tx[TxIdx++]);
00231   }
00232 
00233   TransferStatus3 = Buffercmp((uint16_t *)I2S2_Buffer_Rx, I2S3_Buffer_Tx, BufferSize);
00234   /* TransferStatus3 = PASSED, if the data transmitted from I2S3 and received by
00235                                I2S2 are the same
00236      TransferStatus3 = FAILED, if the data transmitted from I2S3 and received by
00237                                I2S2 are different */
00238  
00239   while (1)
00240   {}
00241 }
00242 
00243 /**
00244   * @brief  Configures the different system clocks.
00245   * @param  None
00246   * @retval None
00247   */
00248 void RCC_Configuration(void)
00249 {
00250   /* RCC system reset(for debug purpose) */
00251   RCC_DeInit();
00252 
00253   /* Enable HSE */
00254   RCC_HSEConfig(RCC_HSE_ON);
00255 
00256   /* Wait till HSE is ready */
00257   HSEStartUpStatus = RCC_WaitForHSEStartUp();
00258 
00259   if(HSEStartUpStatus == SUCCESS)
00260   {
00261     /* Enable Prefetch Buffer */
00262     FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
00263 
00264     /* Flash 2 wait state */
00265     FLASH_SetLatency(FLASH_Latency_2);
00266         
00267     /* HCLK = SYSCLK */
00268     RCC_HCLKConfig(RCC_SYSCLK_Div1); 
00269   
00270     /* PCLK2 = HCLK */
00271     RCC_PCLK2Config(RCC_HCLK_Div1); 
00272 
00273     /* PCLK1 = HCLK/2 */
00274     RCC_PCLK1Config(RCC_HCLK_Div2);
00275 
00276     /* ADCCLK = PCLK2/4 */
00277     RCC_ADCCLKConfig(RCC_PCLK2_Div4); 
00278   
00279 #ifndef STM32F10X_CL  
00280     /* PLLCLK = 8MHz * 9 = 72 MHz */
00281     RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
00282 
00283 #else
00284     /* Configure PLLs *********************************************************/
00285     /* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */
00286     RCC_PREDIV2Config(RCC_PREDIV2_Div5);
00287     RCC_PLL2Config(RCC_PLL2Mul_8);
00288 
00289     /* Enable PLL2 */
00290     RCC_PLL2Cmd(ENABLE);
00291 
00292     /* Wait till PLL2 is ready */
00293     while (RCC_GetFlagStatus(RCC_FLAG_PLL2RDY) == RESET)
00294     {}
00295 
00296     /* PLL configuration: PLLCLK = (PLL2 / 5) * 9 = 72 MHz */ 
00297     RCC_PREDIV1Config(RCC_PREDIV1_Source_PLL2, RCC_PREDIV1_Div5);
00298     RCC_PLLConfig(RCC_PLLSource_PREDIV1, RCC_PLLMul_9);
00299 
00300     /* PPL3 configuration: PLL3CLK = (HSE / 5) * 11 = PLL3_VCO = 110 MHz */
00301     RCC_PLL3Config(RCC_PLL3Mul_11);
00302     /* Enable PLL3 */
00303     RCC_PLL3Cmd(ENABLE);    
00304     /* Wait till PLL3 is ready */
00305     while (RCC_GetFlagStatus(RCC_FLAG_PLL3RDY) == RESET)
00306     {}
00307 
00308     /* Configure I2S clock source: On Connectivity-Line Devices, the I2S can be 
00309         clocked by PLL3 VCO instead of SYS_CLK in order to guarantee higher 
00310         precision */
00311     RCC_I2S3CLKConfig(RCC_I2S3CLKSource_PLL3_VCO);
00312     RCC_I2S2CLKConfig(RCC_I2S2CLKSource_PLL3_VCO);  
00313 #endif
00314 
00315     /* Enable PLL */ 
00316     RCC_PLLCmd(ENABLE);
00317 
00318     /* Wait till PLL is ready */
00319     while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
00320     {
00321     }
00322 
00323     /* Select PLL as system clock source */
00324     RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
00325 
00326     /* Wait till PLL is used as system clock source */
00327     while(RCC_GetSYSCLKSource() != 0x08)
00328     {
00329     }
00330   }  
00331   
00332   /* Enable peripheral clocks --------------------------------------------------*/
00333   /* GPIOA, GPIOB and AFIO clocks enable */
00334   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |
00335                          RCC_APB2Periph_AFIO, ENABLE);
00336 
00337 #ifdef USE_STM3210C_EVAL 
00338   /* GPIOC Clock enable (for the SPI3 remapped pins)  */
00339   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC , ENABLE);  
00340 #endif /* USE_STM3210C_EVAL */  
00341   
00342   /* SPI2 and SPI3 clocks enable */
00343   RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2 | RCC_APB1Periph_SPI3, ENABLE);  
00344 }
00345 
00346 /**
00347   * @brief  Configures the different GPIO ports.
00348   * @param  None
00349   * @retval None
00350   */
00351 void GPIO_Configuration(void)
00352 {
00353   GPIO_InitTypeDef GPIO_InitStructure;
00354 
00355 #ifdef USE_STM3210E_EVAL
00356   /* Disable the JTAG interface and enable the SWJ interface
00357       This operation is not necessary for Connectivity-Line devices since
00358       SPI3 I/Os can be remapped on other GPIO pins */
00359   GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
00360 #endif /* USE_STM3210E_EVAL */ 
00361 
00362   /* Configure SPI2 pins: CK, WS and SD ---------------------------------*/
00363   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_15;
00364   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
00365   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
00366   GPIO_Init(GPIOB, &GPIO_InitStructure);
00367 
00368 #ifdef USE_STM3210C_EVAL
00369   
00370   /* Remap SPI3 on PC10-PC11-PC12-PA4 GPIO pins ------------------------*/
00371   GPIO_PinRemapConfig(GPIO_Remap_SPI3, ENABLE);
00372   
00373   /* Configure SPI3 pins: CK and SD ------------------------------------*/
00374   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_12;
00375   GPIO_Init(GPIOC, &GPIO_InitStructure);
00376 
00377   /* Configure SPI3 pins: WS -------------------------------------------*/
00378   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
00379   GPIO_Init(GPIOA, &GPIO_InitStructure);
00380   
00381 #elif defined (USE_STM3210E_EVAL)
00382   
00383   /* Configure SPI3 pins: CK and SD ------------------------------------*/
00384   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_5;
00385   GPIO_Init(GPIOB, &GPIO_InitStructure);
00386 
00387   /* Configure SPI3 pins: WS -------------------------------------------*/
00388   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
00389   GPIO_Init(GPIOA, &GPIO_InitStructure);
00390   
00391 #endif /* USE_STM3210C_EVAL */ 
00392 }
00393 
00394 /**
00395   * @brief  Compares two buffers.
00396   * @param  pBuffer1, pBuffer2: buffers to be compared.
00397   * @param  BufferLength: buffer's length
00398   * @retval PASSED: pBuffer1 identical to pBuffer2
00399   *   FAILED: pBuffer1 differs from pBuffer2
00400   */
00401 TestStatus Buffercmp(uint16_t* pBuffer1, uint16_t* pBuffer2, uint16_t BufferLength)
00402 {
00403   while (BufferLength--)
00404   {
00405     if (*pBuffer1 != *pBuffer2)
00406     {
00407       return FAILED;
00408     }
00409 
00410     pBuffer1++;
00411     pBuffer2++;
00412   }
00413 
00414   return PASSED;
00415 }
00416 
00417 #ifdef  USE_FULL_ASSERT
00418 /**
00419   * @brief  Reports the name of the source file and the source line number
00420   *         where the assert_param error has occurred.
00421   * @param  file: pointer to the source file name
00422   * @param  line: assert_param error line source number
00423   * @retval None
00424   */
00425 void assert_failed(uint8_t* file, uint32_t line)
00426 {
00427   /* User can add his own implementation to report the file name and line number,
00428      ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
00429 
00430   /* Infinite loop */
00431   while (1)
00432   {}
00433 }
00434 #endif
00435 
00436 /**
00437   * @}
00438   */ 
00439 
00440 /**
00441   * @}
00442   */ 
00443 
00444 /******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/
STM32F10x Standard Peripherals Library: Footer

 

 

 

      For complete documentation on STM32(CORTEX M3) 32-bit Microcontrollers platform visit  www.st.com/STM32