File indexing completed on 2025-05-11 08:24:06
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030 #include <rtems.h>
0031 #include <rtems/libio.h>
0032 #include <stdlib.h>
0033 #include <stdio.h>
0034 #include <string.h>
0035 #include <bsp.h>
0036 #include <rtems/bspIo.h> /* printk */
0037
0038 #include <drvmgr/drvmgr.h>
0039 #include <grlib/ambapp_bus.h>
0040 #include <grlib/occan.h>
0041 #include <grlib/canbtrs.h>
0042
0043 #include <grlib/grlib_impl.h>
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070 #ifndef OCCAN_WORD_REGS
0071 #define OCCAN_BYTE_REGS
0072 #else
0073 #undef OCCAN_BYTE_REGS
0074 #endif
0075
0076
0077 #define OCCAN_TX_IRQ_FLAG_FIXUP 1
0078
0079 #define OCCAN_WORD_REG_OFS 0x80
0080 #define OCCAN_NCORE_OFS 0x100
0081 #define DEFAULT_CLKDIV 0x7
0082 #define DEFAULT_EXTENDED_MODE 1
0083 #define DEFAULT_RX_FIFO_LEN 64
0084 #define DEFAULT_TX_FIFO_LEN 64
0085
0086
0087 #undef REDUNDANT_CHANNELS
0088
0089
0090 #ifdef DEBUG
0091 #define DBG(fmt, vargs...) printk(fmt, ## vargs )
0092 #else
0093 #define DBG(fmt, vargs...)
0094 #endif
0095
0096
0097 typedef struct {
0098 int cnt;
0099 int ovcnt;
0100 int full;
0101 CANMsg *tail, *head;
0102 CANMsg *base;
0103 CANMsg fifoarea[0];
0104 } occan_fifo;
0105
0106
0107
0108 typedef struct {
0109 unsigned char
0110 mode,
0111 cmd,
0112 status,
0113 intflags,
0114 inten,
0115 resv0,
0116 bustim0,
0117 bustim1,
0118 unused0[2],
0119 resv1,
0120 arbcode,
0121 errcode,
0122 errwarn,
0123 rx_err_cnt,
0124 tx_err_cnt,
0125 rx_fi_xff;
0126 union{
0127 struct {
0128 unsigned char id[2];
0129 unsigned char data[8];
0130 unsigned char next_in_fifo[2];
0131 } rx_sff;
0132 struct {
0133 unsigned char id[4];
0134 unsigned char data[8];
0135 } rx_eff;
0136 struct {
0137 unsigned char id[2];
0138 unsigned char data[8];
0139 unsigned char unused[2];
0140 } tx_sff;
0141 struct {
0142 unsigned char id[4];
0143 unsigned char data[8];
0144 } tx_eff;
0145 struct {
0146 unsigned char code[3];
0147 unsigned char mask[4];
0148 } rst_accept;
0149 } msg;
0150 unsigned char rx_msg_cnt;
0151 unsigned char unused1;
0152 unsigned char clkdiv;
0153 } pelican8_regs;
0154
0155 typedef struct {
0156 unsigned char
0157 mode, unused0[3],
0158 cmd, unused1[3],
0159 status, unused2[3],
0160 intflags, unused3[3],
0161 inten, unused4[3],
0162 resv0, unused5[3],
0163 bustim0, unused6[3],
0164 bustim1, unused7[3],
0165 unused8[8],
0166 resv1,unused9[3],
0167 arbcode,unused10[3],
0168 errcode,unused11[3],
0169 errwarn,unused12[3],
0170 rx_err_cnt,unused13[3],
0171 tx_err_cnt,unused14[3],
0172 rx_fi_xff, unused15[3];
0173
0174 union{
0175 struct {
0176 unsigned int id[2];
0177 unsigned int data[8];
0178 unsigned int next_in_fifo[2];
0179 } rx_sff;
0180 struct {
0181 unsigned int id[4];
0182 unsigned int data[8];
0183 } rx_eff;
0184 struct {
0185 unsigned int id[2];
0186 unsigned int data[8];
0187 } tx_sff;
0188 struct {
0189 unsigned int id[4];
0190 unsigned int data[8];
0191 } tx_eff;
0192 struct {
0193 unsigned int code[3];
0194 unsigned int mask[4];
0195 } rst_accept;
0196 } msg;
0197 unsigned char rx_msg_cnt,unused16[3];
0198 unsigned char unused17[4];
0199 unsigned char clkdiv,unused18[3];
0200 } pelican32_regs;
0201
0202 #ifdef OCCAN_BYTE_REGS
0203 #define pelican_regs pelican8_regs
0204 #else
0205 #define pelican_regs pelican32_regs
0206 #endif
0207
0208
0209 #define OCCAN_SAMPLING_POINT 90
0210
0211
0212 struct grlib_canbtrs_ranges occan_btrs_ranges = {
0213 .max_scaler = 64,
0214 .has_bpr = 0,
0215 .divfactor = 1,
0216 .min_tseg1 = 1,
0217 .max_tseg1 = 16,
0218 .min_tseg2 = 1,
0219 .max_tseg2 = 8,
0220 };
0221
0222 typedef struct {
0223 unsigned char btr0;
0224 unsigned char btr1;
0225 } occan_speed_regs;
0226
0227 typedef struct {
0228 struct drvmgr_dev *dev;
0229 char devName[52];
0230 SPIN_DECLARE(devlock);
0231
0232
0233 pelican_regs *regs;
0234 int byte_regs;
0235 int irq;
0236 occan_speed_regs timing;
0237 int channel;
0238 int single_mode;
0239 unsigned int sys_freq_hz;
0240
0241
0242 rtems_id devsem;
0243 rtems_id txsem;
0244 rtems_id rxsem;
0245 int open;
0246 int started;
0247 int rxblk;
0248 int txblk;
0249 int sending;
0250 unsigned int status;
0251 occan_stats stats;
0252
0253
0254 occan_fifo *rxfifo;
0255 occan_fifo *txfifo;
0256
0257
0258 unsigned int speed;
0259 unsigned char acode[4];
0260 unsigned char amask[4];
0261 } occan_priv;
0262
0263
0264 static void occan_fifo_put(occan_fifo *fifo);
0265 static CANMsg *occan_fifo_put_claim(occan_fifo *fifo, int force);
0266 static occan_fifo *occan_fifo_create(int cnt);
0267 static void occan_fifo_free(occan_fifo *fifo);
0268 static int occan_fifo_full(occan_fifo *fifo);
0269 static int occan_fifo_empty(occan_fifo *fifo);
0270 static void occan_fifo_get(occan_fifo *fifo);
0271 static CANMsg *occan_fifo_claim_get(occan_fifo *fifo);
0272 static void occan_fifo_clr(occan_fifo *fifo);
0273
0274
0275 static void convert_timing_to_btrs(
0276 struct grlib_canbtrs_timing *t,
0277 occan_speed_regs *btrs);
0278 static int occan_set_speedregs(occan_priv *priv, occan_speed_regs *timing);
0279 static void pelican_init(occan_priv *priv);
0280 static void pelican_open(occan_priv *priv);
0281 static int pelican_start(occan_priv *priv);
0282 static void pelican_stop(occan_priv *priv);
0283 static int pelican_send(occan_priv *can, CANMsg *msg);
0284 static void pelican_set_accept(occan_priv *priv, unsigned char *acode, unsigned char *amask);
0285 void occan_interrupt(void *arg);
0286 #ifdef DEBUG_PRINT_REGMAP
0287 static void pelican_regadr_print(pelican_regs *regs);
0288 #endif
0289
0290
0291 static rtems_device_driver occan_ioctl(rtems_device_major_number major, rtems_device_minor_number minor, void *arg);
0292 static rtems_device_driver occan_write(rtems_device_major_number major, rtems_device_minor_number minor, void *arg);
0293 static rtems_device_driver occan_read(rtems_device_major_number major, rtems_device_minor_number minor, void *arg);
0294 static rtems_device_driver occan_close(rtems_device_major_number major, rtems_device_minor_number minor, void *arg);
0295 static rtems_device_driver occan_open(rtems_device_major_number major, rtems_device_minor_number minor, void *arg);
0296 static rtems_device_driver occan_initialize(rtems_device_major_number major, rtems_device_minor_number unused, void *arg);
0297
0298 #define OCCAN_DRIVER_TABLE_ENTRY { occan_initialize, occan_open, occan_close, occan_read, occan_write, occan_ioctl }
0299 static rtems_driver_address_table occan_driver = OCCAN_DRIVER_TABLE_ENTRY;
0300
0301
0302
0303
0304
0305
0306 #define READ_REG(priv, address) occan_reg_read(priv, (unsigned int)address)
0307 #define WRITE_REG(priv, address, data) occan_reg_write(priv, (unsigned int)address, data)
0308
0309 static unsigned int occan_reg_read(occan_priv *priv, unsigned int address)
0310 {
0311 unsigned int adr;
0312 if ( priv->byte_regs ) {
0313 adr = address;
0314 } else {
0315
0316 adr = (address & (~0x7f)) | ((address & 0x7f)<<2);
0317 }
0318 return *(volatile unsigned char *)adr;
0319 }
0320
0321 static void occan_reg_write(
0322 occan_priv *priv,
0323 unsigned int address,
0324 unsigned char value)
0325 {
0326 unsigned int adr;
0327 if ( priv->byte_regs ) {
0328 adr = address;
0329 } else {
0330
0331 adr = (address & (~0x7f)) | ((address & 0x7f)<<2);
0332 }
0333 *(volatile unsigned char *)adr = value;;
0334 }
0335
0336
0337 #define PELICAN_MOD_RESET 0x1
0338 #define PELICAN_MOD_LISTEN 0x2
0339 #define PELICAN_MOD_SELFTEST 0x4
0340 #define PELICAN_MOD_ACCEPT 0x8
0341
0342
0343 #define PELICAN_CMD_TXREQ 0x1
0344 #define PELICAN_CMD_ABORT 0x2
0345 #define PELICAN_CMD_RELRXBUF 0x4
0346 #define PELICAN_CMD_CLRDOVR 0x8
0347 #define PELICAN_CMD_SELFRXRQ 0x10
0348
0349
0350 #define PELICAN_STAT_RXBUF 0x1
0351 #define PELICAN_STAT_DOVR 0x2
0352 #define PELICAN_STAT_TXBUF 0x4
0353 #define PELICAN_STAT_TXOK 0x8
0354 #define PELICAN_STAT_RX 0x10
0355 #define PELICAN_STAT_TX 0x20
0356 #define PELICAN_STAT_ERR 0x40
0357 #define PELICAN_STAT_BUS 0x80
0358
0359
0360 #define PELICAN_IF_RX 0x1
0361 #define PELICAN_IF_TX 0x2
0362 #define PELICAN_IF_ERRW 0x4
0363 #define PELICAN_IF_DOVR 0x8
0364 #define PELICAN_IF_ERRP 0x20
0365 #define PELICAN_IF_ARB 0x40
0366 #define PELICAN_IF_BUS 0x80
0367
0368
0369 #define PELICAN_IE_RX 0x1
0370 #define PELICAN_IE_TX 0x2
0371 #define PELICAN_IE_ERRW 0x4
0372 #define PELICAN_IE_DOVR 0x8
0373 #define PELICAN_IE_ERRP 0x20
0374 #define PELICAN_IE_ARB 0x40
0375 #define PELICAN_IE_BUS 0x80
0376
0377
0378 #define PELICAN_ARB_BITS 0x1f
0379
0380
0381 #define PELICAN_ECC_CODE_BIT 0x00
0382 #define PELICAN_ECC_CODE_FORM 0x40
0383 #define PELICAN_ECC_CODE_STUFF 0x80
0384 #define PELICAN_ECC_CODE_OTHER 0xc0
0385 #define PELICAN_ECC_CODE 0xc0
0386
0387 #define PELICAN_ECC_DIR 0x20
0388 #define PELICAN_ECC_SEG 0x1f
0389
0390
0391 #define PELICAN_CDR_DIV 0x7
0392 #define PELICAN_CDR_OFF 0x8
0393 #define PELICAN_CDR_MODE 0x80
0394 #define PELICAN_CDR_MODE_PELICAN 0x80
0395 #define PELICAN_CDR_MODE_BITS 7
0396 #define PELICAN_CDR_MODE_BASICAN 0x00
0397
0398
0399
0400 #define OCCAN_BUSTIM_SJW 0xc0
0401 #define OCCAN_BUSTIM_BRP 0x3f
0402 #define OCCAN_BUSTIM_SJW_BIT 6
0403
0404 #define OCCAN_BUSTIM_SAM 0x80
0405 #define OCCAN_BUSTIM_TSEG2 0x70
0406 #define OCCAN_BUSTIM_TSEG2_BIT 4
0407 #define OCCAN_BUSTIM_TSEG1 0x0f
0408
0409
0410
0411
0412
0413
0414
0415
0416
0417
0418
0419
0420
0421 static int occan_driver_io_registered = 0;
0422 static rtems_device_major_number occan_driver_io_major = 0;
0423
0424
0425
0426
0427 int occan_register_io(rtems_device_major_number *m);
0428 int occan_device_init(occan_priv *pDev);
0429
0430 int occan_init2(struct drvmgr_dev *dev);
0431 int occan_init3(struct drvmgr_dev *dev);
0432
0433 struct drvmgr_drv_ops occan_ops =
0434 {
0435 .init = {NULL, occan_init2, occan_init3, NULL},
0436 .remove = NULL,
0437 .info = NULL
0438 };
0439
0440 struct amba_dev_id occan_ids[] =
0441 {
0442 {VENDOR_GAISLER, GAISLER_CANAHB},
0443 {0, 0}
0444 };
0445
0446 struct amba_drv_info occan_drv_info =
0447 {
0448 {
0449 DRVMGR_OBJ_DRV,
0450 NULL,
0451 NULL,
0452 DRIVER_AMBAPP_GAISLER_OCCAN_ID,
0453 "OCCAN_DRV",
0454 DRVMGR_BUS_TYPE_AMBAPP,
0455 &occan_ops,
0456 NULL,
0457 0,
0458 0,
0459 },
0460 &occan_ids[0]
0461 };
0462
0463 void occan_register_drv (void)
0464 {
0465 DBG("Registering OCCAN driver\n");
0466 drvmgr_drv_register(&occan_drv_info.general);
0467 }
0468
0469 int occan_init2(struct drvmgr_dev *dev)
0470 {
0471 occan_priv *priv;
0472
0473 DBG("OCCAN[%d] on bus %s\n", dev->minor_drv, dev->parent->dev->name);
0474 priv = dev->priv = grlib_calloc(1, sizeof(*priv));
0475 if ( !priv )
0476 return DRVMGR_NOMEM;
0477 priv->dev = dev;
0478
0479 return DRVMGR_OK;
0480 }
0481
0482 int occan_init3(struct drvmgr_dev *dev)
0483 {
0484 occan_priv *priv;
0485 char prefix[32];
0486 rtems_status_code status;
0487
0488 priv = dev->priv;
0489
0490
0491
0492 if ( occan_driver_io_registered == 0) {
0493
0494 if ( occan_register_io(&occan_driver_io_major) ) {
0495
0496 dev->priv = NULL;
0497 return DRVMGR_FAIL;
0498 }
0499
0500 occan_driver_io_registered = 1;
0501 }
0502
0503
0504
0505
0506
0507 if ( occan_device_init(priv) ) {
0508 return DRVMGR_FAIL;
0509 }
0510
0511
0512 prefix[0] = '\0';
0513 if ( drvmgr_get_dev_prefix(dev, prefix) ) {
0514
0515
0516
0517 sprintf(priv->devName, "/dev/occan%d", dev->minor_drv);
0518 } else {
0519
0520
0521
0522 sprintf(priv->devName, "/dev/%soccan%d", prefix, dev->minor_bus);
0523 }
0524
0525
0526 DBG("OCCAN[%d]: Registering %s\n", dev->minor_drv, priv->devName);
0527 status = rtems_io_register_name(priv->devName, occan_driver_io_major, dev->minor_drv);
0528 if (status != RTEMS_SUCCESSFUL) {
0529 return DRVMGR_FAIL;
0530 }
0531
0532 return DRVMGR_OK;
0533 }
0534
0535
0536
0537 int occan_register_io(rtems_device_major_number *m)
0538 {
0539 rtems_status_code r;
0540
0541 if ((r = rtems_io_register_driver(0, &occan_driver, m)) == RTEMS_SUCCESSFUL) {
0542 DBG("OCCAN driver successfully registered, major: %d\n", *m);
0543 } else {
0544 switch(r) {
0545 case RTEMS_TOO_MANY:
0546 printk("OCCAN rtems_io_register_driver failed: RTEMS_TOO_MANY\n");
0547 return -1;
0548 case RTEMS_INVALID_NUMBER:
0549 printk("OCCAN rtems_io_register_driver failed: RTEMS_INVALID_NUMBER\n");
0550 return -1;
0551 case RTEMS_RESOURCE_IN_USE:
0552 printk("OCCAN rtems_io_register_driver failed: RTEMS_RESOURCE_IN_USE\n");
0553 return -1;
0554 default:
0555 printk("OCCAN rtems_io_register_driver failed\n");
0556 return -1;
0557 }
0558 }
0559 return 0;
0560 }
0561
0562 int occan_device_init(occan_priv *pDev)
0563 {
0564 struct amba_dev_info *ambadev;
0565 struct ambapp_core *pnpinfo;
0566 rtems_status_code status;
0567 int minor;
0568
0569
0570 ambadev = (struct amba_dev_info *)pDev->dev->businfo;
0571 if ( ambadev == NULL ) {
0572 return -1;
0573 }
0574 pnpinfo = &ambadev->info;
0575 pDev->irq = pnpinfo->irq;
0576 pDev->regs = (pelican_regs *)(pnpinfo->ahb_slv->start[0] + OCCAN_NCORE_OFS*pnpinfo->index);
0577 pDev->byte_regs = 1;
0578 minor = pDev->dev->minor_drv;
0579
0580
0581 if ( drvmgr_freq_get(pDev->dev, DEV_AHB_SLV, &pDev->sys_freq_hz) ) {
0582 return -1;
0583 }
0584
0585 DBG("OCCAN frequency: %d Hz\n", pDev->sys_freq_hz);
0586
0587
0588 pDev->open = 0;
0589 pDev->started = 0;
0590 pDev->rxfifo = NULL;
0591 pDev->txfifo = NULL;
0592 status = rtems_semaphore_create(
0593 rtems_build_name('C', 'd', 'v', '0'+minor),
0594 1,
0595 RTEMS_FIFO | RTEMS_SIMPLE_BINARY_SEMAPHORE | RTEMS_NO_INHERIT_PRIORITY | \
0596 RTEMS_NO_PRIORITY_CEILING,
0597 0,
0598 &pDev->devsem);
0599 if ( status != RTEMS_SUCCESSFUL ){
0600 printk("OCCAN[%d]: Failed to create dev semaphore, (%d)\n\r",minor, status);
0601 return RTEMS_UNSATISFIED;
0602 }
0603 status = rtems_semaphore_create(
0604 rtems_build_name('C', 't', 'x', '0'+minor),
0605 0,
0606 RTEMS_FIFO | RTEMS_SIMPLE_BINARY_SEMAPHORE | RTEMS_NO_INHERIT_PRIORITY | \
0607 RTEMS_NO_PRIORITY_CEILING,
0608 0,
0609 &pDev->txsem);
0610 if ( status != RTEMS_SUCCESSFUL ){
0611 printk("OCCAN[%d]: Failed to create tx semaphore, (%d)\n\r",minor, status);
0612 return RTEMS_UNSATISFIED;
0613 }
0614 status = rtems_semaphore_create(
0615 rtems_build_name('C', 'r', 'x', '0'+minor),
0616 0,
0617 RTEMS_FIFO | RTEMS_SIMPLE_BINARY_SEMAPHORE | RTEMS_NO_INHERIT_PRIORITY | \
0618 RTEMS_NO_PRIORITY_CEILING,
0619 0,
0620 &pDev->rxsem);
0621 if ( status != RTEMS_SUCCESSFUL ){
0622 printk("OCCAN[%d]: Failed to create rx semaphore, (%d)\n\r",minor, status);
0623 return RTEMS_UNSATISFIED;
0624 }
0625
0626
0627 pelican_init(pDev);
0628
0629 #ifdef DEBUG_PRINT_REGMAP
0630 pelican_regadr_print(pDev->regs);
0631 #endif
0632
0633 return 0;
0634 }
0635
0636
0637 #ifdef DEBUG
0638 static void pelican_regs_print(occan_priv *pDev){
0639 pelican_regs *regs = pDev->regs;
0640 printk("--- PELICAN 0x%lx ---\n\r",(unsigned int)regs);
0641 printk(" MODE: 0x%02x\n\r",READ_REG(pDev, ®s->mode));
0642 printk(" CMD: 0x%02x\n\r",READ_REG(pDev, ®s->cmd));
0643 printk(" STATUS: 0x%02x\n\r",READ_REG(pDev, ®s->status));
0644
0645 printk(" INTEN: 0x%02x\n\r",READ_REG(pDev, ®s->inten));
0646 printk(" BTR0: 0x%02x\n\r",READ_REG(pDev, ®s->bustim0));
0647 printk(" BTR1: 0x%02x\n\r",READ_REG(pDev, ®s->bustim1));
0648 printk(" ARBCODE: 0x%02x\n\r",READ_REG(pDev, ®s->arbcode));
0649 printk(" ERRCODE: 0x%02x\n\r",READ_REG(pDev, ®s->errcode));
0650 printk(" ERRWARN: 0x%02x\n\r",READ_REG(pDev, ®s->errwarn));
0651 printk(" RX_ERR_CNT: 0x%02x\n\r",READ_REG(pDev, ®s->rx_err_cnt));
0652 printk(" TX_ERR_CNT: 0x%02x\n\r",READ_REG(pDev, ®s->tx_err_cnt));
0653 if ( READ_REG(pDev, ®s->mode) & PELICAN_MOD_RESET ){
0654
0655 printk(" ACR0: 0x%02x (0x%lx)\n\r",READ_REG(pDev, ®s->rx_fi_xff),®s->rx_fi_xff);
0656 printk(" ACR1: 0x%02x (0x%lx)\n\r",READ_REG(pDev, ®s->msg.rst_accept.code[0]),(unsigned int)®s->msg.rst_accept.code[0]);
0657 printk(" ACR1: 0x%02x (0x%lx)\n\r",READ_REG(pDev, ®s->msg.rst_accept.code[1]),(unsigned int)®s->msg.rst_accept.code[1]);
0658 printk(" ACR1: 0x%02x (0x%lx)\n\r",READ_REG(pDev, ®s->msg.rst_accept.code[2]),(unsigned int)®s->msg.rst_accept.code[2]);
0659 printk(" AMR0: 0x%02x (0x%lx)\n\r",READ_REG(pDev, ®s->msg.rst_accept.mask[0]),(unsigned int)®s->msg.rst_accept.mask[0]);
0660 printk(" AMR1: 0x%02x (0x%lx)\n\r",READ_REG(pDev, ®s->msg.rst_accept.mask[1]),(unsigned int)®s->msg.rst_accept.mask[1]);
0661 printk(" AMR2: 0x%02x (0x%lx)\n\r",READ_REG(pDev, ®s->msg.rst_accept.mask[2]),(unsigned int)®s->msg.rst_accept.mask[2]);
0662 printk(" AMR3: 0x%02x (0x%lx)\n\r",READ_REG(pDev, ®s->msg.rst_accept.mask[3]),(unsigned int)®s->msg.rst_accept.mask[3]);
0663
0664 }else{
0665 printk(" RXFI_XFF: 0x%02x\n\r",READ_REG(pDev, ®s->rx_fi_xff));
0666 }
0667 printk(" RX_MSG_CNT: 0x%02x\n\r",READ_REG(pDev, ®s->rx_msg_cnt));
0668 printk(" CLKDIV: 0x%02x\n\r",READ_REG(pDev, ®s->clkdiv));
0669 printk("-------------------\n\r");
0670 }
0671 #endif
0672
0673 #ifdef DEBUG_PRINT_REGMAP
0674 static void pelican_regadr_print(pelican_regs *regs){
0675 printk("--- PELICAN 0x%lx ---\n\r",(unsigned int)regs);
0676 printk(" MODE: 0x%lx\n\r",(unsigned int)®s->mode);
0677 printk(" CMD: 0x%lx\n\r",(unsigned int)®s->cmd);
0678 printk(" STATUS: 0x%lx\n\r",(unsigned int)®s->status);
0679
0680 printk(" INTEN: 0x%lx\n\r",(unsigned int)®s->inten);
0681 printk(" BTR0: 0x%lx\n\r",(unsigned int)®s->bustim0);
0682 printk(" BTR1: 0x%lx\n\r",(unsigned int)®s->bustim1);
0683 printk(" ARBCODE: 0x%lx\n\r",(unsigned int)®s->arbcode);
0684 printk(" ERRCODE: 0x%lx\n\r",(unsigned int)®s->errcode);
0685 printk(" ERRWARN: 0x%lx\n\r",(unsigned int)®s->errwarn);
0686 printk(" RX_ERR_CNT: 0x%lx\n\r",(unsigned int)®s->rx_err_cnt);
0687 printk(" TX_ERR_CNT: 0x%lx\n\r",(unsigned int)®s->tx_err_cnt);
0688
0689
0690 printk(" RXFI_XFF: 0x%lx\n\r",(unsigned int)®s->rx_fi_xff);
0691
0692
0693 printk(" ACR0: 0x%lx\n\r",(unsigned int)®s->rx_fi_xff);
0694 printk(" ACR1: 0x%lx\n\r",(unsigned int)®s->msg.rst_accept.code[0]);
0695 printk(" ACR2: 0x%lx\n\r",(unsigned int)®s->msg.rst_accept.code[1]);
0696 printk(" ACR3: 0x%lx\n\r",(unsigned int)®s->msg.rst_accept.code[2]);
0697 printk(" AMR0: 0x%lx\n\r",(unsigned int)®s->msg.rst_accept.mask[0]);
0698 printk(" AMR1: 0x%lx\n\r",(unsigned int)®s->msg.rst_accept.mask[1]);
0699 printk(" AMR2: 0x%lx\n\r",(unsigned int)®s->msg.rst_accept.mask[2]);
0700 printk(" AMR3: 0x%lx\n\r",(unsigned int)®s->msg.rst_accept.mask[3]);
0701
0702
0703 printk(" EFFTX_ID[0]: 0x%lx\n\r",(unsigned int)®s->msg.tx_eff.id[0]);
0704 printk(" EFFTX_ID[1]: 0x%lx\n\r",(unsigned int)®s->msg.tx_eff.id[1]);
0705 printk(" EFFTX_ID[2]: 0x%lx\n\r",(unsigned int)®s->msg.tx_eff.id[2]);
0706 printk(" EFFTX_ID[3]: 0x%lx\n\r",(unsigned int)®s->msg.tx_eff.id[3]);
0707
0708 printk(" EFFTX_DATA[0]: 0x%lx\n\r",(unsigned int)®s->msg.tx_eff.data[0]);
0709 printk(" EFFTX_DATA[1]: 0x%lx\n\r",(unsigned int)®s->msg.tx_eff.data[1]);
0710 printk(" EFFTX_DATA[2]: 0x%lx\n\r",(unsigned int)®s->msg.tx_eff.data[2]);
0711 printk(" EFFTX_DATA[3]: 0x%lx\n\r",(unsigned int)®s->msg.tx_eff.data[3]);
0712 printk(" EFFTX_DATA[4]: 0x%lx\n\r",(unsigned int)®s->msg.tx_eff.data[4]);
0713 printk(" EFFTX_DATA[5]: 0x%lx\n\r",(unsigned int)®s->msg.tx_eff.data[5]);
0714 printk(" EFFTX_DATA[6]: 0x%lx\n\r",(unsigned int)®s->msg.tx_eff.data[6]);
0715 printk(" EFFTX_DATA[7]: 0x%lx\n\r",(unsigned int)®s->msg.tx_eff.data[7]);
0716
0717
0718 printk(" EFFRX_ID[0]: 0x%lx\n\r",(unsigned int)®s->msg.rx_eff.id[0]);
0719 printk(" EFFRX_ID[1]: 0x%lx\n\r",(unsigned int)®s->msg.rx_eff.id[1]);
0720 printk(" EFFRX_ID[2]: 0x%lx\n\r",(unsigned int)®s->msg.rx_eff.id[2]);
0721 printk(" EFFRX_ID[3]: 0x%lx\n\r",(unsigned int)®s->msg.rx_eff.id[3]);
0722
0723 printk(" EFFRX_DATA[0]: 0x%lx\n\r",(unsigned int)®s->msg.rx_eff.data[0]);
0724 printk(" EFFRX_DATA[1]: 0x%lx\n\r",(unsigned int)®s->msg.rx_eff.data[1]);
0725 printk(" EFFRX_DATA[2]: 0x%lx\n\r",(unsigned int)®s->msg.rx_eff.data[2]);
0726 printk(" EFFRX_DATA[3]: 0x%lx\n\r",(unsigned int)®s->msg.rx_eff.data[3]);
0727 printk(" EFFRX_DATA[4]: 0x%lx\n\r",(unsigned int)®s->msg.rx_eff.data[4]);
0728 printk(" EFFRX_DATA[5]: 0x%lx\n\r",(unsigned int)®s->msg.rx_eff.data[5]);
0729 printk(" EFFRX_DATA[6]: 0x%lx\n\r",(unsigned int)®s->msg.rx_eff.data[6]);
0730 printk(" EFFRX_DATA[7]: 0x%lx\n\r",(unsigned int)®s->msg.rx_eff.data[7]);
0731
0732
0733
0734 printk(" SFFRX_ID[0]: 0x%lx\n\r",(unsigned int)®s->msg.rx_sff.id[0]);
0735 printk(" SFFRX_ID[1]: 0x%lx\n\r",(unsigned int)®s->msg.rx_sff.id[1]);
0736
0737 printk(" SFFRX_DATA[0]: 0x%lx\n\r",(unsigned int)®s->msg.rx_sff.data[0]);
0738 printk(" SFFRX_DATA[1]: 0x%lx\n\r",(unsigned int)®s->msg.rx_sff.data[1]);
0739 printk(" SFFRX_DATA[2]: 0x%lx\n\r",(unsigned int)®s->msg.rx_sff.data[2]);
0740 printk(" SFFRX_DATA[3]: 0x%lx\n\r",(unsigned int)®s->msg.rx_sff.data[3]);
0741 printk(" SFFRX_DATA[4]: 0x%lx\n\r",(unsigned int)®s->msg.rx_sff.data[4]);
0742 printk(" SFFRX_DATA[5]: 0x%lx\n\r",(unsigned int)®s->msg.rx_sff.data[5]);
0743 printk(" SFFRX_DATA[6]: 0x%lx\n\r",(unsigned int)®s->msg.rx_sff.data[6]);
0744 printk(" SFFRX_DATA[7]: 0x%lx\n\r",(unsigned int)®s->msg.rx_sff.data[7]);
0745
0746
0747 printk(" SFFTX_ID[0]: 0x%lx\n\r",(unsigned int)®s->msg.tx_sff.id[0]);
0748 printk(" SFFTX_ID[1]: 0x%lx\n\r",(unsigned int)®s->msg.tx_sff.id[1]);
0749
0750 printk(" SFFTX_DATA[0]: 0x%lx\n\r",(unsigned int)®s->msg.tx_sff.data[0]);
0751 printk(" SFFTX_DATA[1]: 0x%lx\n\r",(unsigned int)®s->msg.tx_sff.data[1]);
0752 printk(" SFFTX_DATA[2]: 0x%lx\n\r",(unsigned int)®s->msg.tx_sff.data[2]);
0753 printk(" SFFTX_DATA[3]: 0x%lx\n\r",(unsigned int)®s->msg.tx_sff.data[3]);
0754 printk(" SFFTX_DATA[4]: 0x%lx\n\r",(unsigned int)®s->msg.tx_sff.data[4]);
0755 printk(" SFFTX_DATA[5]: 0x%lx\n\r",(unsigned int)®s->msg.tx_sff.data[5]);
0756 printk(" SFFTX_DATA[6]: 0x%lx\n\r",(unsigned int)®s->msg.tx_sff.data[6]);
0757 printk(" SFFTX_DATA[7]: 0x%lx\n\r",(unsigned int)®s->msg.tx_sff.data[7]);
0758
0759 printk(" RX_MSG_CNT: 0x%lx\n\r",(unsigned int)®s->rx_msg_cnt);
0760 printk(" CLKDIV: 0x%lx\n\r",(unsigned int)®s->clkdiv);
0761 printk("-------------------\n\r");
0762 }
0763 #endif
0764
0765 #ifdef DEBUG
0766 static void occan_stat_print(occan_stats *stats){
0767 printk("----Stats----\n\r");
0768 printk("rx_msgs: %d\n\r",stats->rx_msgs);
0769 printk("tx_msgs: %d\n\r",stats->tx_msgs);
0770 printk("err_warn: %d\n\r",stats->err_warn);
0771 printk("err_dovr: %d\n\r",stats->err_dovr);
0772 printk("err_errp: %d\n\r",stats->err_errp);
0773 printk("err_arb: %d\n\r",stats->err_arb);
0774 printk("err_bus: %d\n\r",stats->err_bus);
0775 printk("Int cnt: %d\n\r",stats->ints);
0776 printk("tx_buf_err: %d\n\r",stats->tx_buf_error);
0777 printk("-------------\n\r");
0778 }
0779 #endif
0780
0781 static void pelican_init(occan_priv *priv){
0782
0783 WRITE_REG(priv, &priv->regs->mode, PELICAN_MOD_RESET);
0784
0785
0786
0787 }
0788
0789 static void pelican_open(occan_priv *priv){
0790 int ret;
0791 struct grlib_canbtrs_timing timing;
0792
0793
0794 priv->speed = OCCAN_SPEED_250K;
0795
0796
0797 priv->acode[0] = 0;
0798 priv->acode[1] = 0;
0799 priv->acode[2] = 0;
0800 priv->acode[3] = 0;
0801 priv->amask[0] = 0xff;
0802 priv->amask[1] = 0xff;
0803 priv->amask[2] = 0xff;
0804 priv->amask[3] = 0xff;
0805
0806
0807
0808 WRITE_REG(priv, &priv->regs->clkdiv, (1<<PELICAN_CDR_MODE_BITS) | (DEFAULT_CLKDIV & PELICAN_CDR_DIV));
0809
0810 ret = grlib_canbtrs_calc_timing(
0811 priv->speed, priv->sys_freq_hz,
0812 OCCAN_SAMPLING_POINT, &occan_btrs_ranges,
0813 (struct grlib_canbtrs_timing *)&timing);
0814 if ( ret ) {
0815
0816 priv->speed = OCCAN_SPEED_50K;
0817 grlib_canbtrs_calc_timing(
0818 priv->speed, priv->sys_freq_hz,
0819 OCCAN_SAMPLING_POINT, &occan_btrs_ranges,
0820 (struct grlib_canbtrs_timing *)&timing);
0821 }
0822 convert_timing_to_btrs(&timing, &priv->timing);
0823
0824
0825 WRITE_REG(priv, &priv->regs->inten, 0);
0826
0827
0828 READ_REG(priv, &priv->regs->intflags);
0829 }
0830
0831 static int pelican_start(occan_priv *priv){
0832
0833
0834 if ( !priv->rxfifo || !priv->txfifo )
0835 return -1;
0836
0837
0838
0839
0840
0841 occan_fifo_clr(priv->txfifo);
0842
0843
0844 priv->status = 0;
0845 priv->sending = 0;
0846
0847
0848 READ_REG(priv, &priv->regs->intflags);
0849
0850
0851 WRITE_REG(priv, &priv->regs->rx_err_cnt, 0);
0852 WRITE_REG(priv, &priv->regs->tx_err_cnt, 0);
0853
0854 #ifdef REDUNDANT_CHANNELS
0855 if ( (priv->channel == 0) || (priv->channel >= REDUNDANT_CHANNELS) ){
0856
0857 OCCAN_SET_CHANNEL(priv,0);
0858 }else{
0859
0860 OCCAN_SET_CHANNEL(priv,priv->channel);
0861 }
0862 #endif
0863
0864 occan_set_speedregs(priv,&priv->timing);
0865
0866 DBG("OCCAN: start: set timing regs btr0: 0x%x, btr1: 0x%x\n\r",
0867 READ_REG(priv, &priv->regs->bustim0),
0868 READ_REG(priv, &priv->regs->bustim1));
0869
0870
0871 pelican_set_accept(priv,priv->acode,priv->amask);
0872
0873
0874
0875 priv->started = 1;
0876
0877
0878 WRITE_REG(priv, &priv->regs->inten,
0879 PELICAN_IE_RX | PELICAN_IE_TX | PELICAN_IE_ERRW |
0880 PELICAN_IE_ERRP | PELICAN_IE_BUS);
0881 #ifdef DEBUG
0882
0883 pelican_regs_print(priv->regs);
0884 occan_stat_print(&priv->stats);
0885 #endif
0886
0887
0888
0889
0890
0891 WRITE_REG(priv, &priv->regs->mode, (priv->single_mode << 3));
0892
0893
0894 drvmgr_interrupt_register(priv->dev, 0, "occan", occan_interrupt, priv);
0895
0896 return 0;
0897 }
0898
0899 static void pelican_stop(occan_priv *priv)
0900 {
0901
0902
0903 drvmgr_interrupt_unregister(priv->dev, 0, occan_interrupt, priv);
0904
0905 #ifdef DEBUG
0906
0907 pelican_regs_print(priv->regs);
0908 occan_stat_print(&priv->stats);
0909 #endif
0910
0911
0912 WRITE_REG(priv, &priv->regs->mode, PELICAN_MOD_RESET);
0913
0914
0915 WRITE_REG(priv, &priv->regs->inten, 0);
0916
0917 priv->status |= OCCAN_STATUS_RESET;
0918 }
0919
0920 static inline int pelican_tx_ready(occan_priv *can)
0921 {
0922 unsigned char status;
0923 pelican_regs *regs = can->regs;
0924
0925
0926 status = READ_REG(can, ®s->status);
0927 if ( !(status & PELICAN_STAT_TXBUF) ) {
0928
0929 return 0;
0930 }
0931
0932 return 1;
0933 }
0934
0935
0936
0937
0938
0939
0940
0941 static int pelican_send(occan_priv *can, CANMsg *msg){
0942 unsigned char tmp;
0943 pelican_regs *regs = can->regs;
0944
0945
0946 if ( !pelican_tx_ready(can) ) {
0947
0948 return -1;
0949 }
0950
0951 tmp = msg->len & 0xf;
0952 if ( msg->rtr )
0953 tmp |= 0x40;
0954
0955 if ( msg->extended ){
0956
0957 WRITE_REG(can, ®s->rx_fi_xff, 0x80 | tmp);
0958 WRITE_REG(can, ®s->msg.tx_eff.id[0],(msg->id >> (5+8+8)) & 0xff);
0959 WRITE_REG(can, ®s->msg.tx_eff.id[1],(msg->id >> (5+8)) & 0xff);
0960 WRITE_REG(can, ®s->msg.tx_eff.id[2],(msg->id >> (5)) & 0xff);
0961 WRITE_REG(can, ®s->msg.tx_eff.id[3],(msg->id << 3) & 0xf8);
0962 tmp = msg->len;
0963 while(tmp--){
0964 WRITE_REG(can, ®s->msg.tx_eff.data[tmp], msg->data[tmp]);
0965 }
0966 }else{
0967
0968 WRITE_REG(can, ®s->rx_fi_xff, tmp);
0969 WRITE_REG(can, ®s->msg.tx_sff.id[0],(msg->id >> 3) & 0xff);
0970 WRITE_REG(can, ®s->msg.tx_sff.id[1],(msg->id << 5) & 0xe0);
0971 tmp = msg->len;
0972 while(tmp--){
0973 WRITE_REG(can, ®s->msg.tx_sff.data[tmp],msg->data[tmp]);
0974 }
0975 }
0976
0977
0978 if ( msg->sshot ){
0979 WRITE_REG(can, ®s->cmd, PELICAN_CMD_TXREQ | PELICAN_CMD_ABORT);
0980 }else{
0981
0982 WRITE_REG(can, ®s->cmd, PELICAN_CMD_TXREQ);
0983 }
0984
0985 return 0;
0986 }
0987
0988
0989 static void pelican_set_accept(occan_priv *priv, unsigned char *acode, unsigned char *amask)
0990 {
0991 unsigned char *acode0, *acode1, *acode2, *acode3;
0992 unsigned char *amask0, *amask1, *amask2, *amask3;
0993
0994 acode0 = &priv->regs->rx_fi_xff;
0995 acode1 = (unsigned char *)&priv->regs->msg.rst_accept.code[0];
0996 acode2 = (unsigned char *)&priv->regs->msg.rst_accept.code[1];
0997 acode3 = (unsigned char *)&priv->regs->msg.rst_accept.code[2];
0998
0999 amask0 = (unsigned char *)&priv->regs->msg.rst_accept.mask[0];
1000 amask1 = (unsigned char *)&priv->regs->msg.rst_accept.mask[1];
1001 amask2 = (unsigned char *)&priv->regs->msg.rst_accept.mask[2];
1002 amask3 = (unsigned char *)&priv->regs->msg.rst_accept.mask[3];
1003
1004
1005 WRITE_REG(priv, acode0, acode[0]);
1006 WRITE_REG(priv, acode1, acode[1]);
1007 WRITE_REG(priv, acode2, acode[2]);
1008 WRITE_REG(priv, acode3, acode[3]);
1009
1010 WRITE_REG(priv, amask0, amask[0]);
1011 WRITE_REG(priv, amask1, amask[1]);
1012 WRITE_REG(priv, amask2, amask[2]);
1013 WRITE_REG(priv, amask3, amask[3]);
1014 }
1015
1016 static void convert_timing_to_btrs(
1017 struct grlib_canbtrs_timing *t,
1018 occan_speed_regs *btrs)
1019 {
1020 btrs->btr0 = (t->rsj << OCCAN_BUSTIM_SJW_BIT) |
1021 (t->scaler & OCCAN_BUSTIM_BRP);
1022 btrs->btr1 = (0<<7) | (t->ps2 << OCCAN_BUSTIM_TSEG2_BIT) | t->ps1;
1023 }
1024
1025 static int occan_set_speedregs(occan_priv *priv, occan_speed_regs *timing)
1026 {
1027 if ( !timing || !priv || !priv->regs)
1028 return -1;
1029
1030 WRITE_REG(priv, &priv->regs->bustim0, timing->btr0);
1031 WRITE_REG(priv, &priv->regs->bustim1, timing->btr1);
1032
1033 return 0;
1034 }
1035
1036 static rtems_device_driver occan_initialize(rtems_device_major_number major, rtems_device_minor_number unused, void *arg)
1037 {
1038 return RTEMS_SUCCESSFUL;
1039 }
1040
1041 static rtems_device_driver occan_open(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
1042 {
1043 occan_priv *can;
1044 struct drvmgr_dev *dev;
1045
1046 DBG("OCCAN: Opening %d\n\r",minor);
1047
1048
1049 if ( drvmgr_get_dev(&occan_drv_info.general, minor, &dev) ) {
1050 DBG("Wrong minor %d\n", minor);
1051 return RTEMS_UNSATISFIED;
1052 }
1053 can = (occan_priv *)dev->priv;
1054
1055
1056 rtems_semaphore_obtain(can->devsem, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
1057 if ( can->open ){
1058 rtems_semaphore_release(can->devsem);
1059 return RTEMS_RESOURCE_IN_USE;
1060 }
1061 can->open = 1;
1062 rtems_semaphore_release(can->devsem);
1063
1064 SPIN_INIT(&can->devlock, can->devName);
1065
1066
1067 can->rxfifo = occan_fifo_create(DEFAULT_RX_FIFO_LEN);
1068 if ( !can->rxfifo ){
1069 can->open = 0;
1070 return RTEMS_NO_MEMORY;
1071 }
1072
1073 can->txfifo = occan_fifo_create(DEFAULT_TX_FIFO_LEN);
1074 if ( !can->txfifo ){
1075 occan_fifo_free(can->rxfifo);
1076 can->rxfifo= NULL;
1077 can->open = 0;
1078 return RTEMS_NO_MEMORY;
1079 }
1080
1081 DBG("OCCAN: Opening %d success\n\r",minor);
1082
1083 can->started = 0;
1084 can->channel = 0;
1085 can->txblk = 1;
1086 can->rxblk = 1;
1087 can->single_mode = 1;
1088
1089
1090 memset(&can->stats,0,sizeof(occan_stats));
1091
1092
1093
1094
1095
1096 pelican_open(can);
1097
1098 return RTEMS_SUCCESSFUL;
1099 }
1100
1101 static rtems_device_driver occan_close(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
1102 {
1103 occan_priv *can;
1104 struct drvmgr_dev *dev;
1105
1106 DBG("OCCAN: Closing %d\n\r",minor);
1107
1108 if ( drvmgr_get_dev(&occan_drv_info.general, minor, &dev) ) {
1109 return RTEMS_INVALID_NAME;
1110 }
1111 can = (occan_priv *)dev->priv;
1112
1113
1114 if ( can->started )
1115 pelican_stop(can);
1116
1117
1118 WRITE_REG(can, &can->regs->mode, PELICAN_MOD_RESET);
1119
1120
1121 occan_fifo_free(can->rxfifo);
1122 occan_fifo_free(can->txfifo);
1123
1124 can->rxfifo = NULL;
1125 can->txfifo = NULL;
1126
1127 can->open = 0;
1128
1129 return RTEMS_SUCCESSFUL;
1130 }
1131
1132 static rtems_device_driver occan_read(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
1133 {
1134 occan_priv *can;
1135 struct drvmgr_dev *dev;
1136 rtems_libio_rw_args_t *rw_args=(rtems_libio_rw_args_t *) arg;
1137 CANMsg *dstmsg, *srcmsg;
1138 SPIN_IRQFLAGS(oldLevel);
1139 int left;
1140
1141 if ( drvmgr_get_dev(&occan_drv_info.general, minor, &dev) ) {
1142 return RTEMS_INVALID_NAME;
1143 }
1144 can = (occan_priv *)dev->priv;
1145
1146 if ( !can->started ){
1147 DBG("OCCAN: cannot read from minor %d when not started\n\r",minor);
1148 return RTEMS_RESOURCE_IN_USE;
1149 }
1150
1151
1152 left = rw_args->count;
1153 if ( left < sizeof(CANMsg) ){
1154 DBG("OCCAN: minor %d length of buffer must be at least %d, our is %d\n\r",minor,sizeof(CANMsg),left);
1155 return RTEMS_INVALID_NAME;
1156 }
1157
1158
1159 dstmsg = (CANMsg *)rw_args->buffer;
1160 if ( !dstmsg ){
1161 DBG("OCCAN: minor %d read: input buffer is NULL\n\r",minor);
1162 return RTEMS_INVALID_NAME;
1163 }
1164
1165 while (left >= sizeof(CANMsg) ){
1166
1167
1168 SPIN_LOCK_IRQ(&can->devlock, oldLevel);
1169
1170
1171 if ( can->status & (OCCAN_STATUS_ERR_BUSOFF|OCCAN_STATUS_RESET) ){
1172 SPIN_UNLOCK_IRQ(&can->devlock, oldLevel);
1173 DBG("OCCAN: read is cancelled due to a BUS OFF error\n\r");
1174 rw_args->bytes_moved = rw_args->count-left;
1175 return RTEMS_IO_ERROR;
1176 }
1177
1178 srcmsg = occan_fifo_claim_get(can->rxfifo);
1179 if ( !srcmsg ){
1180
1181
1182
1183
1184
1185 if ( !can->rxblk || (left != rw_args->count) ){
1186
1187 SPIN_UNLOCK_IRQ(&can->devlock, oldLevel);
1188 break;
1189 }
1190
1191
1192 SPIN_UNLOCK_IRQ(&can->devlock, oldLevel);
1193
1194 DBG("OCCAN: Waiting for RX int\n\r");
1195
1196
1197 rtems_semaphore_obtain(can->rxsem, RTEMS_WAIT,
1198 RTEMS_NO_TIMEOUT);
1199
1200
1201 if ( can->status & (OCCAN_STATUS_ERR_BUSOFF|OCCAN_STATUS_RESET) ){
1202 DBG("OCCAN: Blocking read got woken up by BUS OFF error\n\r");
1203
1204 rw_args->bytes_moved = rw_args->count-left;
1205 return RTEMS_IO_ERROR;
1206 }
1207
1208
1209 continue;
1210 }
1211
1212
1213 *dstmsg = *srcmsg;
1214
1215
1216 occan_fifo_get(can->rxfifo);
1217
1218
1219 SPIN_UNLOCK_IRQ(&can->devlock, oldLevel);
1220
1221
1222 left -= sizeof(CANMsg);
1223 dstmsg++;
1224 }
1225
1226
1227 rw_args->bytes_moved = rw_args->count-left;
1228 if ( rw_args->bytes_moved == 0 ){
1229 DBG("OCCAN: minor %d read would block, returning\n\r",minor);
1230 return RTEMS_TIMEOUT;
1231 }
1232 return RTEMS_SUCCESSFUL;
1233 }
1234
1235 static rtems_device_driver occan_write(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
1236 {
1237 occan_priv *can;
1238 struct drvmgr_dev *dev;
1239 rtems_libio_rw_args_t *rw_args=(rtems_libio_rw_args_t *) arg;
1240 CANMsg *msg,*fifo_msg;
1241 SPIN_IRQFLAGS(oldLevel);
1242 int left;
1243
1244 DBG("OCCAN: Writing %d bytes from 0x%lx (%d)\n\r",rw_args->count,rw_args->buffer,sizeof(CANMsg));
1245
1246 if ( drvmgr_get_dev(&occan_drv_info.general, minor, &dev) ) {
1247 return RTEMS_INVALID_NAME;
1248 }
1249 can = (occan_priv *)dev->priv;
1250
1251 if ( !can->started )
1252 return RTEMS_RESOURCE_IN_USE;
1253
1254 left = rw_args->count;
1255 if ( (left < sizeof(CANMsg)) || (!rw_args->buffer) ){
1256 return RTEMS_INVALID_NAME;
1257 }
1258
1259 msg = (CANMsg *)rw_args->buffer;
1260
1261
1262 msg->len = (msg->len > 8) ? 8 : msg->len;
1263
1264 #ifdef DEBUG_VERBOSE
1265 pelican_regs_print(can->regs);
1266 occan_stat_print(&can->stats);
1267 #endif
1268
1269
1270 SPIN_LOCK_IRQ(&can->devlock, oldLevel);
1271
1272
1273 if ( can->status & (OCCAN_STATUS_ERR_BUSOFF|OCCAN_STATUS_RESET) ){
1274 SPIN_UNLOCK_IRQ(&can->devlock, oldLevel);
1275 rw_args->bytes_moved = 0;
1276 return RTEMS_IO_ERROR;
1277 }
1278
1279
1280
1281
1282
1283 if ( occan_fifo_empty(can->txfifo) ){
1284
1285 if ( !pelican_send(can,msg) ) {
1286
1287
1288
1289 left -= sizeof(CANMsg);
1290 msg++;
1291
1292 #ifdef OCCAN_TX_IRQ_FLAG_FIXUP
1293
1294 can->sending = 1;
1295 #endif
1296
1297
1298 can->stats.tx_msgs++;
1299
1300 DBG("OCCAN: Sending direct via HW\n\r");
1301 }
1302 }
1303
1304
1305 while ( left >= sizeof(CANMsg) ){
1306
1307
1308 msg->len = (msg->len > 8) ? 8 : msg->len;
1309
1310 fifo_msg = occan_fifo_put_claim(can->txfifo,0);
1311 if ( !fifo_msg ){
1312
1313 DBG("OCCAN: FIFO is full\n\r");
1314
1315
1316
1317 if ( !can->txblk || (left != rw_args->count) )
1318 break;
1319
1320
1321
1322
1323
1324
1325
1326 SPIN_UNLOCK_IRQ(&can->devlock, oldLevel);
1327
1328 DBG("OCCAN: Waiting for tx int\n\r");
1329
1330 rtems_semaphore_obtain(can->txsem, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
1331
1332
1333 if ( can->status & (OCCAN_STATUS_ERR_BUSOFF|OCCAN_STATUS_RESET) ){
1334 DBG("OCCAN: Blocking write got woken up by BUS OFF error or RESET event\n\r");
1335
1336 rw_args->bytes_moved = rw_args->count-left;
1337 return RTEMS_IO_ERROR;
1338 }
1339
1340 SPIN_LOCK_IRQ(&can->devlock, oldLevel);
1341
1342 if ( occan_fifo_empty(can->txfifo) ){
1343 if ( !pelican_send(can,msg) ) {
1344
1345
1346
1347 left -= sizeof(CANMsg);
1348 msg++;
1349
1350 #ifdef OCCAN_TX_IRQ_FLAG_FIXUP
1351
1352 can->sending = 1;
1353 #endif
1354
1355
1356 can->stats.tx_msgs++;
1357
1358 DBG("OCCAN: Sending direct2 via HW\n\r");
1359 }
1360 }
1361 continue;
1362 }
1363
1364
1365 *fifo_msg = *msg;
1366
1367
1368 occan_fifo_put(can->txfifo);
1369
1370 DBG("OCCAN: Put info fifo SW\n\r");
1371
1372
1373 msg++;
1374 left-=sizeof(CANMsg);
1375 }
1376
1377 SPIN_UNLOCK_IRQ(&can->devlock, oldLevel);
1378
1379 rw_args->bytes_moved = rw_args->count-left;
1380 DBG("OCCAN: Sent %d\n\r",rw_args->bytes_moved);
1381
1382 if ( left == rw_args->count )
1383 return RTEMS_TIMEOUT;
1384 return RTEMS_SUCCESSFUL;
1385 }
1386
1387 static rtems_device_driver occan_ioctl(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
1388 {
1389 int ret;
1390 struct grlib_canbtrs_timing timing;
1391 occan_priv *can;
1392 struct drvmgr_dev *dev;
1393 unsigned int speed;
1394 rtems_libio_ioctl_args_t *ioarg = (rtems_libio_ioctl_args_t *) arg;
1395 struct occan_afilter *afilter;
1396 occan_stats *dststats;
1397 unsigned int rxcnt,txcnt;
1398
1399 DBG("OCCAN: IOCTL %d\n\r",ioarg->command);
1400
1401 if ( drvmgr_get_dev(&occan_drv_info.general, minor, &dev) ) {
1402 return RTEMS_INVALID_NAME;
1403 }
1404 can = (occan_priv *)dev->priv;
1405
1406 ioarg->ioctl_return = 0;
1407 switch(ioarg->command){
1408 case OCCAN_IOC_SET_SPEED:
1409
1410
1411 if ( can->started )
1412 return RTEMS_RESOURCE_IN_USE;
1413
1414
1415 speed = (unsigned int)ioarg->buffer;
1416
1417 ret = grlib_canbtrs_calc_timing(
1418 speed, can->sys_freq_hz,
1419 OCCAN_SAMPLING_POINT, &occan_btrs_ranges,
1420 (struct grlib_canbtrs_timing *)&timing);
1421 if ( ret )
1422 return RTEMS_INVALID_NAME;
1423
1424
1425
1426
1427
1428 can->speed = speed;
1429 convert_timing_to_btrs(&timing, &can->timing);
1430 break;
1431
1432 case OCCAN_IOC_SET_BTRS:
1433
1434
1435
1436 if ( can->started )
1437 return RTEMS_RESOURCE_IN_USE;
1438
1439 can->speed = 0;
1440 can->timing.btr1 = (unsigned int)ioarg->buffer & 0xff;
1441 can->timing.btr0 = ((unsigned int)ioarg->buffer>>8) & 0xff;
1442
1443
1444
1445
1446
1447
1448
1449 break;
1450
1451 case OCCAN_IOC_SPEED_AUTO:
1452 return RTEMS_NOT_IMPLEMENTED;
1453
1454 case OCCAN_IOC_SET_BUFLEN:
1455
1456 if ( can->started )
1457 return RTEMS_RESOURCE_IN_USE;
1458
1459 rxcnt = (unsigned int)ioarg->buffer & 0x0000ffff;
1460 txcnt = (unsigned int)ioarg->buffer >> 16;
1461
1462 occan_fifo_free(can->rxfifo);
1463 occan_fifo_free(can->txfifo);
1464
1465
1466 can->rxfifo = occan_fifo_create(rxcnt);
1467 can->txfifo = occan_fifo_create(txcnt);
1468
1469 if ( !can->rxfifo || !can->txfifo )
1470 return RTEMS_NO_MEMORY;
1471 break;
1472
1473 case OCCAN_IOC_GET_CONF:
1474 return RTEMS_NOT_IMPLEMENTED;
1475 break;
1476
1477 case OCCAN_IOC_GET_STATS:
1478 dststats = (occan_stats *)ioarg->buffer;
1479 if ( !dststats )
1480 return RTEMS_INVALID_NAME;
1481
1482
1483 if ( can->rxfifo )
1484 can->stats.rx_sw_dovr = can->rxfifo->ovcnt;
1485 *dststats = can->stats;
1486 break;
1487
1488 case OCCAN_IOC_GET_STATUS:
1489
1490 if ( !ioarg->buffer )
1491 return RTEMS_INVALID_NAME;
1492
1493 *(unsigned int *)ioarg->buffer = can->status;
1494 break;
1495
1496
1497 case OCCAN_IOC_SET_LINK:
1498 #ifdef REDUNDANT_CHANNELS
1499 if ( can->started )
1500 return RTEMS_RESOURCE_IN_USE;
1501
1502
1503 can->channel = (unsigned int)ioargs->buffer;
1504 #else
1505 return RTEMS_NOT_IMPLEMENTED;
1506 #endif
1507 break;
1508
1509 case OCCAN_IOC_SET_FILTER:
1510 if ( can->started )
1511 return RTEMS_RESOURCE_IN_USE;
1512
1513 afilter = (struct occan_afilter *)ioarg->buffer;
1514
1515 if ( !afilter )
1516 return RTEMS_INVALID_NAME;
1517
1518
1519 can->acode[0] = afilter->code[0];
1520 can->acode[1] = afilter->code[1];
1521 can->acode[2] = afilter->code[2];
1522 can->acode[3] = afilter->code[3];
1523
1524 can->amask[0] = afilter->mask[0];
1525 can->amask[1] = afilter->mask[1];
1526 can->amask[2] = afilter->mask[2];
1527 can->amask[3] = afilter->mask[3];
1528
1529 can->single_mode = ( afilter->single_mode ) ? 1 : 0;
1530
1531
1532
1533
1534
1535 break;
1536
1537 case OCCAN_IOC_SET_BLK_MODE:
1538 can->rxblk = (unsigned int)ioarg->buffer & OCCAN_BLK_MODE_RX;
1539 can->txblk = ((unsigned int)ioarg->buffer & OCCAN_BLK_MODE_TX) >> 1;
1540 break;
1541
1542 case OCCAN_IOC_START:
1543 if ( can->started )
1544 return RTEMS_RESOURCE_IN_USE;
1545 if ( pelican_start(can) )
1546 return RTEMS_NO_MEMORY;
1547
1548
1549
1550 break;
1551
1552 case OCCAN_IOC_STOP:
1553 if ( !can->started )
1554 return RTEMS_RESOURCE_IN_USE;
1555 pelican_stop(can);
1556 can->started = 0;
1557 break;
1558
1559 default:
1560 return RTEMS_NOT_DEFINED;
1561 }
1562 return RTEMS_SUCCESSFUL;
1563 }
1564
1565 void occan_interrupt(void *arg)
1566 {
1567 occan_priv *can = arg;
1568 unsigned char iflags;
1569 pelican_regs *regs = can->regs;
1570 CANMsg *msg;
1571 int signal_rx=0, signal_tx=0;
1572 unsigned char tmp, errcode, arbcode;
1573 int tx_error_cnt,rx_error_cnt;
1574 SPIN_ISR_IRQFLAGS(irqflags);
1575
1576 if ( !can->started )
1577 return;
1578
1579 SPIN_LOCK(&can->devlock, irqflags);
1580 while (1) {
1581
1582 iflags = READ_REG(can, &can->regs->intflags);
1583
1584 #ifdef OCCAN_TX_IRQ_FLAG_FIXUP
1585
1586
1587
1588
1589
1590 if ((iflags & PELICAN_IF_TX) == 0) {
1591 if (can->sending && pelican_tx_ready(can)) {
1592 can->sending = 0;
1593 iflags |= PELICAN_IF_TX;
1594 }
1595 }
1596 #endif
1597
1598 if (iflags == 0)
1599 break;
1600
1601
1602 can->stats.ints++;
1603
1604 if ( iflags & PELICAN_IF_RX ){
1605
1606
1607
1608
1609
1610 msg = occan_fifo_put_claim(can->rxfifo,1);
1611 tmp = READ_REG(can, ®s->rx_fi_xff);
1612 msg->extended = tmp >> 7;
1613 msg->rtr = (tmp >> 6) & 1;
1614 msg->len = tmp = tmp & 0x0f;
1615
1616 if ( msg->extended ){
1617
1618 msg->id = READ_REG(can, ®s->msg.rx_eff.id[0])<<(5+8+8) |
1619 READ_REG(can, ®s->msg.rx_eff.id[1])<<(5+8) |
1620 READ_REG(can, ®s->msg.rx_eff.id[2])<<5 |
1621 READ_REG(can, ®s->msg.rx_eff.id[3])>>3;
1622
1623 while(tmp--){
1624 msg->data[tmp] = READ_REG(can, ®s->msg.rx_eff.data[tmp]);
1625 }
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636 }else{
1637
1638 msg->id = READ_REG(can, ®s->msg.rx_sff.id[0])<<3 |
1639 READ_REG(can, ®s->msg.rx_sff.id[1])>>5;
1640
1641 while(tmp--){
1642 msg->data[tmp] = READ_REG(can, ®s->msg.rx_sff.data[tmp]);
1643 }
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654 }
1655
1656
1657 WRITE_REG(can, ®s->cmd, PELICAN_CMD_RELRXBUF);
1658
1659
1660 occan_fifo_put(can->rxfifo);
1661
1662
1663 can->stats.rx_msgs++;
1664
1665
1666 signal_rx = 1;
1667 }
1668
1669 if ( iflags & PELICAN_IF_TX ) {
1670
1671
1672
1673 if ( !occan_fifo_empty(can->txfifo) ){
1674
1675 msg = occan_fifo_claim_get(can->txfifo);
1676
1677 if ( pelican_send(can,msg) ){
1678
1679
1680
1681
1682
1683 if ( can->stats.tx_buf_error < 10 ){
1684 printk("OCCAN: got TX interrupt but TX fifo in not empty (%d)\n\r",can->stats.tx_buf_error);
1685 }
1686 can->status |= OCCAN_STATUS_QUEUE_ERROR;
1687 can->stats.tx_buf_error++;
1688 }
1689 #ifdef OCCAN_TX_IRQ_FLAG_FIXUP
1690 can->sending = 1;
1691 #endif
1692
1693
1694 occan_fifo_get(can->txfifo);
1695
1696
1697 can->stats.tx_msgs++;
1698
1699
1700 signal_tx = 1;
1701 }
1702 }
1703
1704 if ( iflags & PELICAN_IF_ERRW ){
1705 tx_error_cnt = READ_REG(can, ®s->tx_err_cnt);
1706 rx_error_cnt = READ_REG(can, ®s->rx_err_cnt);
1707
1708
1709 if ( (tx_error_cnt > 96) || (rx_error_cnt > 96) ){
1710
1711 can->status |= OCCAN_STATUS_WARN;
1712
1713
1714 if ( READ_REG(can, ®s->mode) & PELICAN_MOD_RESET ){
1715
1716 can->status |= OCCAN_STATUS_ERR_BUSOFF | OCCAN_STATUS_RESET;
1717
1718
1719
1720
1721
1722 WRITE_REG(can, ®s->inten,0);
1723
1724
1725
1726
1727
1728
1729
1730 can->started = 0;
1731
1732
1733
1734
1735 signal_rx = 1;
1736 signal_tx = 1;
1737
1738
1739 break;
1740 }
1741
1742 }else{
1743
1744 can->status &= ~(OCCAN_STATUS_WARN);
1745 }
1746 can->stats.err_warn++;
1747 }
1748
1749 if ( iflags & PELICAN_IF_DOVR){
1750 can->status |= OCCAN_STATUS_OVERRUN;
1751 can->stats.err_dovr++;
1752 DBG("OCCAN_INT: DOVR\n\r");
1753 }
1754
1755 if ( iflags & PELICAN_IF_ERRP){
1756
1757
1758
1759 tx_error_cnt = READ_REG(can, ®s->tx_err_cnt);
1760 rx_error_cnt = READ_REG(can, ®s->rx_err_cnt);
1761
1762 if ( (tx_error_cnt > 127) || (rx_error_cnt > 127) ){
1763 can->status |= OCCAN_STATUS_ERR_PASSIVE;
1764 }else{
1765 can->status &= ~(OCCAN_STATUS_ERR_PASSIVE);
1766 }
1767
1768
1769 can->stats.err_errp++;
1770 }
1771
1772 if ( iflags & PELICAN_IF_ARB){
1773 arbcode = READ_REG(can, ®s->arbcode);
1774 can->stats.err_arb_bitnum[arbcode & PELICAN_ARB_BITS]++;
1775 can->stats.err_arb++;
1776 DBG("OCCAN_INT: ARB (0x%x)\n\r",arbcode & PELICAN_ARB_BITS);
1777 }
1778
1779 if ( iflags & PELICAN_IF_BUS){
1780
1781
1782
1783
1784 errcode = READ_REG(can, ®s->errcode);
1785 switch( errcode & PELICAN_ECC_CODE ){
1786 case PELICAN_ECC_CODE_BIT:
1787 can->stats.err_bus_bit++;
1788 break;
1789 case PELICAN_ECC_CODE_FORM:
1790 can->stats.err_bus_form++;
1791 break;
1792 case PELICAN_ECC_CODE_STUFF:
1793 can->stats.err_bus_stuff++;
1794 break;
1795 case PELICAN_ECC_CODE_OTHER:
1796 can->stats.err_bus_other++;
1797 break;
1798 }
1799
1800
1801 if ( errcode & PELICAN_ECC_DIR ){
1802 can->stats.err_bus_rx++;
1803 }else{
1804 can->stats.err_bus_tx++;
1805 }
1806
1807
1808 can->stats.err_bus_segs[errcode & PELICAN_ECC_SEG]++;
1809
1810
1811 can->stats.err_bus++;
1812 }
1813 }
1814 SPIN_UNLOCK(&can->devlock, irqflags);
1815
1816
1817 if ( signal_rx ){
1818 rtems_semaphore_release(can->rxsem);
1819 }
1820
1821 if ( signal_tx ){
1822 rtems_semaphore_release(can->txsem);
1823 }
1824 }
1825
1826
1827
1828
1829
1830 static occan_fifo *occan_fifo_create(int cnt)
1831 {
1832 occan_fifo *fifo;
1833 fifo = grlib_calloc(1, sizeof(*fifo)+cnt*sizeof(CANMsg));
1834 if ( fifo ){
1835 fifo->cnt = cnt;
1836 fifo->base = &fifo->fifoarea[0];
1837 fifo->tail = fifo->head = fifo->base;
1838 }
1839 return fifo;
1840 }
1841
1842 static void occan_fifo_free(occan_fifo *fifo)
1843 {
1844 if ( fifo )
1845 free(fifo);
1846 }
1847
1848 static int occan_fifo_full(occan_fifo *fifo)
1849 {
1850 return fifo->full;
1851 }
1852
1853 static int occan_fifo_empty(occan_fifo *fifo)
1854 {
1855 return (!fifo->full) && (fifo->head == fifo->tail);
1856 }
1857
1858
1859 static CANMsg *occan_fifo_put_claim(occan_fifo *fifo, int force)
1860 {
1861 if ( !fifo )
1862 return NULL;
1863
1864 if ( occan_fifo_full(fifo) ){
1865
1866 if ( !force )
1867 return NULL;
1868
1869
1870 fifo->ovcnt++;
1871 occan_fifo_get(fifo);
1872 }
1873
1874 return fifo->head;
1875 }
1876
1877
1878 static void occan_fifo_put(occan_fifo *fifo)
1879 {
1880 if ( occan_fifo_full(fifo) )
1881 return;
1882
1883
1884 fifo->head = (fifo->head >= &fifo->base[fifo->cnt-1])? fifo->base : fifo->head+1;
1885
1886 if ( fifo->head == fifo->tail )
1887 fifo->full = 1;
1888 }
1889
1890 static CANMsg *occan_fifo_claim_get(occan_fifo *fifo)
1891 {
1892 if ( occan_fifo_empty(fifo) )
1893 return NULL;
1894
1895
1896 return fifo->tail;
1897 }
1898
1899
1900 static void occan_fifo_get(occan_fifo *fifo)
1901 {
1902 if ( !fifo )
1903 return;
1904
1905 if ( occan_fifo_empty(fifo) )
1906 return;
1907
1908
1909 fifo->tail = (fifo->tail >= &fifo->base[fifo->cnt-1]) ?
1910 fifo->base : fifo->tail+1;
1911 fifo->full = 0;
1912 }
1913
1914 static void occan_fifo_clr(occan_fifo *fifo)
1915 {
1916 fifo->full = 0;
1917 fifo->ovcnt = 0;
1918 fifo->head = fifo->tail = fifo->base;
1919 }
1920
1921