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

📄 flexcan.c

📁 56f8300E系列dsp的BOOTloader
💻 C
📖 第 1 页 / 共 3 页
字号:
* DESIGNER NOTES: 
*
* DEPENDENCIES: None
*******************************************************************************/
handle_t  flexcanOpen(const char * pName, int oFlags,  CANADDRESSTYPE canID )
{
    can_sBuffer* pbuf;
    unsigned int cmd;

    /***    open for read ( reception )   ***/  
    if( oFlags & O_RDONLY   )
    {
        nBottomRead--; 
        pbuf = &IOBuffer[nBottomRead];
        pbuf->flags = (unsigned int)nBottomRead | CAN_BUF_READ_HANDLE;
        cmd = FC_MB_ACTIVE;
        periphBitSet( (1 << nBottomRead),  &ArchIO.CAN.IntMask1Reg );
    }
    /***   open for write ( transmission )  ***/    
    else if( oFlags & O_WRONLY )
    {
        pbuf = &IOBuffer[nTopWrite]; /* CAN_BUF_WRITE_HANDLE */
        pbuf->flags = (unsigned int)nTopWrite;
        cmd = FC_MB_NOTREADY;

        nTopWrite++;  /* next buffer */

    }
    if( !(oFlags & O_NONBLOCK) )
    {
        pbuf->flags |= CAN_BUF_SYNCHRONOUS;
    }
    pbuf->canID = canID; 

    if( FlexCANFlags /* oFlags*/ & O_CAN_2B )
    {
        pbuf->flags |= CAN_BUF_2B;
    }

    PrepareCANID( pbuf, cmd );

    return (handle_t)pbuf; 
    
}


/*******************************************************************************
*
* 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
*
* DEPENDENCIES: None 
*******************************************************************************/
ssize_t flexcanWrite( handle_t handle,  const void *pBuffer, size_t size )
{
#if __m56800E_lmm__ 
    asm(move.w A0,A);
    asm(move.w  A1,Y0);
#else
	asm(nop);
	asm(nop);
#endif
    asm( move.w X:(R2 + #sFlexCAN_offset_flags), X0 );
    asm( bfclr #0xFFF0, X0 );    /* clear flags */

    asm( move.w    #1, A );
    asm( asll.w    X0, A );      /* get mask for buffer */

    asm( asll.w  #0x3, X0 ); /* *8, convert to buffer index */
    asm( adda #( BSP_PERIPH_BASE + archoff_FlexCAN_Buffer_0 ), X0, R4 ); 
    /* R4 - message buffer */

    asm( brclr #4, X:( BSP_PERIPH_BASE + archoff_FlexCAN_StatusReg ), continue_1 );
    asm( bfset #4, X:( BSP_PERIPH_BASE + archoff_FlexCAN_StatusReg ) );

#if __m56800E_lmm__ 
    asm(move.l #0xFFFFFFFF,A);
#else
    asm( move.w #0xFFFF, Y0 ); 
#endif

    asm( move.w # CAN_ERR_LOST, CANErrno );
    asm( rts );
continue_1:    
    /* transmission finished ? */
    asm( move.w X:( BSP_PERIPH_BASE + archoff_FlexCAN_IntMask1Reg ), X0 );
    asm( and.w A, X0 );  /* compare with mask */
    asm( beq continue_2 );
#if __m56800E_lmm__ 
    asm(move.l #0xFFFFFFFF,A);
#else
    asm( move.w #0xFFFF, Y0 ); 
#endif
    asm( move.w #CAN_ERR_BUSY, CANErrno );
    asm( rts );
continue_2:

    asm( move.w # FC_MB_NOTREADY, X:(R4 + devoff_FlexCANBuffer_CtlStatusReg) );

    asm(cmp.w       #8, Y0);
    asm(blt         len_lt);    /* change by received len only */
    asm(move.w      #8, Y0);  
len_lt:
    asm( move.w  Y0, X0 );
    asm( inc.w      X0  );
    asm( ror.w      X0  );      /* words to copy */

    asm( adda     # devoff_FlexCANBuffer_DataSegReg_0, R4, R0 );

    asm( do X0, enddo );
    asm( move.bp  X:(R3)+, Y1 ); /* copy from pBuffer */
    asm( asll.w   #8, Y1 );
    asm( moveu.bp  X:(R3)+, X0 ); /* copy from pBuffer */
    asm( or.w   X0, Y1 );
    asm( move.w Y1, X:(R0)+ );  /* copy to hardware */
enddo:

    asm( move.w X:( BSP_PERIPH_BASE + archoff_FlexCAN_IntFlags1Reg ), X0 );
    asm( and.w A, X0 );  /* to clear isr flag */
    asm( move.w X0, X:( BSP_PERIPH_BASE + archoff_FlexCAN_IntFlags1Reg ) );

    asm( move.w X:( BSP_PERIPH_BASE + archoff_FlexCAN_IntMask1Reg ), X0 );
    asm( or.w A, X0 );  /* to update isr mask */
    asm( move.w X0, X:( BSP_PERIPH_BASE + archoff_FlexCAN_IntMask1Reg ) );
 
    asm( bfset # FC_MB_SEND, Y0 );
    asm( move.w Y0, X:(R4 + devoff_FlexCANBuffer_CtlStatusReg) );
    asm( move.w X:( BSP_PERIPH_BASE + archoff_FlexCAN_TimerReg), X0 );

    asm( brclr CAN_BUF_SYNCHRONOUS, X:(R2 + #sFlexCAN_offset_flags), endwrite );
wait_tx:    /* wait in blocked mode only */

    asm( move.w X:( BSP_PERIPH_BASE + archoff_FlexCAN_IntFlags1Reg ), X0 );
    asm( and.w A, X0 );
    asm( beq  wait_tx );
    
endwrite:
    asm( bfclr # 0xFFF0, Y0 ); /* return actual length */
#if __m56800E_lmm__ 
    asm(move.w Y0,A0);
    asm(clr.w A1);
#else
    asm(nop);
    asm(nop);
#endif
  
}

/*******************************************************************************
*
* NAME: Read
*
* DESCRIPTION: Driver read procedure
*              
********************************************************************************
* PARAMETERS:   file descriptor, buffer and size
*
* SIDE EFFECTS: None Known
*
* DESIGNER NOTES: handler is pointer to the CAN ID descriptor, 
*               
* DEPENDENCIES: None
*******************************************************************************/
ssize_t flexcanRead( handle_t handle,  void *pBuffer, size_t size)
{
#if __m56800E_lmm__ 
    asm(move.w A0,A);
    asm(move.w  A1,Y0);
#else
	asm(nop);
	asm(nop);
#endif
    asm( move.w X:(R2 + #sFlexCAN_offset_flags), X0 );
    asm( bfclr #0xFFF0, X0 );    /* clear flags */

    asm( move.w    #1, C );
    asm( asll.w    X0, C );      /* get mask for buffer */

    asm( asll.w  #0x3, X0 ); /* *8, convert to buffer index */

    /* R3 - message buffer */
    asm( adda #( BSP_PERIPH_BASE + archoff_FlexCAN_Buffer_0 ), X0, R4 ); 
    asm( move.w X:(R4 + devoff_FlexCANBuffer_CtlStatusReg), X0 );


    asm( move.w  X0, Y1 );
    asm( bfclr #0xFF0F, Y1 );    /* left only len */
    asm( cmp.w # FC_MB_FULL,  Y1 );
    asm( beq continue_read );
    asm( cmp.w  # FC_MB_OVERRUN,  Y1 ); 
    asm( beq continue_read );

    asm( clr.w Y0 ); 

#if __m56800E_lmm__ 
    asm(clr.w A0);
    asm(clr.w A1);
#else
    asm(nop);
    asm(nop);
#endif

    
    asm( rts );
continue_read: /* mb full or overrun continue read */

    asm( move.w X:(R4 + devoff_FlexCANBuffer_IdRegHi), A ); /* A - ID */
    asm( move.w X:(R4 + devoff_FlexCANBuffer_IdRegLo), A0 );
    asm( jsr GetCANID );    /* A - raw CAN ID -> CAN ID */
    asm( cmp.w   #(8 + 4), Y0 );  /* compare with ext buffer len, Y0 - 12 */
    asm( blt        IDcopy);    /* change by received len only */
    asm(  adda     #8, R3, R0 );
    asm(  asra   R0 );
    asm(  move.w A0, X:(R0)+ );    /* copy ID to tail of long buffer */
    asm(  move.w A1, X:(R0)+ );
IDcopy:

    asm( bfclr #0xFFF0, X0 );    /* left only len */

    asm( cmp         X0, Y0);    /* Y0 - X0 */
    asm( blt         len_lt);    /* change by received len only */
    asm( move.w      X0, Y0);
len_lt:
    asm( adda     # devoff_FlexCANBuffer_DataSegReg_0, R4, R0 );
    asm( move.w  Y0, X0 );
    asm( asr     X0  );      /* words to copy */

    asm( do X0, enddo );
    asm( move.w  X:(R0)+, X0 );
    asm( move.w  X0, Y1 );
    asm( asrr.w   #8, X0 );
    asm( move.bp  X0, X:(R3)+ );
    asm( move.bp  Y1, X:(R3)+ );
enddo:
    asm( brclr #0x0001, Y0, skip_odd_last );
    asm( move.w X:(R0)+, X0 );
    asm( asrr.w   #8, X0 );
    asm( move.bp  X0, X:(R3)+ );
skip_odd_last:


    asm( move.l  X:( R2 + sFlexCAN_offset_canID), B );
    asm( cmp.l A, B );
    asm( beq id_compare );

    asm( move.w X:(R2 + #sFlexCAN_offset_flags), X0 ); /* all flags */
    asm( tfr  B, A );    /* needed CAN ID -> A */

    asm( clr B );   /* form flags on B register */
    asm( brclr    # CAN_BUF_2B, X:(R2 + #sFlexCAN_offset_flags), Bit_16 ); 
    asm( bfset    #CAN_SHORT_IDE_MASK, B1); /* only for long handles */
Bit_16: 

    asm( adda   # devoff_FlexCANBuffer_IdRegHi, R4, R2 ); /* prepare addr for SetCANID */
    asm( jsr SetCANID ); /*  SetCANID(R2, A, B) & used X0 */

id_compare:

    asm( move.w X:( BSP_PERIPH_BASE + archoff_FlexCAN_IntFlags1Reg ), X0 );
    asm( and.w C, X0 );  /* to clear isr flag */
    asm( move.w X0, X:( BSP_PERIPH_BASE + archoff_FlexCAN_IntFlags1Reg ) );

    asm( move.w X:( BSP_PERIPH_BASE + archoff_FlexCAN_IntMask1Reg ), X0 );
    asm( or.w C, X0 );  /* to update isr mask */
    asm( move.w X0, X:( BSP_PERIPH_BASE + archoff_FlexCAN_IntMask1Reg ) );

    asm( move.w #FC_MB_ACTIVE, X:(R4 + devoff_FlexCANBuffer_CtlStatusReg) );
    asm( move.w X:( BSP_PERIPH_BASE + archoff_FlexCAN_TimerReg), X0 );
#if __m56800E_lmm__ 
    asm(move.w Y0,A0);
    asm(clr.w A1);
#else
    asm(nop);
    asm(nop);
#endif
}

/*******************************************************************************
*
* 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  message buffer is full
*                                      but some received messages were lost 
*
* DEPENDENCIES:     None
*******************************************************************************/
unsigned int ioctlCANID_GET_STATUS(handle_t handle, unsigned long params )      
{
    asm( move.w X:(R2 + #sFlexCAN_offset_flags), X0 );
    asm( bfclr #0xFFF0, X0 );    /* clear flags */
    asm( move.w    #1, B );
    asm( asll.w    X0, B );      /* get mask for buffer */

    asm( move.w # CANID_EMPTY,  Y0 ); /* default status */
    asm( brclr CAN_BUF_READ_HANDLE, X:(R2 + #sFlexCAN_offset_flags), tx_case );

    asm( asll.w  #0x3, X0 ); /* x8, convert to buffer index */
    asm( adda #( BSP_PERIPH_BASE + archoff_FlexCAN_Buffer_0 ), X0, R4 ); 
    asm( move.w X:( BSP_PERIPH_BASE + archoff_FlexCAN_IntFlags1Reg ), X0 );

    asm( and.w X0, B );         /* check bit in flag register */
    asm( beq end_status );      /* empty buffer if was no reception */

    asm( move.w X:(R4 + devoff_FlexCANBuffer_CtlStatusReg), Y1 );
    asm( move.w X:( BSP_PERIPH_BASE + archoff_FlexCAN_TimerReg), X0 );
    asm( bfclr #0xFF0F, Y1 );    /* left only raw status */

    asm( move.w # CANID_FULL, Y0 );
    asm( cmp.w # FC_MB_FULL,  Y1 );
    asm( beq end_status );

    asm( move.w # CANID_OVERFLOW,  Y0 );
    asm( cmp.w  # FC_MB_OVERRUN,  Y1 ); 
    asm( beq end_status );

⌨️ 快捷键说明

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