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