1 #include "can/lpc17xx_can.h"
3 static void CAN_configPin();
6 // board can-lmc1 specific functions:
8 int can_lmc1_register(struct hwspecops_t *hwspecops){
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;
22 int can_lmc1_init_hw_data(struct candevice_t *candev){
25 candev->nr_82527_chips=0;
26 candev->nr_sja1000_chips=0;
27 candev->nr_all_chips=1;
33 int can_lmc1_init_chip_data(struct candevice_t *candev, int chipnr){
35 struct can_bittiming_const *btc;
36 struct can_lmc1_chip_data *chip_data;
38 // used CAN1 peripherial -> CAN1 registers base
39 candev->chip[chipnr]->chip_base_addr = CAN1_REGS_BASE;
41 candev->chip[chipnr]->clock = system_frequency / 4;
43 lpc17xx_fill_chipspecops(candev->chip[chipnr]);
45 candev->chip[chipnr]->chip_data=(void *)malloc(sizeof(struct can_lmc1_chip_data));
46 if (candev->chip[chipnr]->chip_data==NULL)
50 chip_data = (struct can_lmc1_chip_data*) candev->chip[chipnr]->chip_data;
52 btc = &chip_data->btc;
54 // set bittiming constants
67 int can_lmc1_init_obj_data(struct canchip_t *chip, int objnr){
72 void can_lmc1_write_register(unsigned data, unsigned long address){
73 (*(volatile uint32_t*)(address)) = data;
76 unsigned can_lmc1_read_register(unsigned long address){
77 return (*(volatile uint32_t*)(address));
80 int can_lmc1_request_io(struct candevice_t *candev)
85 int can_lmc1_reset(struct candevice_t *candev)
90 int can_lmc1_program_irq(struct candevice_t *candev)
95 //---------------------------------------------------------------------------------
96 //---------------------------------------------------------------------------------
99 // lpc17xx can chip specific functions:
102 * lpc17xx_baud_rate: - set communication parameters.
103 * @chip: pointer to chip state structure
104 * @rate: baud rate in Hz
105 * @clock: frequency of CAN clock in Hz
106 * @sjw: synchronization jump width (0-3) prescaled clock cycles
107 * @sampl_pt: sample point in % (0-100) sets (TSEG1+1)/(TSEG1+TSEG2+2) ratio
109 int lpc17xx_baud_rate(struct canchip_t *chip, int rate, int clock, int sjw,
110 int sampl_pt, int flags)
112 int best_error = 1000000000, error;
113 int best_tseg=0, best_brp=0, best_rate=0, brp=0;
114 int tseg=0, tseg1=0, tseg2=0;
116 struct can_lmc1_chip_data *chip_data = (struct can_lmc1_chip_data*) chip->chip_data;
118 struct can_bittiming_const *btc = &chip_data->btc;
120 /* tseg even = round down, odd = round up */
121 for (tseg=(0+0+2)*2; tseg<=(btc->tseg2_max+btc->tseg1_max+2)*2+1; tseg++) {
122 brp = clock/((1+tseg/2)*rate)+tseg%2;
123 if (brp == 0 || brp > 64)
125 error = rate - clock/(brp*(1+tseg/2));
128 if (error <= best_error) {
132 best_rate = clock/(brp*(1+tseg/2));
135 if (best_error && (rate/best_error < 10)) {
136 CANMSG("baud rate %d is not possible with %d Hz clock\n",
138 CANMSG("%d bps. brp=%d, best_tseg=%d, tseg1=%d, tseg2=%d\n",
139 best_rate, best_brp, best_tseg, tseg1, tseg2);
142 tseg2 = best_tseg-(sampl_pt*(best_tseg+1))/100;
145 if (tseg2 > btc->tseg2_max)
146 tseg2 = btc->tseg2_max;
147 tseg1 = best_tseg-tseg2-2;
148 if (tseg1>btc->tseg1_max) {
149 tseg1 = btc->tseg1_max;
150 tseg2 = best_tseg-tseg1-2;
153 DEBUGMSG("Setting %d bps.\n", best_rate);
154 DEBUGMSG("brp=%d, best_tseg=%d, tseg1=%d, tseg2=%d, sampl_pt=%d\n",
155 best_brp, best_tseg, tseg1, tseg2,
156 (100*(best_tseg-tseg2)/(best_tseg+1)));
159 if(chip->chipspecops->set_bittiming(chip, ++best_brp, ++sjw, ++tseg1, ++tseg2) < 0)
167 int lpc17xx_chip_config(struct canchip_t *chip){
172 chip->baudrate=1000000;
174 if (lpc17xx_baud_rate(chip,chip->baudrate,chip->clock,0,75,0))
180 int lpc17xx_pre_write_config(struct canchip_t *chip, struct msgobj_t *obj,
181 struct canmsg_t *msg)
185 // check status of TB1
186 while (!(can_read_reg(chip, CAN_SR_o) & CAN_SR_TBS1)){
187 if(i++<MAX_TRANSMIT_WAIT_LOOPS)
190 // request command to abort transmission request
191 can_write_reg(chip, CAN_CMR_AT, CAN_CMR_o);
200 int lpc17xx_send_msg(struct canchip_t *chip, struct msgobj_t *obj,
201 struct canmsg_t *msg)
205 // write transmission request
206 can_write_reg(chip, (CAN_CMR_TR | CAN_CMR_STB1), CAN_CMR_o);
208 // check transmission complete status
209 while (!(can_read_reg(chip, CAN_SR_o) & CAN_SR_TCS1)){
210 if(i++<MAX_TRANSMIT_WAIT_LOOPS)
213 CANMSG("Abort transmission request\n");
215 // request command to abort transmission request
216 can_write_reg(chip, CAN_CMR_AT, CAN_CMR_o);
223 int lpc17xx_wakeup_tx(struct canchip_t *chip, struct msgobj_t *obj)
226 can_preempt_disable();
228 can_msgobj_set_fl(obj,TX_PENDING);
229 can_msgobj_set_fl(obj,TX_REQUEST);
231 while(!can_msgobj_test_and_set_fl(obj,TX_LOCK)){
232 can_msgobj_clear_fl(obj,TX_REQUEST);
234 if (can_read_reg(chip, CAN_SR_o) & CAN_SR_TBS1){
236 lpc17xx_irq_write_handler(chip, obj);
239 can_msgobj_clear_fl(obj,TX_LOCK);
240 if(!can_msgobj_test_fl(obj,TX_REQUEST)) break;
244 can_preempt_enable();
249 int lpc17xx_irq_handler(int irq, struct canchip_t *chip)
253 struct msgobj_t *obj;
254 obj = chip->msgobj[0];
256 i = can_read_reg(chip, CAN_ICR_o);
258 if(i & (CAN_ICR_TI1 | CAN_ICR_RI)){
260 if(can_read_reg(chip, CAN_SR_o) & CAN_SR_RBS) {
261 lpc17xx_read(chip,obj);
266 if ((can_msgobj_test_fl(obj,TX_PENDING)) || (can_msgobj_test_fl(obj,TX_REQUEST))) {
268 can_msgobj_set_fl(obj,TX_REQUEST);
270 while(!can_msgobj_test_and_set_fl(obj,TX_LOCK)){
273 can_msgobj_clear_fl(obj,TX_REQUEST);
275 if (can_read_reg(chip, CAN_SR_o) & CAN_SR_TBS1){
277 lpc17xx_irq_write_handler(chip, obj);
280 can_msgobj_clear_fl(obj,TX_LOCK);
281 if(!can_msgobj_test_fl(obj,TX_REQUEST)) break;
288 can_write_reg(chip, CAN_CMR_CDO, CAN_CMR_o); // clear data overrun
291 return CANCHIP_IRQ_HANDLED;
295 void lpc17xx_irq_write_handler(struct canchip_t *chip, struct msgobj_t *obj)
301 /* Do local transmitted message distribution if enabled */
303 /* fill CAN message timestamp */
304 can_filltimestamp(&obj->tx_slot->msg.timestamp);
306 obj->tx_slot->msg.flags |= MSG_LOCAL;
307 canque_filter_msg2edges(obj->qends, &obj->tx_slot->msg);
309 /* Free transmitted slot */
310 canque_free_outslot(obj->qends, obj->tx_qedge, obj->tx_slot);
314 can_msgobj_clear_fl(obj,TX_PENDING);
315 cmd=canque_test_outslot(obj->qends, &obj->tx_qedge, &obj->tx_slot);
318 can_msgobj_set_fl(obj,TX_PENDING);
320 if (chip->chipspecops->pre_write_config(chip, obj, &obj->tx_slot->msg)) {
322 canque_notify_inends(obj->tx_qedge, CANQUEUE_NOTIFY_ERRTX_PREP);
323 canque_free_outslot(obj->qends, obj->tx_qedge, obj->tx_slot);
327 if (chip->chipspecops->send_msg(chip, obj, &obj->tx_slot->msg)) {
329 canque_notify_inends(obj->tx_qedge, CANQUEUE_NOTIFY_ERRTX_SEND);
330 canque_free_outslot(obj->qends, obj->tx_qedge, obj->tx_slot);
337 void lpc17xx_read(struct canchip_t *chip, struct msgobj_t *obj) {
340 CAN_recv(chip, &obj->rx_msg);
342 // fill CAN message timestamp
343 can_filltimestamp(&obj->rx_msg.timestamp);
345 canque_filter_msg2edges(obj->qends, &obj->rx_msg);
347 // release Receive buffer
348 can_write_reg(chip, CAN_CMR_RRB, CAN_CMR_o);
352 int lpc17xx_set_bittiming(struct canchip_t *chip, int brp, int sjw, int tseg1, int tseg2){
354 uint8_t SAM = 0; // 0 = the bus is sampled once
370 CANMSG("BRP: %d, SJW: %d, TSEG1: %d, TSEG2: %d \n", brp+1, sjw+1, tseg1+1, tseg2+1);
372 can_disable_irq(chip->chip_irq);
375 can_write_reg(chip, 1, CAN_MOD_o);
377 // set bittiming register
378 can_write_reg(chip, ((SAM<<23)|(tseg2<<20)|(tseg1<<16)|(sjw<<14)|(brp<<0)), CAN_BTR_o);
380 // return to normal operating
381 can_write_reg(chip, 0, CAN_MOD_o);
383 can_enable_irq(chip->chip_irq);
388 int lpc17xx_fill_chipspecops(struct canchip_t *chip){
391 chip->chip_irq = CAN_IRQn;
393 lpc17xx_register(chip->chipspecops);
398 int lpc17xx_register(struct chipspecops_t *chipspecops){
400 CANMSG("initializing lpc17xx can chip operations\n");
402 chipspecops->attach_to_chip = lpc17xx_attach_to_chip;
403 chipspecops->pre_read_config = lpc17xx_pre_read_config;
404 chipspecops->chip_config = lpc17xx_chip_config;
405 chipspecops->pre_write_config = lpc17xx_pre_write_config;
406 chipspecops->send_msg = lpc17xx_send_msg;
407 chipspecops->wakeup_tx = lpc17xx_wakeup_tx;
408 chipspecops->irq_handler = lpc17xx_irq_handler;
410 chipspecops->set_bittiming = lpc17xx_set_bittiming;
417 int lpc17xx_attach_to_chip(struct canchip_t *chip){
422 int lpc17xx_pre_read_config(struct canchip_t *chip, struct msgobj_t *obj){
429 //---------------------------------------------------------------------------------
430 //---------------------------------------------------------------------------------
433 static void CAN_configPin(){
435 // CAN1 - select P0.0 as RD1. P0.1 as TD1
439 uint32_t pinmode_od0;
440 uint8_t pinsel0_val = 1;
441 uint8_t pinmode0_val = 0;
442 uint8_t pinmode_od0_val = 0;
445 pinsel0 = PINCON->PINSEL0;
446 pinsel0 &= ~CAN1_RX_MASK;
447 pinsel0 &= ~CAN1_TX_MASK;
448 pinsel0 |= __val2mfld(CAN1_RX_MASK, pinsel0_val);
449 pinsel0 |= __val2mfld(CAN1_TX_MASK, pinsel0_val);
450 PINCON->PINSEL0 = pinsel0;
452 pinmode0 = PINCON->PINMODE0;
453 pinmode0 &= ~CAN1_RX_MASK;
454 pinmode0 &= ~CAN1_TX_MASK;
455 pinmode0 |= __val2mfld(CAN1_RX_MASK, pinmode0_val);
456 pinmode0 |= __val2mfld(CAN1_TX_MASK, pinmode0_val);
457 PINCON->PINMODE0 = pinmode0;
459 pinmode_od0 = PINCON->PINMODE_OD0;
460 if (pinmode_od0_val){
461 pinmode_od0 |= CAN1_RX_BIT;
462 pinmode_od0 |= CAN1_TX_BIT;
465 pinmode_od0 &= ~CAN1_RX_BIT;
466 pinmode_od0 &= ~CAN1_TX_BIT;
468 PINCON->PINMODE_OD0 = pinmode_od0;
473 void CAN_recv(struct canchip_t *chip, canmsg_t* msg){
475 volatile uint32_t data;
479 msg->length = (can_read_reg(chip, CAN_RFS_o)>>16) & 0xF;
482 msg->id = can_read_reg(chip, CAN_RID_o);
485 if(can_read_reg(chip, CAN_RFS_o) & CAN_RFS_EXT)
486 msg->flags |= MSG_EXT;
488 msg->flags &= ~MSG_EXT;
492 if(can_read_reg(chip, CAN_RFS_o) & CAN_RFS_RTR)
493 msg->flags |= MSG_RTR;
495 msg->flags &= ~MSG_RTR;
499 data = can_read_reg(chip, CAN_RDA_o);
501 msg->data[i] = (data>>(i*8)) & 0xFF;
503 data = can_read_reg(chip, CAN_RDB_o);
505 msg->data[i] = (data>>((i-4)*8)) & 0xFF;
510 void CAN_send(struct canchip_t *chip, canmsg_t* msg){
512 volatile uint32_t data;
513 volatile uint32_t can_tfi1;
516 can_tfi1 = can_read_reg(chip, CAN_TFI1_o);
518 can_tfi1 &= ~0x000F0000;
519 can_tfi1 |= (msg->length)<<16;
522 if(msg->flags & MSG_EXT)
523 can_tfi1 |= CAN_TFI1_EXT;
525 can_tfi1 &= ~CAN_TFI1_EXT;
528 if(msg->flags & MSG_RTR)
529 can_tfi1 |= CAN_TFI1_RTR;
531 can_tfi1 &= ~CAN_TFI1_RTR;
533 can_write_reg(chip, can_tfi1, CAN_TFI1_o);
537 can_write_reg(chip, msg->id, CAN_TID1_o);
540 // write first 4 data bytes
543 data |= (msg->data[i])<<(i*8);
545 can_write_reg(chip, data, CAN_TDA1_o);
547 // write second 4 data bytes
550 data |= (msg->data[i])<<((i-4)*8);
552 can_write_reg(chip, data, CAN_TDB1_o);
556 void CAN_init(struct canchip_t *chip){
563 // configure CAN1 pins
566 // turn on power and clock for CAN1
569 // set clock divide for CAN1
571 val = 0x00; // 00 PCLK_peripheral = CCLK/4
572 pclksel0 = SC->PCLKSEL0;
573 pclksel0 &= ~PCLK_CAN1_MASK;
574 pclksel0 &= ~PCLK_CAN2_MASK;
575 pclksel0 &= ~PCLK_ACF_MASK;
576 pclksel0 |= __val2mfld(PCLK_CAN1_MASK, val);
577 pclksel0 |= __val2mfld(PCLK_CAN2_MASK, val);
578 pclksel0 |= __val2mfld(PCLK_ACF_MASK, val);
579 SC->PCLKSEL0 = pclksel0;
582 can_write_reg(chip, 1, CAN_MOD_o);
584 // disable all CAN interrupts
585 can_write_reg(chip, 0, CAN_IER_o);
587 // reset value of Global Status Register (global controller status and error counters)
588 can_write_reg(chip, 0x3C, CAN_GSR_o);
590 // request command to release Rx, Tx buffer and clear data overrun
591 can_write_reg(chip, (CAN_CMR_AT | CAN_CMR_RRB | CAN_CMR_CDO), CAN_CMR_o);
593 // read to clear interrupt pending in Interrupt Capture Register
594 tmp = can_read_reg(chip, CAN_ICR_o);
596 // return to normal operating
597 can_write_reg(chip, 0, CAN_MOD_o);
600 //--------------------------
602 // Acceptance Filter Off Mode
606 for (i = 0; i < 512; i++) {
607 CANAF_RAM->mask[i] = 0x00;
611 CANAF_SFF_GRP_sa = 0x00;
613 CANAF_EFF_GRP_sa = 0x00;
614 CANAF_ENDofTable = 0x00;
616 // Acceptance Filter Bypass Mode - all messages accepted
619 //--------------------------
622 // enable interrupt after transmit
623 // enable receive interrupt
624 // enable data overrun interrupt
625 can_write_reg(chip, (CAN_IER_TIE1 | CAN_IER_RIE | CAN_IER_DOIE), CAN_IER_o);