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

📄 mscan.c

📁 56f8300E系列dsp的BOOTloader
💻 C
📖 第 1 页 / 共 3 页
字号:

    idx = CANDll[ idx & 0x07 ] & 0x07;

    periphBitClear(idx, &ArchIO.CAN.TxControlReg ); /* clear corresponded flag */

    periphMemWrite( CANWATCHFLAG, &ArchIO.CAN.RxFlagReg ); /* clear error if possible */
    periphMemWrite( CANEvlFlag( periphMemRead(&ArchIO.CAN.RxFlagReg) ),
                                             &ArchIO.CAN.RxIntEnableReg );
}

/*******************************************************************************
*
* NAME: CANTransmit
*
* DESCRIPTION: CAN send buffer 
*
********************************************************************************
* PARAMETERS:   
*
* SIDE EFFECTS: None Known
*
* DESIGNER NOTES: 
*
* DEPENDENCIES: None
*******************************************************************************/
void CANTransmit( UWord16 idx, can_sWriteBuffer* pBuf, can_sData* pData )
{
    arch_sMSCANBuffer* pHBuf = &ArchIO.CAN.TxBuffer[ idx >> 1 ]; /* 1, 2, 4 -> 0, 1, 2 */
    pBuf->flags &= ~( CAN_IDX_BUF0 | CAN_IDX_BUF1 | CAN_IDX_BUF2 | CAN_BUF_ERROR | CAN_BUF_PENDING );
    pBuf->flags |= idx;
    SetCANID( &pHBuf->IdReg0, pBuf->canID );

    periphMemWrite( pData->length ,  &pHBuf->DataLengthReg );
    periphMemWrite( pData->data[0],  &pHBuf->DataSegReg[0] );
    periphMemWrite( pData->data[1],  &pHBuf->DataSegReg[1] );
    periphMemWrite( pData->data[2],  &pHBuf->DataSegReg[2] );
    periphMemWrite( pData->data[3],  &pHBuf->DataSegReg[3] );
    periphMemWrite( pData->data[4],  &pHBuf->DataSegReg[4] );
    periphMemWrite( pData->data[5],  &pHBuf->DataSegReg[5] );
    periphMemWrite( pData->data[6],  &pHBuf->DataSegReg[6] );
    periphMemWrite( pData->data[7],  &pHBuf->DataSegReg[7] );
    periphMemWrite( pBuf->priority,  &pHBuf->U.TxBufferPriorityReg );

        /* hardware send */
    periphMemWrite(idx, &ArchIO.CAN.TxFlagReg);    /* send */
}



/*******************************************************************************
*
* NAME: CANErrorISR
*
* DESCRIPTION: error ISR handler 
*
********************************************************************************
* PARAMETERS:   
*
* SIDE EFFECTS: None Known
*
* DESIGNER NOTES: 
*
* DEPENDENCIES: None
*******************************************************************************/
void CANErrorISR(void)
{
    if( periphBitTest(CANBOFFIF, &ArchIO.CAN.RxFlagReg) )  /* bus-off ? */
    {
        CANInit();
    }
            /* try to clear all errors */
    periphMemWrite( CANWATCHFLAG, &ArchIO.CAN.RxFlagReg ); 
    periphMemWrite( CANEvlFlag( periphMemRead(&ArchIO.CAN.RxFlagReg) ),
                                             &ArchIO.CAN.RxIntEnableReg );
}



/*******************************************************************************
*
* NAME: CANWakeUpISR
*
* DESCRIPTION: wakeup ISR handler 
*
********************************************************************************
* PARAMETERS:   
*
* SIDE EFFECTS: None Known
*
* DESIGNER NOTES: 
*
* DEPENDENCIES: None
*******************************************************************************/
void CANWakeUpISR(void)  /* CAN Wake up */
{
    periphMemWrite( CANWUPIF, &ArchIO.CAN.RxFlagReg ); /* reset by 1 */
}


/*******************************************************************************
*
* NAME: CANFilterWeight
*
* DESCRIPTION: weight function to define optimal appropriate filter for 
*              incoming CAN ID
********************************************************************************
* PARAMETERS:   CAN ID, current code and mask
*
* SIDE EFFECTS: None Known
*
* DESIGNER NOTES: 
*
* DEPENDENCIES: None
*******************************************************************************/
int CANFilterWeight( CANADDRESSTYPE canID, CANADDRESSTYPE code, CANADDRESSTYPE mask )
{
    CANADDRESSTYPE tmp;
    CANADDRESSTYPE d;
    int i = 0;

    if( code == 0 && mask == 0 )
        return 0; /* not used yet */
    tmp = ( code ^ canID ) & ~mask;  /* distance for the input filter */

    while(1)
    {
        d = ~( ~tmp + 1);
        if( (tmp & d) != 0 )
        {
            tmp &= d;
            i++;
        }
        else return i;
    } 
}

/*******************************************************************************
*
* 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, UWord16 mode )
{
    register void* pBuf;

    if( !( mode & (CANLOOPB) >> 1 )   )    
        for( pBuf = sIState.pRxBuffer; 
                pBuf < pLastRead; 
                        ((char*)pBuf) += sIState.RxSize )
    {
        if( ((can_sReadBuffer*)pBuf)->canID == canID)  /* checking receive buffers */
        {
            CANErrno = CAN_ERR_REOPEN;
            return 0;  
        }
    }
    
    if( !( mode & (CANLOOPB)  )   )    
        for( pBuf = sIState.pTxBuffer; 
                pBuf < pLastWrite; 
                        ((char*)pBuf) += sizeof(can_sWriteBuffer)  )
    {
        if( ((can_sWriteBuffer*)pBuf)->canID == canID) /* checking send buffers */
        {
            CANErrno = CAN_ERR_REOPEN;
            return 0;  /* error: re-open is not possible */
        }
    }

    return 1;

}

/*******************************************************************************
*
* NAME: Open
*
* DESCRIPTION: driver Open procedure: open CAN device,  receive and send CAN ID
*              
********************************************************************************
* PARAMETERS:   device name, open flags, pointer to initialization structure
*               of type can_sInitialState
*
* 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
*					O_CAN_PRIORITY_SCHEDULE
*
* DEPENDENCIES: None
*******************************************************************************/
handle_t  canOpen(const char * pName, int oFlags, ...)
{
	int i;
	va_list    Args;
	CANADDRESSTYPE canID;

	Args = (char *)&oFlags;

	canID = va_arg(Args, CANADDRESSTYPE);

	va_end(Args);

    if( pName != BSP_DEVICE_NAME_CAN_0 )
    {
        return (handle_t ) -1;
    }

    /***    open for read ( reception )   ***/  
    if( (UWord16)oFlags & O_RDONLY   )
    {
	can_sReadBuffer* pRead;	
	long xi;	
	long xweight = 0xFF;
	long weight;	 
	
              
        if( !CheckCANID( canID, sIState.regCMCR1 & CANLOOPB )   ) 
        {
             CANErrno = CAN_ERR_REOPEN;
             return (handle_t )-1; /* error: no more driver buffers */
        }

        if( pLastRead >= sIState.pLastRx )
        {
            CANErrno = CAN_ERR_NO_BUFFERS;
            return (handle_t )-1; /* error: no more driver buffers */
        }

        pRead = pLastRead;
		
		pLastRead =	(can_sReadBuffer*)((char*) pLastRead + sIState.RxSize);

        pRead->flags = CAN_BUF_READ_HANDLE;

        pRead->drvInterface = (io_sInterface *)&canInterfaceVT; /* interfaceCAN_Rx; */

        pRead->canID = canID; 

        
        if( !((UWord16)oFlags & O_NONBLOCK) )
            pRead->flags |= CAN_BUF_SYNCHRONOUS;
        
        if( actFilterLimit < CANFILTERLIMIT )/* CAN20B can be defines from canID*/
        {
            sCANFilterMirror[actFilterLimit].code = canID;
            sCANFilterMirror[actFilterLimit].mask = 0;
            actFilterLimit++;
        }
        else
        {   /* filter limit is exhausted, looking for appropriate filter */
			
            for( i = 0; i < CANFILTERLIMIT; i++  )
            {
                weight = CANFilterWeight( canID, 
                                     sCANFilterMirror[i].code,
                                     sCANFilterMirror[i].mask
                                    );

                if( weight < xweight )  /* definition of optimal filter */
                {
                    xweight = weight;
                    xi = i;
                }
            }
            sCANFilterMirror[xi].mask |=  
                canID ^ sCANFilterMirror[xi].code;
        }

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

        /* No need to disable interrupts  since all MSCAN interrupts
           are disabled now 
        */
        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, defined in common mask */
        /* *** */
        periphMemWrite( 0, &ArchIO.CAN.TxControlReg );        /*  no Tx interrupt, controling by DLL handler */
        periphMemWrite( CANWATCHFLAG, &ArchIO.CAN.RxFlagReg );
        periphMemWrite( CANEvlFlag( periphMemRead(&ArchIO.CAN.RxFlagReg ) ),
                                         &ArchIO.CAN.RxIntEnableReg );
                                          
        return (handle_t )pRead; 
    }
    /***   open for write ( transmission )  ***/    
    else if( (UWord16)oFlags & O_WRONLY )
    {
    	UWord16 test = sizeof(can_sWriteBuffer);
        can_sWriteBuffer* pWrite;

        if( !CheckCANID( canID, (sIState.regCMCR1 & CANLOOPB) >> 1 )   ) 
        {
            CANErrno = CAN_ERR_REOPEN;
            return (handle_t )-1; /* error: ID has been opened yet */
        }

        if( pLastWrite >= sIState.pLastTx )
        {
            CANErrno = CAN_ERR_NO_BUFFERS;
            return (handle_t )-1; /* error: no more driver buffers */
        }
        
        
        pWrite = pLastWrite;
        pLastWrite++;  /* next buffer */

        pWrite->drvInterface = (io_sInterface *)&canInterfaceVT; /* interfaceCAN_Tx; */

        pWrite->flags = 0; /* CAN_BUF_WRITE_HANDLE */

        pWrite->canID = canID; 

        if( !((UWord16)oFlags & O_NONBLOCK) )
            pWrite->flags |= CAN_BUF_SYNCHRONOUS;

        /* message schedule block */
        if ((UWord16)oFlags & O_CAN_PRIORITY_SCHEDULE)
        {
            pWrite->flags |= CAN_BUF_PRIORITY_SCHEDULE;

            /* work for restricted ranges */
            pWrite->priority = 
                (UWord16)((pWrite->canID) >> (CANIDSIZE - 7));          
        }

        return (handle_t )pWrite; 
    }

    CANErrno = CAN_ERR_PARAMETER;
    return (handle_t )-1; /* flag error */
    
}

/*******************************************************************************
*
* NAME: Read
*
* DESCRIPTION: Driver read procedure
*              
********************************************************************************
* PARAMETERS:   file descriptor, buffer and size
*
* SIDE EFFECTS: None Known
*
* DESIGNER NOTES: handler is pointer to the bufffer, 
*                 truncation is possible when porting
*                 In case when CAN_8BIT data type is specified, data from one 
*                 receiving register is considered to be of a single 8-bit 
*                 char value.
*                 In case of CAN_16BIT data type the data from two receiving 
*                 registers is composed to a single 16-bit value.
*               
*               
* DEPENDENCIES: None
*******************************************************************************/
ssize_t canRead(handle_t FileDesc,void *pBuffer, size_t size)
{
	//can_sReadBuffer * pHandle = (can_sReadBuffer *)FileDesc;
    can_sReadBuffer* pBuf = (can_sReadBuffer*) FileDesc;
    register char* pSrc;
    
    ssize_t len; 
    
    /* disable source isr */
    periphBitClear( CANRXFIE, &ArchIO.CAN.RxIntEnableReg );

    pSrc = (char *)(&pBuf->data[0]);
        pBuf->flags &= ~(CAN_BUF_FULL | CAN_BUF_OVERFLOW);
    
    len = ((can_sData*)pSrc)->length;
    ((can_sData*)pSrc)->length = 0;  /* mark data as free */

    pSrc = (char *)(((can_sData*)pSrc)->data);

    if( len > size ) 
            len = size;  

⌨️ 快捷键说明

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