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