1 #include "can/lpc17xx_can.h"
3 static void CAN_configPin();
4 static void CAN_setBusTiming(struct canchip_t *chip);
6 #define MAX_TRANSMIT_WAIT_LOOPS 20
8 //---------------------------------------------------------------------------------
9 //---------------------------------------------------------------------------------
12 // board can-lmc1 specific functions:
14 int can_lmc1_register(struct hwspecops_t *hwspecops){
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;
28 int can_lmc1_init_hw_data(struct candevice_t *candev){
31 candev->nr_82527_chips=0;
32 candev->nr_sja1000_chips=0;
33 candev->nr_all_chips=1;
39 int can_lmc1_init_chip_data(struct candevice_t *candev, int chipnr){
41 // used CAN1 peripherial -> CAN1 registers base
42 candev->chip[chipnr]->chip_base_addr = CAN1_REGS_BASE;
44 lpc17xx_fill_chipspecops(candev->chip[chipnr]);
46 candev->chip[chipnr]->chip_data=(void *)malloc(sizeof(struct can_lmc1_chip_data));
47 if (candev->chip[chipnr]->chip_data==NULL)
53 int can_lmc1_init_obj_data(struct canchip_t *chip, int objnr){
58 void can_lmc1_write_register(unsigned data, unsigned long address){
59 (*(volatile uint32_t*)(address)) = data;
62 unsigned can_lmc1_read_register(unsigned long address){
63 return (*(volatile uint32_t*)(address));
66 int can_lmc1_request_io(struct candevice_t *candev)
71 int can_lmc1_reset(struct candevice_t *candev)
76 int can_lmc1_program_irq(struct candevice_t *candev)
81 //---------------------------------------------------------------------------------
82 //---------------------------------------------------------------------------------
85 // lpc17xx can chip specific functions:
88 int lpc17xx_chip_config(struct canchip_t *chip){
95 int lpc17xx_pre_write_config(struct canchip_t *chip, struct msgobj_t *obj,
104 int lpc17xx_send_msg(struct canchip_t *chip, struct msgobj_t *obj,
105 struct canmsg_t *msg)
109 // write transmission request
110 can_write_reg(chip, (CAN_CMR_TR | CAN_CMR_STB1), CAN_CMR_o);
112 while (!(can_read_reg(chip, CAN_SR_o) & (1<<3))){
113 if(i++<MAX_TRANSMIT_WAIT_LOOPS)
116 // request command to abort transmission request
117 can_write_reg(chip, CAN_CMR_AT, CAN_CMR_o);
124 int lpc17xx_wakeup_tx(struct canchip_t *chip, struct msgobj_t *obj)
127 can_preempt_disable();
129 can_msgobj_set_fl(obj,TX_PENDING);
130 can_msgobj_set_fl(obj,TX_REQUEST);
132 while(!can_msgobj_test_and_set_fl(obj,TX_LOCK)){
133 can_msgobj_clear_fl(obj,TX_REQUEST);
135 if (can_read_reg(chip, CAN_SR_o) & CAN_SR_TBS1){
137 lpc17xx_irq_write_handler(chip, obj);
140 can_msgobj_clear_fl(obj,TX_LOCK);
141 if(!can_msgobj_test_fl(obj,TX_REQUEST)) break;
145 can_preempt_enable();
150 int lpc17xx_irq_handler(int irq, struct canchip_t *chip)
154 struct msgobj_t *obj;
155 obj = chip->msgobj[0];
158 i = can_read_reg(chip, CAN_ICR_o);
160 if(i & (CAN_ICR_TI1 | CAN_ICR_RI)){
162 if(can_read_reg(chip, CAN_SR_o) & CAN_SR_RBS) {
163 lpc17xx_read(chip,obj);
168 if ((can_msgobj_test_fl(obj,TX_PENDING)) || (can_msgobj_test_fl(obj,TX_REQUEST))) {
170 can_msgobj_set_fl(obj,TX_REQUEST);
172 while(!can_msgobj_test_and_set_fl(obj,TX_LOCK)){
175 can_msgobj_clear_fl(obj,TX_REQUEST);
177 if (can_read_reg(chip, CAN_SR_o) & CAN_SR_TBS1){
179 lpc17xx_irq_write_handler(chip, obj);
182 can_msgobj_clear_fl(obj,TX_LOCK);
183 if(!can_msgobj_test_fl(obj,TX_REQUEST)) break;
190 can_write_reg(chip, CAN_CMR_CDO, CAN_CMR_o); // clear data overrun
193 return CANCHIP_IRQ_HANDLED;
197 void lpc17xx_irq_write_handler(struct canchip_t *chip, struct msgobj_t *obj)
203 /* Do local transmitted message distribution if enabled */
205 /* fill CAN message timestamp */
206 can_filltimestamp(&obj->tx_slot->msg.timestamp);
208 obj->tx_slot->msg.flags |= MSG_LOCAL;
209 canque_filter_msg2edges(obj->qends, &obj->tx_slot->msg);
211 /* Free transmitted slot */
212 canque_free_outslot(obj->qends, obj->tx_qedge, obj->tx_slot);
216 can_msgobj_clear_fl(obj,TX_PENDING);
217 cmd=canque_test_outslot(obj->qends, &obj->tx_qedge, &obj->tx_slot);
220 can_msgobj_set_fl(obj,TX_PENDING);
222 if (chip->chipspecops->pre_write_config(chip, obj, &obj->tx_slot->msg)) {
224 canque_notify_inends(obj->tx_qedge, CANQUEUE_NOTIFY_ERRTX_PREP);
225 canque_free_outslot(obj->qends, obj->tx_qedge, obj->tx_slot);
229 if (chip->chipspecops->send_msg(chip, obj, &obj->tx_slot->msg)) {
231 canque_notify_inends(obj->tx_qedge, CANQUEUE_NOTIFY_ERRTX_SEND);
232 canque_free_outslot(obj->qends, obj->tx_qedge, obj->tx_slot);
239 void lpc17xx_read(struct canchip_t *chip, struct msgobj_t *obj) {
242 CAN_recv(chip, &obj->rx_msg);
244 // fill CAN message timestamp
245 can_filltimestamp(&obj->rx_msg.timestamp);
247 canque_filter_msg2edges(obj->qends, &obj->rx_msg);
249 // release Receive buffer
250 can_write_reg(chip, CAN_CMR_RRB, CAN_CMR_o);
254 int lpc17xx_fill_chipspecops(struct canchip_t *chip){
257 chip->chip_irq = CAN_IRQn;
259 lpc17xx_register(chip->chipspecops);
264 int lpc17xx_register(struct chipspecops_t *chipspecops){
266 CANMSG("initializing lpc17xx can chip operations\n");
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;
281 int lpc17xx_attach_to_chip(struct canchip_t *chip){
286 int lpc17xx_pre_read_config(struct canchip_t *chip, struct msgobj_t *obj){
293 //---------------------------------------------------------------------------------
294 //---------------------------------------------------------------------------------
297 static void CAN_configPin(){
299 // CAN1 - select P0.0 as RD1. P0.1 as TD1
303 uint32_t pinmode_od0;
304 uint8_t pinsel0_val = 1;
305 uint8_t pinmode0_val = 0;
306 uint8_t pinmode_od0_val = 0;
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;
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;
323 pinmode_od0 = PINCON->PINMODE_OD0;
324 if (pinmode_od0_val){
325 pinmode_od0 |= CAN1_RX_BIT;
326 pinmode_od0 |= CAN1_TX_BIT;
329 pinmode_od0 &= ~CAN1_RX_BIT;
330 pinmode_od0 &= ~CAN1_TX_BIT;
332 PINCON->PINMODE_OD0 = pinmode_od0;
337 void CAN_recv(struct canchip_t *chip, canmsg_t* msg){
339 volatile uint32_t data;
343 msg->length = (can_read_reg(chip, CAN_RFS_o)>>16) & 0xF;
346 msg->id = can_read_reg(chip, CAN_RID_o);
349 if(can_read_reg(chip, CAN_RFS_o) & CAN_RFS_EXT)
350 msg->flags |= MSG_EXT;
352 msg->flags &= ~MSG_EXT;
356 if(can_read_reg(chip, CAN_RFS_o) & CAN_RFS_RTR)
357 msg->flags |= MSG_RTR;
359 msg->flags &= ~MSG_RTR;
363 data = can_read_reg(chip, CAN_RDA_o);
365 msg->data[i] = (data>>(i*8)) & 0xFF;
367 data = can_read_reg(chip, CAN_RDB_o);
369 msg->data[i] = (data>>((i-4)*8)) & 0xFF;
374 void CAN_send(struct canchip_t *chip, canmsg_t* msg){
376 volatile uint32_t data;
377 volatile uint32_t can_tfi1;
380 // check status of TB1
381 while (!(can_read_reg(chip, CAN_SR_o) & CAN_SR_TBS1)){
382 if(i++<MAX_TRANSMIT_WAIT_LOOPS)
385 // request command to abort transmission request
386 can_write_reg(chip, CAN_CMR_AT, CAN_CMR_o);
390 can_tfi1 = can_read_reg(chip, CAN_TFI1_o);
392 can_tfi1 &= ~0x000F0000;
393 can_tfi1 |= (msg->length)<<16;
396 if(msg->flags & MSG_EXT)
397 can_tfi1 |= CAN_TFI1_EXT;
399 can_tfi1 &= ~CAN_TFI1_EXT;
402 if(msg->flags & MSG_RTR)
403 can_tfi1 |= CAN_TFI1_RTR;
405 can_tfi1 &= ~CAN_TFI1_RTR;
407 can_write_reg(chip, can_tfi1, CAN_TFI1_o);
411 can_write_reg(chip, msg->id, CAN_TID1_o);
414 // write first 4 data bytes
417 data |= (msg->data[i])<<(i*8);
419 can_write_reg(chip, data, CAN_TDA1_o);
421 // write second 4 data bytes
424 data |= (msg->data[i])<<((i-4)*8);
426 can_write_reg(chip, data, CAN_TDB1_o);
430 void CAN_set_bittiming(struct canchip_t *chip, uint32_t brp, uint32_t sjw, uint32_t tseg1, uint32_t tseg2){
432 uint8_t SAM = 0; // 0 = the bus is sampled once
439 can_disable_irq(chip->chip_irq);
441 can_write_reg(chip, 1, CAN_MOD_o);
444 can_write_reg(chip, ((SAM<<23)|(tseg2<<20)|(tseg1<<16)|(sjw<<14)|(brp<<0)), CAN_BTR_o);
447 // return to normal operating
448 can_write_reg(chip, 0, CAN_MOD_o);
450 can_enable_irq(chip->chip_irq);
453 void CAN_setBusTiming(struct canchip_t *chip){
458 uint8_t tq_numb; // number of time quantum
459 uint8_t TSEG1, TSEG2;
465 TSEG1 = TSEG2 = BRP = 0;
467 // 0 = the bus is sampled once
470 // the Synchronization Jump Width (this value plus one)
473 // get clock divide for CAN1
474 div = __mfld2val(PCLK_CAN1_MASK, SC->PCLKSEL0);
486 // only for CAN, for other peripherials '11' value means div=8
492 PCLK_CAN = system_frequency / div;
494 res = PCLK_CAN / (chip->baudrate);
497 // calculation of tq_numb - number of time quantum (must be in <8,25>)
498 // tq_numb = TSEG1 + TSEG2 + 3
500 for(tq_numb=25; tq_numb>=8; tq_numb--){
502 if ((res%tq_numb)==0){
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;
507 // sync. segment allways 1 tq
510 // number of tq from the sample point to the next nominal Sync. point (this value plus one)
511 TSEG2 = (tq_numb/3) - 1;
513 // number of tq from Sync. point to the sample point (this value plus one)
514 TSEG1 = tq_numb - (tq_numb/3) - 1;
520 can_write_reg(chip, ((SAM<<23)|(TSEG2<<20)|(TSEG1<<16)|(SJW<<14)|(BRP<<0)), CAN_BTR_o);
524 void CAN_init(struct canchip_t *chip){
531 printf("CAN INIT, baudrate: %d\n", (int) chip->baudrate);
533 // configure CAN1 pins
536 // turn on power and clock for CAN1
539 // set clock divide for CAN1
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;
552 can_write_reg(chip, 1, CAN_MOD_o);
554 // disable all CAN interrupts
555 can_write_reg(chip, 0, CAN_IER_o);
557 // reset value of Global Status Register (global controller status and error counters)
558 can_write_reg(chip, 0x3C, CAN_GSR_o);
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);
563 // read to clear interrupt pending in Interrupt Capture Register
564 tmp = can_read_reg(chip, CAN_ICR_o);
567 CAN_setBusTiming(chip);
569 // return to normal operating
570 can_write_reg(chip, 0, CAN_MOD_o);
573 //--------------------------
575 // Acceptance Filter Off Mode
579 for (i = 0; i < 512; i++) {
580 CANAF_RAM->mask[i] = 0x00;
584 CANAF_SFF_GRP_sa = 0x00;
586 CANAF_EFF_GRP_sa = 0x00;
587 CANAF_ENDofTable = 0x00;
589 // Acceptance Filter Bypass Mode - all messages accepted
592 //--------------------------
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);