STM32F0xx Standard Peripherals Firmware Library
|
STM32F0xx_StdPeriph_Examples/CAN/CAN_LoopBack/main.c
Go to the documentation of this file.
00001 /** 00002 ****************************************************************************** 00003 * @file CAN/CAN_LoopBack/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 CAN_LoopBack 00036 * @{ 00037 */ 00038 00039 /* Private define ------------------------------------------------------------*/ 00040 /* Private typedef -----------------------------------------------------------*/ 00041 typedef enum {FAILED = 0, PASSED = !FAILED} TestStatus; 00042 00043 /* Private macro -------------------------------------------------------------*/ 00044 /* Private variables ---------------------------------------------------------*/ 00045 __IO uint32_t ret = 0; /* for return of the interrupt handling */ 00046 __IO TestStatus TestRx; 00047 00048 /* Private function prototypes -----------------------------------------------*/ 00049 static void NVIC_Config(void); 00050 TestStatus CAN_Polling(void); 00051 TestStatus CAN_Interrupt(void); 00052 00053 /* Private functions ---------------------------------------------------------*/ 00054 00055 /** 00056 * @brief Main program. 00057 * @param None 00058 * @retval None 00059 */ 00060 int main(void) 00061 { 00062 /*!< At this stage the microcontroller clock setting is already configured, 00063 this is done through SystemInit() function which is called from startup 00064 file (startup_stm32f0xx.s) before to branch to application main. 00065 To reconfigure the default setting of SystemInit() function, refer to 00066 system_stm32f0xx.c file 00067 */ 00068 00069 /* CAN Periph clock enable */ 00070 RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN, ENABLE); 00071 00072 00073 /* NVIC Configuration */ 00074 NVIC_Config(); 00075 00076 /* Configures LED 1..4 */ 00077 STM_EVAL_LEDInit(LED1); 00078 STM_EVAL_LEDInit(LED2); 00079 STM_EVAL_LEDInit(LED3); 00080 STM_EVAL_LEDInit(LED4); 00081 00082 /* CAN transmit at 125Kb/s and receive by polling in loopback mode */ 00083 TestRx = CAN_Polling(); 00084 00085 if (TestRx != FAILED) 00086 { /* OK */ 00087 00088 /* Turn on LED1 */ 00089 STM_EVAL_LEDOn(LED1); 00090 } 00091 else 00092 { /* KO */ 00093 00094 /* Turn on LED3 */ 00095 STM_EVAL_LEDOn(LED3); 00096 } 00097 00098 /* CAN transmit at 500Kb/s and receive by interrupt in loopback mode */ 00099 TestRx = CAN_Interrupt(); 00100 00101 if (TestRx != FAILED) 00102 { /* OK */ 00103 00104 /* Turn on LED4 */ 00105 STM_EVAL_LEDOn(LED4); 00106 } 00107 else 00108 { /* KO */ 00109 00110 /* Turn on LED2 */ 00111 STM_EVAL_LEDOn(LED2); 00112 } 00113 00114 /* Infinite loop */ 00115 while (1) 00116 { 00117 } 00118 } 00119 00120 /** 00121 * @brief Configures the CAN, transmit and receive by polling 00122 * @param None 00123 * @retval PASSED if the reception is well done, FAILED in other case 00124 */ 00125 TestStatus CAN_Polling(void) 00126 { 00127 CAN_InitTypeDef CAN_InitStructure; 00128 CAN_FilterInitTypeDef CAN_FilterInitStructure; 00129 CanTxMsg TxMessage; 00130 CanRxMsg RxMessage; 00131 uint32_t i = 0; 00132 uint8_t TransmitMailbox = 0; 00133 00134 /* CAN register init */ 00135 CAN_DeInit(CAN); 00136 00137 CAN_StructInit(&CAN_InitStructure); 00138 00139 /* CAN cell init */ 00140 CAN_InitStructure.CAN_TTCM = DISABLE; 00141 CAN_InitStructure.CAN_ABOM = DISABLE; 00142 CAN_InitStructure.CAN_AWUM = DISABLE; 00143 CAN_InitStructure.CAN_NART = DISABLE; 00144 CAN_InitStructure.CAN_RFLM = DISABLE; 00145 CAN_InitStructure.CAN_TXFP = DISABLE; 00146 CAN_InitStructure.CAN_Mode = CAN_Mode_LoopBack; 00147 CAN_InitStructure.CAN_SJW = CAN_SJW_1tq; 00148 00149 /* CAN Baudrate = 125kbps (CAN clocked at 36 MHz) */ 00150 CAN_InitStructure.CAN_BS1 = CAN_BS1_9tq; 00151 CAN_InitStructure.CAN_BS2 = CAN_BS2_8tq; 00152 CAN_InitStructure.CAN_Prescaler = 16; 00153 CAN_Init(CAN, &CAN_InitStructure); 00154 00155 /* CAN filter init */ 00156 CAN_FilterInitStructure.CAN_FilterNumber = 0; 00157 CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask; 00158 CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit; 00159 CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000; 00160 CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000; 00161 CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000; 00162 CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000; 00163 CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0; 00164 00165 CAN_FilterInitStructure.CAN_FilterActivation = ENABLE; 00166 CAN_FilterInit(&CAN_FilterInitStructure); 00167 00168 /* transmit */ 00169 TxMessage.StdId = 0x11; 00170 TxMessage.RTR = CAN_RTR_DATA; 00171 TxMessage.IDE = CAN_ID_STD; 00172 TxMessage.DLC = 2; 00173 TxMessage.Data[0] = 0xCA; 00174 TxMessage.Data[1] = 0xFE; 00175 00176 TransmitMailbox = CAN_Transmit(CAN, &TxMessage); 00177 i = 0; 00178 while((CAN_TransmitStatus(CAN, TransmitMailbox) != CANTXOK) && (i != 0xFFFF)) 00179 { 00180 i++; 00181 } 00182 00183 i = 0; 00184 while((CAN_MessagePending(CAN, CAN_FIFO0) < 1) && (i != 0xFFFF)) 00185 { 00186 i++; 00187 } 00188 00189 /* receive */ 00190 RxMessage.StdId = 0x00; 00191 RxMessage.IDE = CAN_ID_STD; 00192 RxMessage.DLC = 0; 00193 RxMessage.Data[0] = 0x00; 00194 RxMessage.Data[1] = 0x00; 00195 CAN_Receive(CAN, CAN_FIFO0, &RxMessage); 00196 00197 if (RxMessage.StdId != 0x11) 00198 { 00199 return FAILED; 00200 } 00201 00202 if (RxMessage.IDE != CAN_ID_STD) 00203 { 00204 return FAILED; 00205 } 00206 00207 if (RxMessage.DLC != 2) 00208 { 00209 return FAILED; 00210 } 00211 00212 if ((RxMessage.Data[0]<<8|RxMessage.Data[1]) != 0xCAFE) 00213 { 00214 return FAILED; 00215 } 00216 00217 return PASSED; /* Test Passed */ 00218 } 00219 00220 /** 00221 * @brief Configures the CAN, transmit and receive using interrupt. 00222 * @param None 00223 * @retval PASSED if the reception is well done, FAILED in other case 00224 */ 00225 TestStatus CAN_Interrupt(void) 00226 { 00227 CAN_InitTypeDef CAN_InitStructure; 00228 CAN_FilterInitTypeDef CAN_FilterInitStructure; 00229 CanTxMsg TxMessage; 00230 uint32_t i = 0; 00231 00232 /* CAN register init */ 00233 CAN_DeInit(CAN); 00234 00235 CAN_StructInit(&CAN_InitStructure); 00236 00237 /* CAN cell init */ 00238 CAN_InitStructure.CAN_TTCM = DISABLE; 00239 CAN_InitStructure.CAN_ABOM = DISABLE; 00240 CAN_InitStructure.CAN_AWUM = DISABLE; 00241 CAN_InitStructure.CAN_NART = DISABLE; 00242 CAN_InitStructure.CAN_RFLM = DISABLE; 00243 CAN_InitStructure.CAN_TXFP = DISABLE; 00244 CAN_InitStructure.CAN_Mode = CAN_Mode_LoopBack; 00245 CAN_InitStructure.CAN_SJW = CAN_SJW_1tq; 00246 00247 /* Baudrate = 500 Kbps (CAN clocked with 36Mhz)*/ 00248 CAN_InitStructure.CAN_BS1 = CAN_BS1_9tq; 00249 CAN_InitStructure.CAN_BS2 = CAN_BS2_8tq; 00250 CAN_InitStructure.CAN_Prescaler = 4; 00251 CAN_Init(CAN, &CAN_InitStructure); 00252 00253 /* CAN filter init */ 00254 CAN_FilterInitStructure.CAN_FilterNumber = 1; 00255 CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask; 00256 CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit; 00257 CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000; 00258 CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000; 00259 CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000; 00260 CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000; 00261 CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_FIFO0; 00262 CAN_FilterInitStructure.CAN_FilterActivation = ENABLE; 00263 CAN_FilterInit(&CAN_FilterInitStructure); 00264 00265 /* CAN FIFO0 message pending interrupt enable */ 00266 CAN_ITConfig(CAN, CAN_IT_FMP0, ENABLE); 00267 00268 /* transmit 1 message */ 00269 TxMessage.StdId = 0; 00270 TxMessage.ExtId = 0x1234; 00271 TxMessage.IDE = CAN_ID_EXT; 00272 TxMessage.RTR = CAN_RTR_DATA; 00273 TxMessage.DLC = 2; 00274 TxMessage.Data[0] = 0xDE; 00275 TxMessage.Data[1] = 0xCA; 00276 CAN_Transmit(CAN, &TxMessage); 00277 00278 /* initialize the value that will be returned */ 00279 ret = 0xFF; 00280 00281 /* Receive message with interrupt handling */ 00282 i = 0; 00283 while((ret == 0xFF) && (i < 0xFFF)) 00284 { 00285 i++; 00286 } 00287 00288 if (i == 0xFFF) 00289 { 00290 ret = 0; 00291 } 00292 00293 /* disable interrupt handling */ 00294 CAN_ITConfig(CAN, CAN_IT_FMP0, DISABLE); 00295 00296 return (TestStatus)ret; 00297 } 00298 00299 /** 00300 * @brief Configures the NVIC. 00301 * @param None 00302 * @retval None 00303 */ 00304 static void NVIC_Config(void) 00305 { 00306 NVIC_InitTypeDef NVIC_InitStructure; 00307 00308 /* Enable CAN RX0 interrupt IRQ channel */ 00309 NVIC_InitStructure.NVIC_IRQChannel = CEC_CAN_IRQn; 00310 NVIC_InitStructure.NVIC_IRQChannelPriority = 0; 00311 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 00312 NVIC_Init(&NVIC_InitStructure); 00313 } 00314 00315 #ifdef USE_FULL_ASSERT 00316 00317 /** 00318 * @brief Reports the name of the source file and the source line number 00319 * where the assert_param error has occurred. 00320 * @param file: pointer to the source file name 00321 * @param line: assert_param error line source number 00322 * @retval None 00323 */ 00324 void assert_failed(uint8_t* file, uint32_t line) 00325 { 00326 /* User can add his own implementation to report the file name and line number, 00327 ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ 00328 00329 /* Infinite loop */ 00330 while (1) 00331 { 00332 } 00333 } 00334 00335 #endif 00336 00337 /** 00338 * @} 00339 */ 00340 00341 /** 00342 * @} 00343 */ 00344 00345 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/