source: rtems/bsps/shared/grlib/can/occan.c @ 7eb606d3

Last change on this file since 7eb606d3 was 7eb606d3, checked in by Sebastian Huber <sebastian.huber@…>, on Dec 22, 2018 at 5:31:04 PM

grlib: Move source files

Update #3678.

  • Property mode set to 100644
File size: 54.4 KB
Line 
1/*  OC_CAN driver
2 *
3 *  COPYRIGHT (c) 2007.
4 *  Cobham Gaisler AB.
5 *
6 *  The license and distribution terms for this file may be
7 *  found in the file LICENSE in this distribution or at
8 *  http://www.rtems.org/license/LICENSE.
9 */
10
11#include <rtems.h>
12#include <rtems/libio.h>
13#include <stdlib.h>
14#include <stdio.h>
15#include <string.h>
16#include <bsp.h>
17#include <rtems/bspIo.h> /* printk */
18
19#include <drvmgr/drvmgr.h>
20#include <grlib/ambapp_bus.h>
21#include <grlib/occan.h>
22
23#include <grlib/grlib_impl.h>
24
25/* RTEMS -> ERRNO decoding table
26
27rtems_assoc_t errno_assoc[] = {
28    { "OK",                 RTEMS_SUCCESSFUL,                0 },
29    { "BUSY",               RTEMS_RESOURCE_IN_USE,           EBUSY },
30    { "INVALID NAME",       RTEMS_INVALID_NAME,              EINVAL },
31    { "NOT IMPLEMENTED",    RTEMS_NOT_IMPLEMENTED,           ENOSYS },
32    { "TIMEOUT",            RTEMS_TIMEOUT,                   ETIMEDOUT },
33    { "NO MEMORY",          RTEMS_NO_MEMORY,                 ENOMEM },
34    { "NO DEVICE",          RTEMS_UNSATISFIED,               ENODEV },
35    { "INVALID NUMBER",     RTEMS_INVALID_NUMBER,            EBADF},
36    { "NOT RESOURCE OWNER", RTEMS_NOT_OWNER_OF_RESOURCE,     EPERM},
37    { "IO ERROR",           RTEMS_IO_ERROR,                  EIO},
38    { 0, 0, 0 },
39};
40
41*/
42
43/*
44#undef DEBUG
45#undef DEBUG_EXTRA
46#undef DEBUG_PRINT_REGMAP
47*/
48
49/* default to byte regs */
50#ifndef OCCAN_WORD_REGS
51 #define OCCAN_BYTE_REGS
52#else
53 #undef OCCAN_BYTE_REGS
54#endif
55
56/* Enable Fixup code older OCCAN with a TX IRQ-FLAG bug */
57#define OCCAN_TX_IRQ_FLAG_FIXUP 1
58
59#define OCCAN_WORD_REG_OFS 0x80
60#define OCCAN_NCORE_OFS 0x100
61#define DEFAULT_CLKDIV 0x7
62#define DEFAULT_EXTENDED_MODE 1
63#define DEFAULT_RX_FIFO_LEN 64
64#define DEFAULT_TX_FIFO_LEN 64
65
66/* not implemented yet */
67#undef REDUNDANT_CHANNELS
68
69/* Define common debug macros */
70#ifdef DEBUG
71        #define DBG(fmt, vargs...) printk(fmt, ## vargs )
72#else
73        #define DBG(fmt, vargs...)
74#endif
75
76/* fifo interface */
77typedef struct {
78        int cnt;
79        int ovcnt; /* overwrite count */
80        int full; /* 1 = base contain cnt CANMsgs, tail==head */
81        CANMsg *tail, *head;
82        CANMsg *base;
83        CANMsg fifoarea[0];
84} occan_fifo;
85
86/* PELICAN */
87
88typedef struct {
89        unsigned char
90                mode,
91                cmd,
92                status,
93                intflags,
94                inten,
95                resv0,
96                bustim0,
97                bustim1,
98                unused0[2],
99                resv1,
100                arbcode,
101                errcode,
102                errwarn,
103                rx_err_cnt,
104                tx_err_cnt,
105                rx_fi_xff; /* this is also acceptance code 0 in reset mode */
106                union{
107                        struct {
108                                unsigned char id[2];
109                                unsigned char data[8];
110                                unsigned char next_in_fifo[2];
111                        } rx_sff;
112                        struct {
113                                unsigned char id[4];
114                                unsigned char data[8];
115                        } rx_eff;
116                        struct {
117                                unsigned char id[2];
118                                unsigned char data[8];
119                                unsigned char unused[2];
120                        } tx_sff;
121                        struct {
122                                unsigned char id[4];
123                                unsigned char data[8];
124                        } tx_eff;
125                        struct {
126                                unsigned char code[3];
127                                unsigned char mask[4];
128                        } rst_accept;
129                } msg;
130                unsigned char rx_msg_cnt;
131                unsigned char unused1;
132                unsigned char clkdiv;
133} pelican8_regs;
134
135typedef struct {
136        unsigned char
137                mode, unused0[3],
138                cmd, unused1[3],
139                status, unused2[3],
140                intflags, unused3[3],
141                inten, unused4[3],
142                resv0, unused5[3],
143                bustim0, unused6[3],
144                bustim1, unused7[3],
145                unused8[8],
146                resv1,unused9[3],
147                arbcode,unused10[3],
148                errcode,unused11[3],
149                errwarn,unused12[3],
150                rx_err_cnt,unused13[3],
151                tx_err_cnt,unused14[3],
152                rx_fi_xff, unused15[3]; /* this is also acceptance code 0 in reset mode */
153                /* make sure to use pointers when writing (byte access) to these registers */
154                union{
155                        struct {
156                                unsigned int id[2];
157                                unsigned int data[8];
158                                unsigned int next_in_fifo[2];
159                        } rx_sff;
160                        struct {
161                                unsigned int id[4];
162                                unsigned int data[8];
163                        } rx_eff;
164                        struct {
165                                unsigned int id[2];
166                                unsigned int data[8];
167                        } tx_sff;
168                        struct {
169                                unsigned int id[4];
170                                unsigned int data[8];
171                        } tx_eff;
172                        struct {
173                                unsigned int code[3];
174                                unsigned int mask[4];
175                        } rst_accept;
176                } msg;
177                unsigned char rx_msg_cnt,unused16[3];
178                unsigned char unused17[4];
179                unsigned char clkdiv,unused18[3];
180} pelican32_regs;
181
182#ifdef OCCAN_BYTE_REGS
183#define pelican_regs pelican8_regs
184#else
185#define pelican_regs pelican32_regs
186#endif
187
188
189#define MAX_TSEG2 7
190#define MAX_TSEG1 15
191
192#if 0
193typedef struct {
194        unsigned char brp;
195        unsigned char sjw;
196        unsigned char tseg1;
197        unsigned char tseg2;
198        unsigned char sam;
199} occan_speed_regs;
200#endif
201typedef struct {
202        unsigned char btr0;
203        unsigned char btr1;
204} occan_speed_regs;
205
206typedef struct {
207        struct drvmgr_dev *dev;
208        char devName[32];
209        SPIN_DECLARE(devlock);
210
211        /* hardware shortcuts */
212        pelican_regs *regs;
213        int byte_regs;
214        int irq;
215        occan_speed_regs timing;
216        int channel; /* 0=default, 1=second bus */
217        int single_mode;
218        unsigned int sys_freq_hz;
219
220        /* driver state */
221        rtems_id devsem;
222        rtems_id txsem;
223        rtems_id rxsem;
224        int open;
225        int started;
226        int rxblk;
227        int txblk;
228        int sending;
229        unsigned int status;
230        occan_stats stats;
231
232        /* rx&tx fifos */
233        occan_fifo *rxfifo;
234        occan_fifo *txfifo;
235
236        /* Config */
237        unsigned int speed; /* speed in HZ */
238        unsigned char acode[4];
239        unsigned char amask[4];
240} occan_priv;
241
242/********** FIFO INTERFACE **********/
243static void occan_fifo_put(occan_fifo *fifo);
244static CANMsg *occan_fifo_put_claim(occan_fifo *fifo, int force);
245static occan_fifo *occan_fifo_create(int cnt);
246static void occan_fifo_free(occan_fifo *fifo);
247static int occan_fifo_full(occan_fifo *fifo);
248static int occan_fifo_empty(occan_fifo *fifo);
249static void occan_fifo_get(occan_fifo *fifo);
250static CANMsg *occan_fifo_claim_get(occan_fifo *fifo);
251static void occan_fifo_clr(occan_fifo *fifo);
252
253/**** Hardware related Interface ****/
254static int occan_calc_speedregs(unsigned int clock_hz, unsigned int rate, occan_speed_regs *result);
255static int occan_set_speedregs(occan_priv *priv, occan_speed_regs *timing);
256static void pelican_init(occan_priv *priv);
257static void pelican_open(occan_priv *priv);
258static int pelican_start(occan_priv *priv);
259static void pelican_stop(occan_priv *priv);
260static int pelican_send(occan_priv *can, CANMsg *msg);
261static void pelican_set_accept(occan_priv *priv, unsigned char *acode, unsigned char *amask);
262void occan_interrupt(void *arg);
263#ifdef DEBUG_PRINT_REGMAP
264static void pelican_regadr_print(pelican_regs *regs);
265#endif
266
267/***** Driver related interface *****/
268static rtems_device_driver occan_ioctl(rtems_device_major_number major, rtems_device_minor_number minor, void *arg);
269static rtems_device_driver occan_write(rtems_device_major_number major, rtems_device_minor_number minor, void *arg);
270static rtems_device_driver occan_read(rtems_device_major_number major, rtems_device_minor_number minor, void *arg);
271static rtems_device_driver occan_close(rtems_device_major_number major, rtems_device_minor_number minor, void *arg);
272static rtems_device_driver occan_open(rtems_device_major_number major, rtems_device_minor_number minor, void *arg);
273static rtems_device_driver occan_initialize(rtems_device_major_number major, rtems_device_minor_number unused, void *arg);
274
275#define OCCAN_DRIVER_TABLE_ENTRY { occan_initialize, occan_open, occan_close, occan_read, occan_write, occan_ioctl }
276static rtems_driver_address_table occan_driver = OCCAN_DRIVER_TABLE_ENTRY;
277
278
279/* Read byte bypassing */
280
281
282/* Bypass cache */
283#define READ_REG(priv, address) occan_reg_read(priv, (unsigned int)address)
284#define WRITE_REG(priv, address, data) occan_reg_write(priv, (unsigned int)address, data)
285
286static unsigned int occan_reg_read(occan_priv *priv, unsigned int address)
287{
288        unsigned int adr;
289        if ( priv->byte_regs ) {
290                adr = address;
291        } else {
292                /* Word accessed registers */
293                adr = (address & (~0x7f)) | ((address & 0x7f)<<2);
294        }
295        return *(volatile unsigned char *)adr;
296}
297
298static void occan_reg_write(
299        occan_priv *priv, 
300        unsigned int address,
301        unsigned char value)
302{
303        unsigned int adr;
304        if ( priv->byte_regs ) {
305                adr = address;
306        } else {
307                /* Word accessed registers */
308                adr = (address & (~0x7f)) | ((address & 0x7f)<<2);
309        }
310        *(volatile unsigned char *)adr = value;;
311}
312
313/* Mode register bit definitions */
314#define PELICAN_MOD_RESET          0x1
315#define PELICAN_MOD_LISTEN         0x2
316#define PELICAN_MOD_SELFTEST       0x4
317#define PELICAN_MOD_ACCEPT         0x8
318
319/* Command register bit definitions */
320#define PELICAN_CMD_TXREQ          0x1
321#define PELICAN_CMD_ABORT          0x2
322#define PELICAN_CMD_RELRXBUF       0x4
323#define PELICAN_CMD_CLRDOVR        0x8
324#define PELICAN_CMD_SELFRXRQ       0x10
325
326/* Status register bit definitions */
327#define PELICAN_STAT_RXBUF         0x1
328#define PELICAN_STAT_DOVR          0x2
329#define PELICAN_STAT_TXBUF         0x4
330#define PELICAN_STAT_TXOK          0x8
331#define PELICAN_STAT_RX            0x10
332#define PELICAN_STAT_TX            0x20
333#define PELICAN_STAT_ERR           0x40
334#define PELICAN_STAT_BUS           0x80
335
336/* Interrupt register bit definitions */
337#define PELICAN_IF_RX         0x1
338#define PELICAN_IF_TX         0x2
339#define PELICAN_IF_ERRW       0x4
340#define PELICAN_IF_DOVR       0x8
341#define PELICAN_IF_ERRP       0x20
342#define PELICAN_IF_ARB        0x40
343#define PELICAN_IF_BUS        0x80
344
345/* Interrupt Enable register bit definitions */
346#define PELICAN_IE_RX         0x1
347#define PELICAN_IE_TX         0x2
348#define PELICAN_IE_ERRW       0x4
349#define PELICAN_IE_DOVR       0x8
350#define PELICAN_IE_ERRP       0x20
351#define PELICAN_IE_ARB        0x40
352#define PELICAN_IE_BUS        0x80
353
354/* Arbitration lost capture register bit definitions */
355#define PELICAN_ARB_BITS      0x1f
356
357/*  register bit definitions */
358#define PELICAN_ECC_CODE_BIT     0x00
359#define PELICAN_ECC_CODE_FORM    0x40
360#define PELICAN_ECC_CODE_STUFF   0x80
361#define PELICAN_ECC_CODE_OTHER   0xc0
362#define PELICAN_ECC_CODE    0xc0
363
364#define PELICAN_ECC_DIR     0x20
365#define PELICAN_ECC_SEG     0x1f
366
367/* Clock divider register bit definitions */
368#define PELICAN_CDR_DIV  0x7
369#define PELICAN_CDR_OFF  0x8
370#define PELICAN_CDR_MODE 0x80
371#define PELICAN_CDR_MODE_PELICAN 0x80
372#define PELICAN_CDR_MODE_BITS 7
373#define PELICAN_CDR_MODE_BASICAN 0x00
374
375
376/*  register bit definitions */
377#define OCCAN_BUSTIM_SJW       0xc0
378#define OCCAN_BUSTIM_BRP       0x3f
379#define OCCAN_BUSTIM_SJW_BIT   6
380
381#define OCCAN_BUSTIM_SAM       0x80
382#define OCCAN_BUSTIM_TSEG2     0x70
383#define OCCAN_BUSTIM_TSEG2_BIT 4
384#define OCCAN_BUSTIM_TSEG1     0x0f
385
386/*  register bit definitions */
387/*
388#define PELICAN_S_       0x1
389#define PELICAN_S_       0x2
390#define PELICAN_S_       0x4
391#define PELICAN_S_       0x8
392#define PELICAN_S_       0x10
393#define PELICAN_S_       0x20
394#define PELICAN_S_       0x40
395#define PELICAN_S_       0x80
396*/
397
398static int occan_driver_io_registered = 0;
399static rtems_device_major_number occan_driver_io_major = 0;
400
401/******************* Driver manager interface ***********************/
402
403/* Driver prototypes */
404int occan_register_io(rtems_device_major_number *m);
405int occan_device_init(occan_priv *pDev);
406
407int occan_init2(struct drvmgr_dev *dev);
408int occan_init3(struct drvmgr_dev *dev);
409
410struct drvmgr_drv_ops occan_ops = 
411{
412        .init = {NULL, occan_init2, occan_init3, NULL},
413        .remove = NULL,
414        .info = NULL
415};
416
417struct amba_dev_id occan_ids[] = 
418{
419        {VENDOR_GAISLER, GAISLER_CANAHB},
420        {0, 0}          /* Mark end of table */
421};
422
423struct amba_drv_info occan_drv_info =
424{
425        {
426                DRVMGR_OBJ_DRV,                 /* Driver */
427                NULL,                           /* Next driver */
428                NULL,                           /* Device list */
429                DRIVER_AMBAPP_GAISLER_OCCAN_ID, /* Driver ID */
430                "OCCAN_DRV",                    /* Driver Name */
431                DRVMGR_BUS_TYPE_AMBAPP,         /* Bus Type */
432                &occan_ops,
433                NULL,                           /* Funcs */
434                0,                              /* No devices yet */
435                0,
436        },
437        &occan_ids[0]
438};
439
440void occan_register_drv (void)
441{
442        DBG("Registering OCCAN driver\n");
443        drvmgr_drv_register(&occan_drv_info.general);
444}
445
446int occan_init2(struct drvmgr_dev *dev)
447{
448        occan_priv *priv;
449
450        DBG("OCCAN[%d] on bus %s\n", dev->minor_drv, dev->parent->dev->name);
451        priv = dev->priv = grlib_calloc(1, sizeof(*priv));
452        if ( !priv )
453                return DRVMGR_NOMEM;
454        priv->dev = dev;
455
456        return DRVMGR_OK;
457}
458
459int occan_init3(struct drvmgr_dev *dev)
460{
461        occan_priv *priv;
462        char prefix[32];
463        rtems_status_code status;
464
465        priv = dev->priv;
466
467        /* Do initialization */
468
469        if ( occan_driver_io_registered == 0) {
470                /* Register the I/O driver only once for all cores */
471                if ( occan_register_io(&occan_driver_io_major) ) {
472                        /* Failed to register I/O driver */
473                        dev->priv = NULL;
474                        return DRVMGR_FAIL;
475                }
476
477                occan_driver_io_registered = 1;
478        }
479
480        /* I/O system registered and initialized
481         * Now we take care of device initialization.
482         */
483
484        if ( occan_device_init(priv) ) {
485                return DRVMGR_FAIL;
486        }
487
488        /* Get Filesystem name prefix */
489        prefix[0] = '\0';
490        if ( drvmgr_get_dev_prefix(dev, prefix) ) {
491                /* Failed to get prefix, make sure of a unique FS name
492                 * by using the driver minor.
493                 */
494                sprintf(priv->devName, "/dev/occan%d", dev->minor_drv);
495        } else {
496                /* Got special prefix, this means we have a bus prefix
497                 * And we should use our "bus minor"
498                 */
499                sprintf(priv->devName, "/dev/%soccan%d", prefix, dev->minor_bus);
500        }
501
502        /* Register Device */
503        DBG("OCCAN[%d]: Registering %s\n", dev->minor_drv, priv->devName);
504        status = rtems_io_register_name(priv->devName, occan_driver_io_major, dev->minor_drv);
505        if (status != RTEMS_SUCCESSFUL) {
506                return DRVMGR_FAIL;
507        }
508
509        return DRVMGR_OK;
510}
511
512/******************* Driver Implementation ***********************/
513
514int occan_register_io(rtems_device_major_number *m)
515{
516        rtems_status_code r;
517
518        if ((r = rtems_io_register_driver(0, &occan_driver, m)) == RTEMS_SUCCESSFUL) {
519                DBG("OCCAN driver successfully registered, major: %d\n", *m);
520        } else {
521                switch(r) {
522                case RTEMS_TOO_MANY:
523                        printk("OCCAN rtems_io_register_driver failed: RTEMS_TOO_MANY\n");
524                        return -1;
525                case RTEMS_INVALID_NUMBER: 
526                        printk("OCCAN rtems_io_register_driver failed: RTEMS_INVALID_NUMBER\n");
527                        return -1;
528                case RTEMS_RESOURCE_IN_USE:
529                        printk("OCCAN rtems_io_register_driver failed: RTEMS_RESOURCE_IN_USE\n");
530                        return -1;
531                default:
532                        printk("OCCAN rtems_io_register_driver failed\n");
533                        return -1;
534                }
535        }
536        return 0;
537}
538
539int occan_device_init(occan_priv *pDev)
540{
541        struct amba_dev_info *ambadev;
542        struct ambapp_core *pnpinfo;
543        rtems_status_code status;
544        int minor;
545
546        /* Get device information from AMBA PnP information */
547        ambadev = (struct amba_dev_info *)pDev->dev->businfo;
548        if ( ambadev == NULL ) {
549                return -1;
550        }
551        pnpinfo = &ambadev->info;
552        pDev->irq = pnpinfo->irq;
553        pDev->regs = (pelican_regs *)(pnpinfo->ahb_slv->start[0] + OCCAN_NCORE_OFS*pnpinfo->index);
554        pDev->byte_regs = 1;
555        minor = pDev->dev->minor_drv;
556
557        /* Get frequency in Hz */
558        if ( drvmgr_freq_get(pDev->dev, DEV_AHB_SLV, &pDev->sys_freq_hz) ) {
559                return -1;
560        }
561
562        DBG("OCCAN frequency: %d Hz\n", pDev->sys_freq_hz);
563
564        /* initialize software */
565        pDev->open = 0;
566        pDev->started = 0; /* Needed for spurious interrupts */
567        pDev->rxfifo = NULL;
568        pDev->txfifo = NULL;
569        status = rtems_semaphore_create(
570                        rtems_build_name('C', 'd', 'v', '0'+minor),
571                        1,
572                        RTEMS_FIFO | RTEMS_SIMPLE_BINARY_SEMAPHORE | RTEMS_NO_INHERIT_PRIORITY | \
573                        RTEMS_NO_PRIORITY_CEILING,
574                        0, 
575                        &pDev->devsem);
576        if ( status != RTEMS_SUCCESSFUL ){
577                printk("OCCAN[%d]: Failed to create dev semaphore, (%d)\n\r",minor, status);
578                return RTEMS_UNSATISFIED;
579        }
580        status = rtems_semaphore_create(
581                        rtems_build_name('C', 't', 'x', '0'+minor),
582                        0, 
583                        RTEMS_FIFO | RTEMS_SIMPLE_BINARY_SEMAPHORE | RTEMS_NO_INHERIT_PRIORITY | \
584                        RTEMS_NO_PRIORITY_CEILING,
585                        0, 
586                        &pDev->txsem);
587        if ( status != RTEMS_SUCCESSFUL ){
588                printk("OCCAN[%d]: Failed to create tx semaphore, (%d)\n\r",minor, status);
589                return RTEMS_UNSATISFIED;
590        }
591        status = rtems_semaphore_create(
592                        rtems_build_name('C', 'r', 'x', '0'+minor),
593                        0, 
594                        RTEMS_FIFO | RTEMS_SIMPLE_BINARY_SEMAPHORE | RTEMS_NO_INHERIT_PRIORITY | \
595                        RTEMS_NO_PRIORITY_CEILING,
596                        0,
597                        &pDev->rxsem);
598        if ( status != RTEMS_SUCCESSFUL ){
599                printk("OCCAN[%d]: Failed to create rx semaphore, (%d)\n\r",minor, status);
600                return RTEMS_UNSATISFIED;
601        }
602
603        /* hardware init/reset */
604        pelican_init(pDev);
605
606#ifdef DEBUG_PRINT_REGMAP
607        pelican_regadr_print(pDev->regs);
608#endif
609
610        return 0;
611}
612
613
614#ifdef DEBUG
615static void pelican_regs_print(occan_priv *pDev){
616        pelican_regs *regs = pDev->regs;
617        printk("--- PELICAN 0x%lx ---\n\r",(unsigned int)regs);
618        printk(" MODE: 0x%02x\n\r",READ_REG(pDev, &regs->mode));
619        printk(" CMD: 0x%02x\n\r",READ_REG(pDev, &regs->cmd));
620        printk(" STATUS: 0x%02x\n\r",READ_REG(pDev, &regs->status));
621        /*printk(" INTFLG: 0x%02x\n\r",READ_REG(pDev, &regs->intflags));*/
622        printk(" INTEN: 0x%02x\n\r",READ_REG(pDev, &regs->inten));
623        printk(" BTR0: 0x%02x\n\r",READ_REG(pDev, &regs->bustim0));
624        printk(" BTR1: 0x%02x\n\r",READ_REG(pDev, &regs->bustim1));
625        printk(" ARBCODE: 0x%02x\n\r",READ_REG(pDev, &regs->arbcode));
626        printk(" ERRCODE: 0x%02x\n\r",READ_REG(pDev, &regs->errcode));
627        printk(" ERRWARN: 0x%02x\n\r",READ_REG(pDev, &regs->errwarn));
628        printk(" RX_ERR_CNT: 0x%02x\n\r",READ_REG(pDev, &regs->rx_err_cnt));
629        printk(" TX_ERR_CNT: 0x%02x\n\r",READ_REG(pDev, &regs->tx_err_cnt));
630        if ( READ_REG(pDev, &regs->mode) & PELICAN_MOD_RESET ){
631                /* in reset mode it is possible to read acceptance filters */
632                printk(" ACR0: 0x%02x (0x%lx)\n\r",READ_REG(pDev, &regs->rx_fi_xff),&regs->rx_fi_xff);
633                printk(" ACR1: 0x%02x (0x%lx)\n\r",READ_REG(pDev, &regs->msg.rst_accept.code[0]),(unsigned int)&regs->msg.rst_accept.code[0]);
634                printk(" ACR1: 0x%02x (0x%lx)\n\r",READ_REG(pDev, &regs->msg.rst_accept.code[1]),(unsigned int)&regs->msg.rst_accept.code[1]);
635                printk(" ACR1: 0x%02x (0x%lx)\n\r",READ_REG(pDev, &regs->msg.rst_accept.code[2]),(unsigned int)&regs->msg.rst_accept.code[2]);
636                printk(" AMR0: 0x%02x (0x%lx)\n\r",READ_REG(pDev, &regs->msg.rst_accept.mask[0]),(unsigned int)&regs->msg.rst_accept.mask[0]);
637                printk(" AMR1: 0x%02x (0x%lx)\n\r",READ_REG(pDev, &regs->msg.rst_accept.mask[1]),(unsigned int)&regs->msg.rst_accept.mask[1]);
638                printk(" AMR2: 0x%02x (0x%lx)\n\r",READ_REG(pDev, &regs->msg.rst_accept.mask[2]),(unsigned int)&regs->msg.rst_accept.mask[2]);
639                printk(" AMR3: 0x%02x (0x%lx)\n\r",READ_REG(pDev, &regs->msg.rst_accept.mask[3]),(unsigned int)&regs->msg.rst_accept.mask[3]);
640               
641        }else{
642                printk(" RXFI_XFF: 0x%02x\n\r",READ_REG(pDev, &regs->rx_fi_xff));
643        }
644        printk(" RX_MSG_CNT: 0x%02x\n\r",READ_REG(pDev, &regs->rx_msg_cnt));
645        printk(" CLKDIV: 0x%02x\n\r",READ_REG(pDev, &regs->clkdiv));
646        printk("-------------------\n\r");
647}
648#endif
649
650#ifdef DEBUG_PRINT_REGMAP
651static void pelican_regadr_print(pelican_regs *regs){
652        printk("--- PELICAN 0x%lx ---\n\r",(unsigned int)regs);
653        printk(" MODE: 0x%lx\n\r",(unsigned int)&regs->mode);
654        printk(" CMD: 0x%lx\n\r",(unsigned int)&regs->cmd);
655        printk(" STATUS: 0x%lx\n\r",(unsigned int)&regs->status);
656        /*printk(" INTFLG: 0x%lx\n\r",&regs->intflags);*/
657        printk(" INTEN: 0x%lx\n\r",(unsigned int)&regs->inten);
658        printk(" BTR0: 0x%lx\n\r",(unsigned int)&regs->bustim0);
659        printk(" BTR1: 0x%lx\n\r",(unsigned int)&regs->bustim1);
660        printk(" ARBCODE: 0x%lx\n\r",(unsigned int)&regs->arbcode);
661        printk(" ERRCODE: 0x%lx\n\r",(unsigned int)&regs->errcode);
662        printk(" ERRWARN: 0x%lx\n\r",(unsigned int)&regs->errwarn);
663        printk(" RX_ERR_CNT: 0x%lx\n\r",(unsigned int)&regs->rx_err_cnt);
664        printk(" TX_ERR_CNT: 0x%lx\n\r",(unsigned int)&regs->tx_err_cnt);
665
666        /* in reset mode it is possible to read acceptance filters */
667        printk(" RXFI_XFF: 0x%lx\n\r",(unsigned int)&regs->rx_fi_xff);
668       
669        /* reset registers */
670        printk(" ACR0: 0x%lx\n\r",(unsigned int)&regs->rx_fi_xff);
671        printk(" ACR1: 0x%lx\n\r",(unsigned int)&regs->msg.rst_accept.code[0]);
672        printk(" ACR2: 0x%lx\n\r",(unsigned int)&regs->msg.rst_accept.code[1]);
673        printk(" ACR3: 0x%lx\n\r",(unsigned int)&regs->msg.rst_accept.code[2]);
674        printk(" AMR0: 0x%lx\n\r",(unsigned int)&regs->msg.rst_accept.mask[0]);
675        printk(" AMR1: 0x%lx\n\r",(unsigned int)&regs->msg.rst_accept.mask[1]);
676        printk(" AMR2: 0x%lx\n\r",(unsigned int)&regs->msg.rst_accept.mask[2]);
677        printk(" AMR3: 0x%lx\n\r",(unsigned int)&regs->msg.rst_accept.mask[3]);
678       
679        /* TX Extended */
680        printk(" EFFTX_ID[0]: 0x%lx\n\r",(unsigned int)&regs->msg.tx_eff.id[0]);
681        printk(" EFFTX_ID[1]: 0x%lx\n\r",(unsigned int)&regs->msg.tx_eff.id[1]);
682        printk(" EFFTX_ID[2]: 0x%lx\n\r",(unsigned int)&regs->msg.tx_eff.id[2]);
683        printk(" EFFTX_ID[3]: 0x%lx\n\r",(unsigned int)&regs->msg.tx_eff.id[3]);
684
685        printk(" EFFTX_DATA[0]: 0x%lx\n\r",(unsigned int)&regs->msg.tx_eff.data[0]);
686        printk(" EFFTX_DATA[1]: 0x%lx\n\r",(unsigned int)&regs->msg.tx_eff.data[1]);
687        printk(" EFFTX_DATA[2]: 0x%lx\n\r",(unsigned int)&regs->msg.tx_eff.data[2]);   
688        printk(" EFFTX_DATA[3]: 0x%lx\n\r",(unsigned int)&regs->msg.tx_eff.data[3]);   
689        printk(" EFFTX_DATA[4]: 0x%lx\n\r",(unsigned int)&regs->msg.tx_eff.data[4]);   
690        printk(" EFFTX_DATA[5]: 0x%lx\n\r",(unsigned int)&regs->msg.tx_eff.data[5]);   
691        printk(" EFFTX_DATA[6]: 0x%lx\n\r",(unsigned int)&regs->msg.tx_eff.data[6]);   
692        printk(" EFFTX_DATA[7]: 0x%lx\n\r",(unsigned int)&regs->msg.tx_eff.data[7]);   
693
694        /* RX Extended */
695        printk(" EFFRX_ID[0]: 0x%lx\n\r",(unsigned int)&regs->msg.rx_eff.id[0]);
696        printk(" EFFRX_ID[1]: 0x%lx\n\r",(unsigned int)&regs->msg.rx_eff.id[1]);
697        printk(" EFFRX_ID[2]: 0x%lx\n\r",(unsigned int)&regs->msg.rx_eff.id[2]);
698        printk(" EFFRX_ID[3]: 0x%lx\n\r",(unsigned int)&regs->msg.rx_eff.id[3]);
699
700        printk(" EFFRX_DATA[0]: 0x%lx\n\r",(unsigned int)&regs->msg.rx_eff.data[0]);
701        printk(" EFFRX_DATA[1]: 0x%lx\n\r",(unsigned int)&regs->msg.rx_eff.data[1]);
702        printk(" EFFRX_DATA[2]: 0x%lx\n\r",(unsigned int)&regs->msg.rx_eff.data[2]);   
703        printk(" EFFRX_DATA[3]: 0x%lx\n\r",(unsigned int)&regs->msg.rx_eff.data[3]);   
704        printk(" EFFRX_DATA[4]: 0x%lx\n\r",(unsigned int)&regs->msg.rx_eff.data[4]);   
705        printk(" EFFRX_DATA[5]: 0x%lx\n\r",(unsigned int)&regs->msg.rx_eff.data[5]);   
706        printk(" EFFRX_DATA[6]: 0x%lx\n\r",(unsigned int)&regs->msg.rx_eff.data[6]);   
707        printk(" EFFRX_DATA[7]: 0x%lx\n\r",(unsigned int)&regs->msg.rx_eff.data[7]);   
708
709
710        /* RX Extended */
711        printk(" SFFRX_ID[0]: 0x%lx\n\r",(unsigned int)&regs->msg.rx_sff.id[0]);
712        printk(" SFFRX_ID[1]: 0x%lx\n\r",(unsigned int)&regs->msg.rx_sff.id[1]);
713
714        printk(" SFFRX_DATA[0]: 0x%lx\n\r",(unsigned int)&regs->msg.rx_sff.data[0]);
715        printk(" SFFRX_DATA[1]: 0x%lx\n\r",(unsigned int)&regs->msg.rx_sff.data[1]);
716        printk(" SFFRX_DATA[2]: 0x%lx\n\r",(unsigned int)&regs->msg.rx_sff.data[2]);   
717        printk(" SFFRX_DATA[3]: 0x%lx\n\r",(unsigned int)&regs->msg.rx_sff.data[3]);   
718        printk(" SFFRX_DATA[4]: 0x%lx\n\r",(unsigned int)&regs->msg.rx_sff.data[4]);   
719        printk(" SFFRX_DATA[5]: 0x%lx\n\r",(unsigned int)&regs->msg.rx_sff.data[5]);   
720        printk(" SFFRX_DATA[6]: 0x%lx\n\r",(unsigned int)&regs->msg.rx_sff.data[6]);   
721        printk(" SFFRX_DATA[7]: 0x%lx\n\r",(unsigned int)&regs->msg.rx_sff.data[7]);   
722
723        /* TX Extended */
724        printk(" SFFTX_ID[0]: 0x%lx\n\r",(unsigned int)&regs->msg.tx_sff.id[0]);
725        printk(" SFFTX_ID[1]: 0x%lx\n\r",(unsigned int)&regs->msg.tx_sff.id[1]);
726
727        printk(" SFFTX_DATA[0]: 0x%lx\n\r",(unsigned int)&regs->msg.tx_sff.data[0]);
728        printk(" SFFTX_DATA[1]: 0x%lx\n\r",(unsigned int)&regs->msg.tx_sff.data[1]);
729        printk(" SFFTX_DATA[2]: 0x%lx\n\r",(unsigned int)&regs->msg.tx_sff.data[2]);
730        printk(" SFFTX_DATA[3]: 0x%lx\n\r",(unsigned int)&regs->msg.tx_sff.data[3]);
731        printk(" SFFTX_DATA[4]: 0x%lx\n\r",(unsigned int)&regs->msg.tx_sff.data[4]);
732        printk(" SFFTX_DATA[5]: 0x%lx\n\r",(unsigned int)&regs->msg.tx_sff.data[5]);
733        printk(" SFFTX_DATA[6]: 0x%lx\n\r",(unsigned int)&regs->msg.tx_sff.data[6]);
734        printk(" SFFTX_DATA[7]: 0x%lx\n\r",(unsigned int)&regs->msg.tx_sff.data[7]);
735
736        printk(" RX_MSG_CNT: 0x%lx\n\r",(unsigned int)&regs->rx_msg_cnt);
737        printk(" CLKDIV: 0x%lx\n\r",(unsigned int)&regs->clkdiv);
738        printk("-------------------\n\r");
739}
740#endif
741
742#ifdef DEBUG
743static void occan_stat_print(occan_stats *stats){
744        printk("----Stats----\n\r");
745        printk("rx_msgs: %d\n\r",stats->rx_msgs);
746        printk("tx_msgs: %d\n\r",stats->tx_msgs);
747        printk("err_warn: %d\n\r",stats->err_warn);
748        printk("err_dovr: %d\n\r",stats->err_dovr);
749        printk("err_errp: %d\n\r",stats->err_errp);
750        printk("err_arb: %d\n\r",stats->err_arb);
751        printk("err_bus: %d\n\r",stats->err_bus);
752        printk("Int cnt: %d\n\r",stats->ints);
753        printk("tx_buf_err: %d\n\r",stats->tx_buf_error);
754        printk("-------------\n\r");
755}
756#endif
757
758static void pelican_init(occan_priv *priv){
759        /* Reset core */
760        WRITE_REG(priv, &priv->regs->mode, PELICAN_MOD_RESET);
761
762        /* wait for core to reset complete */
763        /*usleep(1);*/
764}
765
766static void pelican_open(occan_priv *priv){
767        int ret;
768
769        /* Set defaults */
770        priv->speed = OCCAN_SPEED_250K;
771
772        /* set acceptance filters to accept all messages */
773        priv->acode[0] = 0;
774        priv->acode[1] = 0;
775        priv->acode[2] = 0;
776        priv->acode[3] = 0;
777        priv->amask[0] = 0xff;
778        priv->amask[1] = 0xff;
779        priv->amask[2] = 0xff;
780        priv->amask[3] = 0xff;
781
782        /* Set clock divider to extended mode, clkdiv not connected
783         */
784        WRITE_REG(priv, &priv->regs->clkdiv, (1<<PELICAN_CDR_MODE_BITS) | (DEFAULT_CLKDIV & PELICAN_CDR_DIV));
785
786        ret = occan_calc_speedregs(priv->sys_freq_hz,priv->speed,&priv->timing);
787        if ( ret ){
788                /* failed to set speed for this system freq, try with 50K instead */
789                priv->speed = OCCAN_SPEED_50K;
790                occan_calc_speedregs(priv->sys_freq_hz, priv->speed,
791                        &priv->timing);
792        }
793
794        /* disable all interrupts */
795        WRITE_REG(priv, &priv->regs->inten, 0);
796
797        /* clear pending interrupts by reading */
798        READ_REG(priv, &priv->regs->intflags);
799}
800
801static int pelican_start(occan_priv *priv){
802        /* Start HW communication */
803
804        if ( !priv->rxfifo || !priv->txfifo )
805                return -1;
806
807        /* In case we were started before and stopped we
808         * should empty the TX fifo or try to resend those
809         * messages. We make it simple...
810         */
811        occan_fifo_clr(priv->txfifo);
812
813        /* Clear status bits */
814        priv->status = 0;
815        priv->sending = 0;
816
817        /* clear pending interrupts */
818        READ_REG(priv, &priv->regs->intflags);
819
820        /* clear error counters */
821        WRITE_REG(priv, &priv->regs->rx_err_cnt, 0);
822        WRITE_REG(priv, &priv->regs->tx_err_cnt, 0);
823
824#ifdef REDUNDANT_CHANNELS
825        if ( (priv->channel == 0) || (priv->channel >= REDUNDANT_CHANNELS) ){
826                /* Select the first (default) channel */
827                OCCAN_SET_CHANNEL(priv,0);
828        }else{
829                /* set gpio bit, or something */
830                OCCAN_SET_CHANNEL(priv,priv->channel);
831        }
832#endif
833        /* set the speed regs of the CAN core */
834        occan_set_speedregs(priv,&priv->timing);
835
836        DBG("OCCAN: start: set timing regs btr0: 0x%x, btr1: 0x%x\n\r",
837                READ_REG(priv, &priv->regs->bustim0),
838                READ_REG(priv, &priv->regs->bustim1));
839
840        /* Set default acceptance filter */
841        pelican_set_accept(priv,priv->acode,priv->amask);
842
843        /* Nothing can fail from here, this must be set before interrupts are
844         * enabled */
845        priv->started = 1;
846
847        /* turn on interrupts */
848        WRITE_REG(priv, &priv->regs->inten,
849                PELICAN_IE_RX | PELICAN_IE_TX | PELICAN_IE_ERRW |
850                PELICAN_IE_ERRP | PELICAN_IE_BUS);
851#ifdef DEBUG
852        /* print setup before starting */
853        pelican_regs_print(priv->regs);
854        occan_stat_print(&priv->stats);
855#endif
856
857        /* core already in reset mode,
858         *  € Exit reset mode
859         *  € Enter Single/Dual mode filtering.
860         */
861        WRITE_REG(priv, &priv->regs->mode, (priv->single_mode << 3));
862
863        /* Register interrupt routine and unmask IRQ at IRQ controller */
864        drvmgr_interrupt_register(priv->dev, 0, "occan", occan_interrupt, priv);
865
866        return 0;
867}
868
869static void pelican_stop(occan_priv *priv)
870{
871        /* stop HW */
872
873        drvmgr_interrupt_unregister(priv->dev, 0, occan_interrupt, priv);
874
875#ifdef DEBUG
876        /* print setup before stopping */
877        pelican_regs_print(priv->regs);
878        occan_stat_print(&priv->stats);
879#endif
880
881        /* put core in reset mode */
882        WRITE_REG(priv, &priv->regs->mode, PELICAN_MOD_RESET);
883
884        /* turn off interrupts */
885        WRITE_REG(priv, &priv->regs->inten, 0);
886
887        priv->status |= OCCAN_STATUS_RESET;
888}
889
890static inline int pelican_tx_ready(occan_priv *can)
891{
892        unsigned char status;
893        pelican_regs *regs = can->regs;
894
895        /* is there room in send buffer? */
896        status = READ_REG(can, &regs->status);
897        if ( !(status & PELICAN_STAT_TXBUF) ) {
898                /* tx fifo taken, we have to wait */
899                return 0;
900        }
901
902        return 1;
903}
904
905/* Try to send message "msg", if hardware txfifo is
906 * full, then -1 is returned.
907 *
908 * Be sure to have disabled CAN interrupts when
909 * entering this function.
910 */
911static int pelican_send(occan_priv *can, CANMsg *msg){
912        unsigned char tmp;
913        pelican_regs *regs = can->regs;
914
915        /* is there room in send buffer? */
916        if ( !pelican_tx_ready(can) ) {
917                /* tx fifo taken, we have to wait */
918                return -1;
919        }
920
921        tmp = msg->len & 0xf;
922        if ( msg->rtr )
923                tmp |= 0x40;
924
925        if ( msg->extended ){
926                /* Extended Frame */
927                WRITE_REG(can, &regs->rx_fi_xff, 0x80 | tmp);
928                WRITE_REG(can, &regs->msg.tx_eff.id[0],(msg->id >> (5+8+8)) & 0xff);
929                WRITE_REG(can, &regs->msg.tx_eff.id[1],(msg->id >> (5+8)) & 0xff);
930                WRITE_REG(can, &regs->msg.tx_eff.id[2],(msg->id >> (5)) & 0xff);
931                WRITE_REG(can, &regs->msg.tx_eff.id[3],(msg->id << 3) & 0xf8);
932                tmp = msg->len;
933                while(tmp--){
934                        WRITE_REG(can, &regs->msg.tx_eff.data[tmp], msg->data[tmp]);
935                }
936        }else{
937                /* Standard Frame */
938                WRITE_REG(can, &regs->rx_fi_xff, tmp);
939                WRITE_REG(can, &regs->msg.tx_sff.id[0],(msg->id >> 3) & 0xff);
940                WRITE_REG(can, &regs->msg.tx_sff.id[1],(msg->id << 5) & 0xe0);
941                tmp = msg->len;
942                while(tmp--){
943                        WRITE_REG(can, &regs->msg.tx_sff.data[tmp],msg->data[tmp]);
944                }
945        }
946
947        /* let HW know of new message */
948        if ( msg->sshot ){
949                WRITE_REG(can, &regs->cmd, PELICAN_CMD_TXREQ | PELICAN_CMD_ABORT);
950        }else{
951                /* normal case -- try resend until sent */
952                WRITE_REG(can, &regs->cmd, PELICAN_CMD_TXREQ);
953        }
954
955        return 0;
956}
957
958
959static void pelican_set_accept(occan_priv *priv, unsigned char *acode, unsigned char *amask)
960{
961        unsigned char *acode0, *acode1, *acode2, *acode3;
962        unsigned char *amask0, *amask1, *amask2, *amask3;
963
964        acode0 = &priv->regs->rx_fi_xff;
965        acode1 = (unsigned char *)&priv->regs->msg.rst_accept.code[0];
966        acode2 = (unsigned char *)&priv->regs->msg.rst_accept.code[1];
967        acode3 = (unsigned char *)&priv->regs->msg.rst_accept.code[2];
968
969        amask0 = (unsigned char *)&priv->regs->msg.rst_accept.mask[0];
970        amask1 = (unsigned char *)&priv->regs->msg.rst_accept.mask[1];
971        amask2 = (unsigned char *)&priv->regs->msg.rst_accept.mask[2];
972        amask3 = (unsigned char *)&priv->regs->msg.rst_accept.mask[3];
973
974        /* Set new mask & code */
975        WRITE_REG(priv, acode0, acode[0]);
976        WRITE_REG(priv, acode1, acode[1]);
977        WRITE_REG(priv, acode2, acode[2]);
978        WRITE_REG(priv, acode3, acode[3]);
979
980        WRITE_REG(priv, amask0, amask[0]);
981        WRITE_REG(priv, amask1, amask[1]);
982        WRITE_REG(priv, amask2, amask[2]);
983        WRITE_REG(priv, amask3, amask[3]);
984}
985
986
987/* This function calculates BTR0 and BTR1 values for a given bitrate.
988 *
989 * Set communication parameters.
990 * \param clock_hz OC_CAN Core frequency in Hz.
991 * \param rate Requested baud rate in bits/second.
992 * \param result Pointer to where resulting BTRs will be stored.
993 * \return zero if successful to calculate a baud rate.
994 */
995static int occan_calc_speedregs(unsigned int clock_hz, unsigned int rate, occan_speed_regs *result)
996{
997        int best_error = 1000000000;
998        int error;
999        int best_tseg=0, best_brp=0, brp=0;
1000        int tseg=0, tseg1=0, tseg2=0;
1001        int sjw = 0;
1002        int clock = clock_hz / 2;
1003        int sampl_pt = 90;
1004
1005        if ( (rate<5000) || (rate>1000000) ){
1006                /* invalid speed mode */
1007                return -1;
1008        }
1009
1010        /* find best match, return -2 if no good reg
1011         * combination is available for this frequency */
1012
1013        /* some heuristic specials */
1014        if (rate > ((1000000 + 500000) / 2))
1015                sampl_pt = 75;
1016
1017        if (rate < ((12500 + 10000) / 2))
1018                sampl_pt = 75;
1019
1020        if (rate < ((100000 + 125000) / 2))
1021                sjw = 1;
1022
1023        /* tseg even = round down, odd = round up */
1024        for (tseg = (0 + 0 + 2) * 2;
1025             tseg <= (MAX_TSEG2 + MAX_TSEG1 + 2) * 2 + 1;
1026             tseg++)
1027        {
1028                brp = clock / ((1 + tseg / 2) * rate) + tseg % 2;
1029                if ((brp == 0) || (brp > 64))
1030                        continue;
1031
1032                error = rate - clock / (brp * (1 + tseg / 2));
1033                if (error < 0)
1034                {
1035                        error = -error;
1036                }
1037
1038                if (error <= best_error)
1039                {
1040                        best_error = error;
1041                        best_tseg = tseg/2;
1042                        best_brp = brp-1;
1043                }
1044        }
1045
1046        if (best_error && (rate / best_error < 10))
1047        {
1048                printk("OCCAN: bitrate %d is not possible with %d Hz clock\n\r",rate, clock);
1049                return -2;
1050        }else if ( !result )
1051                return 0; /* nothing to store result in, but a valid bitrate can be calculated */
1052
1053        tseg2 = best_tseg - (sampl_pt * (best_tseg + 1)) / 100;
1054
1055        if (tseg2 < 0)
1056        {
1057                tseg2 = 0;
1058        }
1059
1060        if (tseg2 > MAX_TSEG2)
1061        {
1062                tseg2 = MAX_TSEG2;
1063        }
1064
1065        tseg1 = best_tseg - tseg2 - 2;
1066
1067        if (tseg1 > MAX_TSEG1)
1068        {
1069                tseg1 = MAX_TSEG1;
1070                tseg2 = best_tseg - tseg1 - 2;
1071        }
1072
1073        result->btr0 = (sjw<<OCCAN_BUSTIM_SJW_BIT) | (best_brp&OCCAN_BUSTIM_BRP);
1074        result->btr1 = (0<<7) | (tseg2<<OCCAN_BUSTIM_TSEG2_BIT) | tseg1;
1075
1076        return 0;
1077}
1078
1079static int occan_set_speedregs(occan_priv *priv, occan_speed_regs *timing)
1080{
1081        if ( !timing || !priv || !priv->regs)
1082                return -1;
1083
1084        WRITE_REG(priv, &priv->regs->bustim0, timing->btr0);
1085        WRITE_REG(priv, &priv->regs->bustim1, timing->btr1);
1086
1087        return 0;
1088}
1089
1090static rtems_device_driver occan_initialize(rtems_device_major_number major, rtems_device_minor_number unused, void *arg)
1091{
1092        return RTEMS_SUCCESSFUL;
1093}
1094
1095static rtems_device_driver occan_open(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
1096{
1097        occan_priv *can;
1098        struct drvmgr_dev *dev;
1099
1100        DBG("OCCAN: Opening %d\n\r",minor);
1101
1102        /* get can device */   
1103        if ( drvmgr_get_dev(&occan_drv_info.general, minor, &dev) ) {
1104                DBG("Wrong minor %d\n", minor);
1105                return RTEMS_UNSATISFIED; /* NODEV */
1106        }
1107        can = (occan_priv *)dev->priv;
1108
1109        /* already opened? */
1110        rtems_semaphore_obtain(can->devsem, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
1111        if ( can->open ){
1112                rtems_semaphore_release(can->devsem);
1113                return RTEMS_RESOURCE_IN_USE; /* EBUSY */
1114        }
1115        can->open = 1;
1116        rtems_semaphore_release(can->devsem);
1117
1118        SPIN_INIT(&can->devlock, can->devName);
1119
1120        /* allocate fifos */
1121        can->rxfifo = occan_fifo_create(DEFAULT_RX_FIFO_LEN);
1122        if ( !can->rxfifo ){
1123                can->open = 0;
1124                return RTEMS_NO_MEMORY; /* ENOMEM */
1125        }
1126
1127        can->txfifo = occan_fifo_create(DEFAULT_TX_FIFO_LEN);
1128        if ( !can->txfifo ){
1129                occan_fifo_free(can->rxfifo);
1130                can->rxfifo= NULL;
1131                can->open = 0;
1132                return RTEMS_NO_MEMORY; /* ENOMEM */
1133        }
1134
1135        DBG("OCCAN: Opening %d success\n\r",minor);
1136
1137        can->started = 0;
1138        can->channel = 0; /* Default to first can link */
1139        can->txblk = 1; /* Default to Blocking mode */
1140        can->rxblk = 1; /* Default to Blocking mode */
1141        can->single_mode = 1; /* single mode acceptance filter */
1142
1143        /* reset stat counters */
1144        memset(&can->stats,0,sizeof(occan_stats));
1145
1146        /* HW must be in reset mode here (close and initializes resets core...)
1147         *
1148         * 1. set default modes/speeds
1149         */
1150        pelican_open(can);
1151
1152        return RTEMS_SUCCESSFUL;
1153}
1154
1155static rtems_device_driver occan_close(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
1156{
1157        occan_priv *can;
1158        struct drvmgr_dev *dev;
1159
1160        DBG("OCCAN: Closing %d\n\r",minor);
1161
1162        if ( drvmgr_get_dev(&occan_drv_info.general, minor, &dev) ) {
1163                return RTEMS_INVALID_NAME;
1164        }
1165        can = (occan_priv *)dev->priv;
1166
1167        /* stop if running */
1168        if ( can->started )
1169                pelican_stop(can);
1170
1171        /* Enter Reset Mode */
1172        WRITE_REG(can, &can->regs->mode, PELICAN_MOD_RESET);
1173
1174        /* free fifo memory */
1175        occan_fifo_free(can->rxfifo);
1176        occan_fifo_free(can->txfifo);
1177
1178        can->rxfifo = NULL;
1179        can->txfifo = NULL;
1180
1181        can->open = 0;
1182
1183        return RTEMS_SUCCESSFUL;
1184}
1185
1186static rtems_device_driver occan_read(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
1187{
1188        occan_priv *can;
1189        struct drvmgr_dev *dev;
1190        rtems_libio_rw_args_t *rw_args=(rtems_libio_rw_args_t *) arg;
1191        CANMsg *dstmsg, *srcmsg;
1192        SPIN_IRQFLAGS(oldLevel);
1193        int left;
1194
1195        if ( drvmgr_get_dev(&occan_drv_info.general, minor, &dev) ) {
1196                return RTEMS_INVALID_NAME;
1197        }
1198        can = (occan_priv *)dev->priv;
1199
1200        if ( !can->started ){
1201                DBG("OCCAN: cannot read from minor %d when not started\n\r",minor);
1202                return RTEMS_RESOURCE_IN_USE; /* -EBUSY*/
1203        }
1204
1205        /* does at least one message fit */
1206        left = rw_args->count;
1207        if ( left < sizeof(CANMsg) ){
1208                DBG("OCCAN: minor %d length of buffer must be at least %d, our is %d\n\r",minor,sizeof(CANMsg),left);
1209                return  RTEMS_INVALID_NAME; /* -EINVAL */
1210        }
1211
1212        /* get pointer to start where to put CAN messages */
1213        dstmsg = (CANMsg *)rw_args->buffer;
1214        if ( !dstmsg ){
1215                DBG("OCCAN: minor %d read: input buffer is NULL\n\r",minor);
1216                return  RTEMS_INVALID_NAME; /* -EINVAL */
1217        }
1218
1219        while (left >= sizeof(CANMsg) ){
1220
1221                /* turn off interrupts */
1222                SPIN_LOCK_IRQ(&can->devlock, oldLevel);
1223
1224                /* A bus off interrupt may have occured after checking can->started */
1225                if ( can->status & (OCCAN_STATUS_ERR_BUSOFF|OCCAN_STATUS_RESET) ){
1226                        SPIN_UNLOCK_IRQ(&can->devlock, oldLevel);
1227                        DBG("OCCAN: read is cancelled due to a BUS OFF error\n\r");
1228                        rw_args->bytes_moved = rw_args->count-left;
1229                        return RTEMS_IO_ERROR; /* EIO */
1230                }
1231
1232                srcmsg = occan_fifo_claim_get(can->rxfifo);
1233                if ( !srcmsg ){
1234                        /* no more messages in reception fifo.
1235                         * Wait for incoming packets only if in
1236                         * blocking mode AND no messages been
1237                         * read before.
1238                         */
1239                        if ( !can->rxblk || (left != rw_args->count) ){
1240                                /* turn on interrupts again */
1241                                SPIN_UNLOCK_IRQ(&can->devlock, oldLevel);
1242                                break;
1243                        }
1244
1245                        /* turn on interrupts again */
1246                        SPIN_UNLOCK_IRQ(&can->devlock, oldLevel);
1247
1248                        DBG("OCCAN: Waiting for RX int\n\r");
1249
1250                        /* wait for incoming messages */
1251                        rtems_semaphore_obtain(can->rxsem, RTEMS_WAIT,
1252                                RTEMS_NO_TIMEOUT);
1253
1254                        /* did we get woken up by a BUS OFF error? */
1255                        if ( can->status & (OCCAN_STATUS_ERR_BUSOFF|OCCAN_STATUS_RESET) ){
1256                                DBG("OCCAN: Blocking read got woken up by BUS OFF error\n\r");
1257                                /* At this point it should not matter how many messages we handled */
1258                                rw_args->bytes_moved = rw_args->count-left;
1259                                return RTEMS_IO_ERROR; /* EIO */
1260                        }
1261
1262                        /* no errors detected, it must be a message */
1263                        continue;
1264                }
1265
1266                /* got message, copy it to userspace buffer */
1267                *dstmsg = *srcmsg;
1268
1269                /* Return borrowed message, RX interrupt can use it again */
1270                occan_fifo_get(can->rxfifo);
1271
1272                /* turn on interrupts again */
1273                SPIN_UNLOCK_IRQ(&can->devlock, oldLevel);
1274
1275                /* increase pointers */
1276                left -= sizeof(CANMsg);
1277                dstmsg++;
1278        }
1279
1280        /* save number of read bytes. */
1281        rw_args->bytes_moved = rw_args->count-left;
1282        if ( rw_args->bytes_moved == 0 ){
1283                DBG("OCCAN: minor %d read would block, returning\n\r",minor);
1284                return RTEMS_TIMEOUT; /* ETIMEDOUT should be EAGAIN/EWOULDBLOCK */
1285        }
1286        return RTEMS_SUCCESSFUL;
1287}
1288
1289static rtems_device_driver occan_write(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
1290{
1291        occan_priv *can;
1292        struct drvmgr_dev *dev;
1293        rtems_libio_rw_args_t *rw_args=(rtems_libio_rw_args_t *) arg;
1294        CANMsg *msg,*fifo_msg;
1295        SPIN_IRQFLAGS(oldLevel);
1296        int left;
1297
1298        DBG("OCCAN: Writing %d bytes from 0x%lx (%d)\n\r",rw_args->count,rw_args->buffer,sizeof(CANMsg));
1299
1300        if ( drvmgr_get_dev(&occan_drv_info.general, minor, &dev) ) {
1301                return RTEMS_INVALID_NAME;
1302        }
1303        can = (occan_priv *)dev->priv;
1304
1305        if ( !can->started )
1306                return RTEMS_RESOURCE_IN_USE; /* EBUSY */
1307
1308        left = rw_args->count;
1309        if ( (left < sizeof(CANMsg)) || (!rw_args->buffer) ){
1310                return RTEMS_INVALID_NAME; /* EINVAL */
1311        }
1312
1313        msg = (CANMsg *)rw_args->buffer;
1314
1315        /* limit CAN message length to 8 */
1316        msg->len = (msg->len > 8) ? 8 : msg->len;
1317
1318#ifdef DEBUG_VERBOSE
1319        pelican_regs_print(can->regs);
1320        occan_stat_print(&can->stats);
1321#endif
1322
1323        /* turn off interrupts */
1324        SPIN_LOCK_IRQ(&can->devlock, oldLevel);
1325
1326        /* A bus off interrupt may have occured after checking can->started */
1327        if ( can->status & (OCCAN_STATUS_ERR_BUSOFF|OCCAN_STATUS_RESET) ){
1328                SPIN_UNLOCK_IRQ(&can->devlock, oldLevel);
1329                rw_args->bytes_moved = 0;
1330                return RTEMS_IO_ERROR; /* EIO */
1331        }
1332
1333        /* If no messages in software tx fifo, we will
1334         * try to send first message by putting it directly
1335         * into the HW TX fifo.
1336         */
1337        if ( occan_fifo_empty(can->txfifo) ){
1338                /*pelican_regs_print(cans[minor+1].regs);*/
1339                if ( !pelican_send(can,msg) ) {
1340                        /* First message put directly into HW TX fifo
1341                         * This will turn TX interrupt on.
1342                         */
1343                        left -= sizeof(CANMsg);
1344                        msg++;
1345
1346#ifdef OCCAN_TX_IRQ_FLAG_FIXUP
1347                        /* Mark that we have put at least one msg in TX FIFO */
1348                        can->sending = 1;
1349#endif
1350
1351                        /* bump stat counters */
1352                        can->stats.tx_msgs++;
1353
1354                        DBG("OCCAN: Sending direct via HW\n\r");
1355                }
1356        }
1357
1358        /* Put messages into software fifo */
1359        while ( left >= sizeof(CANMsg) ){
1360
1361                /* limit CAN message length to 8 */
1362                msg->len = (msg->len > 8) ? 8 : msg->len;
1363
1364                fifo_msg = occan_fifo_put_claim(can->txfifo,0);
1365                if ( !fifo_msg ){
1366
1367                        DBG("OCCAN: FIFO is full\n\r");
1368                        /* Block only if no messages previously sent
1369                         * and no in blocking mode
1370                         */
1371                        if ( !can->txblk  || (left != rw_args->count) )
1372                                break;
1373
1374                        /* turn on interupts again and wait
1375                                INT_ON
1376                                WAIT FOR FREE BUF;
1377                                INT_OFF;
1378                                CHECK_IF_FIFO_EMPTY ==> SEND DIRECT VIA HW;
1379                        */
1380                        SPIN_UNLOCK_IRQ(&can->devlock, oldLevel);
1381
1382                        DBG("OCCAN: Waiting for tx int\n\r");
1383
1384                        rtems_semaphore_obtain(can->txsem, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
1385
1386                        /* did we get woken up by a BUS OFF error? */
1387                        if ( can->status & (OCCAN_STATUS_ERR_BUSOFF|OCCAN_STATUS_RESET) ){
1388                                DBG("OCCAN: Blocking write got woken up by BUS OFF error or RESET event\n\r");
1389                                /* At this point it should not matter how many messages we handled */
1390                                rw_args->bytes_moved = rw_args->count-left;
1391                                return RTEMS_IO_ERROR; /* EIO */
1392                        }
1393
1394                        SPIN_LOCK_IRQ(&can->devlock, oldLevel);
1395
1396                        if ( occan_fifo_empty(can->txfifo) ){
1397                                if ( !pelican_send(can,msg) ) {
1398                                        /* First message put directly into HW TX fifo
1399                                         * This will turn TX interrupt on.
1400                                         */
1401                                        left -= sizeof(CANMsg);
1402                                        msg++;
1403
1404#ifdef OCCAN_TX_IRQ_FLAG_FIXUP
1405                                        /* Mark that we have put at least one msg in TX FIFO */
1406                                        can->sending = 1;
1407#endif
1408
1409                                        /* bump stat counters */
1410                                        can->stats.tx_msgs++;
1411
1412                                        DBG("OCCAN: Sending direct2 via HW\n\r");
1413                                }
1414                        }
1415                        continue;
1416                }
1417
1418                /* copy message into fifo area */
1419                *fifo_msg = *msg;
1420
1421                /* tell interrupt handler about the message */
1422                occan_fifo_put(can->txfifo);
1423
1424                DBG("OCCAN: Put info fifo SW\n\r");
1425
1426                /* Prepare insert of next message */
1427                msg++;
1428                left-=sizeof(CANMsg);
1429        }
1430
1431        SPIN_UNLOCK_IRQ(&can->devlock, oldLevel);
1432
1433        rw_args->bytes_moved = rw_args->count-left;
1434        DBG("OCCAN: Sent %d\n\r",rw_args->bytes_moved);
1435
1436        if ( left == rw_args->count )
1437                return RTEMS_TIMEOUT; /* ETIMEDOUT should be EAGAIN/EWOULDBLOCK */
1438        return RTEMS_SUCCESSFUL;
1439}
1440
1441static rtems_device_driver occan_ioctl(rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
1442{
1443        int ret;
1444        occan_speed_regs timing;
1445        occan_priv *can;
1446        struct drvmgr_dev *dev;
1447        unsigned int speed;
1448        rtems_libio_ioctl_args_t *ioarg = (rtems_libio_ioctl_args_t *) arg;
1449        struct occan_afilter *afilter;
1450        occan_stats *dststats;
1451        unsigned int rxcnt,txcnt;
1452
1453        DBG("OCCAN: IOCTL %d\n\r",ioarg->command);
1454
1455        if ( drvmgr_get_dev(&occan_drv_info.general, minor, &dev) ) {
1456                return RTEMS_INVALID_NAME;
1457        }
1458        can = (occan_priv *)dev->priv;
1459
1460        ioarg->ioctl_return = 0;
1461        switch(ioarg->command){
1462                case OCCAN_IOC_SET_SPEED:
1463
1464                        /* cannot change speed during run mode */
1465                        if ( can->started )
1466                                return RTEMS_RESOURCE_IN_USE; /* EBUSY */
1467
1468                        /* get speed rate from argument */
1469                        speed = (unsigned int)ioarg->buffer;
1470                        ret = occan_calc_speedregs(can->sys_freq_hz,speed,&timing);
1471                        if ( ret )
1472                                return  RTEMS_INVALID_NAME; /* EINVAL */
1473
1474                        /* set the speed regs of the CAN core */
1475                        /* occan_set_speedregs(can,timing); */
1476
1477                        /* save timing/speed */
1478                        can->speed = speed;
1479                        can->timing = timing;
1480                        break;
1481
1482                case OCCAN_IOC_SET_BTRS:
1483                        /* Set BTR registers manually
1484                         * Read OCCAN Manual.
1485                         */
1486                        if ( can->started )
1487                                return RTEMS_RESOURCE_IN_USE; /* EBUSY */
1488
1489                        can->speed = 0; /* custom */
1490                        can->timing.btr1 = (unsigned int)ioarg->buffer & 0xff;
1491                        can->timing.btr0 = ((unsigned int)ioarg->buffer>>8) & 0xff;
1492/*
1493                        can->timing.sjw = (btr0 >> OCCAN_BUSTIM_SJW_BIT) & 0x3;
1494                        can->timing.brp = btr0 & OCCAN_BUSTIM_BRP;
1495                        can->timing.tseg1 = btr1 & 0xf;
1496                        can->timing.tseg2 = (btr1 >> OCCAN_BUSTIM_TSEG2_BIT) & 0x7;
1497                        can->timing.sam = (btr1 >> 7) & 0x1;
1498                        */
1499                        break;
1500
1501                case OCCAN_IOC_SPEED_AUTO:
1502                        return RTEMS_NOT_IMPLEMENTED;
1503
1504                case OCCAN_IOC_SET_BUFLEN:
1505                        /* set rx & tx fifo buffer length */
1506                        if ( can->started )
1507                                return RTEMS_RESOURCE_IN_USE; /* EBUSY */
1508
1509                        rxcnt = (unsigned int)ioarg->buffer & 0x0000ffff;
1510                        txcnt = (unsigned int)ioarg->buffer >> 16;
1511
1512                        occan_fifo_free(can->rxfifo);
1513                        occan_fifo_free(can->txfifo);
1514
1515                        /* allocate new buffers */
1516                        can->rxfifo = occan_fifo_create(rxcnt);
1517                        can->txfifo = occan_fifo_create(txcnt);
1518
1519                        if ( !can->rxfifo || !can->txfifo )
1520                                return RTEMS_NO_MEMORY; /* ENOMEM */
1521                        break;
1522
1523                case OCCAN_IOC_GET_CONF:
1524                        return RTEMS_NOT_IMPLEMENTED;
1525                        break;
1526
1527                case OCCAN_IOC_GET_STATS:
1528                        dststats = (occan_stats *)ioarg->buffer;
1529                        if ( !dststats )
1530                                return  RTEMS_INVALID_NAME; /* EINVAL */
1531
1532                        /* copy data stats into userspace buffer */
1533                        if ( can->rxfifo )
1534                                can->stats.rx_sw_dovr = can->rxfifo->ovcnt;
1535                        *dststats = can->stats;
1536                        break;
1537
1538                case OCCAN_IOC_GET_STATUS:
1539                        /* return the status of the */
1540                        if ( !ioarg->buffer )
1541                                return RTEMS_INVALID_NAME;
1542
1543                        *(unsigned int *)ioarg->buffer = can->status;
1544                        break;
1545
1546                /* Set physical link */
1547                case OCCAN_IOC_SET_LINK:
1548#ifdef REDUNDANT_CHANNELS
1549                        if ( can->started )
1550                                return RTEMS_RESOURCE_IN_USE; /* EBUSY */
1551
1552                        /* switch HW channel */
1553                        can->channel = (unsigned int)ioargs->buffer;
1554#else
1555                        return RTEMS_NOT_IMPLEMENTED;
1556#endif
1557                        break;
1558
1559                case OCCAN_IOC_SET_FILTER:
1560                        if ( can->started )
1561                                return RTEMS_RESOURCE_IN_USE; /* EBUSY */
1562
1563                        afilter = (struct occan_afilter *)ioarg->buffer;
1564
1565                        if ( !afilter )
1566                                return RTEMS_INVALID_NAME; /* EINVAL */
1567
1568                        /* copy acceptance filter */
1569                        can->acode[0] = afilter->code[0];
1570                        can->acode[1] = afilter->code[1];
1571                        can->acode[2] = afilter->code[2];
1572                        can->acode[3] = afilter->code[3];
1573
1574                        can->amask[0] = afilter->mask[0];
1575                        can->amask[1] = afilter->mask[1];
1576                        can->amask[2] = afilter->mask[2];
1577                        can->amask[3] = afilter->mask[3];
1578
1579                        can->single_mode = ( afilter->single_mode ) ? 1 : 0;
1580
1581                        /* Acceptance filter is written to hardware
1582                         * when starting.
1583                         */
1584                        /* pelican_set_accept(can,can->acode,can->amask);*/
1585                        break;
1586
1587                case OCCAN_IOC_SET_BLK_MODE:
1588                        can->rxblk = (unsigned int)ioarg->buffer & OCCAN_BLK_MODE_RX;
1589                        can->txblk = ((unsigned int)ioarg->buffer & OCCAN_BLK_MODE_TX) >> 1;
1590                        break;
1591
1592                case OCCAN_IOC_START:
1593                        if ( can->started )
1594                                return RTEMS_RESOURCE_IN_USE; /* EBUSY */
1595                        if ( pelican_start(can) )
1596                                return RTEMS_NO_MEMORY; /* failed because of no memory, can happen if SET_BUFLEN failed */
1597                        /* can->started = 1; -- Is set in pelican_start due to interrupt may occur before we
1598                         * get here.
1599                         */
1600                        break;
1601
1602                case OCCAN_IOC_STOP:
1603                        if ( !can->started )
1604                                return RTEMS_RESOURCE_IN_USE; /* EBUSY */
1605                        pelican_stop(can);
1606                        can->started = 0;
1607                        break;
1608
1609                default:
1610                        return RTEMS_NOT_DEFINED;
1611        }
1612        return RTEMS_SUCCESSFUL;
1613}
1614
1615void occan_interrupt(void *arg)
1616{
1617        occan_priv *can = arg;
1618        unsigned char iflags;
1619        pelican_regs *regs = can->regs;
1620        CANMsg *msg;
1621        int signal_rx=0, signal_tx=0;
1622        unsigned char tmp, errcode, arbcode;
1623        int tx_error_cnt,rx_error_cnt;
1624        SPIN_ISR_IRQFLAGS(irqflags);
1625
1626        if ( !can->started )
1627                return; /* Spurious Interrupt, do nothing */
1628
1629        SPIN_LOCK(&can->devlock, irqflags);
1630        while (1) {
1631
1632                iflags = READ_REG(can, &can->regs->intflags);
1633
1634#ifdef OCCAN_TX_IRQ_FLAG_FIXUP
1635                /* TX IRQ may be cleared when reading regs->intflags due
1636                 * to a bug in some chips. Instead of looking at the TX_IRQ_FLAG
1637                 * the TX-fifo emoty register is looked at when something has
1638                 * been scheduled for transmission.
1639                 */
1640                if ((iflags & PELICAN_IF_TX) == 0) {
1641                        if (can->sending && pelican_tx_ready(can)) {
1642                                can->sending = 0;
1643                                iflags |= PELICAN_IF_TX;
1644                        }
1645                }
1646#endif
1647
1648                if (iflags == 0)
1649                        break;
1650                /* still interrupts to handle */
1651
1652                can->stats.ints++;
1653
1654                if ( iflags & PELICAN_IF_RX ){
1655                        /* the rx fifo is not empty
1656                         * put 1 message into rxfifo for later use
1657                         */
1658
1659                        /* get empty (or make room) message */
1660                        msg = occan_fifo_put_claim(can->rxfifo,1);
1661                        tmp = READ_REG(can, &regs->rx_fi_xff);
1662                        msg->extended = tmp >> 7;
1663                        msg->rtr = (tmp >> 6) & 1;
1664                        msg->len = tmp = tmp & 0x0f;
1665
1666                        if ( msg->extended ){
1667                                /* extended message */
1668                                msg->id =  READ_REG(can, &regs->msg.rx_eff.id[0])<<(5+8+8) |
1669                                           READ_REG(can, &regs->msg.rx_eff.id[1])<<(5+8) |
1670                                           READ_REG(can, &regs->msg.rx_eff.id[2])<<5 |
1671                                           READ_REG(can, &regs->msg.rx_eff.id[3])>>3;
1672
1673                                while(tmp--){
1674                                        msg->data[tmp] = READ_REG(can, &regs->msg.rx_eff.data[tmp]);
1675                                }
1676                                /*
1677                                msg->data[0] = READ_REG(can, &regs->msg.rx_eff.data[0]);
1678                                msg->data[1] = READ_REG(can, &regs->msg.rx_eff.data[1]);
1679                                msg->data[2] = READ_REG(can, &regs->msg.rx_eff.data[2]);
1680                                msg->data[3] = READ_REG(can, &regs->msg.rx_eff.data[3]);
1681                                msg->data[4] = READ_REG(can, &regs->msg.rx_eff.data[4]);
1682                                msg->data[5] = READ_REG(can, &regs->msg.rx_eff.data[5]);
1683                                msg->data[6] = READ_REG(can, &regs->msg.rx_eff.data[6]);
1684                                msg->data[7] = READ_REG(can, &regs->msg.rx_eff.data[7]);
1685                                */
1686                        }else{
1687                                /* standard message */
1688                                msg->id = READ_REG(can, &regs->msg.rx_sff.id[0])<<3 |
1689                                          READ_REG(can, &regs->msg.rx_sff.id[1])>>5;
1690
1691                                while(tmp--){
1692                                        msg->data[tmp] = READ_REG(can, &regs->msg.rx_sff.data[tmp]);
1693                                }
1694                                /*
1695                                msg->data[0] = READ_REG(can, &regs->msg.rx_sff.data[0]);
1696                                msg->data[1] = READ_REG(can, &regs->msg.rx_sff.data[1]);
1697                                msg->data[2] = READ_REG(can, &regs->msg.rx_sff.data[2]);
1698                                msg->data[3] = READ_REG(can, &regs->msg.rx_sff.data[3]);
1699                                msg->data[4] = READ_REG(can, &regs->msg.rx_sff.data[4]);
1700                                msg->data[5] = READ_REG(can, &regs->msg.rx_sff.data[5]);
1701                                msg->data[6] = READ_REG(can, &regs->msg.rx_sff.data[6]);
1702                                msg->data[7] = READ_REG(can, &regs->msg.rx_sff.data[7]);
1703                                */
1704                        }
1705
1706                        /* Re-Enable RX buffer for a new message */
1707                        WRITE_REG(can, &regs->cmd, PELICAN_CMD_RELRXBUF);
1708
1709                        /* make message available to the user */
1710                        occan_fifo_put(can->rxfifo);
1711
1712                        /* bump stat counters */
1713                        can->stats.rx_msgs++;
1714
1715                        /* signal the semaphore only once */
1716                        signal_rx = 1;
1717                }
1718
1719                if ( iflags & PELICAN_IF_TX ) {
1720
1721                        /* there is room in tx fifo of HW */
1722
1723                        if ( !occan_fifo_empty(can->txfifo) ){
1724                                /* send 1 more messages */
1725                                msg = occan_fifo_claim_get(can->txfifo);
1726
1727                                if ( pelican_send(can,msg) ){
1728                                        /* ERROR! We got an TX interrupt telling us
1729                                         * tx fifo is empty, yet it is not.
1730                                         *
1731                                         * Complain about this max 10 times
1732                                         */
1733                                        if ( can->stats.tx_buf_error < 10 ){
1734                                                printk("OCCAN: got TX interrupt but TX fifo in not empty (%d)\n\r",can->stats.tx_buf_error);
1735                                        }
1736                                        can->status |= OCCAN_STATUS_QUEUE_ERROR;
1737                                        can->stats.tx_buf_error++;
1738                                }
1739#ifdef OCCAN_TX_IRQ_FLAG_FIXUP
1740                                can->sending = 1;
1741#endif
1742
1743                                /* free software-fifo space taken by sent message */
1744                                occan_fifo_get(can->txfifo);
1745
1746                                /* bump stat counters */
1747                                can->stats.tx_msgs++;
1748
1749                                /* wake any sleeping thread waiting for "fifo not full" */
1750                                signal_tx = 1;
1751                        }
1752                }
1753
1754                if ( iflags & PELICAN_IF_ERRW ){
1755                        tx_error_cnt = READ_REG(can, &regs->tx_err_cnt);
1756                        rx_error_cnt = READ_REG(can, &regs->rx_err_cnt);
1757
1758                        /* 1. if bus off tx error counter = 127 */
1759                        if ( (tx_error_cnt > 96) || (rx_error_cnt > 96) ){
1760                                /* in Error Active Warning area or BUS OFF */
1761                                can->status |= OCCAN_STATUS_WARN;
1762
1763                                /* check reset bit for reset mode */
1764                                if ( READ_REG(can, &regs->mode) & PELICAN_MOD_RESET ){
1765                                        /* in reset mode ==> bus off */
1766                                        can->status |= OCCAN_STATUS_ERR_BUSOFF | OCCAN_STATUS_RESET;
1767
1768                                        /***** pelican_stop(can) ******
1769                                         * turn off interrupts
1770                                         * enter reset mode (HW already done that for us)
1771                                         */
1772                                        WRITE_REG(can, &regs->inten,0);
1773
1774                                        /* Indicate that we are not started any more.
1775                                         * This will make write/read return with EBUSY
1776                                         * on read/write attempts.
1777                                         *
1778                                         * User must issue a ioctl(START) to get going again.
1779                                         */
1780                                        can->started = 0;
1781
1782                                        /* signal any waiting read/write threads, so that they
1783                                         * can handle the bus error.
1784                                         */
1785                                        signal_rx = 1;
1786                                        signal_tx = 1;
1787
1788                                        /* ingnore any old pending interrupt */
1789                                        break;
1790                                }
1791
1792                        }else{
1793                                /* not in Upper Error Active area any more */
1794                                can->status &= ~(OCCAN_STATUS_WARN);
1795                        }
1796                        can->stats.err_warn++;
1797                }
1798
1799                if ( iflags & PELICAN_IF_DOVR){
1800                        can->status |= OCCAN_STATUS_OVERRUN;
1801                        can->stats.err_dovr++;
1802                        DBG("OCCAN_INT: DOVR\n\r");
1803                }
1804
1805                if ( iflags & PELICAN_IF_ERRP){
1806                        /* Let the error counters decide what kind of
1807                         * interrupt it was. In/Out of EPassive area.
1808                         */
1809                        tx_error_cnt = READ_REG(can, &regs->tx_err_cnt);
1810                        rx_error_cnt = READ_REG(can, &regs->rx_err_cnt);
1811
1812                        if ( (tx_error_cnt > 127) || (rx_error_cnt > 127) ){
1813                                can->status |= OCCAN_STATUS_ERR_PASSIVE;
1814                        }else{
1815                                can->status &= ~(OCCAN_STATUS_ERR_PASSIVE);
1816                        }
1817
1818                        /* increase Error Passive In/out interrupt counter */
1819                        can->stats.err_errp++;
1820                }
1821
1822                if ( iflags & PELICAN_IF_ARB){
1823                        arbcode = READ_REG(can, &regs->arbcode);
1824                        can->stats.err_arb_bitnum[arbcode & PELICAN_ARB_BITS]++;
1825                        can->stats.err_arb++;
1826                        DBG("OCCAN_INT: ARB (0x%x)\n\r",arbcode & PELICAN_ARB_BITS);
1827                }
1828
1829                if ( iflags & PELICAN_IF_BUS){
1830                        /* Some kind of BUS error, only used for
1831                         * statistics. Error Register is decoded
1832                         * and put into can->stats.
1833                         */
1834                        errcode = READ_REG(can, &regs->errcode);
1835                        switch( errcode & PELICAN_ECC_CODE ){
1836                                case PELICAN_ECC_CODE_BIT:
1837                                        can->stats.err_bus_bit++;
1838                                        break;
1839                                case PELICAN_ECC_CODE_FORM:
1840                                        can->stats.err_bus_form++;
1841                                        break;
1842                                case PELICAN_ECC_CODE_STUFF:
1843                                        can->stats.err_bus_stuff++;
1844                                        break;
1845                                case PELICAN_ECC_CODE_OTHER:
1846                                        can->stats.err_bus_other++;
1847                                        break;
1848                        }
1849
1850                        /* Get Direction (TX/RX) */
1851                        if ( errcode & PELICAN_ECC_DIR ){
1852                                can->stats.err_bus_rx++;
1853                        }else{
1854                                can->stats.err_bus_tx++;
1855                        }
1856
1857                        /* Get Segment in frame that went wrong */
1858                        can->stats.err_bus_segs[errcode & PELICAN_ECC_SEG]++;
1859
1860                        /* total number of bus errors */
1861                        can->stats.err_bus++;
1862                }
1863        }
1864        SPIN_UNLOCK(&can->devlock, irqflags);
1865
1866        /* signal Binary semaphore, messages available! */
1867        if ( signal_rx ){
1868                rtems_semaphore_release(can->rxsem);
1869        }
1870
1871        if ( signal_tx ){
1872                rtems_semaphore_release(can->txsem);
1873        }
1874}
1875
1876/*******************************************************************************
1877 * FIFO IMPLEMENTATION
1878 */
1879
1880static occan_fifo *occan_fifo_create(int cnt)
1881{
1882        occan_fifo *fifo;
1883        fifo = grlib_calloc(1, sizeof(*fifo)+cnt*sizeof(CANMsg));
1884        if ( fifo ){
1885                fifo->cnt = cnt;
1886                fifo->base = &fifo->fifoarea[0];
1887                fifo->tail = fifo->head = fifo->base;
1888        }
1889        return fifo;
1890}
1891
1892static void occan_fifo_free(occan_fifo *fifo)
1893{
1894        if ( fifo )
1895                free(fifo);
1896}
1897
1898static int occan_fifo_full(occan_fifo *fifo)
1899{
1900        return fifo->full;
1901}
1902
1903static int occan_fifo_empty(occan_fifo *fifo)
1904{
1905        return (!fifo->full) && (fifo->head == fifo->tail);
1906}
1907
1908/* Stage 1 - get buffer to fill (never fails if force!=0) */
1909static CANMsg *occan_fifo_put_claim(occan_fifo *fifo, int force)
1910{
1911        if ( !fifo )
1912                return NULL;
1913
1914        if ( occan_fifo_full(fifo) ){
1915
1916                if ( !force )
1917                        return NULL;
1918
1919                /* all buffers already used ==> overwrite the oldest */
1920                fifo->ovcnt++;
1921                occan_fifo_get(fifo);
1922        }
1923
1924        return fifo->head;
1925}
1926
1927/* Stage 2 - increment indexes */
1928static void occan_fifo_put(occan_fifo *fifo)
1929{
1930        if ( occan_fifo_full(fifo) )
1931                return;
1932
1933        /* wrap around */
1934        fifo->head = (fifo->head >= &fifo->base[fifo->cnt-1])? fifo->base : fifo->head+1;
1935
1936        if ( fifo->head == fifo->tail )
1937                fifo->full = 1;
1938}
1939
1940static CANMsg *occan_fifo_claim_get(occan_fifo *fifo)
1941{
1942        if ( occan_fifo_empty(fifo) )
1943                return NULL;
1944
1945        /* return oldest message */
1946        return fifo->tail;
1947}
1948
1949
1950static void occan_fifo_get(occan_fifo *fifo)
1951{
1952        if ( !fifo )
1953                return;
1954
1955        if ( occan_fifo_empty(fifo) )
1956                return;
1957
1958        /* increment indexes */
1959        fifo->tail = (fifo->tail >= &fifo->base[fifo->cnt-1]) ?
1960                     fifo->base : fifo->tail+1;
1961        fifo->full = 0;
1962}
1963
1964static void occan_fifo_clr(occan_fifo *fifo)
1965{
1966        fifo->full  = 0;
1967        fifo->ovcnt = 0;
1968        fifo->head  = fifo->tail = fifo->base;
1969}
1970
1971/******************************************************************************/
Note: See TracBrowser for help on using the repository browser.