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

📄 mscan.c

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

    memcpy(pBuffer, pSrc, len );

    /* enable source isr */
    periphBitSet( CANRXFIE, &ArchIO.CAN.RxIntEnableReg );

    return len;
    
}


/*******************************************************************************
*
* NAME: Write
*
* DESCRIPTION: Driver write procedure
*              
********************************************************************************
* PARAMETERS:   file descriptor, buffer and size
*
* SIDE EFFECTS: None Known
*
* DESIGNER NOTES: handler is pointer to the buffer, 
*                 truncation is possible when porting
*
*                 In case when CAN_8BIT data type is specified, data taken from
*                 the buffer is considered to be a 8-bit char, and is placed into 
*                 single transmission register 
*                 In case of CAN_16BIT data type the data from the buffer 
*                 is considered to be of a 16-bit value and is decomposed 
*                 to be placed in two transmission registers.
*               
* DEPENDENCIES: None 
*******************************************************************************/
ssize_t canWrite(handle_t FileDesc, const void *pBuffer, size_t size)
{
	register UWord16 msProp;  /* current property *//* static because board memory or compiller bug */
	static UWord16 save; 	  /* static because board memory or compiller bug */
    can_sWriteBuffer* pBuf = (can_sWriteBuffer*)FileDesc;    
    
    unsigned char *data = (unsigned char*)pBuffer; 
    arch_sMSCANBuffer* pHBuf;
   	UWord16 i;
    
// 	static can_sData       cdata;        /* CAN send data */

    /* wait in case synchronouse */
    if (pBuf->flags & CAN_BUF_SYNCHRONOUS)
    {
	    msProp = 0xFF00;    
   		while( !periphBitTest(CANSYNCH, &ArchIO.CAN.Control0Reg) ) /* synchronization test */
	    {
   		    msProp += 1; /* 1 * 256 delays cycle */
       		if( msProp == 0 ) 
	        {
   		        CANErrno = CAN_ERR_SYNCH;
       		    return -1;
	        }
   		}
	    
	    if( periphBitTest( CANBOFFIF, &ArchIO.CAN.RxFlagReg) ) /* bus-off test */ 
    	{
        	CANErrno = CAN_ERR_BUSOFF;
	        return -1;
    	}
   	}

    msProp = CANDll[ periphMemRead(&ArchIO.CAN.TxFlagReg) & (CANTXE0 | CANTXE1 | CANTXE2)]; /* Check free buffers */

    if( msProp & CANM_ALLFREE ) 
        msprio = CANLOWESTPRIO;    /* if all buffers are free - reset the priority */

    if( !(pBuf->flags & CAN_BUF_PRIORITY_SCHEDULE ) )
    {
        if( msprio >= 256 )
        {
            CANErrno = CAN_ERR_BUSY;
            return( -1 );
        }
        pBuf->priority = msprio;
        msprio++;
    }
    
    if( msProp & CANM_ALLBUSY )
    {               
    	/* all Tx buffers busy */
        CANErrno = CAN_ERR_BUSY;
        return -1;
    }
    
 /* disable interrupts ( ISRs  and errors ) */
    save = periphMemRead( &ArchIO.CAN.TxControlReg);  
    periphMemWrite( 0, &ArchIO.CAN.TxControlReg);  
    periphBitClear( CANERRORFLAG, &ArchIO.CAN.RxIntEnableReg );

    if ( size > 8 ) 
    		size = 8;

//    memcpy( cdata.data, pBuffer, size );
//    cdata.length = size;

    pBuf->flags |= CAN_BUF_PENDING;

    msProp &= 0x07;

/*    CANTransmit( msProp , pBuf, &cdata ); */
	
    pHBuf = &ArchIO.CAN.TxBuffer[ (msProp >> 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 |= msProp;
   	SetCANID( &pHBuf->IdReg0, pBuf->canID );

    periphMemWrite( size ,  &pHBuf->DataLengthReg );

    for(i=0;i<size;i++)
   		periphMemWrite( *data++,  &pHBuf->DataSegReg[i] );
    		
   	periphMemWrite( pBuf->priority,  &pHBuf->U.TxBufferPriorityReg );

    /* hardware send */
    periphMemWrite(msProp, &ArchIO.CAN.TxFlagReg);    /* send */
                        
    /* enable interrupts */
    periphMemWrite( CANWATCHFLAG, &ArchIO.CAN.RxFlagReg ); 
    periphBitSet( msProp | save, &ArchIO.CAN.TxControlReg);   /* isr for identified buffer */
    periphMemWrite( CANEvlFlag( periphMemRead(&ArchIO.CAN.RxFlagReg) ),
                                             &ArchIO.CAN.RxIntEnableReg );
                                                                                          
    /* wait in case synchronouse */
    if (pBuf->flags & CAN_BUF_SYNCHRONOUS)
    {
        while( 1 )
        {
            if( ioctlCANID_GET_STATUS((handle_t)pBuf, 0 ) & CANID_EMPTY )
                break;
        }
        if( pBuf->flags & CAN_BUF_ERROR )
        {
            CANErrno = CAN_ERR_LOST;
            return (-1);
        }
    }

    return size;
}

/*******************************************************************************
*
* NAME: ioctlCANID_GET_STATUS
*
* DESCRIPTION: Driver i/o control procedure - Gets status of message buffer
*              
********************************************************************************
* PARAMETERS:       file descriptor, command and parameters list
*
* SIDE EFFECTS:     None Known
*
* DESIGNER NOTES:   returned status value can be one of the following:
*                           CANID_EMPTY - no messages in the message buffer
*                           CANID_FULL - a message is in the message buffer
*                           CANID_OVERFLOW - a READ message buffer queue is full
*                                           and received message was lost 
*
* DEPENDENCIES:     None
*******************************************************************************/
EXPORT UWord16 ioctlCANID_GET_STATUS(handle_t FileDesc, void * pParams )      
{
	can_sReadBuffer * pHandle = (can_sReadBuffer *)FileDesc;
	
    if ( ((can_sReadBuffer*) pHandle)->flags & CAN_BUF_READ_HANDLE )
    {
        register UWord16 status = 0;
        can_sReadBuffer* pBuf = (can_sReadBuffer*) pHandle;

        if( ((can_sReadBuffer*) pHandle)->flags & CAN_BUF_OVERFLOW )
            status = CANID_OVERFLOW;
        else if( ((can_sReadBuffer*) pHandle)->flags & CAN_BUF_FULL )
            status = CANID_FULL;
        if(  ((can_sReadBuffer*) pHandle)->data[0].length == 0 )
            status  = CANID_EMPTY;
        return status;
    }
    else
    {
		register idx;

        idx =((can_sWriteBuffer*) pHandle)->flags & ( CAN_IDX_BUF0 | CAN_IDX_BUF1 | CAN_IDX_BUF2 );

        if( idx & ~periphMemRead(&ArchIO.CAN.TxFlagReg)  )
        {   
            if( ((can_sWriteBuffer*) pHandle)->canID == 
                    GetCANID((volatile UWord16 *)(&ArchIO.CAN.TxBuffer[ idx >> 1 ])) )  /* additional check */
                return CANID_FULL;
            else 
                return CANID_EMPTY; 
        }
        else
        {   /* buffer ready */
            return CANID_EMPTY;
        }
    }

}

/*******************************************************************************
*
* NAME: ioctlCAN_RESET
*
* DESCRIPTION: Driver i/o control procedure - Reset CAN Driver
*              
********************************************************************************
* PARAMETERS:       file descriptor,  parameters list
*
* SIDE EFFECTS:     None Known
*
* DESIGNER NOTES:  
*
* DEPENDENCIES:     None
*******************************************************************************/
EXPORT UWord16 ioctlCAN_RESET(handle_t FileDesc, void * pParams )
{
    CANInit();
    return 0;
}


/*******************************************************************************
*
* NAME: ioctlCAN_SET_SLEEP
*
* DESCRIPTION: Driver i/o control procedure - Sets CAN into SLEEP mode
*              
********************************************************************************
* PARAMETERS:       file descriptor, command and parameters list
*
* SIDE EFFECTS:     None Known
*
* DESIGNER NOTES:   
*
* DEPENDENCIES:     None
*******************************************************************************/
EXPORT UWord16 ioctlCAN_SET_SLEEP(handle_t FileDesc, void * pParams )
{
    periphBitSet(CANSLPRQ, &ArchIO.CAN.Control0Reg ); /* goto sleep mode */
    return 0;
}

/*******************************************************************************
*
* NAME: ioctlCAN_SET_WAKEUP
*
* DESCRIPTION: Driver i/o control procedure - Wakeups CAN
*              
********************************************************************************
* PARAMETERS:       file descriptor, command and parameters list
*
* SIDE EFFECTS:     None Known
*
* DESIGNER NOTES:   
*
* DEPENDENCIES:     None
*******************************************************************************/
EXPORT UWord16 ioctlCAN_SET_WAKEUP(handle_t FileDesc, void * pParams )
{
    if( periphBitTest(CANSLPRQ, &ArchIO.CAN.Control0Reg )  )
        periphBitClear(CANSLPRQ, &ArchIO.CAN.Control0Reg );
    return 0;
}

/*******************************************************************************
*
* NAME: ioctlCAN_GET_STATUS
*
* DESCRIPTION: Driver i/o control procedure - Gets status of CAN control registers
*              
********************************************************************************
* PARAMETERS:       file descriptor, command and parameters list
*
* SIDE EFFECTS:     None Known
*
* DESIGNER NOTES:   returned status value is composed of CANCTL0 + CANRFLG
*
* DEPENDENCIES:     None
*******************************************************************************/
EXPORT UWord16 ioctlCAN_GET_STATUS(handle_t FileDesc, void * pParams )
{
 /* *(UWord16*)pParams =  */
    return  ( periphMemRead(&ArchIO.CAN.Control0Reg ) << 8 )
           | periphMemRead( &ArchIO.CAN.RxFlagReg );

}

/*******************************************************************************
*
* NAME:             Close
*
* DESCRIPTION:      Driver close procedure
*              
********************************************************************************
* PARAMETERS:       file descriptor
*
* SIDE EFFECTS:     filters is staying open
*
* DESIGNER NOTES:   close corresponding message buffer
*
* DEPENDENCIES:     None
*******************************************************************************/
int canClose(handle_t FileDesc)
{
	can_sReadBuffer * pHandle = (can_sReadBuffer *)FileDesc;

    if ( ((can_sReadBuffer*) pHandle)->flags & CAN_BUF_READ_HANDLE )
    {
        if( (char*)pHandle == ((char*)pLastRead) - sIState.RxSize )
        {
            ((can_sReadBuffer*) pHandle)->flags = 0;
            ((can_sReadBuffer*) pHandle)->data[0].length = 0;
			pLastRead = (can_sReadBuffer*)(((char*)pLastRead)-sIState.RxSize);
        }
        else
        {
            return -1;
        }
    }
    else 
    {
        if( (can_sWriteBuffer*)pHandle == pLastWrite - 1 ) /* correct */
        {
            ((can_sWriteBuffer*) pHandle)->flags = 0;
            pLastWrite--;
        }
        else
        {
            return -1;
        }
    }
    return 0;
}

/*******************************************************************************
*
* NAME:             CANDevCreat
*
* DESCRIPTION:      Create CAN driver device installation
*              
********************************************************************************
* PARAMETERS:       A pointer to the initialization structure of type 
*                   can_sInitialState
*
* SIDE EFFECTS:     None Known
*
* DESIGNER NOTES:   The MSCAN interrupts installation and device initialization.
*
* DEPENDENCIES:     None
*******************************************************************************/
UWord16 CANDevCreat(const can_sInitialState* pInitialState)
{
/*  UWord16 driverNumber;	*/
    sIState = *pInitialState; /* need to copy user driver configuration */

/*    driverNumber = ioDrvInstall(canOpen); */
    
#if 0    /* install ISR - obsolete */
    archInstallISR(&(pArchInterrupts->MscanReceiverReady), CANReceiveISR);
    archInstallISR(&(pArchInterrupts->MscanTransmiterReady), CANSendISR);
    archInstallISR(&(pArchInterrupts->MscanError), CANErrorISR);
    archInstallISR(&(pArchInterrupts->MscanWakeup), CANWakeUpISR);
#endif /* 0 */

    pLastRead  = sIState.pRxBuffer;
    pLastWrite = sIState.pTxBuffer;

#if 0    /* install raw callback - done statically */
    if (sIState.pRawCallBack != NULL)
        CANRcvPrepare = sIState.pRawCallBack;
    else
        CANRcvPrepare = CANStdRcvPrepare;
#endif /* 0 */

    actFilterLimit = 0;
    if (sIState.code <= CANIDMASK)
    {   /* set custom filter */
        sCANFilterMirror[0].code = (CANADDRESSTYPE)(sIState.code);
        sCANFilterMirror[0].mask = (CANADDRESSTYPE)(sIState.mask);
        actFilterLimit = 1;
    }

    CANInit();

    return 0;

}
#endif /* defined(DSP56838EVM) */

⌨️ 快捷键说明

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