source: EcnlProtoTool/trunk/asp3_dcre/mbed/targets/hal/TARGET_RENESAS/TARGET_RZ_A1H/can_api.c@ 270

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

mruby版ECNLプロトタイピング・ツールを追加

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-csrc
File size: 30.2 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 int retval = 0;
585
586 if (f <= 1000000) {
587 /* less than 1Mhz */
588 /* set Channel Reset mode */
589 can_set_channel_mode(obj->ch, CH_RESET);
590 can_set_frequency(obj, f);
591 /* set Channel Communication mode */
592 can_set_channel_mode(obj->ch, CH_COMM);
593 retval = 1;
594 }
595
596 return retval;
597}
598
599void can_reset(can_t *obj) {
600 /* Enter global reset mode */
601 can_set_global_mode(GL_RESET);
602 /* Enter channel reset mode */
603 can_set_channel_mode(obj->ch, CH_RESET);
604 /* reset register */
605 can_reset_reg(obj);
606 /* reconfigure channel which is already initialized */
607 can_reconfigure_channel();
608}
609
610int can_write(can_t *obj, CAN_Message msg, int cc) {
611 __IO uint32_t *dmy_sts;
612 __IO uint32_t *dmy_cfsts;
613 __IO uint32_t *dmy_cfid;
614 __IO uint32_t *dmy_cfptr;
615 __IO uint32_t *dmy_cfdf0;
616 __IO uint32_t *dmy_cfdf1;
617 __IO uint32_t *dmy_cfpctr;
618 int retval = 0;
619
620 /* Wait to become channel communication mode */
621 dmy_sts = STS_MATCH[obj->ch];
622 while ((*dmy_sts & 0x07) != 0) {
623 __NOP();
624 }
625
626 if (((msg.format == CANStandard) && (msg.id <= 0x07FF)) || ((msg.format == CANExtended) && (msg.id <= 0x03FFFF))) {
627 /* send/receive FIFO buffer isn't full */
628 dmy_cfsts = CFSTS_TBL[obj->ch][CAN_SEND];
629 if ((*dmy_cfsts & 0x02) != 0x02) {
630 /* set format, frame type and send/receive FIFO buffer ID(b10-0 or b28-11) */
631 dmy_cfid = CFID_TBL[obj->ch][CAN_SEND];
632 *dmy_cfid = ((msg.format << 31) | (msg.type << 30));
633 if (msg.format == CANStandard) {
634 *dmy_cfid |= (msg.id & 0x07FF);
635 } else {
636 *dmy_cfid |= ((msg.id & 0x03FFFF) << 11);
637 }
638 /* set length */
639 dmy_cfptr = CFPTR_TBL[obj->ch][CAN_SEND];
640 *dmy_cfptr = msg.len << 28;
641 /* set data */
642 dmy_cfdf0 = CFDF0_TBL[obj->ch][CAN_SEND];
643 memcpy((void *)dmy_cfdf0, &msg.data[0], 4);
644 dmy_cfdf1 = CFDF1_TBL[obj->ch][CAN_SEND];
645 memcpy((void *)dmy_cfdf1, &msg.data[4], 4);
646 /* send request */
647 dmy_cfpctr = CFPCTR_TBL[obj->ch][CAN_SEND];
648 *dmy_cfpctr = 0xFF;
649 retval = 1;
650 }
651 }
652
653 return retval;
654}
655
656int can_read(can_t *obj, CAN_Message *msg, int handle) {
657 __IO uint32_t *dmy_sts;
658 __IO uint32_t *dmy_cfsts;
659 __IO uint32_t *dmy_cfid;
660 __IO uint32_t *dmy_cfptr;
661 __IO uint32_t *dmy_cfdf0;
662 __IO uint32_t *dmy_cfdf1;
663 __IO uint32_t *dmy_cfpctr;
664 int retval = 0;
665
666 /* Wait to become channel communication mode */
667 dmy_sts = STS_MATCH[obj->ch];
668 while ((*dmy_sts & 0x07) != 0) {
669 __NOP();
670 }
671
672 /* send/receive FIFO buffer isn't empty */
673 dmy_cfsts = CFSTS_TBL[obj->ch][CAN_RECV];
674 while ((*dmy_cfsts & 0x01) != 0x01) {
675 /* get format, frame type and send/receive FIFO buffer ID(b10-0 or b28-11) */
676 dmy_cfid = CFID_TBL[obj->ch][CAN_RECV];
677 msg->format = (CANFormat)(*dmy_cfid >> 31);
678 msg->type = (CANType)(*dmy_cfid >> 30);
679 if (msg->format == CANStandard) {
680 msg->id = (*dmy_cfid & 0x07FF);
681 } else {
682 msg->id = ((*dmy_cfid >> 11) & 0x03FFFF);
683 }
684 /* get length */
685 dmy_cfptr = CFPTR_TBL[obj->ch][CAN_RECV];
686 msg->len = (unsigned char)(*dmy_cfptr >> 28);
687 /* get data */
688 dmy_cfdf0 = CFDF0_TBL[obj->ch][CAN_RECV];
689 memcpy(&msg->data[0], (void *)dmy_cfdf0, 4);
690 dmy_cfdf1 = CFDF1_TBL[obj->ch][CAN_RECV];
691 memcpy(&msg->data[4], (void *)dmy_cfdf1, 4);
692 /* receive(next data) request */
693 dmy_cfpctr = CFPCTR_TBL[obj->ch][CAN_RECV];
694 *dmy_cfpctr = 0xFF;
695 retval = 1;
696 }
697
698 return retval;
699}
700
701unsigned char can_rderror(can_t *obj) {
702 __IO uint32_t *dmy_sts;
703
704 dmy_sts = STS_MATCH[obj->ch];
705 return (unsigned char)((*dmy_sts >> 16) & 0xFF);
706}
707
708unsigned char can_tderror(can_t *obj) {
709 __IO uint32_t *dmy_sts;
710
711 dmy_sts = STS_MATCH[obj->ch];
712 return (unsigned char)((*dmy_sts >> 24) & 0xFF);
713}
714
715int can_mode(can_t *obj, CanMode mode) {
716 __IO uint32_t *dmy_ctr;
717 __IO uint32_t *dmy_sts;
718 __IO uint32_t *dmy_cfcc;
719 int ch_cnt;
720 can_t *tmp_obj;
721 tmp_obj = obj;
722 int retval = 1;
723
724 switch (mode) {
725 case MODE_RESET:
726 can_set_global_mode(GL_RESET);
727 can_set_channel_mode(obj->ch, CH_RESET);
728 for (ch_cnt = 0; ch_cnt < CAN_NUM; ch_cnt++) {
729 can_initialized[ch_cnt] = 0;
730 }
731 break;
732 case MODE_NORMAL:
733 can_set_global_mode(GL_OPE);
734 can_set_channel_mode(obj->ch, CH_COMM);
735 break;
736 case MODE_SILENT:
737 can_set_channel_mode(obj->ch, CH_HOLD);
738 /* set listen only mode, enable communication test mode */
739 dmy_ctr = CTR_MATCH[obj->ch];
740 *dmy_ctr = ((*dmy_ctr & 0x00FFFFFF) | 0x03000000);
741 can_set_channel_mode(obj->ch, CH_COMM);
742 break;
743 case MODE_TEST_LOCAL:
744 can_set_channel_mode(obj->ch, CH_HOLD);
745 /* set self test mode 0, enable communication test mode */
746 dmy_ctr = CTR_MATCH[obj->ch];
747 *dmy_ctr = ((*dmy_ctr & 0x00FFFFFF) | 0x05000000);
748 can_set_channel_mode(obj->ch, CH_COMM);
749 break;
750 case MODE_TEST_GLOBAL:
751 /* set the channel between the communication test on channel 1 and channel 2 */
752 /* set Channel Hold mode */
753 for (tmp_obj->ch = CAN_1; tmp_obj->ch <= CAN_2; tmp_obj->ch++) {
754 dmy_sts = STS_MATCH[tmp_obj->ch];
755 if ((*dmy_sts & 0x04) == 0x04) {
756 /* Channel Stop mode */
757 /* clear Channel Stop mode bit */
758 dmy_ctr = CTR_MATCH[tmp_obj->ch];
759 *dmy_ctr &= 0xFFFFFFFB;
760 can_set_channel_mode(tmp_obj->ch, CH_RESET);
761 }
762 can_set_channel_mode(tmp_obj->ch, CH_HOLD);
763 }
764 can_set_global_mode(GL_TEST);
765 /* enable communication test between channel1 and channel2 */
766 RSCAN0GTSTCFG = 0x06;
767 RSCAN0GTSTCTR = 0x01;
768 /* send and receive setting of channel1 and channel2 */
769 for (tmp_obj->ch = CAN_1; tmp_obj->ch <= CAN_2; tmp_obj->ch++) {
770 can_reset_buffer(tmp_obj);
771 /* set global interrrupt */
772 /* THLEIE, MEIE and DEIE interrupts are disable */
773 RSCAN0GCTR &= 0xFFFFF8FF;
774 /* BLIE, OLIE, BORIE and BOEIE interrupts are disable */
775 /* TAIE, ALIE, EPIE, EWIE and BEIE interrupts are enable */
776 dmy_ctr = CTR_MATCH[tmp_obj->ch];
777 *dmy_ctr &= 0x00018700;
778 can_set_global_mode(GL_OPE);
779 can_set_channel_mode(tmp_obj->ch, CH_COMM);
780 /* Use send/receive FIFO buffer */
781 dmy_cfcc = CFCC_TBL[tmp_obj->ch][CAN_SEND];
782 *dmy_cfcc |= 0x01;
783 dmy_cfcc = CFCC_TBL[tmp_obj->ch][CAN_RECV];
784 *dmy_cfcc |= 0x01;
785 }
786 break;
787 case MODE_TEST_SILENT:
788 /* not supported */
789 /* fall through */
790 default:
791 retval = 0;
792 break;
793 }
794
795 return retval;
796}
797
798int can_filter(can_t *obj, uint32_t id, uint32_t mask, CANFormat format, int32_t handle) {
799 int retval = 0;
800
801 if ((format == CANStandard) || (format == CANExtended)) {
802 if (((format == CANStandard) && (id <= 0x07FF)) || ((format == CANExtended) && (id <= 0x03FFFF))) {
803 /* set Global Reset mode and Channel Reset mode */
804 can_set_global_mode(GL_RESET);
805 can_set_channel_mode(obj->ch, CH_RESET);
806 /* enable receive rule table writing */
807 RSCAN0GAFLECTR = 0x00000100;
808 /* set the page number of receive rule table(page number = 0) */
809 RSCAN0GAFLECTR |= (obj->ch * 4);
810 /* set IDE format */
811 *dmy_gaflid = (format << 31);
812 if (format == CANExtended) {
813 /* set receive rule ID for bit28-11 */
814 *dmy_gaflid |= (id << 11);
815 } else {
816 /* set receive rule ID for bit10-0 */
817 *dmy_gaflid |= id;
818 }
819 /* set ID mask bit */
820 *dmy_gaflm = (0xC0000000 | mask);
821 /* disable receive rule table writing */
822 RSCAN0GAFLECTR &= 0xFFFFFEFF;
823 /* reconfigure channel which is already initialized */
824 can_reconfigure_channel();
825 retval = 1;
826 }
827 }
828
829 return retval;
830}
831
832void can_monitor(can_t *obj, int silent) {
833 __IO uint32_t *dmy_ctr;
834
835 /* set Channel Hold mode */
836 can_set_channel_mode(obj->ch, CH_HOLD);
837 if (silent) {
838 /* set listen only mode, enable communication test mode */
839 dmy_ctr = CTR_MATCH[obj->ch];
840 *dmy_ctr = ((*dmy_ctr & 0x00FFFFFF) | 0x03000000);
841 can_set_channel_mode(obj->ch, CH_COMM);
842 } else {
843 /* set normal test mode, disable communication test mode */
844 dmy_ctr = CTR_MATCH[obj->ch];
845 *dmy_ctr &= 0x00FFFFFF;
846 /* reset register */
847 can_reset_reg(obj);
848 /* reconfigure channel which is already initialized */
849 can_reconfigure_channel();
850 }
851}
852
853static void can_reset_reg(can_t *obj) {
854 __IO uint32_t *dmy_ctr;
855
856 /* time stamp source uses peripheral clock (pclk(P1_phi)/2), CAN clock uses clkc(P1_phi/2), */
857 /* mirror off, DLC not transfer, DLC check permit, transmit buffer priority, clock source not divided */
858 RSCAN0GCFG = 0x00000003;
859 /* set default frequency at 100k */
860 can_set_frequency(obj, 100000);
861 /* set receive rule */
862 can_reset_recv_rule(obj);
863 /* set buffer */
864 can_reset_buffer(obj);
865 /* set global interrrupt */
866 /* THLEIE, MEIE and DEIE interrupts are disable */
867 RSCAN0GCTR &= 0xFFFFF8FF;
868 /* ALIE, BLIE, OLIE, BORIE, BOEIE, EPIE, EWIE and BEIE interrupts are disable */
869 dmy_ctr = CTR_MATCH[obj->ch];
870 *dmy_ctr &= 0xFFFF00FF;
871}
872
873static void can_reset_recv_rule(can_t *obj) {
874 /* number of receive rules of each chanel = 64 */
875 RSCAN0GAFLCFG0 = 0x40404040;
876 RSCAN0GAFLCFG1 = 0x40000000;
877 /* enable receive rule table writing */
878 RSCAN0GAFLECTR = 0x00000100;
879 /* set the page number of receive rule table(ex: id ch = 1, page number = 4) */
880 RSCAN0GAFLECTR |= (obj->ch * 4);
881 /* set standard ID, data frame and receive rule ID */
882 *dmy_gaflid = 0x07FF;
883 /* IDE bit, RTR bit and ID bit(28-0) are not compared */
884 *dmy_gaflm = 0;
885 /* DLC check is 1 bytes, not use a receive buffer */
886 *dmy_gaflp0 = 0x10000000;
887 /* use a send/receive FIFO buffer(ex: if ch = 1, FIFO buffer number = 4 and bit = 12) */
888 *dmy_gaflp1 = (1 << ((obj->ch + 3) * 3));
889 /* disable receive rule table writing */
890 RSCAN0GAFLECTR &= 0xFFFFFEFF;
891}
892
893static void can_reset_buffer(can_t *obj) {
894 __IO uint32_t *dmy_rfcc;
895 __IO uint32_t *dmy_cfcc;
896 __IO uint32_t *dmy_txqcc;
897 __IO uint32_t *dmy_thlcc;
898 int cnt;
899
900 /* set linked send buffer number(ex: if ch = 1 and mode = send, buffer number = 16), interval timer is pclk/2 */
901 /* number of rows of send/receive FIFO buffer = 4 */
902 dmy_cfcc = CFCC_TBL[obj->ch][CAN_SEND];
903 *dmy_cfcc = 0x00011100; /* send/receive FIFO mode is send */
904 dmy_cfcc = CFCC_TBL[obj->ch][CAN_RECV];
905 *dmy_cfcc = 0x00001100; /* send/receive FIFO mode is receive */
906 /* receive buffer is not used */
907 RSCAN0RMNB = 0;
908 /* receive FIFO buffer is not used */
909 for (cnt = 0; cnt < 8; cnt++) {
910 dmy_rfcc = RFCC_MATCH[cnt];
911 *dmy_rfcc = 0;
912 }
913 /* send queue is not used */
914 dmy_txqcc = TXQCC_MATCH[obj->ch];
915 *dmy_txqcc = 0;
916 /* send history is not used */
917 dmy_thlcc = THLCC_MATCH[obj->ch];
918 *dmy_thlcc = 0;
919
920 /* CFTXIE and CFRXIE interrupts are enable */
921 dmy_cfcc = CFCC_TBL[obj->ch][CAN_SEND];
922 *dmy_cfcc |= 0x04;
923 dmy_cfcc = CFCC_TBL[obj->ch][CAN_RECV];
924 *dmy_cfcc |= 0x02;
925 /* TMIEp interrupt is disable */
926 RSCAN0TMIEC0 = 0x00000000;
927 RSCAN0TMIEC1 = 0x00000000;
928 RSCAN0TMIEC2 = 0x00000000;
929}
930
931static void can_reconfigure_channel(void) {
932 __IO uint32_t *dmy_cfcc;
933 int ch_cnt;
934
935 for (ch_cnt = 0; ch_cnt < CAN_NUM; ch_cnt++) {
936 if (can_initialized[ch_cnt] == 1) {
937 /* set Global Operation mode and Channel Communication mode */
938 can_set_global_mode(GL_OPE);
939 can_set_channel_mode(ch_cnt, CH_COMM);
940 /* Use send/receive FIFO buffer */
941 dmy_cfcc = CFCC_TBL[ch_cnt][CAN_SEND];
942 *dmy_cfcc |= 0x01;
943 dmy_cfcc = CFCC_TBL[ch_cnt][CAN_RECV];
944 *dmy_cfcc |= 0x01;
945 }
946 }
947}
948
949static void can_set_frequency(can_t *obj, int f) {
950 __IO uint32_t *dmy_cfg;
951 int oldfreq = 0;
952 int newfreq = 0;
953 uint32_t clkc_val;
954 uint8_t tmp_tq;
955 uint8_t tq = 0;
956 uint8_t tmp_brp;
957 uint8_t brp = 0;
958 uint8_t tseg1 = 0;
959 uint8_t tseg2 = 0;
960
961 /* set clkc */
962 if (RZ_A1_IsClockMode0() == false) {
963 clkc_val = CM1_RENESAS_RZ_A1_P1_CLK / 2;
964 } else {
965 clkc_val = CM0_RENESAS_RZ_A1_P1_CLK / 2;
966 }
967 /* calculate BRP bit and Choose max value of calculated frequency */
968 for (tmp_tq = 8; tmp_tq <= 25; tmp_tq++) {
969 /* f = fCAN / ((BRP+1) * Tq) */
970 /* BRP = (fCAN / (f * Tq)) - 1 */
971 tmp_brp = ((clkc_val / (f * tmp_tq)) - 1) + 1; // carry(decimal point is carry)
972 newfreq = clkc_val / ((tmp_brp + 1) * tmp_tq);
973 if (newfreq >= oldfreq) {
974 oldfreq = newfreq;
975 tq = tmp_tq;
976 brp = tmp_brp;
977 }
978 }
979 /* calculate TSEG1 bit and TSEG2 bit */
980 tseg1 = (tq - 1) * 0.666666667;
981 tseg2 = (tq - 1) - tseg1;
982 /* set RSCAN0CmCFG register */
983 dmy_cfg = CFG_MATCH[obj->ch];
984 *dmy_cfg = ((tseg2 - 1) << 20) | ((tseg1 - 1) << 16) | brp;
985}
986
987static void can_set_global_mode(int mode) {
988 /* set Global mode */
989 RSCAN0GCTR = ((RSCAN0GCTR & 0xFFFFFFFC) | mode);
990 /* Wait to cahnge into Global XXXX mode */
991 while ((RSCAN0GSTS & 0x07) != mode) {
992 __NOP();
993 }
994}
995
996static void can_set_channel_mode(uint32_t ch, int mode) {
997 __IO uint32_t *dmy_ctr;
998 __IO uint32_t *dmy_sts;
999
1000 /* set Channel mode */
1001 dmy_ctr = CTR_MATCH[ch];
1002 *dmy_ctr = ((*dmy_ctr & 0xFFFFFFFC) | mode);
1003 /* Wait to cahnge into Channel XXXX mode */
1004 dmy_sts = STS_MATCH[ch];
1005 while ((*dmy_sts & 0x07) != mode) {
1006 __NOP();
1007 }
1008}
1009
Note: See TracBrowser for help on using the repository browser.