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

📄 scidrv.c

📁 56f8300E系列dsp的BOOTloader
💻 C
📖 第 1 页 / 共 3 页
字号:
    if( periphBitTest( SCI_SCICR_TEIE, &pHandle->Base->StatusReg ) == true )
    {
        ReturnValue |= SCI_STATUS_WRITE_INPROGRESS;            
    }
    
    return ReturnValue;
}
   
/*****************************************************************************
*
* Module:         sciIoctlSCI_CMD_SEND_BREAK()
*
* Description:    Send break symbol via SCI
*
* Returns:        None
*
* Arguments:      hndl - device descriptor
*
* Range Issues:   None
*
* Test Method:    sci.mcp
*
*****************************************************************************/
unsigned int sciIoctlSCI_CMD_SEND_BREAK( handle_t hndl, unsigned long params )
{
   struct sSciDevice * pHandle = (struct sSciDevice *)hndl;

   periphBitSet( SCI_SCICR_SBK, &pHandle->Base->ControlReg );
   periphBitClear( SCI_SCICR_SBK, &pHandle->Base->ControlReg );
}

/*****************************************************************************
*
* Module:         sciIoctlSCI_CMD_WAIT()
*
* Description:    Put SCI device in wait state
*
* Returns:        None
*
* Arguments:      hndl - device descriptor
*
* Range Issues:   None
*
* Test Method:    sci.mcp
*
*****************************************************************************/
unsigned int sciIoctlSCI_CMD_WAIT( handle_t hndl, unsigned long params )
{
   struct sSciDevice * pHandle = (struct sSciDevice *)hndl;

   periphBitSet( SCI_SCICR_RWU, &pHandle->Base->ControlReg );
}

/*****************************************************************************
*
* Module:         sciIoctlSCI_CMD_WAKEUP()
*
* Description:    Wake up device from wait mode
*
* Returns:        None
*
* Arguments:      hndl - device descriptor
*
* Range Issues:   None
*
* Test Method:    sci.mcp
*
*****************************************************************************/
unsigned int sciIoctlSCI_CMD_WAKEUP( handle_t hndl, unsigned long params )
{
   struct sSciDevice * pHandle = (struct sSciDevice *)hndl;

   periphBitClear( SCI_SCICR_RWU, &pHandle->Base->ControlReg );
}

/*****************************************************************************
*
* Module:         sciIoctlSCI_DEVICE_OFF()
*
* Description:    Switch device off, disable device related interrupts
*
* Returns:        None
*
* Arguments:      hndl - device context
*
* Range Issues:   None
*
* Test Method:    sci.mcp
*
*****************************************************************************/
unsigned int sciIoctlSCI_DEVICE_OFF( handle_t hndl, unsigned long params )
{
   struct sSciDevice * pHandle = (struct sSciDevice*)hndl;

   scidrvHWDisableInterrupts( pHandle->Base );
   /* Clear all receiver related interrupts */
   periphMemRead( &pHandle->Base->StatusReg  );
   periphMemRead( &pHandle->Base->DataReg );
   periphMemWrite( 0x0000, &pHandle->Base->StatusReg );
   
   scidrvHWDisableDevice( pHandle->Base );
}
         
/*****************************************************************************
*
* Module:         sciIoctlSCI_DEVICE_ON()
*
* Description:    Switch device on, clear read and write buffers, enable 
*                 receiver related interrupts
*
* Returns:        None
*
* Arguments:      hndl - device context
*
* Range Issues:   None
*
* Test Method:    sci.mcp
*
*****************************************************************************/
unsigned int sciIoctlSCI_DEVICE_ON( handle_t hndl , unsigned long params )
{
   struct sSciDevice * pHandle = (struct sSciDevice *)hndl;

   pHandle->qReceive.begin = pHandle->qReceive.end = 0;
   pHandle->qSend.begin = pHandle->qSend.end = 0;

   scidrvHWEnableDevice( pHandle->Base );
   scidrvHWEnableRxInterrupts( pHandle->Base );   
}

/*****************************************************************************/
/*                                 ISRs                                      */
/*****************************************************************************/

/*****************************************************************************
*
* Module:         sciReceiverISR()
*
* Description:    ISRs for SCI receivers
*                 
* Returns:        None
*
* Arguments:      None
*
* Range Issues:   None
*
* Test Method:    sci.mcp
*
*****************************************************************************/
/* ISR registers allocation:

    R2 - arch
    R3 - context
    R4 - callback
*/
/*
    user callback:
        input:  A0 - value(9 bits) which has been received, A1 - error status 
        output: A0 - value which will be placed into buffer 
                A1 - error state. If clear  If A == -1 value will not be saved
*/

void sciReceiverISR( volatile register arch_sSCI * pArch , struct sSciDevice * pContext, tSciCallBackPtr callback )
{
    /*save context*/
    asm(adda        #2  , SP        );
    asm(move.l      R0  , X:(SP)+   );
    asm(move.l      X0  , X:(SP)+   );  
    asm(move.l      Y   , X:(SP)+   );
    asm(move.l      A2  , X:(SP)+   );
    asm(move.l      A10 , X:(SP)    );

   /* Clear SCI rx and errror related flags */
    asm(move.w      X:(R2 + #arch_sSCI_offset_StatusReg) , A1 );
    asm(clr.w       X:(R2 + #arch_sSCI_offset_StatusReg) );
    asm(move.w      #(SCI_SCISR_OR | SCI_SCISR_NF | SCI_SCISR_FE | SCI_SCISR_PF) , Y1 );
    asm(move.w      X:(R3 + #sSciDevice_offset_Mask) , Y0 );    /* load mask    */
    asm(move.w      X:(R2 + #arch_sSCI_offset_DataReg) , A0 );  /* read Rx reg  */
    asm(and.l       Y  , A );       /* apply mask */

    /* break symbol detecting */
    asm(brclr       #SCI_SCISR_FE , A1 , test_iterators );
    asm(tst.w       A0 );
    asm(bne         test_iterators );
    asm(bfset       #SCI_EXCEPTION_BREAK_SYMBOL , A1 );

test_iterators:
    /* load queue descriptor */
    asm(move.l      X:(R3 + #(sSciDevice_offset_qReceive + sQueue_offset_begin)) , Y ); /* Y0 := begin. Y1 := end */
    asm(move.w      X:(R3 + #(sSciDevice_offset_qReceive + sQueue_offset_mask)) , X0 );
    /* calculate free space in queue */
    asm(sub         Y0 , Y1 );  
    asm(add         X0 , Y1 );          /* Y1 := mask - (begin - end) == free space - 1*/
    asm(bge         call_RxCallBack );  /* if X0 >= Y1, mask >= (begin-end) */
    asm(bfset       #SCI_EXCEPTION_BUFFER_OVERFLOW , A1 );
    
call_RxCallBack:
    /* call callback */
    asm(jsr         (R4) );
    asm(cmp.l       #-1 , A );      /* if return "-1" in A */
    asm(beq         exit_handler );
    asm(cmp.w       Y1 , X0 );
    asm(bcs         exit_handler ); /* if overflow occured */
    /* setup buffer pointer */
    asm(and.w       Y0 , X0);               /* X0 := moduled begin */
    asm(add.w       X:(R3 + #(sSciDevice_offset_qReceive + sQueue_offset_bufferOffset)) , X0 );
    asm(adda        #BASE_CIRCULAR_BUFFER_ADDRESS , X0 , R0 );
    asm(move.w      A0 , X0 );
    asm(move.w      X0 , P:(R0)+ ); 

    /* move begin iterator */
    asm(inc.w       Y0 );   /* Y0 == begin iterator*/
    asm(move.w      Y0 , X:(R3 + #(sSciDevice_offset_qReceive + sQueue_offset_begin)) );
        
exit_handler:
    /*restore context*/
    asm(move.l      X:(SP)- , A  ); 
    asm(move.l      X:(SP)- , A2 );
    asm(move.l      X:(SP)- , Y  ); 
    asm(move.l      X:(SP)- , X0 );
    asm(move.l      X:(SP)- , R0 );
}

/*****************************************************************************
*
* Module:         sciTransmitterISR()
*
* Description:    ISRs for SCI transmitters
*                 
* Returns:        None
*
* Arguments:      None
*
* Range Issues:   None
*
* Test Method:    sci.mcp
*
*****************************************************************************/
/* ISR registers allocation:

    R2 - arch
    R3 - context
    R4 - callback
*/
/*
    user callback:
        input:  A0 - value which is going to sent. A = -1 if there is nothing to send
        output: A0 - value which will be sent, A = "-1" if stop transmission
*/
void sciTransmitterISR( volatile register arch_sSCI * pArch , struct sSciDevice * pContext, tSciCallBackPtr callback )
{
    /*save context*/
    asm(adda        #2  , SP        );
    asm(move.l      R0  , X:(SP)+   );
    asm(move.l      X0  , X:(SP)+   );  
    asm(move.l      Y   , X:(SP)+   );
    asm(move.l      A2  , X:(SP)+   );
    asm(move.l      A10 , X:(SP)    );

    /*setup buffer pointer */
    asm(move.l      X:(R3 + #(sSciDevice_offset_qSend + sQueue_offset_begin)) , Y ); /* Y0 := begin, Y1 := end */
    asm(move.w      X:(R3 + #(sSciDevice_offset_qSend + sQueue_offset_mask)) , X0 );
    asm(and.w       Y1 , X0 );
    asm(add.w       X:(R3 + #(sSciDevice_offset_qSend + sQueue_offset_bufferOffset)) , X0 );
    asm(adda        #BASE_CIRCULAR_BUFFER_ADDRESS , X0 , R0 );
    
    asm(clr         A );
    asm(move.w      P:(R0)+ , X0 ); /* read from queue*/
    asm(move.w      X0 , A0 );
    asm(cmp         Y1 , Y0 );
    asm(bne         tx_callback );
    asm(move.l      #-1 , A );      /* set "-1" */
    
tx_callback:
      /* call users callback */ 
    asm(jsr         ( R4 )  );      /* call transmit callback */
    
go_on:
    asm(cmp.l       #-1 , A );
    asm(bne         transmit_go_on );
    asm(bfclr       #SCI_SCICR_TEIE , X:(R2 + #arch_sSCI_offset_ControlReg) ); /* disable interrupt */
    /* correct queue iterators after force stopping */
    asm(move.w      X:(R3 + #(sSciDevice_offset_qSend + sQueue_offset_end)) , X0);
    asm(move.w      X0 , X:(R3 + #(sSciDevice_offset_qSend + sQueue_offset_begin)) );
    asm(bra         exit_isr);
        
transmit_go_on:
    asm(inc.w       Y1);    /* move end iterator */
    asm(move.w      Y1 , X:(R3 + #(sSciDevice_offset_qSend + sQueue_offset_end)) ); /* update queue descriptor*/    
    /* Clear SCI tx related flags */
    asm(move.w      X:(R2 + #arch_sSCI_offset_StatusReg) , X0 );
    /* be performed before write to Data register to clear SCI Transmitter Ready & Idle flags */
    asm(move.w      X:(R3 + #sSciDevice_offset_Mask) , Y0 );
    asm(and.l       Y , A);
    /* send byte */
    asm(move.w      A0 , X:(R2 + #arch_sSCI_offset_DataReg) );

exit_isr:
    /*restore context*/
    asm(move.l      X:(SP)- , A  ); 
    asm(move.l      X:(SP)- , A2 );
    asm(move.l      X:(SP)- , Y  ); 
    asm(move.l      X:(SP)- , X0 );
    asm(move.l      X:(SP)- , R0 );
}   



⌨️ 快捷键说明

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