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

📄 mscan.c

📁 56f8300E系列dsp的BOOTloader
💻 C
📖 第 1 页 / 共 3 页
字号:
#if defined(DSP56838EVM) 
/*******************************************************************************
*
* Motorola Inc.
* (c) Copyright 2002 Motorola, Inc.
* ALL RIGHTS RESERVED.
*
********************************************************************************
*
* FILE NAME: mscan.c
*
*******************************************************************************/
#include "port.h"
#include "arch.h"
#include "periph.h"
#include "io.h"

#include "stdio.h"
#include "stdlib.h"
#include "stdarg.h"
#include "string.h"

#include "bsp.h"

#include "supconfig.h"
#include "config.h"

#include "mscan.h"

/* MSCAN property resolved table: 1 - free, 0 - busy */
const UWord16 CANDll [/* 8 */] = {
/* 000 */  0x00 | CANM_TXISR | CANM_ALLBUSY,
/* 001 */  0x01 | CANM_TXISR,           
/* 010 */  0x02 | CANM_TXISR | CANM_FREE1,
/* 011 */  0x01,            
/* 100 */  0x04 | CANM_TXISR | CANM_FREE2,
/* 101 */  0x01,            
/* 110 */  0x02 |             CANM_FREE1,
/* 111 */  0x01 |             CANM_ALLFREE /* all free - reset priority */
};

extern const io_sMSCANInterface canInterfaceVT; 
/* extern const io_sDriver interfaceCAN; */

static UWord16 CANInit();
static UWord16 CANEvlFlag( UWord16 flg );
static UWord16 CANSetFilter();
static can_sReadBuffer* CANGetFreeReadBuffer( );
static can_sWriteBuffer* CANGetFreeWriteBuffer( );

static int CANFilterWeight( CANADDRESSTYPE canID, CANADDRESSTYPE code, CANADDRESSTYPE mask );
static void CANTransmit( UWord16 idx, can_sWriteBuffer* pBuf, can_sData* pData );
static can_sWriteBuffer* TakeAway( can_sWriteBuffer* pBuf );
static int CheckCANID( CANADDRESSTYPE canID, UWord16 mode );
static CANADDRESSTYPE GetCANID( volatile UWord16* pAddr );
static void SetCANID( volatile UWord16* pAddr, CANADDRESSTYPE canID );

extern const can_sInitialState canInitialState;   	

/* the number of used buffers is defined statically */
/* to control of open devices */
static can_sWriteBuffer* pLastWrite;
static can_sReadBuffer*  pLastRead;

/* CAN filters in CAN ID format */
static struct CANFilterMirror  sCANFilterMirror[CANFILTERLIMIT];

extern can_pRawCallBack CANRcvPrepare;  /*  RAW CallBack pointer */

/* CAN driver context variables */
int CANErrno;                           /* last error code */
static UWord16 actFilterLimit ;         /* free/busy filter index */
static can_sInitialState sIState;       /* MSCAN initial state */
static UWord16 msprio;                  /* priority support counter */

/*******************************************************************************
*
* NAME: CANStdRcvPrepare
*
* DESCRIPTION: To find driver receive buffer by incoming CANID
*
********************************************************************************
* PARAMETERS:   incoming CAN ID 
*
* SIDE EFFECTS: None Known
*
* DESIGNER NOTES: Can be implemented by asm
*
* DEPENDENCIES: None
*******************************************************************************/
can_sData* CANStdRcvPrepare( CANADDRESSTYPE canID )
{

	can_sReadBuffer* pBuf;
	register can_sData* pData = 0;
	
    for( pBuf = sIState.pRxBuffer;
                pBuf < pLastRead;
                        pBuf = (can_sReadBuffer*)((char*)pBuf + sIState.RxSize))
    {
        if( pBuf->canID == canID )
        {
            pData = &pBuf->data[0];
            if( pData->length != 0 )
                pBuf->flags |= CAN_BUF_OVERFLOW; 
            else
                pBuf->flags |= CAN_BUF_FULL; 
        }
    }
    return pData;
   
}

/*******************************************************************************
*
* NAME: CANEvlFlag
*
* DESCRIPTION: Evaluate CAN flags to obtain interrupt flags
*
********************************************************************************
* PARAMETERS:   current flag set 
*
* SIDE EFFECTS: None Known
*
* DESIGNER NOTES: 
*
* DEPENDENCIES: None
*******************************************************************************/
UWord16 CANEvlFlag( UWord16 flg )
{
    return(  (CANWUPIE | CANRXFIE) | ~( flg | ~CANWATCHFLAG )   );
}

/*******************************************************************************
*
* NAME: GetCANID
*
* DESCRIPTION: Compose 11/29-bit CAN ID from the registers values
*
********************************************************************************
* PARAMETERS:   Address of the registers 
*
* SIDE EFFECTS: None Known
*
* DESIGNER NOTES: 
*
* DEPENDENCIES: None
*******************************************************************************/
CANADDRESSTYPE GetCANID( volatile UWord16* pAddr )
{
#if defined( CAN20B )
    /*  29-bit CAN ID is taken from four MSCAN registers in the following way:
        xxxxxxxx                                IdReg0
                 xxx11xxx                       IdReg1
                          xxxxxxxx              IdReg2
                                    xxxxxxx0    IdReg3
        xxxxxxxx  xxxxxx  xxxxxxxx  xxxxxxx     29-bit CAN ID  */

        return        ( (UWord32)periphMemRead(&pAddr[0]) << 21)
                    | (((UWord32)periphMemRead(&pAddr[1]) & 0xE0) << 13)
                    | (((UWord32)periphMemRead(&pAddr[1]) & 0x7) << 15)
                    | ( (UWord32)periphMemRead(&pAddr[2]) << 7)
                    | ( (UWord32)periphMemRead(&pAddr[3]) >> 1)
                    ;
#else /*  defined (CAN20B) */
    return ( periphMemRead(&pAddr[0]) << 3 )
                    | ( periphMemRead(&pAddr[1]) >> 5 );
#endif /* defined (CAN20B) */
}

/*******************************************************************************
*
* 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 UWord16* pAddr, CANADDRESSTYPE canID )
{
#if defined( CAN20B )
	/* if (canID>0x07FF) */
    /*  29-bit CAN ID is placed into four MSCAN registers in the following way:
        xxxxxxxx                                IdReg0
                 xxx11xxx                       IdReg1
                          xxxxxxxx              IdReg2
                                    xxxxxxx0    IdReg3
        xxxxxxxx  xxxxxx  xxxxxxxx  xxxxxxx     29-bit CAN ID  */
        
    periphMemWrite( (UWord16)(canID >> 21), &pAddr[0] );

    /* check carefully ! */

    periphMemWrite( 
        (UWord16)(( ((canID >> 15) & 0x7) | 0x18 | ((canID >> 13) & 0xE0))), &pAddr[1] );
    periphMemWrite( (UWord16)(canID >> 7), &pAddr[2] );
    periphMemWrite( (UWord16)(canID << 1), &pAddr[3] );

#else /*  defined (CAN20B) */

    periphMemWrite( canID >> 3, &pAddr[0]);   
    periphMemWrite( canID << 5, &pAddr[1]); 

#endif /* defined (CAN20B) */
}

/*******************************************************************************
*
* NAME: CANSetFilter
*
* DESCRIPTION: Set CANCIDARs and CANCIDMRs
*
********************************************************************************
* PARAMETERS:   
*
* SIDE EFFECTS: None Known
*
* DESIGNER NOTES: 
*
* DEPENDENCIES: None
*******************************************************************************/
UWord16 CANSetFilter() 
{
#if defined(CAN20B)
        SetCANID( &ArchIO.CAN.IdAcceptReg0, sCANFilterMirror[0].code );
        SetCANID( &ArchIO.CAN.IdAcceptReg4, sCANFilterMirror[1].code );

        SetCANID( &ArchIO.CAN.IdMaskReg0, sCANFilterMirror[0].mask );
        SetCANID( &ArchIO.CAN.IdMaskReg4, sCANFilterMirror[1].mask );

		if( actFilterLimit > 0)
			periphBitSet(0x1, &ArchIO.CAN.IdMaskReg3 );
		if( actFilterLimit > 1)
			periphBitSet(0x1, &ArchIO.CAN.IdMaskReg7);

#else /* defined (CAN20B) */

        SetCANID( &ArchIO.CAN.IdAcceptReg0, sCANFilterMirror[0].code );
        SetCANID( &ArchIO.CAN.IdAcceptReg2, sCANFilterMirror[1].code );
        SetCANID( &ArchIO.CAN.IdAcceptReg4, sCANFilterMirror[2].code );
        SetCANID( &ArchIO.CAN.IdAcceptReg6, sCANFilterMirror[3].code );

        SetCANID( &ArchIO.CAN.IdMaskReg0, sCANFilterMirror[0].mask );
        SetCANID( &ArchIO.CAN.IdMaskReg2, sCANFilterMirror[1].mask );
        SetCANID( &ArchIO.CAN.IdMaskReg4, sCANFilterMirror[2].mask );
        SetCANID( &ArchIO.CAN.IdMaskReg6, sCANFilterMirror[3].mask );

		if( actFilterLimit > 0)
			periphBitSet(0x7, &ArchIO.CAN.IdMaskReg1 );
		if( actFilterLimit > 1)
			periphBitSet(0x7, &ArchIO.CAN.IdMaskReg3 );
		if( actFilterLimit > 2) 
			periphBitSet(0x7, &ArchIO.CAN.IdMaskReg5 );
		if( actFilterLimit > 3)
			periphBitSet(0x7, &ArchIO.CAN.IdMaskReg7);

#endif /* defined (CAN20B) */

return 0;
}

/*******************************************************************************
*
* NAME: CANInit
*
* DESCRIPTION: Initialize MSCAN device
*              
********************************************************************************
* PARAMETERS:   
*
* SIDE EFFECTS: None Known
*
* DESIGNER NOTES: 
*
* DEPENDENCIES: None
*******************************************************************************/
static UWord16 CANInit()
{
    UWord16 i;
    can_sWriteBuffer* pWriteBuf;
    can_sReadBuffer* pReadBuf;

    periphBitSet(CANSFTRES, &ArchIO.CAN.Control0Reg);         /* set soft reset bit */ 

    for( pWriteBuf = sIState.pTxBuffer; 
                pWriteBuf < pLastWrite; 
                        pWriteBuf++ )
    {
        if( pWriteBuf->flags & ( CAN_IDX_BUF0 | CAN_IDX_BUF1 | CAN_IDX_BUF2 | CAN_BUF_PENDING )  )
        {
            pWriteBuf->flags |= CAN_BUF_ERROR;
            pWriteBuf->flags &= ~( CAN_IDX_BUF0 | CAN_IDX_BUF1 | CAN_IDX_BUF2 | CAN_BUF_PENDING );
        }
    }

    for( pReadBuf = sIState.pRxBuffer;
                pReadBuf < pLastRead;
                        pReadBuf++ )
    {
        pReadBuf->data[0].length = 0;
        pReadBuf->flags &= ~( CAN_BUF_FULL | CAN_BUF_OVERFLOW );
    }


    msprio = CANLOWESTPRIO;

    periphMemWrite( sIState.regCMCR1,  &ArchIO.CAN.Control1Reg ); 
    periphMemWrite( sIState.regCBTR0,  &ArchIO.CAN.BusTiming0Reg ); 
    periphMemWrite( sIState.regCBTR1,  &ArchIO.CAN.BusTiming1Reg ); 
    periphMemWrite( CANFILTERMODE,     &ArchIO.CAN.IdControlReg ); 

    CANSetFilter();
    
    periphBitClear(CANSFTRES, &ArchIO.CAN.Control0Reg ); /* clear SFTRES bit */
    periphMemWrite( sIState.regCMCR0 & 0x28 , &ArchIO.CAN.Control0Reg );
    
    periphMemWrite( 0,  &ArchIO.CAN.TxControlReg );  
    
    /* no Tx interrupt, controling by  handler */
    
    periphMemWrite( CANWATCHFLAG, &ArchIO.CAN.RxFlagReg ); 
    periphMemWrite( CANEvlFlag( periphMemRead(&ArchIO.CAN.RxFlagReg) ), 
                                                &ArchIO.CAN.RxIntEnableReg );
    
    return 0;
}


/*******************************************************************************
*
* NAME: CANReceiveISR
*
* DESCRIPTION: receive ISR handler
*
********************************************************************************
* PARAMETERS:   
*
* SIDE EFFECTS: Slowest handler in the driver, impacts to the interrupt lattency
*
* DESIGNER NOTES: copy is not effective on C, recomended to use asm
*
* DEPENDENCIES: None
*******************************************************************************/
void CANReceiveISR(void)
{
    register  can_sData* pCrd;

    while( periphBitTest(CANRXF, &ArchIO.CAN.RxFlagReg) )     /* RX buffer ready */
    {
      pCrd = (*CANRcvPrepare)( GetCANID(&ArchIO.CAN.RxBuffer.IdReg0) ); /* CANStdRcvPrepare */
        if( pCrd ) 
        {   
            pCrd->length =  ( periphMemRead(&ArchIO.CAN.RxBuffer.DataLengthReg) ) & 0x000F;
            pCrd->data[0] = periphMemRead(&ArchIO.CAN.RxBuffer.DataSegReg[0]);
            pCrd->data[1] = periphMemRead(&ArchIO.CAN.RxBuffer.DataSegReg[1]);
            pCrd->data[2] = periphMemRead(&ArchIO.CAN.RxBuffer.DataSegReg[2]);
            pCrd->data[3] = periphMemRead(&ArchIO.CAN.RxBuffer.DataSegReg[3]);
            pCrd->data[4] = periphMemRead(&ArchIO.CAN.RxBuffer.DataSegReg[4]);
            pCrd->data[5] = periphMemRead(&ArchIO.CAN.RxBuffer.DataSegReg[5]);
            pCrd->data[6] = periphMemRead(&ArchIO.CAN.RxBuffer.DataSegReg[6]);
            pCrd->data[7] = periphMemRead(&ArchIO.CAN.RxBuffer.DataSegReg[7]);
        }
        periphBitSet( CANRXF, &ArchIO.CAN.RxFlagReg );   /* free RX */
    }
    return;
}


/*******************************************************************************
*
* NAME: CANSendISR
*
* DESCRIPTION: send ISR handler
*
********************************************************************************
* PARAMETERS:   
*
* SIDE EFFECTS: None Known
*
* DESIGNER NOTES: 
*
* DEPENDENCIES: None
*******************************************************************************/
void CANSendISR(void)
{
    register UWord16 idx;
    can_sWriteBuffer* pBuf;

    idx = periphMemRead(&ArchIO.CAN.TxControlReg) & periphMemRead(&ArchIO.CAN.TxFlagReg);

⌨️ 快捷键说明

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