
­­­­­­­­­­­­­­­­­­
<!DOCTYPE html>
<html>
3
M]WZJ                 @   sT   d dl Z d dlZd dlmZ d dlZd dlmZmZmZmZm	Z	 G dd deZ
dS )    N)win32)
SerialBaseSerialExceptionto_bytesportNotOpenErrorwriteTimeoutErrorc                   s  e Zd ZdZdIZ fddZdd Zdd Zdd Zdd Z	e
dd ZdJd d!Zd"d# Zd$d% Zd&d' Zd(d) Zd*d+ Zd,d- Zd.d/ Zd0d1 Ze
d2d3 Ze
d4d5 Ze
d6d7 Ze
d8d9 ZdKd<d=ZdLd?d@Ze
dAdB ZdCdD ZdEdF ZdGdH Z  ZS )MSerialz5Serial port implementation for Win32 based on ctypes.2   K   n            ,  X      `	    %   K          c                s(   d | _ d | _d | _tt| j|| d S )N)_port_handle_overlapped_read_overlapped_writesuperr   __init__)selfargskwargs)	__class__ !/usr/lib/python3.6/serialwin32.pyr      s    zSerial.__init__c             C   s  | j dkrtd| jr td| j}y.|j jdrRt|dd dkrRd| }W n tk
rh   Y nX tj	|tj
tjB ddtjtjtjB d| _| jtjkrd| _td	j| jtj ytj | _tjdd
dd| j_tj | _tjdddd| j_tj| jdd tj | _tj| jtj| j | j  tj | jtj!tj"B tj#B tj$B  W n.   y| j%  W n   Y nX d| _ Y nX d| _dS )zx        Open port with current settings. This may throw a SerialException
        if the port cannot be opened.
        Nz.Port must be configured before it can be used.zPort is already open.ZCOM      z\\.\r   zcould not open port {!r}: {!r}   i   T)&Z_portr   is_opennameupper
startswithint
ValueErrorr   Z
CreateFileZGENERIC_READZGENERIC_WRITEZOPEN_EXISTINGFILE_ATTRIBUTE_NORMALZFILE_FLAG_OVERLAPPEDr   ZINVALID_HANDLE_VALUEformatZportstrctypesWinErrorZ
OVERLAPPEDr   ZCreateEventhEventr   	SetupCommCOMMTIMEOUTS_orgTimeoutsZGetCommTimeoutsbyref_reconfigure_port	PurgeCommPURGE_TXCLEARPURGE_TXABORTPURGE_RXCLEARPURGE_RXABORT_close)r   Zportr#   r#   r$   open!   sR    
"




zSerial.openc             C   s  | j stdtj }| jdkr"n*| jdkr6tj|_ntt| jd d|_	| jdkrv| j
dk	rvtt| j
d d|_| jdkrn*| jdkrtj|_ntt| jd d|_tj| j tj| tj| j tj tj }tj| j tj| | j|_| jtjkr
d|_nR| jtjkr d|_n<| jtjkr6d|_n&| jtjkrLd	|_ntd
j| j| jtj krztj!|_"d|_#n| jtj$krtj%|_"d|_#nj| jtj&krtj'|_"d|_#nL| jtj(krtj)|_"d|_#n.| jtj*krtj+|_"d|_#ntdj| j| j,tj-krtj.|_/n@| j,tj0kr2tj1|_/n(| j,tj2krJtj3|_/ntdj| j,d|_4| j5dkr| j6r~tj7|_8n| j9rtj:ntj;|_8| j6|_<n| j5j=stdj| j5j=| j5j>rtdj| j5j>| j5j?dk	rtdj| j5j?| j5j@dk	rtdj| j5j@| j5jAr2tdj| j5jAtjB|_8d|_<| jCrRtjD|_En| jFr`tjGntjH|_E| jC|_I| jJ|_K| jJ|_Ld|_Md|_Nd|_OtjP|_QtjR|_StjT| j tj|stdjtjU dS )z,Set communication parameters on opened port.z'Can only operate on a valid port handleNr   i  r'            r&   z%Unsupported number of data bits: {!r}zUnsupported parity mode: {!r}z%Unsupported number of stop bits: {!r}z:Unsupported value for RS485Settings.rts_level_for_tx: {!r}z:Unsupported value for RS485Settings.rts_level_for_rx: {!r}z9Unsupported value for RS485Settings.delay_before_tx: {!r}z9Unsupported value for RS485Settings.delay_before_rx: {!r}z2Unsupported value for RS485Settings.loopback: {!r}zCCannot configure port, something went wrong. Original message: {!r})Vr   r   r   r4   Z_timeoutZMAXDWORDZReadIntervalTimeoutmaxr,   ZReadTotalTimeoutConstantZ_inter_byte_timeout_write_timeoutZWriteTotalTimeoutConstantSetCommTimeoutsr0   r6   ZSetCommMaskZEV_ERRZDCBZGetCommStateZ	_baudrateZBaudRateZ	_bytesizeserialZFIVEBITSZByteSizeZSIXBITSZ	SEVENBITSZ	EIGHTBITSr-   r/   Z_parityZPARITY_NONEZNOPARITYZParityZfParityZPARITY_EVENZ
EVENPARITYZ
PARITY_ODDZ	ODDPARITYZPARITY_MARKZ
MARKPARITYZPARITY_SPACEZSPACEPARITYZ	_stopbitsZSTOPBITS_ONEZ
ONESTOPBITZStopBitsZSTOPBITS_ONE_POINT_FIVEZONE5STOPBITSZSTOPBITS_TWOZTWOSTOPBITSZfBinaryZ_rs485_modeZ_rtsctsZRTS_CONTROL_HANDSHAKEZfRtsControl
_rts_stateZRTS_CONTROL_ENABLEZRTS_CONTROL_DISABLEZfOutxCtsFlowZrts_level_for_txZrts_level_for_rxZdelay_before_txZdelay_before_rxZloopbackZRTS_CONTROL_TOGGLEZ_dsrdtrZDTR_CONTROL_HANDSHAKEZfDtrControl
_dtr_stateZDTR_CONTROL_ENABLEZDTR_CONTROL_DISABLEZfOutxDsrFlowZ_xonxoffZfOutXZfInXZfNullZ
fErrorCharZfAbortOnErrorZXONZXonCharZXOFFZXoffCharZSetCommStater1   )r   ZtimeoutsZcomDCBr#   r#   r$   r7   b   s    














zSerial._reconfigure_portc             C   s|   | j dk	rxtj| j | j | jdk	r@| j  tj| jj d| _| jdk	rf| j	  tj| jj d| _tj| j  d| _ dS )zinternal close port helperN)
r   r   rD   r5   r   cancel_readZCloseHandler2   r   cancel_write)r   r#   r#   r$   r=      s    


zSerial._closec             C   s   | j r| j  d| _ dS )z
Close portFN)r(   r=   )r   r#   r#   r$   close   s    zSerial.closec             C   s:   t j }t j }t j| jtj|tj|s4td|jS )z9Return the number of bytes currently in the input buffer.zcall to ClearCommError failed)	r   DWORDCOMSTATClearCommErrorr   r0   r6   r   cbInQue)r   flagscomstatr#   r#   r$   
in_waiting   s
    zSerial.in_waitingr'   c       
      C   sT  | j s
t|dkrFtj| jj tj }tj }tj| j	t
j|t
j|s`tdjt
j | jdkrvt|j|n|}|dkr>t
j|}tj }tj| j	||t
j|t
j| j}| rtj tjtjfkrtdjt
j tj| j	t
j| jt
j|d}|s,tj tjkr,tdjt
j |jd|j }	nt }	nt }	t|	S )z        Read size bytes from the serial port. If a timeout is set it may
        return less characters as requested. With no timeout it will block
        until the requested number of bytes is read.
        r   zClearCommError failed ({!r})zReadFile failed ({!r})Tz!GetOverlappedResult failed ({!r})N)r(   r   r   Z
ResetEventr   r2   rK   rL   rM   r   r0   r6   r   r/   r1   ZtimeoutminrN   Zcreate_string_bufferZReadFileGetLastErrorZERROR_SUCCESSERROR_IO_PENDINGGetOverlappedResultERROR_OPERATION_ABORTEDrawvaluebytes)
r   sizerO   rP   nZbufrcZread_okZ	result_okreadr#   r#   r$   r]     s@    



zSerial.readc             C   s   | j s
tt|}|rtj }tj| j|t|tj	|| j
}| rdtj tjkrdtdjtj | jdkrtj| j| j
tj	|d}tj tjkr|jS |jt|krt|jS dS dS )z2Output the given byte string over the serial port.zWriteFile failed ({!r})r   TN)r(   r   r   r   rK   Z	WriteFiler   lenr0   r6   r   rS   rT   r   r/   r1   rC   rU   rV   rX   r   )r   datar[   errr#   r#   r$   write-  s      
zSerial.writec             C   s   x| j rtjd qW dS )zb        Flush of file like objects. In this case, wait until all data
        is written.
        g?N)out_waitingtimeZsleep)r   r#   r#   r$   flushG  s    zSerial.flushc             C   s$   | j s
ttj| jtjtjB  dS )z9Clear input buffer, discarding all that is in the buffer.N)r(   r   r   r8   r   r;   r<   )r   r#   r#   r$   reset_input_bufferR  s    zSerial.reset_input_bufferc             C   s$   | j s
ttj| jtjtjB  dS )zs        Clear output buffer, aborting the current output and discarding all
        that is in the buffer.
        N)r(   r   r   r8   r   r9   r:   )r   r#   r#   r$   reset_output_bufferX  s    zSerial.reset_output_bufferc             C   s.   | j s
t| jrtj| j ntj| j dS )zBSet break: Controls TXD. When active, to transmitting is possible.N)r(   r   Z_break_stater   ZSetCommBreakr   ZClearCommBreak)r   r#   r#   r$   _update_break_statea  s
    zSerial._update_break_statec             C   s,   | j rtj| jtj ntj| jtj dS )z)Set terminal status line: Request To SendN)rF   r   EscapeCommFunctionr   ZSETRTSZCLRRTS)r   r#   r#   r$   _update_rts_statej  s    zSerial._update_rts_statec             C   s,   | j rtj| jtj ntj| jtj dS )z-Set terminal status line: Data Terminal ReadyN)rG   r   rh   r   ZSETDTRZCLRDTR)r   r#   r#   r$   _update_dtr_stateq  s    zSerial._update_dtr_statec             C   s,   | j s
ttj }tj| jtj| |jS )N)	r(   r   r   rK   ZGetCommModemStatusr   r0   r6   rX   )r   statr#   r#   r$   _GetCommModemStatusx  s
    zSerial._GetCommModemStatusc             C   s   t j| j @ dkS )z(Read terminal status line: Clear To Sendr   )r   Z	MS_CTS_ONrl   )r   r#   r#   r$   cts  s    z
Serial.ctsc             C   s   t j| j @ dkS )z)Read terminal status line: Data Set Readyr   )r   Z	MS_DSR_ONrl   )r   r#   r#   r$   dsr  s    z
Serial.dsrc             C   s   t j| j @ dkS )z)Read terminal status line: Ring Indicatorr   )r   Z
MS_RING_ONrl   )r   r#   r#   r$   ri  s    z	Serial.ric             C   s   t j| j @ dkS )z)Read terminal status line: Carrier Detectr   )r   Z
MS_RLSD_ONrl   )r   r#   r#   r$   cd  s    z	Serial.cd   Nc             C   s    |dkr|}t j| j|| dS )z        Recommend a buffer size to the driver (device driver can ignore this
        value). Must be called before the port is opended.
        N)r   r3   r   )r   Zrx_sizeZtx_sizer#   r#   r$   set_buffer_size  s    zSerial.set_buffer_sizeTc             C   s4   | j s
t|r tj| jtj ntj| jtj dS )a*          Manually control flow - when software flow control is enabled.
        This will do the same as if XON (true) or XOFF (false) are received
        from the other device and control the transmission accordingly.
        WARNING: this function is not portable to different platforms!
        N)r(   r   r   rh   r   ZSETXONZSETXOFF)r   enabler#   r#   r$   set_output_flow_control  s
    zSerial.set_output_flow_controlc             C   s:   t j }t j }t j| jtj|tj|s4td|jS )z0Return how many bytes the in the outgoing bufferzcall to ClearCommError failed)	r   rK   rL   rM   r   r0   r6   r   ZcbOutQue)r   rO   rP   r#   r#   r$   rb     s
    zSerial.out_waitingc             C   sR   t j }t j| jtj|tj|d}| rNt j t jt jfkrNt j	| j| dS )zACancel a blocking read operation, may be called from other threadFN)
r   rK   rU   r   r0   r6   rS   rT   ZERROR_IO_INCOMPLETEZ
CancelIoEx)r   Z
overlappedr\   r`   r#   r#   r$   _cancel_overlapped_io  s    zSerial._cancel_overlapped_ioc             C   s   | j | j dS )zACancel a blocking read operation, may be called from other threadN)ru   r   )r   r#   r#   r$   rH     s    zSerial.cancel_readc             C   s   | j | j dS )zBCancel a blocking write operation, may be called from other threadN)ru   r   )r   r#   r#   r$   rI     s    zSerial.cancel_write)r	   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   )r'   )rq   N)T) __name__
__module____qualname____doc__Z	BAUDRATESr   r>   r7   r=   rJ   propertyrQ   r]   ra   rd   re   rf   rg   ri   rj   rl   rm   rn   ro   rp   rr   rt   rb   ru   rH   rI   __classcell__r#   r#   )r"   r$   r      s:    A 	
)		
	
	r   )r0   rc   rE   r   Zserial.serialutilr   r   r   r   r   r   r#   r#   r#   r$   <module>   s
   