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

📄 flexcan.c

📁 56f8300E系列dsp的BOOTloader
💻 C
📖 第 1 页 / 共 3 页
字号:
/******************************************************************************
*
*       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 + -