2 * Linux CAN-bus device driver.
3 * Written by Sergei Sharonov email:sharonov@halliburton.com
4 * sja1000p was used as a prototype
5 * This software is released under the GPL-License.
6 * Version lincan-0.3.2 15 Feb 2006
8 #include "../include/can.h"
9 #include "../include/can_sysdep.h"
10 #include "../include/main.h"
11 #include "../include/mcp2515.h"
15 #define RESET_CMD 0xc0
17 #define WRITE_CMD 0x02
18 #define BITMOD_CMD 0x05
21 /*****************************************************************************/
22 /* SPI ACCESS FUNCTIONS */
23 /*****************************************************************************/
24 static unsigned char read_reg(struct canchip_t *chip, unsigned addr)
26 uint8_t *command, val;
28 command = ((MCP2515_PRIV*)(chip->chip_data))->spi_buf;
29 command[0] = READ_CMD;
31 can_spi_transfer(chip,command,command,3);
35 DEBUGMSG("reg[0x%02x]=>0x%02x\n",addr,(unsigned)val);
40 /*****************************************************************************/
41 static int read_block(struct canchip_t *chip, unsigned startAddr,
42 size_t len, void *data)
46 command = ((MCP2515_PRIV*)(chip->chip_data))->spi_buf;
47 memset(command,0,SPI_BUF_LEN);
48 command[0] = READ_CMD;
49 command[1] = startAddr;
50 can_spi_transfer(chip, command, command, len+2);
51 memcpy(data, command+2, len);
56 DEBUGMSG("reg[0x%02x..]=>",startAddr);
57 for(i=0;i<len;i++) DEBUGMSG(" 0x%02x",(unsigned)((uint8_t*)data)[i]);
64 /*****************************************************************************/
65 static void write_reg(struct canchip_t *chip, unsigned addr, unsigned char data)
67 unsigned char *command;
69 command = ((MCP2515_PRIV*)(chip->chip_data))->spi_buf;
70 command[0] = WRITE_CMD;
73 can_spi_transfer(chip,command,command,3);
76 DEBUGMSG("reg[0x%02x]<=0x%02x\n",addr,(unsigned)data);
81 /*****************************************************************************/
82 static int write_block(struct canchip_t *chip, unsigned startAddr,
83 size_t len, void *data)
87 command = ((MCP2515_PRIV*)(chip->chip_data))->spi_buf;
88 command[0] = WRITE_CMD;
89 command[1] = startAddr;
90 memcpy(command+2,data,len);
91 can_spi_transfer(chip, command, command, len+2);
96 DEBUGMSG("reg[0x%02x..]<=",startAddr);
98 DEBUGMSG(" 0x%02x", (unsigned)((uint8_t*)data)[i]);
106 /*****************************************************************************/
107 static void bitmod_reg(struct canchip_t *chip, unsigned addr,
108 unsigned char mask, unsigned char data)
110 unsigned char *command;
112 command = ((MCP2515_PRIV*)(chip->chip_data))->spi_buf;
113 command[0] = BITMOD_CMD;
117 can_spi_transfer(chip,command,command,4);
120 DEBUGMSG("reg[0x%02x]<=0x%02x mask=0x%02x\n",addr,(unsigned)data,(unsigned)mask);
125 /*****************************************************************************/
127 /*****************************************************************************/
128 int mcp2515_get_info(struct canchip_t *chip, char *buf)
130 MCP2515_PRIV *priv=(MCP2515_PRIV *)(chip->chip_data);
134 can_spi_acquire_bus(chip, 1);
135 opmode = read_reg(chip,MCP2515_CANSTAT) & mcpMOD_MASK;
136 can_spi_release_bus(chip);
137 len += sprintf(buf+len,"opmode : %s%s%s%s%s\n",
138 (opmode == mcpMOD_NORM) ? "norm" : "",
139 (opmode == mcpMOD_SLEEP) ? "sleep" : "",
140 (opmode == mcpMOD_LOOPBACK) ? "loopback" : "",
141 (opmode == mcpMOD_LISTEN) ? "listen" : "",
142 (opmode == mcpMOD_CONFIG) ? "config" : "");
144 len += sprintf(buf+len,"spi ch : %d\n",chip->spi_channel);
145 len += sprintf(buf+len,"rx0ovr : %u\n",priv->errcnt.rx0ovr);
146 len += sprintf(buf+len,"rx1ovr : %u\n",priv->errcnt.rx1ovr);
147 len += sprintf(buf+len,"txbo : %u\n",priv->errcnt.txbo);
148 len += sprintf(buf+len,"txep : %u\n",priv->errcnt.txep);
149 len += sprintf(buf+len,"rxep : %u\n",priv->errcnt.rxep);
150 len += sprintf(buf+len,"txwar : %u\n",priv->errcnt.txwar);
151 len += sprintf(buf+len,"rxwar : %u\n",priv->errcnt.rxwar);
152 len += sprintf(buf+len,"ewarn : %u\n",priv->errcnt.ewarn);
153 len += sprintf(buf+len,"merre : %u\n",priv->errcnt.merre);
154 len += sprintf(buf+len,"wakeup : %u\n",priv->wakeint_cnt);
160 /*****************************************************************************/
162 /*****************************************************************************/
163 static void rx_handler(struct canchip_t *chip, int bufNo, struct msgobj_t *obj)
168 if(chip == NULL) panic("rx_handler: chip==NULL");
169 if(obj == NULL) panic("rx_handler: obj==NULL");
172 /* get all frame data */
174 read_block(chip,MCP2515_RXB0SIDH,sizeof(MCP2515_FRAME),&frame);
175 bitmod_reg(chip,MCP2515_CANINTF, mcpRX0INT, ~mcpRX0INT);
178 read_block(chip,MCP2515_RXB1SIDH,sizeof(MCP2515_FRAME),&frame);
179 bitmod_reg(chip,MCP2515_CANINTF, mcpRX1INT, ~mcpRX1INT);
182 if(frame.sidl & mcpIDE) {
183 DEBUGMSG("extended frame\n");
185 ((uint32_t)frame.eid0) |
186 ((uint32_t)frame.eid8) << 8 |
187 ((uint32_t)frame.sidl & 0x03) << 16 |
188 ((uint32_t)frame.sidl & 0xe0) << 13 |
189 ((uint32_t)frame.sidh) << 21;
190 obj->rx_msg.flags = MSG_EXT | ((frame.dlc & mcpRTR) ? MSG_RTR : 0);
193 DEBUGMSG("standard frame\n");
195 ((uint32_t)frame.sidl) >> 5 |
196 ((uint32_t)frame.sidh) << 3;
197 obj->rx_msg.flags = ((frame.sidl & mcpSRR) ? MSG_RTR : 0);
200 len = frame.dlc & mcpDLC_MASK;
201 if(len > CAN_MSG_LENGTH) len = CAN_MSG_LENGTH;
202 obj->rx_msg.length = len;
204 memcpy(obj->rx_msg.data,frame.data,len);
206 /* fill CAN message timestamp */
207 can_filltimestamp(&obj->rx_msg.timestamp);
208 canque_filter_msg2edges(obj->qends, &obj->rx_msg);
211 /*****************************************************************************/
212 static void tx_handler(struct canchip_t *chip, struct msgobj_t *obj)
216 if(chip == NULL) panic("tx_handler: chip==NULL");
217 if(obj == NULL) panic("tx_handler: obj==NULL");
219 bitmod_reg(chip,MCP2515_CANINTF, mcpTX0INT, ~mcpTX0INT);
223 /* Do local transmitted message distribution if enabled */
225 /* fill CAN message timestamp */
226 can_filltimestamp(&obj->tx_slot->msg.timestamp);
228 obj->tx_slot->msg.flags |= MSG_LOCAL;
229 canque_filter_msg2edges(obj->qends, &obj->tx_slot->msg);
231 /* Free transmitted slot */
232 canque_free_outslot(obj->qends, obj->tx_qedge, obj->tx_slot);
236 can_msgobj_clear_fl(obj,TX_PENDING);
237 cmd=canque_test_outslot(obj->qends, &obj->tx_qedge, &obj->tx_slot);
240 can_msgobj_set_fl(obj,TX_PENDING);
242 if (chip->chipspecops->pre_write_config(chip, obj, &obj->tx_slot->msg)) {
244 canque_notify_inends(obj->tx_qedge, CANQUEUE_NOTIFY_ERRTX_PREP);
245 canque_free_outslot(obj->qends, obj->tx_qedge, obj->tx_slot);
249 if (chip->chipspecops->send_msg(chip, obj, &obj->tx_slot->msg)) {
251 canque_notify_inends(obj->tx_qedge, CANQUEUE_NOTIFY_ERRTX_SEND);
252 canque_free_outslot(obj->qends, obj->tx_qedge, obj->tx_slot);
259 /*****************************************************************************/
260 static void errint_handler(struct canchip_t *chip)
263 MCP2515_PRIV *priv=(MCP2515_PRIV *)(chip->chip_data);
265 error = read_reg(chip, MCP2515_EFLG);
266 bitmod_reg(chip,MCP2515_CANINTF, mcpERRINT, ~mcpERRINT);
269 if(error & mcpRX0OVR) {
270 (priv->errcnt.rx0ovr)++;
271 CANMSG("can: RX0OVR\n");
273 if(error & mcpRX1OVR) (priv->errcnt.rx1ovr)++;
274 if(error & mcpTXBO) (priv->errcnt.txbo)++;
275 if(error & mcpTXEP) (priv->errcnt.txep)++;
276 if(error & mcpRXEP) (priv->errcnt.rxep)++;
277 if(error & mcpTXWAR) (priv->errcnt.txwar)++;
278 if(error & mcpRXWAR) (priv->errcnt.rxwar)++;
279 if(error & mcpEWARN) (priv->errcnt.ewarn)++;
282 /*****************************************************************************/
283 static void irq_work(void *data)
285 struct canchip_t *chip=(struct canchip_t *)data;
291 priv=(MCP2515_PRIV *)(chip->chip_data);
296 flags = read_reg(chip, MCP2515_CANINTF);
297 if(flags == 0) break;
298 DEBUGMSG("mcp251x_irq_work_handler:%s%s%s%s%s%s%s%s\n",
299 (flags & mcpRX0INT) ? " RX0":"",
300 (flags & mcpRX1INT) ? " RX1":"",
301 (flags & mcpTX0INT) ? " TX0":"",
302 (flags & mcpTX1INT) ? " TX1":"",
303 (flags & mcpTX2INT) ? " TX2":"",
304 (flags & mcpERRINT) ? " ERR":"",
305 (flags & mcpWAKINT) ? " WAK":"",
306 (flags & mcpMERREINT) ? " MERRE":"");
308 if(flags & mcpRX0INT) rx_handler(chip,0,chip->msgobj[0]);
309 if(flags & mcpRX1INT) rx_handler(chip,1,chip->msgobj[0]);
310 if(flags & mcpTX0INT) tx_handler(chip,chip->msgobj[0]);
311 if(flags & mcpTX1INT) tx_handler(chip,chip->msgobj[1]);
312 if(flags & mcpTX2INT) tx_handler(chip,chip->msgobj[2]);
313 if(flags & mcpERRINT) errint_handler(chip);
315 if(flags & mcpMERREINT){
316 bitmod_reg(chip,MCP2515_CANINTF, mcpMERREINT, ~mcpMERREINT);
317 (priv->errcnt.merre)++;
319 if(flags & mcpWAKINT) (priv->wakeint_cnt)++;
321 // bitmod_reg(chip, MCP2515_CANINTF, flags, 0);
324 enable_irq(chip->chip_irq);
327 /*****************************************************************************/
329 static void tasklet_handler(unsigned long data)
331 struct canchip_t *chip=(struct canchip_t *)data;
335 /* Already acquired bus, go do work */
337 can_spi_release_bus(chip);
340 /*****************************************************************************/
341 static void workqueue_handler(struct work_struct *work)
343 MCP2515_PRIV *priv = container_of(work,MCP2515_PRIV,workqueue_handler);
344 struct canchip_t *chip = priv->chip;
347 can_spi_acquire_bus(chip, 1);
349 can_spi_release_bus(chip);
352 /*****************************************************************************/
353 /* EXPORT FUNCTIONS */
354 /*****************************************************************************/
355 int mcp2515_reset_chip(struct canchip_t *chip)
357 unsigned char *command;
359 DEBUGMSG("reset chip\n");
361 command = ((MCP2515_PRIV*)(chip->chip_data))->spi_buf;
362 command[0] = RESET_CMD;
363 can_spi_acquire_bus(chip,1);
364 can_spi_transfer(chip,command,command,1);
365 can_spi_release_bus(chip);
368 DEBUGMSG("reset mcp2515:%d\n",chip->chip_idx);
374 * mcp2515_enable_configuration - enable chip configuration mode
375 * @chip: pointer to chip state structure
377 int mcp2515_enable_configuration(struct canchip_t *chip)
380 enum mcp2515_MOD stat;
382 DEBUGMSG("mcp2515_enable_configuration\n");
384 can_disable_irq(chip->chip_irq);
386 can_spi_acquire_bus(chip,1);
388 bitmod_reg(chip, MCP2515_CANCTRL, mcpMOD_MASK, mcpMOD_CONFIG);
389 stat = read_reg(chip,MCP2515_CANSTAT);
390 if((stat & mcpMOD_MASK) == mcpMOD_CONFIG) {
391 can_spi_release_bus(chip);
396 can_spi_release_bus(chip);
398 CANMSG("Failed to set cfg mode\n");
399 can_enable_irq(chip->chip_irq);
404 * mcp2515_disable_configuration - disable chip configuration mode
405 * @chip: pointer to chip state structure
407 int mcp2515_disable_configuration(struct canchip_t *chip)
410 enum mcp2515_MOD stat;
412 DEBUGMSG("mcp2515_disable_configuration\n");
414 can_spi_acquire_bus(chip,1);
416 bitmod_reg(chip, MCP2515_CANCTRL, mcpMOD_MASK, mcpMOD_NORM);
417 stat = read_reg(chip,MCP2515_CANSTAT);
418 if((stat & mcpMOD_MASK) == mcpMOD_NORM) {
419 can_enable_irq(chip->chip_irq);
420 can_spi_release_bus(chip);
425 can_spi_release_bus(chip);
427 CANMSG("Failed to set normal mode\n");
433 * mcp2515_chip_config: - can chip configuration
434 * @chip: pointer to chip state structure
436 * This function configures chip and prepares it for message
437 * transmission and reception. The function resets chip,
438 * resets mask for acceptance of all messages by call to
439 * mcp2515_extended_mask() function and then
440 * computes and sets baudrate with use of function mcp2515_baud_rate().
441 * Return Value: negative value reports error.
442 * File: src/mcp2515.c
444 int mcp2515_chip_config(struct canchip_t *chip)
446 uint8_t pat0[8]={0x00,0xff,0xaa,0x55,0x0f,0xf0,0x3c,0xc3};
450 DEBUGMSG("mcp2515_chip_config\n");
452 ((MCP2515_PRIV *)(chip->chip_data))->chip = chip;
454 if (mcp2515_enable_configuration(chip))
457 /* Acquire SPI bus */
458 can_spi_acquire_bus(chip,1);
460 /* Set TXnRTS pins as digital inputs */
461 write_reg(chip,MCP2515_TXRTSCTRL,0);
463 /* Set RXnBF pins as digital outputs, b0=low, b1=high */
464 write_reg(chip, MCP2515_BFPCTRL,
465 mcpB0BFE | mcpB1BFE | /* mcpB0BFS | */ mcpB1BFS);
467 /* Ensure, that interrupts are disabled even on the chip level now */
468 write_reg(chip, MCP2515_CANINTE, 0);
470 /* Configure second receive buffer for rollover */
471 bitmod_reg(chip, MCP2515_RXB0CTRL, mcpBUKT, mcpBUKT);
474 /* Simple check for chip presence */
476 write_block(chip,MCP2515_TXB0DATA,8,pat0);
478 read_block(chip,MCP2515_TXB0DATA,8,pat1);
479 // *(pat1) = read_reg(chip,MCP2515_TXB0DATA);
480 // *(pat1+1) = read_reg(chip,MCP2515_TXB0DATA+1);
481 // *(pat1+2) = read_reg(chip,MCP2515_TXB0DATA+2);
482 // *(pat1+3) = read_reg(chip,MCP2515_TXB0DATA+3);
483 // *(pat1+4) = read_reg(chip,MCP2515_TXB0DATA+4);
484 // *(pat1+5) = read_reg(chip,MCP2515_TXB0DATA+5);
485 // *(pat1+6) = read_reg(chip,MCP2515_TXB0DATA+6);
486 // *(pat1+7) = read_reg(chip,MCP2515_TXB0DATA+7);
488 if(memcmp(pat0,pat1,8)) {
489 CANMSG("mcp2515_chip_config: chip #%d not found\n",
491 CANMSG("Requested: Ox%X Ox%X Ox%X Ox%X Ox%X Ox%X Ox%X Ox%X\n",pat0[0],pat0[1],pat0[2],pat0[3],pat0[4],pat0[5],pat0[6],pat0[7]);
492 CANMSG("Obtained : Ox%X Ox%X Ox%X Ox%X Ox%X Ox%X Ox%X Ox%X\n",pat1[0],pat1[1],pat1[2],pat1[3],pat1[4],pat1[5],pat1[6],pat1[7]);
501 can_spi_release_bus(chip);
503 CANMSG("Found mcp2515:%d\n",chip->chip_idx);
506 if (mcp2515_extended_mask(chip,0x00000000, 0xffffffff))
509 if (!chip->baudrate) chip->baudrate=1000000;
510 if (mcp2515_baud_rate(chip,chip->baudrate,chip->clock,0,75,0))
513 /* Enable hardware interrupts */
514 can_spi_acquire_bus(chip,1);
515 write_reg(chip, MCP2515_CANINTE, 0xff);
516 can_spi_release_bus(chip);
518 mcp2515_disable_configuration(chip);
523 * mcp2515_extended_mask: - setup of extended mask for message filtering
524 * @chip: pointer to chip state structure
525 * @code: can message acceptance code
526 * @mask: can message acceptance mask
528 * Return Value: negative value reports error.
529 * File: src/mcp2515.c
531 int mcp2515_extended_mask(struct canchip_t *chip, unsigned long code, unsigned long mask)
533 DEBUGMSG("mcp2515_extended_mask\n");
536 if (mcp2515_enable_configuration(chip))
539 // LSB to +3, MSB to +0
540 for(i=SJA_PeliCAN_AC_LEN; --i>=0;) {
541 can_write_reg(chip,code&0xff,SJAACR0+i);
542 can_write_reg(chip,mask&0xff,SJAAMR0+i);
547 DEBUGMSG("Setting acceptance code to 0x%lx\n",(unsigned long)code);
548 DEBUGMSG("Setting acceptance mask to 0x%lx\n",(unsigned long)mask);
550 mcp2515_disable_configuration(chip);
556 * mcp2515_baud_rate: - set communication parameters.
557 * @chip: pointer to chip state structure
558 * @rate: baud rate in Hz
559 * @clock: frequency of mcp2515 clock in Hz (ISA osc is 14318000)
560 * @sjw: synchronization jump width (0-3) prescaled clock cycles
561 * @sampl_pt: sample point in % (0-100) sets (TSEG1+1)/(TSEG1+TSEG2+2) ratio
562 * @flags: fields %BTR1_SAM, %OCMODE, %OCPOL, %OCTP, %OCTN, %CLK_OFF, %CBP
564 * Return Value: negative value reports error.
565 * File: src/mcp2515.c
567 int mcp2515_baud_rate(struct canchip_t *chip, int rate, int clock, int sjw_in,
568 int sampl_pt, int flags)
570 int tqs; /* tbit/TQ */
572 int ps1, ps2, propseg, sjw;
576 DEBUGMSG("mcp2515_baud_rate\n");
577 DEBUGMSG("Clock = %d, rate = %d\n",clock,rate);
579 /* Determine the BRP value that gives the requested bit rate. */
580 for(brp = 0; brp < 8; brp++) {
581 tqs = clock / (2 * (brp + 1)) / rate;
582 if (tqs >= 5 && tqs <= 25
583 && (clock / (2 * (brp + 1)) / tqs) == rate)
589 /* The CAN bus bit time (tbit) is determined by:
590 * tbit = (SyncSeg + PropSeg + PS1 + PS2) * TQ
593 * sample point (between PS1 and PS2) must be at 60%-70% of the bit time
594 * PropSeg + PS1 >= PS2
595 * PropSeg + PS1 >= Tdelay
597 * 1 <= PropSeg <= 8, 1 <= PS1 <=8, 2 <= PS2 <= 8
598 * SJW = 1 is sufficient in most cases.
599 * Tdelay is usually 1 or 2 TQ.
602 propseg = ps1 = ps2 = (tqs - 1) / 3;
603 if (tqs - (1 + propseg + ps1 + ps2) == 2)
605 if (tqs - (1 + propseg + ps1 + ps2) == 1)
609 DEBUGMSG("bit rate: BRP = %d, Tbit = %d TQ, PropSeg = %d, PS1 = %d, PS2 = %d, SJW = %d\n",
610 brp, tqs, propseg, ps1, ps2, sjw);
612 if (mcp2515_enable_configuration(chip))
615 #define CNF2_BTLMODE 0x80
616 #define CNF3_PHSEG2_MASK 0x07
618 can_spi_acquire_bus(chip,1);
620 write_reg(chip, MCP2515_CNF1, ((sjw-1) << 6) | brp);
621 write_reg(chip, MCP2515_CNF2, CNF2_BTLMODE | ((ps1-1) << 3) | (propseg-1));
622 bitmod_reg(chip, MCP2515_CNF3, CNF3_PHSEG2_MASK,(ps2-1));
624 readreg = read_reg(chip, MCP2515_CNF1);
625 if (readreg != (u8)(((sjw-1) << 6) | brp)){
626 CANMSG("Wrong value in CNF1 - sent: 0x%X, received: 0x%X\n",((sjw-1) << 6) | brp,readreg);
629 readreg = read_reg(chip, MCP2515_CNF2);
630 if (readreg != (u8)(CNF2_BTLMODE | ((ps1-1) << 3) | (propseg-1))){
631 CANMSG("Wrong value in CNF2 - sent: 0x%X, received: 0x%X\n",CNF2_BTLMODE | ((ps1-1) << 3) | (propseg-1),readreg);
634 readreg = read_reg(chip, MCP2515_CNF3);
635 if (readreg & CNF3_PHSEG2_MASK != (u8)((ps2-1))){
636 CANMSG("Wrong value in CNF3 - sent: 0x%X, received: 0x%X\n",(ps2-1) | brp,readreg & CNF3_PHSEG2_MASK);
641 can_spi_release_bus(chip);
643 CANMSG("Failed to set bit rate for %d times\n",i);
644 mcp2515_disable_configuration(chip);
648 /* Calculate actual bit rate. */
649 DEBUGMSG("actual bit rate=%u\n",clock / (2 * (brp + 1)) / tqs);
651 mcp2515_disable_configuration(chip);
657 * mcp2515_pre_read_config: - prepares message object for message reception
658 * @chip: pointer to chip state structure
659 * @obj: pointer to message object state structure
661 * Return Value: negative value reports error.
662 * Positive value indicates immediate reception of message.
663 * File: src/mcp2515.c
665 int mcp2515_pre_read_config(struct canchip_t *chip, struct msgobj_t *obj)
667 DEBUGMSG("mcp2515_pre_read_config\n");
669 /* FIXME - error recovery here */
674 #define MAX_TRANSMIT_WAIT_LOOPS 10
676 * mcp2515_pre_write_config: - prepares message object for message transmission
677 * @chip: pointer to chip state structure
678 * @obj: pointer to message object state structure
679 * @msg: pointer to CAN message
681 * This function prepares selected message object for future initiation
682 * of message transmission by mcp2515_send_msg() function.
683 * The CAN message data and message ID are transfered from @msg slot
684 * into chip buffer in this function.
685 * Return Value: negative value reports error.
686 * File: src/mcp2515.c
688 int mcp2515_pre_write_config(struct canchip_t *chip, struct msgobj_t *obj,
689 struct canmsg_t *msg)
696 DEBUGMSG("mcp2515_pre_write_config: id=%u len=%u\n",
698 (unsigned)msg->length);
700 can_spi_acquire_bus(chip,1);
702 /* Wait until Transmit Buffer Status is released */
704 busy = read_reg(chip, MCP2515_TXB0CTRL) & mcpTXREQ;
707 } while (i < MAX_TRANSMIT_WAIT_LOOPS);
710 /* FIXME - error recovery here */
713 CANMSG("Transmit timed out, cancelling\n");
714 bitmod_reg(chip, MCP2515_TXB0CTRL, mcpTXREQ, 0);
715 can_spi_release_bus(chip);
720 frame.sidl = (msg->id << 5) ||
721 ((msg->flags & MSG_EXT) ? mcpEXIDE : 0) ||
722 ((msg->id >> 16) & mcpEID_MASK);
725 if(len > CAN_MSG_LENGTH) len = CAN_MSG_LENGTH;
727 if(msg->flags & MSG_EXT) {
728 frame.sidh = msg->id >> 21;
729 frame.sidl = (msg->id << 5) | ((msg->id >> 27) & 0x3) | mcpEXIDE;
730 frame.eid8 = msg->id >> 19;
732 frame.dlc = len | ((msg->flags & MSG_RTR) ? mcpRTR : 0);
733 memcpy(frame.data, msg->data, len);
736 frame.sidh = msg->id >> 21;
737 frame.sidl = (msg->id << 5) | ((msg->id >> 27) & 0x3);
738 frame.eid8 = msg->id >> 19;
740 frame.dlc = len | ((msg->flags & MSG_RTR) ? mcpRTR : 0);
741 memcpy(frame.data, msg->data, len);
744 write_block(chip, MCP2515_TXB0SIDH, len+5, &frame);
746 can_spi_release_bus(chip);
752 * mcp2515_send_msg: - initiate message transmission
753 * @chip: pointer to chip state structure
754 * @obj: pointer to message object state structure
755 * @msg: pointer to CAN message
757 * This function is called after mcp2515_pre_write_config() function,
758 * which prepares data in chip buffer.
759 * Return Value: negative value reports error.
760 * File: src/mcp2515.c
762 int mcp2515_send_msg(struct canchip_t *chip, struct msgobj_t *obj,
763 struct canmsg_t *msg)
765 DEBUGMSG("mcp2515_send_msg\n");
767 can_spi_acquire_bus(chip,1);
768 bitmod_reg(chip, MCP2515_TXB0CTRL, mcpTXREQ, mcpTXREQ);
769 can_spi_release_bus(chip);
775 * mcp2515_check_tx_stat: - checks state of transmission engine
776 * @chip: pointer to chip state structure
778 * Return Value: negative value reports error.
779 * Positive return value indicates transmission under way status.
780 * Zero value indicates finishing of all issued transmission requests.
781 * File: src/mcp2515.c
783 int mcp2515_check_tx_stat(struct canchip_t *chip)
786 DEBUGMSG("mcp2515_check_tx_stat\n");
788 can_spi_acquire_bus(chip,1);
789 status = read_reg(chip,MCP2515_TXB0CTRL) & mcpTXREQ;
790 can_spi_release_bus(chip);
792 if (status) return 1;
797 * mcp2515_set_btregs: - configures bitrate registers
798 * @chip: pointer to chip state structure
799 * @btr0: bitrate register 0
800 * @btr1: bitrate register 1
802 * Return Value: negative value reports error.
803 * File: src/mcp2515.c
805 int mcp2515_set_btregs(struct canchip_t *chip, unsigned short btr0,
808 DEBUGMSG("mcp2515_set_btregs\n");
810 if (mcp2515_enable_configuration(chip))
813 can_write_reg(chip, btr0, SJABTR0);
814 can_write_reg(chip, btr1, SJABTR1);
816 mcp2515_disable_configuration(chip);
822 * mcp2515_start_chip: - starts chip message processing
823 * @chip: pointer to chip state structure
825 * Return Value: negative value reports error.
826 * File: src/mcp2515.c
828 int mcp2515_start_chip(struct canchip_t *chip)
830 MCP2515_PRIV *priv=(MCP2515_PRIV *)(chip->chip_data);
831 DEBUGMSG("mcp2515_start_chip\n");
833 can_spi_acquire_bus(chip,1);
834 bitmod_reg(chip, MCP2515_CANCTRL, mcpMOD_MASK, mcpMOD_NORM);
835 can_spi_release_bus(chip);
837 /* reset error counters */
838 memset(&(priv->errcnt),0,sizeof(MCP2515_ERRCNT));
844 * mcp2515_stop_chip: - stops chip message processing
845 * @chip: pointer to chip state structure
847 * Return Value: negative value reports error.
848 * File: src/mcp2515.c
850 int mcp2515_stop_chip(struct canchip_t *chip)
852 DEBUGMSG("mcp2515_stop_chip\n");
854 can_spi_acquire_bus(chip,1);
855 bitmod_reg(chip, MCP2515_CANCTRL, mcpMOD_MASK, mcpMOD_SLEEP);
856 can_spi_release_bus(chip);
862 * mcp2515_attach_to_chip: - attaches to the chip, setups registers and state
863 * @chip: pointer to chip state structure
865 * Return Value: negative value reports error.
866 * File: src/mcp2515.c
868 int mcp2515_attach_to_chip(struct canchip_t *chip)
870 DEBUGMSG("mcp2515_attach_to_chip\n");
871 /* Initialize delayed interrupt processing */
872 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
873 INIT_WORK(&(((MCP2515_PRIV *)(chip->chip_data))->workqueue_handler),
877 INIT_WORK(&(((MCP2515_PRIV *)(chip->chip_data))->workqueue_handler),
881 tasklet_init(&(((MCP2515_PRIV *)(chip->chip_data))->tasklet_handler),
883 (unsigned long)chip);
889 * mcp2515_release_chip: - called before chip structure removal if %CHIP_ATTACHED is set
890 * @chip: pointer to chip state structure
892 * Return Value: negative value reports error.
893 * File: src/mcp2515.c
895 int mcp2515_release_chip(struct canchip_t *chip)
897 DEBUGMSG("mcp2515_release_chip\n");
899 panic("release: chip == NULL");
900 if (chip->chip_data==NULL)
901 panic("release: chip_data == NULL");
903 chip->flags &= ~CHIP_ATTACHED;
904 DEBUGMSG("Flush workqueue.\n");
905 cancel_delayed_work(&((MCP2515_PRIV *)(chip->chip_data))->workqueue_handler);
906 flush_scheduled_work();
908 DEBUGMSG("Kill tasklets.\n");
909 tasklet_kill(&((MCP2515_PRIV *)(chip->chip_data))->tasklet_handler);
911 mcp2515_stop_chip(chip);
912 can_write_reg(chip, sjaDISABLE_INTERRUPTS, SJAIER);
918 * mcp2515_remote_request: - configures message object and asks for RTR message
919 * @chip: pointer to chip state structure
920 * @obj: pointer to message object structure
922 * Return Value: negative value reports error.
923 * File: src/mcp2515.c
925 int mcp2515_remote_request(struct canchip_t *chip, struct msgobj_t *obj)
927 CANMSG("mcp2515_remote_request not implemented\n");
932 * mcp2515_standard_mask: - setup of mask for message filtering
933 * @chip: pointer to chip state structure
934 * @code: can message acceptance code
935 * @mask: can message acceptance mask
937 * Return Value: negative value reports error.
938 * File: src/mcp2515.c
940 int mcp2515_standard_mask(struct canchip_t *chip, unsigned short code,
943 CANMSG("mcp2515_standard_mask not implemented\n");
948 * mcp2515_clear_objects: - clears state of all message object residing in chip
949 * @chip: pointer to chip state structure
951 * Return Value: negative value reports error.
952 * File: src/mcp2515.c
954 int mcp2515_clear_objects(struct canchip_t *chip)
956 CANMSG("mcp2515_clear_objects not implemented\n");
961 * mcp2515_config_irqs: - tunes chip hardware interrupt delivery
962 * @chip: pointer to chip state structure
963 * @irqs: requested chip IRQ configuration
965 * Return Value: negative value reports error.
966 * File: src/mcp2515.c
968 int mcp2515_config_irqs(struct canchip_t *chip, short irqs)
970 CANMSG("mcp2515_config_irqs not implemented\n");
978 * mcp2515_irq_handler: - interrupt service routine
979 * @irq: interrupt vector number, this value is system specific
980 * @chip: pointer to chip state structure
982 * Interrupt handler is activated when state of CAN controller chip changes,
983 * there is message to be read or there is more space for new messages or
984 * error occurs. The receive events results in reading of the message from
985 * CAN controller chip and distribution of message through attached
987 * File: src/mcp2515.c
989 int mcp2515_irq_handler(int irq, struct canchip_t *chip)
991 //DEBUGMSG("mcp2515_irq_handler\n");
993 return CANCHIP_IRQ_ACCEPTED;
994 if (~chip->flags & CHIP_ATTACHED)
995 return CANCHIP_IRQ_ACCEPTED;
997 /* do work in tasklet if bus is immediately available */
998 if(can_spi_acquire_bus(chip, 0))
999 tasklet_schedule(&((MCP2515_PRIV *)(chip->chip_data))->tasklet_handler);
1000 else /* do work in workqueue */
1001 schedule_work(&((MCP2515_PRIV *)(chip->chip_data))->workqueue_handler);
1003 disable_irq(chip->chip_irq);
1004 return CANCHIP_IRQ_HANDLED;
1008 * mcp2515_wakeup_tx: - wakeups TX processing
1009 * @chip: pointer to chip state structure
1010 * @obj: pointer to message object structure
1012 * Function is responsible for initiating message transmition.
1013 * It is responsible for clearing of object TX_REQUEST flag
1015 * Return Value: negative value reports error.
1016 * File: src/mcp2515.c
1018 int mcp2515_wakeup_tx(struct canchip_t *chip, struct msgobj_t *obj)
1020 DEBUGMSG("mcp2515_wakeup_tx\n");
1022 //can_preempt_disable();
1024 can_msgobj_set_fl(obj,TX_PENDING);
1025 can_msgobj_set_fl(obj,TX_REQUEST);
1027 while(!can_msgobj_test_and_set_fl(obj,TX_LOCK)){
1030 can_msgobj_clear_fl(obj,TX_REQUEST);
1032 can_spi_acquire_bus(chip,1);
1033 rq = read_reg(chip, MCP2515_TXB0CTRL) & mcpTXREQ;
1035 obj->tx_retry_cnt=0;
1036 tx_handler(chip, obj);
1038 can_spi_release_bus(chip);
1040 can_msgobj_clear_fl(obj,TX_LOCK);
1041 if(!can_msgobj_test_fl(obj,TX_REQUEST)) break;
1042 DEBUGMSG("TX looping in mcp2515_wakeup_tx\n");
1044 //can_preempt_enable();
1049 int mcp2515_register(struct chipspecops_t *chipspecops)
1051 DEBUGMSG("mcp2515_register\n");
1052 chipspecops->chip_config=mcp2515_chip_config;
1053 chipspecops->baud_rate=mcp2515_baud_rate;
1054 chipspecops->standard_mask=mcp2515_standard_mask;
1055 chipspecops->extended_mask=mcp2515_extended_mask;
1056 chipspecops->message15_mask=mcp2515_extended_mask;
1057 chipspecops->clear_objects=mcp2515_clear_objects;
1058 chipspecops->config_irqs=mcp2515_config_irqs;
1059 chipspecops->pre_read_config=mcp2515_pre_read_config;
1060 chipspecops->pre_write_config=mcp2515_pre_write_config;
1061 chipspecops->send_msg=mcp2515_send_msg;
1062 chipspecops->check_tx_stat=mcp2515_check_tx_stat;
1063 chipspecops->wakeup_tx=mcp2515_wakeup_tx;
1064 chipspecops->remote_request=mcp2515_remote_request;
1065 chipspecops->enable_configuration=mcp2515_enable_configuration;
1066 chipspecops->disable_configuration=mcp2515_disable_configuration;
1067 chipspecops->attach_to_chip=mcp2515_attach_to_chip;
1068 chipspecops->release_chip=mcp2515_release_chip;
1069 chipspecops->set_btregs=mcp2515_set_btregs;
1070 chipspecops->start_chip=mcp2515_start_chip;
1071 chipspecops->stop_chip=mcp2515_stop_chip;
1072 chipspecops->irq_handler=mcp2515_irq_handler;
1073 chipspecops->irq_accept=NULL;
1074 chipspecops->reset_chip=mcp2515_reset_chip;
1075 chipspecops->get_info=mcp2515_get_info;
1080 * mcp2515_fill_chipspecops - fills chip specific operations
1081 * @chip: pointer to chip representation structure
1083 * The function fills chip specific operations for mcp2515 (PeliCAN) chip.
1085 * Return Value: returns negative number in the case of fail
1087 int mcp2515_fill_chipspecops(struct canchip_t *chip)
1089 DEBUGMSG("mcp2515_fill_chipspecops\n");
1090 chip->chip_type="mcp2515";
1091 chip->max_objects=2;
1092 mcp2515_register(chip->chipspecops);