]> rtime.felk.cvut.cz Git - lincan.git/blob - lincan/src/hcan2.c
LinCAN sources go through big white-space cleanup.
[lincan.git] / lincan / src / hcan2.c
1 /**************************************************************************/
2 /* File: hcan2.c - Renesas SH7760 HCAN2 controller support                */
3 /*                                                                        */
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>      */
10 /*                                                                        */
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.                                              */
21 /*                                                                        */
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:                                                     */
25 /*                                                                        */
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 /**************************************************************************/
35
36 #include "../include/can.h"
37 #include "../include/can_sysdep.h"
38 #include "../include/main.h"
39 #include "../include/hcan2.h"
40
41 #define myDEBUG 0
42
43 #if myDEBUG
44         #define DEBUGMSG(fmt,args...) can_printk(KERN_ERR "lincan (debug): " fmt,##args)
45 #endif
46
47
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
51
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);
54
55 void hcan2_clear_irq_flags(struct canchip_t *chip);
56 void hcan2_clear_mbox(struct canchip_t *chip, int msgobj_idx);
57
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);
61
62 void hcan2_setup_ctrl_regs(struct canmsg_t * msg, uint16_t * ctrl0, uint16_t * ctrl1, uint16_t * ctrl2);
63
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
69  *
70  * and Errors:
71  * Bus Off, Error Passive, Message Overrun/Overwrite
72  */
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 */
75
76 int hcan2_chip_config(struct canchip_t *chip)
77 {
78         DEBUGMSG("Configuring chip...\n");
79
80         if (hcan2_enable_configuration(chip))
81                 return -ENODEV;
82
83         if (!chip->baudrate)
84                 chip->baudrate=1000000;
85         if (hcan2_baud_rate(chip, chip->baudrate,chip->clock,0,75,0))
86                 return -ENODEV;
87
88         hcan2_config_irqs(chip, IRQs);
89
90         if (hcan2_disable_configuration(chip))
91                 return -ENODEV;
92
93 /*      DEBUGMSG("Chip configured\n"); */
94         return 0;
95 }
96
97 int hcan2_enable_configuration(struct canchip_t *chip)
98 {
99         int i = 0;
100         uint16_t gsr;
101
102         DEBUGMSG("Enabling configuration...\n");
103
104         /* Disable interrupt */
105         can_disable_irq(chip->chip_irq);
106
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 */
110                 return 0;
111
112         can_write_reg_w(chip, HCAN2_MCR_HALT, HCAN2_MCR);
113
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) ) {
117                 udelay(200);
118                 gsr = can_read_reg_w(chip, HCAN2_GSR);
119         }
120
121         if (i >= MAX_SETTING_WAIT_LOOPS) {
122                 CANMSG("Error entering HALT mode (enable configuration) \n");
123                 can_enable_irq(chip->chip_irq);
124                 return -ENODEV;
125         }
126
127 /*      DEBUGMSG("Configuration mode is ENABLED\n"); */
128         return 0;
129 }
130
131 int hcan2_disable_configuration(struct canchip_t *chip)
132 {
133         int i = 0;
134         uint16_t gsr, mcr;
135
136         DEBUGMSG("Disabling configuration mode...\n");
137
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);
141
142         /* if configuration already disabled */
143         if (!(gsr & HCAN2_GSR_HSS) && !(mcr & HCAN2_MCR_HALT))
144             return 0;
145
146         can_write_reg_w(chip, mcr & ~HCAN2_MCR_HALT, HCAN2_MCR);
147
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) ) {
151                 udelay(200);
152                 gsr = can_read_reg_w(chip, HCAN2_GSR);
153         }
154
155         if (i >= MAX_SETTING_WAIT_LOOPS) {
156                 CANMSG("Error leaving HALT mode (enable configuration) \n");
157                 return -ENODEV;
158         }
159
160         /* Enable interrupt */
161         can_enable_irq(chip->chip_irq);
162
163 /*      DEBUGMSG("Configuration mode is DISABLED\n"); */
164         return 0;
165 }
166
167 /* ********************************************* */
168 int hcan2_baud_rate(struct canchip_t *chip, int rate, int clock, int sjw, int sampl_pt, int flags)
169 {
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
176          */
177
178
179         /* rate = clock / ((tseg1 + tseg2 + 1) * brp ) */
180
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;
185
186         DEBUGMSG("Seting Baud rate...\n");
187
188         for (tseg = TSEG_MIN; tseg <= TSEG_MAX; tseg++)
189         {
190                 brp = 10 * clock/(tseg * rate);
191                 brp = brp % 10 > 4 ? brp / 10 + 1: brp / 10;    /* round */
192
193                 if (brp == 0 || brp > 256)
194                         continue;
195
196                 error = rate - clock/(brp * tseg);
197                 if (error < 0)
198                         error = -error;
199                 if (error <= best_error) {
200                         best_error = error;
201                         best_tseg = tseg;
202                         best_brp = brp;
203                         best_rate = clock/(brp * tseg);
204                 }
205         }
206
207         tseg2 = best_tseg - (sampl_pt * best_tseg)/100;
208         if (tseg2 < TSEG2_MIN)          /* tseg2 <= sjw +1 , TSEG2_MIN = 4 */
209                 tseg2 = TSEG2_MIN;
210         if (tseg2 > TSEG2_MAX)
211                 tseg2 = TSEG2_MAX;
212         tseg1 = best_tseg - tseg2 - 1;
213         if (tseg1 > TSEG1_MAX) {
214                 tseg1 = TSEG1_MAX;
215                 tseg2 = best_tseg - tseg1 - 1;
216         }
217
218         if (best_error && (rate/best_error < 10)) {
219                 CANMSG("baud rate %d is not possible with %d Hz clock\n",
220                         rate, clock);
221                 CANMSG("%d bps. brp=%d, best_tseg=%d, tseg1=%d, tseg2=%d\n",
222                         best_rate, best_brp, best_tseg, tseg1, tseg2);
223                 return -EINVAL;
224         }
225
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));
230 */
231         /*
232          * EG   = 0b0   - Resynchronization at falling edge
233          * BSP  = 0b00  - bit sampling at one point (end of TSEG1)
234          */
235
236         bcr1 = (((tseg1 - 1) & 0x000f) << 12) + (((tseg2 - 1) & 0x0007) << 8) + ((sjw & 0x0003) << 4);
237         bcr0 = (best_brp - 1) & 0x00ff;
238
239         hcan2_set_btregs(chip, bcr0, bcr1);
240
241         hcan2_disable_configuration(chip);
242
243 /*      DEBUGMSG("Baud rate set successfully\n"); */
244         return 0;
245 }
246
247 int hcan2_set_btregs(struct canchip_t *chip, unsigned short bcr0, unsigned short bcr1)
248 {
249 /*      DEBUGMSG("Seting BCR0 and BCR1.\n"); */
250
251         /* masks words to correct format */
252         bcr0 &= 0x00ff;
253         bcr1 &= 0xf733;
254
255         can_write_reg_w(chip, bcr1, HCAN2_BCR1);
256         can_write_reg_w(chip, bcr0, HCAN2_BCR0);
257
258 /*      DEBUGMSG("BCR0 and BCR1 successfully set.\n"); */
259         return 0;
260 }
261
262 /* ********************************************* */
263 int hcan2_start_chip(struct canchip_t *chip)
264 {
265 /*      DEBUGMSG("Starting chip %d...\n", chip->chip_idx); */
266
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
269          */
270         hcan2_disable_configuration(chip);
271
272         DEBUGMSG("Chip [%d] started\n", chip->chip_idx);
273         return 0;
274 }
275
276 int hcan2_stop_chip(struct canchip_t *chip)
277 {
278 /*      DEBUGMSG("Stopping chip %d...\n", chip->chip_idx); */
279
280         /* Stop chip turns chip to HALT mode - traffic on CAN bus is ignored after completing curent operation.
281          * - using enable_config
282          */
283         hcan2_enable_configuration(chip);
284
285         DEBUGMSG("Chip [%d] stopped\n", chip->chip_idx);
286         return 0;
287 }
288
289 int hcan2_attach_to_chip(struct canchip_t *chip)
290 {
291 /*      DEBUGMSG("Attaching to chip %d.\n", chip->chip_idx); */
292
293         /* initialize chip */
294
295         if (hcan2_enable_configuration(chip))
296                 return -ENODEV;
297
298         /* Clear all Mailboxes */
299         if (hcan2_clear_objects(chip))
300                 return -ENODEV;
301
302         /* set Baudrate and Interrupts */
303         if (hcan2_chip_config(chip))
304                 return -ENODEV;
305
306         if (hcan2_disable_configuration(chip))
307                 return -ENODEV;
308
309         /* Enable interrupt */
310         can_enable_irq(chip->chip_irq);
311         can_enable_irq(chip->chip_irq);
312
313         CANMSG("Successfully attached to chip [%02d].\n", chip->chip_idx);
314         return 0;
315 }
316
317 int hcan2_release_chip(struct canchip_t *chip)
318 {
319         hcan2_stop_chip(chip);
320         can_disable_irq(chip->chip_irq);
321
322         hcan2_clear_objects(chip);
323
324         DEBUGMSG("Chip released [%02d]\n", chip->chip_idx);
325         return 0;
326 }
327
328 /* ********************************************* */
329 int hcan2_standard_mask(struct canchip_t *chip, unsigned short code, unsigned short mask)
330 {
331         uint16_t ctrl0, lafm0;
332         struct msgobj_t * obj;
333         int obj_idx = (int) (chip->chip_data);
334
335         if (code & 0x1ffff800)
336             return hcan2_extended_mask(chip, code, mask);
337
338
339         if (obj_idx > 0 && obj_idx <= 32)
340             obj = chip->msgobj[obj_idx - 1];
341         else
342             return -ENODEV;
343
344         chip->chip_data = (void*)0;     /* reset mbox number */
345
346
347         ctrl0 = ((code & 0x07ff) << 4);
348         lafm0 = ((mask & 0x07ff) << 4);
349         lafm0 |= 0x0003;                /* ignore Ext ID 17:16  */
350
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);
355
356         DEBUGMSG("MB%02d: Set standard_mask [id:0x%04x, m:0x%04x]\n", obj_idx, code, lafm0);
357         return 0;
358 }
359
360 int hcan2_extended_mask(struct canchip_t *chip, unsigned long code, unsigned long mask)
361 {
362         uint16_t ctrl0, ctrl1, lafm0, lafm1;
363
364         struct msgobj_t * obj;
365
366         int obj_idx = (int) (chip->chip_data);
367
368         if (obj_idx > 0 && obj_idx <= 32)
369             obj = chip->msgobj[obj_idx - 1];
370         else
371             return -ENODEV;
372
373         chip->chip_data = (void*)0; /* reset mbox number */
374
375         ctrl0 = ((code & 0x1ffc0000) >> 14);
376         ctrl0 |=((code & 0x00030000) >> 16);
377         ctrl0 |= HCAN2_MBCT0_IDE;       /* set IDE flag */
378         ctrl1 =  (code & 0x0000ffff);
379
380         lafm0 = ((mask & 0x1ffc0000) >> 14);
381         lafm0 |=((mask & 0x00030000) >> 16);
382         lafm1 =  (mask & 0x0000ffff);
383
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);
388
389         DEBUGMSG("MB%02d: Set extended_mask [id:0x%08x, m:0x%08x]\n", obj_idx, (uint32_t)code, (uint32_t)mask);
390
391         return 0;
392 }
393
394 /* ********************************************* */
395 int hcan2_pre_read_config(struct canchip_t *chip, struct msgobj_t *obj)
396 {
397         DEBUGMSG("Pre read config\n");
398
399         hcan2_enable_configuration(chip);
400
401         /* clears mailbox and setup LFA to accept all Exted Messages */
402         hcan2_setup_mbox4read(obj);
403
404         hcan2_disable_configuration(chip);
405
406         return 0;
407 }
408
409 int hcan2_pre_write_config(struct canchip_t *chip, struct msgobj_t *obj, struct canmsg_t *msg)
410 {
411         DEBUGMSG("Pre write config\n");
412
413         /* change Mailbox header only if neccessary */
414         /* otherwise change only data */
415         if (hcan2_compare_msg(obj, msg))
416         {
417                 if (hcan2_enable_configuration(chip))
418                         return -ENODEV;
419
420                 hcan2_setup_mbox4write(obj, msg);
421
422                 if (hcan2_disable_configuration(chip))
423                         return -ENODEV;
424         }
425         else
426                 hcan2_setup_mbox4write_data(obj, msg);
427
428         return 0;
429 }
430
431 int hcan2_send_msg(struct canchip_t *chip, struct msgobj_t *obj, struct canmsg_t *msg)
432 {
433         unsigned obj_bit;
434         int b_addr = ((obj->object - 1) / 16) * (-2);
435
436         obj_bit = (1 << ((obj->object - 1) % 16));
437
438 /*      CANMSG("Sending message [obj: %d]\n", obj->object - 1); */
439
440         can_write_reg_w(chip, obj_bit, b_addr + HCAN2_TXPR0);
441
442 /*      CANMSG("Message sent [obj: %d]\n", obj->object - 1); */
443         return 0;
444 }
445
446 int hcan2_remote_request(struct canchip_t *chip, struct msgobj_t *obj)
447 {
448         CANMSG("hcan2_remote_request not implemented\n");
449         return -ENOSYS;
450 }
451
452 /* ********************************************* */
453 int hcan2_irq_handler(int irq, struct canchip_t *chip)
454 {
455         uint16_t irq_reg, idx;
456         short loop_cnt = MAX_IRQ_WAIT_LOOPS;
457         uint32_t rxdf, txdf;
458
459 /*
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 */
473
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); //*/
477
478         do {
479
480                 if(!loop_cnt--) {
481                         CANMSG("hcan2_irq_handler IRQ %d stuck\n", irq);
482                         return CANCHIP_IRQ_STUCK;
483                 }
484
485                 /* Received message */
486                 if (irq_reg & HCAN2_IRR_DFRI)
487                 {
488                         rxdf = (can_read_reg_w(chip, HCAN2_RXPR1) << 16) +
489                                 can_read_reg_w(chip, HCAN2_RXPR0);
490
491                         while(rxdf) {
492                                 DEBUGMSG("Received message [0x%08x]\n", rxdf);
493
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*/
499                                                 rxdf &= ~(1 << idx);
500                                         }
501
502
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);
506                         }
507                 }
508
509                 /* Error: Bus Off */
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);
513
514                         /* notify all RX/TX ends */
515                         for (idx = 0; idx < chip->max_objects; idx++) {
516                                 /* notify TX */
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);
521                                 /* notify RX */
522                                 hcan2_notifyRXends(chip->msgobj[idx], CANQUEUE_NOTIFY_ERROR);
523                         }
524
525                         /* reset flag - by writing '1' */
526                         can_write_reg_w(chip, HCAN2_IRR_BOI, HCAN2_IRR);
527                 }
528
529                 /* Warning: Error Passive */
530                 if (irq_reg & HCAN2_IRR_EPI) {
531                         uint16_t tecrec;
532                         tecrec = can_read_reg_w(chip, HCAN2_TECREC);
533
534                         CANMSG("Warning: entering ERROR PASSIVE state\nTEC: %d REC: %d\n",
535                                 (uint16_t)((tecrec >> 8) & 0x00ff), (uint16_t)(tecrec & 0x00ff));
536
537                         /* Show warning only */
538
539                         /* reset flag - by writing '1' */
540                         can_write_reg_w(chip, HCAN2_IRR_EPI, HCAN2_IRR);
541                 }
542
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);
547
548                         /* find the message object */
549                         for (idx = 0; (idx < chip->max_objects) && !(rxdf & (1<<idx)); idx++) { }
550
551                         CANMSG("Error: MESSAGE OVERRUN/OVERWRITTEN [MB: %d]\n",idx);
552
553                         /* notify only injured RXqueue-end */
554                         if (idx < chip->max_objects)
555                                 hcan2_notifyRXends(chip->msgobj[idx], CANQUEUE_NOTIFY_ERROR);
556
557                         /* reset flag */
558                         can_write_reg_w(chip, (1 << (idx % 16)), HCAN2_UMSR0 - 2 * (idx / 16));
559                 }
560
561                 /* Mailbox empty - after message was sent */
562                 if (irq_reg & HCAN2_IRR_MBEI)
563                 {
564                     txdf = (can_read_reg_w(chip, HCAN2_TXACK1) << 16) +
565                         can_read_reg_w(chip, HCAN2_TXACK0);
566
567                     /* find the message object */
568                     for (idx = 0; (idx < chip->max_objects) && !(txdf & (1<<idx)); idx++) { }
569
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;
576                     }
577
578                     /* Clear TXACK flag */
579                     can_write_reg_w(chip, 1 << (idx % 16), HCAN2_TXACK0 - 2 * (idx / 16));
580
581                     /* sends message */
582                     hcan2_wakeup_tx(chip, chip->msgobj[idx]);
583                 }
584
585                 irq_reg = can_read_reg_w(chip, HCAN2_IRR);
586         } while(irq_reg & ~IRQs);
587
588         return CANCHIP_IRQ_HANDLED;
589 }
590
591 int hcan2_irq_accept(int irq, struct canchip_t *chip)
592 {
593         CANMSG("hcan2_irq_accept NOT IMPLEMENTED\n");
594         return -ENOSYS;
595 }
596
597 int hcan2_config_irqs(struct canchip_t *chip, short irqs)
598 {
599         hcan2_clear_irq_flags(chip);
600
601         can_write_reg_w(chip, irqs, HCAN2_IMR);
602
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);
606
607 /*      CANMSG("IRQ Mask set [0x%02x]\n", irqs); */
608         return 0;
609 }
610
611
612 /* ********************************************* */
613 int hcan2_clear_objects(struct canchip_t *chip)
614 {
615         int i;
616         for (i = 0; i < chip->max_objects; i++)
617                 hcan2_clear_mbox(chip, i);
618
619         return 0;
620 }
621
622 int hcan2_check_tx_stat(struct canchip_t *chip)
623 {
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)
627                 return 0;
628         else
629                 return 1;
630 }
631
632 /* Note: this checks TX status of concrete messagebox */
633 int hcan2_check_MB_tx_stat(struct canchip_t *chip, struct msgobj_t *obj)
634 {
635         /* Transmition is complete return 0 - no error */
636
637         /* MB1-MB15 are in CANTXPR0 and MB16-MB31 are in CANTXPR1
638            CANTXPR0 = CANTXPR1 + 0x0002
639            MB0 - receive only */
640
641         char id = obj->object - 1;
642         return (can_read_reg_w(chip, HCAN2_TXPR0 - 2 * (id / 16)) & (1 << (id & 0x00ff)));
643 }
644
645 int hcan2_wakeup_tx(struct canchip_t *chip, struct msgobj_t *obj)
646 {
647         DEBUGMSG("WakeUP TX\n");
648
649         if (obj->object == 1)   /* msgbox 0 cant transmit only receive ! */
650             return -ENODEV;
651
652         can_preempt_disable();
653
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);
659
660                 hcan2_irq_write_handler(chip, obj);
661
662                 can_msgobj_clear_fl(obj,TX_LOCK);
663         }
664         else
665                 can_msgobj_clear_fl(obj,TX_REQUEST);
666
667
668         can_preempt_enable();
669
670 /*      DEBUGMSG("WakeUP TX - END\n"); */
671         return 0;
672 }
673
674 int hcan2_filtch_rq(struct canchip_t *chip, struct msgobj_t * obj)
675 {
676         struct canfilt_t filter;
677
678
679 #if myDEBUG
680         int num = canqueue_ends_filt_conjuction(obj->qends, &filter);
681 #else
682         canqueue_ends_filt_conjuction(obj->qends, &filter);
683 #endif
684
685         /* in structure chip->chip_data is Mailbox number */
686         chip->chip_data = (void*)(obj->object);
687
688         /* HCAN2 uses oposite logic for LAFM: 1-ignore bit, 0-use bit as mask */
689
690         DEBUGMSG("CNT: %d ID: 0x%08x MASK: 0x%08x\n", num, (uint32_t) (filter.id) & 0x1fffffff, (uint32_t) (~filter.mask) & 0x1fffffff);
691
692         if (filter.flags & MSG_EXT)             /* Extended ID */
693                 return hcan2_extended_mask(chip, filter.id, ~filter.mask);
694         else                                    /* Standard ID */
695                 return hcan2_standard_mask(chip, filter.id, ~filter.mask);
696 }
697
698 /* ********************************************* */
699 void hcan2_irq_read_handler(struct canchip_t *chip, struct msgobj_t *obj)
700 {
701         int i, len;
702         unsigned ctrl0, ctrl2, data;
703         unsigned long flag_addr;
704         uint16_t mb_offset;
705
706
707         mb_offset = (int ) obj->obj_base_addr;
708
709 /*      DEBUGMSG("------IRQ Read Handler\n"); */
710
711         ctrl0 = can_read_reg_w(chip, mb_offset + HCAN2_MB_CTRL0);
712         ctrl2 = can_read_reg_w(chip, mb_offset + HCAN2_MB_CTRL2);
713
714         obj->rx_msg.length = len = ctrl2 & HCAN2_MBCT2_DLC;
715         obj->rx_msg.flags = (ctrl0 & HCAN2_MBCT0_RTR) ? MSG_RTR : 0;
716         obj->rx_msg.cob = obj->object - 1;
717
718         /* get ID of received message */
719         if (ctrl0 & HCAN2_MBCT0_IDE)
720         {
721             DEBUGMSG("EXTENDED ID\n");
722             obj->rx_msg.id = (ctrl0 & HCAN2_MBCT0_STDID) << (18 - 4);
723             obj->rx_msg.id |= can_read_reg_w(chip, mb_offset + HCAN2_MB_CTRL1);
724             obj->rx_msg.id |= ((ctrl0 & HCAN2_MBCT0_EXTID) << 16);
725         }
726         else
727             obj->rx_msg.id = (ctrl0 & HCAN2_MBCT0_STDID)>>4;
728
729
730         if(len > CAN_MSG_LENGTH) len = CAN_MSG_LENGTH;
731         for (i = 0; i < len; i++)
732         {
733                 /* rcanqueue_ends_filt_conjuctionead 16bit data - two data bytes*/
734                 data = can_read_reg_w(chip, (int) obj->obj_base_addr + HCAN2_MB_DATA1 + i);
735                 obj->rx_msg.data[i] = (data & 0xff00) >> 8;             // one data byte
736                 if (++i < len) obj->rx_msg.data[i] = data & 0x00ff;     // second data byte
737         }
738
739         /* Computes correct offset address of register from MSGBOX_IDX and RTR flag
740          * result is one of these:
741          * HCAN2_RXPR1, HCAN2_RXPR0, HCAN2_RFPR1, HCAN2_RFPR0
742          */
743         flag_addr = HCAN2_RXPR0 - (int)((obj->object - 1) / 16) * 2;
744
745         /* Reset flag by writing 1 to its position */
746         can_write_reg_w(chip, (1 << ((obj->object - 1) % 16)), flag_addr);
747
748         /* fill CAN message timestamp */
749         can_filltimestamp(&obj->rx_msg.timestamp);
750
751         canque_filter_msg2edges(obj->qends, &obj->rx_msg);
752 }
753
754 void hcan2_irq_write_handler(struct canchip_t *chip, struct msgobj_t *obj)
755 {
756         int cmd;
757
758         if(obj->tx_slot){
759                 /* Do local transmitted message distribution if enabled */
760                 if (processlocal){
761                         /* fill CAN message timestamp */
762                         can_filltimestamp(&obj->tx_slot->msg.timestamp);
763
764                         obj->tx_slot->msg.flags |= MSG_LOCAL;
765                         canque_filter_msg2edges(obj->qends, &obj->tx_slot->msg);
766                 }
767                 /* Free transmitted slot */
768                 canque_free_outslot(obj->qends, obj->tx_qedge, obj->tx_slot);
769                 obj->tx_slot=NULL;
770         }
771
772         cmd = canque_test_outslot(obj->qends, &obj->tx_qedge, &obj->tx_slot);
773         if(cmd < 0)
774                 return;
775
776         if (chip->chipspecops->pre_write_config(chip, obj, &obj->tx_slot->msg)) {
777                 obj->ret = -1;
778                 canque_notify_inends(obj->tx_qedge, CANQUEUE_NOTIFY_ERRTX_PREP);
779                 canque_free_outslot(obj->qends, obj->tx_qedge, obj->tx_slot);
780                 obj->tx_slot = NULL;
781                 return;
782         }
783         if (chip->chipspecops->send_msg(chip, obj, &obj->tx_slot->msg)) {
784                 obj->ret = -1;
785                 canque_notify_inends(obj->tx_qedge, CANQUEUE_NOTIFY_ERRTX_SEND);
786                 canque_free_outslot(obj->qends, obj->tx_qedge, obj->tx_slot);
787                 obj->tx_slot = NULL;
788                 return;
789         }
790 }
791
792 /* ********************************************* */
793 int hcan2_register(struct chipspecops_t *chipspecops)
794 {
795         chipspecops->chip_config = hcan2_chip_config;
796         chipspecops->enable_configuration = hcan2_enable_configuration;
797         chipspecops->disable_configuration = hcan2_disable_configuration;
798
799         chipspecops->baud_rate = hcan2_baud_rate;
800         chipspecops->set_btregs = hcan2_set_btregs;
801
802         chipspecops->start_chip = hcan2_start_chip;
803         chipspecops->stop_chip = hcan2_stop_chip;
804         chipspecops->attach_to_chip = hcan2_attach_to_chip;
805         chipspecops->release_chip = hcan2_release_chip;
806
807         chipspecops->standard_mask = hcan2_standard_mask;
808         chipspecops->extended_mask = hcan2_extended_mask;
809         chipspecops->message15_mask = NULL; /* hcan2_message15_mask; */
810
811         chipspecops->pre_read_config = hcan2_pre_read_config;
812         chipspecops->pre_write_config = hcan2_pre_write_config;
813         chipspecops->send_msg = hcan2_send_msg;
814         chipspecops->remote_request = hcan2_remote_request;
815
816         chipspecops->irq_handler = hcan2_irq_handler;
817         chipspecops->irq_accept = NULL; /* hcan2_irq_accept; */
818         chipspecops->config_irqs = hcan2_config_irqs;
819
820         chipspecops->clear_objects = hcan2_clear_objects;
821         chipspecops->check_tx_stat = hcan2_check_tx_stat;
822         chipspecops->wakeup_tx = hcan2_wakeup_tx;
823         chipspecops->filtch_rq = hcan2_filtch_rq;
824         return 0;
825 }
826
827 int hcan2_fill_chipspecops(struct canchip_t *chip)
828 {
829         chip->chip_type = "hcan2";
830         chip->max_objects = 32;
831         chip->write_register = chip->hostdevice->hwspecops->write_register;
832         chip->read_register = chip->hostdevice->hwspecops->read_register;
833
834         /*
835         chip->flags;
836         chip->baudrate;
837         chip->msgobj;
838         chip->chip_data;
839         chip->chip_lock;
840
841         chip->sja_cdr_reg;
842         chip->sja_ocr_reg;
843         chip->int_cpu_reg;
844         chip->int_clk_reg;
845         chip->int_bus_reg;
846
847         #ifdef CAN_WITH_RTL
848         chip->worker_thread;
849         chip->pend_flags;
850         #endif
851         */
852
853         hcan2_register(chip->chipspecops);
854         return 0;
855 }
856
857
858 /* ********************************************* */
859 int hcan2_reset_chip(struct canchip_t *chip)
860 {
861         /* After reset and reconfig (start_chip) Chip waits for
862          * 11 recessive bits to join CAN bus activity
863          */
864
865         int i;
866         unsigned gsr_reset;
867
868         DEBUGMSG("Resetting HCAN2 chip %d...\n", chip->chip_idx);
869
870         /* send Reset Request */
871         can_write_reg_w(chip, HCAN2_MCR_RESET, HCAN2_MCR );
872
873         /* Check hardware reset status */
874         i = 0;
875         gsr_reset = can_read_reg_w(chip, HCAN2_GSR) & HCAN2_GSR_RESET;
876         while (!(gsr_reset) && ((i++) <= MAX_SETTING_WAIT_LOOPS))
877         {
878                 udelay(10000);
879                 gsr_reset = can_read_reg_w(chip, HCAN2_GSR) & HCAN2_GSR_RESET;
880         }
881
882         if (i >= MAX_SETTING_WAIT_LOOPS) {
883                 CANMSG("Reset status timeout! (enter Reset Mode)\n");
884                 return -ENODEV;
885         }
886
887         /* Clear Reset request flag */
888         can_write_reg_w(chip, can_read_reg_w(chip, HCAN2_MCR) & (~HCAN2_MCR_RESET), HCAN2_MCR);
889
890
891         /* Clear Reset Interrupt Flag IRR 0 */
892         can_write_reg_w(chip, HCAN2_IRR_RHSI, HCAN2_IRR);
893
894 /*      DEBUGMSG("Chips reset status ok.\n"); */
895
896         return 0;
897 }
898
899 /* !!! Functions below doesn't call enable/disable chip config !!! */
900 /* !!! Usable only in block, where enable/diable config is called explicitly !!! */
901 void hcan2_clear_irq_flags(struct canchip_t *chip)
902 {
903         uint16_t irr;
904         DEBUGMSG("Clearing IRQ flags...\n");
905         DEBUGMSG("IRR: %04x\n",can_read_reg_w(chip, HCAN2_IRR));
906
907         irr = HCAN2_IRR_TCMI | HCAN2_IRR_TOI | HCAN2_IRR_WUBA |
908                 HCAN2_IRR_OF | HCAN2_IRR_BOI | HCAN2_IRR_EPI |
909                 HCAN2_IRR_ROWI | HCAN2_IRR_TOWI | HCAN2_IRR_RHSI;
910         can_write_reg_w(chip, irr, HCAN2_IRR);
911
912         /* Other IRQ flags are cleared through other registers - see below */
913
914         /* Meseage Overrun/Overwrite interrupt */
915         can_write_reg_w(chip, 0, HCAN2_UMSR0);
916         can_write_reg_w(chip, 0, HCAN2_UMSR1);
917
918         /* Mailbox Empty Interrupt */
919         can_write_reg_w(chip, 0, HCAN2_TXACK0);
920         can_write_reg_w(chip, 0, HCAN2_TXACK1);
921         can_write_reg_w(chip, 0, HCAN2_ABACK0);
922         can_write_reg_w(chip, 0, HCAN2_ABACK1);
923
924         /* Remote Frame Request Interrupt */
925         can_write_reg_w(chip, 0, HCAN2_RFPR0);
926         can_write_reg_w(chip, 0, HCAN2_RFPR1);
927
928         /* Data Frame Received Interupt Flag */
929         can_write_reg_w(chip, 0, HCAN2_RXPR0);
930         can_write_reg_w(chip, 0, HCAN2_RXPR1);
931
932         DEBUGMSG("clear_irq_flags - OK\n");
933 }
934
935 void hcan2_clear_mbox(struct canchip_t *chip, int msgobj_idx)
936 {
937         unsigned long mb_start_addr = HCAN2_MB0 + msgobj_idx * HCAN2_MB_OFFSET;
938
939 /*      DEBUGMSG("Clearing message object %d\n", msgobj_idx); */
940
941         /* STDID = 0
942          * Standard Identifier format (0)
943          * Data Frame (0)
944          * EXTID{17,16} = 0
945          */
946         can_write_reg_w(chip, 0, mb_start_addr + HCAN2_MB_CTRL0);
947
948         /* EXTID {15:0} = 0 */
949         can_write_reg_w(chip, 0, mb_start_addr + HCAN2_MB_CTRL1);
950
951         /* NMC: overwrite stored message (1)
952          * ATDF: No message is transmited after receiving Remote Frame (0)
953          * DARTX: disable Automatic Retransmition: yes (1)
954          * MBC = 111 - not used: HCAN2_MBCT2_MBC default value correspond to 'Not Used'
955          * CAN Bus error - 0
956          * Data Length = 0
957          */
958         can_write_reg_w(chip, (uint16_t) (HCAN2_MBCT2_NMC | HCAN2_MBCT2_DART | HCAN2_MBCT2_MBC), mb_start_addr + HCAN2_MB_CTRL2);
959
960         /* TimeStamp */
961         can_write_reg_w(chip, 0, mb_start_addr + HCAN2_MB_TSTP);
962
963         /* Data: all bytes 0xff */
964         can_write_reg_w(chip, (uint16_t) 0xffff, mb_start_addr + HCAN2_MB_DATA0);
965         can_write_reg_w(chip, (uint16_t) 0xffff, mb_start_addr + HCAN2_MB_DATA2);
966         can_write_reg_w(chip, (uint16_t) 0xffff, mb_start_addr + HCAN2_MB_DATA4);
967         can_write_reg_w(chip, (uint16_t) 0xffff, mb_start_addr + HCAN2_MB_DATA6);
968
969         /* Local Acceptance Filter Mask - all bits of STDID and EXTID must match values set in mailbox */
970         can_write_reg_w(chip, 0, mb_start_addr + HCAN2_MB_MASK);
971         can_write_reg_w(chip, 0, mb_start_addr + HCAN2_MB_MASK + 2);            /* Mask is 4 bytes */
972
973
974         DEBUGMSG("Mailbox [%d] cleared.\n", msgobj_idx);
975 }
976
977 void hcan2_setup_mbox4write(struct msgobj_t * obj, struct canmsg_t * msg)
978 {
979         int mb_offset;
980         uint16_t ctrl0, ctrl1, ctrl2;
981
982         struct canchip_t * chip = obj->hostchip;
983
984         DEBUGMSG("Change Header\n");
985
986         mb_offset = (int) obj->obj_base_addr;
987
988         hcan2_setup_ctrl_regs(msg, &ctrl0, &ctrl1, &ctrl2);
989
990         can_write_reg_w(chip, ctrl0, mb_offset + HCAN2_MB_CTRL0);
991         can_write_reg_w(chip, ctrl1, mb_offset + HCAN2_MB_CTRL1);       /* set 0 if not using EXT format */
992         can_write_reg_w(chip, ctrl2, mb_offset + HCAN2_MB_CTRL2);
993
994         /* data */
995         hcan2_setup_mbox4write_data(obj, msg);
996 }
997
998 void hcan2_setup_mbox4write_data(struct msgobj_t * obj, struct canmsg_t * msg)
999 {
1000         int len,i, mb_offset;
1001         uint16_t data;
1002
1003         struct canchip_t * chip = obj->hostchip;
1004
1005         DEBUGMSG("Change Data\n");
1006
1007         mb_offset = (int) obj->obj_base_addr;
1008
1009         len = msg->length;
1010         if(len > CAN_MSG_LENGTH) len = CAN_MSG_LENGTH;
1011
1012         for (i = 0; i < len; i+=2)
1013         {
1014                 data = (msg->data[i] << 8) + (i+1 < len ? msg->data[i+1] : 0);
1015                 can_write_reg_w(chip, data, mb_offset + HCAN2_MB_DATA1 + i);
1016         }
1017 }
1018
1019 void hcan2_setup_mbox4read(struct msgobj_t * obj)
1020 {
1021         struct canchip_t * chip = obj->hostchip;
1022
1023         hcan2_clear_mbox(chip, obj->object - 1);
1024
1025         // in structure chip->chip_data is Mailbox number
1026         chip->chip_data = (void*)(obj->object);
1027         hcan2_extended_mask(chip, 2048, 0x1fffffff);    /* accept all */
1028
1029         can_write_reg_w(chip, HCAN2_MBCT2_DART + (HCAN2_MBMOD_RXDR << 8),
1030             (int) obj->obj_base_addr + HCAN2_MB_CTRL2);
1031 }
1032
1033 void hcan2_setup_ctrl_regs(struct canmsg_t * msg, uint16_t * ctrl0, uint16_t * ctrl1, uint16_t * ctrl2)
1034 {
1035         uint8_t len;
1036         uint32_t id = msg->id;
1037
1038         len = msg->length;
1039         if(len > CAN_MSG_LENGTH) len = CAN_MSG_LENGTH;
1040
1041         *ctrl0 = (msg->flags & MSG_RTR ? HCAN2_MBCT0_RTR : 0);
1042
1043         if (msg->flags & MSG_EXT)
1044         {
1045                 /* Extended ID */
1046                 *ctrl0 |= ((id & 0x1ffc0000) << 14);
1047                 *ctrl0 |= ((id & 0x00030000) >> 16) | HCAN2_MBCT0_IDE;  /* get bits {17:16} from EXTID */
1048                 *ctrl1 = (id & 0x0000ffff);
1049         }
1050         else
1051         {
1052                 /* Standard ID */
1053                 *ctrl0 |= ((id & 0x01ff) << 4);
1054                 *ctrl1 = 0;
1055         }
1056
1057         *ctrl2 = HCAN2_MBCT2_DART + HCAN2_MBMOD_TXDR + (len & HCAN2_MBCT2_DLC);
1058 }
1059
1060 int hcan2_compare_msg(struct msgobj_t * obj, struct canmsg_t * msg)
1061 {
1062         /* Check if mailbox header content change is neccessary */
1063         /* Comparing only Control regs */
1064         uint16_t ctrl0, ctrl1, ctrl2;
1065         uint16_t mb_offset;
1066         uint16_t c0,c1,c2;
1067
1068         struct canchip_t * chip = obj->hostchip;
1069
1070         mb_offset = (int) obj->obj_base_addr;
1071
1072         c0 = can_read_reg_w(chip, mb_offset + HCAN2_MB_CTRL0);
1073         c1 = can_read_reg_w(chip, mb_offset + HCAN2_MB_CTRL1);
1074         c2 = can_read_reg_w(chip, mb_offset + HCAN2_MB_CTRL2);
1075
1076         hcan2_setup_ctrl_regs(msg, &ctrl0, &ctrl1, &ctrl2);
1077
1078         /* if using EXT ID conpare also ctrl1 */
1079         if (msg->flags & MSG_EXT && ctrl1 ^ c1)
1080                 return 1;
1081
1082
1083         DEBUGMSG("C0 0x%04x HW: 0x%04x\n", ctrl0, c0);
1084         DEBUGMSG("C1 0x%04x HW: 0x%04x\n", ctrl1, c1);
1085         DEBUGMSG("C2 0x%04x HW: 0x%04x\n", ctrl2, c2);
1086
1087         return ((ctrl0 ^ c0) || (ctrl2 ^ c2));
1088 }
1089
1090 void hcan2_notifyRXends(struct msgobj_t * obj, int what){
1091         struct canque_edge_t * edge;
1092         canque_for_each_inedge(obj->qends, edge){
1093                 canque_notify_outends(edge, what);
1094         }
1095 }