📄 flexcan.c
字号:
/******************************************************************************
*
* COPYRIGHT 2003 MOTOROLA, ALL RIGHTS RESERVED
*
* The code is the property of Motorola St.Petersburg Software Development
* and is Motorola Confidential Proprietary Information.
*
* The copyright notice above does not evidence any
* actual or intended publication of such source code.
*
* Functions:
*
* Description:
*
* Notes:
*
******************************************************************************/
#include "bsp.h"
#include "periph.h"
#include "flexcan.h"
#include "stdarg.h"
can_sBuffer IOBuffer[16]; /* supported buffers */
int nBottomRead = 16; /* bottom pointer */
int nTopWrite = 0;
int CANErrno;
unsigned int nBusyFlags = 0;
extern const unsigned int FlexCANFlags; /* FlexCAN configuration word */
extern const io_sFLEXCANInterface canInterfaceVT;
extern const can_pRawCallBack CANRcvPrepare; /* RAW CallBack pointer */
/*******************************************************************************
*
* NAME: FC_Init
*
* DESCRIPTION: Initialize CAN driver device
*
********************************************************************************
* PARAMETERS:
*
* SIDE EFFECTS: None Known
*
* DESIGNER NOTES: device initialization.
*
* DEPENDENCIES: None
*******************************************************************************/
void FC_Init( )
{
unsigned int i, j;
extern const can_sInitialState canInitialState;
periphMemWrite(0x0200, &ArchIO.CAN.ConfigReg );
i = 0;
periphMemWrite(15, &ArchIO.CAN.MaxMBReg );
periphMemWrite( canInitialState.regFCMCR, &ArchIO.CAN.ConfigReg );
periphMemWrite( canInitialState.regFCCTL0, &ArchIO.CAN.Control0Reg );
periphMemWrite( canInitialState.regFCCTL1, &ArchIO.CAN.Control1Reg );
#if 0 /* default mask state is OK */
periphMemWrite( 0xFFE7, &ArchIO.CAN.RxGlobalMaskHiReg );
periphMemWrite( 0xFFFE, &ArchIO.CAN.RxGlobalMaskLoReg );
periphMemWrite( 0xFFE7, &ArchIO.CAN.Rx14MaskHiReg );
periphMemWrite( 0xFFFE, &ArchIO.CAN.Rx14MaskLoReg );
periphMemWrite( 0xFFE7, &ArchIO.CAN.Rx15MaskHiReg );
periphMemWrite( 0xFFFE, &ArchIO.CAN.Rx15MaskLoReg );
#endif
periphMemWrite(0, &ArchIO.CAN.IntMask1Reg );
for( ; i < 16; i++ )
{
/* reset all elements in all Message Buffers Control Register */
periphMemWrite( FC_MB_NOTREADY, &ArchIO.CAN.Buffer[i].CtlStatusReg );
}
periphBitClear( 0xF000, &ArchIO.CAN.ConfigReg);
}
/*******************************************************************************
*
* NAME: CheckCANID
*
* DESCRIPTION: check CAN ID to protect from reopen
*
********************************************************************************
* PARAMETERS: CAN ID, mode for loopback
*
* SIDE EFFECTS: None Known
*
* DESIGNER NOTES:
*
* DEPENDENCIES: None
*******************************************************************************/
int CheckCANID( CANADDRESSTYPE canID, unsigned int mode )
{
register int i;
if( !( mode & (O_LOOP_BACK) >> 1 ) )
for( i = nBottomRead; i < 16; i++ )
{
if( IOBuffer[i].canID == canID) /* checking receive buffers */
{
CANErrno = CAN_ERR_REOPEN;
return 0;
}
}
if( !( mode & (O_LOOP_BACK) ) )
for( i = 0; i < nTopWrite; i++ )
{
if( IOBuffer[i].canID == canID ) /* checking send buffers */
{
CANErrno = CAN_ERR_REOPEN;
return 0; /* error: re-open is not possible */
}
}
return 1;
}
/*******************************************************************************
*
* NAME: SetCANID
*
* DESCRIPTION: Decompose 11/29-bit CAN ID into the registers
*
********************************************************************************
* PARAMETERS: Address of the registers, CAN ID
*
* SIDE EFFECTS: None Known
*
* DESIGNER NOTES:
*
* DEPENDENCIES: None
*******************************************************************************/
void SetCANID( volatile unsigned short* pAddr, CANADDRESSTYPE canID, unsigned long addr_flags )
{
asm( brclr #CAN_SHORT_IDE_MASK, B1, can2a );
asm( asl A );
asm( move.w A1, X0 );
asm( bfclr #0xFFF8, X0 ); /* ID[18-17] */
asm( or.w X0, B );
asm( move.w A1, X0 ); /* ID[29-18] */
asm( asll.w #0x2, X0 );
asm( bfclr #0x001F, X0 );
asm( or.w X0, B );
asm( move.w B1, X:(R2)+ );
asm( move.w A0, X:(R2)+ );
asm( rts );
can2a:
asm( asll.l #0x5, A );
asm( move.w A0, X:(R2)+ );
asm( clr.w X:(R2)+ );
}
/*******************************************************************************
*
* NAME: GetCANID
*
* DESCRIPTION: Compose 11/29-bit CAN ID from the registers values
*
********************************************************************************
* PARAMETERS: Raw ID
*
* SIDE EFFECTS: None Known
*
* DESIGNER NOTES:
*
* DEPENDENCIES: None
*******************************************************************************/
CANADDRESSTYPE GetCANID( unsigned long id )
{
asm( brclr # CAN_SHORT_IDE_MASK, A1, can2a );
asm( bfclr # (CAN_SHORT_IDE_MASK|CAN_SHORT_SRR_MASK), A1); /* clear srr, ide */
asm( brclr #0x0002, A1, Bit_16 ); /* bit 16th of id */
asm( bfset #CAN_SHORT_IDE_MASK, A1);
Bit_16:
asm( brclr # 0x0004, A1, Bit_17 ); /* bit 17th of id */
asm( bfset # CAN_SHORT_SRR_MASK, A1);
Bit_17:
asm( asr A ); /* bit_15 -> A0 */
asm( move.w A0, B0 );
asm( lsrr.w #2, A ); /* skip bit 16,17 */
asm( move.w B0, A0 );
asm( rts );
can2a:
asm( lsrr.l #21, A );
}
/*******************************************************************************
*
* NAME: PrepareCANID
*
* DESCRIPTION: prepare buffer for reading or write
*
********************************************************************************
* PARAMETERS: buffer descriptor
*
* SIDE EFFECTS: None Known
*
* DESIGNER NOTES:
*
* DEPENDENCIES: None
*******************************************************************************/
void PrepareCANID( can_sBuffer* pbuf, unsigned int cmd )
{
asm( move.w X:(R2 + #sFlexCAN_offset_flags), X0 );
asm( move.w X0, Y1 );
asm( bfclr #0xFFF0, X0 ); /* clear flags */
asm( asll.w #0x3, X0 ); /* x8, convert to buffer index */
asm( adda #( BSP_PERIPH_BASE + archoff_FlexCAN_Buffer_0 ), X0, R4 );
asm( move.w #FC_MB_NOTACTIVE, X:(R4 + devoff_FlexCANBuffer_CtlStatusReg) );
asm( move.l X:( R2 + sFlexCAN_offset_canID), A );
asm( adda # devoff_FlexCANBuffer_IdRegHi, R4, R2 );
asm( clr B ); /* form flags on B register */
asm( brset # CAN_BUF_READ_HANDLE, Y1, Bit_17 );
asm( bfset # CAN_SHORT_SRR_MASK, B1); /* only for write handle */
Bit_17:
asm( brclr # CAN_BUF_2B, Y1, Bit_16 );
asm( bfset #CAN_SHORT_IDE_MASK, B1); /* only for long handles */
Bit_16:
asm( jsr SetCANID ); /* used A,B, X0 */
asm( move.w Y0, X:(R4 + devoff_FlexCANBuffer_CtlStatusReg) );
asm( move.w X:( BSP_PERIPH_BASE + archoff_FlexCAN_TimerReg), X0 );
}
/*******************************************************************************
*
* NAME: flexcanPreOpen
*
* DESCRIPTION: driver Open procedure: open CAN device, receive and send CAN ID
*
********************************************************************************
* PARAMETERS: device name, open flags, CAN ID
*
* SIDE EFFECTS: None Known
*
* DESIGNER NOTES: following I/O flags accepted:
* O_RDONLY - Message buffer is opened for READ,
* O_WRONLY - Message buffer is opened for WRITE,
* transmission mode is synchronous,
* O_WRONLY | O_NON_BLOCK - Message buffer is opened for WRITE,
* transmission mode is asynchronous
*
* DEPENDENCIES: None
*******************************************************************************/
handle_t flexcanPreOpen(const char * pName, int oFlags, ...)
{
int i;
va_list Args;
CANADDRESSTYPE canID;
can_sBuffer* pBuf;
Args = (char *)&oFlags;
canID = va_arg(Args, CANADDRESSTYPE);
va_end(Args);
if( pName != BSP_DEVICE_NAME_CAN_0 )
{
return (handle_t ) -1;
}
if( nBottomRead == nTopWrite ) /* check buffers are available */
{
CANErrno = CAN_ERR_NO_BUFFERS;
return (handle_t) -1; /* error: no more driver buffers */
}
/*** open for read ( reception ) ***/
if( oFlags & O_RDONLY )
{
if( !CheckCANID( canID, FlexCANFlags & O_LOOP_BACK ) )
{
CANErrno = CAN_ERR_REOPEN;
return (handle_t )-1; /* error: no more driver buffers */
}
}
/*** open for write ( transmission ) ***/
else if( oFlags & O_WRONLY )
{
if( !CheckCANID( canID, (FlexCANFlags & O_LOOP_BACK) >> 1 ) )
{
CANErrno = CAN_ERR_REOPEN;
return (handle_t )-1; /* error: ID has been opened yet */
}
}
else
{
CANErrno = CAN_ERR_PARAMETER;
return (handle_t ) -1; /* flag error */
}
pBuf = (can_sBuffer*)flexcanOpen( pName, oFlags, canID );
pBuf->drvInterface = (io_sInterface *)&canInterfaceVT; /* interfaceCAN_Tx; */
return (handle_t)pBuf;
}
/*******************************************************************************
*
* NAME: flexcanOpen
*
* DESCRIPTION: driver Low Open procedure: initialize buffer
*
********************************************************************************
* PARAMETERS: device name, open flags, CAN ID
*
* SIDE EFFECTS: None Known
*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -