STM32F0xx Standard Peripherals Firmware Library
|
STM32F0xx_StdPeriph_Examples/I2S/I2S_DataExchangeDMA/main.c
Go to the documentation of this file.
00001 /** 00002 ****************************************************************************** 00003 * @file I2S/I2S_DataExchangeDMA/main.c 00004 * @author MCD Application Team 00005 * @version V1.4.0 00006 * @date 24-July-2014 00007 * @brief Main program body 00008 ****************************************************************************** 00009 * @attention 00010 * 00011 * <h2><center>© COPYRIGHT 2014 STMicroelectronics</center></h2> 00012 * 00013 * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); 00014 * You may not use this file except in compliance with the License. 00015 * You may obtain a copy of the License at: 00016 * 00017 * http://www.st.com/software_license_agreement_liberty_v2 00018 * 00019 * Unless required by applicable law or agreed to in writing, software 00020 * distributed under the License is distributed on an "AS IS" BASIS, 00021 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00022 * See the License for the specific language governing permissions and 00023 * limitations under the License. 00024 * 00025 ****************************************************************************** 00026 */ 00027 00028 /* Includes ------------------------------------------------------------------*/ 00029 #include "main.h" 00030 00031 /** @addtogroup STM32F0xx_StdPeriph_Examples 00032 * @{ 00033 */ 00034 00035 /** @addtogroup I2S_DataExchangeDMA 00036 * @{ 00037 */ 00038 00039 /* Private typedef -----------------------------------------------------------*/ 00040 typedef enum {FAILED = 0, PASSED = !FAILED} TestStatus; 00041 /* Private define ------------------------------------------------------------*/ 00042 /* DR adresses */ 00043 #define SPI1_DR_Address 0x4001300C 00044 /* Private macro -------------------------------------------------------------*/ 00045 /* Private variables ---------------------------------------------------------*/ 00046 const uint16_t I2S_Buffer_Tx[32] = {0x0102, 0x0304, 0x0506, 0x0708, 0x090A, 0x0B0C, 00047 0x0D0E, 0x0F10, 0x1112, 0x1314, 0x1516, 0x1718, 00048 0x191A, 0x1B1C, 0x1D1E, 0x1F20, 0x2122, 0x2324, 00049 0x2526, 0x2728, 0x292A, 0x2B2C, 0x2D2E, 0x2F30, 00050 0x3132, 0x3334, 0x3536, 0x3738, 0x393A, 0x3B3C, 00051 0x3D3E, 0x3F40}; 00052 uint16_t I2S_Buffer_Rx[32]={0}; 00053 TestStatus TransferStatus = FAILED; 00054 __IO uint32_t TxStatus= 0, RxStatus=0; 00055 00056 /* Private function prototypes -----------------------------------------------*/ 00057 #if defined (I2S_SLAVE_RECEIVER) 00058 static TestStatus Buffercmp(uint16_t* pBuffer1, uint16_t* pBuffer2, uint16_t BufferLength); 00059 #endif 00060 static void I2S_Config(void); 00061 /* Private functions ---------------------------------------------------------*/ 00062 00063 /** 00064 * @brief Main program. 00065 * @param None 00066 * @retval None 00067 */ 00068 int main(void) 00069 { 00070 /*!< At this stage the microcontroller clock setting is already configured, 00071 this is done through SystemInit() function which is called from startup 00072 file (startup_stm32f0xx.s) before to branch to application main. 00073 To reconfigure the default setting of SystemInit() function, refer to 00074 system_stm32f0xx.c file 00075 */ 00076 00077 /* I2S peripheral Configuration */ 00078 I2S_Config(); 00079 00080 /* Initialize the LEDs */ 00081 STM_EVAL_LEDInit(LED3); 00082 STM_EVAL_LEDInit(LED1); 00083 00084 #if defined (I2S_MASTER_TRANSMITTER) 00085 00086 /* Enable the Tamper button */ 00087 STM_EVAL_PBInit(BUTTON_TAMPER, BUTTON_MODE_GPIO); 00088 00089 while (STM_EVAL_PBGetState(BUTTON_TAMPER) != RESET) 00090 {} 00091 00092 /* Enable the DMA1_Channel3 transfer complete */ 00093 DMA_ITConfig(DMA1_Channel3, DMA_IT_TC, ENABLE); 00094 00095 /* Enable the DMA channel Tx */ 00096 DMA_Cmd(DMA1_Channel3, ENABLE); 00097 00098 /* Enable the I2S TX DMA request */ 00099 SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Tx, ENABLE); 00100 00101 /* Enable the SPI1 Master peripheral */ 00102 I2S_Cmd(SPI1, ENABLE); 00103 00104 /* Wait for successful ransfer complete*/ 00105 while(TxStatus == 0); 00106 00107 /* Disable the DMA1_Channel3 transfer complete interrupt */ 00108 DMA_ITConfig(DMA1_Channel3, DMA_IT_TC, DISABLE); 00109 00110 while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) == SET); 00111 00112 /* Disable the SPI1 Master peripheral */ 00113 I2S_Cmd(SPI1, DISABLE); 00114 00115 /* Disable DMA Channel 3*/ 00116 DMA_Cmd(DMA1_Channel3, DISABLE); 00117 00118 /* disables the SPI1/I2S1 DMA interface */ 00119 SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Tx,DISABLE); 00120 #elif defined (I2S_SLAVE_RECEIVER) 00121 00122 /* Wait for received data: Transfer complete */ 00123 while(RxStatus == 0); 00124 00125 while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) == SET); 00126 00127 /* Disable the SPI1 Slave peripheral */ 00128 I2S_Cmd(SPI1, DISABLE); 00129 00130 /* Disable the DMA1_Channel2 transfer complete */ 00131 DMA_ITConfig(DMA1_Channel2, DMA_IT_TC, DISABLE); 00132 00133 /* Enable DMA channel 2 Rx */ 00134 DMA_Cmd(DMA1_Channel2, DISABLE); 00135 00136 /* Enable the I2S1 RX DMA request */ 00137 SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Rx, DISABLE); 00138 00139 /* Check if the data transmitted from Master Board and received by 00140 Slave Board are the same */ 00141 TransferStatus = Buffercmp(I2S_Buffer_Rx, (uint16_t*)I2S_Buffer_Tx, 32); 00142 00143 if (TransferStatus == PASSED) /* successful transfer */ 00144 { 00145 /* Green Led On */ 00146 STM_EVAL_LEDOn(LED1); 00147 STM_EVAL_LEDOff(LED3); 00148 } 00149 else /* unsuccessful transfer */ 00150 { 00151 /* Red Led On */ 00152 STM_EVAL_LEDOn(LED3); 00153 STM_EVAL_LEDOff(LED1); 00154 } 00155 #endif 00156 /* Infinite loop */ 00157 while (1) 00158 {} 00159 00160 } 00161 00162 /** 00163 * @brief Configures I2S peripheral. 00164 * @param None 00165 * @retval None 00166 */ 00167 static void I2S_Config(void) 00168 { 00169 NVIC_InitTypeDef NVIC_InitStructure; 00170 I2S_InitTypeDef I2S_InitStructure; 00171 GPIO_InitTypeDef GPIO_InitStructure; 00172 DMA_InitTypeDef DMA_InitStructure; 00173 00174 /* Enable SPI1 APB clocks */ 00175 RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); 00176 00177 /* Enable GPIOA clocks */ 00178 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA|RCC_AHBPeriph_GPIOB, ENABLE); 00179 00180 /* Enable the DMA1 AHB clocks */ 00181 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); 00182 00183 /* I2S1 Pins configuration */ 00184 #ifdef USE_STM320518_EVAL 00185 /* Configure pins as AF */ 00186 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15 ; 00187 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; 00188 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 00189 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; 00190 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; 00191 GPIO_Init(GPIOA, &GPIO_InitStructure); 00192 00193 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 |GPIO_Pin_5; 00194 GPIO_Init(GPIOB, &GPIO_InitStructure); 00195 00196 /* Connect pin to Periph */ 00197 GPIO_PinAFConfig(GPIOA, GPIO_PinSource15, GPIO_AF_0); 00198 GPIO_PinAFConfig(GPIOB, GPIO_PinSource3, GPIO_AF_0); 00199 GPIO_PinAFConfig(GPIOB, GPIO_PinSource5, GPIO_AF_0); 00200 #else 00201 /* I2S1 Pins configuration */ 00202 /* Configure pins as AF */ 00203 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_7 ; 00204 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; 00205 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 00206 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; 00207 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; 00208 GPIO_Init(GPIOA, &GPIO_InitStructure); 00209 00210 /* Connect pin to Periph */ 00211 GPIO_PinAFConfig(GPIOA, GPIO_PinSource4, GPIO_AF_0); 00212 GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_0); 00213 GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_0); 00214 #endif /* USE_STM320518_EVAL */ 00215 00216 /* I2S peripheral configuration */ 00217 I2S_InitStructure.I2S_Standard = I2S_Standard_Phillips; 00218 I2S_InitStructure.I2S_DataFormat = I2S_DataFormat_16bextended; 00219 I2S_InitStructure.I2S_MCLKOutput = I2S_MCLKOutput_Disable; 00220 I2S_InitStructure.I2S_AudioFreq = I2S_AudioFreq_48k; 00221 I2S_InitStructure.I2S_CPOL = I2S_CPOL_Low; 00222 00223 /* Common DMA configuration */ 00224 DMA_InitStructure.DMA_BufferSize = 32; 00225 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; 00226 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; 00227 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; 00228 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; 00229 DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; 00230 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; 00231 00232 #if defined (I2S_MASTER_TRANSMITTER) 00233 /* I2S Master Transmitter configuration */ 00234 I2S_InitStructure.I2S_Mode = I2S_Mode_MasterTx; 00235 I2S_Init(SPI1, &I2S_InitStructure); 00236 /* DMA1 channel 5 (SPI1_Tx) configuration */ 00237 DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)SPI1_DR_Address; 00238 DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)I2S_Buffer_Tx; 00239 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; 00240 DMA_InitStructure.DMA_Priority = DMA_Priority_Low; 00241 DMA_Init(DMA1_Channel3, &DMA_InitStructure); 00242 00243 #elif defined (I2S_SLAVE_RECEIVER) 00244 /* I2S Slave Receiver configuration */ 00245 I2S_InitStructure.I2S_Mode = I2S_Mode_SlaveRx; 00246 I2S_Init(SPI1, &I2S_InitStructure); 00247 /* DMA1 channel 2 (SPI1_Rx) Configuration */ 00248 DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)SPI1_DR_Address; 00249 DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)I2S_Buffer_Rx; 00250 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; 00251 DMA_InitStructure.DMA_Priority = DMA_Priority_High; 00252 DMA_Init(DMA1_Channel2, &DMA_InitStructure); 00253 00254 DMA_ITConfig(DMA1_Channel2, DMA_IT_TC, ENABLE); 00255 /* Enable the DMA channels */ 00256 DMA_Cmd(DMA1_Channel2, ENABLE); 00257 /* Enable the I2S1 RX DMA request */ 00258 SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Rx, ENABLE); 00259 00260 /* Enable the SPI1 Master peripheral */ 00261 I2S_Cmd(SPI1, ENABLE); 00262 00263 #endif 00264 /* SPI1 IRQ Channel configuration */ 00265 NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel2_3_IRQn; 00266 NVIC_InitStructure.NVIC_IRQChannelPriority = 0; 00267 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 00268 NVIC_Init(&NVIC_InitStructure); 00269 00270 } 00271 00272 #if defined (I2S_SLAVE_RECEIVER) 00273 /** 00274 * @brief Compares two buffers. 00275 * @param pBuffer1, pBuffer2: buffers to be compared. 00276 * @param BufferLength: buffer's length 00277 * @retval PASSED: pBuffer1 identical to pBuffer2 00278 * FAILED: pBuffer1 differs from pBuffer2 00279 */ 00280 static TestStatus Buffercmp(uint16_t* pBuffer1, uint16_t* pBuffer2, uint16_t BufferLength) 00281 { 00282 while (BufferLength--) 00283 { 00284 if (*pBuffer1 != *pBuffer2) 00285 { 00286 return FAILED; 00287 } 00288 00289 pBuffer1++; 00290 pBuffer2++; 00291 } 00292 00293 return PASSED; 00294 } 00295 #endif 00296 00297 #ifdef USE_FULL_ASSERT 00298 00299 /** 00300 * @brief Reports the name of the source file and the source line number 00301 * where the assert_param error has occurred. 00302 * @param file: pointer to the source file name 00303 * @param line: assert_param error line source number 00304 * @retval None 00305 */ 00306 void assert_failed(uint8_t* file, uint32_t line) 00307 { 00308 /* User can add his own implementation to report the file name and line number, 00309 ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ 00310 00311 /* Infinite loop */ 00312 while (1) 00313 { 00314 } 00315 } 00316 #endif 00317 00318 /** 00319 * @} 00320 */ 00321 00322 /** 00323 * @} 00324 */ 00325 00326 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/