c g7ddlmZddlZddlZddlZddlZddlZddlZddlZddl Z ddl m Z m Z m Z mZmZmZGddeZdZejZedddkr'ddlZdZd Zd Zd Zd Zd ZdZdZdZdZ GddeZ!nedkrGddeZ!nedddkrddlZdZ"GddeZ!ncedddks*edddksedddksedddkrGd d!eZ#Gd"deZ!nGd#deZ!e$ed$d%Z%e$ed&d'Z&e$ed(d)Z'e$ed*d+Z(e$ed,dZ)e$ed-dZ*e$ed.d/Z+e$ed0d1Z,e$ed2d3Z-e$ed4d5Z.e$ed6e,Z/e$ed7e-Z0e1ed8rej2Z2n e$ed9d:Z2e$ed;d<Z3ej4d=dZ5ej4d=e*Z6ej4d=e)Z7e$ed>d?Z8e$ed@dAZ9GdBdCe e!Z:GdDdEe:Z;GdFdGe:Z>>(&FFFf$FFFFFFFg%FFF DGW%8#>>>>> v v v !T![![\prs!t!tuuu vsA-B B<#B77B<ctjddgdz} tj|jt||dxxt jzcc<|dxxtzcc<|x|d<|d<tj|jt|dS#t$r(}td ||d}~wwxYw)NrVr@r+r:r;z'Failed to set custom baud rate ({}): {}) rXrrrTCGETS2rYCBAUDBOTHERTCSETS2r\r]r^)rrr_r`s rrz&PlatformSpecific._set_special_baudrates+cA38,,C ` DGWc222A7=.(A& #++AR DGWc22222 ` ` ` !J!Q!QRZ\]!^!^___ `sA:B C !#CC ctjddgdz} tj|jt||dxxt zcc<||jr|dxxtzcc<n|dxxtzcc<|jr|dxxtzcc<n|dxxtzcc<|j r|dxxtzcc<n|dxxtzcc<|j t|j dz|d<|jt|jdz|d<nd|d<tj|jt|dS#t $r'}t#d|d}~wwxYw)NrVrr9r*r+zFailed to set RS485 mode: {})rXrrr TIOCGRS485SER_RS485_ENABLEDloopbackSER_RS485_RX_DURING_TXrts_level_for_txSER_RS485_RTS_ON_SENDrts_level_for_rxSER_RS485_RTS_AFTER_SENDdelay_before_txintdelay_before_rx TIOCSRS485r\r]r^)rrr_r`s rrz PlatformSpecific._set_rs485_modes+cA37++C K DGZ555A++!-%.:A"88A#9"99%69A"77A#8"88%6<A"::A#;";;%5A!$^%Cd%J!K!KA%5A!$^%Cd%J!K!KACF DGZ55555 K K K !?!F!Fq!I!IJJJ KsD8E F"FFN)r#r$r%r&rrrr'rrr/r/_sX  X  X   X   X  X  X   X   X   X   X   X   X   X   X   X  X!  " X#  $?    D v v v$ ` ` `  K K K K Krr/cygwinc *eZdZddddddddd d d d Zd S)r/rArBrCrDrErFrGrHrIrJrK) iirLrMrNrOrPrQrRrSrTN)r#r$r%r&r'rrr/r/s>   rr7darwinlTceZdZejddZdZdZe eddkrdZ dZ d S) r/r+.{t zt rr9cttjd|g}tj|jt|ddS)NrVr*)rXrrr IOSSIOSPEED)rrr_s rrz&PlatformSpecific._set_special_baudrates3k#z22 DG[#q99999rc|jr&tj|jtjdStj|jtjdSz[ Set break: Controls TXD. When active, no transmitting is possible. Nrrrrr/rr r!s rr"z$PlatformSpecific._update_break_stateL  @ DG%5%>????? DG%5%>?????rN) r#r$r%osunamesplit osx_versionrr rrrr"r'rrr/r/s{bhjjm))#..  3{1~  ! # # : : :  @ @ @ @ @rr3bsdr8freebsdnetbsdopenbsdceZdZdZdS)ReturnBaudratec|S)Nr')rkeys r __getitem__zReturnBaudrate.__getitem__sJrN)r#r$r%rr'rrrrs#     rrc0eZdZeZdZdZdZdS)r/rzr{c|jr&tj|jtjdStj|jtjdSrrr!s rr"z$PlatformSpecific._update_break_staterrN)r#r$r%rr&rr r"r'rrr/r/sB,^-- @ @ @ @ @rceZdZdS)r/N)r#r$r%r'rrr/r/ s rTIOCMGETiTTIOCMBISiTTIOCMBICiTTIOCMSETiT TIOCM_DTR TIOCM_RTS TIOCM_CTSrW TIOCM_CARrb TIOCM_RNG TIOCM_DSRTIOCM_CDTIOCM_RITIOCINQFIONREADiTTIOCOUTQiTIri'Tr i(Tc eZdZdZdZddZdZedZd dZ d Z d Z d Z d Z d ZdZdZd!dZdZdZedZedZedZedZedZdZd"dZd"dZdZdS)#Serialz Serial port class POSIX implementation. Serial port configuration is done with termios and fcntl. Runs on Linux and many other Un*x like systems. c|jtd|jrtdd|_ t j|jtjtjztj z|_nG#t$r:}d|_t|j d |j|d}~wwxYwd\|_ |_d\|_|_ |d |js||js|n7#t,$r*}|j tjtjfvrYd}~nd}~wwxYw|t j\|_ |_t j\|_|_t7j|j t6jtj t7j|jt6jtj n#t:$r t j|jn#t>$rYnwxYwd|_|j t j|jd|_|j t j|j d|_ |j t j|jd|_|j t j|jd|_wxYwd|_dS)zo 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.zPort is already open.zcould not open port {}: {}NNT) force_update) _portris_openrropenportstrO_RDWRO_NOCTTY O_NONBLOCKOSErrorerrnor^pipe_abort_read_rpipe_abort_read_wpipe_abort_write_rpipe_abort_write_w_reconfigure_port_dsrdtr_update_dtr_state_rtscts_update_rts_stater\EINVALENOTTY_reset_input_bufferpiperF_SETFL BaseExceptionclose Exception)rmsgr`s rrz Serial.open7s : !"RSS S < ;!"9:: : cgdlBI ,Cbm,STTDGG c c cDG!#)-I-P-PQUQ[]`-a-abb b c :D6 6;E8!8)   " " " 5 5 5 |-**,,,|-**,,,   75<">>>?>>>>   $ $ & & &=?WYY :D "D$:?Awyy GL07=@=!#*>2< ").12 2* 1 1Dw%% 1''40000 7=7=07=@AA 7=7=07=@7>QRR 7G $ $ $ gm^ #E 7H % % % gn_ $E [%gu||DN/K/KLL LFVV [ [ [ ["&"9$."II [ [ [ A&,,FVV AAA&-gx&@&@@FVVVA["%dn"5"5K#Q()B)I)I$.)Y)YZZZ'"WWW$%>%E%Edn%U%UVVVW'! [ [. '- >Q   W[ EE ^q W[ EE ^q W[ EE ^q W[ EE5<V0 0 0 w~& &EE ^v= = = gn %EE ^v2 2 2 gn %EECJJ4>ZZ[[ [ 7=7>122 <6- - - w~6?@ @EE \V/ / / w~./ /E gn %EE \V. . . fW E gnw~5 6EE \V/ / /F / gnv-> ?EE \V0 0 0V 0 gnv- .E w~& &EE3::4<HHII I 7G $ $ 9} I',677<'-7'-GHH} 9',677<'-788 7I & & 0| ,'/*7?++ Wm , , 0| 0'-.7.// !88tczz188>>?? ?7< 199 299%@@AA A!7=  BE5%KyXX  ueVVR@ B B B  "  & &{ 3 3 3   '  !1 2 2 2 2 2 ( 's1A B".BB##DD="D88D=/K N&K)(N&) N 4 K>=N >!L"N !L""N &M(:.N (2NN N&N  N&%N&cx|jr|jtj|jd|_tj|jtj|jtj|jtj|jd\|_|_d\|_|_d|_dSdS)z Close portNrF)rrrrrrrrr!s rrz Serial.closes < !w"!!!/000/00001110111AK>&(>CM@')@ DLLL ! !rctj|jtt}t jd|dS)z9Return the number of bytes currently in the input buffer.rr)rrrrTIOCM_zero_strstructunpackrss r in_waitingzSerial.in_waiting!s0 K. 9 9}S!$$Q''rr*cV|jstt}t|j}t ||kr t j|j|jggg| \}}}|j|vrtj |jdnq|snmtj |j|t |z }|std| |n#t$rl}|jtjtjtjtjtjfvr"td|Yd}~nd}~wt j$rm}|dtjtjtjtjtjfvr"td|Yd}~nd}~wwxYw|rnt ||kt1|S) 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. rhzgdevice reports readiness to read but returned no data (device disconnected or multiple access on port?)zread failed: {}Nr)rr bytearrayr _timeoutlenselectrr time_leftrreadrextendrrEAGAINEALREADY EWOULDBLOCK EINPROGRESSEINTRr^rexpiredbytes)rsizer)timeoutready_r_r`s rr)z Serial.read)s7 | %"$$ ${{$-(($ii$" !$mTWd6L,MrSUW^WhWhWjWjkk q!)U22GD2D999 gdgtc$ii'788 M*LMMM C    - G G G75<ARTYTeglgr"sss)*;*B*B1*E*EFFFtssss< G G GQ4 ene>OQVQbdidoppp)*;*B*B1*E*EFFFqpppp  G$   M$ii$NT{{s3 AD+D/*D G0 A"E11G0A#G++G0cL|jrtj|jddSdSNx)rrwriterr!s r cancel_readzSerial.cancel_read\s1 < 3 HT+T 2 2 2 2 2 3 3rcL|jrtj|jddSdSr7)rrr9rr!s r cancel_writezSerial.cancel_write`s1 < 4 HT,d 3 3 3 3 3 4 4rc|jstt|}t|x}}t |j}|dkra t j|j|}|j r|S|j s| rtdtj |jg|jgg|\}}} |rt j|jdn|stdnl|Jtj |jg|jggd\}}} |rt j|jdnO|st#d||d}||z}n#t"$rt$$rl} | jt&jt&jt&jt&jt&jfvr"t#d| Yd} ~ nd} ~ wtj$rm} | dt&jt&jt&jt&jt&jfvr"t#d| Yd} ~ nd} ~ wwxYw|j s#| rtd|dka|t|z S)z2Output the given byte string over the serial port.rz Write timeoutrhNr*zwrite failed (select)zwrite failed: {})rrrr&r _write_timeoutrr9ris_non_blocking is_infiniter0rr'rr(r)rrrr+r,r-r.r/r^r) rdatadtx_lenlengthr3nabortr4r5r`s rr9z Serial.writeds| %"$$ $ TNNa&& $-..qjj) HHTWa((*GH ,G((F4_EEE&,mT5L4MPTPWyZ\^e^o^o^q^q&r&rOE5! 7>>> F4_EEEF#,,..666&,mT5L4MPTPWyZ\^b&c&cOE5! 7;;; G-.EFFFabbE! "    H H H75<ARTYTeglgr"sss)*<*C*CA*F*FGGGtssss< H H HQ4 ene>OQVQbdidoppp)*<*C*CA*F*FGGGqpppp  H * >w/@/@ >,_===YqjjZAs:"F5A?F6A+F# FI>A"G??I>A#I99I>cb|jsttj|jdS)zb Flush of file like objects. In this case, wait until all data is written. N)rrrYtcdrainrr!s rflushz Serial.flushs2 | %"$$ $     rcNtj|jtjdSz9Clear input buffer, discarding all that is in the buffer.N)rYtcflushrTCIFLUSHr!s rrzSerial._reset_input_buffers!122222rcX|jst|dSrK)rrrr!s rreset_input_bufferzSerial.reset_input_buffers0| %"$$ $   """""rcx|jsttj|jtjdS)zs Clear output buffer, aborting the current output and discarding all that is in the buffer. N)rrrYrLrTCOFLUSHr!s rreset_output_bufferzSerial.reset_output_buffers7 | %"$$ $!122222r?c|jsttj|jt |dz dS)za Send break condition. Timed, returns to idle state after given duration. rSN)rrrY tcsendbreakrrr)rdurations r send_breakzSerial.send_breaksA | %"$$ $DGSD%9%9:::::rc|jr'tj|jtt dStj|jt t dS)z)Set terminal status line: Request To SendN) _rts_staterrrr TIOCM_RTS_strrr!s rrzSerial._update_rts_stateD ? : K= 9 9 9 9 9 K= 9 9 9 9 9rc|jr'tj|jtt dStj|jt t dS)z-Set terminal status line: Data Terminal ReadyN) _dtr_staterrrr TIOCM_DTR_strrr!s rrzSerial._update_dtr_stater[rc|jsttj|jt t }tjd|dtzdkS)z(Read terminal status line: Clear To Sendrr) rrrrrrrrrrrs rctsz Serial.ctsP| %"$$ $ K> : :}S!$$Q')3q88rc|jsttj|jt t }tjd|dtzdkS)z)Read terminal status line: Data Set Readyrr) rrrrrrrrrrrs rdsrz Serial.dsrrarc|jsttj|jt t }tjd|dtzdkS)z)Read terminal status line: Ring Indicatorrr) rrrrrrrrrrrs rriz Serial.riP| %"$$ $ K> : :}S!$$Q'(2a77rc|jsttj|jt t }tjd|dtzdkS)z)Read terminal status line: Carrier Detectrr) rrrrrrrrrrrs rcdz Serial.cdrfrctj|jtt}t jd|dS)z:Return the number of bytes currently in the output buffer.rr)rrrrrrrrs r out_waitingzSerial.out_waitings0 K> : :}S!$$Q''rc:|jst|jS)z For easier use of the serial port instance with select. WARNING: this function is not portable to different platforms! )rrrr!s rfilenoz Serial.filenos! | %"$$ $wrTc|jst|r&tj|jtjdStj|jtjdS)z Manually control flow - when software flow control is enabled. This will send XON (true) or XOFF (false) to the other device. WARNING: this function is not portable to different platforms! N)rrrYtcflowrTCIONTCIOFFrenables rset_input_flow_controlzSerial.set_input_flow_controlZ | %"$$ $  4 N47GM 2 2 2 2 2 N47GN 3 3 3 3 3rc|jst|r&tj|jtjdStj|jtjdS)z Manually control flow of outgoing data - when hardware or software flow control is enabled. WARNING: this function is not portable to different platforms! N)rrrYrnrTCOONTCOOFFrqs rset_output_flow_controlzSerial.set_output_flow_control rtrcDddl}|dtdS)zDEPRECATED - has no userNz0nonblocking() has no effect, already nonblocking)warningswarnDeprecationWarning)rrzs r nonblockingzSerial.nonblockings' HJ\]]]]]rN)Fr*)rST)r#r$r%__doc__rrrpropertyr!r)r:r<r9rIrrOrRrWrrr`rcrerhrjrlrsrxr}r'rrrr0s ???BW3W3W3W3r ! ! ! ((X(1111f333444444l!!!333### 333;;;;::::::99X999X988X888X8((X(  4 4 4 4 4 4 4 4^^^^^rrceZdZdZddZdS)PosixPollSerialz Poll based read implementation. Not all systems support poll properly. However this one has better handling of errors, such as a device disconnecting while it's in use (e.g. USB-serial unplugged). r*cZ|jstt}t|j}t j}||jt j t j zt j zt j z||j t j t j zt j zt j z|dkr4t||kr ||jrdn|dzD]J\}}||j krn9|t j t j zt j zzrt#dK||j krt%j|j dn|t%j|j|t|z }|||s|j|jdkr|snt||k t/|S)r#rNrhzdevice reports error (poll))rrr$r r%r'pollregisterrPOLLINPOLLERRPOLLHUPPOLLNVALrr&r@r(rrr)r*r0rr1)rr2r)r3rreventr_s rr)zPosixPollSerial.read&s | %"$$ ${{$-(({}} dgv}v~=NQWQ``aaa d,fmfn.Lv~.]`f`o.oppp !88d))d"""&73F+h44WM^M^M`M`cgMg!i!iMMIBT333 ?&/ QRM-.KLLLM///GD2D999gdgtc$ii'788 C   ??$$ 4@TE]`aEaEaknEa#d))d""$T{{rNr~)r#r$r%rr)r'rrrrs2      rrc@eZdZdZdfd ZddZeZxZS) VTIMESerialab Implement timeout using vtime of tty device instead of using select. This means that no inter character timeout can be specified and that the error handling is degraded. Overall timeout is disabled when inter-character timeout is used. Note that this implementation does NOT support cancel_read(), it will just ignore that. Tc tt|tj|jtjd|jd}t|jdz}n%|jd}d}nd}t|jdz} tj |j}|\}}}}} } } n>#tj $r,} tj d| d} ~ wwxYw|dks|dkr"td||| tj<|| tj<tj|jtj||||| | | gdS)rrNr*r;rrr)superrrrrrrrrr%rYrrrrr^r]r r r r )rrrrrrrrrrrrr __class__s rrzVTIMESerial._reconfigure_portUs k4  22444 DGU]A...  # /D02566EE ] "DEED *++E U)$'22I=F :E5%} U U U()G)N)Ns)S)STT T U 199 299%@@AA A!7=7<ueVVR@ B B B B Bs#B99C4'C//C4r*c6|jstt}t||krUt j|j|t|z }|sn(||t||kUt|S)r#) rrr$r&rr)rr*r1)rr2r)r_s rr)zVTIMESerial.readss | %"$$ ${{$ii$'$'4#d))#344C  KK    $ii$ T{{rrr~) r#r$r%rrr)rr: __classcell__)rs@rrrIsb  BBBBBB<"(**KKKKKrr)= __future__rrrrr'rsysrYrserial.serialutilrrrrrr objectr rplatformlowerplatrXrcrfrerirtrjrnrprlr/r}rrrrrrrrrrrrrrrrrpackrrZr^rr rrrr'rrrs4:'&&&&&  6666666666666666+++++6+++0   |8wLLLFGG FJJ"&)'_K_K_K_K_K/_K_K_K_KD X      /      "1"XLLLK@@@@@/@@@@* "1"X "1"X "1"X "1"X@@@@@/@@@@(     /   77J / / 77J / / 77J / / 77J / / GG[% 0 0 GG[% 0 0  GG[% 0 0 GG[% 0 0 GG[% 0 0 GG[% 0 0 77J 2 2 77J 2 2 77I3oGGggz622G 77J / /S!$$ C++  C++ 77J / / 77J / /l^l^l^l^l^Z)l^l^l^^'''''f'''T;;;;;&;;;;;r