1 /**************************************************************************/
2 /* File: hcan2.c - Renesas SH7760 HCAN2 controller support */
4 /* LinCAN - (Not only) Linux CAN bus driver */
5 /* Copyright (C) 2002-2009 DCE FEE CTU Prague <http://dce.felk.cvut.cz> */
6 /* Copyright (C) 2002-2009 Pavel Pisa <pisa@cmp.felk.cvut.cz> */
7 /* Copyright (C) 2007-2008 Martin Petera <peterm4@fel.cvut.cz> */
8 /* Funded by OCERA and FRESCOR IST projects */
9 /* Based on CAN driver code by Arnaud Westenberg <arnaud@wanadoo.nl> */
11 /* LinCAN is free software; you can redistribute it and/or modify it */
12 /* under terms of the GNU General Public License as published by the */
13 /* Free Software Foundation; either version 2, or (at your option) any */
14 /* later version. LinCAN is distributed in the hope that it will be */
15 /* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
16 /* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
17 /* General Public License for more details. You should have received a */
18 /* copy of the GNU General Public License along with LinCAN; see file */
19 /* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
20 /* Cambridge, MA 02139, USA. */
22 /* To allow use of LinCAN in the compact embedded systems firmware */
23 /* and RT-executives (RTEMS for example), main authors agree with next */
24 /* special exception: */
26 /* Including LinCAN header files in a file, instantiating LinCAN generics */
27 /* or templates, or linking other files with LinCAN objects to produce */
28 /* an application image/executable, does not by itself cause the */
29 /* resulting application image/executable to be covered by */
30 /* the GNU General Public License. */
31 /* This exception does not however invalidate any other reasons */
32 /* why the executable file might be covered by the GNU Public License. */
33 /* Publication of enhanced or derived LinCAN files is required although. */
34 /**************************************************************************/
36 #include "../include/can.h"
37 #include "../include/can_sysdep.h"
38 #include "../include/main.h"
39 #include "../include/hcan2.h"
44 #define DEBUGMSG(fmt,args...) can_printk(KERN_ERR "lincan (debug): " fmt,##args)
48 #define MAX_TRANSMIT_WAIT_LOOPS 20
49 #define MAX_SETTING_WAIT_LOOPS 25 /* maximal loop count while checking Chip reply to action */
50 #define MAX_IRQ_WAIT_LOOPS 25
52 void hcan2_irq_read_handler(struct canchip_t *chip, struct msgobj_t *obj);
53 void hcan2_irq_write_handler(struct canchip_t *chip, struct msgobj_t *obj);
55 void hcan2_clear_irq_flags(struct canchip_t *chip);
56 void hcan2_clear_mbox(struct canchip_t *chip, int msgobj_idx);
58 void hcan2_setup_mbox4write(struct msgobj_t * obj, struct canmsg_t * msg);
59 void hcan2_setup_mbox4write_data(struct msgobj_t * obj, struct canmsg_t * msg);
60 void hcan2_setup_mbox4read(struct msgobj_t * obj);
62 void hcan2_setup_ctrl_regs(struct canmsg_t * msg, uint16_t * ctrl0, uint16_t * ctrl1, uint16_t * ctrl2);
64 int hcan2_compare_msg(struct msgobj_t * obj, struct canmsg_t * msg);
65 void hcan2_notifyRXends(struct msgobj_t * obj, int what);
66 /* Enable folowing IRQs
67 * HCAN2_IRR_DFRI = Data Frame Received Interrupt Flag
68 * HCAN2_IRR_MBEI = Mailbox Empty Interrupt Flag
71 * Bus Off, Error Passive, Message Overrun/Overwrite
73 uint16_t IRQs = ~(HCAN2_IRR_DFRI + HCAN2_IRR_MBEI + HCAN2_IRR_BOI + HCAN2_IRR_EPI + HCAN2_IRR_MOOI);
74 /* 1 - mask interrupt, 0 - interrupt not masked */
76 int hcan2_chip_config(struct canchip_t *chip)
78 DEBUGMSG("Configuring chip...\n");
80 if (hcan2_enable_configuration(chip))
84 chip->baudrate=1000000;
85 if (hcan2_baud_rate(chip, chip->baudrate,chip->clock,0,75,0))
88 hcan2_config_irqs(chip, IRQs);
90 if (hcan2_disable_configuration(chip))
93 /* DEBUGMSG("Chip configured\n"); */
97 int hcan2_enable_configuration(struct canchip_t *chip)
102 DEBUGMSG("Enabling configuration...\n");
104 /* Disable interrupt */
105 can_disable_irq(chip->chip_irq);
107 /* Halt mode - disable CAN activity after completing current operation */
108 gsr = can_read_reg_w(chip, HCAN2_GSR);
109 if (gsr & (HCAN2_GSR_BOFF | HCAN2_GSR_RESET)) /* chip is already in config mode */
112 can_write_reg_w(chip, HCAN2_MCR_HALT, HCAN2_MCR);
114 /* Waits until chip enters Halt mode - finishes current TX/RX operation */
115 gsr = can_read_reg_w(chip, HCAN2_GSR);
116 while ( !(gsr & HCAN2_GSR_HSS) && ((i++) <= MAX_SETTING_WAIT_LOOPS) ) {
118 gsr = can_read_reg_w(chip, HCAN2_GSR);
121 if (i >= MAX_SETTING_WAIT_LOOPS) {
122 CANMSG("Error entering HALT mode (enable configuration) \n");
123 can_enable_irq(chip->chip_irq);
127 /* DEBUGMSG("Configuration mode is ENABLED\n"); */
131 int hcan2_disable_configuration(struct canchip_t *chip)
136 DEBUGMSG("Disabling configuration mode...\n");
138 /* Halt mode - disable CAN activity after completing current operation */
139 mcr = can_read_reg_w(chip, HCAN2_MCR);
140 gsr = can_read_reg_w(chip, HCAN2_GSR);
142 /* if configuration already disabled */
143 if (!(gsr & HCAN2_GSR_HSS) && !(mcr & HCAN2_MCR_HALT))
146 can_write_reg_w(chip, mcr & ~HCAN2_MCR_HALT, HCAN2_MCR);
148 /* Waits until chip leaves Halt mode */
149 gsr = can_read_reg_w(chip, HCAN2_GSR);
150 while ( (gsr & HCAN2_GSR_BOFF) && ((i++) <= MAX_SETTING_WAIT_LOOPS) ) {
152 gsr = can_read_reg_w(chip, HCAN2_GSR);
155 if (i >= MAX_SETTING_WAIT_LOOPS) {
156 CANMSG("Error leaving HALT mode (enable configuration) \n");
160 /* Enable interrupt */
161 can_enable_irq(chip->chip_irq);
163 /* DEBUGMSG("Configuration mode is DISABLED\n"); */
167 /* ********************************************* */
168 int hcan2_baud_rate(struct canchip_t *chip, int rate, int clock, int sjw, int sampl_pt, int flags)
170 /* Set communication parameters.
171 * param rate baud rate in Hz
172 * param clock frequency of hcan2 clock in Hz (on sh7760 most probably 27.5MHz)
173 * param sjw synchronization jump width (0-3) prescaled clock cycles
174 * param sampl_pt sample point in % (0-100) sets (TSEG1 + 1)/(TSEG1 + TSEG2 + 1) ration
175 * param flags fields BTR1_SAM, OCMODE, OCPOL, OCTP, OCTN, CLK_OFF, CBP
179 /* rate = clock / ((tseg1 + tseg2 + 1) * brp ) */
181 int best_error = 1000000000, error;
182 int best_tseg = 0, best_brp = 0, best_rate = 0, brp = 0;
183 int tseg, tseg1 = 0, tseg2 = 0; /* tseg = TSEG1 + TSEG2 + 1*/
184 uint16_t bcr0 = 0, bcr1 = 0;
186 DEBUGMSG("Seting Baud rate...\n");
188 for (tseg = TSEG_MIN; tseg <= TSEG_MAX; tseg++)
190 brp = 10 * clock/(tseg * rate);
191 brp = brp % 10 > 4 ? brp / 10 + 1: brp / 10; /* round */
193 if (brp == 0 || brp > 256)
196 error = rate - clock/(brp * tseg);
199 if (error <= best_error) {
203 best_rate = clock/(brp * tseg);
207 tseg2 = best_tseg - (sampl_pt * best_tseg)/100;
208 if (tseg2 < TSEG2_MIN) /* tseg2 <= sjw +1 , TSEG2_MIN = 4 */
210 if (tseg2 > TSEG2_MAX)
212 tseg1 = best_tseg - tseg2 - 1;
213 if (tseg1 > TSEG1_MAX) {
215 tseg2 = best_tseg - tseg1 - 1;
218 if (best_error && (rate/best_error < 10)) {
219 CANMSG("baud rate %d is not possible with %d Hz clock\n",
221 CANMSG("%d bps. brp=%d, best_tseg=%d, tseg1=%d, tseg2=%d\n",
222 best_rate, best_brp, best_tseg, tseg1, tseg2);
226 DEBUGMSG("Setting %d bps.\n", best_rate);
227 /* DEBUGMSG("brp=%d, best_tseg=%d, tseg1=%d, tseg2=%d, sampl_pt=%d\n",
228 best_brp, best_tseg, tseg1, tseg2,
229 (100 * tseg1 / best_tseg));
232 * EG = 0b0 - Resynchronization at falling edge
233 * BSP = 0b00 - bit sampling at one point (end of TSEG1)
236 bcr1 = (((tseg1 - 1) & 0x000f) << 12) + (((tseg2 - 1) & 0x0007) << 8) + ((sjw & 0x0003) << 4);
237 bcr0 = (best_brp - 1) & 0x00ff;
239 hcan2_set_btregs(chip, bcr0, bcr1);
241 hcan2_disable_configuration(chip);
243 /* DEBUGMSG("Baud rate set successfully\n"); */
247 int hcan2_set_btregs(struct canchip_t *chip, unsigned short bcr0, unsigned short bcr1)
249 /* DEBUGMSG("Seting BCR0 and BCR1.\n"); */
251 /* masks words to correct format */
255 can_write_reg_w(chip, bcr1, HCAN2_BCR1);
256 can_write_reg_w(chip, bcr0, HCAN2_BCR0);
258 /* DEBUGMSG("BCR0 and BCR1 successfully set.\n"); */
262 /* ********************************************* */
263 int hcan2_start_chip(struct canchip_t *chip)
265 /* DEBUGMSG("Starting chip %d...\n", chip->chip_idx); */
267 /* Stop chip turns chip to HALT mode - traffic on CAN bus is ignored after completing curent operation.
268 * Start chip only turn chip back from HALT state - using disable_config
270 hcan2_disable_configuration(chip);
272 DEBUGMSG("Chip [%d] started\n", chip->chip_idx);
276 int hcan2_stop_chip(struct canchip_t *chip)
278 /* DEBUGMSG("Stopping chip %d...\n", chip->chip_idx); */
280 /* Stop chip turns chip to HALT mode - traffic on CAN bus is ignored after completing curent operation.
281 * - using enable_config
283 hcan2_enable_configuration(chip);
285 DEBUGMSG("Chip [%d] stopped\n", chip->chip_idx);
289 int hcan2_attach_to_chip(struct canchip_t *chip)
291 /* DEBUGMSG("Attaching to chip %d.\n", chip->chip_idx); */
293 /* initialize chip */
295 if (hcan2_enable_configuration(chip))
298 /* Clear all Mailboxes */
299 if (hcan2_clear_objects(chip))
302 /* set Baudrate and Interrupts */
303 if (hcan2_chip_config(chip))
306 if (hcan2_disable_configuration(chip))
309 /* Enable interrupt */
310 can_enable_irq(chip->chip_irq);
311 can_enable_irq(chip->chip_irq);
313 CANMSG("Successfully attached to chip [%02d].\n", chip->chip_idx);
317 int hcan2_release_chip(struct canchip_t *chip)
319 hcan2_stop_chip(chip);
320 can_disable_irq(chip->chip_irq);
322 hcan2_clear_objects(chip);
324 DEBUGMSG("Chip released [%02d]\n", chip->chip_idx);
328 /* ********************************************* */
329 int hcan2_standard_mask(struct canchip_t *chip, unsigned short code, unsigned short mask)
331 uint16_t ctrl0, lafm0;
332 struct msgobj_t * obj;
333 int obj_idx = (int) (chip->chip_data);
335 if (code & 0x1ffff800)
336 return hcan2_extended_mask(chip, code, mask);
339 if (obj_idx > 0 && obj_idx <= 32)
340 obj = chip->msgobj[obj_idx - 1];
344 chip->chip_data = (void*)0; /* reset mbox number */
347 ctrl0 = ((code & 0x07ff) << 4);
348 lafm0 = ((mask & 0x07ff) << 4);
349 lafm0 |= 0x0003; /* ignore Ext ID 17:16 */
351 can_write_reg_w(chip, ctrl0, (int) obj->obj_base_addr + HCAN2_MB_CTRL0);
352 can_write_reg_w(chip, 0x0000, (int) obj->obj_base_addr + HCAN2_MB_CTRL1);
353 can_write_reg_w(chip, lafm0, (int) obj->obj_base_addr + HCAN2_MB_MASK);
354 can_write_reg_w(chip, 0xffff, (int) obj->obj_base_addr + HCAN2_MB_MASK + 2);
356 DEBUGMSG("MB%02d: Set standard_mask [id:0x%04x, m:0x%04x]\n", obj_idx, code, lafm0);
360 int hcan2_extended_mask(struct canchip_t *chip, unsigned long code, unsigned long mask)
362 uint16_t ctrl0, ctrl1, lafm0, lafm1;
364 struct msgobj_t * obj;
366 int obj_idx = (int) (chip->chip_data);
368 if (obj_idx > 0 && obj_idx <= 32)
369 obj = chip->msgobj[obj_idx - 1];
373 chip->chip_data = (void*)0; /* reset mbox number */
375 ctrl0 = ((code & 0x1ffc0000) >> 14);
376 ctrl0 |=((code & 0x00030000) >> 16);
377 ctrl0 |= HCAN2_MBCT0_IDE; /* set IDE flag */
378 ctrl1 = (code & 0x0000ffff);
380 lafm0 = ((mask & 0x1ffc0000) >> 14);
381 lafm0 |=((mask & 0x00030000) >> 16);
382 lafm1 = (mask & 0x0000ffff);
384 can_write_reg_w(chip, ctrl0, (int) obj->obj_base_addr + HCAN2_MB_CTRL0);
385 can_write_reg_w(chip, ctrl1, (int) obj->obj_base_addr + HCAN2_MB_CTRL1);
386 can_write_reg_w(chip, lafm0, (int) obj->obj_base_addr + HCAN2_MB_MASK);
387 can_write_reg_w(chip, lafm1, (int) obj->obj_base_addr + HCAN2_MB_MASK + 2);
389 DEBUGMSG("MB%02d: Set extended_mask [id:0x%08x, m:0x%08x]\n", obj_idx, (uint32_t)code, (uint32_t)mask);
394 /* ********************************************* */
395 int hcan2_pre_read_config(struct canchip_t *chip, struct msgobj_t *obj)
397 DEBUGMSG("Pre read config\n");
399 hcan2_enable_configuration(chip);
401 /* clears mailbox and setup LFA to accept all Exted Messages */
402 hcan2_setup_mbox4read(obj);
404 hcan2_disable_configuration(chip);
409 int hcan2_pre_write_config(struct canchip_t *chip, struct msgobj_t *obj, struct canmsg_t *msg)
411 DEBUGMSG("Pre write config\n");
413 /* change Mailbox header only if neccessary */
414 /* otherwise change only data */
415 if (hcan2_compare_msg(obj, msg))
417 if (hcan2_enable_configuration(chip))
420 hcan2_setup_mbox4write(obj, msg);
422 if (hcan2_disable_configuration(chip))
426 hcan2_setup_mbox4write_data(obj, msg);
431 int hcan2_send_msg(struct canchip_t *chip, struct msgobj_t *obj, struct canmsg_t *msg)
434 int b_addr = ((obj->object - 1) / 16) * (-2);
436 obj_bit = (1 << ((obj->object - 1) % 16));
438 /* CANMSG("Sending message [obj: %d]\n", obj->object - 1); */
440 can_write_reg_w(chip, obj_bit, b_addr + HCAN2_TXPR0);
442 /* CANMSG("Message sent [obj: %d]\n", obj->object - 1); */
446 int hcan2_remote_request(struct canchip_t *chip, struct msgobj_t *obj)
448 CANMSG("hcan2_remote_request not implemented\n");
452 /* ********************************************* */
453 int hcan2_irq_handler(int irq, struct canchip_t *chip)
455 uint16_t irq_reg, idx;
456 short loop_cnt = MAX_IRQ_WAIT_LOOPS;
460 HCAN2_IRR_TCMI - Time Compare Match Register
461 HCAN2_IRR_TOI - Time Overrun Interrupt
462 HCAN2_IRR_WUBA - Wake-up on Bus Activity
463 HCAN2_IRR_MOOI - Message Overrun/Overwrite Interrupt Flag
464 HCAN2_IRR_MBEI - Messagebox Empty Interrupt Flag
465 HCAN2_IRR_OF - Overload Frame
466 HCAN2_IRR_BOI - Bus Off Interrupt Flag
467 HCAN2_IRR_EPI - Error Passive Interrupt Flag
468 HCAN2_IRR_ROWI - Receive Overload Warning Interrupt Flag
469 HCAN2_IRR_TOWI - Transmit Overload Warining Interrupt Flag
470 HCAN2_IRR_RFRI - Remote Frame Request Interrupt Flag
471 HCAN2_IRR_DFRI - Data Frame Received Interrupt Flag
472 HCAN2_IRR_RHSI - Reset/Halt/Sleep Interrupt Flag */
474 irq_reg = can_read_reg_w(chip, HCAN2_IRR);
475 DEBUGMSG("irq: %d, chip base addr: 0x%08x\n", irq, (uint32_t)chip->chip_base_addr);
476 DEBUGMSG("IRQ Handler: HCAN2_IRR: 0x%04x\n", irq_reg); //*/
481 CANMSG("hcan2_irq_handler IRQ %d stuck\n", irq);
482 return CANCHIP_IRQ_STUCK;
485 /* Received message */
486 if (irq_reg & HCAN2_IRR_DFRI)
488 rxdf = (can_read_reg_w(chip, HCAN2_RXPR1) << 16) +
489 can_read_reg_w(chip, HCAN2_RXPR0);
492 DEBUGMSG("Received message [0x%08x]\n", rxdf);
494 /* find the message object */
495 for (idx = 0; (idx < chip->max_objects) && rxdf; idx++)
496 if ((rxdf & (1<<idx))) {
497 hcan2_irq_read_handler(chip, chip->msgobj[idx]);
498 /* RXPR flag for this msgobj is cleared during irq_read_handler*/
503 DEBUGMSG("Before reset flags [0x%08x]\n", rxdf);
504 rxdf = (can_read_reg_w(chip, HCAN2_RXPR1) << 16) +
505 can_read_reg_w(chip, HCAN2_RXPR0);
510 if (irq_reg & HCAN2_IRR_BOI) {
511 CANMSG("Error: entering BUS OFF state\nstatus register: 0x%02x irq register: 0x%02x\n",
512 can_read_reg_w(chip, HCAN2_GSR), irq_reg);
514 /* notify all RX/TX ends */
515 for (idx = 0; idx < chip->max_objects; idx++) {
517 chip->msgobj[idx]->ret=-1;
518 if(chip->msgobj[idx]->tx_slot)
519 canque_notify_inends(chip->msgobj[idx]->tx_qedge,
520 CANQUEUE_NOTIFY_ERROR);
522 hcan2_notifyRXends(chip->msgobj[idx], CANQUEUE_NOTIFY_ERROR);
525 /* reset flag - by writing '1' */
526 can_write_reg_w(chip, HCAN2_IRR_BOI, HCAN2_IRR);
529 /* Warning: Error Passive */
530 if (irq_reg & HCAN2_IRR_EPI) {
532 tecrec = can_read_reg_w(chip, HCAN2_TECREC);
534 CANMSG("Warning: entering ERROR PASSIVE state\nTEC: %d REC: %d\n",
535 (uint16_t)((tecrec >> 8) & 0x00ff), (uint16_t)(tecrec & 0x00ff));
537 /* Show warning only */
539 /* reset flag - by writing '1' */
540 can_write_reg_w(chip, HCAN2_IRR_EPI, HCAN2_IRR);
543 /* Message Overrun/Overwritten */
544 if (irq_reg & HCAN2_IRR_MOOI) {
545 /* put get Unread Message Status Register */
546 rxdf = (can_read_reg_w(chip, HCAN2_UMSR1) << 16) + can_read_reg_w(chip, HCAN2_UMSR0);
548 /* find the message object */
549 for (idx = 0; (idx < chip->max_objects) && !(rxdf & (1<<idx)); idx++) { }
551 CANMSG("Error: MESSAGE OVERRUN/OVERWRITTEN [MB: %d]\n",idx);
553 /* notify only injured RXqueue-end */
554 if (idx < chip->max_objects)
555 hcan2_notifyRXends(chip->msgobj[idx], CANQUEUE_NOTIFY_ERROR);
558 can_write_reg_w(chip, (1 << (idx % 16)), HCAN2_UMSR0 - 2 * (idx / 16));
561 /* Mailbox empty - after message was sent */
562 if (irq_reg & HCAN2_IRR_MBEI)
564 txdf = (can_read_reg_w(chip, HCAN2_TXACK1) << 16) +
565 can_read_reg_w(chip, HCAN2_TXACK0);
567 /* find the message object */
568 for (idx = 0; (idx < chip->max_objects) && !(txdf & (1<<idx)); idx++) { }
570 /* realy i got one? */
571 if (idx >= chip->max_objects) {
572 /* IRQ is caused by Aborted transmition */
573 can_write_reg_w(chip, 0xffff, HCAN2_ABACK0);
574 can_write_reg_w(chip, 0xffff, HCAN2_ABACK1);
575 return CANCHIP_IRQ_HANDLED;
578 /* Clear TXACK flag */
579 can_write_reg_w(chip, 1 << (idx % 16), HCAN2_TXACK0 - 2 * (idx / 16));
582 hcan2_wakeup_tx(chip, chip->msgobj[idx]);
585 irq_reg = can_read_reg_w(chip, HCAN2_IRR);
586 } while(irq_reg & ~IRQs);
588 return CANCHIP_IRQ_HANDLED;
591 int hcan2_irq_accept(int irq, struct canchip_t *chip)
593 CANMSG("hcan2_irq_accept NOT IMPLEMENTED\n");
597 int hcan2_config_irqs(struct canchip_t *chip, short irqs)
599 hcan2_clear_irq_flags(chip);
601 can_write_reg_w(chip, irqs, HCAN2_IMR);
603 /* allow all mailboxes to generate IRQ */
604 can_write_reg_w(chip, 0, HCAN2_MBIMR0);
605 can_write_reg_w(chip, 0, HCAN2_MBIMR1);
607 /* CANMSG("IRQ Mask set [0x%02x]\n", irqs); */
612 /* ********************************************* */
613 int hcan2_clear_objects(struct canchip_t *chip)
616 for (i = 0; i < chip->max_objects; i++)
617 hcan2_clear_mbox(chip, i);
622 int hcan2_check_tx_stat(struct canchip_t *chip)
624 /* DEBUGMSG("Check TX stat\n"); */
625 /* If Transmition is complete return 0 - no error */
626 if (can_read_reg_w(chip, HCAN2_GSR) & HCAN2_GSR_TXC)
632 /* Note: this checks TX status of concrete messagebox */
633 int hcan2_check_MB_tx_stat(struct canchip_t *chip, struct msgobj_t *obj)
635 /* Transmition is complete return 0 - no error */
637 /* MB1-MB15 are in CANTXPR0 and MB16-MB31 are in CANTXPR1
638 CANTXPR0 = CANTXPR1 + 0x0002
639 MB0 - receive only */
641 char id = obj->object - 1;
642 return (can_read_reg_w(chip, HCAN2_TXPR0 - 2 * (id / 16)) & (1 << (id & 0x00ff)));
645 int hcan2_wakeup_tx(struct canchip_t *chip, struct msgobj_t *obj)
647 DEBUGMSG("WakeUP TX\n");
649 if (obj->object == 1) /* msgbox 0 cant transmit only receive ! */
652 can_preempt_disable();
654 can_msgobj_set_fl(obj,TX_REQUEST);
655 if(!can_msgobj_test_and_set_fl(obj,TX_LOCK) &&
656 !hcan2_check_MB_tx_stat(chip, obj))
657 { /* enable transmition only if MB is empty */
658 can_msgobj_clear_fl(obj,TX_REQUEST);
660 hcan2_irq_write_handler(chip, obj);
662 can_msgobj_clear_fl(obj,TX_LOCK);
665 can_msgobj_clear_fl(obj,TX_REQUEST);
668 can_preempt_enable();
670 /* DEBUGMSG("WakeUP TX - END\n"); */
674 int hcan2_filtch_rq(struct canchip_t *chip, struct msgobj_t * obj)
676 struct canfilt_t filter;
680 int num = canqueue_ends_filt_conjuction(obj->qends, &filter);
682 canqueue_ends_filt_conjuction(obj->qends, &filter);
685 /* in structure chip->chip_data is Mailbox number */
686 chip->chip_data = (void*)(obj->object);
688 /* HCAN2 uses oposite logic for LAFM: 1-ignore bit, 0-use bit as mask */
691 DEBUGMSG("CNT: %d ID: 0x%08x MASK: 0x%08x\n", num, (uint32_t) (filter.id) & 0x1fffffff, (uint32_t) (~filter.mask) & 0x1fffffff);
694 if (filter.flags & MSG_EXT) /* Extended ID */
695 return hcan2_extended_mask(chip, filter.id, ~filter.mask);
696 else /* Standard ID */
697 return hcan2_standard_mask(chip, filter.id, ~filter.mask);
700 /* ********************************************* */
701 void hcan2_irq_read_handler(struct canchip_t *chip, struct msgobj_t *obj)
704 unsigned ctrl0, ctrl2, data;
705 unsigned long flag_addr;
709 mb_offset = (int ) obj->obj_base_addr;
711 /* DEBUGMSG("------IRQ Read Handler\n"); */
713 ctrl0 = can_read_reg_w(chip, mb_offset + HCAN2_MB_CTRL0);
714 ctrl2 = can_read_reg_w(chip, mb_offset + HCAN2_MB_CTRL2);
716 obj->rx_msg.length = len = ctrl2 & HCAN2_MBCT2_DLC;
717 obj->rx_msg.flags = (ctrl0 & HCAN2_MBCT0_RTR) ? MSG_RTR : 0;
718 obj->rx_msg.cob = obj->object - 1;
720 /* get ID of received message */
721 if (ctrl0 & HCAN2_MBCT0_IDE)
723 DEBUGMSG("EXTENDED ID\n");
724 obj->rx_msg.id = (ctrl0 & HCAN2_MBCT0_STDID) << (18 - 4);
725 obj->rx_msg.id |= can_read_reg_w(chip, mb_offset + HCAN2_MB_CTRL1);
726 obj->rx_msg.id |= ((ctrl0 & HCAN2_MBCT0_EXTID) << 16);
729 obj->rx_msg.id = (ctrl0 & HCAN2_MBCT0_STDID)>>4;
732 if(len > CAN_MSG_LENGTH) len = CAN_MSG_LENGTH;
733 for (i = 0; i < len; i++)
735 /* rcanqueue_ends_filt_conjuctionead 16bit data - two data bytes*/
736 data = can_read_reg_w(chip, (int) obj->obj_base_addr + HCAN2_MB_DATA1 + i);
737 obj->rx_msg.data[i] = (data & 0xff00) >> 8; // one data byte
738 if (++i < len) obj->rx_msg.data[i] = data & 0x00ff; // second data byte
741 /* Computes correct offset address of register from MSGBOX_IDX and RTR flag
742 * result is one of these:
743 * HCAN2_RXPR1, HCAN2_RXPR0, HCAN2_RFPR1, HCAN2_RFPR0
745 flag_addr = HCAN2_RXPR0 - (int)((obj->object - 1) / 16) * 2;
747 /* Reset flag by writing 1 to its position */
748 can_write_reg_w(chip, (1 << ((obj->object - 1) % 16)), flag_addr);
750 /* fill CAN message timestamp */
751 can_filltimestamp(&obj->rx_msg.timestamp);
753 canque_filter_msg2edges(obj->qends, &obj->rx_msg);
756 void hcan2_irq_write_handler(struct canchip_t *chip, struct msgobj_t *obj)
761 /* Do local transmitted message distribution if enabled */
763 /* fill CAN message timestamp */
764 can_filltimestamp(&obj->tx_slot->msg.timestamp);
766 obj->tx_slot->msg.flags |= MSG_LOCAL;
767 canque_filter_msg2edges(obj->qends, &obj->tx_slot->msg);
769 /* Free transmitted slot */
770 canque_free_outslot(obj->qends, obj->tx_qedge, obj->tx_slot);
774 cmd = canque_test_outslot(obj->qends, &obj->tx_qedge, &obj->tx_slot);
778 if (chip->chipspecops->pre_write_config(chip, obj, &obj->tx_slot->msg)) {
780 canque_notify_inends(obj->tx_qedge, CANQUEUE_NOTIFY_ERRTX_PREP);
781 canque_free_outslot(obj->qends, obj->tx_qedge, obj->tx_slot);
785 if (chip->chipspecops->send_msg(chip, obj, &obj->tx_slot->msg)) {
787 canque_notify_inends(obj->tx_qedge, CANQUEUE_NOTIFY_ERRTX_SEND);
788 canque_free_outslot(obj->qends, obj->tx_qedge, obj->tx_slot);
794 /* ********************************************* */
795 int hcan2_register(struct chipspecops_t *chipspecops)
797 chipspecops->chip_config = hcan2_chip_config;
798 chipspecops->enable_configuration = hcan2_enable_configuration;
799 chipspecops->disable_configuration = hcan2_disable_configuration;
801 chipspecops->baud_rate = hcan2_baud_rate;
802 chipspecops->set_btregs = hcan2_set_btregs;
804 chipspecops->start_chip = hcan2_start_chip;
805 chipspecops->stop_chip = hcan2_stop_chip;
806 chipspecops->attach_to_chip = hcan2_attach_to_chip;
807 chipspecops->release_chip = hcan2_release_chip;
809 chipspecops->standard_mask = hcan2_standard_mask;
810 chipspecops->extended_mask = hcan2_extended_mask;
811 chipspecops->message15_mask = NULL; /* hcan2_message15_mask; */
813 chipspecops->pre_read_config = hcan2_pre_read_config;
814 chipspecops->pre_write_config = hcan2_pre_write_config;
815 chipspecops->send_msg = hcan2_send_msg;
816 chipspecops->remote_request = hcan2_remote_request;
818 chipspecops->irq_handler = hcan2_irq_handler;
819 chipspecops->irq_accept = NULL; /* hcan2_irq_accept; */
820 chipspecops->config_irqs = hcan2_config_irqs;
822 chipspecops->clear_objects = hcan2_clear_objects;
823 chipspecops->check_tx_stat = hcan2_check_tx_stat;
824 chipspecops->wakeup_tx = hcan2_wakeup_tx;
825 chipspecops->filtch_rq = hcan2_filtch_rq;
829 int hcan2_fill_chipspecops(struct canchip_t *chip)
831 chip->chip_type = "hcan2";
832 chip->max_objects = 32;
833 chip->write_register = chip->hostdevice->hwspecops->write_register;
834 chip->read_register = chip->hostdevice->hwspecops->read_register;
855 hcan2_register(chip->chipspecops);
860 /* ********************************************* */
861 int hcan2_reset_chip(struct canchip_t *chip)
863 /* After reset and reconfig (start_chip) Chip waits for
864 * 11 recessive bits to join CAN bus activity
870 DEBUGMSG("Resetting HCAN2 chip %d...\n", chip->chip_idx);
872 /* send Reset Request */
873 can_write_reg_w(chip, HCAN2_MCR_RESET, HCAN2_MCR );
875 /* Check hardware reset status */
877 gsr_reset = can_read_reg_w(chip, HCAN2_GSR) & HCAN2_GSR_RESET;
878 while (!(gsr_reset) && ((i++) <= MAX_SETTING_WAIT_LOOPS))
881 gsr_reset = can_read_reg_w(chip, HCAN2_GSR) & HCAN2_GSR_RESET;
884 if (i >= MAX_SETTING_WAIT_LOOPS) {
885 CANMSG("Reset status timeout! (enter Reset Mode)\n");
889 /* Clear Reset request flag */
890 can_write_reg_w(chip, can_read_reg_w(chip, HCAN2_MCR) & (~HCAN2_MCR_RESET), HCAN2_MCR);
893 /* Clear Reset Interrupt Flag IRR 0 */
894 can_write_reg_w(chip, HCAN2_IRR_RHSI, HCAN2_IRR);
896 /* DEBUGMSG("Chips reset status ok.\n"); */
901 /* !!! Functions below doesn't call enable/disable chip config !!! */
902 /* !!! Usable only in block, where enable/diable config is called explicitly !!! */
903 void hcan2_clear_irq_flags(struct canchip_t *chip)
906 DEBUGMSG("Clearing IRQ flags...\n");
907 DEBUGMSG("IRR: %04x\n",can_read_reg_w(chip, HCAN2_IRR));
909 irr = HCAN2_IRR_TCMI | HCAN2_IRR_TOI | HCAN2_IRR_WUBA |
910 HCAN2_IRR_OF | HCAN2_IRR_BOI | HCAN2_IRR_EPI |
911 HCAN2_IRR_ROWI | HCAN2_IRR_TOWI | HCAN2_IRR_RHSI;
912 can_write_reg_w(chip, irr, HCAN2_IRR);
914 /* Other IRQ flags are cleared through other registers - see below */
916 /* Meseage Overrun/Overwrite interrupt */
917 can_write_reg_w(chip, 0, HCAN2_UMSR0);
918 can_write_reg_w(chip, 0, HCAN2_UMSR1);
920 /* Mailbox Empty Interrupt */
921 can_write_reg_w(chip, 0, HCAN2_TXACK0);
922 can_write_reg_w(chip, 0, HCAN2_TXACK1);
923 can_write_reg_w(chip, 0, HCAN2_ABACK0);
924 can_write_reg_w(chip, 0, HCAN2_ABACK1);
926 /* Remote Frame Request Interrupt */
927 can_write_reg_w(chip, 0, HCAN2_RFPR0);
928 can_write_reg_w(chip, 0, HCAN2_RFPR1);
930 /* Data Frame Received Interupt Flag */
931 can_write_reg_w(chip, 0, HCAN2_RXPR0);
932 can_write_reg_w(chip, 0, HCAN2_RXPR1);
934 DEBUGMSG("clear_irq_flags - OK\n");
937 void hcan2_clear_mbox(struct canchip_t *chip, int msgobj_idx)
939 unsigned long mb_start_addr = HCAN2_MB0 + msgobj_idx * HCAN2_MB_OFFSET;
941 /* DEBUGMSG("Clearing message object %d\n", msgobj_idx); */
944 * Standard Identifier format (0)
948 can_write_reg_w(chip, 0, mb_start_addr + HCAN2_MB_CTRL0);
950 /* EXTID {15:0} = 0 */
951 can_write_reg_w(chip, 0, mb_start_addr + HCAN2_MB_CTRL1);
953 /* NMC: overwrite stored message (1)
954 * ATDF: No message is transmited after receiving Remote Frame (0)
955 * DARTX: disable Automatic Retransmition: yes (1)
956 * MBC = 111 - not used: HCAN2_MBCT2_MBC default value correspond to 'Not Used'
960 can_write_reg_w(chip, (uint16_t) (HCAN2_MBCT2_NMC | HCAN2_MBCT2_DART | HCAN2_MBCT2_MBC), mb_start_addr + HCAN2_MB_CTRL2);
963 can_write_reg_w(chip, 0, mb_start_addr + HCAN2_MB_TSTP);
965 /* Data: all bytes 0xff */
966 can_write_reg_w(chip, (uint16_t) 0xffff, mb_start_addr + HCAN2_MB_DATA0);
967 can_write_reg_w(chip, (uint16_t) 0xffff, mb_start_addr + HCAN2_MB_DATA2);
968 can_write_reg_w(chip, (uint16_t) 0xffff, mb_start_addr + HCAN2_MB_DATA4);
969 can_write_reg_w(chip, (uint16_t) 0xffff, mb_start_addr + HCAN2_MB_DATA6);
971 /* Local Acceptance Filter Mask - all bits of STDID and EXTID must match values set in mailbox */
972 can_write_reg_w(chip, 0, mb_start_addr + HCAN2_MB_MASK);
973 can_write_reg_w(chip, 0, mb_start_addr + HCAN2_MB_MASK + 2); /* Mask is 4 bytes */
976 DEBUGMSG("Mailbox [%d] cleared.\n", msgobj_idx);
979 void hcan2_setup_mbox4write(struct msgobj_t * obj, struct canmsg_t * msg)
982 uint16_t ctrl0, ctrl1, ctrl2;
984 struct canchip_t * chip = obj->hostchip;
986 DEBUGMSG("Change Header\n");
988 mb_offset = (int) obj->obj_base_addr;
990 hcan2_setup_ctrl_regs(msg, &ctrl0, &ctrl1, &ctrl2);
992 can_write_reg_w(chip, ctrl0, mb_offset + HCAN2_MB_CTRL0);
993 can_write_reg_w(chip, ctrl1, mb_offset + HCAN2_MB_CTRL1); /* set 0 if not using EXT format */
994 can_write_reg_w(chip, ctrl2, mb_offset + HCAN2_MB_CTRL2);
997 hcan2_setup_mbox4write_data(obj, msg);
1000 void hcan2_setup_mbox4write_data(struct msgobj_t * obj, struct canmsg_t * msg)
1002 int len,i, mb_offset;
1005 struct canchip_t * chip = obj->hostchip;
1007 DEBUGMSG("Change Data\n");
1009 mb_offset = (int) obj->obj_base_addr;
1012 if(len > CAN_MSG_LENGTH) len = CAN_MSG_LENGTH;
1014 for (i = 0; i < len; i+=2)
1016 data = (msg->data[i] << 8) + (i+1 < len ? msg->data[i+1] : 0);
1017 can_write_reg_w(chip, data, mb_offset + HCAN2_MB_DATA1 + i);
1021 void hcan2_setup_mbox4read(struct msgobj_t * obj)
1023 struct canchip_t * chip = obj->hostchip;
1025 hcan2_clear_mbox(chip, obj->object - 1);
1027 // in structure chip->chip_data is Mailbox number
1028 chip->chip_data = (void*)(obj->object);
1029 hcan2_extended_mask(chip, 2048, 0x1fffffff); /* accept all */
1031 can_write_reg_w(chip, HCAN2_MBCT2_DART + (HCAN2_MBMOD_RXDR << 8),
1032 (int) obj->obj_base_addr + HCAN2_MB_CTRL2);
1035 void hcan2_setup_ctrl_regs(struct canmsg_t * msg, uint16_t * ctrl0, uint16_t * ctrl1, uint16_t * ctrl2)
1038 uint32_t id = msg->id;
1041 if(len > CAN_MSG_LENGTH) len = CAN_MSG_LENGTH;
1043 *ctrl0 = (msg->flags & MSG_RTR ? HCAN2_MBCT0_RTR : 0);
1045 if (msg->flags & MSG_EXT)
1048 *ctrl0 |= ((id & 0x1ffc0000) << 14);
1049 *ctrl0 |= ((id & 0x00030000) >> 16) | HCAN2_MBCT0_IDE; /* get bits {17:16} from EXTID */
1050 *ctrl1 = (id & 0x0000ffff);
1055 *ctrl0 |= ((id & 0x01ff) << 4);
1059 *ctrl2 = HCAN2_MBCT2_DART + HCAN2_MBMOD_TXDR + (len & HCAN2_MBCT2_DLC);
1062 int hcan2_compare_msg(struct msgobj_t * obj, struct canmsg_t * msg)
1064 /* Check if mailbox header content change is neccessary */
1065 /* Comparing only Control regs */
1066 uint16_t ctrl0, ctrl1, ctrl2;
1070 struct canchip_t * chip = obj->hostchip;
1072 mb_offset = (int) obj->obj_base_addr;
1074 c0 = can_read_reg_w(chip, mb_offset + HCAN2_MB_CTRL0);
1075 c1 = can_read_reg_w(chip, mb_offset + HCAN2_MB_CTRL1);
1076 c2 = can_read_reg_w(chip, mb_offset + HCAN2_MB_CTRL2);
1078 hcan2_setup_ctrl_regs(msg, &ctrl0, &ctrl1, &ctrl2);
1080 /* if using EXT ID conpare also ctrl1 */
1081 if (msg->flags & MSG_EXT && ctrl1 ^ c1)
1085 DEBUGMSG("C0 0x%04x HW: 0x%04x\n", ctrl0, c0);
1086 DEBUGMSG("C1 0x%04x HW: 0x%04x\n", ctrl1, c1);
1087 DEBUGMSG("C2 0x%04x HW: 0x%04x\n", ctrl2, c2);
1089 return ((ctrl0 ^ c0) || (ctrl2 ^ c2));
1092 void hcan2_notifyRXends(struct msgobj_t * obj, int what){
1093 struct canque_edge_t * edge;
1094 canque_for_each_inedge(obj->qends, edge){
1095 canque_notify_outends(edge, what);