📄 mscan.c
字号:
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 + -