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

📄 serial_write.c

📁 zilog z80f91串口通用函数
💻 C
字号:
 /*
 * Copyright 2001, Metro Link, Inc.
 * All Rights Reserved
 *
 * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Metro Link, Inc. and may
 * contain proprietary, confidential and trade secret information of
 * Metro Link, Inc. and/or its partners.
 *  
 * The contents of this file may not be disclosed to third parties, copied or
 * duplicated in any form, in whole or in part, without the prior written
 * permission of Metro Link, Inc.
 *
 */
/*
 * File			:	serial_write.c
 *
 * Description	:	Contains implementation of serial write function.
 *					
 * Copyright 2003, ZiLOG Inc.
 * All Rights Reserved
 *
 * This is UNPUBLISHED PROPRIETARY SOURCE CODE of ZiLOG Inc., and might
 * contain proprietary, confidential and trade secret information of
 * ZiLOG, our partners and parties from which this code has been licensed.
 * 
 * The contents of this file may not be disclosed to third parties, copied or
 * duplicated in any form, in whole or in part, without the prior written
 * permission of ZiLOG Inc.
 */
 

#ifdef _IAR_CODE

#ifdef _EZ80F91
#include <ioez80f91.h>
#endif

#ifdef _EZ80F92
#include <ioez80f92.h>
#endif

#ifdef _EZ80F93
#include <ioez80f92.h>
#endif

#ifdef _EZ80L92
#include <ioez80l92.h>
#endif

#ifdef _EZ80190
#include <ioez80190.h>
#endif

#endif

#include <stdio.h>
#include "serial.h"
#include "_ez80.h"
#include "ZTypes.h"
#include "ZSysgen.h"
#include "ZDevice.h"
#include "ZThread.h"
#include "ZSemaphore.h"
#include "ZInterrupt.h"
extern UINT8 eZ80ProductRevision;

DDF_STATUS_t
UARTWrite
(
	RZK_DEVICE_CB_t *				pDev,
	INT8 *							pBuf,
	RZK_DEV_BYTES_t					Len
)
{
	UINT8								Data;
	UART_DVIOBLK *					pDevBlk = (UART_DVIOBLK *) pDev->dvinputoutput;
	UINT8								uart_base = pDevBlk->UARTbase;
	UINT8								do_crlf_check = pDevBlk->serparam->settings & SERSET_ONLCR;
	UINT8								do_cts_check = pDevBlk->serparam->settings & SERSET_RTSCTS;
	UINT8								do_sync =  pDevBlk->serparam->settings & SERSET_SYNC;
	UINT8								send_lf = RZK_FALSE;
	UINT8								msr;
	UINTRMASK						IntMask ;
	RZK_DEV_BYTES_t					txSize = Len ;
	UINT8  tempFCTL = 0;
       static UINT8  setupFlag = 0;

	if( pDevBlk->State != SERIAL_STATE_OPENED )
	{
		return UARTDEV_ERR_INVALID_OPERATION ;
	}
	
	RZKThreadLockForDelete();

	RZKAcquireSemaphore(pDevBlk->TxSem , INFINITE_SUSPEND ) ;
/* new silicon modification @Added by Venkat */
    if (setupFlag == 0)
	{
	    setupFlag = 1;

	    tempFCTL  = (FCTL_TRIG_8 | FCTL_FIFOEN);

        #ifdef _EZ80F91
        
        if (eZ80ProductRevision >= 2)
		{
		    tempFCTL |= (FCTL_CLRTXF | FCTL_CLRRXF);
        }
        #endif
        UART_FCTL(uart_base) = tempFCTL; /* modified by Venkat CR#7743 */
//	    UART_FCTL(0xD0) = tempFCTL;
    }

	while( Len )
	{
		if( pDevBlk->State != SERIAL_STATE_OPENED )
		{
			RZKReleaseSemaphore(pDevBlk->TxSem) ;
			RZKThreadUnLockForDelete();
			return UARTDEV_ERR_INVALID_OPERATION ;
		}

		/*
		 * Defer sending if the peer flows off.  If this happens the current task
		 * will block until the interrupt handler detects CTS has been reasserted.
		 */
		if( do_cts_check )
		{
			IntMask = RZKDisableInterrupts();
			msr = UART_MSR( uart_base );
			if( !(msr&MSR_CTS) )
			{
				pDevBlk->pTxTask = RZKGetCurrentThread();
				UART_IER(uart_base) |= IER_TIE;
//				RZKEnableInterrupts(IntMask);
//				RZKSuspendThread(RZKGetCurrentThread(), INFINITE_SUSPEND);
				RZKSuspendInterruptThread();

				if(pDevBlk->State == SERIAL_STATE_CLOSED)
				{
					RZKReleaseSemaphore( pDevBlk->TxSem );
					RZKThreadUnLockForDelete();
					return (DDFERR_DEVICE_CLOSED);
				}
			}
			RZKEnableInterrupts(IntMask);
			
		}

		IntMask = RZKDisableInterrupts();
		if( pDevBlk->TxCount )
		{
			pDevBlk->TxCount--;
			RZKEnableInterrupts(IntMask);

			// Put the next byte in the Tx fifo
			if( send_lf == RZK_TRUE )
			{
				send_lf = RZK_FALSE;
				UART_THR(uart_base) = '\n';
				Len--;
			}
			else
			{
				Data = *pBuf++;
				if( (do_crlf_check) && (Data == '\n') ) 
				{
					send_lf = RZK_TRUE;
					UART_THR(uart_base) = '\r';
				}
				else
				{
					Len--;				
				UART_THR(uart_base) = Data;
                                }
			}
		}
		else
		{
			RZKEnableInterrupts(IntMask);
			Data = UART_LSR(uart_base);
			if( do_sync ) 
			{	// Synchronous Tx
				while( !(Data & LSR_THRE) )
				{
					Data = UART_LSR(uart_base);	
				}
				pDevBlk->TxCount = UART_FIFODEPTH;
			}
			else
			{	
				if( Data & LSR_THRE )
				{
					pDevBlk->TxCount = UART_FIFODEPTH;
				}
				else
				{	// Interrupt-driven Tx
					IntMask = RZKDisableInterrupts();
					pDevBlk->pTxTask = RZKGetCurrentThread() ;
					UART_IER(uart_base) |= IER_TIE;
					
//					RZKSuspendThread(RZKGetCurrentThread(), INFINITE_SUSPEND);					
					RZKSuspendInterruptThread();
					RZKEnableInterrupts(IntMask);
					if(pDevBlk->State == SERIAL_STATE_CLOSED)
					{
						RZKReleaseSemaphore( pDevBlk->TxSem );
						RZKThreadUnLockForDelete();
						return (DDFERR_DEVICE_CLOSED);
					}
				}
			}
		}
	}
	RZKReleaseSemaphore(pDevBlk->TxSem );
	RZKThreadUnLockForDelete();
	return  txSize ;
}		

⌨️ 快捷键说明

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