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

📄 m8260sccsio.c

📁 au1500开发的应用程序
💻 C
📖 第 1 页 / 共 3 页
字号:
                     M8260_SCC_BD_LEN_OFF), 0x0001);
    CACHE_PIPE_FLUSH ();

    /*
     * buffer address
     * Value is offset from the beginning of dual-port RAM.
     */
    
    M8260_SCC_32_WR((pSccChan->pBdBase + 
                     M8260_SCC_RCV_BD_OFF + 
                     M8260_SCC_BD_ADDR_OFF), pSccChan->rcvBufferAddr);

    /* set the SCC parameter ram field RBASE */

    * pSccChan->pRBASE = 0x00 + (pSccChan->pBdBase - (char *)(pSccChan->immrVal));
    
    /* set up the TRANSMIT buffer descriptors */

    /* 
     * buffer status/control
     * Not ready, Wrap, Bit Clear-to-send_report, Interrupt. [0x3800]
     * if no Clear-to-send_report, use 0x3000.
     */

    M8260_SCC_16_WR((pSccChan->pBdBase + 
                     M8260_SCC_TX_BD_OFF + 
                     M8260_SCC_BD_STAT_OFF), 0x3000);

    /* buffer length. 1 byte */

    M8260_SCC_16_WR((pSccChan->pBdBase + 
                     M8260_SCC_TX_BD_OFF + 
                     M8260_SCC_BD_LEN_OFF), 0x0001);

    /* buffer address */

    M8260_SCC_32_WR((pSccChan->pBdBase + 
                     M8260_SCC_TX_BD_OFF + 
                     M8260_SCC_BD_ADDR_OFF), pSccChan->txBufferAddr);

    /*
     * set the SCC parameter ram field TBASE
     * Value is offset from the beginning of dual-port RAM.
     */

    * pSccChan->pTBASE = 0x08 + (pSccChan->pBdBase - (char *)(pSccChan->immrVal));

    /* disable transmit and receive interrupts */

    * pSCCM &= ~(M8260_SCC_UART_SCCX_RX | M8260_SCC_UART_SCCX_TX);

    /* program the three SCC mode registers: PSMR, GSMR_H, GSMR_L */

    /* 
     * PSMR (Protocol Specific Mode Register) for SCC
     * Normal CTS operation, 8 data bits, 1 stop bit, no parity.
     * If use asynchronous flow control(CTS pin connected), set FLC bit
     */

    * pPSMR = M8260_SCC_UART_PSMR_CL_8BIT; /* M8260_SCC_UART_PSMR_FLC */

    /* 
     * GSMR_H (General Serial Mode Register for SCC, high word)
     * Transmit fifo is 1 byte, receive fifo 8 bits 
     */

    * pGSMR_H = M8260_SCC_GSMRH_RFW | M8260_SCC_GSMRH_TFL;

    /* 
     * GSMR_L (General Serial Mode Register for SCC, low word)
     * Set SCC attributes to standard UART mode, 16x Tx/Rx clock rate,
     * disable transmitter and receiver
     */

    * pGSMR_L = (M8260_SCC_GSMRL_RDCR_X16 | 
		 M8260_SCC_GSMRL_TDCR_X16 | 
		 M8260_SCC_GSMRL_UART) 
		 & ~
		 (M8260_SCC_GSMRL_ENT | M8260_SCC_GSMRL_ENR);

    /* initialize parameter RAM area for this SCC */

    * pRFCR = 0x18;                          /* supervisor data access */
    * pTFCR = 0x18;                          /* supervisor data access */
    * pMRBLR = 1;                            /* max rx buffer length is 1 byte */

    /* initialize some unused parameters in SCC parameter RAM */

    * pMAX_IDL = 0x0;                        /* max idle character */
    * pBRKCR = 0x0001;                       /* number of break characters */
    * pPAREC = 0x0;                          /* received parity errors */
    * pFRMEC = 0x0;                          /* frame errors */
    * pNOSEC = 0x0;                          /* noise errors */
    * pBRKEC = 0x0;                          /* break conditions */
    * pUADDR1 = 0x0;                         /* UART address character 1 */
    * pUADDR2 = 0x0;                         /* UART address character 2 */
    * pTOSEQ = 0x0;                          /* out of sequence character */
    * pCHARACTER1 = 0x8000;                  /*  */
    * pCHARACTER2 = 0x8000;                  /* Rx control character 1 ~ 8 */
    * pCHARACTER3 = 0x8000;                  /* All not used */
    * pCHARACTER4 = 0x8000;
    * pCHARACTER5 = 0x8000;
    * pCHARACTER6 = 0x8000;
    * pCHARACTER7 = 0x8000;
    * pCHARACTER8 = 0x8000;
    * pRCCM = 0x0C0FF;

    CACHE_PIPE_FLUSH ();

    /* wait until the CP is clear */
    
    WAIT_CP_COMPLETE_CMD();
    
    /* Tell CP to initialize tx and rx parameters for SCC */

    cpcrVal = (M8260_CPCR_OP (M8260_CPCR_RT_INIT)
               | M8260_CPCR_SBC (M8260_CPCR_SBC_SCC1 | (scc * 0x1))
               | M8260_CPCR_PAGE (M8260_CPCR_PAGE_SCC1 | (scc * 0x1))
               | M8260_CPCR_MCN (M8260_CPCR_MCN_ETH)
               | M8260_CPCR_FLG);

    M8260_SCC_32_WR (M8260_CPCR (immrVal), cpcrVal);

    CACHE_PIPE_FLUSH ();

    /* wait until the CP is clear */

    WAIT_CP_COMPLETE_CMD();
    
    CACHE_PIPE_FLUSH ();

    /* lastly, enable the transmitter and receiver  */

    * pGSMR_L |= (M8260_SCC_GSMRL_ENT | M8260_SCC_GSMRL_ENR);

    CACHE_PIPE_FLUSH ();

    intUnlock(oldlevel);			/* UNLOCK INTERRUPTS */
    }

/*******************************************************************************
*
* m8260SioIoctl - special device control
*
* This routine support device specific ioctl commands, including buad set,
* baud get, mode set, mode get, available mode get, change stop bit.
*
* NOTE
* - According to the manual, PSMR[SL] can be changed on the fly.
* 
* RETURNS: OK on success, EIO on device error, ENOSYS on unsupported
*          request.
*
*/

LOCAL STATUS m8260SioIoctl
    (
    M8260_SCC_CHAN *	pSccChan,	/* device to control */
    int			request,	/* request code */
    int			arg		/* some argument */
    )
    {
    int 	oldlevel;
    STATUS 	status = OK;
    UINT32      immrVal = pSccChan->immrVal;    /* holder for the immr value */
    UINT8   sccNum = pSccChan->sccNum;          /* holder for the scc number */
    UINT8   scc = sccNum - 1;            	/* a convenience */    
    UINT8   baud = pSccChan->bgrNum - 1;
    int         baudRate;
    VINT16 bdStatus;

    VINT32 *pBRGC = (VINT32 *) (immrVal + M8260_BRGC_BASE + 
			        (baud * M8260_BRGC_OFFSET_NEXT_BRGC));


    VINT16 *pSCCM = (VINT16 *) (immrVal + M8260_SCC_BASE + M8260_SCCM_OFFSET +
		      	        (scc * M8260_SCC_OFFSET_NEXT_SCC));

    VINT16 *pSCCE = (VINT16 *) (immrVal + M8260_SCC_BASE + M8260_SCCE_OFFSET +
		      	        (scc * M8260_SCC_OFFSET_NEXT_SCC));

    VINT16 *pPSMR = (VINT16 *) (immrVal + M8260_SCC_BASE + 
		      	        (scc * M8260_SCC_OFFSET_NEXT_SCC) +
			        M8260_PSMR_OFFSET);

    switch (request)
	{
	case SIO_BAUD_SET:
	    if (arg >= SCC_MIN_BAUD && arg <= SCC_MAX_BAUD)
                {
                
                /* calculate proper counter value, then enable BRG */
                
                baudRate = (pSccChan->clockRate + (8 * arg)) / (16 * arg);

                if (--baudRate > 0xfff)
                    *pBRGC = (M8260_BRGC_CD_MASK &
                   (((baudRate + 8) / 16) << M8260_BRGC_CD_SHIFT)) |
                    M8260_BRGC_EN | M8260_BRGC_DIV16 ;
                else
                    *pBRGC = (M8260_BRGC_CD_MASK &
                        (baudRate << 1)) | M8260_BRGC_EN;

                pSccChan->baudRate = arg;
                }
            else
	        status = EIO;
	    break;
    
	case SIO_BAUD_GET:
	    * (int *) arg = pSccChan->baudRate;
	    break;

	case SIO_MODE_SET:
            if (!((int) arg == SIO_MODE_POLL || (int) arg == SIO_MODE_INT))
                {
                status = EIO;
                break;
                }

            /* lock interrupt  */

            oldlevel = intLock();

            /* initialize channel on first MODE_SET */

            if (!pSccChan->channelMode)
                m8260SioResetChannel(pSccChan);
            
            /*
             * if switching from POLL to INT mode, wait for all characters to
             * clear the output pins
             */

            if ((pSccChan->channelMode == SIO_MODE_POLL) && (arg == SIO_MODE_INT))
                {
                do
                    {
                    M8260_SCC_16_RD((pSccChan->pBdBase +
                                     M8260_SCC_TX_BD_OFF +
                                     M8260_SCC_BD_STAT_OFF), bdStatus);
                    } while (bdStatus & M8260_SCC_UART_TX_BD_READY);
                }
            
            if (arg == SIO_MODE_INT)
		{
                /* reset the SCC's interrupt status bit */

                * M8260_SIPNR_L(immrVal) = pSccChan->intMask;
			
                /* enable this SCC's interrupt  */

		* M8260_SIMR_L(immrVal) |= pSccChan->intMask;

                /* reset the receiver status bit */

                * pSCCE = M8260_SCC_UART_SCCX_RX;
                
		/* enable receive and transmit interrupts at the scc */

		* pSCCM |= (M8260_SCC_UART_SCCX_RX | M8260_SCC_UART_SCCX_TX);

		CACHE_PIPE_FLUSH ();

		}
            else
		{

		/* disable transmit and receive interrupts */

		* pSCCM &= ~(M8260_SCC_UART_SCCX_RX | M8260_SCC_UART_SCCX_TX);

		CACHE_PIPE_FLUSH ();

		/* mask off this SCC's interrupt */
                
                * M8260_SIMR_L(immrVal) &= (~(pSccChan->intMask));
                
                }

            pSccChan->channelMode = arg;

            intUnlock(oldlevel);

            break;

        case SIO_MODE_GET:
            * (int *) arg = pSccChan->channelMode;
	    break;

        case SIO_AVAIL_MODES_GET:
            *(int *)arg = SIO_MODE_INT | SIO_MODE_POLL;
	    break;

        case SIO_HW_OPTS_SET:

	    /* wait for completion of previous transmit */

	    do
		{
		M8260_SCC_16_RD((pSccChan->pBdBase +
				 M8260_SCC_TX_BD_OFF +
				 M8260_SCC_BD_STAT_OFF), bdStatus);
		} while (bdStatus & M8260_SCC_UART_TX_BD_READY);

            if(arg & STOPB)
                {
                /* set stop bit to 2
                 * set PSMR[SL], can be changed on the fly
                 */

                * pPSMR |= M8260_SCC_UART_PSMR_SL;
                }
            else
                {
                /* set stop bit to 1
                 * clear PSMR[SL], it can be changed on the fly
                 */

                * pPSMR &= ~ M8260_SCC_UART_PSMR_SL;
                }
            break;

        case SIO_HW_OPTS_GET:
	default:
	    status = ENOSYS;
	}

    return (status);
    }

/*******************************************************************************
*
* m8260SioInt - handle SCC interrupts
*
* This routine is called to handle SCC interrupts.
*
* RETURNS: NA
*/

void m8260SioInt
    (
    M8260_SCC_CHAN *pSccChan
    )
    {
    char		outChar;
    VINT16              bdStatus;            /* holder for the BD status */

    UINT8       sccNum = pSccChan->sccNum;      /* holder for the fcc number */
    UINT8       scc = sccNum - 1;            	/* a convenience */
    UINT32      immrVal = pSccChan->immrVal;    /* holder for the immr value */

    VINT16 *pSCCE = (VINT16 *) (immrVal + M8260_SCC_BASE + M8260_SCCE_OFFSET +
		      	        (scc * M8260_SCC_OFFSET_NEXT_SCC));

#ifdef DEBUG_SCC
    static UINT32 numIsrEntriesTotal =0;
    static UINT32 numIsrEntriesRx = 0;
    static UINT32 numIsrEntriesTx = 0;
#endif

    CACHE_PIPE_FLUSH ();

    SCC_ISR_TOTAL_ADD;
    SCC_LOG(1, "m8260SioInt: Total(%d). SCC%d.\n", numIsrEntriesTotal, pSccChan->sccNum, 3,4,5,6);

    /* check for a Rx event */

    if (* pSCCE & M8260_SCC_UART_SCCX_RX )
	{

        SCC_ISR_RX_ADD;
        SCC_LOG(1, "m8260SioInt: Rx(%d). SCC%d.\n", numIsrEntriesRx, pSccChan->sccNum, 3,4,5,6);

	/*
	 * clear receive event bit by setting the bit in the event register.

⌨️ 快捷键说明

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