📄 sja1000p.c
字号:
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 + -