1 /*
2 * Copyright (c) 2006-2018, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2018-01-06 sundm75 first version
9 */
10
11 #include "ls1c.h"
12 #include "ls1c_public.h"
13 #include "ls1c_can.h"
14 #include "ls1c_delay.h"
15
set_reset_mode(CAN_TypeDef * CANx)16 unsigned char set_reset_mode(CAN_TypeDef* CANx)
17 {
18 unsigned char status;
19 int i;
20
21 /*检查复位标志*/
22 status = CANx->MOD;
23
24 /* 关闭中断 */
25 CANx->IER = 0x00;
26
27 for (i = 0; i < 100; i++)
28 {
29 if((status & CAN_Mode_RM) == CAN_Mode_RM)
30 return 1;
31
32 /* 设置复位*/
33 CANx->MOD |= ((unsigned char)CAN_Mode_RM);
34
35 /*延时*/
36 delay_us(10);
37
38 /*检查复位标志*/
39 status = CANx->MOD;
40 }
41 printf("\r\nSetting SJA1000 into reset mode failed!\r\n");
42 return 0;
43 }
44
set_normal_mode(CAN_TypeDef * CANx)45 static unsigned char set_normal_mode(CAN_TypeDef* CANx)
46 {
47 unsigned char status;
48 int i;
49
50 /*检查复位标志*/
51 status = CANx->MOD;
52
53 for (i = 0; i < 100; i++)
54 {
55 if((status & CAN_Mode_RM) != CAN_Mode_RM)
56 {
57 /*开所有中断 (总线错误中断不开)*/
58 CANx->IER |= (~(unsigned char)CAN_IR_BEI);
59 return 1;
60 }
61 /* 设置正常工作模式*/
62 CANx->MOD &= (~(unsigned char) CAN_Mode_RM);
63 /*延时*/
64 delay_us(10);
65 status = CANx->MOD;
66 }
67 printf("\r\nSetting SJA1000 into normal mode failed!\r\n");
68 return 0;
69 }
70
set_start(CAN_TypeDef * CANx)71 unsigned char set_start(CAN_TypeDef* CANx)
72 {
73 /*复位TX错误计数器*/
74 CANx->TXERR = 0;
75 /*复位RX错误计数器*/
76 CANx->RXERR = 0;
77 /*时钟分频寄存器: PeliCAN模式; CBP=1,中止输入比较器, RX0激活*/
78 CANx->CDR = 0xC0;
79
80 return set_normal_mode(CANx);
81 }
82
CAN_Init(CAN_TypeDef * CANx,CAN_InitTypeDef * CAN_InitStruct)83 unsigned char CAN_Init(CAN_TypeDef* CANx, CAN_InitTypeDef* CAN_InitStruct)
84 {
85 unsigned char InitStatus = CAN_InitStatus_Failed;
86 unsigned long wait_ack = 0x00000000;
87 unsigned char status;
88
89 status = CANx->MOD;
90 if( status == 0xFF)
91 {
92 printf("\n Probe can0 failed \r\n");
93 return CAN_InitStatus_Failed;
94 }
95
96 /* 进入复位模式 */
97 InitStatus = set_reset_mode(CANx);
98
99 if((CAN_InitStruct->CAN_Mode & CAN_Mode_SM) == CAN_Mode_SM)
100 {
101 /* 睡眠模式 1: 睡眠 0: 唤醒*/
102 CANx->MOD|= (unsigned char)CAN_Mode_SM;
103 }
104 else
105 {
106 CANx->MOD&=~ (unsigned char)CAN_Mode_SM;
107 }
108
109 if((CAN_InitStruct->CAN_Mode & CAN_Mode_LOM) == CAN_Mode_LOM)
110 {
111 /*只听模式 1:只听 0:正常 */
112 CANx->MOD|= (unsigned char)CAN_Mode_LOM;
113 }
114 else
115 {
116 CANx->MOD&=~ (unsigned char)CAN_Mode_LOM;
117 }
118
119 if((CAN_InitStruct->CAN_Mode & CAN_Mode_AFM) == CAN_Mode_AFM)
120 {
121 /*单滤波模式 1:单 0: 双*/
122 CANx->MOD |= (unsigned char)CAN_Mode_AFM;
123 }
124 else
125 {
126 CANx->MOD&=~ (unsigned char)CAN_Mode_AFM;
127 }
128
129 if((CAN_InitStruct->CAN_Mode & CAN_Mode_STM) == CAN_Mode_STM)
130 {
131 /*自检测模式 1:自检测 0:正常 */
132 CANx->MOD |= (unsigned char)CAN_Mode_STM;
133 }
134 else
135 {
136 CANx->MOD&=~ (unsigned char)CAN_Mode_STM;
137 }
138
139 /* 配置时钟频率 */
140 CANx->BTR0 = (( unsigned char )( unsigned char )CAN_InitStruct->CAN_Prescaler -1) | \
141 (unsigned char)CAN_InitStruct->CAN_SJW << 6;
142
143 CANx->BTR1 = ((unsigned char)CAN_InitStruct->CAN_BS1) | \
144 ((unsigned char)CAN_InitStruct->CAN_BS2 << 4) | \
145 ((unsigned char)CAN_InitStruct->CAN_SJW<<7);
146
147 /* 进入工作模式 */
148 set_start(CANx);
149
150 /* 返回初始化结果 */
151 return InitStatus;
152 }
153
CAN_FilterInit(CAN_TypeDef * CANx,CAN_FilterInitTypeDef * CAN_FilterInitStruct)154 void CAN_FilterInit(CAN_TypeDef* CANx, CAN_FilterInitTypeDef * CAN_FilterInitStruct)
155 {
156 unsigned long rtr;
157 unsigned long fcase;
158 unsigned long ide;
159 unsigned long thisid, thisid1, thisid2;
160 unsigned long thismask, thismask1, thismask2;
161 unsigned long firstdata;
162 unsigned long datamask;
163 unsigned char CAN_FilterId0, CAN_FilterId1, CAN_FilterId2, CAN_FilterId3 ;
164 unsigned char CAN_FilterMaskId0, CAN_FilterMaskId1, CAN_FilterMaskId2, CAN_FilterMaskId3;
165
166 thisid = CAN_FilterInitStruct->ID;
167 thismask = CAN_FilterInitStruct->IDMASK;
168 thisid1 = (CAN_FilterInitStruct->ID & 0xFFFF0000 )>>16;
169 thismask1 = (CAN_FilterInitStruct->IDMASK & 0xFFFF0000 )>>16;
170 thisid2 = (CAN_FilterInitStruct->ID & 0x0000FFFF );
171 thismask2 = ( CAN_FilterInitStruct->IDMASK& 0x0000FFFF );
172 rtr = CAN_FilterInitStruct->RTR;
173 ide = CAN_FilterInitStruct->IDE;
174 firstdata = CAN_FilterInitStruct->First_Data;
175 datamask = CAN_FilterInitStruct->Data_Mask;
176 fcase = CAN_FilterInitStruct->MODE;
177
178 if(ide == 0)//标准帧
179 {
180 if(fcase == 0)// 0- 双滤波器模式
181 {
182 CAN_FilterId0 = thisid1>>3;
183 CAN_FilterMaskId0 = thismask1>>3;
184 CAN_FilterId1 = thisid1<<5 | firstdata>>4| rtr<<4;
185 CAN_FilterMaskId1 = thismask1<<4 | datamask>>4 ;
186 CAN_FilterId2 = thisid2 >> 3;
187 CAN_FilterMaskId2 = thismask2 >>3;
188 CAN_FilterId3 = firstdata & 0x0F | thisid2 <<5 | rtr<<4;
189 CAN_FilterMaskId3 = datamask <<4 ;
190 }
191 else if(fcase == 1)// 1-单滤波器模式
192 {
193 CAN_FilterId0 = thisid>>3;
194 CAN_FilterMaskId0 = thismask>>3;
195 CAN_FilterId1 = thisid<<5 | rtr<<4;
196 CAN_FilterMaskId1 = thismask<<5 ;
197 CAN_FilterMaskId1 |= 0x0F ;
198 CAN_FilterId2 = 0x00;
199 CAN_FilterMaskId2 = 0xFF;
200 CAN_FilterId3 = 0x00;
201 CAN_FilterMaskId3 = 0xFF ;
202 }
203 }
204 else if(ide == 1)//扩展帧
205 {
206 if(fcase == 0)// 0- 双滤波器模式
207 {
208 CAN_FilterId0 = thisid1>>8;
209 CAN_FilterMaskId0 = thismask1>>8;
210 CAN_FilterId1 = thisid1 ;
211 CAN_FilterMaskId1 = thismask1 ;
212 CAN_FilterId2 = thisid2>>8;
213 CAN_FilterMaskId2 = thismask2>>8;
214 CAN_FilterId3 = thisid2 ;
215 CAN_FilterMaskId3 = thismask2 ;
216 }
217 else if(fcase == 1)// 1-单滤波器模式
218 {
219 CAN_FilterId0 = thisid>>21;
220 CAN_FilterMaskId0 = thismask>>21;
221 CAN_FilterId1 = thisid>>13 ;
222 CAN_FilterMaskId1 = thismask>>13 ;
223 CAN_FilterId2 = thisid>>5;
224 CAN_FilterMaskId2 = thismask>>5;
225 CAN_FilterId3 = thisid<<3 | rtr<<2;
226 CAN_FilterMaskId3 = thismask<<3;
227 CAN_FilterMaskId3 |= 0x03;
228 }
229 }
230
231 /* 进入复位模式 */
232 set_reset_mode(CANx);
233
234 if(fcase == 1)// 1-单滤波器模式
235 {
236 /*单滤波模式 */
237 CANx->MOD |= (unsigned char)CAN_Mode_AFM;
238 }
239 else if(fcase == 1)// 0- 双滤波器模式
240 {
241 /*双滤波模式 */
242 CANx->MOD &=(~ (unsigned char) CAN_Mode_AFM);
243 }
244
245 CANx->IDE_RTR_DLC = CAN_FilterId0;
246 CANx->ID[0] = CAN_FilterId1;
247 CANx->ID[1] = CAN_FilterId2;
248 CANx->ID[2] = CAN_FilterId3;
249 CANx->ID[3] = CAN_FilterMaskId0;
250 CANx->BUF[0] = CAN_FilterMaskId1;
251 CANx->BUF[1] = CAN_FilterMaskId2;
252 CANx->BUF[2] = CAN_FilterMaskId3;
253 /* 进入工作模式 */
254 set_start(CANx);
255 }
256
CAN_SetBps(CAN_TypeDef * CANx,Ls1c_CanBPS_t Bps)257 unsigned char CAN_SetBps(CAN_TypeDef* CANx, Ls1c_CanBPS_t Bps)
258 {
259 unsigned char InitStatus = CAN_InitStatus_Failed;
260 unsigned char CAN_Prescaler, CAN_BS1, CAN_BS2, CAN_SJW;
261 CAN_SJW = CAN_SJW_1tq;
262 /* 进入复位模式 */
263 InitStatus = set_reset_mode(CANx);
264 if( InitStatus == CAN_InitStatus_Failed)
265 return CAN_InitStatus_Failed;
266
267 /* BaudRate= f(APB)/((1+BS1+BS2)(SJW*2*Prescaler))=126000000/[(1+7+2)*1*2*63]=100000=100K*/
268 /* BPS PRE BS1 BS2 最低40K
269 1M 9 4 2
270 800K 8 7 2
271 500K 9 11 2
272 250K 36 4 2
273 125K 36 11 2
274 100K 63 7 2
275 50K 63 16 3`
276 40K 63 16 8
277 */
278 switch (Bps)
279 {
280 case LS1C_CAN1MBaud:
281 CAN_Prescaler = 9;
282 CAN_BS1 = CAN_BS1_4tq;
283 CAN_BS2 = CAN_BS2_2tq;
284 break;
285 case LS1C_CAN800kBaud:
286 CAN_Prescaler = 8;
287 CAN_BS1 = CAN_BS1_7tq;
288 CAN_BS2 = CAN_BS2_2tq;
289 break;
290 case LS1C_CAN500kBaud:
291 CAN_Prescaler = 9;
292 CAN_BS1 = CAN_BS1_11tq;
293 CAN_BS2 = CAN_BS2_2tq;
294 break;
295 case LS1C_CAN250kBaud:
296 CAN_Prescaler = 36;
297 CAN_BS1 = CAN_BS1_4tq;
298 CAN_BS2 = CAN_BS2_2tq;
299 break;
300 case LS1C_CAN125kBaud:
301 CAN_Prescaler = 36;
302 CAN_BS1 = CAN_BS1_11tq;
303 CAN_BS2 = CAN_BS2_2tq;
304 break;
305 case LS1C_CAN100kBaud:
306 CAN_Prescaler = 63;
307 CAN_BS1 = CAN_BS1_7tq;
308 CAN_BS2 = CAN_BS2_2tq;
309 break;
310 case LS1C_CAN50kBaud:
311 CAN_Prescaler = 63;
312 CAN_BS1 = CAN_BS1_16tq;
313 CAN_BS2 = CAN_BS2_3tq;
314 break;
315 case LS1C_CAN40kBaud:
316 CAN_Prescaler = 63;
317 CAN_BS1 = CAN_BS1_16tq;
318 CAN_BS2 = CAN_BS2_8tq;
319 break;
320 default: //100K
321 CAN_Prescaler = 63;
322 CAN_BS1 = CAN_BS1_7tq;
323 CAN_BS2 = CAN_BS2_2tq;
324 break;
325 }
326 /* 配置时钟频率 */
327 CANx->BTR0 = (( unsigned char )CAN_Prescaler -1) | \
328 (unsigned char)CAN_SJW << 6;
329
330 CANx->BTR1 = ((unsigned char)CAN_BS1) | \
331 ((unsigned char)CAN_BS2 << 4) | \
332 ((unsigned char)CAN_SJW<<7);
333
334 /* 进入工作模式 */
335 set_start(CANx);
336 /* 返回初始化结果 */
337 return CAN_InitStatus_Failed;
338 }
339
340
CAN_SetMode(CAN_TypeDef * CANx,unsigned char mode)341 unsigned char CAN_SetMode(CAN_TypeDef* CANx, unsigned char mode)
342 {
343 unsigned char InitStatus = CAN_InitStatus_Failed;
344 unsigned long wait_ack = 0x00000000;
345 CAN_InitTypeDef CAN_InitStructure;
346
347 /* 进入复位模式 */
348 InitStatus = set_reset_mode(CANx);
349 if( InitStatus == CAN_InitStatus_Failed)
350 return CAN_InitStatus_Failed;
351
352 switch( mode )
353 {
354 case 0://正常
355 CANx->MOD &= ~(unsigned char)CAN_Mode_STM;
356 CANx->MOD &= ~(unsigned char)CAN_Mode_LOM;
357 break;
358 case 1://只听
359 CANx->MOD &= ~(unsigned char)CAN_Mode_STM;
360 CANx->MOD |= (unsigned char)CAN_Mode_LOM;
361 break;
362 case 2://回环
363 CANx->MOD |= (unsigned char)CAN_Mode_STM;
364 CANx->MOD &= ~(unsigned char)CAN_Mode_LOM;
365 break;
366 case 3://只听回环
367 CANx->MOD |= (unsigned char)CAN_Mode_STM;
368 CANx->MOD |= (unsigned char)CAN_Mode_LOM;
369 break;
370 }
371 /* 进入工作模式 */
372 set_start(CANx);
373
374 /* 返回初始化结果 */
375 return CAN_InitStatus_Failed;
376 }
377
CAN_Transmit(CAN_TypeDef * CANx,CanTxMsg * TxMessage)378 unsigned char CAN_Transmit(CAN_TypeDef* CANx, CanTxMsg* TxMessage)
379 {
380 int i;
381 if (TxMessage->IDE == CAN_Id_Extended)
382 {
383 CANx->ID[0]= TxMessage ->ExtId>> 21;
384 CANx->ID[1]= TxMessage ->ExtId>> 13;
385 CANx->ID[2]= TxMessage ->ExtId>> 5;
386 CANx->ID[3]= TxMessage ->ExtId<<3;
387 CANx->IDE_RTR_DLC= (TxMessage ->IDE & 0x01) << 7 |\
388 (TxMessage ->RTR & 0x01) << 6 |\
389 (TxMessage ->DLC & 0x0F);
390 for( i=0;i<TxMessage ->DLC; i++)
391 {
392 CANx->BUF[i]= TxMessage->Data[i];
393 }
394 }
395 else if (TxMessage->IDE ==CAN_Id_Standard)
396 {
397 CANx->ID[0]= TxMessage ->StdId>> 3;
398 CANx->ID[1]= TxMessage ->StdId<< 5;
399 CANx->IDE_RTR_DLC= (TxMessage ->IDE & 0x01) << 7 |\
400 (TxMessage ->RTR & 0x01) << 6 |\
401 (TxMessage ->DLC & 0x0F);
402 CANx->ID[2]= TxMessage ->Data[0];
403 CANx->ID[3]= TxMessage ->Data[1];
404 for( i=0;i<TxMessage ->DLC-2; i++)
405 {
406 CANx->BUF[i]= TxMessage->Data[i+2];
407 }
408 }
409 CANx->CMR = CAN_CMR_TR ;
410 }
411
CAN_Receive(CAN_TypeDef * CANx,CanRxMsg * RxMessage)412 void CAN_Receive(CAN_TypeDef* CANx, CanRxMsg* RxMessage)
413 {
414 /* 获取 IDE */
415 RxMessage->IDE = (CANx->IDE_RTR_DLC & 0x80)>>7;
416 /* 获取 RTR */
417 RxMessage->RTR = (CANx->IDE_RTR_DLC & 0x40)>>4;
418 /* 获取 DLC */
419 RxMessage->DLC= (CANx->IDE_RTR_DLC & 0x0F);
420 if (RxMessage->IDE == CAN_Id_Standard)
421 {
422 RxMessage->StdId = CANx->ID[0]<<3 |CANx->ID[1]>>5 ;
423 /* 获取数据 */
424 RxMessage->Data[0] = (unsigned char)CANx->ID[2];
425 RxMessage->Data[1] = (unsigned char)CANx->ID[3];
426 RxMessage->Data[2] = (unsigned char)CANx->BUF[0];
427 RxMessage->Data[3] = (unsigned char)CANx->BUF[1];
428 RxMessage->Data[4] = (unsigned char)CANx->BUF[2];
429 RxMessage->Data[5] = (unsigned char)CANx->BUF[3];
430 RxMessage->Data[6] = (unsigned char)CANx->BUF[4];
431 RxMessage->Data[7] = (unsigned char)CANx->BUF[5];
432 }
433 else if (RxMessage->IDE == CAN_Id_Extended)
434 {
435 RxMessage->ExtId= CANx->ID[0]<<21 |CANx->ID[1]<<13|CANx->ID[2]<<5|CANx->ID[3]>>3 ;
436 /* 获取数据 */
437 RxMessage->Data[0] = (unsigned char)CANx->BUF[0];
438 RxMessage->Data[1] = (unsigned char)CANx->BUF[1];
439 RxMessage->Data[2] = (unsigned char)CANx->BUF[2];
440 RxMessage->Data[3] = (unsigned char)CANx->BUF[3];
441 RxMessage->Data[4] = (unsigned char)CANx->BUF[4];
442 RxMessage->Data[5] = (unsigned char)CANx->BUF[5];
443 RxMessage->Data[6] = (unsigned char)CANx->BUF[6];
444 RxMessage->Data[7] = (unsigned char)CANx->BUF[7];
445 }
446 }
447
448