source: asp3_tinet_ecnl_arm/trunk/asp3_dcre/mbed/targets/TARGET_RENESAS/TARGET_RZ_A1H/can_api.c@ 352

Last change on this file since 352 was 352, checked in by coas-nagasima, 6 years ago

arm向けASP3版ECNLを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 30.5 KB
Line 
1/* mbed Microcontroller Library
2 * Copyright (c) 2006-2013 ARM Limited
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#include <string.h>
17#include "mbed_assert.h"
18#include "can_api.h"
19#include "RZ_A1_Init.h"
20#include "cmsis.h"
21#include "pinmap.h"
22#include "rscan0_iodefine.h"
23#include "r_typedefs.h"
24#include "MBRZA1H.h"
25
26#define CAN_NUM 5
27#define CAN_SND_RCV 2
28#define IRQ_NUM 8
29
30static void can_rec_irq(uint32_t ch);
31static void can_trx_irq(uint32_t ch);
32static void can_err_irq(uint32_t ch, CanIrqType type);
33static void can0_rec_irq(void);
34static void can1_rec_irq(void);
35static void can2_rec_irq(void);
36static void can3_rec_irq(void);
37static void can4_rec_irq(void);
38static void can0_trx_irq(void);
39static void can1_trx_irq(void);
40static void can2_trx_irq(void);
41static void can3_trx_irq(void);
42static void can4_trx_irq(void);
43static void can0_err_warning_irq(void);
44static void can1_err_warning_irq(void);
45static void can2_err_warning_irq(void);
46static void can3_err_warning_irq(void);
47static void can4_err_warning_irq(void);
48static void can0_overrun_irq(void);
49static void can1_overrun_irq(void);
50static void can2_overrun_irq(void);
51static void can3_overrun_irq(void);
52static void can4_overrun_irq(void);
53static void can0_passive_irq(void);
54static void can1_passive_irq(void);
55static void can2_passive_irq(void);
56static void can3_passive_irq(void);
57static void can4_passive_irq(void);
58static void can0_arb_lost_irq(void);
59static void can1_arb_lost_irq(void);
60static void can2_arb_lost_irq(void);
61static void can3_arb_lost_irq(void);
62static void can4_arb_lost_irq(void);
63static void can0_bus_err_irq(void);
64static void can1_bus_err_irq(void);
65static void can2_bus_err_irq(void);
66static void can3_bus_err_irq(void);
67static void can4_bus_err_irq(void);
68static void can_reset_reg(can_t *obj);
69static void can_reset_recv_rule(can_t *obj);
70static void can_reset_buffer(can_t *obj);
71static void can_reconfigure_channel(void);
72static void can_set_frequency(can_t *obj, int f);
73static void can_set_global_mode(int mode);
74static void can_set_channel_mode(uint32_t ch, int mode);
75
76typedef enum {
77 CAN_SEND = 0,
78 CAN_RECV
79} CANfunc;
80
81typedef enum {
82 GL_OPE = 0,
83 GL_RESET,
84 GL_TEST
85} Globalmode;
86
87typedef enum {
88 CH_COMM = 0,
89 CH_RESET,
90 CH_HOLD
91} Channelmode;
92
93typedef struct {
94 IRQn_Type int_num; /* Interrupt number */
95 IRQHandler handler; /* Interrupt handler */
96} can_info_int_t;
97
98static can_irq_handler irq_handler;
99static uint32_t can_irq_id[CAN_NUM];
100static int can_initialized[CAN_NUM] = {0};
101
102static const PinMap PinMap_CAN_RD[] = {
103 {P7_8 , CAN_0, 4},
104 {P9_1 , CAN_0, 3},
105 {P1_4 , CAN_1, 3},
106 {P5_9 , CAN_1, 5},
107 {P7_11 , CAN_1, 4},
108 {P11_12, CAN_1, 1},
109 {P4_9 , CAN_2, 6},
110 {P6_4 , CAN_2, 3},
111 {P7_2 , CAN_2, 5},
112 {P2_12 , CAN_3, 5},
113 {P4_2 , CAN_3, 4},
114 {P1_5 , CAN_4, 3},
115 {P2_14 , CAN_4, 5},
116 {NC , NC , 0}
117};
118
119static const PinMap PinMap_CAN_TD[] = {
120 {P7_9 , CAN_0, 4},
121 {P9_0 , CAN_0, 3},
122 {P5_10 , CAN_1, 5},
123 {P7_10 , CAN_1, 4},
124 {P11_13, CAN_1, 1},
125 {P4_8 , CAN_2, 6},
126 {P6_5 , CAN_2, 3},
127 {P7_3 , CAN_2, 5},
128 {P2_13 , CAN_3, 5},
129 {P4_3 , CAN_3, 4},
130 {P4_11 , CAN_4, 6},
131 {P8_10 , CAN_4, 5},
132 {NC , NC , 0}
133};
134
135static __IO uint32_t *CTR_MATCH[] = {
136 &RSCAN0C0CTR,
137 &RSCAN0C1CTR,
138 &RSCAN0C2CTR,
139 &RSCAN0C3CTR,
140 &RSCAN0C4CTR,
141};
142
143static __IO uint32_t *CFG_MATCH[] = {
144 &RSCAN0C0CFG,
145 &RSCAN0C1CFG,
146 &RSCAN0C2CFG,
147 &RSCAN0C3CFG,
148 &RSCAN0C4CFG,
149};
150
151static __IO uint32_t *RFCC_MATCH[] = {
152 &RSCAN0RFCC0,
153 &RSCAN0RFCC1,
154 &RSCAN0RFCC2,
155 &RSCAN0RFCC3,
156 &RSCAN0RFCC4,
157 &RSCAN0RFCC5,
158 &RSCAN0RFCC6,
159 &RSCAN0RFCC7
160};
161
162static __IO uint32_t *TXQCC_MATCH[] = {
163 &RSCAN0TXQCC0,
164 &RSCAN0TXQCC1,
165 &RSCAN0TXQCC2,
166 &RSCAN0TXQCC3,
167 &RSCAN0TXQCC4,
168};
169
170static __IO uint32_t *THLCC_MATCH[] = {
171 &RSCAN0THLCC0,
172 &RSCAN0THLCC1,
173 &RSCAN0THLCC2,
174 &RSCAN0THLCC3,
175 &RSCAN0THLCC4,
176};
177
178static __IO uint32_t *STS_MATCH[] = {
179 &RSCAN0C0STS,
180 &RSCAN0C1STS,
181 &RSCAN0C2STS,
182 &RSCAN0C3STS,
183 &RSCAN0C4STS,
184};
185
186static __IO uint32_t *ERFL_MATCH[] = {
187 &RSCAN0C0ERFL,
188 &RSCAN0C1ERFL,
189 &RSCAN0C2ERFL,
190 &RSCAN0C3ERFL,
191 &RSCAN0C4ERFL,
192};
193
194static __IO uint32_t *CFCC_TBL[CAN_NUM][CAN_SND_RCV] = {
195 { &RSCAN0CFCC0 , &RSCAN0CFCC1 },
196 { &RSCAN0CFCC3 , &RSCAN0CFCC4 },
197 { &RSCAN0CFCC6 , &RSCAN0CFCC7 },
198 { &RSCAN0CFCC9 , &RSCAN0CFCC10 },
199 { &RSCAN0CFCC12, &RSCAN0CFCC13 }
200};
201
202static __IO uint32_t *CFSTS_TBL[CAN_NUM][CAN_SND_RCV] = {
203 { &RSCAN0CFSTS0 , &RSCAN0CFSTS1 },
204 { &RSCAN0CFSTS3 , &RSCAN0CFSTS4 },
205 { &RSCAN0CFSTS6 , &RSCAN0CFSTS7 },
206 { &RSCAN0CFSTS9 , &RSCAN0CFSTS10 },
207 { &RSCAN0CFSTS12, &RSCAN0CFSTS13 }
208};
209
210static __IO uint32_t *CFPCTR_TBL[CAN_NUM][CAN_SND_RCV] = {
211 { &RSCAN0CFPCTR0 , &RSCAN0CFPCTR1 },
212 { &RSCAN0CFPCTR3 , &RSCAN0CFPCTR4 },
213 { &RSCAN0CFPCTR6 , &RSCAN0CFPCTR7 },
214 { &RSCAN0CFPCTR9 , &RSCAN0CFPCTR10 },
215 { &RSCAN0CFPCTR12, &RSCAN0CFPCTR13 }
216};
217
218static __IO uint32_t *CFID_TBL[CAN_NUM][CAN_SND_RCV] = {
219 { &RSCAN0CFID0 , &RSCAN0CFID1 },
220 { &RSCAN0CFID3 , &RSCAN0CFID4 },
221 { &RSCAN0CFID6 , &RSCAN0CFID7 },
222 { &RSCAN0CFID9 , &RSCAN0CFID10 },
223 { &RSCAN0CFID12, &RSCAN0CFID13 }
224};
225
226static __IO uint32_t *CFPTR_TBL[CAN_NUM][CAN_SND_RCV] = {
227 { &RSCAN0CFPTR0 , &RSCAN0CFPTR1 },
228 { &RSCAN0CFPTR3 , &RSCAN0CFPTR4 },
229 { &RSCAN0CFPTR6 , &RSCAN0CFPTR7 },
230 { &RSCAN0CFPTR9 , &RSCAN0CFPTR10 },
231 { &RSCAN0CFPTR12, &RSCAN0CFPTR13 }
232};
233
234static __IO uint32_t *CFDF0_TBL[CAN_NUM][CAN_SND_RCV] = {
235 { &RSCAN0CFDF00 , &RSCAN0CFDF01 },
236 { &RSCAN0CFDF03 , &RSCAN0CFDF04 },
237 { &RSCAN0CFDF06 , &RSCAN0CFDF07 },
238 { &RSCAN0CFDF09 , &RSCAN0CFDF010 },
239 { &RSCAN0CFDF012, &RSCAN0CFDF013 }
240};
241
242static __IO uint32_t *CFDF1_TBL[CAN_NUM][CAN_SND_RCV] = {
243 { &RSCAN0CFDF10 , &RSCAN0CFDF11 },
244 { &RSCAN0CFDF13 , &RSCAN0CFDF14 },
245 { &RSCAN0CFDF16 , &RSCAN0CFDF17 },
246 { &RSCAN0CFDF19 , &RSCAN0CFDF110 },
247 { &RSCAN0CFDF112, &RSCAN0CFDF113 }
248};
249
250static const can_info_int_t can_int_info[CAN_NUM][IRQ_NUM] =
251{
252 { /* ch0 */
253 { INTRCAN0REC_IRQn, can0_rec_irq }, /* RxIrq */
254 { INTRCAN0TRX_IRQn, can0_trx_irq }, /* TxIrq */
255 { INTRCAN0ERR_IRQn, can0_err_warning_irq }, /* EwIrq */
256 { INTRCAN0ERR_IRQn, can0_overrun_irq }, /* DoIrq */
257 { INTRCAN0ERR_IRQn, NULL }, /* WuIrq(not supported) */
258 { INTRCAN0ERR_IRQn, can0_passive_irq }, /* EpIrq */
259 { INTRCAN0ERR_IRQn, can0_arb_lost_irq }, /* AlIrq */
260 { INTRCAN0ERR_IRQn, can0_bus_err_irq } /* BeIrq */
261 },
262 { /* ch1 */
263 { INTRCAN1REC_IRQn, can1_rec_irq }, /* RxIrq */
264 { INTRCAN1TRX_IRQn, can1_trx_irq }, /* TxIrq */
265 { INTRCAN1ERR_IRQn, can1_err_warning_irq }, /* EwIrq */
266 { INTRCAN1ERR_IRQn, can1_overrun_irq }, /* DoIrq */
267 { INTRCAN1ERR_IRQn, NULL }, /* WuIrq(not supported) */
268 { INTRCAN1ERR_IRQn, can1_passive_irq }, /* EpIrq */
269 { INTRCAN1ERR_IRQn, can1_arb_lost_irq }, /* AlIrq */
270 { INTRCAN1ERR_IRQn, can1_bus_err_irq } /* BeIrq */
271 },
272 { /* ch2 */
273 { INTRCAN2REC_IRQn, can2_rec_irq }, /* RxIrq */
274 { INTRCAN2TRX_IRQn, can2_trx_irq }, /* TxIrq */
275 { INTRCAN2ERR_IRQn, can2_err_warning_irq }, /* EwIrq */
276 { INTRCAN2ERR_IRQn, can2_overrun_irq }, /* DoIrq */
277 { INTRCAN2ERR_IRQn, NULL }, /* WuIrq(not supported) */
278 { INTRCAN2ERR_IRQn, can2_passive_irq }, /* EpIrq */
279 { INTRCAN2ERR_IRQn, can2_arb_lost_irq }, /* AlIrq */
280 { INTRCAN2ERR_IRQn, can2_bus_err_irq } /* BeIrq */
281 },
282 { /* ch3 */
283 { INTRCAN3REC_IRQn, can3_rec_irq }, /* RxIrq */
284 { INTRCAN3TRX_IRQn, can3_trx_irq }, /* TxIrq */
285 { INTRCAN3ERR_IRQn, can3_err_warning_irq }, /* EwIrq */
286 { INTRCAN3ERR_IRQn, can3_overrun_irq }, /* DoIrq */
287 { INTRCAN3ERR_IRQn, NULL }, /* WuIrq(not supported) */
288 { INTRCAN3ERR_IRQn, can3_passive_irq }, /* EpIrq */
289 { INTRCAN3ERR_IRQn, can3_arb_lost_irq }, /* AlIrq */
290 { INTRCAN3ERR_IRQn, can3_bus_err_irq } /* BeIrq */
291 },
292 { /* ch4 */
293 { INTRCAN4REC_IRQn, can4_rec_irq }, /* RxIrq */
294 { INTRCAN4TRX_IRQn, can4_trx_irq }, /* TxIrq */
295 { INTRCAN4ERR_IRQn, can4_err_warning_irq }, /* EwIrq */
296 { INTRCAN4ERR_IRQn, can4_overrun_irq }, /* DoIrq */
297 { INTRCAN4ERR_IRQn, NULL }, /* WuIrq(not supported) */
298 { INTRCAN4ERR_IRQn, can4_passive_irq }, /* EpIrq */
299 { INTRCAN4ERR_IRQn, can4_arb_lost_irq }, /* AlIrq */
300 { INTRCAN4ERR_IRQn, can4_bus_err_irq } /* BeIrq */
301 }
302};
303
304static __IO uint32_t *dmy_gaflid = &RSCAN0GAFLID0;
305static __IO uint32_t *dmy_gaflm = &RSCAN0GAFLM0;
306static __IO uint32_t *dmy_gaflp0 = &RSCAN0GAFLP00;
307static __IO uint32_t *dmy_gaflp1 = &RSCAN0GAFLP10;
308
309void can_irq_init(can_t *obj, can_irq_handler handler, uint32_t id) {
310 irq_handler = handler;
311 can_irq_id[obj->ch] = id;
312}
313
314void can_irq_free(can_t *obj) {
315 can_irq_id[obj->ch] = 0;
316}
317
318void can_irq_set(can_t *obj, CanIrqType type, uint32_t enable) {
319 __IO uint32_t *dmy_ctr;
320
321 /* Wake-up Irq is not supported */
322 if (type != IRQ_WAKEUP) {
323 if (enable) {
324 dmy_ctr = CTR_MATCH[obj->ch];
325 if (type == IRQ_ERROR) {
326 /* EWIE interrupts is enable */
327 *dmy_ctr |= 0x00000200;
328 } else if (type == IRQ_OVERRUN) {
329 /* OLIE interrupts is enable */
330 *dmy_ctr |= 0x00002000;
331 } else if (type == IRQ_PASSIVE) {
332 /* EPIE interrupts is enable */
333 *dmy_ctr |= 0x00000400;
334 } else if (type == IRQ_ARB) {
335 /* ALIE interrupts is enable */
336 *dmy_ctr |= 0x00008000;
337 } else if (type == IRQ_BUS) {
338 /* BEIE interrupts is enable */
339 *dmy_ctr |= 0x00000100;
340 }
341 InterruptHandlerRegister(can_int_info[obj->ch][type].int_num, can_int_info[obj->ch][type].handler);
342 GIC_SetPriority(can_int_info[obj->ch][type].int_num, 5);
343 GIC_EnableIRQ(can_int_info[obj->ch][type].int_num);
344 } else {
345 GIC_DisableIRQ(can_int_info[obj->ch][type].int_num);
346 }
347 }
348}
349
350static void can_rec_irq(uint32_t ch) {
351 __IO uint32_t *dmy_cfsts;
352
353 dmy_cfsts = CFSTS_TBL[ch][CAN_RECV];
354 *dmy_cfsts &= 0xFFFFFFF7; // Clear CFRXIF
355
356 irq_handler(can_irq_id[ch], IRQ_RX);
357}
358
359static void can_trx_irq(uint32_t ch) {
360 __IO uint32_t *dmy_cfsts;
361
362 dmy_cfsts = CFSTS_TBL[ch][CAN_SEND];
363 *dmy_cfsts &= 0xFFFFFFEF; // Clear CFTXIF
364
365 irq_handler(can_irq_id[ch], IRQ_TX);
366}
367
368static void can_err_irq(uint32_t ch, CanIrqType type) {
369 __IO uint32_t *dmy_erfl;
370 int val = 1;
371
372 dmy_erfl = ERFL_MATCH[ch];
373 switch (type) {
374 case IRQ_ERROR:
375 *dmy_erfl &= 0xFFFFFFFD; // Clear EWF
376 break;
377 case IRQ_OVERRUN:
378 *dmy_erfl &= 0xFFFFFFDF; // Clear OVLF
379 break;
380 case IRQ_PASSIVE:
381 *dmy_erfl &= 0xFFFFFFFB; // Clear EPF
382 break;
383 case IRQ_ARB:
384 *dmy_erfl &= 0xFFFFFF7F; // Clear ALF
385 break;
386 case IRQ_BUS:
387 *dmy_erfl &= 0xFFFF00FF; // Clear ADERR, B0ERR, B1ERR, CERR, AERR, FERR, SERR
388 *dmy_erfl &= 0xFFFFFFFE; // Clear BEF
389 break;
390 case IRQ_WAKEUP:
391 /* not supported */
392 /* fall through */
393 default:
394 val = 0;
395 break;
396 }
397 if (val == 1) {
398 irq_handler(can_irq_id[ch], type);
399 }
400}
401
402static void can0_rec_irq(void) {
403 can_rec_irq(CAN_0);
404}
405
406static void can1_rec_irq(void) {
407 can_rec_irq(CAN_1);
408}
409
410static void can2_rec_irq(void) {
411 can_rec_irq(CAN_2);
412}
413
414static void can3_rec_irq(void) {
415 can_rec_irq(CAN_3);
416}
417
418static void can4_rec_irq(void) {
419 can_rec_irq(CAN_4);
420}
421
422static void can0_trx_irq(void) {
423 can_trx_irq(CAN_0);
424}
425
426static void can1_trx_irq(void) {
427 can_trx_irq(CAN_1);
428}
429
430static void can2_trx_irq(void) {
431 can_trx_irq(CAN_2);
432}
433
434static void can3_trx_irq(void) {
435 can_trx_irq(CAN_3);
436}
437
438static void can4_trx_irq(void) {
439 can_trx_irq(CAN_4);
440}
441
442static void can0_err_warning_irq(void) {
443 can_err_irq(CAN_0, IRQ_ERROR);
444}
445
446static void can1_err_warning_irq(void) {
447 can_err_irq(CAN_1, IRQ_ERROR);
448}
449
450static void can2_err_warning_irq(void) {
451 can_err_irq(CAN_2, IRQ_ERROR);
452}
453
454static void can3_err_warning_irq(void) {
455 can_err_irq(CAN_3, IRQ_ERROR);
456}
457
458static void can4_err_warning_irq(void) {
459 can_err_irq(CAN_4, IRQ_ERROR);
460}
461
462static void can0_overrun_irq(void) {
463 can_err_irq(CAN_0, IRQ_OVERRUN);
464}
465
466static void can1_overrun_irq(void) {
467 can_err_irq(CAN_1, IRQ_OVERRUN);
468}
469
470static void can2_overrun_irq(void) {
471 can_err_irq(CAN_2, IRQ_OVERRUN);
472}
473
474static void can3_overrun_irq(void) {
475 can_err_irq(CAN_3, IRQ_OVERRUN);
476}
477
478static void can4_overrun_irq(void) {
479 can_err_irq(CAN_4, IRQ_OVERRUN);
480}
481
482static void can0_passive_irq(void) {
483 can_err_irq(CAN_0, IRQ_PASSIVE);
484}
485
486static void can1_passive_irq(void) {
487 can_err_irq(CAN_1, IRQ_PASSIVE);
488}
489
490static void can2_passive_irq(void) {
491 can_err_irq(CAN_2, IRQ_PASSIVE);
492}
493
494static void can3_passive_irq(void) {
495 can_err_irq(CAN_3, IRQ_PASSIVE);
496}
497
498static void can4_passive_irq(void) {
499 can_err_irq(CAN_4, IRQ_PASSIVE);
500}
501
502static void can0_arb_lost_irq(void) {
503 can_err_irq(CAN_0, IRQ_ARB);
504}
505
506static void can1_arb_lost_irq(void) {
507 can_err_irq(CAN_1, IRQ_ARB);
508}
509
510static void can2_arb_lost_irq(void) {
511 can_err_irq(CAN_2, IRQ_ARB);
512}
513
514static void can3_arb_lost_irq(void) {
515 can_err_irq(CAN_3, IRQ_ARB);
516}
517
518static void can4_arb_lost_irq(void) {
519 can_err_irq(CAN_4, IRQ_ARB);
520}
521
522static void can0_bus_err_irq(void) {
523 can_err_irq(CAN_0, IRQ_BUS);
524}
525
526static void can1_bus_err_irq(void) {
527 can_err_irq(CAN_1, IRQ_BUS);
528}
529
530static void can2_bus_err_irq(void) {
531 can_err_irq(CAN_2, IRQ_BUS);
532}
533
534static void can3_bus_err_irq(void) {
535 can_err_irq(CAN_3, IRQ_BUS);
536}
537
538static void can4_bus_err_irq(void) {
539 can_err_irq(CAN_4, IRQ_BUS);
540}
541
542void can_init(can_t *obj, PinName rd, PinName td) {
543 __IO uint32_t *dmy_ctr;
544
545 /* determine the CAN to use */
546 uint32_t can_rx = pinmap_peripheral(rd, PinMap_CAN_RD);
547 uint32_t can_tx = pinmap_peripheral(td, PinMap_CAN_TD);
548 obj->ch = pinmap_merge(can_tx, can_rx);
549 MBED_ASSERT((int)obj->ch != NC);
550
551 /* enable CAN clock */
552 CPGSTBCR3 &= ~(CPG_STBCR3_BIT_MSTP32);
553 /* Has CAN RAM initialisation completed ? */
554 while ((RSCAN0GSTS & 0x08) == 0x08) {
555 __NOP();
556 }
557 /* clear Global Stop mode bit */
558 RSCAN0GCTR &= 0xFFFFFFFB;
559 /* clear Channel Stop mode bit */
560 dmy_ctr = CTR_MATCH[obj->ch];
561 *dmy_ctr &= 0xFFFFFFFB;
562 /* Enter global reset mode */
563 can_set_global_mode(GL_RESET);
564 /* Enter channel reset mode */
565 can_set_channel_mode(obj->ch, CH_RESET);
566 /* reset register */
567 can_reset_reg(obj);
568
569 can_initialized[obj->ch] = 1;
570 /* reconfigure channel which is already initialized */
571 can_reconfigure_channel();
572
573 /* pin out the can pins */
574 pinmap_pinout(rd, PinMap_CAN_RD);
575 pinmap_pinout(td, PinMap_CAN_TD);
576}
577
578void can_free(can_t *obj) {
579 /* disable CAN clock */
580 CPGSTBCR3 |= CPG_STBCR3_BIT_MSTP32;
581}
582
583int can_frequency(can_t *obj, int f) {
584 __IO uint32_t *dmy_cfcc;
585 int retval = 0;
586
587 if (f <= 1000000) {
588 /* less than 1Mhz */
589 /* set Channel Reset mode */
590 can_set_channel_mode(obj->ch, CH_RESET);
591 can_set_frequency(obj, f);
592 /* set Channel Communication mode */
593 can_set_channel_mode(obj->ch, CH_COMM);
594 /* restore CFE bit since it is cleared */
595 /* Use send/receive FIFO buffer */
596 dmy_cfcc = CFCC_TBL[obj->ch][CAN_SEND];
597 *dmy_cfcc |= 0x01;
598 dmy_cfcc = CFCC_TBL[obj->ch][CAN_RECV];
599 *dmy_cfcc |= 0x01;
600 retval = 1;
601 }
602
603 return retval;
604}
605
606void can_reset(can_t *obj) {
607 /* Enter global reset mode */
608 can_set_global_mode(GL_RESET);
609 /* Enter channel reset mode */
610 can_set_channel_mode(obj->ch, CH_RESET);
611 /* reset register */
612 can_reset_reg(obj);
613 /* reconfigure channel which is already initialized */
614 can_reconfigure_channel();
615}
616
617int can_write(can_t *obj, CAN_Message msg, int cc) {
618 __IO uint32_t *dmy_sts;
619 __IO uint32_t *dmy_cfsts;
620 __IO uint32_t *dmy_cfid;
621 __IO uint32_t *dmy_cfptr;
622 __IO uint32_t *dmy_cfdf0;
623 __IO uint32_t *dmy_cfdf1;
624 __IO uint32_t *dmy_cfpctr;
625 int retval = 0;
626
627 /* Wait to become channel communication mode */
628 dmy_sts = STS_MATCH[obj->ch];
629 while ((*dmy_sts & 0x07) != 0) {
630 __NOP();
631 }
632
633 if (((msg.format == CANStandard) && (msg.id <= 0x07FF)) || ((msg.format == CANExtended) && (msg.id <= 0x03FFFF))) {
634 /* send/receive FIFO buffer isn't full */
635 dmy_cfsts = CFSTS_TBL[obj->ch][CAN_SEND];
636 if ((*dmy_cfsts & 0x02) != 0x02) {
637 /* set format, frame type and send/receive FIFO buffer ID(b10-0 or b28-11) */
638 dmy_cfid = CFID_TBL[obj->ch][CAN_SEND];
639 *dmy_cfid = ((msg.format << 31) | (msg.type << 30));
640 if (msg.format == CANStandard) {
641 *dmy_cfid |= (msg.id & 0x07FF);
642 } else {
643 *dmy_cfid |= ((msg.id & 0x03FFFF) << 11);
644 }
645 /* set length */
646 dmy_cfptr = CFPTR_TBL[obj->ch][CAN_SEND];
647 *dmy_cfptr = msg.len << 28;
648 /* set data */
649 dmy_cfdf0 = CFDF0_TBL[obj->ch][CAN_SEND];
650 memcpy((void *)dmy_cfdf0, &msg.data[0], 4);
651 dmy_cfdf1 = CFDF1_TBL[obj->ch][CAN_SEND];
652 memcpy((void *)dmy_cfdf1, &msg.data[4], 4);
653 /* send request */
654 dmy_cfpctr = CFPCTR_TBL[obj->ch][CAN_SEND];
655 *dmy_cfpctr = 0xFF;
656 retval = 1;
657 }
658 }
659
660 return retval;
661}
662
663int can_read(can_t *obj, CAN_Message *msg, int handle) {
664 __IO uint32_t *dmy_sts;
665 __IO uint32_t *dmy_cfsts;
666 __IO uint32_t *dmy_cfid;
667 __IO uint32_t *dmy_cfptr;
668 __IO uint32_t *dmy_cfdf0;
669 __IO uint32_t *dmy_cfdf1;
670 __IO uint32_t *dmy_cfpctr;
671 int retval = 0;
672
673 /* Wait to become channel communication mode */
674 dmy_sts = STS_MATCH[obj->ch];
675 while ((*dmy_sts & 0x07) != 0) {
676 __NOP();
677 }
678
679 /* send/receive FIFO buffer isn't empty */
680 dmy_cfsts = CFSTS_TBL[obj->ch][CAN_RECV];
681 while ((*dmy_cfsts & 0x01) != 0x01) {
682 /* get format, frame type and send/receive FIFO buffer ID(b10-0 or b28-11) */
683 dmy_cfid = CFID_TBL[obj->ch][CAN_RECV];
684 msg->format = (CANFormat)(*dmy_cfid >> 31);
685 msg->type = (CANType)(*dmy_cfid >> 30);
686 if (msg->format == CANStandard) {
687 msg->id = (*dmy_cfid & 0x07FF);
688 } else {
689 msg->id = ((*dmy_cfid >> 11) & 0x03FFFF);
690 }
691 /* get length */
692 dmy_cfptr = CFPTR_TBL[obj->ch][CAN_RECV];
693 msg->len = (unsigned char)(*dmy_cfptr >> 28);
694 /* get data */
695 dmy_cfdf0 = CFDF0_TBL[obj->ch][CAN_RECV];
696 memcpy(&msg->data[0], (void *)dmy_cfdf0, 4);
697 dmy_cfdf1 = CFDF1_TBL[obj->ch][CAN_RECV];
698 memcpy(&msg->data[4], (void *)dmy_cfdf1, 4);
699 /* receive(next data) request */
700 dmy_cfpctr = CFPCTR_TBL[obj->ch][CAN_RECV];
701 *dmy_cfpctr = 0xFF;
702 retval = 1;
703 }
704
705 return retval;
706}
707
708unsigned char can_rderror(can_t *obj) {
709 __IO uint32_t *dmy_sts;
710
711 dmy_sts = STS_MATCH[obj->ch];
712 return (unsigned char)((*dmy_sts >> 16) & 0xFF);
713}
714
715unsigned char can_tderror(can_t *obj) {
716 __IO uint32_t *dmy_sts;
717
718 dmy_sts = STS_MATCH[obj->ch];
719 return (unsigned char)((*dmy_sts >> 24) & 0xFF);
720}
721
722int can_mode(can_t *obj, CanMode mode) {
723 __IO uint32_t *dmy_ctr;
724 __IO uint32_t *dmy_sts;
725 __IO uint32_t *dmy_cfcc;
726 int ch_cnt;
727 can_t *tmp_obj;
728 tmp_obj = obj;
729 int retval = 1;
730
731 switch (mode) {
732 case MODE_RESET:
733 can_set_global_mode(GL_RESET);
734 can_set_channel_mode(obj->ch, CH_RESET);
735 for (ch_cnt = 0; ch_cnt < CAN_NUM; ch_cnt++) {
736 can_initialized[ch_cnt] = 0;
737 }
738 break;
739 case MODE_NORMAL:
740 can_set_global_mode(GL_OPE);
741 can_set_channel_mode(obj->ch, CH_COMM);
742 break;
743 case MODE_SILENT:
744 can_set_channel_mode(obj->ch, CH_HOLD);
745 /* set listen only mode, enable communication test mode */
746 dmy_ctr = CTR_MATCH[obj->ch];
747 *dmy_ctr = ((*dmy_ctr & 0x00FFFFFF) | 0x03000000);
748 can_set_channel_mode(obj->ch, CH_COMM);
749 break;
750 case MODE_TEST_LOCAL:
751 can_set_channel_mode(obj->ch, CH_HOLD);
752 /* set self test mode 0, enable communication test mode */
753 dmy_ctr = CTR_MATCH[obj->ch];
754 *dmy_ctr = ((*dmy_ctr & 0x00FFFFFF) | 0x05000000);
755 can_set_channel_mode(obj->ch, CH_COMM);
756 break;
757 case MODE_TEST_GLOBAL:
758 /* set the channel between the communication test on channel 1 and channel 2 */
759 /* set Channel Hold mode */
760 for (tmp_obj->ch = CAN_1; tmp_obj->ch <= CAN_2; tmp_obj->ch++) {
761 dmy_sts = STS_MATCH[tmp_obj->ch];
762 if ((*dmy_sts & 0x04) == 0x04) {
763 /* Channel Stop mode */
764 /* clear Channel Stop mode bit */
765 dmy_ctr = CTR_MATCH[tmp_obj->ch];
766 *dmy_ctr &= 0xFFFFFFFB;
767 can_set_channel_mode(tmp_obj->ch, CH_RESET);
768 }
769 can_set_channel_mode(tmp_obj->ch, CH_HOLD);
770 }
771 can_set_global_mode(GL_TEST);
772 /* enable communication test between channel1 and channel2 */
773 RSCAN0GTSTCFG = 0x06;
774 RSCAN0GTSTCTR = 0x01;
775 /* send and receive setting of channel1 and channel2 */
776 for (tmp_obj->ch = CAN_1; tmp_obj->ch <= CAN_2; tmp_obj->ch++) {
777 can_reset_buffer(tmp_obj);
778 /* set global interrrupt */
779 /* THLEIE, MEIE and DEIE interrupts are disable */
780 RSCAN0GCTR &= 0xFFFFF8FF;
781 /* BLIE, OLIE, BORIE and BOEIE interrupts are disable */
782 /* TAIE, ALIE, EPIE, EWIE and BEIE interrupts are enable */
783 dmy_ctr = CTR_MATCH[tmp_obj->ch];
784 *dmy_ctr &= 0x00018700;
785 can_set_global_mode(GL_OPE);
786 can_set_channel_mode(tmp_obj->ch, CH_COMM);
787 /* Use send/receive FIFO buffer */
788 dmy_cfcc = CFCC_TBL[tmp_obj->ch][CAN_SEND];
789 *dmy_cfcc |= 0x01;
790 dmy_cfcc = CFCC_TBL[tmp_obj->ch][CAN_RECV];
791 *dmy_cfcc |= 0x01;
792 }
793 break;
794 case MODE_TEST_SILENT:
795 /* not supported */
796 /* fall through */
797 default:
798 retval = 0;
799 break;
800 }
801
802 return retval;
803}
804
805int can_filter(can_t *obj, uint32_t id, uint32_t mask, CANFormat format, int32_t handle) {
806 int retval = 0;
807
808 if ((format == CANStandard) || (format == CANExtended)) {
809 if (((format == CANStandard) && (id <= 0x07FF)) || ((format == CANExtended) && (id <= 0x03FFFF))) {
810 /* set Global Reset mode and Channel Reset mode */
811 can_set_global_mode(GL_RESET);
812 can_set_channel_mode(obj->ch, CH_RESET);
813 /* enable receive rule table writing */
814 RSCAN0GAFLECTR = 0x00000100;
815 /* set the page number of receive rule table(page number = 0) */
816 RSCAN0GAFLECTR |= (obj->ch * 4);
817 /* set IDE format */
818 *dmy_gaflid = (format << 31);
819 if (format == CANExtended) {
820 /* set receive rule ID for bit28-11 */
821 *dmy_gaflid |= (id << 11);
822 } else {
823 /* set receive rule ID for bit10-0 */
824 *dmy_gaflid |= id;
825 }
826 /* set ID mask bit */
827 *dmy_gaflm = (0xC0000000 | mask);
828 /* disable receive rule table writing */
829 RSCAN0GAFLECTR &= 0xFFFFFEFF;
830 /* reconfigure channel which is already initialized */
831 can_reconfigure_channel();
832 retval = 1;
833 }
834 }
835
836 return retval;
837}
838
839void can_monitor(can_t *obj, int silent) {
840 __IO uint32_t *dmy_ctr;
841
842 /* set Channel Hold mode */
843 can_set_channel_mode(obj->ch, CH_HOLD);
844 if (silent) {
845 /* set listen only mode, enable communication test mode */
846 dmy_ctr = CTR_MATCH[obj->ch];
847 *dmy_ctr = ((*dmy_ctr & 0x00FFFFFF) | 0x03000000);
848 can_set_channel_mode(obj->ch, CH_COMM);
849 } else {
850 /* set normal test mode, disable communication test mode */
851 dmy_ctr = CTR_MATCH[obj->ch];
852 *dmy_ctr &= 0x00FFFFFF;
853 /* reset register */
854 can_reset_reg(obj);
855 /* reconfigure channel which is already initialized */
856 can_reconfigure_channel();
857 }
858}
859
860static void can_reset_reg(can_t *obj) {
861 __IO uint32_t *dmy_ctr;
862
863 /* time stamp source uses peripheral clock (pclk(P1_phi)/2), CAN clock uses clkc(P1_phi/2), */
864 /* mirror off, DLC not transfer, DLC check permit, transmit buffer priority, clock source not divided */
865 RSCAN0GCFG = 0x00000003;
866 /* set default frequency at 100k */
867 can_set_frequency(obj, 100000);
868 /* set receive rule */
869 can_reset_recv_rule(obj);
870 /* set buffer */
871 can_reset_buffer(obj);
872 /* set global interrrupt */
873 /* THLEIE, MEIE and DEIE interrupts are disable */
874 RSCAN0GCTR &= 0xFFFFF8FF;
875 /* ALIE, BLIE, OLIE, BORIE, BOEIE, EPIE, EWIE and BEIE interrupts are disable */
876 dmy_ctr = CTR_MATCH[obj->ch];
877 *dmy_ctr &= 0xFFFF00FF;
878}
879
880static void can_reset_recv_rule(can_t *obj) {
881 /* number of receive rules of each chanel = 64 */
882 RSCAN0GAFLCFG0 = 0x40404040;
883 RSCAN0GAFLCFG1 = 0x40000000;
884 /* enable receive rule table writing */
885 RSCAN0GAFLECTR = 0x00000100;
886 /* set the page number of receive rule table(ex: id ch = 1, page number = 4) */
887 RSCAN0GAFLECTR |= (obj->ch * 4);
888 /* set standard ID, data frame and receive rule ID */
889 *dmy_gaflid = 0x07FF;
890 /* IDE bit, RTR bit and ID bit(28-0) are not compared */
891 *dmy_gaflm = 0;
892 /* DLC check is 1 bytes, not use a receive buffer */
893 *dmy_gaflp0 = 0x10000000;
894 /* use a send/receive FIFO buffer(ex: if ch = 1, FIFO buffer number = 4 and bit = 12) */
895 *dmy_gaflp1 = (1 << ((obj->ch + 3) * 3));
896 /* disable receive rule table writing */
897 RSCAN0GAFLECTR &= 0xFFFFFEFF;
898}
899
900static void can_reset_buffer(can_t *obj) {
901 __IO uint32_t *dmy_rfcc;
902 __IO uint32_t *dmy_cfcc;
903 __IO uint32_t *dmy_txqcc;
904 __IO uint32_t *dmy_thlcc;
905 int cnt;
906
907 /* set linked send buffer number(ex: if ch = 1 and mode = send, buffer number = 16), interval timer is pclk/2 */
908 /* number of rows of send/receive FIFO buffer = 4 */
909 dmy_cfcc = CFCC_TBL[obj->ch][CAN_SEND];
910 *dmy_cfcc = 0x00011100; /* send/receive FIFO mode is send */
911 dmy_cfcc = CFCC_TBL[obj->ch][CAN_RECV];
912 *dmy_cfcc = 0x00001100; /* send/receive FIFO mode is receive */
913 /* receive buffer is not used */
914 RSCAN0RMNB = 0;
915 /* receive FIFO buffer is not used */
916 for (cnt = 0; cnt < 8; cnt++) {
917 dmy_rfcc = RFCC_MATCH[cnt];
918 *dmy_rfcc = 0;
919 }
920 /* send queue is not used */
921 dmy_txqcc = TXQCC_MATCH[obj->ch];
922 *dmy_txqcc = 0;
923 /* send history is not used */
924 dmy_thlcc = THLCC_MATCH[obj->ch];
925 *dmy_thlcc = 0;
926
927 /* CFTXIE and CFRXIE interrupts are enable */
928 dmy_cfcc = CFCC_TBL[obj->ch][CAN_SEND];
929 *dmy_cfcc |= 0x04;
930 dmy_cfcc = CFCC_TBL[obj->ch][CAN_RECV];
931 *dmy_cfcc |= 0x02;
932 /* TMIEp interrupt is disable */
933 RSCAN0TMIEC0 = 0x00000000;
934 RSCAN0TMIEC1 = 0x00000000;
935 RSCAN0TMIEC2 = 0x00000000;
936}
937
938static void can_reconfigure_channel(void) {
939 __IO uint32_t *dmy_cfcc;
940 int ch_cnt;
941
942 for (ch_cnt = 0; ch_cnt < CAN_NUM; ch_cnt++) {
943 if (can_initialized[ch_cnt] == 1) {
944 /* set Global Operation mode and Channel Communication mode */
945 can_set_global_mode(GL_OPE);
946 can_set_channel_mode(ch_cnt, CH_COMM);
947 /* Use send/receive FIFO buffer */
948 dmy_cfcc = CFCC_TBL[ch_cnt][CAN_SEND];
949 *dmy_cfcc |= 0x01;
950 dmy_cfcc = CFCC_TBL[ch_cnt][CAN_RECV];
951 *dmy_cfcc |= 0x01;
952 }
953 }
954}
955
956static void can_set_frequency(can_t *obj, int f) {
957 __IO uint32_t *dmy_cfg;
958 int oldfreq = 0;
959 int newfreq = 0;
960 uint32_t clkc_val;
961 uint8_t tmp_tq;
962 uint8_t tq = 0;
963 uint8_t tmp_brp;
964 uint8_t brp = 0;
965 uint8_t tseg1 = 0;
966 uint8_t tseg2 = 0;
967
968 /* set clkc */
969 if (RZ_A1_IsClockMode0() == false) {
970 clkc_val = CM1_RENESAS_RZ_A1_P1_CLK / 2;
971 } else {
972 clkc_val = CM0_RENESAS_RZ_A1_P1_CLK / 2;
973 }
974 /* calculate BRP bit and Choose max value of calculated frequency */
975 for (tmp_tq = 8; tmp_tq <= 25; tmp_tq++) {
976 /* f = fCAN / ((BRP+1) * Tq) */
977 /* BRP = (fCAN / (f * Tq)) - 1 */
978 tmp_brp = ((clkc_val / (f * tmp_tq)) - 1) + 1; // carry(decimal point is carry)
979 newfreq = clkc_val / ((tmp_brp + 1) * tmp_tq);
980 if (newfreq >= oldfreq) {
981 oldfreq = newfreq;
982 tq = tmp_tq;
983 brp = tmp_brp;
984 }
985 }
986 /* calculate TSEG1 bit and TSEG2 bit */
987 tseg1 = (tq - 1) * 0.666666667;
988 tseg2 = (tq - 1) - tseg1;
989 /* set RSCAN0CmCFG register */
990 dmy_cfg = CFG_MATCH[obj->ch];
991 *dmy_cfg = ((tseg2 - 1) << 20) | ((tseg1 - 1) << 16) | brp;
992}
993
994static void can_set_global_mode(int mode) {
995 /* set Global mode */
996 RSCAN0GCTR = ((RSCAN0GCTR & 0xFFFFFFFC) | mode);
997 /* Wait to cahnge into Global XXXX mode */
998 while ((RSCAN0GSTS & 0x07) != mode) {
999 __NOP();
1000 }
1001}
1002
1003static void can_set_channel_mode(uint32_t ch, int mode) {
1004 __IO uint32_t *dmy_ctr;
1005 __IO uint32_t *dmy_sts;
1006
1007 /* set Channel mode */
1008 dmy_ctr = CTR_MATCH[ch];
1009 *dmy_ctr = ((*dmy_ctr & 0xFFFFFFFC) | mode);
1010 /* Wait to cahnge into Channel XXXX mode */
1011 dmy_sts = STS_MATCH[ch];
1012 while ((*dmy_sts & 0x07) != mode) {
1013 __NOP();
1014 }
1015}
1016
Note: See TracBrowser for help on using the repository browser.