1 | /* Includes ------------------------------------------------------------------*/
|
2 | #include "stm32f10x.h"
|
3 |
|
4 | /* Private define ------------------------------------------------------------*/
|
5 | //#define __CAN1_USED__
|
6 | #define __CAN2_USED__*/ /* Please check that you device is
|
7 | Connectivity line when using CAN2 */
|
8 |
|
9 | #ifdef __CAN1_USED__
|
10 | #define CANx CAN1
|
11 | #else /*__CAN2_USED__*/
|
12 | #define CANx CAN2
|
13 | #endif /* __CAN1_USED__ */
|
14 |
|
15 | /* Private typedef -----------------------------------------------------------*/
|
16 | typedef enum {FAILED = 0, PASSED = !FAILED} TestStatus;
|
17 | /* Private macro -------------------------------------------------------------*/
|
18 | /* Private variables ---------------------------------------------------------*/
|
19 | __IO uint32_t ret = 0; /* for return of the interrupt handling */
|
20 | volatile TestStatus TestRx;
|
21 |
|
22 | /* Private function prototypes -----------------------------------------------*/
|
23 | void NVIC_Configuration(void);
|
24 | TestStatus CAN_Polling(void);
|
25 | TestStatus CAN_Interrupt(void);
|
26 |
|
27 | /* Private functions ---------------------------------------------------------*/
|
28 |
|
29 |
|
30 | int main(void)
|
31 | {
|
32 |
|
33 |
|
34 | /* CAN1 Periph clock enable */
|
35 | RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
|
36 |
|
37 | // RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
|
38 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
|
39 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
|
40 |
|
41 |
|
42 |
|
43 | GPIO_InitTypeDef GPIO_InitStructure;
|
44 |
|
45 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
|
46 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
47 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
|
48 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;
|
49 | GPIO_Init(GPIOC, &GPIO_InitStructure);
|
50 |
|
51 | // Configure CAN Tx as push-pull
|
52 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
|
53 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
|
54 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
|
55 | GPIO_Init(GPIOB, &GPIO_InitStructure);
|
56 | // Configure CAN Rx as input floating
|
57 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
|
58 | GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
|
59 | GPIO_Init(GPIOB, &GPIO_InitStructure);
|
60 |
|
61 |
|
62 | #ifdef __CAN1_USED__
|
63 | /* CANx Periph clock enable */
|
64 | RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
|
65 | #else /*__CAN2_USED__*/
|
66 | /* CAN1 & 2 Periph clock enable */
|
67 | RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
|
68 | RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, ENABLE);
|
69 | #endif /* __CAN1_USED__ */
|
70 |
|
71 | /* NVIC Configuration */
|
72 | NVIC_Configuration();
|
73 |
|
74 |
|
75 | /* CAN transmit at 125Kb/s and receive by polling in loopback mode */
|
76 | TestRx = CAN_Polling();
|
77 |
|
78 | if (TestRx == FAILED)
|
79 | {
|
80 | /* Turn on led LD3 */
|
81 | // STM_EVAL_LEDOn(LED3);
|
82 |
|
83 | GPIO_WriteBit(GPIOC, GPIO_Pin_6, Bit_SET);
|
84 |
|
85 | }
|
86 | else
|
87 | {
|
88 | /* Turn on led LD1 */
|
89 | //STM_EVAL_LEDOn(LED1);
|
90 | GPIO_WriteBit(GPIOC, GPIO_Pin_6, Bit_RESET);
|
91 |
|
92 | }
|
93 |
|
94 | /* CAN transmit at 500Kb/s and receive by interrupt in loopback mode */
|
95 | TestRx = CAN_Interrupt();
|
96 |
|
97 | if (TestRx == FAILED)
|
98 | {
|
99 | /* Turn on led LD4 */
|
100 | //STM_EVAL_LEDOn(LED4);
|
101 | GPIO_WriteBit(GPIOC, GPIO_Pin_7, Bit_SET);
|
102 | }
|
103 | else
|
104 | {
|
105 | /* Turn on led LD2 */
|
106 | // STM_EVAL_LEDOn(LED2);
|
107 | GPIO_WriteBit(GPIOC, GPIO_Pin_7, Bit_RESET);
|
108 | }
|
109 |
|
110 | /* Infinite loop */
|
111 | while (1)
|
112 | {
|
113 |
|
114 |
|
115 | }
|
116 | }
|
117 |
|
118 | /**
|
119 | * @brief Configures the CAN, transmit and receive by polling
|
120 | * @param None
|
121 | * @retval PASSED if the reception is well done, FAILED in other case
|
122 | */
|
123 | TestStatus CAN_Polling(void)
|
124 | {
|
125 | CAN_InitTypeDef CAN_InitStructure;
|
126 | CAN_FilterInitTypeDef CAN_FilterInitStructure;
|
127 | CanTxMsg TxMessage;
|
128 | CanRxMsg RxMessage;
|
129 | uint32_t i = 0;
|
130 | uint8_t TransmitMailbox = 0;
|
131 |
|
132 | /* CAN register init */
|
133 | CAN_DeInit(CANx);
|
134 |
|
135 | CAN_StructInit(&CAN_InitStructure);
|
136 |
|
137 | /* CAN cell init */
|
138 | CAN_InitStructure.CAN_TTCM=DISABLE;
|
139 | CAN_InitStructure.CAN_ABOM=DISABLE;
|
140 | CAN_InitStructure.CAN_AWUM=DISABLE;
|
141 | CAN_InitStructure.CAN_NART=DISABLE;
|
142 | CAN_InitStructure.CAN_RFLM=DISABLE;
|
143 | CAN_InitStructure.CAN_TXFP=DISABLE;
|
144 | CAN_InitStructure.CAN_Mode=CAN_Mode_LoopBack;
|
145 |
|
146 | /* Baudrate = 125kbps*/
|
147 | CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;
|
148 | CAN_InitStructure.CAN_BS1=CAN_BS1_2tq;
|
149 | CAN_InitStructure.CAN_BS2=CAN_BS2_3tq;
|
150 | CAN_InitStructure.CAN_Prescaler=48;
|
151 | CAN_Init(CANx, &CAN_InitStructure);
|
152 |
|
153 | /* CAN filter init */
|
154 | #ifdef __CAN1_USED__
|
155 | CAN_FilterInitStructure.CAN_FilterNumber=0;
|
156 | #else /*__CAN2_USED__*/
|
157 | CAN_FilterInitStructure.CAN_FilterNumber=14;
|
158 | #endif /* __CAN1_USED__ */
|
159 | CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
|
160 | CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;
|
161 | CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;
|
162 | CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;
|
163 | CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;
|
164 | CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
|
165 | CAN_FilterInitStructure.CAN_FilterFIFOAssignment=0;
|
166 |
|
167 |
|
168 | CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;
|
169 | CAN_FilterInit(&CAN_FilterInitStructure);
|
170 |
|
171 | /* transmit */
|
172 | TxMessage.StdId=0x11;
|
173 | TxMessage.RTR=CAN_RTR_DATA;
|
174 | TxMessage.IDE=CAN_ID_STD;
|
175 | TxMessage.DLC=2;
|
176 | TxMessage.Data[0]=0xCA;
|
177 | TxMessage.Data[1]=0xFE;
|
178 |
|
179 | TransmitMailbox=CAN_Transmit(CANx, &TxMessage);
|
180 | i = 0;
|
181 | while((CAN_TransmitStatus(CANx, TransmitMailbox) != CANTXOK) && (i != 0xFFFF))
|
182 | {
|
183 | i++;
|
184 | }
|
185 |
|
186 | i = 0;
|
187 | while((CAN_MessagePending(CANx, CAN_FIFO0) < 1) && (i != 0xFFFF))
|
188 | {
|
189 | i++;
|
190 | }
|
191 |
|
192 | /* receive */
|
193 | RxMessage.StdId=0x00;
|
194 | RxMessage.IDE=CAN_ID_STD;
|
195 | RxMessage.DLC=0;
|
196 | RxMessage.Data[0]=0x00;
|
197 | RxMessage.Data[1]=0x00;
|
198 | CAN_Receive(CANx, CAN_FIFO0, &RxMessage);
|
199 |
|
200 | if (RxMessage.StdId!=0x11)
|
201 | {
|
202 | return FAILED;
|
203 | }
|
204 |
|
205 | if (RxMessage.IDE!=CAN_ID_STD)
|
206 | {
|
207 | return FAILED;
|
208 | }
|
209 |
|
210 | if (RxMessage.DLC!=2)
|
211 | {
|
212 | return FAILED;
|
213 | }
|
214 |
|
215 | if ((RxMessage.Data[0]<<8|RxMessage.Data[1])!=0xCAFE)
|
216 | {
|
217 | return FAILED;
|
218 | }
|
219 |
|
220 | return PASSED; /* Test Passed */
|
221 | }
|
222 |
|
223 | /**
|
224 | * @brief Configures the CAN, transmit and receive using interrupt.
|
225 | * @param None
|
226 | * @retval PASSED if the reception is well done, FAILED in other case
|
227 | */
|
228 | TestStatus CAN_Interrupt(void)
|
229 | {
|
230 | CAN_InitTypeDef CAN_InitStructure;
|
231 | CAN_FilterInitTypeDef CAN_FilterInitStructure;
|
232 | CanTxMsg TxMessage;
|
233 | uint32_t i = 0;
|
234 |
|
235 | /* CAN register init */
|
236 | CAN_DeInit(CANx);
|
237 |
|
238 |
|
239 | CAN_StructInit(&CAN_InitStructure);
|
240 |
|
241 | /* CAN cell init */
|
242 | CAN_InitStructure.CAN_TTCM=DISABLE;
|
243 | CAN_InitStructure.CAN_ABOM=DISABLE;
|
244 | CAN_InitStructure.CAN_AWUM=DISABLE;
|
245 | CAN_InitStructure.CAN_NART=DISABLE;
|
246 | CAN_InitStructure.CAN_RFLM=DISABLE;
|
247 | CAN_InitStructure.CAN_TXFP=DISABLE;
|
248 | CAN_InitStructure.CAN_Mode=CAN_Mode_LoopBack;
|
249 | CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;
|
250 |
|
251 | /* Baudrate = 500 Kbps */
|
252 | CAN_InitStructure.CAN_BS1=CAN_BS1_2tq;
|
253 | CAN_InitStructure.CAN_BS2=CAN_BS2_3tq;
|
254 | CAN_InitStructure.CAN_Prescaler=12;
|
255 | CAN_Init(CANx, &CAN_InitStructure);
|
256 |
|
257 | /* CAN filter init */
|
258 | #ifdef __CAN1_USED__
|
259 | CAN_FilterInitStructure.CAN_FilterNumber=1;
|
260 | #else /*__CAN2_USED__*/
|
261 | CAN_FilterInitStructure.CAN_FilterNumber=15;
|
262 | #endif /* __CAN1_USED__ */
|
263 | CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
|
264 | CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;
|
265 | CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;
|
266 | CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;
|
267 | CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;
|
268 | CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
|
269 | CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_FIFO0;
|
270 | CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;
|
271 | CAN_FilterInit(&CAN_FilterInitStructure);
|
272 |
|
273 | /* CAN FIFO0 message pending interrupt enable */
|
274 | CAN_ITConfig(CANx, CAN_IT_FMP0, ENABLE);
|
275 |
|
276 | /* transmit 1 message */
|
277 | TxMessage.StdId=0;
|
278 | TxMessage.ExtId=0x1234;
|
279 | TxMessage.IDE=CAN_ID_EXT;
|
280 | TxMessage.RTR=CAN_RTR_DATA;
|
281 | TxMessage.DLC=2;
|
282 | TxMessage.Data[0]=0xDE;
|
283 | TxMessage.Data[1]=0xCA;
|
284 | CAN_Transmit(CANx, &TxMessage);
|
285 |
|
286 | /* initialize the value that will be returned */
|
287 | ret = 0xFF;
|
288 |
|
289 | /* receive message with interrupt handling */
|
290 | i=0;
|
291 | while((ret == 0xFF) && (i < 0xFFF))
|
292 | {
|
293 | i++;
|
294 | }
|
295 |
|
296 | if (i == 0xFFF)
|
297 | {
|
298 | ret=0;
|
299 | }
|
300 |
|
301 | /* disable interrupt handling */
|
302 | CAN_ITConfig(CANx, CAN_IT_FMP0, DISABLE);
|
303 |
|
304 | return (TestStatus)ret;
|
305 | }
|
306 |
|
307 | /**
|
308 | * @brief Configures the NVIC and Vector Table base address.
|
309 | * @param None
|
310 | * @retval None
|
311 | */
|
312 | void NVIC_Configuration(void)
|
313 | {
|
314 | NVIC_InitTypeDef NVIC_InitStructure;
|
315 |
|
316 | /* Enable CANx RX0 interrupt IRQ channel */
|
317 | #ifndef STM32F10X_CL
|
318 |
|
319 | #ifdef __CAN1_USED__
|
320 | NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
|
321 | #else /*__CAN2_USED__*/
|
322 | /* CAN2 is not implemented in the device */
|
323 | #error "CAN2 is implemented only in Connectivity line devices"
|
324 |
|
325 | #endif /*__CAN1_USED__*/
|
326 | #else
|
327 | #ifdef __CAN1_USED__
|
328 | NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn;
|
329 | #else /*__CAN2_USED__*/
|
330 | NVIC_InitStructure.NVIC_IRQChannel = CAN2_RX0_IRQn;
|
331 | #endif /*__CAN1_USED__*/
|
332 |
|
333 | #endif /* STM32F10X_CL*/
|
334 | NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
|
335 | NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
|
336 | NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
|
337 | NVIC_Init(&NVIC_InitStructure);
|
338 | }
|
339 |
|
340 | #ifdef USE_FULL_ASSERT
|
341 |
|
342 | /**
|
343 | * @brief Reports the name of the source file and the source line number
|
344 | * where the assert_param error has occurred.
|
345 | * @param file: pointer to the source file name
|
346 | * @param line: assert_param error line source number
|
347 | * @retval None
|
348 | */
|
349 | void assert_failed(uint8_t* file, uint32_t line)
|
350 | {
|
351 | /* User can add his own implementation to report the file name and line number,
|
352 | ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
|
353 |
|
354 | /* Infinite loop */
|
355 | while (1)
|
356 | {
|
357 | }
|
358 | }
|
359 |
|
360 | #endif
|
361 |
|
362 | /**
|
363 | * @}
|
364 | */
|
365 |
|
366 | /**
|
367 | * @}
|
368 | */
|
369 |
|
370 | /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
|