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

📄 sja1000.c

📁 三星2440 ARM CAN总线驱动 源代码
💻 C
📖 第 1 页 / 共 2 页
字号:

int sja1000_prereadConfig( void )
{
  // If no messages return
  if ( !( REG( SJASR ) & ( 1 << SR_RBS ) ) ) {
    return TRUE;
  }
  
  sja1000_disableIRQ();
  sja1000_readMsg();
  sja1000_enableIRQ();
 
  return TRUE;
}


///////////////////////////////////////////////////////////////////////////////
// sja1000_readMsgFromBuf

int sja1000_readMsgFromBuf( canmsg_t *pmsg )
{
  // Must be a valid pointer
  if ( NULL == pmsg ) return FALSE;

  if ( can_rx_insert_idx == can_rx_extract_idx ) {    
    return FALSE; // Empty, nothing to read
  }

  // Get message
  memcpy( (unsigned char *)pmsg, 
	  (unsigned char *)( (unsigned char *)can_rx_buffer + 
			     can_rx_extract_idx * 
			     sizeof( canmsg_t ) ), 
	  sizeof( canmsg_t ) );

  can_rx_extract_idx++;
  can_rx_extract_idx %= CAN_RX_BUFFER_SIZE;

  return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
// sja1000_sendMsg

int sja1000_sendMsg( canmsg_t *pmsg )
{
  // Wait until Transmit Buffer Status is released 
  while ( !( REG( SJASR ) & ( 1 << SR_TBS ) ) );
  
  if ( !( REG( SJASR ) & ( 1 << SR_TBS ) ) ) {

    // Transmit timed out
    REG( SJACMR ) = CMR_AT; // Abort transmission

    // Wait until Transmit Buffer Status is released 
    while ( !( REG( SJASR ) & ( 1 << SR_TBS ) ) ); 

    if ( !( REG( SJASR ) & ( 1 << SR_TBS ) ) ) {
      // Could not cancel, big problems
      return FALSE;
    }
  }
  
  // Write message to chip
  sja1000_writeMsg( pmsg );

  // Send the message
  REG( SJACMR ) = ( 1 << CMR_TR );

  return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
// sja1000_writeMsg
//

void sja1000_writeMsg( canmsg_t *pmsg )
{
  int i = 0;
  u32 id = 0;

  // Must have a message
  if ( NULL == pmsg ) return;

  pmsg->length &= FRM_DLC_M;
  REG( SJAFRM )= 
    ( ( pmsg->flags & ( 1 << MSG_EXT ) ) ? ( 1 << FRM_FF ) : 0 ) |
    ( ( pmsg->flags & ( 1 << MSG_RTR ) ) 
      ? ( 1 << FRM_RTR ) : 0 ) | pmsg->length;
  
  // Extended message
  if ( pmsg->flags & ( 1 << MSG_EXT ) ) {
   
    id = ( pmsg->id << 3 );
    REG( SJAID0 ) = ( id & 0xff );
    REG( SJAID1 ) = ( ( id >> 8 )  & 0xff );
    REG( SJAID2 ) = ( ( id >> 16 ) & 0xff );
    REG( SJAID3 ) = ( ( id >> 24 ) & 0xff );
    /*
      // Little Endian
      id = ( pmsg->id << 3 );
      REG( SJAID3 ) = ( id & 0xff );
      id >>= 8;
      REG( SJAID2 ) = ( id & 0xff );
      id >>= 8;
      REG( SJAID1 ) = ( id & 0xff );
      id >>= 8;
      REG( SJAID0 ) = id;
    */
    
    for( i=0; i < pmsg->length; i++) {
      REG( SJADATE + i ) = pmsg->data[ i ];
    }
  } 
  else {
    id = ( pmsg->id >> 5 );
    REG( SJAID0 ) = ( id & 0xff );
    REG( SJAID1 ) = ( ( id >> 8 )  & 0xff );
    /*
      // Little Endian
    id = ( pmsg->id >> 5 );
    REG( SJAID0 ) = ( id & 0xff );
    id >>= 8;
    REG( SJAID1 ) = ( id & 0xff );
    */

    for ( i=0; i < pmsg->length; i++ ) {
      REG( SJADATS + i ) = pmsg->data[ i ];
    }
  }
}


///////////////////////////////////////////////////////////////////////////////
// sja1000_sendMsgFromBuf
//

int sja1000_sendMsgFromBuf( void )
{
  canmsg_t *pmsg;

  if ( can_tx_insert_idx == can_tx_extract_idx ) {    
    return FALSE; // Empty, nothing to send
  }

  // Wait until Transmit Buffer Status is released 
  while ( !( REG( SJASR ) & ( 1 << SR_TBS ) ) );
  
  if ( !( REG( SJASR ) & ( 1 << SR_TBS ) ) ) {
    
    // Transmit timed out
    REG( SJACMR ) = CMR_AT; // Abort transmission
    
    // Wait until Transmit Buffer Status is released 
    while ( !( REG( SJASR ) & ( 1 << SR_TBS ) ) ); 
    
    if ( !( REG( SJASR ) & ( 1 << SR_TBS ) ) ) {
      // Could not cancel, big problems
      return FALSE;
    }
  }
  
  // Get message from buffer
  pmsg = (canmsg_t *)( (unsigned char *)can_tx_buffer + 
		       can_tx_extract_idx * 
		       sizeof( canmsg_t ) );
  
  can_tx_extract_idx++;
  can_tx_extract_idx %= CAN_TX_BUFFER_SIZE;

  // Write message to the chip
  sja1000_writeMsg( pmsg );

  // Send the message
  REG( SJACMR ) = ( 1 << CMR_TR );

  // Statistics
  canstat.cntTxPkt++;                 // Counter for sent packets.
  canstat.cntTxData += pmsg->length;  // Counter for sent data.

  return TRUE;
}


///////////////////////////////////////////////////////////////////////////////
// sja1000_writeMsgToBuf
//

int sja1000_writeMsgToBuf( canmsg_t *pmsg )
{
  uint16_t temp;

  // Must have a message
  if ( NULL == pmsg ) return FALSE;

  canmsg_t *pmsgbuf;

  // Put the message in the receive fifo if there is
  // a message and there is room for the message
  temp = ( can_tx_insert_idx + 1 ) % CAN_TX_BUFFER_SIZE;
    
  if ( temp == can_tx_extract_idx ) {
    // The fifo is full - Just update statistics
    canstat.cntTxFifoOvr++;
    return FALSE;
  }
  
  // add message to queue
  pmsgbuf = (canmsg_t *)( (unsigned char *)can_tx_buffer + 
			  can_tx_insert_idx * 
			  sizeof( canmsg_t ) );
  memcpy( (unsigned char *)pmsgbuf, 
	  (unsigned char *)pmsg, 
	  sizeof( canmsg_t ) );
  
  // Update buffer pointer
  can_tx_insert_idx = temp;
  
  // Enable TX interrupt if not enabled.
  if ( !( REG( SJAIER ) & ( 1 << IER_TIE ) ) ) {
    REG( SJAIER ) |= ( 1 << IER_TIE );
    sja1000_sendMsgFromBuf();
  }

  sja1000_sendMsgFromBuf();

  return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
// sja1000_check_tx_stat
//

int sja1000_check_tx_stat( void )
{
  if ( ( SJASR ) & ( 1 << SR_TCS ) ) {
    return FALSE;
  }
  else {
    return  TRUE;
  }
}

///////////////////////////////////////////////////////////////////////////////
// sja1000_setbtregs
//
// Must be in RESET mode
//

int sja1000_setbtregs( u16 btr0, u16 btr1 )
{
  REG( SJABTR0 ) = btr0;
  REG( SJABTR1 ) = btr1;
  
  return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
// sja1000_remoteRequest

int sja1000_remoteRequest( void )
{
  // sja1000_remote_request not implemented!!!
  return FALSE;
}

///////////////////////////////////////////////////////////////////////////////
// sja1000_standardMask

int sja1000_standardMask( u16 code, u16 mask )
{
  // sja1000_standard_mask not implemented!!!
  return FALSE;
}

///////////////////////////////////////////////////////////////////////////////
// getRXMsgCnt
//

u16 getRXMsgCnt( void )
{
  return abs( can_rx_insert_idx - can_rx_extract_idx );
}

///////////////////////////////////////////////////////////////////////////////
// getTXMsgCnt
//

u16 getTXMsgCnt( void )
{
  return abs( can_tx_insert_idx - can_tx_extract_idx );
}


///////////////////////////////////////////////////////////////////////////////
// sja1000 irq-handler
//
// signal handler for external interrupt int0 
//

SIGNAL( SIG_INTERRUPT0 )     
{
  u8 irq_register;

  irq_register = REG( SJAIR );

  // *** Data to Read ***
  if ( ( irq_register & ( 1 << IR_RI ) ) ) {
    // Read Data
    sja1000_readMsg();
  } 
  
  // *** Write Data ***
  if ( ( irq_register & ( 1 << IR_TI ) ) ) {
    // Transmitt Data
    if ( !sja1000_sendMsgFromBuf() ) {
      ;
    }
  }
  
  // *** Problems ***
  if ( ( irq_register & ( ( 1 << IR_EI ) | 
			  ( 1 << IR_BEI ) | 
			  ( 1 << IR_EPI ) | 
			  ( 1 << IR_DOI )  )) )  { 
    // Some error happened    
  }

  if ( inp( PORTD ) & 0x020 ) {
    outp( inp( PORTD ) & ~0x20, PORTD );
  }
  else {
    outp( inp( PORTD ) | 0x20, PORTD );
  }
}












⌨️ 快捷键说明

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