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