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