你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

YMODEM协议串口文件传输

[复制链接]
XinLiYF 发布时间:2018-3-6 01:56
YMODEM协议串口文件传输
GitHub仓库:http://github.com/XinLiGitHub/SerialPortYmodem9 u. [; k/ X" m0 U; X2 y, u
PS:博文不再更新,后续更新会在GitHub仓库进行。% F$ ^1 s2 I* [7 b7 G
4 q' u8 _+ L. s3 I" }8 h. v9 E

/ {% C. J* ?. ^$ D    串口通过YMODEM协议进行文件传输。程序中涉及到YMODEM协议知识,详细介绍见维基百科[YMODEM](http://en.wikipedia.org/wiki/YMODEM)。
1 t" c4 }4 C  _
6 b. V  Z* I, z) m1,开发环境5 c& U* G2 `) \% `0 `% B8 J
      1,框架:Qt 5.7.1
( [: M4 S  Z. o

* L2 c; z' h1 @6 w! u; Z+ D9 F      2,编译器:MSVC2015_64bit: F2 r7 U3 U. C7 U
' D% a8 x2 N; w3 c) I& k9 _
      3,IDE:Qt Creator 4.2.0 社区版, Q3 u; _$ l- P9 L9 ^1 M
      4,操作系统:Windows 10 专业版
: d) ?( F8 z1 i6 @1 k1 G5 ~
$ z) |) }& v) M6 A1 v- w; n2,程序源码
5 b5 n* Y* c7 n7 _5 U, J0 t      Ymodem.h文件
5 N2 @! q% S# u3 g) C8 J
  1. /**: v! i0 ~5 O1 \* j  `
  2.   ******************************************************************************+ o0 s* ~' o* g# q# W
  3.   * @file    Ymodem.h' `, h# o. h2 d9 J0 ~1 @* t
  4.   * @author  XinLi
    $ J1 o- ^; E, r- C) O7 P2 u
  5.   * @version v1.0
    & D4 a5 S0 {% {& k6 ?
  6.   * @date    21-January-2018+ p8 |# |+ e* O0 x4 e' W# r
  7.   * @brief   Header file for Ymodem.cpp module./ ?7 i5 \( G3 E
  8.   ******************************************************************************  o$ m7 Q1 U! c
  9.   * @attention+ u' h7 Y; D) J* I* W
  10.   *
    2 Q% ~) M) x  B
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>
    / L1 _! v* ]/ k  @
  12.   *
    9 F1 W" I  L% `$ n1 R: \8 V
  13.   * This program is free software: you can redistribute it and/or modify
    . Z' _( O, d+ E1 Q3 X! `. L# v& K
  14.   * it under the terms of the GNU General Public License as published by/ S+ ?4 G6 r" u' w/ i  l
  15.   * the Free Software Foundation, either version 3 of the License, or
    7 p  c4 O: g% O3 V
  16.   * (at your option) any later version.9 f2 E9 J+ \& E8 Z9 g" g
  17.   *
    9 @: J0 K6 ^/ }. k. O/ L+ [! t" l7 i. @
  18.   * This program is distributed in the hope that it will be useful,
    7 Z: a0 [; g* N4 Z- n# F2 b
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    6 B4 M- ~& T) R5 b4 \5 m$ D% `7 Y% U
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the3 P3 O3 ~. m/ j
  21.   * GNU General Public License for more details.
    ( a' r, w5 ~# A  c0 K+ q
  22.   *
    " S0 W5 ]$ y) t3 ^
  23.   * You should have received a copy of the GNU General Public License
    ) ~0 @. E' Z0 @5 Q' T
  24.   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    3 C. s# F6 Q6 b' \3 n4 m7 S
  25.   *# z: N; Q' z6 X1 A/ r- U
  26.   ******************************************************************************
    % k. ?' M1 E- P0 P1 F$ q: A
  27.   */+ I# O( f2 v# |, q

  28. 7 c- o% V: u, T: Q
  29. #ifndef __YMODEM_H
    , R8 w# }, N+ l
  30. #define __YMODEM_H
    % K0 d# u% Z" K! H( [1 j

  31. 0 i. H% m" K6 v3 W! N: b
  32. /* Header includes -----------------------------------------------------------*/
    9 _9 b1 \+ B, P6 ^1 }6 Z! X
  33. #include <stdint.h>' p& _8 i3 d/ ^( j
  34. ' R8 R. Y+ X8 _' \( N: l% v
  35. /* Macro definitions ---------------------------------------------------------*/5 S* }& r1 x7 c( ^! D4 q
  36. #define YMODEM_PACKET_HEADER    (3)
    % j! V5 X! ]3 H0 F+ w1 M  Y6 P# k* U
  37. #define YMODEM_PACKET_TRAILER   (2)
    ( Z9 t! P' C3 t3 x3 a& R0 _6 Q, D
  38. #define YMODEM_PACKET_OVERHEAD  (YMODEM_PACKET_HEADER + YMODEM_PACKET_TRAILER)
    8 h( |9 s* @7 i$ N; \
  39. #define YMODEM_PACKET_SIZE      (128)3 @- }: s* d" I$ `# p; f
  40. #define YMODEM_PACKET_1K_SIZE   (1024)) c; ^+ f, S! v4 L
  41. 5 e0 u* |. H' y( i
  42. #define YMODEM_CODE_CAN_NUMBER  (5)
    7 V7 |( G- u' o( e  H

  43. ; E2 B% W' }! `. x5 H: C* f+ |
  44. /* Type definitions ----------------------------------------------------------*/
    ' b* {: _8 t- ?
  45. class Ymodem
    ; X! `) G$ L8 ?$ _$ _8 E) z
  46. {
    & l; y2 M) b& f  x* j  q0 U
  47. public:' ^4 g1 M! L& O, m5 l* X
  48.   enum Code: L- n9 i% P/ I
  49.   {! H4 |* L4 ~9 z, n) V* e* x! _7 J
  50.     CodeNone = 0x00,
    * w6 D+ [4 i. [$ L5 P# `+ \1 P6 C
  51.     CodeSoh  = 0x01,2 _" C! {$ O, K# v+ B9 G
  52.     CodeStx  = 0x02,
    ( [3 F+ s) Y  `2 f2 E$ t& r
  53.     CodeEot  = 0x04,* i  v$ N1 Z3 E6 e3 n
  54.     CodeAck  = 0x06,
    # Y0 x( ^- f* V) `- n1 W
  55.     CodeNak  = 0x15,1 a2 X  w  M4 c# t+ ?
  56.     CodeCan  = 0x18,
    & N0 y- V* r' y
  57.     CodeC    = 0x43,. G2 B( J. D/ ^/ j& E+ a
  58.     CodeA1   = 0x41,
    2 t( N- Q: u. O; Z: p/ X3 Q$ ^
  59.     CodeA2   = 0x61$ v: X. I' o/ u
  60.   };% l9 I: C% n2 @, T7 u. z/ k, T2 U+ o

  61. 4 a! p+ S8 F' z3 m. e9 G
  62.   enum Stage& h! U: R: t  M4 c0 u/ \- v% [8 S- F
  63.   {
    $ I7 Y/ a/ y' N* K& N
  64.     StageNone,$ M/ f5 C- D( e: n- J* P, \2 Z
  65.     StageEstablishing,1 H+ ^9 j' l+ t2 |$ y2 T! f+ D) w
  66.     StageEstablished,
    # ]1 t8 r& Q  q+ z# a* \" Y/ w
  67.     StageTransmitting,9 M2 b+ C" v$ Z- a1 \9 t7 F
  68.     StageFinishing,
    $ z' ?3 {( p% [; P, }" j$ E
  69.     StageFinished
      b: l  x; R' E8 X" b8 R0 J
  70.   };
    2 a0 r$ L6 M3 a" f/ E: R- w
  71. ( V9 {# z) \( [2 c" v- B  B; ^, Z% J
  72.   enum Status
    2 L% L) w7 Y+ B* K
  73.   {; J+ d! T1 `% D/ D6 z7 i6 e
  74.     StatusEstablish,4 e$ G* I& n5 M- F
  75.     StatusTransmit,; Y% v( q' s! d3 L
  76.     StatusFinish,& G9 |" N/ d7 }% q1 J+ C
  77.     StatusAbort,
    " J/ y2 U! E$ `* W1 L9 Y
  78.     StatusTimeout,
    - m# A2 s. j: @2 Q: n% P! n( s
  79.     StatusError+ p3 a( m( k1 g% t2 e
  80.   };8 P* u4 i& ?4 _1 @  V

  81. # U6 m8 k4 ~/ I5 ^2 m( G5 Q% E
  82.   Ymodem(uint32_t timeDivide = 499, uint32_t timeMax = 5, uint32_t errorMax = 999);1 R! l) |' W3 l
  83. / m9 X4 K0 L( |9 @
  84.   void setTimeDivide(uint32_t timeDivide);
    + a" u0 @. Y" Z# A) s
  85.   uint32_t getTimeDivide();
    & ?7 E+ ?4 b' j/ I( q. T8 C# r. w

  86. 0 D; {% i8 w% }) C# O
  87.   void setTimeMax(uint32_t timeMax);8 [# n+ w5 w  r& |2 p
  88.   uint32_t getTimeMax();4 q6 y# U. o5 d

  89. + E5 n5 m- o, u* H0 S8 g
  90.   void setErrorMax(uint32_t errorMax);
      J! P7 ^/ ~' J  q3 R5 H
  91.   uint32_t getErrorMax();
    $ L8 x9 c! ^. B# ^
  92. 4 O2 a5 B) j' Z  G) F' p. d" P
  93.   void receive();
    , n5 Q( }" A) u  B. j
  94.   void transmit();
    8 Z" y8 Q$ V- M. p- C# f# t
  95.   void abort();
    4 n. ~4 v6 X2 a$ |
  96. / R! U4 g, d3 F& _- ^  @
  97. private:
    5 q8 a' S2 t9 ]8 T6 `
  98.   Code receivePacket();' K: n, b+ P% G$ f% N: [3 z1 o
  99. % u4 l; L- O. p
  100.   void receiveStageNone();
    # v8 k6 N( O9 e
  101.   void receiveStageEstablishing();. [  q: S' B  d% B9 T/ Y
  102.   void receiveStageEstablished();; u9 w. _) [0 S# u' q3 q6 H
  103.   void receiveStageTransmitting();/ w- P# p1 i+ E* B" |0 Y. h
  104.   void receiveStageFinishing();# _( P6 l2 Z8 v* i( H$ G
  105.   void receiveStageFinished();) S# _4 d) w+ G
  106. 2 q, v3 T& i; t9 \+ k
  107.   void transmitStageNone();7 G* `7 G' H" X. w: j
  108.   void transmitStageEstablishing();& Q* P6 y8 r; V3 d& b
  109.   void transmitStageEstablished();
    % o5 }; k7 z; i& {  r& C4 J7 Y0 z
  110.   void transmitStageTransmitting();
    ' R1 h) N) V9 a
  111.   void transmitStageFinishing();
    ( e/ R; g# g  `8 ?3 J
  112.   void transmitStageFinished();: R; Q3 `  I+ n+ _8 e. \5 o1 }

  113. # ~8 V- v5 i1 y% ]3 K7 B" j
  114.   uint16_t crc16(uint8_t *buff, uint32_t len);+ B* G' b/ {' ]8 @2 S1 o
  115. $ h5 V5 W& G( d; V( K. W
  116.   virtual Code callback(Status status, uint8_t *buff, uint32_t *len) = 0;1 J0 m: g; P3 h9 M1 F
  117. 1 K( a: A( x+ \3 r
  118.   virtual uint32_t read(uint8_t *buff, uint32_t len)  = 0;
    " [" P4 t! O, L
  119.   virtual uint32_t write(uint8_t *buff, uint32_t len) = 0;3 A5 H  D  ~( n0 u8 n

  120. & y1 Y; `& y; A. e- O
  121.   uint32_t timeDivide;# J4 f; F* m7 Y( r
  122.   uint32_t timeMax;) |5 H3 V; q6 h
  123.   uint32_t errorMax;
    % n/ r7 n! C6 Q8 t

  124. ( C4 ^' K7 z+ f5 J5 p. d
  125.   uint32_t timeCount;
    8 k' q( n$ T" w2 g5 r, K5 D5 O" i0 j" O
  126.   uint32_t errorCount;( W! v7 ^% u8 b+ N6 M
  127.   uint8_t  dataCount;- o* x8 d# ^: E! }' T' n; y

  128. 7 q2 m8 P+ p. q4 c$ Z$ A
  129.   Code  code;
    7 z+ F  s: {7 k. L" e0 \0 o: _, d
  130.   Stage stage;
    3 {8 d# L2 M) O2 C
  131. 3 f; t. g1 u" E9 C( q
  132.   uint8_t  rxBuffer[YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD];3 o& r% A" e" O) n4 b" R4 o* o
  133.   uint8_t  txBuffer[YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD];
    2 y7 p$ h2 s- @' E
  134.   uint32_t rxLength;" @. P) h3 W3 J
  135.   uint32_t txLength;
    . u4 Z. l6 P9 o' L! j
  136. };+ Z% s" m6 m9 K3 g  E

  137. 4 I: J7 a, E# x' }! ~9 C
  138. /* Variable declarations -----------------------------------------------------*/: ]; w2 D6 y2 A3 @
  139. /* Variable definitions ------------------------------------------------------*/
    - h% o" d% u( D9 f
  140. /* Function declarations -----------------------------------------------------*/
    6 W5 P7 N8 z% w
  141. /* Function definitions ------------------------------------------------------*/
    & F  w: w# O1 ]% L- f
  142. : R* e9 U9 g8 f3 z/ h
  143. #endif /* __YMODEM_H */
    $ B+ s. u% U2 p; \' e2 j
复制代码
1 ?$ q7 q* F4 m7 K2 u8 j& @
      Ymodem.cpp文件
- |$ r; e' U, a  O+ H
  1. /**3 E# l2 U0 E1 R* G: ]& I6 t
  2.   ******************************************************************************
    9 n) i; ~/ _, F4 V+ M+ {' b
  3.   * @file    Ymodem.cpp
    ! a% d/ J1 O: i- V* h
  4.   * @author  XinLi, F- L% ~6 c& h! K  Y4 u" x
  5.   * @version v1.05 s" e+ _: Q: X; S* F
  6.   * @date    21-January-20183 \6 @7 y- A0 C( K, O/ c
  7.   * @brief   Ymodem protocol module source file.
    , `2 \# r  |7 I/ I1 g
  8.   ******************************************************************************
    - w6 h% j' ^! t  e; `
  9.   * @attention  z- B& i4 A9 ]  \4 J6 |6 a' Q  S& A( R
  10.   *
    - H0 U; Z. N$ y
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>
      |$ D1 H$ {5 M* x6 x
  12.   *
    " d( ]# A& Q; a4 T. ?6 F- ?* W
  13.   * This program is free software: you can redistribute it and/or modify/ N- q) e7 J- L, I. D/ _/ b3 M* G
  14.   * it under the terms of the GNU General Public License as published by, B+ P# [& Q8 j6 h8 q. D  ^  U5 N
  15.   * the Free Software Foundation, either version 3 of the License, or
    . ]" ~  h$ F* O. H2 N" {
  16.   * (at your option) any later version.
    4 A  ?7 N3 f  ^( Y: L
  17.   *: k& @/ ]7 H( M4 {6 o0 v
  18.   * This program is distributed in the hope that it will be useful,
    7 g& p0 x7 ~* h" C# L2 L1 d, F
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of4 R8 ?. H, s. k4 k6 }
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    " z" {5 b: p1 R1 x
  21.   * GNU General Public License for more details.; F+ e, `2 N1 X7 q' Z* p$ t
  22.   *
    3 Y+ D. M: y7 Y9 f0 I
  23.   * You should have received a copy of the GNU General Public License* ]% h3 p, E" @, q& T  w( o
  24.   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    & p4 A# D" w" g0 h. T
  25.   *
    1 k- J/ t  {5 L' {3 q+ W$ i( ~
  26.   ******************************************************************************& |& U! W5 z+ q2 H5 f  V' J
  27.   */! L. M6 P& Q8 G0 J$ n

  28. 5 R! v- d' m9 X: S. V$ E! {
  29. /* Header includes -----------------------------------------------------------*/# }' }6 B) h0 ]0 h
  30. #include "Ymodem.h"" c* o' m  q/ Z$ f$ j5 s$ d5 \8 a
  31. #include <string.h>
    ) e: b+ s2 b6 |+ n) y

  32. 7 c  ?1 v+ V! Q8 l# j
  33. /* Macro definitions ---------------------------------------------------------*/; i. _' i* F3 H) ~; u9 D
  34. /* Type definitions ----------------------------------------------------------*/3 U4 m" x7 |# h. a  A  E
  35. /* Variable declarations -----------------------------------------------------*/- Y2 _- c4 T  B7 r' U1 U
  36. /* Variable definitions ------------------------------------------------------*/
    4 B* S3 w6 T2 U
  37. /* Function declarations -----------------------------------------------------*/
    7 D6 b! K" @4 c7 K( j/ K# y. E- S0 q
  38. /* Function definitions ------------------------------------------------------*/( w3 g7 L# Q+ U3 K" M* e
  39. , t9 K  P% ?, J. O6 }1 `
  40. /**
    $ }; q8 @' c: h: f0 q
  41.   * @brief  Ymodem constructor.
    ; z5 q4 G& G; A% \1 m. U; q5 G
  42.   * @param  [in] timeDivide: The fractional factor of the time the ymodem is called.+ [( }3 y3 ]' V- s# ^2 V7 t( v  j
  43.   * @param  [in] timeMax:    The maximum time when calling the ymodem.8 r+ v5 O  n& l/ C7 L0 c1 B$ v9 q
  44.   * @param  [in] errorMax:   The maximum error count when calling the ymodem.
    9 Y- A% V9 C0 f7 @' Q7 ^
  45.   * @note   The longest waiting time = call time / (@timeDivide + 1) * (@timeMax + 1).7 c" [! E' P8 S% l* f' t( E
  46.   * @return None.9 y, `, A8 r9 t' Q: p$ g
  47.   */
    : \$ d4 `% v3 ]* @( r5 G
  48. Ymodem::Ymodem(uint32_t timeDivide, uint32_t timeMax, uint32_t errorMax)
    , l+ f4 r6 ^8 @: Z. _7 e2 l. k
  49. {
    4 X( d/ f! J8 G; P' O
  50.   this->timeDivide = timeDivide;
    4 T/ b% x( Z$ y9 B
  51.   this->timeMax    = timeMax;
    6 U6 R, ]# f% U+ q; P% r! ]
  52.   this->errorMax   = errorMax;
    * Y) d' d7 |6 B

  53. ' w% l, y: ?9 f9 n* {$ f
  54.   this->timeCount  = 0;0 V2 W8 X4 m! K9 B1 \, Q
  55.   this->errorCount = 0;0 F8 T- [- E+ Y9 q/ Y
  56.   this->dataCount  = 0;
    & H' T; s9 w) x
  57. 1 u( A% M& O. s. m/ v7 E) L
  58.   this->code       = CodeNone;
    % S1 z3 Q" h7 e" B3 z; L/ C
  59.   this->stage      = StageNone;
    & P- L6 u$ B$ w/ p
  60. }) ]) Y$ _. ]: J- U% }

  61. ; @) q( v4 ^- l' c
  62. /**
    9 q6 F& Q$ j) s; U! u' w
  63.   * @brief  Set the fractional factor of the time the ymodem is called.0 [+ T1 A5 q5 T# W- N
  64.   * @param  [in] timeDivide: The fractional factor of the time the ymodem is called." L. Y$ b0 }+ N9 h4 ]+ l1 p
  65.   * @return None.
    2 C4 b; u# P; _- ?8 b/ a
  66.   */
    3 i/ m3 F) P/ b
  67. void Ymodem::setTimeDivide(uint32_t timeDivide)
    ! i6 e5 L# |: K: G0 B( C; @4 j
  68. {  o5 B& }: m% |# P
  69.   this->timeDivide = timeDivide;1 l! M. q( d' Y" ?) S
  70. }5 l9 K* ?5 W: \. R6 x/ a: m! u

  71.   C5 T& u; q2 t' l1 k
  72. /**3 v1 B- k7 X0 r0 J5 P- c
  73.   * @brief  Get the fractional factor of the time the ymodem is called.
    % @" [8 m. h  c$ ^+ i
  74.   * @param  None.! V' x5 `3 C8 P8 d
  75.   * @return The fractional factor of the time the ymodem is called.
    0 h7 ?$ O1 G2 h0 u* P* t! f0 H
  76.   */
    3 I+ k% j5 V, T. d9 o  Y5 o
  77. uint32_t Ymodem::getTimeDivide()
    ' R1 j, n4 {# ?1 i4 |& b
  78. {
    3 F  e2 [. V+ x0 {( w+ K- M9 p
  79.   return timeDivide;% v0 m+ [8 y- j0 c
  80. }
    , n3 p: y: |- t0 l$ Z4 u7 j

  81. 8 z& z) Q% U$ s$ _" Z
  82. /**
    ! X2 Q3 L. v  C5 `: b0 W) E3 Y
  83.   * @brief  Set the maximum time when calling the ymodem.) J% }! m, y* J! O! b0 P% }
  84.   * @param  [in] timeMax: The maximum time when calling the ymodem.
    ! f2 W+ ^& t+ E' x, U# P0 a
  85.   * @return None.* @0 A& J/ c6 r9 ]7 n% F
  86.   */3 s) o, {" \6 l4 b+ n; r
  87. void Ymodem::setTimeMax(uint32_t timeMax)
    - e) }+ E3 P1 q2 ~! ~' b/ \( x
  88. {
      m1 V2 _. F5 D5 S; I, V
  89.   this->timeMax = timeMax;  {$ F; @/ o& |1 @/ J4 D2 g/ r
  90. }! ~5 m6 y1 c$ F$ B# i5 X- W

  91. : `$ j) R9 m" a8 F3 {8 c
  92. /**! U, d1 f$ Y2 y. g
  93.   * @brief  Get the maximum time when calling the ymodem.
    & c: Z$ x8 M- c2 ~0 i' ?; z  i
  94.   * @param  None.4 s0 k% O9 ~" O$ g
  95.   * @return The maximum time when calling the ymodem.* m8 P. h+ G% J% M& w/ C5 o
  96.   */  ]5 e% {! I4 A6 d" y5 Z5 N- R+ `, N5 G
  97. uint32_t Ymodem::getTimeMax()
    ( d( q$ F  @' O6 P) ?
  98. {
    ! h' V9 h# N( l0 ]/ b0 A
  99.   return timeMax;& m0 f0 O3 H1 L8 ^) d. v# A
  100. }, g* t$ {4 F+ b
  101. + O- i! \* r; U) S8 ~$ D
  102. /**
    . l5 g2 G+ [( ]2 a. ?
  103.   * @brief  Set the maximum error count when calling the ymodem.
      C) Q" [" z- l
  104.   * @param  [in] errorMax: The maximum error count when calling the ymodem.3 D/ `/ c& a) Y' m5 u) S
  105.   * @return None.5 y3 ]9 z& }0 b5 O# V& j
  106.   */
    $ U* V' z0 Q5 |5 c0 G) E0 r+ p
  107. void Ymodem::setErrorMax(uint32_t errorMax)
    9 Z; }  f1 z& S- d! D% \
  108. {
    9 ~( v, F8 t8 |$ ~* J$ P
  109.   this->errorMax = errorMax;3 z) v1 X% V, n3 j! `
  110. }
    % x5 H, N& u+ ]8 d+ [

  111. " b5 e7 ^& h8 f5 Y& o) t; Y4 O
  112. /**1 T4 k! Q* K- F. W' u7 ~' Z
  113.   * @brief  Get the maximum error count when calling the ymodem.7 V8 B+ ^) y: T
  114.   * @param  None.
    # E6 A+ l) m' i- h' m) p, E
  115.   * @return The maximum error count when calling the ymodem.
      k8 G9 d/ ]/ n/ N6 [! a9 t
  116.   */0 A, }0 y4 ^3 s( ]  b+ a9 @0 ?
  117. uint32_t Ymodem::getErrorMax()
    4 K6 g8 J/ [. r1 S) z
  118. {
    , \2 j; q/ O! s) e( L
  119.   return errorMax;
    : o* \& d. y! M) q5 j/ z
  120. }7 u2 H$ C2 _; H

  121. 4 r2 Q6 S( _5 O2 f" c0 k
  122. /**: h) c1 z# V' y+ y
  123.   * @brief  Ymodem receive.
    3 M0 i0 S9 ~. i" ?+ ?2 l$ j0 @- h
  124.   * @param  None.- R5 P. S! W3 ~* x( K* g
  125.   * @return None.
    ( D6 @) C( w! ^+ U( w+ {
  126.   */4 H* q* C  M* D3 F# Q
  127. void Ymodem::receive()
    0 _+ [6 \( b( H3 `
  128. {
    . o# Z% V: `6 j' L5 l( H
  129.   switch(stage)
    ( L1 p' O: J+ u( Y# w
  130.   {
    - A8 x9 T. p# _4 _3 v( T
  131.     case StageNone:
    . ^0 d0 z  a9 Q; n8 i
  132.     {( Z! I# l, r' e: x
  133.       receiveStageNone();
    4 e8 V. M  F* Q2 H: `

  134. 6 C, Q6 [1 `3 {' w/ Q
  135.       break;
    5 g* o4 V) L  w; e* v  f% `+ ^3 _
  136.     }% [7 t8 G8 \5 Y7 ?7 P1 e

  137. 6 p- H$ Z( j' w1 j8 u
  138.     case StageEstablishing:
    ; E% b" z, A: t! s+ `6 T3 m
  139.     {( H" O  d1 `# ^/ a, I% B: r! g( {
  140.       receiveStageEstablishing();
    % L5 @  v3 R) y; d! e. B. L
  141. - E6 r  L+ _2 V, W: _
  142.       break;
    ; H- V' R* ^+ X: e, i/ v. h
  143.     }# N7 m% l3 k3 P

  144. 8 i9 |( w% O4 M. _( w; C6 P
  145.     case StageEstablished:
    7 Q4 s( l5 D8 y, p+ g
  146.     {9 N6 z* p4 u9 @0 r) W0 l$ k8 j, E7 l
  147.       receiveStageEstablished();7 F& ]5 [. R$ \; H$ `  E: c

  148. 9 R0 f+ R  d5 w9 k
  149.       break;. i4 J& I* y$ q, f
  150.     }9 A" \/ X9 g" D& Q6 Q
  151. / k( y# h, C& G8 A
  152.     case StageTransmitting:
    ' x! ~6 B0 {, \& v% |+ @) r2 a
  153.     {
    3 X: T1 ?8 x. J9 ]% G
  154.       receiveStageTransmitting();/ g4 ]* U  w4 O
  155. 9 j9 G8 e$ `- x8 A, W) n
  156.       break;
    $ V( Y/ k& e; o
  157.     }: ], {2 ]  e0 i, k" x
  158. + P' y7 K$ L" G4 t, a& I$ ^
  159.     case StageFinishing:# v/ [( y  o4 q$ Z' x- }
  160.     {* e4 ]. Q4 s! g0 M# \1 L" r" Z" ^
  161.       receiveStageFinishing();) O# d; h8 O  J4 x8 G* N

  162. 9 r# {6 d5 `+ c3 a7 l. b7 ^8 {
  163.       break;
    0 L! @$ v3 V5 o0 L
  164.     }
    - j4 d  R; ?' q7 ^  t. \

  165. # b) H* |- a1 y5 K/ c$ _9 h
  166.     default:' M# ?7 d; L- Q+ I+ r, q  X
  167.     {
    ; A1 O7 _! h; D* {1 ^$ v: z
  168.       receiveStageFinished();! C7 n- \+ I7 n) I9 p
  169.     }. |$ I  h! j* Z9 L! r% U" m% r1 O
  170.   }6 s$ B3 H: }+ x2 Q7 r) N2 v
  171. }
    3 S% V7 U9 f7 O! s8 {$ H" l6 }
  172. 8 {9 P# K- f- m1 u4 r( o8 q& E
  173. /**
    3 u* H* ^3 U$ L9 g
  174.   * @brief  Ymodem transmit.+ n8 P9 U/ D4 h/ k; P
  175.   * @param  None.6 h* @- U* B2 @8 x0 M. l
  176.   * @return None.* h7 a1 c: g6 S, |
  177.   */% Y$ ?% `/ N* k9 w7 Z
  178. void Ymodem::transmit()
    : X; h* m7 i2 H8 U. n
  179. {: ]$ R" _8 X, d. v' D
  180.   switch(stage)' f% }+ r; f+ a* I- A
  181.   {
    6 [8 P( E6 ^: u7 x2 u6 }0 r
  182.     case StageNone:) R: u, g! Y4 y" g/ r! g/ \& D
  183.     {
    / O6 A9 c, U& G. x! k
  184.       transmitStageNone();- Z" b8 [3 x, X" |" Y* [4 q) h

  185. + _/ U! ~1 P5 s: ~' V
  186.       break;5 G7 i+ H) V% o) `  U4 d
  187.     }; |7 Y) H3 m* l3 T* @# P
  188. 9 u  H4 P6 b" J  D+ Q4 K
  189.     case StageEstablishing:
    * o6 D+ b& M: m- u6 e) D5 n+ {7 u
  190.     {
    4 m$ k9 J4 i+ e! B
  191.       transmitStageEstablishing();
    * I, c3 @& k' h$ t% l

  192. 2 |6 ]" L6 k* [$ r5 s7 x
  193.       break;
    8 _/ b( k0 p7 ^; l1 `. Y; u
  194.     }! [# d8 @' v2 @' c8 `+ ?

  195. + T  ?+ {, V: P
  196.     case StageEstablished:
    8 Q6 D- b% A& p$ r% E
  197.     {
    - U* f6 T6 @8 V; l
  198.       transmitStageEstablished();
    : v! Q. g& _: X8 d: A

  199. # O/ Q# h. A8 y4 g1 j: n
  200.       break;- b- f0 D7 B0 i( x: l, B
  201.     }. x1 d1 z; g9 Q! z, E' _4 v

  202. ( [/ e9 |4 K" W% }# B
  203.     case StageTransmitting:. i" p) M0 m0 j
  204.     {
    $ s7 M0 G  E% Z; N7 P& c
  205.       transmitStageTransmitting();  v( z  U! X8 h
  206. 2 A4 y& ^7 Y# |1 U
  207.       break;9 L) r+ n6 Z, A6 z5 R
  208.     }
    ! v1 y8 d, p+ o6 v
  209. / [* [7 p3 @1 _6 _% W, L
  210.     case StageFinishing:
    : l0 B: o+ @8 Z/ J
  211.     {1 x9 _8 S" O7 ~. E6 [: `) `
  212.       transmitStageFinishing();
    9 ]& f  s% I. G
  213. 3 a+ n6 z4 P% q+ I; Z5 I
  214.       break;
    ' [% Z( l' w- k9 K' R6 T" ]' b
  215.     }$ M- h: V3 O1 N5 ^

  216. : G: o8 \& H1 u# f! A# h
  217.     default:+ ~0 o% h+ z8 f9 p0 _6 [( D
  218.     {4 f/ u5 v' z8 f" U0 Y. u2 ^# [
  219.       transmitStageFinished();& Y- ?. {5 h" k# Q4 X8 |- I
  220.     }
    " ^! I; ~1 l- E' C& n
  221.   }+ m" ]* J; }. F1 `) T# Q
  222. }2 q: I) d4 q) Y! w( e8 Y

  223. ' L% a- K+ M6 `
  224. /**
    # d) n4 ?9 V- T5 O/ E) {
  225.   * @brief  Ymodem abort.0 S4 {0 U) i" l1 P
  226.   * @param  None.7 r  U, A6 q  W. w. |0 @; ]
  227.   * @return None.; Q- @5 O# h2 n9 G3 t% o4 g1 E' W% o$ Q
  228.   */8 l( t5 S1 h# q) H' h
  229. void Ymodem::abort()
    4 ~9 R" G% a! _( s5 K
  230. {" Y* X0 v8 c# z$ M& ~
  231.   timeCount  = 0;
    # u: W; Q" X3 ?/ M% _2 w# ^
  232.   errorCount = 0;$ t# D  I6 J4 m
  233.   dataCount  = 0;6 |/ W$ ^+ p/ X$ Q  V! O. c
  234.   code       = CodeNone;5 {+ O7 X6 P: L2 H) r5 D1 W
  235.   stage      = StageNone;, J% l: X+ R7 f8 L& t: l

  236.   d& A0 R) Z) E" q/ d3 }! P: z
  237.   for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)+ u7 a5 n  ]  R* ~/ O5 v. Y
  238.   {0 Q8 Z7 X% _( J- b
  239.     txBuffer[txLength] = CodeCan;$ Z1 F2 S+ B3 \3 ~8 P% B/ K0 |
  240.   }
    ) X" ^# j3 P; u3 h; R

  241. ' N6 g- N( q3 l0 i" r* T, U
  242.   write(txBuffer, txLength);
    9 t+ }5 g, y1 d6 N: i
  243. }9 }$ o5 w2 x; e& ^- ~  D/ i7 W
  244.   r' M2 K; p8 D2 u% I
  245. /**1 a( Z' G6 }$ D4 ^0 j( f: _7 R) N7 N
  246.   * @brief  Receives a packet of data.9 N' ~) L0 i& m/ n
  247.   * @param  None.  N5 ^7 u9 N- R0 J0 Y# N+ K
  248.   * @return Packet type.
    & V0 f0 x+ X$ e+ l) z6 Y
  249.   */" n) N( D* c# p- U2 s# N
  250. Ymodem::Code Ymodem::receivePacket()
    + o: F# j- `6 r
  251. {
    5 n. M$ t/ U3 [) w0 b! ^# u
  252.   if(code == CodeNone)  R$ O: R  |* A2 d5 e
  253.   {# C" m5 Y6 ?' N: h" v' y
  254.     if(read(&(rxBuffer[0]), 1) > 0)
    3 [% @6 d3 T5 S7 l
  255.     {5 E: B* d8 @+ Q1 ~. h" I( X
  256.       if(rxBuffer[0] == CodeSoh). D7 A6 i  `# }* r% `! C+ D
  257.       {
      P9 p' t  ?6 f! ]
  258.         uint32_t len = read(&(rxBuffer[1]), YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 1);
    ! Q$ y$ x- E* y

  259. 0 ]% K0 Y* D: d2 v$ Z& u. w
  260.         if(len < (YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 1))6 O6 D9 N: h5 S( O( b# h# X
  261.         {
    3 m) q7 H" J- F
  262.           rxLength = len + 1;
    0 F+ q/ u& @  Z0 \- R
  263.           code     = CodeSoh;$ P  h: J3 P2 w5 U

  264. - r1 R. q5 j! L" M# Z$ A  e; ?" b
  265.           return CodeNone;
    ' @. `6 ^0 c: E. t+ h2 Z
  266.         }8 P! Q$ B" X6 S1 s  p% G9 b
  267.         else3 `1 y$ D& T4 p- Q  m" b
  268.         {( a+ t9 H6 E7 u' ?
  269.           return CodeSoh;- m) P1 U$ J8 {- N: q7 b( k& B0 n
  270.         }
    . h  \* i' h1 E5 Z# L
  271.       }
    4 c: U% Z9 d1 |2 ~6 P4 V
  272.       else if(rxBuffer[0] == CodeStx); x1 z0 z) W4 W, d7 }' V6 t5 \& b
  273.       {
    ! s  Y! k* P0 g2 w. N5 w* P; p* ^
  274.         uint32_t len = read(&(rxBuffer[1]), YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - 1);
    & M3 a& X( }+ B3 c9 n! S; o

  275. . G$ l9 Z9 `4 E5 b  p+ K
  276.         if(len < (YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - 1))2 p2 _8 ?" f5 J0 r% \
  277.         {
    $ O7 }" M2 u9 C: {
  278.           rxLength = len + 1;
    0 u8 B# ~0 a7 @% v1 K( z% I/ V
  279.           code     = CodeStx;" k7 @, W) s6 R
  280. + X. P+ z, @1 z1 H1 u3 B5 x6 w+ k8 E
  281.           return CodeNone;  K( R( {; D7 m
  282.         }9 B+ G2 s9 t/ p0 j! N/ N
  283.         else
    # w! S1 y$ t/ O) |2 _8 Y
  284.         {: {# w8 Q+ T0 C/ H
  285.           return CodeStx;
    ' Z9 \7 e4 Y0 v% j
  286.         }/ H9 @4 u. _3 O  z8 G9 h  d
  287.       }
    ( y5 V4 ]+ Y& s+ _" Y3 [6 Q9 E
  288.       else7 r+ F$ ^* T( i* J
  289.       {1 H8 ^! V/ s4 c& I/ w# q: Z9 w
  290.         return (Code)(rxBuffer[0]);# K5 k, X$ e1 w. @4 [
  291.       }+ N! y5 `0 R0 W  t) q! `
  292.     }* Z$ l. H5 u; v  f9 E0 q( y
  293.     else6 p% M' `& J, T+ \# y
  294.     {( Z" H5 J2 ^/ R9 _. q+ G% V9 `" w
  295.       return CodeNone;
    $ R8 n8 V4 N( |- K/ b2 Z
  296.     }/ z- }6 N3 Z# y
  297.   }
    8 U3 s* ?# t: [6 I" ~
  298.   else1 c( U: F( O+ E
  299.   {
    ; u0 ~  a: @" w6 v! _' S, |
  300.     if(code == CodeSoh)9 D; @4 s. j! G2 _7 W
  301.     {
    $ Y/ }) [/ p( k# R) m! A3 H
  302.       uint32_t len = read(&(rxBuffer[rxLength]), YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - rxLength);7 w8 \2 F9 s( D/ h7 T- Q! P

  303. - M* p3 G/ g  [1 O, E9 G
  304.       if(len < (YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - rxLength))
    : L; ?1 J$ s: P5 }* u
  305.       {
    1 f. V8 s1 m- y1 t- p" y' Z
  306.         rxLength += len;
    ! i* a. o7 C% u' U4 e/ y

  307. 0 X( M2 R% a! V. N& D+ u7 `
  308.         return CodeNone;
    / T- N7 s& f" y- z, I
  309.       }
    % E( O9 x# Y! c; R
  310.       else
    5 t" r3 f- C6 n0 v% L* b
  311.       {
    , A1 G7 i0 N& U  U7 M
  312.         code = CodeNone;
    / k8 I7 Y$ Y& h& T+ T

  313. ; y( G* z# s6 P; z
  314.         return CodeSoh;
    + r7 D) B1 M5 \/ N3 E# h2 W& B* t
  315.       }
    5 I9 x% n; W( p1 F& w
  316.     }
    ( T* Q* b% V3 l
  317.     else if(code == CodeStx)( y, T6 K, H9 R: V* X+ i" N' z
  318.     {+ f: X/ u+ Y4 w; I
  319.       uint32_t len = read(&(rxBuffer[rxLength]), YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - rxLength);
    / _+ Y6 R3 Z$ k9 k5 h

  320. 7 L, P& ~; l, q& a2 |5 F. @
  321.       if(len < (YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - rxLength))
    6 @1 s0 P1 s0 Q! H
  322.       {) O# u7 v" \/ y& R) z& D& b
  323.         rxLength += len;
    5 O9 u2 S) b7 W! n0 B% o. m; F
  324. 2 K6 D  S" r3 T& M2 h" @' W
  325.         return CodeNone;) b6 b2 c3 {: i. e. h) I7 K
  326.       }& O0 S5 C4 ^2 q* a
  327.       else
    # @( x$ z- ^" A4 y
  328.       {9 G# A/ S8 L: b1 j
  329.         code = CodeNone;% S- |/ o# B1 S
  330. 6 r( a5 h; s4 t9 q7 D6 t% }/ S
  331.         return CodeStx;( F5 U" c# c) q0 y( R
  332.       }
    9 }3 {4 T( T+ @: z+ x+ n
  333.     }
    2 l# k3 N; ^+ V- K) t1 z  l
  334.     else5 b; b9 v) V" M) a1 |- f
  335.     {
    ) z% j6 \5 l6 Y: a8 l4 e
  336.       code = CodeNone;4 T5 Z9 G$ ]  e+ }

  337. * |+ j1 J  b7 Y7 [+ [! |
  338.       return CodeNone;
    ! U/ e) R, V3 k# |
  339.     }1 a; g$ R6 n/ c' U! v
  340.   }
    8 v7 z/ a' v. {4 a
  341. }
    5 n" Y! w$ W" }8 e+ t: i
  342. & w* Y0 }9 J4 C7 i% O2 X' P' [
  343. /**
    & P' B! v- ?' n9 k9 Z+ y
  344.   * @brief  Receive none stage.9 ]2 N+ q6 C2 b4 G* m3 M- E$ n9 j% ~; W
  345.   * @param  None.4 H- K8 S# I. f: n
  346.   * @return None.
    ( W7 s  j) F; k! }( g+ t
  347.   */+ W$ ~7 I. T5 }' x! N! z* |" K" C
  348. void Ymodem::receiveStageNone()3 _- r; ?$ y5 _! B
  349. {6 y1 M( ?% z9 u. ?6 W
  350.   timeCount   = 0;
    & w8 r2 z8 v+ p+ d: k) w- J- l+ ~% [
  351.   errorCount  = 0;
    + T* V; ]; W7 M1 X
  352.   dataCount   = 0;. ~$ O8 o* I/ y5 ]2 q& M5 T. Y7 u
  353.   code        = CodeNone;; W9 Z" d4 s5 z" w3 J0 \4 h8 [6 h
  354.   stage       = StageEstablishing;
    2 a( m4 P: [/ W+ M7 }( |
  355.   txBuffer[0] = CodeC;
    4 K  `& t- ?0 I( ~6 g; q9 n
  356.   txLength    = 1;4 P; m; [8 r+ d: j6 y2 r0 p$ k! V
  357.   write(txBuffer, txLength);
    * |8 M. p6 o. [* a% L: L
  358. }8 L  j% F3 L- |+ P% C- K/ r

  359. ) u5 A0 k) y# N' y* m) ^
  360. /**4 v. x; I; }* u
  361.   * @brief  Receive establishing stage.; s5 ?8 I" `( p9 A, T6 j; g
  362.   * @param  None.- e/ _; x1 b( W% R
  363.   * @return None.6 O% a: n& @, A
  364.   */
    5 E! Q' K/ z+ D" t  v, h
  365. void Ymodem::receiveStageEstablishing()) E, a. l7 V& m* f9 H4 K. R
  366. {
    7 Z9 b3 Q* j3 C3 y* Z+ z' a
  367.   switch(receivePacket())5 S0 a' a1 |6 @/ _' L
  368.   {7 `9 H: ~! J) M* V% q9 x$ J9 }
  369.     case CodeSoh:/ s  q1 i, {: y6 G; ]; V  h. b
  370.     {7 K' K; `: T3 @. o7 i5 y
  371.       uint16_t crc = ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 2]) << 8) |& X- O6 e$ k9 b  ~; G( T9 g2 p
  372.                      ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 1]) << 0);3 I# e0 E! a+ F

  373. ) w' f& L/ i2 T. a6 w2 q( j# L
  374.       if((rxBuffer[1] == 0x00) && (rxBuffer[2] == 0xFF) &&
      h4 N, G# [' l5 l2 F
  375.          (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_SIZE)))
    ! t/ s- O$ d" u! }- ~& L
  376.       {8 M/ F& Z8 o3 q8 g
  377.         uint32_t dataLength = YMODEM_PACKET_SIZE;
    $ ~" \! K' k- F4 w+ T2 \! [

  378. # g; J. p, F. [9 p: g" |1 D; t7 C. ?
  379.         if(callback(StatusEstablish, &(rxBuffer[YMODEM_PACKET_HEADER]), &dataLength) == CodeAck)
      E+ Z$ @$ v( D+ u' W' x- c
  380.         {- A7 Z$ U1 P: |8 ?/ j
  381.           timeCount   = 0;9 O  m. |  \! J" U( k
  382.           errorCount  = 0;! T% o7 r/ U3 s' S
  383.           dataCount   = 0;
    / \: r# p5 z, ?+ A
  384.           code        = CodeNone;
    ) T3 N3 c; Q; g$ x9 l
  385.           stage       = StageEstablished;; u  O" V" ^7 M0 G
  386.           txBuffer[0] = CodeAck;' N9 E0 U- X0 o( U
  387.           txBuffer[1] = CodeC;% N7 h1 x/ Z% ~$ x% c# P- l, g
  388.           txLength    = 2;
    4 I- f9 H* K# A& L- X
  389.           write(txBuffer, txLength);1 t" Z  D* I9 W) `! o
  390.         }& P: i6 C& m: H7 u( e. v2 I
  391.         else3 B9 v7 D" h4 y& i+ E1 W
  392.         {
    * o! Y  d7 Z) M. f/ X
  393.           timeCount  = 0;  c& c- U$ |; @2 e0 Z8 E9 w, [
  394.           errorCount = 0;
    + U6 g1 f- {" z
  395.           dataCount  = 0;/ @3 a$ J; Y4 Y1 A' N
  396.           code       = CodeNone;  D* E, j9 N0 R5 _9 \9 E7 ]
  397.           stage      = StageNone;
    + c0 B: B& A9 L% t- D. ?! N. A9 S2 d

  398.   X8 S. {' V. I+ D. Q0 H; j
  399.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    2 i8 g2 Z( l7 S2 q
  400.           {+ E9 |. H0 P0 y" u: c8 R1 k3 F+ m
  401.             txBuffer[txLength] = CodeCan;
    ) a$ [6 X# A: E) a3 A2 Z( H: \
  402.           }
    - x5 y% T$ n+ q2 ]

  403. # u8 E) E; o0 ^8 C
  404.           write(txBuffer, txLength);
    " e% a3 O# }, @% s3 }5 ~0 V" j; K* d& s
  405.         }
    . w3 y. e2 u( s. M8 N
  406.       }
    , G9 }! i$ i6 }# I
  407.       else1 h, b9 U) n" ^4 c3 j$ k8 q
  408.       {* S4 [, y, d: |( P- C# B
  409.         errorCount++;1 r4 X- J9 T& L4 {2 {4 H

  410. 1 N2 C: k# h+ x" q% z
  411.         if(errorCount > errorMax)
    $ \/ q0 |% N* u& _5 f0 S
  412.         {; E& |4 j: S! G/ s
  413.           timeCount  = 0;5 O" T2 {2 }/ Y/ l
  414.           errorCount = 0;
    & z, W" G" l/ v4 G2 N; h6 k
  415.           dataCount  = 0;( y# F! H& Y  X, ^4 x. m, Q
  416.           code       = CodeNone;7 n* ^* o- t. P. U
  417.           stage      = StageNone;
    2 ]. @* O' R( R0 I. N% N8 D
  418. * {, I* s3 c: f' l* ~% K" [
  419.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++), K: A* Q% K) V, t0 F; ^; W+ T7 V( l
  420.           {1 e$ Z! g1 d/ u  L) B$ z. S
  421.             txBuffer[txLength] = CodeCan;
      i# M% a- O. Q7 o# m
  422.           }. Q2 M4 e6 v7 I% K
  423. 8 n, E. z2 t: d5 i0 H( K8 }. G% o$ f
  424.           write(txBuffer, txLength);+ m* K& m& B2 r7 B- D' y: j
  425.           callback(StatusError, NULL, NULL);
    & s. I6 i- w, q6 Q
  426.         }
    0 j8 F) T  ~' t8 O# ^" f
  427.         else
    % ^) t; C: b4 v
  428.         {& l+ \. y, d5 E$ x3 r, s! Q; V9 E
  429.           txBuffer[0] = CodeC;3 r8 U( ^: Q6 `9 }! y
  430.           txLength    = 1;
    9 p( X: C0 c8 Y, B, u" M0 ~" c' N
  431.           write(txBuffer, txLength);
    0 _( V6 ?2 U6 v+ q5 x* t, a' m
  432.         }
    1 S4 Y( S( P! B  V( N
  433.       }5 [) N9 Y3 E& G2 [

  434. $ `% z$ g- ~5 N- I
  435.       break;5 ]' U8 W3 ]& R& T
  436.     }
    % m, j- v# I3 P0 y+ \
  437. " ~) a) V6 l" Y
  438.     case CodeA1:
      O; m" e! h  R
  439.     case CodeA2:% V' x' s) E0 |8 m, l4 e
  440.     case CodeCan:
    9 o' h  [* M; d& b1 |( G
  441.     {
    ! t* Q6 c  R2 v1 o* m, v+ ?
  442.       timeCount  = 0;; _. R. \* y+ j$ L
  443.       errorCount = 0;
    0 K; {  U3 G7 j" H
  444.       dataCount  = 0;  U8 `6 j. L& t0 k+ b
  445.       code       = CodeNone;
    , T3 b- G! ]6 P% i
  446.       stage      = StageNone;
      q; ]( W% g# R) }& o4 t- f0 s
  447.       callback(StatusAbort, NULL, NULL);7 D8 }/ ~/ z# n
  448. 8 d& i/ {0 E; U5 T: d8 b3 x8 I
  449.       break;
    2 P% q3 J5 l' R% z2 Y* c
  450.     }
    1 H; I: h2 j* G1 W  x! R
  451. 2 R0 U0 U# |+ J) s( I. E5 |& Y
  452.     default:
    ; [/ F& D% t; r. R+ z8 u9 c( h% _
  453.     {8 o1 _) r" O4 O
  454.       timeCount++;3 g7 Q) d3 Y% t6 F

  455. # m% y, Q6 n* P( k1 D$ @+ {
  456.       if((timeCount / (timeDivide + 1)) > timeMax)
    ( g  Z) z$ _* t! r2 {  A
  457.       {
    " C% k) I" G5 [
  458.         timeCount  = 0;
    7 S5 ^5 a( j. t; s5 R0 W
  459.         errorCount = 0;
    , j/ {5 \; ~' @: V' Z: D% Y
  460.         dataCount  = 0;& q; O0 W8 F- S- f8 P) Y! T
  461.         code       = CodeNone;
    0 y3 [: r' T0 Z, B' m5 f0 p1 A
  462.         stage      = StageNone;- J7 E3 O0 F& A3 H7 p
  463. ( r, i9 [: C0 k
  464.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++), X$ I* T9 q7 U$ _+ Z: j8 L
  465.         {
    0 G1 H: \4 ~$ d4 \' d
  466.           txBuffer[txLength] = CodeCan;
    . I4 K8 e. X, @) F& S9 B, g* b0 Q  L
  467.         }
    4 u8 C4 [6 m' c" O. j
  468. # \1 k( J+ F3 |0 r) ?7 J. g
  469.         write(txBuffer, txLength);+ G: L4 [# Z8 m9 |# m' q
  470.         callback(StatusTimeout, NULL, NULL);
    1 E3 l- l$ a. A& N9 A# \2 ^- E" ^
  471.       }/ y5 @( ?1 K( s. t# G
  472.       else if((timeCount % (timeDivide + 1)) == 0)1 B+ ?8 ~  r* A2 @! W
  473.       {
    5 m4 b) G7 T" x# b# J2 l
  474.         txBuffer[0] = CodeC;
    ; Z7 M, t5 F: A+ v9 c
  475.         txLength    = 1;
    & i& y+ F1 k5 Z- e. N+ C2 [3 h7 ?
  476.         write(txBuffer, txLength);* I5 J2 L) x5 J
  477.       }  z3 s0 z; C/ G7 i7 \( Q; T
  478.     }* w0 {9 a2 N1 E
  479.   }
    " g2 N5 G( L' U9 P$ y
  480. }( x9 C5 `1 I0 m2 |
  481. 1 x1 n8 }6 Y- u% x; X5 w! X& u. Q
  482. /**
    , S2 f/ D8 k3 t" H6 |- \! [
  483.   * @brief  Receive established stage.
    ; K* n% p1 c0 C1 f2 \/ a
  484.   * @param  None.
    ; k: V2 ]( w" s
  485.   * @return None.
    / `5 O& `$ d6 d' v
  486.   */
    0 |3 {# X6 Y9 N' X( L5 h
  487. void Ymodem::receiveStageEstablished()+ p+ p) K/ c0 y: ?
  488. {
    / r. x# I9 n- H
  489.   switch(receivePacket())  C: a4 }( T3 t/ s* y. M
  490.   {
    3 f/ F: s; z' A, W- [: R
  491.     case CodeSoh:  [; b. m9 P% {% t/ o" c! `. S& D
  492.     {2 k% h- W; T$ o
  493.       uint16_t crc = ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 2]) << 8) |
    & [) a9 g* H9 j3 [2 }" ]
  494.                      ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 1]) << 0);& O  [5 U" t) C+ f/ r" g
  495. 4 K# [2 Y3 f+ {& P6 M9 E2 ?
  496.       if((rxBuffer[1] == 0x00) && (rxBuffer[2] == 0xFF) &&4 F! ]8 `; h8 v6 [9 C1 Y
  497.          (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_SIZE)))4 D" F& _" R4 v0 v9 Y
  498.       {7 G- a& l; x' o
  499.         errorCount++;
    0 r; A: f% K! s' O/ [' Y* i
  500. 7 i! v0 E0 d$ s% A4 [1 i
  501.         if(errorCount > errorMax)- r! [* x8 \* p1 a) y
  502.         {
    ! a$ I: v0 c- u# L) G. @- R
  503.           timeCount  = 0;
    * X" d( S" d* q) T' L( q# {0 }
  504.           errorCount = 0;
    . A0 T$ L9 d, ~
  505.           dataCount  = 0;  q/ ]( G7 F, L0 j8 C8 Z
  506.           code       = CodeNone;0 A) C  m  S( L% i: `* h
  507.           stage      = StageNone;, W7 ]* Z/ k9 Z

  508. . l* |9 k# Y" \5 A3 {" h
  509.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)7 ]; ], I( r3 ~$ {' z; R
  510.           {, p! f8 U; h/ ]) m: M) u! h( m* A. S
  511.             txBuffer[txLength] = CodeCan;7 D- d. \0 D- o4 D  X. c
  512.           }5 H5 H+ m- Q$ {; u/ r: y4 x# C2 N/ F

  513. 2 M9 v9 Q$ V. k0 L% o- I/ x* g
  514.           write(txBuffer, txLength);
    7 g: M2 i- B$ p, Y9 e; w1 F  W
  515.           callback(StatusError, NULL, NULL);4 f7 P! J- d! N
  516.         }% j' Q7 F: ]+ Y4 Q- L( i" j, c! n
  517.         else
    7 A; I  k; a5 }: \# r
  518.         {
    3 f( q# H: ?, _4 A
  519.           txBuffer[0] = CodeAck;# j4 n: M+ j4 S4 b9 H2 j% b
  520.           txBuffer[1] = CodeC;
    + W5 B/ R4 y% o6 f
  521.           txLength    = 2;
    / h0 D% h2 a1 `
  522.           write(txBuffer, txLength);. M9 e6 R  Q4 ]" {2 [
  523.         }, D" X3 L8 S' `; t4 _2 {
  524.       }
    " h- o) J) r  M" l
  525.       else if((rxBuffer[1] == 0x01) && (rxBuffer[2] == 0xFE) &&! ^+ H# y' f4 X8 w( k
  526.               (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_SIZE)))8 O) E. _  G% Q% e* O6 h
  527.       {0 |# p2 F) d$ J4 P9 q4 L! z
  528.         uint32_t dataLength = YMODEM_PACKET_SIZE;9 ~, d; `5 O5 T- ?

  529. + ?4 p0 U0 J# w9 y. P
  530.         if(callback(StatusTransmit, &(rxBuffer[YMODEM_PACKET_HEADER]), &dataLength) == CodeAck), z' F' V( G7 h1 E/ U
  531.         {% k  f$ |' X6 P9 K
  532.           timeCount   = 0;% O% U- U9 g% Y% x/ n% E: {
  533.           errorCount  = 0;
    9 U# \' A* t& a1 M# ~
  534.           dataCount   = 1;& P$ g& |" D& W) e5 r2 c
  535.           code        = CodeNone;4 j3 N! H' e6 r1 Q8 ~/ c" A
  536.           stage       = StageTransmitting;( Y( h& A' ^) t* q: L/ Q' Q
  537.           txBuffer[0] = CodeAck;
    7 j* e8 y, H. A  c6 z4 v* ?& R" v! y8 O
  538.           txLength    = 1;- _1 j5 t0 C9 ~2 ~, J  t3 p3 [- _
  539.           write(txBuffer, txLength);
    8 w; u' t' ~3 ?1 G  N" s# q& J" _3 q
  540.         }
    + I- @$ d, A1 F; R
  541.         else7 A7 ]) j# z2 {
  542.         {
    8 |+ v3 }' U' C
  543.           timeCount  = 0;9 p- b) t* y% T$ ^- k, z
  544.           errorCount = 0;+ }, x/ i" Z, h
  545.           dataCount  = 0;
    1 z5 k5 ?" P0 X0 r  b+ f% C
  546.           code       = CodeNone;
    " C* z5 I7 U3 w" r$ K* t$ |# @; X' N
  547.           stage      = StageNone;9 B$ g. Q& z5 S5 T3 [

  548. * \$ T( x" X0 E9 j" `2 z$ ?
  549.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    ' M; U% L4 @  i/ U8 J  }* V
  550.           {, b+ t# D; {  j2 Y
  551.             txBuffer[txLength] = CodeCan;" Q; @5 F9 V$ S
  552.           }
    4 T, N7 P& x& G- C

  553. / M5 A' v" D+ e6 s+ ^
  554.           write(txBuffer, txLength);
    ( d* t7 f) t, h% z1 ~
  555.         }) ~% O7 ]+ ^7 K  @( C6 O
  556.       }& T# g( f1 z( R% O
  557.       else# G, N4 F% D4 \, i. T6 I
  558.       {
    + F# b2 G" k# S! m7 k  Q
  559.         errorCount++;
    . }4 {+ c9 [5 N

  560. 1 h" P, D& W6 W/ r. B" a6 u
  561.         if(errorCount > errorMax)8 c" c, {2 W6 z) g3 N# _) [
  562.         {  r& ^2 I$ _! R' h  X
  563.           timeCount  = 0;
    $ ]/ @6 A/ J; i! K/ X5 C
  564.           errorCount = 0;2 ^' ~- F9 ]1 U
  565.           dataCount  = 0;
    8 @; D, O8 v/ W0 N& X$ ~* s  S+ b: D
  566.           code       = CodeNone;
    8 Q: [0 t* Y. y  e) p- Q
  567.           stage      = StageNone;" u7 d4 r) _% ]

  568. . X- R3 X. n8 m: _
  569.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)2 t7 e6 ]+ [" S. F. I
  570.           {( J" k) h0 F" Y, N7 Z
  571.             txBuffer[txLength] = CodeCan;
    ) w  Z  O; R$ l, E; R2 r% p
  572.           }& |# ]1 g# O: s# _! q$ ~% T
  573. $ {5 a+ N- w$ ]8 S6 f
  574.           write(txBuffer, txLength);8 D+ U9 n( x( d+ `, b% D
  575.           callback(StatusError, NULL, NULL);
    . M1 s6 ]  k% F/ p$ E
  576.         }
    1 \7 Z' g) z3 |1 K% Y( i6 ~6 p" O5 R
  577.         else
    , R3 a) q: c0 F) W. F# U' L% C
  578.         {
    3 x( i4 u& }+ K* n9 _- A% k% C- o
  579.           txBuffer[0] = CodeNak;/ M! v) n/ ^: x% J; T
  580.           txLength    = 1;
    $ B/ k5 T6 S8 t, R4 e
  581.           write(txBuffer, txLength);
    8 l4 C8 v; I3 e
  582.         }2 A4 H, A, u, D) M) ^' {. ]
  583.       }2 r; Y+ P$ t/ Y- c& D* a
  584.   l, u7 m8 t6 g) A! _
  585.       break;
    % w5 M1 {  D) m3 o0 s* p
  586.     }
    3 f4 R4 t  [. d) u! l- `0 ~

  587. - y# A/ j8 j3 M. w
  588.     case CodeStx:
    * |0 l/ m$ L3 ^" ?; a
  589.     {. i  w4 h$ s2 r, e# K3 w5 B% p
  590.       uint16_t crc = ((uint16_t)(rxBuffer[YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - 2]) << 8) |; J- A( `/ x. {9 V& I2 ?( J
  591.                      ((uint16_t)(rxBuffer[YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - 1]) << 0);
    ( y$ D0 v4 S% a

  592. . S4 p6 O8 g# U
  593.       if((rxBuffer[1] == 0x01) && (rxBuffer[2] == 0xFE) &&: X9 Y, Q8 M  m6 z
  594.          (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_1K_SIZE)))& n7 `* a: _, F; k) I
  595.       {' q6 ^. e4 l6 p$ ^) g6 f
  596.         uint32_t dataLength = YMODEM_PACKET_1K_SIZE;
    / {; a4 f+ `! _

  597. : @/ w/ x9 [  j4 o+ U
  598.         if(callback(StatusTransmit, &(rxBuffer[YMODEM_PACKET_HEADER]), &dataLength) == CodeAck)
    3 \* P* i4 T2 \3 R* M
  599.         {+ y! Z) K7 d$ W/ a! y; W
  600.           timeCount   = 0;
    ! R; c; ]4 e/ a8 @$ N
  601.           errorCount  = 0;
    ( c, |8 L% B2 G# f1 u+ Q, P
  602.           dataCount   = 1;
    + j' h4 i& h  _9 N$ b. }
  603.           code        = CodeNone;9 a4 j9 n3 m8 D1 @4 k& e
  604.           stage       = StageTransmitting;' J5 T2 Z& u4 U0 V5 d+ e7 l
  605.           txBuffer[0] = CodeAck;8 B5 {. v. _# Y3 V6 b2 ?' K5 c
  606.           txLength    = 1;
    ; H" v. Q9 m0 l2 M8 l( z
  607.           write(txBuffer, txLength);* X. L  G4 L0 ~7 F7 w) D" f$ v
  608.         }/ T0 y/ Q9 F# b0 I! z
  609.         else
    ! }& `- t7 ]+ p+ A2 O
  610.         {/ |' u4 K0 k% E' K4 ]- @! T: t
  611.           timeCount  = 0;& g+ m. g+ P0 A( B; ]+ z) |- N6 R
  612.           errorCount = 0;1 m# P' `# G" ]8 V( _- t$ M
  613.           dataCount  = 0;( Z" S5 i* ?5 u8 C& S8 `
  614.           code       = CodeNone;
    2 G+ X/ y* ^! t
  615.           stage      = StageNone;8 H$ l! z, t5 f  L4 q1 ^0 p3 q

  616. + ^5 d# E3 A' B- J0 d
  617.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)7 H9 n3 S: o$ }1 j& i+ [
  618.           {
    9 m2 H0 B$ _7 T* f: s
  619.             txBuffer[txLength] = CodeCan;
    2 d9 z3 T% v0 S& v: _) H8 j# g8 G6 [
  620.           }6 Z' q+ a9 o1 L

  621. ! Q) ~! I8 S0 y# f6 L9 }$ I
  622.           write(txBuffer, txLength);) V% O7 o! @  I9 ?" G: @: W  q4 C
  623.         }' k& M8 w) @' M. W# }5 P
  624.       }
    * U7 R, t1 |2 s" }" r  u/ z6 I8 y6 J
  625.       else" y! h4 S  z6 d3 R0 E& ]
  626.       {
    % U: S# A5 u1 \+ M% \7 d
  627.         errorCount++;
    7 s1 v. z- S# ]  ?0 L
  628. $ M* _3 d  ]" M+ d0 ?, g. V( f0 l( Z% [
  629.         if(errorCount > errorMax)" D, a' b7 T! i6 ?+ v
  630.         {3 F2 {/ s2 G- Q" K6 z
  631.           timeCount  = 0;5 Z1 `) L7 ~& }0 k2 @: q8 T2 A
  632.           errorCount = 0;, X+ L# P) E0 X9 A: I3 M
  633.           dataCount  = 0;
    0 J5 F# `  ?) `. |$ b3 _0 N" o
  634.           code       = CodeNone;+ i6 J: x. u1 h- S  L- W
  635.           stage      = StageNone;
    % }2 S' `- x: S) }

  636. 3 ^# d8 S" W' v" a" h
  637.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++); u! A' b2 F1 H% g
  638.           {# N- s) x- Q( }( t: ^
  639.             txBuffer[txLength] = CodeCan;  g% c. u8 h" m
  640.           }' h* ~/ p/ Z- W- {$ ]
  641. # y4 t/ g9 V) {
  642.           write(txBuffer, txLength);
    - E& G* q- X0 c2 c8 t- Y7 j( @5 g- t
  643.           callback(StatusError, NULL, NULL);  m1 f4 v  C' x' K; m
  644.         }
    2 x# Y) F: a2 |- c
  645.         else* W/ N" j' a* v) |+ Q
  646.         {
    2 a$ H5 }8 a8 \& B; f) p, o6 P
  647.           txBuffer[0] = CodeNak;
    5 [  K! F+ ^9 `' R3 m
  648.           txLength    = 1;* S2 T/ x. T( |
  649.           write(txBuffer, txLength);- b, x- f( d6 n) n
  650.         }
    9 u: r1 w7 Z, ^: S
  651.       }
    ! R" m. v- e8 a8 T. w; _: C& {

  652. 0 |' d! J9 r& e( d* M5 t/ H7 V
  653.       break;2 M. G# M, b% J8 e
  654.     }; n. s9 N& Y5 I. [, J

  655. ; V( w& f3 |4 d8 {2 a6 i
  656.     case CodeEot:2 c, m6 R3 E0 B" m$ q1 V2 h6 @! [$ I
  657.     {
    , k- Q/ `- m) a) f8 R
  658.       timeCount   = 0;# |3 j/ `& S2 Y% |- W# Q/ f; a+ v# p
  659.       errorCount  = 0;
    ; ~( J- s4 f" u  n3 V, I
  660.       dataCount   = 0;  C; x: _& `$ J( B8 e, y
  661.       code        = CodeNone;  k* z: n" V  R" `& J
  662.       stage       = StageFinishing;
    1 z; H% h" x  U* j# S  L+ t4 z9 j
  663.       txBuffer[0] = CodeNak;; G# p  C4 Q6 }3 S
  664.       txLength    = 1;4 q5 @$ u8 @2 p4 \
  665.       write(txBuffer, txLength);9 l2 C. B3 v: L, M5 W% o* L

  666. ) U5 ~/ }2 P4 i5 Y/ K9 L" _
  667.       break;
    - @, y# G7 p" S
  668.     }' \2 a$ f4 r7 c% z

  669. ' \; \. F2 {( {
  670.     case CodeA1:
    1 d3 x4 I0 z& s. A9 ?# x$ A8 n
  671.     case CodeA2:
    6 L' g! @  P2 q( e5 K8 R
  672.     case CodeCan:
    " O8 u% O. e7 d5 w, q9 q4 ^1 c
  673.     {5 R: T+ o2 [3 T# |( ]- G
  674.       timeCount  = 0;7 i  \7 i+ v$ ?; g; I3 h5 q+ ~' V
  675.       errorCount = 0;
    " z" H- u$ o7 m# F" p
  676.       dataCount  = 0;
    ! Y$ W/ |5 K/ t% j
  677.       code       = CodeNone;
    + f: u7 l9 P2 G8 a% d0 E
  678.       stage      = StageNone;
    0 r, V) h1 E0 D' b
  679.       callback(StatusAbort, NULL, NULL);) {  z- i3 J/ G2 }7 V  [& z* o
  680. + F0 \- C& X% I' b8 C2 ~. L
  681.       break;
    / W$ J3 b, F; H9 s! z' m
  682.     }
    # g, X) P& v: [7 m9 M
  683. 4 y/ e6 M! o6 q' W+ `
  684.     default:
    2 I7 D- K# L8 f) e# Z8 j
  685.     {
    6 W) M/ y" ^, l* N# i9 j
  686.       timeCount++;
    8 S, j( J( s5 `& @8 w
  687. . ?  \4 Q( `# t, [+ q
  688.       if((timeCount / (timeDivide + 1)) > timeMax)
    0 U6 c& |6 E2 Q1 x, ~
  689.       {: l! B3 ?0 E1 L+ W
  690.         timeCount  = 0;
    ' e) P. R2 W7 c) k) [' _' D; b
  691.         errorCount = 0;
    1 Y! x: Y& T! `
  692.         dataCount  = 0;7 M9 ^+ a( f% [% l1 ?+ J
  693.         code       = CodeNone;
    / G: D. g% a! x/ g) |7 f+ z
  694.         stage      = StageNone;$ b/ r  j5 j  X3 b
  695. * U' Y. z* H9 R. r& l, L6 n% d" g! v
  696.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)/ B' l6 g" k& |6 e! G0 l. S5 M# Q
  697.         {2 c) \8 s' [5 F! [2 g
  698.           txBuffer[txLength] = CodeCan;7 }0 b, Y8 P5 ?4 E6 |9 e
  699.         }3 c$ `/ T% \9 l- z
  700. + ?$ ]; F& e2 i" ]# g( J/ ~8 e
  701.         write(txBuffer, txLength);3 O2 x' v, |; _1 i$ `0 h( A
  702.         callback(StatusError, NULL, NULL);6 V# H) Z1 t# X- E, n: i" k9 {/ G
  703.       }
    " X( O' G$ i. o2 a7 D
  704.       else if((timeCount % (timeDivide + 1)) == 0)6 i# Q, V) [. M1 x( B6 ^
  705.       {. F" a4 w( B: ?* r* x8 W
  706.         txBuffer[0] = CodeNak;
    1 B* j, Y! z- O- ^4 o/ h
  707.         txLength    = 1;! V9 \$ K" K7 z& E8 n) G
  708.         write(txBuffer, txLength);- d% c6 }- k: X& Y
  709.       }
    1 W# V' B' j0 j# L+ [# `
  710.     }9 o+ S6 w- X" w" J" l2 C
  711.   }
    $ ]: e. T, \" s+ Y/ }! L  [
  712. }% r# k! s, J5 z1 ?1 x2 n
  713. ( ~( x# \& g6 l
  714. /**- M; }3 V) O9 u/ b. R+ N2 m6 F" ?
  715.   * @brief  Receive transmitting stage.
    2 B( Q2 G  K3 \/ ?, \
  716.   * @param  None.& R$ o* p" ?$ z+ ]: d
  717.   * @return None.
    5 j$ V% [+ p& P* ]/ h- H9 [: R6 s) r5 h
  718.   */8 T- d, O8 C8 @, ]; N0 H
  719. void Ymodem::receiveStageTransmitting()
    $ c3 S+ G( e2 g3 h( n+ B5 |0 h
  720. {6 _$ N6 S* M* \3 n; |
  721.   switch(receivePacket())
    0 C9 I0 o3 v8 U, A; S
  722.   {
      V) a0 a* ?+ ]2 y$ G# g
  723.     case CodeSoh:( u/ E$ A/ h* V% n* ~5 o5 D* Y! O
  724.     {3 e) ?# P5 Y: W6 @8 _
  725.       uint16_t crc = ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 2]) << 8) |
      _9 u; \: H- c  L
  726.                      ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 1]) << 0);: \3 C+ N3 U: C( g' Z/ d  f3 ~

  727. ' e1 D& F" s9 @$ G6 c; J: _; N
  728.       if((rxBuffer[1] == (uint8_t)(dataCount)) && (rxBuffer[2] == (uint8_t)(0xFF - dataCount)) &&0 ~: r% M  h, g3 C! T  I
  729.          (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_SIZE)))
    ' ?$ a4 i4 m* `0 @* R$ d# _; ?
  730.       {6 @  X) Q6 Z, v; G7 V) ^
  731.         errorCount++;
      }' O+ P" j4 n9 s$ V
  732. ) f* s8 ?$ u( C2 k
  733.         if(errorCount > errorMax); y$ I; S& F5 V8 r% K
  734.         {- d  G- S9 p8 O( _0 l) ?
  735.           timeCount  = 0;2 R" K! p1 Q/ p5 a5 B; }5 p
  736.           errorCount = 0;
    ' J! [! k1 r1 `. `5 Q
  737.           dataCount  = 0;
    ! i9 ?- L5 d- N" O' ~
  738.           code       = CodeNone;* l$ d% c. M3 T4 z0 _$ d4 A, I
  739.           stage      = StageNone;! |8 {  t* }. |
  740. 2 I$ H( _2 n7 O, h+ |7 }
  741.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)0 [6 M2 _! o) i: r9 {
  742.           {/ l0 T) |2 U) u; y: N0 ~
  743.             txBuffer[txLength] = CodeCan;+ E" j6 V  l( V8 V
  744.           }
    ) v8 x; h+ D% Y( N$ Y  e- a1 H

  745. ) \4 T6 a( W8 y2 P
  746.           write(txBuffer, txLength);- _% m# Z# t9 d) C
  747.           callback(StatusError, NULL, NULL);
    & m/ Q! m0 k; {: z. v& @
  748.         }0 `6 r$ k/ W; c: }. {& @( Y
  749.         else  j* @# ~6 H) ?8 m3 a  j
  750.         {
    0 F0 x& f( c- s6 q( _5 L
  751.           txBuffer[0] = CodeAck;
    7 Z! n  W+ |3 A( q. m6 m: b
  752.           txLength    = 1;1 g! ]0 V5 _( m1 V2 y2 g# [
  753.           write(txBuffer, txLength);
    3 r& U1 i. M) U
  754.         }$ i  Y: I9 |6 Y
  755.       }8 g4 F* ]+ W6 p$ J8 Q' Q. L9 o
  756.       else if((rxBuffer[1] == (uint8_t)(dataCount + 1)) && (rxBuffer[2] == (uint8_t)(0xFE - dataCount)) &&
    9 y8 i9 Y( a+ e+ y# ]3 c; ~/ S7 {
  757.               (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_SIZE)))
    $ X; T5 K9 W3 o. s3 d4 U: o3 d
  758.       {$ Q! G( d: |  S8 W& @- s9 O3 |$ \
  759.         uint32_t dataLength = YMODEM_PACKET_SIZE;
    ) z) R4 G" b- ~4 l3 y  h
  760. - p, Q& D$ O5 ^. f: ^4 A5 p4 O
  761.         if(callback(StatusTransmit, &(rxBuffer[YMODEM_PACKET_HEADER]), &dataLength) == CodeAck)
    8 H% f/ K' h+ P5 z4 h
  762.         {9 l/ ~: G; r# }( V
  763.           timeCount   = 0;) q6 i. |) c5 t; y
  764.           errorCount  = 0;/ H' Y& z( i' B4 P4 P
  765.           dataCount   = dataCount + 1;
    , _$ _4 ]1 m3 t) ~" M) b
  766.           code        = CodeNone;
    ! Q9 M1 q+ V% e8 ]
  767.           stage       = StageTransmitting;
    3 B7 P9 [7 @+ m$ R# P& q
  768.           txBuffer[0] = CodeAck;' J% G" h$ x  I5 \
  769.           txLength    = 1;; G/ W$ U, e5 N' F
  770.           write(txBuffer, txLength);3 v/ u# s! V9 L- H$ h. q0 b
  771.         }' a% j  T+ J) e) t, A+ T2 ?# D( w0 f
  772.         else$ I. l1 v8 T' e' W- t# r
  773.         {, W  q, {3 S, K1 K5 }1 r; E! t
  774.           timeCount  = 0;
    9 D& @4 @6 _) T
  775.           errorCount = 0;  Y) G# A0 I# U9 U% R1 Q) B
  776.           dataCount  = 0;
    & R5 O0 C9 u1 l# p
  777.           code       = CodeNone;
    * b8 ]7 U1 @1 q# a3 T6 Y# j
  778.           stage      = StageNone;
    - q) f4 E# N1 L! J
  779. : T" K$ @. O0 H! Q" ?8 M
  780.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)0 u9 w) L( L0 ^# n- n8 T
  781.           {
    # g; |7 z1 ~* K2 J0 T
  782.             txBuffer[txLength] = CodeCan;* @1 g" ~. ?6 R/ y4 Y1 }
  783.           }) L; ^& h( `4 _! o  s0 @
  784.   r( Z; X/ C! T/ V  q
  785.           write(txBuffer, txLength);" o" j2 A, Z4 T3 e) x1 M
  786.         }
    # {! L4 o" b' m( H. L: F
  787.       }5 Y' B& B" W9 n3 _
  788.       else3 R* w& q" u# a3 D% ]2 O0 n! ~
  789.       {; j  A% v# Y+ v+ x+ T
  790.         errorCount++;$ E1 F6 V4 N8 h" |
  791. 4 C# c, }* D% ~, v- l6 S$ x" d
  792.         if(errorCount > errorMax)
    ) b' i; J% E2 K+ J) k4 _) W) Y
  793.         {$ {- z, r" o% q& Z
  794.           timeCount  = 0;
    0 w% m1 ?& R/ N, Q2 U+ T+ j. A9 n* q
  795.           errorCount = 0;% F. U! @( |7 Q5 |+ @
  796.           dataCount  = 0;! v- y8 A/ q8 r( I
  797.           code       = CodeNone;
    2 a. h- k. D9 m9 @# N3 f, W
  798.           stage      = StageNone;! I# E1 }3 O# A/ N5 o% N

  799. 0 D5 l" X- r8 H
  800.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)- _# g8 @0 j, @& I4 N
  801.           {' Q2 R) ~. [( j3 y8 y3 `* O- L
  802.             txBuffer[txLength] = CodeCan;) ^# u! m# ]1 [8 u- g+ m
  803.           }7 O( I) ~  f0 l2 ?5 L, v$ C
  804. * v1 _# `6 J$ ?
  805.           write(txBuffer, txLength);
    # s. M5 H$ o) ~  O2 M
  806.           callback(StatusError, NULL, NULL);7 y% v! C4 k* I, Y+ T6 A- t" a" C
  807.         }
    6 c4 g/ |5 B3 [! _( X" F
  808.         else
    ! \: {0 B9 G. g0 t, h7 Q# x
  809.         {
    - v/ z4 V2 `* o# m& y. g
  810.           txBuffer[0] = CodeNak;% S: F' X' g# N# J+ A/ ~0 D4 L+ {2 {/ s
  811.           txLength    = 1;/ R; i: v2 x5 Z' e* V$ J  ]( Q4 Y2 k
  812.           write(txBuffer, txLength);2 D; l1 m' P4 E8 y. G, ~2 Q
  813.         }
    9 x8 x& t& b& Q: L
  814.       }" R# z8 x. D$ O# Z
  815.   _& e+ R7 C4 `: U' [' o9 T
  816.       break;6 m5 _  G/ O  E4 e' R
  817.     }
    1 Y0 S: i4 n0 c" c
  818. % o5 ]8 M# q% X% i( F  k$ \) Y
  819.     case CodeStx:$ Y0 k- \& [! c6 x% I* M
  820.     {
    . f, \: S1 ]: ~# T$ J. F5 Q
  821.       uint16_t crc = ((uint16_t)(rxBuffer[YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - 2]) << 8) |6 C" N0 a" w/ {  ~8 S
  822.                      ((uint16_t)(rxBuffer[YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - 1]) << 0);7 |3 ]  E% c: n8 S) S$ m
  823. + V7 J6 u/ n) H3 x3 h! k; {
  824.       if((rxBuffer[1] == (uint8_t)(dataCount)) && (rxBuffer[2] == (uint8_t)(0xFF - dataCount)) &&5 _, @/ Z8 J% ~- Z/ H6 ]! G
  825.          (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_1K_SIZE)))
    4 r- Y' S9 S, k& n" G  [
  826.       {
    ! F0 o# X1 h8 U3 B% I
  827.         errorCount++;
    & ]  o( y- _5 d# s. E5 T+ k9 O

  828. . K. H; G7 ^3 K: K2 {
  829.         if(errorCount > errorMax)
    , U7 l9 A9 h8 B7 c: A9 `+ J
  830.         {4 \$ F! i4 v6 u" O' |  N
  831.           timeCount  = 0;
    . B8 I' v/ ?$ [9 H8 Z' O' y
  832.           errorCount = 0;5 _- _5 O& l5 J/ ]! }+ `
  833.           dataCount  = 0;
    1 r7 C  D$ Q. j3 P( a6 Y$ V
  834.           code       = CodeNone;
      Y% O$ l0 T. m3 q8 X
  835.           stage      = StageNone;4 R) a, x, }3 \) s0 o0 K
  836. ! W9 H/ }2 Y/ l8 c! D2 U% h3 {
  837.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    8 W, P; ]/ F0 L% m! C
  838.           {
    / B- X2 Q0 I. R
  839.             txBuffer[txLength] = CodeCan;- j' a! o9 A' q$ Z# t& l! u
  840.           }
    7 A- a' _( T' [( {( X
  841. . S4 e6 b; f5 J6 M  ?: M% J3 {
  842.           write(txBuffer, txLength);
    1 C0 a* z+ u8 ^! V2 D: u
  843.           callback(StatusError, NULL, NULL);, G: D& V2 `* s9 k9 L
  844.         }# ]! ~" s! v/ C6 Y7 h7 [0 I
  845.         else2 M# E& q" j4 ~0 {+ q, e+ E
  846.         {
    . [' s) r6 [" F7 D6 t, ~- A
  847.           txBuffer[0] = CodeAck;
    7 E0 i# Q" d) W5 n
  848.           txLength    = 1;6 K. H( [5 q: f9 @9 }6 ~
  849.           write(txBuffer, txLength);
    8 E, F. D! \) Z6 v: ^- ^3 p
  850.         }( q( o5 ?( J7 |5 \* U1 f
  851.       }
    ( T- ]2 t9 U% u$ ]# S
  852.       else if((rxBuffer[1] == (uint8_t)(dataCount + 1)) && (rxBuffer[2] == (uint8_t)(0xFE - dataCount)) &&
    5 o" b8 O* F4 X
  853.               (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_1K_SIZE))). \1 U& q5 f! m- y/ c9 ^, A. V7 [
  854.       {" t) f3 C$ L' Z# S) n
  855.         uint32_t dataLength = YMODEM_PACKET_1K_SIZE;$ i2 O! A. q1 {8 d& |4 j: ]
  856. & d( P$ ]* W: A* l
  857.         if(callback(StatusTransmit, &(rxBuffer[YMODEM_PACKET_HEADER]), &dataLength) == CodeAck)
    ( R' R0 `0 r5 a
  858.         {8 S, z$ L7 u7 Q8 I* i' m  s& w
  859.           timeCount   = 0;
    - F* V% o3 W. `# b# ]. Z1 \6 n
  860.           errorCount  = 0;2 [3 r9 {6 i% \" n
  861.           dataCount   = dataCount + 1;
    ( Z" w& }9 r( n/ n  K* E
  862.           code        = CodeNone;: K3 m  w. ?" \1 [$ E( G* I
  863.           stage       = StageTransmitting;: ?# P1 I, f; N0 i, ?# b; ~
  864.           txBuffer[0] = CodeAck;; d& ]; Y1 X6 s5 _
  865.           txLength    = 1;
    9 t- G8 k0 ~8 ]+ v8 t& `
  866.           write(txBuffer, txLength);
    # h2 g+ m$ y8 A" A0 H) k
  867.         }5 z+ ^# d% P8 H; P& a4 ]9 R$ U# Y- k
  868.         else8 K# `, |/ f$ d* x6 m( L3 n
  869.         {. Y9 B/ B. T$ H" I1 D4 O
  870.           timeCount  = 0;$ ?9 Y2 O' o: G* U& T& l, c
  871.           errorCount = 0;: s# \% E& [) H9 D8 {9 T
  872.           dataCount  = 0;- j5 ?3 e; p( ^# S- F
  873.           code       = CodeNone;/ t" a1 Z$ A- ?# [. ]' u
  874.           stage      = StageNone;* k; E+ j. `' j3 G* _. y
  875. 1 b2 _2 r3 |" ]% L3 m
  876.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    1 m0 V$ C! W/ w: I
  877.           {& V3 `- z) [" F( _8 M
  878.             txBuffer[txLength] = CodeCan;
    " e. S' X1 S( O" {) _
  879.           }$ |8 F: C, y2 g$ N1 I
  880. 3 G  V7 ^( n4 a
  881.           write(txBuffer, txLength);
    & Y0 {+ c) o% Y* h
  882.         }: G! t( j- g4 w' L
  883.       }  i% e$ V8 g/ n1 A. u! R
  884.       else
    7 f3 W- l# N. t8 N. i1 |
  885.       {
    5 Q9 ^: R7 l  g: s+ o: ]: t4 F* z
  886.         errorCount++;
    : U3 u! H) w0 S. P  T% h4 G
  887. , Q7 w' [0 a; E. \5 \  H
  888.         if(errorCount > errorMax)
    ' g- u; F9 M7 }% b
  889.         {
    ; v# Q  Z: }' I
  890.           timeCount  = 0;7 e9 M4 x% X! |
  891.           errorCount = 0;
    + Z2 Z$ H5 B/ D9 D% O( r: \) {/ E. J
  892.           dataCount  = 0;, ^! a) u; W7 D" ~) C: i3 M
  893.           code       = CodeNone;3 n, r5 k' \+ j; x- k9 F
  894.           stage      = StageNone;: ]% X1 k5 W7 t+ b  v

  895. / `" {; H6 F2 J0 }. k
  896.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    ; M& O* t% b5 I+ M
  897.           {, c0 }2 Q+ t5 d$ G; k8 V8 ]
  898.             txBuffer[txLength] = CodeCan;: v9 K7 K' D  i& e" D4 Z
  899.           }9 S8 E7 \! b6 o  C9 n, f# f: H

  900. % h+ J2 {$ C8 p! Q: \% l3 Q; |
  901.           write(txBuffer, txLength);$ D" a$ q) j: i' S* @/ J' ^' ^
  902.           callback(StatusError, NULL, NULL);
    6 j, Z8 S. x9 Q" e; z  @4 @
  903.         }
    8 e8 a/ ?* |2 k9 y+ Z& c
  904.         else& K1 k* a  b/ M) v' m
  905.         {
    3 |4 e5 G7 K& A3 X0 i* I
  906.           txBuffer[0] = CodeNak;9 L- A2 ]* I# U% L
  907.           txLength    = 1;) H% r0 a( i4 Q
  908.           write(txBuffer, txLength);) f5 Z$ ?3 l1 }' P% z3 d; |: n
  909.         }+ ^6 W: j0 O6 f3 y* I% w
  910.       }7 t( N. b( _5 v2 U/ F5 n+ }' p

  911. % Q; G: K7 z2 ~- ~6 H: A
  912.       break;) v+ G5 n. `- ?! e1 I: N' [2 w
  913.     }8 l7 |) M% V! _6 P
  914. ( G' t1 C3 Z/ o0 E( E1 w
  915.     case CodeEot:; t/ w2 o1 b, L+ B
  916.     {- {8 g9 ]* y% c( u# G
  917.       timeCount   = 0;+ z' @2 p, p+ `9 F4 }+ _
  918.       errorCount  = 0;: ^& Z/ w0 A5 N
  919.       dataCount   = 0;3 N. \4 Z( }8 `9 U- \9 D2 x$ F
  920.       code        = CodeNone;
    " Y2 T: _( C& L& c% {# a- J. R# h! F
  921.       stage       = StageFinishing;
    # k: i4 f* ^6 i# S4 j0 p
  922.       txBuffer[0] = CodeNak;
    4 |9 w0 x1 ~) y8 ^1 Y
  923.       txLength    = 1;
    1 K  _! Q) _6 a, R% }% |
  924.       write(txBuffer, txLength);: H' n9 S. \1 L5 U  y- \1 P
  925. 8 I6 H, o+ V+ ?7 C2 D
  926.       break;
    8 F2 M5 l" b2 ?8 D+ y+ l  r
  927.     }; y: T8 T0 {$ a! S1 H

  928. , @. n3 l6 E) q0 W9 |; y
  929.     case CodeA1:
    % {( g' e/ i9 P, s* ]: L. E. v
  930.     case CodeA2:
    . R( t- Q$ Y1 J
  931.     case CodeCan:
    + K% S% m) F  e0 ~8 T2 `1 E
  932.     {
    7 d% T+ E- r9 v* Y
  933.       timeCount  = 0;! u. J% o; ]; |! v, B1 I4 }
  934.       errorCount = 0;3 F! Q! h5 i0 @% G( {; t
  935.       dataCount  = 0;' e! v# z' ?" |( y0 s
  936.       code       = CodeNone;
    - r6 }3 O+ D3 D
  937.       stage      = StageNone;
    % c& L! t7 w% s. X" k
  938.       callback(StatusAbort, NULL, NULL);/ W0 M7 d" j0 i% R% Z3 a2 m( N, k) Q8 ~
  939. . V  i% }  j! l2 ^
  940.       break;6 R/ |+ U2 j+ o& U+ j
  941.     }
    % L, I; e. l, }) p+ E2 T
  942. 6 A/ ?- c7 k! y' O# x# e% F
  943.     default:# U+ J7 S9 M( U& A- i
  944.     {( G7 t" W6 m' }- @# z
  945.       timeCount++;
    4 }' S0 @9 J0 W6 h4 @/ z
  946. 1 N/ O9 h' c  }; w
  947.       if((timeCount / (timeDivide + 1)) > timeMax)! g7 B5 f3 F& [
  948.       {
    ; ?% I1 ~) r% r% Q
  949.         timeCount  = 0;
    7 B. U" _9 @5 V1 R
  950.         errorCount = 0;5 P1 |. O9 o- ?$ i5 Z# e( A3 r
  951.         dataCount  = 0;
    . F2 s2 N5 ~) W( n
  952.         code       = CodeNone;
    7 S% u# f, Q+ e3 h/ n8 r% ]
  953.         stage      = StageNone;* E2 B5 I. g' Y: E& i

  954. 5 q% D) l# M: d9 U$ p. L
  955.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)6 _& S# N' H$ p: P/ e- t! q
  956.         {' ~+ `3 G0 y' {2 W+ ?4 u) r
  957.           txBuffer[txLength] = CodeCan;
    9 [' l& B0 I& q
  958.         }$ A$ \2 T/ r( A% R

  959. . E0 X- O/ N& R& i: j+ m
  960.         write(txBuffer, txLength);
    ! k& I  ?& M* O- |$ M+ C
  961.         callback(StatusError, NULL, NULL);" B  T! R: X/ W) g& A* H
  962.       }
    # z+ ~* V$ a- o5 j3 {# T! D
  963.       else if((timeCount % (timeDivide + 1)) == 0)
    & k8 `0 t# u# v4 L- ?9 @" j# n
  964.       {
    8 O: m: R) r. I
  965.         txBuffer[0] = CodeNak;$ u: P  u8 r% D& c* y0 n
  966.         txLength    = 1;
    & S' F4 H3 q! H; S8 \% f$ G, ?$ K0 V
  967.         write(txBuffer, txLength);
    ' V: G6 U/ I- |% Q
  968.       }- i" J4 [2 I( q- @2 M
  969.     }
    1 l$ f  v5 @8 R: d5 ]3 {  B
  970.   }" Q; m; Q! I' ]
  971. }
    2 B$ I) [  i! s+ T& s  u

  972. & r% g- K0 z/ J+ R8 e% N% q2 o
  973. /**0 p9 X  ?2 r3 r( \6 c& n2 H0 s
  974.   * @brief  Receive finishing stage.
    9 }1 k6 t- f3 I. v2 x
  975.   * @param  None.
    ' I0 u. X! K0 F: `: G- T
  976.   * @return None.( V. c: S* a: D, Y0 W
  977.   */; }* t1 N2 z  J8 o3 W% ?; y( W
  978. void Ymodem::receiveStageFinishing()& D6 P+ Z6 j5 A) n) }
  979. {: j( o8 S: D0 Z2 [2 G3 ~
  980.   switch(receivePacket())
    / o) W8 r" ]+ X5 V- D  c
  981.   {
    ' p4 X3 T0 ?4 B- S
  982.     case CodeEot:' ~" X+ v# e, H1 h
  983.     {
      C; i* l3 t2 N8 `3 ]  U8 U
  984.       timeCount   = 0;( z; ]/ w. Y4 ~. K  l% m: y
  985.       errorCount  = 0;
    . |. {: K7 O, p! ~- C
  986.       dataCount   = 0;
    ! O) R- F! n9 F1 d. [# {
  987.       code        = CodeNone;
    ' @8 Y& Q  \3 x3 N1 ^
  988.       stage       = StageFinished;& ]/ M) {' x0 F  v- M2 K: ]
  989.       txBuffer[0] = CodeAck;
    $ j( `/ F) }; q( i: m) Z
  990.       txBuffer[1] = CodeC;, J) x7 V0 }) Z" p
  991.       txLength    = 2;, w+ U0 F$ U; O" o
  992.       write(txBuffer, txLength);
    8 \( D2 U7 [/ A' ^1 J" B
  993. 3 A, f, G- w; t+ E3 x
  994.       break;+ _7 r2 e. u) g+ [& @
  995.     }
    0 L: a  {0 M6 |8 q& ]
  996. 4 z, s* f0 X+ I
  997.     case CodeA1:
    , j8 G! ~. y1 S+ [, j7 f3 ?
  998.     case CodeA2:
    - y) Y+ L+ c2 s, ]; B, j, ~
  999.     case CodeCan:
    / ~( O  |- Z* s4 h7 `
  1000.     {6 t$ A! o" H& d6 O4 t" h1 G
  1001.       timeCount  = 0;, U& B/ g9 K" ]+ L# s
  1002.       errorCount = 0;  @; A$ O' k* C% b1 O7 ~; t& \1 y
  1003.       dataCount  = 0;
    1 S" A; f8 E( @* M) u( q. q  l
  1004.       code       = CodeNone;
    5 R$ P) x; v0 D! O7 {5 A' g
  1005.       stage      = StageNone;
    % t' f1 h% T% d! R! p) F9 x
  1006.       callback(StatusAbort, NULL, NULL);
    & E, U9 T: Z! x, a5 @+ y$ C
  1007. ( S% `0 \  b6 V7 A/ y$ [; F) l
  1008.       break;
    . z1 f& y7 ^9 i. x. n+ J
  1009.     }) ~& l  P3 Y) [& D
  1010. 8 Y4 W5 W1 t( f& m3 h
  1011.     default:
    6 {9 M7 N, V3 D
  1012.     {
    # ]- r0 {8 r2 x9 |3 V
  1013.       timeCount++;3 Z8 E% w: m1 S. i; t3 N" v7 d
  1014. , k0 e( _1 B" d' _" D% H
  1015.       if((timeCount / (timeDivide + 1)) > timeMax)
    ; [/ \' w8 D: Z$ G! g2 l: q% S
  1016.       {6 t+ {( \0 g, H. ~- z- V
  1017.         timeCount  = 0;
    ) F' ?& X& v6 ]8 ^* v* ?1 y
  1018.         errorCount = 0;
    6 ^1 F5 k7 [9 b, A* P
  1019.         dataCount  = 0;
    4 ]' b' P: g, [* Y3 }7 Q; J0 {; c% ~# b
  1020.         code       = CodeNone;
    " `, T7 r/ K& [
  1021.         stage      = StageNone;
    9 N( V- g/ v5 w! E, g
  1022. - M9 v6 f- R+ w1 V1 @# f
  1023.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)0 ?9 r. K. g8 u* \; D
  1024.         {; h7 N5 o- h5 G. Y1 T
  1025.           txBuffer[txLength] = CodeCan;
    & ^) s' H% @$ r
  1026.         }5 w1 t, Y7 z$ y9 F0 C6 q" \: `- t" e( H
  1027. ; b: H2 `* {' k3 N
  1028.         write(txBuffer, txLength);& T5 W6 `8 M6 Y/ g0 z& n
  1029.         callback(StatusError, NULL, NULL);5 U1 `5 m5 R! x6 y
  1030.       }
    4 F& s' n0 Y9 _4 K2 o
  1031.       else if((timeCount % (timeDivide + 1)) == 0)
    1 E: B: a3 d+ g; g. z/ ]
  1032.       {6 A  f1 ^7 [3 \  H
  1033.         txBuffer[0] = CodeNak;
    * [& f- q' l: Y! C
  1034.         txLength    = 1;. u1 ]0 ~4 }3 a2 a  Q8 J5 [0 e
  1035.         write(txBuffer, txLength);
    1 {6 F. Q! A. @/ w) e4 @
  1036.       }, S- [3 _, }- y( T& K+ b
  1037.     }
    $ r- ^; J+ e9 z( ]
  1038.   }# f) h$ _8 O" v. M$ y
  1039. }
    $ e- T2 _- H7 S
  1040. , J+ v" z7 W8 m7 p5 p
  1041. /**% V8 b" v! O& ]7 H3 Y% @5 ?# ?$ g, \
  1042.   * @brief  Receive finished stage." h) J, V. k& [2 n9 y8 H. K! i
  1043.   * @param  None.# k) m7 o3 x$ t$ E
  1044.   * @return None.
    0 F8 a6 v2 ^" {, A! l: ]  L) B; H! ?
  1045.   */
    0 A  G, s9 Z6 \
  1046. void Ymodem::receiveStageFinished()
    " u8 R0 A! [& r
  1047. {
    : Q$ f- m% A4 I8 k- S
  1048.   switch(receivePacket())4 h7 w' Y: t. a6 {( n
  1049.   {% [' L* O- n7 \' D0 P
  1050.     case CodeSoh:! D5 W- G. M) |6 e% x/ a% p
  1051.     {( e. x- `# w. f$ D" R
  1052.       uint16_t crc = ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 2]) << 8) |7 z+ Q! p" r0 `7 Q) [( Q. f8 {
  1053.                      ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 1]) << 0);6 p% r6 r7 ]* @# Q7 |

  1054. ; e: q2 F* j+ A
  1055.       if((rxBuffer[1] == 0x00) && (rxBuffer[2] == 0xFF) &&1 P1 Y. K3 T# L' T1 ~" f
  1056.          (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_SIZE)))
    ! }* @  l* C; |/ h
  1057.       {
    6 G+ a6 @& a" F( u
  1058.         timeCount   = 0;% ^' h1 @; J+ R3 }
  1059.         errorCount  = 0;
    * I) d# g3 G7 ]# n9 \
  1060.         dataCount   = 0;" ~( O9 N% \- p
  1061.         code        = CodeNone;
    4 f6 p$ D7 {& [3 s' u; x
  1062.         stage       = StageNone;
    0 O6 k# a" Z6 U
  1063.         txBuffer[0] = CodeAck;
    ( T1 m" v7 j, {' ^8 X) a8 C0 m0 n
  1064.         txLength    = 1;
    3 A( B6 b$ r8 {9 ?5 b
  1065.         write(txBuffer, txLength);/ X% O* d2 v, m+ ?: Y' S1 F- k
  1066.         callback(StatusFinish, NULL, NULL);& p6 ?8 J, ]1 M
  1067.       }
    6 ]) T+ y- t  o, U/ R# [
  1068.       else4 o8 ]' y' S8 s# K( [
  1069.       {+ C2 ]* R$ S2 G0 o5 b
  1070.         errorCount++;
    / b; v- N+ Q) I. N7 P6 P

  1071. , t* @+ J0 j; ?$ r8 L
  1072.         if(errorCount > errorMax)
    0 E$ q7 ]$ e  ?2 M4 j
  1073.         {
    # Y9 m$ F/ l/ D* B: X
  1074.           timeCount  = 0;
    1 b, |' r! p6 N, a# u# d1 x
  1075.           errorCount = 0;! k% J2 Y) _  U( Z# \0 X6 ?% O+ k, j
  1076.           dataCount  = 0;
    " _& Q( V1 L: p& H- |& D
  1077.           code       = CodeNone;
    ! R/ h+ N5 T) W
  1078.           stage      = StageNone;
    6 s' }3 k$ a% d8 e# F
  1079. ! S/ i1 x: ~9 f
  1080.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    3 |7 v3 z+ l+ [; s6 l2 H1 a: i% f
  1081.           {
    / a! i6 E* p# T9 }. ]) c
  1082.             txBuffer[txLength] = CodeCan;$ O, W3 G; C; J5 w4 X5 O
  1083.           }
    6 ~/ j' m5 q( n1 ]( _$ _
  1084. 8 v; i2 o2 m: G1 E* z" V9 f
  1085.           write(txBuffer, txLength);
    2 o4 I5 {+ g3 M$ v1 ^/ z
  1086.           callback(StatusError, NULL, NULL);/ Z! k, c, Z. i
  1087.         }: ]* |; ?+ r" Y: @5 E
  1088.         else8 u: G" f2 Z; C3 l
  1089.         {8 ?0 x) R/ m/ Z: p
  1090.           txBuffer[0] = CodeNak;
    4 P7 S* b# F9 ~8 N1 U8 J
  1091.           txLength    = 1;0 O4 ~( G2 m! m. c9 d
  1092.           write(txBuffer, txLength);7 K% X& ]$ F" r
  1093.         }7 q! q1 v7 e$ R: n( b4 G
  1094.       }' j+ q# n5 o  M( f* A7 F+ J, S/ t

  1095. ' E; Q4 E1 |7 f" F' n
  1096.       break;, J# D' a& Y/ V
  1097.     }5 L; k9 Y7 z7 z) m# a# O6 n) K
  1098. # L, d* W: {( `& ]% T
  1099.     case CodeEot:
    5 q' l+ O5 r9 [- c; ~0 b
  1100.     {
    + ^! v# q3 s8 B6 D
  1101.       errorCount++;+ A  P+ f3 _# I

  1102. 2 Q  e; U$ `! M
  1103.       if(errorCount > errorMax)% l! L& r3 ]( u- z
  1104.       {( k1 R8 }% P: T$ L
  1105.         timeCount  = 0;8 o6 o8 @( M2 V! l  o9 @: M" `
  1106.         errorCount = 0;
    5 _6 {) S3 {( X3 f7 a
  1107.         dataCount  = 0;
    ' x, S- X9 y+ g+ y+ E4 @5 U# E1 `
  1108.         code       = CodeNone;' m# L+ p8 H# d5 a6 s' K; q" K3 @
  1109.         stage      = StageNone;
    ! L7 |- F7 i0 ^" l# q2 \

  1110. & n* H( m$ }/ u/ p: C: B* S
  1111.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    & A0 ?) z1 @) F& h, `3 t8 p+ B) G! |
  1112.         {
    8 m4 s  v% O+ G4 _' D% e
  1113.           txBuffer[txLength] = CodeCan;
    1 V* _; S6 ~5 H$ e3 ]
  1114.         }
    - Q* @( M- w' U. j4 N
  1115. 8 {2 J4 M0 t4 Y! y: J( T/ p
  1116.         write(txBuffer, txLength);
    $ I8 s# r; G0 P2 y* }# z
  1117.         callback(StatusError, NULL, NULL);
    - E7 e  [. Z/ r$ ?5 r6 g8 e
  1118.       }5 ?0 q# A3 K% q- B3 b8 P
  1119.       else
    9 Z- P: [9 ?+ Y
  1120.       {8 E+ @6 S7 e2 i2 K2 S
  1121.         txBuffer[0] = CodeAck;
    1 A; R1 i$ p8 e" @# j
  1122.         txBuffer[1] = CodeC;
    : h2 N  }" G  M' c0 N% K
  1123.         txLength    = 2;
    + ^, S& e2 d/ z% _6 G% x8 F
  1124.         write(txBuffer, txLength);
    , M7 ?: o" U) a( \& Z
  1125.       }$ f1 h0 t% q2 L8 w1 f. n3 J7 o

  1126. % y" u* h: O) h2 F; G2 f. u
  1127.       break;: V, T4 i) e" N
  1128.     }
    6 ~  k& D6 J: Q& C: v( J

  1129. - ^: Y+ ]7 K7 \3 i, o0 D
  1130.     case CodeA1:6 p2 [( D7 I$ ^: e2 N
  1131.     case CodeA2:- y0 \! B' C8 i% Y! E) R
  1132.     case CodeCan:
    7 N' O9 M) ?# o
  1133.     {
    5 a4 M6 O8 `" P: h  k
  1134.       timeCount  = 0;
    / N# V- ?* B' c. i" L7 Q
  1135.       errorCount = 0;+ T9 `/ F, u2 B
  1136.       dataCount  = 0;% ?& h! X* I1 j- \3 \: J/ d
  1137.       code       = CodeNone;
    : O6 t; [8 @3 q! B/ b6 @* x+ [+ o
  1138.       stage      = StageNone;
    & K2 F+ e8 D# ?" K
  1139.       callback(StatusAbort, NULL, NULL);- b  u) T, i$ Z

  1140. 7 ?" J% n6 k. L9 Z* u& {" i
  1141.       break;2 V! ^  j& g7 L8 N
  1142.     }
    1 |! k0 g/ V6 w. T7 V

  1143. 1 c- }2 |7 V) z( A0 w8 H: t
  1144.     default:& @( m# N1 v& X1 ~! I
  1145.     {9 T5 v1 R3 h* w, u
  1146.       timeCount++;9 o' h7 j( O+ J4 w

  1147. + i0 G, u5 a- A* c- ~+ |
  1148.       if((timeCount / (timeDivide + 1)) > timeMax)' F  _( k, l' T- r' o3 I9 ]0 m8 I  l$ o
  1149.       {
    2 s* z/ r' L. R+ X* z! h( l/ S' {; P
  1150.         timeCount  = 0;% D5 R  r( j" D4 e) L8 w
  1151.         errorCount = 0;, C% C) E+ |* z. k/ \+ S
  1152.         dataCount  = 0;
    3 N& O* Z3 r% l
  1153.         code       = CodeNone;
    3 g7 {- \1 e8 M2 h( ~; C
  1154.         stage      = StageNone;3 X7 G! C6 `( W$ i4 h* y

  1155. ' n' K- F$ ?4 d$ X( ]
  1156.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)3 L  F( q4 M6 J' B
  1157.         {
    / R/ {! ~, x* g0 _/ p5 ?
  1158.           txBuffer[txLength] = CodeCan;) i# @" {4 ?* i
  1159.         }
    * G6 R5 `9 I0 m6 y  @2 z6 E2 O
  1160. $ i6 `3 F- z6 z* F1 k% m) O
  1161.         write(txBuffer, txLength);* o6 i2 [3 p& X; k7 O6 J. [1 n
  1162.         callback(StatusError, NULL, NULL);, b2 |, }1 i3 a/ K: T
  1163.       }
    - W& U% @/ {/ R+ c& d; L6 Q
  1164.       else if((timeCount % (timeDivide + 1)) == 0)
    $ ~& ?6 f+ @7 z' z* \. Z! W
  1165.       {+ F# L9 B; z  p- i1 a, B6 H
  1166.         txBuffer[0] = CodeNak;
    9 G+ \( v& Q+ h) R
  1167.         txLength    = 1;7 m5 E3 T9 d/ s8 @* u; }+ y% E
  1168.         write(txBuffer, txLength);1 k6 v% G" Q& L# O8 U2 R# `
  1169.       }
    * z; u) U) p( y: K- G7 @1 I$ ~' T, q
  1170.     }
    ( h( R9 B4 N/ i% ^5 N/ L0 o
  1171.   }2 \( `: u' `' A
  1172. }) H* @, z1 C+ R4 h% \! p) G1 I' {5 _& |

  1173. * f& d/ Y# b" }9 K
  1174. /**8 u' t( r+ O+ i/ g4 f
  1175.   * @brief  Transmit none stage.% I4 Z- l# x9 M6 k; V
  1176.   * @param  None.0 b  _( Z9 V4 ]
  1177.   * @return None., r" E3 |5 a, T! a
  1178.   */
    - a- p. C$ d6 r& n) K' Z
  1179. void Ymodem::transmitStageNone()) R$ F. b5 i( v  O
  1180. {. p5 r! A$ ^2 t  i: D
  1181.   timeCount   = 0;
    ; ~5 U9 n" e* s
  1182.   errorCount  = 0;
    % ~) g# m* m% f
  1183.   dataCount   = 0;; A: i( L! u( `
  1184.   code        = CodeNone;
    3 O& \2 v. T4 Z1 e
  1185.   stage       = StageEstablishing;/ ~, t: z' k8 X3 G' d& I# }
  1186. }
    + t' L2 j# `* f0 n
  1187. # H2 s# n; `2 H' v- u4 V# _
  1188. /**
    ) F6 {% `1 c" D1 a5 T7 S2 q. `
  1189.   * @brief  Transmit establishing stage.
    " _* `6 ]5 Y3 e# V
  1190.   * @param  None.9 W0 r# w2 _3 `+ @9 M' }
  1191.   * @return None.* W6 i2 k6 C! ]0 V$ T& @1 E
  1192.   */
    3 l" D: e$ c& ^3 M+ ]
  1193. void Ymodem::transmitStageEstablishing()
    1 v, |  M7 N6 G) ]
  1194. {; o2 F1 w% r2 v3 _6 r2 f* V
  1195.   switch(receivePacket())3 X# y! D) H" r
  1196.   {
    & A, @+ N; N0 z1 a
  1197.     case CodeC:
    ; I* k# {# [7 t! s, @" V+ p
  1198.     {) t9 T& u% a2 S0 r4 g& L- [
  1199.       memset(&(txBuffer[YMODEM_PACKET_HEADER]), NULL, YMODEM_PACKET_SIZE);
    8 X4 [7 v; z! ?; I' Z, B$ h

  1200. : b3 R: ~7 q7 Y( N5 m% l! B: V
  1201.       if(callback(StatusEstablish, &(txBuffer[YMODEM_PACKET_HEADER]), &(txLength)) == CodeAck)
    8 P5 E1 \& S7 h2 T
  1202.       {
    - B/ u$ A1 r% c6 R. N$ u
  1203.         uint16_t crc = crc16(&(txBuffer[YMODEM_PACKET_HEADER]), txLength);' L0 Z6 T8 g" l6 E5 \) c
  1204. 5 r7 C- ^0 E0 S; H4 i0 k
  1205.         timeCount                                       = 0;1 b$ D7 P* x, A' `+ M- s2 s
  1206.         errorCount                                      = 0;
    / D7 s6 ^7 M+ s# H
  1207.         dataCount                                       = 0;8 Y, k' F- w; C* s* p/ d/ P
  1208.         code                                            = CodeNone;. {& Q- V0 }. R; C/ c+ `
  1209.         stage                                           = StageEstablished;4 u2 _" g" ^5 w. s, `. J
  1210.         txBuffer[0]                                     = CodeSoh;3 u) A1 H7 ?( l$ t  Q( H% L  i
  1211.         txBuffer[1]                                     = 0x00;
    ; x/ `# A9 j" G: e: ~; l
  1212.         txBuffer[2]                                     = 0xFF;
    9 q: G+ W- }& k9 \
  1213.         txBuffer[txLength + YMODEM_PACKET_OVERHEAD - 2] = (uint8_t)(crc >> 8);: r9 {' }2 T+ @0 r
  1214.         txBuffer[txLength + YMODEM_PACKET_OVERHEAD - 1] = (uint8_t)(crc >> 0);0 E5 L7 E+ c; z! ]' p0 i$ I
  1215.         txLength                                        = txLength + YMODEM_PACKET_OVERHEAD;1 }. g2 k7 Z5 Q  e, W8 j
  1216.         write(txBuffer, txLength);
    * u6 S0 l: T& s' n! c' o
  1217.       }
    ' S! b/ v+ Q5 ]; _& g: F
  1218.       else
    9 V  M* |/ c6 P- ?& B+ m0 H
  1219.       {! k8 S8 r3 Z- ?
  1220.         timeCount  = 0;: Z4 z6 l: F4 W  K
  1221.         errorCount = 0;
    - e4 r7 k0 g' n' ~
  1222.         dataCount  = 0;* H9 ~2 D6 g# u& ~$ B) N
  1223.         code       = CodeNone;" T% @' J0 i* L; S4 a  b
  1224.         stage      = StageNone;- Z% v3 c$ T8 u
  1225. 4 M9 t* w' V( m8 d1 X
  1226.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    % m3 c/ s6 K' a- O+ I: y+ ?
  1227.         {
    ' v3 B: k( E) C! K& D
  1228.           txBuffer[txLength] = CodeCan;
    9 s5 @7 O& e2 v( p
  1229.         }/ {1 q; E* F9 r/ @) }- H

  1230. 8 u0 {  f& c1 b
  1231.         write(txBuffer, txLength);! e; D3 `/ a3 N5 b9 M5 U) \
  1232.       }
    * _. E0 g/ X7 O1 i0 [

  1233. * H% ~( y3 K3 P5 C: v
  1234.       break;
    + H2 k$ Y# ~" \7 d
  1235.     }" _9 B! l5 u! H: X
  1236. : z% T- e6 N) Y# q( N
  1237.     case CodeA1:. ~2 o4 ~; S6 D
  1238.     case CodeA2:" j7 c+ {3 N8 e2 Q4 }6 X1 d7 _
  1239.     case CodeCan:
    5 W8 u; z3 F9 |- e$ Y5 K  O: D
  1240.     {- @1 Z% d/ Q- L* [% V4 `
  1241.       timeCount  = 0;+ Z8 U+ f' e1 V" F. m
  1242.       errorCount = 0;
    - B  Q5 X$ T8 i8 p
  1243.       dataCount  = 0;
    $ q: y; v7 h% T3 M  j
  1244.       code       = CodeNone;6 w  M& m8 R6 Z
  1245.       stage      = StageNone;! G2 X3 C% `9 l, v5 |4 E
  1246.       callback(StatusAbort, NULL, NULL);
    4 z  Y) _" N$ M6 e0 K3 A5 @

  1247. & T4 c. @" R. Y' F9 _- p
  1248.       break;' r% v3 W* g) g2 R0 D  J% s
  1249.     }
    & s. a/ \9 N: a, c0 B
  1250. & b9 N' w3 n9 p
  1251.     default:
    ! a$ U' W' R) ~- A" ]2 {
  1252.     {
    ( L7 ~- [+ |2 z, l- C2 P! p$ Z
  1253.       timeCount++;% L/ b. z! R( i& U. E4 X, F3 f

  1254. 4 n# O; J6 k) i3 Z: q* v! f2 h
  1255.       if((timeCount / (timeDivide + 1)) > timeMax)
    7 b( K( I5 Z( o/ E0 Q( @
  1256.       {5 p0 R; o9 K( [' f( B5 i* g
  1257.         timeCount  = 0;
    2 G3 D+ n; U4 |- x% u( ~
  1258.         errorCount = 0;
    ! I, n( N& D, I! m0 S9 @3 y. m1 b
  1259.         dataCount  = 0;3 ?  ?7 o$ x- Q9 v& {( V- _! x
  1260.         code       = CodeNone;* Q8 J7 r2 k- T  x$ V  R* x4 Q
  1261.         stage      = StageNone;
    4 A& g) \1 o) H6 @
  1262. ) I, n9 E7 \- h4 \. v: l
  1263.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    1 r3 s% i& i" ?  ]3 @$ C
  1264.         {* x+ i, Q. w) O9 y7 K
  1265.           txBuffer[txLength] = CodeCan;1 I: u7 N4 }% k
  1266.         }$ h. L  ^4 V$ k! `; `% B

  1267. 5 ~! j* t  _; H$ t
  1268.         write(txBuffer, txLength);
    : S3 g" k1 S0 ], R7 p5 c
  1269.         callback(StatusTimeout, NULL, NULL);1 W# o2 w5 j8 s7 S' e& z# W4 {
  1270.       }! N' \3 M8 E3 H. V
  1271.     }
    ) G' J. e) E( D
  1272.   }0 r9 J9 d+ ^; Q0 W
  1273. }
    * U8 \9 G: o7 J5 _  f

  1274. / X) h5 e9 `0 P* A' X
  1275. /**
    8 U! Y$ E/ ]0 n0 R% T
  1276.   * @brief  Transmit established stage.
    0 W3 b. L7 i2 T7 R! a
  1277.   * @param  None.
    2 }1 d) U4 c' y. z* X6 L0 y: \" r% G
  1278.   * @return None.. K' n: }: \( u1 O. l/ _# e4 [
  1279.   */
    1 H% h+ v8 ?& C* Z2 w
  1280. void Ymodem::transmitStageEstablished(); z' H$ e# A# D. W# f2 E& E
  1281. {
    : B! F  t. e) o: V! j) R+ l
  1282.   switch(receivePacket())8 ^/ {( h3 ]9 H  v0 @/ V
  1283.   {8 y/ H: K/ V! H: A2 I2 ^
  1284.     case CodeNak:2 H. b! V1 k* L9 O% ~, K8 \/ S
  1285.     {- Y; F: c  q3 J/ F
  1286.       errorCount++;# \) s! z( C: E1 V% B# a6 p
  1287. ' p9 r( b: ^7 D; j9 b3 x8 E
  1288.       if(errorCount > errorMax)! h$ S8 c$ R5 p7 a4 @$ I: h# b
  1289.       {
    - [& U/ w/ O, a7 W7 R; H- j6 _
  1290.         timeCount  = 0;
    # X  d- R0 E+ e1 O; X
  1291.         errorCount = 0;
    ( L, v/ d0 {) T
  1292.         dataCount  = 0;( V7 [6 |; J3 Z1 x& L+ ^
  1293.         code       = CodeNone;% D* z/ c. ]/ S8 e8 Y* T' o
  1294.         stage      = StageNone;4 ?6 A3 ?+ J+ |( Z( f1 x

  1295. 1 X% K2 Y9 E+ |* i1 d
  1296.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)! N( D) `; `% c+ l) W5 r
  1297.         {
    % q; c. N% J. `3 W5 h: u" a
  1298.           txBuffer[txLength] = CodeCan;
    5 ^- |3 b- x. h" o: f
  1299.         }6 z$ z" B7 l) o8 f! }

  1300. ; ?3 k6 [; r  \& |
  1301.         write(txBuffer, txLength);, j' y- W2 E; ?4 `
  1302.         callback(StatusError, NULL, NULL);
    / k9 B4 l# V/ }* P( m, \3 @& _
  1303.       }% n6 D- J# ^5 f/ ~" I8 }6 T7 e
  1304.       else
    5 p' f& l. v4 B/ g/ t
  1305.       {
    8 u) V$ V( t0 X" n  Y3 x" h
  1306.         write(txBuffer, txLength);& T2 \* i; F2 j9 r# \5 h. D
  1307.       }& x9 ]5 T4 O" a9 `4 x8 {
  1308.   Y; \7 ~& `8 V! O
  1309.       break;
    4 N( y% Y7 i8 N4 r7 @4 K4 q% b
  1310.     }
    ) D4 c* J  o* ~; a2 Q

  1311.   f$ b/ B' K8 X. ]' t, Y/ N. d2 A
  1312.     case CodeC:3 V5 O5 E$ B8 P9 e% j* b8 u% _& m$ |  |
  1313.     {
    6 N: T4 h$ \, P3 Y
  1314.       errorCount++;
    0 b$ ?2 J& G  I# |" ]! n9 _

  1315. ) p3 Q4 [0 F; E8 O, X0 E2 y
  1316.       if(errorCount > errorMax)
    6 E, l! i3 q9 `7 S& t/ C% r; g
  1317.       {
    ' C" D; {& O4 ]
  1318.         timeCount  = 0;
    & r' A6 Y7 a( X1 V! m7 I7 l
  1319.         errorCount = 0;
    0 f( |  J7 R7 {+ t( R
  1320.         dataCount  = 0;
    6 o! w# _6 F* W. }
  1321.         code       = CodeNone;6 `$ r# ?5 i+ d7 s: j
  1322.         stage      = StageNone;
    2 Y8 H7 g( F: w  ~9 T9 A- ~
  1323. , J1 V6 I, E9 J5 X7 U
  1324.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    # k  t5 q* Z8 j  C( S) R8 _
  1325.         {; _- K$ S2 [: m
  1326.           txBuffer[txLength] = CodeCan;
    , n( z/ B( `" Z" v* a
  1327.         }
    3 b: [! ?: e, ]! C' d& t% I
  1328. ' h% `! L  u4 L" \7 p6 ~. ?
  1329.         write(txBuffer, txLength);
    7 f4 Y$ ~3 L# k4 u
  1330.         callback(StatusError, NULL, NULL);
    % ?+ l2 l% o' p# L
  1331.       }4 C! o" S6 g, Q% N7 V
  1332.       else0 [5 p3 h! _* k0 A, \% T, ]
  1333.       {
    - ?$ u8 ~; D1 `0 J; v/ J
  1334.         timeCount  = 0;
    ) q9 B# |8 U: e( |/ M4 K
  1335.         errorCount = 0;
    $ W0 Z3 a7 _+ \8 v
  1336.         dataCount  = dataCount;! s+ U' `' L# {) m) i+ z$ {
  1337.         code       = CodeNone;, c; m5 [' m5 M% g* D6 o& R# g
  1338.         stage      = (Stage)(stage + dataCount);
    3 L' v- L! N2 \4 E- D- ?& D7 n! I
  1339.         write(txBuffer, txLength);
    5 h; [! R- y3 t$ |5 c
  1340.       }! O3 |8 d$ C; L, Y9 a' ?' D

  1341. 9 q2 F1 x7 E; Q$ Q# W$ R, p
  1342.       break;
    % S1 L: b& T2 m& d! q
  1343.     }3 _3 q1 W1 L. q

  1344. 1 d6 U2 v8 Z4 J% f! w; F5 S: \
  1345.     case CodeAck:" [4 E% K9 r/ T! s* Y' K& o
  1346.     {- p4 m% Q( Y" p6 }9 W% h/ Q
  1347.       memset(&(txBuffer[YMODEM_PACKET_HEADER]), NULL, YMODEM_PACKET_1K_SIZE);
    / D1 o+ I9 T6 r! m
  1348. % @1 I8 U% L- `* B! i
  1349.       switch(callback(StatusTransmit, &(txBuffer[YMODEM_PACKET_HEADER]), &(txLength)))
    $ W( ?' p- [: w; }7 I
  1350.       {
    / y, x" F) ]; P! ]3 G" t: j
  1351.         case CodeAck:
    7 c/ x/ \4 i' t" X: i* L; P
  1352.         {- s4 _6 T' u/ }
  1353.           uint16_t crc = crc16(&(txBuffer[YMODEM_PACKET_HEADER]), txLength);
    / Q0 G) I# P2 Q5 W
  1354. 3 I% u6 @4 J$ W. }( x5 B! E' _
  1355.           timeCount                                       = 0;7 z! |% @) U. s9 e
  1356.           errorCount                                      = 0;
    8 o3 B+ ^4 r; r! ^) P
  1357.           dataCount                                       = 1;
    ; P+ w9 z9 i3 s& h( X5 i
  1358.           code                                            = CodeNone;
    ( N+ Y* p2 L& s
  1359.           stage                                           = StageEstablished;
    3 ?1 {/ [, y. D) j" g1 Q
  1360.           txBuffer[0]                                     = txLength > YMODEM_PACKET_SIZE ? CodeStx : CodeSoh;. r0 C: C5 O" O
  1361.           txBuffer[1]                                     = 0x01;
    4 w% [* A9 l, }1 N- S
  1362.           txBuffer[2]                                     = 0xFE;1 v4 r5 t3 I+ U0 ?" d
  1363.           txBuffer[txLength + YMODEM_PACKET_OVERHEAD - 2] = (uint8_t)(crc >> 8);4 O' w, F3 I7 x5 J) d0 ?9 x
  1364.           txBuffer[txLength + YMODEM_PACKET_OVERHEAD - 1] = (uint8_t)(crc >> 0);
    0 p$ Z0 ~% W. ]" n7 j7 r
  1365.           txLength                                        = txLength + YMODEM_PACKET_OVERHEAD;! @2 E! B7 Z+ V$ J( z$ }# a

  1366. ; n2 I* v9 a* n; ~
  1367.           break;
    7 C  @& z- w. \5 D$ X- I. T+ R0 [
  1368.         }
    / V9 i% l% k9 F$ ^. v5 t5 V
  1369.   F& j' k; B7 a
  1370.         case CodeEot:4 }: D9 f7 K( }. \
  1371.         {! Z4 E1 ], J; I
  1372.           timeCount   = 0;
    ' x, K4 {* Q. e! K
  1373.           errorCount  = 0;8 O. Y$ K$ U+ i: t
  1374.           dataCount   = 2;# `3 W: ?  o' @& S7 C: e& Z# R
  1375.           code        = CodeNone;
    - ^; h( e$ \# t+ q/ C1 p. l2 k3 E
  1376.           stage       = StageEstablished;
    9 l. I) U9 }( n6 v
  1377.           txBuffer[0] = CodeEot;
    ) q; T5 n' g5 k! e; Q) N4 e
  1378.           txLength    = 1;
    * s, \& |8 p* }% }* R9 }* z
  1379.           write(txBuffer, txLength);" Y! K+ @4 h% M, `* d
  1380. 0 b! F; ~2 m7 K  C6 Y7 o* Y! T
  1381.           break;
    2 Y& W. @+ O, x
  1382.         }  D" N/ Q4 }/ s6 ^2 Q9 I8 D7 Y
  1383. ) I1 W, w6 P* Q$ z1 E$ }6 Z
  1384.         default:7 q) C! r: p2 r/ Q1 t+ |4 e7 s) ^
  1385.         {
    2 {9 S; ]6 d) O# D; P
  1386.           timeCount  = 0;9 T% `5 u. @" F8 A( t
  1387.           errorCount = 0;
    * B+ c% v% e0 z# g9 ?8 V' o/ C
  1388.           dataCount  = 0;1 U3 k( T; Z+ m" c! m; G
  1389.           code       = CodeNone;% J1 F, a$ z  Q9 L4 _3 `3 S" U
  1390.           stage      = StageNone;3 f% e* t$ g( Y2 V3 t' \5 B+ {! R9 C

  1391. ( g5 o, R2 Y+ s: t! s
  1392.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++), f) g. h: o4 O( v0 I
  1393.           {5 n, v) I2 g7 W" |9 x# Y/ `
  1394.             txBuffer[txLength] = CodeCan;" {) N6 }+ i/ O8 |/ x7 l
  1395.           }2 h( i+ {3 F/ m$ J

  1396. & \: k; n  J3 ~- i, x& u/ H: B
  1397.           write(txBuffer, txLength);
    & a  X2 j5 l1 a- B
  1398.         }
    2 |0 t# o5 |6 E# O: \- Y6 I
  1399.       }
    # z3 m' W) Q6 G+ d0 h- p3 V

  1400. - `- O5 W5 r- {* b2 T
  1401.       break;2 g' B5 B6 h( @! `6 d4 x
  1402.     }4 f2 w- q, p7 o; i  u

  1403. ; P2 G" {8 \+ w+ A" J* w5 X- ]
  1404.     case CodeA1:
    1 r! p7 \2 y# w1 k9 N) v. E% B
  1405.     case CodeA2:
    $ H' R# r1 t9 u( C  C: m) |6 G
  1406.     case CodeCan:8 j4 K/ i5 G; Y5 R9 U' Q
  1407.     {
    7 _. ^# b% R! O7 E( ?% p
  1408.       timeCount  = 0;, k. {3 ^$ {* d% o0 n
  1409.       errorCount = 0;
    : r7 W, E8 N3 O" Z5 s
  1410.       dataCount  = 0;) q" z) j& E4 r  Q7 R# l1 f6 b
  1411.       code       = CodeNone;' g5 U7 |; g! y- v3 v  W
  1412.       stage      = StageNone;
    2 |& Q4 {' K* K# i, l) @( ?
  1413.       callback(StatusAbort, NULL, NULL);
    / @4 k: D; n) L$ s& ^; T

  1414.   g# c0 `( @- [1 Y& Z9 W: Z* \2 Z0 O
  1415.       break;8 k* w/ k0 R" q" w; ~# ^; m: Q3 K
  1416.     }( p5 E; n/ P) u0 `% @+ @2 y% B1 F

  1417. , k5 X5 g2 Q( r, e0 y# ^# O- C
  1418.     default:8 q& Z$ `/ |/ v3 l1 j
  1419.     {' I3 P$ \! {9 f; s' j+ N
  1420.       timeCount++;
    * Z" p6 x% V8 `  Y0 B3 u

  1421. 8 [4 J( I& u. z" U5 N
  1422.       if((timeCount / (timeDivide + 1)) > timeMax). g; T" R1 |) ~0 W. P. O
  1423.       {
    6 t8 E2 I0 }* a8 A# d
  1424.         timeCount  = 0;
    ; }1 i; f- h% R5 T
  1425.         errorCount = 0;- ?8 E/ M4 j) h; y) [. ]
  1426.         dataCount  = 0;; d' I1 d2 {& f6 J
  1427.         code       = CodeNone;
    7 X5 ~+ R2 ^* [! ^) ^/ B
  1428.         stage      = StageNone;* m! K. R4 i/ m- E

  1429. 0 `- K! s, N2 Y0 g
  1430.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)* U" p  L' O; M4 _) q! o
  1431.         {: r* P/ F3 h% W& O, ^, `
  1432.           txBuffer[txLength] = CodeCan;
    , S* g3 b. ]& U
  1433.         }
    1 v7 S. n( ~( F, g* H" _8 Y  K3 i

  1434. " j# K* ?+ |- M% e+ r- V$ A. e
  1435.         write(txBuffer, txLength);+ s- t+ |4 s/ t( H9 }$ U* r
  1436.         callback(StatusError, NULL, NULL);
    % S  S1 L% p* A, F' D
  1437.       }- d0 U0 _) q, u# v2 |
  1438.       else if((timeCount % (timeDivide + 1)) == 0)  s: C: a' F! i1 h  k' S6 e2 Y, Y
  1439.       {
    ; w3 W7 e5 q3 p; t
  1440.         write(txBuffer, txLength);
    7 e/ E, f- C/ Y. r" S
  1441.       }1 P6 b, C3 T; |1 C+ O! I0 ?
  1442.     }6 ?# w- i6 A, m) ]& z
  1443.   }/ l/ B- R9 C$ p2 N/ p4 f' F
  1444. }
    0 G3 [. q9 I' [4 b) k# [# B) `: ?

  1445. " s6 }6 a2 g; k; c+ h
  1446. /**) }* @+ N5 k& x0 P$ x4 b
  1447.   * @brief  Transmit transmitting stage.8 `5 g9 Y8 U  v( z/ m, e# ~) f: M
  1448.   * @param  None.0 I- v3 ^5 [" b+ X5 c8 j, j
  1449.   * @return None.
    / ^. E" u2 t+ H: d/ G
  1450.   */) }1 H/ @  p. v+ D$ ]/ r0 U
  1451. void Ymodem::transmitStageTransmitting()
    & N$ u- d( g, i, R& X/ m
  1452. {( w1 d! b/ T2 {* ]: o8 _  a
  1453.   switch(receivePacket())
    3 }$ U$ k- P; b
  1454.   {4 q# D  B! p' d8 v8 g8 A  W% @
  1455.     case CodeNak:. e5 U; @- g6 D* {# q: e
  1456.     {- x* I" w: U9 ?8 o0 d% g7 U
  1457.       errorCount++;- }$ F6 i$ H, p/ H( n. G2 A

  1458. 0 U2 X: ~. B+ p+ N( P* i  w
  1459.       if(errorCount > errorMax)
    # v+ ]  O. n6 @
  1460.       {! T% \9 ?' I  }9 J
  1461.         timeCount  = 0;# I6 G1 C+ H5 M8 I9 {$ \& q
  1462.         errorCount = 0;
    : o  o* h: w6 Y
  1463.         dataCount  = 0;% O+ R& W+ R$ V) c# d
  1464.         code       = CodeNone;
    / d, b1 w( ]; Y) e  A- i+ A8 R
  1465.         stage      = StageNone;$ @; S. _7 Q( y3 T9 K$ h/ w6 V
  1466. ( O$ D" j1 ~) r( X3 ]! L: i
  1467.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)5 M- h  P' K+ }
  1468.         {6 ^( V- s& o( I/ C
  1469.           txBuffer[txLength] = CodeCan;
      \( S% r; d# ?9 j7 R
  1470.         }
    0 R" m. j4 z2 T

  1471. 5 W: N( x% }% M3 |! q1 h
  1472.         write(txBuffer, txLength);
    - n) K8 z( I7 v: v3 b0 x8 e
  1473.         callback(StatusError, NULL, NULL);+ t! m9 M$ [% R# d: }
  1474.       }8 E! o, m4 T- A6 ?  E+ P
  1475.       else
    . l3 u( K. r* P% o- \" ]9 [' W
  1476.       {% O  h+ y5 n; }3 X0 c  V% v* X$ p! W
  1477.         write(txBuffer, txLength);: r- l$ \* ^! j' N
  1478.       }
    + C1 J& W% ?# B; g; |- W$ P4 A7 P
  1479. : A- D: q% U# E3 L$ ]
  1480.       break;
    , t1 r  j. H& R3 X
  1481.     }
    " S3 P6 H" d8 v; |" h6 e

  1482. + q  L  A0 t  a
  1483.     case CodeAck:
    1 U( G/ s2 {6 G8 y9 Z5 Y
  1484.     {
    9 S0 M8 {" Q. ~
  1485.       memset(&(txBuffer[YMODEM_PACKET_HEADER]), NULL, YMODEM_PACKET_1K_SIZE);; n9 g# R/ T' X) S
  1486. ; z7 j  T; x0 o7 k2 k- F
  1487.       switch(callback(StatusTransmit, &(txBuffer[YMODEM_PACKET_HEADER]), &(txLength)))
    5 O# [( g& S" |- k
  1488.       {
    & Y9 w  C# Y1 {/ y* I: z- h* G
  1489.         case CodeAck:
    ; s. I2 A5 c7 C; C3 W6 {9 N
  1490.         {
    ; d* A4 V8 S$ S9 q( d- A
  1491.           uint16_t crc = crc16(&(txBuffer[YMODEM_PACKET_HEADER]), txLength);0 |2 \# U3 D6 _& D5 G) O

  1492. 3 c$ d7 m' Q& Z) s% ~2 w
  1493.           timeCount                                       = 0;0 ?: D0 O  b( P/ W/ s9 P, `% s- [
  1494.           errorCount                                      = 0;- O. K( F" x* \: B# q) J
  1495.           dataCount                                       = dataCount + 1;! I( _. H7 L' @% x2 f9 Y- q: ?7 ?
  1496.           code                                            = CodeNone;2 R- Z' H. H9 O" u- x% F2 {
  1497.           stage                                           = StageTransmitting;3 [8 O( u7 I2 N1 {9 M
  1498.           txBuffer[0]                                     = txLength > YMODEM_PACKET_SIZE ? CodeStx : CodeSoh;
    ) z( T5 v% z% j
  1499.           txBuffer[1]                                     = dataCount;6 G6 m" t% W  g  t
  1500.           txBuffer[2]                                     = 0xFF - dataCount;
    ( x& B: n/ n+ k. q; v8 }1 t: ?
  1501.           txBuffer[txLength + YMODEM_PACKET_OVERHEAD - 2] = (uint8_t)(crc >> 8);
    % Y# |/ K% I1 j2 r9 t* |6 L/ }
  1502.           txBuffer[txLength + YMODEM_PACKET_OVERHEAD - 1] = (uint8_t)(crc >> 0);9 a# J, y# Y) t: n; }4 W
  1503.           txLength                                        = txLength + YMODEM_PACKET_OVERHEAD;
    * @  q0 j( l5 v
  1504.           write(txBuffer, txLength);! `$ `; R  j* {; }" k
  1505. 3 Y8 V; v4 W' H
  1506.           break;) u7 E: w  U# i; v/ b3 x! D' J1 x( a
  1507.         }
    + x. F  @5 ~. W* \- k

  1508. 7 G: j/ F; g; H  ?5 q
  1509.         case CodeEot:/ f" a8 m& \3 _1 p9 G
  1510.         {
    0 B/ C3 B) I% y7 ]3 [. N; Y
  1511.           timeCount   = 0;6 T# r' @# o* u3 w
  1512.           errorCount  = 0;
    " I/ R+ O; C' z
  1513.           dataCount   = 0;
    - z' J  b" s; z" u+ y
  1514.           code        = CodeNone;
    1 V% \6 {6 R! b: f+ h1 e  p0 `
  1515.           stage       = StageFinishing;
    . D: g) u8 H1 q) V% G, W6 }: s
  1516.           txBuffer[0] = CodeEot;; D" ~' l. {5 L1 }+ R: ~: t
  1517.           txLength    = 1;
    ' _4 i. ^, w- r( f
  1518.           write(txBuffer, txLength);! ?$ |& `5 j& S! z3 I! @  J
  1519. / {/ E+ \  O2 z* ]" ^% L
  1520.           break;; ~6 e0 J' {% c+ _' R0 S% n! z% q
  1521.         }
    8 v* O0 _5 N4 \3 w
  1522. / Y1 f# Y! I0 J% [, m. K
  1523.         default:& O, R3 ?7 H6 X
  1524.         {/ c1 B7 z' |) Y0 |
  1525.           timeCount  = 0;
    * ]/ t1 i/ @5 U) W4 r
  1526.           errorCount = 0;
    4 I/ I6 K  z7 C9 |8 G, s
  1527.           dataCount  = 0;
    1 O6 s0 E* ?  E- x6 H# i
  1528.           code       = CodeNone;4 ^8 Z0 u# ^: r) P& o$ @1 R
  1529.           stage      = StageNone;
    , d" B4 ?% n; _% `8 ]" y5 _
  1530. % ?! f- Y: G9 y& M# q: B! V6 P0 i
  1531.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    ' h# g# @- A6 Q/ E. y! x
  1532.           {
    7 E$ A; n: W( V* u- V$ ?
  1533.             txBuffer[txLength] = CodeCan;* a0 d) z/ @+ G; Y
  1534.           }
    - _7 S8 X1 M% }! J9 |" K! Y

  1535. 6 T+ d, d( D" r1 o4 z
  1536.           write(txBuffer, txLength);
    * R- P5 b* ^" }
  1537.         }6 M0 B6 e8 r+ x& R# ^$ C, d, K
  1538.       }
    ; G1 o# P% _2 `+ H
  1539. ( K. W5 e! e. M" L0 L; a: q% \
  1540.       break;
    * F" t9 _4 Z9 e- q0 y
  1541.     }
    0 `; C3 i7 N" G6 e! _
  1542. 9 y. V; o  `3 M4 `' |
  1543.     case CodeA1:; z2 c  u0 y/ `3 `; \4 Z
  1544.     case CodeA2:  H2 Z7 U* ^' K" U. L9 u' F
  1545.     case CodeCan:
    ! W* m2 j; b3 W( \
  1546.     {& {) g+ d8 Q, {6 e; G3 U( ]
  1547.       timeCount  = 0;
    # }7 o8 f: `6 s- k( o' L4 N+ c
  1548.       errorCount = 0;
    1 y/ n  {1 S1 X7 K
  1549.       dataCount  = 0;! d  |3 P; ?; e) {' ^" Z; r
  1550.       code       = CodeNone;
    9 |  y8 z$ K# x6 B+ `7 v
  1551.       stage      = StageNone;
    - c/ O+ H: x' g* g" E
  1552.       callback(StatusAbort, NULL, NULL);: j* E4 i' c# ^. a5 c7 m

  1553. 8 s! e5 S. }# U" h* ?! I
  1554.       break;
    6 o- D4 P' c- I
  1555.     }
    ( r0 x" X: |0 ?( @; C

  1556. 5 r- P- r8 R. T
  1557.     default:
    4 I. C* w1 r" T8 ~, n
  1558.     {
    1 D6 J* |( |$ H' a) C! M; E
  1559.       timeCount++;
      `: x; y; F: t

  1560. 6 y. ^. ]4 y- V+ S! R7 H
  1561.       if((timeCount / (timeDivide + 1)) > timeMax)
    # Z, b" G6 S' K0 Q: F" E! g
  1562.       {; X  k: T0 ^9 h# y
  1563.         timeCount  = 0;5 Q4 N1 |, F, C8 J/ }2 P9 w2 z
  1564.         errorCount = 0;5 g1 e2 I" A/ ?7 K$ H! G
  1565.         dataCount  = 0;. u4 O3 P$ L" \# U$ S
  1566.         code       = CodeNone;! @6 e7 m( x4 e, r! e9 Z
  1567.         stage      = StageNone;
    7 z9 [# }# K1 [+ M( K" H1 S8 H

  1568. ) _+ Z2 T: s- W. x& e
  1569.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)! |, u5 q8 [- H  P% N
  1570.         {
    1 Y: r5 z' z3 ?* Y" J( E; Q' v
  1571.           txBuffer[txLength] = CodeCan;% [0 Y; P9 I& b$ O# f8 f
  1572.         }
    ! {, X  l: C  {4 n" `7 S
  1573. 1 e2 u( [, Y$ ?6 y
  1574.         write(txBuffer, txLength);
    % t) I+ {3 @$ w
  1575.         callback(StatusError, NULL, NULL);
    0 j- d" P5 O/ A& y9 J) K" m
  1576.       }
    1 g$ q0 O3 q) N3 E
  1577.       else if((timeCount % (timeDivide + 1)) == 0)  F: M" t6 c3 \* F( n. d
  1578.       {% B$ S  y; J( z
  1579.         write(txBuffer, txLength);
    $ b) q( s# y/ S4 h
  1580.       }
    ! T, \& m( b8 R" j/ B6 ^
  1581.     }
    8 J3 n, Y7 v4 e3 M% m, ^' b" U
  1582.   }
    ! l/ m2 n% e/ s; ]. a
  1583. }8 y( T- @' ~' x+ L& |5 H; d

  1584. % K! y. g) u$ x  q
  1585. /**# R( n: w& \' s& W
  1586.   * @brief  Transmit finishing stage.: N8 F3 i% g  r. m: m" y1 T
  1587.   * @param  None.
    1 K' ?2 [) u0 x/ s2 D2 G% d$ {
  1588.   * @return None.
    5 d! e/ r. B/ a4 a/ ~  \
  1589.   */6 M* P4 a: T8 }+ ]1 w% E9 G1 i+ s
  1590. void Ymodem::transmitStageFinishing(), w* n' a/ `3 n  S+ ]; t$ z) v% ~
  1591. {& ~: o1 F: l7 H; h" l6 C' L- [* M
  1592.   switch(receivePacket())) Y+ k7 [3 C5 C
  1593.   {* }6 i" {4 f; V" h) Z
  1594.     case CodeNak:5 i/ m: E- r! b% [: ?! j  a* a
  1595.     {
    3 T" i  J) f: _) C- l
  1596.       timeCount   = 0;
    / E8 F; ]+ `  O' h
  1597.       errorCount  = 0;' e! {; ~! I3 f, ?" m
  1598.       dataCount   = 0;' [% S. K+ V" r# \( ]$ e' R$ j
  1599.       code        = CodeNone;
    * w' a- Z$ q  ~* l
  1600.       stage       = StageFinishing;
    - L; Q$ s5 x3 ]6 K. h
  1601.       txBuffer[0] = CodeEot;7 k! g. q/ I4 F) c: x
  1602.       txLength    = 1;! t0 f1 y& M" }& Y* b' n
  1603.       write(txBuffer, txLength);
    & a0 H$ e/ M; {' P/ U  Y. P

  1604. 9 V9 o& s  P; |, }( a
  1605.       break;/ ~# r6 J' Q6 _
  1606.     }
    0 |2 y, @% Z: w+ u  i1 V
  1607. ! y4 k( i! S* E
  1608.     case CodeC:) f6 \. q5 K2 i& s' c7 K# K. K
  1609.     {& l" @9 _$ _5 x  q
  1610.       memset(&(txBuffer[YMODEM_PACKET_HEADER]), NULL, YMODEM_PACKET_SIZE);
    3 _  }  E9 C" d5 A6 D
  1611.       uint16_t crc = crc16(&(txBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_SIZE);
    ! }( T' V5 j( c. F

  1612. / _+ [. H1 Z/ w6 G
  1613.       timeCount                                                 = 0;
    2 d) }3 l2 {' O
  1614.       errorCount                                                = 0;
    & G* }$ [2 t/ ~" e) I& c# d8 y. t
  1615.       dataCount                                                 = 0;+ k8 N* _3 h" A" g% P( f
  1616.       code                                                      = CodeNone;0 q3 A7 a/ u0 [% Y
  1617.       stage                                                     = StageFinished;
    / C7 x9 ~" o  U0 z* v+ g
  1618.       txBuffer[0]                                               = CodeSoh;* V5 G0 L, p8 i0 c* ?* y  v
  1619.       txBuffer[1]                                               = 0x00;
    3 f: a5 E5 b$ O" N7 F: P
  1620.       txBuffer[2]                                               = 0xFF;) R# a/ `9 f7 B# m+ R7 ~
  1621.       txBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 2] = (uint8_t)(crc >> 8);
    , }3 M. a9 d2 c$ G
  1622.       txBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 1] = (uint8_t)(crc >> 0);: M! z- \7 `2 R7 G" F$ }1 o' I
  1623.       txLength                                                  = YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD;
    3 t8 X0 k: d9 u3 [7 I
  1624.       write(txBuffer, txLength);( y4 G! o- @2 X- F' ~/ {4 F6 X

  1625. ) u+ R% _6 P. K* _/ s, m, y& G
  1626.       break;1 t5 U' u/ n6 m% Y5 D1 Q
  1627.     }: Y- x: N% Q/ \% W0 G  x
  1628. 0 C. y3 [2 R" n2 W
  1629.     case CodeA1:% W: r. ^5 `( ]" B5 Q+ L
  1630.     case CodeA2:
    ! G( C' m- r8 l/ H% v1 }  l. Z
  1631.     case CodeCan:+ R. q' T4 {* w' q4 {& t4 |1 {( P% r8 a
  1632.     {
    ! T  l; b) l& e- {; H' O' `; P8 o
  1633.       timeCount  = 0;- C0 o% x, T8 t4 b; h; ]  e
  1634.       errorCount = 0;
    . f8 o9 h. G+ a! S0 M1 R0 l% T
  1635.       dataCount  = 0;: x6 f6 E* J9 d5 N& e+ t
  1636.       code       = CodeNone;1 a! C6 l, K# ]( Z) I3 J
  1637.       stage      = StageNone;  p+ K. i% X, w( m- l/ _2 Q
  1638.       callback(StatusAbort, NULL, NULL);
    " y4 h( o5 @9 t
  1639. : b1 n1 w: A% X  m$ I0 R6 @
  1640.       break;/ ~; d+ k: [9 W3 D/ u
  1641.     }3 b/ I3 t, N5 [3 q3 {

  1642. $ p) J% w+ c1 ^" U8 \( i; l
  1643.     default:
    7 P2 [( {1 {0 D8 U  K
  1644.     {
    0 j# g0 ^) ]5 X7 i, r, _
  1645.       timeCount++;: \# U1 o9 i! ?$ r$ ]; Z
  1646. - x: e, l1 C% F! }+ m
  1647.       if((timeCount / (timeDivide + 1)) > timeMax)/ v7 C' b/ C! a! A( ^
  1648.       {/ E2 @4 T. L8 `$ I: {1 D
  1649.         timeCount  = 0;
    & V& \  b4 _$ V& i, I
  1650.         errorCount = 0;! c2 g) U8 K8 z: M" \
  1651.         dataCount  = 0;* m, z+ f% H1 d2 F, v: x
  1652.         code       = CodeNone;
      s+ L$ w+ V6 e7 F* b) a+ _7 B
  1653.         stage      = StageNone;& a! G& a& s. r1 s5 O

  1654. 9 F( _" `; ]* i& N
  1655.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    0 u2 d& ^. Q* \5 L$ c' m
  1656.         {
    8 s0 A$ ^$ f! x
  1657.           txBuffer[txLength] = CodeCan;- |& k! B' o8 ^, z  H
  1658.         }3 p1 a) x3 R8 q
  1659. 9 \9 H+ {) m7 m% m
  1660.         write(txBuffer, txLength);% \/ F" P" C3 H( Y' Y( d5 j5 D1 a
  1661.         callback(StatusError, NULL, NULL);( V0 \  ~3 R9 q% y1 u
  1662.       }
    % D  B) k3 c1 K  T1 }
  1663.       else if((timeCount % (timeDivide + 1)) == 0)
    4 r1 b5 |) P  Z2 v: g6 C
  1664.       {; Q2 I8 V3 V6 e' c
  1665.         write(txBuffer, txLength);
    % R0 R+ x3 c4 N
  1666.       }  C5 I* u9 g3 {) Y( Z, M! l9 v
  1667.     }, _% q! ?$ C0 e5 {
  1668.   }! ?( }+ R$ G1 i* D& g4 _$ A
  1669. }
    ' s# ~  X5 P2 O8 b0 w0 T# l# V* j
  1670.   n. }8 f3 z" p- C9 j$ m! G
  1671. /**# V' t8 v& ^% S! J9 }6 Q* w( ?
  1672.   * @brief  Transmit finished stage.
    5 i: O- {' k3 l% s& M. o# ?) J
  1673.   * @param  None.- \& W3 V! V7 h/ V+ V
  1674.   * @return None.) Z, n0 F/ [" c1 k
  1675.   */
    ' a# x) ]0 i. g: H2 F
  1676. void Ymodem::transmitStageFinished()/ r: c& q, O1 p/ A2 R& ?
  1677. {
    ! z) X3 S+ o6 F# T$ x) A
  1678.   switch(receivePacket())
    - V7 D/ T/ R/ c5 a9 m5 g; w- A8 U
  1679.   {
    - m! c( l: ?3 h- ^5 o5 t. l
  1680.     case CodeC:
    + z) p" n/ \, i" Q* b
  1681.     case CodeNak:
    . a6 b5 i' b% Q2 H2 A
  1682.     {
    # ]- P. ~! P4 A
  1683.       errorCount++;
    % h, [0 T: |4 d) y- }* J& [3 H
  1684. : X; @4 n5 @  q* e  J
  1685.       if(errorCount > errorMax)
    6 e7 w- @% C. l! l
  1686.       {% j! [* s( a: @( u# Z/ B! a
  1687.         timeCount  = 0;
    % f8 P2 \6 G% W' U2 g5 h& B
  1688.         errorCount = 0;) E8 D/ l9 y: D+ e  q' l1 `
  1689.         dataCount  = 0;
    - r, a0 o3 x# }) A! r
  1690.         code       = CodeNone;
    ' w/ N- x, w( m9 `* \* j5 Q
  1691.         stage      = StageNone;' L% v, I; L- K0 ?# m! p6 D2 Y8 ?) L
  1692. , N  D( w* [3 e& E7 A6 ~
  1693.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    3 Y5 p; I. _) V/ V/ A- `/ ]8 C9 R
  1694.         {
    6 V6 `1 @7 ]! m& \
  1695.           txBuffer[txLength] = CodeCan;
    1 N- W' b$ J# t
  1696.         }
    0 Y8 l, d; H# ~3 z/ Y1 {

  1697. ' U! i5 Y4 e$ l
  1698.         write(txBuffer, txLength);1 Y( _8 N3 Y+ x! T4 a8 O  s
  1699.         callback(StatusError, NULL, NULL);& T1 R4 l& b( N% ?7 s3 h- B' E2 I
  1700.       }& w4 t0 T3 X# w7 ]: C
  1701.       else
    : q# n2 \+ u; M. ?. P4 h& p* G5 I, f3 @
  1702.       {8 H) Q5 S$ b/ g
  1703.         write(txBuffer, txLength);
    6 C: s1 ^" }' p% {# M
  1704.       }
    ) E6 m9 J* O# j
  1705. . j6 N+ }# N( Q
  1706.       break;
    ; i, m( z6 X0 b  z( z$ f  D
  1707.     }
    7 X( z% n: w6 M* ?7 Z4 l  E

  1708. 2 C4 ]9 o+ d* o! R6 \
  1709.     case CodeAck:- [+ x* v, G, D0 H% R
  1710.     {
    : m. ?' f' h6 R( b9 D# e! u; }- ^
  1711.       timeCount  = 0;3 d" x( x2 Q% c. O/ z
  1712.       errorCount = 0;
    * c# W0 v: B2 U) n" B; I6 U
  1713.       dataCount  = 0;
    ; h6 J; o! s! V3 w/ z9 m$ O' H
  1714.       code       = CodeNone;
    ! m; J& l' k: L& L
  1715.       stage      = StageNone;' k6 v: ?2 X; A# J
  1716.       callback(StatusFinish, NULL, NULL);- ~$ q* w, F* F
  1717. 4 N# L+ x" ~; N7 J5 C1 Y5 s4 l
  1718.       break;) k. {! w. D; T+ i
  1719.     }
    - Z  e6 b# M' q6 q6 h& A
  1720. & d. s2 G6 J, C
  1721.     case CodeA1:3 r/ C4 z# f' i
  1722.     case CodeA2:( D0 v4 V- _# L8 ^
  1723.     case CodeCan:
    ) c4 r" I+ F8 G) D7 y
  1724.     {
    $ i. B2 G' Z. l7 w9 s! E" b
  1725.       timeCount  = 0;* K  ?- h" w: d0 Q  a
  1726.       errorCount = 0;
    / h5 ^& W! E& m, C
  1727.       dataCount  = 0;) D( O0 m# z9 b3 x6 H
  1728.       code       = CodeNone;
    ( b! H/ H6 v; }+ m+ g
  1729.       stage      = StageNone;
    % a1 n$ g7 w: o
  1730.       callback(StatusAbort, NULL, NULL);& e. X4 e, l9 H+ D* Z

  1731. ) B) G, S6 j. T4 M" W/ P; {
  1732.       break;
    ; k( a! A- e5 T# z/ F4 g
  1733.     }
    $ _" E+ y9 ~( D8 T

  1734. 9 U% x" d3 q1 h8 M! i, U# R
  1735.     default:
    9 w% {) s0 {1 T8 J% }- R! [
  1736.     {
    % Q8 s9 o3 r: _' N* l6 m# i) c0 V; S  z
  1737.       timeCount++;  O- S1 x: u3 P/ Z5 p
  1738. 3 W$ u' w& b# C6 j1 B
  1739.       if((timeCount / (timeDivide + 1)) > timeMax)
    5 z6 D& J( j2 Q/ ~+ m) K# P
  1740.       {3 N+ E5 s+ Q3 e" m1 z! n
  1741.         timeCount  = 0;3 \3 J( V- D6 |$ |6 A+ v
  1742.         errorCount = 0;
    3 j- a7 A, Y4 c4 i
  1743.         dataCount  = 0;, O# N1 `0 J9 J# x
  1744.         code       = CodeNone;
      t7 h0 |1 T& l+ m$ [
  1745.         stage      = StageNone;- g" m$ F9 S$ v$ T! A" p6 ?

  1746. ! U, T# d% j) c! a
  1747.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    : m" h" \3 N" v( r, V& f
  1748.         {
    $ {6 G: J5 E" [/ k5 N
  1749.           txBuffer[txLength] = CodeCan;8 N6 g3 x* v* |2 M  J% ?2 {5 W1 b  g  k
  1750.         }9 W# G( k$ r, O7 ?7 A

  1751. 6 n" Y" L$ N/ {; d4 `) w6 u
  1752.         write(txBuffer, txLength);1 S/ x: x4 I4 o" G* }$ B
  1753.         callback(StatusError, NULL, NULL);
    * v' H6 k* q/ e' H2 x9 X
  1754.       }
    ( b: p( W& S  W! g% D
  1755.       else if((timeCount % (timeDivide + 1)) == 0)
      m5 g- ^* Q7 G9 E, T( F
  1756.       {
    4 {, {- G5 `: z' c3 h# U5 V% ~
  1757.         write(txBuffer, txLength);
    ; @' c2 T1 Q* r  r& G7 I
  1758.       }
    2 _8 l0 f/ Z+ e0 D) M) E' r
  1759.     }* f+ z( I* F5 Q3 X6 O
  1760.   }
    , O1 Y$ m+ Y! E! S; j8 B
  1761. }
    # ~$ M4 z3 k, ?* R

  1762. & x" V& D3 i+ q
  1763. /**. w1 m" k- m5 T$ Z
  1764.   * @brief  Calculate CRC16 checksum." j* q0 @" d6 O! ^. U+ Y5 M- I
  1765.   * @param  [in] buff: The data to be calculated.
    5 H# w6 S4 J6 w) E7 n
  1766.   * @param  [in] len:  The length of the data to be calculated.7 b1 ?! Q$ I2 k0 H( B- ~* d
  1767.   * @return Calculated CRC16 checksum.4 B$ u/ L, W" S# `
  1768.   */$ d9 |  w6 x9 d& ?/ W! O
  1769. uint16_t Ymodem::crc16(uint8_t *buff, uint32_t len)
    & f: U& R! ]: S; F
  1770. {1 ]" X9 L5 F5 o+ K
  1771.   uint16_t crc = 0;
    " {+ O2 H' q, z9 o8 V
  1772. . E  h- d3 y' {/ o
  1773.   while(len--)8 f6 Z! o2 U" K% }
  1774.   {
    - L2 y/ P' |3 R( E  Z# ~
  1775.     crc ^= (uint16_t)(*(buff++)) << 8;
    , M' s% q5 }6 b6 Z' P8 F! Y
  1776. / d) B: G8 x9 d- E0 \
  1777.     for(int i = 0; i < 8; i++)
    . D  D2 d- G- w2 @; p5 J6 c$ X
  1778.     {
      d! X" [- I% v! m! g8 X
  1779.       if(crc & 0x8000)
    & x1 @  C7 F/ C* f/ d! P' |
  1780.       {
    ! u& j" R4 w7 m! v5 W& l5 H' x: G
  1781.         crc = (crc << 1) ^ 0x1021;
    % }* v! V" g; b" F  L4 m
  1782.       }
    4 x& g. t/ `( Y* h7 b% |% ]
  1783.       else
    : S; h' }* I, w  G8 d) v5 t8 @
  1784.       {
    & n/ i; @% k( w
  1785.         crc = crc << 1;& }* L/ h- `1 I& q! X: l
  1786.       }/ D0 b4 w+ z* [/ N( |; l. Z9 \, B
  1787.     }
    * X* j3 F5 f! u7 N1 r1 M
  1788.   }
    . t; _4 B# R9 Z1 A
  1789. / T2 M$ B9 L0 H; |, w
  1790.   return crc;) L8 ]2 p2 s0 p# _' J' `. ~7 M  ]
  1791. }! H9 N1 G7 v7 S! E
复制代码

' d6 _8 [1 v# [
8 h, w/ R& h0 Y0 W; C$ P& i2 o% z& P: x& {0 i& ]  \

1 q+ F& p+ P. A5 n& X' {( s

评分

参与人数 1 ST金币 +2 收起 理由
MrJiu + 2 赞一个!

查看全部评分

赞 收藏 1 评论10 发布时间:2018-3-6 01:56

举报

10个回答
XinLiYF 回答时间:2018-3-6 01:58:43
      YmodemFileReceive.h文件
/ q" x/ X! T/ T6 }4 O- i% T
  1. #ifndef YMODEMFILERECEIVE_H
    2 u0 ^  p* m8 Y0 J4 s1 a4 T
  2. #define YMODEMFILERECEIVE_H, b' V- O4 B! j
  3. 0 I+ X0 W9 E! _# A8 N) B
  4. #include <QFile>
    + j0 W# ]  a% A; V! V- x
  5. #include <QTimer>
    ' {+ Y# @; ?3 G, }2 J
  6. #include <QObject>* g5 b$ }/ o( y% o
  7. #include <QSerialPort>
    / G8 F' K+ o0 N! @( H# i9 r
  8. #include "Ymodem.h"  [" ?, G5 {5 q1 H9 I  x4 ]

  9.   s$ k( Q  _7 j9 F1 r" p$ b2 |: w
  10. class YmodemFileReceive : public QObject, public Ymodem4 R! K* Y8 C  ]9 V0 N
  11. {
    0 @/ I9 V1 ~. ]6 _, `
  12.     Q_OBJECT
    # v& |5 d; I" y6 D' ?9 s3 `$ \* P
  13. ( n" S' J/ n4 c7 _: a# t/ @! z; V
  14. public:
    . M& g2 R" i0 B; C( x+ o: ?
  15.     explicit YmodemFileReceive(QObject *parent = 0);2 [$ G0 |7 [3 [+ u
  16.     ~YmodemFileReceive();
    " \# w3 n# M! v6 G- }! f7 o- @

  17.   _3 T4 T: k6 w9 B# v
  18.     void setFilePath(const QString &path);/ G, M5 h0 h  j3 w( V
  19. & H5 u; c+ f  u3 s3 Y8 u8 p, A4 L- P
  20.     void setPortName(const QString &name);8 F* ^5 X8 J: J
  21.     void setPortBaudRate(qint32 baudrate);0 ^. E' x: {' n5 U
  22. ; w% S9 J3 u; k; T0 l
  23.     bool startReceive();
    8 o) j" M5 t$ G  m
  24.     void stopReceive();
    $ C$ U+ ~9 N6 D' ]

  25. 5 D9 J8 X) B  A) k/ I+ V
  26.     int getReceiveProgress();
    & w8 H4 |, g; S: M! }
  27.     Status getReceiveStatus();
    # C* W7 `! a1 l* w% {! N

  28. ; Y7 |; S; [. [' P% G
  29. signals:
    . j* T9 o- l5 D5 n# i
  30.     void receiveProgress(int progress);
    - Z( r, m1 |& L; j3 a$ G
  31.     void receiveStatus(YmodemFileReceive::Status status);) s; f$ e6 G$ r5 ~- x
  32. + R% S4 w3 ]" `5 i5 l+ [7 G1 g4 c
  33. private slots:' h6 [; p, Q5 @5 o2 I& U( I
  34.     void readTimeOut();) }4 H0 g; m+ L2 b$ d$ n: B
  35.     void writeTimeOut();! U8 p4 v4 M7 y& [# G6 |/ {8 i
  36. 7 ]0 G+ s/ u: P+ w. M9 P
  37. private:1 S% H% u! t4 H: K1 U/ W" s
  38.     Code callback(Status status, uint8_t *buff, uint32_t *len);4 P: _) A- d' b6 @, O3 g
  39. ( Z: Z& Z2 ?# k+ j! j" @6 y
  40.     uint32_t read(uint8_t *buff, uint32_t len);) o. o' j/ @% m/ O
  41.     uint32_t write(uint8_t *buff, uint32_t len);7 ^5 z. x: M7 @- @9 P  [
  42. , A8 G( v- g' [$ Y; J: S/ K
  43.     QFile       *file;
    9 j% Z1 |$ {4 p/ Y
  44.     QTimer      *readTimer;
    6 r, Y- \8 |+ X- u* z8 O* W) e
  45.     QTimer      *writeTimer;
    6 r1 x& X/ _0 I* i- U. v
  46.     QSerialPort *serialPort;9 A' T. s2 f& m1 e: r2 F

  47. ! S9 o* M4 l* T) q
  48.     int      progress;
    ' ~- e/ G: a# n8 g- b. S! A
  49.     Status   status;) z& I: a' b, Q# K$ P+ Z, b5 P
  50.     QString  filePath;/ s0 S; {9 W4 l0 L
  51.     QString  fileName;
    * t: y1 O! g7 e! G2 I3 U: C
  52.     uint64_t fileSize;; y" s( H7 a' W
  53.     uint64_t fileCount;! d3 V! V9 \* x( E4 [
  54. };
      z" Z7 o# T5 n- |; N/ t
  55. / ]6 _$ G) M/ v  W/ l5 a# X
  56. #endif // YMODEMFILERECEIVE_H  v# \, ?6 {0 x* ?, q4 n
复制代码
2 ]! V+ ~+ k6 W. k
      YmodemFileReceive.cpp文件
" p+ X# x1 i6 T5 J, }5 J0 {
  1. #include "YmodemFileReceive.h"+ S( K, y# X" i5 U8 S, r

  2. 0 W3 \4 _: M4 f! C, s% V7 r/ ?' X& a
  3. #define READ_TIME_OUT   (10); z3 J, v( {) E8 J! s6 T8 z" g4 J
  4. #define WRITE_TIME_OUT  (100)& `/ k# @* k. S( Y

  5. ( }) ^2 l7 I6 {7 J& t
  6. YmodemFileReceive::YmodemFileReceive(QObject *parent) :* D5 J* G- u" \. B" K
  7.     QObject(parent),
    2 n7 r7 ~1 }0 _( g5 H, b# ^  F
  8.     file(new QFile),# K, @) I1 z! o1 _( Z
  9.     readTimer(new QTimer),* U$ _9 i( u9 y8 _. b. Q
  10.     writeTimer(new QTimer),
    " p0 Y+ B9 U# @* W0 T
  11.     serialPort(new QSerialPort)3 L; a' R: F6 _; Z9 X% d: h( e# ~8 \
  12. {
    6 ?9 a3 `. [0 q- S% w9 t
  13.     setTimeDivide(499);- z1 m& V. l* s. `6 w1 z
  14.     setTimeMax(5);
    9 d1 [+ R9 @0 V0 k# h
  15.     setErrorMax(999);7 B: N" p" [. F
  16. # z% E! c# l8 ?' O2 n0 x4 q
  17.     serialPort->setPortName("COM1");4 s& B. F& r9 L* `& I
  18.     serialPort->setBaudRate(115200);
    * r( Z/ j( I/ O) d; J6 j
  19.     serialPort->setDataBits(QSerialPort::Data8);
    # W0 S8 q; U1 u& I9 p+ f
  20.     serialPort->setStopBits(QSerialPort::OneStop);
    0 K8 z+ M) M' L% n4 Q
  21.     serialPort->setParity(QSerialPort::NoParity);: L1 `+ W  }7 t4 V. p
  22.     serialPort->setFlowControl(QSerialPort::NoFlowControl);
    " e6 |8 @- M; H' m2 _+ e
  23. ) H( c2 G: `! g8 R3 N
  24.     connect(readTimer, SIGNAL(timeout()), this, SLOT(readTimeOut()));
    $ I! Y  S5 X! V: V) w
  25.     connect(writeTimer, SIGNAL(timeout()), this, SLOT(writeTimeOut()));
    , p2 b5 k; M, K; a. B! u
  26. }
    , f* q# U3 Q# d0 C
  27. 8 ]! N$ n/ |& q; ?' S# a
  28. YmodemFileReceive::~YmodemFileReceive()4 U$ p, @5 g1 I3 I/ [# v7 O6 |
  29. {# W' K9 N# a$ l
  30.     delete file;
    9 |: u+ S" a3 o( x
  31.     delete readTimer;
      p1 S6 F2 C2 ]/ E/ g( |6 ~6 L
  32.     delete writeTimer;4 \' W) B3 j& I9 h2 m4 ?
  33.     delete serialPort;. T, r0 Q6 F! H
  34. }
    ( S2 l  ^3 ~% |& G. G
  35. / e& @1 t* o% ?" K4 U5 Q, r' N
  36. void YmodemFileReceive::setFilePath(const QString &path)1 n% @9 n* R4 H8 t1 p
  37. {- `& y; \: _9 D& R" c
  38.     filePath = path + "/";
    $ G9 K2 K- t# g6 ^
  39. }% R, [" K! ^7 U0 w" A
  40. $ p$ s. S0 @* d/ M. E, Y) D  j1 ]
  41. void YmodemFileReceive::setPortName(const QString &name)
    ' y; Z1 M. ^2 Q
  42. {6 v8 [( ~; R3 T/ E( Q% Z% g
  43.     serialPort->setPortName(name);: q7 [) P9 j2 {' C- w: e
  44. }
    8 g- p2 P( [1 p& C! D  G
  45. 6 e# J3 J3 j) N/ y7 p$ p
  46. void YmodemFileReceive::setPortBaudRate(qint32 baudrate)
    4 T$ K! n) b8 l' b* e2 j0 c
  47. {2 K% B. F: {5 S" `; G
  48.     serialPort->setBaudRate(baudrate);
    5 w: s. _3 [/ j
  49. }
    ! P' B; q: W  L
  50. 9 o9 I; `8 p) C
  51. bool YmodemFileReceive::startReceive()
    6 i7 v) z7 c! {/ b# ]8 c
  52. {5 ]+ Q" |( u  @  w' i- L; K6 K
  53.     progress = 0;! y; B# w' Q% @" @! s
  54.     status   = StatusEstablish;
    * W1 ~# D. ^$ _4 K# A. k0 m

  55. 5 t7 j2 }/ t; d8 K  ]
  56.     if(serialPort->open(QSerialPort::ReadWrite) == true)1 m/ p2 V" w" ~+ R* A7 |0 _
  57.     {
    3 I# ?! P# o2 D* d( ~4 A- z" Z
  58.         readTimer->start(READ_TIME_OUT);' p  \( g/ a7 g9 R
  59. ( M' P/ k8 o( r* V: k: ~' m
  60.         return true;
    ( \; \: E4 T; u7 U
  61.     }. K: T3 @+ \( B4 [0 b
  62.     else
    - }4 P+ M, @9 q9 f
  63.     {9 V- A# f) y9 N9 z% y
  64.         return false;
    7 H2 o/ [1 @- Y+ t* L9 h
  65.     }: w/ k8 ?  X) e% j
  66. }  C, E- J$ I+ E

  67. ) v; l/ }9 u2 l
  68. void YmodemFileReceive::stopReceive()
    " M- Q' ?1 ~. Q; M
  69. {
    , S0 H4 j4 v; p; D- [
  70.     file->close();, z. t: h( _! i0 V9 s- j  y
  71.     abort();
    ( O! x. }& P2 m0 f% s& H( d. k
  72.     status = StatusAbort;
    6 l. `- _# n# G9 |) U4 l
  73.     writeTimer->start(WRITE_TIME_OUT);% Y; v1 ^+ Z2 D% r
  74. }0 ?7 Y* n  [3 j' a$ `
  75. 9 Z+ r% l# i8 b4 e
  76. int YmodemFileReceive::getReceiveProgress(): D  f9 }: z' Q* |! Z
  77. {
    ! b. f% y& p! f, ~( w
  78.     return progress;
    2 r' g& d- |$ q: O3 f0 S
  79. }4 X* d# Y/ A2 O+ N" f. \8 D; y7 y, c/ c
  80. . P& ^  H  a5 \; ~
  81. Ymodem::Status YmodemFileReceive::getReceiveStatus()
    2 x# y# G+ m, R8 G
  82. {1 m# M% ?. _1 t9 s6 h; x: W
  83.     return status;) x: m8 ^3 T/ }4 ^4 h
  84. }1 d4 m: u4 A* A/ I3 w
  85. 1 A4 b. r, e2 t# H
  86. void YmodemFileReceive::readTimeOut()1 b$ X; B; F% m+ C5 I! @. z
  87. {
    " D" _' e' S# C
  88.     readTimer->stop();
    $ K% j, ]2 a2 A' ~" J, [. ~
  89. " }  v/ x# `$ z, Z& @
  90.     receive();/ a. A, L  \8 r* R) w( Z/ [+ w" r. _

  91. 3 h" Q( I9 }) l- J
  92.     if((status == StatusEstablish) || (status == StatusTransmit))2 g( z8 ]3 h9 w+ [. F# a/ ]
  93.     {
    ; X" a/ F! {% l. i& e0 c
  94.         readTimer->start(READ_TIME_OUT);
    . L% M9 [2 f, \% p
  95.     }
    " T0 K/ e% `4 ~4 a& |, F
  96. }
    1 B$ ^3 c8 e, D

  97. ! a2 `$ }0 |5 o
  98. void YmodemFileReceive::writeTimeOut(): Y5 ?2 j/ r& m( [4 y; T0 m2 c% T/ z5 \
  99. {
    ! m  I( v% p' U' e
  100.     writeTimer->stop();
    9 r" M+ g2 k; D8 n
  101.     serialPort->close();  Q& [/ T5 m2 R5 _) Y! P" ~* m
  102.     receiveStatus(status);% Q2 X; ]! g3 W! T' ~% W' C
  103. }. w/ i4 m' K9 ]1 ]7 u

  104. 0 d% C( R0 m, a; [. |& F
  105. Ymodem::Code YmodemFileReceive::callback(Status status, uint8_t *buff, uint32_t *len)" H/ M3 s7 u4 [9 g/ l# i5 _
  106. {% r& ?9 J5 Z/ w. l0 h# i  g* `
  107.     switch(status)- J# g9 B' T2 u9 Y
  108.     {, q" T. o8 ?9 u
  109.         case StatusEstablish:
    - \" d1 Z$ w, E/ o( }/ q/ h
  110.         {
    9 u5 U/ n9 @% y, K& @, u1 e! A
  111.             if(buff[0] != 0)- C% x- `0 O7 W5 }3 y- r
  112.             {
    / G( D& W6 [, t1 T, o9 ~* r
  113.                 int  i         =  0;) h$ u2 s' }) V, S, n& o8 u
  114.                 char name[128] = {0};  Q9 |2 l! r) W
  115.                 char size[128] = {0};
    ( d, Y5 }: g8 r$ q2 f  T

  116. & A% b! [  _6 x6 J0 C9 M
  117.                 for(int j = 0; buff[i] != 0; i++, j++)
    ( s- c: N5 Y' G+ ?' {0 Y' x! i
  118.                 {0 I/ K. g9 y2 G5 S3 b9 n
  119.                     name[j] = buff[i];
    3 s$ T) ]. F0 u( ^) H
  120.                 }. J. n# b3 L# g, y
  121. . o" B4 C# L% p; W8 E. |
  122.                 i++;6 e; [- W" P- }0 S

  123. , J" P) b" F. N
  124.                 for(int j = 0; buff[i] != 0; i++, j++); ^) |- e$ }& c0 f7 T- Q
  125.                 {' ^$ E8 o2 ~* {! ]$ y; `
  126.                     size[j] = buff[i];
    4 G1 D3 Z( x% k
  127.                 }9 ~  [0 N  Z- g; @* j5 f: n
  128. ) y+ t$ |, J% |4 N( n. ~9 `$ \
  129.                 fileName  = QString::fromLocal8Bit(name);
    2 d+ V$ p9 y7 o5 o+ v9 }
  130.                 fileSize  = QString(size).toULongLong();
    - v# K5 n0 a1 k% v! |4 H
  131.                 fileCount = 0;5 G4 R3 D1 F+ N9 i* E# Q+ t

  132. 4 M! Z( u/ E% r
  133.                 file->setFileName(filePath + fileName);& `) ?; i4 e' W2 P5 C6 C
  134. & n1 `; y' k) N& X& F/ w  o* g
  135.                 if(file->open(QFile::WriteOnly) == true)
    ' ~8 w/ u1 }( k. u5 L5 H" Q
  136.                 {
    8 y  k) r: C- e- h
  137.                     YmodemFileReceive::status = StatusEstablish;
    # }% y% w  }& T7 |% @2 i/ z

  138. & e6 z, P9 ?' ]
  139.                     receiveStatus(StatusEstablish);3 a+ L2 @" |1 P" f/ w9 E" w; m  o  E2 X- Z
  140. * K) v8 R, z6 l# w. j$ q
  141.                     return CodeAck;/ [& }3 Z) N$ e3 @
  142.                 }
    : P# g5 R" [* z: g
  143.                 else, a6 N) u7 p$ f8 T2 J, ^
  144.                 {
    3 D+ D5 D' z3 B
  145.                     YmodemFileReceive::status = StatusError;$ t. k2 M, m3 ]( m
  146. . F3 X6 }* @; N( ]  F
  147.                     writeTimer->start(WRITE_TIME_OUT);; z1 _/ R1 C6 w; ]- ?

  148. % ?/ f; ^1 F2 D' g, q3 P. N
  149.                     return CodeCan;6 r7 Z! D  ]2 f* Z! \6 D
  150.                 }5 k8 l  ^% M0 B
  151.             }
    * w- I! V  L! x1 ~6 J, W/ g
  152.             else! }3 D) b* L0 q. i2 s
  153.             {  M$ j) V1 y$ {$ q/ c/ T
  154.                 YmodemFileReceive::status = StatusError;
    4 c- D' }0 ~; D- Z1 `" ^& `) j9 M

  155. ( I$ x% y4 U0 f7 V7 _: z5 U
  156.                 writeTimer->start(WRITE_TIME_OUT);( M3 m5 l1 P( y/ |" H
  157. 1 O- p# c! r6 g8 ?$ O5 H$ s7 b9 Y8 T
  158.                 return CodeCan;2 N6 R7 E' P/ d, U( }# F& O* G3 c
  159.             }
    0 J, ~  [4 K# O
  160.         }
    7 a8 m- ?# q- x! J: V0 g
  161. + H' A0 P% ^& I4 z4 I
  162.         case StatusTransmit:
      f6 a+ s. b5 _
  163.         {
    1 e  o% U0 n# O7 w* z
  164.             if((fileSize - fileCount) > *len)0 N  y% e) B6 |6 Z) n9 ^
  165.             {% v# X( \5 W+ R8 p8 Z; D( X! V+ a1 [
  166.                 file->write((char *)buff, *len);) I$ q7 A+ G/ Q# ^4 K, I
  167. ; |0 [; Z9 v4 C0 Y
  168.                 fileCount += *len;
    + S, ]5 s& X4 T0 _" \8 Y
  169.             }, X: V5 b* k' L3 n4 l3 O. _
  170.             else% ^; h. }. h3 v: d3 J! b: m$ u
  171.             {
    * }1 Z4 T2 U& e$ K8 ]1 P) {; b
  172.                 file->write((char *)buff, fileSize - fileCount);
    # T" X0 W; F2 M( C8 H/ E
  173. 0 u; e! S9 O) d4 }) V
  174.                 fileCount += fileSize - fileCount;4 W& S3 y, n' m2 r
  175.             }
    8 e6 X. q1 Z8 G: g& o" }
  176. + p/ F/ J, I0 o
  177.             progress = (int)(fileCount * 100 / fileSize);
    % f1 x1 n5 |$ A: P

  178. 0 @; X' ^2 i* G; ?) R! v
  179.             YmodemFileReceive::status = StatusTransmit;& ?% s# v4 j& e1 Z$ \' h

  180. ; U! F5 ]3 _9 \5 i* a- u
  181.             receiveProgress(progress);
    - |' t- D( \. A! l- T
  182.             receiveStatus(StatusTransmit);
      R+ S! e" z2 F% V2 `* ~. o3 l6 D

  183. : E4 L- S/ Y0 B) X) I* H
  184.             return CodeAck;) P! Q5 o' r' Z' Y
  185.         }
    ' u  \6 E3 s( ?2 o, x5 M  q; u
  186.   ]$ ?  F. F! i. Q7 q8 W
  187.         case StatusFinish:
    6 B( N% ^7 U! z# \6 U( G/ ^5 R. v
  188.         {4 D. P6 ?) L3 `- {" }9 ]. }
  189.             file->close();
    , R) \- u+ D/ n/ E* i* \5 g. V
  190. % s4 d+ L& H0 u) M4 F
  191.             YmodemFileReceive::status = StatusFinish;
    / ]3 N5 F% H$ V# T5 F  i5 L7 k/ P
  192. ) H% P. ~- e* _* [/ `* i5 y. z
  193.             writeTimer->start(WRITE_TIME_OUT);
    6 F+ T% c2 q7 T* J9 {

  194. 2 W3 X9 e* ~, b) C" z2 i
  195.             return CodeAck;" U6 L: _# u7 U& v" i
  196.         }) @4 `0 q( [+ J3 i$ B

  197. - Z: q; K# Z; E, U1 x! a
  198.         case StatusAbort:
    : Z. V! P' S2 w6 [; V0 Q9 k
  199.         {
    2 u! A  c9 _' S7 T' F6 J
  200.             file->close();; w. r8 Q" C+ }  `6 j
  201. 7 E( g2 l* B3 z7 N/ z. k  ~
  202.             YmodemFileReceive::status = StatusAbort;- c* y4 K/ ^% c+ ?5 x5 I  j

  203. + j+ }9 r+ x1 Y" k( z9 r, v; e
  204.             writeTimer->start(WRITE_TIME_OUT);
    6 t! w- P5 L& V6 R
  205. 0 C+ Y  [  V9 Y
  206.             return CodeCan;+ c: Y9 t! E, p; _
  207.         }
    + S6 E" P% {; @. [7 h9 I6 ]1 o

  208. ' t: l# u7 a% n" A$ J' i; x4 k! s. N
  209.         case StatusTimeout:
    : e2 Z( R- v% Q" m) w9 y3 Q
  210.         {
    . {1 m' X3 }# u, `/ P
  211.             YmodemFileReceive::status = StatusTimeout;
    - ?* `0 p; N( n" z  h! T5 c
  212. / e6 D7 j4 H8 p, ^  y  Y
  213.             writeTimer->start(WRITE_TIME_OUT);% f- S# k5 O6 Y0 U3 n

  214. 7 G5 b, P5 H% }( s, a
  215.             return CodeCan;# `2 s& w9 H" W0 @  h" r  p8 _  d
  216.         }2 M0 m6 J9 N, s

  217. ! a4 _4 r. V$ y6 x* Z6 j3 s8 A
  218.         default:. r: O! Q% i. v9 N3 m5 [6 n" J
  219.         {
      g( [; C6 `) ~8 T" G6 w2 |
  220.             file->close();
    1 i) P+ e; r. ~' ~+ y4 Q

  221. / t) J- i4 Q- b
  222.             YmodemFileReceive::status = StatusError;
      C3 N* c6 n2 Y0 T/ ^

  223. * g  G% {* d/ j5 c5 ]/ d. ^  s' {
  224.             writeTimer->start(WRITE_TIME_OUT);
    % y' B- }) [& N

  225. * W3 Z# `. `9 a2 J7 ?
  226.             return CodeCan;
    3 {+ O3 Z# D8 t6 K
  227.         }
    1 C9 I0 u; D+ V) Z- ?  p
  228.     }: S$ a! R/ m9 U; z
  229. }# G, Q/ H4 H/ W6 S; |

  230. 5 }# e# }( p- o% J; D
  231. uint32_t YmodemFileReceive::read(uint8_t *buff, uint32_t len)
    # I) B( v9 @; v) B' g
  232. {
    4 x& b; e" s0 P6 t2 c
  233.     return serialPort->read((char *)buff, len);
    * D/ l, g8 u# r; [6 o
  234. }( V  w* ~+ b( H( p8 I0 G; X
  235. $ e. Q1 o* I2 @; w2 h' P
  236. uint32_t YmodemFileReceive::write(uint8_t *buff, uint32_t len)
    # m0 W! Y( ?, `/ F
  237. {
    # k+ _$ h# D; X9 Z& U1 c
  238.     return serialPort->write((char *)buff, len);
    & z6 `3 h/ t8 |' T' X" z  Q- R) j/ ~
  239. }8 S' l4 A$ Z" m1 q
复制代码
# d* |( u# u/ W
. h( X0 g7 |# ~# c
4 o7 ], S+ \/ \; c5 M2 [
  u! x9 |- c4 N
XinLiYF 回答时间:2018-3-6 02:00:03
      YmodemFileTransmit.h文件, U0 _. x! q- l
  1. #ifndef YMODEMFILETRANSMIT_H
    - Q$ `- |. r9 ]
  2. #define YMODEMFILETRANSMIT_H2 R  K7 l( N& @4 E
  3. 8 J4 N+ R! c+ E+ y" i" {+ F
  4. #include <QFile>' P% |& G1 K( y0 ]8 H2 v
  5. #include <QTimer>0 m. }! g  F1 @4 f( O0 \
  6. #include <QObject>
    & `" }6 m+ |' z( D1 ^
  7. #include <QSerialPort>
    + i7 v( M* h  T4 z% Y: B
  8. #include "Ymodem.h"8 F1 T" D" _/ L, |. z5 e1 W% t9 q3 g
  9. 1 s( {" J/ q  U$ H! p5 k, x/ l
  10. class YmodemFileTransmit : public QObject, public Ymodem
    9 O3 W/ Y+ x" ?# I5 C; S6 R# H  D9 R
  11. {9 {* M1 z- _) o; ^; V
  12.     Q_OBJECT3 d+ n& a9 ?8 U# j$ f# _
  13. ; ^  ~9 h3 L* _$ G8 r
  14. public:* v* ~2 y6 `  D+ f
  15.     explicit YmodemFileTransmit(QObject *parent = 0);" l( e2 ?1 h9 k. }9 q
  16.     ~YmodemFileTransmit();' G* c! x" U3 j3 {8 K
  17. , n, d# \" F) d
  18.     void setFileName(const QString &name);
    6 H' Z( z3 `5 @8 n; x! ?

  19. 6 j6 B/ n7 t# j. t
  20.     void setPortName(const QString &name);
    : h* f' B' }9 Q9 ?
  21.     void setPortBaudRate(qint32 baudrate);/ k2 R( F4 J( O8 z

  22. ' r* {4 i0 Q6 P1 C9 i! J
  23.     bool startTransmit();
    - ^9 J* x$ z5 P5 l  Q+ n
  24.     void stopTransmit();
    4 [* K* t, h1 o0 H" `
  25. + k5 e# \  o+ Z
  26.     int getTransmitProgress();
    3 M5 j9 ^, [6 V: o8 x7 z. ^
  27.     Status getTransmitStatus();
    ; l- M" H- T  p( K
  28. - ^+ _  L7 c8 F
  29. signals:1 a, P( \% m" D3 ?
  30.     void transmitProgress(int progress);
    6 t. w" [. ~6 Y2 u7 Q$ j
  31.     void transmitStatus(YmodemFileTransmit::Status status);
    & Q3 F, S* ?1 b; I3 s

  32. ) W) s  b2 A* b7 q- G# Y
  33. private slots:
    & a- s" Q4 B( ~( m* H
  34.     void readTimeOut();" g6 w$ k; {  u+ s2 e  H
  35.     void writeTimeOut();
    ) o3 i# T& |7 N0 b& x

  36. ; \; l) K) g+ f
  37. private:. x" g% m. A( D/ v5 g8 c
  38.     Code callback(Status status, uint8_t *buff, uint32_t *len);% `/ `( v, L7 I" ]

  39. 9 _6 z. I( o6 l3 j! l0 n0 r8 \( \6 f: d
  40.     uint32_t read(uint8_t *buff, uint32_t len);
    3 x4 X) F# l/ Z' P7 m' Z
  41.     uint32_t write(uint8_t *buff, uint32_t len);: T$ d0 g. B- V; u6 @0 a1 l% i

  42. , z4 d1 p# ~3 S( ~2 s
  43.     QFile       *file;& G. j/ F3 g# F) q% Q
  44.     QTimer      *readTimer;
    3 s6 L6 \4 y" l2 V: t
  45.     QTimer      *writeTimer;
    4 k( \2 v1 m" A; K/ K
  46.     QSerialPort *serialPort;2 l7 |* x6 e) h3 `" ~9 r
  47. * A5 P( M$ f# V! }
  48.     int      progress;. Z* e0 m) b; i1 h) a
  49.     Status   status;; E, ]6 k4 J1 l* h, z- b
  50.     uint64_t fileSize;
    + k, `" d! E7 _- S* `
  51.     uint64_t fileCount;' F+ t. V1 f# ^% ]+ E# E
  52. };
    7 g" }+ D% T# j8 `: S4 H% U
  53. & V$ g' R) L* B9 [- n
  54. #endif // YMODEMFILETRANSMIT_H: E$ X9 {+ s6 h8 P% ]0 R
复制代码
8 b5 Q3 G1 n/ Z6 K* Y5 A' f
      YmodemFileTransmit.cpp文件, V7 z' ~# Y( d" |3 B& ?  f
  1. #include "YmodemFileTransmit.h"
    & ~9 o6 t" |5 n5 l5 C
  2. #include <QFileInfo>
    1 T, t5 \) ?6 r! p* E0 [
  3. * ], T$ S' z$ L# n5 u
  4. #define READ_TIME_OUT   (10)5 E+ m6 e' C/ o, M% ]
  5. #define WRITE_TIME_OUT  (100)
    % E, N$ p, ~. l# [8 J

  6. / t5 @8 j1 R. O( M: p1 w
  7. YmodemFileTransmit::YmodemFileTransmit(QObject *parent) :, u* s" s' Q$ C
  8.     QObject(parent),( V2 h- Q! b2 `) C1 {- M" |$ j
  9.     file(new QFile),0 W8 u5 I% z/ u4 |  G+ q0 U
  10.     readTimer(new QTimer),; ]; y. ?# T" ^* Y( H9 P& B
  11.     writeTimer(new QTimer),
    6 F3 n2 Y/ T5 s3 B
  12.     serialPort(new QSerialPort)' y0 Y9 a1 }9 E& ?. P/ T9 {* h
  13. {
    0 D# ^! O. ~7 Y$ u" w3 t
  14.     setTimeDivide(499);* I, q! `% F! j0 M+ @* a
  15.     setTimeMax(5);% `: p# Y9 G7 `/ l
  16.     setErrorMax(999);1 L8 ^8 H* [+ ?4 `, w

  17. 3 w  A4 i& j) H
  18.     serialPort->setPortName("COM1");. ^7 ^. I* s, U) Z# \* `
  19.     serialPort->setBaudRate(115200);
    ; Q8 P+ M* }6 o& [. L' V
  20.     serialPort->setDataBits(QSerialPort::Data8);% B4 w9 ]* ?' l; O
  21.     serialPort->setStopBits(QSerialPort::OneStop);
      w$ E5 U( L3 s9 O( h9 J5 n. G: ^; h
  22.     serialPort->setParity(QSerialPort::NoParity);+ |- e$ P/ v5 S9 h; A' E/ k
  23.     serialPort->setFlowControl(QSerialPort::NoFlowControl);
    ! p' Q; `! K6 U! [
  24. ' U+ B/ r1 T' o' i
  25.     connect(readTimer, SIGNAL(timeout()), this, SLOT(readTimeOut()));
    5 A" B* N+ D+ T) e% e  {3 w
  26.     connect(writeTimer, SIGNAL(timeout()), this, SLOT(writeTimeOut()));+ S: R) p0 D: i6 X% {  E4 U/ @" B
  27. }! \. b1 _! ?2 U$ K0 N
  28. 6 t& H& s0 u8 q1 q
  29. YmodemFileTransmit::~YmodemFileTransmit()5 i' l$ n* L4 V1 J- {# ]1 q; B3 F
  30. {& K* C$ T6 |$ t& O; V- P9 x
  31.     delete file;
    : [! B: T: a0 J9 M) {: \4 z
  32.     delete readTimer;( l4 F, p! `; I$ {; R. f# L3 w
  33.     delete writeTimer;& m* ]- c! f1 S# U; j
  34.     delete serialPort;2 Z) Y3 L) d. x) W' J
  35. }9 y3 E# X3 p) y4 M/ h8 M- J  Y

  36. - p2 G" C* R0 `0 V; n
  37. void YmodemFileTransmit::setFileName(const QString &name)
    . [* O) P* K' U5 i; |
  38. {
    + X4 e# J; K: ~
  39.     file->setFileName(name);
    ) T0 ^7 W5 Z2 A$ w
  40. }
    8 {/ Y. Z4 e0 C% Y( d: f9 T
  41. 1 A" e* E9 W1 B9 e6 M; o8 c* [
  42. void YmodemFileTransmit::setPortName(const QString &name)
    - S$ A* h6 i9 d6 J6 G% ~
  43. {- v5 d! \2 i! E* b
  44.     serialPort->setPortName(name);
    0 L" E8 |/ a, Y  H( a6 B
  45. }5 u1 H+ U+ I# ]# y0 B/ f

  46. + a) H2 H+ ?8 B+ u3 N; {" d  {+ U2 `
  47. void YmodemFileTransmit::setPortBaudRate(qint32 baudrate), Q( S5 U- D% f$ Y
  48. {. }2 x& {) Y+ R: W
  49.     serialPort->setBaudRate(baudrate);* ~5 ^2 I6 W9 @5 ?
  50. }
    # B" q& L& D2 Z5 o" V, |1 \# t
  51. ; d( b6 X* i& Z# X* m$ L; f
  52. bool YmodemFileTransmit::startTransmit()+ f) R  Q: q) d- d6 ?% e+ e
  53. {
    . f# a, n& C- N/ V" V
  54.     progress = 0;
    / ]; X* L6 Q& w) r9 E9 B; ?
  55.     status   = StatusEstablish;
    3 a) i) [, f6 B- z) S
  56. , v) D. h+ }$ }8 E7 w# w' t+ Y
  57.     if(serialPort->open(QSerialPort::ReadWrite) == true)% `. ?, J1 ~4 Q/ U5 X# N) M( k
  58.     {
    , v; n" T3 F- \/ x% O) L
  59.         readTimer->start(READ_TIME_OUT);
    8 u4 g: b- @1 c" ~, C
  60. 6 z6 N- g" y3 t& J$ c
  61.         return true;
    6 r/ a  I+ f' F2 k
  62.     }
    0 \9 F  s; x9 C) r8 R0 V
  63.     else
    , Q8 J  ^' }7 J0 d8 G9 ?" V- f
  64.     {
    " e8 F/ ~* K: T
  65.         return false;
    % {5 D/ h+ O; f6 N+ Y8 M/ r  B
  66.     }
    9 i# r4 g3 b) T" l/ k8 g! i* L
  67. }1 T" d4 S9 N) G

  68. 6 i& c/ \1 h" B& m; r
  69. void YmodemFileTransmit::stopTransmit(): d6 h# F2 a4 k) c5 E6 X
  70. {
    " D( s4 |( ~3 x# [; m( [
  71.     file->close();
    8 L: i$ O5 p6 T. ]1 ~
  72.     abort();- n1 l) T7 w2 [' q+ s
  73.     status = StatusAbort;$ |2 h# J; I5 \/ d
  74.     writeTimer->start(WRITE_TIME_OUT);
    , R4 w4 D9 d) S6 _. t8 r! t
  75. }1 H; c4 }" [4 _) Z, I+ [* V; d

  76. / W( C  f+ g4 C# n0 P
  77. int YmodemFileTransmit::getTransmitProgress()+ ^4 o" U+ L% Q# p8 y9 ^& \
  78. {
    " h1 Q0 G; z) ?, U( Y/ a
  79.     return progress;+ a6 ]# r% p3 B4 J
  80. }6 }8 ~! ~4 D0 S" A5 ^+ {5 C( E0 @

  81. " \$ `+ o, M) B1 s, ?
  82. Ymodem::Status YmodemFileTransmit::getTransmitStatus()' q' ~1 E* Z$ D, T+ \
  83. {
    ' I) z- n# W+ G
  84.     return status;
    8 M8 I9 ?4 \' f* J7 Q" K$ d" V0 [
  85. }
    & R2 e! X$ C; K/ X

  86. 6 l5 W' l9 B; e$ G, z" x0 [; D$ B4 Z
  87. void YmodemFileTransmit::readTimeOut()
      d) B6 g( m) s6 o7 E3 s8 I( g; w
  88. {
    7 P* b, u$ ^" j$ _" v; \+ R- ^
  89.     readTimer->stop();" e8 @8 Y$ L0 G* d: i, m
  90. % ~8 a# N* U3 J0 Y4 e
  91.     transmit();$ K  G$ ~& P+ F/ ^

  92. + P- C  f0 p/ ^6 {2 G* B7 r; v1 L3 H
  93.     if((status == StatusEstablish) || (status == StatusTransmit))
    8 x; k  l. @& x% p5 _* }# E% d
  94.     {& M; l! N  {5 ^. E' E! k+ P
  95.         readTimer->start(READ_TIME_OUT);1 ]' E4 E: Z9 ]5 P6 x/ y
  96.     }/ H, Q1 N/ z' e' v$ b  y. P
  97. }
    / v4 p2 E5 T  u  |' B
  98. 0 d5 S9 N' ^/ g2 O
  99. void YmodemFileTransmit::writeTimeOut(). A$ s, c4 `6 d% @! J
  100. {$ s8 G& _* ^4 O, j4 _" S: V! i/ c" E
  101.     writeTimer->stop();
    3 v  p' l5 z4 Q3 J8 g; j% g6 G7 V
  102.     serialPort->close();
    : M6 K, W1 g" _* c! H7 q
  103.     transmitStatus(status);; {  b2 k7 a6 E4 X! I
  104. }7 w2 M* n. g" U* ]9 O5 ?
  105. 2 _! D6 p9 W# A4 Y  m; U* D% a2 V2 \
  106. Ymodem::Code YmodemFileTransmit::callback(Status status, uint8_t *buff, uint32_t *len)8 Q  A$ G  a6 b# ^# D# w0 W1 m
  107. {2 e% W' T$ @0 {( k3 X6 C
  108.     switch(status)! ]0 C5 K4 N8 G7 ?2 ^( K
  109.     {
    " W" j4 M4 Y& O9 ~
  110.         case StatusEstablish:
    $ d9 J" L) C7 L- Z% W
  111.         {8 H0 \+ _$ R/ L3 p
  112.             if(file->open(QFile::ReadOnly) == true)
    7 S4 c; W- x9 ^2 [/ s" C
  113.             {8 D) X' i3 v* R: j5 Z9 W
  114.                 QFileInfo fileInfo(*file);) b8 F- @1 e1 @# C8 S# n
  115. , w1 t" c( Z# o  B# N
  116.                 fileSize  = fileInfo.size();
      H+ w- y  I. d4 F5 b
  117.                 fileCount = 0;% {6 n' a# _% l4 V* r
  118. 1 M; ^3 O/ R/ o7 S, p; j
  119.                 strcpy((char *)buff, fileInfo.fileName().toLocal8Bit().data());0 O1 B  f$ l; g3 _9 {( Q  v
  120.                 strcpy((char *)buff + fileInfo.fileName().toLocal8Bit().size() + 1, QByteArray::number(fileInfo.size()).data());1 f% k5 s. w; a9 d- c

  121. 4 @/ Y* U/ A, y/ |
  122.                 *len = YMODEM_PACKET_SIZE;
    - A4 k& U& @5 R* ?, c$ J2 t
  123. & R+ k# Q% O* i2 b2 ~+ Z8 ~
  124.                 YmodemFileTransmit::status = StatusEstablish;
    ( @: J4 q! `/ L, j8 W' A$ j

  125. 6 X% F% A# Q1 ]. \* ^
  126.                 transmitStatus(StatusEstablish);
    & t1 }5 r% ]/ s4 I2 r% u3 ^

  127. 7 ^1 S9 h; l- F
  128.                 return CodeAck;* }6 j5 d) H. k
  129.             }
    / x1 v! n' Q& s
  130.             else
    # s0 C6 P" d( k  e: N' S
  131.             {5 p3 U$ O$ B" Z5 d4 n4 O) ^0 J
  132.                 YmodemFileTransmit::status = StatusError;
    % y1 [% \: e& y, f3 h% l6 Z
  133.   q  x7 @8 z, A! _8 O9 n; K& X1 _
  134.                 writeTimer->start(WRITE_TIME_OUT);2 w- U* g/ C! a2 F" w3 r8 h+ B
  135. 9 U% T$ L4 s5 h6 I' U
  136.                 return CodeCan;( u/ X5 I4 l7 |3 w
  137.             }1 I3 i5 s6 n" r, f
  138.         }
    8 ]) S- e/ w1 \, ?5 b7 O* {  D
  139. # d  T3 H' M" T. F5 j* F! J; Z- M
  140.         case StatusTransmit:) b  W- `5 @  W, j4 t! h& N
  141.         {1 ]5 _. c3 g! v1 Z+ _' A& x
  142.             if(fileSize != fileCount)
    ; u' [$ W& h! e% A- z  o/ ~
  143.             {
    : @1 d# G6 f9 k! ~" \5 F6 [) r
  144.                 if((fileSize - fileCount) > YMODEM_PACKET_SIZE)  m1 J& ?4 t. C( ]! @
  145.                 {2 v5 W: U& b" \. z$ B- g
  146.                     fileCount += file->read((char *)buff, YMODEM_PACKET_1K_SIZE);
    ! F" v! D4 U3 r! t

  147. 4 h+ e5 A' c2 T( I, @5 U. l7 y. y
  148.                     *len = YMODEM_PACKET_1K_SIZE;
    % d: x5 e4 h: l0 T( m0 A+ X
  149.                 }/ d8 C0 {6 A% O( v% K; O
  150.                 else
    ; ]! }! R, J! D# }& b
  151.                 {  A  p# |4 h: i: B
  152.                     fileCount += file->read((char *)buff, YMODEM_PACKET_SIZE);# p  ]* j, G- L; Y2 s: c

  153. 7 X  D; J1 u! a; M) O! \
  154.                     *len = YMODEM_PACKET_SIZE;
    9 E, k, k) m* ~( \' i. [( E
  155.                 }5 m% {- G! {, ~6 F
  156. 1 k$ V) W4 e' j7 L
  157.                 progress = (int)(fileCount * 100 / fileSize);' x- S: M, X/ U$ E( Y5 p% E

  158. 3 N1 n0 L% s5 F. U1 ^  d$ F
  159.                 YmodemFileTransmit::status = StatusTransmit;
    / ~/ O" O/ N) s1 t- q3 r) f' z

  160. 6 P! s: n$ J! @
  161.                 transmitProgress(progress);$ A2 g. @, T" e- Y; i
  162.                 transmitStatus(StatusTransmit);
    2 c, S* a0 N7 H: O! Q9 E1 f- b  F
  163. + m4 \0 f8 {* t2 J  G
  164.                 return CodeAck;6 k8 J/ f: H+ Y6 H, K
  165.             }* e5 e7 P. e& G# C: _9 J
  166.             else1 r3 X' r4 t; g& A! q+ F% U0 @. R
  167.             {
    : w1 b; s" M9 s( b5 ^8 f% v, A) Y
  168.                 YmodemFileTransmit::status = StatusTransmit;
    : t) @8 ?' k: m) p5 a3 N

  169. 8 N. y6 l8 H5 \% a% W
  170.                 transmitStatus(StatusTransmit);
    : v6 _: Z  `/ y2 |! H' J

  171.   M) s& q: j4 p6 e
  172.                 return CodeEot;5 `2 l# x' W9 d  [9 `
  173.             }0 X" m( R4 d  m) P, h. ?4 Q
  174.         }
    3 h8 V$ L4 E1 J( n4 T7 h

  175. # i9 j6 [5 F8 f$ L* U0 j
  176.         case StatusFinish:
    : B+ }" c- V1 x# P4 H- @- j1 z3 z
  177.         {; _4 @& ]7 {. R& _2 n. |
  178.             file->close();
    : M, ]0 _! c  M( \1 k

  179. ) M  Q% [, i# A6 U
  180.             YmodemFileTransmit::status = StatusFinish;
    0 ]/ p5 i$ t2 e! m- C8 O
  181. . T6 {" y- B7 G$ Y7 |
  182.             writeTimer->start(WRITE_TIME_OUT);
    ! E8 `6 K% o' V
  183. % e0 V- x. o5 c
  184.             return CodeAck;
    , F' V$ y! p' |4 n
  185.         }
    % T2 a/ B# K9 i+ X0 u0 q3 U
  186. 7 q, h3 h& }6 r# I: i7 C: ?/ |$ N* d$ M
  187.         case StatusAbort:! K9 U0 ~" N( H* E6 y( y
  188.         {
    & R* q! H+ t& w" F
  189.             file->close();; k' e% {  b, ~* f' m
  190. * z; v7 r9 b2 E5 m" c0 P& ^4 R, q
  191.             YmodemFileTransmit::status = StatusAbort;
    ! h7 g/ A, g. F/ V8 C# f
  192. 1 i9 Y: V' v- r; C0 {* s7 }* {
  193.             writeTimer->start(WRITE_TIME_OUT);8 |: z1 t' Z! W9 G: M' P" ]/ }2 ]

  194. $ V1 f, v2 S, ?+ x
  195.             return CodeCan;
    , y- g5 i$ X6 Z* A- B& X% N
  196.         }( P' V) U& ?% d2 t- b5 t

  197. 7 o6 O# j( `) c* i) l) f, T: Z/ D
  198.         case StatusTimeout:5 |+ y! s% s# s) \2 X
  199.         {
    1 z3 ^9 \- W) @+ y
  200.             YmodemFileTransmit::status = StatusTimeout;
    * e5 O6 a2 f6 m, b
  201. 1 u% p" P! j, D
  202.             writeTimer->start(WRITE_TIME_OUT);& @  a  i# x, N0 q
  203. * o3 \! Z/ q- Q, i
  204.             return CodeCan;
    + E6 g# |8 {$ r6 \* @! D8 N
  205.         }2 R) c# U: _6 y7 H0 Y2 ^0 S

  206. % e: n! {$ e2 r! A$ W
  207.         default:
    / ~5 \5 R/ p" E# j$ T. N# M
  208.         {
    1 L, b  a6 Q2 P8 X
  209.             file->close();
      \& _. ]- }' }1 J3 C% }

  210. ; r" ?* I2 S: {# |! s9 x/ o
  211.             YmodemFileTransmit::status = StatusError;) ~( [% V# X4 _2 {; F9 J  _# |* v

  212.   e3 K0 y, `  F6 y
  213.             writeTimer->start(WRITE_TIME_OUT);8 c- w$ M& P6 O( Y/ m' @- u! I" d& A

  214. ( H7 u; R; v. L! W
  215.             return CodeCan;! d( X; B' \, {) J7 v
  216.         }
    ' p; r4 y6 G9 U  g9 X' q9 U
  217.     }
    6 O9 q) n( u: f7 x& Y
  218. }
    8 @4 R& E- U$ W+ i

  219. - K# L8 @! ], |# R0 k! k3 b1 A
  220. uint32_t YmodemFileTransmit::read(uint8_t *buff, uint32_t len)
    # w; V/ U) ~) P# G
  221. {; P4 l6 w) K6 F
  222.     return serialPort->read((char *)buff, len);
    $ F" C% j3 b4 C+ ~& M
  223. }+ |2 |( Q5 W4 u$ n; K& d) L

  224. - d6 K5 m& q6 p
  225. uint32_t YmodemFileTransmit::write(uint8_t *buff, uint32_t len)
    3 B. T& X5 q; o+ L- S( {  }0 f
  226. {( p7 I% R# R! ]: x
  227.     return serialPort->write((char *)buff, len);
    4 ?' a3 l9 h& ?! {) H" D: x
  228. }$ i" c( K6 r# k9 R8 v: ]
复制代码

) B: E2 U# G8 x; X
6 _( R- w) P+ |* f* d9 P6 M9 y/ i/ m0 ~5 F3 A% e& b1 W4 C& }" t1 X

# O: ^# |$ H$ ?( [8 W
XinLiYF 回答时间:2018-3-6 02:02:04
      widget.ui文件. N6 e: `! ~% P
  1. <?xml version="1.0" encoding="UTF-8"?>
    % |+ S/ d* L+ l" h8 C  B9 N1 n& J
  2. <ui version="4.0">
    ( T6 g- }4 f( Q8 R, y$ W; X& ]
  3. <class>Widget</class>
    ( e: {: d" }: ~9 q$ c3 Q5 \0 @( [
  4. <widget class="QWidget" name="Widget">7 Z% _) m  I2 @& Y5 W4 O; X
  5.   <property name="geometry">
    1 a* @" [1 Z$ P
  6.    <rect>
    4 Q4 [! J! ]2 p1 o, ^) ^8 o
  7.     <x>0</x>
    * S0 j% ?4 ]( f' r
  8.     <y>0</y>- u$ b- @7 q+ v" f
  9.     <width>444</width>% F$ B0 N" W; }, U
  10.     <height>255</height>
    * q# [8 @) g6 c( F, X9 @$ K
  11.    </rect>1 b( }7 f2 W# o3 Q# ~5 g4 h0 E
  12.   </property>
    * X: C- t  D" n
  13.   <property name="minimumSize">+ R* _/ S8 s# [" S* M+ J$ E" a$ o
  14.    <size>
    4 A2 V0 V6 x# q3 q
  15.     <width>444</width>5 l, q* m8 O% g4 r  b# a5 G% I7 H/ n
  16.     <height>255</height>
    & f( a: x! Q/ W: w* x9 a$ H7 A; p& z2 p
  17.    </size>
    ' u' Z0 ]3 ~' M( w5 l- h4 U, ]
  18.   </property>
    . V; |- f1 m7 }( n' `
  19.   <property name="maximumSize">
    - Y* N6 e+ ^) b) k
  20.    <size>; `+ I8 ^& B4 }
  21.     <width>444</width>
    ! s; l9 T8 u9 ]# o2 K
  22.     <height>255</height>
    " M0 K/ H/ E# q! c- H2 ~" _. P
  23.    </size>
    - H& y) R$ r$ a. Z4 J7 o
  24.   </property>
    3 N! Y$ M+ x/ v2 C# P
  25.   <property name="windowTitle">- O* v, A1 p; ?  {* J- H
  26.    <string>SerialPortYmodem</string>8 K3 G3 V- ?5 }6 _8 |/ |# B
  27.   </property>7 _% c: o; t! w' u7 x6 I! G3 |" _# G
  28.   <layout class="QVBoxLayout" name="verticalLayout_3">
    , [# K# u9 a# Z
  29.    <item>
    # a0 W" K5 d4 W$ Y- O
  30.     <widget class="QGroupBox" name="groupBox">
    0 q+ s6 R1 {8 v, `9 G
  31.      <property name="title">) i" i. Y7 X7 @; X& p
  32.       <string>串口配置</string>9 N# Z5 k5 W0 Z+ ]
  33.      </property>& p/ X1 G& ~1 s' {$ i3 H4 U
  34.      <layout class="QHBoxLayout" name="horizontalLayout">
    & a: w3 k6 c- y0 M. G1 v
  35.       <item>& O7 j: K$ Q) \. s
  36.        <widget class="QLabel" name="label">
    ! d4 I& n6 a6 i  x2 K' b
  37.         <property name="text">
    # q0 s! E4 C1 {5 g
  38.          <string>端口:</string>
    , _/ d( v8 @' N) U$ q- N' D' {
  39.         </property>
      X% ]; n4 g2 S) T( }
  40.        </widget>
    ' \0 M" v- @' }& b2 J' ]' M5 h' l
  41.       </item>
    - \! q. L) Y: R
  42.       <item>  Z3 U" R+ H5 b# c% h! s9 T
  43.        <widget class="QComboBox" name="comPort"># S$ ]" I) z4 @9 e) @# M
  44.         <property name="maxVisibleItems">$ x  q6 j% F. Q' X& N( S! u& C
  45.          <number>12</number>
    9 ~1 x5 v4 ?9 S9 U  V$ [1 @
  46.         </property>
      u8 G6 V8 X% i" }
  47.        </widget>
    8 V% c& D0 O8 R# p# U
  48.       </item>
    4 F$ C3 J" U' ^- m  ?5 O- b
  49.       <item>
    , J& [$ N+ p: ^1 {
  50.        <spacer name="horizontalSpacer">7 l: g/ r2 D& g$ N% ^9 c
  51.         <property name="orientation">
    & r3 ~* [' m; F" \. w1 x
  52.          <enum>Qt::Horizontal</enum>
    ) b+ P9 n3 ~: f. J- V7 y$ V4 I& ]
  53.         </property>
    5 l- B8 ~- y1 I
  54.         <property name="sizeHint" stdset="0">  F; z1 `) d" i5 w  B5 N4 b
  55.          <size>
    & G) d6 H* H7 L) |
  56.           <width>40</width>
    * V7 q( T! Y: e) e. z6 o; z# ^
  57.           <height>20</height>
    4 _! B) L2 Y9 J2 |1 J( {# E5 I
  58.          </size>
    ( V8 ^5 g' L$ L: d/ E
  59.         </property>  w+ A$ X+ }, C' e
  60.        </spacer>
    & e* a7 @4 A( b1 d5 f# \
  61.       </item>% z) ?5 F1 z! n# i' M
  62.       <item>
    & K1 O3 S9 \9 G& v) d1 l8 h/ C
  63.        <widget class="QLabel" name="label_2">2 C( N3 s# F4 o* C
  64.         <property name="text">" {8 s% o) k- [% A
  65.          <string>波特率:</string>
    ( ^' x, y+ u7 s$ \
  66.         </property>; R6 c: [8 _" p* K0 [: w& D7 p
  67.        </widget>
    " P( @& u5 ?  J: J; M
  68.       </item>
    . d2 c8 W( h+ v9 r
  69.       <item>
    / ~& H" u! k( r
  70.        <widget class="QComboBox" name="comBaudRate">. Q2 X: {( a# k+ f8 p5 c1 v$ U
  71.         <property name="currentText">' e9 U6 c/ k" s; n( O$ c) i; ~
  72.          <string>115200</string>: b$ A3 M! ?* B6 O& z. g/ m! O
  73.         </property>1 L! C+ v, h3 y' ~/ a
  74.         <property name="currentIndex">5 Z  y3 z# P* v$ A' ^  @6 S. ]
  75.          <number>3</number>
    / G. q' Y0 ?$ F- @3 B/ k$ E- k2 L' |+ R
  76.         </property>$ K3 y0 N6 ]+ Y8 t" i6 c: C
  77.         <property name="maxVisibleItems">
    7 Z5 G. F: W' [4 H
  78.          <number>12</number>
    : A9 j8 t. T# N# d
  79.         </property>5 `  @6 k$ v+ z2 d, b' G
  80.         <item>
    5 K" K4 H( O  S6 k
  81.          <property name="text">$ B7 M' K6 g  l  f1 P! J& W( U
  82.           <string>921600</string>; P2 U* A" H8 X$ B
  83.          </property>' u; q. g9 C5 e6 {2 H
  84.         </item>) D+ G2 I, R. e  U
  85.         <item>
    3 a7 `$ W6 g: t9 Z' S% M- H) g
  86.          <property name="text">5 E' J4 I& D1 I" }
  87.           <string>460800</string>( v% `. |6 e8 E5 u9 k$ i
  88.          </property>4 R1 c" ^# F4 C- Y
  89.         </item>1 W2 W8 `7 \! n& z, G2 G
  90.         <item>& @/ v# i. e7 l* \  J; o
  91.          <property name="text">
    - j+ X1 l4 y& b) O1 y( B/ _/ H1 {* F
  92.           <string>230400</string>2 I/ A; u" S# _# Y! h
  93.          </property>3 T  H: E+ p% B  e6 M" @2 k7 Q
  94.         </item>
    & [, p# L9 B' v* W1 @( y( b+ _3 w. q' u
  95.         <item>
    0 n, g3 h1 b" z$ |$ }* V4 F
  96.          <property name="text">
    2 t' |) ^! [- l# {! X
  97.           <string>115200</string>
    9 e6 C8 t3 E3 k
  98.          </property>
    + n( N& I! m6 ^0 M$ n6 j
  99.         </item>4 h& q9 A* _* C6 W
  100.         <item>' H( {  W( S" r/ E2 U# @9 T
  101.          <property name="text">
    : U, N1 l  s7 ^8 ]! @: v' h
  102.           <string>57600</string>
    2 p4 Y) J  m+ F/ e5 a
  103.          </property>+ R3 l; @9 B; \" F
  104.         </item>
    & r% u; P% Q2 F1 }! o
  105.         <item>  k' w! {6 K- ]4 `3 N$ |( V
  106.          <property name="text">
    " b2 N! K+ a) Q
  107.           <string>38400</string>
    % z  F0 w8 a, I3 o3 `% N: ~0 x
  108.          </property>
    $ l. [! L& Z# B) M# M; H  m
  109.         </item>
    & H0 h8 r; e: c6 F; f
  110.         <item>9 Y; O& [- F4 U3 A( v- r' p
  111.          <property name="text">  ^8 ^- u; a- J2 W8 R% Y$ s7 Z0 Z
  112.           <string>19200</string>! D8 ]* c  j9 l' X* x$ _3 P1 b
  113.          </property>8 d) R2 f/ k* W1 x$ W* t
  114.         </item>) q$ A" J/ Q" Q$ }$ G9 e1 ]
  115.         <item>
    9 B3 M, H( h- w' y) M
  116.          <property name="text">
    / h; r8 }8 L, X; t
  117.           <string>9600</string>
    " i6 Y" ]+ x/ I; {0 v* t
  118.          </property>; z/ o  D1 ]7 J4 X
  119.         </item>
    9 @- `+ I+ i$ g+ \) I4 u  `' P
  120.         <item>4 [! P& e! ?0 T: E) ~) l" Y, o
  121.          <property name="text"># `3 E# u- Y/ T" m& H( k( d
  122.           <string>4800</string>0 {8 @, {. H; p# g
  123.          </property>
    5 A4 ]: j1 D/ q7 p8 `% h
  124.         </item>/ O( F; [3 n. a( W! y" N# n( @. X9 V
  125.         <item>4 q8 i7 V8 Y. ^, S  i$ Z
  126.          <property name="text">8 D1 H9 y% X2 g6 x( ~1 b
  127.           <string>2400</string>
    & p# x9 L) t8 ?* l- j
  128.          </property>
    # s9 Y8 Z' I  w$ f, v
  129.         </item>
    ! {0 N7 N* k$ X1 \6 B
  130.         <item>
    + u% ]1 n& a) G* ^
  131.          <property name="text">' B# Y) D2 W, C7 V
  132.           <string>1200</string>
    ( j, P- w3 S' w
  133.          </property>+ l9 x  X0 t# B+ {0 w/ \$ \6 z- }
  134.         </item>
    ; Y4 |6 Z& ?3 U2 R2 f6 f: x
  135.        </widget>/ I+ \* m2 x/ u' S
  136.       </item>
    : ]4 ?& ?; A4 e: f: K% u3 e
  137.       <item>/ P- Q3 y% f6 S% I( l4 q
  138.        <spacer name="horizontalSpacer_2">; P; P5 Y9 E( U- c* A9 @
  139.         <property name="orientation">7 y" v6 g1 p( Z: a# S
  140.          <enum>Qt::Horizontal</enum>. g- x/ Y& a0 L  o0 P
  141.         </property>; {, a5 J" u. n8 v, Q
  142.         <property name="sizeHint" stdset="0">. a8 s6 D0 b% u0 U2 E
  143.          <size>, l* S9 i, g. s/ x! q% _0 x
  144.           <width>40</width>& J3 J8 h6 k4 ]
  145.           <height>20</height>  b5 A8 J7 B1 w7 w! _( a8 U
  146.          </size>( q4 Z( {3 t- z
  147.         </property>: E8 u3 g4 _- I! I8 [% ^
  148.        </spacer>
      ^. i: `+ e3 ^* G7 b, o. w
  149.       </item>/ R6 x+ N: u0 E% z+ ^% P2 R
  150.       <item>- ~, W# Z0 j" M2 f: ~
  151.        <widget class="QPushButton" name="comButton"># y8 @1 U! D, n5 J3 t
  152.         <property name="text">9 X$ i4 Q; [2 c
  153.          <string>打开</string>$ H. C+ `7 @7 S8 U. M7 y$ x& P
  154.         </property>
    - n- q9 v2 s/ m3 Q- U# A
  155.        </widget>
    ; \0 L3 r' C" B  E0 a! g" V
  156.       </item>
    9 @$ j& H% j. f  c
  157.      </layout>2 |; `" _4 K1 X+ j# @# g  W
  158.     </widget>, I9 n+ D+ e: T+ M
  159.    </item>/ E+ f& O& s- H: e7 }
  160.    <item>
    5 Z  g9 ~9 x0 i9 E% j# h3 U
  161.     <widget class="QGroupBox" name="groupBox_2">( o& K$ S- [/ W( R, D4 ^
  162.      <property name="title">
    9 l& W* t6 Z- Z3 Y, n' O
  163.       <string>文件发送</string>. G1 ?# x; L9 E
  164.      </property>; ?9 k% W! v2 P6 P
  165.      <layout class="QVBoxLayout" name="verticalLayout">' {6 o$ R/ X: N" P
  166.       <item>
    ! n* W5 F& P9 h2 }# b
  167.        <layout class="QHBoxLayout" name="horizontalLayout_2">
    : E4 v* C& h/ r5 Q1 Q$ ^9 f) Y
  168.         <item>( p. t5 L. x# r) d6 e* x$ X
  169.          <widget class="QLabel" name="label_3">
    ( Q* G! G/ ~# C9 y! A9 Z5 u6 J/ N
  170.           <property name="text">
    : C( O) z; p# o8 d  I( |% ?
  171.            <string>文件路径:</string>
    + w$ u8 n8 {6 c2 e* R. [) @7 q
  172.           </property>
    . p" M1 H- @9 l0 d7 g5 r
  173.          </widget>
    ' w- j# _: J0 @, G+ h5 J
  174.         </item>4 L$ x! Z0 r8 j6 H; y1 u" C
  175.         <item>( ~3 l0 p) h) ]  x5 d6 L
  176.          <widget class="QLineEdit" name="transmitPath">3 ]( \( u3 e0 k( v8 Y8 D% a9 M3 C9 }
  177.           <property name="readOnly">3 k: b  s" X. l  P* ]# R1 g4 A
  178.            <bool>true</bool>
    % U  D' F  {9 A: y
  179.           </property>. g4 _0 ~7 n4 F: R
  180.          </widget>
    ; o% U' b- u7 g: f4 Y) P' J8 `
  181.         </item>
    + `# X' A  X# M* }( {
  182.         <item>
      M3 J& M: U* ]% s) J$ J
  183.          <widget class="QPushButton" name="transmitBrowse">
    4 A+ B: O+ y8 g1 r+ a9 R: |5 G+ f1 R6 W) Y
  184.           <property name="enabled">8 `, i) T0 z5 {: T2 R
  185.            <bool>false</bool>8 j4 o8 e$ x) w. e) @
  186.           </property>' h5 a; u( _0 |  y  n: r3 i" r
  187.           <property name="text">+ O  a0 a/ _2 r# F, l6 q
  188.            <string>浏览...</string>1 }3 W8 C4 u+ l$ c- H
  189.           </property>7 K& G$ ^( q- Y+ u. i7 W
  190.          </widget>/ L; A* `" R' g1 m. l8 ^) k; q
  191.         </item>
    " e# p% H4 o- L/ l: ^3 [+ T
  192.         <item>0 n. A* T$ u8 p/ ]( P0 V" D- D
  193.          <widget class="QPushButton" name="transmitButton">
    2 p. [, c% i/ u1 r! o5 w
  194.           <property name="enabled">
    8 \: D8 L. ?9 ?4 H9 Q+ U# d" C
  195.            <bool>false</bool>- j( W8 z& z1 b1 X* T8 _1 C
  196.           </property>
    ; O9 E6 V$ A# Y0 n3 o
  197.           <property name="text">$ a: C4 ^0 F2 v- r$ K; T  k
  198.            <string>发送</string>  O6 e* n0 l" M
  199.           </property>
    , H8 c; d6 x) r9 y5 L
  200.          </widget>
    ! }0 @5 @5 {6 i
  201.         </item>
      S0 G; v$ I( m+ m+ M7 S
  202.        </layout>' E# W3 P9 \: Q8 q, E2 y* [8 |
  203.       </item>& a2 Z, }9 D5 J' t
  204.       <item>
    8 N. q6 s' J- ]' T  |6 a
  205.        <layout class="QHBoxLayout" name="horizontalLayout_3">% ^- p  d, m6 l0 ^6 C) u& G$ A& g
  206.         <item># g: e4 p3 Q$ l& b. q
  207.          <widget class="QLabel" name="label_5">
    7 r- c/ m& D$ N  q/ A3 `
  208.           <property name="text">/ B& Y  [0 t/ G6 Q1 J$ J6 Y
  209.            <string>传输进度:</string>
    ; e5 z2 E8 Q% Z2 y
  210.           </property>
    & _* e3 q( R6 G8 {0 Z# D1 h
  211.          </widget>8 U* e6 c. B2 H1 ]% l
  212.         </item>% s/ a! {& k5 \9 D  b! n
  213.         <item>, i: A$ h/ F' L3 i/ O, v2 h
  214.          <widget class="QProgressBar" name="transmitProgress">3 e3 f2 K8 Y1 Q$ O9 ]
  215.           <property name="value">- B; c- r1 H1 Z& C! ^
  216.            <number>0</number>
    * |1 b5 g- ~  m/ ^+ c- L2 e
  217.           </property>  G% v2 d9 H2 L$ v8 \" u
  218.          </widget>
    # @7 `/ }: j- v* q7 P  ]5 O) U1 e% u
  219.         </item>
    ) x+ ], V, z* u2 B. E
  220.        </layout>
    4 X: Z: J2 m( |" e$ S$ k
  221.       </item>
    " B/ L: q3 x6 l/ [9 l4 R" G
  222.      </layout>; \# i- E9 D0 x7 \; ~
  223.     </widget>
    6 K" b" f! }8 d, c$ c+ s2 ]  j
  224.    </item>
    % `5 C) T% \4 I( C, L
  225.    <item>
    ! x% g* e- Q/ f( U0 d5 L2 X0 K
  226.     <widget class="QGroupBox" name="groupBox_3">/ y; r5 N2 l3 f1 t' W& o/ f2 U
  227.      <property name="title">
    # @5 a+ M! o/ t$ [# l2 O4 E9 t
  228.       <string>文件接收</string>
    2 z3 N: x' D9 k
  229.      </property>
    8 e) g" M" q0 C$ e% X* Z. t
  230.      <layout class="QVBoxLayout" name="verticalLayout_2">1 n4 I# z: D5 S' _$ F& `8 \7 W
  231.       <item>, b* e$ n$ _3 C1 y5 u
  232.        <layout class="QHBoxLayout" name="horizontalLayout_4">6 V8 i; x% p1 U& F" p' Q: s
  233.         <item>
    9 H; \7 Q: Q0 o/ V
  234.          <widget class="QLabel" name="label_4">
    % v: e! K7 _4 C: k8 `
  235.           <property name="text">
    ) a( t  v( @% n
  236.            <string>文件路径:</string>0 d# u# J' U6 u# J' v
  237.           </property>
    " `6 x/ ]! O0 y# }
  238.          </widget>
    3 E, F) i* \- I7 R0 p
  239.         </item>
    : P7 C9 H" ]+ t/ E% }
  240.         <item>
    ; |; q  B- V6 `( a1 i
  241.          <widget class="QLineEdit" name="receivePath">
    ! C- R: s. p+ F" c
  242.           <property name="readOnly">
    ( ?+ Z# s. ^& Q4 N# W4 C: X6 O
  243.            <bool>true</bool>
    8 y9 |) ?$ p: |$ o
  244.           </property>( d9 D6 h6 F2 i/ C3 {  G) E
  245.          </widget>: Z2 p2 r: ?: x; q3 ~
  246.         </item>6 W1 o: N/ z+ l
  247.         <item>
    1 [) E9 U6 R3 L- t3 m
  248.          <widget class="QPushButton" name="receiveBrowse">
    # C0 V& ^( n6 L5 R5 [( Q7 O1 t
  249.           <property name="enabled">
    5 C0 Q5 N) y0 q4 p# K
  250.            <bool>false</bool>
    $ ^* n: R2 u( N: {
  251.           </property>
    & h. Q# h0 |$ O
  252.           <property name="text">
    ; R# `1 K) q3 z/ X: l0 |
  253.            <string>浏览...</string>$ Y  @1 U$ G$ w% `% T$ o$ C% d
  254.           </property>  \. H  F! x, E! C1 W6 S- e! ]2 b
  255.          </widget>4 Y/ }: S" H1 P
  256.         </item>
    3 M: Y7 G2 L! A+ z1 g' Z
  257.         <item>4 }. M2 x1 u" w( v+ K( o3 [6 y6 F
  258.          <widget class="QPushButton" name="receiveButton">& o1 @- C6 P. s2 P6 W) z
  259.           <property name="enabled">
    4 X5 d/ ]4 @7 H. C) e
  260.            <bool>false</bool>
    " N% E7 w' B1 {6 B$ d) d1 _
  261.           </property>
    ; |4 }% o5 d7 ]' Z) c
  262.           <property name="text">
    4 r5 _# i" z) ~, C  b4 M
  263.            <string>接收</string>; n! P  o0 y* }# g
  264.           </property>) K7 H2 V3 y: `; ~5 p
  265.          </widget>
    $ `) g, R' B1 e" e6 ]6 J
  266.         </item>0 e/ K# g3 z% `  U8 a/ }' m( {; S
  267.        </layout>
    7 w" l/ S* C4 ?" {) m
  268.       </item>8 B5 P& |' ^! v* l: e2 X
  269.       <item>
    7 i, s2 V% D/ u6 O0 x: O' _
  270.        <layout class="QHBoxLayout" name="horizontalLayout_5">! F& g4 \  K+ I% |8 \2 f
  271.         <item>
    4 n; |% g- W; h$ y7 q2 ?1 l1 G
  272.          <widget class="QLabel" name="label_6">
    6 J% c* V" X) y; W
  273.           <property name="text">8 h5 j* y" O& v. l9 X# k# V
  274.            <string>传输进度:</string>+ ~1 S: A0 Q5 [& e1 h0 r1 }* H
  275.           </property>- R) d$ ~9 ]- k: T7 w7 w" u
  276.          </widget>  I& q4 }# ^7 m; _, k' X
  277.         </item>& u9 }1 ]& q. r1 _: A, B( E
  278.         <item>7 j% n. N( K" w% p( X: A  n  e1 z
  279.          <widget class="QProgressBar" name="receiveProgress">
    2 O% ~* E' |- b) @. g5 O6 `! s
  280.           <property name="value">- E  R  v9 r7 V% h5 I  H9 ]# G
  281.            <number>0</number>
    8 L# f: \2 o! j, {- i- Z2 @
  282.           </property>7 R. u4 m. j# u/ M" ]2 Z: s1 M  ?' ^
  283.          </widget>+ w" F9 ?% e& j. i) i: \
  284.         </item>0 e# n8 G& H- l
  285.        </layout>
    : Y& k" }, h) ^! J
  286.       </item>
    4 c" T/ d* @: [7 _( w
  287.      </layout>
    3 t, c6 Q) G, y  }  g
  288.     </widget>& H  Z6 R; w5 s( |0 [
  289.    </item>! e6 K+ O0 e+ N5 _
  290.   </layout>0 A. a/ h; r4 ^' t7 b1 e
  291. </widget>( g* v0 a4 l7 o5 ~5 A
  292. <layoutdefault spacing="6" margin="11"/>' S7 A- s3 C, l: ]% V2 u
  293. <resources/>
    - i% Z/ C' Q3 x- S; u- X. q
  294. <connections/>
    4 @6 q1 @- }) V- F
  295. </ui>& r, |- R1 ]5 ~# Q# Z
复制代码
, q, D0 d( M8 R/ b$ b$ j8 L
      widget.h文件
7 Z) b5 L- p8 k1 h: t
  1. #ifndef WIDGET_H( X! J1 U8 |1 A' v9 K
  2. #define WIDGET_H7 L  Y6 B: X! W. T* b# s8 k

  3. 5 L; n7 y  \- `3 r
  4. #include <QWidget>
    $ ^$ b$ `. m& B7 c  e( y1 e+ Q6 g
  5. #include "YmodemFileTransmit.h"
    4 J" K! C1 M9 j& @1 z6 R
  6. #include "YmodemFileReceive.h"8 }/ Q  |* L  {5 h; r3 o
  7. # K$ b* q7 V* d
  8. namespace Ui {/ n, s# E+ {2 d) p, }# {
  9. class Widget;* u; b8 Z  d7 @1 A  Q& w8 [
  10. }# [) k1 x% ?$ ^5 |- }

  11. $ ~8 S5 w! i+ B6 C4 E8 r5 d
  12. class Widget : public QWidget$ K+ h6 V9 n3 o3 @
  13. {
    5 v2 K! D* U4 ]( r- t
  14.     Q_OBJECT
    7 L+ E+ x6 p8 c& v% g) }1 T0 ?
  15. 3 u1 u& @; l$ s
  16. public:! ]0 A- _  D& N' }+ }' \4 W$ n
  17.     explicit Widget(QWidget *parent = 0);
    5 L' t1 v( X# f1 r
  18.     ~Widget();
    1 a! B, t2 @; R; i; l+ r0 n

  19. 8 H$ w$ G: Y! F% F2 }
  20. private slots:
    ! I: N0 [! H$ a6 u
  21.     void on_comButton_clicked();
    , B& U/ @2 C" l" n0 U
  22.     void on_transmitBrowse_clicked();
    3 X6 T0 O& c% |; ?" @1 b5 R& M' n
  23.     void on_receiveBrowse_clicked();
    9 q- ]* J3 d- Y8 f# C
  24.     void on_transmitButton_clicked();
    3 F9 p" G3 N: \7 T
  25.     void on_receiveButton_clicked();3 ?$ t( x: k6 e; C2 Z7 u" S  w8 R7 M
  26.     void transmitProgress(int progress);/ ?* d5 T' m" Q( N
  27.     void receiveProgress(int progress);
    5 o) ]7 N; |$ m- h
  28.     void transmitStatus(YmodemFileTransmit::Status status);4 l7 N- P+ g# E: n  w
  29.     void receiveStatus(YmodemFileReceive::Status status);
    ' H( \7 Z1 Y0 k6 `9 z/ e5 d

  30. % h& y$ b6 r( E# u" \! w. t/ G
  31. private:
    % V# n# U! T$ t/ L, b7 T
  32.     Ui::Widget *ui;
    " R2 G% Y, @0 Q
  33.     QSerialPort *serialPort;
    + o( o% W9 M% \* F* N9 O5 s/ c* K3 Y
  34.     YmodemFileTransmit *ymodemFileTransmit;
    ; n- ~) C1 {) q3 m0 S
  35.     YmodemFileReceive *ymodemFileReceive;
    $ H( d) P  D) o, Z5 m  p
  36. 6 J8 e( Y; z9 a5 R! d7 D- J
  37.     bool transmitButtonStatus;
    : b: o, t$ p( F
  38.     bool receiveButtonStatus;+ v! P5 \( ~) A$ k
  39. };6 c+ x2 S$ M1 S, ^0 i

  40. $ k- V5 m7 k8 `7 y
  41. #endif // WIDGET_H1 |/ s% G; y; D0 e
复制代码
+ U9 Z. ^8 }! l5 R
      widget.cpp文件
3 W: L, |: ?4 n' W1 I0 X/ Z
  1. #include "widget.h"
    ; `9 \* f) Z9 v# ]/ Y% k/ c
  2. #include "ui_widget.h"+ g# W) k3 C( @/ \( ~; \
  3. #include <QMessageBox>
    0 b+ c' R) z: V! ^
  4. #include <QFileDialog>3 Y* d& a& W) x" ]/ ~, b
  5. #include <QSerialPortInfo>
    4 w3 x: x( y2 X6 q8 n
  6. , |& j' e0 k. F- u6 i+ i
  7. Widget::Widget(QWidget *parent) :' x2 Q5 y+ i" L9 S% F; ]" ]2 B. \/ |
  8.     QWidget(parent),: w: ?  P; ]+ h1 g4 f; P1 p
  9.     ui(new Ui::Widget),  i5 k0 Y! X" \3 g! [) G$ h
  10.     serialPort(new QSerialPort),
    # q$ m- P3 [$ P6 ~
  11.     ymodemFileTransmit(new YmodemFileTransmit),
    $ k2 K8 s3 Q/ ^# B& L
  12.     ymodemFileReceive(new YmodemFileReceive)' R' p! i8 W' e' I4 l0 H* p
  13. {: M+ T7 b9 B# d
  14.     transmitButtonStatus = false;6 r8 l6 O  J7 `! @- c% Y' K
  15.     receiveButtonStatus  = false;
    6 E  Y7 S" p* c
  16. & u( g* m& m0 z! E" M0 q# E
  17.     ui->setupUi(this);& @+ ~- M/ C& M9 Z/ C
  18. $ ]$ ~, x2 @9 i' N6 P0 y
  19.     QSerialPortInfo serialPortInfo;
    ' }( s7 a. E+ g0 c/ [! y
  20. % g; x, e' _/ o- x% `
  21.     foreach(serialPortInfo, QSerialPortInfo::availablePorts())
    # y1 q3 t+ E, P5 s  d6 K" p6 N8 g
  22.     {
    ) s0 ^; a$ m7 g( o! l( K) o% [, H
  23.         ui->comPort->addItem(serialPortInfo.portName());
    4 H+ @9 f, l0 o
  24.     }
    : U) \, c, V' j+ r

  25. % j6 F( f( T" H* \, g
  26.     serialPort->setPortName("COM1");7 r0 W8 K, @+ Y9 A$ r8 w; r) C' C
  27.     serialPort->setBaudRate(115200);  C/ A' }' B0 ^0 X
  28.     serialPort->setDataBits(QSerialPort::Data8);; L. k: k# c$ F* l3 A- z
  29.     serialPort->setStopBits(QSerialPort::OneStop);
    7 Q, e  T9 r4 Z8 `1 Z
  30.     serialPort->setParity(QSerialPort::NoParity);0 a# @' }, J, q/ Q7 W; d( i: @4 C6 Z
  31.     serialPort->setFlowControl(QSerialPort::NoFlowControl);
    6 `0 M* A8 u- a/ p$ G6 Q
  32. ( a8 l6 a- l. r  _$ r
  33.     connect(ymodemFileTransmit, SIGNAL(transmitProgress(int)), this, SLOT(transmitProgress(int)));2 D* K/ ^! l- k, j6 f: V
  34.     connect(ymodemFileReceive, SIGNAL(receiveProgress(int)), this, SLOT(receiveProgress(int)));5 t; R2 i: e% G; v
  35.     connect(ymodemFileTransmit, SIGNAL(transmitStatus(YmodemFileTransmit::Status)), this, SLOT(transmitStatus(YmodemFileTransmit::Status)));
    2 a4 S1 @/ E3 t
  36.     connect(ymodemFileReceive, SIGNAL(receiveStatus(YmodemFileReceive::Status)), this, SLOT(receiveStatus(YmodemFileReceive::Status)));  p; R: M# i9 f, n' o
  37. }5 @4 `, x) F: l
  38. , e$ N3 X8 H( t1 O* ~% p5 u
  39. Widget::~Widget()* u8 K7 r4 @& X8 @! y* n
  40. {
    % c! P& U( R! ?4 ^+ X+ K
  41.     delete ui;4 [( Z# T. o; j6 [. C  d; x
  42.     delete serialPort;7 B6 ]+ y$ o  I
  43.     delete ymodemFileTransmit;# t7 B2 v+ F. N% E
  44.     delete ymodemFileReceive;/ d% l2 Q1 I9 U! F3 O0 D- R4 s+ }
  45. }+ J' M! e; e. p3 s: G- ~! M) ]
  46. ( F4 v: g. o, G4 }6 k+ q7 v# o9 ~
  47. void Widget::on_comButton_clicked(), u! a2 H) T( y# p1 u2 q- R
  48. {
    & i6 O+ C% r' `- n) s+ P
  49.     static bool button_status = false;
    % x$ G$ t/ U4 O& w# F

  50. 3 n7 U7 a( E7 o. _/ [- l
  51.     if(button_status == false)
    ) T7 p- A; p" V: |' @1 K
  52.     {
    0 |! ^0 j) `& a# T% s
  53.         serialPort->setPortName(ui->comPort->currentText());
      X: B8 b6 t$ A* P; C
  54.         serialPort->setBaudRate(ui->comBaudRate->currentText().toInt());* b+ Y% I$ {: U0 w5 o
  55. 3 M* U$ q# t& P4 Z
  56.         if(serialPort->open(QSerialPort::ReadWrite) == true)
    : ^6 \$ k% l! J( \7 U% C+ U4 A3 x
  57.         {
    % ^+ c9 R4 U0 g8 g: ?7 ^: J) N
  58.             button_status = true;
    ; c* v, R- ^% g0 v

  59. ! W5 g. D# E  B7 C+ N  }0 P/ v
  60.             ui->comPort->setDisabled(true);
    3 V  P4 s) Q5 N* d% y
  61.             ui->comBaudRate->setDisabled(true);
    6 @# M5 W, z+ F! `+ X& h7 h
  62.             ui->comButton->setText(u8"关闭串口");
    1 [, n9 F) J! }

  63. 2 {: [, D5 T7 j& a. A
  64.             ui->transmitBrowse->setEnabled(true);; O, R7 d  z/ r- ?
  65.             ui->receiveBrowse->setEnabled(true);6 P/ b6 `9 R7 V9 e
  66. 3 p* F% O  t; D/ Y, Q+ m1 G
  67.             if(ui->transmitPath->text().isEmpty() != true)2 J4 z) N# z- N' O; @
  68.             {+ A1 `/ c  P6 `8 [5 U
  69.                 ui->transmitButton->setEnabled(true);
    0 m/ |( @; i# C' a. A
  70.             }# r+ z& V, k  K3 c. R: V, b5 F7 A
  71. 4 m  \7 \* [4 }) z2 M; v$ S: x" k
  72.             if(ui->receivePath->text().isEmpty() != true)
    ( o, q$ _8 n; B6 K! }; k
  73.             {
      ~( S3 o5 f- k% _1 I5 I$ K+ g) Z
  74.                 ui->receiveButton->setEnabled(true);$ r' m1 Y4 Z) h' [# z7 v( {* \+ g
  75.             }
    , t. q' l+ U: b
  76.         }
    $ M3 p3 ]  k( D! ~" M6 m7 i3 r4 A- y
  77.         else5 R' g1 Q1 r3 y6 R/ r. s8 _* q; i. k
  78.         {9 d* Y; z  d  o+ w& z
  79.             QMessageBox::warning(this, u8"串口打开失败", u8"请检查串口是否已被占用!", u8"关闭");
    ' o. U3 X" F+ t- E0 v7 P$ o
  80.         }
    1 Z. g0 g4 x7 o4 K
  81.     }# C$ @( f  ?+ l! F5 A
  82.     else6 x' S  z6 J; G0 e" J: V+ k
  83.     {
    , Z8 D6 @( i) [: ]  `
  84.         button_status = false;
    - O6 h$ O- U0 R* _: H

  85. 9 \! B5 Z1 |; q- v( j8 u/ B/ X
  86.         serialPort->close();" \( J" e: Q8 u5 T: S4 L

  87. ; G5 ?$ g! r- v
  88.         ui->comPort->setEnabled(true);- C! [, B. N: `) j2 Q8 p
  89.         ui->comBaudRate->setEnabled(true);
    ) X/ ?  F7 }. s4 S2 m7 G( ?# \
  90.         ui->comButton->setText(u8"打开串口");
    : l! ~% y9 V2 [6 o, X1 y
  91. 5 Y, }5 P8 x' R8 }; c3 k+ Q) f+ w
  92.         ui->transmitBrowse->setDisabled(true);5 E1 P  R/ l" t
  93.         ui->transmitButton->setDisabled(true);
    / ~" A+ O8 h$ {+ x
  94. / B) O; L- q3 t. V- l/ q3 T
  95.         ui->receiveBrowse->setDisabled(true);
    # A  @% w4 Q8 C
  96.         ui->receiveButton->setDisabled(true);
    9 B1 h: @8 s! J- z6 a
  97.     }& R* y+ E$ u3 _0 r9 ]4 v) _' d2 {
  98. }
    0 E5 \8 x0 R2 W% b

  99. 5 F: P! w8 G1 d, \. u- s  B
  100. void Widget::on_transmitBrowse_clicked()  Y' u7 j$ z4 ^4 q
  101. {9 X& e  t) [" X, W! W& O% e
  102.     ui->transmitPath->setText(QFileDialog::getOpenFileName(this, u8"打开文件", ".", u8"任意文件 (*.*)"));
    9 F( Y+ P! p9 Q+ @4 M" [8 }" E1 Y! x

  103. - w+ d  }4 V6 U$ n8 E
  104.     if(ui->transmitPath->text().isEmpty() != true); Y9 `- ~8 z) T, ~3 C3 V
  105.     {; L. T8 p" P1 v
  106.         ui->transmitButton->setEnabled(true);
    ; v4 j4 V. i5 }) @
  107.     }
    0 A, X( ^/ K/ M! M1 I7 |4 X6 C4 \
  108.     else2 {1 q8 E$ F+ ~" _' l8 `" c$ H
  109.     {' o, }& Y% o0 }. m% P) J6 z
  110.         ui->transmitButton->setDisabled(true);
    2 C9 p. o2 t. i5 L. B! i
  111.     }
    6 w" I, {" f" P) b7 K
  112. }. l" u: I% j1 O! W
  113. ; p+ {1 D$ x5 E) u% E( v  P% m0 @
  114. void Widget::on_receiveBrowse_clicked()- D6 W" Q% p2 g. F
  115. {
    9 P! J2 _' o% _( G& P2 M/ @
  116.     ui->receivePath->setText(QFileDialog::getExistingDirectory(this, u8"选择目录", ".", QFileDialog::ShowDirsOnly));. U: |6 i: d, u. j4 m; j% {# K3 k0 t
  117. - U1 J8 X3 g1 X4 N( e
  118.     if(ui->receivePath->text().isEmpty() != true)! _2 ~0 P# ?; i, [. v
  119.     {
    . V" ~& p' U) L3 n. g
  120.         ui->receiveButton->setEnabled(true);
    7 i8 x( x0 x2 m9 O
  121.     }3 X! k* i: V9 Q" q! q+ D
  122.     else& _& r! P8 u, i5 X
  123.     {
    3 l! Z% W: S/ o3 M
  124.         ui->receiveButton->setDisabled(true);( z2 g$ J$ I; B
  125.     }
    - ]$ w7 A" D8 ^- j# x( G5 z
  126. }
    % H1 F8 C. F: X6 T; P% O$ _

  127. 0 T# z6 Q' v6 q2 z5 v
  128. void Widget::on_transmitButton_clicked()1 h( X- A" q# i3 r+ `
  129. {
    : s3 d" v/ Q& f- i$ n5 W% P
  130.     if(transmitButtonStatus == false), i6 @5 w! P( V3 s
  131.     {, g4 o: P! q4 a% l5 t
  132.         serialPort->close();
    2 T" D  I3 @  q1 Q6 y3 k

  133. , f8 i: a0 p: s. d! |
  134.         ymodemFileTransmit->setFileName(ui->transmitPath->text());
    1 `6 _2 \/ M- E" O& o
  135.         ymodemFileTransmit->setPortName(ui->comPort->currentText());
      q! t- r) Z+ n) ~- v) I
  136.         ymodemFileTransmit->setPortBaudRate(ui->comBaudRate->currentText().toInt());% B* I! k5 e! H3 g8 O* }. w5 O0 D

  137. $ j: H% q2 i4 J$ G( _$ U- y
  138.         if(ymodemFileTransmit->startTransmit() == true)8 H9 F" C; J' `! g/ P' \) s
  139.         {
    ' |0 V6 z( r1 m  @
  140.             transmitButtonStatus = true;
    ; {$ \8 K+ x2 m6 k" ^

  141. 4 `( P( r: |( E% a# o' H
  142.             ui->comButton->setDisabled(true);3 }  v. {7 k1 m: ~
  143. " n( S8 W. e; z$ `! d: H+ k
  144.             ui->receiveBrowse->setDisabled(true);
    ' D& n: c; b% l/ c: d5 P( c
  145.             ui->receiveButton->setDisabled(true);
    : P! a0 K9 F) L- z& u% P3 t( k* N

  146. . ~# u2 l% n8 i! y, {
  147.             ui->transmitBrowse->setDisabled(true);  B. k" ^* M: e1 o
  148.             ui->transmitButton->setText(u8"取消");. v) ^: P" h; X+ i- i( e
  149.             ui->transmitProgress->setValue(0);7 U. i$ a1 A# Y) f* @. h0 s6 b
  150.         }2 Y3 p! J( d# w# |9 Q% o5 [, N, c' ^
  151.         else
    4 E+ r: m* g3 w" n5 B  q! ^& r
  152.         {
    0 J# u$ C' @% F* k1 M
  153.             QMessageBox::warning(this, u8"失败", u8"文件发送失败!", u8"关闭");
    0 j$ b& K3 e' Q. W3 l  \0 M. Z
  154.         }  s  W- `/ t8 |- r, @
  155.     }) U/ y1 s: C. q- P( u+ c
  156.     else) X6 S9 j0 X% {2 E  a% ^2 u# M1 ~7 B
  157.     {0 |2 u6 I# ]! Z9 P
  158.         ymodemFileTransmit->stopTransmit();9 X  W7 S. A0 J7 A! {& H
  159.     }: H- ?5 x) p1 X- p0 l' E9 B5 M
  160. }
    6 {* [' u6 A, O  \: D! o

  161. + D% F4 F! A  E$ q
  162. void Widget::on_receiveButton_clicked(), u; _8 Z" e! M% J) R) ~+ ^, J
  163. {
    2 R+ [: m3 ~$ l0 u8 L
  164.     if(receiveButtonStatus == false)
    1 J8 B. l  G# A2 p$ u1 }, A, _
  165.     {
    ! p6 Q6 J5 V0 |) z
  166.         serialPort->close();
    7 O: n  Z2 A& r) G4 I! |8 W& Z

  167. 8 I: k' e. w5 \9 T, Y" o& ^. B
  168.         ymodemFileReceive->setFilePath(ui->receivePath->text());: K. [" G" g0 D" a; S. j
  169.         ymodemFileReceive->setPortName(ui->comPort->currentText());7 [% V, X; N% {4 W& K
  170.         ymodemFileReceive->setPortBaudRate(ui->comBaudRate->currentText().toInt());! Z' c4 W( x" N# B3 K

  171.   `7 e! p- v- S7 f+ e: |
  172.         if(ymodemFileReceive->startReceive() == true)  w, x8 i- T  S. ~4 z. h
  173.         {' x! j. R- D! D0 f) `
  174.             receiveButtonStatus = true;
    " F# m" B3 p9 g! }) @

  175. , I5 @9 K+ `. v5 |7 B" Y
  176.             ui->comButton->setDisabled(true);
    ; t4 ?  v: E% F8 s7 P# H
  177. 9 C; Q% ~0 }. f/ h# |. t
  178.             ui->transmitBrowse->setDisabled(true);
    / F* i# [$ t& n  Z- @& e
  179.             ui->transmitButton->setDisabled(true);
    9 ?1 a# L+ E9 R
  180. - i: P3 {1 |! F0 z
  181.             ui->receiveBrowse->setDisabled(true);
    1 s9 ~8 Y3 d  W8 `
  182.             ui->receiveButton->setText(u8"取消");
    / m' Z9 k$ k% j. K, ]2 X. t* R0 y' G
  183.             ui->receiveProgress->setValue(0);
    4 p$ B  ^& m$ I3 O+ k# _1 t
  184.         }
    " T' v5 T+ j  W! o$ Z0 S9 p4 P" k
  185.         else
    7 L1 V) b: T( d2 G1 O  ~
  186.         {) r1 `) t- K( o7 N
  187.             QMessageBox::warning(this, u8"失败", u8"文件接收失败!", u8"关闭");; l5 `) f/ [1 U
  188.         }
    , M2 X: Y: s: g% }- ]. H2 a* U4 P
  189.     }6 N! G1 y8 c6 q
  190.     else/ s6 r0 ~2 O/ `; o% R! a. V
  191.     {9 S9 r8 V# g9 G) H3 `
  192.         ymodemFileReceive->stopReceive();
    4 b& e+ B4 l# Z
  193.     }  K7 P7 ~9 X# ?) T
  194. }
    , X- k  ~* @# N" P

  195. ; K" Y, N8 m0 [7 i& R
  196. void Widget::transmitProgress(int progress)
    / F& p( }1 P. `; v4 @" r
  197. {
    - w- I# E% w: ]! \8 g
  198.     ui->transmitProgress->setValue(progress);
    . X6 e3 {, a4 H  q1 l
  199. }$ r2 R" p: w2 ?5 m

  200. 0 l( {8 X; O7 Q7 H9 m
  201. void Widget::receiveProgress(int progress)
    - K! W" H! r5 z* L# ^/ v! v" i% I
  202. {3 W$ a# y0 B2 g, u# k  D
  203.     ui->receiveProgress->setValue(progress);
    & m1 [% |' |) m' R
  204. }: r' J! [7 l1 V& F

  205. 5 }7 \! Q6 {, ?! T8 t# B, \6 u
  206. void Widget::transmitStatus(Ymodem::Status status)( _3 V3 N3 t* M$ ?
  207. {6 A  a5 ?9 v3 w
  208.     switch(status)! G2 I2 y7 @1 t2 R
  209.     {: h2 k7 f( p: r8 d. ^8 c5 b) W
  210.         case YmodemFileTransmit::StatusEstablish:) z; R: a! }; f+ S$ O% N$ B9 }
  211.         {+ k2 u+ i: F% P
  212.             break;% a) o) R9 ~* W  l* l$ G$ {
  213.         }( o1 w/ ~% H; A6 [+ V, \0 \0 H

  214. ! {# d5 [9 j+ B
  215.         case YmodemFileTransmit::StatusTransmit:
    : R5 f1 ^# @7 g) t
  216.         {8 P( y- @. B& A. ~. c
  217.             break;
    5 m; K) O% k" v5 B
  218.         }
    9 [' ~0 d  A( c! l6 S( ?

  219. 0 k* c) J+ T% k. U8 f& G5 X
  220.         case YmodemFileTransmit::StatusFinish:
    7 r* W# v3 V  {. ?1 P2 a# {
  221.         {+ L  `' M$ T$ B
  222.             transmitButtonStatus = false;
    % _  |( X) U; \) M5 n1 V4 n

  223. 6 v" g  c% P! C" I
  224.             ui->comButton->setEnabled(true);
    + `0 d' q- M; v) Q6 ~" c
  225. " B) p2 y. c: r, D
  226.             ui->receiveBrowse->setEnabled(true);
    $ B4 V, ~, F8 D" z
  227. 8 Z+ [! Q' ]- C; z! i
  228.             if(ui->receivePath->text().isEmpty() != true)& ~4 K, j5 K& ]2 c. H: |
  229.             {( B4 [4 i8 c, v# m: B: c( L. ]
  230.                 ui->receiveButton->setEnabled(true);( \7 V/ u- Y- w7 p' L
  231.             }$ F" Y* L& y# P6 R. [4 A

  232. 8 d% X! B4 P8 M4 o
  233.             ui->transmitBrowse->setEnabled(true);9 K; A7 I0 s# C+ X4 X" D$ A
  234.             ui->transmitButton->setText(u8"发送");
    9 R( M' z# E- L5 |
  235. 8 a. ^! I% G6 {0 M$ y$ @
  236.             QMessageBox::warning(this, u8"成功", u8"文件发送成功!", u8"关闭");$ e! q* u! e1 ~# N6 H

  237. 1 U  f9 Q6 g' ~, s+ `' R
  238.             break;
    1 z7 y. J8 d3 ]
  239.         }2 V7 H8 x; l1 ~; o% |
  240. , M, U7 d9 {) O
  241.         case YmodemFileTransmit::StatusAbort:
    ( k, P: f3 ^6 S2 m4 ~
  242.         {
    - ]1 W) F" u# s. {, s! \
  243.             transmitButtonStatus = false;6 k+ e7 M/ E6 Q$ Q+ Z/ L

  244. 0 H/ b3 y0 ?" G" D: U/ i! s
  245.             ui->comButton->setEnabled(true);
    . ~4 f% Q$ P2 k

  246. 4 a8 \$ k' l1 @+ V4 ?" G4 S, ?
  247.             ui->receiveBrowse->setEnabled(true);2 N3 q  C. `$ E( q

  248. : k: h) @% C8 D
  249.             if(ui->receivePath->text().isEmpty() != true)- D- i: ~+ I. k6 I7 a
  250.             {, W9 w. k# n% X5 h/ ~7 r8 W) U2 f
  251.                 ui->receiveButton->setEnabled(true);) @' |  r, }$ c6 o$ v7 j
  252.             }( \8 z. ~8 h& o' q# y
  253. : k6 y/ y2 }8 Q
  254.             ui->transmitBrowse->setEnabled(true);
    ; Q4 j! _2 }3 \, |8 ~1 q, e2 G* U
  255.             ui->transmitButton->setText(u8"发送");& M  T2 u* a+ @

  256. ) [9 u( x. P! x
  257.             QMessageBox::warning(this, u8"失败", u8"文件发送失败!", u8"关闭");; Q# G+ f8 e# K: C" z
  258. / E; h4 n$ _" R3 w" p) q1 Z
  259.             break;# u8 r4 x1 ~$ q* x8 }( ^; {" S3 |
  260.         }$ q; P, G( Z, P7 X# r6 }
  261. - V/ _$ v6 R8 o3 }) u/ m( o
  262.         case YmodemFileTransmit::StatusTimeout:
    8 j8 ^' ?3 \% q$ u" t0 S2 d4 }8 m
  263.         {
    7 ~& |. e# R) a) v0 w1 C' U
  264.             transmitButtonStatus = false;
    - U+ q1 _. t+ r& z; e* R
  265. 9 g) K: h" P1 _5 w7 ^- Y4 S+ q
  266.             ui->comButton->setEnabled(true);' x. q+ H. M4 y% C, ]; Q

  267. ; v& E, {6 S% ?
  268.             ui->receiveBrowse->setEnabled(true);
    / e3 S6 O: V4 ^  |+ K/ y, O" i
  269. + \2 _' B/ o9 s
  270.             if(ui->receivePath->text().isEmpty() != true)
    , s) P! W% M1 f
  271.             {
    2 N7 G$ E: }! l+ p2 \
  272.                 ui->receiveButton->setEnabled(true);7 s* y# \* F& l6 `
  273.             }8 Z8 C1 q# p& R, @4 s, e' L- c; m9 q
  274. " ^' V- N# `3 W  h5 D3 b! F: b
  275.             ui->transmitBrowse->setEnabled(true);$ q# M& Z/ L9 j7 K. U
  276.             ui->transmitButton->setText(u8"发送");* q' a: x: r  L) P. B: N+ D

  277. ' L* e* v8 `" K- P
  278.             QMessageBox::warning(this, u8"失败", u8"文件发送失败!", u8"关闭");
    9 ^) ~2 V# K! d% o# A
  279. ' P% R0 m2 h+ R8 I
  280.             break;) K. j& }, S, E/ ]+ C
  281.         }4 K2 D, X! m* D" T3 B( J+ g! B; ]

  282. % M& e7 c, l2 w, d
  283.         default:
    " {( A# C, t  E0 K
  284.         {) U2 z. d2 c2 ^# m
  285.             transmitButtonStatus = false;
    + A1 j' e% X& _* V( e1 R2 I( r  O
  286. 6 d' P- q1 |: c5 i
  287.             ui->comButton->setEnabled(true);  h. m" a/ A6 m# {& s1 K

  288. ' O+ u$ O' e9 B. |6 l) y
  289.             ui->receiveBrowse->setEnabled(true);4 i" q8 D, U0 y5 N, O7 |- M4 n3 t. [

  290. , y9 I) [# Z+ U6 V$ f8 D9 [! y
  291.             if(ui->receivePath->text().isEmpty() != true)
    9 w9 L% X) A7 Z- q6 y4 H
  292.             {
    4 x/ T8 H3 i' J# s# G, Q8 L
  293.                 ui->receiveButton->setEnabled(true);
      G; z) o4 Y, l) o$ O2 r
  294.             }0 O* n% T0 s0 Y. t
  295. * C& g  B% m/ q9 b" X
  296.             ui->transmitBrowse->setEnabled(true);( E, E* H/ T" ~/ C, T( A, C2 F0 h
  297.             ui->transmitButton->setText(u8"发送");
    " M: h! r& A5 U

  298. ) _( H$ e) T8 u4 o# G
  299.             QMessageBox::warning(this, u8"失败", u8"文件发送失败!", u8"关闭");8 O$ t) z7 H4 F, N9 I0 E2 f* S  M
  300.         }
    7 t9 W. S9 d+ ~6 J' D/ q: C! }
  301.     }3 o5 S  T$ b. y9 Q
  302. }+ e  S% d& l; |) R! T
  303. 6 Z8 {/ a" [: ^/ s2 k7 j; e
  304. void Widget::receiveStatus(YmodemFileReceive::Status status)* }/ u* U1 Y: o" w/ K8 N0 C
  305. {
    & J8 E8 v$ u* Z  c! I" T* F5 E
  306.     switch(status)
    ! [2 l* Z/ p$ ]' s
  307.     {
    . X7 k* j6 w2 b7 \0 W$ D
  308.         case YmodemFileReceive::StatusEstablish:7 Z# m) ?" C( l6 T! j2 a
  309.         {# S, \5 _- y; R2 w1 l0 Z- B* u
  310.             break;9 [# K' k3 s2 h! I8 f
  311.         }
    7 d0 D# v& }5 V3 i" }% J" u: a
  312. ' X5 y5 [# F. [
  313.         case YmodemFileReceive::StatusTransmit:
    ) I. Z4 i! X! C
  314.         {
    7 F0 F' d4 I: W1 D/ @) h
  315.             break;9 N1 |: ?/ V1 {1 G" B( k" L
  316.         }
    * k9 Z+ q7 S4 g5 @* f/ t
  317. & N- X; |2 u! a( L# M; M
  318.         case YmodemFileReceive::StatusFinish:" X5 A! c" _0 M" o
  319.         {
    % X! e$ v) w7 w" i1 u
  320.             receiveButtonStatus = false;
    1 t8 p8 t* F5 ]

  321. . [" v0 M  \4 ^& D
  322.             ui->comButton->setEnabled(true);2 O6 b( e, D8 V
  323. # S9 {0 h" `' _- P
  324.             ui->transmitBrowse->setEnabled(true);
    4 o, ]! E3 [! ]6 {1 c4 g. u3 I
  325. / X: [: |3 P8 @" c- F2 j  n3 N
  326.             if(ui->transmitPath->text().isEmpty() != true)
      Y2 W( \$ Y& B4 O' a
  327.             {# n3 J: t) d$ r( x
  328.                 ui->transmitButton->setEnabled(true);
    . P4 N/ _/ w+ k0 e* D
  329.             }0 ~8 M# c7 T1 ^8 W! k

  330. 3 n! r" y+ y1 t8 p  |- B
  331.             ui->receiveBrowse->setEnabled(true);
    : e8 [4 I+ j8 w+ E4 u. ~# I
  332.             ui->receiveButton->setText(u8"接收");
    # B/ a0 L" ~- h% T7 T0 j2 n
  333. + x; P( j8 h3 @) x( y! b
  334.             QMessageBox::warning(this, u8"成功", u8"文件接收成功!", u8"关闭");
    - P; D, ^+ R! b" K" c
  335. ! j& M( l7 o5 D& \
  336.             break;
    / q" z' O0 A" z  X6 X- [9 F
  337.         }
    ; `$ f2 G: |& j; j  x; e

  338. 3 \6 ^- r" U& V$ ]
  339.         case YmodemFileReceive::StatusAbort:5 `9 D3 v" `7 o9 J
  340.         {4 W7 n# I0 i1 z- f) A% M3 _- G$ j1 g
  341.             receiveButtonStatus = false;! ?0 _9 n5 l" M

  342. 8 l: \2 _6 l5 h! B6 N3 _- ~) ^0 G1 u
  343.             ui->comButton->setEnabled(true);  K; S2 {- k  p6 Q0 a3 Q

  344. 3 n2 K' Z) f/ I: Y) ?
  345.             ui->transmitBrowse->setEnabled(true);2 d3 l9 S% y% j

  346. . k+ `7 `9 a! E$ j  _/ S# q
  347.             if(ui->transmitPath->text().isEmpty() != true)
    4 n( t1 i9 _3 o* ~/ t4 Q
  348.             {
    ' D; F6 D" P# e- f
  349.                 ui->transmitButton->setEnabled(true);; h' }+ p7 P( c! ~8 ]
  350.             }
    # m6 B6 `* @. r, M5 w/ n# R

  351. % V3 n+ p  [4 P1 ]
  352.             ui->receiveBrowse->setEnabled(true);4 I6 V" `( |- s
  353.             ui->receiveButton->setText(u8"接收");
    , j  i7 m: X# |1 v

  354. , L9 B1 R1 C* Y! i1 U' E
  355.             QMessageBox::warning(this, u8"失败", u8"文件接收失败!", u8"关闭");
    , e* i) ~$ M0 s. v) P" b& f
  356. & J8 m. o+ H. B$ W& q5 D+ _# h
  357.             break;* }- Z/ }6 S8 F3 C9 i, }
  358.         }" v% p% i4 s, i1 ]$ d1 H
  359. ; P+ \# `1 E7 v3 D6 Z/ u
  360.         case YmodemFileReceive::StatusTimeout:
    4 t9 p  |4 K% r: K
  361.         {/ G. P; ?; b6 E' L1 q
  362.             receiveButtonStatus = false;6 P" a1 P) T2 M* M9 d
  363. 9 M( P9 ?  m  ]( h* A4 C
  364.             ui->comButton->setEnabled(true);# A1 a8 P' b1 O) Y* W5 l

  365. & N2 `1 j! e, l% V: o. H
  366.             ui->transmitBrowse->setEnabled(true);
    ) Z' @8 |/ h# {- \; w+ a; C& h
  367. & Y$ S% G$ \# _, u$ r2 g, J& F
  368.             if(ui->transmitPath->text().isEmpty() != true)) J, ]- c8 R0 q
  369.             {
    ' d" J& z* Z3 k0 L( `
  370.                 ui->transmitButton->setEnabled(true);7 O; t' M( {2 h0 [2 ?3 k
  371.             }# o0 E. `; I; ]1 d: T& F

  372. # C- Q! i& A: X5 R  `9 t
  373.             ui->receiveBrowse->setEnabled(true);
    6 f0 p# Q9 f# ~. h/ ?& p
  374.             ui->receiveButton->setText(u8"接收");
    % i( S+ ~8 ]8 D

  375.   _4 q9 r1 j7 ?7 t; U8 W' h
  376.             QMessageBox::warning(this, u8"失败", u8"文件接收失败!", u8"关闭");5 J3 c) e7 c  I( q3 x, r2 s6 b* r

  377. & [8 l3 p% T0 N( U7 b% w9 H
  378.             break;
    : h5 h, C) i" j
  379.         }* a0 k" [' v7 y" j9 B# S8 u
  380. , K; r. @* A4 {# E2 B; a% o
  381.         default:3 d, k5 \5 y3 o9 ]4 K( |1 R
  382.         {, f' X  c( s* _2 }) m* ?1 [- Q
  383.             receiveButtonStatus = false;
    2 `( i+ G* {: B/ m

  384. 7 L+ q8 r  \6 p6 R0 {7 [* B
  385.             ui->comButton->setEnabled(true);
    # Y5 g& B5 B5 j9 M
  386. 6 Z# z! t) p6 d+ ?5 [: F" t; w
  387.             ui->transmitBrowse->setEnabled(true);
    & ~$ \* Z( J7 t2 Z  z

  388. + c1 S- p+ p! s: B; W8 C" L
  389.             if(ui->transmitPath->text().isEmpty() != true)6 D' C9 {9 \7 E+ G  a- O/ m
  390.             {
    0 d+ K8 R5 b" ~, K$ q& s
  391.                 ui->transmitButton->setEnabled(true);0 n! f* V' P* V- q
  392.             }5 ]7 v" h% k& y+ x' b
  393. # A- ?' I8 g- F
  394.             ui->receiveBrowse->setEnabled(true);) H2 M1 ~- E% I# g! ]
  395.             ui->receiveButton->setText(u8"接收");
    7 O3 Y* ?0 K% c. J0 F4 n

  396. & r0 n6 d6 d5 `0 i7 f' V4 E
  397.             QMessageBox::warning(this, u8"失败", u8"文件接收失败!", u8"关闭");
    ! Q( U% D# v' m0 s0 k9 |
  398.         }
    ' ?& e5 E. O- A. X& K
  399.     }# ^* J1 O" ?; `2 |: k% r
  400. }
    - Q4 Y1 f3 c: b0 w) c
复制代码

/ A( \, Z3 d$ f* v$ [, P/ M+ ]
0 T& ?! N3 m" T! K% l' h9 R- e) F( b. O  G' j% d
! n) x/ D0 s) ?0 J# \% B

2 l( l' z9 l2 Y; }" q3 V
XinLiYF 回答时间:2018-3-6 02:04:00
      main.cpp文件5 j. X! D! Y* [3 ?& `. t
  1. #include "widget.h"6 J) x, _& n, H  f, R0 G
  2. #include <QApplication>/ v8 ~& O7 N. X! y
  3. 7 k8 @9 n5 f1 e8 y) C  ~
  4. int main(int argc, char *argv[])! u& n  o& {$ a7 y" B3 W
  5. {  o7 M* E+ o! T; @5 b7 m4 F4 c
  6.     QApplication a(argc, argv);! S( C, ^4 F) D0 f, J% d# ?, Q# r
  7.     Widget w;" i+ ?, _3 G" n5 h
  8.     w.show();0 L) B6 m! z) s! e( }) J
  9. 9 N3 O! g. a9 v1 {% r$ u
  10.     return a.exec();
    6 i1 u7 @, L' H( ~* \! _+ [
  11. }
    3 {6 L9 [$ f" q9 p$ t/ u
复制代码
* `8 T0 I+ J; ]2 U+ B
      SerialPortYmodem.pro文件
8 V( P6 d7 O  V  b$ L" P
  1. #-------------------------------------------------3 B; T5 [9 r9 \  k# B  \; C* l
  2. #+ u9 R% I+ S1 M2 [0 y! F
  3. # Project created by QtCreator 2018-01-20T23:00:46: q3 a& R, L' X" ^$ |) A
  4. #
    ! ~3 n/ k3 g3 U
  5. #-------------------------------------------------/ k3 [6 T# p& d

  6. $ z  k- {, U/ F' w- z
  7. QT       += core gui
    $ E4 h4 g" ~& r, f8 R% r
  8. QT       += serialport2 F; X) ~* [! ?8 [' z1 I  h, y) W

  9. 9 w# F- x1 j+ y" S  k6 ~
  10. greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
    / W; L7 T- O, Z

  11. 6 H  ?$ x: ~# U
  12. TARGET = SerialPortYmodem: f: M. R$ t9 a, [/ r  ?
  13. TEMPLATE = app5 d9 ?2 @  V4 |& _0 K0 g& j
  14. 7 o7 R+ X6 n, U6 s9 H$ b
  15. # The following define makes your compiler emit warnings if you use; O* D; u; o3 s  P& j
  16. # any feature of Qt which as been marked as deprecated (the exact warnings% m* H  e! x  l6 y/ Y
  17. # depend on your compiler). Please consult the documentation of the
    % \; A7 k* P; x6 B! ~1 Q
  18. # deprecated API in order to know how to port your code away from it.$ b  g/ k# ~6 w& i
  19. DEFINES += QT_DEPRECATED_WARNINGS
    7 u$ p6 o+ s, F! N  s) \( r" i; n
  20.   T9 K1 p4 f3 y# H: F: {3 ]1 z4 R
  21. # You can also make your code fail to compile if you use deprecated APIs.! w- H# ^9 Z9 n" [2 d
  22. # In order to do so, uncomment the following line.
    ' V! H9 ^' H4 N6 a0 ]; A
  23. # You can also select to disable deprecated APIs only up to a certain version of Qt.$ O! E6 F+ r- v0 w# `1 v' }
  24. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.05 B9 u6 k) U" f& L; d0 U* W

  25. . _% T  e+ q, S: h  |, j

  26. / `+ |) T) Y+ Z; U% @# u7 i8 S6 o9 `
  27. SOURCES += main.cpp\( g. |* R- I# \8 |1 a! Z
  28.         widget.cpp \% O. H" h0 w: U& i: L
  29.     YmodemFileReceive.cpp \
      b  y  I5 L, l* @8 W( {
  30.     Ymodem.cpp \+ [9 L: T' w3 d: ~* l6 P
  31.     YmodemFileTransmit.cpp2 Z  @& Z* x6 m; X- x. m
  32. 0 o* Q- z/ |" m
  33. HEADERS  += widget.h \
      p; x1 P2 g# w
  34.     Ymodem.h \
    3 L' _9 M7 X0 v( Z+ G! ?
  35.     YmodemFileReceive.h \
    ! L, Z5 o3 {4 U. u1 n* X
  36.     YmodemFileTransmit.h
    4 k, _( ]3 p) G; m

  37. % {2 G& J( \( t+ u! ]  ^( Y
  38. FORMS    += widget.ui
    7 U- s) r2 t( A- ~# m

  39. ) w+ s$ Y# A1 y9 k1 d; O1 M) a3 B
  40. RC_ICONS = SerialPortYmodem.ico
    ' m. m7 g- g$ H4 m
复制代码

+ v( q: _$ W2 t9 W6 R4 l4 r      SerialPortYmodem.ico文件' y6 y4 S' y/ q4 \+ U. l

. C1 k% |) S+ I5 S3,运行效果$ ~1 Q: x$ N, G. X; L$ E
% r( m, k! C$ T

8 r. z8 a$ I, H( R  V3 A
/ P- r" W$ f- n# X
hello_bug 回答时间:2018-3-6 11:12:43
好凶猛的代码。。
XinLiYF 回答时间:2018-3-6 11:24:49
hello_bug 发表于 2018-3-6 11:127 u% t% q& N9 Q. U  _- P8 u+ ~: ~2 V
好凶猛的代码。。
# t, j) L7 |5 }; e
XinLiYF 回答时间:2018-3-6 13:16:18
可以用来做用户程序升级的上位机软件。
MrJiu 回答时间:2018-3-6 13:49:12
最好是变成文件比较好。。。关键部分讲解一下,贴上来,就更好了!!!!
XinLiYF 回答时间:2018-3-6 16:14:22
MrJiu 发表于 2018-3-6 13:49
2 m9 [! f/ b7 b  h3 r最好是变成文件比较好。。。关键部分讲解一下,贴上来,就更好了!!!! ...

2 `: Q+ _6 \' U0 dGitHub仓库有工程,还有资料。
zero99 回答时间:2018-3-9 14:41:08
感谢分享,已汇总到3月技术原创:4 ^8 Z, ]" ?1 S( h
https://www.stmcu.org.cn/module/forum/thread-615031-1-1.html
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版