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_lmc1_chip_data *chip_data;
37 // used CAN1 peripherial -> CAN1 registers base
38 candev->chip[chipnr]->chip_base_addr = CAN1_REGS_BASE;
40 candev->chip[chipnr]->clock = system_frequency / 4;
42 lpc17xx_fill_chipspecops(candev->chip[chipnr]);
44 candev->chip[chipnr]->chip_data=(void *)malloc(sizeof(struct can_lmc1_chip_data));
45 if (candev->chip[chipnr]->chip_data==NULL)
49 chip_data = (struct can_lmc1_chip_data*) candev->chip[chipnr]->chip_data;
55 int can_lmc1_init_obj_data(struct canchip_t *chip, int objnr){
60 void can_lmc1_write_register(unsigned data, unsigned long address){
61 (*(volatile uint32_t*)(address)) = data;
64 unsigned can_lmc1_read_register(unsigned long address){
65 return (*(volatile uint32_t*)(address));
68 int can_lmc1_request_io(struct candevice_t *candev)
73 int can_lmc1_reset(struct candevice_t *candev)
78 int can_lmc1_program_irq(struct candevice_t *candev)
83 //---------------------------------------------------------------------------------
84 //---------------------------------------------------------------------------------
87 // lpc17xx can chip specific functions:
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
97 int lpc17xx_baud_rate(struct canchip_t *chip, int rate, int clock, int sjw,
98 int sampl_pt, int flags)
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;
104 struct can_bittiming_const btc_buff;
105 struct can_bittiming_const *btc = &btc_buff;
107 chip->chipspecops->get_bittiming_const(chip, btc);
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)
114 error = rate - clock/(brp*(1+tseg/2));
117 if (error <= best_error) {
121 best_rate = clock/(brp*(1+tseg/2));
124 if (best_error && (rate/best_error < 10)) {
125 CANMSG("baud rate %d is not possible with %d Hz clock\n",
127 CANMSG("%d bps. brp=%d, best_tseg=%d, tseg1=%d, tseg2=%d\n",
128 best_rate, best_brp, best_tseg, tseg1, tseg2);
131 tseg2 = best_tseg-(sampl_pt*(best_tseg+1))/100;
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;
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)));
148 if(chip->chipspecops->set_bittiming(chip, ++best_brp, ++sjw, ++tseg1, ++tseg2) < 0)
156 int lpc17xx_chip_config(struct canchip_t *chip){
161 chip->baudrate=1000000;
163 if (lpc17xx_baud_rate(chip,chip->baudrate,chip->clock,0,75,0))
169 int lpc17xx_pre_write_config(struct canchip_t *chip, struct msgobj_t *obj,
170 struct canmsg_t *msg)
174 // check status of TB1
175 while (!(can_read_reg(chip, CAN_SR_o) & CAN_SR_TBS1)){
176 if(i++<MAX_TRANSMIT_WAIT_LOOPS)
179 // request command to abort transmission request
180 can_write_reg(chip, CAN_CMR_AT, CAN_CMR_o);
189 int lpc17xx_send_msg(struct canchip_t *chip, struct msgobj_t *obj,
190 struct canmsg_t *msg)
194 // write transmission request
195 can_write_reg(chip, (CAN_CMR_TR | CAN_CMR_STB1), CAN_CMR_o);
197 // check transmission complete status
198 while (!(can_read_reg(chip, CAN_SR_o) & CAN_SR_TCS1)){
199 if(i++<MAX_TRANSMIT_WAIT_LOOPS)
202 CANMSG("Abort transmission request\n");
204 // request command to abort transmission request
205 can_write_reg(chip, CAN_CMR_AT, CAN_CMR_o);
212 int lpc17xx_wakeup_tx(struct canchip_t *chip, struct msgobj_t *obj)
215 can_preempt_disable();
217 can_msgobj_set_fl(obj,TX_PENDING);
218 can_msgobj_set_fl(obj,TX_REQUEST);
220 while(!can_msgobj_test_and_set_fl(obj,TX_LOCK)){
221 can_msgobj_clear_fl(obj,TX_REQUEST);
223 if (can_read_reg(chip, CAN_SR_o) & CAN_SR_TBS1){
225 lpc17xx_irq_write_handler(chip, obj);
228 can_msgobj_clear_fl(obj,TX_LOCK);
229 if(!can_msgobj_test_fl(obj,TX_REQUEST)) break;
233 can_preempt_enable();
238 int lpc17xx_irq_handler(int irq, struct canchip_t *chip)
242 struct msgobj_t *obj;
243 obj = chip->msgobj[0];
245 i = can_read_reg(chip, CAN_ICR_o);
247 if(i & (CAN_ICR_TI1 | CAN_ICR_RI)){
249 if(can_read_reg(chip, CAN_SR_o) & CAN_SR_RBS) {
250 lpc17xx_read(chip,obj);
255 if ((can_msgobj_test_fl(obj,TX_PENDING)) || (can_msgobj_test_fl(obj,TX_REQUEST))) {
257 can_msgobj_set_fl(obj,TX_REQUEST);
259 while(!can_msgobj_test_and_set_fl(obj,TX_LOCK)){
262 can_msgobj_clear_fl(obj,TX_REQUEST);
264 if (can_read_reg(chip, CAN_SR_o) & CAN_SR_TBS1){
266 lpc17xx_irq_write_handler(chip, obj);
269 can_msgobj_clear_fl(obj,TX_LOCK);
270 if(!can_msgobj_test_fl(obj,TX_REQUEST)) break;
277 can_write_reg(chip, CAN_CMR_CDO, CAN_CMR_o); // clear data overrun
280 return CANCHIP_IRQ_HANDLED;
284 void lpc17xx_irq_write_handler(struct canchip_t *chip, struct msgobj_t *obj)
290 /* Do local transmitted message distribution if enabled */
292 /* fill CAN message timestamp */
293 can_filltimestamp(&obj->tx_slot->msg.timestamp);
295 obj->tx_slot->msg.flags |= MSG_LOCAL;
296 canque_filter_msg2edges(obj->qends, &obj->tx_slot->msg);
298 /* Free transmitted slot */
299 canque_free_outslot(obj->qends, obj->tx_qedge, obj->tx_slot);
303 can_msgobj_clear_fl(obj,TX_PENDING);
304 cmd=canque_test_outslot(obj->qends, &obj->tx_qedge, &obj->tx_slot);
307 can_msgobj_set_fl(obj,TX_PENDING);
309 if (chip->chipspecops->pre_write_config(chip, obj, &obj->tx_slot->msg)) {
311 canque_notify_inends(obj->tx_qedge, CANQUEUE_NOTIFY_ERRTX_PREP);
312 canque_free_outslot(obj->qends, obj->tx_qedge, obj->tx_slot);
316 if (chip->chipspecops->send_msg(chip, obj, &obj->tx_slot->msg)) {
318 canque_notify_inends(obj->tx_qedge, CANQUEUE_NOTIFY_ERRTX_SEND);
319 canque_free_outslot(obj->qends, obj->tx_qedge, obj->tx_slot);
326 void lpc17xx_read(struct canchip_t *chip, struct msgobj_t *obj) {
329 CAN_recv(chip, &obj->rx_msg);
331 // fill CAN message timestamp
332 can_filltimestamp(&obj->rx_msg.timestamp);
334 canque_filter_msg2edges(obj->qends, &obj->rx_msg);
336 // release Receive buffer
337 can_write_reg(chip, CAN_CMR_RRB, CAN_CMR_o);
341 int lpc17xx_set_bittiming(struct canchip_t *chip, int brp, int sjw, int tseg1, int tseg2){
343 uint8_t SAM = 0; // 0 = the bus is sampled once
359 CANMSG("BRP: %d, SJW: %d, TSEG1: %d, TSEG2: %d \n", brp+1, sjw+1, tseg1+1, tseg2+1);
361 can_disable_irq(chip->chip_irq);
364 can_write_reg(chip, 1, CAN_MOD_o);
366 // set bittiming register
367 can_write_reg(chip, ((SAM<<23)|(tseg2<<20)|(tseg1<<16)|(sjw<<14)|(brp<<0)), CAN_BTR_o);
369 // return to normal operating
370 can_write_reg(chip, 0, CAN_MOD_o);
372 can_enable_irq(chip->chip_irq);
377 int lpc17xx_get_bittiming_const(struct canchip_t *chip, struct can_bittiming_const *btc) {
391 int lpc17xx_fill_chipspecops(struct canchip_t *chip){
394 chip->chip_irq = CAN_IRQn;
396 lpc17xx_register(chip->chipspecops);
401 int lpc17xx_register(struct chipspecops_t *chipspecops){
403 CANMSG("initializing lpc17xx can chip operations\n");
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;
413 chipspecops->set_bittiming = lpc17xx_set_bittiming;
414 chipspecops->get_bittiming_const = lpc17xx_get_bittiming_const;
421 int lpc17xx_attach_to_chip(struct canchip_t *chip){
426 int lpc17xx_pre_read_config(struct canchip_t *chip, struct msgobj_t *obj){
433 //---------------------------------------------------------------------------------
434 //---------------------------------------------------------------------------------
437 static void CAN_configPin(){
439 // CAN1 - select P0.0 as RD1. P0.1 as TD1
443 uint32_t pinmode_od0;
444 uint8_t pinsel0_val = 1;
445 uint8_t pinmode0_val = 0;
446 uint8_t pinmode_od0_val = 0;
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;
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;
463 pinmode_od0 = PINCON->PINMODE_OD0;
464 if (pinmode_od0_val){
465 pinmode_od0 |= CAN1_RX_BIT;
466 pinmode_od0 |= CAN1_TX_BIT;
469 pinmode_od0 &= ~CAN1_RX_BIT;
470 pinmode_od0 &= ~CAN1_TX_BIT;
472 PINCON->PINMODE_OD0 = pinmode_od0;
477 void CAN_recv(struct canchip_t *chip, canmsg_t* msg){
479 volatile uint32_t data;
483 msg->length = (can_read_reg(chip, CAN_RFS_o)>>16) & 0xF;
486 msg->id = can_read_reg(chip, CAN_RID_o);
489 if(can_read_reg(chip, CAN_RFS_o) & CAN_RFS_EXT)
490 msg->flags |= MSG_EXT;
492 msg->flags &= ~MSG_EXT;
496 if(can_read_reg(chip, CAN_RFS_o) & CAN_RFS_RTR)
497 msg->flags |= MSG_RTR;
499 msg->flags &= ~MSG_RTR;
503 data = can_read_reg(chip, CAN_RDA_o);
505 msg->data[i] = (data>>(i*8)) & 0xFF;
507 data = can_read_reg(chip, CAN_RDB_o);
509 msg->data[i] = (data>>((i-4)*8)) & 0xFF;
514 void CAN_send(struct canchip_t *chip, canmsg_t* msg){
516 volatile uint32_t data;
517 volatile uint32_t can_tfi1;
520 can_tfi1 = can_read_reg(chip, CAN_TFI1_o);
522 can_tfi1 &= ~0x000F0000;
523 can_tfi1 |= (msg->length)<<16;
526 if(msg->flags & MSG_EXT)
527 can_tfi1 |= CAN_TFI1_EXT;
529 can_tfi1 &= ~CAN_TFI1_EXT;
532 if(msg->flags & MSG_RTR)
533 can_tfi1 |= CAN_TFI1_RTR;
535 can_tfi1 &= ~CAN_TFI1_RTR;
537 can_write_reg(chip, can_tfi1, CAN_TFI1_o);
541 can_write_reg(chip, msg->id, CAN_TID1_o);
544 // write first 4 data bytes
547 data |= (msg->data[i])<<(i*8);
549 can_write_reg(chip, data, CAN_TDA1_o);
551 // write second 4 data bytes
554 data |= (msg->data[i])<<((i-4)*8);
556 can_write_reg(chip, data, CAN_TDB1_o);
560 void CAN_init(struct canchip_t *chip){
567 // configure CAN1 pins
570 // turn on power and clock for CAN1
573 // set clock divide for CAN1
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;
586 can_write_reg(chip, 1, CAN_MOD_o);
588 // disable all CAN interrupts
589 can_write_reg(chip, 0, CAN_IER_o);
591 // reset value of Global Status Register (global controller status and error counters)
592 can_write_reg(chip, 0x3C, CAN_GSR_o);
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);
597 // read to clear interrupt pending in Interrupt Capture Register
598 tmp = can_read_reg(chip, CAN_ICR_o);
600 // return to normal operating
601 can_write_reg(chip, 0, CAN_MOD_o);
604 //--------------------------
606 // Acceptance Filter Off Mode
610 for (i = 0; i < 512; i++) {
611 CANAF_RAM->mask[i] = 0x00;
615 CANAF_SFF_GRP_sa = 0x00;
617 CANAF_EFF_GRP_sa = 0x00;
618 CANAF_ENDofTable = 0x00;
620 // Acceptance Filter Bypass Mode - all messages accepted
623 //--------------------------
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);