1 #include "can/lpc17xx_can.h"
3 static void CAN_configPin();
4 static void CAN_setBusTiming(struct canchip_t *chip);
6 //---------------------------------------------------------------------------------
7 //---------------------------------------------------------------------------------
10 // board can-lmc1 specific functions:
12 int can_lmc1_register(struct hwspecops_t *hwspecops){
14 hwspecops->request_io = can_lmc1_request_io;
15 hwspecops->reset = can_lmc1_reset;
16 hwspecops->init_hw_data = can_lmc1_init_hw_data;
17 hwspecops->init_chip_data = can_lmc1_init_chip_data;
18 hwspecops->init_obj_data = can_lmc1_init_obj_data;
19 hwspecops->write_register = can_lmc1_write_register;
20 hwspecops->read_register = can_lmc1_read_register;
21 hwspecops->program_irq = can_lmc1_program_irq;
26 int can_lmc1_init_hw_data(struct candevice_t *candev){
29 candev->nr_82527_chips=0;
30 candev->nr_sja1000_chips=0;
31 candev->nr_all_chips=1;
37 int can_lmc1_init_chip_data(struct candevice_t *candev, int chipnr){
39 // used CAN1 peripherial -> CAN1 registers base
40 candev->chip[chipnr]->chip_base_addr = CAN1_REGS_BASE;
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)
51 int can_lmc1_init_obj_data(struct canchip_t *chip, int objnr){
56 void can_lmc1_write_register(unsigned data, unsigned long address){
57 (*(volatile uint32_t*)(address)) = data;
60 unsigned can_lmc1_read_register(unsigned long address){
61 return (*(volatile uint32_t*)(address));
64 int can_lmc1_request_io(struct candevice_t *candev)
69 int can_lmc1_reset(struct candevice_t *candev)
74 int can_lmc1_program_irq(struct candevice_t *candev)
79 //---------------------------------------------------------------------------------
80 //---------------------------------------------------------------------------------
83 // lpc17xx can chip specific functions:
86 int lpc17xx_chip_config(struct canchip_t *chip){
93 int lpc17xx_pre_write_config(struct canchip_t *chip, struct msgobj_t *obj,
102 int lpc17xx_send_msg(struct canchip_t *chip, struct msgobj_t *obj,
103 struct canmsg_t *msg)
106 // write transmission request
107 can_write_reg(chip, (CAN_CMR_TR | CAN_CMR_STB1), CAN_CMR_o);
112 int lpc17xx_wakeup_tx(struct canchip_t *chip, struct msgobj_t *obj)
115 can_preempt_disable();
117 can_msgobj_set_fl(obj,TX_PENDING);
118 can_msgobj_set_fl(obj,TX_REQUEST);
120 while(!can_msgobj_test_and_set_fl(obj,TX_LOCK)){
121 can_msgobj_clear_fl(obj,TX_REQUEST);
123 if (can_read_reg(chip, CAN_SR_o) & CAN_SR_TBS1){
125 lpc17xx_irq_write_handler(chip, obj);
128 can_msgobj_clear_fl(obj,TX_LOCK);
129 if(!can_msgobj_test_fl(obj,TX_REQUEST)) break;
133 can_preempt_enable();
138 int lpc17xx_irq_handler(int irq, struct canchip_t *chip)
142 struct msgobj_t *obj;
143 obj = chip->msgobj[0];
146 i = can_read_reg(chip, CAN_ICR_o);
148 if(i & (CAN_ICR_TI1 | CAN_ICR_RI)){
150 if(can_read_reg(chip, CAN_SR_o) & CAN_SR_RBS) {
151 lpc17xx_read(chip,obj);
156 if ((can_msgobj_test_fl(obj,TX_PENDING)) || (can_msgobj_test_fl(obj,TX_REQUEST))) {
158 can_msgobj_set_fl(obj,TX_REQUEST);
160 while(!can_msgobj_test_and_set_fl(obj,TX_LOCK)){
163 can_msgobj_clear_fl(obj,TX_REQUEST);
165 if (can_read_reg(chip, CAN_SR_o) & CAN_SR_TBS1){
167 lpc17xx_irq_write_handler(chip, obj);
170 can_msgobj_clear_fl(obj,TX_LOCK);
171 if(!can_msgobj_test_fl(obj,TX_REQUEST)) break;
178 can_write_reg(chip, CAN_CMR_CDO, CAN_CMR_o); // clear data overrun
181 return CANCHIP_IRQ_HANDLED;
185 void lpc17xx_irq_write_handler(struct canchip_t *chip, struct msgobj_t *obj)
190 /* Do local transmitted message distribution if enabled */
192 /* fill CAN message timestamp */
193 can_filltimestamp(&obj->tx_slot->msg.timestamp);
195 obj->tx_slot->msg.flags |= MSG_LOCAL;
196 canque_filter_msg2edges(obj->qends, &obj->tx_slot->msg);
198 /* Free transmitted slot */
199 canque_free_outslot(obj->qends, obj->tx_qedge, obj->tx_slot);
203 can_msgobj_clear_fl(obj,TX_PENDING);
204 cmd=canque_test_outslot(obj->qends, &obj->tx_qedge, &obj->tx_slot);
207 can_msgobj_set_fl(obj,TX_PENDING);
209 if (chip->chipspecops->pre_write_config(chip, obj, &obj->tx_slot->msg)) {
211 canque_notify_inends(obj->tx_qedge, CANQUEUE_NOTIFY_ERRTX_PREP);
212 canque_free_outslot(obj->qends, obj->tx_qedge, obj->tx_slot);
216 if (chip->chipspecops->send_msg(chip, obj, &obj->tx_slot->msg)) {
218 canque_notify_inends(obj->tx_qedge, CANQUEUE_NOTIFY_ERRTX_SEND);
219 canque_free_outslot(obj->qends, obj->tx_qedge, obj->tx_slot);
226 void lpc17xx_read(struct canchip_t *chip, struct msgobj_t *obj) {
229 CAN_recv(chip, &obj->rx_msg);
231 // fill CAN message timestamp
232 can_filltimestamp(&obj->rx_msg.timestamp);
234 canque_filter_msg2edges(obj->qends, &obj->rx_msg);
236 // release Receive buffer
237 can_write_reg(chip, CAN_CMR_RRB, CAN_CMR_o);
241 int lpc17xx_fill_chipspecops(struct canchip_t *chip){
244 chip->chip_irq = CAN_IRQn;
246 lpc17xx_register(chip->chipspecops);
251 int lpc17xx_register(struct chipspecops_t *chipspecops){
253 CANMSG("initializing lpc17xx can chip operations\n");
255 chipspecops->attach_to_chip = lpc17xx_attach_to_chip;
256 chipspecops->pre_read_config = lpc17xx_pre_read_config;
257 chipspecops->chip_config = lpc17xx_chip_config;
258 chipspecops->pre_write_config = lpc17xx_pre_write_config;
259 chipspecops->send_msg = lpc17xx_send_msg;
260 chipspecops->wakeup_tx = lpc17xx_wakeup_tx;
261 chipspecops->irq_handler = lpc17xx_irq_handler;
268 int lpc17xx_attach_to_chip(struct canchip_t *chip){
273 int lpc17xx_pre_read_config(struct canchip_t *chip, struct msgobj_t *obj){
280 //---------------------------------------------------------------------------------
281 //---------------------------------------------------------------------------------
284 static void CAN_configPin(){
286 // CAN1 - select P0.0 as RD1. P0.1 as TD1
290 uint32_t pinmode_od0;
291 uint8_t pinsel0_val = 1;
292 uint8_t pinmode0_val = 0;
293 uint8_t pinmode_od0_val = 0;
296 pinsel0 = PINCON->PINSEL0;
297 pinsel0 &= ~CAN1_RX_MASK;
298 pinsel0 &= ~CAN1_TX_MASK;
299 pinsel0 |= __val2mfld(CAN1_RX_MASK, pinsel0_val);
300 pinsel0 |= __val2mfld(CAN1_TX_MASK, pinsel0_val);
301 PINCON->PINSEL0 = pinsel0;
303 pinmode0 = PINCON->PINMODE0;
304 pinmode0 &= ~CAN1_RX_MASK;
305 pinmode0 &= ~CAN1_TX_MASK;
306 pinmode0 |= __val2mfld(CAN1_RX_MASK, pinmode0_val);
307 pinmode0 |= __val2mfld(CAN1_TX_MASK, pinmode0_val);
308 PINCON->PINMODE0 = pinmode0;
310 pinmode_od0 = PINCON->PINMODE_OD0;
311 if (pinmode_od0_val){
312 pinmode_od0 |= CAN1_RX_BIT;
313 pinmode_od0 |= CAN1_TX_BIT;
316 pinmode_od0 &= ~CAN1_RX_BIT;
317 pinmode_od0 &= ~CAN1_TX_BIT;
319 PINCON->PINMODE_OD0 = pinmode_od0;
324 void CAN_recv(struct canchip_t *chip, canmsg_t* msg){
326 volatile uint32_t data;
330 msg->length = (can_read_reg(chip, CAN_RFS_o)>>16) & 0xF;
333 msg->id = can_read_reg(chip, CAN_RID_o);
336 if(can_read_reg(chip, CAN_RFS_o) & CAN_RFS_EXT)
337 msg->flags |= MSG_EXT;
339 msg->flags &= ~MSG_EXT;
343 if(can_read_reg(chip, CAN_RFS_o) & CAN_RFS_RTR)
344 msg->flags |= MSG_RTR;
346 msg->flags &= ~MSG_RTR;
350 data = can_read_reg(chip, CAN_RDA_o);
352 msg->data[i] = (data>>(i*8)) & 0xFF;
354 data = can_read_reg(chip, CAN_RDB_o);
356 msg->data[i] = (data>>((i-4)*8)) & 0xFF;
360 void CAN_send(struct canchip_t *chip, canmsg_t* msg){
362 volatile uint32_t data;
363 volatile uint32_t can_tfi1;
366 // check status of TB1
367 while (!(can_read_reg(chip, CAN_SR_o) & CAN_SR_TBS1)){}
369 can_tfi1 = can_read_reg(chip, CAN_TFI1_o);
371 can_tfi1 &= ~0x000F0000;
372 can_tfi1 |= (msg->length)<<16;
375 if(msg->flags & MSG_EXT)
376 can_tfi1 |= CAN_TFI1_EXT;
378 can_tfi1 &= ~CAN_TFI1_EXT;
381 if(msg->flags & MSG_RTR)
382 can_tfi1 |= CAN_TFI1_RTR;
384 can_tfi1 &= ~CAN_TFI1_RTR;
386 can_write_reg(chip, can_tfi1, CAN_TFI1_o);
390 can_write_reg(chip, msg->id, CAN_TID1_o);
393 // write first 4 data bytes
396 data |= (msg->data[i])<<(i*8);
398 can_write_reg(chip, data, CAN_TDA1_o);
400 // write second 4 data bytes
403 data |= (msg->data[i])<<((i-4)*8);
405 can_write_reg(chip, data, CAN_TDB1_o);
409 void CAN_set_bittiming(struct canchip_t *chip, uint32_t brp, uint32_t sjw, uint32_t tseg1, uint32_t tseg2){
411 uint8_t SAM = 0; // 0 = the bus is sampled once
418 can_disable_irq(chip->chip_irq);
420 can_write_reg(chip, 1, CAN_MOD_o);
423 can_write_reg(chip, ((SAM<<23)|(tseg2<<20)|(tseg1<<16)|(sjw<<14)|(brp<<0)), CAN_BTR_o);
426 // return to normal operating
427 can_write_reg(chip, 0, CAN_MOD_o);
429 can_enable_irq(chip->chip_irq);
432 void CAN_setBusTiming(struct canchip_t *chip){
437 uint8_t tq_numb; // number of time quantum
438 uint8_t TSEG1, TSEG2;
444 TSEG1 = TSEG2 = BRP = 0;
446 // 0 = the bus is sampled once
449 // the Synchronization Jump Width (this value plus one)
452 // get clock divide for CAN1
453 div = __mfld2val(PCLK_CAN1_MASK, SC->PCLKSEL0);
465 // only for CAN, for other peripherials '11' value means div=8
471 PCLK_CAN = system_frequency / div;
473 res = PCLK_CAN / (chip->baudrate);
476 // calculation of tq_numb - number of time quantum (must be in <8,25>)
477 // tq_numb = TSEG1 + TSEG2 + 3
479 for(tq_numb=25; tq_numb>=8; tq_numb--){
481 if ((res%tq_numb)==0){
483 // Baud Rate Prescaler. The PCLK clock is divided by (this value plus one) to produce the CAN clock.
484 BRP = (res / tq_numb) - 1;
486 // sync. segment allways 1 tq
489 // number of tq from the sample point to the next nominal Sync. point (this value plus one)
490 TSEG2 = (tq_numb/3) - 1;
492 // number of tq from Sync. point to the sample point (this value plus one)
493 TSEG1 = tq_numb - (tq_numb/3) - 1;
499 can_write_reg(chip, ((SAM<<23)|(TSEG2<<20)|(TSEG1<<16)|(SJW<<14)|(BRP<<0)), CAN_BTR_o);
503 void CAN_init(struct canchip_t *chip){
510 printf("CAN INIT, baudrate: %d\n", (int) chip->baudrate);
512 // configure CAN1 pins
515 // turn on power and clock for CAN1
518 // set clock divide for CAN1
520 val = 0x00; // 00 PCLK_peripheral = CCLK/4
521 pclksel0 = SC->PCLKSEL0;
522 pclksel0 &= ~PCLK_CAN1_MASK;
523 pclksel0 &= ~PCLK_CAN2_MASK;
524 pclksel0 &= ~PCLK_ACF_MASK;
525 pclksel0 |= __val2mfld(PCLK_CAN1_MASK, val);
526 pclksel0 |= __val2mfld(PCLK_CAN2_MASK, val);
527 pclksel0 |= __val2mfld(PCLK_ACF_MASK, val);
528 SC->PCLKSEL0 = pclksel0;
531 can_write_reg(chip, 1, CAN_MOD_o);
533 // disable all CAN interrupts
534 can_write_reg(chip, 0, CAN_IER_o);
536 // reset value of Global Status Register (global controller status and error counters)
537 can_write_reg(chip, 0x3C, CAN_GSR_o);
539 // request command to release Rx, Tx buffer and clear data overrun
540 can_write_reg(chip, (CAN_CMR_AT | CAN_CMR_RRB | CAN_CMR_CDO), CAN_CMR_o);
542 // read to clear interrupt pending in Interrupt Capture Register
543 tmp = can_read_reg(chip, CAN_ICR_o);
546 CAN_setBusTiming(chip);
548 // return to normal operating
549 can_write_reg(chip, 0, CAN_MOD_o);
552 //--------------------------
554 // Acceptance Filter Off Mode
558 for (i = 0; i < 512; i++) {
559 CANAF_RAM->mask[i] = 0x00;
563 CANAF_SFF_GRP_sa = 0x00;
565 CANAF_EFF_GRP_sa = 0x00;
566 CANAF_ENDofTable = 0x00;
568 // Acceptance Filter Bypass Mode - all messages accepted
571 //--------------------------
574 // enable interrupt after transmit
575 // enable receive interrupt
576 // enable data overrun interrupt
577 can_write_reg(chip, (CAN_IER_TIE1 | CAN_IER_RIE | CAN_IER_DOIE), CAN_IER_o);