Changeset d805da0e in rtems


Ignore:
Timestamp:
Nov 30, 2007, 4:48:06 PM (13 years ago)
Author:
Joel Sherrill <joel.sherrill@…>
Branches:
4.8
Children:
0cec037
Parents:
cf148c7
Message:

2007-11-30 Daniel Hellstrom <daniel@…>

  • shared/can/grcan.c, shared/can/grcan_rasta.c, shared/include/ambapp.h: GRCAN CAN driver. Fixes Interrupt enabling/disabling in the driver, interrupt may not be restored correctly. Implements the baud rate calculation routine. Removed unnecessary printk. Fixed scanning to support GRCAN and GRHCAN hardware. Added GRCAN device number to ambapp.h.
Location:
c/src/lib/libbsp/sparc
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • c/src/lib/libbsp/sparc/ChangeLog

    rcf148c7 rd805da0e  
     12007-11-30      Daniel Hellstrom <daniel@gaisler.com>
     2
     3        * shared/can/grcan.c, shared/can/grcan_rasta.c,
     4        shared/include/ambapp.h: GRCAN CAN driver. Fixes Interrupt
     5        enabling/disabling in the driver, interrupt may not be restored
     6        correctly. Implements the baud rate calculation routine. Removed
     7        unnecessary printk. Fixed scanning to support GRCAN and GRHCAN
     8        hardware. Added GRCAN device number to ambapp.h.
     9
    1102007-10-11      Daniel Hellstrom <daniel@gaisler.com>
    211
  • c/src/lib/libbsp/sparc/shared/can/grcan.c

    rcf148c7 rd805da0e  
    2727#include <grcan.h>
    2828#include <ambapp.h>
    29 #include <pci.h>
    3029
    3130#define WRAP_AROUND_TX_MSGS 1
     
    4443#endif
    4544
     45#ifndef IRQ_GLOBAL_PREPARE
     46 #define IRQ_GLOBAL_PREPARE(level) rtems_interrupt_level level
     47#endif
     48
    4649#ifndef IRQ_GLOBAL_DISABLE
    47  #define IRQ_GLOBAL_DISABLE() sparc_disable_interrupts()
     50 #define IRQ_GLOBAL_DISABLE(level) rtems_interrupt_disable(level)
    4851#endif
    4952
    5053#ifndef IRQ_GLOBAL_ENABLE
    51  #define IRQ_GLOBAL_ENABLE() sparc_enable_interrupts()
     54 #define IRQ_GLOBAL_ENABLE(level) rtems_interrupt_enable(level)
    5255#endif
    5356
     
    9194#endif
    9295
     96#ifndef GRCAN_SAMPLING_POINT
     97#define GRCAN_SAMPLING_POINT 80
     98#endif
     99
    93100/* Uncomment for debug output */
    94101/****************** DEBUG Definitions ********************/
     
    98105
    99106#define DEBUG_FLAGS (DBG_IOCTRL | DBG_RX | DBG_TX )
    100 /*#define DEBUG
    101 #define DEBUGFUNCS*/
    102 
     107/*
     108#define DEBUG
     109#define DEBUGFUNCS
     110*/
    103111#include <debug_defs.h>
    104112
     
    251259#define READ_REG(address) _grcan_read_nocache((unsigned int)(address))
    252260#else
    253 #define READ_REG(address) (*(unsigned int *)(address))
     261#define READ_REG(address) (*(volatile unsigned int *)(address))
    254262#endif
    255263
     
    267275}
    268276#else
    269 #define READ_DMA_WORD(address) (*(unsigned int *)(address))
    270 #define READ_DMA_BYTE(address) (*(unsigned char *)(address))
     277#define READ_DMA_WORD(address) (*(volatile unsigned int *)(address))
     278#define READ_DMA_BYTE(address) (*(volatile unsigned char *)(address))
    271279#endif
    272280
     
    294302{
    295303  unsigned int tmp;
     304  IRQ_GLOBAL_PREPARE(oldLevel);
     305 
    296306  FUNCDBG();
    297307 
     
    336346 
    337347  /* Enable routing of the IRQs */
    338   IRQ_GLOBAL_DISABLE();
     348  IRQ_GLOBAL_DISABLE(oldLevel);
    339349  IRQ_UNMASK(pDev->irq+GRCAN_IRQ_TXSYNC);
    340350  IRQ_UNMASK(pDev->irq+GRCAN_IRQ_RXSYNC);
    341351  IRQ_UNMASK(pDev->irq+GRCAN_IRQ_IRQ);
    342   IRQ_GLOBAL_ENABLE();
     352  IRQ_GLOBAL_ENABLE(oldLevel);
    343353 
    344354  /* Reset some software data */
     
    508518};
    509519
     520
     521#define MIN_TSEG1 1
     522#define MIN_TSEG2 2
     523#define MAX_TSEG1 14
     524#define MAX_TSEG2 8
     525
    510526static int grcan_calc_timing(
    511527  unsigned int baud,          /* The requested BAUD to calculate timing for */
    512528  unsigned int core_hz,       /* Frequency in Hz of GRCAN Core */
     529  unsigned int sampl_pt,
    513530  struct grcan_timing *timing /* result is placed here */
    514531  )
    515532{
    516   return -1; /* not implemented yet */
     533        int best_error = 1000000000;
     534        int error;
     535        int best_tseg=0, best_brp=0, best_rate=0, brp=0;
     536        int tseg=0, tseg1=0, tseg2=0;
     537        int sjw = 1;
     538 
     539  /* Default to 90% */
     540  if ( (sampl_pt < 50) || (sampl_pt>99) ){
     541    sampl_pt = GRCAN_SAMPLING_POINT;
     542  }
     543
     544        if ( (baud<5000) || (baud>1000000) ){
     545                /* invalid speed mode */
     546                return -1;
     547        }
     548       
     549        /* find best match, return -2 if no good reg
     550         * combination is available for this frequency
     551   */
     552
     553        /* some heuristic specials */
     554        if (baud > ((1000000 + 500000) / 2))
     555                sampl_pt = 75;
     556
     557        if (baud < ((12500 + 10000) / 2))
     558                sampl_pt = 75;
     559
     560        /* tseg even = round down, odd = round up */
     561        for (tseg = (MIN_TSEG1 + MIN_TSEG2 + 2) * 2;
     562             tseg <= (MAX_TSEG2 + MAX_TSEG1 + 2) * 2 + 1;
     563             tseg++)
     564        {
     565                brp = core_hz / ((1 + tseg / 2) * baud) + tseg % 2;
     566                if ((brp <= 0) ||
     567        ( (brp > 256*1) && (brp <= 256*2) && (brp&0x1) ) ||
     568        ( (brp > 256*2) && (brp <= 256*4) && (brp&0x3) ) ||
     569        ( (brp > 256*4) && (brp <= 256*8) && (brp&0x7) ) ||
     570        (brp > 256*8)
     571        )
     572                        continue;
     573
     574                error = baud - core_hz / (brp * (1 + tseg / 2));
     575                if (error < 0)
     576                {
     577                        error = -error;
     578                }
     579
     580                if (error <= best_error)
     581                {
     582                        best_error = error;
     583                        best_tseg = tseg/2;
     584                        best_brp = brp-1;
     585                        best_rate = core_hz/(brp*(1+tseg/2));
     586                }
     587        }
     588
     589        if (best_error && (baud / best_error < 10))
     590        {
     591                return -2;
     592        }else if ( !timing )
     593                return 0; /* nothing to store result in, but a valid bitrate can be calculated */
     594
     595        tseg2 = best_tseg - (sampl_pt * (best_tseg + 1)) / 100;
     596
     597        if (tseg2 < MIN_TSEG2)
     598        {
     599                tseg2 = MIN_TSEG2;
     600        }
     601
     602        if (tseg2 > MAX_TSEG2)
     603        {
     604                tseg2 = MAX_TSEG2;
     605        }
     606
     607        tseg1 = best_tseg - tseg2 - 2;
     608
     609        if (tseg1 > MAX_TSEG1)
     610        {
     611                tseg1 = MAX_TSEG1;
     612                tseg2 = best_tseg - tseg1 - 2;
     613        }
     614 
     615  /* Get scaler and BRP from pseudo BRP */
     616  if ( best_brp <= 256 ){
     617    timing->scaler = best_brp;
     618    timing->bpr = 0;
     619  }else if ( best_brp <= 256*2 ){
     620    timing->scaler = ((best_brp+1)>>1) -1;
     621    timing->bpr = 1;
     622  }else if ( best_brp <= 256*4 ){
     623    timing->scaler = ((best_brp+1)>>2) -1;
     624    timing->bpr = 2;
     625  }else{
     626    timing->scaler = ((best_brp+1)>>3) -1;
     627    timing->bpr = 3;
     628  }
     629 
     630        timing->ps1    = tseg1+1;
     631        timing->ps2    = tseg2;
     632        timing->rsj    = sjw;
     633
     634        return 0;
    517635}
    518636
     
    664782  while( (grcan_hw_tx_ongoing(regs)) && i<1000 ){
    665783    i++;
    666     printk("ongoing tx\n");
    667784  }
    668785  regs->tx0wr = (unsigned int)dest - addr; /* Update write pointer */
     
    679796  unsigned int irq_trunk, dataavail;
    680797  int wait;
     798  IRQ_GLOBAL_PREPARE(oldLevel);
    681799 
    682800  FUNCDBG();
    683  
     801
     802  /*** block until receive IRQ received
     803   * Set up a valid IRQ point so that an IRQ is received
     804   * when one or more messages are received
     805   */
     806  IRQ_GLOBAL_DISABLE(oldLevel);
     807   
    684808  size = READ_REG(&pDev->regs->rx0size);
    685809  rp = READ_REG(&pDev->regs->rx0rd);
     
    693817  }else
    694818    irq_trunk = irq;
    695 
    696   /*** block until receive IRQ received
    697    * Set up a valid IRQ point so that an IRQ is received
    698    * when one or more messages are received
    699    */
    700   IRQ_GLOBAL_DISABLE();
    701819 
    702820  /* init IRQ HW */
     
    719837    wait=0;
    720838  }
    721   IRQ_GLOBAL_ENABLE();
     839  IRQ_GLOBAL_ENABLE(oldLevel);
    722840   
    723841    /* Wait for IRQ to fire only if has been triggered */
     
    745863  unsigned int irq, rp, wp, size, space_left;
    746864  unsigned int irq_trunk;
     865  IRQ_GLOBAL_PREPARE(oldLevel);
    747866 
    748867  DBGC(DBG_TX,"\n");
    749868  /*FUNCDBG();*/
    750869 
     870  IRQ_GLOBAL_DISABLE(oldLevel);
     871
     872  /*pDev->regs->tx0ctrl = GRCAN_TXCTRL_ENABLE;*/
     873 
    751874  size = READ_REG(&pDev->regs->tx0size);
    752875  wp = READ_REG(&pDev->regs->tx0wr); 
    753 
    754   IRQ_GLOBAL_DISABLE(); 
    755876 
    756877  rp = READ_REG(&pDev->regs->tx0rd);
     
    789910    wait=0;
    790911  }
    791   IRQ_GLOBAL_ENABLE();
     912  IRQ_GLOBAL_ENABLE(oldLevel);
    792913 
    793914  /* Wait for IRQ to fire only if it has been triggered */
    794915  if ( wait ){
    795     if ( rtems_semaphore_obtain(pDev->tx_sem, RTEMS_WAIT, RTEMS_NO_TIMEOUT) ==
     916    if ( rtems_semaphore_obtain(pDev->tx_sem, RTEMS_WAIT, 100) ==
    796917         RTEMS_UNSATISFIED ){
    797918      /* Device driver has flushed us, this may be due to another thread has
     
    809930  int wait;
    810931  unsigned int rp, wp;
     932  IRQ_GLOBAL_PREPARE(oldLevel);
    811933  FUNCDBG();
    812934 
     
    818940  while ( (wp=READ_REG(&pDev->regs->tx0wr)) != (rp=READ_REG(&pDev->regs->tx0rd)) ) {
    819941    /* Wait for TX empty IRQ */
    820     IRQ_GLOBAL_DISABLE();
     942    IRQ_GLOBAL_DISABLE(oldLevel);
    821943    /* Clear pending TXEmpty IRQ */
    822944    pDev->regs->picr = GRCAN_TXEMPTY_IRQ;
     
    830952      wait = 0;
    831953    }
    832     IRQ_GLOBAL_ENABLE();
     954    IRQ_GLOBAL_ENABLE(oldLevel);
    833955    if ( !wait )
    834956      break;
     
    9331055  char fs_name[20];
    9341056  unsigned int sys_freq_hz;
     1057  unsigned int deviceid = GAISLER_GRHCAN;
    9351058
    9361059  printk("grcan_initialize()\n\r");
     
    9401063  /* find GRCAN cores */
    9411064  if ( !grcan_cores ) {   
    942     grcan_core_cnt = amba_get_number_apbslv_devices(amba_bus,VENDOR_GAISLER,GAISLER_GRHCAN);
     1065    grcan_core_cnt = amba_get_number_apbslv_devices(amba_bus,VENDOR_GAISLER,deviceid);
     1066    if ( grcan_core_cnt < 1 ){
     1067      deviceid = GAISLER_GRCAN;
     1068      grcan_core_cnt = amba_get_number_apbslv_devices(amba_bus,VENDOR_GAISLER,deviceid);
     1069      if ( grcan_core_cnt < 1 ) {
     1070        DBG("GRCAN: Using AMBA Plug&Play, found %d cores\n",grcan_core_cnt);
     1071        return RTEMS_UNSATISFIED;
     1072      }
     1073    }
    9431074    DBG("GRCAN: Using AMBA Plug&Play, found %d cores\n",grcan_core_cnt);
    944     if ( grcan_core_cnt < 1 )
    945       return RTEMS_UNSATISFIED;
    9461075  }
    9471076
     
    10041133    /* Find core address & IRQ */
    10051134    if ( !grcan_cores ) {
    1006       amba_find_next_apbslv(amba_bus,VENDOR_GAISLER,GAISLER_GRHCAN,&dev,minor);
     1135      amba_find_next_apbslv(amba_bus,VENDOR_GAISLER,deviceid,&dev,minor);
    10071136      pDev->irq = dev.irq;
    10081137      pDev->regs = (struct grcan_regs *)dev.start;
     
    10121141    }
    10131142   
    1014     DBG("Registering GRCAN core at [0x%x] irq %d, minor %d as %s\n",pDev->regs,pDev->irq,minor,fs_name);
    10151143    printk("Registering GRCAN core at [0x%x] irq %d, minor %d as %s\n\r",pDev->regs,pDev->irq,minor,fs_name);
    10161144   
     
    11221250   
    11231251  /* Calculate default timing register values */
    1124   grcan_calc_timing(GRCAN_DEFAULT_BAUD,pDev->corefreq_hz,&pDev->config.timing);
     1252  grcan_calc_timing(GRCAN_DEFAULT_BAUD,pDev->corefreq_hz,GRCAN_SAMPLING_POINT,&pDev->config.timing);
    11251253 
    11261254  if ( grcan_alloc_buffers(pDev,1,1) ) {
     
    13341462  struct grcan_stats *stats;
    13351463  struct grcan_filter *filter;
     1464  IRQ_GLOBAL_PREPARE(oldLevel);
    13361465 
    13371466  FUNCDBG();
     
    14491578   
    14501579    case GRCAN_IOC_CLR_STATS:
    1451       IRQ_GLOBAL_DISABLE();
     1580      IRQ_GLOBAL_DISABLE(oldLevel);
    14521581      memset(&pDev->stats,0,sizeof(struct grcan_stats));
    1453       IRQ_GLOBAL_ENABLE();
     1582      IRQ_GLOBAL_ENABLE(oldLevel);
    14541583      break;
    14551584
     
    14621591                        /* get speed rate from argument */
    14631592                        speed = (unsigned int)ioarg->buffer;
    1464                         ret = grcan_calc_timing(pDev->corefreq_hz,speed,&timing);
     1593                        ret = grcan_calc_timing(speed,pDev->corefreq_hz,GRCAN_SAMPLING_POINT,&timing);
    14651594                        if ( ret )
    14661595                                return  RTEMS_INVALID_NAME; /* EINVAL */
     
    15381667  int minor=0;
    15391668  while ( minor < grcan_core_cnt ){
    1540     if ( grcans[minor].irq == (v+0x10) ){
     1669    if ( (grcans[minor].irq+0x10) == v ){
    15411670      grcan_interrupt(&grcans[minor]);
    15421671      break;
  • c/src/lib/libbsp/sparc/shared/can/grcan_rasta.c

    rcf148c7 rd805da0e  
    33
    44/* PCI frequency */
    5 #define SYS_FREQ_HZ 33000000
     5#define SYS_FREQ_HZ 30000000
    66
    77/*#define USE_AT697_RAM              1      */
     
    3030#define IRQ_MASK(irqno)
    3131
    32 #define IRQ_GLOBAL_DISABLE() sparc_disable_interrupts()
    33 #define IRQ_GLOBAL_ENABLE() sparc_enable_interrupts()
     32#define IRQ_GLOBAL_PREPARE(level) rtems_interrupt_level level
     33#define IRQ_GLOBAL_DISABLE(level) rtems_interrupt_disable(level)
     34#define IRQ_GLOBAL_ENABLE(level) rtems_interrupt_enable(level)
    3435
    3536#define GRCAN_REG_INT(handler,irqno,arg) \
  • c/src/lib/libbsp/sparc/shared/include/ambapp.h

    rcf148c7 rd805da0e  
    5959#define GAISLER_SPACEWIRE 0x1f
    6060#define GAISLER_AHB2AHB   0x20
    61 #define GAISLER_GRHCAN    0x34
     61#define GAISLER_I2CMST    0x28
     62#define GAISLER_GRSPW2    0x29
     63#define GAISLER_GRCAN     0x34
     64#define GAISLER_GRHCAN    0x3d
    6265#define GAISLER_GRFIFO    0x35
     66#define GAISLER_GRADCDAC  0x36
    6367#define GAISLER_GRPULSE   0x37
    6468#define GAISLER_GRTIMER   0x38
Note: See TracChangeset for help on using the changeset viewer.