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

📄 flexcan.c

📁 56f8300E系列dsp的BOOTloader
💻 C
📖 第 1 页 / 共 3 页
字号:
    asm( move.w # CANID_EMPTY,  Y0 ); /* for case of interim code */
    asm( bra end_status );

tx_case:
    asm( move.w X:( BSP_PERIPH_BASE + archoff_FlexCAN_IntMask1Reg ), X0 );
    asm( and.w X0, B );    /* check bit in flag register */
    asm( beq end_status );
    asm( move.w # CANID_FULL ,  Y0 );

end_status:
    ;

}


/*******************************************************************************
*
* 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
*******************************************************************************/
unsigned int ioctlCAN_RESET(handle_t FileDesc, unsigned long params )
{
    register int i;

    FC_Init();

    for( i = nBottomRead;  i  < 16; i++ )
    {
         /* MB is active for receive data */
        periphMemWrite( FC_MB_ACTIVE,   &ArchIO.CAN.Buffer[i].CtlStatusReg );   
    }

    return 0;
}


/*******************************************************************************
*
* NAME: ioctlCAN_SET_SLEEP
*
* DESCRIPTION: Driver i/o control  - Sets CAN into SLEEP(power save) mode
*              
********************************************************************************
* PARAMETERS:       file descriptor, command and parameters list
*
* SIDE EFFECTS:     None Known
*
* DESIGNER NOTES:   
*
* DEPENDENCIES:     None
*******************************************************************************/
unsigned int ioctlCAN_SET_SLEEP(handle_t FileDesc, unsigned long params )
{
    periphBitSet(CAN_STOP, &ArchIO.CAN.ConfigReg ); /* goto low power sleep mode */
    return (unsigned int)periphBitTest( CAN_STOP_ACK, &ArchIO.CAN.ConfigReg ) ;
}

/*******************************************************************************
*
* 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
*******************************************************************************/
unsigned int ioctlCAN_SET_WAKEUP(handle_t FileDesc, unsigned long params )
{
    periphBitSet(CAN_SELF_WAKE, &ArchIO.CAN.ConfigReg ); /* goto wake up mode */
    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
*******************************************************************************/
unsigned int ioctlCAN_GET_STATUS(handle_t FileDesc, unsigned long params )
{
    unsigned int status;

    status = periphMemRead( &ArchIO.CAN.StatusReg );
    if( !(status & 0xFC00) )
        status |= 0x0008;

    return status;
}

/*******************************************************************************
*
* NAME:             Close
*
* DESCRIPTION:      Driver close procedure
*              
********************************************************************************
* PARAMETERS:       file descriptor
*
* SIDE EFFECTS:     filters is staying open
*
* DESIGNER NOTES:   close corresponding message buffer
*
* DEPENDENCIES:     None
*******************************************************************************/
int flexcanClose(handle_t handle)
{
    unsigned int i = ((can_sBuffer*)handle)->flags & 0x000F;

    if ( ((can_sBuffer*)handle)->flags & CAN_BUF_READ_HANDLE )
    {
        if( i == nBottomRead )
        {
            nBottomRead++;
            ((can_sBuffer*)handle)->flags = 0;
        }
        else
        {
            return -1;
        }
    }
    else 
    {
        if( i == nTopWrite - 1 ) /* correct */
        {
            nTopWrite--;
            ((can_sBuffer*)handle)->flags = 0;
        }
        else
        {
            return -1;
        }
    }
    periphMemWrite( 0, &ArchIO.CAN.Buffer[i].CtlStatusReg );
    periphBitClear( (1 << i),  &ArchIO.CAN.IntMask1Reg );
    periphBitSet( (1 << i),  &ArchIO.CAN.IntFlags1Reg );

    return 0;
}


/*******************************************************************************
*
* NAME: ioctlCANID_SET_MSAK
*
* DESCRIPTION: update mask according to the buffer
*              
********************************************************************************
* PARAMETERS:       file descriptor, mask
*
* SIDE EFFECTS:     None Known
*
* DESIGNER NOTES:   only for 14 and 15 mask
*
* DEPENDENCIES:     None
*******************************************************************************/
unsigned int ioctlCANID_SET_MASK(handle_t handle, unsigned long params )      
{
    unsigned int i;
    unsigned long maskflag;

    i = ((can_sBuffer*)handle)->flags & 0x000F;
	maskflag = 0;
	if( ((can_sBuffer*)handle)->flags & CAN_BUF_2B )
	{
	    maskflag =   CAN_LONG_IDE_MASK ;
    }

    if( i == 15 )
    {
        SetCANID( (unsigned short*)(BSP_PERIPH_BASE + archoff_FlexCAN_Rx15MaskHiReg ), params, maskflag );
    }
    else if( i == 14 )
    {
        SetCANID( (unsigned short*)(BSP_PERIPH_BASE + archoff_FlexCAN_Rx14MaskHiReg ), params, maskflag );
    }
    else
    {
        SetCANID( (unsigned short*)(BSP_PERIPH_BASE + archoff_FlexCAN_RxGlobalMaskHiReg ), params, maskflag );
    }
    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
*******************************************************************************/
#pragma interrupt called on
void CANReceiveISR(void)
{
    register  can_sData* pCrd;

    pCrd = (*CANRcvPrepare)( 
                GetCANID(
                        ((unsigned long)periphMemRead( &ArchIO.CAN.Buffer[15].IdRegHi)) << 16
                        | periphMemRead( &ArchIO.CAN.Buffer[15].IdRegLo)
                )   
           ); /* CANStdRcvPrepare */
    if( pCrd ) 
    {   
        pCrd->length =  flexcanRead( (handle_t)&IOBuffer[15], 
                        &pCrd->data[0], 8 );
    }
    else 
    {   /* just release */
         flexcanRead( (handle_t)&IOBuffer[15], &pCrd->data[0], 0 ); 
    }
}
#pragma interrupt called off

/*******************************************************************************
*
* NAME:             FC_InitCallBack
*
* DESCRIPTION:      Initialize CAN driver device for callback
*              
********************************************************************************
* PARAMETERS:       
*
* SIDE EFFECTS:     None Known
*
* DESIGNER NOTES:   only 15th buffer is used
*
* DEPENDENCIES:     None
*******************************************************************************/
void FC_InitCallBack( CANADDRESSTYPE mask, CANADDRESSTYPE canID )
{
    flexcanOpen( 0, O_RDONLY, canID ); /* use last buffer with own filter */
    ioctlCANID_SET_MASK((handle_t)&IOBuffer[15], mask );
    periphMemWrite( 0x8000, &ArchIO.CAN.IntMask1Reg ); /* 15th buffer */
    IOBuffer[15].callback = CANReceiveISR;
}


/*******************************************************************************
*
* 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 CANBufferISR(void)
{
    asm( alignsp );	/* saves needed registers only */
    asm( move.l  Y , x:(SP)+ );
    asm( move.l  X0, x:(SP)+ );
    asm( move.l  R2, x:(SP)+ );
    asm( move.l  N, x:(SP) );

    asm( move.w X:( BSP_PERIPH_BASE + archoff_FlexCAN_IntMask1Reg ), Y0 );
    asm( move.w X:( BSP_PERIPH_BASE + archoff_FlexCAN_IntFlags1Reg ), Y1 );
    asm( and.w  Y1, Y0 );           /* actual isr vector */
    asm( clr.w Y1 );
    asm( clb  Y, X0 );              /* left buffer index (Y0) */
    asm( move.w #0x1E, Y0 );
    asm( sub  X0, Y0 );      
    asm( blt end_bufisr );
    asm( move.w    #0x0001, X0 );   /* 0th mask (X0) */
    asm( asll.w    Y0, X0 );        /* actual buffer mask (X0) */
   
    asm( move.w X:( BSP_PERIPH_BASE + archoff_FlexCAN_IntMask1Reg ), Y1 );
    asm( not.w X0 );       /* to clear actual mask */
    asm( and.w X0, Y1 );   /* only current ISR mask clear */
    asm( move.w Y1, X:( BSP_PERIPH_BASE + archoff_FlexCAN_IntMask1Reg ) );   /* release mask */

    asm( move.w #sFlexCAN_word_size, Y1 ); /* get status */
    asm( impy.w Y1, Y0, X0 );          /* Y0*Y1 get contex offset */

    asm( adda #IOBuffer, X0, R2 );  /* get context buffer address */
    asm( tst.l X:(R2 + sFlexCAN_offset_callback) );
    asm( beq end_bufisr );
    asm( move.l X:(R2 + sFlexCAN_offset_callback), N ); /* get callback address */
    asm( jsr (N) );
end_bufisr:

    asm( move.l  x:(SP)-, N );
    asm( move.l  x:(SP)-,R2 );
    asm( move.l  x:(SP)-,X0 );
    asm( move.l  x:(SP)-,Y );
    asm( move.l  x:(SP)-,SP );

    asm(  rti );
}




⌨️ 快捷键说明

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