请选择 进入手机版 | 继续访问电脑版

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

YMODEM协议串口文件传输

[复制链接]
XinLiYF 发布时间:2018-3-6 22:28
YMODEM协议串口文件传输
GitHub仓库:http://github.com/XinLiGitHub/SerialPortYmodem  ?; X& Z6 L  p6 J0 f7 A8 T( O* J; k& L
PS:博文不再更新,后续更新会在GitHub仓库进行。9 [, y1 Z; F0 m# |2 Q) z
7 }# U; l. p% ?+ l3 ~4 [
6 `; f0 ^% O; j: S' r
    串口通过YMODEM协议进行文件传输。程序中涉及到YMODEM协议知识,详细介绍见维基百科[YMODEM](http://en.wikipedia.org/wiki/YMODEM)。% z2 O$ p+ w  o
6 z/ I# q9 E; |* r% w7 S
1,开发环境) h4 O/ T* j7 V$ O7 S
      1,框架:Qt 5.7.1
! b6 f" T0 l3 R

% D; N- M, y3 C& Y% G      2,编译器:MSVC2015_64bit/ s$ d# ~  Z4 h% h" Q

, h/ Z5 W+ w4 }6 n0 ~: q      3,IDE:Qt Creator 4.2.0 社区版
) r3 D& ^6 d4 c2 }0 b4 q2 j      4,操作系统:Windows 10 专业版
6 }# {7 A6 [4 j7 I3 U- D9 o3 O) x0 \9 ?7 e$ c- _- W) ^; z
2,程序源码$ [9 O$ |6 _* G0 W0 G- h. P
      Ymodem.h文件& E1 D9 p! R& u0 Q
  1. /**5 Q8 H5 E: v$ z5 @3 F
  2.   ******************************************************************************
    5 d2 \2 E- f! {8 n
  3.   * @file    Ymodem.h, K) [' {6 |0 l8 R
  4.   * @author  XinLi* M+ U% `, E$ g3 }1 M& E, D2 f1 n" F" V
  5.   * @version v1.0
    , k4 m7 ~  w7 W0 _$ b
  6.   * @date    21-January-2018
    ' v) j) t% Q! Q7 `  V0 ]' p
  7.   * @brief   Header file for Ymodem.cpp module.4 A$ y, _: X! @, ?# k
  8.   ******************************************************************************, `& N7 A$ u/ P5 J2 m
  9.   * @attention
    8 M# b; I% A3 ~- R# }
  10.   *+ g" {' t. B/ Q0 d3 n
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>
    5 }) d0 Y9 B9 Q  V, l9 x- u8 `
  12.   *$ Y! y, L4 A  h1 w% j! w6 |$ Z
  13.   * This program is free software: you can redistribute it and/or modify
      A5 x% a, D& P
  14.   * it under the terms of the GNU General Public License as published by
    ) r0 j/ a% j7 `% \
  15.   * the Free Software Foundation, either version 3 of the License, or) q7 g& j( [8 ^9 t7 [( N
  16.   * (at your option) any later version.; `! v9 F. p" T/ s) H) F! c
  17.   *, l) f5 T1 L) u3 _
  18.   * This program is distributed in the hope that it will be useful,4 b* K+ l& ^$ L2 P) j$ t
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of# b& Z, d& x  h+ Y  c9 m
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the+ H& X/ B5 [& Z( F  K
  21.   * GNU General Public License for more details.
    , r7 J, d! o: g3 J$ _
  22.   *
    ' Z3 Z( a7 R1 F: {& u& K
  23.   * You should have received a copy of the GNU General Public License
    4 [+ q, Y; K6 v
  24.   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    : e# y: D8 L9 a+ r. y. j; C
  25.   *3 j: S2 n! M4 l* Y
  26.   ******************************************************************************. X2 @8 K6 G/ _$ R6 T
  27.   */. M1 Z+ }2 ]9 M. L1 T: Y

  28. " Y/ R# I$ H; m1 i& f7 R
  29. #ifndef __YMODEM_H
    2 {) ~4 I, T, E
  30. #define __YMODEM_H1 \7 l+ w3 z7 Z& s/ D/ t; Q

  31. ' r$ n  X2 L, ]: I
  32. /* Header includes -----------------------------------------------------------*/+ I2 g5 e5 G0 a: g0 z
  33. #include <stdint.h>$ V8 k! y7 h5 t$ \6 }- o
  34. , F/ [& x- Y, \0 e" Z+ z5 Y
  35. /* Macro definitions ---------------------------------------------------------*/; H. i) x' q  S. G2 S) {
  36. #define YMODEM_PACKET_HEADER    (3)
    / ~$ ?3 E  k" ]+ y( \# L
  37. #define YMODEM_PACKET_TRAILER   (2)+ F& `9 i& ?5 t5 i5 n7 n5 ?3 i
  38. #define YMODEM_PACKET_OVERHEAD  (YMODEM_PACKET_HEADER + YMODEM_PACKET_TRAILER), Z, k# ]( H2 `( Q
  39. #define YMODEM_PACKET_SIZE      (128)
    & I: k- P5 z& v! p! n6 J
  40. #define YMODEM_PACKET_1K_SIZE   (1024)
    % A! K& F* K9 o' l$ D3 e% }' \3 Q
  41. " }( o: C6 Y# _: ^7 V% D
  42. #define YMODEM_CODE_CAN_NUMBER  (5)* J+ ~% u0 m1 a7 w# A

  43. & V4 T5 f+ ]3 K+ k
  44. /* Type definitions ----------------------------------------------------------*/4 V; h" K/ p0 M
  45. class Ymodem
    / g. |& x1 b: z
  46. {( a& t$ G$ d' l  T3 s9 e+ g! [* y
  47. public:
    1 V3 U7 |. Z& M+ N& U: |( y1 s
  48.   enum Code- y: ^! [" f, Q
  49.   {
      ]2 m- f  e& F1 {0 _
  50.     CodeNone = 0x00,$ F& h# o8 |; y; h: }
  51.     CodeSoh  = 0x01,1 }; a, r# E9 l4 g
  52.     CodeStx  = 0x02,
    " r. `& l: r0 r% A2 U
  53.     CodeEot  = 0x04,
    : n* A1 F! b9 \' u8 m# j4 {
  54.     CodeAck  = 0x06,
    7 ]9 o7 d) o  Y" I
  55.     CodeNak  = 0x15,( F/ q% k, c. H+ A& c) L
  56.     CodeCan  = 0x18,
    2 i( A" u% a. g! c8 n$ X
  57.     CodeC    = 0x43,5 Q  B0 o8 D7 N! F/ r
  58.     CodeA1   = 0x41,! J6 O% s& u- H0 ~! ]
  59.     CodeA2   = 0x612 D! x# b( Z! H7 W. z7 c" m& ^
  60.   };
    : d, D/ |( ]% }. C- F

  61. % \. _7 n  ^/ G* r
  62.   enum Stage
    6 m9 I# v7 w; W8 C" K- G
  63.   {
    * Q; T6 P# i3 i( B; _% ]' m
  64.     StageNone,
    , a7 o9 W/ W/ c& A6 j( n
  65.     StageEstablishing,
    1 }9 ?  m1 g  r
  66.     StageEstablished,
    9 t) Z7 C- y6 ^4 ~  u1 \2 r
  67.     StageTransmitting,2 _" ?* A2 W2 x- Q7 k7 s  c: w+ ~
  68.     StageFinishing,- A  ^0 H+ H( K1 N
  69.     StageFinished
    " q8 h. b; M9 X6 `" ^
  70.   };! L) X' s$ U3 \# q; e/ M( v. D5 s) _

  71. - E. T7 u2 Q! \' M% |" x
  72.   enum Status
    3 r9 h$ p. C" W' c* T
  73.   {
    : b3 u0 O  \7 f
  74.     StatusEstablish,8 x; o% g8 v# L% N- H: M' J/ {* F
  75.     StatusTransmit,/ [7 B. @- U1 [8 n* w
  76.     StatusFinish,& \) z# b8 y( o  N. s
  77.     StatusAbort,: X4 ]' U( ?  Z. d$ K4 E+ A
  78.     StatusTimeout,
    ! a) y' n  `& S7 q' M, C3 D' H
  79.     StatusError
    ! _6 ?- S0 B4 Y2 i
  80.   };+ _6 C3 o! V. S) I2 d9 b( A
  81. ( S( X( B, P: X1 P
  82.   Ymodem(uint32_t timeDivide = 499, uint32_t timeMax = 5, uint32_t errorMax = 999);3 g, b5 b1 I; C6 {+ U

  83. ' F( ?4 n& @6 ~
  84.   void setTimeDivide(uint32_t timeDivide);; `* O  D% {( ~- P
  85.   uint32_t getTimeDivide();
    / V) G. U) N! g7 H
  86. " n' m- ~6 {6 `
  87.   void setTimeMax(uint32_t timeMax);
    9 v4 M6 c/ p6 m, Y: g) t
  88.   uint32_t getTimeMax();
    9 C( D+ _, L  e# ?: r
  89. " [( h# G; u9 I- I/ e+ v7 R
  90.   void setErrorMax(uint32_t errorMax);
    9 N/ \: `1 }- Y
  91.   uint32_t getErrorMax();) f8 N7 S( D; m6 F2 f5 x# e1 j
  92. 8 k' o( ?% V* T" f6 \+ |
  93.   void receive();3 L. i7 I- l* V/ \# t0 s7 S
  94.   void transmit();
    9 S6 Z  N; q% k) a! `
  95.   void abort();- ^" [% |: P; B% j" J# X0 }* |

  96. 0 G! i! O, c8 r: s; N5 t) o3 |
  97. private:
    ( _, I3 @' h) h1 A2 G
  98.   Code receivePacket();
    0 H  Z* @. S5 e$ g: u

  99. ' X6 M4 d8 M- v- |- r/ l: F
  100.   void receiveStageNone();# A7 r9 {; @, a
  101.   void receiveStageEstablishing();
    / G* W7 C! Y: I- J
  102.   void receiveStageEstablished();- \$ G% E4 L# G: l
  103.   void receiveStageTransmitting();9 o3 f! a1 P7 r  p3 ?, u
  104.   void receiveStageFinishing();( x' \( o# z- f3 a
  105.   void receiveStageFinished();9 S( z9 L# M! R+ N0 d

  106. 7 L( ]3 X1 C, J6 R6 h+ n" E: C
  107.   void transmitStageNone();) X" I0 j8 D& o- [4 C8 m
  108.   void transmitStageEstablishing();7 V6 N  P, h/ Q- U9 A0 [
  109.   void transmitStageEstablished();  i8 v- d9 r& P7 J9 b% w
  110.   void transmitStageTransmitting();
    . t' G* `/ E) x0 i. p" l( S
  111.   void transmitStageFinishing();" M) ]! u1 ^+ _- H1 k& d
  112.   void transmitStageFinished();  Q9 P+ ~: h1 ]! u+ f( f
  113. ( o" g( A1 Y9 `+ U: R- ]6 y3 M
  114.   uint16_t crc16(uint8_t *buff, uint32_t len);
    3 P, [; U7 C' p" \% t
  115. 4 e6 c) P) M1 }. r. l8 z
  116.   virtual Code callback(Status status, uint8_t *buff, uint32_t *len) = 0;
    5 M  f6 T$ f4 {: V% v& f5 }

  117. 3 n) I4 s1 I3 i4 @5 S- ]3 r
  118.   virtual uint32_t read(uint8_t *buff, uint32_t len)  = 0;
    ' s! f7 {+ Q. V$ J
  119.   virtual uint32_t write(uint8_t *buff, uint32_t len) = 0;! t3 a( D9 g2 |
  120. 6 g7 Z. l' j5 a1 O8 a
  121.   uint32_t timeDivide;
    . K$ c/ C* m- k2 l* @; k
  122.   uint32_t timeMax;+ }, G6 q3 V- \2 B' F+ T
  123.   uint32_t errorMax;
    - p' @6 W' z. {  J1 U: U

  124. 2 u5 @: |9 K+ T" m* _+ c# o8 n3 I% G
  125.   uint32_t timeCount;: z5 C' m9 e2 ^9 G
  126.   uint32_t errorCount;
    # C/ J0 p& q7 p
  127.   uint8_t  dataCount;
    ! y& a7 v8 r. u  b; D

  128. . l* M; X9 v& E( F4 F
  129.   Code  code;* T, F' y5 j9 Y8 \% ^8 a
  130.   Stage stage;
    6 [8 m. C" H3 Z, X- S% i
  131. ( G0 p0 R5 D5 }$ k
  132.   uint8_t  rxBuffer[YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD];
    1 L# g1 m, f/ `3 I4 ]
  133.   uint8_t  txBuffer[YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD];" q6 D8 T, p# B6 u( }8 c+ D- v
  134.   uint32_t rxLength;
    3 D8 _% R" }$ ?8 |' Y
  135.   uint32_t txLength;# p/ K9 f) H& {
  136. };4 M: @! Q5 ?& i4 w& Q/ A

  137. # K% u3 r8 K$ {  @2 l9 ]5 {
  138. /* Variable declarations -----------------------------------------------------*/% z4 G6 b  {" i
  139. /* Variable definitions ------------------------------------------------------*/& ]3 @' p; F7 r0 ~* o( k0 `  J
  140. /* Function declarations -----------------------------------------------------*/: C8 r% o- a" y3 ~* P; p
  141. /* Function definitions ------------------------------------------------------*/3 s: P& f8 O- J" L
  142. . m7 u8 k2 L4 P) D5 c) C- f- Z. I
  143. #endif /* __YMODEM_H */8 @/ x  r9 A& f& B
复制代码

) U, f9 Y. c, U! w+ l& F/ P; D      Ymodem.cpp文件$ W' s% Q( l! w  X6 i7 i% Q* V
  1. /**& k- s  R/ W% N
  2.   ******************************************************************************2 r; ]5 }1 x4 q9 ~4 }0 [
  3.   * @file    Ymodem.cpp
    8 s: t5 I& j7 Z
  4.   * @author  XinLi
    ' m- X% z6 w; e8 H& |6 }" W
  5.   * @version v1.0# r7 R5 Y- I* e
  6.   * @date    21-January-20182 _2 v) J  O8 I+ _' v* @
  7.   * @brief   Ymodem protocol module source file.7 Q. E' P( w  o3 q( g6 B; `
  8.   ******************************************************************************
    $ z3 C1 d- ~  e# N# t$ I6 O
  9.   * @attention
    ( \' A  e# M, H  {/ |4 j, l/ Q
  10.   *# I; N8 K+ i1 P' h+ x
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>8 C, P1 H+ d& t1 P/ R8 k4 N
  12.   *
    * E( A- X4 q' J4 f0 ^/ k
  13.   * This program is free software: you can redistribute it and/or modify
    . K9 L4 U0 Y$ j& P2 T4 v
  14.   * it under the terms of the GNU General Public License as published by7 q( Q; W) I9 f  c5 g) M% C
  15.   * the Free Software Foundation, either version 3 of the License, or" \7 q0 u6 ], V& `  b% D! x; T
  16.   * (at your option) any later version./ M* o: a9 X4 |: b' Y9 J  }3 ]( I
  17.   *
    : z' ?) q9 }0 ~* `3 e1 U
  18.   * This program is distributed in the hope that it will be useful,
    1 s) X; {; _- o; j3 w
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    6 c' u, p8 p+ l4 H; {" H
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the# T/ K$ @+ T1 _
  21.   * GNU General Public License for more details./ Z( G& O1 t% O2 D( u( G7 _
  22.   *' M0 K: {2 i  _# }8 Y
  23.   * You should have received a copy of the GNU General Public License! \1 _7 F* B$ E
  24.   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
      C- E$ ]$ d, U6 r* J
  25.   *! d% r# ^7 i- ]; v$ T
  26.   ******************************************************************************
    ' i) N9 Z0 a5 D% s) c) Y" l
  27.   */6 |) m/ X& P$ w& q/ E8 Q
  28. 2 g* o8 z1 A* d/ }5 H, ]3 ~2 p
  29. /* Header includes -----------------------------------------------------------*/
    ) I9 K: f/ B: K1 o, K
  30. #include "Ymodem.h"1 w9 q! N: j8 M4 K) K
  31. #include <string.h>* u+ e  i! c7 Q5 H( A$ _% G1 N
  32. " {  P6 P- M0 X# H" n# T
  33. /* Macro definitions ---------------------------------------------------------*/; i5 H8 s0 l; K0 o1 ~4 Z  I
  34. /* Type definitions ----------------------------------------------------------*/
    1 u; M$ ^- P( |* A% J
  35. /* Variable declarations -----------------------------------------------------*/
    ) r0 c- z5 n3 p- g# D/ |
  36. /* Variable definitions ------------------------------------------------------*/) p# ?8 D1 X- j' K
  37. /* Function declarations -----------------------------------------------------*/' P) A+ f  q" z2 S% G% K$ F. _
  38. /* Function definitions ------------------------------------------------------*/
    * b( @% B% C7 J! ~

  39. . J: y! n6 @1 |- q3 r; `8 v: M
  40. /**; f" g/ D6 K# B) C6 ?" \% q. F
  41.   * @brief  Ymodem constructor.* `5 [) E: I% y, B' e$ g
  42.   * @param  [in] timeDivide: The fractional factor of the time the ymodem is called.( @3 Y2 M, t' E* _* y7 B1 n
  43.   * @param  [in] timeMax:    The maximum time when calling the ymodem.
    / a7 h$ ?9 [$ R/ @6 W" j9 K
  44.   * @param  [in] errorMax:   The maximum error count when calling the ymodem.8 B, \3 X( o4 D" C9 }8 ?
  45.   * @note   The longest waiting time = call time / (@timeDivide + 1) * (@timeMax + 1).# W$ M+ F0 k# c
  46.   * @return None.
    2 c3 r9 X6 n6 w" J1 x
  47.   */& ~+ q6 a$ l+ s) C7 u' g
  48. Ymodem::Ymodem(uint32_t timeDivide, uint32_t timeMax, uint32_t errorMax)# G  N8 \. ~& @/ g# |
  49. {
    . N, Z% @# d& N: u
  50.   this->timeDivide = timeDivide;+ j  X/ d$ |6 Q6 @' o3 H: r
  51.   this->timeMax    = timeMax;8 `7 s2 M! j1 H1 f
  52.   this->errorMax   = errorMax;; j2 E& Q, A# \! ]3 ]

  53. 9 M' l  h5 a5 G8 X3 ?# E" R
  54.   this->timeCount  = 0;( f" F; C& l8 l8 t4 Z
  55.   this->errorCount = 0;3 X2 M1 f# m" B/ y  H! ^
  56.   this->dataCount  = 0;
    8 M/ ~; v7 l! o; A- c2 x
  57. " |2 m4 h  o5 ?: n7 G& p
  58.   this->code       = CodeNone;( W: V6 J6 C1 O6 J# K. l+ P' t
  59.   this->stage      = StageNone;8 Y1 }: j, Q% L% a: t; z
  60. }
    ! |% ^' i- A9 x3 ?4 h7 ]

  61. 3 h- }5 e  e( G. l9 h, @
  62. /**; h- F' d. p2 s+ I9 ~4 U0 n' d
  63.   * @brief  Set the fractional factor of the time the ymodem is called./ y# P5 t3 f( q$ K
  64.   * @param  [in] timeDivide: The fractional factor of the time the ymodem is called.
    " f/ z, C' M* y, z
  65.   * @return None.: L% g$ N0 Q+ w* L; C1 Q
  66.   */* R3 n2 T) g; m
  67. void Ymodem::setTimeDivide(uint32_t timeDivide)7 [# x+ Q$ k2 \- K% g3 }
  68. {4 L$ k" ?2 ~  W4 _) F
  69.   this->timeDivide = timeDivide;5 C- x. W4 S" |+ ~. c
  70. }
    * L7 ^% X$ Z$ K1 n
  71. & ~# Q, c6 M6 d- ~
  72. /**
    - @# s/ F# a; F) W8 M
  73.   * @brief  Get the fractional factor of the time the ymodem is called.9 f5 N; w7 O# E# }4 r- _/ i
  74.   * @param  None.
    . |1 M" ~* s, s, L; R# G; k' W
  75.   * @return The fractional factor of the time the ymodem is called.( `4 A+ i6 g! f1 C, _8 Y
  76.   */. }7 u4 P# U4 ^6 ~$ z
  77. uint32_t Ymodem::getTimeDivide()
    . q/ F7 A' z4 V  E  p7 z
  78. {
    ( F( a2 u9 t7 c$ {( r
  79.   return timeDivide;
    . M! k: r6 z7 a4 |6 M4 P6 S" a
  80. }
    # H' E7 q6 J9 |7 p
  81. - u4 k' ^6 B/ ], |0 x
  82. /**+ W) {. d3 v" P
  83.   * @brief  Set the maximum time when calling the ymodem./ I) S# o" z/ Y4 s* r& m( t9 O5 H) j
  84.   * @param  [in] timeMax: The maximum time when calling the ymodem.% i4 y' m: z& }& e
  85.   * @return None.
    $ x/ j$ \9 X! \
  86.   */
    ( c9 s2 d' T+ ^3 b/ a# w
  87. void Ymodem::setTimeMax(uint32_t timeMax)+ n; _( Q- g& X/ n- n0 h
  88. {9 f0 V) d& B% U
  89.   this->timeMax = timeMax;- }: I7 @; e' ~
  90. }
    8 {# P7 r8 ^6 Q7 g
  91. # e2 @" o8 A5 J
  92. /**
    ( G! P3 g1 O8 u: N  E9 e
  93.   * @brief  Get the maximum time when calling the ymodem.
    4 c3 U# _$ [# M
  94.   * @param  None.7 t, S/ k9 S8 |* o) |1 ^8 V
  95.   * @return The maximum time when calling the ymodem.
    7 Q! `. o/ B3 A) B' r! w8 M
  96.   */
    % _, y5 W( D  I  Y) x  {6 M
  97. uint32_t Ymodem::getTimeMax()
    ! q/ i' H" e+ x: _+ y
  98. {5 y6 i  X* F! U' I# ]- a
  99.   return timeMax;
    ; W2 \- g9 `- r* _9 N& ?9 X
  100. }' _% C6 \/ [. R  h- d

  101. 2 p" T* v5 D* M, @# p
  102. /**8 Y* S- R" ^+ P6 u
  103.   * @brief  Set the maximum error count when calling the ymodem.
    # v9 E4 V/ M% s+ _% S, {
  104.   * @param  [in] errorMax: The maximum error count when calling the ymodem.
    1 f4 l1 O- K$ }
  105.   * @return None.
    3 Z3 k3 v" t, L- q
  106.   */
    ) i+ a/ m6 q* q: X
  107. void Ymodem::setErrorMax(uint32_t errorMax)
    5 m% v0 B1 I2 u% q
  108. {) V  n- N8 u8 W5 C: J% V1 L% y& |
  109.   this->errorMax = errorMax;& G  K# m, [& {2 m$ v# n' `$ z& W
  110. }
    9 }% E# X0 V  O( G( b
  111. % d. f7 M( {, [' h! v7 b
  112. /**/ c/ j/ V# b& m+ ~
  113.   * @brief  Get the maximum error count when calling the ymodem.( ^2 y# n. [" H! M. n/ k+ U' t
  114.   * @param  None.
    9 G8 R- |5 c5 @! e: z' y
  115.   * @return The maximum error count when calling the ymodem.# t$ |" R7 H) x7 y0 Q( |
  116.   */; S' N5 S- o6 V& M+ D/ n
  117. uint32_t Ymodem::getErrorMax()
    1 x: }% d; t8 _( m/ n* X
  118. {
    : S; c  ~+ u& T7 i& `
  119.   return errorMax;9 L2 I5 X9 c! n3 ^. R3 c0 D% P1 M
  120. }% A, j+ j6 H& N* |+ Z

  121. & v. L& P$ i+ {1 L7 m0 n- v
  122. /**# r+ v' |; [3 F! m
  123.   * @brief  Ymodem receive.
    & ?$ S) r3 S! n/ ?
  124.   * @param  None.0 U$ n, w- s" e1 r7 o4 }  g4 H" I! u
  125.   * @return None.
    * E8 Y0 l1 g/ R4 G
  126.   */" [8 o7 ?/ l! w' t
  127. void Ymodem::receive()
    * t- x( u1 C7 D" d: F* U
  128. {; F( X; l. F% y% q* b
  129.   switch(stage)
    + G1 i! i/ ]' N+ A
  130.   {& @  s% ]" H& H4 ~3 }
  131.     case StageNone:# \6 G  i: e" U7 X/ d
  132.     {$ z/ U3 Q, g+ P1 I, t& W2 M" h2 k
  133.       receiveStageNone();' @5 N# x8 V7 ]& s! k% H+ x* m

  134. $ H6 T: M6 u2 k
  135.       break;- j# `: N3 X  j4 {7 S
  136.     }
    / W8 n& @/ k& ]/ l4 f6 Q- U
  137. . p8 S4 p+ H+ R; Q- A0 j: s
  138.     case StageEstablishing:" G6 v5 X& p0 o8 c9 \
  139.     {
    1 _' L/ {4 A% P2 {4 {7 {  I8 }6 J
  140.       receiveStageEstablishing();
    ; b. E) G5 N! j. h
  141. ( H9 c7 M0 U! j, o/ S# s
  142.       break;
    7 O. w7 A5 @8 e: U) K
  143.     }# ^. j* E& K* P: `7 D( R

  144.   I$ {( B  m0 H& g5 ^, j
  145.     case StageEstablished:
    * u: Z8 [# T5 x- R
  146.     {
    # n+ E1 p- p8 j2 c5 [1 N% T) J0 i; C
  147.       receiveStageEstablished();) G* |0 O8 a# N. T

  148.   s8 t# t7 U) ?
  149.       break;1 p" u2 [& c4 `/ x0 ~# S
  150.     }6 H) o3 G: m9 w" }6 d

  151. * x* c9 l& q# T1 j" {
  152.     case StageTransmitting:" u! x0 L9 l( n
  153.     {5 d* i; Z0 H1 b( Q
  154.       receiveStageTransmitting();5 |. k( K  t. t$ k: H9 q5 N
  155.   _% k+ x  {: Z" X( F3 \
  156.       break;  g% ]6 G# V: g. ]
  157.     }
    5 \" _  G( x) U7 J
  158. # t. y! c, \: q) c4 O
  159.     case StageFinishing:
    : w+ |1 }+ o* B
  160.     {  O, `1 L) o4 A6 W  V; _# P# E& s& {
  161.       receiveStageFinishing();
    6 Q6 w7 @- U/ k
  162. 9 s0 {. m1 [6 }9 }! y# e7 H
  163.       break;8 u5 O( G$ j3 x1 C; }/ k) s" s- A
  164.     }' U+ O) p$ Z" o% j

  165. 9 ]' g9 {; u5 O' T, `* ?* `
  166.     default:6 Q0 q: \+ H! T+ l1 t. g# m+ Y
  167.     {3 ^5 A5 i; [! T2 S. x& U
  168.       receiveStageFinished();
    ; q/ \0 ~+ @2 Y+ U3 C5 W4 n
  169.     }
    ) _0 n) f1 z& Q5 r9 l
  170.   }
    , y5 o0 G! l9 q. K- @: d; x
  171. }6 A/ e7 X* G% h8 R5 S# w

  172. " G# z: Z5 ?: B) N
  173. /**; u9 c& C9 h1 x: R" `
  174.   * @brief  Ymodem transmit.
    - G- b2 g9 r5 g. d! a3 v
  175.   * @param  None.2 i; P5 M, E; U
  176.   * @return None.
    ! G: d+ B, w4 ~1 W+ @$ _) }7 ]
  177.   */) Q  l, p; h: ^. K& {
  178. void Ymodem::transmit()% P6 r2 V% p, E5 ~3 c
  179. {
    / A6 p% w  H# j: d% ~! J% \: y
  180.   switch(stage)% h  d" [0 a5 J7 O7 _
  181.   {2 m! U( [. P, N. F8 Z0 F+ z
  182.     case StageNone:
    * r; E/ K$ t/ p+ W
  183.     {7 h- ]0 d( F, E* _
  184.       transmitStageNone();; k$ k5 T! p6 n9 b; a! J7 N
  185. " h# m( L7 `2 ?" E" P
  186.       break;
    6 j& b* X+ u9 L' C- Q3 [3 T
  187.     }
    ( f, j$ D, x1 m2 g3 g& c$ d

  188. - q! B7 |# z' v
  189.     case StageEstablishing:
    * u% T/ l' V5 R* H
  190.     {* f& w' Y/ c& \1 j$ r  X$ h
  191.       transmitStageEstablishing();
    - {% m- |" c) X

  192. 6 S3 J4 q3 U6 h7 J
  193.       break;, L' y3 b. N% v- f' N3 \5 G
  194.     }, d$ L: ]6 X2 W4 |. \  ?
  195. ' g& a5 J. _; S; O
  196.     case StageEstablished:
    * K- V5 i* k, I
  197.     {: p+ P+ Z1 L& |2 [
  198.       transmitStageEstablished();
    $ S0 C+ g; ?, A4 c* S+ N
  199. , i; m7 V' H' u; s4 _3 i
  200.       break;! E$ ~) ^. m# R2 ]0 ~
  201.     }- _1 Y# m+ h# k, G- O" ?2 `

  202. ) J4 y# O/ {- g* C! s; K1 Q
  203.     case StageTransmitting:9 T: x( Z' V' b0 R3 ?5 g: f
  204.     {4 t9 i$ [6 p& `3 l  ?
  205.       transmitStageTransmitting();
    " D) N4 d5 }. e' ?# T

  206. # a) \7 K& Q$ V# z
  207.       break;
    . @8 q& P/ ?, [
  208.     }
    / \: y$ s# k" `, f3 z  j, C

  209. ) u# r0 I# c5 Q) i* U% K
  210.     case StageFinishing:# m- y, f% K3 G9 T1 I
  211.     {
    2 V" w! w  K8 Y" K- f1 K7 L& u
  212.       transmitStageFinishing();
    ! T$ g% h# |; e) Q
  213. 3 S& H8 i5 E3 y/ I
  214.       break;
    2 x# s9 d, y# X  i9 O0 p) |
  215.     }5 v+ f' x) C  [8 n+ n. S

  216. , C- J5 W1 i* F( w+ T
  217.     default:' ?6 c) H9 y. n4 ?/ f4 a% J
  218.     {
    9 L  |# F% Q& n& w! a4 S
  219.       transmitStageFinished();
    / {1 ?/ B  \+ r* c8 {
  220.     }/ o# _2 e; x. z
  221.   }
    4 E0 h9 ~! X! _9 m& i* p6 h
  222. }
    ' b' {) S% k+ I0 Y! Y- {

  223. " y5 P1 s& P4 w% Q
  224. /**5 z' ]9 `1 f, d& k# ~) ~
  225.   * @brief  Ymodem abort.
    , H7 N' [1 h' c. ~* E6 O
  226.   * @param  None.
    ; e6 c8 G6 k8 l' r6 U. n' g& V! G; m4 `# d
  227.   * @return None." @/ }5 `9 s' w
  228.   */
    + Q$ x9 L9 ~; Z5 E' P3 j
  229. void Ymodem::abort()" _5 f2 {( @8 }
  230. {
    / ]1 A- @1 {$ V$ P: F# k
  231.   timeCount  = 0;/ C" i; e2 P! c3 N  \: b
  232.   errorCount = 0;5 K# Y( w/ Q' f+ T& \% y
  233.   dataCount  = 0;# {5 C+ ?' H; P+ @$ F
  234.   code       = CodeNone;/ d$ k: \4 F; x/ R  g- r8 q
  235.   stage      = StageNone;
    * Z+ \# O. i+ K3 ~( v
  236. 1 E& a$ ]& k- L
  237.   for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
      b+ z- Z& s$ M; Y' \& t/ o- x* }
  238.   {
    ! G) ?- g7 }$ d% G! h$ c) `8 Q: y" H
  239.     txBuffer[txLength] = CodeCan;5 ^2 B. ~( i3 O1 R1 v3 C7 c4 ], P
  240.   }& Y8 q! [9 {+ ?8 E. X! r7 m) V

  241. & e8 f7 d0 w) }2 Y$ n- d3 o1 \7 ^# E7 t/ }
  242.   write(txBuffer, txLength);
    % C0 i  U1 D1 Y
  243. }2 w7 w; C+ f% o

  244. 8 l: k( M3 d- P- \
  245. /**
    . J" R  C' o5 {/ M# v! {' \. p
  246.   * @brief  Receives a packet of data.. L0 B! n) K/ t
  247.   * @param  None.
    ' m# c0 Q: c6 K) i1 a6 |! z
  248.   * @return Packet type.% [3 `8 \+ p& N1 V2 O7 p) [0 i
  249.   */
    ( G. S1 j) ?* s( A
  250. Ymodem::Code Ymodem::receivePacket()7 g9 r* K* O4 B( D% n
  251. {7 ~6 \5 O2 h& F
  252.   if(code == CodeNone)/ d/ ^' c* {5 I  E- X
  253.   {+ [5 \% d- O5 D0 }
  254.     if(read(&(rxBuffer[0]), 1) > 0)1 J7 @' q8 S( V( g5 I6 j
  255.     {
    & d$ F3 b3 F! f( G/ v3 B
  256.       if(rxBuffer[0] == CodeSoh)2 H. x$ A# O) |$ O
  257.       {
    2 u5 }0 z- ~# z1 c; X( \
  258.         uint32_t len = read(&(rxBuffer[1]), YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 1);
    # }2 Y6 @2 v- ?
  259. 4 G* N0 c! \- o$ @/ b8 b/ r! i' y1 z
  260.         if(len < (YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 1))
    1 U4 S$ \8 @: H( A& ]/ h6 T
  261.         {
    6 [, P' n' q. v! b+ a" o# W
  262.           rxLength = len + 1;8 R$ N" y3 z% Z2 _" |& z( z
  263.           code     = CodeSoh;
    ' g8 b4 e6 ~" ^; ?
  264. 0 h/ F7 c# G$ n) a8 \7 l
  265.           return CodeNone;5 p% L  i- L# ^2 N$ o$ ~
  266.         }: y) R8 z6 L/ L- I8 ?. C# f4 U
  267.         else- Z8 M  u8 n/ C" r2 @
  268.         {, T* R( a0 s6 B0 L; e
  269.           return CodeSoh;6 u5 v; a  x, W- S
  270.         }
    3 A, |0 a$ W$ L# U% G
  271.       }
    4 x1 O" D/ \0 g; b* ?# i. S
  272.       else if(rxBuffer[0] == CodeStx)
    2 ?' i  @- Q5 W+ ~: d, d
  273.       {$ g/ X6 `, H, {: U4 @
  274.         uint32_t len = read(&(rxBuffer[1]), YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - 1);/ J* P% I( ~' M' m0 C/ i6 a1 I

  275.   [; A; c2 t" J9 g) x5 m
  276.         if(len < (YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - 1))* O" X: C7 Q2 L: [" W7 N5 k
  277.         {) V# f( o5 |9 Q+ v
  278.           rxLength = len + 1;
    , p4 p5 v' P; J3 N( U
  279.           code     = CodeStx;
    , f( E9 m7 f( a( o

  280. 7 h3 X( C2 D" L" H, L2 u
  281.           return CodeNone;
    5 G& T4 S. d6 e6 |6 }
  282.         }0 Y& ]6 P. q7 C( ]: W
  283.         else, j4 D2 e/ D. N. j8 V8 `
  284.         {
    1 J$ y; L2 u  l, L! d: r
  285.           return CodeStx;' ~' V- M- B4 j5 o8 U7 n( Z* S# [
  286.         }6 e8 H8 N  ]) A4 M6 q+ O
  287.       }, O8 O  H  J8 |: a- _( Z
  288.       else" H$ o) P3 k% J% d
  289.       {) s  i! a7 W" f" D1 H$ ~* ?
  290.         return (Code)(rxBuffer[0]);
    + e/ b( W0 i0 t" c0 ]+ I
  291.       }' F) [2 ]/ t6 m& ?- i! G# u9 p$ M
  292.     }7 f6 b8 d2 E9 k7 p. F! z" C
  293.     else1 k+ Y- p) U+ Q# U& D' M) v! W
  294.     {) K; ]4 ?6 [) q, O6 _; `. _- z+ m7 e
  295.       return CodeNone;4 C4 f4 H& l1 ]. p9 b
  296.     }  E" @: |  g. o+ q; F
  297.   }
    0 k  |8 _5 Q3 K
  298.   else
    & K( |- y+ [1 h0 K2 l
  299.   {, ~2 y0 V( S" }- F" v( h
  300.     if(code == CodeSoh)
    ! L. ~2 E9 R# f9 Y- a% O
  301.     {
      Y/ d! U+ P. X+ j
  302.       uint32_t len = read(&(rxBuffer[rxLength]), YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - rxLength);
    % }, G# S, e& t( j* x5 c

  303. ! ?  O7 d6 E& p2 g3 G- f3 k# }
  304.       if(len < (YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - rxLength)). j! S" {* W* e2 g4 Y) }5 r# m9 f
  305.       {/ u9 o8 v' m6 G( v( ?- C4 O% d: N
  306.         rxLength += len;, J3 O! ]* @" k+ b2 b- v

  307. $ U( U+ r1 l: `2 m8 |1 p3 `: a
  308.         return CodeNone;: B8 k# y$ O0 l  k( s6 P8 {: Q- i
  309.       }
    2 {; z/ j/ Q) m* ^; B' V" _, l
  310.       else; C+ g2 h/ {4 \' L% \4 W; `) ^# |
  311.       {4 ?8 C, [: X4 x: z" ~# g
  312.         code = CodeNone;
    6 r6 L5 |! W! S' V! q2 K
  313. - ~1 o' {  O5 u- o/ }! |+ v: O7 J* u
  314.         return CodeSoh;; s) b) T, K) Y
  315.       }6 `8 K4 ]: z9 I. f7 [1 N
  316.     }
    7 _6 x& m& g) z2 q- E2 N% H6 e
  317.     else if(code == CodeStx)/ g, C# h) f' c3 S" ]7 N6 K- l
  318.     {4 z+ P  L) |6 A: v  q4 N9 n) X
  319.       uint32_t len = read(&(rxBuffer[rxLength]), YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - rxLength);0 \) d# E  p: x0 v

  320. . M$ _* b- Q& j! S1 r8 d
  321.       if(len < (YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - rxLength))
    " \2 \' Q& C! ?/ C/ ]* D
  322.       {
    , e) O6 ?1 b" U1 F3 b1 y
  323.         rxLength += len;
    ! ?: L2 O! q: ^$ ?& v- N. b2 S; z
  324. ' ]2 S8 d7 t6 k$ W* p9 d4 a. i
  325.         return CodeNone;
    & f0 U% I! @$ R! g  ?: m! N4 v9 S
  326.       }: V; R4 G! P/ }- h& j) v3 v
  327.       else
    % Q, L- Y% Y2 V- E( o+ {2 R
  328.       {
    2 z+ S( [. J# _: q
  329.         code = CodeNone;% p% `& j1 r$ P  E/ X% R2 x# m/ c3 S

  330. + N: X1 Q- E1 p
  331.         return CodeStx;& b" s7 C" u# T$ j( ^
  332.       }0 a- z5 E: h; d, ]2 g
  333.     }$ ~! f0 v% K/ E& J& V$ c
  334.     else
    3 z8 E/ K4 A$ C; g. Y. `! ~
  335.     {
    9 q4 A7 i  z4 x; J# D9 b5 x7 H
  336.       code = CodeNone;
    2 X+ O" T3 ]9 n6 L- K$ O5 P7 E

  337. ! ~) w7 ^2 Q3 U8 }! j- @
  338.       return CodeNone;
    # ^' N8 }9 p$ o4 r+ u" s
  339.     }
    9 J4 Q& m6 Y9 T0 R* m2 _
  340.   }
    5 l) q+ ]# t$ }" V# I! _
  341. }
    " w" G+ E! T  X# I$ g

  342. $ {$ d! G) b( Q4 N8 E
  343. /**
    % R0 }( z6 `3 r$ W
  344.   * @brief  Receive none stage.  X9 u) n1 T/ p( Y* F  T# e
  345.   * @param  None.
    : r+ E: T6 N; W2 p  \+ s( ]% Y& ?
  346.   * @return None.; P! C! T  f, X; L+ I5 }& ]$ n
  347.   */$ o$ m1 q  j3 H0 ]3 Y2 F& v
  348. void Ymodem::receiveStageNone()- u; \6 P- {% a# N& {7 V: u. s. |
  349. {1 M' Y/ r; S3 l3 c6 H; E
  350.   timeCount   = 0;0 e' V  l- L; B& s- l7 ?4 P
  351.   errorCount  = 0;
    4 K3 z2 X) b2 G$ X
  352.   dataCount   = 0;
    " B. N! s( r" T6 K! p
  353.   code        = CodeNone;  I0 S$ T  H6 ^, G" l" m( G1 Y
  354.   stage       = StageEstablishing;
    ' }8 x" v7 l9 K2 ?
  355.   txBuffer[0] = CodeC;
    * ^! H$ q( L& N! H/ X6 e" z) K1 o
  356.   txLength    = 1;" i9 q, ]3 Z; V2 ^: V/ _
  357.   write(txBuffer, txLength);1 @2 A. B, l/ v6 w. h
  358. }
    + `( q7 r! R- x( b6 M5 [

  359. " H* n" l' o% I' v2 [7 g9 _
  360. /**1 i, e+ h; e$ g* H2 k+ R; g
  361.   * @brief  Receive establishing stage.
    7 K, g# T) K5 p; s
  362.   * @param  None.
    - Y9 b8 d0 L$ C: b/ u6 [8 l" x
  363.   * @return None.( b# R/ R4 w& [
  364.   */
    # V* ~2 j& F: b% n
  365. void Ymodem::receiveStageEstablishing(); J) A( m; I- n) c1 |
  366. {
    , S( g) X9 H% g0 b( n
  367.   switch(receivePacket())
      c3 x) U; N% M+ r
  368.   {( U$ o; w1 j6 I/ U/ Q4 M
  369.     case CodeSoh:
    9 l7 F+ k: s2 U2 z- i# t/ f/ n
  370.     {) r4 T8 _$ I/ M" ]: E
  371.       uint16_t crc = ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 2]) << 8) |
    0 K: |2 F. s( Y, |  f
  372.                      ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 1]) << 0);
    5 s+ C. P4 n0 g' [% w

  373. - w* V* i5 N' Q* [1 ?  @
  374.       if((rxBuffer[1] == 0x00) && (rxBuffer[2] == 0xFF) &&4 G9 J8 @0 Y, u
  375.          (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_SIZE))). X0 M+ r6 z; T
  376.       {4 c6 ]+ l" O0 E3 {/ ^" R
  377.         uint32_t dataLength = YMODEM_PACKET_SIZE;
    9 q$ K5 Q6 R# @% P; Y
  378. 6 o+ f+ b' F- }/ S1 w1 A
  379.         if(callback(StatusEstablish, &(rxBuffer[YMODEM_PACKET_HEADER]), &dataLength) == CodeAck)
    & S, ]! G0 H3 a' o! |3 \
  380.         {% S& H! f) _* }1 ^( C( Y, T9 X
  381.           timeCount   = 0;
    5 m% u4 J+ q9 I% A  p! j7 O
  382.           errorCount  = 0;+ E0 e3 Z! [2 Z4 ]$ r, L
  383.           dataCount   = 0;1 f% g; ?+ V. \. V' }' R: \
  384.           code        = CodeNone;
    / }/ A; x3 Z1 Y
  385.           stage       = StageEstablished;( z" i* T" R; Y1 `$ K
  386.           txBuffer[0] = CodeAck;: w7 P1 ^2 W' ]
  387.           txBuffer[1] = CodeC;0 b4 G9 G% d- p7 N$ I4 F
  388.           txLength    = 2;- O1 D5 T6 @6 t' U: u' X. v
  389.           write(txBuffer, txLength);
    - |' o* }9 b$ c/ B- y( g
  390.         }" o9 q; G+ \* ~7 I7 i2 S2 V
  391.         else+ O7 C! ?6 \5 K" i
  392.         {6 J: b7 Z8 t7 V
  393.           timeCount  = 0;3 x5 f# I# ^  {% ?7 G  S$ D
  394.           errorCount = 0;$ Z! D% C: G" {9 [1 U4 a% D
  395.           dataCount  = 0;/ _, k& Z# ]% r8 m& N# h' ?2 h$ ?8 B
  396.           code       = CodeNone;
      {* A& g; O: q) i' L4 v$ O
  397.           stage      = StageNone;0 h& ?: F: R) ~5 g0 m# `; x
  398. 1 C  F: J7 q- O. l1 Q
  399.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    , F$ N- d1 ~7 ^( T" O& s
  400.           {5 o" d* P- U1 c) `% ]
  401.             txBuffer[txLength] = CodeCan;
    / j" l2 L& x& }3 r% x* f
  402.           }
    9 n. I& ^, m' j: a5 H  E& j. Q
  403. + V/ d) g: N* t0 c# z
  404.           write(txBuffer, txLength);
    + N! A2 R  b# z8 O) c
  405.         }/ r# c- c1 S2 {% Z9 @
  406.       }
    ( f. A' f9 p& B6 ?4 `+ I
  407.       else" L1 \* K9 C. S- S
  408.       {/ ^5 c: }" V5 c& [! x8 o
  409.         errorCount++;0 N  A# C7 S% K& ^( f$ I

  410. ! [7 Q, [  Z. H
  411.         if(errorCount > errorMax)0 ^  c5 \$ b, X  L7 Z3 z. K
  412.         {1 Q! r1 t9 \8 D" r
  413.           timeCount  = 0;2 a7 _* U2 w$ u4 Z7 \: _; ~
  414.           errorCount = 0;/ F8 n7 ~; Z( [. h7 T. Y/ X& ^) ^
  415.           dataCount  = 0;
    4 T. Y+ [4 v6 J/ S
  416.           code       = CodeNone;  F' j3 h8 _, R9 d3 _) M, D
  417.           stage      = StageNone;
    . r# z: N6 I/ g/ L0 p
  418. ; ^" W) N! L. S. i
  419.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    3 j- W, U0 _# s& ?
  420.           {
    , |3 V: ^2 W8 h5 d' p" ?
  421.             txBuffer[txLength] = CodeCan;0 ~$ R+ f9 h- o- o7 P# {
  422.           }5 F' \$ o  G( ~) T
  423. 0 s6 w( t# Y5 q$ F7 s
  424.           write(txBuffer, txLength);
    & q# Q1 a2 z5 M8 K5 H3 b
  425.           callback(StatusError, NULL, NULL);" `* ~" b! g: k
  426.         }
    5 I, @$ D0 K  e# \$ O4 B
  427.         else: H- u* D4 t  {# j
  428.         {
    2 N" p2 J$ A+ L
  429.           txBuffer[0] = CodeC;
      [% O3 y# f6 {1 n% t
  430.           txLength    = 1;" x4 Z1 q$ ~0 i& L5 r( t$ w
  431.           write(txBuffer, txLength);# X; E8 k7 F, U- K9 m1 W6 {8 f* B
  432.         }
    & t" w" ?; d) i
  433.       }/ t+ X$ Y  Y  @4 e" F

  434. ; z" p) N3 K# ~  o+ t8 w* A
  435.       break;
    2 \& A( A- T+ X% e( H
  436.     }
    " J; [$ N: S" o4 ?# l0 L
  437. : ~" r- q! o/ `# w
  438.     case CodeA1:! b% S& x. k. V5 u6 ~) }
  439.     case CodeA2:# t$ K( F( J& B' C" M9 l
  440.     case CodeCan:
    / l/ |$ {) \3 {: @
  441.     {
    0 Q7 v* j5 j# ?! b
  442.       timeCount  = 0;
    5 c4 H, H$ {$ {; C
  443.       errorCount = 0;1 O! I! h+ ]( y9 ?$ c% ]/ ^9 l: L
  444.       dataCount  = 0;
    & u# v5 Q' z4 F7 v
  445.       code       = CodeNone;" }5 Y) y7 p3 [
  446.       stage      = StageNone;
    ( i. d, c3 x8 b3 C! n: H! k4 P/ r
  447.       callback(StatusAbort, NULL, NULL);
    4 K" b- u- z- h1 [0 D

  448. 8 f. A" w( i  _9 X
  449.       break;- l( Y; D: r/ x( X2 J5 A- Q# M
  450.     }
    0 l  i/ J2 c# b# B6 J
  451. 3 x. x. b3 M# T0 ?) }) a
  452.     default:
    9 |7 B7 ~: ?% U
  453.     {4 d! p. D* p1 o  m' j. K
  454.       timeCount++;  p1 x. ?! o3 b3 r

  455. 5 o5 R  m& j+ D8 N: e8 `$ R
  456.       if((timeCount / (timeDivide + 1)) > timeMax)
    ) S6 \7 R+ m, ?- F" T
  457.       {
    8 l: S. X7 o+ V% D3 ~8 ~% ?8 G2 Z8 t
  458.         timeCount  = 0;- D+ `6 h2 i6 `
  459.         errorCount = 0;! m$ @; o6 t+ P4 i" B
  460.         dataCount  = 0;6 [; N2 N; u& ^/ Q
  461.         code       = CodeNone;
    : a- }+ k# @8 d' W( {
  462.         stage      = StageNone;
    ! W2 `/ }  e! _5 |9 j

  463. 6 H2 M; j! Q- X
  464.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    : O! ~5 M) g# B  s' Y
  465.         {
    2 i+ U0 Y2 h6 U1 j7 x. b# ?
  466.           txBuffer[txLength] = CodeCan;
      }8 P! Q& A, R/ K* q. k
  467.         }
    , }% d/ I5 ^, R8 ^! b# b
  468. * p+ s8 P+ @$ A' I
  469.         write(txBuffer, txLength);
    ! O- c- X# O5 q
  470.         callback(StatusTimeout, NULL, NULL);
    0 ]+ Y1 O. O0 S+ Z
  471.       }
      w( x; ]  x) `6 D7 R$ l
  472.       else if((timeCount % (timeDivide + 1)) == 0)
    : A" L  |/ u% S
  473.       {
    ; W3 v  j" k- ?  \8 G
  474.         txBuffer[0] = CodeC;7 E* m. v' l- J# F
  475.         txLength    = 1;
    . ?& _. Z8 c% o
  476.         write(txBuffer, txLength);. P3 Z' v2 D8 \4 f
  477.       }
    8 \8 R; H% X! f3 N# ~( q' D2 V
  478.     }
    ! V2 t. j: ~' ]2 D1 O; a8 [: Z
  479.   }6 p! U0 H# G. r) ^/ C) P
  480. }
    - X0 H# C& ^0 o/ G: M

  481. 4 j8 J' c1 O5 ]+ ?% r4 _+ P, S: e
  482. /**' p  B  h  G) h
  483.   * @brief  Receive established stage.
    9 W2 ?1 x2 Q" ~, R+ ]( `
  484.   * @param  None." r2 E# |, p# V8 t& m
  485.   * @return None.! U3 `: N3 `& D8 L6 [# P
  486.   */3 a1 A% Q2 A. @1 ?0 o
  487. void Ymodem::receiveStageEstablished(). D: [/ |( p- O7 E% w
  488. {. K9 g0 b6 @0 q3 d* A* G0 f: ^
  489.   switch(receivePacket())' w( w5 \7 j+ j
  490.   {2 N0 [) {4 U2 c" I/ h3 \
  491.     case CodeSoh:
    0 a2 k9 A$ H, L3 u; k) @
  492.     {
    2 b4 S$ x& Y9 y. E2 E
  493.       uint16_t crc = ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 2]) << 8) |
    2 {  F" Q- E+ x5 u8 V. w
  494.                      ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 1]) << 0);# M; F7 p1 {$ S1 {8 X4 L
  495. . q1 o% j3 c6 q+ N
  496.       if((rxBuffer[1] == 0x00) && (rxBuffer[2] == 0xFF) &&
    % Z' R  U6 R: J5 I9 x
  497.          (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_SIZE)))
    + o* R7 |+ o7 {$ K( }2 R$ [, J
  498.       {
    2 }, k; a. L$ [' M! r
  499.         errorCount++;
      J( X( g6 S' g! Z* m. m- Z- c

  500. * c. d" S! a5 b! h) F
  501.         if(errorCount > errorMax), u4 g4 U! b' I' T! a- X1 [5 P
  502.         {1 |! u! ^' r( e, O3 x; A! a
  503.           timeCount  = 0;2 Y: M; c6 S6 v, f+ e
  504.           errorCount = 0;- q) k* s1 J5 a
  505.           dataCount  = 0;
    1 J6 w0 n1 u6 |% L0 M$ H2 X
  506.           code       = CodeNone;2 p& @% y8 R& l# e3 s- p
  507.           stage      = StageNone;( d! }5 @3 [' v- l4 U8 D% H4 s. F

  508. & T  v& W8 B8 o4 J
  509.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)7 z2 m( o, \8 |. g
  510.           {
    + J* A. A) m9 U% {1 K5 N) A
  511.             txBuffer[txLength] = CodeCan;. l# L/ {1 M( R
  512.           }1 g2 P" c) g2 J9 K+ X

  513. * T  G- J; f; Q  A
  514.           write(txBuffer, txLength);
    / ]% A2 W  T. i
  515.           callback(StatusError, NULL, NULL);9 v0 v0 O8 o5 @: f% \( w' @" m
  516.         }
    6 m; k) d' O( F- O
  517.         else
    # P; g0 M4 y  o
  518.         {
    & y. |4 z' d! s
  519.           txBuffer[0] = CodeAck;
    , W5 a* P. j2 r9 [$ q
  520.           txBuffer[1] = CodeC;$ T3 g' U  F7 d, Y" c3 V" b5 w
  521.           txLength    = 2;. ~/ m% c% f- R! p* p$ r) ]
  522.           write(txBuffer, txLength);
    2 P8 I4 Z4 g! F
  523.         }
    : L; Z# b: G3 Z& d
  524.       }
    ( r* T3 P0 _4 K. }
  525.       else if((rxBuffer[1] == 0x01) && (rxBuffer[2] == 0xFE) &&+ t( f1 N6 w6 `4 g2 V
  526.               (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_SIZE)))
    5 a$ L7 _  d8 [3 G0 \0 r5 ?
  527.       {  V: R% N1 X/ y3 T$ S
  528.         uint32_t dataLength = YMODEM_PACKET_SIZE;
    1 X' G- n( p6 l5 }# f

  529. 4 L4 t2 T( `: {9 {" S" f
  530.         if(callback(StatusTransmit, &(rxBuffer[YMODEM_PACKET_HEADER]), &dataLength) == CodeAck)
    & F# \4 N$ N. r  W) q. ]
  531.         {* g) M- S# t4 t& {
  532.           timeCount   = 0;, ]" U$ Q$ i9 y4 \
  533.           errorCount  = 0;
    - g! @; S' K, T# i% h
  534.           dataCount   = 1;: L. h! ]" l/ {( |5 Z8 s( Q
  535.           code        = CodeNone;+ ?7 k1 \  R1 _  L; o2 V
  536.           stage       = StageTransmitting;: E1 w9 a6 g: X; c9 }" h" n/ @
  537.           txBuffer[0] = CodeAck;
    6 ~9 f& g' Q# f- b' z6 C
  538.           txLength    = 1;) _! B! u1 g2 L, m6 s, s" |
  539.           write(txBuffer, txLength);
    ) w" _- N7 f; [( d' i; R
  540.         }
    / T! A; _9 K  D0 R7 s) E- y7 a
  541.         else/ |. H" [& G6 ]& ]; [
  542.         {. b5 V' a8 l6 d
  543.           timeCount  = 0;
    . s4 v& E  W5 _3 Y0 G3 S
  544.           errorCount = 0;
    4 F6 T& ~; N$ b+ U
  545.           dataCount  = 0;
    , P, i7 h: L* s1 g2 X
  546.           code       = CodeNone;! ~! i0 {; N% _, {  {
  547.           stage      = StageNone;0 k0 I, D+ h6 X
  548. ' s; f7 }* {4 n5 `) Q
  549.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    . {  f; [# V4 Z9 R& S. }
  550.           {3 d3 y$ |$ J6 W5 J9 V: u* P# f
  551.             txBuffer[txLength] = CodeCan;1 ~6 z& S' v( P2 [/ ]$ h+ |- ^/ b; z
  552.           }
    4 }0 l; e2 t$ |: K) m: j' t

  553. + D  t9 q9 d% I
  554.           write(txBuffer, txLength);- A0 p7 I6 Y9 j
  555.         }8 Z  N( v7 ?1 m3 ~$ u; B) C; B
  556.       }
    : n' `: G0 |0 a5 F
  557.       else
    9 U2 j0 `7 d" z5 u/ G. q
  558.       {
    9 k! p- x. ~9 b
  559.         errorCount++;  K6 y  a4 d1 S% N: g4 Q
  560. 3 D! }9 J9 K1 {( J5 w; E9 ~
  561.         if(errorCount > errorMax)
    : w) t& V' S" E
  562.         {( e6 E, z: S/ d+ c' n
  563.           timeCount  = 0;8 R/ m5 F$ R6 P7 b& U6 U# q# c
  564.           errorCount = 0;
    + ?/ [- p" W8 z1 K2 |, Y* d
  565.           dataCount  = 0;6 y* ~6 j( [. ]8 G
  566.           code       = CodeNone;* J2 Q! L. m0 I5 G4 C
  567.           stage      = StageNone;! A/ q+ J" A0 l

  568.   D5 I7 ?# _4 x6 Q( V! j+ L. g8 o
  569.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++). k* ~3 `  `4 c$ Z% k9 W5 |! {
  570.           {
    $ H8 U. n' X& e% z! R8 r" M
  571.             txBuffer[txLength] = CodeCan;& ^' j3 s$ g# U* N+ a# j, x' v
  572.           }
      f, A& E) ]4 x% ~) y5 }

  573. : A! m: z+ E0 j- @
  574.           write(txBuffer, txLength);+ G. P0 D1 |* ~/ \6 J
  575.           callback(StatusError, NULL, NULL);
    # j* f! g- K* N- ~' i. u' m
  576.         }( Y: X$ [4 h% o* e' U. X) T! |
  577.         else
    0 d5 p0 @" C- Y
  578.         {
      b* ^& t5 e4 B8 }6 {2 f
  579.           txBuffer[0] = CodeNak;( D4 i8 ^' k) g% _: S' |
  580.           txLength    = 1;
    & X. c8 d& y) Z3 t: E* p
  581.           write(txBuffer, txLength);
    8 j+ J  c. U4 j% {' i* N7 \# K
  582.         }
    % c$ T" K  S1 g2 l  `
  583.       }' b: G/ e# ^5 R! G2 q

  584. ( D' F, v6 i7 A! P
  585.       break;3 X% V' V: C/ Q! `3 Q! A7 ^) V
  586.     }, f4 a& `8 F. w" M* G! }

  587. 6 u) k+ X* [& U3 `) P9 B: m% S& N' Q3 o2 m
  588.     case CodeStx:0 s2 M$ E7 F" J! ^- {7 n
  589.     {. Z' @9 t6 Q  u! z% M4 P
  590.       uint16_t crc = ((uint16_t)(rxBuffer[YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - 2]) << 8) |7 {9 _1 L) u# R
  591.                      ((uint16_t)(rxBuffer[YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - 1]) << 0);1 M1 Y5 p# ]/ c! b

  592. : ~$ P# ?% h3 L. S- T% I. V' S  o5 }
  593.       if((rxBuffer[1] == 0x01) && (rxBuffer[2] == 0xFE) &&) I' l' Z5 N2 q: K) C% D8 l! ^
  594.          (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_1K_SIZE)))
    & g5 e& k4 m) ~8 H4 ]8 p
  595.       {
    3 f: U  |* e) F' f$ w
  596.         uint32_t dataLength = YMODEM_PACKET_1K_SIZE;
    0 x2 w& r6 U! h9 W# Y) M/ ^) y

  597. ( D0 {& e3 O' [5 u; r/ G
  598.         if(callback(StatusTransmit, &(rxBuffer[YMODEM_PACKET_HEADER]), &dataLength) == CodeAck)
    6 u% I* F- @) U
  599.         {
    ) M3 ~( X! n5 D  h, L5 x% ]0 h
  600.           timeCount   = 0;
    2 o7 l% s. K5 @! ]% _
  601.           errorCount  = 0;
    3 e" h( O2 z* X6 q$ L& `9 U, C
  602.           dataCount   = 1;
    ( \0 B9 k: m. j3 y
  603.           code        = CodeNone;" e/ P4 C7 c% u% H+ w5 i  r
  604.           stage       = StageTransmitting;
      Q* ^6 P& z0 I0 G/ Z
  605.           txBuffer[0] = CodeAck;( ?) p4 Q# m# U( `- C8 _/ k( ?
  606.           txLength    = 1;
      a+ W- P  e8 d
  607.           write(txBuffer, txLength);3 G5 }7 y, G" y" s" N% K/ H4 C3 Y
  608.         }
    3 V; X/ W' U) j* M  E9 n% V
  609.         else
    $ U5 N! |! i/ |: @$ C- A0 f* M5 l
  610.         {
    0 t2 Q, q) u) c8 @8 |
  611.           timeCount  = 0;
    ' A1 i( o9 W2 A$ p+ u
  612.           errorCount = 0;7 U8 S2 R- R% z
  613.           dataCount  = 0;) u8 I3 y0 @& ]5 i4 I2 [- ^+ ~
  614.           code       = CodeNone;& J' m! r: l# j3 o, {
  615.           stage      = StageNone;
    / E" ?# |. M9 J0 @% M& e: g

  616. & [# e, i) r. E# k; s1 H
  617.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)+ D5 g& w7 i9 x. S8 w
  618.           {
    0 `5 S: A, b/ [5 F, [; ^
  619.             txBuffer[txLength] = CodeCan;$ E$ r" ?. @& n$ I
  620.           }9 f8 V1 q% v9 c% u  i
  621. % t, d. y2 j! [$ B# w' `! [
  622.           write(txBuffer, txLength);. ^4 E; {& E: c
  623.         }
    " |: Z, S; A# p
  624.       }
    ' Z! w7 l0 u) A1 e+ j. B1 K
  625.       else8 r/ w' ~  A4 R' y- `0 J1 L
  626.       {
    - M" x" W6 o( W: q" H2 {
  627.         errorCount++;
    - g2 Y* {5 ]/ p( J  G7 J5 p

  628. , k! m/ W- C1 i) i5 e& b
  629.         if(errorCount > errorMax)$ K; S8 L. z0 _
  630.         {
    & y" E# u$ `/ ]2 l9 {+ }, f
  631.           timeCount  = 0;
    9 v0 i9 d  D, O" Z0 R2 @
  632.           errorCount = 0;
    1 V( V! L' j2 v0 M0 t
  633.           dataCount  = 0;0 T( g* ]( O2 R& D
  634.           code       = CodeNone;
    9 i3 i* Q" J9 ]) j" {# P. e, B
  635.           stage      = StageNone;
    - ]* Q9 C; _# L1 n8 C, V9 I
  636. ! v# n  G9 L& }% S. S) h( j
  637.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    ( ?, e) \" d' p$ k. f; I
  638.           {: \) Q( [2 n  j
  639.             txBuffer[txLength] = CodeCan;
    . Z8 I1 @  y( g% ~1 q5 `! V  q
  640.           }; a. R3 u, x& H, X, B
  641. ( W; X# y8 _) N2 C
  642.           write(txBuffer, txLength);- u, _3 r1 F: n& F
  643.           callback(StatusError, NULL, NULL);
    " K0 G, m$ @* i* u2 x2 y# [
  644.         }: X7 m7 r( ^, b: s1 y
  645.         else
    & ~$ @; l% J' W+ T# y" k
  646.         {
    3 b/ N3 A' {2 }" h2 Q
  647.           txBuffer[0] = CodeNak;
    9 T% W3 k' [% x% ?  q7 w3 a2 U
  648.           txLength    = 1;7 F6 o0 E: q. L
  649.           write(txBuffer, txLength);
    : ]5 n4 Z( n& M3 {$ Z
  650.         }
    ! C1 e* D% P5 y7 l( g: G& b
  651.       }
    5 K: u- M6 A1 |$ F
  652. 7 s$ s! f. i- M8 X) ]1 c
  653.       break;
    ' o, v3 o/ e& f- N; c0 z) Z( H
  654.     }
    " U7 e6 |3 d7 {* t" R1 y# D, Z/ U9 S
  655. % G# [1 ?4 j  o3 r; G2 T
  656.     case CodeEot:
    " O  Z4 A6 M! s" S* F
  657.     {
    ) W1 H4 r7 x( ?0 K, D
  658.       timeCount   = 0;
    + C: ?. Z- N; w
  659.       errorCount  = 0;
    . G9 u2 y+ J$ f8 ^5 r
  660.       dataCount   = 0;
    ' Y$ w1 T: U2 {* N$ f* i& p+ W
  661.       code        = CodeNone;
    ( c; |' J: |2 X9 t1 U0 S. O
  662.       stage       = StageFinishing;, r/ _8 W% {6 |! g, X
  663.       txBuffer[0] = CodeNak;/ ^6 T  e) E9 N
  664.       txLength    = 1;
    . G( s* z2 |1 D% t$ L
  665.       write(txBuffer, txLength);
    ( v: a5 {- A& B& R
  666. . d  e# N9 i0 l3 U! n, p
  667.       break;
    2 _8 }$ o" F4 U
  668.     }  a1 H& C5 d& F# a! K& S' D

  669. 4 D7 ?3 Z% g& L8 r6 A% }0 A/ R
  670.     case CodeA1:
      ~- x8 M: V8 h' m* A
  671.     case CodeA2:" N7 c3 v; G/ z  R" l. a
  672.     case CodeCan:0 x# d6 i( _6 g9 S" e7 Q
  673.     {! l1 ^8 L1 R6 U4 t
  674.       timeCount  = 0;  F( l% n5 E. C6 U" m* h6 p
  675.       errorCount = 0;
    ) ~! G; Y8 R# Q& i0 u
  676.       dataCount  = 0;: l, l$ q. s/ u! U$ B7 [" u
  677.       code       = CodeNone;7 s% T# X3 d7 d. W6 d! a
  678.       stage      = StageNone;
    ' o% @9 X7 b( `4 W
  679.       callback(StatusAbort, NULL, NULL);! U) S, W( o. i7 H

  680. . w2 q+ _" p8 J* F# `. ~
  681.       break;5 I" h3 i8 B, p4 z. D4 I
  682.     }
    9 n& Z$ h2 j* e# v
  683. / Q9 ?0 m/ }! |1 b: L# P
  684.     default:  _) |9 N! F6 \- X$ K2 ]
  685.     {. d, d" q3 R. g. k, b' r3 _2 d
  686.       timeCount++;
    9 Q7 o9 f- y" Q! K
  687. % {% T: o( M/ m& ?- a8 Q
  688.       if((timeCount / (timeDivide + 1)) > timeMax)
    , R+ Z- ?+ U& k: d7 s2 y
  689.       {" E2 _) b9 k3 `. ?2 E1 W/ t5 p
  690.         timeCount  = 0;
    , p- @4 N* B. Y5 G# a
  691.         errorCount = 0;
    4 @9 u; O' O  k( V, K# G6 a
  692.         dataCount  = 0;- _; z+ j- q- t0 C+ s3 U" i2 w- [& s& w
  693.         code       = CodeNone;
    5 F2 S, E& _* Z4 ~6 y, [
  694.         stage      = StageNone;
    - w4 `1 L/ a$ |9 v: o) U  v% B# z
  695. & K2 N; {  v% x2 @5 L& }
  696.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    ! [6 B" a( D$ j
  697.         {4 U" I. E% P. N; w; z5 g: W
  698.           txBuffer[txLength] = CodeCan;' v4 ]+ Q, U% A1 m9 [( x
  699.         }# f9 [6 Y* j- x. e5 w
  700. & x; [& s  U4 K$ h
  701.         write(txBuffer, txLength);5 b8 [- g0 \' S% r
  702.         callback(StatusError, NULL, NULL);4 L4 l2 f8 z" ^5 L  l
  703.       }
    ' \8 K8 T8 r0 i" C
  704.       else if((timeCount % (timeDivide + 1)) == 0)7 z5 n$ f% a+ z
  705.       {. C% Z0 u! J, {# c# x$ v/ i
  706.         txBuffer[0] = CodeNak;
    4 E9 Z4 }+ L9 b( I
  707.         txLength    = 1;
    5 p; {0 d+ S4 @7 ]
  708.         write(txBuffer, txLength);8 }) v0 Y1 s% }: L8 e; e: S
  709.       }8 T  g8 m1 x+ h  ?8 o1 Y# V
  710.     }- k" U: x* R( ~* m/ O
  711.   }: }5 E: T" ]4 e; J+ j7 @
  712. }
    ' K9 _' t$ ^0 v' v# y

  713. / c; }8 P3 {4 t3 ]" r7 I5 `( h
  714. /**
    ( d. w) f3 {; O
  715.   * @brief  Receive transmitting stage.
    # U/ c# A, `6 t4 j4 P# H
  716.   * @param  None.
    1 ~9 Z* |4 m+ d7 O
  717.   * @return None.8 H) ^8 I: a# g( I  p/ Z* [" g
  718.   */+ W2 B) A. y, u
  719. void Ymodem::receiveStageTransmitting()
    1 r8 u1 T2 a$ F+ B7 K' i( @
  720. {# d' T- o) C  h& }. @% E
  721.   switch(receivePacket())
    " g1 F- d! Z& p9 @! Z
  722.   {
    ' o/ E  \" r# K
  723.     case CodeSoh:# P5 D' d0 s5 Y; m# o" x
  724.     {( F8 u, l+ t5 m, e8 E5 c, Y
  725.       uint16_t crc = ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 2]) << 8) |
    # B1 O8 H/ \. V9 `" e
  726.                      ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 1]) << 0);* m/ O$ N+ e: s$ I& i4 G
  727. 2 v$ ]6 ]5 C  `6 o0 d
  728.       if((rxBuffer[1] == (uint8_t)(dataCount)) && (rxBuffer[2] == (uint8_t)(0xFF - dataCount)) &&. T$ X! n9 G# G; p! T& p
  729.          (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_SIZE)))# X8 _7 D: d/ N& N3 f4 M3 y2 W
  730.       {+ P" n9 t  @( F1 C
  731.         errorCount++;9 f& g1 d3 T0 Y7 _: X" Y7 ~
  732. " J2 ~) v  m# K$ f3 B# H
  733.         if(errorCount > errorMax)
    0 J. N; P2 i( e3 I" [
  734.         {
    6 p& t; s% R9 ]6 z/ L' T  ?- s
  735.           timeCount  = 0;% Z8 j6 a! p# T! S. p& j
  736.           errorCount = 0;
    9 I$ \3 k- }$ R8 v6 q" l- O" z
  737.           dataCount  = 0;
    & P! J4 l3 d0 l0 [% `& j6 u1 Y
  738.           code       = CodeNone;
    5 M6 ^- r+ p$ z7 S
  739.           stage      = StageNone;
    8 _$ Z* `+ ]' o; X6 E; V: F! S

  740. . b( L$ W6 W; R
  741.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++): ~* W, u* q7 N$ J' p( _
  742.           {
    ! C% A- E* ^7 r1 y8 H. ^: ^
  743.             txBuffer[txLength] = CodeCan;
    & P+ q4 O7 @2 T! [% q
  744.           }$ C3 Z! \* P7 u: G
  745.   \* ~' D7 d& v2 U5 v# H
  746.           write(txBuffer, txLength);
    7 i: A( Y. S4 a
  747.           callback(StatusError, NULL, NULL);
    ; {. u9 N9 t$ G8 \9 T( F! h- {
  748.         }" M% H( T" J# n" x4 S" [) {
  749.         else1 N1 e. h& f8 Z, R/ q9 @- |1 [9 U
  750.         {* T9 ^0 ^! m5 d8 E1 n
  751.           txBuffer[0] = CodeAck;
    3 Y3 Q( G1 D- n" U: g! J( m
  752.           txLength    = 1;
    " n2 F$ D2 }+ n/ Y, e* N
  753.           write(txBuffer, txLength);
    9 [8 M/ G) @8 J( r: q
  754.         }
    & ^, D. W; J+ _) m& o3 w! ~
  755.       }
    1 i' ~/ U/ {1 w1 q9 Q+ E
  756.       else if((rxBuffer[1] == (uint8_t)(dataCount + 1)) && (rxBuffer[2] == (uint8_t)(0xFE - dataCount)) &&6 ?: V1 p* O5 A; k7 `: P6 u
  757.               (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_SIZE)))3 O: Z, y+ l, N9 p$ k0 e
  758.       {
    6 g) s0 J% L9 z6 g0 T% o1 T
  759.         uint32_t dataLength = YMODEM_PACKET_SIZE;6 w/ d" n3 K# @' a

  760.   k( G( J1 M4 h# p" D2 G* c# T
  761.         if(callback(StatusTransmit, &(rxBuffer[YMODEM_PACKET_HEADER]), &dataLength) == CodeAck)0 O& o) W* e# l1 Y1 c; b4 `
  762.         {: h' w. u( y, Q/ l3 E
  763.           timeCount   = 0;
    - b9 y5 X* H3 R" x( r  B4 w, I
  764.           errorCount  = 0;) Q; I0 O2 T" e4 Z$ C6 k
  765.           dataCount   = dataCount + 1;& q! ~3 I7 O! H
  766.           code        = CodeNone;" v% z+ m# {  |" P
  767.           stage       = StageTransmitting;
    ; ^; h" f) c* [+ ]9 c, h# |
  768.           txBuffer[0] = CodeAck;
    , p# q' t' A( g9 s1 R
  769.           txLength    = 1;; x0 K/ R, s/ r2 p# b7 Z
  770.           write(txBuffer, txLength);
    ( o% {" `1 t& K# _, C9 Q% ]- E( u
  771.         }
    ' }$ S6 X4 S# }8 C  W
  772.         else
    ; R/ K% I3 V2 `
  773.         {
    7 e: [2 A7 F* T" M2 u/ P( w0 r
  774.           timeCount  = 0;
    , j) F; T2 K0 ]0 Q; J; w! P- r
  775.           errorCount = 0;' {! e- q5 E5 U, q* M, c7 i4 I
  776.           dataCount  = 0;
    % E7 f' ?4 S. A* i( r  {
  777.           code       = CodeNone;7 b; G$ Y8 H& g' _2 \
  778.           stage      = StageNone;6 h0 \- i7 e; {. @) a

  779. % M$ q1 n& Y4 B* I. h9 n
  780.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)' i* h- u) l/ Y9 y- m' z" C
  781.           {
    ( o5 M1 _7 a  o
  782.             txBuffer[txLength] = CodeCan;( t* O% k# p! i3 S; ?& @% Q2 [
  783.           }6 F- J. \: U4 o, }
  784. : ~( l1 V6 t- |0 D
  785.           write(txBuffer, txLength);
    8 q7 [! M* v# `8 J
  786.         }
    + O4 y0 `6 r4 y* }# x
  787.       }; V/ f1 [8 g6 z9 D7 h
  788.       else8 }6 q$ V; f/ L
  789.       {
    ' j0 |2 x- V+ {! J- ]
  790.         errorCount++;
    " h+ _7 i% j5 `) G# c

  791.   \. D( V: B5 f; i0 ~5 d* f
  792.         if(errorCount > errorMax)2 v1 ^+ w6 n1 h
  793.         {" I4 [& W8 E. s$ T% f7 \; k
  794.           timeCount  = 0;# `7 G! U* r2 I
  795.           errorCount = 0;
    0 V0 N5 }( t2 O! _4 q) A- G8 G; |% H
  796.           dataCount  = 0;8 Y) W5 n( p% ~* t
  797.           code       = CodeNone;1 G4 x0 g+ M# A2 X" H
  798.           stage      = StageNone;
    4 g" ^# c# _8 V6 i

  799. 0 v/ }0 D" {- C4 k" K0 V7 R; q3 I
  800.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)% P: l9 H* K5 l; w" i0 g9 T
  801.           {! |7 p% A# r9 }9 h; g
  802.             txBuffer[txLength] = CodeCan;  _. W- @- N! A
  803.           }
    ; W/ d5 B! Y, F  k9 Q2 b: i: d
  804. % E2 Y2 o: ?4 R( C! q
  805.           write(txBuffer, txLength);
    & I2 u1 h2 I; h
  806.           callback(StatusError, NULL, NULL);# Y& W) k5 ?4 C2 C/ |% J# o3 z
  807.         }
    & w6 y$ F/ q8 h
  808.         else
    1 |" M/ u: Y9 X! M# W$ |
  809.         {. b# |1 H  r3 Y8 K4 b1 O! R3 P
  810.           txBuffer[0] = CodeNak;% }' g8 F  Y! r# q+ A5 ~
  811.           txLength    = 1;
    0 Q# b3 p5 t; q' f1 H
  812.           write(txBuffer, txLength);
    3 d: t- B: ]; W
  813.         }6 q. ?  n% M  A( g/ C
  814.       }
    % q5 ~4 k; Z7 g2 s. o3 ^
  815. - A# ~( b. M5 m8 m% n7 e
  816.       break;; d5 p* f. G: J# ^& M/ z/ S
  817.     }4 f! u# |4 a5 w9 _1 \  v9 Q

  818. 3 x2 v: s9 p7 f. ^
  819.     case CodeStx:
    7 u: Y. O/ H2 B! }: ]2 k5 M& B
  820.     {
    , I# y$ @  J9 D& y. P$ q( a
  821.       uint16_t crc = ((uint16_t)(rxBuffer[YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - 2]) << 8) |! k7 E# H6 j/ L5 K& @
  822.                      ((uint16_t)(rxBuffer[YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - 1]) << 0);6 ^6 i& Q! l8 p! f) ^/ {+ M
  823. % |, E# d4 [5 S" ~
  824.       if((rxBuffer[1] == (uint8_t)(dataCount)) && (rxBuffer[2] == (uint8_t)(0xFF - dataCount)) &&; m4 i; M4 a1 V, I  q/ W6 }" p2 x1 U3 e
  825.          (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_1K_SIZE)))3 T: n! z( q# Y+ d( `7 F+ J
  826.       {) u* w  K$ l4 H. E  w* y
  827.         errorCount++;5 e7 G0 n5 n1 |$ E& L
  828. $ `* y& L, |1 S  J
  829.         if(errorCount > errorMax)! z9 o* M8 L' @# S" z* j
  830.         {
    0 G  A. h# o/ A9 p
  831.           timeCount  = 0;
    9 K/ R6 P, k' s8 a* Y4 B1 O% m8 ~+ r
  832.           errorCount = 0;$ g% k% ]  r2 H  z
  833.           dataCount  = 0;" o( n' ]+ _5 i- F' l2 F2 w
  834.           code       = CodeNone;0 K: K9 Y+ d; q$ [0 D
  835.           stage      = StageNone;# f. A- H/ S9 y( u  o

  836. # i) m3 u7 s6 j* L: A+ R. }
  837.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)- c+ ?! v: G, M% _
  838.           {) m5 L' l- u& y/ p$ L5 x& p
  839.             txBuffer[txLength] = CodeCan;0 E$ i  M$ [0 l# ^  v  _* J
  840.           }
    # l5 Z7 K3 Z' I- f% x% ~7 I
  841. * c: f& Y: Q3 z
  842.           write(txBuffer, txLength);
    : I* s0 F* ^7 A" _9 E
  843.           callback(StatusError, NULL, NULL);. r! ]2 m6 O' S2 I/ X
  844.         }4 W3 U6 ^- d: c- w) Z- V$ v: {
  845.         else: w5 G- a% L) q
  846.         {& |: R2 m; e) E2 h9 W" e
  847.           txBuffer[0] = CodeAck;. U. c  e( @8 i  `( l
  848.           txLength    = 1;7 J( p$ K, V. O! W* x* C. L7 u
  849.           write(txBuffer, txLength);/ y  b9 B( v5 l# L  y% R
  850.         }, N% f% ^5 B' r& r- D
  851.       }/ `. o1 t6 j: A& g7 L1 y8 }' W
  852.       else if((rxBuffer[1] == (uint8_t)(dataCount + 1)) && (rxBuffer[2] == (uint8_t)(0xFE - dataCount)) &&2 n! u: e6 K( [7 t" R
  853.               (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_1K_SIZE)))
    / g/ J0 J# c( K( K
  854.       {
    ) r& H/ n0 u: c/ V; \. h6 M. M8 @
  855.         uint32_t dataLength = YMODEM_PACKET_1K_SIZE;
    + H9 \; i9 L2 K) C+ n

  856. % H! L4 f. E0 B0 G; }
  857.         if(callback(StatusTransmit, &(rxBuffer[YMODEM_PACKET_HEADER]), &dataLength) == CodeAck)2 q. D! V4 j% i
  858.         {/ [: e) Q3 r/ j7 W
  859.           timeCount   = 0;% |1 Z9 H" g( k8 x5 B" u6 X
  860.           errorCount  = 0;: y- x) m. }% i
  861.           dataCount   = dataCount + 1;
    & T2 n3 |6 D: `  |$ F  Z
  862.           code        = CodeNone;' g) b& h: N5 D$ ]
  863.           stage       = StageTransmitting;' [: e1 W  O! b: v% O2 @; M
  864.           txBuffer[0] = CodeAck;3 i7 c# |. K5 ?' X0 o4 |+ w
  865.           txLength    = 1;
    " F8 r9 T/ h! ?% m6 u
  866.           write(txBuffer, txLength);
    * ~6 x4 c! g+ B) R
  867.         }
    1 c$ L% N  ]3 n+ ^# V. b3 x
  868.         else* x; i5 }6 @$ u3 i$ W
  869.         {& ^& y2 ^$ S# Y+ v6 H+ }7 ~
  870.           timeCount  = 0;4 q3 l1 x. q! v5 S( J9 F* @
  871.           errorCount = 0;" X  h9 g3 g  B' T* Q& x
  872.           dataCount  = 0;
    4 Y) Z+ Q' F. ]  z( x1 p9 v! C
  873.           code       = CodeNone;
    ) W3 c  [, j# l- p
  874.           stage      = StageNone;
    " M( ~5 e9 p4 g* ^, p* o
  875. + H* C% |& j, A0 [
  876.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    3 F% e3 @. X/ r4 e) \7 v7 |
  877.           {
    8 u# \5 K: f% J( F4 h
  878.             txBuffer[txLength] = CodeCan;
    # K7 }8 w3 T. a. D7 z. u" U/ E0 `, f
  879.           }
    ' x+ K  W+ ^& X' i
  880. 9 |3 z- w/ I9 F" i
  881.           write(txBuffer, txLength);7 L3 O  ~9 h7 l9 x6 ]
  882.         }: x0 V. o! H7 c
  883.       }# Y. n4 ?* y& {4 P1 X  G
  884.       else5 n6 E* c! A0 {' B$ F
  885.       {
    7 `8 w# F# c1 i+ ]$ x4 r
  886.         errorCount++;
    , x$ m/ I' H" b9 U4 f" n

  887. ) D4 p1 ~" E+ r9 y$ m# b
  888.         if(errorCount > errorMax)
    , R9 C# J# w( \' I5 d& v9 f
  889.         {, }7 C, `2 Z$ X) B
  890.           timeCount  = 0;
    ; S+ w, U+ r& c, |5 H  `4 z$ E0 T, e" _
  891.           errorCount = 0;) f& h! I4 m' Q, q. E& M/ v* b
  892.           dataCount  = 0;" Y. m5 Z# }+ a
  893.           code       = CodeNone;
    6 i2 j% B, g6 J' _
  894.           stage      = StageNone;
    8 y. x, T; `7 ]% ]& m8 b4 ^$ a* ?6 u

  895. 6 b8 ?- d# f8 S/ ~) p
  896.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    0 F) y9 f) ~/ N
  897.           {, ~/ c, {7 N7 [' o5 `; X" Z. S
  898.             txBuffer[txLength] = CodeCan;0 W) R+ `/ F8 {" b9 I# H% U3 o
  899.           }
    # _/ I+ a3 I# T- e" N

  900. 0 C( Y1 j/ T4 E" ~
  901.           write(txBuffer, txLength);
    * n' o* w4 j. E* t% L: U
  902.           callback(StatusError, NULL, NULL);; ~( L) b" N8 x7 A, b
  903.         }
    4 R8 w! z9 J# h( x1 M$ g
  904.         else
    2 F, ]0 `6 J$ h. ?
  905.         {
    - Z3 a: E  {1 m: X: I
  906.           txBuffer[0] = CodeNak;" F: q, X( c. c, D- i& K% V1 |; R
  907.           txLength    = 1;% S* h4 _" T# h" o4 i6 f/ O3 E9 Z$ |
  908.           write(txBuffer, txLength);
    5 b: n: B% _5 u' Z4 [. ^( O
  909.         }
    2 i" D6 _4 C1 U
  910.       }
    $ b4 H! {( ~  Y4 K1 W5 W0 u
  911. 6 w  c* s* L8 P' n& A
  912.       break;9 M& v7 o* |& P* J
  913.     }
    ' W2 ^. w) A4 N! z" A$ G0 A, @
  914.   ?& z; g) z4 {4 w
  915.     case CodeEot:
    ! M! E$ o* [2 A0 ^& ?" q  e$ w
  916.     {
    " K1 d$ o0 k  N! @: G
  917.       timeCount   = 0;
    3 f* l1 i6 j- i! G
  918.       errorCount  = 0;
    : h: X- ]) {; e( U
  919.       dataCount   = 0;. G* ]& ~" ?7 a5 e' `2 u! E# X
  920.       code        = CodeNone;
    7 Y, B6 Q0 v8 a. X/ |
  921.       stage       = StageFinishing;) E. ]9 [& V8 a" X4 k: a
  922.       txBuffer[0] = CodeNak;! x+ }8 a3 d* ^/ Q7 N4 |
  923.       txLength    = 1;
    3 l& N' @& a' H0 q' J! \" b7 ^" s6 j
  924.       write(txBuffer, txLength);
    . G% ?0 ?$ Z4 I! V& {, i) N) g3 c& E
  925. & b" ~: _/ W) U& \6 k
  926.       break;3 O8 Z4 h5 h" |  m* j
  927.     }/ }# j- d. q& N8 C, K& c( c( u

  928. : G; ~+ b3 d8 t2 M+ O
  929.     case CodeA1:& S+ a$ w* B% p/ w6 ]1 J
  930.     case CodeA2:
    5 l# F* V7 ~+ ?6 v, Q: F
  931.     case CodeCan:! N! c2 f  |5 w3 L& a5 |" e; m
  932.     {
    ! x& t! @. y, k' j
  933.       timeCount  = 0;
    4 G. v" y/ G; K
  934.       errorCount = 0;
    - i: K& e$ T( \( ]. [1 S' q
  935.       dataCount  = 0;
    ; y& M2 [0 u" w  k# x" A
  936.       code       = CodeNone;$ I. |8 }7 O" T- `1 a2 U
  937.       stage      = StageNone;$ _5 W! A/ `* y1 H" `
  938.       callback(StatusAbort, NULL, NULL);
    , p3 x3 Q/ D  P& r7 f
  939. 3 k2 @7 v, {" F# C. Q) H& d: ]
  940.       break;
    7 C) p4 \) }  X
  941.     }6 F; O( m1 r6 q$ h# B$ y: Z
  942. 9 ]8 Q6 I/ h7 G' H& z
  943.     default:# @* a4 J! e' }  w+ A  O3 J1 q2 E
  944.     {& @' g# b, q7 N) {: g9 Z# N# p1 ]
  945.       timeCount++;
    ' ?& Z; ~! y9 ]9 L/ b8 C
  946. : X+ v( A- u5 X6 n1 g
  947.       if((timeCount / (timeDivide + 1)) > timeMax)
    1 K8 i! l( N* q4 z' }
  948.       {( }1 I% r" |( Z5 ~( v1 ^. G5 e( V
  949.         timeCount  = 0;
    + k% Z, z& ]3 O6 K" D
  950.         errorCount = 0;  T& Z4 c# u5 t
  951.         dataCount  = 0;
    8 S% J& T9 v8 P/ o. V
  952.         code       = CodeNone;
    ( T7 u, V0 G) [; g$ h. D; ]
  953.         stage      = StageNone;% ~$ `! Z* K: \/ O3 k3 B5 {

  954. ! F2 F7 A' l3 ]$ d9 P( d' y3 H
  955.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    ! K$ \  T) I: O8 Q6 ^
  956.         {1 r$ q0 o, Q. Q' P, j* n; a- f
  957.           txBuffer[txLength] = CodeCan;
    8 F6 ~' v' }, p  c
  958.         }
    5 d* B# @+ l4 |# w3 |5 a

  959. - ~* q6 y5 [, e" t
  960.         write(txBuffer, txLength);3 j* i. I% q" |
  961.         callback(StatusError, NULL, NULL);
    5 `6 I; W2 R  g0 S2 U1 J
  962.       }
    " G3 f. a$ f9 B- A! D
  963.       else if((timeCount % (timeDivide + 1)) == 0)
    ! F# ]8 r  H2 i2 I( e9 u
  964.       {$ a$ r4 H  ?: K: Z  X# s9 L
  965.         txBuffer[0] = CodeNak;
    ) {$ h5 i' r, O/ O8 M0 i
  966.         txLength    = 1;
    7 i. ^" ]0 P0 K
  967.         write(txBuffer, txLength);
    & M1 W" ~; j" y5 ^7 W7 L
  968.       }
    ( K. _3 t' N# [' U8 C5 y! r/ d1 j
  969.     }5 x/ C+ ~+ _* i0 b" S" l
  970.   }7 W9 J* c1 b. [! R
  971. }4 X. V- d- y9 l5 o1 v; n& x9 J6 j

  972. 0 H0 H8 D& |2 F+ Z
  973. /**
    & z, n4 i  |0 D" j3 ^" u* L& i4 l) w
  974.   * @brief  Receive finishing stage.
    ' s8 Q, T9 Q; T! P; U( `7 z* S
  975.   * @param  None.2 U2 \3 I: n: {3 g
  976.   * @return None.6 E3 m3 B" k0 m# J" v3 F! p+ M
  977.   */9 h) p2 a. `. {' |/ N
  978. void Ymodem::receiveStageFinishing()3 R/ Z' D% r/ d1 O
  979. {% q; h/ V  [1 P
  980.   switch(receivePacket())& K2 \- Y& T. q2 O
  981.   {
    6 T% Z, r& y2 Z4 ^/ ~, m
  982.     case CodeEot:
    % Q/ G& Q8 ^$ J  Z2 [1 V
  983.     {
    ! Q& Z3 M; U0 @# T# @
  984.       timeCount   = 0;
    : g; c$ J; F: g8 C0 {" f: n
  985.       errorCount  = 0;* R0 Y/ {* Y- @" S9 l
  986.       dataCount   = 0;
    6 E- i0 ^& ~& k- U' {1 Y; F- v- w
  987.       code        = CodeNone;5 k- A  G0 \0 `. O5 S" P
  988.       stage       = StageFinished;
    / J# A4 Q; A3 g/ M
  989.       txBuffer[0] = CodeAck;1 R, o# i2 S2 P# m/ a: R* K; N
  990.       txBuffer[1] = CodeC;
    " m4 s) X3 x- [) O7 {, E) G9 ^0 J6 k* C
  991.       txLength    = 2;" H) M6 c; ^" q8 D4 x  h& o6 H
  992.       write(txBuffer, txLength);
    , |+ b: ^& a/ E& @/ f
  993. 6 Y5 I# w/ V4 z9 C- K
  994.       break;4 J& V0 n+ Z# m. D& n/ S/ C
  995.     }* {" P8 k' m% k( {3 C* }. i

  996. ' x0 U8 P9 j, w- G% O
  997.     case CodeA1:! G" x5 z* u; w1 w1 O# ~; \
  998.     case CodeA2:
    / h. J* r0 o/ P2 U! w" ]- \) h
  999.     case CodeCan:
    - c: ?, ~5 p& |6 |
  1000.     {
    # s: d8 d/ e9 g
  1001.       timeCount  = 0;
    5 V& G  o' D; L" K2 R/ V9 V
  1002.       errorCount = 0;
    2 @3 r3 B' Q- P& @/ i- W* B% g
  1003.       dataCount  = 0;
    1 ~* g) c$ Z6 X1 }. ^- x
  1004.       code       = CodeNone;
    6 E# |- N) S2 @! J' ~, v$ S
  1005.       stage      = StageNone;
    ! U, l& c' `" J0 p" n9 r
  1006.       callback(StatusAbort, NULL, NULL);
    2 B7 k1 _, z7 N% ^
  1007. # k5 ]# U" o" v& q
  1008.       break;
    , w7 T+ @1 W% b; [3 R
  1009.     }6 [( ?( x, L8 ~) U7 Y

  1010. , d* t2 Y  p( K, k0 X5 ]5 y4 q, x
  1011.     default:0 p4 W3 k( P6 w* J
  1012.     {! p1 N$ j3 {' s
  1013.       timeCount++;- l3 M3 S% Q; i6 x+ a

  1014. . \7 L! q7 f, s6 ~1 ^  J
  1015.       if((timeCount / (timeDivide + 1)) > timeMax)  d2 e: h3 e" X! U
  1016.       {
    7 @. g4 ~# k! J! D' w
  1017.         timeCount  = 0;" S' x, i- F8 Q. ~5 x3 H) E. Y
  1018.         errorCount = 0;; D! x% z1 ~) A9 `) {) M( v- L
  1019.         dataCount  = 0;
    6 y7 i  F( v4 K# O; a# m4 S
  1020.         code       = CodeNone;
    + k( B4 L$ f+ X7 C$ }4 q
  1021.         stage      = StageNone;" [) L/ Z- L9 [/ d: {, @

  1022. / Q  n! g$ t" d
  1023.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    ' X& b  e+ E9 Y& r7 q4 w
  1024.         {+ ]3 f* x& S/ U4 v+ o7 }$ T
  1025.           txBuffer[txLength] = CodeCan;
    . s6 w* F; Z6 F" W- _
  1026.         }
    ) F# f5 H  @- d0 z( ~# ~
  1027. ( [6 O5 V9 t- a8 p
  1028.         write(txBuffer, txLength);; k% N7 \& B* s4 m/ U0 k& }6 ^
  1029.         callback(StatusError, NULL, NULL);
    " ~9 [4 t, f  |
  1030.       }
    $ G  X2 w7 w, M5 n
  1031.       else if((timeCount % (timeDivide + 1)) == 0)8 s4 t) U! n6 X6 x! M" k( X
  1032.       {  p  Y' C8 I/ O1 C2 _
  1033.         txBuffer[0] = CodeNak;) x% k/ _9 ~+ F9 J
  1034.         txLength    = 1;9 J4 K, O4 ^! u5 U
  1035.         write(txBuffer, txLength);
    7 X  H4 T* W5 ?# r
  1036.       }
    7 t! S* `# I& m# R
  1037.     }
    3 _0 {8 s2 q! m  h
  1038.   }6 I1 l, o$ J7 w0 f" f* A* J
  1039. }
    , R3 P! {2 v7 f1 M; ?2 J

  1040. % ]- h0 f$ D$ _  |! x
  1041. /**6 m2 v% x: _9 j1 R
  1042.   * @brief  Receive finished stage.( `* ]' J. `# E: M
  1043.   * @param  None.% e# A$ K8 p6 s' w$ R8 y7 X
  1044.   * @return None.8 M9 `8 v4 G4 _  _" S$ N
  1045.   */
    3 l# {0 C$ y2 R7 ]) K) v, Y  G% R) K
  1046. void Ymodem::receiveStageFinished(). e, S) t; n1 V+ p$ @4 F3 q! K
  1047. {+ r. f% I5 F6 i: I8 M4 _3 j+ B
  1048.   switch(receivePacket())
    + j8 j- J0 T5 ?0 p& P$ G2 Q" C
  1049.   {' F2 F9 j: i2 `% R9 `
  1050.     case CodeSoh:5 ], g4 t# a$ C. c+ o# n
  1051.     {% X" m% ]/ p8 c
  1052.       uint16_t crc = ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 2]) << 8) |
    1 C1 V( E0 K3 @3 S
  1053.                      ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 1]) << 0);; _+ r! w0 ^' P3 W) w  E7 U# x) T
  1054. $ w$ B! `5 \0 p, n. ?* u& O! m
  1055.       if((rxBuffer[1] == 0x00) && (rxBuffer[2] == 0xFF) &&. n0 g4 x  I" ?' x; l
  1056.          (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_SIZE)))+ g) }( o+ _; X7 h1 N. \1 R( x
  1057.       {5 y) x$ p, b( M* L( S+ A
  1058.         timeCount   = 0;
    3 r5 Z0 g* k8 N2 P
  1059.         errorCount  = 0;
    - A1 k) R6 K2 Z' W
  1060.         dataCount   = 0;# \* W$ A' ]. w8 d2 I5 w
  1061.         code        = CodeNone;+ D0 C9 l/ u. x- D
  1062.         stage       = StageNone;2 A2 N3 b, g- l
  1063.         txBuffer[0] = CodeAck;* v3 x+ q" L2 x2 O' I3 V0 Y
  1064.         txLength    = 1;4 P: a6 l: H7 A. |; k
  1065.         write(txBuffer, txLength);
    : q. c7 l0 a8 J( \
  1066.         callback(StatusFinish, NULL, NULL);
    9 D4 ~- s& C/ P4 s' C5 a; W
  1067.       }
    0 l7 m5 I/ f: V" Y' F
  1068.       else& D$ y- I( f  M9 B9 Z! s
  1069.       {- z5 K4 T5 u+ a: B
  1070.         errorCount++;
    % V& ]) `1 G' b3 k) S5 b, r

  1071.   O# h2 L9 G" x
  1072.         if(errorCount > errorMax)
    + H7 j, K( H5 q8 t; @8 Z
  1073.         {6 |. I9 e. ]+ g/ R1 @, a% m
  1074.           timeCount  = 0;9 S7 h4 z, p) O0 [/ e  f/ W" F" h
  1075.           errorCount = 0;3 N& T) c  B, i% c  Y. S
  1076.           dataCount  = 0;
    ) n; I5 X) m/ O, Y  \4 Q" }1 `4 Y, `
  1077.           code       = CodeNone;
    $ o( W8 p2 o  C3 ]9 l: {* {
  1078.           stage      = StageNone;- e/ n+ `0 }# `3 z) ?# G
  1079. 9 s% v; ?* v7 v9 g  k( a7 M3 V
  1080.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)6 C7 N+ P' `+ [( F7 f9 \
  1081.           {- U) u% v& m3 b- f
  1082.             txBuffer[txLength] = CodeCan;- W" M5 Y5 x3 j; J1 Y3 b
  1083.           }$ j$ P9 U' Z3 f2 |# f

  1084. 1 ]4 B7 ?' q+ l
  1085.           write(txBuffer, txLength);, ?. `; }8 o, X$ X" L
  1086.           callback(StatusError, NULL, NULL);3 Y7 n+ ^5 f% X
  1087.         }  N6 m  S4 C# |6 t" o" B9 w
  1088.         else2 }3 H5 d$ F2 {4 u7 W4 B
  1089.         {. s) b  m' _2 v% O- U4 x
  1090.           txBuffer[0] = CodeNak;
    : u0 r3 }" l  @$ x& ?
  1091.           txLength    = 1;
    2 e* D% [: c( x/ U
  1092.           write(txBuffer, txLength);# |7 E* e  K& X: U. d% i
  1093.         }4 }7 w3 s4 W7 }* t
  1094.       }
    0 l( ]+ s/ _8 K) z6 E

  1095. 0 K( R$ b( _! S0 E% b( Q  e8 d
  1096.       break;
    3 g2 t7 K% J  C6 `
  1097.     }
    - W, C4 b7 W4 v' h% P) x6 S: n

  1098. / |7 a+ G1 X9 ]4 x! D! v8 W
  1099.     case CodeEot:- C9 w9 @. E0 |) t. z3 W& z
  1100.     {' Q. B% y6 Q8 I4 \- [+ H
  1101.       errorCount++;
    1 F! G; q9 V+ d  W1 z+ Z5 ]2 g$ z2 l
  1102. 2 U7 K  z* `0 s" D$ |; @6 F! f
  1103.       if(errorCount > errorMax)8 B5 L' P$ m, J7 A. c6 }
  1104.       {
    ; H" `* ?7 s7 O: m2 u
  1105.         timeCount  = 0;
    / I/ |1 u. D6 E1 P1 m) T# b; |
  1106.         errorCount = 0;# k8 _: U5 z3 J3 b4 q; ^' k
  1107.         dataCount  = 0;
    ) M, ?& p9 \1 p$ x# k( M0 p4 R( g% y
  1108.         code       = CodeNone;
    7 l; s$ O; ^5 D# k5 ~! j. v* Y0 @
  1109.         stage      = StageNone;3 o  e! N. n1 \  ^9 V1 E% I. P

  1110. 5 c% d( L5 k* ]5 h; ]! I
  1111.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)3 s$ c4 U% g2 P1 ?
  1112.         {! E; {8 L! x1 X- Z4 h2 N+ b
  1113.           txBuffer[txLength] = CodeCan;4 y/ X& Z  [& s( H2 Q0 x
  1114.         }5 h% r3 _+ e, r$ c. X# @& m8 X

  1115. 4 e: ^  J( K  R! V' i
  1116.         write(txBuffer, txLength);/ x: F* ]4 s. y6 Z! G* |
  1117.         callback(StatusError, NULL, NULL);
      R2 b+ X2 Y: A, M
  1118.       }& m( f6 k( y; ?  W; E
  1119.       else
    / f# N& M# Q0 M2 M& ^) E# p6 Y
  1120.       {
    9 ?" _9 B5 _9 x& G4 z# Z/ o
  1121.         txBuffer[0] = CodeAck;2 v( G) n- T. }' J- X& {) i
  1122.         txBuffer[1] = CodeC;
    ! u! }) y( d0 C( v  @4 A
  1123.         txLength    = 2;
    $ t# j0 M; W8 C" v
  1124.         write(txBuffer, txLength);+ h0 b1 R6 J- Z! M0 p4 a' R% h
  1125.       }
    6 c  g6 K' d: n3 v2 V" b, E5 m
  1126. 7 y1 @- T9 C. F; i1 d
  1127.       break;
    & ?. K) v6 O5 p4 {6 W6 a" q
  1128.     }
    4 `* J' o! z- \* a- |$ w! I

  1129. 7 O8 ~4 Z8 N! f/ T7 R
  1130.     case CodeA1:" x4 ~, q* N# U  e
  1131.     case CodeA2:1 n2 _) g$ x; c) M3 P& o
  1132.     case CodeCan:3 c6 h0 N0 t8 S+ Z& P) M
  1133.     {7 f# D% P& {) _8 j7 K1 Z$ J
  1134.       timeCount  = 0;
    % c5 X3 R$ ?* D6 x/ T
  1135.       errorCount = 0;' `' ]1 _' Q4 S0 l9 |' v- a
  1136.       dataCount  = 0;: y7 W# C, E4 b7 V0 L
  1137.       code       = CodeNone;) ^" n( Q: c" f& M; T; I
  1138.       stage      = StageNone;: M# f. t. s; l. e: K/ u: D/ y6 m
  1139.       callback(StatusAbort, NULL, NULL);7 u% K! [9 }$ a
  1140. * i$ s( n& @8 b7 N" |! r$ |3 U
  1141.       break;
    " s2 X! X$ w  p- _6 j
  1142.     }+ q, G; T4 `4 _# K1 n

  1143. ' T+ a1 W0 i1 g5 S
  1144.     default:
    3 k8 m( f# K9 Z1 L
  1145.     {
    & o/ j5 B0 I% |( v( O6 G
  1146.       timeCount++;2 w) p8 m, F4 k% x. V. p
  1147. : H7 v  w2 x7 M4 {
  1148.       if((timeCount / (timeDivide + 1)) > timeMax)+ P6 G4 x/ c9 s
  1149.       {
    6 [+ i4 x9 N( v1 e" T: l* x
  1150.         timeCount  = 0;- K/ z& z, h6 v1 c" I* T( k0 E
  1151.         errorCount = 0;
    # u; I: \5 Y" O' C
  1152.         dataCount  = 0;) x+ F) x. U. @9 y/ R
  1153.         code       = CodeNone;
      L  L# s( }" k; [3 Y7 I9 U
  1154.         stage      = StageNone;
    1 w) ~. m# d9 X. O0 b* S6 }# d0 e
  1155. ' F$ h6 Z% }9 r" m' @) m
  1156.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    1 K; F( ~  x( d  B; h, d. [3 |2 M# L
  1157.         {
    + H+ I' s/ i5 _0 c+ j4 t
  1158.           txBuffer[txLength] = CodeCan;
    * q5 a, u/ z  w
  1159.         }
    6 K# r. W5 f- K1 H6 w6 L

  1160. : H& C; f' L+ P1 G5 h0 S
  1161.         write(txBuffer, txLength);8 m7 E6 V, u8 a/ ~  @) A
  1162.         callback(StatusError, NULL, NULL);( o2 b! O: g$ r" L
  1163.       }* x3 X$ I) c& I7 j. e
  1164.       else if((timeCount % (timeDivide + 1)) == 0)  |) k6 H3 V0 V9 D: X" [: j# \6 u
  1165.       {. u$ [& Z# U5 l0 m5 K
  1166.         txBuffer[0] = CodeNak;% O8 H  L. P; `5 }# e
  1167.         txLength    = 1;0 s5 x$ @. n, u3 U! y
  1168.         write(txBuffer, txLength);
    , I- B. K" b5 l
  1169.       }
    * K, x! B1 E' Z+ H; j
  1170.     }, r/ H1 W1 C* R  W" l3 C7 `% Z/ X4 R
  1171.   }
    ; A2 q* G0 Q* F# e
  1172. }
    2 w2 y3 ^# P2 w0 z

  1173. # f, u5 w. V/ s& _7 b
  1174. /**
      |5 ^& a% [. i1 I, N0 O2 x
  1175.   * @brief  Transmit none stage.
    5 D/ P& u' ^  O9 c' ]
  1176.   * @param  None.
    , S% R: g" j5 w8 {
  1177.   * @return None.# l3 s- @( T5 }' R% {) X
  1178.   */
      o2 p/ s& Z$ m
  1179. void Ymodem::transmitStageNone()0 B. H0 d) c0 a% j. f
  1180. {  m* ?0 m) B: a8 m( ]( ~: q& u
  1181.   timeCount   = 0;( o7 k+ x1 ^4 B; |% R
  1182.   errorCount  = 0;
    - v* Z) M# f% B# ^' c  p3 Z
  1183.   dataCount   = 0;1 o7 T8 b. Q+ J
  1184.   code        = CodeNone;
    7 n0 O; G5 @& b0 p& ]) c. V
  1185.   stage       = StageEstablishing;! M& ?% F; I) O& |! ]3 N
  1186. }
    7 [6 \" \8 ~7 u/ e1 P) B

  1187. 6 G/ f' n/ R5 i! m$ ?
  1188. /**
    + h; Z( Z- F) y* d1 _( m0 r' R
  1189.   * @brief  Transmit establishing stage.
    * q3 ?9 {! \+ @# O0 s5 U/ @, O
  1190.   * @param  None.
    1 r1 d0 M0 f6 _
  1191.   * @return None.! L$ ?( |# H8 u+ ?
  1192.   */
    , l8 L' a+ a" d- {3 k
  1193. void Ymodem::transmitStageEstablishing()
    6 v1 N) Y% X3 G
  1194. {4 G2 h& f9 z5 T' Z' m4 M
  1195.   switch(receivePacket())
    & `. w* i0 j! t9 I) L
  1196.   {
    5 @9 L' H3 e9 n- k
  1197.     case CodeC:7 {7 v1 u; n  A) ?9 ^. J
  1198.     {
    * u2 r' ]: i" O
  1199.       memset(&(txBuffer[YMODEM_PACKET_HEADER]), NULL, YMODEM_PACKET_SIZE);
    . X) p. B. o7 l, {3 |# C' J
  1200. 3 t/ ~/ U. M; |% \) s, R
  1201.       if(callback(StatusEstablish, &(txBuffer[YMODEM_PACKET_HEADER]), &(txLength)) == CodeAck)4 Y5 F5 J' i( V% E4 Y
  1202.       {0 u* W5 v% d. I
  1203.         uint16_t crc = crc16(&(txBuffer[YMODEM_PACKET_HEADER]), txLength);9 c7 g3 L- y0 z( {0 Z
  1204. , J2 \; m3 K7 ]; R3 u& y3 V) o( B
  1205.         timeCount                                       = 0;4 |% m4 [+ e0 H- H
  1206.         errorCount                                      = 0;0 e# g% G7 @" r% b
  1207.         dataCount                                       = 0;
    . |8 I1 h, G! Q* T# m' m& `
  1208.         code                                            = CodeNone;
    , M; J6 I! d4 g: C0 |
  1209.         stage                                           = StageEstablished;6 ~6 e7 }# t0 e% p0 o
  1210.         txBuffer[0]                                     = CodeSoh;
    ; P! \4 L1 ^3 f* Q' f
  1211.         txBuffer[1]                                     = 0x00;+ h" _- ~# Y# q- y+ F* f7 k( W
  1212.         txBuffer[2]                                     = 0xFF;
    % P5 f# u( K, O  g
  1213.         txBuffer[txLength + YMODEM_PACKET_OVERHEAD - 2] = (uint8_t)(crc >> 8);
    . r* W# |2 a' J9 w
  1214.         txBuffer[txLength + YMODEM_PACKET_OVERHEAD - 1] = (uint8_t)(crc >> 0);
    / v2 B" C- q  H1 |' c* v$ ^
  1215.         txLength                                        = txLength + YMODEM_PACKET_OVERHEAD;6 \: |. R) ^) ]7 z! O  t) u1 O& O
  1216.         write(txBuffer, txLength);# N6 A$ u2 n: J' a* s: ?
  1217.       }
    ) e! A# A8 t& ^9 i  z/ W. R
  1218.       else% G2 }0 V3 ]$ b- M/ Y  o. m
  1219.       {
    3 g) u! F; {4 t1 s2 C% z
  1220.         timeCount  = 0;- `5 [% u) @) u# B- q3 j( X
  1221.         errorCount = 0;
    # g. z1 \' l; X) p% x
  1222.         dataCount  = 0;
    7 s, G( h* ~% u$ J; P
  1223.         code       = CodeNone;8 s% `+ w# S# i( X
  1224.         stage      = StageNone;
    ' ~8 |2 _4 g+ R2 m; p1 [' q0 n: o
  1225. 3 `5 R9 I& y1 R! s$ n& S  }
  1226.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    6 d$ |! @/ E6 x
  1227.         {
      d, E$ e" r/ x! I
  1228.           txBuffer[txLength] = CodeCan;
    + B( a5 ~% ]0 c
  1229.         }! U. @$ G/ ^( h" b
  1230. ' z0 P: Y+ T8 T9 [' l
  1231.         write(txBuffer, txLength);
    $ C7 r* a" e' `! a* j9 M5 E
  1232.       }
    # ^, j. N3 s. D# ~# E
  1233. 4 E7 g, x- m1 E; m
  1234.       break;2 I3 Z7 e& b8 W9 N9 V& j- }/ `
  1235.     }% Q4 @9 Q6 s1 W7 Y) z4 t

  1236. / s5 ]3 z  ]9 e% s$ z) k% r! y3 ?
  1237.     case CodeA1:
    $ |% R, m) m" ~6 U" I" W% y% u
  1238.     case CodeA2:) @( g2 `7 a( k& m/ V8 S0 Q$ P
  1239.     case CodeCan:; X3 D" r/ n1 {6 f- O
  1240.     {) d: L' ?; d2 t! o6 @
  1241.       timeCount  = 0;) f* r# ~( t* r5 [0 |" N
  1242.       errorCount = 0;
    3 S8 u  t  i; |! [
  1243.       dataCount  = 0;/ c( l, l* r' n# L/ l7 _! E
  1244.       code       = CodeNone;
    " o7 z9 Q, K: [" l# R2 ]
  1245.       stage      = StageNone;
    ' g! v7 v, {' H" `/ Z
  1246.       callback(StatusAbort, NULL, NULL);; t& K% G* ]* r. @/ H$ ?1 \% Q/ N
  1247. 3 R! t6 P- m5 M- u) m4 k  a
  1248.       break;* D3 x& y# p! x6 V5 G9 P- x, x1 z
  1249.     }
    3 F  c4 z3 Z% T  S% |7 P9 t; X
  1250. 3 r  O% w( z$ r7 C5 T; P+ m; n5 ]" j
  1251.     default:( B& `8 v2 k7 V5 {/ i7 M4 l, [$ o
  1252.     {% q$ p  L4 X6 C$ G7 y1 i
  1253.       timeCount++;
    . P7 b. ~  L5 u; D7 q+ ^

  1254. 4 R& ]# U$ I/ i# H
  1255.       if((timeCount / (timeDivide + 1)) > timeMax)% b! S- e6 o/ z: F) O6 {0 e
  1256.       {) F, G* ^) P4 Z2 E7 M3 b/ t
  1257.         timeCount  = 0;
    5 L% y) i( g% k3 L* j: C* f4 N% G+ f  x
  1258.         errorCount = 0;5 _/ N+ Q0 }" a/ @2 E: D
  1259.         dataCount  = 0;
    2 d- j7 T* s3 n. B) ]/ _
  1260.         code       = CodeNone;' y5 T& i2 c5 b% c$ E) P
  1261.         stage      = StageNone;
    - _& H  Z# }/ f- T; v) R8 Z( P) z
  1262. - D" w4 u: O% H$ Y  {  K( W% G* _2 v
  1263.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
      Q% m3 G, e, n  C# _
  1264.         {0 O/ O) t0 L. e) ~  D+ e( P
  1265.           txBuffer[txLength] = CodeCan;5 O' K$ w8 r# h4 ?
  1266.         }3 O. [+ g5 g+ z; E
  1267. 0 v' Y) z" f6 M" Y2 B
  1268.         write(txBuffer, txLength);
    9 u7 `/ W; B' q1 x; E
  1269.         callback(StatusTimeout, NULL, NULL);
    ; @, y+ y# ]! }: n! W
  1270.       }4 K& l- E3 z5 j9 W' Z! ?0 i  [
  1271.     }
    % {/ _& P" v/ E2 n+ O
  1272.   }+ Q, E3 g+ i+ B. T3 q( A
  1273. }; u# t3 [4 x5 e) i* h

  1274. ! a+ I2 M/ X8 ?8 G* z0 z3 L0 r
  1275. /**
    % ^9 C0 ^1 I8 q
  1276.   * @brief  Transmit established stage.
    8 v8 \) v7 t, ~3 _: g; t! V; l
  1277.   * @param  None.
    0 D% ?5 o5 J: c8 f1 [5 s! g% c
  1278.   * @return None.
    2 C+ T8 e7 P+ ^) @4 H. K9 P
  1279.   */
    & w% J8 S! h9 O- y6 r9 j$ A$ c  b6 G4 P
  1280. void Ymodem::transmitStageEstablished()2 u3 C8 I# x# Z' C- |+ K" ^
  1281. {' \- p3 H/ L9 O& k
  1282.   switch(receivePacket()); \5 E: V. g2 m# Q9 I/ R7 r
  1283.   {
    8 T3 ?0 ^/ ^" {2 ?8 A! X6 l
  1284.     case CodeNak:
    % w- x3 j, J0 d+ o; t3 [* |
  1285.     {
    : Q% h7 M  G2 V4 t# W3 ]- T
  1286.       errorCount++;/ X8 F" |. p3 L9 J

  1287. % Q2 j. |8 L0 a3 V3 g
  1288.       if(errorCount > errorMax)5 f7 ?  Q9 D4 d: ~! W8 l, u4 L- f
  1289.       {
    " n6 J2 [4 L' {7 T1 z
  1290.         timeCount  = 0;
    7 s5 r: f. k1 \! C( |
  1291.         errorCount = 0;! i. C  I' Q3 P# E7 h$ l8 N
  1292.         dataCount  = 0;
    & X1 }9 L7 f7 K4 `8 V
  1293.         code       = CodeNone;, Y8 E1 L0 x* P3 [8 b+ M
  1294.         stage      = StageNone;
    ' x& |: s% Q+ K" t+ q5 R6 w
  1295. ) s3 n) J. c1 i
  1296.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
      m& t9 Q5 Y1 s( O( q! C
  1297.         {2 ^9 r6 E1 Q( m: _
  1298.           txBuffer[txLength] = CodeCan;1 X) h& C5 j2 L
  1299.         }4 }* I' e& B  |* @
  1300. 5 ?1 ?3 {4 V7 E
  1301.         write(txBuffer, txLength);
    0 c& J/ c) F5 c% `, |9 }
  1302.         callback(StatusError, NULL, NULL);
    ( Z4 g# Q: |4 j4 O5 x  Y( q
  1303.       }0 Y( h5 Y! |4 A+ ?2 n# ]- |2 y
  1304.       else1 M7 i7 s, d! \6 G4 [* z" h/ |3 k
  1305.       {" l+ a$ x  B$ B3 D3 A) W
  1306.         write(txBuffer, txLength);. k  T3 L. F9 [% @
  1307.       }$ `/ c4 H9 d. `: Y' A! Z
  1308. # D  d; N1 t9 Y3 M8 q
  1309.       break;
    5 e* E. S8 u. b0 M* g
  1310.     }- z6 p+ y1 L2 H2 n+ U8 y$ M" I

  1311. ) U5 r: T5 G. i' Z
  1312.     case CodeC:
    1 @1 z* S; ?5 l! `1 B
  1313.     {) j! ~" B( R+ B6 W3 j% t
  1314.       errorCount++;
    . }# s# E2 W/ _+ A( f- Z# }. B
  1315. 4 p* E1 L- L  K0 v( i) v4 W) P
  1316.       if(errorCount > errorMax)
    ' g: J9 F- x, v! `* w+ i
  1317.       {
    5 }, o: @+ r6 p" D. X
  1318.         timeCount  = 0;
    " C" v9 ]0 O* x7 k
  1319.         errorCount = 0;
    # N3 T$ W6 o: U" \& f  j) m
  1320.         dataCount  = 0;) Q! t$ S8 K& m- P6 }  F
  1321.         code       = CodeNone;
    ' h5 ~: q( E- k- \  C" O+ c
  1322.         stage      = StageNone;
    $ b2 W* i' \$ k" v) e
  1323. ! r1 W: N/ z' f2 @+ f9 L
  1324.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    ) S3 t8 g+ @0 R! e) b6 j: ^
  1325.         {) N) ?% b9 Y2 ^  I
  1326.           txBuffer[txLength] = CodeCan;
    & e" U0 q$ `0 Z: E8 W
  1327.         }
    8 ~6 [/ v1 U' o$ |% j) O& W) I
  1328. 4 F3 |5 S5 `: D/ A" G
  1329.         write(txBuffer, txLength);
    7 }" E. W0 W1 q# o
  1330.         callback(StatusError, NULL, NULL);9 {/ k! j& ]% e
  1331.       }! i1 r6 l" }" E1 O3 i# W
  1332.       else; M8 ?3 j4 S) s
  1333.       {3 I5 s- |0 R& l5 u
  1334.         timeCount  = 0;
    ( `: N8 ]" R2 h6 w
  1335.         errorCount = 0;
      @, e8 f) i( [
  1336.         dataCount  = dataCount;
    / B1 w& B! q0 M( C' C
  1337.         code       = CodeNone;% d% F4 Q" S/ m
  1338.         stage      = (Stage)(stage + dataCount);& N8 G  Y( E6 i3 L( a, r
  1339.         write(txBuffer, txLength);
    7 `! Y* @! ~$ x% q' v
  1340.       }/ {1 g/ U# G$ r( y! p/ Y% x

  1341. ( t7 j' G2 j  N: O
  1342.       break;
    ! F/ \" k( C: f  E; Y% F
  1343.     }+ S# {9 m  D+ C7 G& `
  1344. - V; R1 r8 r9 O$ Y7 A0 ?9 A
  1345.     case CodeAck:& `. V& T$ C+ t' N, `2 n
  1346.     {' x- c1 `8 J  w* }3 {
  1347.       memset(&(txBuffer[YMODEM_PACKET_HEADER]), NULL, YMODEM_PACKET_1K_SIZE);
      W2 C9 E' S8 U

  1348. , u; \* p7 q$ N& ?' X
  1349.       switch(callback(StatusTransmit, &(txBuffer[YMODEM_PACKET_HEADER]), &(txLength)))
    3 R6 ~1 N$ t5 K5 {3 d9 ]  K+ n/ H
  1350.       {( x8 V% B  T+ v* {% g
  1351.         case CodeAck:0 h  K3 i- ^8 r% D( D
  1352.         {; z; O- P7 O7 o; ?
  1353.           uint16_t crc = crc16(&(txBuffer[YMODEM_PACKET_HEADER]), txLength);, u$ j* i/ @' i& I2 m2 `

  1354. 0 d  w8 S1 a1 B. g7 @
  1355.           timeCount                                       = 0;: E1 ~+ n- o# U# X
  1356.           errorCount                                      = 0;7 d" e6 K9 u3 w" P# [4 h
  1357.           dataCount                                       = 1;
    " J! v" i% C$ ]$ g. {0 d) w
  1358.           code                                            = CodeNone;
    + q4 w) o: J( @. F2 s
  1359.           stage                                           = StageEstablished;& }3 H) J2 h$ l4 B* q
  1360.           txBuffer[0]                                     = txLength > YMODEM_PACKET_SIZE ? CodeStx : CodeSoh;
    % a; ]$ u, o3 w1 f- }& A: n% L
  1361.           txBuffer[1]                                     = 0x01;
    3 H$ W( q2 Y! l: ^5 G6 `
  1362.           txBuffer[2]                                     = 0xFE;
    1 K$ l8 K9 D1 a4 [9 H
  1363.           txBuffer[txLength + YMODEM_PACKET_OVERHEAD - 2] = (uint8_t)(crc >> 8);" |8 n7 d- e, S2 ^9 Q* `- d9 {
  1364.           txBuffer[txLength + YMODEM_PACKET_OVERHEAD - 1] = (uint8_t)(crc >> 0);+ ]$ r2 n5 ~8 e$ r8 f
  1365.           txLength                                        = txLength + YMODEM_PACKET_OVERHEAD;
    " `0 j$ x; W! l( W9 K

  1366. * }: i1 ]8 }9 y' h
  1367.           break;) ~  l) h& y8 U( |! R% T
  1368.         }
    ! y/ Y( D1 I1 F
  1369. 1 V: e9 X2 ]6 ~& D3 X8 S
  1370.         case CodeEot:
    ( `3 |$ p! o% J5 |2 _4 Y' Q3 W
  1371.         {* p2 t2 M6 c- T5 X0 ?
  1372.           timeCount   = 0;( g' P4 H7 J& E( A+ k
  1373.           errorCount  = 0;
    8 Z" a5 `: U& o. ?+ d6 H$ I
  1374.           dataCount   = 2;' o% l* ]8 q  l" D6 n0 D! ?
  1375.           code        = CodeNone;
    - {0 D8 J. R- n: c( C1 T
  1376.           stage       = StageEstablished;
    # m& c, g7 l+ h+ l6 \6 @6 j4 u; F3 [1 t
  1377.           txBuffer[0] = CodeEot;6 K" k2 u2 _4 T& |; _
  1378.           txLength    = 1;
    % g) K- m+ K" B* z
  1379.           write(txBuffer, txLength);
    ( P, ]  z4 J; Z1 D8 q
  1380. 2 |3 z- H1 m, e, C* l9 Q, z3 K5 C
  1381.           break;/ I, }+ [( x+ X7 l
  1382.         }% Z) g9 _" r& r/ }; p# Q9 ^

  1383. 6 \8 A4 r8 ]& a% P
  1384.         default:6 M3 I' e# j) G: |2 a
  1385.         {) A0 F6 F% K" o- i9 f8 n
  1386.           timeCount  = 0;
    ; J7 i* }% \( B5 M; w
  1387.           errorCount = 0;% k) X3 A7 _; K1 @
  1388.           dataCount  = 0;
    ; ]* o/ e4 q* k9 Z1 `7 H5 k  H  Q& u
  1389.           code       = CodeNone;) X' l$ x4 L; l" f1 p; z
  1390.           stage      = StageNone;( _. k2 V2 k0 s* h) u- G

  1391. 8 B+ S9 ]1 p2 p+ ~% a/ d4 w- F3 M
  1392.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)7 w' t1 U, D) P9 |5 H9 L; S
  1393.           {& u7 f& K# L" W* w/ @( M. B
  1394.             txBuffer[txLength] = CodeCan;
    ; L9 v: Z* {, k+ ]" v# f) Z
  1395.           }5 w3 `# L) e2 D% }0 v
  1396. % ~- w+ t9 f' B( z1 a0 f3 J
  1397.           write(txBuffer, txLength);& y- b( o+ h! q, r
  1398.         }* s! O- I  x  [! q; L2 i
  1399.       }
    % Z, W# s, N# G5 H+ d, v' O& ]( w

  1400. / F3 @5 l3 u. w6 ?- r8 j
  1401.       break;  \7 t/ g: ?+ b) h$ H" P& a
  1402.     }
    " @1 N7 \" K8 t9 g  Y

  1403. & E5 g4 c! B2 n% g  ?+ L6 \
  1404.     case CodeA1:7 w- _1 O) d8 o& [$ x0 ], X* u
  1405.     case CodeA2:' ?  ]/ {9 |* `- \6 b) [
  1406.     case CodeCan:7 H. p0 E3 |8 n& M
  1407.     {& D; _! x4 I: @% @' Q
  1408.       timeCount  = 0;
    2 ~- J4 V, D5 P1 G# _
  1409.       errorCount = 0;
    . d* F5 D! C& G+ ~4 V8 \
  1410.       dataCount  = 0;3 n" g0 A9 [6 x# ^6 X% C
  1411.       code       = CodeNone;
    $ Z0 |  C  a6 u" F2 k: {
  1412.       stage      = StageNone;
    $ z( b& p( {$ c  P+ w: V8 u
  1413.       callback(StatusAbort, NULL, NULL);& |; _% f5 ^5 [& f6 G9 O) I: [8 j

  1414. . ?1 G' t/ X" Z5 j; ]1 g  H
  1415.       break;+ j% w( C' ~7 l( b) l& L
  1416.     }
    / l: l8 N& }; r9 r$ j

  1417. : b' ]! L' a' z8 q" D: B6 ?. c
  1418.     default:
    5 P/ w& i3 r6 r/ c/ i) N
  1419.     {! v; D5 h9 n' x# q8 m# v' g! p
  1420.       timeCount++;9 h4 C8 P) b9 L

  1421. # A* B( U( W# {6 S
  1422.       if((timeCount / (timeDivide + 1)) > timeMax)
    / r: S# [* N0 h
  1423.       {: s! {4 R) P& N; K; A0 C8 i. U
  1424.         timeCount  = 0;2 C* i, i/ ]5 ^4 z' i
  1425.         errorCount = 0;
    * @2 I: w! s" E3 S0 l
  1426.         dataCount  = 0;7 b2 C+ m" d' C6 G2 a) o8 Y
  1427.         code       = CodeNone;
    6 ^9 l  p9 j5 t4 d
  1428.         stage      = StageNone;% f  r; g8 r) l# I

  1429. ( ?/ {% W$ \. O9 {6 Z9 ]3 M
  1430.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    " b9 Y2 `0 |8 x  e
  1431.         {7 N8 L/ J$ k, v$ w1 j0 ]
  1432.           txBuffer[txLength] = CodeCan;
    0 n# N2 h6 v9 `9 G' D
  1433.         }
    ! I% Y( _% C1 _5 D! g5 P( Q0 A

  1434. ) L7 Q' B8 K( o5 e" _- T
  1435.         write(txBuffer, txLength);
    9 C$ M9 k; k% J9 i
  1436.         callback(StatusError, NULL, NULL);
    ' h7 y( n. t& g9 |& y% y
  1437.       }
    6 s( _" [1 m# c: M- ~8 P3 K9 O
  1438.       else if((timeCount % (timeDivide + 1)) == 0)
    : _+ _" |* l; r6 S7 t  Y
  1439.       {' e$ E, ~; t5 G$ y
  1440.         write(txBuffer, txLength);0 N3 F! }/ k9 s( d
  1441.       }* o) d. c# g9 r" O, k+ e
  1442.     }
    ) ?. B9 ]  }: `& K+ A. k% I
  1443.   }% `& J$ d7 I+ U( S, w1 b% ]2 T
  1444. }
    % N2 L+ m3 X& U' A0 T& z/ @
  1445. ' n' K4 A% m/ [
  1446. /**7 J8 Q5 l% m8 P/ d& P' S+ X
  1447.   * @brief  Transmit transmitting stage.
    " T) T# Y9 {8 y  \+ @
  1448.   * @param  None.) v- D. T* y; s; Z
  1449.   * @return None.+ {9 X  _; O% L# \  u
  1450.   */* y6 y: o& g. w; u
  1451. void Ymodem::transmitStageTransmitting()
    1 u9 V3 [) v/ }8 u+ m
  1452. {* Q% u5 e0 x0 s0 T
  1453.   switch(receivePacket())
    " v7 V" b9 e# |* i2 d% t- i/ k
  1454.   {
    ' k; I; a2 a- A. ?7 v6 ~
  1455.     case CodeNak:5 H- g) u, G, {7 Z' A/ \3 S
  1456.     {
    . W9 d7 H+ T; S& v0 h
  1457.       errorCount++;5 m0 G0 @3 Q# d2 d1 K8 O. r% B0 a
  1458. % ]2 O- B2 B! T6 F% F, \
  1459.       if(errorCount > errorMax)
    3 l3 u0 o9 k/ I9 L  l8 m; x& q
  1460.       {
    4 N% e% V! N6 ], H( L
  1461.         timeCount  = 0;
    3 P! R2 d, o4 I: s) T1 l9 l: o
  1462.         errorCount = 0;  R& W2 I' Y: |# S2 X4 d9 A# V
  1463.         dataCount  = 0;
    # E+ }% a: i1 v& \' f/ }# @
  1464.         code       = CodeNone;
    # m( X* G0 \- A, j% ]
  1465.         stage      = StageNone;1 S+ s2 J- @1 J! u3 {4 |. u; c

  1466. . a; b( B. B# j4 `. d6 i
  1467.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)2 x! z- }7 z- m+ B* b' V
  1468.         {/ z3 K6 c: M% ?: U
  1469.           txBuffer[txLength] = CodeCan;& Y+ j! Y" P) m- I
  1470.         }6 ?$ H1 k! L) I
  1471. " h2 p8 m1 u! Z2 W* L9 F# E+ I! v
  1472.         write(txBuffer, txLength);
    0 E4 l& K4 I; ~( B7 `# b
  1473.         callback(StatusError, NULL, NULL);
    4 k2 N. g0 z: z2 K; r
  1474.       }# k& e) w" e6 ^+ i
  1475.       else% v3 {) [0 X) R; r6 ]
  1476.       {' i  J+ g$ i3 D1 s  l* k- ]5 Y
  1477.         write(txBuffer, txLength);. T) E) M  Z; L, V
  1478.       }
    2 ~( v" v" M0 L% O
  1479. , Z3 z2 b. Y$ e* V$ _- O
  1480.       break;5 U+ s; k7 ^( ?9 |7 k6 r
  1481.     }
    8 y' v# q9 h+ t

  1482. - I2 O8 C. S! }' y- B) h
  1483.     case CodeAck:* \2 d, \. ^2 a. v3 W
  1484.     {9 i; U0 |- s2 O! m- {' g2 W
  1485.       memset(&(txBuffer[YMODEM_PACKET_HEADER]), NULL, YMODEM_PACKET_1K_SIZE);
    , a3 e2 P% A- J  g
  1486. 1 G  m0 h2 U6 A% t5 g5 h# b% }
  1487.       switch(callback(StatusTransmit, &(txBuffer[YMODEM_PACKET_HEADER]), &(txLength)))
    * i; T) S7 @" ^4 \
  1488.       {
    ( u6 J' u4 M& T1 h
  1489.         case CodeAck:8 R: e3 {$ _9 y2 L1 ~. W
  1490.         {
    9 ^' x9 `7 `# Z9 ]' _1 P
  1491.           uint16_t crc = crc16(&(txBuffer[YMODEM_PACKET_HEADER]), txLength);
    1 ~# y9 I5 K8 R& j; p
  1492. " w, w; q2 T. }) `9 W! ]9 G
  1493.           timeCount                                       = 0;( i4 S: |, k3 T. X& T
  1494.           errorCount                                      = 0;4 F  Y3 H( S0 Q& }! `3 L
  1495.           dataCount                                       = dataCount + 1;% E7 B$ d& z' t3 S- W
  1496.           code                                            = CodeNone;
    % m4 D4 F' N: b3 s
  1497.           stage                                           = StageTransmitting;
    7 J- o. K$ x& K) T) ]) s
  1498.           txBuffer[0]                                     = txLength > YMODEM_PACKET_SIZE ? CodeStx : CodeSoh;
    ( |/ f) g( q5 \* F& I$ ?8 Z' U
  1499.           txBuffer[1]                                     = dataCount;
    ! J) g, N' e, q/ j4 n
  1500.           txBuffer[2]                                     = 0xFF - dataCount;
    9 H5 E& e: H: u2 O& ^7 v* a9 g  o
  1501.           txBuffer[txLength + YMODEM_PACKET_OVERHEAD - 2] = (uint8_t)(crc >> 8);% f# k2 l# E6 U0 F
  1502.           txBuffer[txLength + YMODEM_PACKET_OVERHEAD - 1] = (uint8_t)(crc >> 0);8 a! F  \# L% W
  1503.           txLength                                        = txLength + YMODEM_PACKET_OVERHEAD;, P  a# V. ?. F+ S
  1504.           write(txBuffer, txLength);7 @5 }. B) z, z  d& _( @. Q
  1505. & r, I8 l( a, E$ C, c& S$ r" K: K
  1506.           break;$ ?) i; s6 Y  U& F# I6 }" @
  1507.         }
    5 j. q% L, t! {: F! a
  1508. ) ^0 {& K6 c! \4 N: D9 X$ A
  1509.         case CodeEot:& ~! k" G  X  i8 f& q  o% Z
  1510.         {
    5 X3 {0 b3 u3 _
  1511.           timeCount   = 0;
    $ j$ R4 [# ~. z2 h
  1512.           errorCount  = 0;* L" [* U# G- B# f' m1 Z" J: n
  1513.           dataCount   = 0;
    ! B  {8 e" k# Q, Y% C( H
  1514.           code        = CodeNone;
    , C% L6 O8 l0 w4 ^  R4 i2 b: [
  1515.           stage       = StageFinishing;
    2 J- w# i6 T& N: q  T# x3 L' O' i
  1516.           txBuffer[0] = CodeEot;
    ' u$ }9 k5 D+ S9 h
  1517.           txLength    = 1;$ z: \/ c# ?) m+ q8 |' L5 p+ {
  1518.           write(txBuffer, txLength);1 Y9 c* ^3 u4 C# w2 Q2 u# E

  1519. 1 |3 F4 `4 |( {
  1520.           break;
    9 ?8 Q5 U8 B) h& c* D3 q5 \* l) h
  1521.         }
    & Q! S5 b) }2 ?) Z( Y$ U4 N" i
  1522.   o+ g9 h7 f! \, P, X  m* ^  M
  1523.         default:
    + O( A' ^+ ], r- n
  1524.         {+ w) N( F0 N! V5 U5 z* ]4 I
  1525.           timeCount  = 0;
    ' q" c# T+ z# j" h! v
  1526.           errorCount = 0;
    ( _) k& _# D6 m& X
  1527.           dataCount  = 0;
    0 C! |, u( Z1 b" f$ L
  1528.           code       = CodeNone;
    + S+ U! V2 h( m4 t6 K; c9 H
  1529.           stage      = StageNone;
    9 X! Z; k  B4 H2 F  a
  1530. , |) s) b9 h  w' D: M# j! N
  1531.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)- F) Q3 Q0 q0 Z7 M. A: o5 l
  1532.           {; ^. i$ l0 D  g; p
  1533.             txBuffer[txLength] = CodeCan;
    " J" @( {! n6 u$ D7 O$ x8 N
  1534.           }% O  O" B; k# R: Y" \

  1535. # I1 k+ x5 X3 }/ L& ~, j, P
  1536.           write(txBuffer, txLength);+ ?. J0 \1 K+ k* V
  1537.         }5 @  t# V! \3 r" K
  1538.       }0 v' d( n! o! O% F& g; P
  1539. . \8 {8 u' @9 u( V5 N9 z( s: g
  1540.       break;
    ) w3 ^5 C- b: l8 V
  1541.     }8 S1 F! B" u* g$ F$ S0 o* l
  1542. / Q. P4 e! n: `9 i  R6 V7 l! c
  1543.     case CodeA1:; A9 {+ T& R+ v3 b) s1 p! s* |
  1544.     case CodeA2:
    ' R4 ~( O; x; B. X; ^
  1545.     case CodeCan:
    1 z  C0 {# K3 S& i1 y, s" r6 i
  1546.     {
    / v: \2 H; L; J( @' }: o6 k. r- l
  1547.       timeCount  = 0;
    % y4 u! a2 H+ G# z6 E/ f1 K: Y' S7 g
  1548.       errorCount = 0;( H! h" Y6 f, E( O1 u$ e
  1549.       dataCount  = 0;
    7 V8 N4 P" W4 ], x- k; |
  1550.       code       = CodeNone;6 g$ K. I2 _$ T1 p; U
  1551.       stage      = StageNone;
    * Y2 k: w; @( y9 d7 r
  1552.       callback(StatusAbort, NULL, NULL);
    7 e( n- O( c8 @+ z, }+ m2 M. l

  1553. $ F) W- [! {# x
  1554.       break;7 d6 T% z8 H" e; V4 K
  1555.     }! _& ~4 T  D" K2 \

  1556. 2 O" ?8 x. O* Q  {0 L9 ~# n# o( e7 w
  1557.     default:, Z' q; X* A; d
  1558.     {
    - P; ]' ?( T1 O' u' P
  1559.       timeCount++;4 _. {+ J& l( e/ b
  1560. - T7 K5 {- O  R% {( L1 v% ^$ [
  1561.       if((timeCount / (timeDivide + 1)) > timeMax)
    % `2 j; Q. y/ ]$ N3 H( d) r0 p
  1562.       {! v1 ]: v6 c6 s" @. _/ v- O
  1563.         timeCount  = 0;3 L6 k# z% s1 {8 F& t/ X+ b* J
  1564.         errorCount = 0;7 c5 A  h( x  B
  1565.         dataCount  = 0;
    2 K9 T* h8 N! t4 s! x" p. T- \
  1566.         code       = CodeNone;: S5 B# r+ _, b9 J- z( Y& m4 w
  1567.         stage      = StageNone;
    / `) k; A' q' h% ]" m
  1568. - l7 [9 U& }0 l$ P- E$ B& e; q
  1569.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    % r$ ]# E5 i0 R3 [0 q
  1570.         {8 b- f1 x& @" ^( y1 [+ ~- V2 V# B2 o7 @
  1571.           txBuffer[txLength] = CodeCan;
    " |1 Q0 H* a+ C4 A3 h0 M
  1572.         }4 @( M2 P7 n" G( {! U7 F/ s3 m
  1573. + ]8 h9 @" Y. q- a
  1574.         write(txBuffer, txLength);, M8 ~# F8 ?! ?, q% s3 w
  1575.         callback(StatusError, NULL, NULL);
      }# |% o; [' ^$ E
  1576.       }; n2 r5 R7 c: o/ j
  1577.       else if((timeCount % (timeDivide + 1)) == 0)2 _3 X* F3 W/ l/ u- ?
  1578.       {0 j, e- N1 Y' E
  1579.         write(txBuffer, txLength);
    * b+ r; ~" S: _# g
  1580.       }
    # c/ R3 G! b8 N" c3 }4 k; p) {
  1581.     }! F8 A. u! U* j, V7 V- L* l7 v
  1582.   }
    / l3 J5 E6 Y' {  \: O. C6 N
  1583. }3 F' C. n5 p2 ~  c! y

  1584.   ^- Y/ @9 \: c- U; T' V/ h5 d0 ~
  1585. /**
    5 b- U6 t; D/ f
  1586.   * @brief  Transmit finishing stage." o$ u. M7 z1 a  Y! p' a, ?# J( l
  1587.   * @param  None.
    ! o9 G3 X$ W2 b4 G5 |2 r1 y
  1588.   * @return None.2 s, i- w% E3 [% Y0 T$ i& q8 S
  1589.   */
    7 w: l, @! c( B) a, }6 y
  1590. void Ymodem::transmitStageFinishing()0 S  Y6 X& |6 A3 ^
  1591. {
    9 S# ]/ s7 j/ `" N
  1592.   switch(receivePacket())* p, q4 Y/ h7 g) v5 L# s; x6 H) o  P. G
  1593.   {
    $ O- m( ~+ |2 ^7 z5 u/ `
  1594.     case CodeNak:2 {7 ]9 a- ^8 e1 D
  1595.     {- I" D0 r% j4 t! ?1 y4 @: Q& m
  1596.       timeCount   = 0;# a$ V; N( e- H/ [1 p$ {
  1597.       errorCount  = 0;# w5 C7 S$ @7 o) V
  1598.       dataCount   = 0;# w, `) i" @+ M4 i: A* a
  1599.       code        = CodeNone;
    3 \" U6 Y, r6 Y
  1600.       stage       = StageFinishing;# S" j: P: o7 V. E: W  P' Y3 |
  1601.       txBuffer[0] = CodeEot;6 z2 g7 r+ S5 U' C
  1602.       txLength    = 1;
    : F; U0 v* p8 O$ M8 R5 g
  1603.       write(txBuffer, txLength);
    / |' b7 A6 ]2 Q! X

  1604. # g$ N! I. n; H  o, b8 m9 I
  1605.       break;
    : g* C+ C& N8 j, K
  1606.     }6 N$ U7 \( f1 w5 A+ B

  1607. 4 e. w2 z/ ]8 T! I/ B3 r
  1608.     case CodeC:
    & M( K- J4 {+ s3 m
  1609.     {" O0 o. R3 r: \9 s# ?5 X
  1610.       memset(&(txBuffer[YMODEM_PACKET_HEADER]), NULL, YMODEM_PACKET_SIZE);0 p( j/ @. N9 M5 A; C3 m
  1611.       uint16_t crc = crc16(&(txBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_SIZE);/ N4 y$ m* D" Z
  1612. " @% v4 g- s& i" C: a+ \$ U" B" ?
  1613.       timeCount                                                 = 0;9 I' S9 C  h* ?: n2 l( t
  1614.       errorCount                                                = 0;
    4 w. ?+ y" X2 k/ [* U$ x+ y
  1615.       dataCount                                                 = 0;
    + W: M7 f! z! e2 `  E; R( [
  1616.       code                                                      = CodeNone;
    6 C3 U. q9 t" p" v
  1617.       stage                                                     = StageFinished;
    2 b" m' q/ O; K
  1618.       txBuffer[0]                                               = CodeSoh;
    8 {. V( |# Y) \4 l" `! l0 b$ P! ^: O
  1619.       txBuffer[1]                                               = 0x00;
    ; `* @! p8 V+ b* T
  1620.       txBuffer[2]                                               = 0xFF;
    , k" V. u3 K9 v% p
  1621.       txBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 2] = (uint8_t)(crc >> 8);0 g6 _  c! ^$ n9 H. T' W
  1622.       txBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 1] = (uint8_t)(crc >> 0);: r* @$ R# D5 r* {  Y. K4 r
  1623.       txLength                                                  = YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD;
    , [5 |0 n0 y1 ~
  1624.       write(txBuffer, txLength);% K6 d' @! L: j8 a( [- Z
  1625. 7 [" l# B5 D: m# ?+ c6 d
  1626.       break;6 Y# }8 M2 \# V/ l9 k  j
  1627.     }
    ; }! Y) p  q4 b6 }  y

  1628. , h/ N" ~  W" \
  1629.     case CodeA1:
    4 w! D/ |, l( g- a
  1630.     case CodeA2:
    2 E0 j7 N  d- F+ m/ z
  1631.     case CodeCan:; i5 I! ]8 z' B  O- E2 _
  1632.     {
    6 d" L& B9 y5 i; q% `2 B
  1633.       timeCount  = 0;
    ) j; o% ?' [) x3 x9 A6 {) s
  1634.       errorCount = 0;' u$ P. C5 [$ [% O5 R/ D' H. C
  1635.       dataCount  = 0;1 j8 Z4 W; H" K$ w( S
  1636.       code       = CodeNone;: z* f$ \  n3 G1 r" x
  1637.       stage      = StageNone;
    " X5 j2 q3 O  S7 a: c4 k
  1638.       callback(StatusAbort, NULL, NULL);7 M+ U$ f: B( y5 j
  1639.   ^, g- q# o  c2 L* J
  1640.       break;
    5 X! i* T6 e+ s* s1 F
  1641.     }
    ) M" \; E8 d; i

  1642. . g5 J* |6 m1 I2 o
  1643.     default:1 F* J7 R3 R& u1 y
  1644.     {, p- f' Z$ k& T6 o2 N
  1645.       timeCount++;
    , P' `: P/ ]4 S( A% g

  1646. : X) `6 _. d6 v9 p
  1647.       if((timeCount / (timeDivide + 1)) > timeMax)
    1 K: r, g: d( {4 _
  1648.       {6 N; e" h3 V  R6 z
  1649.         timeCount  = 0;, B  n# H/ D8 P0 A8 _3 {
  1650.         errorCount = 0;
    1 O  @, x6 h) `4 ~
  1651.         dataCount  = 0;4 Y! a" I. Z8 W  y. C. l
  1652.         code       = CodeNone;1 @+ u) q4 w9 s5 l% r) }
  1653.         stage      = StageNone;/ G6 w! D" P, b- D

  1654. # Z+ e1 j$ d" \0 P8 Q. S
  1655.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)" i. M7 f* b6 a! ?/ r8 B7 f" Z
  1656.         {
    - G* [" \+ H" a! K- P
  1657.           txBuffer[txLength] = CodeCan;
    4 V  N& N/ w  \9 G2 c
  1658.         }% v) S) e$ E) N  h

  1659. 1 k# Z- i) D) h4 n
  1660.         write(txBuffer, txLength);# e4 ^# Y* }0 o, w+ a3 z
  1661.         callback(StatusError, NULL, NULL);2 P) w' h& \# h' {; g& @
  1662.       }
    ; O7 E9 k' ^# F" |2 ~* A
  1663.       else if((timeCount % (timeDivide + 1)) == 0)- w4 C* c+ Y0 ^- E
  1664.       {
    ' _9 S  ]3 k) F
  1665.         write(txBuffer, txLength);
    # L% L$ I- ~; t
  1666.       }4 `7 S) {+ i9 V! y/ f
  1667.     }
    6 Q% {5 D# r: n& C& M# Y6 C
  1668.   }
    ( G& `/ Y6 ~4 C$ l
  1669. }8 p' R" j9 `; {" C

  1670. ; V6 Y1 Z; I  K: [# L
  1671. /**
    " ?% _# ^  D  F( R. k% p5 W
  1672.   * @brief  Transmit finished stage.
      C" `/ k0 o$ i% Y( k2 b
  1673.   * @param  None./ p9 i3 j3 ~) T6 v) x
  1674.   * @return None.
    7 ~0 G' d: d* l  U
  1675.   */
    ( q0 \4 R( x0 o: M1 e
  1676. void Ymodem::transmitStageFinished(), `; x9 f. s9 ~5 y
  1677. {$ W) J& j/ w+ j* z% B
  1678.   switch(receivePacket())
    : M# M2 Q/ b: w% n; ^
  1679.   {9 S2 ?: y0 o4 }/ ]
  1680.     case CodeC:; Y: a4 D8 h# n) Y
  1681.     case CodeNak:3 b2 I- y! [5 E( H
  1682.     {5 t) s5 T' F. i+ B: D
  1683.       errorCount++;
    " j* c- f; R7 R# |% d( P4 Y2 }6 Q

  1684. 6 m$ ?7 ~, z8 f& h% I, Y2 Q) m
  1685.       if(errorCount > errorMax): d6 y/ x2 s( n
  1686.       {# J1 s/ c- ^' G4 G8 X
  1687.         timeCount  = 0;% f% t2 L/ \  m+ G$ R
  1688.         errorCount = 0;. s0 P& L! U2 F- _
  1689.         dataCount  = 0;' f5 D; `4 @8 g8 j
  1690.         code       = CodeNone;, B; j" p: `) T1 o- P  j
  1691.         stage      = StageNone;' ]/ Q, R8 j6 f3 x0 V* f

  1692. 4 |8 ?7 w' ^3 b
  1693.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
      q7 K/ J) I1 a3 M4 h5 D
  1694.         {
    8 O7 z  q$ K7 ?  r+ B
  1695.           txBuffer[txLength] = CodeCan;
    7 J- U, [5 S! `$ t
  1696.         }
    * j; P& U- J9 {4 ^: a0 [
  1697. % O/ k, N% P+ g" z& D+ ^5 l; b
  1698.         write(txBuffer, txLength);
    3 G. V: H) c& z5 f$ U
  1699.         callback(StatusError, NULL, NULL);8 D+ r. s/ C# ]" f& Y; g
  1700.       }
    " w) s' m1 R2 P  A) l4 t
  1701.       else, N9 F: y5 T( b0 ~3 c0 ]
  1702.       {
    2 f" V, L# ]- \* V9 ]
  1703.         write(txBuffer, txLength);; u2 H7 o% W# K+ |* C+ ]
  1704.       }
    % `5 @) Y+ _. _* E$ x' E6 W7 D( ]
  1705. 9 O% ?  _7 ]% b6 e9 s6 N; a0 N
  1706.       break;
    4 T& I8 J* b8 _8 ^9 Z7 e8 @
  1707.     }
    0 A' A& O, g% n# y5 U7 l' e

  1708. " l. H! R8 N2 t& [, n& \
  1709.     case CodeAck:  s  Z6 J9 Q$ [; t) A6 L; C
  1710.     {
    - Q  G/ K& D  a* u( |! J/ f5 N
  1711.       timeCount  = 0;6 W+ H7 N' P  g4 \7 ]: p
  1712.       errorCount = 0;: ~" ]; ]* x7 H! r1 l& x( ?
  1713.       dataCount  = 0;7 k* O8 C( s$ t) N! Y- W( g
  1714.       code       = CodeNone;  j, ^9 {6 n+ J3 d5 M6 q+ x2 s
  1715.       stage      = StageNone;2 [3 ^" s6 E* G9 L) S3 S6 ~
  1716.       callback(StatusFinish, NULL, NULL);
      [& ^4 C0 i5 B1 S$ }% |
  1717. ) P* j9 E1 Y* `% T5 L7 c/ |) x+ o
  1718.       break;6 r; N1 m6 a+ ~% y2 X3 j+ `) u
  1719.     }* C1 t3 n! [# J1 r! ~
  1720. ! B3 S) ^; D# V2 C5 o7 P1 B1 o
  1721.     case CodeA1:- N: }; `" t# l( a3 g- O
  1722.     case CodeA2:
    % i( w. [4 _" @7 `* i
  1723.     case CodeCan:
    / u: n/ _" E2 W2 v% [( H
  1724.     {' ^* v0 t, G' }3 q2 J
  1725.       timeCount  = 0;. L6 B0 f4 k9 s
  1726.       errorCount = 0;" y3 K) X! h3 M( t; u# M$ [
  1727.       dataCount  = 0;
    $ X5 E( {8 b. i0 M+ Y5 c
  1728.       code       = CodeNone;+ y3 |& j/ L1 W" s
  1729.       stage      = StageNone;
    9 w. W# `3 l) b( }3 U
  1730.       callback(StatusAbort, NULL, NULL);+ Q+ y5 P+ K. S) I9 U- i8 H3 G

  1731. 9 N- ~& f7 {5 g8 O  k2 v* j
  1732.       break;
    + f0 t/ q+ J/ ~! |! g+ M9 j/ L0 ?: O
  1733.     }& m9 M/ O5 f. p
  1734. 5 l1 [! M# T: E8 C
  1735.     default:
    2 u; _" O( S2 q" `1 {
  1736.     {4 o% o4 P0 Y% s0 \
  1737.       timeCount++;
    7 `! A6 X' Z: Y$ P+ ]+ g( U

  1738. # Y. m# G+ Y- \& z
  1739.       if((timeCount / (timeDivide + 1)) > timeMax)
    # O7 z- R8 M: m
  1740.       {1 `6 W( a5 K' p0 p+ H, I& Y' G
  1741.         timeCount  = 0;( n  d% r9 y+ R4 F0 |
  1742.         errorCount = 0;
    - |2 a; M) |9 K; G. |8 T- F' c
  1743.         dataCount  = 0;
    , I. ~& }- T# ~9 ^* L
  1744.         code       = CodeNone;
    * v  w8 L6 g' D
  1745.         stage      = StageNone;
    ; E5 M5 l: u" G  Z
  1746. 5 C  y" P7 N/ P$ m& L1 v
  1747.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)9 T+ [* O+ G8 r4 O1 o
  1748.         {' K4 F. r( ^. k7 T
  1749.           txBuffer[txLength] = CodeCan;
      z6 Y, X: ?" u- s; O
  1750.         }
    ! t/ B! h( K. j/ D: q

  1751. * G* u, u0 m$ T0 j
  1752.         write(txBuffer, txLength);
    ( b2 z8 c7 Y  _  ?% r
  1753.         callback(StatusError, NULL, NULL);
    * N2 q; Z# c' s; W/ m
  1754.       }
    5 e8 N% @4 ]) K& T
  1755.       else if((timeCount % (timeDivide + 1)) == 0)7 d* i1 E  O: w9 R2 C2 S! \- P: @4 Y
  1756.       {
    6 z% b. v; h  N. B
  1757.         write(txBuffer, txLength);
    & x3 Q  T& j  K
  1758.       }
    + s& Z; o8 N4 I( H8 E. V4 Q4 P, J
  1759.     }
    * f3 c7 w8 g  @! f: Y) ]
  1760.   }
    - h) I; d7 p9 Q9 P
  1761. }
    . p# f0 Q- Q7 o+ s0 @- y

  1762. 5 Z1 H5 Y7 x6 U+ E' U5 M5 S% @# }3 o6 l8 k
  1763. /**
    ' Q* e8 D8 ]- L
  1764.   * @brief  Calculate CRC16 checksum.
    9 f2 \" e0 J3 z5 r
  1765.   * @param  [in] buff: The data to be calculated.0 }7 k, G2 S+ t( ?. Q4 ?
  1766.   * @param  [in] len:  The length of the data to be calculated.
    2 c9 t. q5 D2 O
  1767.   * @return Calculated CRC16 checksum.2 }% T: W1 \; Y* R! O0 t6 R& E$ g
  1768.   */
    4 e+ ^: ^3 N& p5 ^% @
  1769. uint16_t Ymodem::crc16(uint8_t *buff, uint32_t len)0 e: P2 g' K1 X, t" V+ t
  1770. {
    ) H/ G0 G/ |( r) @
  1771.   uint16_t crc = 0;5 ?% u0 ~' d3 r* m9 O: L8 g8 b

  1772. ' f* {; u9 A4 W: \
  1773.   while(len--)  f) h" c) y4 g% V
  1774.   {% g- T; d6 u' C# d
  1775.     crc ^= (uint16_t)(*(buff++)) << 8;
    1 w& k8 `: k1 V- q; o! V
  1776. ; |) I6 @) I' e  H9 q" V; N" u' A
  1777.     for(int i = 0; i < 8; i++)( W3 @  U" d- O9 W/ g& p
  1778.     {$ _7 \( d' h9 u; d# t
  1779.       if(crc & 0x8000)1 k! [- S$ u. f- r$ d: y
  1780.       {& @1 X7 _0 F% N* P; v3 F/ o
  1781.         crc = (crc << 1) ^ 0x1021;
    ' ?: l4 @, ?: L# t% M
  1782.       }
    ) v3 C) U% D; u, \2 F$ F# ^
  1783.       else, e6 @) x2 ?7 c. i
  1784.       {! F. Q1 l+ D, A9 \  f& V/ K) a
  1785.         crc = crc << 1;: o4 Y3 P5 C7 @5 W8 ^0 {
  1786.       }
    $ i( c: b- c+ {8 o% J% x
  1787.     }) C( @& m+ I7 t3 a5 b" [
  1788.   }' F7 E% M/ O8 B, q6 W. ]$ f! m
  1789. 4 a! V$ a& `* U( D1 u2 ]0 D- W
  1790.   return crc;; V/ O) Y, K$ i
  1791. }
    * L: }& C3 J0 d; W
复制代码
' e+ Z# T7 M9 `0 V$ ~" V

2 |6 U" L# h9 w9 J$ p& n% A5 R0 C& d% w+ N0 o3 d

& e/ n& ~; W' P9 w2 g/ }9 w* _; I% f" c: O) u0 C4 S9 a, I! X: q) N
收藏 1 评论11 发布时间:2018-3-6 22:28

举报

11个回答
XinLiYF 回答时间:2018-3-6 22:30:39
      YmodemFileReceive.h文件
* o5 X" b* c% F7 {
  1. #ifndef YMODEMFILERECEIVE_H
    6 ^# J2 g# E$ E2 c. q  \
  2. #define YMODEMFILERECEIVE_H
    5 Z/ T3 [  Y2 O' I

  3. 1 u0 n+ q5 h" w! W7 ~) _
  4. #include <QFile>0 {& F9 C# C8 k# Q: b. P
  5. #include <QTimer>8 g: @$ b* t# Y/ `8 g
  6. #include <QObject>
    6 Z0 J/ y: D- M) F* {; d  v
  7. #include <QSerialPort>: \% M, O: k0 ~5 s* ^( K
  8. #include "Ymodem.h"" e0 ^8 X6 |. q6 Z3 U+ K

  9. . x$ i4 K3 N$ I( @' V- ^; O
  10. class YmodemFileReceive : public QObject, public Ymodem, `4 B8 m6 \1 ~
  11. {+ p/ _4 p7 L; S- w; m- g4 F; z7 Z
  12.     Q_OBJECT
    ' B1 X; A2 P( K0 J; Y6 b- i3 i
  13. 7 p% f* k" J4 S& \
  14. public:
    7 R) }. a) V% O' e
  15.     explicit YmodemFileReceive(QObject *parent = 0);
      `$ v; A# K: ?
  16.     ~YmodemFileReceive();
    : i/ N) k7 W. t9 X9 M
  17. ; G% s4 {5 F- h- `, S$ }
  18.     void setFilePath(const QString &path);# t. J+ N/ V& V9 Q3 g! |6 F4 ^
  19. 4 ?* a3 V. u( I5 b$ o* Q% s7 o
  20.     void setPortName(const QString &name);0 P1 H  P1 W2 v+ X8 W6 x% [% k
  21.     void setPortBaudRate(qint32 baudrate);" T! r; y. j  K$ Y/ ~" _* F

  22. % _) y6 C0 I/ z" }2 ?& a
  23.     bool startReceive();
    5 Q' g. E; H3 {
  24.     void stopReceive();
    ) W; v: h( \$ P/ F$ b

  25. , s( H/ _7 a. y2 y( S: a1 X: f
  26.     int getReceiveProgress();/ W2 \8 }& _: t5 o9 y( n- L
  27.     Status getReceiveStatus();
    6 B6 K5 Z1 \& C( `- |
  28. 2 U3 M* E% Y% j
  29. signals:$ t2 n  O! i4 w2 O% k
  30.     void receiveProgress(int progress);
    ( a8 O4 _3 x9 b( d4 y6 U
  31.     void receiveStatus(YmodemFileReceive::Status status);
    ( Y2 ]8 O$ N4 m1 V) C& E
  32. 6 p4 l6 ?( w) b, X, z) c5 e
  33. private slots:  G4 W) A' L; e) H
  34.     void readTimeOut();# O9 d( m* c; i2 ^8 N4 g: D
  35.     void writeTimeOut();, ?) \- P& j/ M* V  p
  36.   N- _0 b0 X% x& l3 J
  37. private:
    # j# C! ?( i/ o& _
  38.     Code callback(Status status, uint8_t *buff, uint32_t *len);( F9 u: N7 D2 _; o
  39. 3 ^/ ~6 R8 _& N( S$ d  X" ]
  40.     uint32_t read(uint8_t *buff, uint32_t len);
    ' I) K1 q5 U$ u3 _4 }
  41.     uint32_t write(uint8_t *buff, uint32_t len);
      A! o% |% m+ j! R. @% M, Q# K
  42. & k3 {! [# T( M& l
  43.     QFile       *file;
    ( U; S0 x% K( |
  44.     QTimer      *readTimer;
    / U1 w' Z/ b" l$ D* u
  45.     QTimer      *writeTimer;
    ! G) M* k" n+ u7 `0 m/ O7 L7 R* F; o: {
  46.     QSerialPort *serialPort;
    5 v2 S' a* O0 b5 ^

  47. 5 S  l- \: q$ r+ y
  48.     int      progress;
    , \* f! p: A7 r, u
  49.     Status   status;
    + R8 _: t) T* I; ?, @* r) k
  50.     QString  filePath;! E4 P1 r1 x3 {$ H, m
  51.     QString  fileName;* {( n( D4 n, e' t1 o) \8 Q
  52.     uint64_t fileSize;
    : T! [% N" u5 n) _7 h+ o
  53.     uint64_t fileCount;+ j* P" E! g; ]" T5 n( B
  54. };
    7 T0 T+ Y2 D" d; o( q, F
  55. 9 x5 C. a) ^# y* r
  56. #endif // YMODEMFILERECEIVE_H8 F& D- S6 p* C- Z) L  \- X
复制代码

) k/ O; R' ^6 S  k4 X2 F      YmodemFileReceive.cpp文件. U: k- d* g' r  H. `: T, i) A
  1. #include "YmodemFileReceive.h"* w0 o) a' m* T: M0 w- O: y

  2. * S2 N4 }! o, n- `! ^
  3. #define READ_TIME_OUT   (10)- S% E, H& n; _3 F; V. |
  4. #define WRITE_TIME_OUT  (100)
    ; o% W9 }8 {# j  Q
  5. . q2 m9 i7 ]; E7 d
  6. YmodemFileReceive::YmodemFileReceive(QObject *parent) :
    ) T( f- i5 f' X+ K5 ]( }
  7.     QObject(parent),
    ) ]' s( O0 t9 D) R  ^( C$ P5 b
  8.     file(new QFile),
    ' T) u' q$ t9 Y+ b0 n
  9.     readTimer(new QTimer),
    2 s, I# A+ S% G( a1 M/ K
  10.     writeTimer(new QTimer),' a0 }8 g; n/ O- W& R
  11.     serialPort(new QSerialPort)
    ) C4 B! t. f+ C* h. |4 G/ l; |& r# b
  12. {& \$ V: o2 N- u6 A8 H" x
  13.     setTimeDivide(499);
    ' H+ Q) l' r  I, C- S
  14.     setTimeMax(5);: @; B4 F) c( P2 I- N$ d) P
  15.     setErrorMax(999);
    : m3 s! ?1 L/ `( m% Y  J& N

  16. ; J/ i$ j  a+ m9 `& X
  17.     serialPort->setPortName("COM1");1 W  a9 W4 j8 p
  18.     serialPort->setBaudRate(115200);" t4 _1 Y; [. M1 g. Q
  19.     serialPort->setDataBits(QSerialPort::Data8);/ X2 M: L: r  s3 ?3 ^% a( i6 V0 J
  20.     serialPort->setStopBits(QSerialPort::OneStop);8 q# g6 n0 X6 u, j* q
  21.     serialPort->setParity(QSerialPort::NoParity);
    1 q0 P3 {& ]% T6 i9 Q% r
  22.     serialPort->setFlowControl(QSerialPort::NoFlowControl);7 v3 \0 C! B( N; v2 }

  23. 7 C) R. H. P6 ^8 r9 H/ l
  24.     connect(readTimer, SIGNAL(timeout()), this, SLOT(readTimeOut()));( r- b+ d0 c) n6 j' `* H5 h' y4 s
  25.     connect(writeTimer, SIGNAL(timeout()), this, SLOT(writeTimeOut()));
    % @  l( t0 B9 z6 L9 o
  26. }
    8 ?9 S/ j$ A! c. @" |

  27. 2 q# W' o) F1 p8 v- _( \. i
  28. YmodemFileReceive::~YmodemFileReceive()
    9 G& F5 C+ N& k. S7 z
  29. {
    ; [, x% s/ d/ h9 {; s) F
  30.     delete file;# S3 S1 M7 H( C; e5 Q! ^
  31.     delete readTimer;
    / u5 A: l& g  x
  32.     delete writeTimer;
    $ b4 W% Q4 k0 S) B5 p  ~+ X
  33.     delete serialPort;7 A4 Q8 S8 f- c6 b6 y; V: _
  34. }
    ) F6 K$ k0 O8 J
  35. 8 H$ R# _( H; F$ m8 `
  36. void YmodemFileReceive::setFilePath(const QString &path)
    6 _* Q, P6 a% P+ b. c& d6 s
  37. {6 @" A% s1 b& X* Z4 g, a
  38.     filePath = path + "/";
    3 P% y0 t* H" K6 s
  39. }
    # t( H2 h" B3 K7 ^

  40. , N" }  r! X6 S4 ~
  41. void YmodemFileReceive::setPortName(const QString &name)! a. _# B& r9 `) t$ E9 h3 k
  42. {- r8 m5 Q& n/ P" v* R: x6 ^; N
  43.     serialPort->setPortName(name);
    : R# M& o/ p% N" ^0 B
  44. }
    - z0 E) q" v8 c+ o' [
  45. 4 c8 H; a! k& l, T
  46. void YmodemFileReceive::setPortBaudRate(qint32 baudrate)
    0 s" e* z0 {# d9 Y3 R
  47. {
      o9 r/ s6 P4 Y- V% X, L3 s
  48.     serialPort->setBaudRate(baudrate);
    / d" u% x; Z& ?  Z
  49. }" L  D3 Q# Z* ?( d
  50. ; l" M# Y6 z& w- H1 i" T  v
  51. bool YmodemFileReceive::startReceive(), S2 k8 t( b2 g* u( p* X. G
  52. {. u/ T& {+ Q7 |( C- T
  53.     progress = 0;2 m0 R" ~: M( y
  54.     status   = StatusEstablish;! r9 `8 a. t3 Z5 `5 |0 b4 ]- N

  55. - j. G* D* Z" z0 f  w7 S% M) t/ V
  56.     if(serialPort->open(QSerialPort::ReadWrite) == true)
    8 H% Y& ~/ W8 M1 y
  57.     {3 A6 K% x( N6 F
  58.         readTimer->start(READ_TIME_OUT);
    " @% b8 A% N# h

  59. 0 \( c/ }% Z" ]6 y# g' j
  60.         return true;
    & \4 H5 ?% g4 _9 W5 Q
  61.     }& v+ F0 ~3 [+ u% k
  62.     else! ~* O7 ~) r0 l6 @' v& Z9 s
  63.     {" `; L+ ?  g7 a4 v
  64.         return false;
    0 L# C' l- q7 V9 c) m8 E1 {. u# }; Y
  65.     }3 c% M; T% i5 l1 J1 l
  66. }
    # i8 Z$ U+ G/ W! k. o

  67. . Y+ H( M8 G* P7 Y* x) L- ]
  68. void YmodemFileReceive::stopReceive(). [& x9 n. ?4 ?" O, I. E
  69. {
      [0 e) I' r; h3 d  P% ?) K
  70.     file->close();# g3 w* Z' t% T+ k1 E- ]& l7 X
  71.     abort();3 O& n# E7 \. H6 Z% T* a
  72.     status = StatusAbort;
    3 l. i* }" }% a% T! F* y* [6 W
  73.     writeTimer->start(WRITE_TIME_OUT);
    1 a/ _, K4 O1 p8 ~2 Z# ?/ b4 H4 O; [
  74. }
    - z% @! D7 H6 m& @5 U* Q
  75. ; b4 j% @. a, T
  76. int YmodemFileReceive::getReceiveProgress()6 }8 m: i9 @9 Z, `
  77. {3 N, Z; o# a" ~7 Y$ W
  78.     return progress;* x- _9 Y( Q$ m" s
  79. }
    * f6 j  s0 D) j' p% _; n

  80.   r# R. R- O$ T
  81. Ymodem::Status YmodemFileReceive::getReceiveStatus()
    6 H' d( C  u3 Q
  82. {
    : J7 |: y! `. r
  83.     return status;
    7 h, K: G6 P* T% J% T* E5 k, U  J9 |# u
  84. }9 c- D  [2 r, C- x
  85. ; h/ p- y9 E1 ~! J# L+ o) A
  86. void YmodemFileReceive::readTimeOut()2 I8 T. |9 |3 `2 ?
  87. {
    ( I% _: g; d$ F7 |
  88.     readTimer->stop();
    ( J4 p, ~$ |" Q8 H5 R4 n  a

  89. 9 W! o; a4 Q4 ^
  90.     receive();
    4 g1 {* Z5 C/ _1 `

  91. 9 U, J. N& D- h! P
  92.     if((status == StatusEstablish) || (status == StatusTransmit))1 R! b( y% z' U; B% N
  93.     {
    ! H% p0 o1 M8 L1 {% H( H' S/ B, n
  94.         readTimer->start(READ_TIME_OUT);2 g7 Y5 s/ }) K3 U  l
  95.     }
    3 T7 A$ i" `8 s* ~. ^2 [
  96. }
    0 N" w& d; [, y. D) t
  97. 7 R% s( {' {6 q* [' U4 D+ G( E  h
  98. void YmodemFileReceive::writeTimeOut()( E( ~: @& P& k% a
  99. {: K  a* Y2 S* F8 x
  100.     writeTimer->stop();* A2 O' E, p' l* |" U% z  ~2 V: _* R
  101.     serialPort->close();
    6 M* R! k7 x3 V
  102.     receiveStatus(status);
    ( Y* H+ c: h* l  X6 E. C1 |- z
  103. }( O6 g: o: t8 Z( O' s
  104. + N+ c" Y3 T/ Y+ b  Z& y+ B3 B
  105. Ymodem::Code YmodemFileReceive::callback(Status status, uint8_t *buff, uint32_t *len)
    + M1 E- Z$ H- K" T. j$ U2 ^3 [
  106. {. W  V- P) e& Q0 T$ A( ~
  107.     switch(status)
    8 s2 b3 s+ M, H
  108.     {
    3 H; e# X2 u5 Y8 Z
  109.         case StatusEstablish:+ t* i" }1 @8 P! o* J4 Q+ ?
  110.         {
    7 n4 Q. ?& m4 d
  111.             if(buff[0] != 0)0 l* Q! L  L  j8 ^9 }# u) M$ b3 _
  112.             {4 E3 m" N  }! _
  113.                 int  i         =  0;* |2 V$ o" ~7 H' Y( x
  114.                 char name[128] = {0};
    ( O7 Z4 m' {1 l+ l% I
  115.                 char size[128] = {0};9 G5 a9 _; N6 y$ u: l( E
  116. 8 r. ~& |4 {8 U
  117.                 for(int j = 0; buff[i] != 0; i++, j++)+ z9 A4 {+ c3 ~5 \% G' u8 C
  118.                 {
    : d; F, M, }$ A7 i
  119.                     name[j] = buff[i];
    ( ]# |% a$ I* m
  120.                 }/ R, z( I& b7 q3 ^. Z
  121. & [# P8 y  c" W! ?2 W- c; v
  122.                 i++;% A6 [6 E/ N, b. Z4 }$ U

  123. - _6 s3 p2 n4 O) z7 p2 s
  124.                 for(int j = 0; buff[i] != 0; i++, j++)* Q3 o: n7 E7 ^; _
  125.                 {
    * R/ H' l  ~! ?
  126.                     size[j] = buff[i];
    9 K* `1 R6 e. t1 k
  127.                 }
    8 z; \# P% u9 O9 M
  128. 1 a) {3 Z- a' \  A
  129.                 fileName  = QString::fromLocal8Bit(name);, B. R6 Q1 C5 K: ]
  130.                 fileSize  = QString(size).toULongLong();3 S$ m, M5 r: y1 B$ Z2 ~" l
  131.                 fileCount = 0;4 ?* B+ z% M/ Y

  132. ! \7 s2 Q8 j  |4 [4 k
  133.                 file->setFileName(filePath + fileName);' r8 l9 ~- }6 _( E

  134. 4 @& o: a. y1 p0 v+ v
  135.                 if(file->open(QFile::WriteOnly) == true); K! j, q' L! ^
  136.                 {
    + }8 L0 f! i8 Q
  137.                     YmodemFileReceive::status = StatusEstablish;
    % N) r* h& Q+ Z. K7 l
  138. ' U7 r4 W6 Z# _  e) `( Q
  139.                     receiveStatus(StatusEstablish);
    $ K. j3 e1 O3 y7 Q" |  w* ~
  140. / \3 }2 r6 M7 V2 M$ b
  141.                     return CodeAck;
    ! b& _* I5 N: Y/ p) T& n
  142.                 }8 f; z; s5 ~4 P: S% d* x
  143.                 else
    / {( R$ K& U2 [5 Z
  144.                 {
    , g9 u8 U! R4 r$ n0 q
  145.                     YmodemFileReceive::status = StatusError;
    8 c( x. E- D/ N6 M4 a. v; f8 A

  146. ' j& R5 v8 D9 `& q9 O) t. i
  147.                     writeTimer->start(WRITE_TIME_OUT);0 m- F8 h& S) ~

  148. 8 `, i3 n" d. O# g, w' I$ |
  149.                     return CodeCan;
    & l7 K  A! o$ m4 ~8 q. C( j
  150.                 }/ M) i  b1 S9 K1 I
  151.             }5 [5 ?- B2 A. b
  152.             else
    : U: l, p6 l+ D$ X
  153.             {0 l9 H  k4 t, {
  154.                 YmodemFileReceive::status = StatusError;0 {* A; r4 T* W3 C$ F
  155. & {6 y0 U& n2 L8 @
  156.                 writeTimer->start(WRITE_TIME_OUT);
    * Z1 Y4 k9 O5 {; f

  157. % T, m) \/ d$ P0 L1 o
  158.                 return CodeCan;4 L: b$ c" {" v3 M# l1 s8 L4 O
  159.             }
    0 t2 j; f+ w1 V* O
  160.         }/ B& i; G/ h  [  U
  161. ) K9 C& S) Q5 c" g8 W# C4 G8 ^
  162.         case StatusTransmit:  S' w8 E9 d7 }) z+ H" V" G0 P) L$ i
  163.         {8 J, t+ g6 ]- ^7 d1 T  K
  164.             if((fileSize - fileCount) > *len)
    $ \# S9 c8 t/ o: }" U, [7 P6 g
  165.             {0 b2 w/ C  s; l7 X2 S
  166.                 file->write((char *)buff, *len);& q6 z$ |- R: ?
  167. + L" ?! O- U8 Q' w' y6 d6 L
  168.                 fileCount += *len;
    / `& h$ W8 i  W6 K1 C4 s
  169.             }7 s( k: m8 r; R0 Y" U$ S* I
  170.             else
    % F1 u; ~" ~+ c
  171.             {
    2 N1 N' j2 @2 l* l) k$ I
  172.                 file->write((char *)buff, fileSize - fileCount);+ U; v/ _1 Y& d* t! p6 ~

  173. 6 p$ G; S0 G, C5 c) q: N
  174.                 fileCount += fileSize - fileCount;
      [: O8 p9 V$ T% k0 O
  175.             }
    8 W* F% [% G4 c1 t! o( `
  176. & ]& o6 T7 z9 m! O
  177.             progress = (int)(fileCount * 100 / fileSize);) v0 Z( ], ~. W8 |! U7 O
  178. , u" {+ K' J! I2 z. K. V+ z3 C
  179.             YmodemFileReceive::status = StatusTransmit;
    ' i$ S5 P# B2 ^6 G5 d+ D

  180. $ r6 `! r$ C* o3 F) t9 D5 j
  181.             receiveProgress(progress);
    & u* }+ L& l2 e+ G1 W1 ?3 S
  182.             receiveStatus(StatusTransmit);6 X  S; ]$ d0 r% M9 R

  183.   K- d' d. X' A: b5 [3 Q- C
  184.             return CodeAck;
    # J# K) q. q* S" e5 n2 ], \, ^
  185.         }- E5 u$ E; b/ T& R  Y$ F) O
  186. * {  \% R% `9 p& X' A, ?' s. B
  187.         case StatusFinish:: h% W' K2 O1 w/ `2 X2 C
  188.         {
      f4 Y6 R$ H: b* ]( P3 o$ K
  189.             file->close();
    . M7 p* K+ X7 @+ h

  190. # C) r2 z* h9 ~) q/ u8 A" g0 p3 f
  191.             YmodemFileReceive::status = StatusFinish;% t" Q" ~+ b' h/ R' B5 `( Z/ R& D
  192. * K- L# X. }" W+ H# E
  193.             writeTimer->start(WRITE_TIME_OUT);
    $ ?2 U* ]7 O6 L! g4 A2 v
  194. ) u. ^0 `* a4 r4 g8 n3 v, ]
  195.             return CodeAck;
    . H; z$ \% m( m& Y7 S" v
  196.         }/ C8 k9 O" s; R) ], N" x

  197. 2 D" L0 S. u6 ?- t& C* U
  198.         case StatusAbort:7 o' V1 c/ G! E) t0 O" ^
  199.         {
    ( C: W" n0 J- s" X
  200.             file->close();( L' l4 `0 i/ e* ^! M. N
  201. 8 H, p' M. a$ T. l9 a3 C0 W
  202.             YmodemFileReceive::status = StatusAbort;! f4 P9 y6 {( d& m. S( p3 F
  203. % p1 I1 v; T" b+ T8 M
  204.             writeTimer->start(WRITE_TIME_OUT);
    ) X# {2 E/ [9 n
  205. 3 S& [; \% @7 |' Q- {5 D
  206.             return CodeCan;! {% y9 D# D" n6 N
  207.         }
    9 b# U: r2 N# H3 V, X" v% H' o
  208. ' {$ ?: I* k. }" C! m
  209.         case StatusTimeout:
    ; S% }5 p( r  {! v1 k) r& q
  210.         {
    . v8 u: v$ h( Q9 h( z/ ?; h& J% J
  211.             YmodemFileReceive::status = StatusTimeout;, ~8 H! S) R8 k$ J9 R/ H

  212. & R' l" x7 k, J# `& b
  213.             writeTimer->start(WRITE_TIME_OUT);
    + C- t5 T+ ?) v- B, |

  214. / D6 C; J  F/ D! y" E8 o
  215.             return CodeCan;
    - h7 j4 M& h8 Q2 t: e
  216.         }, k% @) ?' E- Y- }8 k; p

  217. 7 k! s: e2 |: z
  218.         default:
    2 B2 t7 M2 h* ?) M, f" b5 ]
  219.         {
    2 i: @  f& `. b5 F$ u9 K
  220.             file->close();; ?* N2 w1 ~  ~8 l7 |' e

  221. ' b8 d. W, x9 z/ Y! E  _, ^
  222.             YmodemFileReceive::status = StatusError;
    ' h1 h+ r4 D7 y( D1 E. V5 H% K; W% P

  223. - H; V) P) f5 \
  224.             writeTimer->start(WRITE_TIME_OUT);" \: `, B! W$ W: t9 [  g3 c

  225. 5 y' ~. G6 t: [7 A
  226.             return CodeCan;$ D# s1 W7 u2 P+ o
  227.         }
    ; u) e# ^9 T% G! y
  228.     }! G% P% |: a5 U$ n6 V/ w
  229. }
      T: n3 B- c" l2 d" k. Z6 A

  230. 4 E. N/ c: ]* X- `, Q' U
  231. uint32_t YmodemFileReceive::read(uint8_t *buff, uint32_t len)
    4 h$ Y- O- Z0 h' W
  232. {
    % R. q8 h2 _/ s9 A3 P  u& I
  233.     return serialPort->read((char *)buff, len);
    3 O  _# P- \! ~) W6 R" N
  234. }& `9 ^! c# U: T; s" K9 [

  235. 1 T6 u, S# U  I1 n! A$ `
  236. uint32_t YmodemFileReceive::write(uint8_t *buff, uint32_t len)3 r8 U4 ?7 ^# ]  l
  237. {/ f; X& m) F( c/ H& C; j& ^
  238.     return serialPort->write((char *)buff, len);8 y; o! s! j* N. F7 v
  239. }
    1 Z7 p$ l! H0 [* P5 s6 L6 o/ }
复制代码

0 L9 E5 B, i9 O$ ~# a2 I9 Q1 e$ {' L$ ?, m' ^4 v$ _
6 r; ~* e3 p8 X3 D
  L  |- m9 O2 ?4 w% W1 Q# k

* S6 u' ]" ]% y6 s: ]- J3 h0 ^
XinLiYF 回答时间:2018-3-6 22:31:26
      YmodemFileTransmit.h文件& x* l# k5 H# b2 z0 Z
  1. #ifndef YMODEMFILETRANSMIT_H
    0 `5 I9 t: I# G6 L$ z* x
  2. #define YMODEMFILETRANSMIT_H. C2 U0 P, h) p5 N( H3 E
  3. " g$ e+ E3 L) I# N
  4. #include <QFile>& s2 O& V8 H+ ]' m4 Y# P
  5. #include <QTimer>( u$ ?& c2 h- m( d( H2 A) |
  6. #include <QObject>
    3 L; c2 ]3 ^" F2 Y* d
  7. #include <QSerialPort>
    & [) v* r0 _) B: p
  8. #include "Ymodem.h"
    4 s" `* z7 V  n8 j9 L/ s, k3 e+ E- H! p5 ~

  9. ) U. v) h0 G$ Q. I7 o
  10. class YmodemFileTransmit : public QObject, public Ymodem
    . E8 Z& z. a$ C  J. B, _. u# o1 x
  11. {
    4 z  u0 B4 l( U* g5 H( D+ N( [2 g. T
  12.     Q_OBJECT1 Y! z$ H# W$ X  Q( Z; T% e2 F3 x
  13. * b' x, }5 n) Y4 V0 f( t
  14. public:2 A' q3 Y) l; O& B
  15.     explicit YmodemFileTransmit(QObject *parent = 0);- O' _( H8 ~1 d
  16.     ~YmodemFileTransmit();4 ]4 F* Z( N6 y7 [3 q) d

  17. 7 U  w6 w0 x) ?, K& q7 W" W& c5 q7 v
  18.     void setFileName(const QString &name);
    . N$ c% n% U$ m* z$ @) s9 B0 d

  19. # x1 o; q9 r2 y5 q6 Z; d4 F
  20.     void setPortName(const QString &name);
    2 p4 d0 U$ f, s' V% Q; L# T
  21.     void setPortBaudRate(qint32 baudrate);$ i2 X' c8 a6 P
  22. : d3 k( ?, ~7 t! L9 W, c  o
  23.     bool startTransmit();
    " }0 n+ S$ Q- X* p5 m5 O: V# ^
  24.     void stopTransmit();
    & [/ M! Z: _2 s) L
  25. 5 p5 J8 _: a) Y9 b3 o- b  m3 |
  26.     int getTransmitProgress();9 I" R! V2 R- y/ s0 l5 W
  27.     Status getTransmitStatus();- U# O' F" l9 X

  28. " V8 j# ?+ _' B' e
  29. signals:
    5 g) C) ~5 f5 p7 L8 N9 b
  30.     void transmitProgress(int progress);+ o- A3 E* N6 T; J* L$ j
  31.     void transmitStatus(YmodemFileTransmit::Status status);
    , c9 s) F, P: _/ t6 I$ Y% T/ M5 s
  32. 6 I" g! J9 v7 e3 z8 m/ I  g: t
  33. private slots:
    7 f6 m* b* n" T5 P% ^+ R
  34.     void readTimeOut();# r" X1 `5 D# S5 V
  35.     void writeTimeOut();2 ^5 E  F# i3 t3 U& Y: f) v
  36. ( O) m1 E/ u4 g% p
  37. private:+ {, N* v8 w0 v1 P5 f' J
  38.     Code callback(Status status, uint8_t *buff, uint32_t *len);
    3 d! {( Y) m, o2 r& S

  39. 5 N5 ~! i3 Z0 t# I% y7 J0 d# b$ C( a
  40.     uint32_t read(uint8_t *buff, uint32_t len);
    # Y- I; v3 b  k
  41.     uint32_t write(uint8_t *buff, uint32_t len);$ w6 `& i- l0 B5 p% `! u

  42. # y' H! a! [, W9 w
  43.     QFile       *file;+ f! H, g, b. v7 G. \( Y
  44.     QTimer      *readTimer;- N3 L) j+ }1 u$ M
  45.     QTimer      *writeTimer;$ }4 C$ B4 [0 [" E- K* R
  46.     QSerialPort *serialPort;
    9 L! O0 s/ e3 O- m( }

  47. 1 x7 H5 }# x8 `; @0 _( B
  48.     int      progress;  _* {# E9 ~5 H9 u! w1 K' \
  49.     Status   status;
    8 g0 z5 D, N' x4 E9 B- |  @
  50.     uint64_t fileSize;
    ( y. f* ^/ }1 y% [# i) ~
  51.     uint64_t fileCount;
    ) w% A( d. W9 b6 ?8 ~- w% K( b
  52. };
    1 s- f! @6 I: B! H# l) _' i

  53. ( T; A0 C: y$ ]0 k/ z/ R$ l, N
  54. #endif // YMODEMFILETRANSMIT_H
    6 d0 u2 |* [$ F! s
复制代码

3 C- d! m* y, b4 [* p8 P      YmodemFileTransmit.cpp文件
! `: s: X5 e) |. S; C% l& D' a. K
  1. #include "YmodemFileTransmit.h"
    8 d. ^" j0 }8 z  E3 T9 B1 N
  2. #include <QFileInfo>
    5 _' n# z6 ?  y# }) p' a
  3. . j2 W" R& o7 V
  4. #define READ_TIME_OUT   (10)
    9 M6 v) x& M* R6 Q8 T( G# h
  5. #define WRITE_TIME_OUT  (100)
    ' c9 j8 s7 f  ?% p+ s+ `' N" r# @
  6. 9 ^: i- w- f7 |9 W; n
  7. YmodemFileTransmit::YmodemFileTransmit(QObject *parent) :
    4 k* o' M" v; ~! T! H& U/ N
  8.     QObject(parent),
    ( K4 \1 F: E/ r, R* @! b
  9.     file(new QFile),& v: O: z" d- J9 {
  10.     readTimer(new QTimer),: t8 {2 j- M- R0 q* x. A
  11.     writeTimer(new QTimer),
    " k$ r/ |( N2 Q; o( u
  12.     serialPort(new QSerialPort)
    7 D, \  r: n7 s5 B9 w+ a
  13. {
      u% R! T% ]$ s8 N& J$ H
  14.     setTimeDivide(499);: j, l2 P1 t$ s+ }
  15.     setTimeMax(5);( }: d& c/ A+ ?/ G4 i4 P
  16.     setErrorMax(999);
    3 H+ Z6 B& m/ P7 D$ L. e

  17. 2 i' v: q# v4 W8 c: i
  18.     serialPort->setPortName("COM1");$ P* A3 y( Y  s: |' f7 M/ Q- ]
  19.     serialPort->setBaudRate(115200);
    / C% b) V( N; A- U4 R
  20.     serialPort->setDataBits(QSerialPort::Data8);
    " {" v2 Y- V9 _! R3 @' \
  21.     serialPort->setStopBits(QSerialPort::OneStop);
    ' p2 E/ ~0 k7 D: k" d3 A, Q9 i
  22.     serialPort->setParity(QSerialPort::NoParity);1 q& Z1 e4 X- R! H
  23.     serialPort->setFlowControl(QSerialPort::NoFlowControl);
    8 b, \+ q2 ?  T; ~% M- c9 i# z

  24. : A  o' o% H) S5 w; D( z5 J4 ~
  25.     connect(readTimer, SIGNAL(timeout()), this, SLOT(readTimeOut()));% g- X" R# M# A6 g
  26.     connect(writeTimer, SIGNAL(timeout()), this, SLOT(writeTimeOut()));
    ) ]. l; V  A# T
  27. }
    $ h" x! Y5 V4 b1 w! j
  28.   o5 f- g3 X) {8 X; w* R1 S
  29. YmodemFileTransmit::~YmodemFileTransmit()) E3 D/ ?8 M* ]% E, A2 P4 }9 b$ Z! x
  30. {# x1 v4 e/ c( J; l
  31.     delete file;- r' J* T( f# D) O. W
  32.     delete readTimer;
    9 G+ K! u- _1 q0 S
  33.     delete writeTimer;2 }6 k, J7 L& H" m
  34.     delete serialPort;
    5 n* r3 C6 B0 M* K' p
  35. }
    ' w" N* d4 h( T3 e( ~

  36. 1 U2 j* h5 d# m- v8 T; [/ Q3 s
  37. void YmodemFileTransmit::setFileName(const QString &name)
    1 i: Z- Q" n6 S9 y" y0 m( }
  38. {8 g9 _& [& P* r8 R+ ~. A" C
  39.     file->setFileName(name);! C6 G- L( T5 z0 h1 F' Y
  40. }% R& W% g$ r3 L/ u

  41. & m  |4 [$ N( U% e) A& C! s
  42. void YmodemFileTransmit::setPortName(const QString &name)) ?9 E- w; D: V: l2 o# o6 p: ^
  43. {) B5 F/ O9 A6 p/ j" ]& h9 ~
  44.     serialPort->setPortName(name);' G$ O" Y- ]3 g* R6 `
  45. }
    9 v0 w- J" D( K+ E; |2 u

  46. ; V( G9 ^' C& P; S! N: f& |
  47. void YmodemFileTransmit::setPortBaudRate(qint32 baudrate)' ~* A1 h; X( G1 n5 H
  48. {7 X: E+ Z$ s* @0 J  @
  49.     serialPort->setBaudRate(baudrate);
      n1 v/ ]0 g% u/ z4 C
  50. }" S( Q* ]! G# T, T  r$ Z
  51. ' l. K  v0 r, y1 T: r8 z3 U
  52. bool YmodemFileTransmit::startTransmit()
    % O+ ^2 d4 G5 `  D0 x
  53. {$ S5 _. @& Q$ Y1 Z: G  m, |9 ?
  54.     progress = 0;
    : P/ v9 E4 @6 q8 B0 c0 l
  55.     status   = StatusEstablish;. B9 O. c9 H1 }. U

  56. 7 |: _& R' r! H0 u5 ?2 o9 @% K
  57.     if(serialPort->open(QSerialPort::ReadWrite) == true)5 u- O: y% h% Y  B8 u
  58.     {' ^! m" V& z* @  R0 k: e2 ^
  59.         readTimer->start(READ_TIME_OUT);
    - A$ U% W- `3 q( N' {. W; ~- b0 j- Q

  60. 4 D' V+ Z; O/ z* \" [5 O
  61.         return true;4 c/ F  h% Q/ h1 ^. _/ j
  62.     }2 K  e" i6 p- o; U$ `
  63.     else
    5 P- @& O: ^, Z0 |) l8 |! c
  64.     {
    + b; i: v, d, @
  65.         return false;& S. h; D( O' L- D& D
  66.     }
    0 k1 b# n8 h% ]8 m# u
  67. }" n7 I" x; j3 N( t. c, @3 J5 h) ?

  68. 6 j+ a1 Q$ G# e6 \& O0 }: x5 @
  69. void YmodemFileTransmit::stopTransmit()
    2 m# J( M# E! Y3 [
  70. {
    / D( ^7 ~) h& a# }
  71.     file->close();
    , B" }; C  ?. u9 P" w, b+ @2 b, I
  72.     abort();
    5 U/ |0 A9 {# U- ?: t0 s
  73.     status = StatusAbort;
    $ C! Z8 }, s+ z8 i" @
  74.     writeTimer->start(WRITE_TIME_OUT);7 v: n/ C; M0 \" {9 M! m" {$ b
  75. }
    & N0 |* J3 w5 K  e6 h
  76. ! N! f7 d  |$ T, j+ m
  77. int YmodemFileTransmit::getTransmitProgress()% X. W, n- g2 }! @2 }4 V4 w
  78. {
    5 N$ Y! t4 _$ r( G3 ?- k) a0 r9 \
  79.     return progress;& \) j8 K/ v7 X9 S
  80. }9 ?: r7 \# J2 J2 x+ D% o2 `( g
  81. - [/ a5 A" h  Y6 X3 o
  82. Ymodem::Status YmodemFileTransmit::getTransmitStatus()
    ( c6 {4 B- v8 w  r- c
  83. {/ A4 w" e* p, L) ~" l6 p/ s
  84.     return status;
    ' K- |( |9 t  P/ o0 F' A$ i7 u  t2 G/ I
  85. }
    3 C& L6 X8 `( P, N4 D
  86. ( }4 g8 \1 U; u3 K
  87. void YmodemFileTransmit::readTimeOut()
    # a: o8 ]) D; Q% C! U
  88. {; e$ R( [6 |8 T! p8 ?, H
  89.     readTimer->stop();
    1 F! V& |8 P4 m
  90. " d6 |8 W; d! ~4 N; ~# f8 F
  91.     transmit();" V/ b5 r& F# I) E* }
  92. : t) q$ C8 h6 q- k4 ]2 z
  93.     if((status == StatusEstablish) || (status == StatusTransmit))
    4 M* ^; m1 X* t& U% N6 C
  94.     {
    ; I$ w, y$ P8 t# K: k
  95.         readTimer->start(READ_TIME_OUT);" A- X% v3 o, m
  96.     }
    * e, Z. @, T, P
  97. }7 J; u8 M2 R/ M) H1 C% D
  98. % u7 M+ e) a) p6 c4 M& X: @) `
  99. void YmodemFileTransmit::writeTimeOut()
    4 L- v+ z+ L7 ^; B% y  a
  100. {% j9 K/ U" `- C7 E- y: Z
  101.     writeTimer->stop();0 a$ f  F4 A1 a  v1 A- p+ Z  A, L
  102.     serialPort->close();% h: w5 k) \! ?8 g$ s! z5 [5 j
  103.     transmitStatus(status);
    5 Q$ G; f% P) V2 j( |& ]* R
  104. }
    5 p0 i' }1 X5 C, l" G
  105. % i+ m9 P* W2 `# e+ w# Q0 w
  106. Ymodem::Code YmodemFileTransmit::callback(Status status, uint8_t *buff, uint32_t *len)
    7 @" H1 N" h. S; r
  107. {
    ' x) B8 ?; }- B( e) y
  108.     switch(status)' @& n+ V' @3 X$ ^  R7 Z
  109.     {
    8 M5 \2 w& e# U$ _8 b* g: t( s' E: J; T6 A
  110.         case StatusEstablish:
    7 y& r' z' ~5 a: R" @
  111.         {
    + I, Z2 s, S, f$ d" Q
  112.             if(file->open(QFile::ReadOnly) == true)5 C0 M% L. }" J
  113.             {6 f: p8 [% G" v$ E) s6 K( b
  114.                 QFileInfo fileInfo(*file);* N! V0 Y, k* l7 W7 U: g% M
  115. 2 @7 r9 K1 e, v! v
  116.                 fileSize  = fileInfo.size();
    ' l3 {/ N4 U* O' t* e: [4 l/ d
  117.                 fileCount = 0;
    # @3 {9 @  M. U2 A- v1 m( R
  118. $ Q0 a, J* W/ u$ y
  119.                 strcpy((char *)buff, fileInfo.fileName().toLocal8Bit().data());& H) D: q! e, W3 o4 y$ M: `$ Q
  120.                 strcpy((char *)buff + fileInfo.fileName().toLocal8Bit().size() + 1, QByteArray::number(fileInfo.size()).data());* t9 i, L# E% t4 q' ~
  121. ( s7 E# o5 |, ^2 D. y# h0 Q8 g) L5 T: v
  122.                 *len = YMODEM_PACKET_SIZE;
    2 T9 k8 U8 R/ q, k5 A

  123. % q% s+ Q4 `( n( C
  124.                 YmodemFileTransmit::status = StatusEstablish;" R2 }) w7 l  g4 l2 {; C; n# s5 k
  125. ( I1 }9 L$ z, E: _2 `
  126.                 transmitStatus(StatusEstablish);3 B+ T: }9 v! t; u/ J
  127. - Q- j: D- s  _. @
  128.                 return CodeAck;# s8 C3 L( Z5 i* I  R9 S
  129.             }
    % y$ V/ O' Q6 ?1 r
  130.             else# i3 h% X' L' ^; J
  131.             {* w( C2 f% m! b4 d. a4 T
  132.                 YmodemFileTransmit::status = StatusError;
    5 D* ]4 ~% p4 t; g7 P  \

  133. # M% J+ a8 g3 M8 H, B. C
  134.                 writeTimer->start(WRITE_TIME_OUT);
    0 j* G) M  |: A8 q2 O6 I% K
  135. " r5 T; M3 ^: e, g& J, L
  136.                 return CodeCan;8 ^. z" W! F" x# N) T
  137.             }: h$ j  s, ^9 C5 e! d
  138.         }
    ! ?1 l0 Y! D1 I/ _) q1 ^: h
  139. - O6 O' i: z6 T4 H3 ~
  140.         case StatusTransmit:
    " @8 q2 }4 T# d
  141.         {( ?3 U) |( D* b
  142.             if(fileSize != fileCount)
    6 Q0 I) g1 H4 t+ o
  143.             {( m, Y6 j7 b. J( H
  144.                 if((fileSize - fileCount) > YMODEM_PACKET_SIZE)
    & e# Y# |( X- K% ~
  145.                 {
    & X$ {6 Y* q/ v
  146.                     fileCount += file->read((char *)buff, YMODEM_PACKET_1K_SIZE);3 u. x" f8 t+ Y. R

  147. ( O/ n1 B3 P/ m& F. Q
  148.                     *len = YMODEM_PACKET_1K_SIZE;2 q5 w3 b4 y4 P
  149.                 }
    ; D* A  M  N- h
  150.                 else7 w9 _1 t$ E3 q4 U5 V
  151.                 {
    7 c' s* I8 Y' D" S* G. Z% x: {" T$ k
  152.                     fileCount += file->read((char *)buff, YMODEM_PACKET_SIZE);( b- y7 `) ^& h$ D& d/ L
  153.   \& X, k" W0 P" l: _8 J4 x# A
  154.                     *len = YMODEM_PACKET_SIZE;
    ( i) y) h) o( l- K9 p! Q
  155.                 }
    7 q# S  P. e( `) h7 N1 d1 p

  156. & {! E. h. Q7 l# o7 ]
  157.                 progress = (int)(fileCount * 100 / fileSize);
    5 |" C7 B# F. H+ K1 N
  158. 5 u) T  ?, R; G, x
  159.                 YmodemFileTransmit::status = StatusTransmit;9 E0 Y% u- o, m  Q2 S

  160.   @, |% N$ e  ]
  161.                 transmitProgress(progress);
    + B" d7 ?( y0 y' A; X
  162.                 transmitStatus(StatusTransmit);
    2 S& x' O1 L, l( ^: x- h

  163. 8 a. G  W9 p$ V, D9 D
  164.                 return CodeAck;, O% F' r4 {( W. V: j6 ]
  165.             }" j* U6 h5 t0 j
  166.             else$ `  X9 j- k; h) ?+ P( {- ~
  167.             {
    . N2 B: V& z1 S9 Q9 \6 f0 F. ?
  168.                 YmodemFileTransmit::status = StatusTransmit;4 |# b* t. X$ d0 h  y5 w! L$ c1 p' k) C

  169. " ^. F1 z& v  ^( w" J3 ]
  170.                 transmitStatus(StatusTransmit);
    6 l9 S- A* ~6 S/ @$ k5 t

  171. / ?( _5 w3 T* M& e
  172.                 return CodeEot;+ b( |! x) }: `1 w
  173.             }
    2 Y5 p* {' d/ q) A
  174.         }
    7 n0 w0 V/ {6 Q3 ?

  175. 2 ]) d3 f# d: t: b9 |6 Z
  176.         case StatusFinish:
    1 D, a  B( U. f' w, R0 a1 T) @. H
  177.         {0 Z9 n+ P  d3 G
  178.             file->close();2 R+ B4 @' m2 B5 m* c6 |0 p+ j( n1 k

  179. & r$ G5 b( U- Q. h* {. Z- U
  180.             YmodemFileTransmit::status = StatusFinish;
    . P1 `! I  Q5 y  |

  181. 0 }, d/ ]+ v: F' a! l) t$ k
  182.             writeTimer->start(WRITE_TIME_OUT);
    ) n+ @0 |. T! M1 K1 c& y( _

  183. - S, p# m4 I( _" N* _& A& ^
  184.             return CodeAck;" C2 t* r2 b$ j
  185.         }3 g, Y' r# E2 z7 ]6 j; Q
  186. $ _. U5 j+ N+ Q/ }0 u
  187.         case StatusAbort:; V) c3 {% L3 n) b! A
  188.         {4 _3 r+ g$ Z( b% ^
  189.             file->close();
    ) X$ u3 Y; n; f
  190. / v+ U1 k; S" ~2 P3 J( ]
  191.             YmodemFileTransmit::status = StatusAbort;
    : T; K' S8 o4 Q1 a
  192. 3 f9 T  j$ b  @- v' E: A0 V& I
  193.             writeTimer->start(WRITE_TIME_OUT);4 o$ [$ x% U; i3 {

  194. 8 D& a8 c+ X6 ~' Y1 ~
  195.             return CodeCan;5 E' f6 m& Y/ G- r/ W' M
  196.         }
    % K2 k4 _" D6 f! T- N
  197. & ]( U/ e. z4 u
  198.         case StatusTimeout:
    + @) z% n) U  L5 Y  Y
  199.         {- e  t" w3 k0 e: k6 n, G
  200.             YmodemFileTransmit::status = StatusTimeout;
    1 N* @# z+ ]  `( G' \7 _
  201. 1 E1 G' t- P$ A7 V# A  n
  202.             writeTimer->start(WRITE_TIME_OUT);
    % n6 {0 e& y, [! M: V$ u7 L( P

  203. : r: B/ b: g0 [! i5 }# D
  204.             return CodeCan;
    % j# o# n8 ?0 S( Q
  205.         }
    & B1 w7 Z7 _7 a7 b: I

  206. , j; p9 Q0 M/ j8 _0 u* \8 H
  207.         default:
    ! V: h5 k6 l9 L
  208.         {
    ) m4 [. s6 K+ z2 q9 P9 p+ a
  209.             file->close();
    / s7 C; G. K( G3 x3 s, \

  210. ! `+ w: q  M# [. i( t- {
  211.             YmodemFileTransmit::status = StatusError;
    0 L1 r2 j/ m+ @6 ?% f* t! r0 x- V
  212. 0 K5 \% o6 l/ D# i
  213.             writeTimer->start(WRITE_TIME_OUT);3 n# `# S0 M7 y3 N9 o7 A" B+ G

  214. 6 k5 |$ `/ E! h. L
  215.             return CodeCan;( I8 R9 k8 `& k' a- E+ F! L7 G4 t' @
  216.         }; o5 a* {* v$ ?8 U1 ~! D* b5 f
  217.     }* I. @4 `' J9 ~) F
  218. }
    5 d' q) t9 H0 [5 I( Y9 i2 R

  219. 7 X$ W( }& H0 r# f# Z0 h
  220. uint32_t YmodemFileTransmit::read(uint8_t *buff, uint32_t len)8 h: k$ B0 `8 K3 ~- [& _
  221. {
    4 t1 z# i" Z. B' z: j
  222.     return serialPort->read((char *)buff, len);
    ; K& y( n8 c8 ?+ _( h* x
  223. }
      V0 D' z$ S: W( ~6 W. S4 L/ \

  224. 3 P+ i3 Y" f* f, P
  225. uint32_t YmodemFileTransmit::write(uint8_t *buff, uint32_t len)
    4 G0 y/ q8 z6 Q" C% ^4 |/ @0 E
  226. {; v+ s$ r) t& ~  ?
  227.     return serialPort->write((char *)buff, len);# ^1 G, w: Z2 G7 A8 _: }
  228. }
    - ~. I, k+ V3 L0 x2 ^0 X+ c
复制代码
8 O" X/ Y7 `7 D$ M+ Z

0 ^. W2 E7 ?- U9 @7 a6 {# a6 _  s9 L
4 k. ]4 u" O3 B% K+ t
9 m2 b2 a1 H# A2 c9 V2 e! M. U- @$ v7 ?+ I+ u& f. N
XinLiYF 回答时间:2018-3-6 22:32:05
      widget.ui文件
  x$ u" _$ T: @( j6 D2 I. G# j
  1. <?xml version="1.0" encoding="UTF-8"?>
    8 v) T3 ]$ @9 G: E# t
  2. <ui version="4.0">
    . O7 s% R; l7 T# C
  3. <class>Widget</class>+ O( g. m& f6 q$ C& T+ g+ }
  4. <widget class="QWidget" name="Widget">
    $ a/ i0 e$ [/ Y1 F- v, S1 s
  5.   <property name="geometry">/ B+ t/ H( C- a+ V' Z6 e  c
  6.    <rect>" F0 ^# ]( w. Q# @# X
  7.     <x>0</x>4 ^* ]. r  k# L1 p+ l
  8.     <y>0</y>
    - b; f' n) T! F1 t
  9.     <width>444</width>7 G: b/ @7 s4 _2 r; R
  10.     <height>255</height>. W2 w* k% h8 N* g: P) Q( j/ \
  11.    </rect>
    2 A  K; a: i( j* A  x+ W  x
  12.   </property>0 w" c6 I* w  i; {! d8 ?- S
  13.   <property name="minimumSize">! e. R0 u# d1 k
  14.    <size>
    3 U4 Y. ?& U" v2 u
  15.     <width>444</width>
    * p, w* c% B) T& ]) L
  16.     <height>255</height>
    1 U$ d& L* ]% j5 G
  17.    </size>5 m( ~. n$ ?! G6 P4 r. L7 k
  18.   </property>8 b* P; j* K6 Y, K
  19.   <property name="maximumSize">
    3 s2 f: q( `5 Q) Y! g
  20.    <size>
    ! `* Z4 O% q* }5 r
  21.     <width>444</width>) B) b* e4 z- Z. `  w# Z. {
  22.     <height>255</height>
    ! ]& e5 x2 R( t( r* Q1 J& `( O
  23.    </size>
    . f9 \' c# Q- b3 a
  24.   </property>4 @7 R" t8 f) k) }. Q- C' {' j
  25.   <property name="windowTitle">
    ! h) H  K8 p: m
  26.    <string>SerialPortYmodem</string>
    : I* [' }2 U) R  q1 M9 t. G4 V
  27.   </property>
    ' A" I  r* M( H( g5 ^# |2 k
  28.   <layout class="QVBoxLayout" name="verticalLayout_3">: O6 ~7 ]- |) T/ s% T
  29.    <item>% D$ _3 x8 R" {  y" |; s$ ~
  30.     <widget class="QGroupBox" name="groupBox">
    . ]4 V& t$ `+ C$ o  x! Y5 B" ^. H
  31.      <property name="title">, @, h1 ?4 S* H( b. t
  32.       <string>串口配置</string>
    1 n  E/ _; x# O8 X. @( @
  33.      </property>2 x/ x5 _+ P# v) l1 X
  34.      <layout class="QHBoxLayout" name="horizontalLayout">- C6 f% `5 t% Z3 q" L: j
  35.       <item>
    * T: w7 Q9 y! Y/ N
  36.        <widget class="QLabel" name="label">! A* ]( K! X( B7 w4 n; J
  37.         <property name="text">9 i# `* E- V6 ^
  38.          <string>端口:</string>
    $ [* V8 F: G) |$ C
  39.         </property>3 j" Y, I! O0 ?4 {* U
  40.        </widget>
    * g5 F( Q6 h: o# H2 p
  41.       </item>: m, c# r7 _6 w4 B) S
  42.       <item>
    % F) b2 E0 V# l6 {* O
  43.        <widget class="QComboBox" name="comPort">
    - g, a# }* s% e4 J2 V
  44.         <property name="maxVisibleItems">7 Y: A( `; s3 {# k
  45.          <number>12</number>& T* `1 H+ D7 Q1 k* l) z
  46.         </property>
    & [, f, c- o0 L
  47.        </widget># I: L. c) W# ~0 O. m
  48.       </item>
    ( b; u. V6 t) y# A' I; E1 @4 j- f
  49.       <item>
    ) b- d8 f( B1 ~' R* r" U' H
  50.        <spacer name="horizontalSpacer">
    * @( k/ Z* j* F
  51.         <property name="orientation">
    * T3 S1 u, X' F8 ^) k0 j- w/ I6 b+ ?
  52.          <enum>Qt::Horizontal</enum>' o. c5 ]; V% m2 X( a
  53.         </property>
    . ]% Y& y: \: \* x
  54.         <property name="sizeHint" stdset="0">6 ?7 B# Y, C% S
  55.          <size>
    ; ^! w/ N& l& u3 A2 Q: G3 ^
  56.           <width>40</width>
    * L. E) Z4 d8 B$ U! j2 h
  57.           <height>20</height>
    / E5 ^1 k, R1 m9 p) c  l* X; p5 W0 @
  58.          </size>8 `% {1 }) H% l; J
  59.         </property>. F3 `( K* N& B; ]! }$ g" J! ?
  60.        </spacer>
    6 E( e2 n) f, R; K2 i
  61.       </item>
    ; f. ~# s" L' v7 R! U. H2 \: ~: o! p
  62.       <item>
    . f- H( ~1 T6 g
  63.        <widget class="QLabel" name="label_2">
    9 B. ]4 b4 b" I) @5 M
  64.         <property name="text">
    + H" C& ~' b1 F2 f) X2 o. p: k
  65.          <string>波特率:</string>
    7 K! P, Y# y0 l7 A
  66.         </property>
    : F6 M' g+ Y% ]$ _( Y
  67.        </widget>
    $ x0 N: I! S# L  R& U$ |6 q9 n6 I
  68.       </item>; j: g2 a2 Q( ?  X  L7 Y
  69.       <item>
    - ^" i- S1 p; \& k" z# d3 l4 Z
  70.        <widget class="QComboBox" name="comBaudRate">" B& o* b* i3 d) r0 o
  71.         <property name="currentText">( h8 I: w: ~3 Y" F$ D% n/ R
  72.          <string>115200</string>4 P4 f' N) p# q! T. a$ d
  73.         </property>
    , A2 X' f) R& Z6 l  q
  74.         <property name="currentIndex">4 m, \2 B7 g: \1 F
  75.          <number>3</number>
    0 V, w0 |2 G% _6 R& _9 `
  76.         </property>
    , e; h: S/ D2 \0 r  L! q
  77.         <property name="maxVisibleItems">
    ; {4 J/ C- o0 N$ \' ^( w8 m, m; _1 V
  78.          <number>12</number>
    : B& O, Z" {2 b, `; [" G0 L
  79.         </property>
    . t9 F* t! ^  o% }' Z
  80.         <item>& T" Y0 Z! n8 L# A! W1 o9 f2 }' A: y- n" Y
  81.          <property name="text">+ R4 t! t4 ?' I1 i  F4 H$ A- B
  82.           <string>921600</string>
    4 d( Y) y; \+ l( J# G) J
  83.          </property>4 x; P, S+ b1 e( R& s' ~
  84.         </item>
    : q1 y8 H1 A3 Y; `6 h' o# w
  85.         <item>
      ~1 V4 M: _1 p4 K3 I& \
  86.          <property name="text">% M- X$ {3 j' r+ Y1 r% W& E
  87.           <string>460800</string>
    - N5 X0 e% N3 \) u
  88.          </property>$ i; \, v  C6 G; t% w- }" D; C
  89.         </item>
    3 T& t2 `. q; J- i  \
  90.         <item>! J, B8 U4 R4 I# U
  91.          <property name="text">
    * i/ Y, U1 k6 }1 c! V: y8 n1 p/ J
  92.           <string>230400</string>9 P. ^' P3 P' ^" `8 c7 C" t/ x
  93.          </property>; ]1 N# x4 y9 [( Q
  94.         </item>
    " ]) f+ e! t; J
  95.         <item>
    ) y3 k) d4 N6 X. F
  96.          <property name="text">( {) k! q# @& M9 p" f8 H
  97.           <string>115200</string>
    & I9 o+ ~+ V' X1 m
  98.          </property>
    . A6 q! j! r8 V  y' \/ O
  99.         </item>
    - f2 I* v! f+ n! e0 Y
  100.         <item>
    " t& ]( O! d  ^" q7 t/ D  B# X) p2 I
  101.          <property name="text">. ^* M8 L! K) M  z/ O
  102.           <string>57600</string>
    , D. |- `0 R) ^. P  G/ U
  103.          </property>" ?& }1 X1 R  P8 l
  104.         </item>
    1 a1 u. w' R! a! d& V
  105.         <item>4 x/ A3 n$ f8 _8 C# H
  106.          <property name="text">
    0 `0 _1 e/ d1 x1 G% e0 p+ P* s
  107.           <string>38400</string>
    & M8 q4 H# L# k+ s: e! k# Y# Q
  108.          </property>
    1 S  b$ F- C! ~, I" {7 Y
  109.         </item>
    - X$ Q9 C; Z( P  T# S: r
  110.         <item>
    ; h; }, A# k, R1 U' g! X
  111.          <property name="text">
    0 K/ {; u4 l' E4 O2 m5 w/ Q
  112.           <string>19200</string>
    2 ?* B7 x& J8 V7 x3 N0 l
  113.          </property>
    9 `- n3 h6 F  y. _# c) T# j
  114.         </item>
    1 B# }: J( E" J" E, e1 G6 {6 D
  115.         <item>& Q, s  J+ k$ J) m
  116.          <property name="text">
    ) |8 m" j3 V( u2 }7 S8 Q
  117.           <string>9600</string>; D4 N  {: w( ^3 {# c( _
  118.          </property>/ _5 z  o! [  t
  119.         </item>3 F3 H$ i. k7 R3 |4 v( g
  120.         <item>7 T0 O  N8 C6 e' u& ?7 N; B
  121.          <property name="text">* i, J9 C3 _* \! D, T# M  h: O
  122.           <string>4800</string>; p) z, |! V' C. n& N
  123.          </property>
    $ \( N; d/ K7 I+ E
  124.         </item>
    1 z; _( B0 b7 j, [  g$ Y5 N
  125.         <item>
    + h) j7 u9 z0 q3 P" v8 ]
  126.          <property name="text">
    # ?) A3 |1 G) q8 m# N" M, |
  127.           <string>2400</string>" E. A' f9 C- s8 P; o: F
  128.          </property>& |; E2 j; \) _( ]3 `7 H2 f
  129.         </item>
    ) L3 U' L/ c' `/ k0 m
  130.         <item>: c, a) N- _+ m0 ]
  131.          <property name="text">
    " V" G) P& I2 ?! O& p* S
  132.           <string>1200</string>! S' `( F& H: @$ Y# i  J& M5 V, K) y
  133.          </property>. H1 _5 N; G3 ^4 H* T
  134.         </item>, Z3 L3 S( W: D
  135.        </widget>$ w9 u% e+ X% W2 Q2 @: `* n" s( j
  136.       </item>/ e0 [3 e  q- W+ b
  137.       <item>, E4 N( S+ o% V8 c1 W0 k) S  K
  138.        <spacer name="horizontalSpacer_2">0 q5 Y3 t" G- z' N
  139.         <property name="orientation">: F- u6 ^: ?4 ?
  140.          <enum>Qt::Horizontal</enum>
    # T4 F0 v% v' y: S- p4 E4 y- [/ s
  141.         </property>+ k' `; ?4 q; m) ~" r7 y& R( l$ p
  142.         <property name="sizeHint" stdset="0">
    7 P9 ~1 I! i7 D
  143.          <size>1 [; l" ?& J+ j+ W% \9 T8 \3 X
  144.           <width>40</width>
    - w; J  @% F* n7 H8 C+ V. S3 a
  145.           <height>20</height>& b7 ?5 w. Z1 _- I5 z' P
  146.          </size>% \) w. U  b$ M; k2 D$ L
  147.         </property>
    - B7 I( a$ q1 i3 s9 e' R% j' b) {
  148.        </spacer>9 I, d4 u/ X. m/ w* ]5 |% F% j
  149.       </item>
    * d+ j9 Y! W  b7 a0 D
  150.       <item>
    1 S# l! b) D; v6 d
  151.        <widget class="QPushButton" name="comButton">
    + |% L* X' X' |$ Q
  152.         <property name="text">! R! l( ^1 U' n- @* o
  153.          <string>打开</string>0 O$ o& ~4 Z0 {* \4 d
  154.         </property>
    " @( J# k7 H; i, l" V$ k
  155.        </widget>$ m; Q. r. t" y: R& B3 m- `
  156.       </item>
    & z, ?0 q& L2 t6 x* ~4 n
  157.      </layout>3 f, y) N4 l% R. U% J
  158.     </widget>. S9 l! d- o1 A8 e8 J
  159.    </item>
    1 F* e( ]- j  B& F0 R2 i
  160.    <item>- l% o: ^8 k$ n1 I. o
  161.     <widget class="QGroupBox" name="groupBox_2">) B. ~) X7 ~* N- V
  162.      <property name="title">
    / \; K0 h4 E. B. D; Z( o
  163.       <string>文件发送</string>9 ~9 j% c6 d2 ]! ^
  164.      </property>
    5 {% I* `$ D8 K( h2 @+ y
  165.      <layout class="QVBoxLayout" name="verticalLayout">
    ( R4 F$ l" b; ^
  166.       <item>
    : j$ M5 }6 T" ~9 r' w; L
  167.        <layout class="QHBoxLayout" name="horizontalLayout_2">1 v  a+ I/ E- N" m6 x) X
  168.         <item>
    / O" P; _& a$ L8 T" i
  169.          <widget class="QLabel" name="label_3">( F4 n, P* D. ^  k" ~' B
  170.           <property name="text">0 U) P8 ~: @' e! }" e6 [5 L! H) c
  171.            <string>文件路径:</string>; N# R( {, s9 M# e1 q' Z0 _( H4 G
  172.           </property>/ Y: E4 ]+ c% }6 a0 ~% {& P; H
  173.          </widget>! p" Z/ @0 X0 S/ ]. Z8 {/ M
  174.         </item>* J$ Z; ^% P, y0 C; W
  175.         <item>
      v& |7 c# W" p( @% H3 E
  176.          <widget class="QLineEdit" name="transmitPath">
    7 G1 D) K2 M6 X" m7 B/ N# j0 q
  177.           <property name="readOnly">
    ) f  G# W: u5 P' s6 A3 m6 ~. ~
  178.            <bool>true</bool>6 p+ l- Q/ A+ F( n* _
  179.           </property>' j: m1 P6 @/ T3 _: m
  180.          </widget>" k3 `, U5 {, d; s* x2 d+ E7 M9 q
  181.         </item>$ p5 G# F2 M. S# @* l
  182.         <item>* n  d* \; F0 G! y2 Z% c5 `; a; @
  183.          <widget class="QPushButton" name="transmitBrowse">0 _' R+ O+ Y8 u
  184.           <property name="enabled">  Z- \, _4 Q! z' t1 C- f: F7 g
  185.            <bool>false</bool>
    - v( Z2 L; q  |: a5 k+ z
  186.           </property>! I# e. J! [+ W) a) E$ U* R
  187.           <property name="text">2 u$ c$ V5 a3 P3 y$ H: L' b
  188.            <string>浏览...</string>
    0 ?9 d- H2 a  y
  189.           </property>1 \3 _% _( q  e: c$ {& Q
  190.          </widget>4 p# i: V' H+ R5 a
  191.         </item>1 |' q9 G8 M% B- K
  192.         <item>
    / ~- P. ]' [# ?6 {  Z: k
  193.          <widget class="QPushButton" name="transmitButton">
    4 y' x( \1 [4 G# C' v7 v( F6 p
  194.           <property name="enabled">7 K& J9 Z1 {+ j% d. S2 O2 n3 v% L
  195.            <bool>false</bool>' i& c2 x- U  Z
  196.           </property>
    ( I! ^4 G* V4 g5 t0 M2 J* z
  197.           <property name="text">
    $ M9 u1 \) I5 _8 S
  198.            <string>发送</string>" }- W# X; J# X( v" D) `) R- l% `; D
  199.           </property># T8 g9 v& M& C" o. S/ ^
  200.          </widget>
      n9 {" J: }. ]( f; r, b
  201.         </item>: ]& d6 u$ G* a4 L9 i" z/ r  @
  202.        </layout>
    2 K% M1 U& b6 ]' ^1 R/ _0 @
  203.       </item>1 l  o9 ^/ b& v  ~& d4 q
  204.       <item>0 z2 c# G) c- b% s7 |
  205.        <layout class="QHBoxLayout" name="horizontalLayout_3">
    & W% O3 K) k. n$ R$ F# o
  206.         <item>5 I; C" t3 [; S4 W4 n$ O
  207.          <widget class="QLabel" name="label_5">' Z- p6 q  w) _# ~4 Q( I" _
  208.           <property name="text">4 m- c8 g& e6 j# _. P% p' S3 U3 G
  209.            <string>传输进度:</string>- L6 [8 h9 d7 x1 I. [6 [  C- ?
  210.           </property>0 y' j' D) F! U6 ?- f: ?+ p. z
  211.          </widget>
    7 L" A* W! P- E
  212.         </item>* a* A0 O& U7 m
  213.         <item>0 K3 u) }% w: i- F' M
  214.          <widget class="QProgressBar" name="transmitProgress">
    " L. f9 z6 |0 x* }- M6 C: z; \7 Z5 c
  215.           <property name="value">
    " `; O/ J. C) u7 k" {1 W
  216.            <number>0</number>3 s+ c% x+ ^+ y0 E: l9 G$ ?5 y; c
  217.           </property>
    ' t- B+ a6 Z- I& J  q+ Z
  218.          </widget>
    6 ~) s  @* K' [. a! J0 d& x) T
  219.         </item>
    4 C. V( K! z3 N
  220.        </layout>
    ' p4 l  k& \3 z- ?, ]6 a
  221.       </item>
    1 P" H5 ~" F+ n! S" x& H
  222.      </layout>
    3 f# i( g* Z) r7 |3 N' {9 k
  223.     </widget>( f$ y' y% _" r+ ?& G) f6 F
  224.    </item># A* @" p. F" z7 ~+ ^1 H
  225.    <item>
    # O) n3 Q+ [" W' g( `' t3 q+ k6 a% D
  226.     <widget class="QGroupBox" name="groupBox_3">; h8 E( ^8 [0 U2 U8 L
  227.      <property name="title"># N- x2 M9 x  S; ?
  228.       <string>文件接收</string># \1 l1 x5 F1 L' g; u3 c
  229.      </property>5 j$ U/ x9 ]: y" e, u
  230.      <layout class="QVBoxLayout" name="verticalLayout_2">
    + c! e* `) G( }7 v2 c* H, J
  231.       <item>
    ! R% O3 F3 _6 m6 h& r- P/ j$ Q
  232.        <layout class="QHBoxLayout" name="horizontalLayout_4">
    + C9 H& _  B2 d  s) P& \
  233.         <item>' q6 |7 |  l1 z5 i" G
  234.          <widget class="QLabel" name="label_4">( i  [5 ]% s( v, |6 o/ q
  235.           <property name="text">2 s8 a7 {6 r) H3 W4 X+ s5 N
  236.            <string>文件路径:</string>& Y4 G3 i2 D# a0 i
  237.           </property>
    4 I6 F  a  q1 a% X
  238.          </widget>: |4 m5 G6 `* P( ^) v2 {
  239.         </item>
    9 W4 E/ d! j' B; k/ ^/ L% n
  240.         <item>
    ' U. l+ B, F! C. Y
  241.          <widget class="QLineEdit" name="receivePath">
    ' i' U; N, g+ ~& U" X) U# r- u+ L
  242.           <property name="readOnly">5 x/ x8 S2 U" \5 n- ^
  243.            <bool>true</bool>
    7 N# I$ {3 y7 f: g0 Q, o% J' a
  244.           </property>9 q, Z# r' A$ g; s1 z( E6 v
  245.          </widget>
    . Y) m4 b0 F8 z- P9 i
  246.         </item>
    2 C5 K. O$ y+ U
  247.         <item>
    ( n* ^) h( R  ^: Q+ P' m4 H$ H
  248.          <widget class="QPushButton" name="receiveBrowse">
      U% J3 g) o4 [
  249.           <property name="enabled"># Z. R; X5 I1 T0 s  d( D8 K5 G
  250.            <bool>false</bool>" @+ ?& G. q( x/ @
  251.           </property>
    , S/ x: k7 ]8 x+ ^. I
  252.           <property name="text">7 x& I* d$ U( _7 Z
  253.            <string>浏览...</string>
    / C- q: j3 [+ r& z. {% V4 }1 {
  254.           </property>
    8 D2 F8 Q5 b1 t
  255.          </widget>
    4 |5 Y8 p" d& c( l( x
  256.         </item>; S, H9 _1 L) \
  257.         <item>
    % A) k, w1 a7 M' C0 R! x
  258.          <widget class="QPushButton" name="receiveButton">
    6 [  Y2 F( F2 q
  259.           <property name="enabled"># t$ Y" n1 b9 o
  260.            <bool>false</bool>. h) b! A% n" \# {( j7 v
  261.           </property>
    7 L' z) c2 s7 R* D
  262.           <property name="text">
    9 d, B: O- t2 `) x7 |- L9 E
  263.            <string>接收</string>
    % n3 q- k' w' H- R/ @
  264.           </property>  `7 Z& g. X& E; k6 E
  265.          </widget>4 b- w6 Y5 U  G1 z) W. O8 I6 Q
  266.         </item>: Z+ f* [6 e( D! o4 I: J, s
  267.        </layout>, u1 w7 O+ A5 e7 p8 t
  268.       </item>4 B. @7 y2 r8 R+ ?+ }  b
  269.       <item>
    9 ]/ w3 P5 f: X- Y
  270.        <layout class="QHBoxLayout" name="horizontalLayout_5">
    ! ?1 y" C! ]# c; ~0 e" C
  271.         <item>3 t' q( f1 F. f" ]
  272.          <widget class="QLabel" name="label_6">
    2 {+ X, t7 Q' M' _; z9 C) G
  273.           <property name="text">3 {# x- P# _/ x4 w3 D6 g
  274.            <string>传输进度:</string>+ K. H# Q$ @& x! M+ K, N
  275.           </property>8 }2 ]2 e; }6 \7 @4 O
  276.          </widget>! `) `& y7 B8 \- u& `$ C1 {  z4 w; o
  277.         </item>
    5 t# ~, D6 G" c; S
  278.         <item>
    ) @) [- k! P* o$ D; r
  279.          <widget class="QProgressBar" name="receiveProgress">
    6 T! k0 z+ C2 i$ N* p+ t
  280.           <property name="value">5 |  Z0 N% ~4 {9 p. s/ ^9 r
  281.            <number>0</number>2 Y+ w! S1 i- I9 y& b
  282.           </property>
    ) {! w% t* q# L; g" U) a0 K
  283.          </widget>
    1 I7 s9 p& Y& `1 @  K- L
  284.         </item>
    * T! a/ c; c+ A
  285.        </layout>
    * @! l' C/ v2 J. p, J" b
  286.       </item>
    # D# }0 l: S& p! I5 G: K
  287.      </layout>$ q9 }( @# y0 \7 _/ P. p
  288.     </widget>- b  _' ~# t0 Z- d4 h3 b/ g/ f% p
  289.    </item>
    # t% C# B$ T$ d/ H+ j/ h
  290.   </layout>4 E/ L* U' l1 H0 }
  291. </widget>8 G7 f9 x2 H9 T; |: J; k
  292. <layoutdefault spacing="6" margin="11"/>! c* y; _1 U0 C
  293. <resources/>/ t7 t* w. x) b6 v3 P9 m* o
  294. <connections/>! \1 ^( M$ X# M7 H
  295. </ui>  c, U" y' Q# k5 q7 K, E# ?
复制代码

2 \# X2 P. |9 Q( y" E, c. U      widget.h文件8 [  S* [  D; d1 N
  1. #ifndef WIDGET_H+ w' Z! V* B8 t( m; f4 ?4 |
  2. #define WIDGET_H9 J3 E+ D* t& W$ Q
  3. ' ?; q! S: R: d* C
  4. #include <QWidget>; g9 @2 F0 P; L. w/ o
  5. #include "YmodemFileTransmit.h"7 M- e4 f# Y% i8 h% }# y5 J, p
  6. #include "YmodemFileReceive.h"5 D9 `5 _& x: A

  7. : i: o7 I( L- u( L+ `. o
  8. namespace Ui {; j: G4 }( o- O9 F! A( W- p
  9. class Widget;
    9 Y) n/ `' Y, C0 B5 [! @
  10. }/ ~3 F) @  {- W7 f/ |: w
  11. ; _3 q$ C5 {: }8 g% x
  12. class Widget : public QWidget9 o& m* u4 W5 g# ?) r
  13. {
    8 v. ^; w" e. P/ k
  14.     Q_OBJECT& K1 B# _3 ]( X# p) I7 V

  15. $ G8 a& m8 ~9 y2 V$ j: y) i  i# Z9 b
  16. public:4 h8 B  \( e8 c6 ^  U/ l
  17.     explicit Widget(QWidget *parent = 0);: \0 z/ E! E6 X1 f! W. H6 V
  18.     ~Widget();1 Y$ O3 x9 X; S# L1 t8 _( t0 \! i
  19. ' [9 \4 b( p: f& E. t, h  p
  20. private slots:% U4 ?9 d2 S$ s+ x
  21.     void on_comButton_clicked();& }( K0 r$ b# f& L- P
  22.     void on_transmitBrowse_clicked();
    . t- S' Y& T* n& x6 g& O# t0 O
  23.     void on_receiveBrowse_clicked();
    , g+ g" m* Z0 [$ v3 J8 I, }8 k
  24.     void on_transmitButton_clicked();
    0 v0 N# h& q% Z
  25.     void on_receiveButton_clicked();
    $ q- T, i# o9 z1 Y1 K4 d% R/ I+ g; c
  26.     void transmitProgress(int progress);( ~& S$ y6 U/ r( [
  27.     void receiveProgress(int progress);
    9 J; v1 g4 E8 ]7 f6 P
  28.     void transmitStatus(YmodemFileTransmit::Status status);' y$ m8 K2 I" O( X) |7 z; s
  29.     void receiveStatus(YmodemFileReceive::Status status);( b4 V  _' K4 K6 i$ Q

  30. ! [/ b! S2 d* |9 F
  31. private:
    ! N2 ?1 u& H: G: T/ w. j
  32.     Ui::Widget *ui;
    1 N+ I  K; d, n
  33.     QSerialPort *serialPort;
    6 n+ }0 z) B. n* q& i
  34.     YmodemFileTransmit *ymodemFileTransmit;
    , Z! B8 K6 N7 n4 @6 N( g/ H/ L3 T
  35.     YmodemFileReceive *ymodemFileReceive;
    7 }0 ?- y" u9 i* Q
  36. : Y( C) l9 X5 V6 K$ a6 m9 W
  37.     bool transmitButtonStatus;
    ; F- g( q' S8 X2 k3 b1 h
  38.     bool receiveButtonStatus;) }) J: t; O+ E' K* H( w: `) d
  39. };
    * w  O5 k8 l& u& E! t
  40. 6 `( z4 l& }/ G. o
  41. #endif // WIDGET_H
    0 l" |3 n$ t0 R+ V+ o+ _6 }* V7 w
复制代码
- x& Z* I  \3 A
      widget.cpp文件: J3 l- B) R' Q4 c* Z; s
  1. #include "widget.h"4 K5 |- F1 ~7 i: y
  2. #include "ui_widget.h"# N4 ]  V3 ~: H
  3. #include <QMessageBox>; n- I9 x2 O+ ]+ H( N/ b& P
  4. #include <QFileDialog>/ }3 A, [- a" M4 n: X& M1 ?$ _) C
  5. #include <QSerialPortInfo>
    & v9 v2 R! @$ w) B& o8 [) a5 n
  6. 8 V& m4 I+ h% G2 l
  7. Widget::Widget(QWidget *parent) :! Z; z. p4 @# ^0 x- Z9 G, A7 s
  8.     QWidget(parent),
    $ f& U. A/ a6 J
  9.     ui(new Ui::Widget),
    % K5 ~+ [6 C% h; K/ t6 l9 S
  10.     serialPort(new QSerialPort),
    1 J1 C- Z1 h. I2 n
  11.     ymodemFileTransmit(new YmodemFileTransmit),
    ! ~5 h. m( t8 Y. @) i: x5 i
  12.     ymodemFileReceive(new YmodemFileReceive)5 [) {, X+ O# N; s$ r- T2 a
  13. {
    & g0 R$ D; \7 _, P
  14.     transmitButtonStatus = false;' ~& _9 t9 d% V! {
  15.     receiveButtonStatus  = false;
    " g3 A- ]' H3 o- O. J& x8 E

  16. 7 g  S4 _% R4 s
  17.     ui->setupUi(this);
    " x% }$ S' H) W- L& q& N

  18. # c! e. B& X7 l% G# _4 V/ ?
  19.     QSerialPortInfo serialPortInfo;* J( w6 W- z0 a# p4 t7 R2 k: \! M" d

  20. ( {+ \5 Q( U* r
  21.     foreach(serialPortInfo, QSerialPortInfo::availablePorts())4 t- }1 d' K' H& E& Q$ ]
  22.     {( I/ d6 v3 ^# W; [/ f: J
  23.         ui->comPort->addItem(serialPortInfo.portName());
    & h+ o! _( f8 t( X) U  j# K% z
  24.     }
    3 U0 l5 f. X( o+ H$ F9 T4 f% X2 {
  25. $ C/ }: p0 e/ A" A+ s8 J. c! r9 V
  26.     serialPort->setPortName("COM1");4 L7 I$ U# M) E5 V
  27.     serialPort->setBaudRate(115200);  h' }$ ?* A2 Q; t$ F5 m
  28.     serialPort->setDataBits(QSerialPort::Data8);
      j" S' c  h* h' N% }. ?3 l
  29.     serialPort->setStopBits(QSerialPort::OneStop);
    ) `: a5 x& z* W
  30.     serialPort->setParity(QSerialPort::NoParity);& h. O5 ]" _0 K
  31.     serialPort->setFlowControl(QSerialPort::NoFlowControl);
    & I# Q1 \( z8 N3 q0 \

  32. 3 T5 @$ @! w$ @2 @1 |% z: w, _
  33.     connect(ymodemFileTransmit, SIGNAL(transmitProgress(int)), this, SLOT(transmitProgress(int)));
    2 R- q9 X: j% E
  34.     connect(ymodemFileReceive, SIGNAL(receiveProgress(int)), this, SLOT(receiveProgress(int)));
    7 n6 b( B) P+ C+ F9 D% a
  35. ' N* v5 P2 l6 v, W# D, R" u9 ~
  36.    connect(ymodemFileTransmit,
    + L9 V4 F1 i& k! C% Y; g3 Y% D8 a
  37. SIGNAL(transmitStatus(YmodemFileTransmit::Status)), this,
    " u4 @0 l, u. x, N4 C) e# P
  38. SLOT(transmitStatus(YmodemFileTransmit::Status)));, u( w7 t! v/ y; b
  39.    
    # [- a$ ]! s: g- e, G7 X
  40. connect(ymodemFileReceive, 7 h0 E4 v6 X' |
  41. SIGNAL(receiveStatus(YmodemFileReceive::Status)), this, . C# \# f7 X8 [! R# e
  42. SLOT(receiveStatus(YmodemFileReceive::Status)));, Z) x6 M: ?) ^: o  S- B
  43. }
    ( I" D3 x+ O7 N! W" z! h* I

  44. ( z. q4 B. \7 j- g( p3 ~7 N" p
  45. Widget::~Widget()/ t7 T% i3 J) s5 Q& h# r
  46. {
    ! ~$ O/ A. Y" J# G# N5 x
  47.     delete ui;
    ; S* ~5 ~" V; f" Y1 o) q+ Y3 F
  48.     delete serialPort;
    # w+ C: `# K1 T/ ?
  49.     delete ymodemFileTransmit;
    ' U) M5 T% B. X
  50.     delete ymodemFileReceive;
    " @* g" Z7 F. i
  51. }
    ) H4 |. E9 e" K- m' H8 @! W5 _+ D- p
  52. 3 W+ J) o5 W. @% j  g# T
  53. void Widget::on_comButton_clicked()) H3 I% j9 p0 P2 S9 |
  54. {* X) W5 d; X, l- x6 Y
  55.     static bool button_status = false;- ?2 G8 Y2 R2 i' p5 }% @
  56. 1 h/ G0 ~1 B4 b% Y; p
  57.     if(button_status == false)
    + C; X  z1 W8 q+ n2 ?( R
  58.     {
    6 F  p( U8 s- ?# ?0 {$ w  m
  59.         serialPort->setPortName(ui->comPort->currentText());( D) E) x" f/ a0 X
  60.         serialPort->setBaudRate(ui->comBaudRate->currentText().toInt());" K, [7 p' Y) y+ l$ C

  61. 3 |) R( ]: u5 w. T1 a" `! u/ k. ^
  62.         if(serialPort->open(QSerialPort::ReadWrite) == true)
    * b1 Z5 t8 @, t; |" N, r4 _2 p/ i
  63.         {
    ; R5 O$ I. x! y+ p- F
  64.             button_status = true;
      S$ H! K, |$ n; D  a6 A  J
  65.   t  s, E# {6 l
  66.             ui->comPort->setDisabled(true);, u. j9 V9 P/ e2 B' {# R5 H$ j% l( \
  67.             ui->comBaudRate->setDisabled(true);
    ( ~$ b! _" a8 D" P, s
  68.             ui->comButton->setText(u8"关闭串口");7 r6 D* ?) @1 V6 @8 v2 \% |

  69. % j: m- s$ s" u% E8 `6 h5 C
  70.             ui->transmitBrowse->setEnabled(true);% t; \* s  I9 g7 ?- S4 X0 {! d
  71.             ui->receiveBrowse->setEnabled(true);. d) E0 B: r3 J3 ~7 o

  72. 9 @& |5 L8 }0 J; g5 @
  73.             if(ui->transmitPath->text().isEmpty() != true)
    ( C! K+ S  ^/ _- e0 |0 f
  74.             {3 h. u$ b5 d9 s' P( ^
  75.                 ui->transmitButton->setEnabled(true);2 D. I' M8 \# ]# t5 D
  76.             }
    , |8 ]: @( L8 k% b9 h; |& B! K% I- }) T

  77. ! p! R* O* ^1 q1 [% a3 W7 @( f
  78.             if(ui->receivePath->text().isEmpty() != true)
    1 v0 }7 E8 a5 p+ Q+ B  r) F
  79.             {6 }. _  P- q% K/ M7 `+ d6 x
  80.                 ui->receiveButton->setEnabled(true);6 b1 |8 y% R$ k! I$ G" \
  81.             }
    # c0 f$ j0 N- P/ |( C
  82.         }
    $ _* P' O9 ?9 x6 d
  83.         else0 v) W5 u: A" d0 l
  84.         {
    . O8 @3 ~/ v2 Q1 p
  85.             QMessageBox::warning(this, u8"串口打开失败", u8"请检查串口是否已被占用!", u8"关闭");
    % @2 N9 T; l) K5 j6 u6 {
  86.         }
    2 Q7 W$ g0 a; x" t' }5 U9 X# H. X( T
  87.     }
    7 E5 e" @: e9 r) Y; M
  88.     else% u$ s3 E$ p, f4 t" a
  89.     {
    9 o* `3 t% M+ E) q0 A# l2 K( q
  90.         button_status = false;
    $ H: N+ c' Q. R& {
  91. ' K: J3 [# ^) l- b) j
  92.         serialPort->close();
    + o+ j0 F; Z# ?0 A
  93. 7 B; |! b, b1 x
  94.         ui->comPort->setEnabled(true);
    # ?7 U7 A- h5 B3 A0 V
  95.         ui->comBaudRate->setEnabled(true);
    & k4 K) I+ u  [) p6 T1 H! Z8 ~
  96.         ui->comButton->setText(u8"打开串口");
    $ H$ r2 l# w" @. ^$ q; I
  97. : \2 x) J: K0 k
  98.         ui->transmitBrowse->setDisabled(true);' J8 |( U7 b+ L8 H+ n, p* n9 g8 ^
  99.         ui->transmitButton->setDisabled(true);
    $ j5 f1 x* I- j0 h$ J! t

  100. 2 N  j$ @4 G: A; l. s
  101.         ui->receiveBrowse->setDisabled(true);
      u1 A) y- D$ r% h1 _6 H+ g5 j
  102.         ui->receiveButton->setDisabled(true);! Y7 o- l7 V: L0 r. d+ e
  103.     }. X: v( Y3 n/ l8 v7 O9 J
  104. }
    3 Y* k: w- _0 u" x

  105. 9 @: p$ f$ E( ~3 I! g: U
  106. void Widget::on_transmitBrowse_clicked()" H2 N& s% L& i% J! U8 B& ~4 f6 o: N
  107. {
    - W3 [/ r, C4 g% F3 i7 R
  108.     ui->transmitPath->setText(QFileDialog::getOpenFileName(this, u8"打开文件", ".", u8"任意文件 (*.*)"));
    % b+ b4 w: ]7 O7 `

  109. 2 _1 U( J1 ]4 Y; N
  110.     if(ui->transmitPath->text().isEmpty() != true)
    1 v/ w- X, I1 ~+ s
  111.     {
    ' |# k! E. u- E) J4 W# h* r+ f
  112.         ui->transmitButton->setEnabled(true);6 {) Z4 U2 k% {6 ^6 `
  113.     }
    5 r& L$ |6 O4 ]8 l9 R! o6 _
  114.     else
    8 h# p# \& ]  q9 g: W% x% f
  115.     {$ i' A: h6 s4 ~% E
  116.         ui->transmitButton->setDisabled(true);
    8 _2 y; K8 Y6 Y$ t7 |: E6 z
  117.     }# ^3 j/ k0 f7 y7 m: [2 f
  118. }
    + D4 U, e9 w' m* M: I4 k
  119. " P; t# I6 x+ v
  120. void Widget::on_receiveBrowse_clicked(); K, Y# t/ ?3 f8 o+ n" E. n# w; I
  121. {. H1 ]; q- W& ]
  122.     ui->receivePath->setText(QFileDialog::getExistingDirectory(this, u8"选择目录", ".", QFileDialog::ShowDirsOnly));
    & [  D6 C. E0 `5 y8 b& }' o: H* X
  123. 2 S" s: N& @1 I  G
  124.     if(ui->receivePath->text().isEmpty() != true)* |' q/ ]3 _4 w% y
  125.     {' n4 i) b/ v- c5 ^1 p/ d
  126.         ui->receiveButton->setEnabled(true);
    0 N" W+ l+ x+ Z3 c# _0 T) D% B
  127.     }. U" I: [" _2 w( N" I
  128.     else; @/ m# x3 ?6 S  v
  129.     {; e" z1 [, a  r
  130.         ui->receiveButton->setDisabled(true);
    " F6 F3 @1 J) G2 [0 {6 v
  131.     }5 a/ T% J2 O, H( d9 f6 p
  132. }$ ?: n. X+ T+ |3 s: D! w
  133. : D$ }; D; D, |) a4 q" T7 X
  134. void Widget::on_transmitButton_clicked()
    + o( v$ K2 M, V* \% I
  135. {$ d8 S- E) v% ~9 W5 {) p
  136.     if(transmitButtonStatus == false)% B, d! \7 q7 G. Z: F- P
  137.     {+ j. e' i/ z" X/ |3 T
  138.         serialPort->close();+ ~2 z2 f7 D4 K7 L. r% B

  139. " D: V! p1 }- u$ G4 c* M
  140.         ymodemFileTransmit->setFileName(ui->transmitPath->text());
    : M! E2 H1 B  }
  141.         ymodemFileTransmit->setPortName(ui->comPort->currentText());$ v. P: ]* R# P; ~
  142.         ymodemFileTransmit->setPortBaudRate(ui->comBaudRate->currentText().toInt());
    " [/ {3 T5 A7 J
  143. ; W7 s* y% ^0 o) ~' J
  144.         if(ymodemFileTransmit->startTransmit() == true)/ U; ~0 R9 n5 A6 \
  145.         {5 ?% ^( J- Y$ M. Y% d
  146.             transmitButtonStatus = true;# |4 t" O7 C- M. L; g0 B& Q
  147. / ?+ y8 k; N# H6 \, m$ Y2 c
  148.             ui->comButton->setDisabled(true);
    6 S; o$ u% x, S4 M3 v; c
  149. 3 j7 p# {  }" U% v; B/ ]4 Z
  150.             ui->receiveBrowse->setDisabled(true);
    2 t2 [5 [# z5 [
  151.             ui->receiveButton->setDisabled(true);
    4 n! E) r' t/ t( v, @

  152. 5 c, s" c9 y4 B1 i- c9 \
  153.             ui->transmitBrowse->setDisabled(true);& H* E0 e4 o5 m1 k' q, @
  154.             ui->transmitButton->setText(u8"取消");
    * O$ |& ~+ n* m. X4 e+ {
  155.             ui->transmitProgress->setValue(0);. |: N( k6 J( q: m( N# j, ]
  156.         }
    1 t2 f4 C: Z. H4 [6 T
  157.         else
    , x3 O" y4 N& U* N; n( C1 @/ f
  158.         {3 l1 F5 N) i, ^5 o: N
  159.             QMessageBox::warning(this, u8"失败", u8"文件发送失败!", u8"关闭");
    4 ?/ C4 l1 |8 M' h
  160.         }- N0 @3 A) d# R; V$ m* x# S
  161.     }
    - b# _: D6 z- [
  162.     else. u5 \, B5 |$ A; w2 t) q* I
  163.     {" I" h2 t  F9 W' }5 m- N
  164.         ymodemFileTransmit->stopTransmit();
    ; a4 }0 d2 a+ a
  165.     }( L! Y1 y5 }1 D* l6 W* D
  166. }
    ( d7 W1 d. K. i9 Q; \8 d( g9 H

  167. , F- n, j* z/ f% G7 V. i
  168. void Widget::on_receiveButton_clicked()
    8 e, I$ d& E0 }; Z: c
  169. {
    0 r9 U( B: k2 F. M# L$ m' ], v
  170.     if(receiveButtonStatus == false)/ k) d1 g) b5 Q% i! P: s
  171.     {& k4 H# v2 h7 w: T1 }; \* |9 G
  172.         serialPort->close();
    * q% Z8 K' g+ B# {4 X

  173. : \9 S6 J: Q6 }
  174.         ymodemFileReceive->setFilePath(ui->receivePath->text());
    % S! U4 ~; n) c6 }8 h
  175.         ymodemFileReceive->setPortName(ui->comPort->currentText());7 I! W, |3 @, ~6 N( C- q
  176.         ymodemFileReceive->setPortBaudRate(ui->comBaudRate->currentText().toInt());2 f& ?1 t0 u* f$ A2 K5 Z" e* @

  177. ( x7 y  a# m8 e
  178.         if(ymodemFileReceive->startReceive() == true)
    2 R& O+ A' D1 L, a' t+ r
  179.         {2 w1 a+ H( f) U; b* c2 N3 [5 B
  180.             receiveButtonStatus = true;
    " S- `) _, U& c. q$ H6 D
  181. 5 V8 i% d: {+ j9 q1 C( ?3 T
  182.             ui->comButton->setDisabled(true);5 P: L/ l- T) K7 }

  183. 8 Y$ L0 q/ `# Z0 `3 V3 F& w; U1 e
  184.             ui->transmitBrowse->setDisabled(true);
    * b. I9 c8 [% d- O3 W8 o0 m
  185.             ui->transmitButton->setDisabled(true);. l0 X- a; _% O7 G2 l% ^* p
  186. 9 u9 z- [3 b4 N+ \& b! |% i6 Z2 l# s
  187.             ui->receiveBrowse->setDisabled(true);
    4 u2 G- e6 o' p$ L
  188.             ui->receiveButton->setText(u8"取消");
    5 v8 p& ?7 Z' E6 a9 l
  189.             ui->receiveProgress->setValue(0);
    : N4 k& Q# S8 i0 T0 K1 }  Y
  190.         }
    . m3 b, B& R9 \: U9 i6 K
  191.         else$ r% A( g/ g+ k& c  u6 q. `* e8 ?
  192.         {! ~) M! g4 k0 m- ?( T+ F: R- l
  193.             QMessageBox::warning(this, u8"失败", u8"文件接收失败!", u8"关闭");
    ! P0 \( b' z* H3 V5 [' s
  194.         }3 i% |! G9 t- g9 c; ]" D0 M
  195.     }
    ( Q; w  \! N& z) g/ ^) M% Q! W! q
  196.     else
    & }8 y& C' N8 \( u6 Y- w! D! R6 J
  197.     {: s$ B2 y4 v' i# o7 z
  198.         ymodemFileReceive->stopReceive();
    / r% Q% i: D2 N" j; c
  199.     }
    : S* k0 Q$ P0 e: {3 N
  200. }$ d3 H( Z& J2 e9 L
  201. 3 S/ ^" C- d- @; }' U4 d
  202. void Widget::transmitProgress(int progress)
    5 P) m6 K! G6 R
  203. {9 V& C# d% q3 r' O
  204.     ui->transmitProgress->setValue(progress);
    . {' {  Q+ ]' z, G5 e/ A% ^& d
  205. }9 \( E  }+ c* f* U% h; v
  206. . M4 i  l  d( ?. W% s; }
  207. void Widget::receiveProgress(int progress)
    4 S, |* ~  o1 W+ {5 s4 E
  208. {7 F% k) F, V! ~6 V& m& V* y7 g. X0 L
  209.     ui->receiveProgress->setValue(progress);3 }& M2 u0 n& W6 k
  210. }+ y% A4 r- @5 ?. T! l3 W0 p

  211. ) Q0 T9 ~( O& `2 w0 t3 H
  212. void Widget::transmitStatus(Ymodem::Status status)
    3 M( H* a( V7 R
  213. {/ d2 @- `& W- f% ^# f5 M
  214.     switch(status)" W" H& R! e; B7 a3 z2 Y
  215.     {" s( _2 J$ `6 Z( v3 X; n
  216.         case YmodemFileTransmit::StatusEstablish:0 i& o# c9 y2 D( K
  217.         {& @3 t2 d- V' {5 X6 K" z
  218.             break;
    1 V% `' C7 [  |5 C3 U
  219.         }
    9 b- `4 H$ M) P# ]

  220. & j: z5 a8 B' Q
  221.         case YmodemFileTransmit::StatusTransmit:
    ! L$ G/ B. _* x! S
  222.         {/ {- l: i* N0 m' R% l; l
  223.             break;6 C' q, |* D# `" Q8 i9 G; z6 m( W/ c
  224.         }4 t2 w. G& b$ x' E: B
  225. 6 j, |! M. y) e3 d% K
  226.         case YmodemFileTransmit::StatusFinish:( P* O+ j; U; P1 I8 }; L
  227.         {9 S! H1 b; S' P+ e/ ~! A( T* a
  228.             transmitButtonStatus = false;: i' k1 q1 I# F; b9 @8 k0 I

  229. 2 d0 i( \1 a. G7 n1 T& u
  230.             ui->comButton->setEnabled(true);1 G8 G  a0 g7 X! |: N8 U- X
  231. : S% y/ l7 D0 A. B4 X
  232.             ui->receiveBrowse->setEnabled(true);8 N; p4 A- C9 d: p2 Y

  233. 5 Z( A" M. l" Q3 v1 W+ Y8 G$ d
  234.             if(ui->receivePath->text().isEmpty() != true)9 f. ?0 }( u# |3 R: G% y% q
  235.             {* y. k2 V0 ], k7 v. @
  236.                 ui->receiveButton->setEnabled(true);
    7 _% t8 ^+ u2 J% E
  237.             }2 }& Q7 g  M3 Z0 B8 u& t* {

  238. ) `0 ?3 p- R  S# G% V
  239.             ui->transmitBrowse->setEnabled(true);& ?) X2 l8 c$ U. ?% c  c
  240.             ui->transmitButton->setText(u8"发送");0 n: ]$ f' U  n  Z

  241. % g3 |1 r. P( Q
  242.             QMessageBox::warning(this, u8"成功", u8"文件发送成功!", u8"关闭");5 z+ H6 z/ p, x
  243. 1 `8 I% U2 G/ \  E* m. B
  244.             break;
    7 B$ Z/ {4 U! v
  245.         }( ~0 r# g, i" _% I% V4 a

  246. ; i; m- `, C6 \9 t2 k4 f
  247.         case YmodemFileTransmit::StatusAbort:3 h3 R8 Z, t5 s- B/ F
  248.         {
    5 @4 f) J1 Z) l, |) t' Q
  249.             transmitButtonStatus = false;# e# Y  i) m) T

  250. , S+ y- @& B4 s: P+ P0 t5 s; |
  251.             ui->comButton->setEnabled(true);6 i' ^2 a7 \! [  K5 d! V
  252. ( Q9 Z. P8 Y/ y
  253.             ui->receiveBrowse->setEnabled(true);7 z! h7 x( M7 T3 V% ?  U

  254. 3 f: _5 l: P( ]  u% O! i
  255.             if(ui->receivePath->text().isEmpty() != true)
    3 q: F5 l! M! o% _! d0 T
  256.             {
    1 _" e0 p8 k  w" |5 j
  257.                 ui->receiveButton->setEnabled(true);
    7 Z% w, }( A# s! W8 }
  258.             }
    3 w: y0 [9 V( c2 x1 i
  259. " f0 S' C$ u' H" A+ s
  260.             ui->transmitBrowse->setEnabled(true);
    0 ]4 w4 f' h3 h6 i$ d2 ?% w1 r
  261.             ui->transmitButton->setText(u8"发送");
    5 p# s9 X7 L* t* d& A% B- j- \- O

  262. % s5 h% C8 L, V: \0 s4 h0 ?
  263.             QMessageBox::warning(this, u8"失败", u8"文件发送失败!", u8"关闭");+ ~# d! v4 n5 g  p0 {! h8 `  {

  264. $ K+ {; F. |7 U0 a% V8 N; {0 y: r
  265.             break;
    * z# {" M) V/ R" X& _- m
  266.         }
    6 ~6 r% N' v# t$ `/ Q% h
  267. $ S' A+ q3 Q! `- v2 w5 c- b0 q
  268.         case YmodemFileTransmit::StatusTimeout:; O- T- [6 T9 [, d' B
  269.         {
    3 w& w9 l' z8 r3 k7 k/ i) j0 b- a
  270.             transmitButtonStatus = false;
    : s- U4 i* K- r; b

  271. ; c" u0 G( o8 r4 E
  272.             ui->comButton->setEnabled(true);
    , p4 {- F6 K* }! v

  273. * E5 g' {0 D$ b5 i- @! h
  274.             ui->receiveBrowse->setEnabled(true);) Y0 m) {) U: u4 ?$ I6 E+ C
  275.   I& j. A0 h# N& r; M
  276.             if(ui->receivePath->text().isEmpty() != true); y9 S' Q" U! ^# \0 P/ t5 j
  277.             {! x( t! g1 |7 l% `2 f) x
  278.                 ui->receiveButton->setEnabled(true);
    / A8 U' g, M; M; D% E, ~3 q
  279.             }
    9 ^9 W+ `. q6 P! d8 ?( u+ H3 V
  280. 9 h- v: V6 {9 x) O4 O" c
  281.             ui->transmitBrowse->setEnabled(true);
    ' {4 f2 \: H; Z) ]2 q
  282.             ui->transmitButton->setText(u8"发送");; U) y: x0 [5 _' s

  283. 7 s1 [, c* L; ~" _. c
  284.             QMessageBox::warning(this, u8"失败", u8"文件发送失败!", u8"关闭");/ H, E7 q1 p, ?8 {# q$ |( s
  285. $ U5 G' C& k" w0 y+ m% M$ A
  286.             break;
    * P) ~, v* @+ g2 o% N
  287.         }, b* T% ?# ^4 z' K$ J  D! q

  288.   r' L) ?8 S$ _) |
  289.         default:
    % ~! {2 h; b% |7 x- a8 c
  290.         {
    9 i* q5 `; t8 _8 k- O1 D
  291.             transmitButtonStatus = false;1 p( m7 A- P; d4 N6 f7 N: n

  292. ' l# h1 v1 e$ ]* J, o* D( ~4 E4 y
  293.             ui->comButton->setEnabled(true);
    " n& x# g( V! t( h9 m

  294. 9 j1 ?/ d/ \( U* }7 n$ \2 y& K
  295.             ui->receiveBrowse->setEnabled(true);! e* {4 r* |! D0 L

  296. # h6 p! F- z9 M+ e
  297.             if(ui->receivePath->text().isEmpty() != true)3 r" v+ ]% m- I! t8 q6 z
  298.             {
    / F9 @  x+ K% N( B: v
  299.                 ui->receiveButton->setEnabled(true);
    3 c' g6 L. A- {3 j
  300.             }
    $ \. }3 @  C# a8 J' H
  301. 7 N9 u0 P8 D7 C1 ~  i9 {! t& w: n
  302.             ui->transmitBrowse->setEnabled(true);+ k' B: ^% J3 [: b9 t
  303.             ui->transmitButton->setText(u8"发送");1 h6 @1 a3 i" Z; B, D& L, N

  304. ' z7 s% k. s* N4 [* G! y
  305.             QMessageBox::warning(this, u8"失败", u8"文件发送失败!", u8"关闭");
    & ~4 ]7 Q, U5 O/ }
  306.         }# _* R* B# `2 v- D% Z
  307.     }
    7 P. c# x) r- ?" M& x
  308. }
    2 x, `+ Z1 y4 J8 p; N( o
  309. & C- `  r: ^; H' b
  310. void Widget::receiveStatus(YmodemFileReceive::Status status)
    7 u& G4 B; T- j1 @) W
  311. {; N8 P% w- C$ A' c) b2 F* Y: d, j: ?
  312.     switch(status)
    ! H$ N4 m- ^# S( E4 X2 v
  313.     {* j" [8 H0 d" x( S+ z5 `2 p
  314.         case YmodemFileReceive::StatusEstablish:
    / e; E7 O5 m. e- p1 L0 f
  315.         {
    ) H( v+ y# n5 K6 u
  316.             break;
    & z6 V% l/ p1 Z6 O+ ?2 ]
  317.         }+ @5 Y6 I. K8 O# b

  318. * E$ w# q: \0 H3 N
  319.         case YmodemFileReceive::StatusTransmit:
    4 E7 c& I4 U+ n" u% M7 y0 ]' @7 ^% T5 }4 E
  320.         {; Y, i- d+ e  L/ ]3 J6 N, V
  321.             break;2 W- k, l- h0 d. w7 X- W
  322.         }. u7 x! }$ c) f0 _2 P$ e

  323. " g' f2 }* a7 ^! {+ h: ~9 j9 o. C
  324.         case YmodemFileReceive::StatusFinish:
    # s- w1 j, X# G' `* B8 d* K5 y
  325.         {  [( r! t( Y: O5 Z" W7 e
  326.             receiveButtonStatus = false;
    - Y/ @* ^7 O7 R  s3 v

  327. # @7 |% v& _/ z: {
  328.             ui->comButton->setEnabled(true);
    . V/ z  |/ p+ C/ T
  329. / l7 x' U0 M4 F  r/ n! c
  330.             ui->transmitBrowse->setEnabled(true);: L9 q5 {; @# i8 s9 ^! B
  331. 2 k3 K, j: `! k2 ^# x/ q: f/ p
  332.             if(ui->transmitPath->text().isEmpty() != true)
    ; `9 P: P9 S1 l: _) Y2 d
  333.             {; v4 n. ?. I& g' N% Y4 V; \
  334.                 ui->transmitButton->setEnabled(true);
    2 X. T( G. r* r/ a, P
  335.             }
    - N0 D: a4 H( W1 P- N
  336. 3 m) G( B% h. {5 K+ D2 O
  337.             ui->receiveBrowse->setEnabled(true);
    2 E4 G: M. D9 m& T6 Y
  338.             ui->receiveButton->setText(u8"接收");
    $ Y- \% ~+ E7 ~) \1 g, y
  339. ! U; m5 `% E# `. r9 i
  340.             QMessageBox::warning(this, u8"成功", u8"文件接收成功!", u8"关闭");
    ; }! u; w5 i: K* a' e# R8 ~

  341. ! e7 E& X3 Q6 {( g
  342.             break;* S/ y" s$ {) {1 J6 s
  343.         }! ]2 a' ?" e: T+ a, P) @; p

  344. , W+ d, t' Q, Q0 j
  345.         case YmodemFileReceive::StatusAbort:
    ! s# {  v) o# a  W$ G$ T( K
  346.         {+ ]" }! z( j1 w( V& G7 c4 S1 `
  347.             receiveButtonStatus = false;7 n5 |" G8 F! x' k- X6 |
  348. ! d% r* w6 Y' V& P$ p1 S
  349.             ui->comButton->setEnabled(true);
    - B4 T4 t3 a0 t# K0 _
  350. 1 ], d, f/ m' _% B" E0 Y
  351.             ui->transmitBrowse->setEnabled(true);# K3 R$ i& I8 M  J: w3 ]7 ]

  352. ! N& D; q2 B$ G% \( i
  353.             if(ui->transmitPath->text().isEmpty() != true)5 T  s% i2 o- w/ I& V
  354.             {
    + `% m+ K1 o. b
  355.                 ui->transmitButton->setEnabled(true);7 b4 G7 y# D, {! V4 g0 |; R. r0 A& [
  356.             }, V4 L! I4 A7 C
  357. 7 s$ ~5 L8 y9 E4 I
  358.             ui->receiveBrowse->setEnabled(true);& J0 H# ^0 ^+ l4 R4 D; E% @) L3 f
  359.             ui->receiveButton->setText(u8"接收");- L# d: p- O( k) N+ Y, T. J7 m7 z
  360. 0 O$ n4 C: _: P2 X" h) s
  361.             QMessageBox::warning(this, u8"失败", u8"文件接收失败!", u8"关闭");' T4 d3 r3 S1 l0 d
  362. 4 N# o5 c. w0 T! F, x, D9 T3 L
  363.             break;
    2 ?* B8 |  d* y
  364.         }& t1 z2 C! B$ ~. ?  ?
  365. / Q2 F8 G$ ?% [- `: _) m
  366.         case YmodemFileReceive::StatusTimeout:
    ) X" @" O0 x1 |( s. \2 ?6 V
  367.         {
    ! l4 Q" f' f/ ?+ n. l
  368.             receiveButtonStatus = false;8 {& W$ N8 M+ n5 L5 J  q

  369. ! H: D9 C0 c; r8 r) y7 u
  370.             ui->comButton->setEnabled(true);
    2 [4 c, {4 o$ k
  371. : N# `- D4 O/ B7 e( Z
  372.             ui->transmitBrowse->setEnabled(true);+ P8 C& ?8 U. M" a0 P# }$ i
  373. + @, t& d' t" a$ V; X
  374.             if(ui->transmitPath->text().isEmpty() != true)
    ) V8 z; y9 m# \. t: n5 U$ e% d
  375.             {
    ' G6 Y( Q) S; v/ q
  376.                 ui->transmitButton->setEnabled(true);; Z( ^2 Z; ?/ n! U, n
  377.             }/ \8 z  O) T' y) k- C
  378. ' h9 m" U  k# U& x  k: K
  379.             ui->receiveBrowse->setEnabled(true);" f- u6 j! h* l) c# z3 K: F1 n- r# S
  380.             ui->receiveButton->setText(u8"接收");
    7 k: m0 {. h: X) a# L
  381. " |3 h( e' R: K7 |
  382.             QMessageBox::warning(this, u8"失败", u8"文件接收失败!", u8"关闭");
    ; B2 X' p$ \- W, S' }

  383. . y9 y4 Y$ j0 G1 ^* Q; Y+ ^7 |8 j
  384.             break;; R* T$ q$ m  U
  385.         }6 C) V  p- Y+ L
  386. ) }8 N3 X- R0 ^+ G0 t
  387.         default:
    : U" o$ {$ J' w3 X' H
  388.         {6 Z" f. _3 }0 L* ~1 Z# S5 F$ Q
  389.             receiveButtonStatus = false;
    6 ^  H! \+ d- q  X0 H- |0 w

  390. " p& X% r- ]6 [: T( }) z  u4 ?
  391.             ui->comButton->setEnabled(true);; |# X  Q- c3 ^% O" \% W

  392. - I! A7 ]9 E) `$ {, U0 z4 m% I3 W' P
  393.             ui->transmitBrowse->setEnabled(true);
    6 ^+ x5 V, c, k1 M
  394. 9 G, ^( A# F. u: n3 Z3 G
  395.             if(ui->transmitPath->text().isEmpty() != true)# p" ~6 l: K' Q! i1 `3 h5 s- C
  396.             {
    6 B* q7 p& p/ q
  397.                 ui->transmitButton->setEnabled(true);. K1 [# \/ G- g- {4 N' _
  398.             }: X$ z0 S2 S8 m3 r  q

  399.   z; W4 Q4 J2 M' n1 |
  400.             ui->receiveBrowse->setEnabled(true);# F" h' d( d/ v7 t4 {) L2 A/ F9 |% l
  401.             ui->receiveButton->setText(u8"接收");% @+ d; o/ Y4 b* t% \
  402. . Y0 n# T0 {5 }" f  l& L
  403.             QMessageBox::warning(this, u8"失败", u8"文件接收失败!", u8"关闭");: e$ S( m+ E6 j
  404.         }/ o$ g1 c: E4 U& O4 x
  405.     }* k+ x! E6 V* l7 W
  406. }& j* M% H- \+ `
复制代码

# k, [/ \  P7 v3 W3 e9 E; k$ g! P7 H  t! E0 K
4 Q; T3 P; B9 _7 [/ B8 z

" U2 ^4 e1 B7 {+ Y- g+ a# E: ~( t) B  d1 E6 j. [

% V# G6 b# C9 y' a8 V4 V
XinLiYF 回答时间:2018-3-6 22:32:40
      main.cpp文件
2 u1 ^# Q- ^4 Y! c3 i$ ~- y
  1. #include "widget.h"
    : ~, W4 P/ O) H8 l( B. z0 I
  2. #include <QApplication>
    6 n4 g; v0 j7 y' y+ W/ M
  3. : l6 D- i/ P0 L3 n) ^3 w
  4. int main(int argc, char *argv[])" |$ l" O* m, ^6 D( V* A$ y
  5. {
    9 I, t; t# S* s( o! i+ [5 Z& T
  6.     QApplication a(argc, argv);4 o2 x# n; ~  z
  7.     Widget w;( z+ ~4 Q! ?* v# d
  8.     w.show();  ^" p' Z7 O, E* ^& g
  9. 1 L8 Z2 n. w. \, U' ^: U: n$ O
  10.     return a.exec();5 _' ~$ ]2 a8 p9 r: T4 y
  11. }
    / w5 Z. \& Y5 u, k0 [1 }
复制代码

$ S- y; x) g# I: w& f      SerialPortYmodem.pro文件
) m2 q) e" w( i4 A7 E, [
  1. #-------------------------------------------------- l# R2 t+ I3 ?4 U7 V* z/ w3 m
  2. #
    5 Z, [( B) m' X9 m1 j
  3. # Project created by QtCreator 2018-01-20T23:00:46
    3 q3 V7 O. E! y/ {
  4. #
    ' O9 }2 s* d- l$ H1 {: f
  5. #-------------------------------------------------& I# k8 ?5 N7 B3 W* H( P
  6. ( i$ ~  U$ Q" q& c5 w) s0 Q
  7. QT       += core gui
    8 H) A9 D) a1 I
  8. QT       += serialport
    7 g  ]& {9 Q1 N8 q/ g' m- [  I

  9. 2 _7 Z4 Q+ q' I1 l
  10. greaterThan(QT_MAJOR_VERSION, 4): QT += widgets1 v3 z  K4 }) Z4 w  U# U% N
  11. 8 Z) e+ l# D; i. ]  G' K; O
  12. TARGET = SerialPortYmodem
      L- z: v! `# [/ S
  13. TEMPLATE = app3 M3 `. a, Q3 e" W

  14. ) Z6 B& B% X* ?' e; t% _
  15. # The following define makes your compiler emit warnings if you use# s: ^' G+ F+ p! I% s5 n
  16. # any feature of Qt which as been marked as deprecated (the exact warnings
    - w: g) G. d8 \9 N
  17. # depend on your compiler). Please consult the documentation of the
    $ M$ {* D( m5 K0 N& v
  18. # deprecated API in order to know how to port your code away from it.8 ]# p9 i/ H+ o; @7 h
  19. DEFINES += QT_DEPRECATED_WARNINGS3 i$ f/ e5 I9 F! Y1 c2 c
  20. / N2 n) G) v- h& R
  21. # You can also make your code fail to compile if you use deprecated APIs.0 E$ i, P8 w5 a" N5 v
  22. # In order to do so, uncomment the following line.
    7 ]3 d6 j) l4 M2 @. i. R& {
  23. # You can also select to disable deprecated APIs only up to a certain version of Qt.
    8 L+ ?# n) I4 ]* r1 m% ^
  24. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0. {- c( h1 U3 _" s

  25. & V" g1 T8 w  t6 H, G4 a

  26. 1 I; m; [9 {1 r3 Y
  27. SOURCES += main.cpp\+ A& w2 `. Y+ g5 @+ C
  28.         widget.cpp \
    5 i1 x1 P, P9 s/ N3 O! T* O8 ]/ f
  29.     YmodemFileReceive.cpp \0 S( g/ ^0 Y* a! @- q
  30.     Ymodem.cpp \
    , I" B' z3 l' l) N, s, M& H" d  q
  31.     YmodemFileTransmit.cpp
    % M- o- n& k2 v
  32. # u9 A: n+ h" b8 W
  33. HEADERS  += widget.h \
    : T% \) f/ @6 G
  34.     Ymodem.h \1 i% j: B1 k, P7 n- Q, s  W4 C
  35.     YmodemFileReceive.h \
    6 E5 C* h7 ~7 V
  36.     YmodemFileTransmit.h1 s& U! l$ U: o) Z9 |+ w8 [

  37. ; S* P) d4 n% h. ~$ H
  38. FORMS    += widget.ui
    9 z! ?) c- ^: u
  39. $ F! U( ], `0 W
  40. RC_ICONS = SerialPortYmodem.ico
    4 {* d, N. r0 K2 u; a
复制代码
$ j9 v# Q/ W7 w" ^$ \1 O0 r6 ^
      SerialPortYmodem.ico文件
1 Z! R0 e! ^4 t+ I+ H

7 }/ u! R" J+ A& ?' ^( d3 j/ m3,运行效果
7 ?: j6 C# X# a) \1 I2 c2 K
6 d4 R0 `" D. R+ b

+ u' s+ n6 i: k' b
: D8 H0 Y# g& P  J) V+ f: Q" a( o& o' h6 T1 w' H: @5 n  C
XinLiYF 回答时间:2018-3-6 22:33:09
可以用来做用户程序升级的上位机软件。GitHub仓库有工程,还有资料。
anobodykey 回答时间:2018-3-7 09:21:37
感谢楼主分享
shuihehe 回答时间:2018-8-13 15:37:45
网络在线升级的技术资料呢?
any012 回答时间:2018-12-19 14:03:21
请教,单片机端如何处理呢?
XinLiYF 回答时间:2018-12-22 17:06:17
any012 发表于 2018-12-19 14:03: `' p, R8 X* ^& g$ g, e0 H
请教,单片机端如何处理呢?
5 h& U; V! |: {% y" b
可以移植到单片机上,文件的接收和发送都支持。
Kevin_G 回答时间:2018-12-26 09:46:05
收藏
huangchao09 回答时间:2019-3-24 20:37:59
多谢楼主共享

所属标签

相似分享

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版