STM32F0xx Standard Peripherals Firmware Library
|
STM32F0xx_StdPeriph_Examples/SPI/SPI_TwoBoards/DataExchangeDMA/main.c
Go to the documentation of this file.
00001 /** 00002 ****************************************************************************** 00003 * @file SPI/SPI_TwoBoards/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 SPI_DataExchangeDMA 00036 * @{ 00037 */ 00038 00039 /* Private typedef -----------------------------------------------------------*/ 00040 /* Private define ------------------------------------------------------------*/ 00041 /* Private macro -------------------------------------------------------------*/ 00042 /* Private variables ---------------------------------------------------------*/ 00043 SPI_InitTypeDef SPI_InitStructure; 00044 DMA_InitTypeDef DMA_InitStructure; 00045 TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; 00046 TIM_OCInitTypeDef TIM_OCInitStructure; 00047 uint8_t TxBuffer[] = "SPI DMA Example: Communication between two SPI using DMA"; 00048 uint8_t RxBuffer [RXBUFFERSIZE]; 00049 00050 __IO JOYState_TypeDef PressedButton = JOY_NONE; 00051 __IO uint32_t CommandTransmitted = 0x00; 00052 __IO uint32_t CommandReceived = 0x00; 00053 __IO uint16_t NumberOfByte = 0x00; 00054 __IO uint16_t PrescalerValue = 0; 00055 __IO uint32_t TimeOut = 0x0; 00056 00057 /* Private function prototypes -----------------------------------------------*/ 00058 static void SPI_Config(void); 00059 static void SysTickConfig(void); 00060 static void TimeOut_UserCallback(void); 00061 static TestStatus Buffercmp(uint8_t* pBuffer1, uint8_t* pBuffer2, uint16_t BufferLength, uint8_t DataMask); 00062 #ifdef SPI_MASTER 00063 static void TIM_Config(void); 00064 static JOYState_TypeDef Read_Joystick(void); 00065 static void Fill_Buffer(uint8_t *pBuffer, uint16_t BufferLength); 00066 #endif 00067 00068 /* Private functions ---------------------------------------------------------*/ 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_stm32f0xx.s) before to branch to application main. 00080 To reconfigure the default setting of SystemInit() function, refer to 00081 system_stm32f0xx.c file 00082 */ 00083 00084 /* SPI configuration ------------------------------------------------------*/ 00085 SPI_Config(); 00086 00087 /* SysTick configuration ---------------------------------------------------*/ 00088 SysTickConfig(); 00089 00090 /* Initialize LEDs mounted on STM320518-EVAL board */ 00091 STM_EVAL_LEDInit(LED1); 00092 STM_EVAL_LEDInit(LED2); 00093 STM_EVAL_LEDInit(LED3); 00094 STM_EVAL_LEDInit(LED4); 00095 00096 /* Master board configuration ------------------------------------------------*/ 00097 #ifdef SPI_MASTER 00098 /* Initialize push-buttons mounted on STM320518-EVAL board */ 00099 STM_EVAL_PBInit(BUTTON_RIGHT, BUTTON_MODE_GPIO); 00100 STM_EVAL_PBInit(BUTTON_LEFT, BUTTON_MODE_GPIO); 00101 STM_EVAL_PBInit(BUTTON_UP, BUTTON_MODE_GPIO); 00102 STM_EVAL_PBInit(BUTTON_DOWN, BUTTON_MODE_GPIO); 00103 STM_EVAL_PBInit(BUTTON_SEL, BUTTON_MODE_GPIO); 00104 00105 /* Initializes the SPI communication */ 00106 SPI_InitStructure.SPI_Mode = SPI_Mode_Master; 00107 SPI_Init(SPIx, &SPI_InitStructure); 00108 00109 /* Initialize the FIFO threshold */ 00110 SPI_RxFIFOThresholdConfig(SPIx, SPI_RxFIFOThreshold_QF); 00111 00112 /* TIM configuration ------------------------------------------------------*/ 00113 TIM_Config(); 00114 00115 /* Enable the SPI peripheral */ 00116 SPI_Cmd(SPIx, ENABLE); 00117 00118 /* Enable NSS output for master mode */ 00119 SPI_SSOutputCmd(SPIx, ENABLE); 00120 00121 /* TIM Capture Compare DMA Request enable */ 00122 TIM_DMACmd(TIMx, TIMx_DMA_CHANNEL, ENABLE); 00123 00124 while (1) 00125 { 00126 /* DMA channel Rx of SPI Configuration */ 00127 DMA_InitStructure.DMA_BufferSize = (uint16_t)1; 00128 DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)SPIx_DR_ADDRESS; 00129 DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) &CommandReceived; 00130 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; 00131 DMA_InitStructure.DMA_Priority = DMA_Priority_High; 00132 DMA_Init(SPIx_RX_DMA_CHANNEL, &DMA_InitStructure); 00133 00134 /* DMA TIM trigger channel Configuration */ 00135 DMA_InitStructure.DMA_BufferSize = (uint16_t)1; 00136 DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)SPIx_DR_ADDRESS; 00137 DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) &CommandTransmitted; 00138 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; 00139 DMA_InitStructure.DMA_Priority = DMA_Priority_Low; 00140 DMA_Init(TIMx_CHANNEL_DMA_CHANNEL, &DMA_InitStructure); 00141 00142 /* Enable the SPI Rx DMA request */ 00143 SPI_I2S_DMACmd(SPIx, SPI_I2S_DMAReq_Rx, ENABLE); 00144 00145 CommandTransmitted = 0x00; 00146 CommandReceived = 0x00; 00147 00148 /* Clear the RxBuffer */ 00149 Fill_Buffer(RxBuffer, TXBUFFERSIZE); 00150 00151 PressedButton = Read_Joystick(); 00152 while (PressedButton == JOY_NONE) 00153 { 00154 PressedButton = Read_Joystick(); 00155 } 00156 00157 switch (PressedButton) 00158 { 00159 /* JOY_RIGHT button pressed */ 00160 case JOY_RIGHT: 00161 CommandTransmitted = CMD_RIGHT; 00162 NumberOfByte = CMD_RIGHT_SIZE; 00163 break; 00164 /* JOY_LEFT button pressed */ 00165 case JOY_LEFT: 00166 CommandTransmitted = CMD_LEFT; 00167 NumberOfByte = CMD_LEFT_SIZE; 00168 break; 00169 /* JOY_UP button pressed */ 00170 case JOY_UP: 00171 CommandTransmitted = CMD_UP; 00172 NumberOfByte = CMD_UP_SIZE; 00173 break; 00174 /* JOY_DOWN button pressed */ 00175 case JOY_DOWN: 00176 CommandTransmitted = CMD_DOWN; 00177 NumberOfByte = CMD_DOWN_SIZE; 00178 break; 00179 /* JOY_SEL button pressed */ 00180 case JOY_SEL: 00181 CommandTransmitted = CMD_SEL; 00182 NumberOfByte = CMD_SEL_SIZE; 00183 break; 00184 default: 00185 break; 00186 } 00187 00188 /* Enable the DMA channel */ 00189 DMA_Cmd(SPIx_RX_DMA_CHANNEL, ENABLE); 00190 00191 /* Enable DMA1 TIM Trigger Channel */ 00192 DMA_Cmd(TIMx_CHANNEL_DMA_CHANNEL, ENABLE); 00193 00194 /* TIM enable counter */ 00195 TIM_Cmd(TIMx, ENABLE); 00196 00197 /* Wait the SPI DMA Rx transfer complete or time out*/ 00198 TimeOut = USER_TIMEOUT; 00199 while ((DMA_GetFlagStatus(SPIx_RX_DMA_FLAG_TC) == RESET)&&(TimeOut != 0x00)) 00200 {} 00201 if(TimeOut == 0) 00202 { 00203 TimeOut_UserCallback(); 00204 } 00205 /* The BSY flag can be monitored to ensure that the SPI communication is complete. 00206 This is required to avoid corrupting the last transmission before disabling 00207 the SPI or entering the Stop mode. The software must first wait until TXE=1 00208 and then until BSY=0.*/ 00209 TimeOut = USER_TIMEOUT; 00210 while ((SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_TXE) == RESET)&&(TimeOut != 0x00)) 00211 {} 00212 if(TimeOut == 0) 00213 { 00214 TimeOut_UserCallback(); 00215 } 00216 00217 TimeOut = USER_TIMEOUT; 00218 while ((SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_BSY) == SET)&&(TimeOut != 0x00)) 00219 {} 00220 if(TimeOut == 0) 00221 { 00222 TimeOut_UserCallback(); 00223 } 00224 00225 /* Clear DMA1 global flags*/ 00226 DMA_ClearFlag(TIMx_CHANNEL_DMA_FLAG_GL); 00227 DMA_ClearFlag(SPIx_RX_DMA_FLAG_GL); 00228 00229 /* disable the DMA channels */ 00230 DMA_Cmd(SPIx_RX_DMA_CHANNEL, DISABLE); 00231 DMA_Cmd(TIMx_CHANNEL_DMA_CHANNEL, DISABLE); 00232 00233 /* disable the SPI Rx DMA request */ 00234 SPI_I2S_DMACmd(SPIx, SPI_I2S_DMAReq_Rx, DISABLE); 00235 00236 /* TIM disable counter */ 00237 TIM_Cmd(TIMx, DISABLE); 00238 00239 if (CommandReceived == CMD_ACK) 00240 { 00241 /* DMA channel Rx of SPI Configuration */ 00242 DMA_InitStructure.DMA_BufferSize = (uint16_t)NumberOfByte; 00243 DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)SPIx_DR_ADDRESS; 00244 DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)RxBuffer; 00245 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; 00246 DMA_InitStructure.DMA_Priority = DMA_Priority_High; 00247 DMA_Init(SPIx_RX_DMA_CHANNEL, &DMA_InitStructure); 00248 00249 /* DMA channel Tx of SPI Configuration */ 00250 DMA_InitStructure.DMA_BufferSize = (uint16_t)NumberOfByte; 00251 DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)SPIx_DR_ADDRESS; 00252 DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)TxBuffer; 00253 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; 00254 DMA_InitStructure.DMA_Priority = DMA_Priority_Low; 00255 DMA_Init(TIMx_CHANNEL_DMA_CHANNEL, &DMA_InitStructure); 00256 00257 /* Enable the SPI Rx DMA request */ 00258 SPI_I2S_DMACmd(SPIx, SPI_I2S_DMAReq_Rx, ENABLE); 00259 00260 /* Enable the DMA channel */ 00261 DMA_Cmd(SPIx_RX_DMA_CHANNEL, ENABLE); 00262 00263 /* Enable DMA1 TIM Trigger Channel */ 00264 DMA_Cmd(TIMx_CHANNEL_DMA_CHANNEL, ENABLE); 00265 00266 /* TIM enable counter */ 00267 TIM_Cmd(TIMx, ENABLE); 00268 00269 /* Wait the SPI Rx DMA transfer complete or time out */ 00270 TimeOut = USER_TIMEOUT; 00271 while ((DMA_GetFlagStatus(SPIx_RX_DMA_FLAG_TC) == RESET)&&(TimeOut != 0x00)) 00272 {} 00273 if(TimeOut == 0) 00274 { 00275 TimeOut_UserCallback(); 00276 } 00277 /* The BSY flag can be monitored to ensure that the SPI communication is complete. 00278 This is required to avoid corrupting the last transmission before disabling 00279 the SPI or entering the Stop mode. The software must first wait until TXE=1 00280 and then until BSY=0.*/ 00281 TimeOut = USER_TIMEOUT; 00282 while ((SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_TXE) == RESET)&&(TimeOut != 0x00)) 00283 {} 00284 if(TimeOut == 0) 00285 { 00286 TimeOut_UserCallback(); 00287 } 00288 00289 TimeOut = USER_TIMEOUT; 00290 while ((SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_BSY) == SET)&&(TimeOut != 0x00)) 00291 {} 00292 if(TimeOut == 0) 00293 { 00294 TimeOut_UserCallback(); 00295 } 00296 00297 /* Clear DMA1 global flags */ 00298 DMA_ClearFlag(TIMx_CHANNEL_DMA_FLAG_GL); 00299 DMA_ClearFlag(SPIx_RX_DMA_FLAG_GL); 00300 00301 /* Disable the DMA channels */ 00302 DMA_Cmd(SPIx_RX_DMA_CHANNEL, DISABLE); 00303 DMA_Cmd(TIMx_CHANNEL_DMA_CHANNEL, DISABLE); 00304 00305 /* Disable the SPI Rx and Tx DMA requests */ 00306 SPI_I2S_DMACmd(SPIx, SPI_I2S_DMAReq_Rx, DISABLE); 00307 00308 /* TIM disable counter */ 00309 TIM_Cmd(TIMx, DISABLE); 00310 00311 switch (NumberOfByte) 00312 { 00313 /* CMD_RIGHT command received */ 00314 case CMD_RIGHT_SIZE: 00315 if ((Buffercmp(TxBuffer, RxBuffer, CMD_RIGHT_SIZE, SPI_DATAMASK) != FAILED) && (CommandReceived == CMD_ACK)) 00316 { 00317 /* Turn ON LED2 and LED3 */ 00318 STM_EVAL_LEDOn(LED2); 00319 STM_EVAL_LEDOn(LED3); 00320 /* Turn OFF LED4 */ 00321 STM_EVAL_LEDOff(LED4); 00322 } 00323 break; 00324 /* CMD_LEFT command received */ 00325 case CMD_LEFT_SIZE: 00326 if ((Buffercmp(TxBuffer, RxBuffer, CMD_LEFT_SIZE, SPI_DATAMASK) != FAILED) && (CommandReceived == CMD_ACK)) 00327 { 00328 /* Turn ON LED4 */ 00329 STM_EVAL_LEDOn(LED4); 00330 /* Turn OFF LED2 and LED3 */ 00331 STM_EVAL_LEDOff(LED2); 00332 STM_EVAL_LEDOff(LED3); 00333 } 00334 break; 00335 /* CMD_UP command received */ 00336 case CMD_UP_SIZE: 00337 if ((Buffercmp(TxBuffer, RxBuffer, CMD_UP_SIZE, SPI_DATAMASK) != FAILED) && (CommandReceived == CMD_ACK)) 00338 { 00339 /* Turn ON LED2 */ 00340 STM_EVAL_LEDOn(LED2); 00341 /* Turn OFF LED3 and LED4 */ 00342 STM_EVAL_LEDOff(LED3); 00343 STM_EVAL_LEDOff(LED4); 00344 } 00345 break; 00346 /* CMD_DOWN command received */ 00347 case CMD_DOWN_SIZE: 00348 if ((Buffercmp(TxBuffer, RxBuffer, CMD_DOWN_SIZE, SPI_DATAMASK) != FAILED) && (CommandReceived == CMD_ACK)) 00349 { 00350 /* Turn ON LED3 */ 00351 STM_EVAL_LEDOn(LED3); 00352 /* Turn OFF LED2 and LED4 */ 00353 STM_EVAL_LEDOff(LED2); 00354 STM_EVAL_LEDOff(LED4); 00355 } 00356 break; 00357 /* CMD_SEL command received */ 00358 case CMD_SEL_SIZE: 00359 if ((Buffercmp(TxBuffer, RxBuffer, CMD_SEL_SIZE, SPI_DATAMASK) != FAILED) && (CommandReceived == CMD_ACK)) 00360 { 00361 /* Turn ON LED2, LED3 and LED4 */ 00362 STM_EVAL_LEDOn(LED2); 00363 STM_EVAL_LEDOn(LED3); 00364 STM_EVAL_LEDOn(LED4); 00365 } 00366 break; 00367 default: 00368 break; 00369 } 00370 } 00371 } 00372 #endif /* SPI_MASTER */ 00373 00374 /* Slave board configuration -----------------------------------------------*/ 00375 #ifdef SPI_SLAVE 00376 00377 /* Initializes the SPI communication */ 00378 SPI_I2S_DeInit(SPIx); 00379 SPI_InitStructure.SPI_Mode = SPI_Mode_Slave; 00380 SPI_Init(SPIx, &SPI_InitStructure); 00381 00382 /* Initialize the FIFO threshold */ 00383 SPI_RxFIFOThresholdConfig(SPIx, SPI_RxFIFOThreshold_QF); 00384 00385 CommandTransmitted = CMD_ACK; 00386 00387 /* Infinite Loop */ 00388 while (1) 00389 { 00390 /* DMA channel Rx of SPI Configuration */ 00391 DMA_InitStructure.DMA_BufferSize = 1; 00392 DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)SPIx_DR_ADDRESS; 00393 DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) &CommandReceived; 00394 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; 00395 DMA_InitStructure.DMA_Priority = DMA_Priority_High; 00396 DMA_Init(SPIx_RX_DMA_CHANNEL, &DMA_InitStructure); 00397 00398 /* DMA channel Tx of SPI Configuration */ 00399 DMA_InitStructure.DMA_BufferSize = 1; 00400 DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)SPIx_DR_ADDRESS; 00401 DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) &CommandTransmitted; 00402 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; 00403 DMA_InitStructure.DMA_Priority = DMA_Priority_Low; 00404 DMA_Init(SPIx_TX_DMA_CHANNEL, &DMA_InitStructure); 00405 00406 /* Enable the SPI Rx and Tx DMA requests */ 00407 SPI_I2S_DMACmd(SPIx, SPI_I2S_DMAReq_Rx, ENABLE); 00408 SPI_I2S_DMACmd(SPIx, SPI_I2S_DMAReq_Tx, ENABLE); 00409 00410 /* Enable the SPI peripheral */ 00411 SPI_Cmd(SPIx, ENABLE); 00412 00413 CommandReceived = 0x00; 00414 00415 /* Enable the DMA channels */ 00416 DMA_Cmd(SPIx_RX_DMA_CHANNEL, ENABLE); 00417 DMA_Cmd(SPIx_TX_DMA_CHANNEL, ENABLE); 00418 00419 /* Wait the SPI DMA transfers complete or time out */ 00420 while (DMA_GetFlagStatus(SPIx_RX_DMA_FLAG_TC) == RESET) 00421 {} 00422 00423 TimeOut = USER_TIMEOUT; 00424 while ((DMA_GetFlagStatus(SPIx_TX_DMA_FLAG_TC) == RESET)&&(TimeOut != 0x00)) 00425 {} 00426 if(TimeOut == 0) 00427 { 00428 TimeOut_UserCallback(); 00429 } 00430 00431 /* The BSY flag can be monitored to ensure that the SPI communication is complete. 00432 This is required to avoid corrupting the last transmission before disabling 00433 the SPI or entering the Stop mode. The software must first wait until TXE=1 00434 and then until BSY=0.*/ 00435 TimeOut = USER_TIMEOUT; 00436 while ((SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_TXE) == RESET)&&(TimeOut != 0x00)) 00437 {} 00438 if(TimeOut == 0) 00439 { 00440 TimeOut_UserCallback(); 00441 } 00442 00443 TimeOut = USER_TIMEOUT; 00444 while ((SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_BSY) == SET)&&(TimeOut != 0x00)) 00445 {} 00446 if(TimeOut == 0) 00447 { 00448 TimeOut_UserCallback(); 00449 } 00450 00451 /* Clear DMA1 global flags */ 00452 DMA_ClearFlag(SPIx_TX_DMA_FLAG_GL); 00453 DMA_ClearFlag(SPIx_RX_DMA_FLAG_GL); 00454 00455 /* Disable the DMA channels */ 00456 DMA_Cmd(SPIx_RX_DMA_CHANNEL, DISABLE); 00457 DMA_Cmd(SPIx_TX_DMA_CHANNEL, DISABLE); 00458 00459 /* Disable the SPI peripheral */ 00460 SPI_Cmd(SPIx, DISABLE); 00461 00462 /* Disable the SPI Rx and Tx DMA requests */ 00463 SPI_I2S_DMACmd(SPIx, SPI_I2S_DMAReq_Rx, DISABLE); 00464 SPI_I2S_DMACmd(SPIx, SPI_I2S_DMAReq_Tx, DISABLE); 00465 00466 00467 switch (CommandReceived) 00468 { 00469 /* CMD_RIGHT command received */ 00470 case CMD_RIGHT: 00471 NumberOfByte = CMD_RIGHT_SIZE; 00472 break; 00473 /* CMD_LEFT command received */ 00474 case CMD_LEFT: 00475 NumberOfByte = CMD_LEFT_SIZE; 00476 break; 00477 /* CMD_UP command received */ 00478 case CMD_UP: 00479 NumberOfByte = CMD_UP_SIZE; 00480 break; 00481 /* CMD_DOWN command received */ 00482 case CMD_DOWN: 00483 NumberOfByte = CMD_DOWN_SIZE; 00484 break; 00485 /* CMD_SEL command received */ 00486 case CMD_SEL: 00487 NumberOfByte = CMD_SEL_SIZE; 00488 break; 00489 default: 00490 break; 00491 } 00492 00493 /* DMA channel Rx of SPI Configuration */ 00494 DMA_InitStructure.DMA_BufferSize = NumberOfByte; 00495 DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)SPIx_DR_ADDRESS; 00496 DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)RxBuffer; 00497 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; 00498 DMA_InitStructure.DMA_Priority = DMA_Priority_High; 00499 DMA_Init(SPIx_RX_DMA_CHANNEL, &DMA_InitStructure); 00500 00501 /* DMA channel Tx of SPI Configuration */ 00502 DMA_InitStructure.DMA_BufferSize = NumberOfByte; 00503 DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)SPIx_DR_ADDRESS; 00504 DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)TxBuffer; 00505 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; 00506 DMA_InitStructure.DMA_Priority = DMA_Priority_Low; 00507 DMA_Init(SPIx_TX_DMA_CHANNEL, &DMA_InitStructure); 00508 00509 /* Enable the SPI Rx and Tx DMA requests */ 00510 SPI_I2S_DMACmd(SPIx, SPI_I2S_DMAReq_Rx, ENABLE); 00511 SPI_I2S_DMACmd(SPIx, SPI_I2S_DMAReq_Tx, ENABLE); 00512 00513 /* Enable the SPI peripheral */ 00514 SPI_Cmd(SPIx, ENABLE); 00515 00516 /* Enable the DMA channels */ 00517 DMA_Cmd(SPIx_RX_DMA_CHANNEL, ENABLE); 00518 DMA_Cmd(SPIx_TX_DMA_CHANNEL, ENABLE); 00519 00520 /* Wait the SPI DMA transfers complete or time out */ 00521 while (DMA_GetFlagStatus(SPIx_RX_DMA_FLAG_TC) == RESET) 00522 {} 00523 00524 TimeOut = USER_TIMEOUT; 00525 while ((DMA_GetFlagStatus(SPIx_TX_DMA_FLAG_TC) == RESET)&&(TimeOut != 0x00)) 00526 {} 00527 if(TimeOut == 0) 00528 { 00529 TimeOut_UserCallback(); 00530 } 00531 00532 /* The BSY flag can be monitored to ensure that the SPI communication is complete. 00533 This is required to avoid corrupting the last transmission before disabling 00534 the SPI or entering the Stop mode. The software must first wait until TXE=1 00535 and then until BSY=0.*/ 00536 TimeOut = USER_TIMEOUT; 00537 while ((SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_TXE) == RESET)&&(TimeOut != 0x00)) 00538 {} 00539 if(TimeOut == 0) 00540 { 00541 TimeOut_UserCallback(); 00542 } 00543 00544 TimeOut = USER_TIMEOUT; 00545 while ((SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_BSY) == SET)&&(TimeOut != 0x00)) 00546 {} 00547 if(TimeOut == 0) 00548 { 00549 TimeOut_UserCallback(); 00550 } 00551 00552 switch (NumberOfByte) 00553 { 00554 /* CMD_RIGHT command received */ 00555 case CMD_RIGHT_SIZE: 00556 if (Buffercmp(TxBuffer, RxBuffer, CMD_RIGHT_SIZE, SPI_DATAMASK) != FAILED) 00557 { 00558 /* Turn ON LED2 and LED3 */ 00559 STM_EVAL_LEDOn(LED2); 00560 STM_EVAL_LEDOn(LED3); 00561 /* Turn OFF LED4 */ 00562 STM_EVAL_LEDOff(LED4); 00563 } 00564 break; 00565 /* CMD_LEFT command received */ 00566 case CMD_LEFT_SIZE: 00567 if (Buffercmp(TxBuffer, RxBuffer, CMD_LEFT_SIZE, SPI_DATAMASK) != FAILED) 00568 { 00569 /* Turn ON LED4 */ 00570 STM_EVAL_LEDOn(LED4); 00571 /* Turn OFF LED2 and LED3 */ 00572 STM_EVAL_LEDOff(LED2); 00573 STM_EVAL_LEDOff(LED3); 00574 } 00575 break; 00576 /* CMD_UP command received */ 00577 case CMD_UP_SIZE: 00578 if (Buffercmp(TxBuffer, RxBuffer, CMD_UP_SIZE, SPI_DATAMASK) != FAILED) 00579 { 00580 /* Turn ON LED2 */ 00581 STM_EVAL_LEDOn(LED2); 00582 /* Turn OFF LED3 and LED4 */ 00583 STM_EVAL_LEDOff(LED3); 00584 STM_EVAL_LEDOff(LED4); 00585 } 00586 break; 00587 /* CMD_DOWN command received */ 00588 case CMD_DOWN_SIZE: 00589 if (Buffercmp(TxBuffer, RxBuffer, CMD_DOWN_SIZE, SPI_DATAMASK) != FAILED) 00590 { 00591 /* Turn ON LED3 */ 00592 STM_EVAL_LEDOn(LED3); 00593 /* Turn OFF LED2 and LED4 */ 00594 STM_EVAL_LEDOff(LED2); 00595 STM_EVAL_LEDOff(LED4); 00596 } 00597 break; 00598 /* CMD_SEL command received */ 00599 case CMD_SEL_SIZE: 00600 if (Buffercmp(TxBuffer, RxBuffer, CMD_SEL_SIZE, SPI_DATAMASK) != FAILED) 00601 { 00602 /* Turn ON LED2, LED3 and LED4 */ 00603 STM_EVAL_LEDOn(LED2); 00604 STM_EVAL_LEDOn(LED3); 00605 STM_EVAL_LEDOn(LED4); 00606 } 00607 break; 00608 default: 00609 break; 00610 } 00611 00612 /* Clear DMA1 global flags */ 00613 DMA_ClearFlag(SPIx_TX_DMA_FLAG_GL); 00614 DMA_ClearFlag(SPIx_RX_DMA_FLAG_GL); 00615 00616 /* Disable the DMA channels */ 00617 DMA_Cmd(SPIx_RX_DMA_CHANNEL, DISABLE); 00618 DMA_Cmd(SPIx_TX_DMA_CHANNEL, DISABLE); 00619 00620 /* Disable the SPI peripheral */ 00621 SPI_Cmd(SPIx, DISABLE); 00622 00623 /* Disable the SPI Rx and Tx DMA requests */ 00624 SPI_I2S_DMACmd(SPIx, SPI_I2S_DMAReq_Rx, DISABLE); 00625 SPI_I2S_DMACmd(SPIx, SPI_I2S_DMAReq_Tx, DISABLE); 00626 } 00627 #endif /* SPI_SLAVE */ 00628 } 00629 00630 /** 00631 * @brief Configures the SPI Peripheral. 00632 * @param None 00633 * @retval None 00634 */ 00635 static void SPI_Config(void) 00636 { 00637 GPIO_InitTypeDef GPIO_InitStructure; 00638 00639 /* Enable the SPI peripheral */ 00640 RCC_APB2PeriphClockCmd(SPIx_CLK, ENABLE); 00641 00642 /* Enable the DMA peripheral */ 00643 RCC_AHBPeriphClockCmd(DMAx_CLK, ENABLE); 00644 00645 /* Enable the TIM peripheral */ 00646 RCC_APB1PeriphClockCmd(TIMx_CLK, ENABLE); 00647 00648 /* Enable SCK, MOSI, MISO and NSS GPIO clocks */ 00649 RCC_AHBPeriphClockCmd(SPIx_SCK_GPIO_CLK | SPIx_MISO_GPIO_CLK | SPIx_MOSI_GPIO_CLK | 00650 SPIx_NSS_GPIO_CLK , ENABLE); 00651 00652 /* Enable TIM DMA trigger clock */ 00653 RCC_AHBPeriphClockCmd(TIMx_TRIGGER_GPIO_CLK, ENABLE); 00654 00655 /* SPI pin mappings */ 00656 GPIO_PinAFConfig(SPIx_SCK_GPIO_PORT, SPIx_SCK_SOURCE, SPIx_SCK_AF); 00657 GPIO_PinAFConfig(SPIx_MOSI_GPIO_PORT, SPIx_MOSI_SOURCE, SPIx_MOSI_AF); 00658 GPIO_PinAFConfig(SPIx_MISO_GPIO_PORT, SPIx_MISO_SOURCE, SPIx_MISO_AF); 00659 GPIO_PinAFConfig(SPIx_NSS_GPIO_PORT, SPIx_NSS_SOURCE, SPIx_NSS_AF); 00660 00661 /* TIM capture compare pin mapping */ 00662 GPIO_PinAFConfig(TIMx_TRIGGER_GPIO_PORT, TIMx_TRIGGER_SOURCE, TIMx_TRIGGER_AF); 00663 00664 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; 00665 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; 00666 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; 00667 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Level_3; 00668 00669 /* SPI SCK pin configuration */ 00670 GPIO_InitStructure.GPIO_Pin = SPIx_SCK_PIN; 00671 GPIO_Init(SPIx_SCK_GPIO_PORT, &GPIO_InitStructure); 00672 00673 /* SPI MOSI pin configuration */ 00674 GPIO_InitStructure.GPIO_Pin = SPIx_MOSI_PIN; 00675 GPIO_Init(SPIx_MOSI_GPIO_PORT, &GPIO_InitStructure); 00676 00677 /* SPI MISO pin configuration */ 00678 GPIO_InitStructure.GPIO_Pin = SPIx_MISO_PIN; 00679 GPIO_Init(SPIx_MISO_GPIO_PORT, &GPIO_InitStructure); 00680 00681 /* SPI NSS pin configuration */ 00682 GPIO_InitStructure.GPIO_Pin = SPIx_NSS_PIN; 00683 GPIO_Init(SPIx_NSS_GPIO_PORT, &GPIO_InitStructure); 00684 00685 /* Configure the TIM channelx capture compare as DMA Trigger */ 00686 GPIO_InitStructure.GPIO_Pin = TIMx_TRIGGER_PIN; 00687 GPIO_Init(TIMx_TRIGGER_GPIO_PORT, &GPIO_InitStructure); 00688 00689 /* SPI configuration -------------------------------------------------------*/ 00690 SPI_I2S_DeInit(SPIx); 00691 SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; 00692 SPI_InitStructure.SPI_DataSize = SPI_DATASIZE; 00693 SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; 00694 SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; 00695 SPI_InitStructure.SPI_NSS = SPI_NSS_Hard; 00696 SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4; 00697 SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; 00698 SPI_InitStructure.SPI_CRCPolynomial = 7; 00699 00700 /* DMA Configuration -------------------------------------------------------*/ 00701 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; 00702 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; 00703 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; 00704 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; 00705 DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; 00706 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; 00707 } 00708 00709 /** 00710 * @brief Basic management of the timeout situation. 00711 * @param None. 00712 * @retval None. 00713 */ 00714 static void TimeOut_UserCallback(void) 00715 { 00716 /* User can add his own implementation to manage TimeOut Communication failure */ 00717 /* Block communication and all processes */ 00718 while (1) 00719 { 00720 } 00721 } 00722 00723 /** 00724 * @brief Configure a SysTick Base time to 10 ms. 00725 * @param None 00726 * @retval None 00727 */ 00728 static void SysTickConfig(void) 00729 { 00730 /* Setup SysTick Timer for 10ms interrupts */ 00731 if (SysTick_Config(SystemCoreClock / 100)) 00732 { 00733 /* Capture error */ 00734 while (1); 00735 } 00736 00737 /* Configure the SysTick handler priority */ 00738 NVIC_SetPriority(SysTick_IRQn, 0x0); 00739 } 00740 00741 /** 00742 * @brief Compares two buffers. 00743 * @param pBuffer1, pBuffer2: buffers to be compared. 00744 * @param BufferLength: buffer's length 00745 * @retval PASSED: pBuffer1 identical to pBuffer2 00746 * FAILED: pBuffer1 differs from pBuffer2 00747 */ 00748 static TestStatus Buffercmp(uint8_t* pBuffer1, uint8_t* pBuffer2, uint16_t BufferLength, uint8_t DataMask) 00749 { 00750 while (BufferLength--) 00751 { 00752 if (((*pBuffer1) & DataMask) != *pBuffer2) 00753 { 00754 return FAILED; 00755 } 00756 pBuffer1++; 00757 pBuffer2++; 00758 } 00759 00760 return PASSED; 00761 } 00762 00763 #ifdef SPI_MASTER 00764 /** 00765 * @brief Configures the TIM Peripheral. 00766 * @param None 00767 * @retval None 00768 */ 00769 static void TIM_Config(void) 00770 { 00771 /* --------------------------------------------------------------------------- 00772 TIM2 Configuration: generate 1 PWM signals with 50% duty cycle. 00773 The TIM2CLK frequency is set to SystemCoreClock (Hz), to get TIM2 counter 00774 clock at 32 MHz the Prescaler is computed as following: 00775 - Prescaler = (TIM2CLK / TIM2 counter clock) - 1 00776 SystemCoreClock is set to 48 MHz for Ultra Low Power Medium-density devices. 00777 00778 The TIM2 is running at 4 KHz: TIM2 Frequency = TIM2 counter clock/(TIM2_ARR + 1) 00779 = 48 MHz / (TIM2_ARR +1) = 4 KHz 00780 ==> TIM2_ARR + 1 = 12000 00781 TIM2 Channel2 duty cycle = (TIM2_CCR4/ TIM2_ARR)* 100 = 50% 00782 ==> TIM2_CCR4 = TIM2_ARR/2 = 6000 00783 ----------------------------------------------------------------------------*/ 00784 /* Compute the prescaler value */ 00785 PrescalerValue = (uint16_t) (SystemCoreClock / 48000000) - 1; 00786 00787 /* Time base configuration */ 00788 TIM_TimeBaseStructure.TIM_Period = TIM_ARR; 00789 TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue; 00790 TIM_TimeBaseStructure.TIM_ClockDivision = 0; 00791 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; 00792 00793 TIM_TimeBaseInit(TIMx, &TIM_TimeBaseStructure); 00794 00795 /* TIM PWM1 Mode configuration: Channel */ 00796 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; 00797 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; 00798 TIM_OCInitStructure.TIM_Pulse = TIM_CCR; 00799 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; 00800 00801 TIMx_CHANNEL_INIT(TIMx, &TIM_OCInitStructure); 00802 } 00803 /** 00804 * @brief Reads key from evaluationboard. 00805 * @param None 00806 * @retval Return JOY_RIGHT, JOY_LEFT, JOY_SEL, JOY_UP, JOY_DOWN or JOY_NONE 00807 */ 00808 static JOYState_TypeDef Read_Joystick(void) 00809 { 00810 /* "JOY_RIGHT" key is pressed */ 00811 if (STM_EVAL_PBGetState(BUTTON_RIGHT)) 00812 { 00813 while (STM_EVAL_PBGetState(BUTTON_RIGHT) == RESET) 00814 {} 00815 return JOY_RIGHT; 00816 } 00817 /* "JOY_LEFT" key is pressed */ 00818 if (STM_EVAL_PBGetState(BUTTON_LEFT)) 00819 { 00820 while (STM_EVAL_PBGetState(BUTTON_LEFT) == RESET) 00821 {} 00822 return JOY_LEFT; 00823 } 00824 /* "JOY_UP" key is pressed */ 00825 if (STM_EVAL_PBGetState(BUTTON_UP)) 00826 { 00827 while (STM_EVAL_PBGetState(BUTTON_UP) == RESET) 00828 {} 00829 return JOY_UP; 00830 } 00831 /* "JOY_DOWN" key is pressed */ 00832 if (STM_EVAL_PBGetState(BUTTON_DOWN)) 00833 { 00834 while (STM_EVAL_PBGetState(BUTTON_DOWN) == RESET) 00835 {} 00836 return JOY_DOWN; 00837 } 00838 /* "JOY_SEL" key is pressed */ 00839 if (STM_EVAL_PBGetState(BUTTON_SEL)) 00840 { 00841 while (STM_EVAL_PBGetState(BUTTON_SEL) == RESET) 00842 {} 00843 return JOY_SEL; 00844 } 00845 /* No key is pressed */ 00846 else 00847 { 00848 return JOY_NONE; 00849 } 00850 } 00851 00852 /** 00853 * @brief Fills buffer. 00854 * @param pBuffer: pointer on the Buffer to fill 00855 * @param BufferLength: size of the buffer to fill 00856 * @retval None 00857 */ 00858 static void Fill_Buffer(uint8_t *pBuffer, uint16_t BufferLength) 00859 { 00860 uint16_t index = 0; 00861 00862 /* Put in global buffer same values */ 00863 for (index = 0; index < BufferLength; index++ ) 00864 { 00865 pBuffer[index] = 0x00; 00866 } 00867 } 00868 #endif 00869 00870 #ifdef USE_FULL_ASSERT 00871 00872 /** 00873 * @brief Reports the name of the source file and the source line number 00874 * where the assert_param error has occurred. 00875 * @param file: pointer to the source file name 00876 * @param line: assert_param error line source number 00877 * @retval None 00878 */ 00879 void assert_failed(uint8_t* file, uint32_t line) 00880 { 00881 /* User can add his own implementation to report the file name and line number, 00882 ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ 00883 00884 /* Infinite loop */ 00885 while (1) 00886 { 00887 } 00888 } 00889 #endif 00890 00891 /** 00892 * @} 00893 */ 00894 00895 /** 00896 * @} 00897 */ 00898 00899 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/