source: rtems/c/src/lib/libbsp/sparc/shared/can/grcan.c @ ad203e58

5
Last change on this file since ad203e58 was ad203e58, checked in by Martin Aberg <maberg@…>, on Jan 24, 2017 at 9:00:07 AM

leon, grcan: function based user interface

This commit preserves all driver services, using a function based user
interface instead of the I/O interface.

The messages count parameter is now number of CAN messages instead of
number of bytes.

  • Property mode set to 100644
File size: 40.5 KB
Line 
1/*
2 *  GRCAN driver
3 *
4 *  COPYRIGHT (c) 2007.
5 *  Cobham Gaisler AB.
6 *
7 *  The license and distribution terms for this file may be
8 *  found in the file LICENSE in this distribution or at
9 *  http://www.rtems.org/license/LICENSE.
10 */
11
12#include <bsp.h>
13#include <stdlib.h>
14#include <stdio.h>
15#include <string.h>
16#include <assert.h>
17#include <ctype.h>
18#include <rtems/bspIo.h>
19
20#include <bsp/grcan.h>
21#include <drvmgr/drvmgr.h>
22#include <drvmgr/ambapp_bus.h>
23#include <ambapp.h>
24
25/* Maximum number of GRCAN devices supported by driver */
26#define GRCAN_COUNT_MAX 8
27
28#define WRAP_AROUND_TX_MSGS 1
29#define WRAP_AROUND_RX_MSGS 2
30#define GRCAN_MSG_SIZE sizeof(struct grcan_msg)
31#define BLOCK_SIZE (16*4)
32
33/* grcan needs to have it buffers aligned to 1k boundaries */
34#define BUFFER_ALIGNMENT_NEEDS 1024
35
36/* Default Maximium buffer size for statically allocated buffers */
37#ifndef TX_BUF_SIZE
38 #define TX_BUF_SIZE (BLOCK_SIZE*16)
39#endif
40
41/* Make receiver buffers bigger than transmitt */
42#ifndef RX_BUF_SIZE
43 #define RX_BUF_SIZE ((3*BLOCK_SIZE)*16)
44#endif
45
46#ifndef IRQ_GLOBAL_PREPARE
47 #define IRQ_GLOBAL_PREPARE(level) rtems_interrupt_level level
48#endif
49
50#ifndef IRQ_GLOBAL_DISABLE
51 #define IRQ_GLOBAL_DISABLE(level) rtems_interrupt_disable(level)
52#endif
53
54#ifndef IRQ_GLOBAL_ENABLE
55 #define IRQ_GLOBAL_ENABLE(level) rtems_interrupt_enable(level)
56#endif
57
58#ifndef IRQ_CLEAR_PENDING
59 #define IRQ_CLEAR_PENDING(irqno)
60#endif
61
62#ifndef IRQ_UNMASK
63 #define IRQ_UNMASK(irqno)
64#endif
65
66#ifndef IRQ_MASK
67 #define IRQ_MASK(irqno)
68#endif
69
70#ifndef GRCAN_DEFAULT_BAUD
71 /* default to 500kbits/s */
72 #define GRCAN_DEFAULT_BAUD 500000
73#endif
74
75#ifndef GRCAN_SAMPLING_POINT
76 #define GRCAN_SAMPLING_POINT 80
77#endif
78
79/* Uncomment for debug output */
80/****************** DEBUG Definitions ********************/
81#define DBG_IOCTRL 1
82#define DBG_TX 2
83#define DBG_RX 4
84
85#define DEBUG_FLAGS (DBG_IOCTRL | DBG_RX | DBG_TX )
86/*
87#define DEBUG
88#define DEBUGFUNCS
89*/
90#include <bsp/debug_defs.h>
91
92/*********************************************************/
93
94struct grcan_msg {
95        unsigned int head[2];
96        unsigned char data[8];
97};
98
99struct grcan_config {
100        struct grcan_timing timing;
101        struct grcan_selection selection;
102        int abort;
103        int silent;
104};
105
106struct grcan_priv {
107        struct drvmgr_dev *dev; /* Driver manager device */
108        char devName[32];       /* Device Name */
109        unsigned int baseaddr, ram_base;
110        struct grcan_regs *regs;
111        int irq;
112        int minor;
113        int open;
114        int started;
115        unsigned int channel;
116        int flushing;
117        unsigned int corefreq_hz;
118
119        /* Circular DMA buffers */
120        void *_rx, *_rx_hw;
121        void *_tx, *_tx_hw;
122        void *txbuf_adr;
123        void *rxbuf_adr;
124        struct grcan_msg *rx;
125        struct grcan_msg *tx;
126        unsigned int rxbuf_size;    /* requested RX buf size in bytes */
127        unsigned int txbuf_size;    /* requested TX buf size in bytes */
128
129        int txblock, rxblock;
130        int txcomplete, rxcomplete;
131        int txerror, rxerror;
132
133        struct grcan_filter sfilter;
134        struct grcan_filter afilter;
135        int config_changed; /* 0=no changes, 1=changes ==> a Core reset is needed */
136        struct grcan_config config;
137        struct grcan_stats stats;
138
139        rtems_id rx_sem, tx_sem, txempty_sem, dev_sem;
140};
141
142static void __inline__ grcan_hw_reset(struct grcan_regs *regs);
143
144static unsigned int grcan_hw_read_try(
145  struct grcan_priv *pDev,
146  struct grcan_regs *regs,
147  CANMsg *buffer,
148  int max);
149
150static unsigned int grcan_hw_write_try(
151  struct grcan_priv *pDev,
152  struct grcan_regs *regs,
153  CANMsg *buffer,
154  int count);
155
156static void grcan_hw_config(
157  struct grcan_regs *regs,
158  struct grcan_config *conf);
159
160static void grcan_hw_accept(
161  struct grcan_regs *regs,
162  struct grcan_filter *afilter);
163
164static void grcan_hw_sync(
165  struct grcan_regs *regs,
166  struct grcan_filter *sfilter);
167
168static void grcan_interrupt(void *arg);
169
170#ifdef GRCAN_REG_BYPASS_CACHE
171#define READ_REG(address) _grcan_read_nocache((unsigned int)(address))
172#else
173#define READ_REG(address) (*(volatile unsigned int *)(address))
174#endif
175
176#ifdef GRCAN_DMA_BYPASS_CACHE
177#define READ_DMA_WORD(address) _grcan_read_nocache((unsigned int)(address))
178#define READ_DMA_BYTE(address) _grcan_read_nocache_byte((unsigned int)(address))
179static unsigned char __inline__ _grcan_read_nocache_byte(unsigned int address)
180{
181        unsigned char tmp;
182        __asm__ (" lduba [%1]1, %0 "
183            : "=r"(tmp)
184            : "r"(address)
185        );
186        return tmp;
187}
188#else
189#define READ_DMA_WORD(address) (*(volatile unsigned int *)(address))
190#define READ_DMA_BYTE(address) (*(volatile unsigned char *)(address))
191#endif
192
193#if defined(GRCAN_REG_BYPASS_CACHE) || defined(GRCAN_DMA_BYPASS_CACHE)
194static unsigned int __inline__ _grcan_read_nocache(unsigned int address)
195{
196        unsigned int tmp;
197        __asm__ (" lda [%1]1, %0 "
198                : "=r"(tmp)
199                : "r"(address)
200        );
201        return tmp;
202}
203#endif
204
205static int grcan_count = 0;
206static struct grcan_priv *priv_tab[GRCAN_COUNT_MAX];
207
208/******************* Driver manager interface ***********************/
209
210/* Driver prototypes */
211int grcan_device_init(struct grcan_priv *pDev);
212
213int grcan_init2(struct drvmgr_dev *dev);
214int grcan_init3(struct drvmgr_dev *dev);
215
216struct drvmgr_drv_ops grcan_ops = 
217{
218        .init = {NULL, grcan_init2, grcan_init3, NULL},
219        .remove = NULL,
220        .info = NULL
221};
222
223struct amba_dev_id grcan_ids[] = 
224{
225        {VENDOR_GAISLER, GAISLER_GRCAN},
226        {VENDOR_GAISLER, GAISLER_GRHCAN},
227        {0, 0}          /* Mark end of table */
228};
229
230struct amba_drv_info grcan_drv_info =
231{
232        {
233                DRVMGR_OBJ_DRV,                 /* Driver */
234                NULL,                           /* Next driver */
235                NULL,                           /* Device list */
236                DRIVER_AMBAPP_GAISLER_GRCAN_ID, /* Driver ID */
237                "GRCAN_DRV",                    /* Driver Name */
238                DRVMGR_BUS_TYPE_AMBAPP,         /* Bus Type */
239                &grcan_ops,
240                NULL,                           /* Funcs */
241                0,                              /* No devices yet */
242                0,
243        },
244        &grcan_ids[0]
245};
246
247void grcan_register_drv (void)
248{
249        DBG("Registering GRCAN driver\n");
250        drvmgr_drv_register(&grcan_drv_info.general);
251}
252
253int grcan_init2(struct drvmgr_dev *dev)
254{
255        struct grcan_priv *priv;
256
257        DBG("GRCAN[%d] on bus %s\n", dev->minor_drv, dev->parent->dev->name);
258        if (GRCAN_COUNT_MAX <= grcan_count)
259                return DRVMGR_ENORES;
260        priv = dev->priv = malloc(sizeof(struct grcan_priv));
261        if ( !priv )
262                return DRVMGR_NOMEM;
263        memset(priv, 0, sizeof(*priv));
264        priv->dev = dev;
265
266        /* This core will not find other cores, so we wait for init2() */
267
268        return DRVMGR_OK;
269}
270
271int grcan_init3(struct drvmgr_dev *dev)
272{
273        struct grcan_priv *priv;
274        char prefix[32];
275
276        priv = dev->priv;
277
278        /*
279         * Now we take care of device initialization.
280         */
281
282        if ( grcan_device_init(priv) ) {
283                return DRVMGR_FAIL;
284        }
285
286        priv_tab[grcan_count] = priv;
287        grcan_count++;
288
289        /* Get Filesystem name prefix */
290        prefix[0] = '\0';
291        if ( drvmgr_get_dev_prefix(dev, prefix) ) {
292                /* Failed to get prefix, make sure of a unique FS name
293                 * by using the driver minor.
294                 */
295                sprintf(priv->devName, "/dev/grcan%d", dev->minor_drv);
296        } else {
297                /* Got special prefix, this means we have a bus prefix
298                 * And we should use our "bus minor"
299                 */
300                sprintf(priv->devName, "/dev/%sgrcan%d", prefix, dev->minor_bus);
301        }
302
303        return DRVMGR_OK;
304}
305
306int grcan_device_init(struct grcan_priv *pDev)
307{
308        struct amba_dev_info *ambadev;
309        struct ambapp_core *pnpinfo;
310
311        /* Get device information from AMBA PnP information */
312        ambadev = (struct amba_dev_info *)pDev->dev->businfo;
313        if ( ambadev == NULL ) {
314                return -1;
315        }
316        pnpinfo = &ambadev->info;
317        pDev->irq = pnpinfo->irq;
318        pDev->regs = (struct grcan_regs *)pnpinfo->apb_slv->start;
319        pDev->minor = pDev->dev->minor_drv;
320
321        /* Get frequency in Hz */
322        if ( drvmgr_freq_get(pDev->dev, DEV_APB_SLV, &pDev->corefreq_hz) ) {
323                return -1;
324        }
325
326        DBG("GRCAN frequency: %d Hz\n", pDev->corefreq_hz);
327
328        /* Reset Hardware before attaching IRQ handler */
329        grcan_hw_reset(pDev->regs);
330
331        /* RX Semaphore created with count = 0 */
332        if ( rtems_semaphore_create(rtems_build_name('G', 'C', 'R', '0' + pDev->minor),
333                0,
334                RTEMS_FIFO|RTEMS_SIMPLE_BINARY_SEMAPHORE|RTEMS_NO_INHERIT_PRIORITY|\
335                RTEMS_LOCAL|RTEMS_NO_PRIORITY_CEILING, 
336                0,
337                &pDev->rx_sem) != RTEMS_SUCCESSFUL ) {
338                return RTEMS_INTERNAL_ERROR;
339        }
340
341        /* TX Semaphore created with count = 0 */
342        if ( rtems_semaphore_create(rtems_build_name('G', 'C', 'T', '0' + pDev->minor),
343                0,
344                RTEMS_FIFO|RTEMS_SIMPLE_BINARY_SEMAPHORE|RTEMS_NO_INHERIT_PRIORITY|\
345                RTEMS_LOCAL|RTEMS_NO_PRIORITY_CEILING, 
346                0,
347                &pDev->tx_sem) != RTEMS_SUCCESSFUL ) {
348                return RTEMS_INTERNAL_ERROR;
349        }
350
351        /* TX Empty Semaphore created with count = 0 */
352        if ( rtems_semaphore_create(rtems_build_name('G', 'C', 'E', '0' + pDev->minor),
353                0,
354                RTEMS_FIFO|RTEMS_SIMPLE_BINARY_SEMAPHORE|RTEMS_NO_INHERIT_PRIORITY|\
355                RTEMS_LOCAL|RTEMS_NO_PRIORITY_CEILING, 
356                0,
357                &pDev->txempty_sem) != RTEMS_SUCCESSFUL ) {
358                return RTEMS_INTERNAL_ERROR;
359        }
360
361        /* Device Semaphore created with count = 1 */
362        if ( rtems_semaphore_create(rtems_build_name('G', 'C', 'A', '0' + pDev->minor),
363                1,
364                RTEMS_FIFO|RTEMS_SIMPLE_BINARY_SEMAPHORE|RTEMS_NO_INHERIT_PRIORITY|\
365                RTEMS_LOCAL|RTEMS_NO_PRIORITY_CEILING,
366                0,
367                &pDev->dev_sem) != RTEMS_SUCCESSFUL ) {
368                return RTEMS_INTERNAL_ERROR;
369        }
370
371        return 0;
372}
373
374static void __inline__ grcan_hw_reset(struct grcan_regs *regs)
375{
376        regs->ctrl = GRCAN_CTRL_RESET;
377}
378
379static rtems_device_driver grcan_hw_start(struct grcan_priv *pDev)
380{
381  /*
382   * tmp is set but never used. GCC gives a warning for this
383   * and we need to tell GCC not to complain.
384   */
385  unsigned int tmp RTEMS_UNUSED;
386
387  IRQ_GLOBAL_PREPARE(oldLevel);
388
389  FUNCDBG();
390
391  /* Check that memory has been allocated successfully */
392  if ( !pDev->tx || !pDev->rx )
393    return RTEMS_NO_MEMORY;
394
395  /* Configure FIFO configuration register
396   * and Setup timing
397   */
398  if ( pDev->config_changed ){
399    grcan_hw_config(pDev->regs,&pDev->config);
400    pDev->config_changed = 0;
401  }
402
403  /* Setup receiver */
404  pDev->regs->rx0addr = (unsigned int)pDev->_rx_hw;
405  pDev->regs->rx0size = pDev->rxbuf_size;
406
407  /* Setup Transmitter */
408  pDev->regs->tx0addr = (unsigned int)pDev->_tx_hw;
409  pDev->regs->tx0size = pDev->txbuf_size;
410
411  /* Setup acceptance filters */
412  grcan_hw_accept(pDev->regs,&pDev->afilter);
413
414  /* Sync filters */
415  grcan_hw_sync(pDev->regs,&pDev->sfilter);
416
417  /* Clear status bits */
418  tmp = READ_REG(&pDev->regs->stat);
419  pDev->regs->stat = 0;
420
421  /* Setup IRQ handling */
422
423  /* Clear all IRQs */
424  tmp = READ_REG(&pDev->regs->pir);
425  pDev->regs->picr = 0x1ffff;
426
427  /* unmask TxLoss|TxErrCntr|RxErrCntr|TxAHBErr|RxAHBErr|OR|OFF|PASS */
428  pDev->regs->imr = 0x1601f;
429
430  /* Enable routing of the IRQs */
431  IRQ_GLOBAL_DISABLE(oldLevel);
432  IRQ_UNMASK(pDev->irq+GRCAN_IRQ_TXSYNC);
433  IRQ_UNMASK(pDev->irq+GRCAN_IRQ_RXSYNC);
434  IRQ_UNMASK(pDev->irq+GRCAN_IRQ_IRQ);
435  IRQ_GLOBAL_ENABLE(oldLevel);
436
437  /* Reset some software data */
438  /*pDev->txerror = 0;
439  pDev->rxerror = 0;*/
440
441  /* Enable receiver/transmitter */
442  pDev->regs->rx0ctrl = GRCAN_RXCTRL_ENABLE;
443  pDev->regs->tx0ctrl = GRCAN_TXCTRL_ENABLE;
444
445  /* Enable HurriCANe core */
446  pDev->regs->ctrl = GRCAN_CTRL_ENABLE;
447
448  /* Leave transmitter disabled, it is enabled when
449   * trying to send something.
450   */
451  return RTEMS_SUCCESSFUL;
452}
453
454static void grcan_hw_stop(struct grcan_priv *pDev)
455{
456  FUNCDBG();
457
458  /* Mask all IRQs */
459  pDev->regs->imr = 0;
460  IRQ_MASK(pDev->irq+GRCAN_IRQ_TXSYNC);
461  IRQ_MASK(pDev->irq+GRCAN_IRQ_RXSYNC);
462  IRQ_MASK(pDev->irq+GRCAN_IRQ_IRQ);
463
464  /* Disable receiver & transmitter */
465  pDev->regs->rx0ctrl = 0;
466  pDev->regs->tx0ctrl = 0;
467
468  /* Reset semaphores to the initial state and wakeing
469   * all threads waiting for an IRQ. The threads that
470   * get woken up must check for RTEMS_UNSATISFIED in
471   * order to determine that they should return to
472   * user space with error status.
473   */
474  rtems_semaphore_flush(pDev->rx_sem);
475  rtems_semaphore_flush(pDev->tx_sem);
476  rtems_semaphore_flush(pDev->txempty_sem);
477}
478
479static void grcan_hw_config(
480  struct grcan_regs *regs,
481  struct grcan_config *conf
482  )
483{
484  unsigned int config=0;
485
486  /* Reset HurriCANe Core */
487  regs->ctrl = 0;
488
489  if ( conf->silent )
490    config |= GRCAN_CFG_SILENT;
491
492  if ( conf->abort )
493    config |= GRCAN_CFG_ABORT;
494
495  if ( conf->selection.selection )
496    config |= GRCAN_CFG_SELECTION;
497
498  if ( conf->selection.enable0 )
499    config |= GRCAN_CFG_ENABLE0;
500
501  if ( conf->selection.enable1 )
502    config |= GRCAN_CFG_ENABLE1;
503
504  /* Timing */
505  config |= (conf->timing.bpr<<GRCAN_CFG_BPR_BIT) & GRCAN_CFG_BPR;
506  config |= (conf->timing.rsj<<GRCAN_CFG_RSJ_BIT) & GRCAN_CFG_RSJ;
507  config |= (conf->timing.ps1<<GRCAN_CFG_PS1_BIT) & GRCAN_CFG_PS1;
508  config |= (conf->timing.ps2<<GRCAN_CFG_PS2_BIT) & GRCAN_CFG_PS2;
509  config |= (conf->timing.scaler<<GRCAN_CFG_SCALER_BIT) & GRCAN_CFG_SCALER;
510
511  /* Write configuration */
512  regs->conf = config;
513
514  /* Enable HurriCANe Core */
515  regs->ctrl = GRCAN_CTRL_ENABLE;
516}
517
518static void grcan_hw_accept(
519  struct grcan_regs *regs,
520  struct grcan_filter *afilter
521  )
522{
523  /* Disable Sync mask totaly (if we change scode or smask
524   * in an unfortunate way we may trigger a sync match)
525   */
526  regs->rx0mask = 0xffffffff;
527
528  /* Set Sync Filter in a controlled way */
529  regs->rx0code = afilter->code;
530  regs->rx0mask = afilter->mask;
531}
532
533static void grcan_hw_sync(
534  struct grcan_regs *regs,
535  struct grcan_filter *sfilter
536  )
537{
538  /* Disable Sync mask totaly (if we change scode or smask
539   * in an unfortunate way we may trigger a sync match)
540   */
541  regs->smask = 0xffffffff;
542
543  /* Set Sync Filter in a controlled way */
544  regs->scode = sfilter->code;
545  regs->smask = sfilter->mask;
546}
547
548static unsigned int grcan_hw_rxavail(
549  unsigned int rp,
550  unsigned int wp,
551  unsigned int size
552  )
553{
554  if ( rp == wp ) {
555    /* read pointer and write pointer is equal only
556     * when RX buffer is empty.
557     */
558    return 0;
559  }
560
561  if ( wp > rp ) {
562    return (wp-rp)/GRCAN_MSG_SIZE;
563  }else{
564    return (size-(rp-wp))/GRCAN_MSG_SIZE;
565  }
566}
567
568static unsigned int grcan_hw_txspace(
569  unsigned int rp,
570  unsigned int wp,
571  unsigned int size
572  )
573{
574  unsigned int left;
575
576  if ( rp == wp ) {
577    /* read pointer and write pointer is equal only
578     * when TX buffer is empty.
579     */
580    return size/GRCAN_MSG_SIZE-WRAP_AROUND_TX_MSGS;
581  }
582
583  /* size - 4 - abs(read-write) */
584  if ( wp > rp ) {
585    left = size-(wp-rp);
586  }else{
587    left = rp-wp;
588  }
589
590  return left/GRCAN_MSG_SIZE-WRAP_AROUND_TX_MSGS;
591}
592
593static int grcan_hw_rx_ongoing(struct grcan_regs *regs)
594{
595  return READ_REG(&regs->rx0ctrl) & GRCAN_RXCTRL_ONGOING;
596};
597
598static int grcan_hw_tx_ongoing(struct grcan_regs *regs)
599{
600  return READ_REG(&regs->tx0ctrl) & GRCAN_TXCTRL_ONGOING;
601};
602
603
604#define MIN_TSEG1 1
605#define MIN_TSEG2 2
606#define MAX_TSEG1 14
607#define MAX_TSEG2 8
608
609static int grcan_calc_timing(
610  unsigned int baud,          /* The requested BAUD to calculate timing for */
611  unsigned int core_hz,       /* Frequency in Hz of GRCAN Core */
612  unsigned int sampl_pt,
613  struct grcan_timing *timing /* result is placed here */
614  )
615{
616        int best_error = 1000000000;
617        int error;
618        int best_tseg=0, best_brp=0, brp=0;
619        int tseg=0, tseg1=0, tseg2=0;
620        int sjw = 1;
621
622  /* Default to 90% */
623  if ( (sampl_pt < 50) || (sampl_pt>99) ){
624    sampl_pt = GRCAN_SAMPLING_POINT;
625  }
626
627        if ( (baud<5000) || (baud>1000000) ){
628                /* invalid speed mode */
629                return -1;
630        }
631
632        /* find best match, return -2 if no good reg
633         * combination is available for this frequency
634   */
635
636        /* some heuristic specials */
637        if (baud > ((1000000 + 500000) / 2))
638                sampl_pt = 75;
639
640        if (baud < ((12500 + 10000) / 2))
641                sampl_pt = 75;
642
643        /* tseg even = round down, odd = round up */
644        for (tseg = (MIN_TSEG1 + MIN_TSEG2 + 2) * 2;
645             tseg <= (MAX_TSEG2 + MAX_TSEG1 + 2) * 2 + 1;
646             tseg++)
647        {
648                brp = core_hz / ((1 + tseg / 2) * baud) + tseg % 2;
649                if ((brp <= 0) ||
650        ( (brp > 256*1) && (brp <= 256*2) && (brp&0x1) ) ||
651        ( (brp > 256*2) && (brp <= 256*4) && (brp&0x3) ) ||
652        ( (brp > 256*4) && (brp <= 256*8) && (brp&0x7) ) ||
653        (brp > 256*8)
654        )
655                        continue;
656
657                error = baud - core_hz / (brp * (1 + tseg / 2));
658                if (error < 0)
659                {
660                        error = -error;
661                }
662
663                if (error <= best_error)
664                {
665                        best_error = error;
666                        best_tseg = tseg/2;
667                        best_brp = brp-1;
668                }
669        }
670
671        if (best_error && (baud / best_error < 10))
672        {
673                return -2;
674        }else if ( !timing )
675                return 0; /* nothing to store result in, but a valid bitrate can be calculated */
676
677        tseg2 = best_tseg - (sampl_pt * (best_tseg + 1)) / 100;
678
679        if (tseg2 < MIN_TSEG2)
680        {
681                tseg2 = MIN_TSEG2;
682        }
683
684        if (tseg2 > MAX_TSEG2)
685        {
686                tseg2 = MAX_TSEG2;
687        }
688
689        tseg1 = best_tseg - tseg2 - 2;
690
691        if (tseg1 > MAX_TSEG1)
692        {
693                tseg1 = MAX_TSEG1;
694                tseg2 = best_tseg - tseg1 - 2;
695        }
696
697  /* Get scaler and BRP from pseudo BRP */
698  if ( best_brp <= 256 ){
699    timing->scaler = best_brp;
700    timing->bpr = 0;
701  }else if ( best_brp <= 256*2 ){
702    timing->scaler = ((best_brp+1)>>1) -1;
703    timing->bpr = 1;
704  }else if ( best_brp <= 256*4 ){
705    timing->scaler = ((best_brp+1)>>2) -1;
706    timing->bpr = 2;
707  }else{
708    timing->scaler = ((best_brp+1)>>3) -1;
709    timing->bpr = 3;
710  }
711
712        timing->ps1    = tseg1+1;
713        timing->ps2    = tseg2;
714        timing->rsj    = sjw;
715
716        return 0;
717}
718
719static unsigned int grcan_hw_read_try(
720  struct grcan_priv *pDev,
721  struct grcan_regs *regs,
722  CANMsg *buffer,
723  int max
724  )
725{
726  int i,j;
727  CANMsg *dest;
728  struct grcan_msg *source,tmp;
729  unsigned int wp,rp,size,rxmax,addr,trunk_msg_cnt;
730
731  FUNCDBG();
732
733  wp = READ_REG(&regs->rx0wr);
734  rp = READ_REG(&regs->rx0rd);
735
736  /*
737   * Due to hardware wrap around simplification write pointer will
738   * never reach the read pointer, at least a gap of 8 bytes.
739   * The only time they are equal is when the read pointer has
740   * reached the write pointer (empty buffer)
741   *
742   */
743  if ( wp != rp ){
744    /* Not empty, we have received chars...
745     * Read as much as possible from DMA buffer
746     */
747    size = READ_REG(&regs->rx0size);
748
749    /* Get number of bytes available in RX buffer */
750    trunk_msg_cnt = grcan_hw_rxavail(rp,wp,size);
751
752    /* truncate size if user space buffer hasn't room for
753     * all received chars.
754     */
755    if ( trunk_msg_cnt > max )
756      trunk_msg_cnt = max;
757
758    /* Read until i is 0 */
759    i=trunk_msg_cnt;
760
761    addr = (unsigned int)pDev->rx;
762    source = (struct grcan_msg *)(addr + rp);
763    dest = buffer;
764    rxmax = addr + (size-GRCAN_MSG_SIZE);
765
766    /* Read as many can messages as possible */
767    while(i>0){
768      /* Read CAN message from DMA buffer */
769      tmp.head[0] = READ_DMA_WORD(&source->head[0]);
770      tmp.head[1] = READ_DMA_WORD(&source->head[1]);
771      /* Convert one grcan CAN message to one "software" CAN message */
772      dest->extended = tmp.head[0]>>31;
773      dest->rtr = (tmp.head[0] >>30) & 0x1;
774      if ( dest->extended ){
775        dest->id = tmp.head[0] & 0x3fffffff;
776      }else{
777        dest->id = (tmp.head[0] >>18) & 0xfff;
778      }
779      dest->len = tmp.head[1] >> 28;
780      for(j=0; j<dest->len; j++)
781        dest->data[j] = READ_DMA_BYTE(&source->data[j]);
782
783      /* wrap around if neccessary */
784      source = ( (unsigned int)source >= rxmax ) ? (struct grcan_msg *)addr : source+1;
785      dest++; /* straight user buffer */
786      i--;
787    }
788    /* Increment Hardware READ pointer (mark read byte as read)
789     * ! wait for registers to be safely re-configurable
790     */
791    regs->rx0ctrl = 0; /* DISABLE RX CHANNEL */
792    i=0;
793    while( grcan_hw_rx_ongoing(regs) && (i<1000) ){
794      i++;
795    }
796    regs->rx0rd = (unsigned int)source-addr;
797    regs->rx0ctrl = GRCAN_RXCTRL_ENABLE; /* ENABLE_RX_CHANNEL */
798    return trunk_msg_cnt;
799  }
800  return 0;
801}
802
803static unsigned int grcan_hw_write_try(
804  struct grcan_priv *pDev,
805  struct grcan_regs *regs,
806  CANMsg *buffer,
807  int count
808  )
809{
810  unsigned int rp, wp, size, txmax, addr, ret;
811  struct grcan_msg *dest;
812  CANMsg *source;
813  int space_left;
814  unsigned int tmp;
815  int i;
816
817  DBGC(DBG_TX,"\n");
818  /*FUNCDBG();*/
819
820  rp = READ_REG(&regs->tx0rd);
821  wp = READ_REG(&regs->tx0wr);
822  size = READ_REG(&regs->tx0size);
823
824  space_left = grcan_hw_txspace(rp,wp,size);
825
826  /* is circular fifo full? */
827  if ( space_left < 1 )
828    return 0;
829
830  /* Truncate size */
831  if ( space_left > count )
832    space_left = count;
833  ret = space_left;
834
835  addr = (unsigned int)pDev->tx;
836
837  dest = (struct grcan_msg *)(addr + wp);
838  source = (CANMsg *)buffer;
839  txmax = addr + (size-GRCAN_MSG_SIZE);
840
841  while ( space_left>0 ) {
842    /* Convert and write CAN message to DMA buffer */
843    if ( source->extended ){
844      tmp = (1<<31) | (source->id & 0x3fffffff);
845    }else{
846      tmp = (source->id&0xfff)<<18;
847    }
848    if ( source->rtr )
849      tmp|=(1<<30);
850    dest->head[0] = tmp;
851    dest->head[1] = source->len<<28;
852    for ( i=0; i<source->len; i++)
853      dest->data[i] = source->data[i];
854    source++; /* straight user buffer */
855    dest = ((unsigned int)dest >= txmax) ? (struct grcan_msg *)addr : dest+1;
856    space_left--;
857  }
858
859  /* Update write pointer
860   * ! wait for registers to be safely re-configurable
861   */
862  regs->tx0ctrl = 0; /* DISABLE TX CHANNEL */
863  i=0;
864  while( (grcan_hw_tx_ongoing(regs)) && i<1000 ){
865    i++;
866  }
867  regs->tx0wr = (unsigned int)dest - addr; /* Update write pointer */
868  regs->tx0ctrl = GRCAN_TXCTRL_ENABLE; /* ENABLE_TX_CHANNEL */
869  return ret;
870}
871
872static int grcan_wait_rxdata(
873  struct grcan_priv *pDev,
874  int min
875  )
876{
877  unsigned int wp, rp, size, irq;
878  unsigned int irq_trunk, dataavail;
879  int wait;
880  IRQ_GLOBAL_PREPARE(oldLevel);
881
882  FUNCDBG();
883
884  /*** block until receive IRQ received
885   * Set up a valid IRQ point so that an IRQ is received
886   * when one or more messages are received
887   */
888  IRQ_GLOBAL_DISABLE(oldLevel);
889
890  size = READ_REG(&pDev->regs->rx0size);
891  rp = READ_REG(&pDev->regs->rx0rd);
892  wp = READ_REG(&pDev->regs->rx0wr);
893
894  /**** Calculate IRQ Pointer ****/
895  irq = wp + min*GRCAN_MSG_SIZE;
896  /* wrap irq around */
897  if ( irq >= size ){
898    irq_trunk = irq-size;
899  }else
900    irq_trunk = irq;
901
902  /* init IRQ HW */
903  pDev->regs->rx0irq = irq_trunk;
904
905  /* Clear pending Rx IRQ */
906  pDev->regs->picr = GRCAN_RXIRQ_IRQ;
907
908  wp = READ_REG(&pDev->regs->rx0wr);
909
910  /* Calculate messages available */
911  dataavail = grcan_hw_rxavail(rp,wp,size);
912
913  if ( dataavail < min ){
914    /* Still empty, proceed with sleep - Turn on IRQ (unmask irq) */
915    pDev->regs->imr = READ_REG(&pDev->regs->imr) | GRCAN_RXIRQ_IRQ;
916    wait=1;
917  }else{
918    /* enough message has been received, abort sleep - don't unmask interrupt */
919    wait=0;
920  }
921  IRQ_GLOBAL_ENABLE(oldLevel);
922
923    /* Wait for IRQ to fire only if has been triggered */
924  if ( wait ){
925    if ( rtems_semaphore_obtain(pDev->rx_sem, RTEMS_WAIT, RTEMS_NO_TIMEOUT) == RTEMS_UNSATISFIED )
926      return -1; /* Device driver has been closed or stopped, return with error status */
927  }
928
929  return 0;
930}
931
932/* Wait until min bytes available in TX circular buffer.
933 * The IRQ RxIrq is used to pin point the location of
934 *
935 * min must be at least WRAP_AROUND_TX_BYTES bytes less
936 * than max buffer for this algo to work.
937 *
938 */
939static int grcan_wait_txspace(
940  struct grcan_priv *pDev,
941  int min
942  )
943{
944  int wait;
945  unsigned int irq, rp, wp, size, space_left;
946  unsigned int irq_trunk;
947  IRQ_GLOBAL_PREPARE(oldLevel);
948
949  DBGC(DBG_TX,"\n");
950  /*FUNCDBG();*/
951
952  IRQ_GLOBAL_DISABLE(oldLevel);
953
954  pDev->regs->tx0ctrl = GRCAN_TXCTRL_ENABLE;
955
956  size = READ_REG(&pDev->regs->tx0size);
957  wp = READ_REG(&pDev->regs->tx0wr);
958
959  rp = READ_REG(&pDev->regs->tx0rd);
960
961  /**** Calculate IRQ Pointer ****/
962  irq = rp + min*GRCAN_MSG_SIZE;
963  /* wrap irq around */
964  if ( irq >= size ){
965    irq_trunk = irq - size;
966  }else
967    irq_trunk = irq;
968
969  /* trigger HW to do a IRQ when enough room in buffer */
970  pDev->regs->tx0irq = irq_trunk;
971
972  /* Clear pending Tx IRQ */
973  pDev->regs->picr = GRCAN_TXIRQ_IRQ;
974
975  /* One problem, if HW already gone past IRQ place the IRQ will
976   * never be received resulting in a thread hang. We check if so
977   * before proceeding.
978   *
979   * has the HW already gone past the IRQ generation place?
980   *  == does min fit info tx buffer?
981   */
982  rp = READ_REG(&pDev->regs->tx0rd);
983
984  space_left = grcan_hw_txspace(rp,wp,size);
985
986  if ( space_left < min ){
987    /* Still too full, proceed with sleep - Turn on IRQ (unmask irq) */
988    pDev->regs->imr = READ_REG(&pDev->regs->imr) | GRCAN_TXIRQ_IRQ;
989    wait=1;
990  }else{
991    /* There are enough room in buffer, abort wait - don't unmask interrupt */
992    wait=0;
993  }
994  IRQ_GLOBAL_ENABLE(oldLevel);
995
996  /* Wait for IRQ to fire only if it has been triggered */
997  if ( wait ){
998    if ( rtems_semaphore_obtain(pDev->tx_sem, RTEMS_WAIT, 100) ==
999         RTEMS_UNSATISFIED ){
1000      /* Device driver has flushed us, this may be due to another thread has
1001       * closed the device, this is to avoid deadlock */
1002      return -1;
1003    }
1004  }
1005
1006  /* At this point the TxIRQ has been masked, we ned not to mask it */
1007  return 0;
1008}
1009
1010static int grcan_tx_flush(struct grcan_priv *pDev)
1011{
1012  int wait;
1013  unsigned int rp, wp;
1014  IRQ_GLOBAL_PREPARE(oldLevel);
1015  FUNCDBG();
1016
1017  /* loop until all data in circular buffer has been read by hw.
1018   * (write pointer != read pointer )
1019   *
1020   * Hardware doesn't update write pointer - we do
1021   */
1022  while ( (wp=READ_REG(&pDev->regs->tx0wr)) != (rp=READ_REG(&pDev->regs->tx0rd)) ) {
1023    /* Wait for TX empty IRQ */
1024    IRQ_GLOBAL_DISABLE(oldLevel);
1025    /* Clear pending TXEmpty IRQ */
1026    pDev->regs->picr = GRCAN_TXEMPTY_IRQ;
1027
1028    if ( wp != READ_REG(&pDev->regs->tx0rd) ) {
1029      /* Still not empty, proceed with sleep - Turn on IRQ (unmask irq) */
1030      pDev->regs->imr = READ_REG(&pDev->regs->imr) | GRCAN_TXEMPTY_IRQ;
1031      wait = 1;
1032    }else{
1033      /* TX fifo is empty */
1034      wait = 0;
1035    }
1036    IRQ_GLOBAL_ENABLE(oldLevel);
1037    if ( !wait )
1038      break;
1039
1040    /* Wait for IRQ to wake us */
1041    if ( rtems_semaphore_obtain(pDev->txempty_sem, RTEMS_WAIT, RTEMS_NO_TIMEOUT) ==
1042         RTEMS_UNSATISFIED ) {
1043      return -1;
1044    }
1045  }
1046  return 0;
1047}
1048
1049static int grcan_alloc_buffers(struct grcan_priv *pDev, int rx, int tx)
1050{
1051        unsigned int adr;
1052        FUNCDBG();
1053
1054        if ( tx ) {
1055                adr = (unsigned int)pDev->txbuf_adr;
1056                if (adr & 0x1) {
1057                        /* User defined "remote" address. Translate it into
1058                         * a CPU accessible address
1059                         */
1060                        pDev->_tx_hw = (void *)(adr & ~0x1);
1061                        drvmgr_translate_check(
1062                                pDev->dev,
1063                                DMAMEM_TO_CPU,
1064                                (void *)pDev->_tx_hw,
1065                                (void **)&pDev->_tx,
1066                                pDev->txbuf_size);
1067                        pDev->tx = (struct grcan_msg *)pDev->_tx;
1068                } else {
1069                        if (adr == 0) {
1070                                pDev->_tx = malloc(pDev->txbuf_size +
1071                                                   BUFFER_ALIGNMENT_NEEDS);
1072                                if (!pDev->_tx)
1073                                        return -1;
1074                        } else {
1075                                /* User defined "cou-local" address. Translate
1076                                 * it into a CPU accessible address
1077                                 */
1078                                pDev->_tx = (void *)adr;
1079                        }
1080                        /* Align TX buffer */
1081                        pDev->tx = (struct grcan_msg *)
1082                                   (((unsigned int)pDev->_tx +
1083                                   (BUFFER_ALIGNMENT_NEEDS-1)) &
1084                                   ~(BUFFER_ALIGNMENT_NEEDS-1));
1085
1086                        /* Translate address into an hardware accessible
1087                         * address
1088                         */
1089                        drvmgr_translate_check(
1090                                pDev->dev,
1091                                CPUMEM_TO_DMA,
1092                                (void *)pDev->tx,
1093                                (void **)&pDev->_tx_hw,
1094                                pDev->txbuf_size);
1095                }
1096        }
1097
1098        if ( rx ) {
1099                adr = (unsigned int)pDev->rxbuf_adr;
1100                if (adr & 0x1) {
1101                        /* User defined "remote" address. Translate it into
1102                         * a CPU accessible address
1103                         */
1104                        pDev->_rx_hw = (void *)(adr & ~0x1);
1105                        drvmgr_translate_check(
1106                                pDev->dev,
1107                                DMAMEM_TO_CPU,
1108                                (void *)pDev->_rx_hw,
1109                                (void **)&pDev->_rx,
1110                                pDev->rxbuf_size);
1111                        pDev->rx = (struct grcan_msg *)pDev->_rx;
1112                } else {
1113                        if (adr == 0) {
1114                                pDev->_rx = malloc(pDev->rxbuf_size +
1115                                                   BUFFER_ALIGNMENT_NEEDS);
1116                                if (!pDev->_rx)
1117                                        return -1;
1118                        } else {
1119                                /* User defined "cou-local" address. Translate
1120                                 * it into a CPU accessible address
1121                                 */
1122                                pDev->_rx = (void *)adr;
1123                        }
1124                        /* Align RX buffer */
1125                        pDev->rx = (struct grcan_msg *)
1126                                   (((unsigned int)pDev->_rx +
1127                                   (BUFFER_ALIGNMENT_NEEDS-1)) &
1128                                   ~(BUFFER_ALIGNMENT_NEEDS-1));
1129
1130                        /* Translate address into an hardware accessible
1131                         * address
1132                         */
1133                        drvmgr_translate_check(
1134                                pDev->dev,
1135                                CPUMEM_TO_DMA,
1136                                (void *)pDev->rx,
1137                                (void **)&pDev->_rx_hw,
1138                                pDev->rxbuf_size);
1139                }
1140        }
1141        return 0;
1142}
1143
1144static void grcan_free_buffers(struct grcan_priv *pDev, int rx, int tx)
1145{
1146  FUNCDBG();
1147
1148  if ( tx && pDev->_tx ){
1149    free(pDev->_tx);
1150    pDev->_tx = NULL;
1151    pDev->tx = NULL;
1152  }
1153
1154  if ( rx && pDev->_rx ){
1155    free(pDev->_rx);
1156    pDev->_rx = NULL;
1157    pDev->rx = NULL;
1158  }
1159}
1160
1161int grcan_dev_count(void)
1162{
1163        return grcan_count;
1164}
1165
1166void *grcan_open(int dev_no)
1167{
1168        struct grcan_priv *pDev;
1169        void *ret;
1170        union drvmgr_key_value *value;
1171
1172        FUNCDBG();
1173
1174        if (grcan_count == 0 || (grcan_count <= dev_no)) {
1175                return NULL;
1176        }
1177
1178        pDev = priv_tab[dev_no];
1179
1180        /* Wait until we get semaphore */
1181        if (rtems_semaphore_obtain(pDev->dev_sem, RTEMS_WAIT, RTEMS_NO_TIMEOUT)
1182            != RTEMS_SUCCESSFUL) {
1183                return NULL;
1184        }
1185
1186        /* is device busy/taken? */
1187        if ( pDev->open ) {
1188                ret = NULL;
1189                goto out;
1190        }
1191
1192        /* Mark device taken */
1193        pDev->open = 1;
1194
1195        pDev->txblock = pDev->rxblock = 1;
1196        pDev->txcomplete = pDev->rxcomplete = 0;
1197        pDev->started = 0;
1198        pDev->config_changed = 1;
1199        pDev->config.silent = 0;
1200        pDev->config.abort = 0;
1201        pDev->config.selection.selection = 0;
1202        pDev->config.selection.enable0 = 0;
1203        pDev->config.selection.enable1 = 1;
1204        pDev->flushing = 0;
1205        pDev->rx = pDev->_rx = NULL;
1206        pDev->tx = pDev->_tx = NULL;
1207        pDev->txbuf_adr = 0;
1208        pDev->rxbuf_adr = 0;
1209        pDev->txbuf_size = TX_BUF_SIZE;
1210        pDev->rxbuf_size = RX_BUF_SIZE;
1211
1212        /* Override default buffer sizes if available from bus resource */
1213        value = drvmgr_dev_key_get(pDev->dev, "txBufSize", DRVMGR_KT_INT);
1214        if ( value )
1215                pDev->txbuf_size = value->i;
1216
1217        value = drvmgr_dev_key_get(pDev->dev, "rxBufSize", DRVMGR_KT_INT);
1218        if ( value )
1219                pDev->rxbuf_size = value->i;
1220
1221        value = drvmgr_dev_key_get(pDev->dev, "txBufAdr", DRVMGR_KT_POINTER);
1222        if ( value )
1223                pDev->txbuf_adr = value->ptr;
1224
1225        value = drvmgr_dev_key_get(pDev->dev, "rxBufAdr", DRVMGR_KT_POINTER);
1226        if ( value )
1227                pDev->rxbuf_adr = value->ptr;
1228
1229        DBG("Defaulting to rxbufsize: %d, txbufsize: %d\n",RX_BUF_SIZE,TX_BUF_SIZE);
1230
1231        /* Default to accept all messages */
1232        pDev->afilter.mask = 0x00000000;
1233        pDev->afilter.code = 0x00000000;
1234
1235        /* Default to disable sync messages (only trigger when id is set to all ones) */
1236        pDev->sfilter.mask = 0xffffffff;
1237        pDev->sfilter.code = 0x00000000;
1238
1239        /* Calculate default timing register values */
1240        grcan_calc_timing(GRCAN_DEFAULT_BAUD,pDev->corefreq_hz,GRCAN_SAMPLING_POINT,&pDev->config.timing);
1241
1242        if ( grcan_alloc_buffers(pDev,1,1) ) {
1243                ret = NULL;
1244                goto out;
1245        }
1246
1247        /* Clear statistics */
1248        memset(&pDev->stats,0,sizeof(struct grcan_stats));
1249
1250        ret = pDev;
1251out:
1252        rtems_semaphore_release(pDev->dev_sem);
1253        return ret;
1254}
1255
1256int grcan_close(void *d)
1257{
1258        struct grcan_priv *pDev = d;
1259
1260        FUNCDBG();
1261
1262        if ( pDev->started )
1263                grcan_hw_stop(pDev);
1264
1265        grcan_hw_reset(pDev->regs);
1266
1267        grcan_free_buffers(pDev,1,1);
1268
1269        /* Mark Device as closed */
1270        pDev->open = 0;
1271
1272        return 0;
1273}
1274
1275int grcan_read(void *d, CANMsg *msg, size_t ucount)
1276{
1277        struct grcan_priv *pDev = d;
1278        CANMsg *dest;
1279        unsigned int count, left;
1280        int req_cnt;
1281
1282        FUNCDBG();
1283
1284        dest = msg;
1285        req_cnt = ucount;
1286
1287        if ( (!dest) || (req_cnt<1) )
1288                return -1;
1289
1290        if ( !pDev->started )
1291                return -2;
1292
1293        /*FUNCDBG("grcan_read [%i,%i]: buf: 0x%x len: %i\n",major, minor, (unsigned int)rw_args->buffer,rw_args->count);*/
1294
1295        count = grcan_hw_read_try(pDev,pDev->regs,dest,req_cnt);
1296        if ( !( pDev->rxblock && pDev->rxcomplete && (count!=req_cnt) ) ){
1297                if ( count > 0 ) {
1298                        /* Successfully received messages (at least one) */
1299                        return count;
1300                }
1301
1302                /* nothing read, shall we block? */
1303                if ( !pDev->rxblock ) {
1304                        /* non-blocking mode */
1305                        return -3;
1306                }
1307        }
1308
1309        while(count == 0 || (pDev->rxcomplete && (count!=req_cnt)) ){
1310
1311        if ( !pDev->rxcomplete ){
1312                left = 1; /* return as soon as there is one message available */
1313        }else{
1314                left = req_cnt - count;     /* return as soon as all data are available */
1315
1316                /* never wait for more than the half the maximum size of the receive buffer
1317                 * Why? We need some time to copy buffer before to catch up with hw,
1318                 * otherwise we would have to copy everything when the data has been
1319                 * received.
1320                 */
1321                if ( left > ((pDev->rxbuf_size/GRCAN_MSG_SIZE)/2) ){
1322                        left = (pDev->rxbuf_size/GRCAN_MSG_SIZE)/2;
1323                }
1324        }
1325
1326        if ( grcan_wait_rxdata(pDev,left) ) {
1327                /* The wait has been aborted, probably due to
1328                 * the device driver has been closed by another
1329                 * thread.
1330                 */
1331                return count;
1332        }
1333
1334        /* Try read bytes from circular buffer */
1335        count += grcan_hw_read_try(
1336                        pDev,
1337                        pDev->regs,
1338                        dest+count,
1339                        req_cnt-count);
1340        }
1341        /* no need to unmask IRQ as IRQ Handler do that for us. */
1342        return count;
1343}
1344
1345int grcan_write(void *d, CANMsg *msg, size_t ucount)
1346{
1347        struct grcan_priv *pDev = d;
1348        CANMsg *source;
1349        unsigned int count, left;
1350        int req_cnt;
1351
1352        DBGC(DBG_TX,"\n");
1353
1354        if ( !pDev->started || pDev->config.silent || pDev->flushing )
1355                return -2;
1356
1357        req_cnt = ucount;
1358        source = (CANMsg *) msg;
1359
1360        /* check proper length and buffer pointer */
1361        if (( req_cnt < 1) || (source == NULL) ){
1362                return -1;
1363        }
1364
1365        count = grcan_hw_write_try(pDev,pDev->regs,source,req_cnt);
1366        if ( !(pDev->txblock && pDev->txcomplete && (count!=req_cnt)) ) {
1367                if ( count > 0 ) {
1368                        /* Successfully transmitted chars (at least one char) */
1369                        return count;
1370                }
1371
1372                /* nothing written, shall we block? */
1373                if ( !pDev->txblock ) {
1374                        /* non-blocking mode */
1375                        return -3;
1376                }
1377        }
1378
1379        /* if in txcomplete mode we need to transmit all chars */
1380        while((count == 0) || (pDev->txcomplete && (count!=req_cnt)) ){
1381                /*** block until room to fit all or as much of transmit buffer as possible
1382                 * IRQ comes. Set up a valid IRQ point so that an IRQ is received
1383                 * when we can put a chunk of data into transmit fifo
1384                 */
1385                if ( !pDev->txcomplete ){
1386                        left = 1; /* wait for anything to fit buffer */
1387                }else{
1388                        left = req_cnt - count; /* wait for all data to fit in buffer */
1389
1390                        /* never wait for more than the half the maximum size of the transmit
1391                         * buffer
1392                         * Why? We need some time to fill buffer before hw catches up.
1393                         */
1394                        if ( left > ((pDev->txbuf_size/GRCAN_MSG_SIZE)/2) ){
1395                                left = (pDev->txbuf_size/GRCAN_MSG_SIZE)/2;
1396                        }
1397                }
1398
1399                /* Wait until more room in transmit buffer */
1400                if ( grcan_wait_txspace(pDev,left) ){
1401                        /* The wait has been aborted, probably due to
1402                         * the device driver has been closed by another
1403                         * thread. To avoid deadlock we return directly
1404                         * with error status.
1405                         */
1406                        return count;
1407                }
1408
1409                if ( pDev->txerror ){
1410                        /* Return number of bytes sent, compare write pointers */
1411                        pDev->txerror = 0;
1412#if 0 
1413#error HANDLE AMBA error
1414#endif
1415                }
1416
1417                /* Try read bytes from circular buffer */
1418                count += grcan_hw_write_try(
1419                        pDev,
1420                        pDev->regs,
1421                        source+count,
1422                        req_cnt-count);
1423        }
1424        /* no need to unmask IRQ as IRQ Handler do that for us. */
1425
1426        return count;
1427}
1428
1429int grcan_start(void *d)
1430{
1431        struct grcan_priv *pDev = d;
1432        rtems_device_driver status;
1433
1434        FUNCDBG();
1435
1436        if ( pDev->started )
1437                return -1;
1438
1439        if ( (status=grcan_hw_start(pDev)) != RTEMS_SUCCESSFUL ){
1440                return -2;
1441        }
1442
1443        /* Read and write are now open... */
1444        pDev->started = 1;
1445
1446        /* Register interrupt routine and enable IRQ at IRQ ctrl */
1447        drvmgr_interrupt_register(pDev->dev, 0, "grcan", grcan_interrupt, pDev);
1448
1449        return 0;
1450}
1451
1452int grcan_stop(void *d)
1453{
1454        struct grcan_priv *pDev = d;
1455
1456        FUNCDBG();
1457
1458        if ( !pDev->started )
1459                return -1;
1460
1461        /* Disable interrupts */
1462        drvmgr_interrupt_unregister(pDev->dev, 0, grcan_interrupt, pDev);
1463
1464        grcan_hw_stop(pDev);
1465        pDev->started = 0;
1466
1467        return 0;
1468}
1469
1470int grcan_isstarted(void *d)
1471{
1472        struct grcan_priv *pDev = d;
1473
1474        FUNCDBG();
1475
1476        return pDev->started;
1477}
1478
1479int grcan_flush(void *d)
1480{
1481        struct grcan_priv *pDev = d;
1482        int tmp;
1483
1484        FUNCDBG();
1485
1486        if ( !pDev->started || pDev->flushing || pDev->config.silent )
1487                return -1;
1488
1489        pDev->flushing = 1;
1490        tmp = grcan_tx_flush(pDev);
1491        pDev->flushing = 0;
1492        if ( tmp ) {
1493                /* The wait has been aborted, probably due to
1494                 * the device driver has been closed by another
1495                 * thread.
1496                 */
1497                return -1;
1498        }
1499
1500        return 0;
1501}
1502
1503int grcan_set_silent(void* d, int silent)
1504{
1505        struct grcan_priv *pDev = d;
1506
1507        FUNCDBG();
1508
1509        if ( pDev->started )
1510                return -1;
1511
1512        pDev->config.silent = silent;
1513        pDev->config_changed = 1;
1514
1515        return 0;
1516}
1517
1518int grcan_set_abort(void* d, int abort)
1519{
1520        struct grcan_priv *pDev = d;
1521
1522        FUNCDBG();
1523
1524        if ( pDev->started )
1525                return -1;
1526
1527        pDev->config.abort = abort;
1528        /* This Configuration parameter doesn't need HurriCANe reset
1529         * ==> no pDev->config_changed = 1;
1530         */
1531
1532        return 0;
1533}
1534
1535int grcan_set_selection(void *d, const struct grcan_selection *selection)
1536{
1537        struct grcan_priv *pDev = d;
1538
1539        FUNCDBG();
1540
1541        if ( pDev->started )
1542                return -1;
1543
1544        if ( !selection )
1545                return -2;
1546
1547        pDev->config.selection = *selection;
1548        pDev->config_changed = 1;
1549
1550        return 0;
1551}
1552
1553int grcan_set_rxblock(void *d, int block)
1554{
1555        struct grcan_priv *pDev = d;
1556
1557        FUNCDBG();
1558
1559        pDev->rxblock = block;
1560
1561        return 0;
1562}
1563
1564int grcan_set_txblock(void *d, int block)
1565{
1566        struct grcan_priv *pDev = d;
1567
1568        FUNCDBG();
1569
1570        pDev->txblock = block;
1571
1572        return 0;
1573}
1574
1575int grcan_set_txcomplete(void *d, int complete)
1576{
1577        struct grcan_priv *pDev = d;
1578
1579        FUNCDBG();
1580
1581        pDev->txcomplete = complete;
1582
1583        return 0;
1584}
1585
1586int grcan_set_rxcomplete(void *d, int complete)
1587{
1588        struct grcan_priv *pDev = d;
1589
1590        FUNCDBG();
1591
1592        pDev->rxcomplete = complete;
1593
1594        return 0;
1595}
1596
1597int grcan_get_stats(void *d, struct grcan_stats *stats)
1598{
1599        struct grcan_priv *pDev = d;
1600
1601        FUNCDBG();
1602
1603        if ( !stats )
1604                return -1;
1605
1606        *stats = pDev->stats;
1607
1608        return 0;
1609}
1610
1611int grcan_clr_stats(void *d)
1612{
1613        struct grcan_priv *pDev = d;
1614        IRQ_GLOBAL_PREPARE(oldLevel);
1615
1616        FUNCDBG();
1617
1618        IRQ_GLOBAL_DISABLE(oldLevel);
1619        memset(&pDev->stats,0,sizeof(struct grcan_stats));
1620        IRQ_GLOBAL_ENABLE(oldLevel);
1621
1622        return 0;
1623}
1624
1625int grcan_set_speed(void *d, unsigned int speed)
1626{
1627        struct grcan_priv *pDev = d;
1628        struct grcan_timing timing;
1629        int ret;
1630
1631        FUNCDBG();
1632
1633        /* cannot change speed during run mode */
1634        if ( pDev->started )
1635                return -1;
1636
1637        /* get speed rate from argument */
1638        ret = grcan_calc_timing(speed, pDev->corefreq_hz, GRCAN_SAMPLING_POINT, &timing);
1639        if ( ret )
1640                return -2;
1641
1642        /* save timing/speed */
1643        pDev->config.timing = timing;
1644        pDev->config_changed = 1;
1645
1646        return 0;
1647}
1648
1649int grcan_set_btrs(void *d, const struct grcan_timing *timing)
1650{
1651        struct grcan_priv *pDev = d;
1652
1653        FUNCDBG();
1654
1655        /* Set BTR registers manually
1656         * Read GRCAN/HurriCANe Manual.
1657         */
1658        if ( pDev->started )
1659                return -1;
1660
1661        if ( !timing )
1662                return -2;
1663
1664        pDev->config.timing = *timing;
1665        pDev->config_changed = 1;
1666
1667        return 0;
1668}
1669
1670int grcan_set_afilter(void *d, const struct grcan_filter *filter)
1671{
1672        struct grcan_priv *pDev = d;
1673
1674        FUNCDBG();
1675
1676        if ( !filter ){
1677                /* Disable filtering - let all messages pass */
1678                pDev->afilter.mask = 0x0;
1679                pDev->afilter.code = 0x0;
1680        }else{
1681                /* Save filter */
1682                pDev->afilter = *filter;
1683        }
1684        /* Set hardware acceptance filter */
1685        grcan_hw_accept(pDev->regs,&pDev->afilter);
1686
1687        return 0;
1688}
1689
1690int grcan_set_sfilter(void *d, const struct grcan_filter *filter)
1691{
1692        struct grcan_priv *pDev = d;
1693
1694        FUNCDBG();
1695
1696        if ( !filter ){
1697                /* disable TX/RX SYNC filtering */
1698                pDev->sfilter.mask = 0xffffffff;
1699                pDev->sfilter.mask = 0;
1700
1701                 /* disable Sync interrupt */
1702                pDev->regs->imr = READ_REG(&pDev->regs->imr) & ~(GRCAN_RXSYNC_IRQ|GRCAN_TXSYNC_IRQ);
1703        }else{
1704                /* Save filter */
1705                pDev->sfilter = *filter;
1706
1707                /* Enable Sync interrupt */
1708                pDev->regs->imr = READ_REG(&pDev->regs->imr) | (GRCAN_RXSYNC_IRQ|GRCAN_TXSYNC_IRQ);
1709        }
1710        /* Set Sync RX/TX filter */
1711        grcan_hw_sync(pDev->regs,&pDev->sfilter);
1712
1713        return 0;
1714}
1715
1716int grcan_get_status(void* d, unsigned int *data)
1717{
1718        struct grcan_priv *pDev = d;
1719
1720        FUNCDBG();
1721
1722        if ( !data )
1723                return -1;
1724
1725        /* Read out the statsu register from the GRCAN core */
1726        data[0] = READ_REG(&pDev->regs->stat);
1727
1728        return 0;
1729}
1730
1731/* Handle the IRQ */
1732static void grcan_interrupt(void *arg)
1733{
1734        struct grcan_priv *pDev = arg;
1735        unsigned int status = READ_REG(&pDev->regs->pimsr);
1736        unsigned int canstat = READ_REG(&pDev->regs->stat);
1737
1738        /* Spurious IRQ call? */
1739        if ( !status && !canstat )
1740                return;
1741
1742        FUNCDBG();
1743
1744        /* Increment number of interrupts counter */
1745        pDev->stats.ints++;
1746
1747        if ( (status & GRCAN_ERR_IRQ) || (canstat & GRCAN_STAT_PASS) ){
1748                /* Error-Passive interrupt */
1749                pDev->stats.passive_cnt++;
1750        }
1751
1752        if ( (status & GRCAN_OFF_IRQ) || (canstat & GRCAN_STAT_OFF) ){
1753                /* Bus-off condition interrupt
1754                 * The link is brought down by hardware, we wake all threads
1755                 * that is blocked in read/write calls and stop futher calls
1756                 * to read/write until user has called ioctl(fd,START,0).
1757                 */
1758                pDev->started = 0;
1759                grcan_hw_stop(pDev); /* this mask all IRQ sources */
1760                status=0x1ffff; /* clear all interrupts */
1761                goto out;
1762        }
1763
1764        if ( (status & GRCAN_OR_IRQ) || (canstat & GRCAN_STAT_OR) ){
1765                /* Over-run during reception interrupt */
1766                pDev->stats.overrun_cnt++;
1767        }
1768
1769        if ( (status & GRCAN_RXAHBERR_IRQ) ||
1770             (status & GRCAN_TXAHBERR_IRQ) ||
1771             (canstat & GRCAN_STAT_AHBERR) ){
1772                /* RX or Tx AHB Error interrupt */
1773                printk("AHBERROR: status: 0x%x, canstat: 0x%x\n",status,canstat);
1774                pDev->stats.ahberr_cnt++;
1775        }
1776
1777        if ( status & GRCAN_TXLOSS_IRQ ) {
1778                pDev->stats.txloss_cnt++;
1779        }
1780
1781        if ( status & GRCAN_RXIRQ_IRQ ){
1782                /* RX IRQ pointer interrupt */
1783                /*printk("RxIrq 0x%x\n",status);*/
1784                pDev->regs->imr = READ_REG(&pDev->regs->imr) & ~GRCAN_RXIRQ_IRQ;
1785                rtems_semaphore_release(pDev->rx_sem);
1786        }
1787
1788        if ( status & GRCAN_TXIRQ_IRQ ){
1789                /* TX IRQ pointer interrupt */
1790                pDev->regs->imr = READ_REG(&pDev->regs->imr) & ~GRCAN_TXIRQ_IRQ;
1791                rtems_semaphore_release(pDev->tx_sem);
1792        }
1793
1794        if ( status & GRCAN_TXSYNC_IRQ ){
1795                /* TxSync message transmitted interrupt */
1796                pDev->stats.txsync_cnt++;
1797        }
1798
1799        if ( status & GRCAN_RXSYNC_IRQ ){
1800                /* RxSync message received interrupt */
1801                pDev->stats.rxsync_cnt++;
1802        }
1803
1804        if ( status & GRCAN_TXEMPTY_IRQ ){
1805                pDev->regs->imr = READ_REG(&pDev->regs->imr) & ~GRCAN_TXEMPTY_IRQ;
1806                rtems_semaphore_release(pDev->txempty_sem);
1807        }
1808
1809out:
1810        /* Clear IRQs */
1811        pDev->regs->picr = status;
1812}
Note: See TracBrowser for help on using the repository browser.