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

📄 scidrv.c

📁 56f8300E系列dsp的BOOTloader
💻 C
📖 第 1 页 / 共 3 页
字号:
/*******************************************************************************
*
* Motorola Inc.
* (c) Copyright 2002 Motorola, Inc.
* ALL RIGHTS RESERVED.
*
*
* Description:       source file for the 56838 SCI device driver 
*
* Notes:  
*
******************************************************************************/

#include <stdarg.h>

#include "bsp.h"
#include "syslib.h"
#include "periph.h"
#include "scidrv.h"
#include "arch_off.h"
#include "gpioinline.h"

/*****************************************************************************/
/*                         Driver Function prototypes                        */
/*****************************************************************************/

#define scidrvHWDisableInterrupts(BaseAddress)      (periphBitClear(SCI_SCICR_TEIE | SCI_SCICR_TIIE | SCI_SCICR_RIE | SCI_SCICR_REIE, &BaseAddress->ControlReg))
#define scidrvHWEnableRxInterrupts(BaseAddress)     (periphBitSet(SCI_SCICR_RIE | SCI_SCICR_REIE, &BaseAddress->ControlReg))
#define scidrvHWDisableRxInterrupts(BaseAddress)    (periphBitClear(SCI_SCICR_RIE | SCI_SCICR_REIE, &BaseAddress->ControlReg))
#define scidrvHWEnableTxCompleteInterrupt(BaseAddress) (periphBitSet(SCI_SCICR_TIIE, &BaseAddress->ControlReg))
#define scidrvHWEnableTxReadyInterrupt(BaseAddress) (periphBitSet(SCI_SCICR_TEIE, &BaseAddress->ControlReg))
#define scidrvHWDisableTxInterrupts(BaseAddress)    (periphBitClear(SCI_SCICR_TEIE | SCI_SCICR_TIIE, &BaseAddress->ControlReg))
#define scidrvHWDisableTx(BaseAddress)              (periphBitClear(SCI_SCICR_TE, &BaseAddress->ControlReg))
#define scidrvHWDisableRx(BaseAddress)              (periphBitClear(SCI_SCICR_RE, &BaseAddress->ControlReg))
#define scidrvHWDisableDevice(BaseAddress)          (periphBitClear(SCI_SCICR_TE | SCI_SCICR_RE, &BaseAddress->ControlReg))
#define scidrvHWEnableDevice(BaseAddress)           (periphBitSet(SCI_SCICR_TE | SCI_SCICR_RE, &BaseAddress->ControlReg))

/*****************************************************************************/
/*                                 API                                       */
/*****************************************************************************/

handle_t sciPreOpen( const char * pName, struct io_sDevice* pDev, int OFlags , ... )
{
    struct  sSciDevice    * pSciDevice;
    unsigned long   BaudRate;
    unsigned long   rawBaudRate;
    va_list         Args;
    
    Args = (char *)&OFlags;
    BaudRate = va_arg(Args, unsigned long);
    va_end(Args);

    switch ((int)pName)
    {
    case (int) BSP_DEVICE_NAME_SCI_0:
         pSciDevice = &Sci0DeviceContext;

         /* CONFIGURE SCI PINS TO BE PERIPHERAL */
        gpioIoctlGPIO_SETAS_PERIPHERAL( SCI0_GPIO_BASE_ADDRESS, SCI0_GPIO_MASK );
    break;
 
    case (int) BSP_DEVICE_NAME_SCI_1:
         pSciDevice = &Sci1DeviceContext;  

         /* CONFIGURE SCI PINS TO BE PERIPHERAL */
        gpioIoctlGPIO_SETAS_PERIPHERAL( SCI1_GPIO_BASE_ADDRESS, SCI1_GPIO_MASK );
    break;
 
    default:
        return (handle_t)-1;
    }
    scidrvHWDisableInterrupts( pSciDevice->Base );
    scidrvHWDisableDevice( pSciDevice->Base );

    if(OFlags & O_NONBLOCK)
    {
      extern const struct io_sSCIInterface scidrvIONonBlockInterfaceVT;
      pSciDevice->drvInterface = (io_sInterface *)&scidrvIONonBlockInterfaceVT;
    }
    else
    {
      extern const struct io_sSCIInterface scidrvIOBlockInterfaceVT;
      pSciDevice->drvInterface = (io_sInterface *)&scidrvIOBlockInterfaceVT;
    }


    rawBaudRate = sci_getBaudRate( BaudRate );

    return sciOpen( (const char*)pSciDevice,  OFlags, rawBaudRate );

}




/*****************************************************************************
*
* Module:         sciOpen
*
* Description:    Open SCI device.
*                 Initialize device context
*
* Returns:        Device handle if successful,
*                 -1 if device name is not supported
*
* Arguments:      pName - BSP SCI device name
*                 OFlags - open mode (for detail see sci.h file)
*                           O_NONBLOCK 
*                           O_BLOCK
*                           O_SCI_DISABLE_IN_WAIT   
*                           O_SCI_ENABLE_IN_WAIT    
*                           O_SCI_WAKE_BY_ADDRESS   
*                           O_SCI_WAKE_BY_IDLE      
*                           O_SCI_WORD_9BIT         
*                           O_SCI_WORD_8BIT         
*                           O_SCI_PARITY_NONE       
*                           O_SCI_PARITY_ODD        
*                           O_SCI_PARITY_EVEN       
*                           O_SCI_7_DATA_BITS_ODD_PARITY 
*                           O_SCI_7_DATA_BITS_EVEN_PARITY
*                           O_SCI_8_DATA_BITS_NO_PARITY  
*                           O_SCI_8_DATA_BITS_ODD_PARITY 
*                           O_SCI_8_DATA_BITS_EVEN_PARITY
*                           O_SCI_9_DATA_BITS_NO_PARITY  
*                           O_SCI_TX_INVERTED       
*                           O_SCI_TX_NOT_INVERTED   
*                           O_SCI_INVERT_ALL_BITS        
*                           O_SCI_DONT_INVERT_ANY_BITS   
*                           O_SCI_LOOPBACK_DISABLED 
*                           O_SCI_LOOPBACK_ENABLED  
*                           O_SCI_LOOPBACK_SINGLE_WIRE_ENABLED
*                           
*
* Range Issues:   None
*
* Test Method:    sci.mcp
*
*****************************************************************************/
handle_t sciOpen( const char * pName, int OFlags, unsigned long rawBaudRate )
{
    struct sSciDevice* pSciDevice = (struct sSciDevice*)pName;
    unsigned int    ControlWord;
    short           Control = 0;

    if(OFlags && 0xFFF0)
    {
        Control = OFlags & 0xFFF0;
    }

    if( OFlags & O_SCI_DATA_9BIT )
    {
        if( OFlags & (O_SCI_PARITY_ODD | O_SCI_PARITY_EVEN)  )
            pSciDevice->Mask = SCI_SCIDR_8BIT_MASK; /* 8 with parity */
        else
            pSciDevice->Mask = SCI_SCIDR_9BIT_MASK;
    }
    else  /* O_SCI_DATA_8BIT */
    {
        if( OFlags & (O_SCI_PARITY_ODD | O_SCI_PARITY_EVEN)  )
            pSciDevice->Mask = SCI_SCIDR_7BIT_MASK;
        else
            pSciDevice->Mask = SCI_SCIDR_8BIT_MASK; /* 8 without parity */
    }

    periphMemWrite( rawBaudRate, &pSciDevice->Base->BaudRateReg );
    periphMemWrite( Control & SCI_SCICR_USER_MASK, &pSciDevice->Base->ControlReg  );


    /* Clear all receiver related interrupts */
    periphMemRead( &pSciDevice->Base->StatusReg );
    periphMemRead( &pSciDevice->Base->DataReg );
    periphMemWrite( 0x0000, &pSciDevice->Base->StatusReg );

    scidrvHWEnableRxInterrupts( pSciDevice->Base );
    scidrvHWEnableDevice( pSciDevice->Base );

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

    return (handle_t)pSciDevice;
}

/*****************************************************************************
*
* Module:         sciClose()
*
* Description:    Close SCI device. Uninstall ISR vectors, if used.
*
* Returns:        0
*
* Arguments:      hndl - device context
*
* Range Issues:   None
*
* Test Method:    sci.mcp
*
*****************************************************************************/
int sciClose( handle_t hndl )
{ 
   struct   sSciDevice   * pHandle = (struct sSciDevice *)hndl;
   volatile unsigned int   status  = 0;
   
   scidrvHWDisableRx( pHandle->Base );
   
   while(1)
   {
       status = periphMemRead( &pHandle->Base->StatusReg );
       if( status & SCI_SCISR_TIDLE )
       {
           break;
       }
   }             
   
   scidrvHWDisableTx( pHandle->Base );
   
#if defined(BSP_DEVICE_NAME_SCI_0)
   /* return GPIO pins in default state */
   if( pHandle->Base == SCI0_BASE_ADDRESS )     
   {
      gpioIoctlGPIO_SETAS_GPIO( SCI0_GPIO_BASE_ADDRESS, SCI0_GPIO_MASK );
   }
#endif
#if defined(BSP_DEVICE_NAME_SCI_1)
   if( pHandle->Base == SCI1_BASE_ADDRESS )     
   {
      gpioIoctlGPIO_SETAS_GPIO( SCI1_GPIO_BASE_ADDRESS, SCI1_GPIO_MASK );
   }
#endif /* defined(BSP_DEVICE_NAME_SCI_1) */
   return 0;
}

/*****************************************************************************
*
* Module:         sciNonBlockRead()
*
* Description:    Read data from SCI driver into user buffer
*
*                 In NonBlocking mode, "read" returns the actual data that
*                 has already been received from the SCI device. It does not
*                 wait for more data, if NBytes is greater than data size
*                 already contained in the buffer.
*
* Returns:        Actual read size
*
* Arguments:      hndl        - SCI Device descriptor returned by "sciOpen" call.
*                 pBuffer     - Char pointer to user buffer. 
*                 NBytes      - NBytes (in 8-bit bytes) of the data to be read 
*                               from SCI device; 
*
* Range Issues:   None
*
* Test Method:    sci.mcp
*
*****************************************************************************/
ssize_t sciNonBlockRead( handle_t hndl, void * pBuffer, size_t NBytes )
{
    asm(move.w   M01, B );  /* save modulo context in B */
  
#if __m56800E_lmm__ 
    asm(move.w A0,A);
    asm(move.w  A1,Y0);
#else
	asm(nop);
	asm(nop);
#endif
    asm(move.w      Y0,A);  /* A := size */
    
    /* load queue descriptor */
    asm(move.l      X:(R2 + #(sSciDevice_offset_qReceive + sQueue_offset_begin) ), Y);  /* Y0 := begin, Y1 := end */
    /* use space in queue */
    asm(sub         Y1,Y0); /* Y0 := begin - end */
    asm(cmp.w       Y0,A);
    asm(tgt         Y0,A);  /* if ("buffer size" < "count of ready chars in queue") then copy only "buffer size" chars */
    /* setup modulo */
    asm(move.w      X:(R2 + #(sSciDevice_offset_qReceive + sQueue_offset_mask) ) , X0);
    asm(moveu.w     X0,M01);
    /* setup buffer pointer */
    asm(and.w       Y1,X0); /* X0 := moduled begin (Y0) */
    asm(add.w       X:(R2 + #(sSciDevice_offset_qReceive + sQueue_offset_bufferOffset) ) , X0);
    asm(adda        #BASE_CIRCULAR_BUFFER_ADDRESS,X0,R0);
    
    asm(do          A,end_reading_loop);
        asm(move.w      P:(R0)+,X0);
        asm(nop);
        asm(nop);
        asm(move.bp     X0,X:(R3)+);
    asm(end_reading_loop:);
    
    /* update queue descriptor */
    asm(add         A,Y1);
    asm(move.w      Y1,X:(R2 + #(sSciDevice_offset_qReceive + sQueue_offset_end) ) );
    
    asm(move.w      A,Y0);

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

    asm(moveu.w  B, M01 );  /* restore modulo context */

    /* asm(rts); */
}

/*****************************************************************************
*

⌨️ 快捷键说明

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