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

YMODEM协议串口文件传输

[复制链接]
XinLiYF 发布时间:2018-3-6 01:56
YMODEM协议串口文件传输
GitHub仓库:http://github.com/XinLiGitHub/SerialPortYmodem
. l4 E* l! T& v% O0 S% P3 mPS:博文不再更新,后续更新会在GitHub仓库进行。) ]  |- H+ ^: L* K7 N2 T

4 \/ `1 U# p7 L( K* G! ~
1 O# R- h: ?8 ~4 A
    串口通过YMODEM协议进行文件传输。程序中涉及到YMODEM协议知识,详细介绍见维基百科[YMODEM](http://en.wikipedia.org/wiki/YMODEM)。
9 [0 t% G: Z" i. H+ E% R4 \
, ^8 ]7 u6 u. [, T; V0 u. f; k1,开发环境+ a/ \  A8 M" _% q
      1,框架:Qt 5.7.13 w0 \6 f  z- J, u

7 \% C% P+ [2 i: c; a( S      2,编译器:MSVC2015_64bit
6 @& s  \$ x, N' ]. u
7 W. o, d5 w$ X# x5 w9 [
      3,IDE:Qt Creator 4.2.0 社区版
& q3 c! T3 W- R9 h, b7 L0 E      4,操作系统:Windows 10 专业版7 ?' }' F9 U, X3 ^: |  u
4 r' Q) O0 X/ V! I
2,程序源码
6 A" e. o3 p% a0 B      Ymodem.h文件# {" q7 i' A! p
  1. /**
    & y) c8 k$ {3 n& D; o
  2.   ******************************************************************************
    4 B, L* t' ^3 M  Y2 H7 {8 o
  3.   * @file    Ymodem.h
    " |: u- M- e/ I2 K
  4.   * @author  XinLi
    1 s8 v3 V! A+ K
  5.   * @version v1.0  I# A; P4 P* ]& R' G* K& h* R
  6.   * @date    21-January-2018
    + E. z" S, h6 k4 f. t
  7.   * @brief   Header file for Ymodem.cpp module.
    0 [3 k- G/ O/ ?5 m2 ^
  8.   ******************************************************************************
    8 G) `$ L6 q' X; i
  9.   * @attention/ g; @' S9 l0 Z6 V/ z0 F
  10.   *
    - V7 u+ h! _6 o* _; @" W/ W
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>* v+ @7 v( x# T  [6 _& L$ h
  12.   *
    ( R0 `6 [6 w( {: h8 j, u1 F0 Y5 k
  13.   * This program is free software: you can redistribute it and/or modify( B) Q7 S; O# Y# M0 E) `' H8 e9 e. D7 b
  14.   * it under the terms of the GNU General Public License as published by
    & p4 A( ~5 S" G" m- H+ t0 @3 p6 [
  15.   * the Free Software Foundation, either version 3 of the License, or
    3 t$ ^0 {$ _# M, [7 H( d, {
  16.   * (at your option) any later version.
    % L7 R% V: t0 g& N
  17.   *
    ; v: y: l: f9 G- [' x5 D% e- w
  18.   * This program is distributed in the hope that it will be useful,+ p9 B) t: C* s0 s0 L  X
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of( r# v4 W  n9 B: r$ Q9 `
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    . k1 e, {( i9 G
  21.   * GNU General Public License for more details.
    4 L  Z" _4 U6 J) u0 N
  22.   *
    * u3 i3 f! {# H7 a6 e2 q7 T* |3 L
  23.   * You should have received a copy of the GNU General Public License
    ! A/ e, z' c4 g: [
  24.   * along with this program.  If not, see <http://www.gnu.org/licenses/>.: |$ b% V& ^4 T8 j
  25.   *- }/ ]3 J4 S: G- X  L; B" I0 d  Z
  26.   ******************************************************************************1 z1 t2 m% e* c: y8 E5 v, }' x, o3 D
  27.   */6 h; E$ R8 S( i/ E& n
  28. 1 T- F0 a/ {3 M1 v/ C* G
  29. #ifndef __YMODEM_H7 D# H, w) z' |5 e' T0 `
  30. #define __YMODEM_H$ C  W3 f0 P% T# G7 f# h
  31. 6 Y' O* i$ U/ L- Z: H2 g8 e
  32. /* Header includes -----------------------------------------------------------*/
    9 p% h3 Y0 k& U5 S  r6 Z
  33. #include <stdint.h>4 j. k: c: b9 |
  34. 5 |- x6 B: a/ I" v! {, F' W- I( S1 K
  35. /* Macro definitions ---------------------------------------------------------*/1 t5 k- n  Z' N# B* X3 ]/ n0 C
  36. #define YMODEM_PACKET_HEADER    (3)
    & ], c1 ^* j1 w  B$ i
  37. #define YMODEM_PACKET_TRAILER   (2)
    6 K# [2 |5 L$ n; X! a
  38. #define YMODEM_PACKET_OVERHEAD  (YMODEM_PACKET_HEADER + YMODEM_PACKET_TRAILER)
    0 ]* |! u2 B6 W- G! C$ N$ Q
  39. #define YMODEM_PACKET_SIZE      (128)9 W4 d4 x" g) j: t1 ]  s9 V% l
  40. #define YMODEM_PACKET_1K_SIZE   (1024)9 J" f2 x/ O' t5 }9 @7 a$ R7 e

  41. 9 d8 q& M  E0 l: J1 U+ q! g: {, v
  42. #define YMODEM_CODE_CAN_NUMBER  (5)- D4 @2 W% w9 N$ e
  43. - ~, d! P+ F; Q- `3 M
  44. /* Type definitions ----------------------------------------------------------*/
    . ?5 l( G7 p% V3 Y& C6 `/ U" w
  45. class Ymodem
    # k" _6 H" P7 w. M, l
  46. {. ?, [( m+ M# V, M+ f, D
  47. public:$ v9 ^2 ^, `5 T' M* _7 A, D
  48.   enum Code% y7 I: Y& v0 c; ^2 ~, b+ U3 ]
  49.   {
    ( D9 ~# g, F( O3 a. V" r4 O9 Z8 |! j
  50.     CodeNone = 0x00,6 Z. r' o7 ]5 g/ \" d# q1 }1 Z
  51.     CodeSoh  = 0x01,
    . f! G) w3 X4 ~$ B2 @- Z: N2 w, [" g
  52.     CodeStx  = 0x02,( t8 l2 n# x' }
  53.     CodeEot  = 0x04,  Q+ q% L& c( i, H
  54.     CodeAck  = 0x06," k( S& q+ }& X2 C' V
  55.     CodeNak  = 0x15,2 t1 @2 r6 G" Q$ z9 G  ]; E
  56.     CodeCan  = 0x18,
    - B" i# z# V' _% J  t# |2 q% k( |
  57.     CodeC    = 0x43,
    % d3 \4 F- f& m  J$ C! u7 ^: _
  58.     CodeA1   = 0x41,0 G' U) h1 y/ v8 g0 ?& g4 l
  59.     CodeA2   = 0x619 k9 Z7 d3 h3 k) F% a
  60.   };% C. J/ V' v1 G9 e
  61. $ ]7 x& \- z; \, `* C
  62.   enum Stage
    3 |$ h9 t, I+ F
  63.   {
    6 H; o7 u7 L- X
  64.     StageNone,' h  l7 G0 `$ ?7 ]& f% j* u: z$ q
  65.     StageEstablishing,
    9 N7 R% Q; g4 P# Q
  66.     StageEstablished,& T! G$ ?- h+ U/ U
  67.     StageTransmitting,1 e4 g& c, L2 G8 `
  68.     StageFinishing,# ^  `5 m; ~5 ]: ^: [  W; u
  69.     StageFinished
    9 O) {$ Q% h" C. m( e
  70.   };+ |9 p7 d0 j* l) F, b. k, L

  71. 5 p. ^0 U5 E% Q' q7 p* ?8 P
  72.   enum Status7 B, O: [$ v1 r9 R; ~. |* `
  73.   {% z& V( Z  ?$ D; |
  74.     StatusEstablish,; F. ^. j# M' O- Q: \
  75.     StatusTransmit,
    : Q. ?1 A5 K# k1 `. O$ C# |
  76.     StatusFinish,6 J4 p2 i$ H, L6 h: s, ?5 m4 u' J
  77.     StatusAbort,$ U% P! ^9 m1 O1 `: l! _6 a. E
  78.     StatusTimeout,/ o6 v# u; o0 _1 `  y
  79.     StatusError1 I$ I) X( a* K9 C- E1 k( f9 N. y3 G
  80.   };8 G" W( c" d7 z3 ^$ L) Q8 A3 }
  81. + G/ I# s  s4 l, j- h' N# ?% s
  82.   Ymodem(uint32_t timeDivide = 499, uint32_t timeMax = 5, uint32_t errorMax = 999);
    8 g" T4 p0 c6 w" u

  83. 0 q( n; _- H* o  I
  84.   void setTimeDivide(uint32_t timeDivide);
    # m. \4 x& j6 v" e
  85.   uint32_t getTimeDivide();
    ; r  W- G; @( v9 S$ g, B* ?+ O. l
  86. ' k7 Q% z8 f6 B6 m; W! b5 q* n
  87.   void setTimeMax(uint32_t timeMax);
    ( w( [* r7 O9 r- [  n5 N
  88.   uint32_t getTimeMax();5 n6 z( y( J/ X' Y  `; a) v
  89. 6 \. S8 o) G; |3 B/ L9 i
  90.   void setErrorMax(uint32_t errorMax);
    " w' x; h/ b+ |" ^8 W
  91.   uint32_t getErrorMax();: E7 j7 \* A2 P6 k

  92. - v+ h8 Y: K0 Z2 f1 i
  93.   void receive();, |- y4 ?0 v. S9 T
  94.   void transmit();, W  [' P* \/ g: j
  95.   void abort();
    7 j/ C3 J/ p: l  k. H$ k

  96. % V' w+ P. o( x/ x5 V4 Q$ R; m2 m
  97. private:
    5 F  Y) |4 J2 C* L0 T1 Y
  98.   Code receivePacket();* }! ~+ {% E7 X5 {0 m2 p4 O, G4 r

  99. 3 X0 u0 {/ g5 H& B, k
  100.   void receiveStageNone();
    * b& l! b7 ^% ^  [# I
  101.   void receiveStageEstablishing();
    " }6 S! I0 ]* {
  102.   void receiveStageEstablished();. m7 `  _0 U. h' _" M
  103.   void receiveStageTransmitting();
    # k% I6 |6 S1 [( o5 F  U1 T+ ^
  104.   void receiveStageFinishing();% E- j1 D2 w$ c' B$ `6 s+ a2 Z
  105.   void receiveStageFinished();
    3 r1 c8 O! ?8 H" q2 W0 I6 k
  106. ) X$ {& E2 z# A# O2 C: y
  107.   void transmitStageNone();
    - H6 S6 z  t1 Z; s+ y
  108.   void transmitStageEstablishing();/ i$ I0 h4 D' J" q: x0 L1 E2 ?) H, u. o
  109.   void transmitStageEstablished();
    . I. f  s/ c7 g4 w: Q  X8 N
  110.   void transmitStageTransmitting();
      D* Y' C" q* L3 L
  111.   void transmitStageFinishing();
    3 J8 P5 r7 B' v+ s5 j+ @& Z" Q
  112.   void transmitStageFinished();( v- N7 e8 S- U4 m) [
  113. * L# x+ a* i; @6 s9 t  ^
  114.   uint16_t crc16(uint8_t *buff, uint32_t len);, q4 V6 s* H9 P$ t, x& G+ x$ H
  115. 8 p; Q" M* _. ]- w/ l. O& ?$ P
  116.   virtual Code callback(Status status, uint8_t *buff, uint32_t *len) = 0;$ H7 i' D, V' h, T" p( h
  117. 2 g" r1 A0 l  _% c
  118.   virtual uint32_t read(uint8_t *buff, uint32_t len)  = 0;
    % X8 p; b8 |3 Z, d" b+ v
  119.   virtual uint32_t write(uint8_t *buff, uint32_t len) = 0;
    . ?+ ]2 g, @7 Q, D& @3 R
  120. " u4 b1 l8 ^4 ^7 x; H1 q* _
  121.   uint32_t timeDivide;7 R6 U' F6 a( c& |# b
  122.   uint32_t timeMax;4 K# e) v+ V. B& @3 V9 K: L
  123.   uint32_t errorMax;
    $ q7 ~0 I# g  a; p
  124. 0 K; k% M- Y) {* K3 R
  125.   uint32_t timeCount;& w- O) h' m  H  ^$ T/ N  Z
  126.   uint32_t errorCount;
    6 C# \, G- a1 v9 @
  127.   uint8_t  dataCount;  v2 [& }4 b6 ~' L/ _* k
  128. 4 |9 V% {7 {! o( r+ n
  129.   Code  code;8 @8 V+ c5 N3 @" y$ ?9 y
  130.   Stage stage;
      ]) }$ ^/ ~4 k( V" V

  131. 2 c6 d6 Y% P8 R7 p6 b3 ~) w
  132.   uint8_t  rxBuffer[YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD];
    - d7 Q8 L- @2 A! G/ v
  133.   uint8_t  txBuffer[YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD];+ V- t/ P* @' |6 k
  134.   uint32_t rxLength;
    ! Y; Z* ]7 x* O- o8 O5 ?3 S  H
  135.   uint32_t txLength;  Q5 p3 A$ ?. j2 Q+ A& h
  136. };* {) l5 P& H1 J% I, O4 g
  137. - v8 T  u# b% D# T( S  A1 l3 O# Y
  138. /* Variable declarations -----------------------------------------------------*/( U# M" U9 S$ `  B8 e% n+ [
  139. /* Variable definitions ------------------------------------------------------*/
    - l- G, O% @; g& L  A8 _# @6 h
  140. /* Function declarations -----------------------------------------------------*/: q! T+ e5 Z& W! c; U( e% P
  141. /* Function definitions ------------------------------------------------------*/& X- `$ F) s& B& M: v, n
  142. . d5 o) k' Q% ?6 R& E' w
  143. #endif /* __YMODEM_H */
    # Z5 n1 ]8 D" h7 b
复制代码

; _$ c! s& z# I% F8 m      Ymodem.cpp文件& U& [  C/ |9 Q  M' Y
  1. /**
    & B) l, S+ {! y; b- e/ L! M" U
  2.   ******************************************************************************) [4 m% I% q4 N2 M, C4 g9 l! ~
  3.   * @file    Ymodem.cpp
    - }5 L) T4 M" r2 f1 q
  4.   * @author  XinLi
    1 ~' T$ A  ^3 t8 I
  5.   * @version v1.0
      l1 @9 O/ c# T
  6.   * @date    21-January-2018/ N% f2 A% i! o, N
  7.   * @brief   Ymodem protocol module source file.% `% `! S, w) `9 ?3 e) B
  8.   ******************************************************************************) L( E4 r0 T+ u' b0 l% b
  9.   * @attention
    ; V, F& F! G* ~2 ?
  10.   *
    1 c9 B* ]- }/ o9 \
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>
    ) [& C* [  B8 _+ ^$ d1 l
  12.   *( [6 `) A- j7 l/ m- o
  13.   * This program is free software: you can redistribute it and/or modify
    9 h, c6 t: \6 M3 q5 }, G; {
  14.   * it under the terms of the GNU General Public License as published by: |% M$ K. V; D
  15.   * the Free Software Foundation, either version 3 of the License, or  T& m: x; j* {+ r* k( r1 j
  16.   * (at your option) any later version.
    * z( d9 N2 |  d& d' y8 g, k4 H
  17.   *& n" B& [# y0 m; u1 o1 P7 @: ^
  18.   * This program is distributed in the hope that it will be useful,
    / h8 w% U4 A8 v1 j: J3 X
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    / [! F, _+ d, n
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    ; z5 i. r2 O# o1 H3 `
  21.   * GNU General Public License for more details.8 `; w4 O1 i, q$ s! `! Y
  22.   *
    ; h& X+ h. k9 R% ]3 d! n
  23.   * You should have received a copy of the GNU General Public License
    0 m8 A8 a' K+ t; g
  24.   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    4 Y$ A/ }! M( o5 ^
  25.   *
    ) z' X4 p; b- c( A
  26.   ******************************************************************************
    3 b' k6 D; E6 S0 c
  27.   */
    # p8 J" F! U- \3 g' I( `( K
  28. - s: a1 W! F+ j9 ^
  29. /* Header includes -----------------------------------------------------------*/' |( C3 t2 [9 p5 T
  30. #include "Ymodem.h"
    ! Q6 {+ ]( u. o- b- m. x
  31. #include <string.h>4 ^; G6 G. _) |9 N3 l/ ?
  32. ( M$ v; m/ z- Z5 s! s
  33. /* Macro definitions ---------------------------------------------------------*/2 I- p' y9 d, E
  34. /* Type definitions ----------------------------------------------------------*/. q, V2 w  v( d
  35. /* Variable declarations -----------------------------------------------------*/
    / _& m- v8 q5 t0 I* m0 p6 K: {& e" _
  36. /* Variable definitions ------------------------------------------------------*/8 m) `8 r' E" b0 ~
  37. /* Function declarations -----------------------------------------------------*/: w. f4 X8 I% H! {( E" u2 F
  38. /* Function definitions ------------------------------------------------------*/
    9 s4 W$ Q$ W: a1 F0 y! f
  39. ' F, i2 {$ n0 J5 s- @" x
  40. /**
    ) Z0 d# d& H. Y" _
  41.   * @brief  Ymodem constructor.
    ' h( _' h& T$ X- g/ D
  42.   * @param  [in] timeDivide: The fractional factor of the time the ymodem is called.0 E+ V. L* o0 b3 ]
  43.   * @param  [in] timeMax:    The maximum time when calling the ymodem.9 e  d1 U; q' K* \* f; A
  44.   * @param  [in] errorMax:   The maximum error count when calling the ymodem.
      l/ @* H7 w! V# l
  45.   * @note   The longest waiting time = call time / (@timeDivide + 1) * (@timeMax + 1).
    8 c2 h4 E) _' f& c* Y
  46.   * @return None.' g* ^5 ~0 n8 Q4 I% x0 ?9 V5 w8 }5 j
  47.   */
      C- O' n- T% ^+ D) }  n; L
  48. Ymodem::Ymodem(uint32_t timeDivide, uint32_t timeMax, uint32_t errorMax)
    6 t. i% [8 \$ W& a6 P
  49. {5 \" V; V& t! `: S+ J0 e5 N/ ~
  50.   this->timeDivide = timeDivide;
      m$ p5 g0 Z- _3 Y, |
  51.   this->timeMax    = timeMax;
    + j( d# `* z. h* b
  52.   this->errorMax   = errorMax;/ Q4 U! ~6 j  e' J7 L# q

  53. 4 Q6 s" X* N0 \. r9 [% \
  54.   this->timeCount  = 0;6 \: f7 n1 T- _" Q' ]; J
  55.   this->errorCount = 0;
    ( P  r, r4 q- k
  56.   this->dataCount  = 0;0 {- T# x* K; ]: T+ J" X5 w% O

  57. 9 Q2 _8 T$ Z# b9 Y7 R0 k+ c" S
  58.   this->code       = CodeNone;
    : m/ F9 B7 x0 J  C2 X1 {
  59.   this->stage      = StageNone;' L! L( c( @' `7 b; o# h
  60. }( k6 j0 G( T% @/ p
  61. 9 |" H4 \) `/ _, r  a
  62. /**( i7 G) K9 @+ U# J" m2 v$ I
  63.   * @brief  Set the fractional factor of the time the ymodem is called.
    % v! b5 z: ]6 ]0 A2 \
  64.   * @param  [in] timeDivide: The fractional factor of the time the ymodem is called.% z- @3 T& r! F# c& n$ h' ^
  65.   * @return None.
    + J+ N! Q: Y# r2 Q
  66.   */
    $ b' t5 f1 `7 P' |& ~. H
  67. void Ymodem::setTimeDivide(uint32_t timeDivide)
    ; N' D0 o0 ]4 |
  68. {
    : ]6 m" a- W5 q  g/ L+ b2 L2 `) h) C
  69.   this->timeDivide = timeDivide;
    & ~6 ~" ?1 v6 U- S
  70. }
    " _$ K5 ?, \  @' e/ ^; H' r$ q

  71. ' `4 m4 E$ E" _3 v2 y
  72. /**
    0 r. e. z* K5 _0 o# @  v4 o
  73.   * @brief  Get the fractional factor of the time the ymodem is called." l* ^$ j5 R  U( z* B6 Q2 b
  74.   * @param  None.
    " b, q$ e6 q- K* r5 C1 @( V9 w# K2 C
  75.   * @return The fractional factor of the time the ymodem is called.* m  d) V- S  j# u, o3 ^
  76.   */
    ' W6 P! P! V  Q: W
  77. uint32_t Ymodem::getTimeDivide()
    . e7 [! U  g0 D' N- X
  78. {( N" M- }1 L# F, [
  79.   return timeDivide;0 }2 m1 g) U( n0 s. G9 c' O0 {- |
  80. }* r9 {4 M  i5 k$ i9 }
  81. 5 ]! A; T' S* }- ^
  82. /**
    ' C: z) y. B3 J2 k3 b# }8 N
  83.   * @brief  Set the maximum time when calling the ymodem.6 N7 \4 Z( Z; a& Q+ G. F
  84.   * @param  [in] timeMax: The maximum time when calling the ymodem.5 r  ~- f+ ?& e& i$ h- E5 m  c6 q% T  ?
  85.   * @return None.
    # `# T" `7 a1 e7 [: T; w( {
  86.   */
    * _) ^7 M3 z3 {* p1 ~6 `  c
  87. void Ymodem::setTimeMax(uint32_t timeMax), r2 w( _4 l9 v. j/ j+ b
  88. {) I# _5 |3 C  O
  89.   this->timeMax = timeMax;+ P& w" f( p: U4 B3 Z: Z
  90. }/ m% ^* E) X3 f) t
  91. # L& p7 @9 A, g, G# V1 y% Y; G
  92. /**1 m4 K) P, |. [9 A: X" t
  93.   * @brief  Get the maximum time when calling the ymodem.5 S6 P, n" e# D& E3 V/ T
  94.   * @param  None.# M  f* |% ~) W& A9 p1 t
  95.   * @return The maximum time when calling the ymodem.
    , X- w+ O4 X5 B- u7 }# n& ]' m
  96.   */
    ; N* g# w2 `+ Y# T
  97. uint32_t Ymodem::getTimeMax()
    ; y- L+ R+ K2 ]7 e3 e& C" @
  98. {  i% O, t: h9 `7 `+ D
  99.   return timeMax;# r( Q. B4 O( F* L0 S3 i% D
  100. }
    4 S- Q0 r' j/ K
  101.   E/ U: c! U0 R3 O0 d- o
  102. /**7 |/ W0 \, x, T6 A$ d+ i
  103.   * @brief  Set the maximum error count when calling the ymodem.
    5 _2 f1 f* y6 c( `" O' e
  104.   * @param  [in] errorMax: The maximum error count when calling the ymodem.
    1 l( j: Y9 Q- V6 N* s
  105.   * @return None., W7 F( i0 _5 a7 s7 p/ \* b- x
  106.   */( `3 g' g1 Z+ a6 J+ g- [! E
  107. void Ymodem::setErrorMax(uint32_t errorMax). ~0 X8 x4 O* {3 K1 }* S
  108. {2 j$ K7 P9 j* H2 o$ A- _
  109.   this->errorMax = errorMax;
      n+ Q2 `# Q0 ]* h. U/ T0 w
  110. }' O/ B# V7 u3 o) B" K
  111. " ^& ]3 D0 ~; a8 {; X
  112. /**
    6 c  G) J) }' d# R( f
  113.   * @brief  Get the maximum error count when calling the ymodem.
    6 n( ^2 o7 W) I9 W1 b* w+ J
  114.   * @param  None.
    ) f5 F/ ~/ @6 k# g" \
  115.   * @return The maximum error count when calling the ymodem.( q7 l2 _: r4 C7 o" P& {7 F7 q
  116.   */
    / T+ a4 T5 a% t" a5 z/ c& C% T$ R
  117. uint32_t Ymodem::getErrorMax()( M  f& ~! ]3 m( D, O
  118. {
    ; ]9 y' L% Y0 x1 ]$ @
  119.   return errorMax;
    5 w0 o( s2 ?( h
  120. }) g4 j8 x+ j4 s; W. ~
  121. ; ~7 X5 w4 T  E: J
  122. /**8 K) T& `1 E" C% ]
  123.   * @brief  Ymodem receive.
    9 a7 r! i. ]4 t6 I
  124.   * @param  None.
    " Z# I: [! C- U
  125.   * @return None.
    1 z4 P; \" n, Q' U
  126.   */
    # v2 G6 e0 F5 K0 P* T' i5 O3 @+ T$ d
  127. void Ymodem::receive()2 _8 `6 I7 I& o
  128. {
    4 y" V8 B( {8 N( {
  129.   switch(stage), ?4 K9 z2 B% A! k# h* |
  130.   {5 j7 c: l% ?+ B
  131.     case StageNone:
    # {1 [# V/ A6 o- \: c5 r
  132.     {4 k* A% w9 f7 ?8 ]
  133.       receiveStageNone();
    9 o2 Z6 N, c- r9 D

  134. 7 M. a& F/ y  R3 l& I
  135.       break;. P1 E" S4 A" v% \" p
  136.     }
    & S( w  r; e! G" n  W8 p( Z
  137. 4 @3 @1 q& E2 r8 T
  138.     case StageEstablishing:
    8 o( m, I* |4 I
  139.     {) |* C( L; N5 k; H3 P
  140.       receiveStageEstablishing();
    : V6 ?$ W* b/ J. u4 d0 K( W
  141. ' ^9 `) W( \/ \
  142.       break;
    $ u4 \6 T, h' Z4 ~" O9 E# B
  143.     }0 W% k# p$ R7 A& y6 U

  144. , I' l2 y/ B6 [0 c8 q& d: t6 j% Z. F
  145.     case StageEstablished:
      z. d9 i5 s: b  l  f
  146.     {
    ( A( k, x' W; C/ d% ~3 F
  147.       receiveStageEstablished();
    - v' N* G+ O" i9 G0 U

  148. . R1 Q. B! c3 e4 H1 h3 B5 W9 Q
  149.       break;
    $ A& x% z( M& X& Z8 v' ~. E: m9 o
  150.     }6 v2 b* [  x) E$ m7 n
  151. $ u, l; a5 |- m5 d: p$ k5 l) n0 Y
  152.     case StageTransmitting:: }/ X2 S) E: b% _! Q% u3 c
  153.     {$ o- b/ R( Q# h
  154.       receiveStageTransmitting();
    2 }( a: o) f. z, R
  155. # y2 J6 G" x: L% `: a" z% g- I
  156.       break;) N2 X& y! Y" Z* z, {
  157.     }
      c- Z% v5 X, f- ^9 L, R- s' d

  158. / H- s; }* O( f2 D" q% M" N) @
  159.     case StageFinishing:
    6 n) o6 c3 g; ~4 J
  160.     {
    % G8 _3 W4 Q: e- p! W
  161.       receiveStageFinishing();6 j3 j) L% ^- t4 Q! p, n: V4 R8 e

  162. " \. f+ p5 e. D0 R
  163.       break;+ b% A2 J1 J7 H) j/ I# e
  164.     }
    " D5 B8 a! x' s  Z; F0 \

  165. 6 D/ s. V/ N, P: Z
  166.     default:+ {  n7 J* U# u9 S+ i
  167.     {3 M7 M0 R! P, D) j( ]) j
  168.       receiveStageFinished();
    6 @8 g% J" S) P- B; z
  169.     }
    , N" Z& i/ z9 ~- f0 `6 H
  170.   }+ S6 X- K8 c* x9 o1 t2 {
  171. }, o5 u8 ~  F# Y5 I7 z" i% W* g0 G

  172. ' H9 {' _/ {$ C2 p5 n$ k1 s
  173. /**9 W: O* |9 f3 a# W
  174.   * @brief  Ymodem transmit.
    " b; T. F0 _& B. J) p4 D+ h
  175.   * @param  None.
    + _* D$ j$ r6 D% Z! e
  176.   * @return None.
    & {% ?4 n, V) v) X! |
  177.   */
    ; a; t  p: \: C8 h
  178. void Ymodem::transmit()! C; h$ ?; v6 R) q, z, Y
  179. {
    # C$ y( P# M( u7 }- F* Q
  180.   switch(stage)
    4 Y8 b, j( I/ _( `  _
  181.   {- C% H4 B# P1 e4 p3 l. I4 M
  182.     case StageNone:
    . }& t7 z$ k/ o( D9 ?. c9 Y
  183.     {. [( u5 s/ }! A1 `+ [
  184.       transmitStageNone();% p. N/ }# {) Q, I
  185. # o2 }# ~/ z% U. r: k% z* \  D
  186.       break;
    * \0 \3 e% h4 ?8 I' c2 c
  187.     }; d5 F0 y7 {6 I. n
  188. 7 Y  `" z6 G" w* N3 ]) K2 a
  189.     case StageEstablishing:
    4 a* W2 C. [; q
  190.     {8 [$ O! Z9 p7 e2 a2 G: S
  191.       transmitStageEstablishing();* S' t- {6 `, V& E3 l1 Q9 A! N. S
  192. ; l% K; X; M8 f+ p5 x/ f8 Y
  193.       break;
    8 c! K7 L8 K9 f. N
  194.     }
    . H+ {. P$ T6 Z9 J. d# N# k( V

  195. , }( z. K) w: h
  196.     case StageEstablished:
    . s2 u! Q6 ~$ `+ t$ W
  197.     {4 l0 G5 {0 }: _3 B$ H" S
  198.       transmitStageEstablished();. v) z: e3 v; z* Z1 B) F2 }

  199. , ~) U/ b8 [# t+ [# j" f. h6 n
  200.       break;
    : L  r) j$ K! d0 U* U) j
  201.     }/ z) [0 s7 H( P$ U. f7 {5 l
  202. - C! s8 B, s! b+ G
  203.     case StageTransmitting:% G/ V/ C5 M  K0 P- C
  204.     {; L' S' ^" B; `7 o; P  F2 a" {
  205.       transmitStageTransmitting();) L. @3 a& F( O  }0 M; i  L
  206. : F* m6 ^6 N+ a$ K! J4 K  q
  207.       break;
    & m& h: P& ~) h/ L" L9 S9 F
  208.     }
    3 j* N/ F2 P" B8 b# n$ v
  209. % }, @0 E8 V; i( j, \
  210.     case StageFinishing:! d6 t; `+ m% \
  211.     {
    % Y% \" X; Q' r. x
  212.       transmitStageFinishing();; q1 p- V% c, d
  213. 7 e; C7 L. d/ e3 {
  214.       break;
    & D( F& O; a: s# @' Q
  215.     }! a6 \+ Z# P$ ?6 m% z: Q, K& U
  216. * A8 T& _: t. ~# d; K
  217.     default:0 l( H# N1 I/ Q
  218.     {
    ) P8 D9 m, b+ _) g0 s) x- L2 ^
  219.       transmitStageFinished();
    4 j2 a- O! t$ N
  220.     }
    8 N7 I9 f  Y3 y
  221.   }
    . p3 Z% {( ]# S9 J' o; z0 b
  222. }% Z9 M  ]3 L: t* Y5 X
  223. ) n  ~/ u- J, B6 U0 c5 l; s
  224. /**
    & b) K( l( j* E* I
  225.   * @brief  Ymodem abort.
    * o' Z- B8 h' h  ~# B
  226.   * @param  None.
    * z9 g! A+ F9 l0 j
  227.   * @return None.# O% {" R8 u* |% _2 k
  228.   */
    2 C& l" ]3 D7 u3 D. a' f$ ~7 r
  229. void Ymodem::abort()& m, f* ~5 e3 U
  230. {- s' C$ `! M- U! E9 a$ [
  231.   timeCount  = 0;
    2 F% h# b5 N  G7 i; _: i, p  A
  232.   errorCount = 0;
    / _/ @1 u# |0 A1 c3 e# O
  233.   dataCount  = 0;/ @2 i: A( r" R9 {3 s
  234.   code       = CodeNone;
    . v" {% o- N5 f0 K8 v) k6 V: \& ]
  235.   stage      = StageNone;
    - k$ M) L& d; z
  236. - }) ~3 s0 h8 Q/ G. {$ k- A3 |
  237.   for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    5 J% ?: ~! G! I& w$ r
  238.   {
    6 P* U! c- x' J3 }" v
  239.     txBuffer[txLength] = CodeCan;! z" W: Q5 m5 m& B9 R4 l3 a0 G' x/ \
  240.   }5 S. Z* p8 I% i  `
  241. . n) h) f) @5 ]9 W4 O4 [7 N( I
  242.   write(txBuffer, txLength);% Z" l3 X" S- B  d, ]9 L* e3 G* x
  243. }
    ! m% U8 y- K# F- r$ I" t  z

  244. 2 ^) O6 E9 X- S8 e9 R% c
  245. /**
    % E2 c- V5 O4 z6 D/ z1 t. V$ M' \1 W
  246.   * @brief  Receives a packet of data.: [; o# g) z0 O
  247.   * @param  None.9 n6 C% {3 @2 R1 r9 l& X
  248.   * @return Packet type.
    8 h& [3 m: `% F+ r1 O; I
  249.   */- S  Y0 V5 m7 j* Z, g6 b: f
  250. Ymodem::Code Ymodem::receivePacket()( o9 `/ y# U( i& D
  251. {, d% a" |; H. K. m
  252.   if(code == CodeNone)
    / M* ~) Q7 @' D+ q6 D5 H
  253.   {" Y  m, }; G! i  h
  254.     if(read(&(rxBuffer[0]), 1) > 0)
    " Z* A  m) N9 q9 [. u4 n' p
  255.     {
      i" e# _7 I0 K, A0 U3 S! p1 I
  256.       if(rxBuffer[0] == CodeSoh)
    + ]0 n1 u% s) w+ N) E8 b, i
  257.       {) M/ ?+ |! l: X  e* ]
  258.         uint32_t len = read(&(rxBuffer[1]), YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 1);3 m) m+ P2 [/ p9 X9 a8 X
  259. $ c6 E, D. j4 v, u+ \9 [
  260.         if(len < (YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 1))
    , v% X( t( o& Z# s% U6 W; h! \
  261.         {( a. m2 a$ y1 G! m0 L
  262.           rxLength = len + 1;2 h1 J9 k0 @  b3 C5 C( }6 \
  263.           code     = CodeSoh;  L( M2 ~! J7 R; e, d' e& x

  264. 1 |" `8 a# o/ I/ P* Z
  265.           return CodeNone;
    5 T* K7 N1 Q, Q  T. g2 L# c
  266.         }
    $ q8 g& t) j' G/ U9 I6 p1 ~3 j
  267.         else
    4 ~$ u! x7 f' d& J3 w  Z$ l
  268.         {+ d4 E" \: M7 j9 N* ]. _
  269.           return CodeSoh;8 F& q  u) ?" P3 ?1 t( M8 t" Z
  270.         }' e9 X5 e+ K( v3 H. M( D
  271.       }) i$ A; F9 B( j; `
  272.       else if(rxBuffer[0] == CodeStx)
    / X! \5 E8 F# T, T2 N
  273.       {7 }! }8 c: S, ]2 O: ^3 w
  274.         uint32_t len = read(&(rxBuffer[1]), YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - 1);* F, f, \7 E" Y2 k

  275. : \( n" E: ^6 {' W: u& a
  276.         if(len < (YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - 1))) s$ o& d0 Y- J" b
  277.         {( ~+ f6 F) [; ~9 z
  278.           rxLength = len + 1;. k/ }: k/ j: C4 X; S0 c+ q# v6 q
  279.           code     = CodeStx;% U8 E/ _, r# }- _  O! A$ W9 h3 }
  280. * [7 E* u- A" k2 W  _: m- w
  281.           return CodeNone;
    , R& ^6 Q/ o5 S7 R
  282.         }
    " n% X3 |3 @; E+ k0 _4 o
  283.         else
    7 Y0 R4 ^0 O- u) h1 `
  284.         {
    2 i. R6 T% ?! K$ x
  285.           return CodeStx;7 @/ _% l; }$ S: Z, x& N, _$ ]
  286.         }
    $ f1 F, R: p# q7 {
  287.       }
    / J: T4 i- M' E& c: p) @8 q. A
  288.       else" q# m, R  m. [$ K* ?3 g" N7 P. ]
  289.       {' u! k0 V% [0 U7 b: r
  290.         return (Code)(rxBuffer[0]);' s3 A. `+ F& C4 S" f
  291.       }. _2 R9 z0 D( C4 @9 g2 r
  292.     }+ Z8 \2 R: j/ ?& e# z
  293.     else8 j& u% g7 R3 [7 W
  294.     {
    / R0 }  m4 [3 `( s
  295.       return CodeNone;
    9 \7 u( K; \. {4 g! {/ R
  296.     }1 Z5 g1 d1 P7 d
  297.   }
    * n, S" L3 [6 ^4 b7 t  V, E
  298.   else
    6 v+ I; \  d; u- _& a9 d
  299.   {
    7 `( q8 J4 A) E( B! i9 Z% n0 j
  300.     if(code == CodeSoh)+ E" c+ \& P9 M  Y$ H
  301.     {8 h$ Z+ c0 ?" D" {" Z; _7 ~% q: c3 t
  302.       uint32_t len = read(&(rxBuffer[rxLength]), YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - rxLength);% @; m( j. q. Q! C% g

  303. : p1 h5 a6 f+ }5 ]7 t) ^
  304.       if(len < (YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - rxLength)). E% {# h3 m4 L' K6 ?
  305.       {3 w3 |0 |2 u& _. X' S. f* \2 j
  306.         rxLength += len;0 B+ K& W7 N" t& g; a
  307. 5 M1 G* C: ?4 \1 Q3 h, z) Z
  308.         return CodeNone;" M' L  e3 @3 ]4 T
  309.       }8 H( x9 l' B. c# {+ C+ L4 H
  310.       else
    $ G" I; Q. W2 J: c5 ?" b
  311.       {4 Q) ?7 O5 ^. `# W
  312.         code = CodeNone;) Y9 O7 L  k. @. H: x0 U

  313.   {' n2 l9 {! J: G- p
  314.         return CodeSoh;
    3 k- H* P1 C5 K  U
  315.       }
    2 h$ B+ k$ i( k
  316.     }* s4 X+ F( P) n" z" ]. T# l! W4 q
  317.     else if(code == CodeStx)
    3 n  G. t0 G! \" G* s" ~$ f
  318.     {. n* i. U# h) a; [' E
  319.       uint32_t len = read(&(rxBuffer[rxLength]), YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - rxLength);  R, e+ Z  ], p+ l% [
  320. 1 K' ^6 d3 s9 B5 Q
  321.       if(len < (YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - rxLength))
    ' s  n6 K$ d, Q6 N( M
  322.       {
    6 t+ z/ }3 z- h& D( G0 z7 m
  323.         rxLength += len;4 Q2 U. o1 Q; X  r( H
  324. 0 ]: `  ~3 U/ a) [, ~1 [7 S: T5 L
  325.         return CodeNone;9 n3 Y! y/ V$ f, R4 {: I
  326.       }% g- G! x6 F; S6 J$ O2 ^' B
  327.       else
    7 w1 K4 O5 }9 C3 U$ y
  328.       {" F  x" H" ^2 f0 g0 x' w: ~" E
  329.         code = CodeNone;
    : O$ ?1 E: t6 G! w6 o

  330. 3 W6 u" R6 d' [% G- V- D
  331.         return CodeStx;+ E9 v/ `0 L8 e& c  `
  332.       }) T% M9 w! J1 r$ x+ o, L
  333.     }) Z. j9 f9 V) i9 J1 [
  334.     else
    ( @) X/ Y! [8 d1 Z
  335.     {0 h* ]3 }. p7 F# X0 O, ]
  336.       code = CodeNone;  A% c7 B# ?6 g# i% G- W6 w
  337. 5 p7 f' }+ p. V
  338.       return CodeNone;
    ; x4 l, W9 E% {2 ]
  339.     }
    0 I* w$ q- i# k2 o, H2 a
  340.   }
    1 g& V- w3 n6 D2 Z5 P
  341. }
    # A& p2 S6 ]+ m/ f! ^7 G. B" H
  342. 6 R; Z  z- Y1 s9 Z
  343. /**
    5 W& \) G- ^+ v
  344.   * @brief  Receive none stage.( l! p( ?5 K% i! [0 c% `
  345.   * @param  None.
    % y2 c6 Z9 }5 M
  346.   * @return None.
    $ [' r! ~0 |0 w* z7 D! y
  347.   */9 `; z2 d0 a, \8 F7 d
  348. void Ymodem::receiveStageNone()6 ^9 L& ^3 _7 b; Y' f6 b! x& U- n
  349. {
    " {1 M% Z, W' D( W5 ?1 ^
  350.   timeCount   = 0;/ m7 V) R" y+ z. ^* v+ o) }  M' _
  351.   errorCount  = 0;# z0 j* g5 ^5 o6 ?; i4 h
  352.   dataCount   = 0;, u# o( ]$ R( q: M9 ?3 H* Z9 W, F$ L
  353.   code        = CodeNone;7 E$ _1 Q0 t" A! }
  354.   stage       = StageEstablishing;4 ], d  |1 V; ~4 j: `' a
  355.   txBuffer[0] = CodeC;0 f' w% A$ B0 T6 d! u* {
  356.   txLength    = 1;
    0 D# ~& Q  j. C" {4 W
  357.   write(txBuffer, txLength);
    # M9 R0 Q3 q( r( f
  358. }$ {( \4 w  e* Q1 f

  359. 5 d5 O7 g. K9 }0 ?; d9 ?$ B
  360. /**
    # C% r" l9 P% V* v& d
  361.   * @brief  Receive establishing stage.
    6 m+ E$ H, Z5 ^3 {5 J9 z
  362.   * @param  None.
    - V6 A% [4 _% W0 Y7 t6 M% d
  363.   * @return None.6 Q7 S; d' Q4 f
  364.   */
    ! K: c% K3 e+ G
  365. void Ymodem::receiveStageEstablishing()$ A: X) T: \; L+ h2 r4 f9 r! u
  366. {
    ! l+ N9 U2 `* d3 f( s$ N) o* Q
  367.   switch(receivePacket())# P& ~! Y- V1 F- v0 s! d
  368.   {
    ! ^1 y1 P" ^# w: b
  369.     case CodeSoh:# R$ C. m; v' N% ?
  370.     {
    ! E, J7 {* A5 B# J% ~2 Q. d( m
  371.       uint16_t crc = ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 2]) << 8) |! q( S! A* ^2 A9 j
  372.                      ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 1]) << 0);. w( o5 h$ p0 L2 ~
  373. $ ^0 Y. J$ E1 t) G# u
  374.       if((rxBuffer[1] == 0x00) && (rxBuffer[2] == 0xFF) &&
    + V2 u) p; X. K2 s8 q. a* Y
  375.          (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_SIZE))), j9 B+ [; m( T3 S- P
  376.       {6 K% R) }: i$ [$ E
  377.         uint32_t dataLength = YMODEM_PACKET_SIZE;# T2 i* i* N: E: V- _- I

  378. 1 D3 Z$ |! Q5 i( b7 o
  379.         if(callback(StatusEstablish, &(rxBuffer[YMODEM_PACKET_HEADER]), &dataLength) == CodeAck)
    & r2 |  e: u, N# a! d+ Z
  380.         {  I* e4 Z% @# X2 _& G! u& v7 Y
  381.           timeCount   = 0;
    ; F9 Y9 R# [) r3 j9 h
  382.           errorCount  = 0;* v5 {. T7 h/ \1 c, b  |% W
  383.           dataCount   = 0;1 v+ M( j3 ^0 V2 d
  384.           code        = CodeNone;
    % h- D$ w& @" w4 H: x/ c4 P* p6 X. T
  385.           stage       = StageEstablished;
    ! Y+ f0 J, q& d+ Q( o0 K, J: V6 S& o8 {
  386.           txBuffer[0] = CodeAck;
    / x: B) t- @; j' S# y3 l
  387.           txBuffer[1] = CodeC;* T. i8 T' @/ u- k
  388.           txLength    = 2;
    + j! y' {: ?8 j. I0 |; K3 J; d
  389.           write(txBuffer, txLength);
    - X# `1 Z) n, d) y
  390.         }
      q# H& H; S6 M. L& {, N
  391.         else
    1 ]( s5 n& s3 V  c; R7 Y5 ~* Y
  392.         {
    3 i! j4 f- j1 W3 ^- @
  393.           timeCount  = 0;. O8 r* Y" X3 X* W: K) |! ?8 T
  394.           errorCount = 0;
    , @$ O6 I  @' Z( h7 Z9 w. U
  395.           dataCount  = 0;* s6 {, g: @. g! {' y, @. ]3 g! b
  396.           code       = CodeNone;5 }7 j: T2 z: O' h0 J# R' f
  397.           stage      = StageNone;
    ( |4 y. d% x) f' Q

  398. 4 E6 p& M) p) ~7 `( h6 @: I
  399.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    ! i/ Z' K8 z+ c' @/ d) a3 z
  400.           {0 i. m' w1 M% N+ ]0 H
  401.             txBuffer[txLength] = CodeCan;& D+ A1 b' ]  }/ s1 q% I9 H: x3 Q4 h
  402.           }
    8 M2 Y% K. ^1 L6 U, i. H& i

  403. $ v+ [7 N. D* K, X  X2 d
  404.           write(txBuffer, txLength);
    % S- V& q9 L! K- |6 q" n9 P
  405.         }. X9 B7 f& F8 N" h
  406.       }
    : o# e7 d6 Y7 L/ r2 P2 r
  407.       else* ?7 R$ W8 g0 ]- v, E3 v+ X
  408.       {
    - H9 g' l" {- \* s: j8 @
  409.         errorCount++;4 |2 C2 k) a. J* v0 e; G' _
  410. ) c  i0 H( H. v  Z
  411.         if(errorCount > errorMax)# W7 A3 c+ W$ @0 X  }' M. w
  412.         {
    . o% M) E- p' F2 X! N
  413.           timeCount  = 0;
    . B, ~4 G' S$ _1 p) v' G' p! t/ _
  414.           errorCount = 0;# `% k7 ]6 o" D' d. G
  415.           dataCount  = 0;3 U/ i) l, H  ^/ {+ `; L. d: R) G
  416.           code       = CodeNone;
    * O0 t1 C, Y8 |- j6 G1 K
  417.           stage      = StageNone;; l3 x8 x/ ~  C) Q
  418. 1 ^- X6 F5 F/ n3 K0 N
  419.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    1 g- L+ K4 l, s( D
  420.           {
    & M% A/ U  X9 f. [5 e
  421.             txBuffer[txLength] = CodeCan;* g  \- U: p* U  {
  422.           }# |3 j. w2 ~( c6 M; H6 b

  423. & z+ c; B% O# U& Z9 S# O9 S) ?8 ?/ Y
  424.           write(txBuffer, txLength);
    7 h  s5 ~' T& X  o" t
  425.           callback(StatusError, NULL, NULL);# P' O* y5 ]' Y9 n2 [
  426.         }5 }% s3 C- [$ q, |: [( k+ d
  427.         else
    " X3 |) u4 _/ P0 Q6 P! S
  428.         {7 n+ j8 {: E8 u3 Y6 F
  429.           txBuffer[0] = CodeC;
    9 x& x, c5 s$ x9 y4 x
  430.           txLength    = 1;( T8 _4 z7 c. D6 z7 x# K; x( B, L
  431.           write(txBuffer, txLength);9 a8 ~. Z9 j9 \& }
  432.         }9 r( `4 L) G9 k" x
  433.       }
    " e# K# l; g7 |$ S/ r2 i: P

  434. + @9 g1 P7 a& L
  435.       break;
    3 G- S0 G2 [: [. R0 g) X
  436.     }
    + ]. \' h3 G4 t8 {8 a8 M, o' u
  437. 7 c, R8 k7 _& c; \) }1 e
  438.     case CodeA1:
    * S1 m- Q' U& @/ p# Y" ~
  439.     case CodeA2:
    , z- t! m7 @( c+ c/ U% A
  440.     case CodeCan:
    2 L" M+ J1 J- \+ ~4 P+ R) y8 }
  441.     {& b9 e  h% S( h6 ^
  442.       timeCount  = 0;' p4 i' W) r5 ]# I8 O9 V9 i2 r# i
  443.       errorCount = 0;
    , w8 k$ U7 H9 c4 {* q5 n" Z
  444.       dataCount  = 0;
    5 g+ v$ O& d2 _+ ]6 Y) Q& z  h
  445.       code       = CodeNone;
      d3 q( N7 X  C! @8 T9 L. q# [
  446.       stage      = StageNone;" a) V7 d2 a3 H& Z, s  w
  447.       callback(StatusAbort, NULL, NULL);
    5 F, N$ O! z) I# I

  448. ! L6 ^- T! l; U8 z* g/ B
  449.       break;
      f8 }" R1 P$ G% ?* o
  450.     }
    : k  Z; e- [) y& U9 T- ~
  451. 7 ?& c+ Y! p# Y- E2 y+ f. @
  452.     default:  M' x5 {* }" A* l
  453.     {5 g+ ^* i4 F3 K
  454.       timeCount++;
    : C6 k2 x" P) k# S0 m* I/ |* W

  455. ; v+ \4 U" w5 Y4 X8 |5 N& y
  456.       if((timeCount / (timeDivide + 1)) > timeMax)+ T* F. {) ~9 p/ W0 u
  457.       {- I4 N3 L! d9 l5 V
  458.         timeCount  = 0;
    " E: r) Z4 [6 Y' d
  459.         errorCount = 0;% Z: G3 h, E; F) p7 b' ^6 |+ }
  460.         dataCount  = 0;3 g1 F. `; ^: E9 u4 {4 ~
  461.         code       = CodeNone;
    + S# B; K" n: X7 Z
  462.         stage      = StageNone;
    5 B! E2 y  ^0 D, Y, z6 R( m- [
  463. ( U, o' S. S8 C0 I3 Y+ _+ ~8 k4 F
  464.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    + J# _) s" v" P
  465.         {. _* P2 o" @& z$ y# c" Y' f7 A, j
  466.           txBuffer[txLength] = CodeCan;1 y+ z) q* ]$ Z* P' T8 u
  467.         }
      E( F  d  i- A! d
  468. 7 F3 ^3 F% q2 d7 z9 t# ~
  469.         write(txBuffer, txLength);
    % P& x. ?, t7 K* F2 ]+ [) H) I! P
  470.         callback(StatusTimeout, NULL, NULL);1 L3 v/ e! f  d2 M( z8 V
  471.       }
    6 |, m# C, S" T# E4 k. ~2 Q) {% Z
  472.       else if((timeCount % (timeDivide + 1)) == 0)
    . A0 a; s+ r9 T% N
  473.       {
    " I% n2 |: e7 K1 i1 F6 q: D
  474.         txBuffer[0] = CodeC;
    - A. w$ C. c$ _- Y
  475.         txLength    = 1;" F, n. a3 ]2 S" ]0 u+ |
  476.         write(txBuffer, txLength);
      ?( b* J6 ^% Y
  477.       }1 q9 C0 M1 q" {, E  e0 j8 m
  478.     }$ q9 ]# {* J% |( Y) m% B
  479.   }
    / H( J3 X& N: F
  480. }
    2 T3 I! a' R! A7 K) ?1 |/ S
  481. % V) C0 E! M; [3 Z. T
  482. /**2 }9 _% R9 |2 H+ f. p" `7 |
  483.   * @brief  Receive established stage.$ i, v! J' c  S# ]6 ^' g
  484.   * @param  None.
    ; L2 c& u$ I4 b/ s* h* w- b
  485.   * @return None.# B! D# B6 ]6 W5 I0 N- c
  486.   */- |- _! j( K& V- J- E
  487. void Ymodem::receiveStageEstablished()
    ; }/ Z, W& a' o5 |: A- ]$ X! P) }
  488. {4 L$ L  [/ T0 {" q) {( D  g
  489.   switch(receivePacket())+ m& v% p% H) I' \
  490.   {8 Q, \+ {& Z) `0 i8 S7 a) s/ O
  491.     case CodeSoh:! Z  \  Q: v4 Z: u
  492.     {
    3 B% y& p$ c* r8 [1 V2 O5 Q. \8 L. k
  493.       uint16_t crc = ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 2]) << 8) |7 Q4 D& n. [/ m) F
  494.                      ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 1]) << 0);9 g( G8 ^. ~5 x0 r9 H0 A

  495. , D6 K; x' z$ c2 U; S/ i
  496.       if((rxBuffer[1] == 0x00) && (rxBuffer[2] == 0xFF) &&, q5 k& k+ h. b1 {" K
  497.          (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_SIZE)))2 {0 A$ c2 u/ y
  498.       {
    0 ~- c% I% |& O0 S* ^1 |/ M8 y
  499.         errorCount++;
    9 l2 I( e, \. f- d+ P0 T# c
  500. " `# W' C6 |2 V
  501.         if(errorCount > errorMax)
    8 u* ~" f3 G, [6 o, T4 S* c- K! V& H
  502.         {/ R/ E1 g. ~( q6 x# q: Y! |7 W
  503.           timeCount  = 0;
    8 ^$ T9 P. n$ p3 d+ H
  504.           errorCount = 0;
    2 n- R9 L8 E  w. _5 c3 C) Z
  505.           dataCount  = 0;
    . e5 x. g; [! C4 }. f
  506.           code       = CodeNone;1 h. w5 d3 ~! Z* Y2 m4 m" ]' r
  507.           stage      = StageNone;
    , a, i1 X( W7 |7 f3 m6 b( Z

  508. ( f7 G6 w- ^. f8 M6 K
  509.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)! d# H! R5 H* a( Z
  510.           {
    7 F+ p/ z( a2 @4 n- z* ^
  511.             txBuffer[txLength] = CodeCan;
    ! C- f2 J: {7 `* q
  512.           }
    3 z* y2 _; v$ D  u
  513. $ \' m* \" M4 S
  514.           write(txBuffer, txLength);
    6 M( L( ~7 {& k' t! J' r% j1 x
  515.           callback(StatusError, NULL, NULL);) r0 Q! F8 v7 h0 g+ F, A7 ^- e
  516.         }
    + Q+ H$ z. ]: u1 G) R7 {
  517.         else, D/ ~2 O% [. Q9 e$ g
  518.         {) |0 w5 T6 }/ S
  519.           txBuffer[0] = CodeAck;
    , P/ ]" Q5 X, |, X" ?2 Y: X  @# Q
  520.           txBuffer[1] = CodeC;+ F+ f' v4 N: y9 d
  521.           txLength    = 2;& v* V* O" C. \7 ^5 h% b$ i
  522.           write(txBuffer, txLength);
    ' ?$ D9 F5 _+ U! w' |8 s
  523.         }9 a  p) E6 s5 u
  524.       }
    ! d6 _- U0 Z# s+ V; `
  525.       else if((rxBuffer[1] == 0x01) && (rxBuffer[2] == 0xFE) &&
    # B1 P% M9 S& D2 F* F
  526.               (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_SIZE)))
    $ d0 k, n8 L1 x3 A! _0 z& ?
  527.       {
    ; c: }+ b+ _$ `: B
  528.         uint32_t dataLength = YMODEM_PACKET_SIZE;
    4 Y3 d( L$ r) F7 b

  529.   m6 |6 ]4 T; m" w) i
  530.         if(callback(StatusTransmit, &(rxBuffer[YMODEM_PACKET_HEADER]), &dataLength) == CodeAck)! Q2 \0 w9 L) Z. _/ s+ O3 f
  531.         {7 Y/ J+ \, g! Y  [5 y5 K
  532.           timeCount   = 0;% P* g, g; C' ^/ j
  533.           errorCount  = 0;
    & W4 e! i) c* {3 s2 `1 {
  534.           dataCount   = 1;
    % C* P) f- K9 l! m( X4 t$ X% U2 K% p
  535.           code        = CodeNone;1 w$ o( v. f4 R- s' V  x5 \
  536.           stage       = StageTransmitting;
    9 b4 }, t. w2 {
  537.           txBuffer[0] = CodeAck;5 h/ |7 r% x8 z) I! r! |3 s1 a" m) V  L
  538.           txLength    = 1;
    ' d; \4 j) c, P/ ?  R6 r
  539.           write(txBuffer, txLength);
    7 l- O' L3 w* l
  540.         }
    , ]0 E1 f) f& R6 u" j0 ^% W0 f/ u
  541.         else  m% I: t7 Z% U! F
  542.         {5 H  \. \: u/ f$ V! B2 f
  543.           timeCount  = 0;/ v1 _  s0 R3 a5 M+ X( Y1 v
  544.           errorCount = 0;( P: K6 m; e/ b* T* w# U- r
  545.           dataCount  = 0;3 |( {+ V) e6 o0 y0 \
  546.           code       = CodeNone;) o  {8 U4 O1 l8 Z
  547.           stage      = StageNone;
    ; k, b7 a2 y+ U( F

  548. 8 c3 T0 `/ M% O2 |4 S. `! ?  \
  549.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)2 k, Z) L* F% u" h8 k% m
  550.           {5 B4 q+ M) ~! }' z, i" x7 H" s
  551.             txBuffer[txLength] = CodeCan;
    ' h! D, b- c# v( q
  552.           }
    1 u+ A: [# U9 }: L6 V

  553. 2 O7 `. k0 @  P% y. f
  554.           write(txBuffer, txLength);
    - s/ [  J* [* N; C% C7 S' z
  555.         }3 P& x$ m  S0 h' E8 u1 n3 U
  556.       }$ G& A" r1 o  F: }# P1 I
  557.       else
    ( K* V. X( B2 P1 K3 u* Q0 X
  558.       {
    - u! Y7 ?" E; A+ D  V+ z5 V2 q
  559.         errorCount++;- x8 H, F/ l( Y9 f& i
  560. 1 \+ f* q( ^; g- ]
  561.         if(errorCount > errorMax)
    $ m3 w1 E/ s$ }& h7 O
  562.         {
    / V- J3 L* q3 P3 i! l
  563.           timeCount  = 0;
    0 S1 ]  G( t1 e
  564.           errorCount = 0;
    ! Y  M& {- h/ _/ _2 P& x7 F4 a
  565.           dataCount  = 0;
    . ]% {, q- W: c4 _' J. @+ R7 m3 x
  566.           code       = CodeNone;$ w. a( L( N: n7 y
  567.           stage      = StageNone;& a" }+ W5 Q+ i* x% Q/ M/ G
  568. 5 i- C7 c; [4 I# P/ e! m
  569.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)5 @( M2 ?4 {* s# A) J
  570.           {
    , Z, u" Y$ O6 J* j; d
  571.             txBuffer[txLength] = CodeCan;
    0 j' B5 |4 S- p, {) V% _2 f- q" W
  572.           }) A4 B$ ~& }1 r1 f. H! T! I3 q- B+ V9 z

  573. % f9 m5 w- X7 K# {1 z
  574.           write(txBuffer, txLength);$ t  l' \4 d/ p8 P0 b% r% L
  575.           callback(StatusError, NULL, NULL);
    " ?  j- J& @) e7 r
  576.         }1 [) G2 N' Y) s1 _( K
  577.         else- c1 L( v/ f  C4 t# j0 E
  578.         {: ]  X5 R' ^/ e; ^. q/ \
  579.           txBuffer[0] = CodeNak;
    . G; @5 p+ m7 w6 R
  580.           txLength    = 1;$ S# U8 H8 J' L: i# C- n
  581.           write(txBuffer, txLength);
    6 V# P$ @$ w. X3 e
  582.         }
    8 w/ ^( c- y# {2 N/ u& n) n
  583.       }
    " K6 R8 d: Z& n# N

  584. ' ?6 G! @3 k" Y; }2 B, \- w) h
  585.       break;' U: E) R/ ]; C( q/ Y6 P+ N
  586.     }* n0 s  b5 Z) m6 y0 R, b3 M$ R

  587. ; @3 C' m" D6 C' i; @( _& z' Q
  588.     case CodeStx:$ a: U; a5 w7 U; s& s
  589.     {
    ' [9 E( o5 e1 D7 c" f9 L# P
  590.       uint16_t crc = ((uint16_t)(rxBuffer[YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - 2]) << 8) |" S$ B8 w+ e1 \5 ]3 H' P! z* X# n
  591.                      ((uint16_t)(rxBuffer[YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - 1]) << 0);
    , T; }" I1 i. r9 r( U

  592. * H" J% u4 j* c- m" I( F
  593.       if((rxBuffer[1] == 0x01) && (rxBuffer[2] == 0xFE) &&
    7 O/ Z, k% \  g3 U: a
  594.          (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_1K_SIZE)))
    ' L* J' S5 j+ C; X4 {8 a
  595.       {4 N) S& U( p7 w, @" ]) W: e
  596.         uint32_t dataLength = YMODEM_PACKET_1K_SIZE;4 B1 D! \7 I1 U. `2 W

  597. / Q! Q- T' E! q5 i; u# K
  598.         if(callback(StatusTransmit, &(rxBuffer[YMODEM_PACKET_HEADER]), &dataLength) == CodeAck)/ o1 C' V! P. u2 N) ^
  599.         {
    " I- Y% l" `, F0 y* a
  600.           timeCount   = 0;: Q  Y9 Y1 o& P5 A. N6 q4 N
  601.           errorCount  = 0;; R+ T1 t# q& i4 G
  602.           dataCount   = 1;; j0 {3 Q$ W, u. C9 S. q& b
  603.           code        = CodeNone;
    5 w' q+ M* f, ^9 H
  604.           stage       = StageTransmitting;
    , O2 _$ D% O9 p8 M
  605.           txBuffer[0] = CodeAck;  S- Y3 e0 W+ Q" u% E
  606.           txLength    = 1;
    5 @- h: r' u* Y5 {8 K% x
  607.           write(txBuffer, txLength);# [) {( T8 O: g
  608.         }8 B" O! \+ q# J
  609.         else4 ]$ z' F, ^3 U* g5 r- u$ ^+ p
  610.         {
    6 o4 ^$ u" ^" S
  611.           timeCount  = 0;8 ?9 M# Q" J- I+ H9 Q5 b( h( x
  612.           errorCount = 0;0 o5 t* V# b+ h+ B1 N
  613.           dataCount  = 0;4 n4 N9 z! G0 J3 a# @
  614.           code       = CodeNone;2 o5 p- j1 |% D# O& ~2 [; _
  615.           stage      = StageNone;; p& A- l* P  {% \: P+ \" c' Y

  616. / `$ D/ r2 {" o; z4 o
  617.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    ! j- H6 u1 Y! A5 N* g1 a* W2 c
  618.           {
    / N' {) a* Q. w# V
  619.             txBuffer[txLength] = CodeCan;/ ~* O& f3 N% U+ }4 l7 k' v! j
  620.           }
    2 \8 K$ d% ^  ~' z; D1 d" t. ]

  621. . y4 W6 r' O' r0 O7 u( A
  622.           write(txBuffer, txLength);
    ) b6 z5 k+ d/ Q: A* a2 }( f
  623.         }
    ) N' _+ G% l( i* ~
  624.       }( V) z& e. A; I# h
  625.       else
      o( \9 E- v7 ?, `2 x
  626.       {
    ( e2 T- n: ?0 F# T$ Y
  627.         errorCount++;, z! O) ~+ G: u) E8 g+ A/ z* n0 Q. l
  628. / a7 I2 G% h4 ]. s( @: F
  629.         if(errorCount > errorMax)
    9 D2 C( I8 g( k2 b  I
  630.         {+ X5 \5 z) l" J
  631.           timeCount  = 0;/ i8 s' w$ J9 V6 |* c2 A0 V( X
  632.           errorCount = 0;
    + v8 f6 _4 s& P+ J- ~5 h8 k  ^
  633.           dataCount  = 0;
    / @" o& G) F! k
  634.           code       = CodeNone;. t' f4 }1 r; L6 I  D, P
  635.           stage      = StageNone;
    ! z2 h7 V) m' f  H8 M

  636. 4 m1 L9 w2 W1 s1 }  k
  637.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)+ `8 g( u, I& \5 U1 I& D
  638.           {
    . D! w# ]0 b7 v4 _
  639.             txBuffer[txLength] = CodeCan;
    - V) z1 a( o% a: ~$ i+ Y
  640.           }9 j/ c4 o3 {' D  H
  641. 4 @. g6 Y% i, \2 T9 {! \
  642.           write(txBuffer, txLength);: U3 g8 R) g) T" ^8 C; a$ w; \
  643.           callback(StatusError, NULL, NULL);0 @. k. T  u) e, w0 }
  644.         }
    ( X) m- [  X- e: l7 [
  645.         else/ E& F8 L1 u5 B1 v
  646.         {
    - J3 {6 Z+ V8 t0 q
  647.           txBuffer[0] = CodeNak;
    ; l6 x( k2 E0 o' B2 ~' y' `
  648.           txLength    = 1;  k$ i" }) ^! }0 V$ }- {! @
  649.           write(txBuffer, txLength);6 j! x) i/ C, B5 {; }4 G
  650.         }
    & |3 j/ Y8 z) k' }
  651.       }; Q- q$ I( ]6 q% @; \) U0 ^

  652. 0 O0 _/ _' S. F' D! V
  653.       break;, L8 k! y$ k! B% j8 y' `, @3 f
  654.     }5 Y+ ]1 J5 K2 |& r; l5 z1 u# Y

  655. 8 D* _4 ?: |. U$ ^4 Y
  656.     case CodeEot:7 K2 }4 ^! z7 a2 s
  657.     {0 C4 ]  }- X2 N. ]. m
  658.       timeCount   = 0;
    4 b  p. ]: C4 K* E, Z6 b. k
  659.       errorCount  = 0;9 ]! t2 A9 t& F' S6 n% E
  660.       dataCount   = 0;! `1 c4 M  j: h" y: }- N! r
  661.       code        = CodeNone;
    0 P- a# G' g# _& A
  662.       stage       = StageFinishing;! L$ r% n2 I3 M8 O
  663.       txBuffer[0] = CodeNak;
    & z+ `# ^2 I( E0 @% V
  664.       txLength    = 1;, k9 n: ?$ P, K+ i1 u
  665.       write(txBuffer, txLength);
    / u) o* K  @  U1 l9 B% y
  666. * x% T2 A$ y- }6 o; ^+ I
  667.       break;; F" C8 O; f* C# ?3 _! E
  668.     }) J# ]2 l. g  r1 d/ _- P

  669. 1 P$ L) X  d( B% f5 G, C" R
  670.     case CodeA1:! I- B' `# H8 P$ r, k/ n) g& g
  671.     case CodeA2:' D0 H" }! e, k  U4 F( S
  672.     case CodeCan:- v/ J+ Q& v& l. _6 I
  673.     {9 I4 u3 h% l. `, a. b, [4 {3 ?
  674.       timeCount  = 0;
    ( c1 N* W! p9 N0 k& `6 T
  675.       errorCount = 0;
    : p% ^% f" Q9 E/ K
  676.       dataCount  = 0;/ l+ L$ ?" H- }* J
  677.       code       = CodeNone;
    $ }' v8 q: Q+ m+ o( C2 M) t4 Z
  678.       stage      = StageNone;- ^/ b' C+ I: h. K3 a4 [
  679.       callback(StatusAbort, NULL, NULL);8 V# }  k. d1 x6 V/ ?, L2 f; h" l5 k

  680. / d$ a5 b1 ]$ j% m+ I% k
  681.       break;
    * {# L" g5 k7 i5 o/ N
  682.     }* m) l5 v+ X4 z& g! ^
  683. : Z' p$ d# O2 F5 U. K9 I- E
  684.     default:% v" P" s& z( O; {; l0 `1 x! X; w
  685.     {+ l* _7 m/ C- s5 B5 Q& q3 x
  686.       timeCount++;
    + w" P* p+ o6 G$ E  |: x5 d

  687. 8 T% J! d7 m3 V- b
  688.       if((timeCount / (timeDivide + 1)) > timeMax)
    " i/ s% c% p) A8 L' {7 C
  689.       {  N1 G' ?( r, P1 E& l
  690.         timeCount  = 0;1 L+ t( K/ N8 X. E' Y
  691.         errorCount = 0;
    0 N; V( Z# g. M) Z5 J8 A2 s' A
  692.         dataCount  = 0;
    # m6 z& _" ^  j
  693.         code       = CodeNone;
    2 j, ]0 }1 Q: }! O/ Y, q  m0 b" U
  694.         stage      = StageNone;6 U; a/ Z& A, \& U) n2 Y
  695. ' X7 d+ l8 d6 f8 D% e- `
  696.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    + x( @; s; A! c; X3 |6 G
  697.         {
    7 x  ?: Y" @2 s% n0 o5 G
  698.           txBuffer[txLength] = CodeCan;
    0 Q! b! [  H( J& ~) K, _# n
  699.         }# d& q' n- Y% m" w) N2 X

  700. 1 m) b" ?$ x" @
  701.         write(txBuffer, txLength);! x) J4 x2 J$ P$ I
  702.         callback(StatusError, NULL, NULL);
    . J/ @% e8 r9 P' a; @
  703.       }
    . l$ }, \8 n/ o: m
  704.       else if((timeCount % (timeDivide + 1)) == 0); ]# p- F3 p% O: D3 N; S
  705.       {% a. x6 @" J$ w$ X
  706.         txBuffer[0] = CodeNak;
    4 P- c/ H- w% r! Q6 I$ z
  707.         txLength    = 1;  i: g, f- O# l4 B2 d
  708.         write(txBuffer, txLength);
    4 J* h0 g* X- y7 d
  709.       }
    ! ?- \' p( ~( H$ C% d
  710.     }
    ' e. r: C1 f/ T0 l$ H2 K- x0 D1 H
  711.   }
    0 P2 A. A6 e* y- X; E7 k
  712. }, J2 T5 h" I) q  f3 V$ V: d  B

  713. 6 E5 Y1 D* t/ r
  714. /**+ F/ I4 T" O9 W, C8 T: p6 S
  715.   * @brief  Receive transmitting stage.: s0 a/ J1 m5 Z0 w
  716.   * @param  None./ }2 q1 c1 g6 f' Y+ N- M) H1 [
  717.   * @return None.
    , V3 h8 S) |/ v- \3 G' {  v4 I& Q
  718.   */
    ! c, g0 r" D" ^, r
  719. void Ymodem::receiveStageTransmitting()
    9 R7 r2 g% w1 c
  720. {
    1 J1 q% J3 S; i+ K
  721.   switch(receivePacket())
    ; k2 G/ Y5 U- c; D* C3 H+ f
  722.   {
    5 m1 @- Q$ X5 A
  723.     case CodeSoh:3 T8 q* K* _1 u, A
  724.     {
    ( E/ ?0 H3 W# b8 [8 i4 f
  725.       uint16_t crc = ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 2]) << 8) |2 [6 \( u! [0 q6 K) X) f
  726.                      ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 1]) << 0);  l2 ~8 _/ t/ _

  727. ( H4 L$ Y: K* p$ b' Z- t
  728.       if((rxBuffer[1] == (uint8_t)(dataCount)) && (rxBuffer[2] == (uint8_t)(0xFF - dataCount)) &&7 @5 c2 Z( S+ h0 c" a
  729.          (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_SIZE)))
    7 m0 B# i7 B& R0 b$ _, W: d- I
  730.       {2 E' M. \, f  m: c& r$ W
  731.         errorCount++;9 ~6 m; x' V0 O
  732. 7 }! n; W+ w( T
  733.         if(errorCount > errorMax)
    . `6 x. B5 h- l) |, l/ K$ O( ^) y
  734.         {  `* y7 c% z( o% E  J: l1 E
  735.           timeCount  = 0;
    $ t' w3 P& k' E8 P+ {
  736.           errorCount = 0;
    , L+ f; ~1 k2 p1 O" S
  737.           dataCount  = 0;
    ; }; h" H7 z* q' M1 k
  738.           code       = CodeNone;
    - T& \! s; _4 @: }! d
  739.           stage      = StageNone;# F+ h" m0 a5 E. q3 n

  740. : ]9 d0 `% C* f) i) P+ |
  741.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    - b7 a/ D2 M" T! H' {) n
  742.           {9 p( n6 Y) t4 O% V; n7 o
  743.             txBuffer[txLength] = CodeCan;
    ) H5 b4 D: s+ F
  744.           }1 k* Q1 M# n& q, a0 @1 _
  745. ! _, X* `1 ]. k  A4 z) f
  746.           write(txBuffer, txLength);5 t6 c% c# X- g7 b
  747.           callback(StatusError, NULL, NULL);2 o  x0 Y/ m2 ]: U7 M
  748.         }- h6 K% B+ E' _! o
  749.         else# D- q) [. E( H, a
  750.         {5 u/ y& S' q! ]% ?% T9 e* ~
  751.           txBuffer[0] = CodeAck;
    / s% H# i& p* h" Z+ V0 P
  752.           txLength    = 1;
    5 @- [  J- v- ]
  753.           write(txBuffer, txLength);, c- N/ G% H( }8 D( v+ W+ z
  754.         }$ _6 y! F/ O7 L% q; K
  755.       }9 T% g0 r) S+ k* |
  756.       else if((rxBuffer[1] == (uint8_t)(dataCount + 1)) && (rxBuffer[2] == (uint8_t)(0xFE - dataCount)) &&
    ' e* j! o; \* ^  T& w3 Y
  757.               (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_SIZE)))
    & w2 }" `- T0 d. Z- n8 d
  758.       {  n8 l4 R% Q/ L6 j$ p, I; M, R
  759.         uint32_t dataLength = YMODEM_PACKET_SIZE;7 P, T1 [9 {9 c7 {$ d; L$ P0 o
  760. 3 B6 Y  m  O6 J6 |0 T. p
  761.         if(callback(StatusTransmit, &(rxBuffer[YMODEM_PACKET_HEADER]), &dataLength) == CodeAck)3 q" U7 H6 m& L& P9 j" E# }% `
  762.         {" k6 h0 U" O, F  G7 w  t9 i1 J& ]
  763.           timeCount   = 0;
    7 x) T) O( f. f( g1 F
  764.           errorCount  = 0;+ b& \2 m; X9 ~4 F# @
  765.           dataCount   = dataCount + 1;
    2 ^3 o. ?' ]  t3 ?! c
  766.           code        = CodeNone;
      ^# b2 ~* R# _9 `
  767.           stage       = StageTransmitting;) o. J2 ?0 w( N( o% W
  768.           txBuffer[0] = CodeAck;, l5 a2 h- Q- Q2 }
  769.           txLength    = 1;7 Y- B+ l& _6 f. X- o
  770.           write(txBuffer, txLength);
    # Z% L* q" Q( [- c4 O3 ~4 x
  771.         }8 n0 E' D! v* m
  772.         else
    , s% y1 v, M4 U) u
  773.         {
    . l2 K' w2 I3 Y* ~. [/ j3 m
  774.           timeCount  = 0;+ ?; ]/ P! Y; e3 s# L! I* e) C, D0 L
  775.           errorCount = 0;
      |: i% }1 k& }7 r
  776.           dataCount  = 0;; f5 Z3 A2 D6 r/ O
  777.           code       = CodeNone;
    - A+ N( z3 Q3 w8 `$ S
  778.           stage      = StageNone;
    ( m) |" z; b; M/ l/ [' \- ~
  779. 2 W4 l6 ~6 W* ~% n9 v8 t2 ^: X
  780.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    3 X# B8 x2 v2 J4 h1 k0 Q" |
  781.           {& t. a4 ]  U- h/ n  G/ M& J
  782.             txBuffer[txLength] = CodeCan;
    ; f8 r* K/ b! E  s
  783.           }
    # X2 r: R8 R- y6 O0 `/ L& ~
  784. , k, Q; ~: ~7 P  z. \% G% {
  785.           write(txBuffer, txLength);8 [  G, |* V+ C5 A3 r) y( e
  786.         }
    & T# k; b6 F- R
  787.       }  J" d$ |( @% g4 O
  788.       else0 y  q7 a6 e+ G
  789.       {
    ) k" r) m5 `! q! y* w
  790.         errorCount++;
    2 h2 T& S: U0 b- ^* w
  791. 8 D6 w1 d9 D2 Y
  792.         if(errorCount > errorMax)" Q* f( N' O& e( y
  793.         {/ b# c8 j/ M3 V/ g3 `5 L; i
  794.           timeCount  = 0;) A5 ?9 P( r$ C, h
  795.           errorCount = 0;6 i6 O' u+ O7 v
  796.           dataCount  = 0;8 K# q2 Y; ]3 n0 o
  797.           code       = CodeNone;
    " m( a6 q0 L' C8 d, l0 e( s; V
  798.           stage      = StageNone;
    9 T* i( C9 j% S! b  I8 Y
  799. & `6 w$ H- c: z
  800.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    1 b$ d4 I" r' D' h% d2 {
  801.           {& C5 C7 C" m' ?2 M1 d3 \$ M
  802.             txBuffer[txLength] = CodeCan;
    1 w  x! z5 L/ e$ A) ]
  803.           }3 P/ \/ j0 T( g. o9 a
  804. ) P( ^7 Y) n5 D. K$ F2 N1 v
  805.           write(txBuffer, txLength);
    5 g. r* C9 H8 ^& g
  806.           callback(StatusError, NULL, NULL);$ [3 |; f! \4 e* {+ E8 a
  807.         }
    ' ^# _; k3 q9 s
  808.         else
    ( I% P5 }! z: ?0 X( o' i# l/ {
  809.         {! j6 L  M8 q4 ?3 \0 ]
  810.           txBuffer[0] = CodeNak;
    + J8 J) H" Z) z4 k/ ]5 v6 a
  811.           txLength    = 1;
    7 a9 h( r: Q3 F
  812.           write(txBuffer, txLength);
    " [8 s1 W7 t  w5 z" Y# S
  813.         }
    ; q7 z- O7 F; V3 ?0 d0 d( ]' U4 V
  814.       }; f6 C  y$ ]: F. }+ W
  815. 4 @4 H1 O8 l9 T
  816.       break;
    * I0 m  `* d' s3 G
  817.     }
    5 f% y- n5 C; A$ }- d7 y
  818. 5 l7 U5 X& _3 j' ]9 ^
  819.     case CodeStx:
    ; ~* Y7 ^0 `. p$ I6 Q
  820.     {& @7 O! ]) Y# i# B( ?  q
  821.       uint16_t crc = ((uint16_t)(rxBuffer[YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - 2]) << 8) |) k  ]* D, M" l0 K
  822.                      ((uint16_t)(rxBuffer[YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - 1]) << 0);
    2 e0 }3 m1 c$ f0 D8 l

  823. / m9 j# p  o( X; r; U  \$ s
  824.       if((rxBuffer[1] == (uint8_t)(dataCount)) && (rxBuffer[2] == (uint8_t)(0xFF - dataCount)) &&; n' r7 a. A& k6 y
  825.          (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_1K_SIZE))); X5 p  g. }6 v0 p
  826.       {
    " C- H8 C3 a2 e; }
  827.         errorCount++;
    ! O7 K1 ]- A, j6 S8 k
  828. ! ~& a. s8 B% {  k0 R
  829.         if(errorCount > errorMax)4 J' |4 `+ @. L) h' S! ]0 Q
  830.         {. b' b4 m7 O4 ^0 `% g3 X# v* P
  831.           timeCount  = 0;" q' F. p( D1 k: [. _! y
  832.           errorCount = 0;
    3 E( R! v) Q  ^( n
  833.           dataCount  = 0;4 n% L' E5 Z. d1 F$ e  Q: k! X% t
  834.           code       = CodeNone;
    7 C) e8 l, [3 x) O4 b" K
  835.           stage      = StageNone;
    : a# s# y0 e; `* m7 P* d) Q

  836. % a( v% k- x* d* J: X2 N( [- z
  837.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    + N" \1 G. H' I' Z
  838.           {$ x2 Q) Z# p: s- D! w; W2 |. c
  839.             txBuffer[txLength] = CodeCan;: g# b1 v( j; n
  840.           }- T& J2 n% ~  M* |3 g: n
  841. - `6 n8 {5 G4 E
  842.           write(txBuffer, txLength);+ u% f1 E3 i6 R
  843.           callback(StatusError, NULL, NULL);$ W, {7 N- e% H( q7 ^
  844.         }
    , d; n' }: g" Z) M; T$ I
  845.         else& v1 ?; i5 }- `
  846.         {& u( }# U3 i2 |& j+ B6 }0 T* t8 U
  847.           txBuffer[0] = CodeAck;
    0 E6 L) j  m) G9 V
  848.           txLength    = 1;
    ! N( g' e* y/ N  J% Q
  849.           write(txBuffer, txLength);9 \5 H/ D/ f: f$ H
  850.         }* O% N5 P' Y; Q* M' a
  851.       }7 Q6 d! w, ?6 U3 k$ B
  852.       else if((rxBuffer[1] == (uint8_t)(dataCount + 1)) && (rxBuffer[2] == (uint8_t)(0xFE - dataCount)) &&" ]0 E  y  ]( r5 z0 d
  853.               (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_1K_SIZE)))8 K: e$ `0 ^0 X7 V) O7 Y& z3 N  f7 E
  854.       {9 T8 L) D" g8 A" o
  855.         uint32_t dataLength = YMODEM_PACKET_1K_SIZE;
    , p$ q' @: Y$ |8 D& _9 \
  856. 0 Q! b2 @1 l/ L. d$ ?( ^1 ~
  857.         if(callback(StatusTransmit, &(rxBuffer[YMODEM_PACKET_HEADER]), &dataLength) == CodeAck)
    # {! ?  c% a* [+ x! o( p# ^) N4 ?
  858.         {/ T& s. R7 u, n6 _% j
  859.           timeCount   = 0;
    , {5 A' _* ^- _/ W  n% ^5 m; Q
  860.           errorCount  = 0;% W$ d& s2 o! S
  861.           dataCount   = dataCount + 1;8 k% b7 b0 j# M; c+ D) [# o
  862.           code        = CodeNone;
    3 D' i$ ~0 e3 j+ l6 `
  863.           stage       = StageTransmitting;
    % ~& u1 w, q+ N5 K; m
  864.           txBuffer[0] = CodeAck;
    ' L* Z7 V$ n9 h
  865.           txLength    = 1;
    ( K, [. ^5 I9 f3 }9 O
  866.           write(txBuffer, txLength);& J4 c' l# t: B4 V% n" \& K  U6 S# Z
  867.         }
    8 {6 K3 }' L% a9 I
  868.         else- p$ h  D4 ^. O8 ]  w
  869.         {7 }, p) K0 A- p5 w  u
  870.           timeCount  = 0;
    ! q0 W' x2 T! J3 t
  871.           errorCount = 0;
    + V* @- k) o6 V
  872.           dataCount  = 0;5 n: U, C/ u# V: b; `! ]
  873.           code       = CodeNone;
    ! A6 U" q7 A1 z. b: d- j. Y
  874.           stage      = StageNone;
    ) T& M. n8 K+ Y0 _8 D& B) m

  875. $ R) z5 S* u, k+ Z% x/ \
  876.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    * F( u9 ]+ h) F, ^7 ?( M5 o; J
  877.           {. |' f. L9 f6 E1 f" p
  878.             txBuffer[txLength] = CodeCan;
    - M7 ^/ Q$ j: m9 f* I
  879.           }
    0 i8 ~& L5 m6 u

  880. 0 u( p4 m0 u! T+ c% H* |' Q
  881.           write(txBuffer, txLength);. V3 V6 c: y; N  C
  882.         }
    % C% n+ {3 t, d" r; K! @  ^
  883.       }: K# i) r8 w- ]
  884.       else
    2 n. c: f, r7 b2 Y* M0 U
  885.       {3 A- [" v! T) V+ F
  886.         errorCount++;) l9 h% F8 L, B) j. W- H) F

  887. ( v- T: L, R6 b( Q  S
  888.         if(errorCount > errorMax)) _* \+ _" B2 Z/ m. u+ y* {
  889.         {
    1 O( W/ m, v& j+ q  R2 f7 z* X
  890.           timeCount  = 0;; u8 W; r/ G2 I  K% @4 z
  891.           errorCount = 0;
    ) D# W: p4 d: F( j$ H" L  E
  892.           dataCount  = 0;1 z6 |4 p  g7 O3 n
  893.           code       = CodeNone;
    6 d. [& F4 q0 ^4 w: W
  894.           stage      = StageNone;
    8 s* C  V8 r# J
  895. # p2 L9 m9 z* ^# e4 Q6 c( {' E7 J( W+ L
  896.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    , h% C  y* L3 `+ c4 c1 {& n
  897.           {. u. x4 Q  _6 ~( W; M3 c- p
  898.             txBuffer[txLength] = CodeCan;
    $ ^) c: u( R3 p; R9 Z" t0 b+ b
  899.           }
    4 ?8 P9 {$ t. ~" H" I1 t

  900. ! b5 q9 |& f+ |3 c- ]
  901.           write(txBuffer, txLength);8 C' G- |6 F/ w+ f" J$ g" ^: u
  902.           callback(StatusError, NULL, NULL);# ]3 p. w2 e) J, U" \% ~
  903.         }/ W' Q7 n8 |2 P# G! l" Y% D
  904.         else
    8 ]& J. ?4 f+ B0 L1 F
  905.         {
    + O$ O# a1 K/ @% m0 O& k; k5 u. r$ P& {
  906.           txBuffer[0] = CodeNak;
    ( t# V  F- ?3 D! w
  907.           txLength    = 1;
    5 m. d6 ]! k9 L6 |+ }
  908.           write(txBuffer, txLength);
    . W% k7 D' x2 }$ N3 b. _& t
  909.         }+ b, e8 |" |( J3 D
  910.       }
    1 E/ b. P6 ?( C" [. f
  911. 3 Y* {; P% w: y) I" b, U
  912.       break;
    2 F8 L) N6 d" z+ j4 [" y+ \8 P
  913.     }
    $ z% M: G2 Z3 K$ U% V1 ^2 j. \
  914. . p6 k# M7 h7 P' ~" ]6 W; Z7 P2 z
  915.     case CodeEot:0 g  m" o2 D$ Q& l7 o' ?
  916.     {
    9 s" j' v, N- ?/ E; Z: }
  917.       timeCount   = 0;
    1 S5 ~6 s5 E" M; u% \
  918.       errorCount  = 0;
    2 H+ b, _/ y0 r, G7 S
  919.       dataCount   = 0;
    2 G: d8 t6 u3 r" ]- Y' }
  920.       code        = CodeNone;
    3 A7 W0 {3 R9 |+ C: v) |2 A( O' T
  921.       stage       = StageFinishing;4 h" O6 |9 j. L8 u+ a5 o* ^
  922.       txBuffer[0] = CodeNak;
    / l1 s" |! p. I0 h1 b
  923.       txLength    = 1;
    , G6 I$ C% S: @+ a
  924.       write(txBuffer, txLength);6 H% ~) e7 L: i) P
  925. # V7 i6 L# F  W% p' D# D
  926.       break;, l( B! k& \, a5 c/ P5 l% r7 P
  927.     }
    ( ~2 w% y+ q0 R: T. f% Q& i: Q
  928. , [' V: b' W8 Z5 ~" ^6 c, [# V# i
  929.     case CodeA1:$ w3 r0 l2 Y( [5 H7 I! E
  930.     case CodeA2:
    0 C  I* y: H+ [' |4 }; n7 ]4 W
  931.     case CodeCan:$ I5 ?8 u! N% ^4 y
  932.     {5 b& }" D/ }9 X
  933.       timeCount  = 0;7 [7 a" u/ L$ Y1 f/ C3 f2 O
  934.       errorCount = 0;! X( y0 `7 q) [7 }. U
  935.       dataCount  = 0;
    , a% p" g9 @6 H1 W; M8 P, @$ d
  936.       code       = CodeNone;
    ) J' d! k- H: e
  937.       stage      = StageNone;6 o1 b4 {  }) t. K3 ~! Q
  938.       callback(StatusAbort, NULL, NULL);
    2 U% z' P0 Y) b3 Q2 S: ^

  939. % L; @# X' ~1 u( W  T* j
  940.       break;( a0 O2 P6 p$ ?( a5 n0 ^. R5 d
  941.     }$ a  b% K: |/ E

  942. 1 b9 w2 {4 i# D: ^
  943.     default:6 s$ C; m; ~$ v
  944.     {* `! Y) F! a8 h; G$ c9 [
  945.       timeCount++;9 i3 I$ K5 }4 T3 a  {  @# K/ P8 [
  946. ( v  t! y$ Z. r5 C  d* k% j+ z
  947.       if((timeCount / (timeDivide + 1)) > timeMax)
    & j2 E- C* S( L4 q2 x
  948.       {( E9 U/ a" u; m2 {, P; {
  949.         timeCount  = 0;
    ; Y9 N; j8 ?2 x# N  ~: b& L* }: }
  950.         errorCount = 0;
    ' q; z( l6 `. y( |6 q5 ~/ x
  951.         dataCount  = 0;
    4 j" |" _3 u  B
  952.         code       = CodeNone;
    ; G7 W% p0 }( J
  953.         stage      = StageNone;' @8 b$ [" O* C8 d" ^( n

  954. 6 j$ ]7 `3 \1 x% ]
  955.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++); L6 ~9 _' q/ I& N
  956.         {
    6 h* W5 c* L' ^- X
  957.           txBuffer[txLength] = CodeCan;
    + x. p7 f" |7 J
  958.         }
    4 P7 H; I+ r3 z$ t4 p& A

  959. ' |, K( z/ o% L* P7 j" C& m
  960.         write(txBuffer, txLength);% r0 \$ }( P- G* C7 y7 k2 p1 _
  961.         callback(StatusError, NULL, NULL);- r! [- _9 v' q' y
  962.       }
    - ^7 r" b. ~4 |5 m7 o, J" [
  963.       else if((timeCount % (timeDivide + 1)) == 0)
    & P4 G, E# i0 s6 Z
  964.       {# ]  [3 h& o6 D  V8 G; e
  965.         txBuffer[0] = CodeNak;
    8 W7 `* d5 N* m
  966.         txLength    = 1;  p0 w6 N' s, f+ D; w' a. g3 I
  967.         write(txBuffer, txLength);
    3 B2 K+ j+ h- n; v' O) V& k8 m  ?
  968.       }
    9 u* J; b# Y' G. c# D0 W
  969.     }* D4 W$ P' U5 }- t5 W( `6 x4 W) C
  970.   }4 u, ]' G9 t; i1 C+ b, K/ M% l
  971. }: S% X" t: y, ?' ]
  972. 6 Z, ~. @/ u* k  H; u7 U$ R: p8 ]
  973. /**  |0 [3 x- i/ Y& P. a
  974.   * @brief  Receive finishing stage.) L' U2 Y) \- ?1 Z+ U$ f5 n
  975.   * @param  None.
    ( c# g9 ~+ a  l. {8 T8 K* g9 o# ]
  976.   * @return None.& v1 m! H4 @' m# s3 z# S0 p
  977.   */
    . ~* b) U" b5 m' B
  978. void Ymodem::receiveStageFinishing()
    ; b" N- z' v% p
  979. {/ f5 l" C: o* U1 X& _  [% w) ^
  980.   switch(receivePacket())5 l0 {" {1 b3 D& @3 t; b& p
  981.   {
    9 |) {' k& i6 V8 M
  982.     case CodeEot:
    - j1 H0 q8 U' s6 l7 `) J& r4 ?
  983.     {
    5 V# a7 h/ B6 X; ~6 }
  984.       timeCount   = 0;- @( Q6 ]1 @% \4 C3 T
  985.       errorCount  = 0;" D- y: t6 q; {$ |$ o" V# k
  986.       dataCount   = 0;
    " |0 I/ \" v( n0 g1 s, U# s
  987.       code        = CodeNone;
    , U# `; _, h' c0 T
  988.       stage       = StageFinished;
    1 P8 b4 H: S7 ^! b# T* a
  989.       txBuffer[0] = CodeAck;9 t& x. z  }' f% o' H. j
  990.       txBuffer[1] = CodeC;5 r9 T8 o$ L6 S/ q8 m
  991.       txLength    = 2;
    # ~; f" I' ^5 S* r0 W
  992.       write(txBuffer, txLength);3 v( g, I, Y" b1 b* U- |( k: q$ s) A

  993. 3 L5 Y9 u; \. ~6 ^( C, C/ F
  994.       break;+ i4 ^. a; h- N  a
  995.     }- H% |$ v- g# _9 W

  996. / o, |4 [5 H2 Y: t) M
  997.     case CodeA1:
    - |5 g3 q8 @( ^0 ]; }& h+ E
  998.     case CodeA2:
    ( n' E# T6 y% W: ?/ L  _8 G
  999.     case CodeCan:+ X. {$ I. ^- C5 i/ l5 P5 W! n9 z  n
  1000.     {
    9 u" n/ R# D2 P3 S& w7 D6 b! e3 e
  1001.       timeCount  = 0;
    2 J& Q. \' ~6 r1 c4 Z+ O9 r
  1002.       errorCount = 0;
      `/ o: Y; b! H/ i) K" B0 H
  1003.       dataCount  = 0;4 b' Q* t2 K+ o: u2 \2 p
  1004.       code       = CodeNone;8 l& h% V5 S' D% V
  1005.       stage      = StageNone;
    # ^$ n) n0 }( }# o5 g
  1006.       callback(StatusAbort, NULL, NULL);
    % p- c& e* p6 K  a

  1007.   @8 Y( I9 P; Q& O( M
  1008.       break;
    ( b( F& A% s9 b6 _; u, O
  1009.     }
    $ ]- A7 F: p0 h# e" m3 s5 s( {
  1010. 6 J8 P1 h8 Q! a% ~% X" |# r3 G$ K( h
  1011.     default:
    8 T  c. q6 V$ y% u- ]
  1012.     {
    ! V3 a  @  s; f& Y; s. y
  1013.       timeCount++;
    6 L9 P: P$ [6 r- P0 C
  1014. 4 W+ E: i, P& e- W0 R
  1015.       if((timeCount / (timeDivide + 1)) > timeMax)
    : J) @" \6 f! o. t3 _/ a0 A
  1016.       {
    : `! D# \0 r; D/ w
  1017.         timeCount  = 0;
    : x8 D- O7 P! Q$ y% R! u6 O6 l" g
  1018.         errorCount = 0;
    ( u+ P) j+ v7 z* T5 M' \; O0 }1 E5 T
  1019.         dataCount  = 0;2 R) k0 f) _4 c+ |5 a% i
  1020.         code       = CodeNone;+ C: @. ]1 j" E2 a" P6 N' X
  1021.         stage      = StageNone;- l$ u  }) R1 ?  X$ e
  1022. ( e6 D2 A! r( g8 M0 f5 F9 m4 f
  1023.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    " C- g5 q4 x: Q5 f( W! }
  1024.         {8 ~" Y, x7 a2 R
  1025.           txBuffer[txLength] = CodeCan;6 j8 d8 U1 y9 @  i
  1026.         }
    * D# `. f8 }3 v5 d8 `8 X: n, i

  1027. % s, N$ V% V$ [6 `& K1 Z! D
  1028.         write(txBuffer, txLength);
    & H2 D# D. Q5 z6 Y
  1029.         callback(StatusError, NULL, NULL);) ^! t4 t& ?) b, J9 o
  1030.       }7 W1 C! E+ F& X
  1031.       else if((timeCount % (timeDivide + 1)) == 0)
    ' y, n& h3 Y8 O" _& J# N
  1032.       {
    , L4 s2 L; \% Q9 h
  1033.         txBuffer[0] = CodeNak;
    $ r- G2 o+ n' y
  1034.         txLength    = 1;5 [' h1 P$ }' q: ?) k  ~+ ]
  1035.         write(txBuffer, txLength);( _$ ^. N4 H! k4 e! ]
  1036.       }
    ' a# ~$ g- B+ X! y
  1037.     }; g0 }. N) r' T2 s+ @( B
  1038.   }- c( H2 |: N( Y, B0 k; q
  1039. }
    9 b* a- z9 Z8 ]- I# w! Q
  1040. 3 u6 S$ V1 A* k+ f( T
  1041. /**; U6 g' Z2 i/ h
  1042.   * @brief  Receive finished stage.
    4 D* o9 F" [6 C
  1043.   * @param  None.% M" k* V- {+ [! l5 N, C' e
  1044.   * @return None.
    ! M+ G. E# b, C& H! M% a
  1045.   */
    # Z" u3 n5 c  [. t% ]% e0 M  S
  1046. void Ymodem::receiveStageFinished()
    6 k* ?" e' T. c: Q
  1047. {6 Q& v% t7 |; j' D1 `3 |/ l
  1048.   switch(receivePacket()), V2 y: ^1 Z1 D0 Z  K6 I9 T
  1049.   {6 b6 Q' Y. _4 U5 r. t
  1050.     case CodeSoh:; n* T. t. b. k9 v' N0 g8 Z
  1051.     {
    ' y5 ^5 P1 a- {) ~8 |) E
  1052.       uint16_t crc = ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 2]) << 8) |* X  D7 I' n# v, i) A  R1 `
  1053.                      ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 1]) << 0);( v2 D! w' W$ X, ~- e: s
  1054. 9 r; F2 m5 l7 e. `; i
  1055.       if((rxBuffer[1] == 0x00) && (rxBuffer[2] == 0xFF) &&0 k: P8 t& G- F
  1056.          (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_SIZE)))0 Q" }8 ?$ v  Q* {, k. O0 V( _: G
  1057.       {
    ; K( E) E" M0 F, I* m: R
  1058.         timeCount   = 0;4 U# c" ?  Z! Y: ^5 x. f/ a* L
  1059.         errorCount  = 0;
    9 y" c/ {. J) I6 ]
  1060.         dataCount   = 0;" u; M: a2 t( {+ u# G
  1061.         code        = CodeNone;
    & J  z3 x3 ]! A  O+ C2 S
  1062.         stage       = StageNone;
    3 {% b6 r7 Z9 Z! N2 c& o1 q
  1063.         txBuffer[0] = CodeAck;
    + F5 E6 T+ N' z# G, [' I3 j. F; v! g
  1064.         txLength    = 1;- s8 R4 H" y$ d" }  f
  1065.         write(txBuffer, txLength);
    0 e; l) T7 N8 V9 u* C) k& g8 a( L
  1066.         callback(StatusFinish, NULL, NULL);2 p. b7 U1 k* R1 f0 N% a7 l
  1067.       }$ R9 P7 Y! t9 a& d% U- V
  1068.       else! J2 `  n5 n, P5 U3 y- l
  1069.       {) I/ G7 j. Y; e" x& T
  1070.         errorCount++;$ n) _! ?% t' f% K1 I0 q, y! |
  1071. : ?8 E$ S! N( d% {
  1072.         if(errorCount > errorMax)
    ( ^/ j% t: B, k7 K/ r8 ^7 T; ?; |
  1073.         {
    2 e  @+ O9 t1 h1 {( K2 v0 W
  1074.           timeCount  = 0;+ v. `/ t* _1 F2 k8 h
  1075.           errorCount = 0;
    5 R3 Y/ e$ d, F: v, x2 m6 y% ]
  1076.           dataCount  = 0;
    " N7 w" j, a- L2 u
  1077.           code       = CodeNone;
    ! I# g8 D1 E6 U7 V% f- n0 r
  1078.           stage      = StageNone;
    2 M1 i3 ~4 P! r- J  P
  1079. ! h/ N5 M2 U! v1 {1 q, W
  1080.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)! {$ b* ?: Z/ J# D
  1081.           {4 {) @3 @+ c$ X8 r
  1082.             txBuffer[txLength] = CodeCan;
    9 D$ \. w+ P: C& B! c
  1083.           }
    ) [& a1 A+ `0 n1 N# \4 V' J
  1084. ) U9 n4 L+ E. J3 z9 p- n
  1085.           write(txBuffer, txLength);
    ; a5 r! m" M/ H8 j
  1086.           callback(StatusError, NULL, NULL);
    ; J, ]) [8 F' w
  1087.         }
    * r# d# r2 I* K0 Q6 u
  1088.         else
    * W: }. t/ K6 K# r/ G+ s; b
  1089.         {4 Z$ s" Z9 B- V2 V3 N( ^. w4 O
  1090.           txBuffer[0] = CodeNak;
    1 g' g8 M7 y! g8 h
  1091.           txLength    = 1;7 r( S& `# R0 r' p, E% n, ^
  1092.           write(txBuffer, txLength);8 G9 x# F# _. ]$ h0 G+ y: W
  1093.         }9 t/ ^3 Z9 M8 x
  1094.       }- E1 s& c& b# L$ q8 n/ }, x
  1095. ; o1 e& c$ S  ?  D+ M' j
  1096.       break;
    5 \; X$ d# F; e# {
  1097.     }) K, Q$ o4 R$ i' S

  1098. ) k7 A) u  r( K
  1099.     case CodeEot:0 ^; i' Y9 v* Z' T& v6 e9 p+ }
  1100.     {
      J( u1 F9 D; A+ }
  1101.       errorCount++;/ b3 P: `7 N* u5 i6 [. k
  1102. . N8 x. B" N* X& c0 @
  1103.       if(errorCount > errorMax)
    1 L( U9 o* q! X+ J% V
  1104.       {
    / b6 G: t: G. j) ~
  1105.         timeCount  = 0;
    & v0 `- M2 d) b, J  V1 L( R
  1106.         errorCount = 0;
    / ~, S  V+ G7 M1 A
  1107.         dataCount  = 0;
    : B& ?6 j/ n- B, j. e
  1108.         code       = CodeNone;$ S0 ^5 b+ Y3 }, U" x- a; l  U6 y
  1109.         stage      = StageNone;
    2 w# X0 _4 C0 Y5 s8 V0 \  o

  1110. ' `5 f( O" \. {+ |
  1111.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)+ K+ F, @1 q* \  J8 Q
  1112.         {
    0 R6 t% z/ n" b: y
  1113.           txBuffer[txLength] = CodeCan;5 v& R+ H2 {1 C& `/ @' ~2 X" L
  1114.         }. Z4 P9 J3 n$ @* G
  1115. 5 C6 K) s9 V0 d7 Z0 H6 O
  1116.         write(txBuffer, txLength);2 s  v) f1 _; B% S7 K1 l! ^
  1117.         callback(StatusError, NULL, NULL);$ w% o! y% z8 d  g
  1118.       }
    ' s! i0 d8 X+ Y% L8 s$ ^
  1119.       else8 c" [, N; d$ A
  1120.       {8 x/ T( w: F+ e
  1121.         txBuffer[0] = CodeAck;
    ' j) g& |$ P' k
  1122.         txBuffer[1] = CodeC;
    8 E: x0 }7 X  C, V7 q* S' B
  1123.         txLength    = 2;
    1 U5 |0 T3 P" g  v* a8 L2 q" [+ H
  1124.         write(txBuffer, txLength);  R3 z) p" e6 b3 N! W' r
  1125.       }% i1 ~6 D9 |# `- O# `0 ^

  1126. 2 Z2 g/ [% i! b
  1127.       break;& W% d, P7 V4 R/ i& T( ]
  1128.     }
    4 g, z1 A5 i& H- Z$ F

  1129. * a' P/ h% s- _4 V0 y' k
  1130.     case CodeA1:
    * R/ A  r) }7 x2 p3 u
  1131.     case CodeA2:1 h- ?+ Y( X7 ~. f' E- k! P
  1132.     case CodeCan:9 ]$ c1 _* K: e! C! W! y( b
  1133.     {, T! N: s9 z7 l# D1 o
  1134.       timeCount  = 0;
      e3 n  ~& r. X( W6 X" O
  1135.       errorCount = 0;
      C/ B3 v% V* k
  1136.       dataCount  = 0;, R" [+ A1 V1 m/ ~; d8 A
  1137.       code       = CodeNone;
    ' P1 V7 }* N% x/ D, r6 z
  1138.       stage      = StageNone;
    * s+ h- Q; a) K& U/ U" M3 N7 z$ r
  1139.       callback(StatusAbort, NULL, NULL);2 e6 r8 Z" }/ U

  1140. 5 {% G) v, }$ P6 L) A
  1141.       break;/ p  m6 y# |' H  ~8 Z& \' @3 K
  1142.     }
    ( A4 x2 F2 F4 x" t

  1143. 2 Z( p+ z+ k' k& i
  1144.     default:, B5 \. m- ?( Q. E1 W% @8 b) `
  1145.     {
    ; t, t! H' t7 h+ o/ ^# v
  1146.       timeCount++;
    1 o4 h% j/ }1 P3 x' v5 W9 {( G. t- w
  1147. 0 D) j) `! C3 B9 |% Y5 o$ X
  1148.       if((timeCount / (timeDivide + 1)) > timeMax)
    & _' {$ v  d/ o* y6 H
  1149.       {: y- R% Y( g! L# G" M
  1150.         timeCount  = 0;
    2 d- o6 i, Y& ^- X6 i: W) j* ]  ^
  1151.         errorCount = 0;7 o0 ^& V# J. _  Q% m/ H  w
  1152.         dataCount  = 0;
    / v1 u8 j" t" Q( m+ ~
  1153.         code       = CodeNone;+ x. ]5 a+ ?- A# W0 c5 f
  1154.         stage      = StageNone;
    6 |/ E. v; j! k& W2 b$ z, q& M
  1155. ' h: D- V, g, `+ |5 g* H7 q
  1156.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)9 j( I* S% T" V- J' L. L. K
  1157.         {2 w8 D2 L1 O& }; `) |
  1158.           txBuffer[txLength] = CodeCan;
    9 p2 X% y" H8 u
  1159.         }
    5 h. v5 {4 h9 M! l. U% q6 ^* S4 e2 L
  1160. . _4 `  I% ^& G6 t
  1161.         write(txBuffer, txLength);
    6 P. t- Z5 E" }7 n! l
  1162.         callback(StatusError, NULL, NULL);8 x7 U! ^, P. Y, R+ {5 B& b3 h
  1163.       }
    7 s/ ^) ?3 ]9 e8 w
  1164.       else if((timeCount % (timeDivide + 1)) == 0)/ j1 ^* V/ s) F6 s
  1165.       {! Z1 J# ~; n, H/ t2 f8 c! u
  1166.         txBuffer[0] = CodeNak;! g  _5 h6 @! k' i/ P  {
  1167.         txLength    = 1;
    8 R& a5 \4 S& f9 J8 y
  1168.         write(txBuffer, txLength);
    . G# y, p  ~( G$ S# e% i0 h) S& w
  1169.       }7 t- A* t0 L$ B" b
  1170.     }. G6 F$ ~& C: ^9 \  j9 f
  1171.   }
    : ?7 s2 z/ q! D1 W
  1172. }
    7 G7 ?$ `  J4 m- n  }/ t

  1173. % N  G; V" s* x/ j( o  l
  1174. /**! Q. V6 J4 U" \4 g+ B& _" H' [
  1175.   * @brief  Transmit none stage.
    1 `, n- B, g0 g# s, O# k
  1176.   * @param  None.! ]+ u8 a( ?& F0 q* w5 {
  1177.   * @return None.- h4 I* q. \2 }; {, _
  1178.   */
      b% D5 U4 {6 E9 n6 `
  1179. void Ymodem::transmitStageNone()
    / f' S* W* t: p/ C
  1180. {
    ) _8 E3 I: W& F- {
  1181.   timeCount   = 0;. F- v2 ]/ D$ T# ?2 B7 n
  1182.   errorCount  = 0;
    ) @3 R+ ^0 y, `% V7 W
  1183.   dataCount   = 0;: H7 J& t# j, B% @( V7 u  N
  1184.   code        = CodeNone;
    5 s; B- C5 v7 X3 S8 }8 N( U6 U  `
  1185.   stage       = StageEstablishing;$ ?! Y; Q) z- d  D9 D& Q  s
  1186. }" w/ V' w, O; F' A; j" o

  1187. ' ?+ t. K, N5 U0 w2 _) K
  1188. /**8 X! N5 O7 V# c
  1189.   * @brief  Transmit establishing stage.
    & I* U9 _! U7 ]3 e, q
  1190.   * @param  None.- F6 Y2 o+ n' s! Z: D
  1191.   * @return None.6 E. n5 `! j1 i/ b3 L' u
  1192.   */
    7 I8 `: V# y+ F  c' f) X
  1193. void Ymodem::transmitStageEstablishing()
    + n' h0 t2 m1 z# Y
  1194. {
    7 e/ b7 B% q( ]& w- Z, i
  1195.   switch(receivePacket())
    $ ~. D2 x0 V$ P0 \) O. P
  1196.   {
    " G* Y: j7 f: [" P) p8 f
  1197.     case CodeC:
    6 g+ R# l8 s- l: s
  1198.     {
      y0 o) w! l) r9 S0 T! \
  1199.       memset(&(txBuffer[YMODEM_PACKET_HEADER]), NULL, YMODEM_PACKET_SIZE);* ~6 c7 i' \' ]2 X6 k8 H4 k0 l

  1200. 2 ?! J1 }% R* A8 r2 x4 w# m1 V
  1201.       if(callback(StatusEstablish, &(txBuffer[YMODEM_PACKET_HEADER]), &(txLength)) == CodeAck)4 F; t' Q) H! k( N+ L" Z( L
  1202.       {$ \4 p2 ~- h  A
  1203.         uint16_t crc = crc16(&(txBuffer[YMODEM_PACKET_HEADER]), txLength);: K- Y8 Y- ~8 J( I# i
  1204. # e, ], W3 U/ O( Y; }# ^: I7 X
  1205.         timeCount                                       = 0;
    ; m# Q5 U1 U- T4 D( Q) \$ Y- P
  1206.         errorCount                                      = 0;
    ; P; y" b' U/ `0 R* Y
  1207.         dataCount                                       = 0;8 i! h! ^% l8 C: C. C
  1208.         code                                            = CodeNone;
    - Q6 B9 s5 o) B* Q- N
  1209.         stage                                           = StageEstablished;* i3 F  A- Q% p& @
  1210.         txBuffer[0]                                     = CodeSoh;
    ( e6 f, Y6 K1 C$ _, o) w
  1211.         txBuffer[1]                                     = 0x00;- a: I; N( L) y5 V2 }+ f
  1212.         txBuffer[2]                                     = 0xFF;
    , @& A" P- D* ~) F; }+ d
  1213.         txBuffer[txLength + YMODEM_PACKET_OVERHEAD - 2] = (uint8_t)(crc >> 8);
    9 y; H& P( f) r# j
  1214.         txBuffer[txLength + YMODEM_PACKET_OVERHEAD - 1] = (uint8_t)(crc >> 0);
    ( N% y, C; I6 X( @) l
  1215.         txLength                                        = txLength + YMODEM_PACKET_OVERHEAD;
    % f3 p! X3 k' Q3 i$ }1 l
  1216.         write(txBuffer, txLength);
      f" u2 r+ q. ]4 B* g: g2 ?
  1217.       }$ A4 E" x2 W1 w: ]& D
  1218.       else
    3 e8 S/ |; `: @! O# c0 g) ?$ m* e3 ~
  1219.       {
    % u$ O8 c6 K9 V5 o
  1220.         timeCount  = 0;
    : D# _4 @/ C# K( W
  1221.         errorCount = 0;
    : C; F, ]3 C$ l! l# R$ u1 R- s
  1222.         dataCount  = 0;% u2 @  }; J" _- b" @' k3 a3 N
  1223.         code       = CodeNone;( M; Y) F& C5 P
  1224.         stage      = StageNone;+ o! L8 X) g3 ~0 B

  1225. 6 r# Y* c; O( N, @: s
  1226.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    6 N7 h& @9 k2 h# W2 k% K
  1227.         {
    + e1 n( H4 i2 B
  1228.           txBuffer[txLength] = CodeCan;& O% Q. Y  V  g5 R4 c) s  p. s
  1229.         }$ g1 F, e# x( W& u' ~

  1230. 9 \* R) H5 s. H( M0 P9 r4 i
  1231.         write(txBuffer, txLength);
    / h5 e: m: E: c1 d$ C, z$ i
  1232.       }
    $ u# ~8 ]0 [+ Y+ {

  1233. + T$ c4 O% W& ]
  1234.       break;! D, g2 {/ K) T# N, h. R9 @5 |/ L
  1235.     }
    0 d( U, i! ?5 l+ W2 f
  1236. 5 a" @& H) Z" @. l* ]1 a+ Z* U/ _
  1237.     case CodeA1:
    7 k5 r; D4 y, l; W5 U9 d
  1238.     case CodeA2:
    ; V6 W3 E/ H5 d- ]
  1239.     case CodeCan:
    ' F1 Z, }8 L! y" q) k, n2 y6 }
  1240.     {! S" n2 H6 E8 |& [- f' |
  1241.       timeCount  = 0;
    & H. G7 x" \( Z  J9 \
  1242.       errorCount = 0;
    5 |% k- ]! H, l8 [0 x, f# ]: j8 N
  1243.       dataCount  = 0;* o9 H/ c) ~  {' t) y, u) b  H
  1244.       code       = CodeNone;
    : T  \7 s( [: O6 d$ k: M2 i
  1245.       stage      = StageNone;
      M; j  j9 F: b% c. `  r! P
  1246.       callback(StatusAbort, NULL, NULL);
    2 H+ g5 U& F( V9 u( v
  1247. ; L; U- v8 T& }. u1 f2 n9 Z
  1248.       break;' Z4 \3 \  b0 O" [# h
  1249.     }2 i4 i4 n& \+ B2 `5 ^
  1250. 7 S2 h3 o9 s" l7 N; ?; |/ _
  1251.     default:2 h: z3 R* O, v7 ^. L, K+ }
  1252.     {
    7 {( U0 Y  h" ]9 j9 o, H/ r- J
  1253.       timeCount++;5 V5 ~$ O1 V9 v# R, m% i

  1254.   E+ J" w, p8 f  Q* g
  1255.       if((timeCount / (timeDivide + 1)) > timeMax)" A  r+ Q1 ?! p
  1256.       {
    * x. E8 Y, p$ v3 a1 R  N( |* n
  1257.         timeCount  = 0;5 }$ Y) a. V3 f: n8 x+ d" A" r0 N* M
  1258.         errorCount = 0;
    5 U+ n6 r2 R5 F8 P) U4 Z
  1259.         dataCount  = 0;2 f$ |( u  j% ^2 c6 Z# o
  1260.         code       = CodeNone;
    7 t/ F) U2 l+ y4 |9 C+ \. C) R
  1261.         stage      = StageNone;! [' V- U4 q8 x4 C% }1 }* r$ j. W7 |
  1262. 0 c6 C8 ]% M5 O( a( _3 n
  1263.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    7 `. `. }8 e1 g7 T! ~6 _* N
  1264.         {6 ]! Y3 R* k$ C! A& z! e
  1265.           txBuffer[txLength] = CodeCan;, K. G$ ~5 z# C7 L; w0 x( h
  1266.         }
    * v& t' Z+ ~, H9 |9 M2 M
  1267. 2 h* C) {3 y: W5 g% M9 p! }
  1268.         write(txBuffer, txLength);
    ) D9 B" U) K  m( n2 O$ u6 r- |& V
  1269.         callback(StatusTimeout, NULL, NULL);
    ; t2 f! @, X3 w) Z6 e7 E
  1270.       }0 T" x1 Z5 U& t- v, N- e
  1271.     }
    $ ~. R, j( J8 s& T/ U
  1272.   }
    0 X, B' V* l7 p. |
  1273. }9 s# c  n6 K0 s& g8 M; |

  1274. 6 o& [% ?+ @+ c* S% U3 R
  1275. /**% U3 }  k' |6 N' l
  1276.   * @brief  Transmit established stage.8 ?- S) L3 \1 ~- c3 C; G
  1277.   * @param  None.
    ' b+ w- z! d. `% u& S$ `6 N8 X& J
  1278.   * @return None.
    & n+ Y' X3 u! \* \# C% z
  1279.   */% A- t) q6 q/ y
  1280. void Ymodem::transmitStageEstablished()- g7 g- N; C- H3 j8 F/ z
  1281. {  _& s9 }5 V" r% v% U, i; B1 P. \
  1282.   switch(receivePacket()): H2 R7 z) l8 _0 c3 f7 S5 W9 x
  1283.   {* ~* l, u3 ^; i
  1284.     case CodeNak:
    / [4 x( n) a. p5 k* P
  1285.     {/ n1 Y5 V, ?! d' p9 D. j) g
  1286.       errorCount++;
    2 M2 V2 ~8 T. d9 Y
  1287. 2 V7 Q& X& S0 K
  1288.       if(errorCount > errorMax)9 }- q7 ^- U) H% i8 r7 u! B
  1289.       {
    4 e, i2 p4 i0 \( V
  1290.         timeCount  = 0;" b- p) _( I! A" u+ q4 ~) T
  1291.         errorCount = 0;
    $ Q. f* V4 _. }1 n/ ~; i7 ]2 Q
  1292.         dataCount  = 0;
    , {1 I+ ~! O5 N! c9 Q1 A
  1293.         code       = CodeNone;1 p! y5 u0 a. ?: N/ j7 Z3 z
  1294.         stage      = StageNone;
    # A7 \6 n! a4 F
  1295. ( _+ x: a6 d! t0 Z) U1 g
  1296.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    5 E: O% Q, a' x% B1 b/ @/ o
  1297.         {
    $ b1 }7 ?3 P& i. ^
  1298.           txBuffer[txLength] = CodeCan;
    - T6 F. p1 X/ g5 C; a+ ?
  1299.         }
    0 b/ P7 H+ L  I# p# r
  1300. 1 k- H" r% e# m. F3 _: F
  1301.         write(txBuffer, txLength);! W# w9 ]: f$ \5 ~
  1302.         callback(StatusError, NULL, NULL);
    # M. {+ s9 [% o6 l4 @4 `5 Z
  1303.       }3 A4 V0 J6 F) o
  1304.       else9 P. K' D* }0 |. z
  1305.       {
    : {0 g5 S  w% t& c7 Y  w3 l
  1306.         write(txBuffer, txLength);$ d$ \" W' p9 d: {
  1307.       }
    5 B  b& Y3 I5 {' |$ h8 q

  1308. . f: D# o- T( ?8 O. b6 [* }& ?
  1309.       break;
    4 _) i% D7 }& `4 g
  1310.     }
    : r7 w* F2 h9 ]$ y3 w' W

  1311. " k- O* r! O  O
  1312.     case CodeC:! G* j6 K' D1 z3 O) P, n0 F( E
  1313.     {
    $ Q; n% H0 A& E' w- V. x4 v# @& s$ Q
  1314.       errorCount++;  p  \/ }5 j/ q$ J6 K- ^+ z  e
  1315. ; Q$ ?6 T) ]3 m+ Y) m8 C5 H
  1316.       if(errorCount > errorMax)
    + ?2 [1 M2 s( C
  1317.       {$ Q8 ?  h0 ?# A* }7 j
  1318.         timeCount  = 0;
    8 M! E9 f4 X5 t& \8 Y! _" V; w
  1319.         errorCount = 0;( M- x3 q) U/ b* q( B
  1320.         dataCount  = 0;
    5 J8 ?1 |4 R6 y  ?4 m: t
  1321.         code       = CodeNone;$ p; K5 n) ^6 k4 }- l- |4 Z
  1322.         stage      = StageNone;+ O" j1 }7 Q) B  I- y

  1323. 6 W# a; p' j+ I" {; [
  1324.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    " k$ ~- W7 h2 j4 {% @! N, I% K
  1325.         {
    5 a( v0 }) n" S# X- a& T
  1326.           txBuffer[txLength] = CodeCan;+ U8 m  X$ d0 Q& f: q4 T
  1327.         }) y4 H7 @$ ?! X3 N7 {3 |$ C

  1328. 4 X8 a) X8 S3 ?+ O) C
  1329.         write(txBuffer, txLength);3 x! M& }# }1 x0 q' K
  1330.         callback(StatusError, NULL, NULL);* a. x/ k5 B+ q# f, k
  1331.       }
    + H' |8 G! R: G# T
  1332.       else
    7 m; c, `6 P$ p6 R9 D0 d3 }
  1333.       {7 H5 O1 L$ Y0 S# A) R6 H+ q
  1334.         timeCount  = 0;
    ' s2 g7 s, i1 N; ^/ Y$ [% h4 l
  1335.         errorCount = 0;4 l! Y' `4 _. v1 F/ K
  1336.         dataCount  = dataCount;" l% s2 R2 Z) A  G! c2 K7 m7 \7 g' @
  1337.         code       = CodeNone;( U& |. e5 X  `( g2 b8 _; a, b
  1338.         stage      = (Stage)(stage + dataCount);* G& s3 T! ]) b1 n; L3 _
  1339.         write(txBuffer, txLength);
    , ~  Y! J1 W% V' |- p
  1340.       }. m/ M6 o$ Q3 d; ^  y
  1341. ( `' ^* r  x! E: W
  1342.       break;& u2 v& \) f: g' v/ ]
  1343.     }2 o6 G2 P+ b: C
  1344. 0 o( t) X1 L6 J; Y$ r
  1345.     case CodeAck:: i; K7 Y% i7 E' K7 X
  1346.     {
    ' z) N" `1 D) u1 [- j; r4 C
  1347.       memset(&(txBuffer[YMODEM_PACKET_HEADER]), NULL, YMODEM_PACKET_1K_SIZE);1 L' E% |) J7 f9 a, \
  1348. 4 [, ~9 u" z5 j( ^( ?
  1349.       switch(callback(StatusTransmit, &(txBuffer[YMODEM_PACKET_HEADER]), &(txLength)))/ q% C6 U$ x$ q& ?; \
  1350.       {
    6 y6 g6 @4 p7 F: F9 P8 A" {
  1351.         case CodeAck:
    . _# Q/ ]1 F, z  m
  1352.         {! j/ @3 b' G3 B% h0 Z
  1353.           uint16_t crc = crc16(&(txBuffer[YMODEM_PACKET_HEADER]), txLength);; p7 M% m+ W, k! q

  1354. 3 k% R# I( K, v$ b
  1355.           timeCount                                       = 0;
    3 u* ?  B% V( `& w
  1356.           errorCount                                      = 0;
    3 I2 q( n/ v* j& {6 p$ ~  x
  1357.           dataCount                                       = 1;5 u+ }0 Z2 C- B/ [; M* y0 o, x/ |1 R
  1358.           code                                            = CodeNone;+ I- p# Q" T- N, V* D2 |
  1359.           stage                                           = StageEstablished;7 r- `1 N: A7 }( {! r, `$ e
  1360.           txBuffer[0]                                     = txLength > YMODEM_PACKET_SIZE ? CodeStx : CodeSoh;! F6 a4 ^( M8 _  C: d
  1361.           txBuffer[1]                                     = 0x01;5 _8 W# C7 C, [/ `( {
  1362.           txBuffer[2]                                     = 0xFE;
    6 @' c# M- a  ]3 r) W
  1363.           txBuffer[txLength + YMODEM_PACKET_OVERHEAD - 2] = (uint8_t)(crc >> 8);
    - E6 O. H, ]% T
  1364.           txBuffer[txLength + YMODEM_PACKET_OVERHEAD - 1] = (uint8_t)(crc >> 0);
    & f; q% ?: G" v6 v2 h
  1365.           txLength                                        = txLength + YMODEM_PACKET_OVERHEAD;# V4 e4 i( x6 L  t
  1366. 3 F/ p9 \7 b) M$ f' _
  1367.           break;
    : N9 E2 Z# U! h8 @3 Z3 W2 \  c! j4 p
  1368.         }
    1 F' Q6 G& Z$ t8 z1 _

  1369. # r) [7 L7 \7 b- M5 ^
  1370.         case CodeEot:
    ! k$ [) e! h3 r# e: F
  1371.         {
    9 l7 k4 C. y# L: |  m  K9 k4 i
  1372.           timeCount   = 0;6 Q; B+ l( ~" D% L2 S; t+ l" \8 P
  1373.           errorCount  = 0;
    # Q! W5 p& R$ l% ?* F
  1374.           dataCount   = 2;. P  c$ D3 o6 G) r
  1375.           code        = CodeNone;
    ! \$ H3 g. L' k
  1376.           stage       = StageEstablished;# O) R& T; a, [7 b- ~
  1377.           txBuffer[0] = CodeEot;6 e. S* }' G# g# r
  1378.           txLength    = 1;& z5 N( n/ ^* o: K( p  k: o4 k
  1379.           write(txBuffer, txLength);9 {; S( a. o$ b5 D% A$ \" I2 s4 O; {

  1380. 1 M9 Z  m" B) g% j% C8 v
  1381.           break;
    , _# \- ~" [$ @: ~
  1382.         }: n$ }+ R6 X- z8 N" ]( n1 q( M

  1383. ' x, I) w) m, K) H# G
  1384.         default:. C; b( ~: u! T0 e7 G
  1385.         {6 L- k. N" K" s* G$ y
  1386.           timeCount  = 0;% x& S. g0 T- ^' F* u1 H7 f
  1387.           errorCount = 0;6 s3 o2 h) ]4 }
  1388.           dataCount  = 0;/ a: a, }3 C2 Y' \; x: O3 M# ?1 @
  1389.           code       = CodeNone;
    ' q8 M( Q' G9 _0 \( l) Y; B: z
  1390.           stage      = StageNone;
    0 i! j0 U( N7 }

  1391. 5 a, j8 I1 r1 X6 ?
  1392.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    $ W- J' F; ?; d* T7 N8 g9 R0 H
  1393.           {
      p* Y  X0 L1 Y( y0 j9 Z
  1394.             txBuffer[txLength] = CodeCan;+ ^; ]/ q! {( w/ q% r7 o( G
  1395.           }) S* k5 n1 f* i

  1396. * m) m1 b: Z: Q: P& {4 F* R) A
  1397.           write(txBuffer, txLength);
    . ?! C1 p- y# A8 a1 b7 Y3 c
  1398.         }8 L1 j* |$ z& _4 L3 x8 M
  1399.       }
    2 H4 |: t: H/ E" q. S. W* B! U
  1400. + Y4 B! N: T% v# ^
  1401.       break;( ]  C0 p6 i! }, X! @2 [. i7 p& [
  1402.     }5 M; a% G' @0 u% U4 ^4 q3 `0 E

  1403. 3 l; n0 O7 Q  Q8 o. D. x
  1404.     case CodeA1:
    2 N0 Z& p' k) D2 V- }
  1405.     case CodeA2:0 W1 d2 G6 q- P; G9 i3 G# a
  1406.     case CodeCan:
    + y4 g5 I/ u, M4 m* Y$ o
  1407.     {6 a! ?. `. l: C) i; l
  1408.       timeCount  = 0;
    . S% k7 p2 H3 \: b5 e- Q, B
  1409.       errorCount = 0;
    4 v, Q9 {$ b6 F6 y' H2 t
  1410.       dataCount  = 0;* _# _7 k5 H. Y$ Q
  1411.       code       = CodeNone;4 X- w1 r7 \0 l) [; P8 l
  1412.       stage      = StageNone;
    ( O# ^3 a+ C& X3 y! D" q
  1413.       callback(StatusAbort, NULL, NULL);
    $ V) c: l5 F! l: p$ S) b) N/ L
  1414. 4 R9 o* M  j. t% R1 R8 `
  1415.       break;+ K6 T  f  I5 Y- V9 k; |8 A8 J
  1416.     }0 O0 f$ Z1 G# I- [

  1417. , C3 N! {! F  J6 I
  1418.     default:% ?4 t5 o! {3 A& T
  1419.     {$ f! w8 W6 s, I1 `
  1420.       timeCount++;
    $ `% a2 E" [- J* y1 K  \1 c

  1421. ! |4 w' D# s0 {+ k1 D. n' {
  1422.       if((timeCount / (timeDivide + 1)) > timeMax)
    $ ]8 O' Z- X, [
  1423.       {5 f0 f2 L! E' O
  1424.         timeCount  = 0;7 c: b7 O" V6 V5 v# |$ f: c
  1425.         errorCount = 0;: G: p. X" ]+ |0 X/ R4 E7 W2 p
  1426.         dataCount  = 0;6 L- Z+ h( ]/ B, j( `
  1427.         code       = CodeNone;
    , n+ v. `- I! k; v/ s; \* j" S' _% A- K
  1428.         stage      = StageNone;% I' `# m; ~) y7 s' Q# H2 J

  1429. 2 W3 P" A1 W3 l0 I; P
  1430.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)& [& x8 [- @3 T% a, j0 W
  1431.         {+ g7 X, ^- r7 G. k6 \# I0 U$ d& Z7 o
  1432.           txBuffer[txLength] = CodeCan;9 v, K0 ?4 P. t( J5 M* ]
  1433.         }
    7 w& R, J7 d% A5 u1 C
  1434.   o( e: P" o8 I) w! A/ M# R
  1435.         write(txBuffer, txLength);- b4 M7 W$ L" y+ q9 E0 o
  1436.         callback(StatusError, NULL, NULL);
    2 A# y" ^% ^3 Q+ s7 X) k) ~
  1437.       }
    / n  B4 J( _1 p3 z* y( i
  1438.       else if((timeCount % (timeDivide + 1)) == 0)+ ?  ]( I$ N& ~8 `% h
  1439.       {
    ! F& n, k2 Q, B' H
  1440.         write(txBuffer, txLength);
    + v( \1 f9 g( Y; Z# H* _; o
  1441.       }
    $ a9 e: `9 R& x2 Y) Z$ u3 |" A
  1442.     }
    7 z- h+ R; R0 r6 |, {( u+ R
  1443.   }+ q8 j8 P/ {, O1 ?' l/ ^
  1444. }4 e7 I, n6 V/ z4 ]8 |. O  a/ I; I6 M

  1445. 1 s1 k4 v5 H3 `* d2 }, W
  1446. /**9 q6 C1 [) L8 D  f( f
  1447.   * @brief  Transmit transmitting stage.
    ' r4 [0 K) \5 m* K$ q4 N5 D0 `
  1448.   * @param  None.+ B6 S& Y' h! C6 Y5 k
  1449.   * @return None.
    % L; x! d9 T( j2 T1 M3 d2 Z
  1450.   */
    & _) F- r" C0 l' Q: c6 k0 L5 S8 _
  1451. void Ymodem::transmitStageTransmitting()
    7 j3 M  F. C/ ^& M6 \% P
  1452. {
    5 J: |2 V5 V; ~7 S; m
  1453.   switch(receivePacket())  S, [. I  I0 ]: d8 e
  1454.   {$ ^/ ^9 j* g: o! X6 b
  1455.     case CodeNak:
    / Q( S9 b7 k& q& k" E6 L( ?) @
  1456.     {2 H% |$ [' A. b' t
  1457.       errorCount++;
    . \* k& v; j8 |
  1458. / V3 H) A( _2 _" b  B" C
  1459.       if(errorCount > errorMax)5 z( `. K# e. \6 H5 G5 ^6 e7 g
  1460.       {
    . \4 ^4 m8 Z9 R9 z
  1461.         timeCount  = 0;  g3 w0 Q( @! m5 P. P9 ~6 }2 ?
  1462.         errorCount = 0;
    $ D; z* v; S: v7 x: y4 Y0 p$ |
  1463.         dataCount  = 0;; Y9 n( Q7 m( e: i$ w
  1464.         code       = CodeNone;, H0 P* e" X2 }8 e- O" |9 Y
  1465.         stage      = StageNone;
    3 p6 O/ \# }& N. w6 o7 Y' n) O

  1466. ( N) d8 w( @5 V- ]/ {
  1467.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    9 x+ b3 v: v5 ^- }" [
  1468.         {
    - C5 c1 Y4 w7 J3 J4 c5 t
  1469.           txBuffer[txLength] = CodeCan;
    / A: G5 b9 Z2 Y0 k
  1470.         }
    ' Y6 l" n: c' Q' ?- F; t- H

  1471. 0 z+ {$ P. {* r* L/ H: t7 t
  1472.         write(txBuffer, txLength);# K$ U* t0 b4 U( s( y% d+ D
  1473.         callback(StatusError, NULL, NULL);
    , Y8 t, g3 N" R; g7 u
  1474.       }0 N& W6 ?) R$ F& X( c4 g
  1475.       else; h6 H: J5 f; M9 w& I7 h
  1476.       {- f8 b# ?$ Z* `4 n6 b# b! _
  1477.         write(txBuffer, txLength);5 h- [/ S: y4 c/ m
  1478.       }
    & w, D! W/ J! ^% Q9 L0 U% S

  1479. $ q  w# h: k" T
  1480.       break;7 t9 s& p# Q" Z8 J
  1481.     }
    6 c5 f1 f( T* x9 ]- Z
  1482. 8 L+ x3 j- o& E* p
  1483.     case CodeAck:
    + H* I$ b' Q% U9 t5 u
  1484.     {
    9 c4 c* C" a9 l' ?  [
  1485.       memset(&(txBuffer[YMODEM_PACKET_HEADER]), NULL, YMODEM_PACKET_1K_SIZE);- ^- m9 I% k+ n0 d2 a* S8 V* ^

  1486. " [. P" M% l$ h9 Q9 b
  1487.       switch(callback(StatusTransmit, &(txBuffer[YMODEM_PACKET_HEADER]), &(txLength)))
    4 [! S$ c9 E+ f" ]$ p3 `
  1488.       {
    / \4 D6 Z. w1 x" q
  1489.         case CodeAck:
    5 V4 w' n2 A2 R4 f
  1490.         {
    . v) Y/ ~2 _% c' |' c# ?7 l- P
  1491.           uint16_t crc = crc16(&(txBuffer[YMODEM_PACKET_HEADER]), txLength);
    # F7 z5 @0 Z- A( I5 B1 F
  1492. + x/ x: [# h: z( d; t4 z
  1493.           timeCount                                       = 0;
    + @0 \9 s8 \2 @! \8 G4 [
  1494.           errorCount                                      = 0;6 t7 Z- p  n# U. |3 |+ u1 I/ g
  1495.           dataCount                                       = dataCount + 1;% c3 @8 E7 J: L; R9 `0 l; q! }" `  B
  1496.           code                                            = CodeNone;
    ( f+ N: u0 h6 c$ [+ m( z
  1497.           stage                                           = StageTransmitting;
    6 g  x3 V( N: Y. N# G
  1498.           txBuffer[0]                                     = txLength > YMODEM_PACKET_SIZE ? CodeStx : CodeSoh;
    0 X. N6 p2 J7 w
  1499.           txBuffer[1]                                     = dataCount;& {/ p/ ?- Z& E7 ~/ [6 U
  1500.           txBuffer[2]                                     = 0xFF - dataCount;
    * z( P# C  q' E- t
  1501.           txBuffer[txLength + YMODEM_PACKET_OVERHEAD - 2] = (uint8_t)(crc >> 8);
    * z3 |2 b" g7 M, d
  1502.           txBuffer[txLength + YMODEM_PACKET_OVERHEAD - 1] = (uint8_t)(crc >> 0);
    6 v3 R3 B1 O0 ^2 C
  1503.           txLength                                        = txLength + YMODEM_PACKET_OVERHEAD;
    $ m: p5 _* O! O+ e% Q! o
  1504.           write(txBuffer, txLength);
    8 P; C/ s5 z1 _. e- D6 I! s* n
  1505. # j  p" F1 L+ ?+ O# {  p8 A
  1506.           break;/ \4 n, N( p( C, Z6 L
  1507.         }
    5 R, s) n& E  Y4 X% ^5 R
  1508. : g. Y" f) s3 I' R
  1509.         case CodeEot:6 ?8 _* A) h; Z+ I
  1510.         {: ~" d2 T! F: u9 p  d
  1511.           timeCount   = 0;
    3 X+ ?! W6 U, P9 f' j
  1512.           errorCount  = 0;
    7 W, g3 i0 O5 \/ m
  1513.           dataCount   = 0;
    " b! Y0 k8 b' c% _7 G  G
  1514.           code        = CodeNone;
    $ x+ o/ ?: r, ~% u4 v
  1515.           stage       = StageFinishing;( ]/ A9 v9 `4 ~& g: T$ e' j' ?
  1516.           txBuffer[0] = CodeEot;! B( l  z* @* B7 p9 @
  1517.           txLength    = 1;
    0 A! [+ N2 s! j3 y+ E) |
  1518.           write(txBuffer, txLength);& H" E, O5 w* L+ w5 h  h
  1519. . f& a. b! [/ o
  1520.           break;
    ( E$ N7 k3 W1 r" \, @
  1521.         }& B7 j0 s' W" A6 ^% m! z% _" @

  1522. , I7 d3 z, M, B
  1523.         default:
    7 X! `4 L7 H3 A% D
  1524.         {3 d. |  `; F# N4 J4 {1 j
  1525.           timeCount  = 0;2 F: c4 V8 K  p+ n: m, w
  1526.           errorCount = 0;( G$ x1 F' }2 ?0 |& B
  1527.           dataCount  = 0;' K7 H$ k. ]* _  C
  1528.           code       = CodeNone;
    1 w  w' Y/ ]8 A  D" P% ~9 v
  1529.           stage      = StageNone;9 G8 r9 V& i7 H0 C- e2 d! `" [
  1530.   J% A) o) C* Q0 I$ B
  1531.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++), e0 S7 h2 u. a! L* ~
  1532.           {
      R# `& A1 w# g0 r4 `
  1533.             txBuffer[txLength] = CodeCan;+ e! x0 {4 Z8 i8 ]. {
  1534.           }
    1 Q4 ]8 w; L; t1 p8 G' p
  1535. 3 E& {; Z* F: [& O6 @+ w! C
  1536.           write(txBuffer, txLength);! f/ a4 Y! ^8 N& \6 W# ~5 Q; \
  1537.         }
    $ ~$ R' M! p! w( ]
  1538.       }
      Q+ e7 h# F1 R/ }

  1539. 7 `" X. p  Z' h8 G1 O& x/ A
  1540.       break;
    . o: O* E) G- I) a5 a
  1541.     }. I, h  L; A4 d1 d6 p! M& @
  1542. + v; r: }3 f' L- X! [
  1543.     case CodeA1:
    & Q& S' @1 V+ Q5 u2 R) ]
  1544.     case CodeA2:
    2 r& U( A$ b& g
  1545.     case CodeCan:  i% s3 Y; B% g( Z) b
  1546.     {8 J6 O$ P4 @( x( b
  1547.       timeCount  = 0;
    ! l# b+ ~7 n& Z
  1548.       errorCount = 0;
    4 o6 r% Z4 |+ I! B8 D" }
  1549.       dataCount  = 0;1 q: W5 |* _- z: Z5 V. J" g2 U
  1550.       code       = CodeNone;
    & s7 J; f4 y) R( G) J6 W  ?
  1551.       stage      = StageNone;
    * t4 b; E' V: H6 o) [/ g( J
  1552.       callback(StatusAbort, NULL, NULL);" z5 b; V% w. y3 u+ V* p

  1553. * ?' T: q& b' w+ {0 B
  1554.       break;$ E+ `  [& \' A, v* U+ @" J
  1555.     }
    0 e- _4 z/ y& }* |; l) @

  1556.   ~5 k# {3 H% C
  1557.     default:
    - \0 \% ]) k6 Y: s- D+ i8 o
  1558.     {3 C3 _) x5 }$ i# A2 w- f% `9 Z
  1559.       timeCount++;" n0 P' d9 h5 J' J3 f% m

  1560. 9 d4 d# O1 f4 N2 e4 _  W, k
  1561.       if((timeCount / (timeDivide + 1)) > timeMax)3 |/ W6 ?$ K3 `; A! ]7 x& [! s; F6 j
  1562.       {
    ' N$ K/ h; L0 z
  1563.         timeCount  = 0;$ o0 B  K8 y/ H0 X9 }
  1564.         errorCount = 0;( l6 j! l- P$ F  o" D  i0 L6 O
  1565.         dataCount  = 0;; P$ j, w& o, M7 a+ O/ K
  1566.         code       = CodeNone;3 P( m1 P4 R. w3 H9 }
  1567.         stage      = StageNone;
    ; w* v  Q1 i" A8 k: v$ ~* I- I
  1568. 2 f7 X0 a6 [; D0 o  f6 J
  1569.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    / h6 F* c$ Y; ^( x. H  C
  1570.         {
    6 B7 u/ b1 N* u, P' F! g) M
  1571.           txBuffer[txLength] = CodeCan;. W- G" @5 c: F
  1572.         }
    8 H3 R! L; g5 b! ^
  1573. . c& k5 w) D8 s7 R2 [) g
  1574.         write(txBuffer, txLength);
    5 U7 Y0 _1 B: ?+ y8 J
  1575.         callback(StatusError, NULL, NULL);5 D6 _% w% r2 Z" ~+ G! P
  1576.       }: [; r9 f$ z0 L! J( M6 Y( v& F+ c. ^
  1577.       else if((timeCount % (timeDivide + 1)) == 0)* Z1 C  N, u# h6 I# N( Z
  1578.       {4 \! V4 W3 k; `. `+ D1 H
  1579.         write(txBuffer, txLength);6 B2 a) a; R0 q' v
  1580.       }
    $ u$ \+ A, }: p* i- g6 W4 a  Z+ J+ C, T
  1581.     }
    ( o& n6 s: ^( S3 K# T) ]2 d- n
  1582.   }
    ; e' g/ _4 \7 s/ f
  1583. }6 ~0 e8 B9 J7 R( W/ F* }# V9 k

  1584. - E8 r0 K7 v; F9 N7 X
  1585. /**  \8 v8 \/ W4 O, N
  1586.   * @brief  Transmit finishing stage.9 C1 o/ w1 U3 x
  1587.   * @param  None.
    ( s* U* @% j1 G& z5 R
  1588.   * @return None.
    1 L0 v1 v. A1 Z, m4 \) u! ]
  1589.   */0 Q; w) t0 n2 q0 Q2 @* P) N
  1590. void Ymodem::transmitStageFinishing()
    0 y4 q& l0 ~% w
  1591. {
    9 D& N6 p, R8 q* F+ ~
  1592.   switch(receivePacket())# b6 J9 O2 ]+ s, k# u/ x0 M
  1593.   {6 z3 B% K! w& h2 `
  1594.     case CodeNak:
    9 Z( u: k; q9 }3 W9 |
  1595.     {2 N9 c$ i' n7 O- G: I. B
  1596.       timeCount   = 0;# s; p0 \/ a  G# a7 o) m! P6 i" ]/ S
  1597.       errorCount  = 0;# m7 q# E3 e+ k$ R( t" f+ j/ h
  1598.       dataCount   = 0;5 t3 |. v4 W' \
  1599.       code        = CodeNone;
    7 Q( E7 p+ u9 W% B' V( v
  1600.       stage       = StageFinishing;8 m0 V+ f# ~4 ~/ b& ~% ^! q& G
  1601.       txBuffer[0] = CodeEot;
    5 L0 M6 {' o& f1 B( n
  1602.       txLength    = 1;
    $ m$ C1 h0 Z. g' ]: E
  1603.       write(txBuffer, txLength);0 o. Y2 \! e0 `$ F

  1604. % b! L. g* I& Q5 N% I8 i# l
  1605.       break;
    * Q/ T& \2 k# n7 o, A. Z3 T
  1606.     }8 f6 b8 y, F5 i  z6 J. L

  1607. / F/ ]" I0 [( E! l
  1608.     case CodeC:
    : A* m6 ?# E5 B  E5 E: D' V
  1609.     {
    $ J; Y9 o& E: [( r; A
  1610.       memset(&(txBuffer[YMODEM_PACKET_HEADER]), NULL, YMODEM_PACKET_SIZE);* d* V7 S$ S3 D% Q5 v: d% Q
  1611.       uint16_t crc = crc16(&(txBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_SIZE);
    ! B! J1 T' y* n5 x

  1612. ) g/ q+ `- }$ z. v
  1613.       timeCount                                                 = 0;
    1 Z: @' e  v$ C* G5 {" q3 j
  1614.       errorCount                                                = 0;! v+ m( w4 e7 Q0 s6 N1 a
  1615.       dataCount                                                 = 0;
    % Y' R0 A: B! l+ v! t4 {
  1616.       code                                                      = CodeNone;; T2 J* }+ _. d9 r! {- `
  1617.       stage                                                     = StageFinished;
    " e, E9 ?7 u. r
  1618.       txBuffer[0]                                               = CodeSoh;/ f7 Z# N6 T) _
  1619.       txBuffer[1]                                               = 0x00;. S! v" C- h# }
  1620.       txBuffer[2]                                               = 0xFF;
    - d* S" b1 F: n+ F: a( D5 B! V
  1621.       txBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 2] = (uint8_t)(crc >> 8);) H. @8 R: C/ k8 u% N/ B
  1622.       txBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 1] = (uint8_t)(crc >> 0);
    9 W) e- k3 L* t' M1 \+ k
  1623.       txLength                                                  = YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD;6 p* p9 J# {+ N& [( ?( W
  1624.       write(txBuffer, txLength);
    5 S0 G/ Y) |- r' A8 j4 C

  1625. % Q3 T' Y" l0 s! Z3 q
  1626.       break;  F) Y& H4 J& c% G0 p/ d
  1627.     }4 [$ O, F4 c9 P" u! }5 U

  1628. ) m  E' ?* j, y% T+ y
  1629.     case CodeA1:9 a' W5 w; c* y" e$ M5 J
  1630.     case CodeA2:
    7 H1 }( f2 }4 d/ W
  1631.     case CodeCan:2 I) \# ]# ^* h0 ?
  1632.     {$ X5 o% |  U, X1 c
  1633.       timeCount  = 0;1 J& d& O* R( v( u- T% {
  1634.       errorCount = 0;
    ( z7 a7 c& ^& A$ n1 [7 P
  1635.       dataCount  = 0;8 T& ]' h8 J( }- c7 o
  1636.       code       = CodeNone;7 F+ e+ n9 A* ~# }( j6 G
  1637.       stage      = StageNone;  h" C% ?4 h; W# q
  1638.       callback(StatusAbort, NULL, NULL);
    # w6 s& \. A/ o) \! |; ?0 r+ T# w

  1639. 1 {8 u0 Y6 O0 `* o
  1640.       break;
    3 M; Z( D+ P+ k- x+ G; \6 e& @
  1641.     }
    # u% \$ b; g  n; t

  1642. / k* B' j3 s! j; _# e
  1643.     default:2 r! g3 ~& R$ f& Q8 i
  1644.     {  X7 B' A" Q7 A, d0 V4 C
  1645.       timeCount++;4 R% A' o% Y* j3 e& e1 w

  1646. ! ]+ r& [3 ^- O/ U% C3 v
  1647.       if((timeCount / (timeDivide + 1)) > timeMax)) ?* q) |  ~$ h9 i: n
  1648.       {
    - I& w/ m+ O+ Y1 m! w& N9 T: C$ [4 v( U
  1649.         timeCount  = 0;8 l4 |& N  ^4 u7 Y8 ^& S0 R
  1650.         errorCount = 0;3 ~/ i4 v! ?3 {. H$ i
  1651.         dataCount  = 0;
    - X5 f  ^( u& Y. @8 w5 E* H
  1652.         code       = CodeNone;
    0 b9 x3 A# s  [* Y0 t8 |1 g
  1653.         stage      = StageNone;* y& C: a- R! q  z% r
  1654. ; d" o" r- w! K" O3 z* X. d1 a
  1655.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)$ U3 z9 j# Y/ c+ x
  1656.         {& X  o- W  R3 o2 K" z. S
  1657.           txBuffer[txLength] = CodeCan;
    + E! G/ B# s; K; s  k0 o. V* H
  1658.         }, v: a7 p6 M: b( H% u7 \
  1659. 5 C7 @5 A$ X9 j7 p! r* \
  1660.         write(txBuffer, txLength);
    + V; T8 H/ |( {2 @$ b
  1661.         callback(StatusError, NULL, NULL);" M! }) @4 w. t7 E% D; h! ]
  1662.       }; }6 n( o5 [* E5 l* K
  1663.       else if((timeCount % (timeDivide + 1)) == 0)0 T3 Y4 j) t" \. P3 ?. p
  1664.       {& l" R1 p' `. O% P- B
  1665.         write(txBuffer, txLength);
    & ^3 O! D  \  U7 ]7 b
  1666.       }
    : m- R' J$ J" j* y2 V* q, W0 i
  1667.     }
    ' T% v3 N5 n' @, |
  1668.   }: A- u  y8 a$ t& v  T/ i9 L9 E6 w
  1669. }  `0 L# h  g+ z  b7 K" G
  1670. 9 K/ K" k! |5 {3 F
  1671. /**
    & w! f: b& {8 R; J- Q' h! Z
  1672.   * @brief  Transmit finished stage.
      I4 Y& H( A) F8 D
  1673.   * @param  None.
    ! r: m; F* U9 T: G$ w/ ^2 z
  1674.   * @return None.
    : t& H2 U4 D% T( E: ]) ^8 x) g
  1675.   */# N. `% b8 Z  V# }9 r& M, q
  1676. void Ymodem::transmitStageFinished()
    - L- I7 u6 {) i0 v0 o
  1677. {
    ( o2 }$ K0 c  w0 K6 \
  1678.   switch(receivePacket())
    % W0 I  t2 l- g
  1679.   {% K# z* H5 U' e' E) b9 k( ?8 F5 ]5 a
  1680.     case CodeC:
    2 u9 G1 T2 }  R- x; M; F& \: [
  1681.     case CodeNak:
    5 v0 _8 E, B+ `: n
  1682.     {
    % s# j! @; X% a7 [% t% w
  1683.       errorCount++;0 _6 D9 e" J1 Y/ |

  1684. ( N, a4 `3 Z6 t+ P9 P" @5 u: g
  1685.       if(errorCount > errorMax)( d/ P* o5 O3 Y
  1686.       {
    0 G" r1 ]6 w0 O  X
  1687.         timeCount  = 0;2 z0 r7 x- P3 R
  1688.         errorCount = 0;
    " t7 I* L) d( {  N4 O
  1689.         dataCount  = 0;
    / s8 @8 m5 ^; h% }0 x
  1690.         code       = CodeNone;
    , P2 {: t$ r/ D" `# G- q
  1691.         stage      = StageNone;' R( W  W8 P2 c; K3 Q7 v2 H
  1692. ! U+ C# t+ w# y) i( k$ d8 r
  1693.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)* i0 z( R) Q3 x) R
  1694.         {7 a& T* K) Q  G+ R
  1695.           txBuffer[txLength] = CodeCan;( D6 b3 z' F. O8 z% G
  1696.         }5 g  V0 N& Z( N9 d
  1697. ! U0 I% C0 b' r0 ^* n
  1698.         write(txBuffer, txLength);1 O* [& N2 k9 d4 Y. w
  1699.         callback(StatusError, NULL, NULL);
    2 J$ ~, P+ h7 v- J; i4 u& X
  1700.       }
    + s2 R) X$ [8 h/ C$ J
  1701.       else
    + |$ }2 d/ Q* n9 A/ r4 `
  1702.       {
    4 J2 B, }# o" ^9 ?
  1703.         write(txBuffer, txLength);. U3 A: B# {4 |" a
  1704.       }6 k; W7 T1 L& S) o0 b3 u3 c

  1705. ! h6 V  i/ o" j
  1706.       break;) `1 I8 O+ z9 s" {$ U7 y
  1707.     }, L6 z6 f3 s% h/ |+ ?

  1708. " L/ v: e6 z  @, L
  1709.     case CodeAck:7 y" r6 `* J1 D- y2 t
  1710.     {% ~: v1 V& H8 w0 w8 N
  1711.       timeCount  = 0;4 A8 n3 o* [. a9 Y3 L! Y
  1712.       errorCount = 0;
    & N( c9 W! _% n9 }* ]! N
  1713.       dataCount  = 0;& \+ P) S& ]1 |' h$ b
  1714.       code       = CodeNone;
    1 ^2 J4 h" v! Z7 ~/ W) o8 X. Z# p* u
  1715.       stage      = StageNone;# ?% @" i1 G; v
  1716.       callback(StatusFinish, NULL, NULL);4 x+ _0 m! {7 v# Q; _

  1717. & w4 [2 B( b- o+ E+ F+ m
  1718.       break;, ~) i8 k+ I/ @8 c; E
  1719.     }
    9 }) x% u  U9 R8 W# Z2 F' t
  1720. ! ]) e/ R' G0 E9 ~! e/ P/ L
  1721.     case CodeA1:
    4 ]+ C; {8 S, u' @- [
  1722.     case CodeA2:
    ( e% v& ~9 r& ~/ w. T% ^: X
  1723.     case CodeCan:
    " s6 \( Y4 h/ t8 A& i1 O, {9 U3 K
  1724.     {
    , p" A: Y5 C* V
  1725.       timeCount  = 0;/ m+ \  Y) `5 B4 a) J" \
  1726.       errorCount = 0;# O/ }8 k* W- ?2 K% T- L2 S
  1727.       dataCount  = 0;! [3 p/ `( o# K
  1728.       code       = CodeNone;
    . O: M9 Q, [( N5 S: }" [' x
  1729.       stage      = StageNone;
    1 y' |! q( A; X0 Q2 v% v- }; [0 l
  1730.       callback(StatusAbort, NULL, NULL);
    + j" ]8 N/ y% F; C2 H! s
  1731. . g" k0 m6 j: ^8 _. J2 y4 X% e
  1732.       break;
    . |* y4 |( T+ S- C4 v- Y8 a
  1733.     }
    7 ~" w- q0 P3 k4 Q, v: B' O6 e

  1734. * _# ]5 }- p+ i6 k* \* l
  1735.     default:3 r2 q. Q' }  o& N% _
  1736.     {
    5 q7 ?6 F5 S+ t8 s: S; n& j+ n
  1737.       timeCount++;: I0 @$ R" X# S& a
  1738.   v. I1 d2 y; I3 L$ D- \( C
  1739.       if((timeCount / (timeDivide + 1)) > timeMax)1 f0 @( B3 P, G( {+ v' ]
  1740.       {+ M2 u  ?! d0 ^# \7 q0 Z
  1741.         timeCount  = 0;% z: n( ~% ]. h" [& p) Y: h
  1742.         errorCount = 0;* l8 e/ s# U+ s4 n3 T" Y; p7 k$ u3 v
  1743.         dataCount  = 0;
    * |8 J3 D  {" v# O. Q1 _
  1744.         code       = CodeNone;# l" _8 J$ U  J8 k; b3 J
  1745.         stage      = StageNone;; v6 f7 w" A; ], c1 l9 [
  1746. 4 [8 Y7 ~& ^/ r, D4 I$ i
  1747.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    1 j" W( T+ R0 B( B7 D
  1748.         {
    % ~' U9 D7 {9 N& I2 f5 ~
  1749.           txBuffer[txLength] = CodeCan;/ S/ j  Q* [  j9 l+ t- f' k
  1750.         }
    8 U5 L9 q3 D2 x  |7 C% x7 P3 P$ [
  1751. 6 V! w% ]7 l/ o: E
  1752.         write(txBuffer, txLength);; x* N* D  E$ m; {
  1753.         callback(StatusError, NULL, NULL);
    * P- L3 x& j( }2 p# w- A
  1754.       }
    4 Q1 C/ {4 P! U( X( u' b; H3 b& j
  1755.       else if((timeCount % (timeDivide + 1)) == 0)
    " C/ C7 f7 z; I: E% S: n
  1756.       {
    ; |/ |* v. M: b- x$ b/ W& P1 c
  1757.         write(txBuffer, txLength);
    6 S( O: Y; Y. G
  1758.       }) l" ]% ~  c# o4 N3 {8 m( j
  1759.     }
    + v- v7 P/ `1 J* l
  1760.   }
    4 N4 M2 D# V% |7 I/ g' a! u
  1761. }# @3 n0 P( J' E3 U9 {: b# f  m

  1762.   t  K$ u1 [" j' o
  1763. /**
    & E& m* S* l, W! I# q
  1764.   * @brief  Calculate CRC16 checksum.+ C; H  _: `, k& h* Z
  1765.   * @param  [in] buff: The data to be calculated.
    1 G9 o# F* v% K5 J$ _8 a' M
  1766.   * @param  [in] len:  The length of the data to be calculated.9 _7 T9 K6 V* Q  Y# u! ?
  1767.   * @return Calculated CRC16 checksum.
    - @9 M' N8 B2 k& N* s3 |
  1768.   */
    # q& T' ]0 W2 Z2 s8 j& N5 e
  1769. uint16_t Ymodem::crc16(uint8_t *buff, uint32_t len)& ^! F4 x! A4 S0 E* I: {& b
  1770. {
      ^2 ~- D( _" T/ |2 O: ?
  1771.   uint16_t crc = 0;
    6 K$ h- @9 W# c+ W5 @! Y

  1772. 0 H2 H* f8 \* D# R  y6 E
  1773.   while(len--)/ x& r1 Y7 d$ U# a1 H8 J  ~' X
  1774.   {7 l  D) _: I( C6 I, Q
  1775.     crc ^= (uint16_t)(*(buff++)) << 8;4 f/ A3 }6 e  J. }7 R6 ^  ^1 m
  1776. ( g- h: s8 Q3 r9 ~) d/ q6 S. m
  1777.     for(int i = 0; i < 8; i++), D7 m3 I& h) Y4 K
  1778.     {
      X  _. r' @6 T2 y- b
  1779.       if(crc & 0x8000)
    # |/ T) Z% b* g8 L9 k. B! Z
  1780.       {! E# K" Q- D- _- c* O$ D) N
  1781.         crc = (crc << 1) ^ 0x1021;" V7 f. ~8 O6 [
  1782.       }
    4 y( a. `4 c. v: w! w
  1783.       else
    ; f( I! j! b% T1 T8 U7 ~' k/ n
  1784.       {, B' p- l4 x) T" Q  ^7 N, \) f; {
  1785.         crc = crc << 1;
    0 C. `4 n+ \* b$ P7 W+ ~# \
  1786.       }
    0 c7 N6 D5 \2 T' \0 j+ _, n
  1787.     }
    9 f/ w- K6 z7 n* H; T
  1788.   }- K+ T. Q: q; I6 u  ?' [
  1789. 0 S1 c- H7 c) b' c: c1 r
  1790.   return crc;* e4 x# q+ x3 n# I
  1791. }
    4 l/ m5 Q9 c9 E1 s
复制代码
7 J6 ~* {4 q* B

2 b/ m' p, @! r6 M4 D% R" ?5 O* S& N" x8 _% V- s  M! D9 u- s
( Y2 i" ~) R' _8 m8 \

评分

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

查看全部评分

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

举报

10个回答
XinLiYF 回答时间:2018-3-6 01:58:43
      YmodemFileReceive.h文件
. t0 U- r1 P7 v. ^8 Y2 W+ [
  1. #ifndef YMODEMFILERECEIVE_H
    + X3 e5 h. y- G, {! |' W2 i
  2. #define YMODEMFILERECEIVE_H, l! b" H( M% z! {) F6 u; _- E/ i

  3. 2 w, R' Y' Q5 F9 }: Y
  4. #include <QFile>
    % b( X/ B3 l) T
  5. #include <QTimer>5 W* M, A0 C0 k, }4 @$ Q; N" o& x
  6. #include <QObject>
    2 M( r) u) {$ h6 L
  7. #include <QSerialPort>
    ( b3 v* S+ G) l& R3 }
  8. #include "Ymodem.h"
    - G% _- ?1 P5 A" S& T2 B/ I. \* {
  9. 3 b% {0 N1 n% S9 P$ C& X: l3 V! V
  10. class YmodemFileReceive : public QObject, public Ymodem
    2 i3 ]0 D9 l; V( `* z: k
  11. {, k: H5 C' j, X4 i, Q
  12.     Q_OBJECT9 t$ f  l" m$ d; y# Y7 ~& P/ V

  13. ) C5 r  w/ w8 U  \# [
  14. public:
    # q7 D$ l7 K1 X( l* g
  15.     explicit YmodemFileReceive(QObject *parent = 0);
    ) L2 U/ R8 \6 N; P) }0 b9 {
  16.     ~YmodemFileReceive();1 c" A1 _' y  G* q( N
  17. 7 m' _2 k- J7 r5 D! S( O$ o3 W
  18.     void setFilePath(const QString &path);
    9 g4 H; @: j9 A% y: Z" L$ `5 |2 a

  19. % @- k! v) K/ s. i7 ]% L. z2 a1 W
  20.     void setPortName(const QString &name);  J! K- I* F4 w, _
  21.     void setPortBaudRate(qint32 baudrate);
    ! ]9 s/ `2 k- C9 M0 Z
  22. ( O9 E2 i1 _8 l: q4 t# [$ ^6 G
  23.     bool startReceive();
    " t! v7 b% e/ C3 b" w- o
  24.     void stopReceive();% n2 v6 l  C3 {  a

  25. ' Q1 ~: C2 A- m* `% V
  26.     int getReceiveProgress();3 \3 a+ |  J) L5 c+ r: A" l
  27.     Status getReceiveStatus();
    / F# c5 u# j" N

  28. 1 t7 G1 n+ ^7 Z
  29. signals:5 t$ H! ?8 ~$ ~) }7 J% R
  30.     void receiveProgress(int progress);
    , F. I5 F8 U0 V9 R
  31.     void receiveStatus(YmodemFileReceive::Status status);: G% s# \! ?# U8 G) o) h5 ~/ C6 |
  32. $ y1 g) V4 a+ o$ b4 a9 s1 |5 u
  33. private slots:
    : c+ W- o- O/ T- P( p/ B
  34.     void readTimeOut();
    2 W. G) ~9 v: _+ t1 b3 O7 o
  35.     void writeTimeOut();
    3 {5 S' `/ |; e; W7 l- m" ?4 c

  36. , i. D, D' F) W' x, A* V5 p7 @
  37. private:# Q  l2 y9 @6 h2 o% P
  38.     Code callback(Status status, uint8_t *buff, uint32_t *len);
    ) A; W* h; u. r3 O) O) P
  39. 4 `1 `- m9 H' U5 |
  40.     uint32_t read(uint8_t *buff, uint32_t len);. E* C, `; q& R9 A5 q- q
  41.     uint32_t write(uint8_t *buff, uint32_t len);
    ; w) Z/ }8 w. k' P9 k
  42. & |- e% f2 T' g% ^# l% V/ d
  43.     QFile       *file;
      ^( M( H4 `' t! q+ m4 l4 o
  44.     QTimer      *readTimer;
    * P. L6 o" {; j: ~; F
  45.     QTimer      *writeTimer;: Z8 }$ \* z% m6 o
  46.     QSerialPort *serialPort;" w: @, j/ K/ G0 `8 E  \9 v

  47. 7 L4 ^  D) B$ K9 e
  48.     int      progress;
    / G# p( z6 i0 U0 x8 e3 Y
  49.     Status   status;, B' p8 a+ z; t1 g; Y
  50.     QString  filePath;
    9 b; p& M, g+ {8 W6 D  z; {& a
  51.     QString  fileName;9 E0 |* D5 b- ~; M1 q9 P9 M
  52.     uint64_t fileSize;
    6 ^1 z+ ], n" s8 _+ ~. `5 o, n
  53.     uint64_t fileCount;1 J3 O; l* E- {0 P/ r0 S
  54. };
    4 C8 g; f& _6 t9 X+ Q5 A6 i! f, g

  55. . E" U# m+ k. x; Y; B
  56. #endif // YMODEMFILERECEIVE_H
    ! P  p6 [. t& l, O4 d5 Y; |6 h; q
复制代码
& w9 C/ i5 n$ K9 z, q' I0 b
      YmodemFileReceive.cpp文件& M7 a5 B$ {8 [- O. L
  1. #include "YmodemFileReceive.h") d. Z# ?8 Q* D. m

  2. 8 g8 v9 ~' O" C2 S4 o
  3. #define READ_TIME_OUT   (10). Z2 S$ |4 o7 v) N* Z* D$ Z9 ]% \
  4. #define WRITE_TIME_OUT  (100)& I: D$ T0 c% h8 t1 c6 m
  5. 5 A! H. j( r/ C! }
  6. YmodemFileReceive::YmodemFileReceive(QObject *parent) :
    & U% U# ?& b6 f
  7.     QObject(parent),( }& u# K% a, P# }- q8 f% O
  8.     file(new QFile),, q" a% j) o) U- V, I
  9.     readTimer(new QTimer),! a  s. o5 E9 [& C, U' e( F
  10.     writeTimer(new QTimer),
    : r: D+ {! F7 M/ B# l
  11.     serialPort(new QSerialPort), j9 A( R0 p7 Z& K4 N
  12. {
    " r! G$ c$ S. F6 u. n+ b1 g
  13.     setTimeDivide(499);7 I: y' p* t: ]' o% ]
  14.     setTimeMax(5);
    $ A$ \9 g4 i# ~) i/ v
  15.     setErrorMax(999);
    8 z0 ^6 ]4 X; b0 v0 N
  16. 8 I0 |, i" C8 j  ?3 J9 d# a
  17.     serialPort->setPortName("COM1");
    3 p6 R* @1 s9 k! w7 r
  18.     serialPort->setBaudRate(115200);
    ; L4 e4 d8 a; t' i
  19.     serialPort->setDataBits(QSerialPort::Data8);
    - U5 v; B. _1 w9 P1 C: {
  20.     serialPort->setStopBits(QSerialPort::OneStop);+ ^; O6 M; a. G+ s; j; f: E6 X- J
  21.     serialPort->setParity(QSerialPort::NoParity);' k3 G# d8 y7 p) G8 m
  22.     serialPort->setFlowControl(QSerialPort::NoFlowControl);
    0 u! A$ a9 A, h% w% [

  23. " j. A! s: e6 ?. N1 v: o3 Y
  24.     connect(readTimer, SIGNAL(timeout()), this, SLOT(readTimeOut()));0 {  V* K! K  c/ C' o
  25.     connect(writeTimer, SIGNAL(timeout()), this, SLOT(writeTimeOut()));
    1 X- g: F& x6 s1 n
  26. }1 y4 X5 n( _! G  i6 N
  27. ! z" X+ Z* t4 I/ }
  28. YmodemFileReceive::~YmodemFileReceive()
    2 P& r" Q. C: D+ i
  29. {/ u- i) Y, F- Z+ S
  30.     delete file;
    8 o$ j' k% _6 W5 V7 K/ j
  31.     delete readTimer;
    " x3 U) H# ]2 E) S2 u
  32.     delete writeTimer;
    9 x2 k* Z. c1 Q! W4 n$ e9 S
  33.     delete serialPort;
    7 i4 p' M- k+ n/ l& q
  34. }: \3 I; V; {5 v# t1 M
  35. / h! h* S! D6 k+ `; E* c0 G
  36. void YmodemFileReceive::setFilePath(const QString &path)
    2 N' ]4 u8 C7 S" F( j; s
  37. {# `) Y) v$ C- B/ B- Q
  38.     filePath = path + "/";; v5 H4 f3 A' M8 L
  39. }7 h- [" [/ }" W, P9 |3 Y

  40. 1 H7 I% c3 L) x1 O. \* W, f% T
  41. void YmodemFileReceive::setPortName(const QString &name). a6 _% [' S( w/ x6 @; ?8 H
  42. {4 Q. r: ~% ~' [" p9 t: w" ^
  43.     serialPort->setPortName(name);2 C. f) [0 k2 B7 ?- {8 P$ P
  44. }
    & E& ?: `' V* b& L

  45. 7 M4 W& `, a0 j; Q: j, v/ y8 J
  46. void YmodemFileReceive::setPortBaudRate(qint32 baudrate)9 L( J+ T: X3 M$ \( l1 m- a
  47. {1 _% g  z9 r& ]0 X  P* \
  48.     serialPort->setBaudRate(baudrate);; I/ x% ?. I& g5 c8 b/ N
  49. }# ]5 F, h5 g$ e4 r
  50. * B0 T: c; I. W1 `) z8 t
  51. bool YmodemFileReceive::startReceive(); Z0 K: ~, h5 F! t" h' y
  52. {2 h% N' A9 {) }! D% ]: c9 _
  53.     progress = 0;
      f5 i( Q8 K5 ^3 |
  54.     status   = StatusEstablish;9 I2 z9 T! Y+ n; Z2 u
  55. 4 s: A* W& l, ~# ?
  56.     if(serialPort->open(QSerialPort::ReadWrite) == true)
    / F: L+ y" R4 g5 {% g# U$ d
  57.     {
    9 |5 H: d& A5 Y
  58.         readTimer->start(READ_TIME_OUT);
    $ u& d5 E) @( @6 z: Z/ B; C9 `
  59.   F3 [# M3 S$ d  p7 K
  60.         return true;
    " F- r- [! j- L+ A; S) D
  61.     }* s. v' ]5 ~0 Q! \! ]
  62.     else
    5 F6 {0 E; [  D! R# w( w% ^
  63.     {
    ' P: v7 \- X5 S0 U$ @1 G6 Q7 i5 e1 |
  64.         return false;
    # `7 Z" t# [; l" `* @9 o& ?# G
  65.     }
      Z! M4 j* h  K2 Q3 J
  66. }
    8 c9 B3 q( _$ [
  67. + v- X% Q  Q9 W% ]- C  [
  68. void YmodemFileReceive::stopReceive()
    6 F- @& T- H+ @1 N; V! v
  69. {9 \* m  M1 F( z) W; a
  70.     file->close();
    & l* S2 y( b7 I9 L8 [
  71.     abort();0 O5 P: a; S8 Y) ?8 ?. q% H
  72.     status = StatusAbort;- b( `5 \/ C# L) ?7 E
  73.     writeTimer->start(WRITE_TIME_OUT);7 O. r, \& n4 B; v6 v, Z# v$ Z
  74. }
    8 o5 y( m' b" m& ~/ s8 D( f% N$ G

  75. : S- W# T  n- \0 |, y/ p6 ~
  76. int YmodemFileReceive::getReceiveProgress()$ D6 C; J" B+ ~- X7 ^
  77. {
    9 u3 O7 X" @2 }! `0 G6 _% o' J
  78.     return progress;# ?* K5 n& x$ B( C0 q
  79. }2 y1 b% w1 q' \" c) r4 r8 H
  80. ) Z) L: V2 K1 j3 x! q* l, O
  81. Ymodem::Status YmodemFileReceive::getReceiveStatus()# b5 A, L& s- B# D' W. \4 R" l
  82. {; c: y2 D  E2 p* F; ~
  83.     return status;
    3 h7 H4 _+ b1 a$ S' W$ C) L* e
  84. }# M. x6 u( N/ n

  85. 2 x# s8 N! p& U; T: }
  86. void YmodemFileReceive::readTimeOut()
    # T: l) e! i+ [8 n& G3 i; }
  87. {
    / \' O# {8 A  k5 y
  88.     readTimer->stop();* C! V$ k/ A/ \+ T
  89. & q5 i% ~. @0 F4 R4 M
  90.     receive();6 T6 m7 t4 O4 C. U! t

  91. . y  B% F# V9 o% ?$ U* O
  92.     if((status == StatusEstablish) || (status == StatusTransmit)): ]5 [5 K6 p& ?8 A! `: b
  93.     {
    6 P) O8 z0 v9 t3 k1 ?* ?
  94.         readTimer->start(READ_TIME_OUT);9 }5 e) k. @& j$ h! i3 @
  95.     }
    9 k$ N) b4 O0 s2 @, `7 Q
  96. }
    - ^; W2 `* J/ O1 S; F4 ?
  97. , y- E6 \& M, y% G
  98. void YmodemFileReceive::writeTimeOut(): C# y( T  P% r1 H& ]5 k. T
  99. {4 m5 H/ q" f: ]
  100.     writeTimer->stop();" }: `' A4 X9 n# A; H0 A6 m
  101.     serialPort->close();
    - D/ C4 u: o9 R: W
  102.     receiveStatus(status);
    0 _( u4 y5 k; N, J
  103. }
    ; b; x/ \) ]* F4 E# i$ K* R' W
  104. ! x+ F5 Q/ t- e+ q5 p6 P2 F3 j
  105. Ymodem::Code YmodemFileReceive::callback(Status status, uint8_t *buff, uint32_t *len)1 ^8 W( n! X2 p) z3 ]0 ?
  106. {) Y. h& v! }3 j9 g1 q
  107.     switch(status): V( y6 x( P6 o9 B" ?; ?
  108.     {
    * ^! e9 `2 g" t+ R  q* d( f
  109.         case StatusEstablish:
    # G( z% W9 D: l! m3 S6 H
  110.         {& {0 J+ ?- v' O+ ?  H7 I6 ^1 M
  111.             if(buff[0] != 0); H$ Y. r. I. D. L* C/ I
  112.             {
    3 a) P% e- p' L# q8 S4 ?
  113.                 int  i         =  0;0 S+ w- O. g$ |' |) t' T
  114.                 char name[128] = {0};
    ' `; M: l) j- J! P
  115.                 char size[128] = {0};
    - T" ], I( ^. o

  116. ! _3 q0 N* ^* j1 j, r  ?- h7 S
  117.                 for(int j = 0; buff[i] != 0; i++, j++)
    / k6 U! g4 M! s& k  M- w8 F& ~7 ]1 K
  118.                 {
    4 f) [- B  Y' m' B0 G$ a
  119.                     name[j] = buff[i];
    ( E+ t0 m+ |- p1 ^8 N
  120.                 }
    ' b& s; j0 u- k! N- X- a2 W

  121. 6 Q% ?% g* n; a, e( O
  122.                 i++;8 O" P0 n) P& o% t* l3 u! Q+ G

  123. ( P! b4 \) K- x8 D8 _
  124.                 for(int j = 0; buff[i] != 0; i++, j++)
    & }: X4 U# e! L% y5 s' E& r% X5 \
  125.                 {
    5 \7 ?, \  g0 X- `+ T, x
  126.                     size[j] = buff[i];. r! y9 B7 C2 j* c" s8 ^' S# x; T
  127.                 }
    . r! R4 K7 d/ F( ~$ i1 y

  128. 4 q* S% q8 C: D" }5 Y  k0 L$ @
  129.                 fileName  = QString::fromLocal8Bit(name);
    0 x' H1 o; y7 ]
  130.                 fileSize  = QString(size).toULongLong();
    " E4 }% A& N7 K, I( r
  131.                 fileCount = 0;
    7 `# L3 Z4 b# a: ^* U
  132. 4 Q9 N( }& b2 |! f. J3 H/ ]
  133.                 file->setFileName(filePath + fileName);
    7 z* m( z! e7 M9 M
  134. 0 }( _; d( f6 M; [& n" d) a; _
  135.                 if(file->open(QFile::WriteOnly) == true)
      v$ \: v$ r0 D  p# y
  136.                 {
    5 x+ n) ?' E2 E& O
  137.                     YmodemFileReceive::status = StatusEstablish;
    % [/ o( @* g5 s5 F. K, l( P

  138. 6 a7 Y7 \0 q  B8 {: T
  139.                     receiveStatus(StatusEstablish);
    & U4 y6 O6 x0 i# ~

  140. 1 {% Z- `- r- ?( x$ u3 `
  141.                     return CodeAck;
    1 C+ N& I" L1 J! b# `
  142.                 }
    8 D' u2 c7 Q  H1 o+ }4 }
  143.                 else. s+ s( c, E3 u7 x. I% j9 s
  144.                 {2 D( Z, y- t+ x" u3 y( Y2 O
  145.                     YmodemFileReceive::status = StatusError;
    % x5 L  s! b1 |" k

  146. 2 l8 B9 N, G0 N+ Z8 W  R/ |' \
  147.                     writeTimer->start(WRITE_TIME_OUT);
    4 q4 D7 w7 A% Z4 S9 y6 v  {
  148. , f+ Z6 r& w7 h" r6 ~+ \) a8 j
  149.                     return CodeCan;
    4 e  t. V, f0 @$ V. s7 P& ^" }* R2 k
  150.                 }
    5 ?& K5 Z/ \2 ~9 K
  151.             }& \  v3 e1 j  P8 ?; A3 F
  152.             else
    5 V" q7 j+ ]: C1 L! l! U
  153.             {
    0 J* w. g0 r1 U4 x0 q" E  U7 r4 I
  154.                 YmodemFileReceive::status = StatusError;
    % i* O" v3 p9 J; @

  155.   H4 O, L: J" Z# c
  156.                 writeTimer->start(WRITE_TIME_OUT);2 A' A1 g- E% b* S$ w: g
  157. - Y: [  f+ M- L( W: n- h5 L1 U5 \
  158.                 return CodeCan;
    - i" c! ~2 F# V
  159.             }6 V  L6 i: B% P6 \2 M& G' ^  f# S
  160.         }, F8 O- i, k# I9 X1 _: |! e

  161. + N. e2 N& Q+ r6 z/ @' }& e' K8 m
  162.         case StatusTransmit:
    + W. Q! y+ \5 S
  163.         {) h6 ?, C& S* F6 [& r1 b0 x
  164.             if((fileSize - fileCount) > *len)
    - F6 ~9 T& I1 V) ?- @
  165.             {
    1 q  q+ S; q$ X4 l) d- J6 m& J
  166.                 file->write((char *)buff, *len);
    0 W4 ^# ^- Q1 W" x/ Q+ O; e. m

  167. 7 o5 N+ o5 g/ h
  168.                 fileCount += *len;9 b3 G/ B  }5 j
  169.             }
    : [1 Q6 I- l- o* P' H' H/ {
  170.             else) r+ y# b& D; |8 G5 N% r0 v
  171.             {5 a5 u5 W3 A. U: h
  172.                 file->write((char *)buff, fileSize - fileCount);/ z9 f; [( r9 C" B" e
  173. : g# N$ P8 a2 r$ V
  174.                 fileCount += fileSize - fileCount;, M/ ]9 E0 Q! [: D5 X4 \
  175.             }- [! O1 U: `- r
  176. ( ~0 V6 `$ m/ O
  177.             progress = (int)(fileCount * 100 / fileSize);5 O7 }1 J, s6 y1 T9 s& m

  178. % ]3 f6 c* A* X6 q) p% I
  179.             YmodemFileReceive::status = StatusTransmit;9 e+ B# f5 N% T$ I" r9 w% L3 t- A

  180. 5 ]$ l7 Z$ {) x% F0 h+ x" P
  181.             receiveProgress(progress);
    " o& A- b1 [2 \! x* I/ Y8 |5 ]
  182.             receiveStatus(StatusTransmit);
    7 ?. I/ V9 |: X# k! H

  183. ) M! V( e, b. G; H
  184.             return CodeAck;
    / l5 k. k8 ]# S) s9 W: t
  185.         }
    6 d, ]" m) e' N; b+ S% \+ @

  186. % B1 l/ E1 r9 h7 w6 M
  187.         case StatusFinish:* D1 d4 q( {  f# h" q, u/ }# x. V8 [1 g
  188.         {+ Y$ o6 f  B. R- z7 W6 Q% f3 m  {
  189.             file->close();. Y5 g+ v' G  J( S. q: ~- Q
  190. & n# B+ w1 u0 ?
  191.             YmodemFileReceive::status = StatusFinish;9 U. a" ~: o  d

  192. 1 O- w& a) g: A4 G# s6 N
  193.             writeTimer->start(WRITE_TIME_OUT);) k+ A0 p5 ^' x9 D$ F3 B/ F
  194.   b" N( k1 K% ?4 t6 T9 A/ m/ v
  195.             return CodeAck;( a3 V% f/ _7 }6 l4 `/ Y
  196.         }$ Y# A; C3 v% H; k

  197. ! A# |: m$ q* g" m7 n) C2 i
  198.         case StatusAbort:. O8 K( Q, y1 v+ B3 {) ~* [
  199.         {
    ) z& ~4 H' H: Y! @6 P5 ]- f
  200.             file->close();
    $ }1 _! u6 u, Q

  201. - s$ Y$ I. q! ]0 Z4 ~# m. i& u  |  a
  202.             YmodemFileReceive::status = StatusAbort;4 n; h5 b6 p- B/ D* G( U' m

  203. & z" {( x- R( Y3 n" _6 F
  204.             writeTimer->start(WRITE_TIME_OUT);
    6 d* ~- i+ [# O% `$ ~( I
  205. 2 M& @2 V9 ]3 c6 N0 Q) O
  206.             return CodeCan;
    4 z3 K7 e  H% l0 g/ M/ _' i
  207.         }
    9 t( M( N$ H' F
  208. 0 n' c& P7 D' M+ n# I
  209.         case StatusTimeout:+ g/ y+ D) q' F9 @6 Y( u8 O* ^
  210.         {# _' P  q/ a& b9 n, U
  211.             YmodemFileReceive::status = StatusTimeout;! e5 b. o2 M9 r, m. U4 D

  212. 5 L& u' ^4 A4 C) T- r
  213.             writeTimer->start(WRITE_TIME_OUT);
    6 k1 J1 h6 m* j! O! I: M: m: D

  214. ) C& U  y  b; I" h
  215.             return CodeCan;( V0 x% _* S1 V5 h
  216.         }- h8 A9 N8 A" W4 k
  217. 1 ]5 |5 ^9 n) X
  218.         default:* ?  B$ C0 ~) j% `0 @- t4 `" m
  219.         {5 Z. e$ x% n9 r4 {+ \5 h1 l
  220.             file->close();
    * G( L- L  b4 q2 d0 l/ U1 A

  221. 6 m- f. J* W! ]+ `' p: T
  222.             YmodemFileReceive::status = StatusError;
    $ n7 h8 m  t  `, S6 y! q
  223. 8 V' c; \4 ~* Z4 H
  224.             writeTimer->start(WRITE_TIME_OUT);: `# v4 E& X' u' d8 i

  225. " `: d8 U1 [, D: }  ?
  226.             return CodeCan;
    " P+ h9 m" |' i" ?  }* v
  227.         }" C7 J0 z  |2 j1 }
  228.     }
    0 [# Q/ W, p* Q. l4 }+ x- }/ C
  229. }7 I9 j* F8 y  O2 s

  230. / O& F6 v9 C; B1 L7 r
  231. uint32_t YmodemFileReceive::read(uint8_t *buff, uint32_t len)
    ; q# W/ E& X0 w0 ]+ U3 z
  232. {/ T  b. Z& _. r2 h$ U: r* h- I8 [
  233.     return serialPort->read((char *)buff, len);. p. w$ [5 \( [% I( y
  234. }
    : V: ~& P7 B  s2 Q+ b+ X" y
  235. 0 P' y* V* N* }$ R
  236. uint32_t YmodemFileReceive::write(uint8_t *buff, uint32_t len)
    ; E( Y+ g- a3 v% C. n/ P# \
  237. {
    : t' w; N0 t4 P# e, U9 V
  238.     return serialPort->write((char *)buff, len);
    . W8 |0 p- y: [
  239. }3 _5 P2 j' M. K- G, b" L: o- S
复制代码

# Y0 ]& D& w" t& x" l9 e% B% b5 q8 ^% I

9 B' |( i5 ~( K! w* R7 g+ n  X8 B% V  y# n5 b, [
XinLiYF 回答时间:2018-3-6 02:00:03
      YmodemFileTransmit.h文件
$ q& C* e7 }2 H3 I5 b
  1. #ifndef YMODEMFILETRANSMIT_H, I, Y5 D* Z% q% E: C  J! N
  2. #define YMODEMFILETRANSMIT_H
    3 m3 v% H7 V: p4 H3 N4 V
  3. / T5 `2 `) i/ r
  4. #include <QFile>
    % S4 q/ W3 \4 B, e
  5. #include <QTimer>/ A- L+ q4 W& P, i, b! j
  6. #include <QObject>
    2 h6 _8 m2 B$ _
  7. #include <QSerialPort>
    % O8 M) e$ m3 {" x( k
  8. #include "Ymodem.h"  j8 i4 z; n. }' V' Z* K, ~: S

  9. 2 `% y9 S$ f7 y$ M2 A8 |8 j/ O
  10. class YmodemFileTransmit : public QObject, public Ymodem% k6 `; m3 [# }9 B7 U* q; I- _
  11. {$ N/ r/ M1 O. [1 ?" F$ @# ?
  12.     Q_OBJECT
    , I1 [- a% j' [- M9 u  A3 T; b
  13. 4 N/ l9 G$ }& Z
  14. public:, d1 h8 c" [) o3 W% _0 |
  15.     explicit YmodemFileTransmit(QObject *parent = 0);7 v& j9 T' I7 w. `' x& U
  16.     ~YmodemFileTransmit();% x' V0 }1 C1 W2 z* @  f

  17. 0 p3 T: y" P- q; L+ q
  18.     void setFileName(const QString &name);3 Q/ K$ |" q3 O

  19. , I1 {) _2 m4 w2 R0 f
  20.     void setPortName(const QString &name);: l( N* u! b5 b+ x% T
  21.     void setPortBaudRate(qint32 baudrate);5 l: s  x' E4 M  v, m4 E

  22.   v3 c4 W  j/ C3 x4 S$ j
  23.     bool startTransmit();! u2 V+ ?- m- f) }3 I
  24.     void stopTransmit();9 O7 E: `2 \1 z8 m# D6 C
  25. - w# R2 D7 C. F' R. Z1 X) A
  26.     int getTransmitProgress();5 _* n* ~# Z8 a* I5 k/ `; \
  27.     Status getTransmitStatus();! J% Y0 b- ]7 W1 U1 ^
  28. ) d$ J8 r7 H7 U; O0 _' B: A
  29. signals:
    $ M9 {( g. l& u0 Z8 ^- i4 P
  30.     void transmitProgress(int progress);
    $ ]( J3 r+ _- J6 J$ t* b: o
  31.     void transmitStatus(YmodemFileTransmit::Status status);) n  m, m" x  R  Q/ {

  32. 6 N" f- U' H* t6 m) C* U
  33. private slots:
    / l4 G! V- j- k& m6 R0 m3 L
  34.     void readTimeOut();. P6 h* Q! l% {! N6 o2 }6 o/ \
  35.     void writeTimeOut();2 Q6 l% k4 @$ i6 T* N. }9 o8 V
  36. 1 x: m9 K, W# X8 i/ J
  37. private:9 [, P. ?6 J  d' i. F# a
  38.     Code callback(Status status, uint8_t *buff, uint32_t *len);
    ' V1 x8 _: J: U. _

  39. , n( s0 M  I9 V# V0 Q6 A
  40.     uint32_t read(uint8_t *buff, uint32_t len);5 ]6 U7 g- k, r+ J
  41.     uint32_t write(uint8_t *buff, uint32_t len);+ n. W3 x$ d9 W' g
  42. 8 D4 |, ~0 @  v& |) q8 a, U; n
  43.     QFile       *file;
    5 Z8 L: L; f2 {
  44.     QTimer      *readTimer;
    & {& _8 Y9 i; z# a! e  q6 G1 n. v
  45.     QTimer      *writeTimer;
    ( m6 N- O# W, ]! d2 Y
  46.     QSerialPort *serialPort;9 D; o8 Q& N, C4 L$ L
  47. , K5 d- W8 v7 G6 R4 K0 S- w
  48.     int      progress;
    - `  x% d- u" D+ M
  49.     Status   status;
    % G* b6 A0 j2 x/ R) H4 H3 @
  50.     uint64_t fileSize;
    , t9 i: X* f4 V
  51.     uint64_t fileCount;# r; o& E9 _* s) E
  52. };
    , i8 `/ R7 M% ~1 F+ p* g
  53. 7 a0 ~# ^" i; A
  54. #endif // YMODEMFILETRANSMIT_H' h1 e! j7 P% d$ g% [. b% i' ?
复制代码

+ \1 O9 |& J/ f) w5 m" h# N" h/ a4 I3 V      YmodemFileTransmit.cpp文件
, R! n) p& w5 P& C; Z/ v
  1. #include "YmodemFileTransmit.h"/ v. \4 b0 ?, I
  2. #include <QFileInfo>
    : [  n1 o+ D+ C5 @; S9 v& ?2 C
  3. $ e' @3 t6 A; \8 F" y& [" {* L
  4. #define READ_TIME_OUT   (10)# D* _& m# u; m) y" b
  5. #define WRITE_TIME_OUT  (100)
    3 l9 y3 L4 c  f2 t  _

  6. ( f3 f5 x  m* Y0 F% X: ]
  7. YmodemFileTransmit::YmodemFileTransmit(QObject *parent) :" z+ x2 w6 S/ F: n" Q. v
  8.     QObject(parent),
    $ G4 C) G3 E! @2 A
  9.     file(new QFile),- E2 b4 c6 W3 Y& [7 R5 o
  10.     readTimer(new QTimer),& m, C. M' C# Z: Z; q( h* I) i
  11.     writeTimer(new QTimer),
    2 Q' y  q$ X2 p6 e/ r! K. v" A
  12.     serialPort(new QSerialPort)
    $ s& e; O, G9 |
  13. {$ D9 h# Z, B; w3 d$ g; V% K
  14.     setTimeDivide(499);) ^7 g2 Q: C  c2 |; F+ \$ Y3 r* o
  15.     setTimeMax(5);$ ~6 P, F- d& Q& |9 L9 D
  16.     setErrorMax(999);
    3 [- r, k0 b3 J$ [' a' I

  17. 2 A  e, M) _8 ]  U( E5 r
  18.     serialPort->setPortName("COM1");
    1 }, r6 D& {+ M; w% u
  19.     serialPort->setBaudRate(115200);
    4 c8 j# |' P% t$ m% ^
  20.     serialPort->setDataBits(QSerialPort::Data8);
    % @* {" z1 u) A, I$ ^: w7 k6 G
  21.     serialPort->setStopBits(QSerialPort::OneStop);
    8 l0 n5 b$ N$ F8 T' b# ^. c' Q9 z
  22.     serialPort->setParity(QSerialPort::NoParity);
    % d8 }+ _6 T6 s3 Q& {$ n- u' C4 l
  23.     serialPort->setFlowControl(QSerialPort::NoFlowControl);
    . s2 z, G' b' w6 p. _4 U; d) A
  24. 4 f5 v  t, L- p2 D3 s% O
  25.     connect(readTimer, SIGNAL(timeout()), this, SLOT(readTimeOut()));
    % m& @* D: D: \& }# R8 J4 l! I
  26.     connect(writeTimer, SIGNAL(timeout()), this, SLOT(writeTimeOut()));2 J8 n2 Y7 g! z! [$ d9 N9 q, b
  27. }0 O; d  P7 _5 T8 `0 c
  28. 9 m  _& R& ^5 I6 [" ]. D; B, t/ Y" r
  29. YmodemFileTransmit::~YmodemFileTransmit()+ O8 K, Y1 k9 r; E9 x5 @* V" a! I* D
  30. {
    * L. ~# w2 a0 i
  31.     delete file;' u, {" m3 x  ?
  32.     delete readTimer;- R- {6 N0 v7 y: E9 }  S
  33.     delete writeTimer;! X( ?% w0 |* G$ H( A0 {
  34.     delete serialPort;: @; H6 C) p2 c9 o
  35. }: K' h- D" _  x; a6 Q

  36. , m7 W; v8 s- q% V' w7 F! t
  37. void YmodemFileTransmit::setFileName(const QString &name)' x$ A4 \% e, _$ X6 `
  38. {
    8 w: q# H4 h3 p: w9 z+ Y
  39.     file->setFileName(name);
    % h1 ]6 X# u/ D* X) Y1 l( f: H" r
  40. }5 q& c& X0 k6 _7 B9 A2 G
  41. & w0 e+ ?, l0 L" q, f9 W
  42. void YmodemFileTransmit::setPortName(const QString &name)2 _9 v+ Q9 X; E( L: J& B8 N" J; ]
  43. {& m- g0 f; p4 E$ P. I, [* b4 O
  44.     serialPort->setPortName(name);
    # Y+ Y4 b& h6 Q$ k6 N
  45. }
    9 U; q, e% J$ S! x+ _
  46. + E* Z. d& f- r7 |$ J6 W' K2 w4 j
  47. void YmodemFileTransmit::setPortBaudRate(qint32 baudrate)8 X  J. L& Y% q5 Z
  48. {
    : M3 e2 s) @3 k5 y8 W
  49.     serialPort->setBaudRate(baudrate);" }" K+ G5 @5 X
  50. }
    - \2 e6 l/ W( S( w
  51. * l: ~* e, J& ]% S
  52. bool YmodemFileTransmit::startTransmit()! W, v4 D. b: ?, Q
  53. {
    7 f; ^+ K: Q$ h- h
  54.     progress = 0;$ e5 P# p7 Y5 I. |2 O6 m
  55.     status   = StatusEstablish;
    ( F( l9 O* o* t" J

  56. 3 i3 _, O' L- d+ {# p8 h6 h
  57.     if(serialPort->open(QSerialPort::ReadWrite) == true)# n1 i! @3 x' \5 E& d( f0 P5 [& w  a
  58.     {# d) d& j4 x! K3 d! K
  59.         readTimer->start(READ_TIME_OUT);
    ' k% ?7 p$ h2 O; v% N; @
  60. ; I4 k2 }( X0 W
  61.         return true;7 N+ s( g. n. y& o7 ~
  62.     }
    5 P+ m, E8 I; M
  63.     else' l& M- }4 g( Q8 o% F: ?, o0 |' x# _
  64.     {
      ?; u3 ~" k3 t, s4 t
  65.         return false;7 a6 M7 c. C* O6 Y
  66.     }3 M- j7 `! Q, B/ v5 Z6 W
  67. }
    ' v5 L: _( v8 C+ j

  68. % J- e) p9 ]( j8 [1 x
  69. void YmodemFileTransmit::stopTransmit()/ U8 j! g) ]( N: I5 h6 Y( h& C% `1 |
  70. {" Z/ u5 X8 ]% N$ M, ?& S
  71.     file->close();' Z6 `/ [* U8 H( q3 Y
  72.     abort();
    0 S$ V) g0 Z1 o9 B
  73.     status = StatusAbort;
    : q& x4 Q  o9 V, r  w* u% i
  74.     writeTimer->start(WRITE_TIME_OUT);
    / g- a7 G  @' V3 n" y0 s
  75. }/ y. [! i1 r) Y( U8 B

  76. 9 E+ m  _6 {( X* w
  77. int YmodemFileTransmit::getTransmitProgress()& B. a( i0 F, E0 A! Z: q
  78. {
    $ b: z% x  R7 R4 R9 F# ^: ]# M
  79.     return progress;* Z/ [0 r, |) z" W
  80. }3 ?" N9 o) L3 u2 E

  81. 2 _  N' D: ^! p" o" b& s* F$ d+ P
  82. Ymodem::Status YmodemFileTransmit::getTransmitStatus()
    ( a- G, e+ f" T" a9 {
  83. {
    & e, W4 w1 v, _) d& o
  84.     return status;8 ?$ _' V& o& w# B0 u' `9 F) o
  85. }- \8 Y" @' Y5 H  M6 \: P# A

  86. ' ]- N6 E3 v* t$ D
  87. void YmodemFileTransmit::readTimeOut()
    9 Z. _* y! J" }. B8 ~
  88. {
    9 T& ~" D  @0 ~' W  y5 d
  89.     readTimer->stop();7 h, D& R7 p8 z6 n/ W

  90. ! n2 r+ q7 \3 D( O
  91.     transmit();
    " z; w9 E; H8 U4 @
  92. 3 l6 K- N: h$ N# f: ?
  93.     if((status == StatusEstablish) || (status == StatusTransmit))* Q4 B; v7 r9 s, s2 Y% k
  94.     {( W, j3 E- ~  x+ w+ ]4 W% a! S# ]
  95.         readTimer->start(READ_TIME_OUT);
      i! \" T; S+ G0 N7 C6 l  k
  96.     }) u' l  }! U; x& y0 `
  97. }
    0 z' W' n. p9 F! x' n0 u. ^
  98. & A+ S( l  k( j% i% I
  99. void YmodemFileTransmit::writeTimeOut()- r' }+ x1 K$ ~! N9 D
  100. {
    ; w) F7 ]- `( N# Q% I- V5 `
  101.     writeTimer->stop();) E, \9 C. W8 b# n4 R1 B
  102.     serialPort->close();
    6 ^! P" |+ t) N: [. \7 i
  103.     transmitStatus(status);+ |, I# H. i9 l+ b9 @# f- J& x  W
  104. }
      A3 J0 I- m7 F7 n0 F

  105. - I( g8 a6 @/ Q! v$ k/ y4 @7 r
  106. Ymodem::Code YmodemFileTransmit::callback(Status status, uint8_t *buff, uint32_t *len)
    0 m' X9 W, G$ ~" x
  107. {
    # ]3 Q+ v) x' \) S
  108.     switch(status)) e/ O4 {  ?2 i! \
  109.     {
    ) @" ]/ t$ ~: _
  110.         case StatusEstablish:
    0 g# N( z' B* v* `( N: O: O
  111.         {
    2 D" @% V( N/ h( T# u3 j  ]3 J
  112.             if(file->open(QFile::ReadOnly) == true)# }3 \5 \- ~! i% ]7 R0 p, R9 S
  113.             {
    9 v3 u& n. ^. S  x: e4 F: R
  114.                 QFileInfo fileInfo(*file);) i3 e0 R# L* V/ J" k' d* G  P0 T
  115. ' S) U/ Q! V/ N9 P! W; ?& N" o
  116.                 fileSize  = fileInfo.size();  p% `2 j3 }0 ?6 G
  117.                 fileCount = 0;
    7 P9 g- Z( C6 h' f0 v  F
  118. % M' P+ y, [4 k/ L( z$ g5 a
  119.                 strcpy((char *)buff, fileInfo.fileName().toLocal8Bit().data());& [/ p; n+ [' @' X# m+ O5 P
  120.                 strcpy((char *)buff + fileInfo.fileName().toLocal8Bit().size() + 1, QByteArray::number(fileInfo.size()).data());" u) g: m# `4 h8 a( c+ S
  121. # n2 M7 D0 ^8 J  g, M" w4 K, p
  122.                 *len = YMODEM_PACKET_SIZE;
    6 Q. H8 o( n8 `, F

  123. ; D) i4 b7 d7 g! N# W4 [
  124.                 YmodemFileTransmit::status = StatusEstablish;& H2 V% T6 T3 E9 L- s. h

  125. 5 q9 O$ u, s3 h/ U: `$ P7 ~3 H) w
  126.                 transmitStatus(StatusEstablish);. `3 k0 M! A; T  }- |2 c7 g7 s

  127. ( ^8 r8 I  B% e  G8 q- _9 }3 N
  128.                 return CodeAck;% [: N: t( T$ W/ Q0 F
  129.             }
    : b" p# {: O0 I  @/ h" ?2 W$ \2 h
  130.             else
    8 w! s% Q, I2 L- `
  131.             {
    4 d; S# Y/ _' `7 r. M  {
  132.                 YmodemFileTransmit::status = StatusError;
    * d3 Y( Q" w, f5 C# G( e

  133. & D$ c! ^' P8 R- S4 }4 I
  134.                 writeTimer->start(WRITE_TIME_OUT);
    ' z* O7 m6 ]! S7 l% d8 j
  135. 7 a" ]+ ~. o8 B( ~& ?) g
  136.                 return CodeCan;4 R9 ^5 G$ F4 W* S- t8 Y
  137.             }3 {! T  O. Z& {! @" Q
  138.         }4 q$ c: Y6 ^9 j- k! [
  139. " {% j: `3 w( w) \
  140.         case StatusTransmit:# D) f2 i9 [$ f5 @4 }9 L
  141.         {5 h0 J- `9 \1 k1 @* Q
  142.             if(fileSize != fileCount)- p/ G/ Q+ M) U% {
  143.             {
    4 Z" U% S5 i1 \& V+ ]: L
  144.                 if((fileSize - fileCount) > YMODEM_PACKET_SIZE)
    + V( y' S: `1 U- J3 _5 v
  145.                 {
    , Z$ W+ e) X( [' m& M) U+ @3 Z1 N+ X
  146.                     fileCount += file->read((char *)buff, YMODEM_PACKET_1K_SIZE);
    ' H' B  v  X, P8 Y. l
  147. 6 L+ P, u$ v" ]+ Q" K; s
  148.                     *len = YMODEM_PACKET_1K_SIZE;
    : g. [1 ?' k+ d% M1 c: P3 O
  149.                 }; @/ j1 f! F) ^8 c2 N, _, x
  150.                 else- T, n+ E3 U" A3 ^" X
  151.                 {; o1 Y2 D; g5 E) A3 x7 s3 k
  152.                     fileCount += file->read((char *)buff, YMODEM_PACKET_SIZE);# M! W: M% {% M& `, k

  153. 1 }; d: F' x$ f, k) Q
  154.                     *len = YMODEM_PACKET_SIZE;
    % m& m- P1 O4 z. F$ h1 s8 X- J
  155.                 }6 k$ z( C( Q1 ~/ j/ b7 Y8 K) o
  156. 6 V& B. {4 }& d# {* i
  157.                 progress = (int)(fileCount * 100 / fileSize);
    " [4 O! C/ C1 s5 c
  158. - D' D3 Z) L) C) x# d. E  p
  159.                 YmodemFileTransmit::status = StatusTransmit;
    7 R! K+ ]3 _$ _+ A+ j

  160. : z- J9 S- S1 L; r& c" w6 a+ `
  161.                 transmitProgress(progress);7 N6 v" T5 {! L% L, e( h' E6 n, d
  162.                 transmitStatus(StatusTransmit);
    9 D+ X1 k8 d( m: y; J4 n1 Y
  163. 6 r9 r1 H5 J) J7 L" u
  164.                 return CodeAck;" ]- l4 c- Q2 R
  165.             }3 N0 a. Y7 U/ r5 K7 A* l
  166.             else+ _& [0 w3 f1 |% I
  167.             {# @3 @3 _" W0 C$ P9 j5 g# A
  168.                 YmodemFileTransmit::status = StatusTransmit;
    2 j. J  a  W: X

  169.   S1 @  w' g1 r# S, E' f! y- O
  170.                 transmitStatus(StatusTransmit);! R! B2 g  c3 O* J

  171. , h9 P. a# D. i* k4 Q6 s$ f. E7 _8 G
  172.                 return CodeEot;
    $ ]' ?. n& t3 A" d% W
  173.             }
    4 M/ v8 }) [6 p% j
  174.         }
      z& P9 u4 N6 k) ]3 @

  175. 5 |. h- N3 _7 }! P4 f, N
  176.         case StatusFinish:
    # u+ E, \% ?2 c
  177.         {& D) R5 @8 r5 l5 k' N( f
  178.             file->close();
    ) J3 o: ?  d4 z. ^6 |/ X" q, K
  179. # z) s5 V& h4 G) P! E/ _
  180.             YmodemFileTransmit::status = StatusFinish;
    , `9 B) i8 X( J7 J. C- ^* A
  181. 5 \  |* m5 G3 ?& \3 U2 w
  182.             writeTimer->start(WRITE_TIME_OUT);9 w% }. H+ x- c: L0 |) `

  183. 9 v7 e4 p+ k- J7 g( [/ T) w8 b
  184.             return CodeAck;
    1 n: `4 ]6 k* c7 c
  185.         }. g1 |4 X  b3 O! R! U
  186. ; o0 g3 b2 W2 F0 I2 h: v$ L' O
  187.         case StatusAbort:. @/ |% B3 z  Y* W, `: s- W
  188.         {4 _( ~! T" s5 C7 W0 g6 g" v
  189.             file->close();
    ' s, o+ W" |" R
  190. * q% ]7 X: r9 k' z' n1 t! \
  191.             YmodemFileTransmit::status = StatusAbort;
    1 s& y; {- f; x& Z$ j& r

  192. ! w3 N  D; R6 g& q) q, [4 [
  193.             writeTimer->start(WRITE_TIME_OUT);
    * f  ^9 F( g5 R, O- R% }8 s, ^6 Z
  194. - g$ [( @& H# A, w
  195.             return CodeCan;
    8 R* p' i' K( v: N
  196.         }5 y5 p6 e, T7 S+ F% L. o0 J( \0 w

  197. # [" T0 y0 N7 r; P3 u. O1 w: v
  198.         case StatusTimeout:
    : F9 R2 e/ ~3 m  K# I, E
  199.         {( o6 ?- Z" w7 O( ]4 A; E
  200.             YmodemFileTransmit::status = StatusTimeout;7 P# p+ z( y9 b; Y; Q

  201.   F2 b5 s6 c! q! d
  202.             writeTimer->start(WRITE_TIME_OUT);+ B2 S. _1 ^; V3 r
  203. : `( L- z# q% Y+ G/ z1 l$ ~  g* j, c
  204.             return CodeCan;4 ]" {" l7 @6 Z0 m7 p8 j
  205.         }2 s) Q, f& |3 F7 `) o7 P

  206. - |  `& A+ @# T7 Q) x' {) L' g  i
  207.         default:
    4 [: s% E9 r1 f) [8 U5 F
  208.         {" u7 p0 W% {8 V
  209.             file->close();
    $ {' d& O7 j  Z% J# T
  210. 7 G& F2 n; [8 U* N6 I' \! L
  211.             YmodemFileTransmit::status = StatusError;$ r* S# U0 S& U/ Q6 w) Y, F

  212. 3 [+ _( e7 g8 j6 F- [
  213.             writeTimer->start(WRITE_TIME_OUT);
    # M  D3 c. b" P! A
  214. # x0 k& z1 J$ g& A+ I8 h& c+ H% V& s
  215.             return CodeCan;9 P9 C  f- x, G: ^  `
  216.         }
    5 e0 w7 ^, g% O- N4 m( i
  217.     }
    , c! E, O6 y% g8 @- Q. p8 W
  218. }+ A0 c% W" j$ s8 n0 P
  219. ' M' {- e9 S8 }  U" |
  220. uint32_t YmodemFileTransmit::read(uint8_t *buff, uint32_t len)
    6 O/ O7 ]4 |, g, d6 C
  221. {3 K+ C( c- ~2 Q7 x1 W& |1 x* L
  222.     return serialPort->read((char *)buff, len);1 b3 N  ~* z4 c0 B0 \5 E+ S
  223. }
    1 P( a; q* v: d

  224. ; p1 [6 D+ A( A$ b4 j& @
  225. uint32_t YmodemFileTransmit::write(uint8_t *buff, uint32_t len)
    4 q6 e  @- O! V' m* Z' Z; s
  226. {
    " Q0 A8 q3 `9 ?, L! z& h
  227.     return serialPort->write((char *)buff, len);" c, r: [: g5 Q1 L) D
  228. }
    3 N8 @( F) l8 ^$ \$ _' q& x
复制代码
5 m0 I5 V  c2 f- A, D9 j
: I) i6 [3 S2 N

) k9 f  P6 `  e, C% _) Y/ o
6 G( M! N( S5 A) G# x0 s
XinLiYF 回答时间:2018-3-6 02:02:04
      widget.ui文件( x: c- U; [, k. ^
  1. <?xml version="1.0" encoding="UTF-8"?>
    ! z! j( i7 v3 s- f3 j
  2. <ui version="4.0">3 G1 S3 k0 L) o- y: ?* \% z2 e0 j
  3. <class>Widget</class>% i" J, w5 S+ U+ t4 z. R
  4. <widget class="QWidget" name="Widget">
    $ Y0 v8 u. X! T8 b
  5.   <property name="geometry">
      ^3 w. ^2 o- r6 i
  6.    <rect>
    * ?3 P) s# i9 p7 Y" f
  7.     <x>0</x>
    * ]$ p/ q; [. S! p5 b8 w9 I
  8.     <y>0</y>9 w" \7 X! y2 Q: W" ?+ w  U
  9.     <width>444</width>3 p$ ^" J4 y8 n! Q
  10.     <height>255</height>+ B+ o9 L4 _" l% I' n
  11.    </rect>
    ' `+ A/ l/ V2 Z/ X# ^% `* H
  12.   </property>& R: v0 z7 O* L' t
  13.   <property name="minimumSize">: c" }- C8 Y1 A) i. Z$ Q# x
  14.    <size>, |! _5 M1 d& |0 o) h: K
  15.     <width>444</width>
    4 @5 ^: T; E2 B% D6 h
  16.     <height>255</height>
    / _0 a+ G7 Z3 _9 ?6 f( y) s
  17.    </size>
    9 c5 C# `5 q" U3 S5 e0 O
  18.   </property>3 |5 x1 a. x- b$ J  A2 z0 a* b
  19.   <property name="maximumSize">8 i( s+ D* B! W! |! t+ ?
  20.    <size>; M' `9 V  ?5 V! b
  21.     <width>444</width>3 w( g, T( P! [3 p" C
  22.     <height>255</height># e: @4 m2 P% R( \; t
  23.    </size>4 C* S& E( _5 U+ O
  24.   </property>
    2 t( ~8 _. Z+ S: b
  25.   <property name="windowTitle">- K0 W, m2 s* M5 p$ ~0 M2 N# n
  26.    <string>SerialPortYmodem</string>
    - s3 I, u7 U  k1 O. Q6 O7 ?+ {7 f
  27.   </property>* Q; n: A8 o0 A  p! d2 H7 u2 I
  28.   <layout class="QVBoxLayout" name="verticalLayout_3">
    * h/ a( {) C0 Y7 m7 R
  29.    <item>
    % h% Q/ T+ [" M- c
  30.     <widget class="QGroupBox" name="groupBox">7 r; V3 [4 j+ c6 a/ F+ V
  31.      <property name="title">
    " ^6 u6 o, O+ D5 Z$ @8 l
  32.       <string>串口配置</string>
    $ e6 x) m& J# k5 B6 q
  33.      </property>! [2 R+ p* ~3 ^6 e3 @
  34.      <layout class="QHBoxLayout" name="horizontalLayout">) t6 o. m0 V( v: a/ I# E8 |
  35.       <item>
    , X7 _2 n5 _/ G8 b, C* I( Q
  36.        <widget class="QLabel" name="label">1 x; t  b, p: K  q) G) f
  37.         <property name="text">2 q6 N5 s1 v& e! Y$ @8 [
  38.          <string>端口:</string>/ U7 W8 p/ b0 L' c& D
  39.         </property>* D4 p7 C& N+ o) I
  40.        </widget>' N/ Z, G* O9 ^$ ]# y" Y" M  [
  41.       </item>% i9 B( Y6 k- I* c
  42.       <item>
    0 e& u+ k+ q( p; {0 v2 U6 n
  43.        <widget class="QComboBox" name="comPort">
    & u5 ~5 b8 [# l
  44.         <property name="maxVisibleItems">6 W5 O& r- a6 R! z/ {
  45.          <number>12</number>
    1 a4 h8 A, O! K, b% s' e9 l
  46.         </property>( d$ Q6 ~. x$ G# _/ E4 C$ H+ P) `
  47.        </widget>2 E+ |! S# A) `( e3 e
  48.       </item>
    1 v. V3 j8 P' g$ L* w- p: h! r+ D/ q
  49.       <item>* Z8 \8 [7 N8 s& C: y( u
  50.        <spacer name="horizontalSpacer">
    0 @2 n2 a* W9 s8 |- X  d6 D
  51.         <property name="orientation">
    7 \$ `1 T" [$ ]! m" o, z
  52.          <enum>Qt::Horizontal</enum>/ R9 V5 y  n0 D% x: P
  53.         </property>
      R) h7 B1 z3 U0 ]. |/ W4 R
  54.         <property name="sizeHint" stdset="0">
    5 p9 B% _3 @* y  D1 P5 [
  55.          <size>3 Z7 }5 |/ w4 ~0 X
  56.           <width>40</width>
      N" Q/ A+ z. x7 Q$ H
  57.           <height>20</height>, g  @- K, ?$ |/ @- \: q
  58.          </size>
    , ^) l# Z, k5 v; a
  59.         </property>: n1 D1 X6 u5 s) s( I
  60.        </spacer>
      o% s  C; @8 R: G
  61.       </item>
    3 [% {( ^1 B2 f1 V
  62.       <item>" l9 n2 W) X2 m
  63.        <widget class="QLabel" name="label_2">: L8 h: P# |) `
  64.         <property name="text">
    * n: Q% p+ s$ a7 Q
  65.          <string>波特率:</string>$ ?6 c+ q) e2 E5 {
  66.         </property>
      F" j, q$ `5 Q
  67.        </widget>
    2 x& V( |/ q  K  R
  68.       </item>
    9 @7 b6 c* ^; ]9 ]$ g3 M
  69.       <item>
    / ?4 O  ?: M' G, ^, V& ?7 W8 t; X; {" h
  70.        <widget class="QComboBox" name="comBaudRate">+ h. C8 R+ H/ S) v. l4 I& B# P- o
  71.         <property name="currentText">
    # T1 `% x$ K+ h( U; W. M
  72.          <string>115200</string>2 T( @$ i2 }. V
  73.         </property>& ?. k2 U' ?% f7 m  K8 b
  74.         <property name="currentIndex">% Y( h( U9 N: t5 c3 j$ L% M. o( O
  75.          <number>3</number>2 E1 e2 G! n* `( Y
  76.         </property>
    5 U+ C: n& N  T3 m
  77.         <property name="maxVisibleItems">
    ' X: d3 y" j: C5 x8 ]
  78.          <number>12</number>
      ?. c1 b2 B! z. K+ Z$ W' ]% m
  79.         </property>( ~' [; e8 x; h
  80.         <item>* [0 t' o* B+ T/ E: z, Z% ~) D
  81.          <property name="text">
    8 z8 d, q9 T3 R6 ~; [/ ^5 i
  82.           <string>921600</string>
    " f, T* l( o5 [0 q  d2 D
  83.          </property>7 l2 W+ }! H; {" d0 O1 X% m2 ^  ]$ N
  84.         </item>& u; `( \/ n) I4 J
  85.         <item>
    1 ^1 m4 [' w9 B/ O" x; q
  86.          <property name="text">
    4 n% k( u7 H# ^* v2 Z. A+ Q. t
  87.           <string>460800</string>4 E) V) u1 H, E7 D4 E7 g% r! D
  88.          </property>
    9 R7 I, R/ i. K' s6 _% j
  89.         </item>4 v/ X# I* j) W0 G! m" [- W
  90.         <item>6 k; C% H9 B1 z
  91.          <property name="text"># w3 ^/ y' c( \3 P! p
  92.           <string>230400</string>" O3 C: `! e+ e6 e
  93.          </property>/ P6 J3 O+ d1 U" m* J2 ]; g
  94.         </item>" T8 c2 V$ W# x: d* H
  95.         <item>6 t9 Y: O+ x5 U
  96.          <property name="text">
    : u1 s1 c' Q0 ~
  97.           <string>115200</string>
    2 r* f2 _# [4 K' l
  98.          </property>
    $ u+ Q7 G/ |0 v# ~
  99.         </item>! ^2 K0 J8 d2 w7 V6 T
  100.         <item>! C4 c/ ~7 E. K/ z
  101.          <property name="text">
    5 k3 w; p9 F3 ^/ B" w: L
  102.           <string>57600</string># n' ]6 J, @. S! a# F  j! y( i
  103.          </property>
    6 W2 Q# W2 s( V; F  k
  104.         </item>, S: E: |& G2 P
  105.         <item>' _) g% R% ]; w$ [$ A
  106.          <property name="text">
    ! ^9 L' K' W' y" l# A) Q* n  P
  107.           <string>38400</string>
    ! v3 v; |+ i: Q# A+ l4 h/ z0 ^% Z
  108.          </property>
    ! j' @: Z/ E  [# J* v2 |1 ^. T3 M
  109.         </item>( g9 R0 ]8 r, ?0 }$ u
  110.         <item>* v0 n6 X0 P$ m/ z0 I+ \8 c. |, g
  111.          <property name="text">
    ! t$ L& d1 x1 \# r3 x
  112.           <string>19200</string>- j1 t- s4 u; m4 M. s, ?
  113.          </property>/ w1 [/ X: w- j/ r9 l
  114.         </item>1 n/ G: n- ]5 u/ B9 q
  115.         <item>
    1 g8 S: H3 ^1 K# h2 Y( X; i
  116.          <property name="text">
    / r) N% M- x' X& p9 R2 G+ C! m
  117.           <string>9600</string>+ _6 _! F, |0 t* C. m1 A
  118.          </property>2 x, |1 \; [. x3 [, B3 }
  119.         </item>
    & ^5 y# x4 b$ {- W
  120.         <item>% ]2 ^. g9 A8 q) r, i
  121.          <property name="text">
    ! M. p* x( G$ U5 }3 L9 G5 z, m9 o
  122.           <string>4800</string>
    % L. ?) M5 f( K- q, ~
  123.          </property>0 H  P7 K) z' Q& ~4 [
  124.         </item>+ V& X: j1 Y) X
  125.         <item>
    * M2 ?: v5 d* M$ L7 \2 Z
  126.          <property name="text">
    2 g" Y2 o. ^! ~- c5 D" _( O/ v! l
  127.           <string>2400</string>) p/ T, m8 B3 @+ I2 p
  128.          </property>$ U4 z# a" W  u
  129.         </item>0 @; `5 J% }/ T; M6 g$ J* w4 l( m
  130.         <item>
    / L$ M2 _3 h) e5 g( V" _+ T, \! N
  131.          <property name="text">
    ) i# R6 R2 m) h9 L! Z0 K
  132.           <string>1200</string>
    ! p1 [" G( K+ r4 E/ `7 N
  133.          </property>
    % G; b7 P: s, ]3 }' f2 E
  134.         </item>
    ; a0 |- ~7 D- J# l( D
  135.        </widget>8 }) J3 d9 D9 X* [7 p
  136.       </item>
    6 L0 L' P  n9 k. g* U
  137.       <item>- I4 ~) c* o0 O; S/ [; z2 A1 ]
  138.        <spacer name="horizontalSpacer_2">) O. N# g7 o2 {. a3 V. `
  139.         <property name="orientation">6 F6 G  g8 k) H  I* d0 \: _& ?! v
  140.          <enum>Qt::Horizontal</enum>
    ( @; v" L9 Z) P- i2 c( O2 `' i- ~
  141.         </property>
    ; i3 \4 F7 T- X& h" |
  142.         <property name="sizeHint" stdset="0">* Z" ^( }9 ?8 A1 V1 M  `  s
  143.          <size>4 t# ^7 v; f; x( v  {
  144.           <width>40</width>- e9 Q( b3 P7 j) Z/ C0 u1 p
  145.           <height>20</height>
    9 ~: i: X& W% J$ B4 c6 {* s
  146.          </size>5 V3 J+ E- a; @/ t
  147.         </property>
    3 P0 n# d4 z. k% s  @( V) x
  148.        </spacer>( W6 @, n" x) b4 U+ w' f! i
  149.       </item>
    ( L" Y! D0 {, {4 D" g% F- t
  150.       <item>/ i4 y. A, }$ L+ u' [
  151.        <widget class="QPushButton" name="comButton">1 d$ K. T* I. R
  152.         <property name="text">1 J2 n6 l4 d8 ~3 ~% g! T
  153.          <string>打开</string>+ R+ K, H4 v2 M" h- s' E
  154.         </property>
    & w6 t3 k4 |+ @! y
  155.        </widget>
    % G$ @. D, p& N
  156.       </item>" h& |. V5 r& k) C# H& s
  157.      </layout>
    7 m6 T' s$ D. w2 _3 ^, b
  158.     </widget>
    - d# W' i6 h6 Y
  159.    </item>
    ' E7 _; @2 }& y
  160.    <item>+ |) m' [5 ]% ]
  161.     <widget class="QGroupBox" name="groupBox_2">
    * r9 e  R& u- R2 M1 O' y2 \
  162.      <property name="title">' r2 L) H2 @% e* M# ~
  163.       <string>文件发送</string>
    2 d) s. n  }9 |0 N: |, Z
  164.      </property>
    , x9 e/ n, A6 \  V0 I- E& e
  165.      <layout class="QVBoxLayout" name="verticalLayout">
    ' r7 d# T2 }4 S% q4 Y
  166.       <item>
    : e+ {$ P/ L' D+ ~2 D  \- K
  167.        <layout class="QHBoxLayout" name="horizontalLayout_2">
    & J9 }; b( V/ q0 X6 @, K' V6 o
  168.         <item>9 ]3 |; x$ \, L; T4 b
  169.          <widget class="QLabel" name="label_3">
    9 f$ d+ Z" Y; g0 J+ {& ]
  170.           <property name="text">, U0 u4 H$ o# _2 X- H8 b2 u' {
  171.            <string>文件路径:</string>
    1 \# h* g7 Z4 Q4 V9 o# |* s% a, o
  172.           </property>
    / V6 c9 C9 s6 d' r2 q# I0 p
  173.          </widget>6 N, k/ Y/ z  c" t# V) f9 [
  174.         </item>
      V, u, U; r) n8 S
  175.         <item>
    ' Y: k$ j, R2 l5 Y9 f. S* ~
  176.          <widget class="QLineEdit" name="transmitPath">
    $ k3 A( u2 D6 v0 z! A
  177.           <property name="readOnly">& f& l! X; ]; e: G& r" ?8 X0 `
  178.            <bool>true</bool>
    & x. R/ c$ F4 e7 E
  179.           </property>& R. N7 `2 a) j5 Y4 o
  180.          </widget>
    . g0 C7 D$ P) n1 k: a4 ]& }
  181.         </item>8 a( l+ ?. X) e8 k" j: }' x5 z0 |
  182.         <item>5 |" L$ C1 L1 }5 S+ L
  183.          <widget class="QPushButton" name="transmitBrowse">
    ; W! l: Y2 A, B- |, Y3 l) n" U
  184.           <property name="enabled">
    1 H  i, R! S1 S1 I9 F8 p, g# M
  185.            <bool>false</bool>
    ! f' |+ O: R9 A6 F
  186.           </property>! m& s( y  W" `( H/ k) V/ D1 a2 ]
  187.           <property name="text">: t$ w( G' N: x/ Y0 o% v' r
  188.            <string>浏览...</string>
    9 v  K( T( i- _- Y8 L# u
  189.           </property>  U' ]" p  b, S* K. Y& n  ?$ i2 U
  190.          </widget>
    ( [# K* ~  \$ Y% }2 O6 L  ?8 Q, s* \
  191.         </item>; W( C7 _0 J- b# {6 t& ]' o
  192.         <item>
    . A! K5 `+ U3 i; T5 G4 t
  193.          <widget class="QPushButton" name="transmitButton">! r% W$ ^  {  @. }7 U
  194.           <property name="enabled">( C' ]" T# T  _0 [  h
  195.            <bool>false</bool>9 K7 I( |/ I) B) u; g! m$ Y
  196.           </property>* L" v( }( l, O8 L
  197.           <property name="text">
    , \7 G( g, ?  \& x
  198.            <string>发送</string># m4 l0 [: ?7 ?
  199.           </property>
    7 X0 D9 g. R! s4 o4 K; p7 |. g
  200.          </widget>
    # E, W  ?* y3 f) o9 W; [
  201.         </item>0 v5 \; N& l: e9 d# [& m
  202.        </layout>) Q/ a7 u9 R: z
  203.       </item>
    ( O6 ?' _5 q' |1 r
  204.       <item>
    / t) o! E3 S4 g& ~+ |/ Y; S4 J0 K
  205.        <layout class="QHBoxLayout" name="horizontalLayout_3">
    - C. _5 g* ^. ]0 Q
  206.         <item>* Y3 s% H2 t3 j! v( [, t
  207.          <widget class="QLabel" name="label_5">* ]+ R* v! o6 b5 _8 F, i
  208.           <property name="text">) c( M0 I& Z1 x, x, ]9 H
  209.            <string>传输进度:</string>
    , Y# _: H  k  S, C( j0 H
  210.           </property>! `6 u6 G+ ~! v' X" [4 X: c
  211.          </widget>/ A1 h1 [8 P* T) _6 R
  212.         </item>- E# L( D1 S" t/ z; i
  213.         <item>! v7 I8 a2 E0 p# B+ i
  214.          <widget class="QProgressBar" name="transmitProgress">9 p3 i. i0 G# J! Q
  215.           <property name="value">
    $ C5 i1 U* J# q/ c! {! R2 c
  216.            <number>0</number>% m+ N' |3 l  |% Q
  217.           </property>
    8 u, @  Q1 f$ \
  218.          </widget>% m" E! `( I1 w5 L3 B
  219.         </item>% A* r) g5 H6 v
  220.        </layout>
    $ G. s; z+ A/ ^. @6 Y
  221.       </item>) P: p' K  u- G$ [% N/ v
  222.      </layout>
    & u8 m  }% w0 a3 a
  223.     </widget>' o( ^2 S% M: V  C3 n' B' v: n
  224.    </item>
    5 K/ O* b9 F9 [3 p. m2 n
  225.    <item>
    9 q. Z7 v6 J! }( t8 t) g% ]
  226.     <widget class="QGroupBox" name="groupBox_3">9 J. D- M$ M- M5 n8 h, S6 W" Z- U
  227.      <property name="title">9 ]" z5 A6 T7 G& @# X- a1 A" ^+ a
  228.       <string>文件接收</string>: N6 L1 j* B- d# W( B1 {* W4 Y
  229.      </property>6 w7 p9 n0 r9 i: _0 \& M
  230.      <layout class="QVBoxLayout" name="verticalLayout_2">
    ' ?  r% ?- |1 R  Q+ m
  231.       <item>
    , @  e6 F8 M8 u1 j
  232.        <layout class="QHBoxLayout" name="horizontalLayout_4">
    8 y8 z3 B: N) i% r) o* [  S& T
  233.         <item>
    1 W9 D( R/ a( l% E
  234.          <widget class="QLabel" name="label_4">
      N4 w; ~4 o. Y* ^
  235.           <property name="text">
    , |+ W1 \" G8 m6 A( t' H
  236.            <string>文件路径:</string>1 G/ K" N  h& a0 E/ l3 B
  237.           </property>
    ! d4 Z6 O7 Z; p2 c6 w1 y6 B
  238.          </widget>
    , E3 B- _' s2 D7 s( T) c! U; c' o3 I
  239.         </item>! f0 z  v2 X* C8 W7 G
  240.         <item>
    2 ~9 o. _/ n$ q( }, H' O) @
  241.          <widget class="QLineEdit" name="receivePath">
    ; c; G/ d) P7 r! ?. _" b: V
  242.           <property name="readOnly">! f. @9 @0 [1 B) Z: I$ u" F; M
  243.            <bool>true</bool>
    3 o' s  r: v6 r9 }3 {/ H' X- ^
  244.           </property>
    6 W+ G. e# V0 o. U3 F$ ]. d" K
  245.          </widget>
    2 F, z! q4 [, j: C( f# x% o; i
  246.         </item>
      e! M# r5 W, Y: ~% ~
  247.         <item>$ }) s% {" i7 i6 Z9 E8 G
  248.          <widget class="QPushButton" name="receiveBrowse">+ h- V6 T( _9 ]. E# Z- G
  249.           <property name="enabled">  @2 S+ P6 K# P5 k- C
  250.            <bool>false</bool>
    9 j/ k& P' w9 f% _, ?4 g
  251.           </property>
    & p6 z$ g# x2 j- A1 k; D
  252.           <property name="text">
    % K- A  U2 p4 c: _8 J& `, ?
  253.            <string>浏览...</string>
    " r" l% Q$ X- r8 _% w
  254.           </property>
    ) }0 y, t. L7 W+ ?# s2 E" z# [9 E
  255.          </widget>
    ! a3 S( @5 u$ }- e: q1 a9 I$ H
  256.         </item>) T/ j, e! F# j6 b" @! V# v* J
  257.         <item>
    ; r" u' h/ Z2 d6 \" ]# ?
  258.          <widget class="QPushButton" name="receiveButton">
    1 n# _& U. g% g+ G3 A
  259.           <property name="enabled">3 P# i; w1 F4 S
  260.            <bool>false</bool>+ |7 i# N) P- N* l& B
  261.           </property>' d  p# m* y5 P9 _
  262.           <property name="text">2 H' q8 y+ P" q* H8 K
  263.            <string>接收</string>
    4 P& p/ {3 _+ X* p/ d
  264.           </property>: o6 q# {) y' c  ^4 X; c" y. I/ U
  265.          </widget>
    / n% v6 H/ t2 s
  266.         </item>3 c% _* _& T$ _, \
  267.        </layout>$ f$ G) u4 R& p
  268.       </item>
    % G$ Z1 b# D9 i6 U5 ?+ ?& k0 R
  269.       <item>
    / w  E9 w7 d4 h3 l+ {/ Y
  270.        <layout class="QHBoxLayout" name="horizontalLayout_5">6 ?7 v: {, X" s
  271.         <item>' O" y9 }6 K' V1 l; a
  272.          <widget class="QLabel" name="label_6">1 p* o% ]6 l5 ]
  273.           <property name="text">9 B6 z& Q! s' v6 @. M* b
  274.            <string>传输进度:</string>
    $ E  ^2 H: _4 I! t
  275.           </property>( n9 j' x5 T1 K) H: x
  276.          </widget>: K  n# f5 `  K) R$ o
  277.         </item>
    ( n: {6 k9 X& \/ t4 p) y! h
  278.         <item>$ d5 |+ C( S2 p& s* m& Y
  279.          <widget class="QProgressBar" name="receiveProgress">
    . ?" o, w. d5 A9 ~4 L
  280.           <property name="value">
    ( r5 B# E3 y4 g; |' U
  281.            <number>0</number>
    5 g4 {  s( t0 v, ?" i
  282.           </property>
    + s$ N: {3 g* |. n, L5 m) }
  283.          </widget>) A6 r, M" Z3 F. A
  284.         </item>2 e7 B8 K  A" y$ e
  285.        </layout>
    ! Q- @/ `  o  s7 r" ?0 f! n  G! a
  286.       </item>5 L( G3 l5 g4 ~9 k
  287.      </layout>; R0 B" H- z$ u6 U. C- S" a
  288.     </widget>
    . E/ o( J; A1 a2 ?* N
  289.    </item>% t8 i. u0 d1 d  S2 S; M  v' P
  290.   </layout>
      }# O4 m5 w+ C6 q9 U" Q; A
  291. </widget>
    . f# M7 x5 Q. |# U7 q# @
  292. <layoutdefault spacing="6" margin="11"/>
    4 P( X( S  r, g* o& |. q9 i4 @
  293. <resources/>' ~$ _1 ^. i. \8 I+ N4 i3 Y( @
  294. <connections/>
    . D; _. e! Q; ?3 I+ A% d0 y) Q9 c+ ^
  295. </ui>7 |1 @( n, m5 s
复制代码

  v7 b3 x# r1 S2 k* R7 W7 e5 S      widget.h文件5 \% d. T* K. L  ]' l! m
  1. #ifndef WIDGET_H% w) v8 M& f1 x" i7 b
  2. #define WIDGET_H
    0 x. d3 H7 Q: `: W3 G
  3.   g* K) T( H% S. d4 u. @; H% V9 j
  4. #include <QWidget>
    - h4 c2 z  T: n7 y7 |3 Y& N
  5. #include "YmodemFileTransmit.h"
    , y  R7 t, ?0 q# `: k2 ]: s0 j
  6. #include "YmodemFileReceive.h"
    * q9 S- e; [! j5 A( e: x6 u
  7. 7 i5 ?. U% n+ B+ D8 i3 X% |! g
  8. namespace Ui {
    1 P2 U, v6 ^+ q: g+ U
  9. class Widget;- `5 F$ F4 Z. n% ]5 q; p
  10. }
    9 b( `9 u2 o% {' w

  11. 0 D& Y  i8 `0 W
  12. class Widget : public QWidget: h/ a$ B5 E0 w3 A7 o
  13. {
    5 R0 u* N6 y3 {' S7 A
  14.     Q_OBJECT
    6 j0 \& p0 ?/ c  j

  15. ) G# ]- v% v& y; [* z
  16. public:
    / C* a3 x' j$ ^8 p
  17.     explicit Widget(QWidget *parent = 0);1 k. w- Q$ R* T3 F- M" \3 M+ v
  18.     ~Widget();
    ' }6 y! `2 D9 ?( V& M' r
  19. % y- _2 t2 a! X; Y
  20. private slots:
    , r. g' O' J3 L4 ]
  21.     void on_comButton_clicked();
    ' m# N2 q1 S5 o3 L# B2 S
  22.     void on_transmitBrowse_clicked();+ L8 G1 T& I5 V- D. R
  23.     void on_receiveBrowse_clicked();
    . Z2 s& g: @. H2 d9 ?! {) D0 ^
  24.     void on_transmitButton_clicked();0 l, u; I4 N0 l, q% ^' L( F$ {
  25.     void on_receiveButton_clicked();
    ! Z2 f4 J& l: D9 g
  26.     void transmitProgress(int progress);
    . w- m2 }, c9 U7 B$ b# c
  27.     void receiveProgress(int progress);
    $ b: r& Y+ Z4 \) V. ^0 i, w$ |% w
  28.     void transmitStatus(YmodemFileTransmit::Status status);
    - Y' q9 V- q+ W3 u: \
  29.     void receiveStatus(YmodemFileReceive::Status status);
    ! q: s+ I7 }1 H" B& v
  30. / B8 ?1 Z  F9 N+ A1 j) q
  31. private:
      i7 n1 O* u+ N
  32.     Ui::Widget *ui;4 s% e3 A- @( p/ t, I* i
  33.     QSerialPort *serialPort;1 u. i- h( G8 ~# D, S* b
  34.     YmodemFileTransmit *ymodemFileTransmit;
    ) ?# h% s9 y9 Q! j5 [5 s% s
  35.     YmodemFileReceive *ymodemFileReceive;
    * U" U/ ]$ y) p. d

  36. 2 |3 ^: F( R: w( e' q  B& [
  37.     bool transmitButtonStatus;
    ( o) G$ @" X9 q! O; U/ N9 a0 [* b& ^
  38.     bool receiveButtonStatus;& ^! x% u6 p3 Z9 d& j. s0 X8 \
  39. };
    ! I$ F, \2 {) Q: }2 ~0 o
  40. 4 x: e. l5 B7 o# h7 q8 F
  41. #endif // WIDGET_H
    ( K  D" ?( o  o3 `$ F
复制代码
' D" G, h* ~/ Q9 i" Y
      widget.cpp文件# Z) G0 ^/ q7 B+ e7 K+ M
  1. #include "widget.h"
    , O3 ~, q; |% O' }9 c5 i& [
  2. #include "ui_widget.h"
    5 D% r% C8 w9 u0 m& u9 m" d4 q
  3. #include <QMessageBox>, q, k% s5 x! H
  4. #include <QFileDialog>
      ]) Y/ Q+ p& v
  5. #include <QSerialPortInfo>
    * p4 ]; z  D% w

  6. 2 {& {7 Q% T- }4 K
  7. Widget::Widget(QWidget *parent) :$ |3 X3 q7 ?" i2 g* H* J
  8.     QWidget(parent),: w& r! n* E$ q# f, t/ o0 _9 O
  9.     ui(new Ui::Widget),$ z+ K( n" C( C/ V% h) t
  10.     serialPort(new QSerialPort),
    : Q3 l* y+ w. n- o7 H
  11.     ymodemFileTransmit(new YmodemFileTransmit),  m% C1 H) r2 L
  12.     ymodemFileReceive(new YmodemFileReceive)
    9 M; i: O1 f' A8 B4 l1 y$ H$ z% S
  13. {' \0 e9 n9 S3 c  k& P9 U
  14.     transmitButtonStatus = false;
    & @9 G5 [7 H/ V5 O
  15.     receiveButtonStatus  = false;1 j% [0 L  d: k$ B7 g! D

  16. 3 W3 A! E+ }+ {9 t% Z
  17.     ui->setupUi(this);
    + v2 E  ~7 x* d/ b) K
  18. ; w3 i& o8 l# W/ N3 U
  19.     QSerialPortInfo serialPortInfo;
    2 C1 R$ e4 Z0 V

  20. 7 a' \1 y  H) `) m; w! w, s
  21.     foreach(serialPortInfo, QSerialPortInfo::availablePorts()); k3 e" k3 s( W  `- }
  22.     {3 g/ a. m& o/ w" j6 o
  23.         ui->comPort->addItem(serialPortInfo.portName());2 K/ ~. \( e% H
  24.     }
    8 V) E! N  P0 ]6 J; c

  25. $ g) A$ h' E# f
  26.     serialPort->setPortName("COM1");
    " m% w: f* m% q0 P: F
  27.     serialPort->setBaudRate(115200);
    9 v1 Y2 l: j- `! P
  28.     serialPort->setDataBits(QSerialPort::Data8);# x' B. L( D% B: i5 t8 q0 _
  29.     serialPort->setStopBits(QSerialPort::OneStop);
    1 H0 l( E. M4 A. z! s. @1 G& [. I
  30.     serialPort->setParity(QSerialPort::NoParity);, }  A, @6 Y- }# W0 a: o
  31.     serialPort->setFlowControl(QSerialPort::NoFlowControl);
    % C, c# T4 e* Y% @' X

  32. 0 \7 b. @( p& N
  33.     connect(ymodemFileTransmit, SIGNAL(transmitProgress(int)), this, SLOT(transmitProgress(int)));
    2 \" P2 _" ]* G, w3 c3 w, j( i5 v/ m
  34.     connect(ymodemFileReceive, SIGNAL(receiveProgress(int)), this, SLOT(receiveProgress(int)));7 R' ~" a+ Z4 R) h8 g# u/ e
  35.     connect(ymodemFileTransmit, SIGNAL(transmitStatus(YmodemFileTransmit::Status)), this, SLOT(transmitStatus(YmodemFileTransmit::Status)));( {8 z6 V8 j* F, F
  36.     connect(ymodemFileReceive, SIGNAL(receiveStatus(YmodemFileReceive::Status)), this, SLOT(receiveStatus(YmodemFileReceive::Status)));
    + f9 l  L6 r, l3 k& N# R
  37. }
    ) l% a+ i- J4 s8 F
  38. ) x7 b) t, B; Y
  39. Widget::~Widget()* ]  b, @) {9 p" F5 ^$ D
  40. {
    4 I- ~0 [! c: b( b( X5 U  O
  41.     delete ui;: ]0 q3 \( b6 w* A$ H8 ], z" T% y
  42.     delete serialPort;
      ]% i- w. P2 Y0 \
  43.     delete ymodemFileTransmit;
    ' H( J$ t6 G' k$ k  Z7 R9 u
  44.     delete ymodemFileReceive;/ K. `* r3 n/ k" V: Z
  45. }8 Q, [- H5 j( D  _' y7 {: Y) s

  46. ( @0 f4 O9 C+ _( L+ _7 x
  47. void Widget::on_comButton_clicked()* [# H! T0 a; ]! T
  48. {
    & x6 x) l; A# e; S
  49.     static bool button_status = false;
    . X. e: l7 f- f; e

  50. 8 {6 U& b; E! H. T- W) b1 x8 @
  51.     if(button_status == false)
    2 l( ~% N4 ^9 r" S
  52.     {
    ) Z: z3 O: u; k
  53.         serialPort->setPortName(ui->comPort->currentText());) Z7 k( S2 z/ f+ ?; L! R# U
  54.         serialPort->setBaudRate(ui->comBaudRate->currentText().toInt());! I8 x8 f* z4 ~
  55. 2 X$ s& `) p# \9 f% C  ^
  56.         if(serialPort->open(QSerialPort::ReadWrite) == true)
      V' E/ m1 J8 C  A4 G- S: k
  57.         {
    5 M9 }7 ^* h0 i  y, V6 T3 {
  58.             button_status = true;& c+ m5 N+ D! x* v! N; U0 U

  59. % E6 {- S# L& C( L( b
  60.             ui->comPort->setDisabled(true);% J' L: s8 y+ C* W3 e
  61.             ui->comBaudRate->setDisabled(true);1 E- v  `& ?# n& W( q, c
  62.             ui->comButton->setText(u8"关闭串口");6 O% C( g" g" _: e* j

  63. " L+ c) p1 Z+ k2 U
  64.             ui->transmitBrowse->setEnabled(true);6 b$ t0 g* L8 H
  65.             ui->receiveBrowse->setEnabled(true);5 W% r2 h4 k& _0 o

  66.   X/ P! m# a) V/ M! D  f: _4 Z
  67.             if(ui->transmitPath->text().isEmpty() != true). g5 @+ i  H  R3 l0 M, H0 x
  68.             {2 l+ e9 P9 T- q, ^6 A% X
  69.                 ui->transmitButton->setEnabled(true);1 _& z+ p% K2 A/ q! W0 @, I
  70.             }+ a# Q% ~# `$ Q, F

  71. ' s& ~( `, |* q  n& [; y
  72.             if(ui->receivePath->text().isEmpty() != true)" W4 f3 W- U  R+ u7 |! j6 X9 J' O
  73.             {, C" I3 K  f; ]% }
  74.                 ui->receiveButton->setEnabled(true);! M/ N& x. G2 m# K1 Y: Y& \* O
  75.             }
    1 F  S7 Q: D3 L
  76.         }8 ~7 U- ?8 K/ C' g, R/ @
  77.         else
    0 Z: O; g  e; g9 g
  78.         {4 @, o' O) T% ^" P7 J1 Y
  79.             QMessageBox::warning(this, u8"串口打开失败", u8"请检查串口是否已被占用!", u8"关闭");7 x/ s$ s9 D# p. m. ]5 R/ v
  80.         }
      A% a  n; O" g* Z) |6 c$ S
  81.     }6 m0 }$ X9 n* I0 L8 ]- T
  82.     else
    " X/ o( M; b% k3 D' Y- Y
  83.     {* F1 ?- V/ Q( H
  84.         button_status = false;0 R! c1 d  D& I1 A% W
  85. / n) p; `! u% b$ e; S5 |: u
  86.         serialPort->close();& m  ], S/ b2 V6 w  U# A$ R1 X

  87. 4 X) E& p  v3 a& q! s' \4 Q7 t+ d( }
  88.         ui->comPort->setEnabled(true);
    # `7 M$ u. M  T9 ^
  89.         ui->comBaudRate->setEnabled(true);% u/ a) d% G  W+ O1 A
  90.         ui->comButton->setText(u8"打开串口");
    , o7 I$ y  r* X5 q
  91. # G1 Z* q; z7 @! Q' N
  92.         ui->transmitBrowse->setDisabled(true);
    % C2 H* N8 k/ c' R5 J5 n' b
  93.         ui->transmitButton->setDisabled(true);& b: r0 k8 J9 V9 G
  94. + K2 W( X1 B: n( p/ F9 V* M
  95.         ui->receiveBrowse->setDisabled(true);
    . O0 `$ j6 ]; S9 r' L
  96.         ui->receiveButton->setDisabled(true);% y* U1 W& _9 U) z9 y
  97.     }
    ( L; `/ P6 I! l% a& p% @: J  {. B
  98. }2 |6 H4 \8 s8 q2 U

  99. 6 S+ s  `3 g! P- @0 D
  100. void Widget::on_transmitBrowse_clicked()
    . _2 K+ q4 x& ~: n) e2 c2 m, X
  101. {9 Y% ^% C' S* `- ?: g3 S- R+ p+ i
  102.     ui->transmitPath->setText(QFileDialog::getOpenFileName(this, u8"打开文件", ".", u8"任意文件 (*.*)"));/ Q) Q) g6 e) }+ {2 ~
  103. 7 F0 [1 _8 [! F7 g; E' ^
  104.     if(ui->transmitPath->text().isEmpty() != true)
    9 q" u7 i: ]) c$ B% Y8 t3 }; Z7 [+ y
  105.     {" ^7 W9 |7 ?, U5 r* y8 q) `
  106.         ui->transmitButton->setEnabled(true);
    ( R* i! Z+ y+ Y' ^7 r. F
  107.     }7 H8 V$ c. u6 i" Q' N2 z. `' N& F
  108.     else& W1 x& O. W: M' n$ J8 X/ E/ a+ {
  109.     {) g; Z  A: g4 M) a8 u: D. T; t6 M
  110.         ui->transmitButton->setDisabled(true);1 `) [0 v5 k+ x* {3 h3 ~, u" d! l
  111.     }  @$ _$ o& |; X: h& n8 w
  112. }
    ) Q; U$ c0 L( Z
  113. 6 o1 `# X" `1 M) R3 s4 I# P3 l
  114. void Widget::on_receiveBrowse_clicked()
    8 |0 m  c% l/ D0 L8 q( w; [
  115. {
    2 q: D( M3 T% Q" p- t8 u
  116.     ui->receivePath->setText(QFileDialog::getExistingDirectory(this, u8"选择目录", ".", QFileDialog::ShowDirsOnly));# ^* J* D: B1 W' k3 x4 a1 d
  117. 8 b( e' B* o  a1 h- M3 ?2 Z
  118.     if(ui->receivePath->text().isEmpty() != true)
    6 P+ x$ ]9 w4 N: d
  119.     {8 D2 P) K" D- h- C
  120.         ui->receiveButton->setEnabled(true);
    ' c* D( {* {7 ~+ j$ ?- `
  121.     }
    2 i9 a3 M9 a# E; I3 M1 D
  122.     else
    , y+ A4 _9 e' N# a/ ?
  123.     {
    2 X( _. t6 n( v  ~
  124.         ui->receiveButton->setDisabled(true);
    0 i8 m% R; Y: u& |
  125.     }  z) ~$ c: n) ]1 u% H" [
  126. }, x" |1 i1 N5 M
  127. : g. }+ o* Q; z9 u: Z# A
  128. void Widget::on_transmitButton_clicked()
    0 G( U2 ~2 \6 v8 \
  129. {
    4 d/ m; f& B7 d4 {$ F! o
  130.     if(transmitButtonStatus == false)
    + N% z. E- l" X2 N2 r% o3 l
  131.     {
    : V3 a; L& z2 |# ~( n
  132.         serialPort->close();; u4 D; ]9 h; \* a  u: p% ~

  133. 4 U) y+ y- ]" V8 l! L
  134.         ymodemFileTransmit->setFileName(ui->transmitPath->text());
      ~. b; \9 e! O
  135.         ymodemFileTransmit->setPortName(ui->comPort->currentText());
    : S9 o) c3 s* H2 m! t) ?  J
  136.         ymodemFileTransmit->setPortBaudRate(ui->comBaudRate->currentText().toInt());
    9 p! T8 \: y6 h5 |6 a
  137. 0 H0 V9 f0 ~/ O( w8 ]- r+ E" d* g
  138.         if(ymodemFileTransmit->startTransmit() == true)
    0 c+ }- ^# o" Y2 Q) A9 ~7 K- z
  139.         {
    ; A  C% h5 b4 N' \- }$ Q
  140.             transmitButtonStatus = true;+ M0 R" F% ?  Y/ @+ K2 q

  141. ) b( j: s3 n% l- |3 B
  142.             ui->comButton->setDisabled(true);
      ?, m+ R4 c! }, }' I0 x
  143. % z# u/ g$ l; x$ @, W6 S
  144.             ui->receiveBrowse->setDisabled(true);: g/ E. n+ a* S5 u
  145.             ui->receiveButton->setDisabled(true);8 f% X5 q* P. O

  146. 1 c( l. n& f& D, G. a7 V% S
  147.             ui->transmitBrowse->setDisabled(true);' i6 B( }& Q( w" ^& a
  148.             ui->transmitButton->setText(u8"取消");
    " G+ V# P5 a' M( k' Q8 ^4 q; a3 j+ s
  149.             ui->transmitProgress->setValue(0);
    3 D! F1 k& u/ K
  150.         }  ]2 d0 p: n3 ?, }. \
  151.         else
    : m7 m+ H* T. J" G* ]$ G
  152.         {$ t1 R2 h3 @- X2 X- T
  153.             QMessageBox::warning(this, u8"失败", u8"文件发送失败!", u8"关闭");
    2 j6 L, A! {* y1 ]% n5 u
  154.         }2 ]! D4 h( h7 U7 g) I
  155.     }
    4 s( t" w3 S7 {8 f2 @' z' }
  156.     else4 Y# _0 l6 m4 Q
  157.     {
    , r; T( J" \1 d
  158.         ymodemFileTransmit->stopTransmit();
    " `- S7 D0 R) @( \. B1 A
  159.     }1 L) F6 k9 d9 ~$ G% P* p( O
  160. }
      x" {! s+ A& o1 Z% [- G
  161. , x6 S3 {( [! i+ F1 `
  162. void Widget::on_receiveButton_clicked()5 g- }/ t/ l& \
  163. {% a; ^0 w+ _2 u
  164.     if(receiveButtonStatus == false)
    # q5 ^, k1 [& q, _
  165.     {
    ! S" b( y' B: u# B, W- J0 h
  166.         serialPort->close();
    : i% e$ _6 C/ G8 b

  167. ( j2 v; X( _; R( w. \7 ~" Q
  168.         ymodemFileReceive->setFilePath(ui->receivePath->text());4 J' Y! V4 W8 c' i( J$ n" ?
  169.         ymodemFileReceive->setPortName(ui->comPort->currentText());0 s5 T* {6 @4 R
  170.         ymodemFileReceive->setPortBaudRate(ui->comBaudRate->currentText().toInt());
    $ f- _6 ?4 i  E1 U$ q

  171. . y! `  G2 T& T1 ^) l% h
  172.         if(ymodemFileReceive->startReceive() == true)+ h( W: p8 j/ L, C# |
  173.         {
    " o+ L, ?' [+ [; Z% u
  174.             receiveButtonStatus = true;" s7 t: m* _% c3 d$ ~- V
  175. # v( r8 f9 g* _
  176.             ui->comButton->setDisabled(true);5 d2 k1 {0 w! t- H' e/ _" \1 j: x0 ~

  177. , J+ k7 m6 D0 m  X
  178.             ui->transmitBrowse->setDisabled(true);
    2 f2 Y" F- I$ B  ^7 g8 U" I- n8 `. V
  179.             ui->transmitButton->setDisabled(true);
    6 p9 S( T$ q" l

  180. 5 c0 k" F' w. z' u3 w( E
  181.             ui->receiveBrowse->setDisabled(true);
    8 i9 n' {0 x2 T
  182.             ui->receiveButton->setText(u8"取消");4 q9 J0 q% T. M6 g- l  l$ F
  183.             ui->receiveProgress->setValue(0);; }! j$ e8 z2 W! A" j+ m5 @7 H
  184.         }
    - B/ G* F) f) A
  185.         else
    . A# b5 j% v8 z- @, o+ S& W( _
  186.         {4 N& x! l3 P5 v5 N9 f2 L
  187.             QMessageBox::warning(this, u8"失败", u8"文件接收失败!", u8"关闭");
    ( M5 y( K4 v9 \& t! j
  188.         }0 P' H2 @, `' h5 y$ ^8 k
  189.     }) p! }1 F. ~1 o6 v+ \
  190.     else3 q  p7 }; }/ j- j9 }* `5 y  P
  191.     {. ~/ ?# f' |, N& r
  192.         ymodemFileReceive->stopReceive();
    & \% I, l6 l7 N5 |
  193.     }
    0 F/ _) U3 \. C" h; u
  194. }
    1 b* ~& K# ?2 G( r3 y% M
  195. 0 J) h5 T' V& p/ W9 H
  196. void Widget::transmitProgress(int progress)( ~2 b# T! m% _7 c7 Y% V  h
  197. {
    4 X% J! ^# `4 t
  198.     ui->transmitProgress->setValue(progress);0 ~# w1 m/ \+ }, O: j
  199. }
    1 ~2 F5 R2 k  a3 R

  200. : l* S4 m6 q5 E4 v4 n1 I3 L+ R0 S
  201. void Widget::receiveProgress(int progress)
    & l% f6 b. B$ |! v( P5 P& Y
  202. {0 y/ m9 k- O3 t
  203.     ui->receiveProgress->setValue(progress);
    : [1 W+ D! l+ ^4 T
  204. }
    + D" I% G/ J; G' B) `0 |

  205. 1 z* L1 r% n* X
  206. void Widget::transmitStatus(Ymodem::Status status)7 @# X; h0 {% ^1 G5 T
  207. {
    & l' L4 }5 h- Y* l. B, o
  208.     switch(status)
    # f2 K$ p  K* e4 ~5 _7 Q; s
  209.     {% ~" [3 p3 \$ k  |% \
  210.         case YmodemFileTransmit::StatusEstablish:
    9 f' P3 s! f# ~9 f* ?1 ~+ b* G
  211.         {. m2 h6 Z9 C' |1 c5 b! o- l
  212.             break;
    % M) g5 g8 t0 k& [) P0 q8 C
  213.         }( F: H- n. i' \* Q) M

  214. 2 d+ p1 K2 ]5 B2 i- j( K: J5 d
  215.         case YmodemFileTransmit::StatusTransmit:
    : k0 L8 u  c2 Y! x
  216.         {
    % Z! \/ _. M2 y- U4 j3 e6 c
  217.             break;
    4 _5 w9 w& l/ ]; h6 `0 V- d
  218.         }- d, n# _6 k7 R& Y. H4 A

  219. + L$ E6 T/ W6 l# u0 _8 k
  220.         case YmodemFileTransmit::StatusFinish:
    8 L) s) I2 Z3 y8 \
  221.         {
    6 P, B) l* j0 q- v
  222.             transmitButtonStatus = false;
    . i( a$ r: m( C: C

  223. ) T8 u: I+ I, S9 d
  224.             ui->comButton->setEnabled(true);
    ; z; ^6 }: A9 R* P! {
  225. 3 V$ _: x! Z+ S# e6 _
  226.             ui->receiveBrowse->setEnabled(true);
    5 f% q& y+ A2 T( n. E! t& b1 [7 h
  227. # [( [  Y, I/ V! c
  228.             if(ui->receivePath->text().isEmpty() != true)- F, ]& m0 R4 c8 m+ X+ A) m
  229.             {
    - T9 S. Q1 G9 S/ Y' c$ K5 W% V
  230.                 ui->receiveButton->setEnabled(true);/ s1 B& ]; c. ?4 m. l
  231.             }
      F* K& J  {* h0 A- }* @

  232. 9 T: m1 k# Y! i5 v
  233.             ui->transmitBrowse->setEnabled(true);
    2 ?8 G& L7 |' |7 O7 h" `, o' n6 b8 m
  234.             ui->transmitButton->setText(u8"发送");  }8 m: M  w7 N. C. G

  235. 0 l" l; b) y: `5 H
  236.             QMessageBox::warning(this, u8"成功", u8"文件发送成功!", u8"关闭");. u& v0 R$ ~; C% k4 I. O

  237. 3 V7 m$ J0 P9 D+ T  s( m- B" Z
  238.             break;; G3 u& V( r& B& Y: |4 j, h/ R9 @) `
  239.         }- A: q6 H( j4 g6 F

  240. . D  `1 X# |. x  Y$ q; Q
  241.         case YmodemFileTransmit::StatusAbort:
      r! e& _9 F/ L
  242.         {! a3 v' Y" o) q& n. f4 i
  243.             transmitButtonStatus = false;, G7 \, d, J( h/ |6 @

  244. + B& b1 q: x1 u% S+ D
  245.             ui->comButton->setEnabled(true);( ~& X' s2 x8 g! k* P2 K, p& S/ n

  246. : o& j" j' j  D
  247.             ui->receiveBrowse->setEnabled(true);$ f9 o0 }1 m( J* U8 U- y
  248. 2 t3 ?5 e6 X# A, w* z3 S
  249.             if(ui->receivePath->text().isEmpty() != true)
    $ u7 I7 ]) [2 t$ X, W
  250.             {+ I/ N; C: ^, \7 J6 K2 b
  251.                 ui->receiveButton->setEnabled(true);
    : y# f, y) N% P% h  z2 _" g
  252.             }
    7 `$ U( ?2 x7 }0 r1 M( k
  253. 0 V6 H) S: J. ^* W1 d7 U$ n2 ^
  254.             ui->transmitBrowse->setEnabled(true);% p) a7 h) Q9 r& w' U9 }1 {& w
  255.             ui->transmitButton->setText(u8"发送");8 O5 f  m' i' o& l
  256. 6 u1 e; _( l; r
  257.             QMessageBox::warning(this, u8"失败", u8"文件发送失败!", u8"关闭");
    6 F" U: @8 J2 `

  258. ; J. E# b  d+ F) z' U" `
  259.             break;
    - Q, V7 Y8 ?& B: W8 U- z! b8 Y
  260.         }0 w; f! o" h3 C) y- N
  261.   e( v0 r8 }, k- x. a; a& @
  262.         case YmodemFileTransmit::StatusTimeout:
    ( L. ]( t' h/ h* d
  263.         {
    ! _2 S5 Q7 g) y
  264.             transmitButtonStatus = false;
    ' z, o0 v' h4 L1 V% m* J  b
  265. " D& n0 q& ~  _# ?
  266.             ui->comButton->setEnabled(true);
    + [- R8 R( u6 G+ j' H; d% R2 p7 ]/ i
  267. 0 A1 G# ^, o6 f
  268.             ui->receiveBrowse->setEnabled(true);5 c7 k6 p  g" ?; p
  269. + n, V  C- T: H  e: _( e) E
  270.             if(ui->receivePath->text().isEmpty() != true)
    + Z9 b6 d9 C6 ~  b8 [' u& @
  271.             {
    & v) P& _" j. `1 p- P7 Q& y
  272.                 ui->receiveButton->setEnabled(true);3 Y) k, u6 n  z& J4 n2 }/ s
  273.             }6 L/ i# C% \$ Z, W& |! d% d

  274. ( n+ L3 @, Y. G# a0 Q0 _4 L' i4 r
  275.             ui->transmitBrowse->setEnabled(true);
    8 z' V" y- z4 b) ^2 I. j8 A3 @
  276.             ui->transmitButton->setText(u8"发送");0 j0 W2 }! S; O/ u1 E* J- b% d% S
  277. ( q( u* t5 M1 [2 ?3 s3 W1 s
  278.             QMessageBox::warning(this, u8"失败", u8"文件发送失败!", u8"关闭");- W/ T' d. {1 m4 ^* u
  279.   O3 v9 t3 N! l! F# r  T4 Q4 t
  280.             break;
    6 a2 U2 O. `" C7 N& B: t
  281.         }" _/ Z1 m# R5 V  d( @

  282. 9 y* N7 N7 b* h9 S6 j1 R' m
  283.         default:; e5 v- V' K. ^$ A# W: `; ^) V- c' R
  284.         {
    4 W0 x& \( e) @; r) |
  285.             transmitButtonStatus = false;
    8 R9 E$ l& ~5 m5 E  U: U! _# }' a7 ]! T
  286. / g) l" g- k* V3 U
  287.             ui->comButton->setEnabled(true);6 r8 p+ q5 @, }) C3 y8 ]7 i

  288. % h5 {5 `: g2 _2 s' n2 S
  289.             ui->receiveBrowse->setEnabled(true);# a  G8 U* L+ }% E4 P# Z3 N: L; D; G

  290. 1 s6 B; x. g+ ~9 J
  291.             if(ui->receivePath->text().isEmpty() != true)
    ) j: |1 D$ G$ [; g3 B! O' E: H! y7 |$ ^
  292.             {! X; M& i7 A) `
  293.                 ui->receiveButton->setEnabled(true);& m2 ^) a1 j/ \- u
  294.             }" [: t2 V9 Y! {6 e1 S5 z

  295. 7 L8 R7 u% @! ^. p8 N
  296.             ui->transmitBrowse->setEnabled(true);* |7 F+ P, f( ?3 p4 {6 X
  297.             ui->transmitButton->setText(u8"发送");
    " A9 P* j2 |: z9 v" G6 C& U
  298. ; `/ h$ k4 c% I# r' v  t
  299.             QMessageBox::warning(this, u8"失败", u8"文件发送失败!", u8"关闭");
    : f3 k# Z" w- B2 \
  300.         }9 Q; v3 S6 I6 _% c% `+ f
  301.     }0 e! ]' ^3 p9 W  }! s5 F( p
  302. }
    " T5 _2 i( Z$ O+ j+ C( n
  303. $ a( B1 H& J. {  n4 C
  304. void Widget::receiveStatus(YmodemFileReceive::Status status)
    - V7 B- Y$ ^" O4 U( {, C' J
  305. {
    8 B/ T) ^8 f& {# R
  306.     switch(status)
      I7 w" b8 [1 D! t
  307.     {
    . E5 ^7 k; x) Q6 S+ X  R
  308.         case YmodemFileReceive::StatusEstablish:: }4 Y; O, w+ e* v" m6 L
  309.         {8 H1 K- M+ ]+ z- }4 k* D9 P
  310.             break;
    / k, A7 E7 I3 W+ j# y
  311.         }
    / s. x4 W- Q) d: ^' Z6 K8 C

  312. 3 a3 Q5 a/ _$ c6 f6 x& O7 B3 g9 M
  313.         case YmodemFileReceive::StatusTransmit:
    ) _- ^' F6 P3 f& K
  314.         {
    0 h0 g6 N9 r- X5 w
  315.             break;
    8 {* V" B- k8 w' {
  316.         }8 p, Z" c7 h7 D

  317. 1 q% s# N$ R! n9 y4 {: @* g" P
  318.         case YmodemFileReceive::StatusFinish:
    # D: q! g# ~: a+ V6 |
  319.         {
    8 {. ]* C2 C& n7 g6 G9 Z3 _" \* c
  320.             receiveButtonStatus = false;" [# H! Z7 _) F$ a- M# A' [+ Q
  321. , B: f3 I, `$ r
  322.             ui->comButton->setEnabled(true);
    # O8 ], ?% }! o" G& a3 y

  323. 3 c, b/ F3 x, G6 b6 I! |" j
  324.             ui->transmitBrowse->setEnabled(true);1 W7 d5 [8 n  ~

  325.   s0 ^5 ~" P9 Q. C  r- [
  326.             if(ui->transmitPath->text().isEmpty() != true)
    5 S+ i) ?% X2 P1 g( y$ s8 y# T' T
  327.             {$ G( r6 C! |( F3 P  W; S" Q
  328.                 ui->transmitButton->setEnabled(true);! M9 k, B$ c) X
  329.             }
    - f. t5 _9 e5 s- ^
  330. ) {. p- S3 p" C  N+ x
  331.             ui->receiveBrowse->setEnabled(true);
    3 m7 T& C5 ]+ ]3 Z' n
  332.             ui->receiveButton->setText(u8"接收");- `! Z% k8 n* _# a" m- k: Q
  333.   M: e- W- l/ ?/ |# ~
  334.             QMessageBox::warning(this, u8"成功", u8"文件接收成功!", u8"关闭");/ }0 M* ^* J/ \/ |+ d% ?6 o
  335. ' w, [* j& t# c& q. ~
  336.             break;
    4 R  I! h8 m2 d( H
  337.         }4 v7 r8 q3 G/ S

  338. + d3 Y7 R: i% U/ A
  339.         case YmodemFileReceive::StatusAbort:
    2 c5 d# Y$ M4 [) \2 P
  340.         {
    + Z2 y# H- e  Z2 k( K& [" g( F& j, R
  341.             receiveButtonStatus = false;
    : k# F  c1 N! g; e3 }- n  ~8 c

  342. $ r% i, D5 w% j
  343.             ui->comButton->setEnabled(true);
    9 Z  B/ e; h% ~7 x) m2 \
  344. ; v* }) e! ^( }2 I0 N9 d- |6 @2 [0 @
  345.             ui->transmitBrowse->setEnabled(true);
    + {& g, I" u2 q
  346. % L8 \) Y' J) `) O; i# ^
  347.             if(ui->transmitPath->text().isEmpty() != true): K8 w0 g* s# A! j
  348.             {
    ' Z+ I2 F* g1 K/ }. E/ d
  349.                 ui->transmitButton->setEnabled(true);( f: w& Z- r6 a( ~+ V; R" b# m9 R
  350.             }. H) S5 t, z, M

  351. 7 t$ F# m: m0 K1 y" r/ a4 D
  352.             ui->receiveBrowse->setEnabled(true);
    ( n+ |7 G: b8 f0 i
  353.             ui->receiveButton->setText(u8"接收");3 \3 Y: K. W. o3 u4 L5 g+ U

  354. % M, y+ H! |& L# P' v& M$ B
  355.             QMessageBox::warning(this, u8"失败", u8"文件接收失败!", u8"关闭");/ @3 \! b( a" J/ M' r2 q6 O2 ]4 u
  356. 2 b" R7 d9 w3 o+ L5 ?! G
  357.             break;
    9 x8 u1 g" V; k8 o% j
  358.         }
    & n+ i6 ^# _! K1 u# \

  359. . F' [7 ~( s, L% S
  360.         case YmodemFileReceive::StatusTimeout:, n$ N4 Y. ~) v2 H5 I' L% d, h
  361.         {3 E+ C& O4 W6 ~+ c" C; l: g$ y
  362.             receiveButtonStatus = false;
    2 t1 c- [9 B" H3 j

  363. ( [6 L8 m" ?  E+ v- n" y4 b! F
  364.             ui->comButton->setEnabled(true);
    / a/ Q% f9 K% N- @1 T
  365. , f" n- a! S5 H( u4 S1 X; [4 m
  366.             ui->transmitBrowse->setEnabled(true);
    9 H7 F. B3 g( \% d  b: n- Z
  367. 8 \  V2 s) i1 P3 i- U; F. N* p  z
  368.             if(ui->transmitPath->text().isEmpty() != true)
    3 \4 w1 y1 I6 `7 Y; r7 b
  369.             {( H4 z* _; \9 x8 {- O
  370.                 ui->transmitButton->setEnabled(true);
    4 j3 V; W2 g* N; y
  371.             }9 C* H0 f) o) T5 c' S& N
  372. 4 n5 Q' r  \. S, W$ p: s
  373.             ui->receiveBrowse->setEnabled(true);
    , l  ]8 D" e6 x0 j' F. E
  374.             ui->receiveButton->setText(u8"接收");
    3 ?2 p+ ]- \/ w) K

  375. , Q; S7 U  e" G; y" f
  376.             QMessageBox::warning(this, u8"失败", u8"文件接收失败!", u8"关闭");
    " E9 z0 U6 F* W: h6 t; |# K

  377. ! |$ A: Y& ?' z; B) o( n; l( D
  378.             break;1 h) T8 `$ ^4 P; V9 a9 ~! e1 I4 b
  379.         }
    ) T/ }3 W7 ?' T0 \, j0 `
  380. + L1 i0 l3 S  U- w/ G5 @' z' Q
  381.         default:
      m- z3 [' W0 G, H7 t
  382.         {
    7 w3 r4 c; W" ~9 A" _/ v
  383.             receiveButtonStatus = false;6 C# u  e0 f7 X. _" N

  384. 3 F. G+ m& b7 p5 f; m! e
  385.             ui->comButton->setEnabled(true);
    ! e4 Q) D( D! i) ]- c1 Z" k

  386. % l8 }( T5 e6 @2 j, z9 `
  387.             ui->transmitBrowse->setEnabled(true);! t3 z. C. A  G( c" h) r

  388. 6 N8 @/ n, \$ ^# Q3 u( R/ R) V
  389.             if(ui->transmitPath->text().isEmpty() != true)
    8 u6 \1 ~, W9 Q' E. M; c
  390.             {
    8 y% E: c' A! x7 R6 Q7 {
  391.                 ui->transmitButton->setEnabled(true);( H" i& B" V- O" y
  392.             }8 Y0 a  P( l* G

  393. + W' J" A7 V. l5 N
  394.             ui->receiveBrowse->setEnabled(true);
    , |4 E' _! O! o& v3 _3 t
  395.             ui->receiveButton->setText(u8"接收");% W  [! Q2 E: y! x
  396. 0 k) q( Q: k8 U+ P
  397.             QMessageBox::warning(this, u8"失败", u8"文件接收失败!", u8"关闭");' Q& V1 r* G% y# T- L7 W
  398.         }+ w  _3 I4 m1 V$ d5 w2 r$ ^
  399.     }
    1 J3 E) I$ w4 F8 t
  400. }' ^0 U! H& ^# R/ R% @% q
复制代码
, w% L7 @9 z; L0 y5 B

$ L% d; J. L) V; G+ @3 l1 Y. m
% B6 Q. r" \, r$ \8 F+ R6 j+ K
- v; b) ?% J+ j" G" r, y" |3 T
) p3 t7 k% Y% D+ R- p
XinLiYF 回答时间:2018-3-6 02:04:00
      main.cpp文件
. p- P2 C  Q( v9 N/ F+ U  U
  1. #include "widget.h"2 \9 H7 V" O. w( {& H6 J5 c: `
  2. #include <QApplication>
    3 _- ^! L0 B6 X, r$ S
  3. " H" h. a) b8 k! Y0 {
  4. int main(int argc, char *argv[])
    7 `& l; L" ^2 ]3 t3 s. y, d
  5. {
    1 p7 T& a! M1 Z9 j3 T0 y' p
  6.     QApplication a(argc, argv);
      O0 x/ L6 t+ i
  7.     Widget w;2 t3 k" u+ {" J3 ^
  8.     w.show();6 K1 P" r  k9 A  {8 I

  9. * ^8 y1 Y9 ^$ C' d7 m
  10.     return a.exec();/ B, ~+ L' v$ z3 Q
  11. }" e: d2 n( x( U5 o' F- D6 g- a9 _& X
复制代码

2 A9 Z( B) I+ L      SerialPortYmodem.pro文件
3 G( `- o3 b/ N0 J$ y
  1. #-------------------------------------------------
    3 c2 }8 ]* E# {9 c* ^# z
  2. #
    ) }8 I" C$ q9 V" X' |0 `! \  I
  3. # Project created by QtCreator 2018-01-20T23:00:46
    : x0 W$ y0 s9 o# x9 \* c
  4. #
      n0 ?. J- |" Y
  5. #-------------------------------------------------& Q  P; v, U1 D+ b
  6. / h; F4 Q- `; p$ `0 {7 H
  7. QT       += core gui
    3 X7 _3 d1 X$ g
  8. QT       += serialport
    # Q+ c, g/ j, [# H5 M: J

  9. 4 h5 B/ e1 x2 Q; C& y4 A% z' `
  10. greaterThan(QT_MAJOR_VERSION, 4): QT += widgets* t. r8 X7 e: P7 _
  11. 1 A  I6 T, {& Y- ~- {+ P' x& O
  12. TARGET = SerialPortYmodem
    4 F5 E2 Q: K4 Y, m  K
  13. TEMPLATE = app
    1 B3 W& B' h  ]

  14. " n) M3 n/ L' l5 }5 ~% J, `
  15. # The following define makes your compiler emit warnings if you use
    * S2 q& p3 k2 b. N
  16. # any feature of Qt which as been marked as deprecated (the exact warnings
    + ~* I5 ^9 I9 `0 Q2 k  `0 q/ f
  17. # depend on your compiler). Please consult the documentation of the
    ) O' D% A; K! J. n" ^$ T# G
  18. # deprecated API in order to know how to port your code away from it.
    * {2 [* u* H3 T/ Q
  19. DEFINES += QT_DEPRECATED_WARNINGS6 t3 ^1 R* L' \5 K4 ]# ~

  20. 9 l; p  C) \6 c' A
  21. # You can also make your code fail to compile if you use deprecated APIs.
    5 `0 H% m0 v& w  a2 G
  22. # In order to do so, uncomment the following line.: R% m* `/ I7 o& F: |1 Y
  23. # You can also select to disable deprecated APIs only up to a certain version of Qt.8 F# w; H2 d: K( r7 N+ P
  24. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0* ^% S( n6 E( \1 U
  25. ' t* F" i- ~2 B6 b" Y5 g$ G9 n
  26. " {! b* b- R+ d* z, l" `" r
  27. SOURCES += main.cpp\
    0 X: d( C* j; s( O, D6 y) K
  28.         widget.cpp \
    0 \7 b. C0 ^8 R. c) @
  29.     YmodemFileReceive.cpp \; {9 ]# h$ u) B% I- a: m0 a+ g
  30.     Ymodem.cpp \
    + p- z! u( G% i4 S' w! ^9 h" p
  31.     YmodemFileTransmit.cpp, D& D; Y" l: s+ E# c" y

  32. * R: i1 v+ a/ `2 |  O/ v! K
  33. HEADERS  += widget.h \
    % K9 i5 Y7 q% m
  34.     Ymodem.h \' Y* y' u3 T9 Z7 N0 H
  35.     YmodemFileReceive.h \+ j$ E) [3 I" P: `& p2 \$ k  K
  36.     YmodemFileTransmit.h" v& A* `( P# R# a$ g
  37. 8 a: k: c! j8 A. P! o2 |" g. N/ X) O
  38. FORMS    += widget.ui9 j- M1 K) V% ~* Y

  39. ' V2 K. H/ w3 X% s
  40. RC_ICONS = SerialPortYmodem.ico. a$ R7 r. S$ w" U, b. S
复制代码
/ d/ d" v7 u0 {" l1 m' F# c0 ]8 ]
      SerialPortYmodem.ico文件
+ h6 B* I4 `7 V
3 e. X) E( v5 P% ^8 Y' S9 K
3,运行效果- K0 T& D. p) P, @! t
) c8 C2 p  [% L& Y8 o; F
8 z! K, ?) r$ k1 I( V/ n. Z% H4 B
5 H7 J! Z- `, _
hello_bug 回答时间:2018-3-6 11:12:43
好凶猛的代码。。
XinLiYF 回答时间:2018-3-6 11:24:49
hello_bug 发表于 2018-3-6 11:12' {. \) ^) d& C( U
好凶猛的代码。。
6 H$ M, m( {- t  d# s$ {2 A$ k
XinLiYF 回答时间:2018-3-6 13:16:18
可以用来做用户程序升级的上位机软件。
MrJiu 回答时间:2018-3-6 13:49:12
最好是变成文件比较好。。。关键部分讲解一下,贴上来,就更好了!!!!
XinLiYF 回答时间:2018-3-6 16:14:22
MrJiu 发表于 2018-3-6 13:49" `+ a. V6 f) ~( s1 n1 E
最好是变成文件比较好。。。关键部分讲解一下,贴上来,就更好了!!!! ...
3 j9 @2 {, q+ y3 ~2 i, O, b
GitHub仓库有工程,还有资料。
zero99 回答时间:2018-3-9 14:41:08
感谢分享,已汇总到3月技术原创:& Q. K  W# j+ o, K+ h5 c7 g
https://www.stmcu.org.cn/module/forum/thread-615031-1-1.html

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版