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