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

YMODEM协议串口文件传输

[复制链接]
XinLiYF 发布时间:2018-3-6 22:28
YMODEM协议串口文件传输
GitHub仓库:http://github.com/XinLiGitHub/SerialPortYmodem% u" ]/ Q  F4 f( l) n9 D+ E
PS:博文不再更新,后续更新会在GitHub仓库进行。# A, h2 g8 v4 ?0 j& Q
& J. n1 e* j  ~' b

* Q3 h8 Y, o- Y- S9 B4 F3 w    串口通过YMODEM协议进行文件传输。程序中涉及到YMODEM协议知识,详细介绍见维基百科[YMODEM](http://en.wikipedia.org/wiki/YMODEM)。7 |1 l% M2 h7 W) T
3 q7 j2 z" L& m
1,开发环境
4 u# t3 R, P9 Q# }8 {) _      1,框架:Qt 5.7.1
5 |" P! Y1 S  W3 C- ?3 h1 J  V
' Y% D9 o% Y/ l% }: J4 [" I
      2,编译器:MSVC2015_64bit
- P! y& O( S# c. F1 R- h- o

7 g) q6 P7 i5 Y/ P$ v$ ]0 K! \# X& |3 I      3,IDE:Qt Creator 4.2.0 社区版+ O7 g1 B, X6 t7 x8 y* e% a7 z
      4,操作系统:Windows 10 专业版
  K5 W7 L% ^' `( O# _, _6 G+ o1 u+ J4 O9 T+ _
2,程序源码- ^) x2 H& r, J0 ~
      Ymodem.h文件5 i& V4 [$ l3 W# f, s: _" ?! D, z' K: O
  1. /**
    # @7 R6 V$ X- Y* o6 [* m
  2.   ******************************************************************************
    $ r4 @7 ?$ w8 Z
  3.   * @file    Ymodem.h
    * f) @" V4 F" h- |: s
  4.   * @author  XinLi, E8 C) r! U- y' M4 F: r4 _- S
  5.   * @version v1.0' z8 q4 _5 Z2 M' z6 `! b# K2 k
  6.   * @date    21-January-2018
    ' ^( k- a9 z  ]% a9 T* T3 N+ D
  7.   * @brief   Header file for Ymodem.cpp module.* k" S8 W. E, C- d
  8.   ******************************************************************************
    $ {" ?8 d) o$ l8 E
  9.   * @attention
    ; T  E! _( ?/ ~4 n2 j' c
  10.   *& s0 B$ ^- n1 K7 B0 I
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>
    , ~+ j$ N5 G5 R/ Q7 `
  12.   *
    + Z; c+ _2 }! {% K  R9 P
  13.   * This program is free software: you can redistribute it and/or modify8 j/ S1 H/ x# N3 J
  14.   * it under the terms of the GNU General Public License as published by
    2 b+ C" U( k  p
  15.   * the Free Software Foundation, either version 3 of the License, or
    3 ?8 r' E# J# h6 x  J
  16.   * (at your option) any later version.7 @- d, t% B" f* o& G8 i. R5 h
  17.   *
    $ F: ], @* ^3 d
  18.   * This program is distributed in the hope that it will be useful,
    % K) D; R* z2 C/ x* Z) \. F
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    4 U  D, Y' I8 K, X
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    - N9 c3 W6 G6 h; y2 N) O$ m
  21.   * GNU General Public License for more details.2 Y1 L4 g& U4 o2 n
  22.   *" V* [2 @' o: l* C0 S
  23.   * You should have received a copy of the GNU General Public License  Z2 E4 ]: k" K, R
  24.   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    $ U! Q1 V- L4 o9 `4 ^) s
  25.   *
    9 Z7 ]: h; T' i) @+ v* ?, Y
  26.   ******************************************************************************
    ; M/ b7 v6 ~) g( X& K6 c9 H6 \
  27.   */6 f4 F1 @" M- J
  28. 8 R/ o0 C. Y: G; g
  29. #ifndef __YMODEM_H3 F# d  f+ i. R& C( ?
  30. #define __YMODEM_H
    ! o0 a$ R* o4 g$ U

  31. # D+ @) ?" J& B* }5 A) H6 a8 ^
  32. /* Header includes -----------------------------------------------------------*/
    , |9 j$ j/ Q0 |, t. Z. {5 }. r4 z
  33. #include <stdint.h>
    5 \. d# R  b0 ]* N3 M$ D

  34. 9 r/ w1 c8 x* V) w9 Z
  35. /* Macro definitions ---------------------------------------------------------*/! n9 X- R: n4 R
  36. #define YMODEM_PACKET_HEADER    (3)# l, n3 m6 j" ]  P6 k/ b
  37. #define YMODEM_PACKET_TRAILER   (2), o0 X# Z9 `1 D" `8 l
  38. #define YMODEM_PACKET_OVERHEAD  (YMODEM_PACKET_HEADER + YMODEM_PACKET_TRAILER)2 z, N  H6 @0 q# n8 K
  39. #define YMODEM_PACKET_SIZE      (128)
    5 V3 ^% M1 U6 D  e$ L
  40. #define YMODEM_PACKET_1K_SIZE   (1024)1 z0 I. s- G5 L- C" J" E8 k
  41. # B4 u1 z8 k2 t: P5 k! ^0 y) i
  42. #define YMODEM_CODE_CAN_NUMBER  (5)
    & G  r5 k) f6 T' r8 r
  43. ; c& J1 D3 `6 T- r# D
  44. /* Type definitions ----------------------------------------------------------*/
    3 E' X3 U% a( O' _8 d0 v. W
  45. class Ymodem
    / F$ _- e0 V9 ?/ G( m# u% r7 L3 E# u
  46. {$ ?9 ~3 P, F4 _7 I/ U0 G% u" _
  47. public:
    ; |. z  P" ]" h
  48.   enum Code) X8 j8 v8 o/ x9 E1 \0 V! E, r; h4 P0 z
  49.   {& A, v& Y& @6 `+ a5 X$ F+ x, |" o
  50.     CodeNone = 0x00,
    " _! c4 I' D& I+ Y7 Y
  51.     CodeSoh  = 0x01,
    . u7 Y& Q7 O8 b9 V; a: }
  52.     CodeStx  = 0x02,6 @9 P, i& {0 T  M# @2 s( n
  53.     CodeEot  = 0x04,
    " B" I" R" Y6 t
  54.     CodeAck  = 0x06,
    # Y' C6 t5 N" K
  55.     CodeNak  = 0x15,
    9 w. G' w4 X. O& X6 \8 |. i
  56.     CodeCan  = 0x18,
    5 ]- E* k. D. w5 e8 [$ x
  57.     CodeC    = 0x43,
    ; m- l2 Y1 A; t( [) p
  58.     CodeA1   = 0x41," B8 Y& [! N* p
  59.     CodeA2   = 0x61
    # E$ [9 O9 j) j& n* N) ?
  60.   };
    + h% n4 y( }. |8 y1 B" l
  61. / R7 G$ y5 ^; o2 i- l) a8 Z" Q9 y
  62.   enum Stage  O( x* `, Q+ F( |5 v* C4 j
  63.   {
    2 ]; B! j: ~) O& x. J4 @0 z; j: w3 \
  64.     StageNone,) @5 r0 X: y6 f+ A
  65.     StageEstablishing,# O( P+ S$ S' f- y8 ^6 T" D
  66.     StageEstablished,: e3 P- H! G6 H7 [
  67.     StageTransmitting,7 v& z* n$ m; o3 o- c
  68.     StageFinishing,7 V* w; U1 f+ p- @% N. M
  69.     StageFinished
    1 l' C8 A) q5 Q; D0 {1 o
  70.   };4 ^. z& I! D) }: s

  71. ' s3 h3 y, z' O# n
  72.   enum Status# n4 X; A' g, }% H
  73.   {' ?! o  i% j  _% Z" x2 _2 G
  74.     StatusEstablish,4 |( U& _0 o0 U8 [/ m8 a5 a
  75.     StatusTransmit,
    9 N1 V4 S% X$ N0 G5 s$ h% ?
  76.     StatusFinish,
    + v. @! J3 E* O
  77.     StatusAbort,
    / H0 Q% T- Y7 l9 r
  78.     StatusTimeout,: g% x2 M- V( x0 i2 \4 R. P
  79.     StatusError. t5 K! w! q) r1 R
  80.   };- `7 j6 q" p! y) Q3 s

  81. ) P! O# |7 s! M& m: O; O# Q
  82.   Ymodem(uint32_t timeDivide = 499, uint32_t timeMax = 5, uint32_t errorMax = 999);5 O3 b, ]7 l) R0 \2 F* N4 A
  83. ) v; Z+ l' d# i( @1 L' \. @# \- \
  84.   void setTimeDivide(uint32_t timeDivide);
    . D/ b4 I- t# L8 x- Q+ o) ^
  85.   uint32_t getTimeDivide();: E2 A$ @8 G* @9 X4 C: c: B+ X7 P3 V4 m

  86. 4 e& `( |9 X( n9 `0 t  N
  87.   void setTimeMax(uint32_t timeMax);
    3 Y. B6 D( b  a+ Z2 C, \: V
  88.   uint32_t getTimeMax();
    2 n5 b" I- W7 u

  89. 8 D: i- |* B/ \' J7 q, J+ N7 \
  90.   void setErrorMax(uint32_t errorMax);6 Q9 N* X. J$ E
  91.   uint32_t getErrorMax();! W/ ?6 i# r6 c- U

  92. 2 b3 I) \  ]" E, O2 ?7 X5 ?
  93.   void receive();" C' u/ X: R( {" V5 f
  94.   void transmit();4 A3 M0 q/ E1 [7 B( s7 B- E
  95.   void abort();
    3 F  q; n$ Y  o* w" F0 a% h
  96. / Y, O7 {2 v* M2 Q7 w9 g: a; z
  97. private:
    9 q% ^  W% W) Y7 X" Q
  98.   Code receivePacket();8 N6 C$ o" }, v7 O

  99. 4 {- H) t9 |; X( H0 L
  100.   void receiveStageNone();
      h# S7 N+ F& x# T
  101.   void receiveStageEstablishing();
    2 M/ O% b; d  j4 Q0 a$ _' }
  102.   void receiveStageEstablished();
    + Y1 C& u& S' X! _
  103.   void receiveStageTransmitting();
    3 `- m6 j$ G% w1 P
  104.   void receiveStageFinishing();- F  k" B" {4 ~& Q+ T
  105.   void receiveStageFinished();5 {7 K$ e' N5 A

  106. . ~! ^# Y0 {: [6 d2 F* i% N
  107.   void transmitStageNone();7 N1 u/ S( }6 h- s7 x0 T! O! O$ t( ?: G
  108.   void transmitStageEstablishing();; u* O  m: W" W" H  k1 k
  109.   void transmitStageEstablished();$ m+ h' f8 e) |
  110.   void transmitStageTransmitting();. L: a# H% m* x& M! i
  111.   void transmitStageFinishing();
    6 t+ ^, c  q: q0 V5 U$ t
  112.   void transmitStageFinished();. {: w% A2 `3 ]4 j+ p7 j
  113. $ S  B& F8 S* a# W3 x+ B$ l
  114.   uint16_t crc16(uint8_t *buff, uint32_t len);& U* N' c$ s# p
  115. ' W# G  u9 b7 f4 z; T+ Y
  116.   virtual Code callback(Status status, uint8_t *buff, uint32_t *len) = 0;, a" O4 c9 G# c$ b- z: f$ W

  117. ; h$ C; c8 _! ?! M7 D
  118.   virtual uint32_t read(uint8_t *buff, uint32_t len)  = 0;9 o" t8 O: S2 S5 P2 d; S
  119.   virtual uint32_t write(uint8_t *buff, uint32_t len) = 0;
    ! A4 X" Y( Z! Y. G$ ^
  120. & b3 q/ o- r6 t, J2 B. |
  121.   uint32_t timeDivide;
    . p# |% i8 \$ d( F. P
  122.   uint32_t timeMax;2 h, i  }0 ?! [8 Q/ a; B
  123.   uint32_t errorMax;0 k$ {! G% g3 V

  124. 0 O8 Q3 W9 y9 l2 Y, n) z' s
  125.   uint32_t timeCount;
    . s( p8 {2 t. u2 P( l
  126.   uint32_t errorCount;
    3 U2 @( O# |$ d
  127.   uint8_t  dataCount;* V! v9 v3 E/ o
  128. 5 _5 z# D+ |/ F, \& M! Z4 I4 m
  129.   Code  code;+ k' o" V) l4 n: }6 K4 I1 }
  130.   Stage stage;! q5 n2 `& U- U; z5 ]( h
  131. * ~8 A5 f: D- e% {2 O$ N/ i& L0 P
  132.   uint8_t  rxBuffer[YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD];! A$ J# Q3 u: z
  133.   uint8_t  txBuffer[YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD];
    1 q: B4 H; `. {
  134.   uint32_t rxLength;
    6 t4 W- W6 G3 i+ a, i
  135.   uint32_t txLength;
    * Y; @$ H! c* _  i" b
  136. };
      g# b7 S# G% W3 v- }! H
  137. . r# w8 D( K& Y
  138. /* Variable declarations -----------------------------------------------------*/& m+ |, S) x; q3 H
  139. /* Variable definitions ------------------------------------------------------*/
    & y5 M% X2 y5 y9 z3 |) `
  140. /* Function declarations -----------------------------------------------------*/
    ) `" q8 w6 j' S/ W5 I. G- Q
  141. /* Function definitions ------------------------------------------------------*/
    0 ^2 E5 I  `+ }9 @9 ~7 k
  142. / w8 o! R) c4 p0 P  H2 J
  143. #endif /* __YMODEM_H */% M' O* a. c+ {3 P$ K5 h/ l
复制代码
& ~8 s, a6 {' a% U% Z$ p3 q7 o
      Ymodem.cpp文件) D+ R- {/ r! H
  1. /**
    5 F6 T. z% A; ?; I) |
  2.   ******************************************************************************1 w0 A9 g% ]8 B8 t; E7 s
  3.   * @file    Ymodem.cpp
      @; P4 q/ \$ E- a6 d& Y
  4.   * @author  XinLi- R4 Y! H* x7 ]1 L
  5.   * @version v1.0
    3 `7 o' p, w" X5 K8 n4 J
  6.   * @date    21-January-2018
    ! ?  d1 o3 I" ~' j9 P
  7.   * @brief   Ymodem protocol module source file.
    & Q& _; R6 c) ]9 y7 a% ^
  8.   ******************************************************************************" d) |7 H; H: \% G8 C+ u' a4 F
  9.   * @attention; [6 W  n5 z9 e  j% I1 K+ E
  10.   ** b7 o+ [9 M) x, W7 |+ \& b* s* q
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>
    % X: A1 z8 w/ l( m* _, V
  12.   *
    3 p, Z* H6 M' Z
  13.   * This program is free software: you can redistribute it and/or modify! ^' t9 h4 V9 t3 x5 b+ V) S$ ^
  14.   * it under the terms of the GNU General Public License as published by+ V2 _' \% ~9 x" k6 u+ F% i7 i: p
  15.   * the Free Software Foundation, either version 3 of the License, or
    ) p1 D( M1 e* p
  16.   * (at your option) any later version.* y4 I+ f8 [% H5 L
  17.   *" R) K& k' y4 G7 N8 |3 N  n4 ]! \
  18.   * This program is distributed in the hope that it will be useful,
    3 f! T3 Q% k8 U$ A. H' C
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    8 w! {: P  E& G4 t. m0 M
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1 a  D- N: u4 ?, }
  21.   * GNU General Public License for more details./ S$ I5 `) w7 w
  22.   *6 U( {1 i, S0 ^. S& s- W
  23.   * You should have received a copy of the GNU General Public License; R. e) Y+ K) X: i4 P2 e: y
  24.   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    5 M/ s8 G3 ~3 V: g/ U: U, \" E
  25.   *
      s$ c$ e. s5 Q: V  B7 L9 c
  26.   ******************************************************************************
    2 U! c- ~7 J% d5 [- j* o# m
  27.   */
    $ d8 {' |, R/ L. b: V+ u+ x: w+ d

  28. % h3 s" S. q' o) r
  29. /* Header includes -----------------------------------------------------------*/! U# ?! v6 ?7 v* C$ W, F
  30. #include "Ymodem.h"2 }& D- d8 L$ P& j4 G7 y' e
  31. #include <string.h>% F  O+ k' y% k. |: r
  32. 6 C. C) t" E$ F6 O$ _) B  [
  33. /* Macro definitions ---------------------------------------------------------*/
    3 G/ f! @) o* B' n) ?/ |# z
  34. /* Type definitions ----------------------------------------------------------*/* v; S0 _% I9 m- w7 n+ s9 a9 u
  35. /* Variable declarations -----------------------------------------------------*/
    9 _( O. O( f# |+ t! `1 n$ C
  36. /* Variable definitions ------------------------------------------------------*/
    7 I3 d8 H) E/ C
  37. /* Function declarations -----------------------------------------------------*/
    ) L8 v0 \: l4 O
  38. /* Function definitions ------------------------------------------------------*/
    1 l' d* j  @0 j/ c

  39. " X, m" N7 e6 M
  40. /**
    . x7 D  R/ k& D% ^3 L4 L/ H
  41.   * @brief  Ymodem constructor." X0 j* [- P1 i' h: C
  42.   * @param  [in] timeDivide: The fractional factor of the time the ymodem is called.
    0 D5 D) p0 s0 h  R+ Z
  43.   * @param  [in] timeMax:    The maximum time when calling the ymodem.+ a! a# e  x2 L8 ~' c) e! F
  44.   * @param  [in] errorMax:   The maximum error count when calling the ymodem.4 L2 q# q" q1 K) u3 r6 p
  45.   * @note   The longest waiting time = call time / (@timeDivide + 1) * (@timeMax + 1).5 [) {7 _. G% ?* b) B8 x! |
  46.   * @return None.
    ; V8 u7 x$ r3 N5 i& O
  47.   */
    0 ]4 ^9 o. X8 C' l7 s( }
  48. Ymodem::Ymodem(uint32_t timeDivide, uint32_t timeMax, uint32_t errorMax)( h$ F( D# P6 w- x5 v1 U( P  A
  49. {- y' Q3 I  ?. D7 r: f5 z0 n$ z- V+ B
  50.   this->timeDivide = timeDivide;+ D0 B1 o5 Y5 j1 o; C
  51.   this->timeMax    = timeMax;; @+ A' g$ B1 t3 r
  52.   this->errorMax   = errorMax;
    % S% O( {4 ~0 k6 U! O

  53. 8 U, z& K+ X/ A
  54.   this->timeCount  = 0;
    ) X& g2 g* ?0 q6 q9 X/ V7 q! J4 ^
  55.   this->errorCount = 0;; r! K# _" V" ^( k: R* p! e
  56.   this->dataCount  = 0;
    + F+ N) U  z  z$ h4 F
  57. $ n2 ^  X7 T( `! H" V
  58.   this->code       = CodeNone;
    ' W  p, J! ?, e0 i* G1 l+ M0 C
  59.   this->stage      = StageNone;
    % ]: k' g) t3 x; F
  60. }& C2 X0 k& K# g3 N( }$ Z9 u+ R  R
  61. ' ?7 x( Y& V2 S3 Z4 ^$ }
  62. /**+ v  w+ B9 y0 b; G* V- h- L4 }; [
  63.   * @brief  Set the fractional factor of the time the ymodem is called.% a: o$ S, y9 Y7 Q. `
  64.   * @param  [in] timeDivide: The fractional factor of the time the ymodem is called.
    4 t6 R) x0 |- ^
  65.   * @return None.
    6 L# x4 i& f6 G* e% e
  66.   */
    1 U! M# f0 B# N
  67. void Ymodem::setTimeDivide(uint32_t timeDivide)
    $ ?# b3 g5 G" G- B% ~
  68. {6 D  t" F. b4 c# j3 q
  69.   this->timeDivide = timeDivide;3 V/ e/ v9 x& N% G! s! g
  70. }
    7 P5 g) b% `2 w) ~

  71. * k5 V3 V0 {/ b" N! [
  72. /**, M" R( X0 n' t. b0 a
  73.   * @brief  Get the fractional factor of the time the ymodem is called." b3 f; Y" E# Y: S
  74.   * @param  None.
    9 K6 x$ L# |8 S3 R) s  L
  75.   * @return The fractional factor of the time the ymodem is called.4 w+ Q0 l  S7 S# L0 L7 ]
  76.   */' Z, ~* J4 r% y
  77. uint32_t Ymodem::getTimeDivide()0 V8 @: [3 ^! B( F( ?
  78. {
    1 l( h4 ~  u" M! H1 w/ }
  79.   return timeDivide;5 R5 |, ?9 g/ T4 I/ ?" b# M# S# o
  80. }' Q- ]; H! {+ {2 ?& u# d( F. c0 u) ^
  81. 6 o  M! l( m& e: o/ S
  82. /**
      `) H0 [$ m1 E3 B. u- q
  83.   * @brief  Set the maximum time when calling the ymodem." h& V3 g3 ~% P* K" ^  g
  84.   * @param  [in] timeMax: The maximum time when calling the ymodem.% r# y( y" V% p7 ]) H/ x- \& P$ u; U. X
  85.   * @return None.; O# \. x* S" Q4 b! h$ n+ e
  86.   */% u9 o& `: y" S7 v
  87. void Ymodem::setTimeMax(uint32_t timeMax)3 R1 \; a8 g: ?6 }
  88. {
    ! [- O( F; ~  O% }
  89.   this->timeMax = timeMax;! k, G# ?0 }/ o0 p& L( C% c
  90. }" t  [1 i8 @3 A- O$ z7 S2 R
  91. 5 r2 |6 H% M4 k. o& v
  92. /**
    * P4 X: _8 U0 ^' O
  93.   * @brief  Get the maximum time when calling the ymodem.4 z4 ?1 z( E9 j% E* x2 b0 Y
  94.   * @param  None.
      D$ L4 q' M- f) n. O, g) H
  95.   * @return The maximum time when calling the ymodem.
    $ p7 v' o  h3 {
  96.   */" W9 M, v  u$ K" l, E4 K% x, r
  97. uint32_t Ymodem::getTimeMax()
    % m1 Q) X+ E/ Y. o+ M2 J
  98. {
    1 l( I: [# o  A, M
  99.   return timeMax;
    * R; v2 m9 Y$ G" F# O6 K
  100. }1 T( p% E/ c7 G
  101. 3 U! {) z- `! T+ Q
  102. /**4 o. c" X6 G0 s8 C9 g
  103.   * @brief  Set the maximum error count when calling the ymodem.
    7 W- T& @: g: x% D+ m/ J! N
  104.   * @param  [in] errorMax: The maximum error count when calling the ymodem.: k0 v( K6 S  U, D# Y
  105.   * @return None.
    # i; f9 X! p" r* T1 J! |+ [  K6 R
  106.   */
    " ^0 n' }. `: ~2 Z
  107. void Ymodem::setErrorMax(uint32_t errorMax)
    $ Z: N$ F3 ]1 h
  108. {. c$ W" `& {7 _& w2 \1 c
  109.   this->errorMax = errorMax;6 U$ f+ e/ N: g
  110. }
    6 j  T, ^7 x3 F" h3 r& ~2 |1 Y3 m
  111. , E5 h  F6 j: s) P
  112. /**9 C# A/ E1 b" L4 R3 a/ M# ~1 M% ^
  113.   * @brief  Get the maximum error count when calling the ymodem.
    % w$ r. K% k) x  C+ q1 a. w, {# \
  114.   * @param  None.$ r0 q0 B* l1 `# V0 y+ L, K
  115.   * @return The maximum error count when calling the ymodem.
    3 q( c- X0 q# e0 U: J
  116.   */! ~& x4 G7 s* K9 q  y5 T
  117. uint32_t Ymodem::getErrorMax()
    - J1 R# E) I' T; l
  118. {3 y: T" D/ V/ A8 K+ B; B" Q
  119.   return errorMax;5 g" c: U7 {+ ~* Q- R8 ^1 K1 k
  120. }! S8 C2 x# D( ]! ]% q( E8 M

  121. 9 n3 [- U! b: ^! ^/ C4 u
  122. /**
    . R( E! c$ W6 Q# S
  123.   * @brief  Ymodem receive.( O0 X6 }3 Z9 O( Y5 \  a1 o
  124.   * @param  None.
    . Y; E; S4 L% u" t
  125.   * @return None.
    0 Q( p6 k6 T( ~) P/ Y/ S  D
  126.   */
    ) C7 r$ v6 H3 a" j. T+ M1 Y4 }: }
  127. void Ymodem::receive()" }7 c$ u, H' @( A- w1 z
  128. {1 r$ Y9 s5 Q6 H7 t2 C
  129.   switch(stage)
    * C; O2 r0 s; c/ n' z, |
  130.   {/ E' x9 _1 M( P$ m! I
  131.     case StageNone:/ c/ |+ f- p* J9 @& ]
  132.     {+ k& [' L$ Y; V' y# w
  133.       receiveStageNone();
    ; I/ a6 R+ g! s1 M% Z
  134. $ x1 U2 \3 V0 ^% F6 L# d0 `9 \
  135.       break;* E' p( G# O8 L9 H/ x7 l
  136.     }( M( D' k5 d% T4 L7 ?0 u

  137. 7 [" g" q" ^: Z
  138.     case StageEstablishing:4 z( `7 d. }: S0 x6 ]0 A/ u
  139.     {8 G4 ~" K5 O5 M7 v
  140.       receiveStageEstablishing();1 Z" R; B# E, f' \# y. J; R
  141. # J/ B  ]7 j2 j; V
  142.       break;: f0 \: i; j: o: I; q* Y; I5 z- J7 c
  143.     }
    1 H9 M# H, L# Y1 _& a

  144. ! P2 M1 k& x/ i0 r7 P
  145.     case StageEstablished:
    7 n% N) j2 t2 o. Z5 T$ O2 F
  146.     {4 X" K: c9 S' F9 Z, |- ?. J5 k# T! J
  147.       receiveStageEstablished();8 {8 C" s7 R7 k: b# n
  148. % }# J$ W! y0 G+ Z* s5 `9 _
  149.       break;/ g' u6 ]& H, d+ f
  150.     }; C! I0 e& C8 ?: d+ B9 F) P

  151. + l$ h! T4 {  w8 W7 C8 o6 z0 F
  152.     case StageTransmitting:8 L6 z4 [* c9 g" V
  153.     {. o5 ]  ~! j) ^2 E
  154.       receiveStageTransmitting();* z( y1 {& p$ T4 P, y& N- N
  155. + ~: Q0 w' K3 l8 u, U7 M1 w( g
  156.       break;
    - x. a9 E) n# H6 Z
  157.     }
    : e: d% j/ y5 R$ t

  158. 5 ?# T; I& `3 ?; X) ?4 {/ E
  159.     case StageFinishing:# G2 b- f4 I5 M9 p0 U0 V/ H6 B
  160.     {
    2 w# T# z% E+ R/ v
  161.       receiveStageFinishing();4 \4 B$ }: L# T5 B. _# I

  162. , Z1 H+ ^' S* N( R* w6 F& ~% K9 b" ]
  163.       break;
    0 z. ?, O& v1 o5 i+ A" f- Y
  164.     }
    , M) h/ y) e' r
  165. ( K, ^, ?. {9 p3 b% ]
  166.     default:
    . k) ?/ V; p6 q6 f( B
  167.     {
    " i+ m# o2 p6 I+ y8 L
  168.       receiveStageFinished();
    8 W! ?3 ?! B, P
  169.     }
    ' \$ N' h1 u- m7 ]* R: ~( y% i
  170.   }5 e1 H, R5 `+ l) M$ h' L1 |) t8 ?
  171. }
    # A; ~# ^( y, G! ^) w8 ]' i
  172. 5 B6 z9 S+ r+ d2 o6 `
  173. /**
    ; _+ j! m( i" c7 M# C
  174.   * @brief  Ymodem transmit.
    0 L/ i: V/ [; Z$ ]4 L3 k
  175.   * @param  None.* L: }8 b  @$ M9 b  |2 k! ^6 F8 s
  176.   * @return None.
    * u/ q+ l0 ], W6 H8 m5 c' ?& V7 g
  177.   */
    / e& _% Q3 s) G$ M
  178. void Ymodem::transmit()( N5 w$ J3 H' e* K  R
  179. {9 Y: u# P  G4 W: ~8 r3 K" R
  180.   switch(stage)
    * t0 {$ M" F! S: s
  181.   {' ]  H' p+ H# m
  182.     case StageNone:7 @( o% t; e- N& Z
  183.     {
    / J6 s; N% {7 M
  184.       transmitStageNone();
    ( A- g3 {$ Z  X" @6 z
  185. . y  W, t& x1 [+ A( l+ o1 w
  186.       break;
    * V4 z# O6 j. L6 A
  187.     }
    9 ]2 `) i/ u- j2 S: o# s
  188. 3 Y+ H" Q& ^5 x
  189.     case StageEstablishing:
    2 m, [* J& a' G9 q1 h% N8 ^
  190.     {
    # k! h" t' F2 T% C3 g+ I
  191.       transmitStageEstablishing();
    5 F, L  F8 O2 e. o# v# h

  192. / f$ P. u8 k$ }! u
  193.       break;0 K( R6 N8 N4 F/ C. X
  194.     }+ t& m  x) R. d
  195. 7 A6 L$ {! G4 m' u% u/ }
  196.     case StageEstablished:7 }+ b; A6 z: X; ~* i# v- C0 S
  197.     {' x9 Q/ G( j* }6 @9 d- o' g
  198.       transmitStageEstablished();0 F+ e& {3 j  C: S  o$ L

  199. + Z$ f+ O2 Q2 ?& Y4 S# h. N9 W
  200.       break;
    0 K+ n/ a& a& y* M) M7 E, j
  201.     }
    : R* P+ I. s( e5 O& l  \. D

  202. ; U* r8 o/ T8 B! W
  203.     case StageTransmitting:0 r5 _+ M2 t7 w: X+ `
  204.     {6 w! s& ?; k% m* F6 }
  205.       transmitStageTransmitting();# ]) h0 M8 b! b+ w' V

  206. ; G* X' z, p: @  I
  207.       break;2 r& {  B3 K2 `2 h8 A  f* o
  208.     }
    1 P3 I. `* c# \: Q  {6 n, {
  209. 9 n6 A; X! p; S' c* Q' a* U
  210.     case StageFinishing:
    % T. A; R- \. a+ @9 _- ]6 j
  211.     {
    3 w$ h# N. M* I/ O$ r4 B
  212.       transmitStageFinishing();
    4 M& N) |- Y5 B' J; c" ^" P
  213. & B" ~. m. S: m$ }8 q0 q+ n
  214.       break;' f0 l- n! }& l4 I, c9 D9 m
  215.     }
    $ P& W4 H1 }9 a9 h  e
  216. . @9 R6 [8 L  b: W7 d2 ?# w; B
  217.     default:
    0 |! W$ h2 u+ T) H% {. m
  218.     {
    4 [/ B+ b8 c( E; {0 U
  219.       transmitStageFinished();+ O* y" F) R0 s9 @: H/ C; }
  220.     }% u# ?/ S1 S& m
  221.   }0 o* B3 C' M7 G3 @
  222. }7 t# T5 m  M/ ~- q8 [' @6 X2 a
  223. , `9 ?* z$ y# V& ~3 G) z9 \& `6 y7 S
  224. /**
    : Q  v! u2 H& {8 F5 r: u
  225.   * @brief  Ymodem abort.
    $ d% |% s1 c( c# T) u" P
  226.   * @param  None.
    8 w, X: D1 `" p6 {
  227.   * @return None.  ^1 R# A# z0 }* K
  228.   */" D( G3 g% N! l$ d& R
  229. void Ymodem::abort()
    ; P0 u6 m0 B; `9 k! `+ W
  230. {4 v* E. _; o2 G3 r" C; L
  231.   timeCount  = 0;
    ! j4 C, ~( ?( ^% K7 C
  232.   errorCount = 0;
    # V; b/ ~/ P1 _! L( r  j5 u
  233.   dataCount  = 0;: E% H) B+ g' E* e7 J
  234.   code       = CodeNone;
    6 A; O; d# R# H3 A0 y+ _! `$ E% A
  235.   stage      = StageNone;
      u5 ]# H7 a$ _5 G
  236. ) u# p( F% @' s5 m# l, |/ h: F
  237.   for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    3 O7 X" r0 d( }# L# g! v- p
  238.   {4 e) _5 [6 l/ c4 ]8 T* x
  239.     txBuffer[txLength] = CodeCan;
    / N- [7 a* z4 ^
  240.   }
    6 _4 V8 O8 f8 t3 Z

  241. 1 a) S2 {3 Y( k
  242.   write(txBuffer, txLength);# \* u0 z( ~' s& e- S
  243. }
    8 o( V, s; Y/ ]4 |# @' ?+ L( `* Z( M
  244. 5 v' f/ w5 ?( i, K
  245. /**
    / u. B) T) d% h$ @$ a  ^+ B8 U# y
  246.   * @brief  Receives a packet of data.
    - m- f' K8 [$ |1 `6 {
  247.   * @param  None.' C) Q+ F0 v8 l) N4 I7 ^
  248.   * @return Packet type.9 r- _# p# Y8 X! z8 [0 {; ?) q; S1 w
  249.   */1 C5 F$ w! F) T: O
  250. Ymodem::Code Ymodem::receivePacket()
    + @- f2 K# G& m" u: s# X/ S
  251. {
    ; ^7 K& }* L6 E3 _" P0 y/ k
  252.   if(code == CodeNone)
    8 G: t' z) \% b2 q' P$ M9 u
  253.   {
    . x0 a0 _3 {) U+ V
  254.     if(read(&(rxBuffer[0]), 1) > 0)
    $ c& p/ H: F+ Z4 k0 G! i
  255.     {
    4 X- N8 _6 u* a1 ^* u" n* `/ \" B) G
  256.       if(rxBuffer[0] == CodeSoh)1 {6 {! F- g# [/ S) G" J
  257.       {3 G* h* a2 t/ k& ~6 r
  258.         uint32_t len = read(&(rxBuffer[1]), YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 1);9 z' o" Z7 d0 d7 {! `
  259. " X& y' O2 `4 J, `0 j
  260.         if(len < (YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 1))
    ) o) C) p. k! V/ r
  261.         {8 U7 t9 x( _0 [. t9 \9 r$ C
  262.           rxLength = len + 1;/ ~8 j7 _7 i3 V
  263.           code     = CodeSoh;
    ( N" l) t, B( W& i9 K6 m

  264. ! y% H, `: N% F# Q/ t, ]
  265.           return CodeNone;$ h- h6 s% o% M. H& \4 _6 y( G. a
  266.         }
    ! A# Z" ~/ o# r: P, s
  267.         else
    ( L4 Y, |( }. D- o1 g
  268.         {
    2 G0 I$ U% P5 m- F6 X
  269.           return CodeSoh;5 _- u% w' c3 \% D* D! A6 h
  270.         }! a  l' _- i' H
  271.       }1 q% V; o6 D" h1 [
  272.       else if(rxBuffer[0] == CodeStx)/ ~. l6 d$ g4 U! E7 u5 A$ K
  273.       {" S9 c! `  N" @  F, z7 l
  274.         uint32_t len = read(&(rxBuffer[1]), YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - 1);  N4 |9 @5 w7 J3 f9 x$ U
  275. " t" j; V# Y: f7 K& @& J1 r
  276.         if(len < (YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - 1))
    ; x* g  e' F$ `/ E2 h, M# c
  277.         {
    ) G) A1 F: T0 K2 T- m) ?
  278.           rxLength = len + 1;$ O, v4 I* t. d! b9 m
  279.           code     = CodeStx;8 c% _& R' y: Z: j
  280. / ^: s+ m) {/ K& [0 H; \
  281.           return CodeNone;
    ! f) h& Z6 U$ }+ m
  282.         }. U: l) I. Q( e. g0 N" ^# v7 \4 d
  283.         else
    : s  y  I+ p5 \$ I
  284.         {1 A2 W9 ]: a" W3 D
  285.           return CodeStx;
    ' L( s8 c$ E. }9 u
  286.         }- J% V7 S( D6 g! D$ ?! ^# N# t
  287.       }0 d; K+ ~% ?! B: f4 Y
  288.       else, t3 W: {. |; ?. F# B1 c
  289.       {
    & n( l0 [* q4 n3 I6 O* b7 {
  290.         return (Code)(rxBuffer[0]);
    8 E: Q6 f4 j% S6 _2 Q8 r( U3 A0 }" n
  291.       }. n( Y8 M! M+ g1 I3 r6 T
  292.     }
    & j6 s2 ]8 u$ k/ h& O% V' C$ o
  293.     else
    8 i( x. i# ~' W2 b% p. ^/ M# W: h
  294.     {
    2 n5 |; ]$ j8 p- [  J$ @& p. z
  295.       return CodeNone;: H7 T+ ^$ U$ y9 d, R
  296.     }5 `$ y4 Q7 Z2 `
  297.   }  a4 h) z9 d% ?$ z& w
  298.   else
    8 L1 @& U8 I& |# x8 J/ Z
  299.   {( [8 \/ N; Y$ M+ M& B0 j* `6 n
  300.     if(code == CodeSoh)& ?& T0 E2 ~: s9 @3 ^! c  k
  301.     {! c+ v9 V/ H$ }! ^$ O) Q0 ?
  302.       uint32_t len = read(&(rxBuffer[rxLength]), YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - rxLength);# H7 g, g* ?+ z# @2 l1 ^' Z
  303. . f; B! d9 _; H
  304.       if(len < (YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - rxLength))# K! P7 C; S0 o5 f( V9 j# Z! [3 u
  305.       {
    * V" W. {( K5 A. [" g
  306.         rxLength += len;. W3 J. p' |4 M0 Q

  307. : ~% S9 l9 `. e2 c; ^8 C9 }
  308.         return CodeNone;0 @$ i8 @' q8 B& Q3 Y
  309.       }
    3 `$ G0 A5 I/ Q- q
  310.       else
    & ?+ a& e6 v8 ~! F/ W
  311.       {
    ) |/ H: |  p, }
  312.         code = CodeNone;
    2 \. X1 z2 u/ M. P, `
  313. 9 m& Z! ]* ~$ @; I3 m7 O. R
  314.         return CodeSoh;
    ) F. Y! @8 i, j6 a9 C  i# m% u
  315.       }
    2 e& E7 l% ^1 K- v/ ^% @
  316.     }8 R( X& d5 W1 A8 D& S0 u9 A% S, |5 ?
  317.     else if(code == CodeStx)6 a) K$ r) G6 W; ?8 o1 Z1 U
  318.     {
    " M( M3 i4 H2 e; g
  319.       uint32_t len = read(&(rxBuffer[rxLength]), YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - rxLength);/ L' o4 B, c( h( Q( ^0 T
  320.   T( q+ Y0 F7 T8 t) K; p  ?9 ]( w" W
  321.       if(len < (YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - rxLength))
      K9 e5 a, @- n) a; q& j% h
  322.       {
    ! e& p1 k* w8 d1 Q) \# y
  323.         rxLength += len;
    8 @2 N  N* B, D6 n% e. @: p6 x
  324. 0 ]8 P2 c% q9 N4 v
  325.         return CodeNone;
    % t) M; _& r: c' x# I7 D& G
  326.       }
    , s) {* P3 R2 p8 w- V' a
  327.       else9 C- a* S* R! u
  328.       {# E$ H- J$ @* ~4 l
  329.         code = CodeNone;
    3 @% G, J4 d3 b  z4 N

  330. , K. v* t" r2 Y8 f7 z% k$ b
  331.         return CodeStx;
    2 s& ?+ }, h* U* A0 W
  332.       }4 j" l0 h% m# [; T4 r4 Z
  333.     }1 N3 t. \) Z, x" e4 P  }0 P
  334.     else
    6 M5 H4 {* }$ y" M/ _
  335.     {
    % P! ~) m4 E: ^4 H0 b, ]& G- q
  336.       code = CodeNone;* E  g; \2 s8 i9 Y* e
  337. 7 |$ n) t0 e$ l
  338.       return CodeNone;
    7 G0 z/ B$ K' u/ }' y  _
  339.     }
    / y& H/ I  ?4 P2 a" b* m
  340.   }
    3 l/ {* c4 F: }$ u
  341. }9 Z# w% s; m! b4 b1 j

  342. & w2 C. a% }& a& X$ M: w
  343. /**
    1 W$ h+ z: v; W0 h
  344.   * @brief  Receive none stage.
    9 `5 b* E) ?5 P5 P8 X
  345.   * @param  None.3 \! u) j$ U% |
  346.   * @return None.% h3 L9 _+ y* A2 R# C( j
  347.   */
    , ~2 `2 ?: _/ ]! W9 V8 p, O
  348. void Ymodem::receiveStageNone()" W$ t4 T' O2 f- h
  349. {- c1 p. N+ T9 d  T/ l* s0 _* L9 z
  350.   timeCount   = 0;* V1 E2 C' m* {' z9 O& e9 ]
  351.   errorCount  = 0;0 ~- I- S8 u* F# ?
  352.   dataCount   = 0;
    # `! Y; j, ~  q
  353.   code        = CodeNone;/ u, G3 _3 |6 Z
  354.   stage       = StageEstablishing;
    3 f/ a3 G$ T: @2 z
  355.   txBuffer[0] = CodeC;( P7 D5 ~; l, Y2 I
  356.   txLength    = 1;
    6 O% I( s2 n0 ^& J
  357.   write(txBuffer, txLength);
    8 V( k. F3 j" B4 ]( X* _1 X; w
  358. }
    0 t" Y4 s1 I* q% X- w
  359. " T" d6 f9 Z0 v- w6 A! d
  360. /**
    ! D2 U0 K, ^4 q2 M' ~: M6 W
  361.   * @brief  Receive establishing stage.
    9 M9 t% F, n7 @+ C" N2 e
  362.   * @param  None.
    ; W. n! B" Z3 j" p& @
  363.   * @return None.! Y/ y0 a: @' O$ b
  364.   */
    0 ?- W1 M) q5 [6 N! Z$ }8 D8 Z
  365. void Ymodem::receiveStageEstablishing(). u: a4 J/ W# e; i7 d) \
  366. {
    + S8 S; i4 B$ [( x# G
  367.   switch(receivePacket())
    5 q4 \; Z' u9 i; H- k
  368.   {
    * `0 U7 J/ X2 z+ `' }4 A
  369.     case CodeSoh:
    7 |7 Z' z, }. Q% f! A
  370.     {2 Q( R$ a+ N$ {# K8 f
  371.       uint16_t crc = ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 2]) << 8) |& u0 r# S9 J# p; g1 O2 b
  372.                      ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 1]) << 0);! V3 i7 L0 e) o. V. H  a& l
  373. $ ]' T: E& [8 _0 B6 }1 ^
  374.       if((rxBuffer[1] == 0x00) && (rxBuffer[2] == 0xFF) &&
    * W+ W0 }6 J+ l! d
  375.          (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_SIZE)))+ t; a/ Q3 e/ ?9 w! r% ], ^" s9 l
  376.       {. g' }6 E' s2 p4 F
  377.         uint32_t dataLength = YMODEM_PACKET_SIZE;
    6 K6 U. B) B& r+ e' F

  378. . C$ Y' U" r$ T
  379.         if(callback(StatusEstablish, &(rxBuffer[YMODEM_PACKET_HEADER]), &dataLength) == CodeAck)" J9 P0 s7 x2 n2 M! a8 [
  380.         {
    , ]3 C, \9 t) r! R, T
  381.           timeCount   = 0;: a% v% a$ _+ b; d& h
  382.           errorCount  = 0;
      {( N4 V' R: |1 C; G
  383.           dataCount   = 0;6 p* a; d) V& C0 e$ d1 H
  384.           code        = CodeNone;# b2 q) G9 h7 D7 m  J
  385.           stage       = StageEstablished;% [# B+ [/ w, S: B. p) o
  386.           txBuffer[0] = CodeAck;
    ( k" r, b* z3 [$ P$ J; z. z
  387.           txBuffer[1] = CodeC;. A1 A, F& y5 X0 l
  388.           txLength    = 2;7 K* i$ g4 @: r* K
  389.           write(txBuffer, txLength);: d0 b  U8 \9 {1 D, }
  390.         }
    # b/ K" z& G) T# v0 }
  391.         else
    1 q3 b3 D8 F5 ?8 \; O  M! |' }
  392.         {
    * A4 j2 @7 @) u4 ?% w* x8 {3 R
  393.           timeCount  = 0;# C( a3 g/ e% X5 r' J
  394.           errorCount = 0;
    % R4 V* d& L8 K. g6 t* O
  395.           dataCount  = 0;8 `1 p/ i5 r1 x; e  f/ U. n
  396.           code       = CodeNone;) v4 T  u: ~* ]  k- O" a
  397.           stage      = StageNone;
    / p. L, g. y8 i) f; s

  398. 0 P- J7 Y9 e, D" w# t$ E
  399.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    $ b& w( i! |+ V
  400.           {
    4 t) }2 Q; ]' h
  401.             txBuffer[txLength] = CodeCan;" }; X1 c: k" ^( W# o
  402.           }
    " b4 f3 O* u4 {

  403. " Y: _; I: \  w3 A8 h
  404.           write(txBuffer, txLength);
    : h2 O8 `8 u, q5 c
  405.         }8 _5 i5 ~  i( T' C+ ^$ l& I
  406.       }
    & @! W% R4 e7 I4 c) E& T
  407.       else
    + \, G! F4 r  t/ M
  408.       {: E/ a3 G5 [3 ~% M! g. U  J
  409.         errorCount++;( ~' p5 u0 `' u- J4 f  m
  410. 6 X2 ^5 T( V: O
  411.         if(errorCount > errorMax)2 z( S1 I( Z  a' i# y5 o
  412.         {
    ( X0 p* A+ [& K% A. Y3 H- }3 C+ v
  413.           timeCount  = 0;& u, H  n) W7 \+ {
  414.           errorCount = 0;
      t+ m# |) s: U7 @" A3 W9 V; B
  415.           dataCount  = 0;) f4 o; y/ t* r
  416.           code       = CodeNone;
    6 ?4 m; J. G5 D0 P
  417.           stage      = StageNone;/ Z" Z* ?9 L) X$ |

  418. . X4 N% r3 _4 Z6 t& D4 Y/ N( U+ e1 L
  419.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)* O# C: h9 U- m0 R9 @" e) [
  420.           {' ?' Z$ h. ?% M& K( G. x4 x
  421.             txBuffer[txLength] = CodeCan;
    ) S, _! L0 J1 O; v
  422.           }4 y% X/ u0 h8 y. w6 B

  423. ' C. e6 }" A5 V
  424.           write(txBuffer, txLength);
    # [! Z: w  Y. C* ?) _
  425.           callback(StatusError, NULL, NULL);8 S- `4 n0 g* _# u9 i1 G
  426.         }
    1 a3 e8 [' ?0 h- E
  427.         else
    ( j' d! N7 T7 F4 ^' \( D2 x2 w
  428.         {
    2 P! _& P% k: W, G/ O4 }- g- x0 U
  429.           txBuffer[0] = CodeC;& C% U( [+ P7 x6 o1 b# \
  430.           txLength    = 1;
    * c* F2 J. o9 b# s
  431.           write(txBuffer, txLength);1 N& E( h6 z  I& a0 \9 u/ Z
  432.         }
    ' Y, a& h; G* N& o
  433.       }
    6 z: U: A0 `) ~$ W$ E  I! H+ q

  434. ) I5 C& C5 g$ A; _% l! [
  435.       break;/ ?7 Q) a- @; O; q2 I( M
  436.     }
    9 W. h5 x2 [2 Y
  437. ) [, c" @9 K- u3 v+ T
  438.     case CodeA1:
    9 r4 S  L8 n, F% w9 `+ n0 P7 B: F9 }" K' ]
  439.     case CodeA2:1 h" j& ~9 T( j% j- U- }
  440.     case CodeCan:. Z: o( T8 H' e  y) \9 b5 w
  441.     {5 {/ f8 ~& K( W+ Q" `
  442.       timeCount  = 0;9 K6 c7 F) }, s+ w7 a% t
  443.       errorCount = 0;
    ) L4 B. ]5 m2 n) a4 N3 m! ]
  444.       dataCount  = 0;8 I" l. ~, I$ w" k7 k1 T
  445.       code       = CodeNone;* o1 q2 @! X1 P) z, C
  446.       stage      = StageNone;
    ( C% s, i. J; `* r" i4 q
  447.       callback(StatusAbort, NULL, NULL);6 p9 N' ~; p, ?$ G4 D0 E% U& U
  448. 7 w8 V* @& k7 r) T7 a  T
  449.       break;
    8 x0 Z; M6 B; d6 q% ^! A* l- S6 R5 t: |
  450.     }+ |! e# G& |' K' V

  451. 8 G' b- h9 t4 J# x/ I$ \
  452.     default:
    1 o) B5 ~$ _' R  i$ `. {
  453.     {% y+ ?- M  i8 G+ _" ~! C
  454.       timeCount++;
    5 Y6 Q; O5 X" A9 s- @% N3 L
  455. 4 |6 Y) O$ Q" f. B; B
  456.       if((timeCount / (timeDivide + 1)) > timeMax)
    % R! R9 J0 Y  L; Y
  457.       {1 S0 Z) N( P, |9 l6 p
  458.         timeCount  = 0;! Y' v4 K. ~5 B6 W
  459.         errorCount = 0;
    4 e. B! G4 [/ W
  460.         dataCount  = 0;" v' A0 f/ e6 {9 g& i- Q/ \3 Y
  461.         code       = CodeNone;
    % _. }9 S# ?) S0 z
  462.         stage      = StageNone;
    - O. n  L" q4 v$ r% T* h

  463. ' {2 J, L( }$ s3 d* }
  464.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    - ]4 r4 k2 M1 z, ^' K& I( d. z
  465.         {9 d/ A# Y; n8 i- t
  466.           txBuffer[txLength] = CodeCan;! l- b9 A. R% p& L0 Q! ]
  467.         }
    8 Q# {, ^8 `6 q, @0 h

  468.   m2 @$ \3 S6 Y8 o$ Z
  469.         write(txBuffer, txLength);
    $ u2 \& e7 F! Q# [5 N  J4 V+ U
  470.         callback(StatusTimeout, NULL, NULL);' U8 `/ L) b9 y* X' i6 [7 M; d4 Q5 u
  471.       }
    # C- k# F# O0 }! g2 |' F
  472.       else if((timeCount % (timeDivide + 1)) == 0)' h6 c" |% w, V
  473.       {
    1 x0 T* f9 V. K% T5 J, B
  474.         txBuffer[0] = CodeC;
    0 ^2 r: i3 L/ A$ s  i: o! Z
  475.         txLength    = 1;# ~+ ^" e$ l1 Y8 Y
  476.         write(txBuffer, txLength);2 b) f! _& G$ \; r6 M
  477.       }, |) G1 k/ L- O# S# p
  478.     }* O: I1 @2 P0 D. f: N
  479.   }" P" t* F1 V. J% |0 f5 o
  480. }  n2 k* F9 T( W; F9 C

  481. ; ?0 F8 g5 U9 x4 M2 p, B
  482. /**
    7 _" Y$ g6 @3 q8 o
  483.   * @brief  Receive established stage.
    6 q6 l1 K; u4 m. f
  484.   * @param  None.
    4 `. z. |+ N1 u( U8 g5 e6 Q" p# q- G7 e
  485.   * @return None.8 A' G0 C5 v" }
  486.   */
    ; x: r# n5 r' M+ n5 a$ W! G
  487. void Ymodem::receiveStageEstablished()& M8 Y5 [/ X3 V. R
  488. {
    7 X9 j. ^) R* a& s* u0 \9 g. G
  489.   switch(receivePacket())
    ! d" |  n* Z6 w, j/ k0 |4 X4 {5 g/ i
  490.   {+ r1 S( v, |, j
  491.     case CodeSoh:! L; \3 n/ [- r0 [6 Q
  492.     {
    $ J. G6 j# [4 \5 z+ |0 ?
  493.       uint16_t crc = ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 2]) << 8) |: ]; M1 m: r. T: c3 n5 E- t5 [8 m
  494.                      ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 1]) << 0);- |2 r; D* S  l0 R3 s; O% B& ]

  495. . b& o, L: S; P% o% ]# Q4 {
  496.       if((rxBuffer[1] == 0x00) && (rxBuffer[2] == 0xFF) &&
    . H, f. W) n" P
  497.          (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_SIZE)))
    ! i* J7 u" R1 |# M' u1 A
  498.       {
    0 P) J) b. Q+ s7 j; \
  499.         errorCount++;% e7 i/ m/ Z' A# Q3 }

  500. ( L9 _. y+ L$ j
  501.         if(errorCount > errorMax). f+ ~) X) y: B9 b0 v" g7 _
  502.         {5 e, `+ z3 o! Q& b% {& x4 j& j
  503.           timeCount  = 0;
    - G0 g% W; M, H  B2 F3 s' F
  504.           errorCount = 0;0 ?) W' Q6 M$ W2 k" E
  505.           dataCount  = 0;: b- B( t' q+ T
  506.           code       = CodeNone;
    ) e0 W% K( }. w9 J
  507.           stage      = StageNone;, D- Z; @5 f2 o% ?( A
  508. " R; H, ]( n) n/ {+ u" [5 V& M8 @/ E
  509.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    * r* @/ W; Y) J/ o' F3 I
  510.           {
    5 g6 g: a7 Q  I, n8 m+ [! s) {- {, \+ B
  511.             txBuffer[txLength] = CodeCan;# R2 {+ e6 h4 P7 q6 s# a; I
  512.           }$ d, M( `. _3 }% _' U% W6 r
  513. 7 l( A& ~6 n- A4 H  l
  514.           write(txBuffer, txLength);
    , J+ `- n" z4 h* A
  515.           callback(StatusError, NULL, NULL);
    ! j; o1 l: ?) a5 F# y
  516.         }+ w: X- l" t! A& |0 @. {
  517.         else) w* m+ [- O; F- f. M& m
  518.         {/ P( O0 w" }' N/ P% ^
  519.           txBuffer[0] = CodeAck;
      r" z9 h# I+ J* E6 K# Q+ G
  520.           txBuffer[1] = CodeC;( c. {. v& J/ F+ o$ {; x2 `
  521.           txLength    = 2;" O4 z& @! t8 _  M: }
  522.           write(txBuffer, txLength);5 U/ R# z3 s/ g. b
  523.         }- E: J) c  a0 B
  524.       }% S; h% b) Q/ |* Y, E% V; X$ M
  525.       else if((rxBuffer[1] == 0x01) && (rxBuffer[2] == 0xFE) &&( Z7 v8 b% F% z- f
  526.               (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_SIZE)))8 G$ P$ ~! j7 \+ p. F
  527.       {
    ; U; g% ?! _: n& w* u
  528.         uint32_t dataLength = YMODEM_PACKET_SIZE;
    ; j" K8 |+ r( X; T/ k. W1 o
  529. 1 W  E% a2 b! b5 P. i7 |
  530.         if(callback(StatusTransmit, &(rxBuffer[YMODEM_PACKET_HEADER]), &dataLength) == CodeAck)% Y8 [) B* c1 e
  531.         {
    % q; n4 B+ R9 k) _& T9 x
  532.           timeCount   = 0;
    & r9 s2 R# l/ d) [# j
  533.           errorCount  = 0;7 O  I' A  p7 l& y) l. D, X
  534.           dataCount   = 1;5 C9 A9 |1 ?4 n7 `: n0 o' t
  535.           code        = CodeNone;
    - f2 ~5 G1 y" F+ H
  536.           stage       = StageTransmitting;
    4 P5 \5 g* e6 s! r5 C; J4 A7 \5 n
  537.           txBuffer[0] = CodeAck;
    $ k( J& n8 y2 N& ~/ O( J+ b6 L7 J) H
  538.           txLength    = 1;
    ( i% \3 i3 B5 {# f7 M
  539.           write(txBuffer, txLength);
    $ y) b; D. q% a6 G* V1 s
  540.         }, P  \2 @& Y7 J3 S/ Z6 k$ w' l
  541.         else' a4 r$ b; T. x8 j9 M( z4 U
  542.         {7 d' C% z) k" f. L, j7 m! b% D
  543.           timeCount  = 0;
    : n$ @$ ?+ x+ t; p; x% \, ~% O7 o
  544.           errorCount = 0;7 i& J& ~/ v( U8 z9 v- a2 }2 `4 M" I
  545.           dataCount  = 0;3 F$ X0 v( U+ R- w/ ]3 P* v
  546.           code       = CodeNone;7 \5 e+ u# g' z% m  E0 s* L' q0 Z" q( A
  547.           stage      = StageNone;
      V2 q7 l# W) w; w' S6 O- {

  548. 0 A4 t8 \4 Z2 n/ Z. T9 B
  549.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    2 @4 H8 r% w- S1 R/ X5 N( X
  550.           {1 k) r7 y* y  h6 j2 c
  551.             txBuffer[txLength] = CodeCan;; c7 _' J6 o1 t, o' X: ^, Y$ c
  552.           }
    5 W& _* m: [) p, A/ c4 l
  553. ( C2 i+ w4 z5 j# t( U5 t5 r
  554.           write(txBuffer, txLength);
    1 D- j) n+ _: a
  555.         }
    6 |2 j8 {' g8 H
  556.       }
    6 p; Q9 g, k! ]/ p
  557.       else* A. P8 {* v6 p1 E5 j3 F
  558.       {
    3 H" u, O" {& {" ~
  559.         errorCount++;7 L: `) z5 H% e0 W; D9 G& t  A
  560. $ i5 B4 E4 T4 Y8 O
  561.         if(errorCount > errorMax). Y% f  O" \. T5 D" N
  562.         {5 S1 |0 [3 I0 ~- U
  563.           timeCount  = 0;! t( E. J& X  E6 h1 s
  564.           errorCount = 0;
    ! l+ ]- m; j- t2 A
  565.           dataCount  = 0;
    7 ^' }. C  d( y, c% q( o
  566.           code       = CodeNone;
    9 i2 I, F" L3 R
  567.           stage      = StageNone;
    , n: r% V" j' x7 }1 R

  568. ) F1 k5 M& j! X" t9 Y+ j
  569.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)- B0 c; U0 `9 E: N) ], ?+ O- T
  570.           {+ @( b8 a( g* K
  571.             txBuffer[txLength] = CodeCan;
      ^4 R: `  m: c4 s  G7 G
  572.           }2 a1 S3 M* D8 D) D7 h& r) M& K
  573. / e  O# M1 E5 C, Z$ k5 L- f
  574.           write(txBuffer, txLength);  p* v3 h. x  Q9 C* g' W
  575.           callback(StatusError, NULL, NULL);5 e4 @3 C/ b8 ?; x8 X4 s; U
  576.         }
    , h9 N/ e8 S8 W4 A- y1 O$ t
  577.         else6 k/ K. E! c2 D/ O! C0 g
  578.         {
    7 |" w" m6 ?1 S/ k( ], \
  579.           txBuffer[0] = CodeNak;
    & M1 S* ]/ {) h8 r7 C* A- E# v
  580.           txLength    = 1;
    ) c3 H8 G; C' H, s. }9 G
  581.           write(txBuffer, txLength);: `' N! }: W# [* _1 a
  582.         }" f* `) ~2 F4 C1 u% c$ c7 Y
  583.       }
    , K3 r0 o# X5 A0 V! g& \3 }6 U
  584. , \4 c( E2 K7 q3 F5 U
  585.       break;
    5 t+ y* `& }; y, D  v  G9 d
  586.     }
    ) g0 ?5 Y0 _) T7 v4 C

  587. 3 Q; Y- o1 {! Q3 l4 Q
  588.     case CodeStx:
    1 u1 s7 P% T6 g
  589.     {
    ! _2 p/ H' O4 f5 y; J) C$ |+ [) _
  590.       uint16_t crc = ((uint16_t)(rxBuffer[YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - 2]) << 8) |' s/ q# V( L1 j0 z9 U  G4 g0 X
  591.                      ((uint16_t)(rxBuffer[YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - 1]) << 0);& f7 E5 g: d/ f
  592. # Q+ E5 \' b( S4 f$ q3 o
  593.       if((rxBuffer[1] == 0x01) && (rxBuffer[2] == 0xFE) &&
    4 ~) H9 M. {8 G: ~' ]
  594.          (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_1K_SIZE)))
    2 w* R0 k% L* {: Z* F; f
  595.       {% B; F: Y# S" m: r/ Y: q7 G
  596.         uint32_t dataLength = YMODEM_PACKET_1K_SIZE;
    6 n3 c- H6 r8 I( N  N

  597. , }( x6 K+ N% S4 N- s- h0 w
  598.         if(callback(StatusTransmit, &(rxBuffer[YMODEM_PACKET_HEADER]), &dataLength) == CodeAck)
    5 k  |2 o" `% \0 c5 i( W
  599.         {, ?- t: ?' e/ _7 k3 K' R& K
  600.           timeCount   = 0;( O, ^& i3 W: x% q- k
  601.           errorCount  = 0;1 |. t! d9 I1 m  ]' ~( [( H! M
  602.           dataCount   = 1;
    ' }9 o4 `0 N+ F
  603.           code        = CodeNone;
    ' d; X) b: C7 B) B+ u9 z( h
  604.           stage       = StageTransmitting;
    1 s  I8 Q/ A; r: d  \5 F5 Z
  605.           txBuffer[0] = CodeAck;5 W* U( F4 P: H* @8 P% k' K
  606.           txLength    = 1;
    ( ?9 e: L* e) Q- U. t
  607.           write(txBuffer, txLength);
    1 v3 H6 h' r2 W0 m7 m$ l
  608.         }5 [7 Q/ e$ e3 r0 k# o, w  P
  609.         else
    1 V  v  c6 @2 P9 R- l
  610.         {
    $ j- U2 R1 j! k/ P) w
  611.           timeCount  = 0;5 g, W  O- b1 F. D- h
  612.           errorCount = 0;
    : I4 }$ _6 l8 ~9 @/ `0 T0 s2 g6 V# C8 [
  613.           dataCount  = 0;
    - n" n& M- }7 ^
  614.           code       = CodeNone;
    1 ~: ?1 d, j# p
  615.           stage      = StageNone;
    & M8 T* ^% S4 a
  616. , p/ U7 h% S* G# Q
  617.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)  p. q7 n* F/ J3 ^
  618.           {
    : _9 [! }% \! D2 U& [" R8 B
  619.             txBuffer[txLength] = CodeCan;
    3 l3 p4 l; L( B! a
  620.           }6 X4 A: @+ G/ l: n; _5 w

  621. ; n$ o. n% U* D( h
  622.           write(txBuffer, txLength);
    4 g( y* G. G5 g- y: g& @& l
  623.         }% R7 N7 r6 g# L+ _: M6 {: V( l: E
  624.       }' g7 ]5 {$ P( T2 O$ _3 z
  625.       else
    " v- D+ ~8 ^+ t+ z/ O7 Y
  626.       {8 N0 Y$ `& a8 ~4 x4 |% V
  627.         errorCount++;
    8 G/ D5 N. X) O& ?

  628. ; y8 t% r- Z( E+ M
  629.         if(errorCount > errorMax)
    4 D, L/ a; O/ u" l, q
  630.         {
    $ r1 g& q$ g1 M
  631.           timeCount  = 0;
    1 G* u3 ]: }: _- S/ W* \
  632.           errorCount = 0;
    . ]7 {, [  J: G; Q  ^
  633.           dataCount  = 0;
    3 y/ R# j- `6 z* `( f
  634.           code       = CodeNone;) g- K! ^1 f% M2 k* W. S$ ^
  635.           stage      = StageNone;+ n% _! {$ S: f( u" ?1 [, |4 i2 ^

  636. $ z7 e+ Q8 @2 j
  637.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    : S9 A; ~2 R; U) _
  638.           {# V) D1 ]) H7 J3 t& E4 A# D0 h
  639.             txBuffer[txLength] = CodeCan;  E+ i8 X9 j0 T9 A3 c6 }
  640.           }
    8 B/ r: D$ o/ ]1 h& @0 s* y" Z

  641.   U- H1 V' Z8 g4 p+ p1 `, _* ^
  642.           write(txBuffer, txLength);
    % q4 H% L8 @  b. I
  643.           callback(StatusError, NULL, NULL);! j# Q* P  n  w
  644.         }! W3 {* g+ ?# d+ p" L$ D
  645.         else
    , L+ k% o* O+ K3 H
  646.         {5 x6 O* p7 t5 U: i0 }6 C
  647.           txBuffer[0] = CodeNak;2 ~; }( [+ U/ j" M- w. i2 N
  648.           txLength    = 1;3 P/ p, R) q8 X* l: M, j
  649.           write(txBuffer, txLength);
    7 P' Y, b3 {3 r. _& J3 f/ q& h
  650.         }* O7 j6 D. L/ v. m6 d0 z/ @7 t. U
  651.       }! h2 x& \! \& A2 Y, j
  652. + x6 V, Y2 G& Y9 q" h. a
  653.       break;. X# N6 T2 k7 i7 T5 j1 D/ h, o! u. n
  654.     }
    # F+ [, x: }7 D3 d! }
  655. 2 @8 M4 x, E) t, O. n& B4 l& E
  656.     case CodeEot:
    # |1 U) \  y' p
  657.     {3 B. B: q* k5 N8 F) T6 z! p
  658.       timeCount   = 0;
    8 U; {4 |+ G4 v- |& f- M9 R
  659.       errorCount  = 0;
    8 {/ X/ `  Z; X! E9 H
  660.       dataCount   = 0;
    $ ?6 J2 z8 v% y+ S
  661.       code        = CodeNone;
    * Z) g2 c  K, Y3 {. f* d+ d
  662.       stage       = StageFinishing;! u5 I6 q: k& |" w4 j5 W" r
  663.       txBuffer[0] = CodeNak;
    # \9 W* K/ t4 E) T, `
  664.       txLength    = 1;* p1 t! G$ p$ F) b3 W
  665.       write(txBuffer, txLength);
    : H' s4 \7 I* }* H( M2 I3 N% g% x8 A

  666. 4 [0 }0 |3 p3 z* X! p: @
  667.       break;
    . C9 ~; ~# M7 t- _
  668.     }
    # P* g* A& l5 {0 `( M
  669. + \1 Z) \# E3 O& K+ b; E# i4 N
  670.     case CodeA1:1 A) G9 U. |! r3 B9 W- g+ o
  671.     case CodeA2:' C. k& ~! u1 x- I* v' U8 y
  672.     case CodeCan:: C# [) e- ]& T( [# P
  673.     {
    * `* C: {9 O& k* J( c8 \$ b
  674.       timeCount  = 0;( [; R0 Q! A/ g
  675.       errorCount = 0;
    1 U9 C( s' @4 f
  676.       dataCount  = 0;6 B6 h0 z/ r, y0 A; `1 @. \/ d
  677.       code       = CodeNone;: }4 f5 y6 q/ Z- I( k/ o
  678.       stage      = StageNone;
    1 Z" P: a- k' F, ]% u- r
  679.       callback(StatusAbort, NULL, NULL);7 t7 n2 U1 a5 }* S' `/ {" p

  680.   |/ u' l0 j7 i! x5 n
  681.       break;* s6 i8 j. x3 _  R
  682.     }) C$ u+ Y. m" O+ e5 G% f( m- h
  683. 3 I0 T  s+ b4 w6 H
  684.     default:" B& b. \  d/ X! M7 n
  685.     {
    # k( i8 E0 U- _; X
  686.       timeCount++;
    ! e, g7 @) z* w; R2 t
  687. - E  C8 o# j1 y9 |+ q2 Z
  688.       if((timeCount / (timeDivide + 1)) > timeMax)
    5 V! O3 L3 @! C7 [. p4 I* F
  689.       {1 c; D4 E4 |% v
  690.         timeCount  = 0;
    4 Q4 T: `8 i* f4 C; P/ ]: ]) _
  691.         errorCount = 0;2 R0 R% v3 c0 b; L" N1 a& X
  692.         dataCount  = 0;. G' e# n4 X. r! M1 _5 }: N
  693.         code       = CodeNone;
    " k$ }% k+ F5 q' y* u
  694.         stage      = StageNone;) {3 v6 h; ]# a' R' N7 l( K

  695. 0 W. p3 k, E9 Y9 ~5 l. I( l* L
  696.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)6 j) A! N8 v, d5 ?* q
  697.         {
    # X0 `! S5 C5 }) b
  698.           txBuffer[txLength] = CodeCan;" F$ D/ S& s/ c2 |; M
  699.         }
    , R$ S  @5 G8 i' q" \" Q6 O

  700. ! m' _$ d6 s' C) \
  701.         write(txBuffer, txLength);# E3 j4 \$ b2 o. E" j
  702.         callback(StatusError, NULL, NULL);
    - Y' E+ [4 X- ^' k0 q
  703.       }* M7 K# X* k, v( \3 x7 f" c! L' ^
  704.       else if((timeCount % (timeDivide + 1)) == 0)  B+ Q# C4 f0 A$ {6 [- R
  705.       {
    & L1 H3 I$ q; u5 y# p6 ~/ A8 k
  706.         txBuffer[0] = CodeNak;" U& J4 M, Y( t6 {; I! f
  707.         txLength    = 1;
    6 {4 V# c! b; @  R
  708.         write(txBuffer, txLength);: X  k7 v0 ~- j. ]# l
  709.       }5 M- w% c/ Z1 v% x2 W
  710.     }# ^) p2 Y" N8 K+ j1 c2 q% I
  711.   }0 Y4 O( p% m; Z
  712. }1 g; Z" X" n; |7 ^

  713. " }0 y1 J) k+ J9 t/ L
  714. /**! N* `- E' q. v& D$ s
  715.   * @brief  Receive transmitting stage.
    + ]' O' b+ E9 n1 I2 f) p
  716.   * @param  None." z6 ^+ ?4 E+ K; ^1 _& I1 ]
  717.   * @return None.0 @, P' f' D" b' }* I0 E3 W
  718.   */
    5 d8 N' M2 m  c3 V" \/ u8 [7 ^$ S4 X
  719. void Ymodem::receiveStageTransmitting()8 v# @9 J5 i% ^5 i) ~1 @/ L1 W
  720. {
    5 T2 J% ~( F- |' Z0 H4 l5 K
  721.   switch(receivePacket())6 p5 g" B& F9 T2 l7 R7 E. G5 j
  722.   {% x: V; z# T8 G; A+ E
  723.     case CodeSoh:
    ' ~1 a0 f; n$ W9 X  }
  724.     {) x5 H% Y- _+ E9 @
  725.       uint16_t crc = ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 2]) << 8) |
    8 A: ^; j$ E0 i/ X) H6 J5 q
  726.                      ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 1]) << 0);# Q4 G% ?; o; q

  727. * c: d9 s* e+ j. @: ~
  728.       if((rxBuffer[1] == (uint8_t)(dataCount)) && (rxBuffer[2] == (uint8_t)(0xFF - dataCount)) &&
    / w- x  K, ^  p. _5 g
  729.          (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_SIZE)))
    8 u0 e0 O8 q- t; O+ `: k
  730.       {
    3 a: w* h2 S9 v
  731.         errorCount++;
    , z: l9 |, y" Z( h! Q1 v

  732. . a; b1 t) ?' h$ X& M3 R0 p% a. Q
  733.         if(errorCount > errorMax)
    # w: P( R! @$ d0 U5 ?
  734.         {
    " J+ [) G/ D( p* V* {# }4 d2 ]$ W
  735.           timeCount  = 0;! O3 g% b! s$ s' ^. g6 V
  736.           errorCount = 0;
    * q7 X* p6 x! U( n1 m0 q) K
  737.           dataCount  = 0;) h; R! |0 q+ T: e8 z$ H
  738.           code       = CodeNone;6 U  a; {8 |! p8 k" e& g
  739.           stage      = StageNone;
    ( ~8 k7 g* {+ H3 o& ~+ ~& ^4 e0 m

  740. " Y9 p$ y0 S' ^$ z
  741.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    9 _5 I1 M6 }+ G  c3 y
  742.           {
    % ^9 t) n/ u( ^2 Z9 l7 s$ A. O
  743.             txBuffer[txLength] = CodeCan;
    * J  \/ |/ Y5 O9 l
  744.           }
    . o; O+ m# I  D- u6 |) N0 h2 d& I

  745. 8 S9 O1 ], s$ k1 @
  746.           write(txBuffer, txLength);9 l: u/ [' ~: V0 `2 t
  747.           callback(StatusError, NULL, NULL);
    , U% ~- Y7 x2 C! z) C; N0 ^( [. Y
  748.         }" w5 H3 {7 q2 F6 q9 m4 r
  749.         else
    . }4 h$ K1 k7 n& m
  750.         {
    # z; }- Z. S+ K. f+ b8 l
  751.           txBuffer[0] = CodeAck;
    1 {, y: r. ^5 f; i7 c, n; z
  752.           txLength    = 1;
    4 C8 u0 e  Z5 y: d& l
  753.           write(txBuffer, txLength);; \3 \6 I! k9 S
  754.         }
    * C6 C9 D  s7 t7 M
  755.       }  d3 O/ l# g" {
  756.       else if((rxBuffer[1] == (uint8_t)(dataCount + 1)) && (rxBuffer[2] == (uint8_t)(0xFE - dataCount)) &&* ]7 o' t: ~5 _5 E$ K
  757.               (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_SIZE)))
    ' g) f4 E  I) ^
  758.       {4 j! J/ o3 {% X1 Q
  759.         uint32_t dataLength = YMODEM_PACKET_SIZE;( F% _- `! H( m* \8 o9 ?
  760. ; P/ M: P) W9 f$ j. A& m& S2 L
  761.         if(callback(StatusTransmit, &(rxBuffer[YMODEM_PACKET_HEADER]), &dataLength) == CodeAck)* G; A, E. M! h/ E
  762.         {
    " W- z9 }, \% _" @9 d
  763.           timeCount   = 0;
    9 i9 M) o8 L- w) ]1 ?
  764.           errorCount  = 0;
    4 C: `3 m3 u6 x: J) K
  765.           dataCount   = dataCount + 1;
    3 o! x  X5 v& s8 w. R
  766.           code        = CodeNone;. D5 X# w5 e1 c# t
  767.           stage       = StageTransmitting;2 m/ G- [+ t! P) [
  768.           txBuffer[0] = CodeAck;9 w# K0 ?4 }8 A1 a  f
  769.           txLength    = 1;9 y- ?- l6 {. B0 y# d. g
  770.           write(txBuffer, txLength);
    , S5 f. P# w+ L( j  V
  771.         }
    : V3 C# C" J0 g2 {$ B
  772.         else
    & a5 a) g; O8 S
  773.         {
    ' J" z& ~6 ~9 y0 {: \0 V+ z* p
  774.           timeCount  = 0;/ E8 a' f5 e9 }6 ]+ x6 i) U
  775.           errorCount = 0;
    ; J" y* c1 R) d( J
  776.           dataCount  = 0;6 P4 D1 s/ D) {4 a, R3 v7 d) X
  777.           code       = CodeNone;
    , E7 b* J2 Q  B" }/ l) ?1 h. p9 B
  778.           stage      = StageNone;1 Q' i# D5 o" G' d+ h

  779. 2 k* m0 @2 A$ Z0 z5 E
  780.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    2 f" p0 g% A4 U2 V7 X/ D8 L
  781.           {; E: y4 e: T- Y( H3 P) t
  782.             txBuffer[txLength] = CodeCan;5 m% a4 W, M- x9 M- \' Y
  783.           }
    9 J0 n6 J! B$ G& s5 J/ J7 X
  784. 6 x; C8 ~0 k/ k8 v  n9 b. m
  785.           write(txBuffer, txLength);5 `  r% \6 x4 x
  786.         }
    , I1 G% x) W0 _0 \9 Y7 I
  787.       }
    $ P, k7 h3 T$ C
  788.       else/ }0 |6 E. ~( C& y4 D' r
  789.       {
    6 R2 b( |" Z7 z2 C2 ?
  790.         errorCount++;! Q" B+ P. n; z9 J+ G! Y/ t

  791. - A$ N0 y' Q6 `! Z# @# \
  792.         if(errorCount > errorMax)
    & D" R1 T; Y" b- b. W
  793.         {
    6 ?2 g9 k/ j6 p
  794.           timeCount  = 0;" B! K- P$ _( f
  795.           errorCount = 0;
    / j  ?- G. h/ \; Y0 s3 X, e9 @
  796.           dataCount  = 0;. j) I2 D+ Y% B7 w. a7 K
  797.           code       = CodeNone;
    5 `* s! j1 J/ k" S) k2 ?+ R8 z7 k
  798.           stage      = StageNone;
    : H+ S1 q4 _  c7 ]) a* m

  799. " v/ t5 }' @) w8 t
  800.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    2 w' G- _$ ~! i0 K! P0 f$ `- \9 D
  801.           {
    3 m2 Z8 H- l  z( E5 Z2 C- t
  802.             txBuffer[txLength] = CodeCan;
    5 |! {0 ^, s8 ?# u0 ~- p
  803.           }
    - O$ `1 o- [/ j- [- p' F6 z1 P

  804. 6 r  U6 t. T# i6 Y2 C1 O( ~
  805.           write(txBuffer, txLength);
    ; M# w# x+ B6 f% K  R8 b* Z
  806.           callback(StatusError, NULL, NULL);8 P7 `0 h+ }9 R- u2 `! E7 }
  807.         }
    2 ]1 I$ h+ I' x3 S( M9 L) M  j
  808.         else: ]- H( B& S9 E: `2 X
  809.         {
    / q" I/ c' `& `
  810.           txBuffer[0] = CodeNak;! h& q8 R$ k4 s# K8 B; {
  811.           txLength    = 1;- E+ }: f/ [. F3 f) S$ N$ M* O& A6 s
  812.           write(txBuffer, txLength);
    - Z) _; f6 k$ b7 w4 W
  813.         }) u- D0 `- L. K! w# h. H. j; G
  814.       }0 K! v: V1 e3 G0 c9 i

  815. 4 {  C5 ?! `+ f. |3 Q" j
  816.       break;
    / C( T& w2 L- J5 o
  817.     }
    7 @' }3 s( s5 P+ W& i4 L1 k

  818. ! f/ l5 A" d5 x( r  F
  819.     case CodeStx:
    * m  M! }1 A( h! T% g; x
  820.     {
    " S) R: q% v- d: M
  821.       uint16_t crc = ((uint16_t)(rxBuffer[YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - 2]) << 8) |
    . F4 b! m4 R. J- W" c0 ]
  822.                      ((uint16_t)(rxBuffer[YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - 1]) << 0);# s. t- h  ~! r- `* d
  823. 5 D) T4 w& {1 ^5 J7 X( h
  824.       if((rxBuffer[1] == (uint8_t)(dataCount)) && (rxBuffer[2] == (uint8_t)(0xFF - dataCount)) &&# H, a3 y" |) n/ v1 N. ~
  825.          (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_1K_SIZE)))8 e' b6 }0 K. x9 r" U8 |
  826.       {
    * i5 x( e: F; T1 H! @! x/ K2 J
  827.         errorCount++;
    $ s( a. A1 }, j- N" v( Q' w" K: n- s

  828. % D* e& G/ J0 f6 M3 q. t. C0 l
  829.         if(errorCount > errorMax)
    9 H8 [* Y: [) e1 T
  830.         {
    % Q7 j3 _+ h; l* Q6 ?; `1 q
  831.           timeCount  = 0;
      Z( |' [+ `) v
  832.           errorCount = 0;" ?: o+ T2 s/ {; }: R
  833.           dataCount  = 0;; t4 k( b2 `, k& y& G/ I; o
  834.           code       = CodeNone;
    * B4 n) K& Z4 x3 |" W  `, ?
  835.           stage      = StageNone;4 r9 i4 z1 f# a' C4 \
  836. : i0 ~$ r1 Q5 p. V1 `. E5 q
  837.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)8 W  C; p3 j: Y; \  |3 H
  838.           {0 v. R6 v) K/ Q( y1 s' P
  839.             txBuffer[txLength] = CodeCan;
    5 t5 R4 ?/ ~1 s" ~
  840.           }# G* h* u) u& X6 E  {/ v! z

  841. 7 c' h& D9 i1 T& ?% m- l1 F6 @
  842.           write(txBuffer, txLength);
    + B" |# F+ G( r4 i/ K2 P
  843.           callback(StatusError, NULL, NULL);
    - U8 t- A+ c& Q. @0 ^7 K
  844.         }
    5 Z9 [# ?6 u% |, R6 L4 p8 }
  845.         else
    & M$ V0 X7 t0 {# J- L
  846.         {& Y& v; Y- N% o! w! j; n" w
  847.           txBuffer[0] = CodeAck;0 }# |) B$ n$ i: S8 r" C- W7 o
  848.           txLength    = 1;: s/ C4 U( t% O* A4 I. O
  849.           write(txBuffer, txLength);! f- J( D6 C1 h! n7 J, b6 v7 _
  850.         }/ ^7 M5 J: e: ]0 F7 q
  851.       }/ V3 K# I5 _' I5 R! U6 O* }6 Z
  852.       else if((rxBuffer[1] == (uint8_t)(dataCount + 1)) && (rxBuffer[2] == (uint8_t)(0xFE - dataCount)) &&
      ^$ d  l4 A% G0 ^  z
  853.               (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_1K_SIZE))), I- M& M% R4 X* R+ L1 }
  854.       {7 u7 C% j" q: p6 k$ f; h% ?
  855.         uint32_t dataLength = YMODEM_PACKET_1K_SIZE;9 W2 m/ C; h! n
  856. * r. M) d' r+ A3 Q' _
  857.         if(callback(StatusTransmit, &(rxBuffer[YMODEM_PACKET_HEADER]), &dataLength) == CodeAck)+ Q4 t" t2 _& [. Y8 I$ s& U3 e
  858.         {
    5 ^- X. K: t, u/ p  g# d
  859.           timeCount   = 0;# {4 [8 E$ \3 f1 I
  860.           errorCount  = 0;% M+ x4 g) w4 ]6 G
  861.           dataCount   = dataCount + 1;- A) M0 d; r  Y) v( Z
  862.           code        = CodeNone;
    2 X- ^6 `. a. J9 u. R- ]
  863.           stage       = StageTransmitting;0 `; F, j- l! l8 e8 h. Y( @! Z. z( U
  864.           txBuffer[0] = CodeAck;3 T% B8 Z1 s/ O, O5 ~
  865.           txLength    = 1;8 H3 A4 x4 k4 H% M+ P1 p+ O+ {
  866.           write(txBuffer, txLength);5 b7 U5 g4 L4 ?
  867.         }
    6 f# j* v8 |8 K' }/ z/ f4 W7 W' U
  868.         else
    8 o) Y2 v7 V( _8 C" N1 U
  869.         {
    9 }( l. s: I1 @8 C
  870.           timeCount  = 0;4 v% k& z2 N( m* z, o$ U/ I
  871.           errorCount = 0;6 Y; U# y. Q5 I1 y% G! Z
  872.           dataCount  = 0;
    ' l1 ~. q6 n4 p
  873.           code       = CodeNone;3 d2 Q* U& W5 T
  874.           stage      = StageNone;
    , O, K  d2 s4 U) |
  875. 0 A* T6 n4 x; m9 C
  876.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    4 Z  K3 y  |* f' K; p
  877.           {6 W9 J; y& G0 j8 U6 Q
  878.             txBuffer[txLength] = CodeCan;* M1 `6 G; {* h4 f
  879.           }* Y* [+ e, j5 _5 n4 H% _: C; h

  880. 7 z  J' q" }7 W. _$ [1 V. X
  881.           write(txBuffer, txLength);
    1 L2 I: [' Z1 j
  882.         }; `$ [; v4 C$ W  U% H# G) @
  883.       }
    4 o8 j% M# T& T, d& N7 O) l" h
  884.       else+ q$ v: B. ~* x/ \5 J& k1 O( Z
  885.       {
    " F) o# ^# y1 ?1 V$ u* z
  886.         errorCount++;
    % ?1 U* o4 u* ], Y0 j% c3 o, b5 N5 L. w

  887. " w& _9 I2 s  O) n# Q3 H: g
  888.         if(errorCount > errorMax)) Y/ \1 K. |$ F' I/ X
  889.         {
    , \4 M% E) @4 x" |& D7 j' w
  890.           timeCount  = 0;. ^+ [' B1 n" C6 \5 C
  891.           errorCount = 0;
    ( x5 k3 K9 c6 _3 _! \
  892.           dataCount  = 0;
    - x2 _# ]* C+ ^( ?/ r
  893.           code       = CodeNone;) I4 E/ G$ |7 i) J2 m% z- f
  894.           stage      = StageNone;+ W- M5 {  p/ Q# o  N; b2 X# a0 [
  895. 1 O; n- y' \  a" |4 w" {
  896.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)8 @' W8 T# ]/ Y* {& ^+ w3 h
  897.           {
    5 P; a' Z) u8 N- Z
  898.             txBuffer[txLength] = CodeCan;# N5 p" W$ [- y' }0 ^8 N3 y, E
  899.           }
    ; K- t9 Z7 |/ {# ~
  900. ( e- v6 l4 T8 n
  901.           write(txBuffer, txLength);
    0 b# G6 w& s8 y8 a5 `% @' g3 O
  902.           callback(StatusError, NULL, NULL);
    2 F( ~5 m$ z9 b% O" F
  903.         }
    9 A, r* l2 e- A' `3 m; R
  904.         else
    ! `6 f0 P6 ^$ d6 q  P5 \7 Q( ]
  905.         {
    / ?- R; X' M; l' }. Z
  906.           txBuffer[0] = CodeNak;2 Y6 }' o& L) z+ R8 L* V1 Y
  907.           txLength    = 1;
    , L3 R4 Y( g1 u; c
  908.           write(txBuffer, txLength);
      @2 M0 H4 m! }7 _+ I% i
  909.         }' u7 P) {: Q, n
  910.       }
    9 e; U8 P7 |* D/ i1 U3 ?! G
  911. 2 q2 M# T" e' w# u9 D
  912.       break;
    / V1 k1 y% i* L& G1 h+ q% [
  913.     }5 O# j9 m; N% _3 K: s/ I8 t. A/ C
  914. 1 V: Z2 `/ ]8 Y$ v5 e; v: g
  915.     case CodeEot:
    $ p0 H* _8 j# ~! e* e$ m
  916.     {
    8 H3 o' {; n( h/ u
  917.       timeCount   = 0;
    & f  E2 g6 z+ F
  918.       errorCount  = 0;" q' g3 \! ]8 R
  919.       dataCount   = 0;
    2 A* y% J; @/ c+ D% V
  920.       code        = CodeNone;
    $ X/ c& l0 F% M' B" i
  921.       stage       = StageFinishing;
    1 b1 j! P/ P$ }2 I8 l" y+ k& o/ V
  922.       txBuffer[0] = CodeNak;3 P1 s% O. p! G% H8 I0 e; H
  923.       txLength    = 1;
    7 x1 Q- C4 i5 X1 C! {$ R
  924.       write(txBuffer, txLength);
    ) ?. F+ j. e  {- k# v
  925. 7 P6 j# C) q* h, _. i' R2 g
  926.       break;# u" {' l, M8 }* L
  927.     }
    ' k' r# Q6 o/ F& V0 k/ `; G: E: ^

  928. ) `; j  c' w$ D( ?( [/ C! ]
  929.     case CodeA1:6 J0 n, ]$ }5 a: E0 ]
  930.     case CodeA2:5 r0 E' Y, R2 J$ H
  931.     case CodeCan:
    & x; ~3 p( I6 Z4 L' k  Q
  932.     {
    2 f. B: Q" O* X9 R
  933.       timeCount  = 0;
    4 b2 f  z% n9 h
  934.       errorCount = 0;" T! Z$ K! Z& C" b4 l: A( p
  935.       dataCount  = 0;
    6 C6 [4 d( `7 T& W% L& d& O
  936.       code       = CodeNone;" t7 B: {; j9 B6 e% B: N
  937.       stage      = StageNone;
    6 a: X3 E, M# t+ a: q  l2 d* N
  938.       callback(StatusAbort, NULL, NULL);
    ( P9 d2 v; H. H1 @5 ^( w0 z- V- q. F
  939. & G. Z% O9 m0 [& T/ o
  940.       break;
    " \  e& w! k6 v. I7 p# [4 `) }$ c
  941.     }0 q3 k* C. a* v1 M2 Y; a1 k* u
  942. + k* t8 j4 H6 ~
  943.     default:
    , ?* }- P+ M- u0 V$ r: A
  944.     {2 e7 U9 O( E" Y. R
  945.       timeCount++;4 U# z) E- m* A9 `; |5 T- x( J
  946. 3 p* S1 ^" C6 S$ B2 K$ L& H; @$ @4 q
  947.       if((timeCount / (timeDivide + 1)) > timeMax)4 ?- X8 [1 J  p; t
  948.       {% m0 }4 I" h% ]+ g; w. D
  949.         timeCount  = 0;2 S( N% \" M7 n
  950.         errorCount = 0;
    , U% _$ {$ q6 l
  951.         dataCount  = 0;
    0 D( p# L* y3 J) b, u
  952.         code       = CodeNone;
    . j. w1 v+ k* n; A( I8 D0 k# h
  953.         stage      = StageNone;
    & d* w$ X1 E2 }* ?; `4 ~

  954. ' _* K* D: d9 B" r
  955.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++), Q( J3 a2 _4 z& l, t# n
  956.         {
    % W$ s3 g3 U4 }3 g
  957.           txBuffer[txLength] = CodeCan;' ?1 N9 m! ?! w3 A
  958.         }
    . z9 D9 @' t( m: y
  959. 3 t9 H* x; ?, a
  960.         write(txBuffer, txLength);
    ! t7 e7 f2 O: U' @* ^  I
  961.         callback(StatusError, NULL, NULL);
    # \% H+ K2 v6 K; j8 ?/ ]6 _3 I' s
  962.       }+ D! Z+ P3 ^. r) G; ~, ?
  963.       else if((timeCount % (timeDivide + 1)) == 0)
    ' V% L( t0 M4 ?
  964.       {
    % v5 t3 M  p* I, I0 Q' E; R
  965.         txBuffer[0] = CodeNak;) {3 a4 ^1 X. t% Q$ C% E- Y
  966.         txLength    = 1;
      g2 B: @1 a3 X
  967.         write(txBuffer, txLength);2 o/ y) Z- n( V) Q, \2 g4 |
  968.       }
    4 C5 [. P/ ^; q4 L
  969.     }
    - N' `9 s' E% X2 ?- z
  970.   }/ Q8 c+ H1 p9 _% c& `
  971. }
    6 O2 G, V, o$ c) ]+ _
  972. & O4 m5 g3 k2 z% \, f: i+ ]; S' j  b6 C
  973. /**7 x5 N! r; ?: W% W+ M
  974.   * @brief  Receive finishing stage.
    ; O3 W" }0 H! Q+ F- Z& n
  975.   * @param  None.) a4 J7 c7 k) B0 j
  976.   * @return None.
    9 z4 ~$ ^8 b& L  g. q8 r& f" k
  977.   */1 f" g7 q% V4 _6 q5 Z
  978. void Ymodem::receiveStageFinishing()
    - a. D2 T! N8 Y8 Z8 f1 _6 ]4 \2 B4 [
  979. {
    0 `0 V- A) ?8 c" N9 b, B3 }
  980.   switch(receivePacket())0 T% e" {  [  G
  981.   {+ X6 \& d1 ]1 s( D4 k
  982.     case CodeEot:6 R. W- ~4 |6 D+ T3 c* r& |6 d/ \
  983.     {
    : T2 }9 N; j0 p$ R& N0 _
  984.       timeCount   = 0;  ^) C, d" r! q! K: z0 D1 y2 y
  985.       errorCount  = 0;9 Z$ N$ ^( `/ X% B% d/ Y7 z. Y
  986.       dataCount   = 0;! R7 v8 C4 }0 i- V1 d& C2 v8 x
  987.       code        = CodeNone;
    ; ^9 J: m" E* N+ T( P$ l( a
  988.       stage       = StageFinished;
    7 r& i- z% ~; K7 s1 O+ P0 ^
  989.       txBuffer[0] = CodeAck;
    - d, V2 y% }# o
  990.       txBuffer[1] = CodeC;7 a, _8 t7 f9 a/ i0 R
  991.       txLength    = 2;
    ' m5 R1 ?& r+ s* t
  992.       write(txBuffer, txLength);
    4 C& P7 W$ U2 Z* }1 f* d2 H

  993. ; s8 K9 A8 |" g
  994.       break;3 p* j! Z* }. {/ H0 A) ]5 s2 I
  995.     }$ }" y2 O; k# e  a

  996. $ _% L  r' n5 @* B' }
  997.     case CodeA1:
    ' C8 X9 W8 V6 C  P, ^* ~6 I/ ]- u
  998.     case CodeA2:, T% r) x) d9 W
  999.     case CodeCan:. ^2 ?" m6 K4 |" W
  1000.     {
    / r. I  g3 y3 n4 O0 ~, e
  1001.       timeCount  = 0;
    & N5 _  b; k6 U* ~" ]  W
  1002.       errorCount = 0;
    ; r7 I& }; u4 S8 E6 h6 W
  1003.       dataCount  = 0;
    8 {& Z/ x# k- J7 Q% ]0 x# T
  1004.       code       = CodeNone;
    ! ?3 G7 X9 H# _" y
  1005.       stage      = StageNone;& ~) B% i/ F1 {% f, E, a- k* y
  1006.       callback(StatusAbort, NULL, NULL);
    2 ?& T) N9 T. h& b+ v1 A" o1 [$ A
  1007. ! O# d! ]  D5 D! c& O$ O8 }
  1008.       break;( g" G8 K% @9 S
  1009.     }5 C! U9 {6 T3 \% b7 |: p

  1010. 1 h  a2 y8 M- S
  1011.     default:
    ! x5 K3 a+ g2 W% C7 f4 J3 n3 z4 m: Y6 ?
  1012.     {- j- K& s$ L. ?
  1013.       timeCount++;
    $ m" k/ N5 X( @# a. z! V( x
  1014. " T3 B" S8 \5 i9 w
  1015.       if((timeCount / (timeDivide + 1)) > timeMax)
    2 h+ k, ]+ D( ?+ ]& e9 X
  1016.       {) ?) C5 O& |+ ?, s/ N4 E4 y3 A% g
  1017.         timeCount  = 0;
    0 J8 g1 p7 |5 F" Y# J1 ?- I
  1018.         errorCount = 0;2 z& Q# Q. C8 \* G
  1019.         dataCount  = 0;* H3 t) e( _9 u9 ]! s2 S
  1020.         code       = CodeNone;2 B2 F' y- m4 P) @  ]- D
  1021.         stage      = StageNone;) I+ l" o8 p3 i" z- ^

  1022. 0 _5 A7 }; u+ s0 w; ^
  1023.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)  M* b# p# m( k/ ?- K
  1024.         {: ~: |0 x, j8 r' ?
  1025.           txBuffer[txLength] = CodeCan;
    6 |  o# P: a' R9 o- L8 N3 W( K( M
  1026.         }3 x1 j* P, h2 z' d' X4 I
  1027. " P8 x5 }# e9 r
  1028.         write(txBuffer, txLength);; a, d$ T( `) A0 k: D9 C4 p, g. i
  1029.         callback(StatusError, NULL, NULL);! m0 k+ p% F# k4 I& D/ O9 u0 e$ v
  1030.       }; w- A; _& ~8 S2 [. d7 S
  1031.       else if((timeCount % (timeDivide + 1)) == 0)7 I) X: J4 \; R7 w- e* c. M0 g
  1032.       {8 l# R4 u5 ~0 v
  1033.         txBuffer[0] = CodeNak;
    - l7 a$ U3 }- y
  1034.         txLength    = 1;8 k( n  p" m5 U( v6 \1 `# f
  1035.         write(txBuffer, txLength);/ z. A2 {  a2 L! R$ N
  1036.       }: L+ E7 v% G7 v! }! L: M5 N
  1037.     }
    / {$ A+ @. U2 i, J4 p
  1038.   }5 y8 y8 [& @) l
  1039. }
      Z) g9 `; W+ k) ~2 N
  1040. . ?. [$ \2 Y$ o; v* R
  1041. /**; [2 O+ j. C- |, K; m( x% N, L
  1042.   * @brief  Receive finished stage.
    # v6 M, ~" w. D+ {
  1043.   * @param  None.( a+ P) z& A* H( t7 }+ c
  1044.   * @return None.9 P4 A# M4 {. O6 ?+ z. ~
  1045.   *// b5 L5 [# R  W) p% c, {
  1046. void Ymodem::receiveStageFinished()+ J9 |" p) p7 f% Z3 R, P
  1047. {
    1 n% i- K5 t6 Z" y; q* j2 \1 i
  1048.   switch(receivePacket())
    0 q5 k5 G4 f5 V9 \. U  ~1 v
  1049.   {" I0 U- z" C4 O/ V' b: w( p6 A
  1050.     case CodeSoh:8 v7 c: R# R3 c$ L" p8 {2 F. ~
  1051.     {
    + |( O0 F1 Q( z3 `  {. a/ B. T
  1052.       uint16_t crc = ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 2]) << 8) |3 h; t9 Z' A7 A( R7 B% E9 [
  1053.                      ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 1]) << 0);
    4 g# u$ L+ [' o6 Q& `5 o

  1054. " _" D* C# z' g! i. H: L
  1055.       if((rxBuffer[1] == 0x00) && (rxBuffer[2] == 0xFF) &&9 i9 {3 R3 H) B9 ]+ m2 c; g
  1056.          (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_SIZE)))% n) y1 f; Y5 [8 j! e
  1057.       {" n% a: o, Q& X+ F$ g2 D4 i7 K: Z3 r
  1058.         timeCount   = 0;5 e( n7 }  S+ {6 L
  1059.         errorCount  = 0;! I* i8 ]! `( |2 m  x. j
  1060.         dataCount   = 0;
    7 f% p% k+ i) \
  1061.         code        = CodeNone;
    & n' n* T6 H; W, s
  1062.         stage       = StageNone;
    * W$ w1 g: F) n# k
  1063.         txBuffer[0] = CodeAck;3 k/ S& P0 E' V2 }) ]- b7 b
  1064.         txLength    = 1;
      {% W. E, _5 {7 ?! W
  1065.         write(txBuffer, txLength);" |9 r/ }: `4 c* P* k
  1066.         callback(StatusFinish, NULL, NULL);
    ) ~) I* S" D0 N; G, @  h
  1067.       }
    4 \# b0 v( z: W$ t" T" x
  1068.       else5 a( c+ C. K+ l7 y
  1069.       {
    8 T/ E6 _3 C+ v, `/ E% W# j9 @
  1070.         errorCount++;
    7 E; s  ~  P0 ?% k4 g

  1071. ! K# }7 t5 \0 K- e3 n" R
  1072.         if(errorCount > errorMax)
    ; k3 G( \4 L6 }
  1073.         {( \$ Y8 C0 c5 B; y' [' W6 o
  1074.           timeCount  = 0;
    3 T0 f1 Q- j4 {- Y9 ~4 p
  1075.           errorCount = 0;
    % L' q7 D# `$ N0 B; G& p
  1076.           dataCount  = 0;
    0 k6 s3 `7 t: t/ u: A
  1077.           code       = CodeNone;
    & B( J: S/ o2 e4 k. r
  1078.           stage      = StageNone;
    % Z5 B3 C" V" d& x5 o( h" c
  1079. 4 c0 V" j2 x) q! p  ~, S
  1080.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    1 C" U- `% v4 m0 F% E+ o
  1081.           {
    + u, _) _. J  h& w5 R, I3 \+ z8 g
  1082.             txBuffer[txLength] = CodeCan;
    5 B  s, t, f$ Q; `* v
  1083.           }& ]' W% k0 a6 m* @6 K2 m, n6 P

  1084. % S8 z: _3 x7 B2 d! E$ d
  1085.           write(txBuffer, txLength);/ o- [  {$ N, H0 W8 Y7 N
  1086.           callback(StatusError, NULL, NULL);
    2 {0 i& X& v( H2 u
  1087.         }6 c8 d( o5 T' |+ q2 N1 @5 L0 q/ ^- J
  1088.         else9 P9 O  i: B! r3 I6 P/ o0 u  b/ f$ U
  1089.         {
    6 K5 X. Y6 c8 d, T
  1090.           txBuffer[0] = CodeNak;
    * @5 k5 p" l0 j5 R. _
  1091.           txLength    = 1;" }* l5 k8 j" ?; j- C
  1092.           write(txBuffer, txLength);- T8 g& e" K7 I
  1093.         }
    ) y- k6 F+ s& i& g; v6 i9 i
  1094.       }# v% J, U3 z" M8 Q6 V/ M
  1095. , [7 z5 s+ N- H* K' ^/ [, W
  1096.       break;# s2 o) R$ A( n7 p% {+ N$ _4 D  F! U
  1097.     }% O! P5 m2 h# r# ~% X. `
  1098. 9 B8 `% \2 C5 J- E) T) ?4 ?
  1099.     case CodeEot:& `: d1 t. U: o$ a) h6 ~8 g6 e: V
  1100.     {
    8 n. o/ R0 B7 g% Y! a) P( C: w9 p
  1101.       errorCount++;) ~4 D4 {: X- ^7 M0 _

  1102. ) B" n$ D- f- X4 g7 _  Z) U& Z/ a* p
  1103.       if(errorCount > errorMax)
    # X+ X4 K1 y( P7 \! ~$ f( D
  1104.       {
    ( w% o0 w6 C- P0 o, q
  1105.         timeCount  = 0;4 ?2 M3 d* N. u
  1106.         errorCount = 0;9 D1 v5 t" c: t, {
  1107.         dataCount  = 0;+ ^" I: c1 ?+ s
  1108.         code       = CodeNone;  y. l- K' ^5 h8 A
  1109.         stage      = StageNone;9 _: |: O6 T2 m/ z  `+ R0 n+ {0 K

  1110. 9 I' \6 q) `! i5 G! T  V7 n
  1111.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    - t6 }5 s4 t+ Z2 ?2 \0 o
  1112.         {
    8 y. E3 w1 {3 ]" D* K" R- u$ e
  1113.           txBuffer[txLength] = CodeCan;
      J0 D3 q1 A0 F1 K0 f& V
  1114.         }" {7 S" K( ^! c$ h& ^+ m1 W
  1115. ( O$ R/ E# Z; Q5 J9 u
  1116.         write(txBuffer, txLength);
    : I0 W6 M+ e% a
  1117.         callback(StatusError, NULL, NULL);2 c7 Y+ S1 `: m  h
  1118.       }, R5 _8 X  i7 s2 v/ ~/ O) {6 {
  1119.       else8 [! S0 t$ X  P! h# K
  1120.       {
    " q; v. ~+ b4 h( S7 h& U+ V/ O7 @3 A
  1121.         txBuffer[0] = CodeAck;. J6 x, D" j$ c: O& J2 x, a
  1122.         txBuffer[1] = CodeC;
    ) Z- p: G. d" K, ~( _% t9 s3 c
  1123.         txLength    = 2;, |% B3 |3 Q$ F2 t/ L4 h
  1124.         write(txBuffer, txLength);
    / j1 p# c9 e- M! r' m% [
  1125.       }- w- G2 {! a% S) _1 m
  1126. 7 @4 q8 _  v* K$ `4 v2 s
  1127.       break;
    ; h1 e7 f: |5 t% f' v- z
  1128.     }7 x( ^3 T4 u! h7 r  {* e; }5 D3 m
  1129. ' G6 n; X6 Z( q
  1130.     case CodeA1:
    . g2 h. ~0 I- z# x1 ]
  1131.     case CodeA2:
    ; }6 f! a6 m# j
  1132.     case CodeCan:3 \2 T0 }9 [8 d8 S  c" C. e* F
  1133.     {
    , f. F" a4 o- X% ]$ b$ E
  1134.       timeCount  = 0;2 I3 A. g5 V; T% x) v2 @
  1135.       errorCount = 0;
    / j' q3 t: J1 c/ j- @& K3 n% S+ n4 L
  1136.       dataCount  = 0;
    4 ~1 h/ F" N* C0 e
  1137.       code       = CodeNone;
    3 c8 l4 F* r7 N. [9 n' q! N
  1138.       stage      = StageNone;: k* |& `- _: t( V
  1139.       callback(StatusAbort, NULL, NULL);
    , s- H. r3 u' y6 }  y* i

  1140. ' q$ N$ U3 l% x9 J2 Y  _1 b
  1141.       break;
    2 m- j0 F0 Z% C8 ]  u* {+ K
  1142.     }
    8 T* T2 _' F$ ^7 v
  1143. 2 k$ R( `& w. a& Y- e9 H+ f8 h
  1144.     default:
    / V: o: r& N* ]; ?8 f( v
  1145.     {: G) j+ P; ?3 l- y4 a6 S
  1146.       timeCount++;; h9 P7 Y8 q9 h2 p

  1147. & d8 \* ]! W; |' ]% h
  1148.       if((timeCount / (timeDivide + 1)) > timeMax)4 e9 ^5 T$ M. I3 A+ O9 `0 D
  1149.       {
    7 Z* ]8 T. Y6 }6 [
  1150.         timeCount  = 0;: z, b9 C' c; V# I/ D
  1151.         errorCount = 0;
    , H0 I& p* W" J, c: F
  1152.         dataCount  = 0;
    : v1 `3 B+ h; ?" U; P/ M
  1153.         code       = CodeNone;
    % A  k; c  A% k8 r  D
  1154.         stage      = StageNone;; ?% Z3 {: E6 w4 b: ]7 a
  1155. $ Q7 a* M7 v, ~% ?3 I
  1156.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)+ m, o- }, G+ v/ W) U
  1157.         {2 d# h# ?6 G& Q0 y, E  w
  1158.           txBuffer[txLength] = CodeCan;
    ; x5 f3 G, W1 J7 N9 \) J
  1159.         }
    ) e2 T# C' [6 g6 Y# Q$ P+ ^

  1160. , L' ?( z# f* i* v
  1161.         write(txBuffer, txLength);
    9 k( U# F) N7 C+ D0 l5 G: y9 G2 n
  1162.         callback(StatusError, NULL, NULL);
    5 u/ j+ P: w7 X# p
  1163.       }9 [; V! G! }9 N$ }0 L$ n9 Y; o
  1164.       else if((timeCount % (timeDivide + 1)) == 0)
    / p: t# q* B, q2 _) I
  1165.       {
    & S) R1 V9 q+ Z7 I# a! u( ]
  1166.         txBuffer[0] = CodeNak;
    # G/ G/ l) c+ f1 G! L# I' F
  1167.         txLength    = 1;) w8 ~; K) p+ P0 O  y
  1168.         write(txBuffer, txLength);
    + j; r) |7 I9 N
  1169.       }
    4 m( G8 L1 ^3 l1 L. m- c" X
  1170.     }
    + i5 k; d$ j8 z7 t8 u
  1171.   }* d' u% N4 Z% ~* Z6 {
  1172. }
    $ [+ l: D# n1 Y0 J* Y

  1173. 7 l2 {4 A3 Q3 P3 n7 k+ {# ^
  1174. /**9 ^4 k. F7 H3 f, Z  K
  1175.   * @brief  Transmit none stage.( p1 d5 a3 d3 G. t; e: c
  1176.   * @param  None.8 Q9 U2 u) j0 F
  1177.   * @return None.. S& w& K: F; k' E
  1178.   */. r- J/ {0 N7 ~8 @: I/ Y
  1179. void Ymodem::transmitStageNone()
    ( K; I4 V% \  y9 ?3 j
  1180. {
      S! J2 l1 b5 G; c% p+ [
  1181.   timeCount   = 0;) T! ^, F/ O1 i8 V, Q
  1182.   errorCount  = 0;
    * F- |6 h2 l  [& ]( H  D" r. d
  1183.   dataCount   = 0;7 d4 g9 v4 J  d; V2 K  {9 c, \* x
  1184.   code        = CodeNone;
    , P$ a% t- Y! J* g/ m' Q8 l
  1185.   stage       = StageEstablishing;. r8 x1 D: _/ C5 t+ D
  1186. }6 H* Z4 b% u6 |7 L: v
  1187. ; b' ?3 U( O! z9 @- S
  1188. /**8 I3 D- }' J* l; w
  1189.   * @brief  Transmit establishing stage./ E$ L) F4 J/ X# R: S
  1190.   * @param  None.
    . S: e9 q3 \: ?. t
  1191.   * @return None.% P- R9 _4 o9 o- ^: q7 {
  1192.   */
    ) C, l- c. y  f. i! U) `
  1193. void Ymodem::transmitStageEstablishing()/ @3 D, ~' m9 \( a: S
  1194. {$ C7 n) A  b4 ?- t
  1195.   switch(receivePacket())
    ( d% V( A% g; i( ^% C8 e
  1196.   {
    & y% O7 F+ P4 [, g! U
  1197.     case CodeC:0 o  U  F( w: t
  1198.     {
    4 z  L2 _! Y7 k! L* x) \
  1199.       memset(&(txBuffer[YMODEM_PACKET_HEADER]), NULL, YMODEM_PACKET_SIZE);" v3 ?& S' H' c- M! \
  1200. - d* `3 x% H2 w% J
  1201.       if(callback(StatusEstablish, &(txBuffer[YMODEM_PACKET_HEADER]), &(txLength)) == CodeAck)7 V1 D5 c  G: \
  1202.       {3 `; p% |* A8 s- }7 X. y. i
  1203.         uint16_t crc = crc16(&(txBuffer[YMODEM_PACKET_HEADER]), txLength);
    / _5 ^& b6 N" I+ ?* N+ C* T, l
  1204. ' ?& H, A! f2 J
  1205.         timeCount                                       = 0;# ?9 K' _- p( e- E0 f) C5 L
  1206.         errorCount                                      = 0;# B. `9 t0 O: w7 f
  1207.         dataCount                                       = 0;
    " w- V" p3 ~0 F. _. G# b
  1208.         code                                            = CodeNone;4 [1 u. ?. g1 D' J
  1209.         stage                                           = StageEstablished;: Z( ]1 d: C) X3 p! K
  1210.         txBuffer[0]                                     = CodeSoh;8 _6 r1 e$ k, r8 v- s6 z( @
  1211.         txBuffer[1]                                     = 0x00;
    . O( ]) ^6 l1 E9 [; x3 M9 U
  1212.         txBuffer[2]                                     = 0xFF;- P8 r; p* ?1 V3 ^7 J0 U
  1213.         txBuffer[txLength + YMODEM_PACKET_OVERHEAD - 2] = (uint8_t)(crc >> 8);2 w. u; k) g4 i0 I, b( F2 V
  1214.         txBuffer[txLength + YMODEM_PACKET_OVERHEAD - 1] = (uint8_t)(crc >> 0);
    ) x! H7 i* V! U$ T( D) s3 S  `
  1215.         txLength                                        = txLength + YMODEM_PACKET_OVERHEAD;
    / H  R4 r/ r* P4 \9 W3 L3 F" M3 F
  1216.         write(txBuffer, txLength);" d9 v/ E# B4 o4 j2 S# P
  1217.       }1 W6 ]# ]7 i/ F5 }5 v
  1218.       else
    9 A7 B+ o* Y2 Y, V4 H" }- n, |. r
  1219.       {
    ( b; P' G( V0 J9 d1 m- ^
  1220.         timeCount  = 0;
    ( @6 E7 h* s0 \2 T4 }+ w5 p
  1221.         errorCount = 0;- H( I; s- F/ y
  1222.         dataCount  = 0;
    9 E- }3 F8 t7 W9 @- C7 v! N
  1223.         code       = CodeNone;$ \  M1 ~) _$ s, J! e0 T
  1224.         stage      = StageNone;) g1 o7 l$ J7 B3 t1 p2 f9 p

  1225. + G. ^3 K5 _3 \: \
  1226.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)  X, V% o! X: c
  1227.         {
    : g7 |9 [+ e0 {; Z1 {& |8 L
  1228.           txBuffer[txLength] = CodeCan;3 K: X" P3 i* @$ y# w4 S9 Y$ V' \5 ]
  1229.         }
    9 ]; U) S! a1 z2 H
  1230. + z0 Z2 _3 X( M2 v
  1231.         write(txBuffer, txLength);
    ( A6 M6 ]1 n+ [8 Y! _
  1232.       }
    1 p/ |( @* s/ `0 H# _3 v9 [

  1233. . R  [' h3 w3 J- I3 [7 v* n8 E; p
  1234.       break;# @$ J, w) E' o9 X, I5 L; K
  1235.     }: z, D: a* j/ R) ]
  1236. 4 C* `/ D$ ?2 @% U' m
  1237.     case CodeA1:
    ! q0 Q/ ~. _1 l/ s/ c7 Y* ~
  1238.     case CodeA2:
    8 v& H" u" e8 d, b$ D+ H' r2 F
  1239.     case CodeCan:
    ' k! m3 g) h0 q) q  s6 _' K3 z/ ^
  1240.     {
    8 d3 ^! C3 c" @$ l1 R- q7 X& A
  1241.       timeCount  = 0;
    3 v) X, a' @3 D+ m# K
  1242.       errorCount = 0;7 @+ C7 Z& e% r0 c9 u0 s
  1243.       dataCount  = 0;
    , C* }7 d- b; o) `# U
  1244.       code       = CodeNone;3 ~/ f  Y% Y5 |. W7 o9 ~( r# q: u
  1245.       stage      = StageNone;
    * _  |# n# r( w" g
  1246.       callback(StatusAbort, NULL, NULL);
    , }6 Q* E7 i  C# O' ^- a. R

  1247. + m! g8 E" J1 Q+ R. y: e
  1248.       break;
    ; h. t6 s6 z$ ~$ Y6 ~
  1249.     }  X) }+ {# ~# k' Q+ U. Z

  1250. ! a& G( v2 y: {2 p1 J2 ~3 c5 v
  1251.     default:
    $ N9 ]  N$ i* r& g0 m
  1252.     {
    # t' i0 J. s5 i7 A4 P) y& X/ y4 V
  1253.       timeCount++;
    * _2 R/ E4 G; A) J
  1254. % C. z; I( k0 G9 L+ Q  X& C" t
  1255.       if((timeCount / (timeDivide + 1)) > timeMax)
    ) T# D) f+ p4 F9 r) T4 d0 L0 `
  1256.       {
    $ m% M. \0 M7 `
  1257.         timeCount  = 0;6 w7 l( |$ z6 z3 @. }
  1258.         errorCount = 0;
      ~3 T) k2 H# _! M
  1259.         dataCount  = 0;
    % k3 Q! M' E6 E
  1260.         code       = CodeNone;
    7 J! I! y! |. p5 L2 L' X  \
  1261.         stage      = StageNone;( ~! d  ~) V8 V* X

  1262. 2 b; U2 Z4 @3 E# S* d
  1263.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    2 e# W8 [/ H' _- y. D) x# ~
  1264.         {
      Y2 F- s9 d% c& e7 e
  1265.           txBuffer[txLength] = CodeCan;
    3 p1 f7 Y& G2 w2 b
  1266.         }' K+ g9 B( H) R, a9 G4 \: a. @* t! A8 ]

  1267. 0 T$ u, {/ i) B( s4 {. C$ Z
  1268.         write(txBuffer, txLength);. ~! X1 T9 j& i% N8 ?! Q
  1269.         callback(StatusTimeout, NULL, NULL);. L, O5 {3 q! [4 C) e
  1270.       }
      l& E7 t1 k$ r+ n% n' L
  1271.     }
    6 S% J- o! P" \2 g$ a! ?7 Z
  1272.   }
    8 P' N7 i- K" y& }7 Y
  1273. }
    # D/ T3 ~6 u. B& s, M0 [3 y

  1274. 3 w" w9 H& q) B+ L: O8 C5 X
  1275. /**
    : B" m4 p+ w2 O! r1 k7 m
  1276.   * @brief  Transmit established stage.( p% q  E! e$ m, h: \+ L; L
  1277.   * @param  None.
    ) _& T  L8 ?2 u) R1 P- J
  1278.   * @return None.
    ! ^/ u4 l" E* J1 i  h# Q
  1279.   */
    ! }1 ~: F: g/ F& y2 F9 n3 H
  1280. void Ymodem::transmitStageEstablished()
    ( a+ K: l& `+ v( _" ?  F! ~
  1281. {6 M- H& ?" F! e% P5 t) ?% W
  1282.   switch(receivePacket())
    ) i7 U# Y/ C& o9 c0 e* Z
  1283.   {
    4 X! b6 Y6 `5 j: N5 L7 S
  1284.     case CodeNak:
    ; J  e7 f7 U9 ^+ Z: W1 Q  h7 m
  1285.     {
    6 C7 C: l* d8 h; L
  1286.       errorCount++;5 J. N8 Y4 ^$ l- \

  1287. % c0 L% K2 r8 n& L6 i& V# L- t
  1288.       if(errorCount > errorMax)
    ( R8 }& m# B% b& D6 s" j
  1289.       {" e9 D, {' D8 G6 ?1 P% h* {% |
  1290.         timeCount  = 0;
    ; j; t8 h" {+ l* w
  1291.         errorCount = 0;
    ) _$ g: Y* V9 M9 }0 D4 z+ \# K+ @6 a
  1292.         dataCount  = 0;. P  B) L& w: a* b8 |
  1293.         code       = CodeNone;
    ; u) U% L: {  U7 C
  1294.         stage      = StageNone;0 _4 E% x! s0 B- r
  1295. 9 M. V' X- G7 X8 X$ v# a
  1296.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++); R0 P. ~) v' l, ^7 S
  1297.         {
    5 g% ?+ P2 ]* L
  1298.           txBuffer[txLength] = CodeCan;1 f/ v+ T: }3 l2 x- m
  1299.         }
    . n6 F6 |2 {6 K

  1300. ) Z1 s( e8 ?# `9 x% h& d% v
  1301.         write(txBuffer, txLength);" Q& P8 `: }! z5 h& ?
  1302.         callback(StatusError, NULL, NULL);
    7 k* J+ v& M4 J. u1 @  K+ ]) P
  1303.       }+ r4 B- v/ ^3 m. n! `6 c' d
  1304.       else% z# n% H2 g- Y5 P
  1305.       {
    " }, D' p5 S3 {5 M4 C9 h; G
  1306.         write(txBuffer, txLength);* O4 h4 \4 e* b  f, Y
  1307.       }
    7 B/ |" t) g) Z$ k, ?, R

  1308. 7 J, d$ I$ k6 j& Z
  1309.       break;. R& A8 D' A! ~0 P# u
  1310.     }# M$ a+ o9 Y8 V  e

  1311. * @/ g, i; r! L9 g: W
  1312.     case CodeC:
    5 o0 j% v  T! P7 F
  1313.     {2 q1 `- l% R3 |' P* I
  1314.       errorCount++;8 m3 r1 l; K8 o) Q# o$ j

  1315. ' E3 P# @9 z* L6 H3 t" f% k
  1316.       if(errorCount > errorMax)9 @% m, L4 y$ y, ]" k- {% N4 i
  1317.       {% C; P3 N- B6 S" a6 w  t8 ^# W6 m
  1318.         timeCount  = 0;) c% F4 d8 @2 g! C! z
  1319.         errorCount = 0;
    / B* z7 G* t' Q! O
  1320.         dataCount  = 0;6 _* R& r. a- U! X; S
  1321.         code       = CodeNone;( Y9 x% L3 F' t& M
  1322.         stage      = StageNone;" S1 c, ~: V* C- M- H; b% Z
  1323. 4 J7 k( _+ k9 L
  1324.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)9 m/ I# H$ ?, c& Q# A
  1325.         {8 |4 o% F. B6 H8 }
  1326.           txBuffer[txLength] = CodeCan;  X0 c  R9 y$ h6 `) {$ |
  1327.         }$ c" ?# z6 X; N- ?
  1328. ( t# S# T2 A6 T9 o9 b
  1329.         write(txBuffer, txLength);* Q5 s, {6 I8 a+ q
  1330.         callback(StatusError, NULL, NULL);2 J# k! I" v) k' y" X
  1331.       }
    # S  G8 w% k3 q3 A9 m: a
  1332.       else2 B# {, K0 V$ n- Y2 f$ g4 d& }; }* e
  1333.       {' G5 g$ H  o3 V# _( L
  1334.         timeCount  = 0;
    3 x9 {* g% m2 ]# r  Q) O7 G
  1335.         errorCount = 0;) `$ K9 N% E& L5 m; U. R
  1336.         dataCount  = dataCount;- D3 [9 e7 Q1 J/ B
  1337.         code       = CodeNone;/ Y) ~4 V5 P* C8 G" C6 Q" x  W' [
  1338.         stage      = (Stage)(stage + dataCount);% v) J* M4 m% d! a. l3 F  Q
  1339.         write(txBuffer, txLength);3 F2 o8 `2 V% t. C
  1340.       }. r) J& V. Q* v  X/ P% K& p9 }" i

  1341. ! k5 y8 B$ V6 N1 \
  1342.       break;' N; e8 g# D6 T& |: E* a/ \7 d8 \
  1343.     }1 [% C( p1 Y/ H+ k6 T9 ^6 o; U" @
  1344. 3 f- ?/ K5 O& Z
  1345.     case CodeAck:# f9 d; j: F0 R; ?9 R- X( j( k- n) q
  1346.     {+ \: {, ^& R6 p$ P  {
  1347.       memset(&(txBuffer[YMODEM_PACKET_HEADER]), NULL, YMODEM_PACKET_1K_SIZE);5 H* \# f1 m# E! U

  1348. ) }& t& t5 e6 K1 f* P- U' z9 u
  1349.       switch(callback(StatusTransmit, &(txBuffer[YMODEM_PACKET_HEADER]), &(txLength)))
    + f5 [, [- a3 |, n- w8 r) z. l" M
  1350.       {& K8 m) l( X6 a0 ~
  1351.         case CodeAck:6 l1 i$ m, F& [' z* c1 q. \- S
  1352.         {
    " u9 R" ^, g1 ?8 n  [
  1353.           uint16_t crc = crc16(&(txBuffer[YMODEM_PACKET_HEADER]), txLength);
    + _* g/ T* X- I$ j0 j( o) v4 Y

  1354. % d3 T3 k$ T. e
  1355.           timeCount                                       = 0;
    + W4 d( k2 s0 ?* r
  1356.           errorCount                                      = 0;
    6 ^& t0 w3 ?! x6 M8 t$ r
  1357.           dataCount                                       = 1;
    * z1 Q1 y! f, t
  1358.           code                                            = CodeNone;
    ( u& W, m/ U( q' t
  1359.           stage                                           = StageEstablished;
    1 v  z8 U2 W; E
  1360.           txBuffer[0]                                     = txLength > YMODEM_PACKET_SIZE ? CodeStx : CodeSoh;1 i# i& Q( d% P" C  W6 j
  1361.           txBuffer[1]                                     = 0x01;
    & |$ [1 t: `+ q) J% `; o: h
  1362.           txBuffer[2]                                     = 0xFE;5 F0 G4 q# ^5 k# G0 U( r
  1363.           txBuffer[txLength + YMODEM_PACKET_OVERHEAD - 2] = (uint8_t)(crc >> 8);
    ; S/ M, |2 j6 r* ?: L9 Q
  1364.           txBuffer[txLength + YMODEM_PACKET_OVERHEAD - 1] = (uint8_t)(crc >> 0);. w6 V  I/ ]+ Q% T) o
  1365.           txLength                                        = txLength + YMODEM_PACKET_OVERHEAD;  [1 @& O, p- R
  1366. 4 N6 Y: i+ w3 L8 l4 y5 t
  1367.           break;: d. u7 B1 P% |6 ^
  1368.         }
    ) {( p% l6 S1 J0 K4 S# k

  1369. / \: R: H, \" r: ]9 v
  1370.         case CodeEot:
    . Z6 Q) ?( A2 x; n* H# r/ k
  1371.         {+ l0 o4 N' n% b4 I/ ?3 p. Y
  1372.           timeCount   = 0;1 g1 f4 f7 x  }# N: d
  1373.           errorCount  = 0;
    0 l& A1 J0 n' f
  1374.           dataCount   = 2;
    % X7 B1 H" V$ H
  1375.           code        = CodeNone;4 u- ~& N  k6 t8 A
  1376.           stage       = StageEstablished;. T' W( }  g/ P- O9 I
  1377.           txBuffer[0] = CodeEot;
    % ]5 e- c8 z7 x. W0 D7 \# E- n
  1378.           txLength    = 1;6 X7 e4 W( O  \
  1379.           write(txBuffer, txLength);
    8 Y* A' }& T5 X7 X; v+ P1 j
  1380. 5 b# ^& J* G0 n' a( u. o9 B0 s2 Z
  1381.           break;
    8 E# h; _- y8 u; T- p: A& j
  1382.         }
    ) [. C2 f+ {9 O0 [3 ^2 g1 \. g
  1383. $ P3 }# ~7 y! F; `" s- S7 q
  1384.         default:
    % h0 C# r  G: {% ^  x( a
  1385.         {
    ( _5 @/ }$ X2 P5 @9 G
  1386.           timeCount  = 0;
    2 B( ]- T/ ^& p
  1387.           errorCount = 0;8 G9 X# W* g7 _6 o
  1388.           dataCount  = 0;
    4 s& [8 \' C0 |& W% W
  1389.           code       = CodeNone;" e" A% t0 ^! [
  1390.           stage      = StageNone;
    : Z4 ^2 ]" K; Y& P9 \

  1391. 2 v% N) j, U) X! y3 a) p$ u
  1392.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    . ]" _: w) U( `) d+ a
  1393.           {- \* n4 y& H2 J6 U2 s& ]
  1394.             txBuffer[txLength] = CodeCan;( S$ V" N. W: x5 Z! A0 R
  1395.           }
    ; }/ e1 k' x; {; y  [& y6 ]9 o" ?

  1396. + a/ E5 i1 Z( }0 g, a2 Z
  1397.           write(txBuffer, txLength);: B' A! }8 n! I; ~7 j* Y
  1398.         }3 U# g0 }. W  p% j0 v1 |& Q
  1399.       }
    : q+ k3 b8 B# c( d

  1400. : s) T* O7 d2 X$ Z& ?8 ^
  1401.       break;
    - W; X( G' w/ T# S
  1402.     }
    ! R( a$ p* z$ A

  1403. % \! @& _0 v( b9 W$ }" `7 T
  1404.     case CodeA1:) B! m0 h2 `$ u! C9 v2 m
  1405.     case CodeA2:" ^" a; j8 @9 O/ \7 Y' m* `7 b; H. u
  1406.     case CodeCan:/ P* S$ e6 w( j  \7 k
  1407.     {
    : ^1 t8 `8 `$ D- q
  1408.       timeCount  = 0;# X2 ]$ b! y6 i: c4 L6 I
  1409.       errorCount = 0;. B# C) @. q( B% t1 g! E0 L6 m: O
  1410.       dataCount  = 0;
    $ X; @2 a  x0 I9 ?
  1411.       code       = CodeNone;
    8 |4 S/ F& S! {) l
  1412.       stage      = StageNone;7 V/ t0 ]; H% y9 u2 m1 m- M
  1413.       callback(StatusAbort, NULL, NULL);
    9 A) Y  Q6 t) M5 l
  1414. . ?' K2 l+ u. J
  1415.       break;
    8 B1 v! D! e) v  W) @
  1416.     }
      A. c; T6 d. |8 K9 }2 W

  1417. + X6 J$ X1 A7 I5 h- y; q# a
  1418.     default:+ s6 I7 J0 D: h" \; g# S' ?) C
  1419.     {7 a" G6 o) k/ k& n
  1420.       timeCount++;
    7 c2 D8 o) {" a# R  C" a5 ~" c: O

  1421. ! [; j' h$ q5 w# B( M2 M
  1422.       if((timeCount / (timeDivide + 1)) > timeMax)
    & \; M% l' X% o2 E
  1423.       {5 e3 Z7 `% {0 g2 H
  1424.         timeCount  = 0;7 X" p1 W6 c( I
  1425.         errorCount = 0;* C- T7 C) N. ?; R
  1426.         dataCount  = 0;
    : D% ]0 _- w6 x  j! Y  Z
  1427.         code       = CodeNone;
    " q. ]0 |# U+ d. n+ z
  1428.         stage      = StageNone;  O6 v! G; k! |' m: ]

  1429. & J* e1 Z5 |  o/ Z$ M1 @) _3 [
  1430.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    / b& F4 n+ f7 u7 a
  1431.         {
    # Q  o1 d: a3 n3 [' f5 V
  1432.           txBuffer[txLength] = CodeCan;3 j/ u# ^! x3 n5 W# ?& R; |
  1433.         }
    , P( K0 `' Z8 E9 g

  1434. . f( ]$ X  Q/ r1 X
  1435.         write(txBuffer, txLength);! T: o6 ]( x, q8 q. {
  1436.         callback(StatusError, NULL, NULL);
    ; T0 Z# I6 S: i% C1 W
  1437.       }
    & C" m$ H- y' U- F
  1438.       else if((timeCount % (timeDivide + 1)) == 0), ^, G4 P) J: i  E1 s& e
  1439.       {
    2 u6 O8 c' _$ R  g
  1440.         write(txBuffer, txLength);
    2 I: L& Y0 h0 A  U$ F+ P. s& o
  1441.       }/ l- ], ~6 b% ?
  1442.     }
    6 Q: u. r1 ?: p1 c
  1443.   }
    3 I" _6 X0 g; z
  1444. }
    3 t1 g! k% Y% J% D

  1445. 1 W/ @# t8 i1 I5 T; r1 e) H8 i) F; ]4 ?
  1446. /**6 W! q+ T; h4 i% E/ V
  1447.   * @brief  Transmit transmitting stage.
    + ]% c6 B4 F2 o: I2 O
  1448.   * @param  None.- n( `3 l' F* m+ i/ {
  1449.   * @return None.- G3 Y1 {: e4 S5 z( u+ b7 e
  1450.   */8 W+ B) ^5 W" R' P
  1451. void Ymodem::transmitStageTransmitting()
    5 i- Q) T  k1 l9 ^8 t$ C
  1452. {
    1 c2 k* F) ~- Y  A% M" ?
  1453.   switch(receivePacket())
    & D  J& Y: E8 s1 E6 @5 Z4 B
  1454.   {
    3 b4 }' _- S  v; _  ]" F
  1455.     case CodeNak:
    * x1 b' S$ ?6 l6 `" A% s0 f0 O
  1456.     {" @% k7 S5 {2 g  P
  1457.       errorCount++;+ @- V, N7 c2 T8 I% d$ b; g

  1458. 1 Q  H( l+ G6 ~6 P% T: H
  1459.       if(errorCount > errorMax)
    ( |! B) L# M" m4 O) M
  1460.       {; r' D% @) X- D0 e
  1461.         timeCount  = 0;' K6 t7 X/ |/ I1 h3 G
  1462.         errorCount = 0;
    . F6 q2 {' R; ^& k) _4 `& m7 D/ a; I6 X
  1463.         dataCount  = 0;
    + p, y& l5 w% A
  1464.         code       = CodeNone;
    8 k9 ]6 G# ^) g" |$ t
  1465.         stage      = StageNone;
    - v: n. U+ q- l7 P

  1466. 7 ^4 C# g, {' P( L6 ~7 U
  1467.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)! l* V; f' N+ S* M; h6 [  O5 P
  1468.         {
    & v6 A, S) R! Z, ?4 a/ P
  1469.           txBuffer[txLength] = CodeCan;# _6 m! e4 O% \7 n$ _
  1470.         }  |( q4 z! ^' }- n' [# r1 ?

  1471. 3 f! b; r2 T9 ?9 E, M! Z
  1472.         write(txBuffer, txLength);9 `; E) F+ m7 p2 t% }$ @( n& w
  1473.         callback(StatusError, NULL, NULL);6 @; `+ W7 h1 a" W
  1474.       }% [( V2 ]" C- m; a5 E1 H; V
  1475.       else
    , h' [2 D8 M) L- l
  1476.       {" \! L" N& U7 M- f% I! l
  1477.         write(txBuffer, txLength);
    , }* o* k$ P+ o) U# z' d3 u
  1478.       }
    - p4 o8 m, W' V' a  |( J3 F: z$ n9 x
  1479. 1 d7 g) q' P. F  o# P" {
  1480.       break;
    4 B5 D3 O: ]1 a% j: ~
  1481.     }
    ) u/ W5 u+ k5 @5 f/ C) y) ?$ e
  1482. ( q9 ?! |2 c9 n' w6 K
  1483.     case CodeAck:+ e) [" O6 L$ G# n
  1484.     {
    7 X4 l" q! m# y5 h
  1485.       memset(&(txBuffer[YMODEM_PACKET_HEADER]), NULL, YMODEM_PACKET_1K_SIZE);2 v) l; e3 i4 A: b0 G

  1486. : U3 \- z4 c, C0 z+ s
  1487.       switch(callback(StatusTransmit, &(txBuffer[YMODEM_PACKET_HEADER]), &(txLength)))4 d4 `$ ~/ U+ s
  1488.       {
    - y5 E& x8 b( H9 l9 n$ ~
  1489.         case CodeAck:. c6 [8 x; v8 j8 D& d" I
  1490.         {
    ; i' O0 f8 v' |
  1491.           uint16_t crc = crc16(&(txBuffer[YMODEM_PACKET_HEADER]), txLength);$ G" z6 O  b) y: U
  1492. 9 H! w1 O' ]+ {% L
  1493.           timeCount                                       = 0;
    , F5 O* d1 e2 i3 D- x- f# p
  1494.           errorCount                                      = 0;
    / `0 Y& M9 t3 r7 ^0 D3 w2 l
  1495.           dataCount                                       = dataCount + 1;
    ! c  Z+ F( t, j* O
  1496.           code                                            = CodeNone;
    + A6 ]8 ^7 ^3 o. u& u, ~6 u# Y
  1497.           stage                                           = StageTransmitting;5 L5 F2 Z; ]: F
  1498.           txBuffer[0]                                     = txLength > YMODEM_PACKET_SIZE ? CodeStx : CodeSoh;7 G0 C$ J+ b! |% {6 S: [( i. I. ?& y* A
  1499.           txBuffer[1]                                     = dataCount;
    / k  R# U/ h# f9 S
  1500.           txBuffer[2]                                     = 0xFF - dataCount;
    4 Y# r# |" A4 h0 p
  1501.           txBuffer[txLength + YMODEM_PACKET_OVERHEAD - 2] = (uint8_t)(crc >> 8);
    ; P7 S5 D% H; Y! E9 k
  1502.           txBuffer[txLength + YMODEM_PACKET_OVERHEAD - 1] = (uint8_t)(crc >> 0);3 E3 v( r  e- q  \
  1503.           txLength                                        = txLength + YMODEM_PACKET_OVERHEAD;
    # J* X3 R% S9 t3 L- }2 P" ^7 q
  1504.           write(txBuffer, txLength);9 H3 z* `1 a* |+ a, H

  1505. 8 G# M* c! [; u8 I: d. w* d2 y
  1506.           break;& `) n8 A( m+ p$ N" f
  1507.         }! i! o2 j% E6 b! I
  1508. : _  P5 v# @# K0 P/ V& S
  1509.         case CodeEot:
    * O, }: a$ l# Q& k
  1510.         {- y* {9 U, v4 U  p. h" w$ U
  1511.           timeCount   = 0;7 W- D# b; [( R) m' z
  1512.           errorCount  = 0;0 ?* x3 k5 O0 x
  1513.           dataCount   = 0;2 a8 U( {; ^2 Y$ M
  1514.           code        = CodeNone;/ n% T( Q8 }# S$ E0 l4 r& Z3 X
  1515.           stage       = StageFinishing;
    ! s! |4 b0 m" @5 k( Q
  1516.           txBuffer[0] = CodeEot;
    + t0 p3 ]& l6 [/ P
  1517.           txLength    = 1;
    : `! z; H+ F+ A% H$ Z
  1518.           write(txBuffer, txLength);& Q1 [. p/ U' w! `( i) H6 M

  1519. 8 G/ V, i9 c0 l+ n. [
  1520.           break;1 I$ ]9 B0 n( j" e' }
  1521.         }  `* e3 @' ~; k1 w- t

  1522.   L4 P- ]  Q5 L, e, b8 M; M+ d
  1523.         default:
    5 F/ A8 d% [7 I- ^( ]' Z
  1524.         {
    9 k( T* g6 g3 H# c
  1525.           timeCount  = 0;
    6 w1 V; n: G7 M: x  _
  1526.           errorCount = 0;: E$ X" k+ T4 ?* i
  1527.           dataCount  = 0;+ J+ M! ?& A0 w2 r7 |4 R) Z
  1528.           code       = CodeNone;$ |, q' L1 r# l9 K( \
  1529.           stage      = StageNone;# m6 l  s9 ]7 o4 o! R3 ~5 N4 X

  1530. ! f; X! Y7 Q- K; Q
  1531.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)- K& }0 q3 V2 ]- {- C1 B
  1532.           {
    " G* S) |! {8 L4 M3 s3 c8 }
  1533.             txBuffer[txLength] = CodeCan;6 {! [2 d0 r$ ]( k" C3 T3 k- C
  1534.           }. y8 O4 q3 j4 W! c7 N
  1535. $ i# f+ Z; [8 o
  1536.           write(txBuffer, txLength);4 D; y8 ?3 }- R1 ^1 f/ |8 v) v) k
  1537.         }, O! D( g& ^7 ^( j
  1538.       }# {9 K) v; M. _& P$ _, h$ N

  1539. ! O4 }, E; J# _0 |: s" B7 w. C* W
  1540.       break;( N' c+ q1 J+ Q: p/ d6 _
  1541.     }
    2 o# X) T1 V8 Y; ~0 e' Q# l

  1542. . Q* P2 a- z' t- N6 \" c
  1543.     case CodeA1:0 W9 s" W2 R! J% k6 G$ G+ k8 b
  1544.     case CodeA2:9 S* X/ X% z, Q+ D" l' f2 [% M
  1545.     case CodeCan:
    8 b2 x" t; p! ]1 \3 a. L
  1546.     {
    / k/ n4 G, j& ?2 T' U2 {; C
  1547.       timeCount  = 0;$ }6 k- v5 s, E' G
  1548.       errorCount = 0;
    1 X4 E/ N1 g) h0 x# G
  1549.       dataCount  = 0;
    ) d/ E  H% [# i! g) t
  1550.       code       = CodeNone;
    0 U1 r0 |0 M7 _
  1551.       stage      = StageNone;
    / S7 G% y0 a0 i
  1552.       callback(StatusAbort, NULL, NULL);* k: D1 \- P' r7 O5 H$ t- O
  1553. 2 N6 a  j3 u  N8 I3 N: h
  1554.       break;
    / S( I0 s* _6 b8 I
  1555.     }' u. b; ]) A$ [2 d) [" H# ~3 u* j
  1556. & O8 Z; V) r  P, C* M2 t
  1557.     default:
    9 G/ m( `2 u! C( D
  1558.     {
    / v: P! z# u  A! N( J* W9 C
  1559.       timeCount++;
    ; `& Z$ ?& X1 `/ \" n; p1 u

  1560. & f, p/ P2 @2 D' C8 n
  1561.       if((timeCount / (timeDivide + 1)) > timeMax)
    ; Y* o* ^2 _# J+ K7 S
  1562.       {
    ( P% W& |1 z/ b# @/ P+ v
  1563.         timeCount  = 0;1 e( o9 V/ p% M; z, c4 u
  1564.         errorCount = 0;+ U0 p1 n  z9 z$ \/ D
  1565.         dataCount  = 0;
    5 B4 Y$ m" X$ T; @
  1566.         code       = CodeNone;9 Q9 h8 E# v- r8 B& d: U6 K$ V
  1567.         stage      = StageNone;: r* @. E5 \4 r% V: [, V
  1568. ; ?: r% Q3 m2 E2 J* v8 c8 d7 \
  1569.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)' N' q- k1 e% N0 z& s
  1570.         {
      L. L4 ?9 ]; G6 O8 U6 j% E; r5 G
  1571.           txBuffer[txLength] = CodeCan;; y8 q2 P1 Z% }# t
  1572.         }
    2 K* D7 G. r9 j2 d# p8 B$ V
  1573. 3 ]9 J: A% C' C6 n7 I
  1574.         write(txBuffer, txLength);- Z/ N; `$ A$ y4 ~! o. H$ d
  1575.         callback(StatusError, NULL, NULL);
    % O" z+ F* b* N; m' [* U! t6 s3 `
  1576.       }) n/ M4 M! E5 j& G  |9 `' S' N
  1577.       else if((timeCount % (timeDivide + 1)) == 0)# k0 i+ z: o" i: l  i/ k
  1578.       {
    3 ~3 R1 w; e1 @7 B  B+ l
  1579.         write(txBuffer, txLength);; Q$ U9 I5 L6 }& N* I9 d
  1580.       }
    * }. N; |. {8 ?! K) i
  1581.     }
    & z7 @) |9 \0 y4 i  _9 Y5 `  C
  1582.   }7 w3 g) \. l$ s8 Y8 q5 _4 U9 W
  1583. }9 R/ G8 S+ z& \7 z: o! D  K
  1584. . d; h( I( ]. [- W, `! \' b
  1585. /**
    7 f$ y# \! b5 L& Q, |
  1586.   * @brief  Transmit finishing stage.; c. d7 l1 q0 X4 s0 d# D) `
  1587.   * @param  None.1 j, i  q- s3 m$ y% [
  1588.   * @return None.5 y% n) E7 V. o% D" t7 b6 d) O
  1589.   */+ K% z7 t& J% u, v" x- R
  1590. void Ymodem::transmitStageFinishing()
    2 S6 ~" f9 }7 r/ R" [: W! @
  1591. {
    , |$ @0 s$ N. i# ]% d
  1592.   switch(receivePacket())2 m( V6 W( T; g! V7 f& E
  1593.   {) h' F2 Z% I$ J- j2 [
  1594.     case CodeNak:
    3 l2 o2 y  m% [: u8 r$ m1 K5 s
  1595.     {" @0 n( y# z$ I/ U2 |% f: i
  1596.       timeCount   = 0;
    * J" k0 l3 I0 I0 X& @# Z% U  m* d7 r( @
  1597.       errorCount  = 0;" T* H+ W4 }# F& f6 j) E1 |
  1598.       dataCount   = 0;
    , g1 h2 Q- F0 O  a
  1599.       code        = CodeNone;6 n3 M& v( V$ H, [
  1600.       stage       = StageFinishing;: _7 a* y, D$ t6 `6 {9 V5 ^
  1601.       txBuffer[0] = CodeEot;
    7 q! s. g+ g9 y2 q# n* K
  1602.       txLength    = 1;
    : O* ?! T8 S4 P: j- H+ @
  1603.       write(txBuffer, txLength);
    / B, R0 ~  d. w, S/ r0 }8 T/ a

  1604. % |( j# u$ Y6 ?5 q/ |; c
  1605.       break;
    : V* V. T, m/ ^/ Q
  1606.     }. v' J# e1 [3 f7 i+ l
  1607. " d2 O* |- q, Q! p  Z7 L5 f
  1608.     case CodeC:
    3 P! e& \+ ?) y5 I3 o: Q! E: w
  1609.     {, p& z6 L$ Q. X' o- Q$ h
  1610.       memset(&(txBuffer[YMODEM_PACKET_HEADER]), NULL, YMODEM_PACKET_SIZE);
      X" A$ X7 [( t. d4 _2 @+ o# u+ M
  1611.       uint16_t crc = crc16(&(txBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_SIZE);
    # B4 v5 F4 f/ ~3 O6 \: L
  1612. / e) d% K, G9 H  T' l; k! H
  1613.       timeCount                                                 = 0;
    , C. d  p, I1 ^- `1 u% ]9 T
  1614.       errorCount                                                = 0;
    3 ]) Q+ a7 h. U) f4 S
  1615.       dataCount                                                 = 0;- E2 X/ e) c' R# g
  1616.       code                                                      = CodeNone;. u4 |( S  i7 ]8 ~
  1617.       stage                                                     = StageFinished;
    7 t5 Y+ g" Z: b4 j; q% F( `7 J
  1618.       txBuffer[0]                                               = CodeSoh;
    / [; s: A7 {! T
  1619.       txBuffer[1]                                               = 0x00;! Q. V0 V+ j7 c# ?$ b
  1620.       txBuffer[2]                                               = 0xFF;
    - {8 c" k" G* C/ k* \
  1621.       txBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 2] = (uint8_t)(crc >> 8);
    7 P8 y% k5 Q8 v3 g3 @) N4 y1 T
  1622.       txBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 1] = (uint8_t)(crc >> 0);. T8 l4 d$ i5 C" D
  1623.       txLength                                                  = YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD;* U1 r5 p- g  P3 Q' B7 c
  1624.       write(txBuffer, txLength);
    1 }0 U+ R" J% `! z7 g

  1625. . ^: C2 G: N; T! l( }
  1626.       break;2 ~/ y: I1 Q8 V
  1627.     }
    : O  o+ a3 i5 I+ K

  1628. 7 Y. P/ S% G- |- _& F
  1629.     case CodeA1:
    & g% I7 r* u; a) \6 j4 c2 P. l
  1630.     case CodeA2:. ~/ X% c9 p. r
  1631.     case CodeCan:  t5 J! v3 G! p& E3 \+ d
  1632.     {
    ( v: U! p( ^' ~( g- {2 ^6 r! S
  1633.       timeCount  = 0;
    9 k" n% q- X+ X$ l* ^
  1634.       errorCount = 0;
    ( n& r' x4 I* y) w# G- s
  1635.       dataCount  = 0;
    ( b2 f1 G1 d# L; ?5 e, I
  1636.       code       = CodeNone;
    $ M4 e2 I' V' c6 I
  1637.       stage      = StageNone;# z2 u' {0 _9 b) `
  1638.       callback(StatusAbort, NULL, NULL);: V2 y/ |/ J* c

  1639. 7 {. Y- b; S6 F
  1640.       break;: ?- l/ S% V2 O8 ^& i+ f+ g
  1641.     }
    6 r+ s  E% D% e* ?

  1642. . [8 _* }. q8 k8 p9 g- n" b
  1643.     default:% r% a' L/ B3 g2 l
  1644.     {# D- o# `; U. w8 x6 M7 c
  1645.       timeCount++;" ^* F/ _" {8 M4 _+ K5 {
  1646. , `% K% j$ a  H0 K* @- h
  1647.       if((timeCount / (timeDivide + 1)) > timeMax)+ b$ o0 w) o. Y& f1 r
  1648.       {
    , m: O- c: O; Q5 m) F
  1649.         timeCount  = 0;
    - d7 s' Y: f7 B" v. u8 Y
  1650.         errorCount = 0;& p$ i$ T7 q6 k+ O
  1651.         dataCount  = 0;6 |+ M4 Q$ K" e6 |3 U* I' A) X
  1652.         code       = CodeNone;
    . [' [' z4 K+ S' E/ L
  1653.         stage      = StageNone;
      x& }) X, [" a- d# e

  1654. $ O/ ]' w5 K6 ^6 ?: z3 L0 N8 ?
  1655.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)3 i7 w+ f8 @. y- c
  1656.         {
    9 v, K3 H/ d* G7 Z' y
  1657.           txBuffer[txLength] = CodeCan;
    / Y' Q7 e  K8 x4 C) D
  1658.         }( T5 Q2 G" R6 R6 m
  1659. / z% Q2 D: _' Y+ s3 [, h$ ~: [5 @
  1660.         write(txBuffer, txLength);) D/ z) G+ M# S6 B9 H1 N
  1661.         callback(StatusError, NULL, NULL);
    3 K: A4 T* l: y/ m. N# {
  1662.       }+ n7 l/ n* @3 H! c8 d" ~
  1663.       else if((timeCount % (timeDivide + 1)) == 0)+ _' I" T1 L$ T- ]- h1 [' C0 |
  1664.       {
    1 L6 B& H+ Y' P4 {2 s7 T
  1665.         write(txBuffer, txLength);
    2 H7 l5 a8 Z; G. W
  1666.       }
    : p& `3 _1 V3 ]% v" L% I, \
  1667.     }
    9 L! _" ^+ \6 O1 \, N& d
  1668.   }4 t0 d) ?$ z& V* D& Y  ?
  1669. }
    5 C7 w/ V; V8 L
  1670. * f# M+ f& m9 c& x2 k$ |! ~, p
  1671. /**0 ?8 j. w/ }/ v1 P
  1672.   * @brief  Transmit finished stage.  q4 H0 J( o/ o' U
  1673.   * @param  None.0 X) y0 x" f/ s9 L9 m
  1674.   * @return None.' Q$ D# h& u; y5 e! ]; A5 b( i! m% f
  1675.   */
    2 r! G! t6 U* W
  1676. void Ymodem::transmitStageFinished()0 ^+ e" e. V' `3 @: h% k6 P
  1677. {+ W/ G6 b8 i- d! z: L0 |
  1678.   switch(receivePacket())# @) Z) m: q) Q, z8 R& t' A9 v! ~
  1679.   {' p" a! L9 `4 P5 `- [) o+ y/ ]
  1680.     case CodeC:
    : O/ Z7 f. d* \  w* E3 d' Z
  1681.     case CodeNak:
    1 G% S' ?: B5 r; g" t# a
  1682.     {
    5 k, l  [+ k. v7 R: A$ [; D' n
  1683.       errorCount++;
    3 h1 N/ d  S5 _- W; P* s
  1684. ( I) {& M+ y2 n! ?( q5 B! O
  1685.       if(errorCount > errorMax)6 k% Y2 N( \9 f5 z, l- d
  1686.       {! A- m0 D0 a% {  V. w1 k- _/ j& `
  1687.         timeCount  = 0;/ N3 x, R8 n8 l' m, b& B: G) s
  1688.         errorCount = 0;5 T: f. b8 u% h! J0 b) j; L
  1689.         dataCount  = 0;
    & M- h7 a8 z) j; I: O
  1690.         code       = CodeNone;
    $ E. H+ v. }0 [$ B9 Q/ j
  1691.         stage      = StageNone;8 a9 a3 O( t3 [/ ^; r" l+ }* x

  1692. 3 `! |6 S/ U2 t
  1693.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)" I# W1 ?$ m( s, B( ~1 |( n
  1694.         {+ B" V9 C) z1 y- A
  1695.           txBuffer[txLength] = CodeCan;
    * I% r0 j( S% T* w
  1696.         }  U; J5 n" }8 @
  1697. 4 b9 U4 @( l( T; c- m+ e+ k3 K4 C; m
  1698.         write(txBuffer, txLength);+ x; F; f. ?( J( q$ b# E7 F2 F
  1699.         callback(StatusError, NULL, NULL);
    : X' S- @) ~0 R( ]! M
  1700.       }+ @9 J" K. S# \* I( G$ {" H; R  {4 e
  1701.       else1 o6 g: J6 p7 r* }' h! D
  1702.       {
    : c2 l, r2 @/ J. V/ x
  1703.         write(txBuffer, txLength);" f$ u; V. ?$ ~9 B2 x, m! u3 M9 d
  1704.       }
    ! h$ w9 ^( i# O$ d2 o2 M

  1705. ; O0 a8 s( K! M. F
  1706.       break;6 c+ }4 \9 P7 `) V8 s2 c! l" P
  1707.     }
    / \$ n& g- y( g

  1708. , ^& v, C  A; _8 l/ j
  1709.     case CodeAck:
    * g( u. F5 W; S- P& P/ m9 u
  1710.     {
    # ~" `2 L" j& Z/ W( a1 _4 @
  1711.       timeCount  = 0;; C) ]+ E* W# T/ C, W
  1712.       errorCount = 0;
    - ]. |$ z1 x/ D! p) _3 s
  1713.       dataCount  = 0;
    0 I6 b' O. O1 Y, ]7 ?- ~
  1714.       code       = CodeNone;% z4 f, L+ }0 T1 p8 Y3 {" L
  1715.       stage      = StageNone;' {# v5 A% J0 W0 i
  1716.       callback(StatusFinish, NULL, NULL);
    / D8 T( O$ N0 w' e
  1717. 8 S1 V0 @& k) T
  1718.       break;
    / c6 s) Z" W! a9 d1 T5 f; ]$ d
  1719.     }
    1 J& k5 x  a; a! l  X

  1720. % U6 b( L3 K1 U* i
  1721.     case CodeA1:  I; @" `% ~# j8 a7 C
  1722.     case CodeA2:
    ( T3 r# `; @; b/ b
  1723.     case CodeCan:
    4 l$ c; n7 F  n: H) q2 s( x2 x. G
  1724.     {5 H# H' ^8 G& O3 I- W
  1725.       timeCount  = 0;+ r  |+ X: _! m9 g- r1 F! {
  1726.       errorCount = 0;' S( b) D. x1 w  J* b( y
  1727.       dataCount  = 0;, k& C  t: c9 u3 r& F
  1728.       code       = CodeNone;
    : a- G5 r" x9 q3 N9 P
  1729.       stage      = StageNone;
    2 y7 ]: p: N* S, p+ G& r; f4 n
  1730.       callback(StatusAbort, NULL, NULL);
    ) I. o" M( P8 s6 x2 D
  1731. ( i) a7 g% p3 q7 l- `+ i" b
  1732.       break;0 s( _  o. h) q- |0 a! q, m
  1733.     }% J+ E* w4 L- `' I$ i+ f

  1734. $ d4 M/ X/ P. X  ]
  1735.     default:% b2 a: v9 V9 c5 l+ Q: N+ S; e
  1736.     {# D1 y' {' k/ J" p# u& n9 Z7 n8 ]
  1737.       timeCount++;
    4 ?3 C; F- J1 |0 _

  1738. / I9 }4 U2 C" {: ^7 b
  1739.       if((timeCount / (timeDivide + 1)) > timeMax)2 l/ T: k/ c) r6 ^2 d# m
  1740.       {8 W- {, W$ y; x7 E$ m3 T7 e
  1741.         timeCount  = 0;
    ! b' X/ s8 E1 d& x* _
  1742.         errorCount = 0;& L; d7 b- q' G5 s$ y; F
  1743.         dataCount  = 0;
    # O2 \7 D/ p* q# P& ]) M  [
  1744.         code       = CodeNone;
    " i7 y2 ~+ X1 d
  1745.         stage      = StageNone;
    3 r! n( J% ?- \  J+ x% R' e! u

  1746. / _" \; ]  r8 ~# x6 I
  1747.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    # k& c- I6 X- a& A/ F4 R8 a  E
  1748.         {/ G$ G, p# l2 K
  1749.           txBuffer[txLength] = CodeCan;
    ! V% |' V# l- Y+ g- F/ c( j! l: O
  1750.         }. K' F9 k9 C# g  A* _/ y; O$ i
  1751. ; p) T! y; |, Q# }$ D& o/ o
  1752.         write(txBuffer, txLength);
    , {3 ^! E* m7 Y; k) B
  1753.         callback(StatusError, NULL, NULL);
      M7 g' |. K$ y# N8 h
  1754.       }' ^, ?5 P$ @% R2 j; h( h
  1755.       else if((timeCount % (timeDivide + 1)) == 0)8 j' B& T6 w$ G1 x/ r# \  @% K. m5 E
  1756.       {; ~+ j1 z3 ?6 X8 M+ p
  1757.         write(txBuffer, txLength);; J6 |; o! F9 l/ d% |
  1758.       }7 g- j; i6 ^! _* E2 B6 ^
  1759.     }
    3 Q, S! L6 e1 e. `8 j8 u
  1760.   }" y: h6 w; G% s4 {5 R5 U* H. \/ f' }
  1761. }. B- N  T+ W' Y, ^( q7 J; U

  1762. * D& E5 S$ ?) b4 i6 J8 T1 c! j
  1763. /**
    * p0 H  |. }# h5 a
  1764.   * @brief  Calculate CRC16 checksum.
      B# U4 e6 O7 ]6 W4 M% e* a7 K. q
  1765.   * @param  [in] buff: The data to be calculated.9 w) }) b- e4 ^/ b+ c) X/ ^
  1766.   * @param  [in] len:  The length of the data to be calculated.
    9 S1 M. Q! ~6 l+ {5 t1 f
  1767.   * @return Calculated CRC16 checksum.
    " x' A& w0 t/ L, f' ~+ G
  1768.   */8 n% v% R; P! n+ @( S, d6 l. |
  1769. uint16_t Ymodem::crc16(uint8_t *buff, uint32_t len)
    5 o9 r& D" ^0 w( S4 w( A
  1770. {
    + r, z8 e8 [# r
  1771.   uint16_t crc = 0;. K2 o9 [/ R2 z  T  J. n+ f/ }5 u

  1772. 5 ?6 W5 p- ^- |1 ]
  1773.   while(len--)) B% m  c5 h- r( |" M# Z5 s# x
  1774.   {& z3 J) _, [8 g7 }# h
  1775.     crc ^= (uint16_t)(*(buff++)) << 8;* j. m; A: l4 d6 L, j' G

  1776. 6 z2 e/ d" C7 k0 Y
  1777.     for(int i = 0; i < 8; i++)5 g% t- i& t: V# b) B
  1778.     {) l( V5 O( _1 l/ `: @
  1779.       if(crc & 0x8000)
    & G1 ^- M1 I& F  N3 M/ S
  1780.       {
    2 F! b8 P9 U* J9 n+ [/ E
  1781.         crc = (crc << 1) ^ 0x1021;7 w8 U/ F9 a) |1 k4 H. U8 \
  1782.       }& z! C1 ]! O/ F; ]2 M6 [4 s
  1783.       else# o  h/ _: T4 j: a- O; F
  1784.       {
    4 `& B( |. A* o, |) K
  1785.         crc = crc << 1;
    ; _) R* }- W% B) {$ K5 D- t7 [7 h
  1786.       }
    1 \* f  x" ]2 i
  1787.     }2 ^8 \- l! c, J; Q) r7 j
  1788.   }
    & V' F8 W4 `7 N  C+ @  A
  1789. # b4 m2 t6 u5 z& [3 T. b5 M' j* Q- n, s
  1790.   return crc;
    9 l$ u7 I) A; V. c) m0 v8 a% ^
  1791. }8 J7 J" Y2 s" E* O) M& V3 e
复制代码
1 M1 `# t5 Q8 d* q. ~) S( ^
* @6 N! s" G  I2 {9 L8 |  P! v

; Q" b4 Z3 L/ w% @8 R8 i1 }4 T  a( j
* M. p  M6 r/ E$ w5 p7 a
* V! p" l8 ~- o
收藏 1 评论11 发布时间:2018-3-6 22:28

举报

11个回答
XinLiYF 回答时间:2018-3-6 22:30:39
      YmodemFileReceive.h文件
+ O% o0 T9 v  N
  1. #ifndef YMODEMFILERECEIVE_H
    4 M2 c( u+ V$ b6 F$ b6 ?& M
  2. #define YMODEMFILERECEIVE_H& G2 n1 Z) h0 J. _3 I3 V6 z! P9 A5 Q9 E
  3. 4 n4 O0 x& D% t
  4. #include <QFile>1 Y9 p' c/ ]0 ?7 f8 b
  5. #include <QTimer>0 Q" [$ N! n+ R  I) `: e. M7 G
  6. #include <QObject>! A8 o' Y; g1 U1 o8 t  o  o* _+ L+ W
  7. #include <QSerialPort>
    1 p0 ], V  X8 M: P( P
  8. #include "Ymodem.h") R  t3 F: p. D& }
  9. ' y4 k! \! D! Z4 R/ n+ W1 I+ g
  10. class YmodemFileReceive : public QObject, public Ymodem
    ; W% F- f) y2 t/ H0 F
  11. {
    7 }3 r! D' ]5 D. `; F: {: ^
  12.     Q_OBJECT  L: L, }8 i  \" H* I; W1 r

  13. % \( A5 k' r1 ^& S* X
  14. public:
    ' V& d0 U! j8 R# k: e9 x+ y; E) H: q
  15.     explicit YmodemFileReceive(QObject *parent = 0);8 U" z7 B; h' Y% n7 n; V' l
  16.     ~YmodemFileReceive();1 W& B  M0 a; g: Z

  17. * G2 R; H0 ?6 [6 ?+ L; ^
  18.     void setFilePath(const QString &path);3 _% x( n% \. O9 S: r( Y$ w
  19. 5 P0 C5 ]6 h9 a
  20.     void setPortName(const QString &name);9 l0 u1 @. N2 L3 K8 `
  21.     void setPortBaudRate(qint32 baudrate);1 v% w* h$ o6 {( ]2 y1 p; i

  22. 6 `- r8 E3 C6 p- |
  23.     bool startReceive();
    4 |' r! w: R0 }; a2 ~6 @/ Q" e
  24.     void stopReceive();
    7 M0 {  S; q' s, w
  25. 2 c& ?- Y  ~5 r  w* n+ L
  26.     int getReceiveProgress();
    : X8 P5 R. E, L$ j
  27.     Status getReceiveStatus();- {' ~; v9 C! B- e
  28. 8 Y- f2 f5 H! ^) A3 v4 T
  29. signals:
    * V. x  ~' k' A% o+ s& }+ I8 S9 k
  30.     void receiveProgress(int progress);
    1 g! C* ?# b7 s+ m
  31.     void receiveStatus(YmodemFileReceive::Status status);3 \: M. v' C: C/ h/ m5 H, t7 [4 l
  32. : o) @7 B% ?, f2 F
  33. private slots:" H% s7 H* ~8 v( {' R& k5 X
  34.     void readTimeOut();$ a% L) ~& R# G* R
  35.     void writeTimeOut();
    ( {3 p8 {0 A. Y/ Q" t, G# C9 ~' E
  36. $ n4 e$ i& W' l% b; n- l* V
  37. private:. R. r; o( N/ @  p9 C2 j- G' o
  38.     Code callback(Status status, uint8_t *buff, uint32_t *len);, j! _* X# q- A

  39. 4 o% x, [0 `# a* y* \
  40.     uint32_t read(uint8_t *buff, uint32_t len);7 a5 ]5 N$ @2 G
  41.     uint32_t write(uint8_t *buff, uint32_t len);5 }& f. y& v) i! }

  42. ' H# D) m; R* J' v
  43.     QFile       *file;$ v8 ~  |# ~& ]: o1 ^/ @1 \2 M
  44.     QTimer      *readTimer;
    + x3 l2 d- x" R
  45.     QTimer      *writeTimer;; K7 Q6 Z4 z1 e
  46.     QSerialPort *serialPort;1 P! j9 j' l. _) @

  47. # j# D0 q% V7 k- U! T
  48.     int      progress;3 C. A) d, ~4 t* L
  49.     Status   status;. q& X1 W8 p( s+ I6 {- u9 ^
  50.     QString  filePath;
    8 p% ~9 w! K+ [$ c0 F' K3 d$ S
  51.     QString  fileName;% r) y: K+ f: Y2 Q& J9 u
  52.     uint64_t fileSize;
    9 p9 f1 A4 F7 K7 B# i4 Z
  53.     uint64_t fileCount;7 E+ g* _3 f. o$ U# R( k1 b
  54. };6 m! d5 I% w- |( o7 c2 `# ~
  55. * m* e" L. g1 V* w
  56. #endif // YMODEMFILERECEIVE_H
    ; g  c) e/ D& ?5 j; E0 J
复制代码

9 |. {8 f: O: m# @, u% n. ?      YmodemFileReceive.cpp文件
* U3 N; \- h# }6 V; G+ N
  1. #include "YmodemFileReceive.h"0 X* C; Y, Y+ G! ^8 s! I& i2 U
  2. ( Z# Z- }7 v* b$ G- q
  3. #define READ_TIME_OUT   (10)  A0 F( y. c( y9 g$ c0 d
  4. #define WRITE_TIME_OUT  (100)
    4 m& x8 I6 A5 w" X  Z) }

  5. 6 ?3 E7 j1 J  M0 v- H
  6. YmodemFileReceive::YmodemFileReceive(QObject *parent) :  n5 E6 }8 r4 r" H* j
  7.     QObject(parent),
    ) s7 z: W' I/ R0 D3 f
  8.     file(new QFile),3 ?0 O+ k; q1 b7 s, s" a8 N' ]
  9.     readTimer(new QTimer),$ |5 v% p) _( S: j* W
  10.     writeTimer(new QTimer),& o1 ^5 r4 e) E) e" R+ c. r; v
  11.     serialPort(new QSerialPort)* V0 i( n- t9 j: G
  12. {! m6 j  a5 H$ o, M0 t4 z  g  Y4 [
  13.     setTimeDivide(499);
    % u; q- `! Y0 c. u9 |  e$ Q
  14.     setTimeMax(5);
    - T5 c% L5 x. p$ I; D
  15.     setErrorMax(999);
    * a* ]& M" y4 G' g# ?- `

  16. : D& u: ^) {6 Y1 q
  17.     serialPort->setPortName("COM1");
    # {7 Q  r8 R7 X3 k; G  j4 y# z
  18.     serialPort->setBaudRate(115200);
    3 }/ ]" K( r* P# ?8 \+ j' x
  19.     serialPort->setDataBits(QSerialPort::Data8);
    6 f' l  v- R9 i6 v* P+ b+ `
  20.     serialPort->setStopBits(QSerialPort::OneStop);; A0 N: h7 A0 v6 g4 X  d
  21.     serialPort->setParity(QSerialPort::NoParity);- f) e2 j5 Q. y7 v6 Z
  22.     serialPort->setFlowControl(QSerialPort::NoFlowControl);
    * P5 ]7 M3 Q: L6 O: r  Y
  23. 3 P: I( m2 \- I0 T
  24.     connect(readTimer, SIGNAL(timeout()), this, SLOT(readTimeOut()));
    2 l6 s) D+ Y: I( [# O
  25.     connect(writeTimer, SIGNAL(timeout()), this, SLOT(writeTimeOut()));
    . F2 E8 {" C& b+ R2 |2 `- }; x' g: `+ t
  26. }
    $ j2 @6 r- Z1 _8 s: e% ~5 d* E, E

  27. . O- T1 T8 ]9 F! V$ d
  28. YmodemFileReceive::~YmodemFileReceive()- W  I0 I8 {% U9 e  ]" w: I+ _: D
  29. {
    + a. Y1 D' u# ]1 E( M( I; M( G
  30.     delete file;
    + o1 W  q; \% ?" V$ A9 |
  31.     delete readTimer;* C# \2 W! H. q7 X
  32.     delete writeTimer;: t+ O+ t3 ~3 g# C. N  r
  33.     delete serialPort;! |# S3 a) |* ?/ H) A7 L8 I/ n
  34. }
    1 z7 `# f& E* s5 l: h. k/ a8 E+ c6 d

  35. ; j: M, h4 [$ S2 |& @3 O3 N
  36. void YmodemFileReceive::setFilePath(const QString &path)
    2 F1 y( t2 U9 ]3 w8 y
  37. {7 N; e# Y2 i0 B7 v5 U3 _
  38.     filePath = path + "/";
    7 G- `) W( D' |: r9 h
  39. }) G! h& v( S% @7 w
  40. : b4 _: \  G, z! ~" f
  41. void YmodemFileReceive::setPortName(const QString &name)/ r8 r! `6 O" [0 n' _) q& ?& j
  42. {
    / ]- k0 t9 s) P2 u
  43.     serialPort->setPortName(name);
    ; G$ [1 `3 t  y$ s3 F" w
  44. }
    : I& F3 G2 r8 q- P. h/ U" M
  45. 0 r/ Z. d6 J3 Q) W8 }, p
  46. void YmodemFileReceive::setPortBaudRate(qint32 baudrate)
    : d. H' E# Q+ K. R
  47. {& @- M* z3 \. ]4 t2 O, ?) g, U6 t
  48.     serialPort->setBaudRate(baudrate);
    , O9 l: R8 g. }/ G
  49. }
    9 [: Z- T% n1 n# `* c
  50. ' c8 u1 [& s5 S5 Q
  51. bool YmodemFileReceive::startReceive()
    / o' `- }6 N+ p1 ~' @$ n
  52. {( U8 E( o* Q" S/ E  o6 y' W5 Z3 V
  53.     progress = 0;
    + p- ~" Z& ^0 [! ^2 k3 A. u2 h' _
  54.     status   = StatusEstablish;
    9 ^- r8 N" S+ ^9 o& |" C
  55. - U* k7 L  B+ h. Z
  56.     if(serialPort->open(QSerialPort::ReadWrite) == true): Y5 }: q% A7 w- ]
  57.     {0 t; c1 w7 G% Z3 u  T; p- ?% u2 I
  58.         readTimer->start(READ_TIME_OUT);
    / y6 p+ ~  b- J2 o; ?

  59. - }. m* Q3 }; y, J2 a
  60.         return true;1 s8 v/ j; f3 l9 s# }  _
  61.     }" K$ ~4 T/ p* e! a, r% [# {
  62.     else/ D8 X+ _2 M* W0 m. _$ _4 w
  63.     {9 _, p: G+ N/ |. v$ C7 i
  64.         return false;
    : R7 P9 m4 Q2 f  H) d+ F
  65.     }
    + U" m8 |. e4 T
  66. }) ~- Y: J. o- T: z: w
  67. / N4 ]+ L2 R5 R  g3 d
  68. void YmodemFileReceive::stopReceive()+ J, Q. n9 ?( H4 d1 K+ c7 e; Z' l( c
  69. {) R" p# n% d( Y5 h# K, G
  70.     file->close();
    0 G# S1 S9 T4 c; N+ h" O# M1 K: _
  71.     abort();2 M4 N2 t. M1 \
  72.     status = StatusAbort;
    6 y/ ]5 [- G; d+ m  m2 x
  73.     writeTimer->start(WRITE_TIME_OUT);$ n& s# w0 k6 m1 z. n/ _
  74. }
    9 h# W" }3 t- i- [+ c1 }

  75. * m0 o, v8 M$ J7 {" i2 E5 D4 g" F
  76. int YmodemFileReceive::getReceiveProgress()
    # H7 p$ ^5 Y0 u: F& O9 A7 j
  77. {  h  r" h( \" t' I0 g$ [
  78.     return progress;" l; s+ O- ^; ?3 b# o/ O# D
  79. }0 @3 ^: b2 j. f: _

  80. 1 e2 a1 ^2 ?; t
  81. Ymodem::Status YmodemFileReceive::getReceiveStatus()" w4 w- ^' I, m
  82. {5 g5 \2 c! o" P% t* y0 p# B3 X
  83.     return status;
    3 u2 [: I3 x9 D5 Q3 b& Z
  84. }
    / ^7 O3 O/ C0 p4 q) I

  85. 3 ~' V# X! c7 M7 `% P' |
  86. void YmodemFileReceive::readTimeOut()
    ( H' W& I, k- [9 `1 E1 f( H
  87. {0 L: e# Y; p" O2 B
  88.     readTimer->stop();
      e! M+ U8 S/ u6 z( e
  89. : l: b) v; }; f
  90.     receive();+ r- \2 @7 ~2 W

  91. & }  G3 ~0 k2 N+ Q4 K. Z5 A- p# m
  92.     if((status == StatusEstablish) || (status == StatusTransmit))8 V9 {( ?6 _5 \# n- J; e% i) A
  93.     {
    1 C& b9 }8 Y" c! q' X% J8 J+ k! |. j
  94.         readTimer->start(READ_TIME_OUT);
    * M- F$ ]4 K5 U8 o$ V4 f
  95.     }
    1 Z* d% A. y' I1 F$ z
  96. }7 s0 X% |+ Y9 `8 h, W5 L

  97. 2 {4 r' G2 @+ H, c. E: M3 k6 `
  98. void YmodemFileReceive::writeTimeOut()$ h3 r$ t6 p: p) Q
  99. {
    : q# A# z- t$ S
  100.     writeTimer->stop();- v7 A2 X" x  C+ i, y0 b5 Z
  101.     serialPort->close();5 A& g* B7 Z8 a9 |1 h% w! _
  102.     receiveStatus(status);2 d' q3 ]. O3 g# r3 I7 o/ h+ k5 d
  103. }
    ' }: m9 k$ K, g4 Y, _0 j

  104. * x; J) `6 t7 x) c% W/ q& B
  105. Ymodem::Code YmodemFileReceive::callback(Status status, uint8_t *buff, uint32_t *len)# p: v: E9 j, i# D1 }  V" h
  106. {/ E' a* U9 }- b! X1 C, e- Q
  107.     switch(status)# d* l2 j2 j4 f
  108.     {
    " }. a+ O% X3 n) C* r5 W
  109.         case StatusEstablish:
    7 C, T6 Q- _6 a( u4 s% I6 z$ M
  110.         {
    ) K, ^2 R/ \5 s8 a6 T9 T
  111.             if(buff[0] != 0)
    7 z# [8 s% }. c4 |* f3 r
  112.             {
    + h& n5 m2 T0 E/ J+ C
  113.                 int  i         =  0;
    # f8 D) U; R5 w: s
  114.                 char name[128] = {0};
    1 F3 o1 E: f$ E7 \' }5 Y% t
  115.                 char size[128] = {0};
    $ ~7 _# z* W' q7 E

  116. 3 ]  i/ x3 D/ |- u, [9 x0 K( p; K
  117.                 for(int j = 0; buff[i] != 0; i++, j++)
    ( |0 R- ~5 J) p9 A6 a' b. h
  118.                 {! A! p, w7 T) `( d( P9 s
  119.                     name[j] = buff[i];
    8 n9 Y* z. W/ ]  T2 @
  120.                 }/ g2 d. G( Z- b% W( X

  121. 7 i% n) O/ C1 J) G' f* D4 l* X
  122.                 i++;
    " u) O( {  w  \2 W
  123. 8 J! M1 Q) i$ |6 I7 L
  124.                 for(int j = 0; buff[i] != 0; i++, j++)
    ' ]- t) t) a) N- }. K3 y% C- q
  125.                 {3 Q- U' G: J# K1 G: \# h- Q3 j
  126.                     size[j] = buff[i];
    9 q0 R0 O3 b& T1 [
  127.                 }1 `) U, ?4 `' F- K* t; I

  128. 4 Z( [( g& y- }; H
  129.                 fileName  = QString::fromLocal8Bit(name);! M; f% N7 F# n& t" U+ O: ?% ?2 I
  130.                 fileSize  = QString(size).toULongLong();$ ]$ l1 p7 }9 n3 o
  131.                 fileCount = 0;9 T+ e! h) j* Y; o5 P: w
  132. . r( h9 _1 f. D$ G$ {: _1 J% ?
  133.                 file->setFileName(filePath + fileName);
      [- f& ~3 [/ Z1 v

  134. 2 l# q5 i7 K. h- n
  135.                 if(file->open(QFile::WriteOnly) == true)* F5 d8 C- K, e. w7 ?
  136.                 {
    : C; Y0 b  d) E
  137.                     YmodemFileReceive::status = StatusEstablish;
    : a+ S. v( O7 b- B  a) |- p
  138. 1 t$ Y( f6 }$ L. e
  139.                     receiveStatus(StatusEstablish);; |3 d3 c& R% ?# n

  140. . V9 @) Y+ L) S. l) v% T& D
  141.                     return CodeAck;
    ' t2 ~. R1 M8 a, z  S# f& I( a
  142.                 }0 W$ P9 A( M9 h. C. Q/ U. i
  143.                 else
    ! A+ p( M6 [' z! l) L) g" @
  144.                 {
    - P3 T* Q7 B( C% t+ i& I1 g8 g
  145.                     YmodemFileReceive::status = StatusError;
    ) C' @8 Q% W1 n+ r

  146. , Y/ f/ i9 ^4 v0 h6 R4 W! r
  147.                     writeTimer->start(WRITE_TIME_OUT);7 G7 t3 {( n9 z8 V2 j+ p! x

  148. ( s- v% K- u/ i$ o: n) @! ~5 p9 F
  149.                     return CodeCan;( g+ l/ O# l0 K- r7 k; w. z
  150.                 }# I# A, T* x- U/ A8 z- q- e3 G
  151.             }: T6 v  A& u, \$ r
  152.             else0 B2 r# ?' L; l/ v* ^) p& [3 T
  153.             {+ v. D" U" N! e8 b
  154.                 YmodemFileReceive::status = StatusError;
    6 w5 b6 N. H: @1 k: w' k

  155. ( K' l- i3 e; f* u
  156.                 writeTimer->start(WRITE_TIME_OUT);! e. U* n; B% M9 F6 ~

  157. # p4 M0 @. P5 G! [8 r
  158.                 return CodeCan;
    / E3 f) J; X& z8 g! _/ ~
  159.             }
    9 |& {1 _% z7 c  d
  160.         }
    , @8 J! r- {1 `$ s9 }5 J

  161. & {  p- z) {+ _- g: n0 e
  162.         case StatusTransmit:
    $ a) y+ w/ ?1 ~# F8 h. q7 R. }6 x
  163.         {( `) @: G& C8 ^4 B0 L7 r% F4 A0 D
  164.             if((fileSize - fileCount) > *len)
    : {6 }" E$ A* A" a1 p3 D
  165.             {% I: d) `7 \4 f; [6 t
  166.                 file->write((char *)buff, *len);
    ( r; Z4 ]( l6 Z* J* ?3 V
  167. 8 _: y* b3 Q, Q
  168.                 fileCount += *len;( i9 s# [& P0 P9 u/ p4 M# D9 M1 n
  169.             }
    5 p* G7 j9 }8 a# S7 O& p
  170.             else; J- ^) n, Z+ I. v# \3 o
  171.             {
    + Y! f% _3 G- ^$ a4 d0 W
  172.                 file->write((char *)buff, fileSize - fileCount);# A$ {9 [" ]* l. s, k: J

  173. 9 T& y& z4 @" x$ n6 w: `( c
  174.                 fileCount += fileSize - fileCount;
    3 C+ g; `- J+ Q' d$ w8 n9 C2 F
  175.             }
    / u6 q$ q2 z- y& g1 U* u; ?2 N" u4 o7 f
  176. 2 J: I, D: r1 l  E. |2 x( q
  177.             progress = (int)(fileCount * 100 / fileSize);3 ?0 w' U( Q- O
  178. - N" J1 A3 z3 a# P0 a+ T, G/ d3 u) s( C
  179.             YmodemFileReceive::status = StatusTransmit;
    1 n( a. w3 G1 s1 J# K6 E2 S) n' b
  180. 3 u8 s7 m, F& H, F
  181.             receiveProgress(progress);" D0 D. j5 O! s$ r) y5 J5 t+ W* q( }
  182.             receiveStatus(StatusTransmit);
    " W+ E! c5 A, E$ z

  183. " s, G, e, {' c8 d* z& I4 ^
  184.             return CodeAck;2 d. y& e: u; U
  185.         }
    8 M6 P8 c" U! i% E+ }0 W) Y
  186. 4 H, q: Z/ l# @% o0 B
  187.         case StatusFinish:/ x- w( J/ n& F7 B/ N  Q( [' f
  188.         {
    & g. ?& j: b* m+ ?8 R8 K7 @( a
  189.             file->close();! W# j/ k0 ?( b1 O6 G7 S+ t- c
  190. 4 B" ^$ c6 D3 c
  191.             YmodemFileReceive::status = StatusFinish;
    9 }; z9 t- V( H

  192. + [: u  O# v% I
  193.             writeTimer->start(WRITE_TIME_OUT);
    ; b% h" S, r) J) C; N9 Z
  194. 7 A. D/ J) @; W) e# s  l
  195.             return CodeAck;$ r9 g( h$ h/ c; v
  196.         }. Z  D9 p6 N0 {+ \7 T: x

  197. + z5 H& z& i. q) j0 m
  198.         case StatusAbort:
    4 A& @) p$ U6 |! ?% A! j! c
  199.         {. ]" t7 {1 v5 `$ p3 p
  200.             file->close();8 v$ f) m' ^7 [+ U0 |

  201. 9 P3 \4 R& [# c, R+ x% Y
  202.             YmodemFileReceive::status = StatusAbort;; \7 b$ ^# P8 h/ E9 `- _( ?7 @5 w

  203. 4 v* g5 W% @* s& I: k8 a# `
  204.             writeTimer->start(WRITE_TIME_OUT);
    * n& V- I; X9 Y/ n* c/ r

  205. " r/ E  Y: g! K. k$ d
  206.             return CodeCan;- \% m! G: ^: }9 E% T
  207.         }
    ! k6 w  a0 V$ G& T. t9 |
  208. + z) B1 Z2 |, S# A& [
  209.         case StatusTimeout:
    2 Q+ i# }, I5 |. o, e2 Z! ]
  210.         {
    4 D/ @! s; _3 m3 Q5 @
  211.             YmodemFileReceive::status = StatusTimeout;; S. H( |2 K$ o& ]+ u

  212.   V) f7 X' K4 b" ~8 c( l. Z
  213.             writeTimer->start(WRITE_TIME_OUT);
    & ^/ |% v8 H/ S6 _8 R

  214. 6 C. |( t; K0 d$ t' n- w7 X
  215.             return CodeCan;
    1 d$ v) n/ K. {6 G6 w/ X) b
  216.         }
    6 ~4 o! e% B  j+ E8 {# O; g

  217. 3 k9 v* O1 r# y& ~1 F! N& z
  218.         default:
    $ p3 y; _& r2 \! O
  219.         {
    9 E! u: d6 ?6 e1 P# m6 G! E. o
  220.             file->close();; K* g, ~" n4 t6 ^, ~) U, C. u
  221. ( u0 G) q+ N* b# A. F- W. ~# V
  222.             YmodemFileReceive::status = StatusError;
    % ^7 m8 U/ l7 |

  223. 5 s. E, Z) u4 }5 \, A# c% g
  224.             writeTimer->start(WRITE_TIME_OUT);# S" C' z' [: m0 `+ M) @

  225. : @' _- ^# t0 j6 {. W, x
  226.             return CodeCan;+ y  j  p+ J) H% m8 I1 G9 |
  227.         }
    7 Z! C% z5 I% V  n/ }# X
  228.     }2 |2 }4 e3 Z2 ]8 U7 r+ s  A
  229. }1 Z7 f  `( a" [; R" X$ {: j6 ]
  230. $ V# i" e7 i5 E0 ~2 m- V6 f
  231. uint32_t YmodemFileReceive::read(uint8_t *buff, uint32_t len)
    ( _. P/ g: J6 u; X. o3 U4 K9 ], _
  232. {
    ' y! J* N$ {* s# P
  233.     return serialPort->read((char *)buff, len);; p$ H& p) o. ?3 c
  234. }
    2 Q( t- O4 ?4 k/ Y$ N
  235. ( p2 M  F8 M) }6 d: W8 x8 Z
  236. uint32_t YmodemFileReceive::write(uint8_t *buff, uint32_t len)  p, X( s$ x, O& e
  237. {
    $ ^( s* o5 r( ]' b
  238.     return serialPort->write((char *)buff, len);
    : [* J! V) D. ^2 @
  239. }
    - c- \0 p: r7 }6 Q( S+ E7 L% R( S
复制代码
, a3 Y0 _4 H2 w* A7 v& V

3 X! u; E, |/ K( y2 Z4 I2 S
8 x; M& K1 }# j' p/ R5 ~' B% u/ u1 S+ X+ k) i& `9 x$ r! p+ J0 A8 }
$ F7 G# x# R) c: P8 D$ E% p
XinLiYF 回答时间:2018-3-6 22:31:26
      YmodemFileTransmit.h文件3 |( w/ ^* U0 I4 O1 Q( V5 g1 K9 Y
  1. #ifndef YMODEMFILETRANSMIT_H
    ) k$ }) u" _% h8 j8 f
  2. #define YMODEMFILETRANSMIT_H2 t; y, ]# S* j3 Q" _# y  ]" h6 t/ ^

  3. % X( W7 y3 D/ E# H( E
  4. #include <QFile>
    7 E6 t6 T# b  v  j5 ^
  5. #include <QTimer>; J2 y: C, z/ f5 L
  6. #include <QObject>5 Z8 B# u  r0 G  @- h
  7. #include <QSerialPort>) _. @  u) h% Y, |% E
  8. #include "Ymodem.h", H# m/ i; ?: A! c: D+ O! v
  9. * _1 H  k; k5 k: I3 B' u. A, p
  10. class YmodemFileTransmit : public QObject, public Ymodem) P' y/ q3 r! s- o0 ?, p2 J# Z
  11. {3 G0 q( x" }, {2 v! ]% U
  12.     Q_OBJECT, k2 e" v! a5 O, v+ D
  13. $ e5 T2 h7 \: O. ?& n% L6 p
  14. public:
    9 F# X/ x" x5 q, z3 r$ |
  15.     explicit YmodemFileTransmit(QObject *parent = 0);
    : q* J1 _( C  A7 z  p5 c
  16.     ~YmodemFileTransmit();% u6 C& @* z! Z0 e, d& b5 m
  17. 5 w. P+ ^: H/ s! ^( p7 J% f
  18.     void setFileName(const QString &name);
    - l$ M0 O( i  r9 ?! K1 H: y1 \- i2 J

  19. ! R/ z9 ?2 m- K1 I/ ]$ ?
  20.     void setPortName(const QString &name);; a* T& r* B7 w+ i+ U' R8 i& U
  21.     void setPortBaudRate(qint32 baudrate);
    : H& }: o. o2 T1 B* t
  22. 0 K  A( \9 o: d$ l( J+ r8 n3 |
  23.     bool startTransmit();9 X  S; ?4 P7 f6 y$ F8 k- K) |$ C% ~
  24.     void stopTransmit();
    2 Q# C% G* r6 {
  25. 5 a6 g& r& ~3 l9 R1 \1 G
  26.     int getTransmitProgress();0 n. {; G3 X0 a6 }' E
  27.     Status getTransmitStatus();
    2 P  z  H7 c9 f4 k

  28. 7 z3 J/ c: o5 e
  29. signals:* V; T- M# O2 N$ N! h
  30.     void transmitProgress(int progress);
    % k. p" E+ I+ j) o' E
  31.     void transmitStatus(YmodemFileTransmit::Status status);
    2 Y, {& a' c3 D: m+ k

  32. - e/ p8 i0 k: O2 I+ @4 I% _9 w
  33. private slots:
      V* j  f# E; U0 e; H
  34.     void readTimeOut();
    : Y, |" w) B% u% R" G) u. f# ~+ ~# ?
  35.     void writeTimeOut();" Z) @4 D( b" z6 }* f+ w* `
  36. ; d8 @- g& }0 l% H
  37. private:" p1 F+ e4 w0 U; z. @# X7 P; T
  38.     Code callback(Status status, uint8_t *buff, uint32_t *len);
    . }- z$ p' U% @, m6 B
  39. 0 _. Y% |* P' f
  40.     uint32_t read(uint8_t *buff, uint32_t len);7 r6 v, n4 o6 h1 N2 x, u$ g
  41.     uint32_t write(uint8_t *buff, uint32_t len);' @) T/ X1 {9 x" {& J2 s% R( c$ n

  42. $ X3 B5 X' m, y$ D$ ^" Q) c! f
  43.     QFile       *file;
    2 M" Y. F& h0 z
  44.     QTimer      *readTimer;
    8 e+ W1 Y$ t2 C5 l" @' a! I
  45.     QTimer      *writeTimer;& h) L8 ]; \5 M, Q% W& |  A
  46.     QSerialPort *serialPort;
    $ o1 I; J1 `! r" T/ ~# t& W; x

  47. ; {% w) n( E; J2 z: V9 M( k
  48.     int      progress;
    2 h) N- p7 I4 A- C/ `
  49.     Status   status;
      [, y- v6 ?( |- h  o1 U6 l& v
  50.     uint64_t fileSize;
      g1 l/ }" n& a9 e( o1 l6 w! n" ?5 _
  51.     uint64_t fileCount;9 e# R+ S' |+ ]9 g" b
  52. };
    0 b8 _6 m! k" V9 S% l7 a2 {4 R
  53. 0 [, Y  v) p0 M6 B2 }  M: J
  54. #endif // YMODEMFILETRANSMIT_H
    1 k6 P: `3 @" L; p
复制代码

+ p/ ^1 l, N8 Q1 S2 |  |      YmodemFileTransmit.cpp文件# t( W8 T3 v+ N2 b+ T1 w7 a8 c
  1. #include "YmodemFileTransmit.h"8 n9 g7 j3 ?! H, \& i. [
  2. #include <QFileInfo># k3 x/ m* z: H# i5 n

  3. ' I1 V% V/ h( v5 B
  4. #define READ_TIME_OUT   (10)9 V- W1 q2 K5 Z! a( n0 `+ [5 H" `
  5. #define WRITE_TIME_OUT  (100)4 t5 h0 A* i8 g+ r% I
  6. 4 J- q# u4 d' R" l  X4 u: A1 {
  7. YmodemFileTransmit::YmodemFileTransmit(QObject *parent) :' e7 Q, o) N: V2 X$ `* }
  8.     QObject(parent),: D7 ^$ q. N( y3 y8 ]
  9.     file(new QFile),
    ' I# x* }- s2 R3 ?2 `, ]
  10.     readTimer(new QTimer),8 f8 c& y1 A) m3 ~+ C, n7 R4 W& }
  11.     writeTimer(new QTimer),
    + p+ m: a. z# }& T
  12.     serialPort(new QSerialPort). t" z* ^0 O' `
  13. {
    + Q9 T' Z4 P% q& Z3 M( A
  14.     setTimeDivide(499);
    ) J# ~1 s$ g+ W( j: J
  15.     setTimeMax(5);
    + `/ _! s: G5 u9 |& `' o: @( _9 A
  16.     setErrorMax(999);
    & ^- v' o. w7 R8 A0 f

  17. 1 I- [( R6 [2 C7 u
  18.     serialPort->setPortName("COM1");
    " l. j5 N9 y7 s, W, v6 ^3 @
  19.     serialPort->setBaudRate(115200);
    . v% _1 ~5 ~/ l: l
  20.     serialPort->setDataBits(QSerialPort::Data8);( i' \6 R9 x; ^# P6 }
  21.     serialPort->setStopBits(QSerialPort::OneStop);, U2 R+ F' P9 ?7 }% P& \
  22.     serialPort->setParity(QSerialPort::NoParity);& [2 \! p/ z4 V/ v5 X
  23.     serialPort->setFlowControl(QSerialPort::NoFlowControl);$ B: e5 u* K: _0 @/ T& ~

  24. 7 H7 I9 }9 }& k$ |% |0 c; M
  25.     connect(readTimer, SIGNAL(timeout()), this, SLOT(readTimeOut()));
    & {# g. f) P) R* f
  26.     connect(writeTimer, SIGNAL(timeout()), this, SLOT(writeTimeOut()));. P8 A0 p/ B5 I+ p  f. f) N" H
  27. }
    & r5 Z  }# y$ U/ z* d* X3 Y

  28. * c4 M' W3 r. u5 v2 D1 }
  29. YmodemFileTransmit::~YmodemFileTransmit()/ ~& `9 t/ c# ?; n3 C- l$ Z
  30. {
    $ E; z) n  @4 j# X  Z5 Z
  31.     delete file;, x4 ]; V0 V4 B& h+ U) v9 s8 S
  32.     delete readTimer;( d: b4 c  S  A7 }( V/ O
  33.     delete writeTimer;
      e& f, X5 G0 j, d
  34.     delete serialPort;% Y% L( u# y* O& t& `
  35. }4 }$ j+ R9 X7 W3 `, C

  36. ! y" i) V0 |; y. C1 B) h7 z, S2 x
  37. void YmodemFileTransmit::setFileName(const QString &name)* l8 F: ?  }( x
  38. {5 [3 i% V" d- C! p
  39.     file->setFileName(name);
    : r/ c2 S3 \2 W; P' @- R8 k+ I
  40. }1 ?6 G% ~( C5 r

  41. 6 t$ y  R8 _8 l' g8 k
  42. void YmodemFileTransmit::setPortName(const QString &name)
    2 v0 L8 B. v6 ^
  43. {- H2 a( S, B  a  D; o9 n
  44.     serialPort->setPortName(name);5 X8 q; Q9 _7 a9 l/ v' e
  45. }0 t) u/ |% ]7 a5 A
  46. ) x2 z0 j( u- u$ B$ _) c
  47. void YmodemFileTransmit::setPortBaudRate(qint32 baudrate), m- ]" G( C; D
  48. {0 t& j6 U- \* O) a) y, [* M" B
  49.     serialPort->setBaudRate(baudrate);
    ! y0 G3 ?4 {9 {
  50. }9 s7 q4 s& `% P

  51. 7 F, f+ L; }$ i& Q, V4 _
  52. bool YmodemFileTransmit::startTransmit()
    ' N& {, ?: e( {! x! d" h2 d
  53. {
    $ ~+ l1 n5 T0 |1 P( m1 O
  54.     progress = 0;  O. C& D5 Y8 |
  55.     status   = StatusEstablish;+ l7 i% Q" w8 |, [3 h0 m; V. Z# W; d
  56. 0 P2 W  ~4 p& T; _
  57.     if(serialPort->open(QSerialPort::ReadWrite) == true)
    6 \/ |6 G0 K2 Y/ [& G9 C, R
  58.     {+ }, H( `" G3 a9 n! z  k% e
  59.         readTimer->start(READ_TIME_OUT);
    ) n0 q- b' e; f( z! g

  60. 1 M, X2 q/ G1 F" x1 l
  61.         return true;
      F. I  s! R2 `5 m) R
  62.     }
    * ?1 q8 r4 E* a, K
  63.     else7 F# I2 a5 [* k- Y7 R" t  _
  64.     {
    . U5 }4 M1 e  x6 q- Q" D8 x  b
  65.         return false;
    - O1 L# Q# n3 x, T' y
  66.     }
    7 G2 C+ A% d8 B/ L
  67. }0 S8 B) V) y1 |9 R5 ~) S

  68. # s) K( T7 ]! i# W- f0 P, z
  69. void YmodemFileTransmit::stopTransmit(); G' y! J, I' S  |
  70. {
    & d* V  T: k1 D9 X3 s
  71.     file->close();
    6 P" q' E; d. D- B+ @2 B; B
  72.     abort();6 G5 H; h! Z2 u$ |/ f6 g  v
  73.     status = StatusAbort;
    & E! a* [$ J) n8 I% z  y7 N5 q
  74.     writeTimer->start(WRITE_TIME_OUT);) B& U1 v% N) m. [. I: X
  75. }% j/ y, p# K$ H- g" T5 J2 s* O. x# P

  76. 7 n- N+ ~+ o2 K
  77. int YmodemFileTransmit::getTransmitProgress()
    9 g' V* p$ I4 l* P" w) V& i
  78. {% ]- I+ h) E1 _( i6 Q$ l& p
  79.     return progress;
    3 |; b( i8 p4 u% ]! @; r' e3 k
  80. }
    ' F. r% z* n( P1 M( m) Z
  81. , T- y7 ^7 g" T9 [7 h
  82. Ymodem::Status YmodemFileTransmit::getTransmitStatus()% Z# Z8 i+ M# s( H/ @' t) J
  83. {
    + n# w( Y3 o0 k
  84.     return status;* K  m/ `  b0 }, o
  85. }8 ^# E* l( d% J# H( v3 v
  86. 7 ^' ?0 e! ~4 V$ U. O
  87. void YmodemFileTransmit::readTimeOut()9 Z6 ?% [* z" H) h% M0 P
  88. {) }- a6 P0 a5 s1 T8 L. |
  89.     readTimer->stop();% q$ t8 ?( i6 `1 }
  90. 7 n% I; W# h! t7 W
  91.     transmit();3 s$ m. }% m9 C

  92. , x5 p  V, o6 _
  93.     if((status == StatusEstablish) || (status == StatusTransmit))
    , a" ^+ W0 d% b
  94.     {1 s. x3 f' Y! o$ a
  95.         readTimer->start(READ_TIME_OUT);
    5 P1 o8 Z( F- F. ^
  96.     }2 E4 \) i. n7 u9 ^/ ?+ X" k" ~
  97. }2 w7 B" ^8 }; ^9 f5 S

  98. 3 K. Y! S- V2 k- f9 b6 k, j( c
  99. void YmodemFileTransmit::writeTimeOut()
    / b8 W0 J: u: U: q- v
  100. {
    + t5 S- u' U6 U* \
  101.     writeTimer->stop();9 k2 }+ |0 ~+ v% t- ?# V
  102.     serialPort->close();
    9 v5 N# z( _4 z4 {2 I% D0 w! w
  103.     transmitStatus(status);
    9 v+ V! P& H" N9 t/ l
  104. }! y! n5 u4 o/ p9 Q3 d' C" i" {
  105. 7 f2 Z4 N& A# Z' ~/ m9 q
  106. Ymodem::Code YmodemFileTransmit::callback(Status status, uint8_t *buff, uint32_t *len)  M, I; |6 c- c3 g
  107. {; N6 z/ Y0 `) ^  Z1 N' m
  108.     switch(status)
    ( ]" J) \& g* j# `$ |( i4 z& i
  109.     {
    5 E) v6 k8 Y7 ~0 u! r1 ]
  110.         case StatusEstablish:
    - @# P. {; H% a  [4 z
  111.         {
    $ J. n( k& j* _3 S8 l; V& W
  112.             if(file->open(QFile::ReadOnly) == true)6 L# a+ f/ m. K) l9 @
  113.             {
      Y+ f1 h  M" C0 r
  114.                 QFileInfo fileInfo(*file);
    & `; @9 N1 [% t! d1 o! r

  115. ; S% y8 ^# L7 X4 F* w
  116.                 fileSize  = fileInfo.size();
    $ j1 M' R) d& F2 u  y4 G
  117.                 fileCount = 0;6 _2 D* T$ v6 l

  118. 2 z0 d. l  S9 {8 L
  119.                 strcpy((char *)buff, fileInfo.fileName().toLocal8Bit().data());( {9 m% c' _" N! u% _5 t$ X' C
  120.                 strcpy((char *)buff + fileInfo.fileName().toLocal8Bit().size() + 1, QByteArray::number(fileInfo.size()).data());4 \, E8 O, Q% Z) _+ x* x) g2 C

  121. 5 E. ~& a2 J( ?: C4 T- G+ v7 S
  122.                 *len = YMODEM_PACKET_SIZE;; @; c: V. E: A7 Y- {

  123. ! W3 `" V7 Q4 F: A% @+ W- R( d9 R
  124.                 YmodemFileTransmit::status = StatusEstablish;- U1 E6 Z. Y" w

  125. 5 z1 \: \7 }0 c7 s
  126.                 transmitStatus(StatusEstablish);5 {( D7 D2 v6 k; ]5 v1 G- _  Y
  127. - H( D  F: R- y) M
  128.                 return CodeAck;/ t$ k. d6 J3 r3 L3 E2 m
  129.             }
    , F" ~4 f  @7 O) _9 X
  130.             else# N# b& s% Z) g, Y
  131.             {
    * D( Z5 ^; C1 i3 A. N) G/ s' y
  132.                 YmodemFileTransmit::status = StatusError;3 o3 o3 z$ r1 ]7 c" R! M' b
  133. . i  J- @, I* G
  134.                 writeTimer->start(WRITE_TIME_OUT);
      x- o4 @; M$ R, w

  135. 9 O" L! t: o& c! R7 w  C; w6 b
  136.                 return CodeCan;
    2 O) R6 G; s+ o
  137.             }
    7 }/ d2 Y& Q4 D7 m
  138.         }+ |* }3 x: h6 H

  139. & s9 x- S* A. ]; g  P
  140.         case StatusTransmit:2 o$ ~7 Q  `# P, G( v5 l
  141.         {% L& T# T. _1 }9 |
  142.             if(fileSize != fileCount)
    8 R5 `, q/ ~0 ~
  143.             {
    & p3 W5 [( u. a4 C/ H9 m
  144.                 if((fileSize - fileCount) > YMODEM_PACKET_SIZE)
    " T7 _9 ?6 ?, _' g7 @
  145.                 {; g$ E( i. O$ R# e' P2 T0 z
  146.                     fileCount += file->read((char *)buff, YMODEM_PACKET_1K_SIZE);
    # {+ }% i8 m% v% T5 v* S. ^# z0 D

  147. & Y0 F) b4 Y: y/ `# O# k* B
  148.                     *len = YMODEM_PACKET_1K_SIZE;
    2 J" k4 f3 D& X/ }; z" a
  149.                 }' Y7 E8 ~' F1 ]
  150.                 else
    * C% M+ s/ L" p6 D9 g& {  v
  151.                 {+ z4 e6 ^, s0 S# w- I& q0 H" R4 L
  152.                     fileCount += file->read((char *)buff, YMODEM_PACKET_SIZE);# K4 I; |2 |. V+ p9 @  h( `% ?6 R& Q
  153. 1 n$ g' {" o  d% T( G7 j* X
  154.                     *len = YMODEM_PACKET_SIZE;, @# H4 J, R/ H# V
  155.                 }" u4 W/ p% a/ N0 p4 w. ?
  156. # P2 M+ R# \  i* R
  157.                 progress = (int)(fileCount * 100 / fileSize);
    ! b4 Y8 x+ Z% _0 u9 v) W! C
  158. 4 V, U+ X( t% q
  159.                 YmodemFileTransmit::status = StatusTransmit;0 e; c# m1 }+ c
  160. ( x/ R4 }, u+ f$ {
  161.                 transmitProgress(progress);
    # u  J. L1 z% ]2 u2 D- _  d4 [
  162.                 transmitStatus(StatusTransmit);
    / E  R' ]' p# N! E8 H! n. M9 @' e
  163. * @! E: m. b. Z# N4 Q8 P
  164.                 return CodeAck;: i" _. ^* K% g3 r! J4 y6 K
  165.             }4 g4 B4 V1 p! F# s7 m2 u8 N
  166.             else
    0 V2 J8 |* x6 t+ t
  167.             {2 s7 {9 x% u* T1 n. c: L+ T
  168.                 YmodemFileTransmit::status = StatusTransmit;
    % m& [. ?" M) e  m

  169. * j8 T* g& m) [! w2 `" v
  170.                 transmitStatus(StatusTransmit);
    : v6 O1 X. C. S% D
  171. 2 Z. c5 o7 ?4 c" A
  172.                 return CodeEot;
    / V* |+ l- c4 M
  173.             }
    8 V: E' z- ~$ b  w
  174.         }
    4 d& c- g# M6 t  j: w# s; O

  175. 1 v9 f  W' c3 u. C
  176.         case StatusFinish:: [9 y/ O5 O: z
  177.         {" m4 L& \; W" }
  178.             file->close();
    2 o) ?% Q8 ]2 c+ e8 T0 f5 C9 @

  179. 8 t3 J9 Y: G$ C- X; e# D' i
  180.             YmodemFileTransmit::status = StatusFinish;% V; @) t8 D. {* {( v

  181.   c1 q5 f$ x  a% d6 k) |
  182.             writeTimer->start(WRITE_TIME_OUT);  C& `* \( S% a

  183. + W5 }. Q$ }2 {( N% \+ h( z" E
  184.             return CodeAck;& v; X$ z: E  U+ G- G
  185.         }% T& Y6 v; n) H$ R

  186. 7 T. m2 D0 i/ f. b, [; L8 t
  187.         case StatusAbort:. ^6 g7 F3 e2 _7 f) n
  188.         {: a# Y6 m  n1 \4 K& |& j0 z
  189.             file->close();
    ; @/ [" @7 A( C1 u! X, z
  190. % J: ]# v% N! ]' _( e8 c* P
  191.             YmodemFileTransmit::status = StatusAbort;: ^6 y* X2 K4 P& C+ W, q* `

  192. ( {. V0 l7 e% |1 n1 w9 K0 L. G1 V4 A) L
  193.             writeTimer->start(WRITE_TIME_OUT);
    ( t  U. _( ~. k, R- V* T* x6 Y

  194. . {' V4 G6 W5 B6 |" ~* d0 J' K0 T
  195.             return CodeCan;
    ! Q2 `2 z# s1 i; v
  196.         }8 |, K( N) N# z# v$ e

  197. , V: i9 L- v* e7 v, o9 `
  198.         case StatusTimeout:
    9 [- Z. X' L9 |2 d# e. m
  199.         {
    0 C- I% H5 Q7 j: R
  200.             YmodemFileTransmit::status = StatusTimeout;
    * p3 X6 Y2 c. z7 r
  201. * b( q* {+ g  S, ~+ U& p7 p
  202.             writeTimer->start(WRITE_TIME_OUT);
    3 `1 O% H  A- l$ C' B
  203. ) N2 [, u6 ^3 {# z
  204.             return CodeCan;9 c: M8 ]6 o/ F- Z
  205.         }
    8 P! H8 ]% T/ N( y
  206. # b% x/ j0 X, V/ y7 j' C
  207.         default:
    & H8 [) E" o- b- Y+ {# k$ b6 }6 b
  208.         {
      {1 d8 ^; e: R! _. D& U+ T
  209.             file->close();
    + v" h3 R8 x' o1 p; _
  210. # c; [/ D" a0 m2 P1 G# s
  211.             YmodemFileTransmit::status = StatusError;
    + x: L* _  J; ?3 |/ o
  212. 5 d; _- f2 i0 z# r5 w8 K) q
  213.             writeTimer->start(WRITE_TIME_OUT);! A+ p4 V% Y4 L/ l. N
  214. & a' d2 L' l& C; ?% k; j  u7 O
  215.             return CodeCan;
      D# }" b* B2 r# Q: u
  216.         }9 q9 O/ j5 Z2 z' K
  217.     }' _) `7 f5 B. T$ I9 Z4 c/ L
  218. }8 ^' A2 \$ h/ q3 W6 N$ o) G% H
  219. 3 p. O/ S: P* z+ r4 D) L" X$ g
  220. uint32_t YmodemFileTransmit::read(uint8_t *buff, uint32_t len)& q! B0 a: B/ D
  221. {1 r, T+ m1 j# m/ F+ F: j
  222.     return serialPort->read((char *)buff, len);. r" W8 K8 s3 m5 ]+ V- n
  223. }+ M6 ~9 ~) V2 D6 ]) l% v
  224. + k- Q, G0 ?  n* S$ N2 L* L9 R
  225. uint32_t YmodemFileTransmit::write(uint8_t *buff, uint32_t len)# o, k3 ^! X1 Y$ d/ Z
  226. {
    ( T3 x' l1 {5 F$ U- @+ T( g
  227.     return serialPort->write((char *)buff, len);
    6 p) N" C) r, H( `6 Y. G
  228. }  {3 b6 k  M7 I/ @1 `
复制代码

: ?+ Q+ \( N$ y7 S. w& |6 ]3 p/ @9 B5 k) u
- T4 |: F+ W2 d" x/ @  O) x
& z. P& N& E1 f" L
7 r( T9 l1 x2 Z0 `! v! R- o
XinLiYF 回答时间:2018-3-6 22:32:05
      widget.ui文件# _" }; r+ O/ x& {4 f5 O4 ~
  1. <?xml version="1.0" encoding="UTF-8"?>- n: d7 H* O3 l& E: R3 r% s
  2. <ui version="4.0">
    7 Y/ x% [$ m4 |; Z  |. }
  3. <class>Widget</class>
      _( K( \4 I2 i$ U5 a
  4. <widget class="QWidget" name="Widget">
    4 ^, B3 _9 G. J. |
  5.   <property name="geometry">2 I+ ?- q. o, ~
  6.    <rect>
    " u# D" b) G* N! V
  7.     <x>0</x>
    7 S2 E8 ?6 f6 _; H
  8.     <y>0</y>
    7 K% y' t6 Q9 k5 W
  9.     <width>444</width>
    ; ^. m8 Y( r% @2 j0 n
  10.     <height>255</height>( _7 Y( m$ }7 G8 H+ j: X( b+ w
  11.    </rect>+ P* _6 {+ _8 M7 s. z1 j- J
  12.   </property>
    5 _3 O) @4 t6 t, ~$ {4 s
  13.   <property name="minimumSize">; L  L* b2 V" L. m* ^
  14.    <size>
    7 C" M; K: b) L; P3 h
  15.     <width>444</width>
    - s" A/ J0 R3 b  ?/ J1 I
  16.     <height>255</height>
    8 C2 P, E& R5 R, q4 W
  17.    </size>
    5 M/ P6 t' W" h
  18.   </property>. ]1 z' [6 F$ t7 F/ E' O  |7 `8 g
  19.   <property name="maximumSize">0 |0 b8 F# f0 B
  20.    <size>
    2 X. F2 e3 F0 w* D" H  t9 U4 o
  21.     <width>444</width>! y/ N% i% s! w" F( X
  22.     <height>255</height>
    4 {+ V+ f* N7 J; X, U! ?4 O& H7 [9 V) ^
  23.    </size>  k2 ^% N) L) F- }  r# B' F
  24.   </property>
    ; L, ]% q4 e5 Z1 M( I
  25.   <property name="windowTitle">+ ^0 [: V1 V4 l, x  {
  26.    <string>SerialPortYmodem</string>
    1 U3 K, p% F! s( h- R
  27.   </property>) N# I# k% J7 H2 {
  28.   <layout class="QVBoxLayout" name="verticalLayout_3">) a6 W  _. N* o& C4 X5 }9 j- k
  29.    <item>4 ^* I% V0 x1 Y2 _4 I" H
  30.     <widget class="QGroupBox" name="groupBox">' ^% E0 F, N# O9 X
  31.      <property name="title">
    $ }2 T. _) P9 E1 n
  32.       <string>串口配置</string>3 W' R* ^: R) H
  33.      </property>" D% {# G& p9 C( c* G$ Q6 c
  34.      <layout class="QHBoxLayout" name="horizontalLayout">
    8 f$ e1 U2 m) ~2 S  q& s% s# L; b, z
  35.       <item>
    & X+ Y0 o' O1 h* q  G6 i# Q
  36.        <widget class="QLabel" name="label">% Y3 k' g1 P6 l8 W
  37.         <property name="text">2 q, W( ^8 Y( @# I( m1 j2 ~( {
  38.          <string>端口:</string>
    * W; E+ ~) J- t3 u- [8 ?* h' \
  39.         </property>' \5 b( Z9 l* M- W
  40.        </widget>
    7 T( r& x: a, J& u' \
  41.       </item>
    ) R8 S8 S6 O5 f, k- y: I
  42.       <item>
    # d( e0 W  o+ @! R
  43.        <widget class="QComboBox" name="comPort">
    ' l* a5 o, N8 h; x# }4 D5 C
  44.         <property name="maxVisibleItems">/ ?; t0 l0 f5 O% `+ k# j  }
  45.          <number>12</number>
    ! v" Z% Y" \% n8 A
  46.         </property>
    ' ^0 e+ e) @+ k
  47.        </widget>3 x8 M: A5 Q% e$ k+ a' e3 r. u- Q
  48.       </item>
    2 J1 r* d+ p: g0 p) u6 R; T
  49.       <item>
    / p5 `% R4 B" g
  50.        <spacer name="horizontalSpacer">
      u! ^' @  Z/ `; Y
  51.         <property name="orientation">- v) E0 L! y9 V; ~( ?. D* V
  52.          <enum>Qt::Horizontal</enum>5 q. P% q8 ]* g" Y) C! I% G
  53.         </property>7 x* P  ?% ~- `
  54.         <property name="sizeHint" stdset="0">
    3 F0 }" I4 i1 b8 j
  55.          <size>7 C! V# y) b' @5 Z. S7 J' J
  56.           <width>40</width>- b0 Q- x& R* I+ t
  57.           <height>20</height>1 S8 W; Z/ l1 h% `
  58.          </size>* {# Y" H6 Y( [3 D; b" x  N
  59.         </property>
    8 @1 J- ]& X  _: _; ?/ ]1 {1 |
  60.        </spacer>) Q- z$ j  r0 p( H8 f% k
  61.       </item>( ]+ [" u& x7 }# L
  62.       <item>
    : y) @! g1 Z) B4 s
  63.        <widget class="QLabel" name="label_2">& M6 v) b9 E4 c- t
  64.         <property name="text">, A& o, E; \5 U) C$ a& D& n3 A5 k
  65.          <string>波特率:</string>
    " }+ M  _) P3 j) ]- W/ B/ k7 ]
  66.         </property>5 ]* B+ U2 @0 B* X6 ?+ C
  67.        </widget>; k! {) ~6 [5 u2 @5 _
  68.       </item>
    2 U- C& F9 u* h$ @' W$ Q: x0 m; E  A
  69.       <item>2 ]; w  I+ H6 R( V! _9 T
  70.        <widget class="QComboBox" name="comBaudRate">
    4 K6 D9 X& _- g7 ?# k
  71.         <property name="currentText">( n) e* b1 J6 ~2 \3 j
  72.          <string>115200</string>
    3 u+ ?* f6 j0 |  h7 ^
  73.         </property>+ x7 y+ q3 J( m/ R6 G
  74.         <property name="currentIndex">* I4 {8 M. O; x, c0 f0 c
  75.          <number>3</number>* q( P5 i6 n% W# N: b4 l! R
  76.         </property>
    ( _9 @. q, K6 ]
  77.         <property name="maxVisibleItems">
    / E6 P8 D( T& f# x* e) X
  78.          <number>12</number>
    7 n9 F4 u: \, k- Q
  79.         </property>( [3 y) U! U3 Q8 Y2 j- t( u
  80.         <item>
    + Q' Q* ^5 H2 w# ^. b% ?
  81.          <property name="text">
    . q- l+ \* K% w2 \: W0 `
  82.           <string>921600</string>4 j$ w+ _$ x' h' H
  83.          </property>& p/ z, M0 |8 s% z6 U# E
  84.         </item>
    $ L5 w: |! a* h' X1 |: C- \7 a
  85.         <item>
    " ?: H, q% H6 ]/ E' D1 ?" g- t
  86.          <property name="text">0 ~, L9 }4 P6 m5 t
  87.           <string>460800</string>7 R, x, j* Q) x* q( G
  88.          </property>% \& g) f! v7 O% ~# G" l
  89.         </item>
    % }' s! J7 v: S- a/ F
  90.         <item>
    & {& U6 J9 G0 N
  91.          <property name="text">
    6 A& U+ I, o7 Q, ^$ f
  92.           <string>230400</string>2 X# A5 Z/ E- {. E* a* i
  93.          </property>
    . c: ~2 T8 S8 F; Y
  94.         </item>2 q5 E" Z3 P0 f6 G
  95.         <item>' p; f1 M, {. Q: G! J+ I  i9 T, v
  96.          <property name="text">( G! y& I5 i: ?! b' c
  97.           <string>115200</string>7 Q& `. J- o4 c( l4 y& C6 \9 V6 i* d
  98.          </property>( I" |' Q) Y) L! @  G3 ]1 M
  99.         </item>
    ! X3 K" R4 ]: k7 h
  100.         <item>
    & o0 i) Y: e; g, Q- y
  101.          <property name="text">
    ) ]! P5 _2 p$ A% C' t1 x( C
  102.           <string>57600</string>8 @/ c: K. ]/ b+ u. X, E
  103.          </property>
    ( p# x0 ?6 _2 S; r0 ^' ]' R
  104.         </item>  Y8 Q2 e: h) ~( v! B- l
  105.         <item>" f' o' m% J2 @5 w
  106.          <property name="text">! @# l( e, i; ^
  107.           <string>38400</string>/ Q8 T; n$ V3 r/ X3 ~' N5 I4 G
  108.          </property>
    % v2 V' w  J) ?; }; Z  I
  109.         </item>
    ' c5 v0 Y6 Z1 ]' L3 _
  110.         <item>+ ?% w5 C) e0 _7 y" ]. s
  111.          <property name="text">
      Q+ \0 b* J$ }- L' P" N+ N6 Z
  112.           <string>19200</string>
    % k- A* e9 K4 ^* }. N
  113.          </property>7 g0 k7 _5 ~7 j+ \" Y
  114.         </item>+ G6 m& U/ R; J; {' F
  115.         <item># u7 H) Q7 o, W: _9 L3 w
  116.          <property name="text">
    7 O  j( b( K5 x& O3 V1 Y
  117.           <string>9600</string>. F9 \& \6 z5 ?0 G/ _
  118.          </property>
    ( ?; T4 c- w& K$ ~: Y
  119.         </item>
    6 W/ U$ i5 T' p9 @
  120.         <item>& ?8 E0 m9 r$ Q% n* m! \
  121.          <property name="text">9 n' D% t2 d( S  E8 m& ]& o
  122.           <string>4800</string>
    " N6 {) s* d, w1 z- W, N
  123.          </property>
    ! q9 v3 ?7 p. H; A, r
  124.         </item>
    + {1 h+ H7 W/ m( F9 E' x
  125.         <item>* Q& w3 ^/ n* |
  126.          <property name="text">6 z/ U1 E: V) B2 p
  127.           <string>2400</string>
    & t* H* g0 r: p% u
  128.          </property>) S) J# R$ F  c( n0 P! n
  129.         </item>  F# B3 h" g; W9 U4 O, i. N& B
  130.         <item>4 E5 j  o' ~& N
  131.          <property name="text">' L, @5 M& v8 l2 t7 E* Y
  132.           <string>1200</string>! f1 _0 a( C0 D- o# _" o1 q
  133.          </property>
    & m2 _+ c7 w, S2 k& F
  134.         </item>
    4 O$ N$ O2 P2 G7 J% h$ [
  135.        </widget>
    1 l0 S) `& q. u: j* D
  136.       </item>4 g3 e+ \* z* w
  137.       <item>
    + _9 n8 j' ?  L
  138.        <spacer name="horizontalSpacer_2">6 D/ a# C. d" ?) c: G
  139.         <property name="orientation">
    7 B. a+ r$ O1 t# L2 [" z
  140.          <enum>Qt::Horizontal</enum>) m  S+ _! H5 o* d$ z' x
  141.         </property>1 ^8 U$ b! |  F3 L$ H; T6 O0 Y
  142.         <property name="sizeHint" stdset="0">& Q; V( u" A/ `9 q- z' B* d8 Q0 u% B1 p
  143.          <size>9 I3 c/ M7 O9 {
  144.           <width>40</width>; F, ]5 u6 A, `1 T( o
  145.           <height>20</height>1 m! n. i  l2 _- q2 t% Y0 s3 Y
  146.          </size>3 [" U0 @# R6 o- `% q
  147.         </property>. O% I6 l+ [2 m
  148.        </spacer>/ g) B, @- h: v& u1 G$ h9 ]
  149.       </item>& X& H' S4 L! F& D
  150.       <item>) K. F% E9 x$ ~- J
  151.        <widget class="QPushButton" name="comButton">
    ! H& Z! v9 V9 Z7 i( s
  152.         <property name="text">7 }! C! E) l' {4 C! N
  153.          <string>打开</string>
    + v) N3 k8 F- j1 D
  154.         </property>& S  p, O# x+ f8 e' K
  155.        </widget>
    $ `8 ]/ b# d: n  m5 v
  156.       </item>
    6 u1 v" B& l5 g( d
  157.      </layout>+ U' Q. g: x) M( ]  n6 x) N
  158.     </widget>! l) V- a/ R0 U# V
  159.    </item>9 `$ X/ B0 |9 r; i- Y9 s
  160.    <item>
      D- S7 X' ?) b  K
  161.     <widget class="QGroupBox" name="groupBox_2">
    4 v' a( _, M6 x0 U& `
  162.      <property name="title">
    ) l1 x$ }5 C: @  |
  163.       <string>文件发送</string>' V0 I; S- }1 l9 G! j* J9 c  [1 F
  164.      </property>% H& ]- z# [7 l3 n0 Y7 v$ M/ o
  165.      <layout class="QVBoxLayout" name="verticalLayout">5 m0 W( X- X0 h: u
  166.       <item>9 ^- b  l: ?! D; x- B
  167.        <layout class="QHBoxLayout" name="horizontalLayout_2">
    # `( u% N5 L5 d9 w5 |
  168.         <item>' e! |3 T/ H4 [7 l  z3 n' U
  169.          <widget class="QLabel" name="label_3">- l7 U& o& s- T: n& G
  170.           <property name="text">; E6 s0 [1 B2 i; V4 B
  171.            <string>文件路径:</string>
    $ o0 f. v6 h; o, K
  172.           </property>2 i, A; }$ o0 D, M& I7 O' I! ]- `8 J4 E
  173.          </widget>% t3 B" |. U. O5 b8 c
  174.         </item>+ I9 T8 D! V- C2 o* D5 X
  175.         <item>1 H8 N/ ^- o0 G
  176.          <widget class="QLineEdit" name="transmitPath">- q# F; g. T' L: ]  Q1 Y2 W% S
  177.           <property name="readOnly">
    4 q, W- r( o7 D! {
  178.            <bool>true</bool>6 n  w# F9 p' n. |# c! c
  179.           </property>. K9 J, \3 W% r
  180.          </widget>
    8 v* n/ q9 F# y+ T
  181.         </item>3 B; [, A7 }' q/ o+ K+ h# j1 _# m
  182.         <item>
    . M/ T( j! j: I1 m0 S, m4 V2 C. I4 \
  183.          <widget class="QPushButton" name="transmitBrowse">2 ~- q% I6 h6 ]/ Z, a4 o+ c
  184.           <property name="enabled">
    ) H/ m& D8 _/ h5 E) v7 J: T
  185.            <bool>false</bool>
    2 b! |! q' X, M3 t
  186.           </property>
    5 ?4 X9 B+ i8 h2 o' J( k$ G% \
  187.           <property name="text">+ t- g5 B% U# e7 M- \6 ^: f8 B& S( G
  188.            <string>浏览...</string>3 z  u. e$ L3 s  F
  189.           </property># ?  H' p' J+ N( @# e+ }9 S2 h: V
  190.          </widget>
    5 g& X& w: `  Q6 Z
  191.         </item>- h. J2 C. Q( _1 ?; @
  192.         <item>: k8 H5 \$ U1 U0 r2 m
  193.          <widget class="QPushButton" name="transmitButton">
    # `& B" `! u2 n6 P0 R( A
  194.           <property name="enabled">
    * [9 ^8 O  I5 F1 D3 P8 V! y* Z
  195.            <bool>false</bool>
    6 A2 j. r: ?2 K. ~
  196.           </property>2 r9 T6 C% X1 }- d
  197.           <property name="text">
    9 B9 B8 @  K* h; P6 G9 d) j0 ^4 A
  198.            <string>发送</string>+ ^& s2 y5 i/ \  x# L/ w" }
  199.           </property>
    / @; r% k: j  ~, R% `* W) s
  200.          </widget># p0 W$ d+ A9 D0 K
  201.         </item>1 j- m2 O6 W$ ^: M% M
  202.        </layout>, a2 L: S8 B. g4 l- y
  203.       </item>
    , X& C8 _4 U' i! w- [, u
  204.       <item>
    5 Y/ Z6 p, U0 G" z# \0 S
  205.        <layout class="QHBoxLayout" name="horizontalLayout_3">" G9 n# U3 Y) ?
  206.         <item>& N$ s% u& }0 E8 ~/ J7 c
  207.          <widget class="QLabel" name="label_5">
    - U% J" w! j8 v% v& t
  208.           <property name="text">
    ' i$ Q4 L; b: I5 j' A
  209.            <string>传输进度:</string>7 X0 h7 j" X" R. f
  210.           </property>
    * I2 w8 e: l% J0 I6 Z( U
  211.          </widget>8 @' n: K9 }+ M- P! M, Z
  212.         </item>) ~' D3 p( d7 Z9 @7 B4 D" j
  213.         <item>
    1 b) F2 y+ p" m0 \
  214.          <widget class="QProgressBar" name="transmitProgress">9 B5 N2 e0 I7 D1 D; E& `) A  K
  215.           <property name="value">
    , {$ e* R2 ?% w% o3 N4 t" c( a
  216.            <number>0</number>
    7 G% M: q+ O1 ^$ q6 W' y9 I
  217.           </property>' |& ~8 g4 k9 a6 C3 I/ Q, F
  218.          </widget>1 L+ W. _' i$ t( u
  219.         </item>
    ) N0 P; H8 i' E* F/ C2 [) I" b
  220.        </layout>
    - M( i% S8 L, Z+ y) E. X, ]5 E
  221.       </item>
    5 ]5 w- i& e2 |2 v6 A5 k  {) j& C
  222.      </layout>* C( |8 i4 P! q- C6 O
  223.     </widget>
    - O, k1 `1 Z% t5 T. f* v3 ?( B2 u) v
  224.    </item>( G) A$ z# [$ D* R
  225.    <item>
    . G) M0 c  K8 t6 Y: ^
  226.     <widget class="QGroupBox" name="groupBox_3">- c! f. \- T. \! i8 D/ a
  227.      <property name="title">
    4 J( k* L! M- [$ C; c2 e4 _5 u
  228.       <string>文件接收</string>
    ; @$ |( ^: j8 W( f' M: u' n
  229.      </property>
    , A* z" Y# r! @6 _3 M% E/ O
  230.      <layout class="QVBoxLayout" name="verticalLayout_2">
    . x) j5 T, p. h
  231.       <item>! V% P  r4 P  Z8 P0 v7 V; Y% F
  232.        <layout class="QHBoxLayout" name="horizontalLayout_4">
    0 I  U4 f- @' p' A/ [
  233.         <item>
    2 l* V7 H% f; w
  234.          <widget class="QLabel" name="label_4">+ ~+ M" W' d# P% Q( M. a
  235.           <property name="text">  y# T: q2 c  S( `" a7 [$ l; k
  236.            <string>文件路径:</string>
    . o  f/ c' z. P- X8 u( A3 J
  237.           </property>) E. h' s! T. H7 }9 H
  238.          </widget>
    1 _' Y' d7 o) n6 l+ I
  239.         </item>
    1 P) Y! z$ X" f. I( Q( n9 U7 \
  240.         <item>; o0 X# r( D- }! a) ]5 \& }
  241.          <widget class="QLineEdit" name="receivePath">* C( j1 Q2 G5 ^8 `0 h: ?  i
  242.           <property name="readOnly">
    + w) F2 t8 S+ V
  243.            <bool>true</bool>
    2 [$ S, t  w1 P; R! U
  244.           </property>7 |! N; b! A8 s5 I4 R
  245.          </widget>
    ) ]( B& G6 y* \4 f0 R
  246.         </item>
    6 }6 Y2 d$ K! M# `8 m
  247.         <item>
    7 @- K8 e# y) K' h. m5 c6 a
  248.          <widget class="QPushButton" name="receiveBrowse">$ r7 w" R# b; s4 k  N: I! |
  249.           <property name="enabled">" s7 h. Y* A& Q
  250.            <bool>false</bool>( D9 z6 \9 i) P: i  t
  251.           </property>
    ; N$ G/ |& u; e5 e1 c# @
  252.           <property name="text">
    / F3 T. g' V" ?9 W0 V) g% N
  253.            <string>浏览...</string>
    ( _& W7 X, m- A9 G2 J1 U( S
  254.           </property># \3 A# ]1 U5 _8 c9 W, V/ a0 Y
  255.          </widget>
    5 S: }2 X) H# ?, u5 Z2 \0 L' [0 P& Q6 u* U
  256.         </item>
    7 A( Q; I9 G5 l% @/ E+ J
  257.         <item>
    # F! \# n6 [# D0 Y
  258.          <widget class="QPushButton" name="receiveButton">  `; D9 i2 k' Z* ]' O: f) P
  259.           <property name="enabled">; k* H: h/ ~4 l% R6 b/ j" D
  260.            <bool>false</bool>+ p" b- q0 B' ?' d! j
  261.           </property>7 X' W0 A9 t+ ~
  262.           <property name="text">7 o+ b5 l; s2 n# {7 Z$ V1 A' {
  263.            <string>接收</string>
    " ?$ A6 H; }2 x2 D# d
  264.           </property>9 b6 o: q. [  O7 ?& o
  265.          </widget>
    , J( A4 \9 P( U& c' b
  266.         </item>5 B) T2 }, B+ B+ M: D
  267.        </layout>: X$ g" |1 O6 f  k6 y
  268.       </item>1 B) D/ i6 |9 a8 C2 z
  269.       <item>% J& z( s, f) n6 |
  270.        <layout class="QHBoxLayout" name="horizontalLayout_5">6 [0 |2 s5 o/ s5 B" [6 T1 S. H
  271.         <item>
      W1 _+ m- }& Z8 T, z" l8 ^. @4 A
  272.          <widget class="QLabel" name="label_6">
    . j, u0 h3 @# M! U1 `$ z6 Y
  273.           <property name="text">) C' [9 b( N8 q" A; v3 G; v# N* y
  274.            <string>传输进度:</string>
    3 ^2 M! z8 X8 P; \- P
  275.           </property>
    8 D( u& `: O: G* }6 r$ ]( m& H$ g2 G
  276.          </widget>
    - i$ w2 \; g- p1 j! X: R
  277.         </item>
    ) F- B" j. \8 F
  278.         <item>! a7 l0 l+ S4 X7 D$ L
  279.          <widget class="QProgressBar" name="receiveProgress">
    1 C8 O2 k8 O! L7 q
  280.           <property name="value">
    " z0 h1 L4 x( [" t, K* _
  281.            <number>0</number>
    9 }( Q; L+ z$ u
  282.           </property>
    7 l% t5 q' O8 @$ X0 C" Q/ t/ U; v  I
  283.          </widget>
    2 v+ r1 p6 f5 {- F: q! S- l! Q
  284.         </item># K6 n, m7 X+ k9 U
  285.        </layout>
    1 Q$ {) b9 l1 I9 p2 N$ c
  286.       </item>
    ; z5 T8 O% y" Z2 ?+ h0 d! }
  287.      </layout>
    1 a0 h- Y; _) j* H
  288.     </widget>
    * v3 x- b. t' z: _% N
  289.    </item>/ p9 @" o0 q# t, b3 w0 C4 E
  290.   </layout>
    $ c5 n$ {6 r% l6 D. I& G6 q
  291. </widget>5 L9 @6 Y* [+ N9 a1 M' |
  292. <layoutdefault spacing="6" margin="11"/>
    * l# [# m6 ]/ c2 |8 ?3 y% r7 l6 ~0 j
  293. <resources/>/ H7 }% E* E9 _/ ?
  294. <connections/>
    ! P. w6 s) U% \7 ~. A
  295. </ui>5 X" J. s# Y: Y& J5 |4 c, k
复制代码

0 x- W4 a2 V7 a      widget.h文件! i- _* L1 P) L
  1. #ifndef WIDGET_H
    3 i0 @- U) @3 H. F. o2 L
  2. #define WIDGET_H2 I0 i  @; h0 }* y7 }

  3. & ]  Z2 G- C7 B5 F7 Q3 K( L* S. r/ l
  4. #include <QWidget>
    ! m3 G6 q. o& y% t
  5. #include "YmodemFileTransmit.h"
    % ^: {8 y& |& S6 R' F# C9 ]
  6. #include "YmodemFileReceive.h") i' U8 `4 ~' _8 V( j
  7. ' m& ?- h* K, L8 [, w3 E
  8. namespace Ui {. p; \0 p6 a9 H! p
  9. class Widget;
    3 y$ P0 n8 R' S
  10. }$ u& `/ Z5 G0 H9 l, Q- O# E* ^' e

  11. ) k* g7 E+ Z+ N: i6 S. _
  12. class Widget : public QWidget
    ; x$ U# j, A* T9 X0 l
  13. {+ w# C* f7 I3 R
  14.     Q_OBJECT
    * Y) Z- |. E- q

  15. ( B, U. K! v0 W4 h6 u4 ~
  16. public:* j: s% K$ F8 i* A* H
  17.     explicit Widget(QWidget *parent = 0);
      P) P7 A3 O9 C; g2 P4 k. R
  18.     ~Widget();/ L1 `3 u: v  W2 t- _# ^7 X5 ^

  19. ) G5 F2 s. w  I6 A/ t
  20. private slots:
    0 x! V5 ]; e7 h
  21.     void on_comButton_clicked();
    # ]( l) S8 {: h$ H& T* k7 F$ o
  22.     void on_transmitBrowse_clicked();
    4 j. ~$ d: F* |8 @  o
  23.     void on_receiveBrowse_clicked();
    % g( n5 e% O/ p& x+ P- s3 S8 r
  24.     void on_transmitButton_clicked();
    : I% y2 G. b/ N6 ~  K
  25.     void on_receiveButton_clicked();
    2 e/ Q9 K# |) ~8 r( A
  26.     void transmitProgress(int progress);+ E* ~& a+ Z- g# P; o
  27.     void receiveProgress(int progress);
    ( s! M8 d6 q$ G/ t. i( r
  28.     void transmitStatus(YmodemFileTransmit::Status status);" W/ y" E; V+ o& G7 V. D9 a
  29.     void receiveStatus(YmodemFileReceive::Status status);/ y. n! N( H! H7 M

  30. ( p9 R" I' O5 u, ?& p! o: U
  31. private:( }9 [& A5 Q4 ^+ M9 v
  32.     Ui::Widget *ui;
    : K5 ~# ?0 M0 T
  33.     QSerialPort *serialPort;
    0 o+ @) g: ]; Y% N4 ^
  34.     YmodemFileTransmit *ymodemFileTransmit;
    4 I8 s9 N8 V* y7 |- I  C- b
  35.     YmodemFileReceive *ymodemFileReceive;
    8 D+ A8 n( G! L& `& f2 j

  36. 1 G# b3 _! d: J* a' ]
  37.     bool transmitButtonStatus;$ y; H4 v/ u. J: u7 k
  38.     bool receiveButtonStatus;
      o! M# o3 h7 T! g$ W6 m, Q; h
  39. };
    8 B6 _/ x0 T" _
  40. 7 j, O) y# W, z: n7 ^
  41. #endif // WIDGET_H
    3 t" B9 n3 u: }+ E) m! ]
复制代码

. l  m# t9 V& }8 {      widget.cpp文件
2 e5 ~9 f5 m* S! c
  1. #include "widget.h"7 V+ i$ b8 G  j8 q. W+ }
  2. #include "ui_widget.h"3 q# O; @4 t* o3 E; _* l
  3. #include <QMessageBox>
    7 b/ z9 O3 g0 j3 E$ F" M* G; S, H
  4. #include <QFileDialog>
    ' G6 {) \/ h  Q7 V" l7 c
  5. #include <QSerialPortInfo>+ f4 o" n9 p7 t* c; T! d4 o
  6. . U1 y  C1 m* I
  7. Widget::Widget(QWidget *parent) :
    + s3 A5 a, a% A9 k2 m5 b
  8.     QWidget(parent),3 B! v/ k! m, q1 C& j
  9.     ui(new Ui::Widget),# ~, H1 @5 u+ g, |; l
  10.     serialPort(new QSerialPort),$ @+ @' }: `8 j  R0 N' t
  11.     ymodemFileTransmit(new YmodemFileTransmit),! q- Z3 v6 r2 }. @: r! ?  V
  12.     ymodemFileReceive(new YmodemFileReceive)
    " m- L  e4 V" f1 I% e
  13. {7 @" ~1 Y; M3 }' F
  14.     transmitButtonStatus = false;& U- O8 a2 t4 r- s$ m& I
  15.     receiveButtonStatus  = false;% r" s( `- a9 s8 R" b4 R' N$ g

  16. ) B( f" F: H1 n, i4 T
  17.     ui->setupUi(this);% W* X6 o9 ]1 m! u* j% @! v
  18. ' R4 |2 z7 J7 e8 w- x" p, w
  19.     QSerialPortInfo serialPortInfo;
    7 H! G4 ?5 ?, I  E

  20. " J, L& }9 ~# w: k+ h1 X9 }5 c
  21.     foreach(serialPortInfo, QSerialPortInfo::availablePorts())6 Z' \. O) t5 w1 K
  22.     {8 ^' o* n1 y! G9 a2 I
  23.         ui->comPort->addItem(serialPortInfo.portName());7 \: l. A$ n& Q
  24.     }
    3 k1 Q% Z, n$ u$ j% B
  25. 3 i& [& u, B8 R+ }6 R7 A6 p
  26.     serialPort->setPortName("COM1");- ~5 x, s/ E/ `2 s( i2 T
  27.     serialPort->setBaudRate(115200);
    0 C, g. Z" m; Q2 M- a
  28.     serialPort->setDataBits(QSerialPort::Data8);
    4 G  c5 T' V- Q
  29.     serialPort->setStopBits(QSerialPort::OneStop);
    ' R# j/ ]) V9 e/ l. g- e
  30.     serialPort->setParity(QSerialPort::NoParity);: O& i! l, I- ^. p: c' Q$ D
  31.     serialPort->setFlowControl(QSerialPort::NoFlowControl);5 B, }" W$ P7 h

  32.   f4 J6 N% w) [! i8 e
  33.     connect(ymodemFileTransmit, SIGNAL(transmitProgress(int)), this, SLOT(transmitProgress(int)));
    5 u  c3 E! [' P$ O( R7 T6 U. |
  34.     connect(ymodemFileReceive, SIGNAL(receiveProgress(int)), this, SLOT(receiveProgress(int)));8 h+ R, r" ]8 t; }% D1 d  s4 q! i! I

  35. 0 m: Y2 l  |  Z0 k. |
  36.    connect(ymodemFileTransmit,
    ( z# `/ D% A- X( X
  37. SIGNAL(transmitStatus(YmodemFileTransmit::Status)), this,
    8 j- ?. n4 n# q' R% d
  38. SLOT(transmitStatus(YmodemFileTransmit::Status)));* l7 l& I/ ]0 I7 [6 a
  39.     6 q0 o* V! x$ f( b
  40. connect(ymodemFileReceive, / r; Z6 d6 b& }
  41. SIGNAL(receiveStatus(YmodemFileReceive::Status)), this,
    ! O3 t1 z; W& L$ a0 a5 \8 J7 `0 B0 O( J
  42. SLOT(receiveStatus(YmodemFileReceive::Status)));' e2 \4 G2 c- b# ^, q$ h, G; P. A5 W
  43. }+ ?. L/ O: s+ u3 k: {

  44. ; Q& o3 e& V* e/ q' h
  45. Widget::~Widget()
    " u7 @( S7 M. h
  46. {- L  F$ m3 c0 t* k" k
  47.     delete ui;
    ) L# s9 ~+ y( ^
  48.     delete serialPort;
    2 ~& i6 w" V3 X! B8 }4 u+ U
  49.     delete ymodemFileTransmit;" E1 X1 S6 {# A: k7 ^
  50.     delete ymodemFileReceive;
    8 j! p2 X' x; B
  51. }% v" `. E4 q1 e* E. ^
  52. , J! i5 u. F3 r: N8 I+ V$ `' U
  53. void Widget::on_comButton_clicked()
    ! j. g8 b6 L1 r7 ^* G: l
  54. {6 i' g) M9 e/ p- D. C7 T9 J5 ]* t
  55.     static bool button_status = false;
    * M/ ]5 M# q. F. l

  56. ' M3 V: o( f& c& B" O$ P
  57.     if(button_status == false)% i$ m$ \  K7 e1 L7 |; e, Z( ]9 D
  58.     {
    ) R; E* G7 N! P3 d
  59.         serialPort->setPortName(ui->comPort->currentText());
    * {) X% c, l) Y
  60.         serialPort->setBaudRate(ui->comBaudRate->currentText().toInt());
    $ y( r$ g0 B& k5 b6 `

  61. 4 N( h) Y; J; K3 k
  62.         if(serialPort->open(QSerialPort::ReadWrite) == true)  ?' ?& p( _9 `: r( g
  63.         {
    ; V7 i7 e5 `, }
  64.             button_status = true;  V: E+ j& ?8 }) y: K
  65. 3 A, g+ {9 `3 ~; Z( G
  66.             ui->comPort->setDisabled(true);
    0 S, {. ]$ b" e
  67.             ui->comBaudRate->setDisabled(true);
      ~6 Y$ o0 ^% Y! l/ `8 o' q2 j$ ?
  68.             ui->comButton->setText(u8"关闭串口");
    % x5 f0 e1 Y# ?, a- p1 n' V" M
  69. ! N* n& `6 J6 z. v5 u, Q! e& j
  70.             ui->transmitBrowse->setEnabled(true);
    5 u: Y% T, X6 h7 H; o# P
  71.             ui->receiveBrowse->setEnabled(true);' f( Q+ c9 @; u7 E. p

  72. 8 b( j) g. V. W8 N
  73.             if(ui->transmitPath->text().isEmpty() != true)$ ~" N9 ~3 N2 ^$ d" K- y
  74.             {7 d  {2 o7 F8 R$ D( H: c
  75.                 ui->transmitButton->setEnabled(true);
    . B. c/ ^% l0 f4 B- o: k2 v
  76.             }
    : Q+ Q; x5 @. s+ f

  77. + y$ K: I. V- T; f3 q8 U
  78.             if(ui->receivePath->text().isEmpty() != true)& U- |) g; Q2 Z# O
  79.             {: n. c( W5 D: S2 L8 R  Q1 ^1 `
  80.                 ui->receiveButton->setEnabled(true);. |5 k( b6 g6 Q# P* V
  81.             }
    ( c  u, C6 ~7 ]9 s$ j$ U$ }
  82.         }3 S8 |" J: ]4 J# J7 `
  83.         else
    ' U5 y! {8 p9 T
  84.         {
    0 T& R* z- ?# F& f: _8 v6 [
  85.             QMessageBox::warning(this, u8"串口打开失败", u8"请检查串口是否已被占用!", u8"关闭");& y/ U; Y8 `4 y4 x, c, O/ K
  86.         }
    4 g/ i( D( Q4 e
  87.     }1 a8 ], m3 f7 M( I; C
  88.     else, p9 ~3 Z- D7 s* ]# ^) @
  89.     {; D9 V* R4 X* {/ K2 b8 l
  90.         button_status = false;& a/ ?- `2 |$ Z  L% u

  91. - R* }! Z# d6 M2 J
  92.         serialPort->close();2 U6 c1 Q2 r: _) f( p! `  n4 G9 }
  93. . I" V9 f: @/ G. v6 S- p& K
  94.         ui->comPort->setEnabled(true);
    $ ~1 r5 s1 y9 _
  95.         ui->comBaudRate->setEnabled(true);# M: h) @. ]& @: d$ K5 I/ ]+ g" z
  96.         ui->comButton->setText(u8"打开串口");
      E; m- R1 H$ P' L
  97. 4 e5 r: R$ N% \9 m! C1 X
  98.         ui->transmitBrowse->setDisabled(true);+ e+ _& B8 V7 }  i" H5 D2 a
  99.         ui->transmitButton->setDisabled(true);; a! _$ y* F0 K6 C( g* a7 I, ?

  100. 4 v; W3 g3 M& S. S/ G
  101.         ui->receiveBrowse->setDisabled(true);4 A2 k% s$ n3 R2 ]0 O
  102.         ui->receiveButton->setDisabled(true);5 k- b; f5 Q8 X8 w+ R2 t
  103.     }3 J- W# Y$ ^; F" t# @- ]
  104. }
    / ~$ m+ y& R; k3 \
  105. " G; O3 o/ S7 R0 {; v6 k# V
  106. void Widget::on_transmitBrowse_clicked(), g: A% o0 H1 v9 A3 |0 s. k( X
  107. {
      x! Y: M3 L/ a( k6 k8 ^+ y  O4 R
  108.     ui->transmitPath->setText(QFileDialog::getOpenFileName(this, u8"打开文件", ".", u8"任意文件 (*.*)"));
    ( [$ v: |/ A; E/ T) f- i  j

  109. 5 `. |) ^+ l. W2 y' Q) {
  110.     if(ui->transmitPath->text().isEmpty() != true)5 u2 i: x, L6 q  }4 J
  111.     {
    6 e1 v. h5 q9 S/ K* G- B
  112.         ui->transmitButton->setEnabled(true);2 |* W5 A) d' R' @$ `  L
  113.     }
    7 R4 I5 _2 Z3 }' a
  114.     else+ N/ c) @9 y) z7 q& @3 `
  115.     {
    / P0 R! s1 K6 z& Z
  116.         ui->transmitButton->setDisabled(true);; X1 T8 N& d' `
  117.     }
    / G: d. @3 V# e. q* |/ B  P7 W
  118. }2 ?" m: [- v5 N* J) u4 N
  119. + C' W' ~" E" F5 v
  120. void Widget::on_receiveBrowse_clicked()
      P) p! i- z1 W* |1 o. O
  121. {5 T( A4 q- {8 c8 q3 ~8 n+ D
  122.     ui->receivePath->setText(QFileDialog::getExistingDirectory(this, u8"选择目录", ".", QFileDialog::ShowDirsOnly));
    * U; ]" ~2 V* Q1 Y7 b6 E) P
  123. $ i$ @5 Z( ?- `# Z: `2 V9 H
  124.     if(ui->receivePath->text().isEmpty() != true)
    9 z- c2 c& x3 f" K+ y$ h3 P
  125.     {) |  H! H$ u+ f. y
  126.         ui->receiveButton->setEnabled(true);
      Z+ @& m3 Z' u1 Z/ }
  127.     }* _* L/ h! y: Y, j
  128.     else6 E* ]9 [" {% P# A. H% C1 {
  129.     {
    ! x6 s+ E/ p) H" ~2 U# b4 d2 ]
  130.         ui->receiveButton->setDisabled(true);# h2 B" M, H/ o  t4 V
  131.     }
    / G/ ^2 j4 {  R$ G( e! ]) I
  132. }4 O) D, t0 G/ h+ c- \" O& h- s

  133. * u5 D4 o2 V: W. D* l
  134. void Widget::on_transmitButton_clicked()6 x% `+ W0 H- S- G9 {# L& |3 x
  135. {
    7 Q7 \# {: A; L) O6 i$ e
  136.     if(transmitButtonStatus == false)* S! M0 F) l3 r/ V" {
  137.     {
    1 c. _$ v9 `$ W1 o7 y- v
  138.         serialPort->close();* O9 U* m$ _2 |/ w  _# J/ g9 H
  139. 4 U/ D" Q9 w# G4 [! @3 s( b
  140.         ymodemFileTransmit->setFileName(ui->transmitPath->text());- [4 B. y- O' V+ |& ]) w, X: ]+ h
  141.         ymodemFileTransmit->setPortName(ui->comPort->currentText());$ @9 i9 p* i* O$ H" u' q
  142.         ymodemFileTransmit->setPortBaudRate(ui->comBaudRate->currentText().toInt());
    ) ]8 J: X1 c. r/ B) {5 |# l
  143. 2 T; F# j/ \) i0 Q
  144.         if(ymodemFileTransmit->startTransmit() == true)" R0 C0 O. Q* g( u7 M
  145.         {
    4 O& ]) W8 y' w0 m7 t6 f
  146.             transmitButtonStatus = true;3 P( U, P5 J' V8 f" t  K

  147. ( d$ c! Y- o  P! d' z
  148.             ui->comButton->setDisabled(true);. I3 ~7 W6 H9 r; c
  149. 6 y' o& P' f8 ]! q# f
  150.             ui->receiveBrowse->setDisabled(true);- F8 s" g; K7 S, L
  151.             ui->receiveButton->setDisabled(true);9 e3 X! r" q) w! C4 g# `- ?& Q. }
  152. 9 W& D  B* c2 I1 q3 X6 m$ i
  153.             ui->transmitBrowse->setDisabled(true);) ?9 N4 s; b+ k- q( t7 z% k
  154.             ui->transmitButton->setText(u8"取消");
    % k6 [, N, t4 M$ J# w, J
  155.             ui->transmitProgress->setValue(0);: t  _4 A* D) C8 J" |$ s- _
  156.         }$ l- x2 m; r& Z
  157.         else
    2 H: \4 {* A( I5 O2 G, ]
  158.         {; t: t, k2 N8 O5 H, Q% c' Z
  159.             QMessageBox::warning(this, u8"失败", u8"文件发送失败!", u8"关闭");
    0 F: X9 @2 b- O3 \2 S" ?! M
  160.         }( ^& o7 X; L4 g% h# V  S: ]' y
  161.     }
    1 d5 D1 p* |2 k* u4 X# g3 A
  162.     else
    $ g7 B4 q; X/ Q% z5 q
  163.     {7 f: n) Y* F) W/ e9 ~0 R2 }# e$ T
  164.         ymodemFileTransmit->stopTransmit();. u% c  R8 h+ k$ |) v' C
  165.     }
    " P+ C9 B# X9 |- `$ t- q- U
  166. }
    5 i0 ^* b4 Q0 \# Z: z

  167. / x5 C) ~( z7 g3 X0 _0 \
  168. void Widget::on_receiveButton_clicked()# z8 F: m( M  ~2 X
  169. {/ e/ z% Q, L. g# o
  170.     if(receiveButtonStatus == false)6 D% @7 h8 j3 W
  171.     {) M- J+ u  Y- A/ e3 H
  172.         serialPort->close();
    # O' `6 t7 k1 Z; U4 ^0 j% D% F

  173. & Q! c: i, s" ~
  174.         ymodemFileReceive->setFilePath(ui->receivePath->text());/ X* t8 W: p2 w
  175.         ymodemFileReceive->setPortName(ui->comPort->currentText());
    : c+ w6 X/ ]5 Q4 m) n! \
  176.         ymodemFileReceive->setPortBaudRate(ui->comBaudRate->currentText().toInt());
    9 F3 ]5 U1 _7 c5 P" L: j

  177.   z# M& R# Q  W( F' X& n4 ^  r
  178.         if(ymodemFileReceive->startReceive() == true). E4 e3 m! j% g/ F( {9 Y* Y2 F& H
  179.         {, n, ^' I* D& a8 g- n6 a0 }; ]; U  r
  180.             receiveButtonStatus = true;
    ; b0 {5 D8 a5 Q- q
  181. 0 |. d6 B! I* n8 x2 Z
  182.             ui->comButton->setDisabled(true);
    7 J+ q. Z& `! p- u2 x4 d

  183.   e; ~0 u/ T! [( U3 i
  184.             ui->transmitBrowse->setDisabled(true);3 c! s- X: ^$ y# Y0 i2 U
  185.             ui->transmitButton->setDisabled(true);
    % n0 Z4 c1 ]. g1 t$ d

  186. . `( G8 d7 M2 l. W0 L  M
  187.             ui->receiveBrowse->setDisabled(true);, d$ _6 s& T, i
  188.             ui->receiveButton->setText(u8"取消");
    1 e4 w- i: S5 h4 x7 R0 T% a" y
  189.             ui->receiveProgress->setValue(0);
    4 m+ Y. y0 K! w
  190.         }! o% V5 }: [  o5 ?9 \/ ]5 m
  191.         else
    8 S: |! M+ D5 ?& c0 ~
  192.         {' X, B: H. Q" ~) p/ |
  193.             QMessageBox::warning(this, u8"失败", u8"文件接收失败!", u8"关闭");: b1 Y2 f3 y8 V; |8 ]; K: Z" d4 x
  194.         }
    2 Z4 R5 z3 l9 k8 Z! F
  195.     }
    # v$ j1 r6 r) F2 F: ~
  196.     else
      G% ]" D; M  R
  197.     {, s7 m- y. V0 i" d! y; i
  198.         ymodemFileReceive->stopReceive();
    ' b: G1 x7 Z, M: [
  199.     }
    " e  Q+ j8 Q' l7 K
  200. }. g0 {( ?4 x! l: l% r
  201. . ^' K) N7 t1 `. m
  202. void Widget::transmitProgress(int progress), @5 c' o9 h! @9 [- o, u3 S$ `
  203. {
    " G* F! D( J$ b( z# k
  204.     ui->transmitProgress->setValue(progress);
    / M# S& c3 K; D# ^' |9 X
  205. }5 c* G7 `! @' A

  206. , g5 S+ c, z9 O2 g" N+ G# S
  207. void Widget::receiveProgress(int progress)
    : E  X* u1 l) D% O0 O
  208. {
    ) m$ C( F* J. H- ]' c$ o
  209.     ui->receiveProgress->setValue(progress);
    3 I; h4 y" m7 x" j( w
  210. }2 W' H$ K" b9 W" ?8 t

  211.   W# v* f: Q) Y) n$ ]" \
  212. void Widget::transmitStatus(Ymodem::Status status)( {8 p) o, l: q# o, R* t* i
  213. {
    $ e5 ]3 k) Q* W% t
  214.     switch(status)9 L5 P8 }& A" e% c6 `1 z
  215.     {
    / n& |: n) `- a% y
  216.         case YmodemFileTransmit::StatusEstablish:
    8 Q- u9 G' I0 n- Y! _5 n' [7 S
  217.         {
    0 o! S/ i0 T) z% V( c; W& g
  218.             break;2 d! L4 l: \2 F
  219.         }
    & h# v& A: a+ T# N8 ~: H; B
  220. 3 p5 C  X  I" W! j+ n* f* \' |
  221.         case YmodemFileTransmit::StatusTransmit:. K- d/ s& w' A
  222.         {. ~8 X$ Q; ]8 ~  m; Z8 P0 r- x
  223.             break;
    - X3 @) s, p3 l/ t! X% ^
  224.         }  v; W" B# G2 U; ]) J: ~
  225. " e8 \. R) s) Q; S4 ]
  226.         case YmodemFileTransmit::StatusFinish:
    ; _) W; x  q# p
  227.         {
    : e7 `8 f" f8 s, f/ P8 i
  228.             transmitButtonStatus = false;
    : t" a* T, u1 @1 c7 z. ^+ x

  229. 2 H: Q: u$ H8 N& o" _: l  j
  230.             ui->comButton->setEnabled(true);
    6 C9 T8 P; X: \& O" W# v6 a

  231. . S8 c9 C9 C4 B  _5 |
  232.             ui->receiveBrowse->setEnabled(true);
    ' H; l. k$ p: k% i9 \
  233. 1 g! }1 u& V# u9 A# E
  234.             if(ui->receivePath->text().isEmpty() != true): E/ \: ~. ]  U: f, K4 w+ ?
  235.             {
    7 C4 j* L, d5 d+ A6 ^9 c$ U
  236.                 ui->receiveButton->setEnabled(true);" ?  D* u6 {, Y) N# q
  237.             }
    ( Z: e* ]8 O& w3 x
  238. 2 N+ V* S+ G2 F; n
  239.             ui->transmitBrowse->setEnabled(true);7 z1 y/ L4 U/ ~3 e: E8 X0 G
  240.             ui->transmitButton->setText(u8"发送");
    % H5 h" |. o; _$ [' E+ u
  241. - |7 A0 C% I% `( j# r
  242.             QMessageBox::warning(this, u8"成功", u8"文件发送成功!", u8"关闭");
    / ~3 I& K4 z1 k" L+ u( j
  243. * ^1 t5 f6 a# H& n' m
  244.             break;
    # w) X# N! S: I% @4 n# V/ z6 L
  245.         }
    7 r. P! x3 Q0 w3 O

  246. ' h( x" v. p2 n, Z: {0 E
  247.         case YmodemFileTransmit::StatusAbort:
    2 o  H2 f, {5 a, I; O2 R. l( E$ H
  248.         {
    8 l! {! N1 C, C" S. ~. o8 d, {% ]
  249.             transmitButtonStatus = false;! R( a5 a$ o1 r) q$ {" t
  250. & W# I9 ]; C& l# U4 q+ I! |
  251.             ui->comButton->setEnabled(true);8 M4 C5 d; S) c; M% f1 z. _6 V- w

  252. * v/ H4 d3 r. l& r. P
  253.             ui->receiveBrowse->setEnabled(true);9 G0 p9 {/ T: w/ u* J# u) c

  254. * w. a5 o6 Y  G) m
  255.             if(ui->receivePath->text().isEmpty() != true)
    1 _9 `, o6 ^; S6 l$ {0 J
  256.             {
    " c+ {4 S- o7 ^$ q
  257.                 ui->receiveButton->setEnabled(true);  [1 }/ R3 }: D7 [. d" {
  258.             }
    6 R4 ^- V; C9 e9 e& q  d

  259. & |5 S! u# O2 ^2 z. S- m! ]3 G4 y7 y
  260.             ui->transmitBrowse->setEnabled(true);" c* t9 i1 B/ j8 H
  261.             ui->transmitButton->setText(u8"发送");
    9 f% ?! f6 w4 V& u  T" v! s
  262. / w$ V3 O4 U+ C4 r1 ^6 a! a; G2 \
  263.             QMessageBox::warning(this, u8"失败", u8"文件发送失败!", u8"关闭");
    9 N5 s( A& }( r6 h

  264. 8 L! w6 S# d9 ]/ ]7 t3 n" |  Y
  265.             break;
    6 L* i/ O% N) W- S8 r
  266.         }5 }7 y6 b9 L4 j, [& `( K+ j

  267. ( B# p* p4 K7 ]* P1 T
  268.         case YmodemFileTransmit::StatusTimeout:
    7 G9 Y6 v& Z* ^7 L4 c1 [
  269.         {0 H* t1 G- x- \0 T, t4 B1 W
  270.             transmitButtonStatus = false;* W+ b! V5 N! ^# K: q
  271. ; h* y" c  z) h
  272.             ui->comButton->setEnabled(true);4 S2 j  U: C% ]$ {& T4 _; n
  273. ' {6 q. G/ B- k7 O) \) ?
  274.             ui->receiveBrowse->setEnabled(true);
    ! j, K+ r- `8 U; s
  275. - y6 l7 X" N, R0 K4 l3 d3 ]
  276.             if(ui->receivePath->text().isEmpty() != true)5 L7 e& z; n4 H# u; o# S
  277.             {! s' V7 w% B* H/ Z* f7 m" ~
  278.                 ui->receiveButton->setEnabled(true);
    # w3 V4 R, n: `# I/ E: [6 I3 l. H- W* X
  279.             }. Z+ K1 D$ s6 F
  280. " b/ w& ?/ S. h8 ~
  281.             ui->transmitBrowse->setEnabled(true);! U; }4 E0 v; R* j) p  W  ]4 n
  282.             ui->transmitButton->setText(u8"发送");
    3 I$ N* @$ v' y2 w& W7 K  x
  283. : B" A8 Y9 W8 K* ~" L, y
  284.             QMessageBox::warning(this, u8"失败", u8"文件发送失败!", u8"关闭");
    9 V" d% z+ y7 r! L& p
  285. , N2 a% w8 m3 v& D
  286.             break;- ~, j8 E; V& I* m9 q, L
  287.         }1 A# G0 R$ F4 M1 \1 i* X4 H
  288. 2 N6 H* z+ @6 y. G* a+ U) {
  289.         default:
    7 s( x- {. c% m, X
  290.         {: X; [) E; a5 s& T$ |( d) O
  291.             transmitButtonStatus = false;5 ^1 T! r% o( w; B1 t- E
  292.   e& y0 Z5 K) c0 N6 S9 L8 Q# @8 Z
  293.             ui->comButton->setEnabled(true);! P( T* e. P) g2 y' g9 ^
  294. , m$ ]0 k7 j! U$ U
  295.             ui->receiveBrowse->setEnabled(true);) H1 T" y; ~% b3 ^( m$ V
  296. 5 f8 b5 j7 T1 i) y- ]$ @2 t
  297.             if(ui->receivePath->text().isEmpty() != true)
    6 Q& {3 X  v5 T) U& a2 B4 f
  298.             {- |. R& g9 B! o7 @
  299.                 ui->receiveButton->setEnabled(true);
    / Y& K2 |/ k5 ~" A5 ?4 z0 y, i$ {8 C
  300.             }
    - f& C; q3 G# Y1 `. J
  301. ! j% P! J5 e4 q: @) P' B+ Y
  302.             ui->transmitBrowse->setEnabled(true);
    ' o. N/ X" t) ]6 z2 o3 G9 R0 w+ A
  303.             ui->transmitButton->setText(u8"发送");
    4 r9 Q5 a8 N- e8 w$ s

  304. ) G( j9 i; {; t& O" J  Q# `
  305.             QMessageBox::warning(this, u8"失败", u8"文件发送失败!", u8"关闭");
    ! s2 |4 f0 V  @8 D
  306.         }' G$ e: H" A) S7 g. \
  307.     }1 S2 a. t: Q/ |
  308. }: [- l  Y3 t+ {3 U6 e

  309. 9 [' @2 B. t0 t* t
  310. void Widget::receiveStatus(YmodemFileReceive::Status status)
    : P2 e& {& q: U; L, M, ^$ ~, A* b
  311. {
    & z# [3 y) f  w3 k9 ~
  312.     switch(status): e0 d. Y$ F( A  r6 I- ^! f0 y
  313.     {
    - }. o8 S, ?2 d9 p, q# u/ z" s
  314.         case YmodemFileReceive::StatusEstablish:
    8 I6 b: M" q" K- {, q. Y% |, c4 T
  315.         {
    6 g% k+ |; }0 F0 x
  316.             break;/ O& ^! n1 W, ^2 W8 y  d7 f
  317.         }& [" M0 ^# H& ~/ t, z1 u
  318. 9 l. I( u8 J; a; m2 s6 g
  319.         case YmodemFileReceive::StatusTransmit:
    & m. X1 |6 [+ D
  320.         {
    + F7 [( E5 M  C! l3 W0 l- m; y* t
  321.             break;# t  {% C- N3 a5 A
  322.         }
    ( R' D) Q! Y% h* G

  323. ) q) W7 a; a/ d% D* R5 i- x& f2 c3 C. R
  324.         case YmodemFileReceive::StatusFinish:8 M2 M# s0 x5 l4 J0 G  z
  325.         {
    : G+ {: U7 i4 V3 O! V( n
  326.             receiveButtonStatus = false;
    + n- K' v3 r/ R8 J, F9 u

  327. % `* i' B- N7 I
  328.             ui->comButton->setEnabled(true);
    4 ?2 }% R7 I1 y
  329. % u( b2 W4 H! T2 R% V  p
  330.             ui->transmitBrowse->setEnabled(true);
    2 `+ C0 q9 M& c6 P( U! @; Z

  331. 0 D$ m. R* W  I6 w4 W. w% Y
  332.             if(ui->transmitPath->text().isEmpty() != true)
    ' S- p, N6 \* e% a% x
  333.             {
    4 A0 V4 W3 G3 S- A7 k( G& I
  334.                 ui->transmitButton->setEnabled(true);' J1 W1 A1 F) s9 c/ X9 F( i
  335.             }, l. ~; u2 E* r  S

  336. ( |. ]+ b1 A* T- g
  337.             ui->receiveBrowse->setEnabled(true);  p  V/ Q- v, [
  338.             ui->receiveButton->setText(u8"接收");  A6 b+ E8 @+ J8 j4 P" L3 ?

  339. : R4 y4 ^% o9 o. e* J2 [0 @
  340.             QMessageBox::warning(this, u8"成功", u8"文件接收成功!", u8"关闭");9 F- @" p  h) L. N7 L' n: n

  341. 7 t) f4 b6 h' ^4 J  Y
  342.             break;: X) n+ x$ T  F  g# p
  343.         }# h7 I) ?# w7 G, h: S  A3 t

  344. ! |  _6 j* {# ~' b7 q: s9 G
  345.         case YmodemFileReceive::StatusAbort:* N8 A* A! Q/ O# g' g% P3 e
  346.         {
    8 ?! G2 n1 t- z6 R
  347.             receiveButtonStatus = false;( x" o1 h. Z5 Q  @7 r6 H

  348. + h6 }: C' h9 q2 K- v1 G5 H/ B& M
  349.             ui->comButton->setEnabled(true);
    ' P* _, [" f0 i" E

  350. $ F9 E: D. P5 y. P2 a
  351.             ui->transmitBrowse->setEnabled(true);
    9 K6 c6 i1 t! X0 \' ^
  352. 3 ^0 I  ^9 I, Z# N/ j1 [
  353.             if(ui->transmitPath->text().isEmpty() != true)
    0 W, _# Z4 s4 v. b! M% g- U8 Y8 @
  354.             {
    + `- U) U' H" O1 D4 V% `1 k
  355.                 ui->transmitButton->setEnabled(true);2 _% F% e0 ^# k0 l% D0 ?( {
  356.             }
    ) ]# d, H0 L  C4 y
  357. 2 W- i, H  m+ v1 t8 V) @
  358.             ui->receiveBrowse->setEnabled(true);
    # A, V" \7 X5 `2 g. H) W
  359.             ui->receiveButton->setText(u8"接收");
    4 R& l0 R, T* j1 O# v
  360. 2 @/ w+ s  S, f8 E) s
  361.             QMessageBox::warning(this, u8"失败", u8"文件接收失败!", u8"关闭");: s; ^/ ?# M" p* y6 \

  362. 6 _7 `' j, J+ W7 `3 b4 E- Y! H
  363.             break;
    + B* O8 v4 Q" U% y9 }8 g+ ^
  364.         }
    6 }! M1 o: ]% |  C1 o8 K8 U3 \
  365. 7 Z0 n' d0 E$ v: `! e. U3 J
  366.         case YmodemFileReceive::StatusTimeout:
    5 \3 t5 u4 I8 ^# Z8 |
  367.         {2 e% X* e; Z, h
  368.             receiveButtonStatus = false;5 @) t! E' b2 u$ |) u- ^2 n3 s; F

  369. % c# M- i% v8 @# m% V5 a2 f* y
  370.             ui->comButton->setEnabled(true);
    0 Z2 S# w( u. a2 m  `% M$ y. Q
  371. 8 y* X& s& Q* O0 b& X+ v) T; w
  372.             ui->transmitBrowse->setEnabled(true);
    - e! Q- f+ S+ y( H6 F
  373. . Q5 Q6 b. \$ |. Z
  374.             if(ui->transmitPath->text().isEmpty() != true)
    4 o2 ^  X: F2 B) c2 o% [) v' _
  375.             {0 j& t3 \3 R8 o) K. d" V
  376.                 ui->transmitButton->setEnabled(true);
    # q, w4 r' W, J+ W2 H2 b- ^0 m
  377.             }3 b& f2 [' h+ [, }) Y
  378. 8 U% G) o* ?& U! j) i1 a: a, O% b
  379.             ui->receiveBrowse->setEnabled(true);
    # |8 h+ N8 Q# J2 }' G/ g
  380.             ui->receiveButton->setText(u8"接收");1 W4 i" c7 [+ _  f' p

  381. : ^- ^- \5 |, ^* T5 d
  382.             QMessageBox::warning(this, u8"失败", u8"文件接收失败!", u8"关闭");3 [) ^7 u* q2 Q; @
  383. . B$ \8 S" }- X  p# l
  384.             break;
    * T- h( r" p4 ]& k  Z0 K
  385.         }
    , L$ O9 d( J$ Z! E+ S7 E

  386. % `  C- e& y5 o& l! V
  387.         default:
    , J- u* T. {) Y* P9 C" i# Z6 I% D+ y
  388.         {
    ( W* ~2 H1 C' n' u6 j
  389.             receiveButtonStatus = false;
    " r5 T3 v: _0 u* A

  390. 6 N' ]( {$ |) M4 _& i5 h! b$ r! r0 K
  391.             ui->comButton->setEnabled(true);9 Y/ M0 L& t/ f' ?1 i

  392. / a  S; n) |) K- H
  393.             ui->transmitBrowse->setEnabled(true);
    ! C& b! S% J0 R, R! m, T
  394. % R+ H, j0 ]1 Y" Z
  395.             if(ui->transmitPath->text().isEmpty() != true)
    4 B  g$ I: `! d" S
  396.             {
    ; f) f4 r' Q. y8 z5 d, v, n
  397.                 ui->transmitButton->setEnabled(true);
    # V! W' N' k! V5 u$ ^! }: A# S
  398.             }
    . x; R9 R: f1 v, k* k5 G4 B
  399. 0 A2 N% f8 T  \% z
  400.             ui->receiveBrowse->setEnabled(true);0 \8 _6 P" P; `; C% d
  401.             ui->receiveButton->setText(u8"接收");$ @* {) K& k3 \- t- Q' @3 k

  402. 5 h0 t( B- R+ G5 t' \
  403.             QMessageBox::warning(this, u8"失败", u8"文件接收失败!", u8"关闭");1 ^8 h  S, s/ a: K! H  x( A9 _+ \
  404.         }
    - t2 q5 w& Y9 d
  405.     }% c$ x5 l+ b( F' N& s
  406. }
      Y% `' C9 Y8 n5 U/ y
复制代码

% ?3 X5 j! O# P6 n% v9 Z
" X& @* J  ^+ k
( @7 a5 Y0 ^" h' N2 y: `; ^/ j0 W
8 d2 _" W$ C& v3 T: Y) Z9 }! \' j& Y, i
" L/ ^3 [6 X6 c0 s8 t7 ~3 c
XinLiYF 回答时间:2018-3-6 22:32:40
      main.cpp文件
1 c& Y# u' u( y+ J
  1. #include "widget.h"
    / v: |% }; {) s9 e8 B  n1 Y
  2. #include <QApplication>
    6 o# ]: L: B% r5 p7 `* r2 R! n
  3.   j) w+ @6 J# Z( o) c- S7 q. j8 a
  4. int main(int argc, char *argv[])3 T, g6 {2 Z* g* l
  5. {
    + L3 N8 @( x' s! a4 `+ `
  6.     QApplication a(argc, argv);3 _4 O6 z" o+ A: n
  7.     Widget w;
    " U7 \2 g' y: G! L; I! C' B& s
  8.     w.show();
    # ?4 B* J! R9 f" h6 A
  9. % L8 u7 K% f7 w$ r7 X- M
  10.     return a.exec();" ~. @4 r( f8 t' A2 h; u
  11. }, \( h  w, M# ]1 h4 I
复制代码
0 w  K$ ?. |6 h* }9 [, `7 F- A
      SerialPortYmodem.pro文件
9 _) A; O' b% Z
  1. #-------------------------------------------------
    : S2 O, l' ]8 L/ v
  2. #: X7 ?5 K2 ]. Y) j2 y
  3. # Project created by QtCreator 2018-01-20T23:00:46
    : o8 ?- Y8 U) n& @& q0 ~/ g
  4. #! T' }: T! q$ f
  5. #-------------------------------------------------
    . h9 @1 `: V1 U* X+ L6 e3 V- U
  6. + v+ z6 F1 S) i# J
  7. QT       += core gui
    & l" S; P7 C+ a3 W) r0 G% f
  8. QT       += serialport6 J4 H; [+ n1 t

  9. ' M' D5 Y2 x, j; d% P  F
  10. greaterThan(QT_MAJOR_VERSION, 4): QT += widgets3 M; q( V9 b+ C5 ^, Z# _
  11. , B/ M# l0 ~$ D2 U8 P
  12. TARGET = SerialPortYmodem) {9 Q% }8 E$ Q2 h
  13. TEMPLATE = app5 F3 h$ P  |- Y) O
  14. 6 Q0 g- t, M; b9 j8 A
  15. # The following define makes your compiler emit warnings if you use: c7 w1 w  q& }* X  {5 j6 F  R( ]
  16. # any feature of Qt which as been marked as deprecated (the exact warnings# I+ ?# J8 M: C$ l" _. ~4 v
  17. # depend on your compiler). Please consult the documentation of the
    ( q3 j/ j! r3 X7 o( I
  18. # deprecated API in order to know how to port your code away from it., [2 p! c* o* R* a; f; V% K' O
  19. DEFINES += QT_DEPRECATED_WARNINGS5 l; Q; a  N, i
  20. 2 P7 R+ K; C0 X, @- W
  21. # You can also make your code fail to compile if you use deprecated APIs.
    ; C( S, y! n2 z" ?5 y% C
  22. # In order to do so, uncomment the following line.
    0 T2 t  ?$ E* s& Q) b( M
  23. # You can also select to disable deprecated APIs only up to a certain version of Qt.
    ; F/ B% p7 H6 P+ }* i
  24. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0+ |: H, g3 t0 ~9 y# r# F' p* I5 t

  25. ) w% J! i! k1 ?
  26. : d$ R/ A6 k. K; R8 ?
  27. SOURCES += main.cpp\
      l5 _4 t. ^9 b- Y, Y3 J
  28.         widget.cpp \
    + h$ c9 B8 U: ]) ?8 Q! ?! o
  29.     YmodemFileReceive.cpp \& R0 u* V; Q0 U8 U' |) i! r& l
  30.     Ymodem.cpp \9 t; P# Q( x9 `. l& T6 T
  31.     YmodemFileTransmit.cpp7 W9 l/ {! ?+ ^# Q: l/ @
  32.   G! X: W: S4 U8 L3 j
  33. HEADERS  += widget.h \
    * F, f. J) B8 w+ b7 M6 v3 \. v
  34.     Ymodem.h \
    2 b* }. o3 E$ X- v* [( P
  35.     YmodemFileReceive.h \9 n# k) z! N. c$ q0 w9 C+ B/ X
  36.     YmodemFileTransmit.h' v& s" Z3 Q2 r  U

  37. - ~6 ^4 V, m" q! j" F) R
  38. FORMS    += widget.ui1 t6 p7 a2 ^0 B; e. m) A2 Z  x: j
  39. : L# f8 ], X$ y! Q% D
  40. RC_ICONS = SerialPortYmodem.ico; ~* W4 U7 @; \0 L: d
复制代码
3 B) e6 Z: o( j
      SerialPortYmodem.ico文件0 u% l% E+ J# e, L, N4 g/ {

5 s) ^/ d: Z5 H8 {6 s4 z4 P) i' o3,运行效果
/ m* K  O9 d5 f# V4 ?: Z

( z0 _* L8 Y4 `  }
$ h' _# j1 P. p, R0 f
# W2 z, A! ^# v6 m& U' O4 M6 Y$ B" d; B
XinLiYF 回答时间:2018-3-6 22:33:09
可以用来做用户程序升级的上位机软件。GitHub仓库有工程,还有资料。
anobodykey 回答时间:2018-3-7 09:21:37
感谢楼主分享
shuihehe 回答时间:2018-8-13 15:37:45
网络在线升级的技术资料呢?
any012 回答时间:2018-12-19 14:03:21
请教,单片机端如何处理呢?
XinLiYF 回答时间:2018-12-22 17:06:17
any012 发表于 2018-12-19 14:03
- X3 g2 p1 ]. u+ G请教,单片机端如何处理呢?
( a3 }/ s0 K- }6 z
可以移植到单片机上,文件的接收和发送都支持。
Kevin_G 回答时间:2018-12-26 09:46:05
收藏
huangchao09 回答时间:2019-3-24 20:37:59
多谢楼主共享

所属标签

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