U
    ÓÖ½XwN  ã                   @   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dZ‡ fdd„Zdd„ Zdd„ Zd	d
„ Zdd„ Z	e
dd„ ƒZd;dd„Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zd d!„ Ze
d"d#„ ƒZe
d$d%„ ƒZe
d&d'„ ƒZe
d(d)„ ƒZd<d,d-„Zd=d/d0„Ze
d1d2„ ƒZd3d4„ Zd5d6„ Zd7d8„ Zej j!d9d:„ ƒZ ‡  Z"S )>ÚSerialz5Serial port implementation for Win32 based on ctypes.)é2   éK   én   é†   é–   éÈ   i,  iX  i°  i  i`	  iÀ  i€%  i K  i –  i á  i Â c                    s(   d | _ d | _d | _tt| ƒj||Ž d S ©N)Ú_port_handleÚ_overlapped_readÚ_overlapped_writeÚsuperr   Ú__init__)ÚselfÚargsÚkwargs©Ú	__class__© ú4/usr/lib/python3/dist-packages/serial/serialwin32.pyr      s    zSerial.__init__c              	   C   s  | j dkrtdƒ‚| jr tdƒ‚| j}z.| ¡  d¡rRt|dd… ƒdkrRd| }W n tk
rh   Y nX t 	|tj
tjB ddtjtjtjB d¡| _| jtjkr¼d| _td	 | jt ¡ ¡ƒ‚zšt ¡ | _t dd
dd¡| j_t ¡ | _t dddd¡| j_t | jdd¡ t ¡ | _t | jt | j¡¡ |  ¡  t  | jtj!tj"B tj#B tj$B ¡ W n.   z|  %¡  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}é   é   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!   s^    
"

ù



ÿÿþzSerial.openc                 C   sÎ  | j stdƒ‚t ¡ }| 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r‚n*| jdkr–tj|_ntt| jd ƒdƒ|_t | j t |¡¡ t | j tj¡ t ¡ }t | j t |¡¡ | 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tj krztj!|_"d|_#nˆ| jtj$kr˜tj%|_"d|_#nj| jtj&kr¶tj'|_"d|_#nL| jtj(krÔtj)|_"d|_#n.| jtj*kròtj+|_"d|_#ntd | j¡ƒ‚| j,tj-krtj.|_/n@| j,tj0kr2tj1|_/n(| j,tj2krJtj3|_/ntd | j,¡ƒ‚d|_4| j5dkrž| j6r~tj7|_8n| j9rŒtj:ntj;|_8| j6|_<n¢| j5j=sºtd | j5j=¡ƒ‚| j5j>rÖtd | j5j>¡ƒ‚| j5j?dk	rötd | j5j?¡ƒ‚| j5j@dk	rtd | j5j@¡ƒ‚| j5jAr2td | 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 T| j t |¡¡sÊtd t U¡ ¡ƒ‚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   r,   Z_timeoutZMAXDWORDZReadIntervalTimeoutÚmaxr$   ZReadTotalTimeoutConstantZ_inter_byte_timeoutÚ_write_timeoutZWriteTotalTimeoutConstantÚSetCommTimeoutsr(   r.   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SetCommStater)   )r   ZtimeoutsZcomDCBr   r   r   r/   b   sÖ    











ÿÿ
ÿÿÿÿÿÿ
ÿÿ
ÿÿzSerial._reconfigure_portc                 C   s|   | j dk	rxt | j | j¡ | jdk	r@|  ¡  t | jj¡ d| _| jdk	rf|  	¡  t | jj¡ d| _t | j ¡ d| _ dS )zinternal close port helperN)
r   r   r<   r-   r   Úcancel_readZCloseHandler*   r   Úcancel_write©r   r   r   r   r5   ã   s    


zSerial._closec                 C   s   | j r|  ¡  d| _ dS )z
Close portFN)r    r5   rB   r   r   r   Úcloseó   s    zSerial.closec                 C   sD   t  ¡ }t  ¡ }t  | jt |¡t |¡¡s>td t 	¡ ¡ƒ‚|j
S )z9Return the number of bytes currently in the input buffer.úClearCommError failed ({!r}))r   ÚDWORDÚCOMSTATÚClearCommErrorr   r(   r.   r   r'   r)   ÚcbInQue©r   ÚflagsÚcomstatr   r   r   Ú
in_waitingû   s
    zSerial.in_waitingr   c           
   	   C   sR  | j s
t‚|dkrDt | jj¡ t ¡ }t ¡ }t | j	t
 |¡t
 |¡¡s`td t
 ¡ ¡ƒ‚| jdkrvt|j|ƒn|}|dkr<t
 |¡}t ¡ }t | j	||t
 |¡t
 | j¡¡}|sât ¡ tjtjfkrâtd t
 ¡ ¡ƒ‚t | j	t
 | j¡t
 |¡d¡}|s*t ¡ tjkr*td t
 ¡ ¡ƒ‚|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   rD   zReadFile failed ({!r})Tz!GetOverlappedResult failed ({!r})N)r    r   r   Z
ResetEventr   r*   rE   rF   rG   r   r(   r.   r   r'   r)   ZtimeoutÚminrH   Zcreate_string_bufferZReadFileÚGetLastErrorÚERROR_SUCCESSÚERROR_IO_PENDINGÚGetOverlappedResultÚERROR_OPERATION_ABORTEDÚrawÚvalueÚbytes)
r   ÚsizerJ   rK   ÚnZbufÚrcZread_okZ	result_okÚreadr   r   r   rY     sD    



û
üzSerial.readc                 C   s  | j s
t‚t|ƒ}|rt ¡ }t | j|t|ƒt 	|¡| j
¡}| jdkrº|stt ¡ tjtjfkrttd t ¡ ¡ƒ‚t | j| j
t 	|¡d¡ t ¡ tjkr¢|jS |jt|ƒkr´t‚|jS |rÄtjnt ¡ }|tjtjtjfkrädS |tjtjfk rþt|ƒS td t ¡ ¡ƒ‚ndS dS )z2Output the given byte string over the serial port.r   zWriteFile failed ({!r})TN)r    r   r   r   rE   Z	WriteFiler   Úlenr(   r.   r   r;   rN   rO   rP   r   r'   r)   rQ   rR   rT   r   ZERROR_INVALID_USER_BUFFERZERROR_NOT_ENOUGH_MEMORY)r   ÚdatarW   ZsuccessZ	errorcoder   r   r   Úwrite-  s0     

ÿzSerial.writec                 C   s   | j rt d¡ q dS )zb        Flush of file like objects. In this case, wait until all data
        is written.
        gš™™™™™©?N)Úout_waitingÚtimeÚsleeprB   r   r   r   ÚflushR  s    zSerial.flushc                 C   s$   | j s
t‚t | jtjtjB ¡ dS )z9Clear input buffer, discarding all that is in the buffer.N)r    r   r   r0   r   r3   r4   rB   r   r   r   Úreset_input_buffer]  s    zSerial.reset_input_bufferc                 C   s$   | j s
t‚t | 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   r0   r   r1   r2   rB   r   r   r   Úreset_output_bufferc  s    zSerial.reset_output_bufferc                 C   s.   | j s
t‚| jrt | j¡ nt | j¡ dS )zBSet break: Controls TXD. When active, to transmitting is possible.N)r    r   Z_break_stater   ZSetCommBreakr   ZClearCommBreakrB   r   r   r   Ú_update_break_statel  s
    zSerial._update_break_statec                 C   s,   | j rt | jtj¡ nt | jtj¡ dS )z)Set terminal status line: Request To SendN)r>   r   ÚEscapeCommFunctionr   ZSETRTSZCLRRTSrB   r   r   r   Ú_update_rts_stateu  s    zSerial._update_rts_statec                 C   s,   | j rt | jtj¡ nt | jtj¡ dS )z-Set terminal status line: Data Terminal ReadyN)r?   r   rd   r   ZSETDTRZCLRDTRrB   r   r   r   Ú_update_dtr_state|  s    zSerial._update_dtr_statec                 C   s,   | j s
t‚t ¡ }t | jt |¡¡ |jS r   )	r    r   r   rE   ZGetCommModemStatusr   r(   r.   rT   )r   Ústatr   r   r   Ú_GetCommModemStatusƒ  s
    zSerial._GetCommModemStatusc                 C   s   t j|  ¡ @ dkS )z(Read terminal status line: Clear To Sendr   )r   Z	MS_CTS_ONrh   rB   r   r   r   ÚctsŠ  s    z
Serial.ctsc                 C   s   t j|  ¡ @ dkS )z)Read terminal status line: Data Set Readyr   )r   Z	MS_DSR_ONrh   rB   r   r   r   Údsr  s    z
Serial.dsrc                 C   s   t j|  ¡ @ dkS )z)Read terminal status line: Ring Indicatorr   )r   Z
MS_RING_ONrh   rB   r   r   r   Úri”  s    z	Serial.ric                 C   s   t j|  ¡ @ dkS )z)Read terminal status line: Carrier Detectr   )r   Z
MS_RLSD_ONrh   rB   r   r   r   Úcd™  s    z	Serial.cdr   Nc                 C   s    |dkr|}t  | j||¡ dS )z        Recommend a buffer size to the driver (device driver can ignore this
        value). Must be called before the port is opened.
        N)r   r+   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tj¡ nt | 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   rd   r   ZSETXONZSETXOFF)r   Úenabler   r   r   Úset_output_flow_control©  s
    zSerial.set_output_flow_controlc                 C   sD   t  ¡ }t  ¡ }t  | jt |¡t |¡¡s>td t 	¡ ¡ƒ‚|j
S )z0Return how many bytes the in the outgoing bufferrD   )r   rE   rF   rG   r   r(   r.   r   r'   r)   ZcbOutQuerI   r   r   r   r]   ·  s
    zSerial.out_waitingc                 C   sP   t  ¡ }t  | jt |¡t |¡d¡}|sLt  ¡ t jt jfkrLt  	| j|¡ dS )úACancel a blocking read operation, may be called from other threadFN)
r   rE   rQ   r   r(   r.   rN   rP   ZERROR_IO_INCOMPLETEZ
CancelIoEx)r   Z
overlappedrX   Úerrr   r   r   Ú_cancel_overlapped_ioÀ  s    üzSerial._cancel_overlapped_ioc                 C   s   |   | j¡ dS )rp   N)rr   r   rB   r   r   r   r@   Í  s    zSerial.cancel_readc                 C   s   |   | j¡ dS )zBCancel a blocking write operation, may be called from other threadN)rr   r   rB   r   r   r   rA   Ñ  s    zSerial.cancel_writec                 C   s0   |dk	r|st d |¡ƒ‚ntjj | |¡ dS )z$Change the exclusive access setting.Nz.win32 only supports exclusive access (not: {}))r%   r'   r=   r   Ú	exclusiveÚ__set__)r   rs   r   r   r   rs   Õ  s    zSerial.exclusive)r   )r   N)T)#Ú__name__Ú
__module__Ú__qualname__Ú__doc__Z	BAUDRATESr   r6   r/   r5   rC   ÚpropertyrL   rY   r\   r`   ra   rb   rc   re   rf   rh   ri   rj   rk   rl   rm   ro   r]   rr   r@   rA   r   rs   ÚsetterÚ__classcell__r   r   r   r   r      sH   A 

)%		




	

r   )r(   r^   r=   r   Zserial.serialutilr   r   r   r   r   r   r   r   r   r   Ú<module>   s
   