⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sja1000p.c

📁 sja1000 peliCAN模式 在linux下面的驱动程序。
💻 C
📖 第 1 页 / 共 2 页
字号:

  pchip->write_register( DISABLE_INTERRUPTS, 
			 pchip->vbase_addr + SJAIER); //disable interrupts for a moment
  sja1000p_read( pchip );
  pchip->write_register( ENABLE_INTERRUPTS,
			 pchip->vbase_addr + SJAIER); //enable interrupts
  return 1;
}

///////////////////////////////////////////////////////////////////////////////
// sja1000p_pre_write_config

#define MAX_TRANSMIT_WAIT_LOOPS 200

int sja1000p_pre_write_config( struct chip_t *pchip, struct canmsg_t *pmsg )
{
  int i=0; 
  unsigned int id = 0;

  /* Wait until Transmit Buffer Status is released */
  while ( !( pchip->read_register( pchip->vbase_addr +  SJASR ) & SR_TBS ) && 
	  i++ < MAX_TRANSMIT_WAIT_LOOPS ) {
    udelay (i );
  }
	
  if ( !( pchip->read_register( pchip->vbase_addr +  SJASR) & SR_TBS ) ) {
    CANMSG("Transmit timed out, cancelling\n");
    // here we should check if there is no write/select waiting for this
    // transmit. If so, set error ret and wake up.
    // CHECKME: if we do not disable IER_TIE (TX IRQ) here we get interrupt
    // immediately
    pchip->write_register( CMR_AT, pchip->vbase_addr + SJACMR );
    i=0;
    while ( !( pchip->read_register( pchip->vbase_addr + SJASR ) & SR_TBS) &&
	    i++ < MAX_TRANSMIT_WAIT_LOOPS ) {
      udelay( i );
    }
    if ( !( pchip->read_register( pchip->vbase_addr +  SJASR) & SR_TBS ) ) {
      CANMSG("Could not cancel, please reset\n");
      return -EIO;
    }
  }
  pmsg->length &= FRM_DLC_M;
  pchip->write_register( ( ( pmsg->flags & MSG_EXT )? FRM_FF:0 ) |
		 ( ( pmsg->flags & MSG_RTR ) ? FRM_RTR : 0) |
		 pmsg->length, pchip->vbase_addr + SJAFRM );
  if ( pmsg->flags & MSG_EXT ) {
    id = pmsg->id<<3;
    pchip->write_register( id & 0xff, pchip->vbase_addr + SJAID3 );
    id >>= 8;
    pchip->write_register( id & 0xff, pchip->vbase_addr + SJAID2 );
    id >>= 8;
    pchip->write_register( id & 0xff, pchip->vbase_addr + SJAID1 );
    id >>= 8;
    pchip->write_register( id, pchip->vbase_addr + SJAID0);
    for( i=0; i < pmsg->length; i++) {
      pchip->write_register( pmsg->data[i], pchip->vbase_addr + SJADATE + i );
    }
  } else {
    id = pmsg->id >> 5;
    pchip->write_register( id & 0xff, pchip->vbase_addr + SJAID0 );
    id >>= 8;
    pchip->write_register( id & 0xff, pchip->vbase_addr + SJAID1 );
    for(i=0; i < pmsg->length; i++) {
      pchip->write_register( pmsg->data[ i ], pchip->vbase_addr + SJADATS + i );
    }
  }
  return 0;
}

///////////////////////////////////////////////////////////////////////////////
// sja1000p_send_msg

int sja1000p_send_msg( struct chip_t *pchip, int bRtr )
{
  pchip->write_register( CMR_TR, pchip->vbase_addr + SJACMR );
  return 0;
}

///////////////////////////////////////////////////////////////////////////////
// sja1000p_check_tx_stat

int sja1000p_check_tx_stat( struct chip_t *pchip )
{
  if ( pchip->read_register( pchip->vbase_addr + SJASR ) & SR_TCS)
    return 0;
  else
    return 1;
}

///////////////////////////////////////////////////////////////////////////////
// sja1000p_set_btregs

int sja1000p_set_btregs( struct chip_t *pchip, 
			 u16 btr0, 
			 u16 btr1)
{
  if ( sja1000p_enable_configuration( pchip ) )
    return -ENODEV;

  pchip->write_register( btr0, pchip->vbase_addr + SJABTR0 );
  pchip->write_register( btr1, pchip->vbase_addr + SJABTR1 );

  sja1000p_disable_configuration(pchip);

  return 0;
}

///////////////////////////////////////////////////////////////////////////////
// sja1000p_start_chip

int sja1000p_start_chip( struct chip_t *pchip )
{
  enum sja1000_PeliCAN_MOD flags;

  flags = pchip->read_register( pchip->vbase_addr + SJAMOD) & 
    (MOD_LOM|MOD_STM|MOD_AFM|MOD_SM);
  pchip->write_register( flags, pchip->vbase_addr + SJAMOD );

  return 0;
}

///////////////////////////////////////////////////////////////////////////////
// sja1000p_stop_chip

int sja1000p_stop_chip( struct chip_t *pchip )
{
  enum sja1000_PeliCAN_MOD flags;

  flags = pchip->read_register( pchip->vbase_addr + SJAMOD) & 
    ( MOD_LOM | MOD_STM | MOD_AFM | MOD_SM );
  pchip->write_register( flags | MOD_RM, pchip->vbase_addr + SJAMOD );

  return 0;
}


///////////////////////////////////////////////////////////////////////////////
// sja1000p_remote_request

int sja1000p_remote_request( struct chip_t *pchip )
{
  CANMSG("sja1000p_remote_request not implemented\n");
  return -ENOSYS;
}

///////////////////////////////////////////////////////////////////////////////
// sja1000p_standard_mask

int sja1000p_standard_mask( struct chip_t *pchip, 
			    u16 code,
			    u16 mask)
{
  CANMSG("sja1000p_standard_mask not implemented\n");
  return -ENOSYS;
}

///////////////////////////////////////////////////////////////////////////////
// sja1000p_clear_objects

int sja1000p_clear_objects( struct chip_t *pchip )
{
  CANMSG("sja1000p_clear_objects not implemented\n");
  return -ENOSYS;
}

///////////////////////////////////////////////////////////////////////////////
// sja1000p_config_irqs

int sja1000p_config_irqs( struct chip_t *pchip, u16 irqs )
{
  CANMSG("sja1000p_config_irqs not implemented\n");
  return -ENOSYS;
}

///////////////////////////////////////////////////////////////////////////////
// sja1000p_irq_handler

void sja1000p_irq_handler( int irq, void *dev_id, struct pt_regs *regs )
{
  int irq_register;
  struct chip_t *pchip = (struct chip_t *)dev_id;
  //struct canfifo_t *pfifo = pchip->pmsgobj[ 0 ]->pfifo;

  //put_reg = pchip->write_register;
  //get_reg = pchip->read_register;

  irq_register = pchip->read_register( pchip->vbase_addr + SJAIR );

  //	DEBUGMSG( "sja1000_irq_handler: SJAIR:%02x\n",irq_register);
  //	DEBUGMSG( "sja1000_irq_handler: SJASR:%02x\n",
  //		  pchip->read_register( pchip->vbase_addr + SJASR ) );

  if ( ( irq_register & ( IR_BEI|IR_EPI|IR_DOI|IR_EI|IR_TI|IR_RI ) ) == 0 ) {
    return;
  }

  if ( ( irq_register & IR_RI ) != 0 ) {

    sja1000p_read( pchip );
    pchip->rv = 0;

    if ( waitqueue_active( &pchip->fifo.readq ) ) {
      wake_up_interruptible( &pchip->fifo.readq );
    }
  }
  if ( ( irq_register & IR_TI) != 0 ) {
    pchip->rv = 0;
    if ( waitqueue_active( &pchip->fifo.writeq ) ) {
      wake_up_interruptible( &pchip->fifo.writeq );
    }
  }
  if ( ( irq_register & (IR_EI|IR_BEI|IR_EPI|IR_DOI)) != 0 ) { 

    // Some error happened
    CANMSG( "Error: status register: 0x%x irq_register: 0x%02x\n",
	    pchip->read_register( pchip->vbase_addr + SJASR ), irq_register );
    // FIXME: chip should be brought to usable state. 
    // Transmission cancelled if in progress.
    // Reset flag set to 0 if chip is already off the bus. Full state report
    pchip->rv = -1;

    if ( waitqueue_active( &pchip->fifo.writeq ) )
      wake_up_interruptible( &pchip->fifo.writeq );

    if (waitqueue_active( &pchip->fifo.readq ) )
      wake_up_interruptible( &pchip->fifo.readq );
  }

  return;
}

///////////////////////////////////////////////////////////////////////////////
//爏ja1000p_register

int sja1000p_register(struct chip_t *pchip )
{
  CANMSG("initializing sja1000p chip operations\n");
  pchip->chip_config = sja1000p_chip_config;
  pchip->set_baud_rate = sja1000p_baud_rate;
  pchip->set_standard_mask = sja1000p_standard_mask;
  pchip->set_extended_mask = sja1000p_extended_mask;
  pchip->set_message15_mask = sja1000p_extended_mask;
  pchip->clear_objects = sja1000p_clear_objects;
  pchip->config_irqs = sja1000p_config_irqs;
  pchip->pre_read_config = sja1000p_pre_read_config;
  pchip->pre_write_config = sja1000p_pre_write_config;
  pchip->send_msg = sja1000p_send_msg;
  pchip->check_tx_stat = sja1000p_check_tx_stat;
  pchip->remote_request = sja1000p_remote_request;
  pchip->enable_configuration = sja1000p_enable_configuration;
  pchip->disable_configuration = sja1000p_disable_configuration;
  pchip->set_btregs = sja1000p_set_btregs;
  pchip->start_chip = sja1000p_start_chip;
  pchip->stop_chip = sja1000p_stop_chip;
  pchip->irq_handler = sja1000p_irq_handler;

  return 0;
}








⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -