]> rtime.felk.cvut.cz Git - lincan.git/blob - embedded/app/usbcan/lpc17xx_can.c
Some bugs related with bit timing fixed.
[lincan.git] / embedded / app / usbcan / lpc17xx_can.c
1 #include "can/lpc17xx_can.h"
2
3 static void CAN_configPin();
4 static void CAN_setBusTiming(struct canchip_t *chip);
5
6 #define MAX_TRANSMIT_WAIT_LOOPS 20
7
8 //---------------------------------------------------------------------------------
9 //---------------------------------------------------------------------------------
10
11
12 // board can-lmc1 specific functions:
13
14 int can_lmc1_register(struct hwspecops_t *hwspecops){
15
16         hwspecops->request_io = can_lmc1_request_io;
17         hwspecops->reset = can_lmc1_reset;
18         hwspecops->init_hw_data = can_lmc1_init_hw_data;
19         hwspecops->init_chip_data = can_lmc1_init_chip_data;
20         hwspecops->init_obj_data = can_lmc1_init_obj_data;
21         hwspecops->write_register = can_lmc1_write_register;
22         hwspecops->read_register = can_lmc1_read_register;
23         hwspecops->program_irq = can_lmc1_program_irq;
24
25         return 0;
26 }
27
28 int can_lmc1_init_hw_data(struct candevice_t *candev){
29
30         candev->res_addr=0;
31         candev->nr_82527_chips=0;
32         candev->nr_sja1000_chips=0;
33         candev->nr_all_chips=1;
34         candev->flags = 0;
35
36         return 0;
37 }
38
39 int can_lmc1_init_chip_data(struct candevice_t *candev, int chipnr){
40
41         // used CAN1 peripherial -> CAN1 registers base 
42         candev->chip[chipnr]->chip_base_addr = CAN1_REGS_BASE;
43
44         lpc17xx_fill_chipspecops(candev->chip[chipnr]);
45
46         candev->chip[chipnr]->chip_data=(void *)malloc(sizeof(struct can_lmc1_chip_data));
47         if (candev->chip[chipnr]->chip_data==NULL)
48                 return -ENOMEM;
49
50         return 0;
51 }
52
53 int can_lmc1_init_obj_data(struct canchip_t *chip, int objnr){
54         
55         return 0;
56 }
57
58 void can_lmc1_write_register(unsigned data, unsigned long address){
59         (*(volatile uint32_t*)(address)) = data;
60 }
61
62 unsigned can_lmc1_read_register(unsigned long address){
63         return (*(volatile uint32_t*)(address));
64 }
65
66 int can_lmc1_request_io(struct candevice_t *candev)
67 {
68         return 0;
69 }
70
71 int can_lmc1_reset(struct candevice_t *candev)
72 {
73         return 0;
74 }
75
76 int can_lmc1_program_irq(struct candevice_t *candev)
77 {
78         return 0;
79 }
80
81 //---------------------------------------------------------------------------------
82 //---------------------------------------------------------------------------------
83
84
85 // lpc17xx can chip specific functions:
86
87
88 int lpc17xx_chip_config(struct canchip_t *chip){
89
90         CAN_init(chip);
91
92         return 0;
93 }
94
95 int lpc17xx_pre_write_config(struct canchip_t *chip, struct msgobj_t *obj,
96                                                         struct canmsg_t *msg)
97 {
98         
99         CAN_send(chip, msg);
100
101         return 0;
102 }
103
104 int lpc17xx_send_msg(struct canchip_t *chip, struct msgobj_t *obj,
105                                                         struct canmsg_t *msg)
106 {
107         uint32_t i=0;   
108
109         // write transmission request
110         can_write_reg(chip, (CAN_CMR_TR | CAN_CMR_STB1), CAN_CMR_o); 
111
112         while (!(can_read_reg(chip, CAN_SR_o) & (1<<3))){
113                 if(i++<MAX_TRANSMIT_WAIT_LOOPS)
114                         continue;
115
116                 // request command to abort transmission request
117                 can_write_reg(chip, CAN_CMR_AT, CAN_CMR_o);
118                 break;
119         }
120
121         return 0;
122 }
123
124 int lpc17xx_wakeup_tx(struct canchip_t *chip, struct msgobj_t *obj)
125 {
126
127         can_preempt_disable();
128
129         can_msgobj_set_fl(obj,TX_PENDING);
130         can_msgobj_set_fl(obj,TX_REQUEST);
131
132         while(!can_msgobj_test_and_set_fl(obj,TX_LOCK)){
133                 can_msgobj_clear_fl(obj,TX_REQUEST);
134
135                 if (can_read_reg(chip, CAN_SR_o) & CAN_SR_TBS1){
136                         obj->tx_retry_cnt=0;
137                         lpc17xx_irq_write_handler(chip, obj);
138                 }
139
140                 can_msgobj_clear_fl(obj,TX_LOCK);
141                 if(!can_msgobj_test_fl(obj,TX_REQUEST)) break;
142
143         }
144
145         can_preempt_enable();
146
147         return 0;
148 }
149
150 int lpc17xx_irq_handler(int irq, struct canchip_t *chip)
151 {
152
153         uint32_t i;
154         struct msgobj_t *obj;   
155         obj = chip->msgobj[0];
156
157         
158         i = can_read_reg(chip, CAN_ICR_o);
159
160         if(i & (CAN_ICR_TI1 | CAN_ICR_RI)){
161
162                 if(can_read_reg(chip, CAN_SR_o) & CAN_SR_RBS) {
163                                 lpc17xx_read(chip,obj);
164                                 obj->ret = 0;
165                 }
166         
167         
168                 if ((can_msgobj_test_fl(obj,TX_PENDING)) || (can_msgobj_test_fl(obj,TX_REQUEST))) {
169                         
170                         can_msgobj_set_fl(obj,TX_REQUEST);
171
172                         while(!can_msgobj_test_and_set_fl(obj,TX_LOCK)){
173
174                                 obj->ret=0;
175                                 can_msgobj_clear_fl(obj,TX_REQUEST);
176
177                                 if (can_read_reg(chip, CAN_SR_o) & CAN_SR_TBS1){
178                                         obj->tx_retry_cnt=0;
179                                         lpc17xx_irq_write_handler(chip, obj);
180                                 }
181
182                                 can_msgobj_clear_fl(obj,TX_LOCK);
183                                 if(!can_msgobj_test_fl(obj,TX_REQUEST)) break;
184
185                         }       
186                 }
187
188         }
189         if(i & CAN_ICR_DOI)
190                 can_write_reg(chip, CAN_CMR_CDO, CAN_CMR_o);    // clear data overrun
191
192
193         return CANCHIP_IRQ_HANDLED;
194
195 }
196
197 void lpc17xx_irq_write_handler(struct canchip_t *chip, struct msgobj_t *obj)
198 {
199         int cmd;
200
201
202         if(obj->tx_slot){
203                 /* Do local transmitted message distribution if enabled */
204                 if (processlocal){
205                         /* fill CAN message timestamp */
206                         can_filltimestamp(&obj->tx_slot->msg.timestamp);
207
208                         obj->tx_slot->msg.flags |= MSG_LOCAL;
209                         canque_filter_msg2edges(obj->qends, &obj->tx_slot->msg);
210                 }
211                 /* Free transmitted slot */
212                 canque_free_outslot(obj->qends, obj->tx_qedge, obj->tx_slot);
213                 obj->tx_slot=NULL;
214         }
215
216         can_msgobj_clear_fl(obj,TX_PENDING);
217         cmd=canque_test_outslot(obj->qends, &obj->tx_qedge, &obj->tx_slot);
218         if(cmd<0)
219                 return;
220         can_msgobj_set_fl(obj,TX_PENDING);
221
222         if (chip->chipspecops->pre_write_config(chip, obj, &obj->tx_slot->msg)) {
223                 obj->ret = -1;
224                 canque_notify_inends(obj->tx_qedge, CANQUEUE_NOTIFY_ERRTX_PREP);
225                 canque_free_outslot(obj->qends, obj->tx_qedge, obj->tx_slot);
226                 obj->tx_slot=NULL;
227                 return;
228         }
229         if (chip->chipspecops->send_msg(chip, obj, &obj->tx_slot->msg)) {
230                 obj->ret = -1;
231                 canque_notify_inends(obj->tx_qedge, CANQUEUE_NOTIFY_ERRTX_SEND);
232                 canque_free_outslot(obj->qends, obj->tx_qedge, obj->tx_slot);
233                 obj->tx_slot=NULL;
234                 return;
235         }
236
237 }
238
239 void lpc17xx_read(struct canchip_t *chip, struct msgobj_t *obj) {
240
241
242                 CAN_recv(chip, &obj->rx_msg);
243                 
244                 // fill CAN message timestamp
245                 can_filltimestamp(&obj->rx_msg.timestamp);
246
247                 canque_filter_msg2edges(obj->qends, &obj->rx_msg);
248
249                 // release Receive buffer
250                 can_write_reg(chip, CAN_CMR_RRB, CAN_CMR_o);
251
252 }
253
254 int lpc17xx_fill_chipspecops(struct canchip_t *chip){
255
256         chip->max_objects=1;
257         chip->chip_irq = CAN_IRQn;
258         
259         lpc17xx_register(chip->chipspecops);
260
261         return 0;
262 }
263
264 int lpc17xx_register(struct chipspecops_t *chipspecops){
265
266         CANMSG("initializing lpc17xx can chip operations\n");
267
268         chipspecops->attach_to_chip = lpc17xx_attach_to_chip;
269         chipspecops->pre_read_config = lpc17xx_pre_read_config;
270         chipspecops->chip_config = lpc17xx_chip_config;
271         chipspecops->pre_write_config = lpc17xx_pre_write_config;
272         chipspecops->send_msg = lpc17xx_send_msg;
273         chipspecops->wakeup_tx = lpc17xx_wakeup_tx;
274         chipspecops->irq_handler = lpc17xx_irq_handler;
275
276         return 0;       
277
278 }
279
280
281 int lpc17xx_attach_to_chip(struct canchip_t *chip){
282
283         return 0;
284 }
285
286 int lpc17xx_pre_read_config(struct canchip_t *chip, struct msgobj_t *obj){
287
288         return 1;
289 }
290
291
292
293 //---------------------------------------------------------------------------------
294 //---------------------------------------------------------------------------------
295
296
297 static void CAN_configPin(){
298
299 //      CAN1 - select P0.0 as RD1. P0.1 as TD1
300
301         uint32_t pinsel0;
302         uint32_t pinmode0;
303         uint32_t pinmode_od0;
304         uint8_t pinsel0_val = 1;
305         uint8_t pinmode0_val = 0;
306         uint8_t pinmode_od0_val = 0;
307
308
309         pinsel0 = PINCON->PINSEL0;
310         pinsel0 &= ~CAN1_RX_MASK;
311         pinsel0 &= ~CAN1_TX_MASK;
312         pinsel0 |= __val2mfld(CAN1_RX_MASK, pinsel0_val);
313         pinsel0 |= __val2mfld(CAN1_TX_MASK, pinsel0_val);
314         PINCON->PINSEL0 = pinsel0;
315
316         pinmode0 = PINCON->PINMODE0;
317         pinmode0 &= ~CAN1_RX_MASK;
318         pinmode0 &= ~CAN1_TX_MASK;
319         pinmode0 |= __val2mfld(CAN1_RX_MASK, pinmode0_val);
320         pinmode0 |= __val2mfld(CAN1_TX_MASK, pinmode0_val);
321         PINCON->PINMODE0 = pinmode0;
322
323         pinmode_od0 = PINCON->PINMODE_OD0;
324         if (pinmode_od0_val){
325                 pinmode_od0 |= CAN1_RX_BIT;
326                 pinmode_od0 |= CAN1_TX_BIT;
327         }
328         else{
329                 pinmode_od0 &= ~CAN1_RX_BIT;
330                 pinmode_od0 &= ~CAN1_TX_BIT;
331         }
332         PINCON->PINMODE_OD0 = pinmode_od0;
333         
334
335 }
336
337 void CAN_recv(struct canchip_t *chip, canmsg_t* msg){
338
339         volatile uint32_t data;
340         uint32_t i;
341
342         // read data lenght
343         msg->length = (can_read_reg(chip, CAN_RFS_o)>>16) & 0xF;
344
345         // read identifier
346         msg->id = can_read_reg(chip, CAN_RID_o);
347
348         // EXT frame
349         if(can_read_reg(chip, CAN_RFS_o) & CAN_RFS_EXT)
350                 msg->flags |= MSG_EXT;
351         else
352                 msg->flags &= ~MSG_EXT;
353
354         
355         // RTR frame
356         if(can_read_reg(chip, CAN_RFS_o) & CAN_RFS_RTR)
357                 msg->flags |= MSG_RTR;
358         else
359                 msg->flags &= ~MSG_RTR;
360
361
362         // read data            
363         data = can_read_reg(chip, CAN_RDA_o);           
364         for(i=0; i<4; i++)
365                 msg->data[i] = (data>>(i*8)) & 0xFF;
366
367         data = can_read_reg(chip, CAN_RDB_o);   
368         for(i=4; i<8; i++)
369                 msg->data[i] = (data>>((i-4)*8)) & 0xFF;
370
371 }
372
373
374 void CAN_send(struct canchip_t *chip, canmsg_t* msg){
375
376         volatile uint32_t data;
377         volatile uint32_t can_tfi1;
378         uint32_t i=0;
379
380         // check status of TB1
381         while (!(can_read_reg(chip, CAN_SR_o) & CAN_SR_TBS1)){
382                 if(i++<MAX_TRANSMIT_WAIT_LOOPS)
383                         continue;
384
385                 // request command to abort transmission request
386                 can_write_reg(chip, CAN_CMR_AT, CAN_CMR_o);
387                 return;
388         }       
389
390         can_tfi1 = can_read_reg(chip, CAN_TFI1_o);
391
392         can_tfi1 &= ~0x000F0000;
393         can_tfi1 |= (msg->length)<<16;
394
395         // EXT frame
396         if(msg->flags & MSG_EXT)
397                 can_tfi1 |= CAN_TFI1_EXT;
398         else
399                 can_tfi1 &= ~CAN_TFI1_EXT;
400                 
401         // RTR frame
402         if(msg->flags & MSG_RTR)
403                 can_tfi1 |= CAN_TFI1_RTR;
404         else
405                 can_tfi1 &= ~CAN_TFI1_RTR;
406
407         can_write_reg(chip, can_tfi1, CAN_TFI1_o);
408
409
410         // write CAN ID
411         can_write_reg(chip, msg->id, CAN_TID1_o);
412
413
414         // write first 4 data bytes
415         data=0;
416         for(i=0; i<4; i++)
417                 data |= (msg->data[i])<<(i*8);
418
419         can_write_reg(chip, data, CAN_TDA1_o);
420
421         // write second 4 data bytes
422         data=0;
423         for(i=4; i<8; i++)
424                 data |= (msg->data[i])<<((i-4)*8);
425         
426         can_write_reg(chip, data, CAN_TDB1_o);
427
428 }
429
430 void CAN_set_bittiming(struct canchip_t *chip, uint32_t brp, uint32_t sjw, uint32_t tseg1, uint32_t tseg2){
431
432         uint8_t SAM = 0; // 0 = the bus is sampled once
433
434         brp--;
435         sjw--;
436         tseg1--;
437         tseg2--;
438
439         can_disable_irq(chip->chip_irq);
440         // enter reset mode
441         can_write_reg(chip, 1, CAN_MOD_o);
442
443
444         can_write_reg(chip, ((SAM<<23)|(tseg2<<20)|(tseg1<<16)|(sjw<<14)|(brp<<0)), CAN_BTR_o);
445
446
447         // return to normal operating 
448         can_write_reg(chip, 0, CAN_MOD_o);
449
450         can_enable_irq(chip->chip_irq);
451 }
452
453 void CAN_setBusTiming(struct canchip_t *chip){
454
455         uint32_t PCLK_CAN;
456         uint32_t res;
457
458         uint8_t tq_numb; // number of time quantum
459         uint8_t TSEG1, TSEG2;
460         uint8_t BRP;
461         uint8_t SJW;
462         uint8_t SAM;
463         uint8_t div;
464
465         TSEG1 = TSEG2 = BRP = 0;
466
467         // 0 = the bus is sampled once
468         SAM = 0;
469
470         // the Synchronization Jump Width (this value plus one) 
471         SJW = 3;
472
473         // get clock divide for CAN1    
474         div = __mfld2val(PCLK_CAN1_MASK, SC->PCLKSEL0);
475         switch(div){
476                 case 0:
477                         div = 4;
478                         break;
479                 case 1:
480                         div = 1;
481                         break;
482                 case 2:
483                         div = 2;
484                         break;
485                 case 3:
486                         // only for CAN, for other peripherials '11' value means div=8
487                         div = 6;
488                         break;
489         }
490
491
492         PCLK_CAN = system_frequency / div;
493
494         res = PCLK_CAN / (chip->baudrate);
495
496
497         // calculation of tq_numb - number of time quantum (must be in <8,25>)
498         // tq_numb = TSEG1 + TSEG2 + 3
499
500         for(tq_numb=25; tq_numb>=8; tq_numb--){
501                 
502                 if ((res%tq_numb)==0){
503                 
504                         // Baud Rate Prescaler. The PCLK clock is divided by (this value plus one) to produce the CAN clock.
505                         BRP = (res / tq_numb) - 1;
506
507                         // sync. segment allways 1 tq
508                         tq_numb--;
509
510                         // number of tq from the sample point to the next nominal Sync. point (this value plus one)                     
511                         TSEG2 = (tq_numb/3) - 1;
512
513                         // number of tq from Sync. point to the sample point (this value plus one)                      
514                         TSEG1 = tq_numb - (tq_numb/3) - 1;
515
516                         break;
517                 }
518         }
519
520         can_write_reg(chip, ((SAM<<23)|(TSEG2<<20)|(TSEG1<<16)|(SJW<<14)|(BRP<<0)), CAN_BTR_o);
521
522 }
523
524 void CAN_init(struct canchip_t *chip){
525
526         uint32_t tmp;
527         uint32_t pclksel0;
528         uint32_t val;
529         uint32_t i;
530         
531         printf("CAN INIT, baudrate: %d\n", (int) chip->baudrate);
532
533         // configure CAN1 pins 
534         CAN_configPin();
535
536         // turn on power and clock for CAN1 
537         SC->PCONP |= PCCAN1;
538         
539         // set clock divide for CAN1 
540
541         val = 0x00; // 00       PCLK_peripheral = CCLK/4 
542         pclksel0 = SC->PCLKSEL0;
543         pclksel0 &= ~PCLK_CAN1_MASK;
544         pclksel0 &= ~PCLK_CAN2_MASK;
545         pclksel0 &= ~PCLK_ACF_MASK;
546         pclksel0 |= __val2mfld(PCLK_CAN1_MASK, val);
547         pclksel0 |= __val2mfld(PCLK_CAN2_MASK, val);
548         pclksel0 |= __val2mfld(PCLK_ACF_MASK, val);
549         SC->PCLKSEL0 = pclksel0;
550         
551         // enter reset mode
552         can_write_reg(chip, 1, CAN_MOD_o);
553
554         // disable all CAN interrupts
555         can_write_reg(chip, 0, CAN_IER_o);
556
557         // reset value of Global Status Register (global controller status and error counters) 
558         can_write_reg(chip, 0x3C, CAN_GSR_o);
559
560         // request command to release Rx, Tx buffer and clear data overrun 
561         can_write_reg(chip, (CAN_CMR_AT | CAN_CMR_RRB | CAN_CMR_CDO), CAN_CMR_o);
562
563         // read to clear interrupt pending in Interrupt Capture Register 
564         tmp = can_read_reg(chip, CAN_ICR_o);
565
566         // set bus timing 
567         CAN_setBusTiming(chip);
568
569         // return to normal operating 
570         can_write_reg(chip, 0, CAN_MOD_o);
571
572
573         //--------------------------
574
575         // Acceptance Filter Off Mode
576         CANAF_AFMR = 0x01;
577
578         // clear RAM masks
579         for (i = 0; i < 512; i++) {
580                 CANAF_RAM->mask[i] = 0x00;
581         }
582
583         CANAF_SFF_sa = 0x00;
584         CANAF_SFF_GRP_sa = 0x00;
585         CANAF_EFF_sa = 0x00;
586         CANAF_EFF_GRP_sa = 0x00;
587         CANAF_ENDofTable = 0x00;
588
589         // Acceptance Filter Bypass Mode - all messages accepted
590         CANAF_AFMR = 0x02;
591
592         //--------------------------
593
594
595         // enable interrupt after transmit
596         // enable receive interrupt
597         // enable data overrun interrupt
598         can_write_reg(chip, (CAN_IER_TIE1 | CAN_IER_RIE | CAN_IER_DOIE), CAN_IER_o);
599         
600         
601 }
602