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

YMODEM协议串口文件传输

[复制链接]
XinLiYF 发布时间:2018-3-6 22:28
YMODEM协议串口文件传输
GitHub仓库:http://github.com/XinLiGitHub/SerialPortYmodem2 f4 C* u$ l2 c
PS:博文不再更新,后续更新会在GitHub仓库进行。
% P3 D7 l/ y; c
' |- H4 N4 C/ c3 b: l  d: b* _
! [* A" `. Z( f
    串口通过YMODEM协议进行文件传输。程序中涉及到YMODEM协议知识,详细介绍见维基百科[YMODEM](http://en.wikipedia.org/wiki/YMODEM)。
9 M% \& c5 f, C4 R$ }) `) ]8 ?+ D" L1 ?: n6 \* H" P# F1 J/ w
1,开发环境0 L+ |, v4 r- H6 n- T! ~  B
      1,框架:Qt 5.7.10 q' {5 s" M3 q/ _
2 G( k$ h6 |: ?. i, H+ O* a
      2,编译器:MSVC2015_64bit
1 @- B- \, B8 g# g8 q
$ k% |0 A" ]5 v* h( O6 [1 k
      3,IDE:Qt Creator 4.2.0 社区版
% x2 N9 M: z/ X7 V$ P; }+ Y0 ~      4,操作系统:Windows 10 专业版
0 x2 n9 Q6 O* ^( q2 ^6 i4 T5 p2 ]' o# w  q) V8 O3 b
2,程序源码
: t7 w" Z: ^7 O5 f* K      Ymodem.h文件
5 |% d8 [4 s, ?4 `! |" R
  1. /**: d2 c5 P7 T/ @! @. c1 ]
  2.   ******************************************************************************
    7 A8 f( \$ v" V
  3.   * @file    Ymodem.h+ ?3 C2 A6 a( }5 q2 _! f) R/ Y
  4.   * @author  XinLi+ q- p! Y1 F; [% C4 m; {0 M$ H1 @
  5.   * @version v1.0$ x$ X+ L$ M& K+ z6 ~4 Y/ J6 n7 M6 j
  6.   * @date    21-January-2018
    + }% \* s7 L, @$ l1 w
  7.   * @brief   Header file for Ymodem.cpp module.
    & G4 ^, {8 q4 k/ \) c5 ^& K
  8.   ******************************************************************************2 _) u! W4 t* _# V3 D6 F
  9.   * @attention
    5 ]! z$ y4 Y2 ^2 U& o
  10.   *; G/ v. E8 n9 N( _5 [
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>
    ; M; X: ^1 ]! |- d# B7 F; o* S! c
  12.   *
    1 C& v1 S% w% d# x6 m3 S( m8 V
  13.   * This program is free software: you can redistribute it and/or modify/ T" x& e1 j' B
  14.   * it under the terms of the GNU General Public License as published by
    ( p3 e& H" J  k) ~' H( }
  15.   * the Free Software Foundation, either version 3 of the License, or
    # X% }& L$ s' i1 @
  16.   * (at your option) any later version., E0 g* H% z: z, {1 G& j' _
  17.   *
    ! M. F! G3 G- ~9 Y6 y% s( h
  18.   * This program is distributed in the hope that it will be useful,  j6 w5 V; |, Q: K' r+ g0 f2 f! m# u
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    # J  B3 ]* d" M$ I* N3 q, D4 V
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    ( L6 z4 e8 i  Z6 J( Q  r1 o
  21.   * GNU General Public License for more details.
    8 w+ d- k) t1 F1 B# [2 P
  22.   *
    & |* I5 h% Q4 Q1 \+ B! R9 m+ @+ x
  23.   * You should have received a copy of the GNU General Public License
    0 S6 N; f; G8 z0 \7 Y" Q1 \* c
  24.   * along with this program.  If not, see <http://www.gnu.org/licenses/>., ]2 j! {+ t8 N( J% Q
  25.   *
    6 P. |4 X% o! \
  26.   ******************************************************************************- I: M0 B- K4 v+ X+ ~5 x. S
  27.   */
    6 n5 f! g: q0 L( G

  28. ! }: X0 `1 u/ [6 j+ x* a
  29. #ifndef __YMODEM_H
    % |6 b" u. H: e- |4 Q9 h
  30. #define __YMODEM_H
    0 ^; i; G7 j4 u
  31. 8 B" ?0 E- y" n6 I* t
  32. /* Header includes -----------------------------------------------------------*/
    6 J" ]2 C+ T4 Z" l  y+ A8 J
  33. #include <stdint.h>- k" }8 R0 I7 p* Y

  34. 7 N; M' b& n$ v
  35. /* Macro definitions ---------------------------------------------------------*/
    5 W* ~9 O$ o2 }8 L+ C1 U
  36. #define YMODEM_PACKET_HEADER    (3)- p! j" V4 v; G/ U
  37. #define YMODEM_PACKET_TRAILER   (2)
    % @* j- \. Q( G9 V8 }
  38. #define YMODEM_PACKET_OVERHEAD  (YMODEM_PACKET_HEADER + YMODEM_PACKET_TRAILER)( ]# ~- a$ R. h5 H9 k/ I/ r
  39. #define YMODEM_PACKET_SIZE      (128)
    8 H% I6 I: R: ~# j% B9 U
  40. #define YMODEM_PACKET_1K_SIZE   (1024), B* X2 ^7 A% _1 S8 g& e

  41. - o: `- [+ I, ?
  42. #define YMODEM_CODE_CAN_NUMBER  (5)7 Y# Q: B/ g5 A4 u

  43. ' l1 m1 U3 q/ C+ G7 p9 u2 o' |
  44. /* Type definitions ----------------------------------------------------------*/0 g& R6 |* `+ E6 B1 I2 r$ n
  45. class Ymodem+ ~& R/ g4 c$ s
  46. {1 R+ T- H. k7 U& l/ S
  47. public:
    " H- B& D& Z1 x# E0 ]( `
  48.   enum Code# B6 L/ N) S  O% @; j
  49.   {+ Z" j3 q& c9 g9 J) y
  50.     CodeNone = 0x00,
    $ c, v  L! W" O% D9 k7 W: l
  51.     CodeSoh  = 0x01,
      ?+ k9 H) \2 Q) v
  52.     CodeStx  = 0x02,) v, l0 u6 U, q/ L4 ?
  53.     CodeEot  = 0x04,
    4 n1 Y8 O& W5 f5 l
  54.     CodeAck  = 0x06,
    ' B& y( l5 P  P7 s' L: l* O: f) X
  55.     CodeNak  = 0x15,7 C+ y' Q* [6 l
  56.     CodeCan  = 0x18,
    , z3 u& E  \# N; l
  57.     CodeC    = 0x43,  B, S7 _5 p! J9 D/ m
  58.     CodeA1   = 0x41,
    7 [7 `9 c0 t' U  Z
  59.     CodeA2   = 0x61. J$ n6 U$ O7 |$ ^0 L
  60.   };* K: o% S5 [: ~7 R; S7 b
  61. 5 S3 T: J. k" R7 I% o
  62.   enum Stage, H* f( h& V+ `) Z7 G# D
  63.   {# [# _# q0 t; X1 F$ C2 V
  64.     StageNone,$ x  }7 K  n$ P& d9 b' x8 o
  65.     StageEstablishing,6 ?$ P! b+ X& S% S; U5 a
  66.     StageEstablished,/ o# ?8 \# H# a/ e, o1 X
  67.     StageTransmitting,
    3 C+ `, J* z) i" I; H
  68.     StageFinishing,
    * `& U% |  w& ~1 C% W
  69.     StageFinished
    $ x! x% {) C5 w( F0 \$ z3 F
  70.   };
    # B6 u/ M6 q7 @% R( a
  71. 9 C& P+ c0 g, H- T- W# m
  72.   enum Status
    4 C3 b- I2 b  I/ V8 g' W
  73.   {9 K; X* A: Q# ?, x. H9 P
  74.     StatusEstablish,' ^+ x) I8 B4 {: R
  75.     StatusTransmit,
    ) s: a: U( d# W+ o% e# u
  76.     StatusFinish,* i7 ~) I5 k6 f7 s* k
  77.     StatusAbort,
    . `  f" Y1 |9 @) h: c( ?5 n7 r: |
  78.     StatusTimeout,
    1 I0 q! s, G$ ?/ N5 f5 q  V
  79.     StatusError
    3 O5 e8 d$ O4 ?
  80.   };( S7 G- J4 K: }$ k- Z  e, O

  81. 8 b  b4 @0 R6 Q& j; g$ }: }( K0 n
  82.   Ymodem(uint32_t timeDivide = 499, uint32_t timeMax = 5, uint32_t errorMax = 999);" E& ]# y$ r4 Y  [4 ~! r3 j

  83. " r# O- {' q9 _* j% F
  84.   void setTimeDivide(uint32_t timeDivide);' f# {' H& p2 n0 Q% B
  85.   uint32_t getTimeDivide();
    $ \) Q2 e2 e+ A- @0 h2 F
  86. " H* `* h3 M: I5 J4 d5 U% Z$ s
  87.   void setTimeMax(uint32_t timeMax);: T/ n3 _5 R$ p1 V, }! e
  88.   uint32_t getTimeMax();
    , P2 k; k6 ]- s, C/ r7 k, m
  89. # t  t0 U/ g/ t* [
  90.   void setErrorMax(uint32_t errorMax);8 P& ?3 g! r5 N0 Y; Y
  91.   uint32_t getErrorMax();
    2 U! i* c/ `' G2 F! h

  92. : B& u( B- l3 f) k
  93.   void receive();
    * v8 L9 ^4 ^" \
  94.   void transmit();
    $ I' Z+ k. d4 V2 a  \% `/ ]( X6 {
  95.   void abort();
    - K$ t; ^* ]# P- `+ i: c0 u8 q

  96. 4 f4 u6 r2 b$ b1 ]- a
  97. private:
    9 X9 W) o& m' f
  98.   Code receivePacket();' T0 |) e' V4 q
  99. 1 c% t( A9 k1 ^3 b$ p- w7 r
  100.   void receiveStageNone();! Q" \5 j5 B: B  j. Q  i
  101.   void receiveStageEstablishing();& C( G' i4 r" |; _* R9 g; N
  102.   void receiveStageEstablished();. V$ u9 D& B: ]0 L* T
  103.   void receiveStageTransmitting();
    3 k- D. G# l+ A9 B
  104.   void receiveStageFinishing();; \% h) d* Q8 y' B1 M- x- V$ d5 k
  105.   void receiveStageFinished();2 r3 O  d( D) o2 U. k8 [9 b4 B
  106. % ~& u2 U3 t. v9 c/ b( I2 O
  107.   void transmitStageNone();
    ) \! }) s; C! G+ j9 x
  108.   void transmitStageEstablishing();6 U4 m. H  |% b; ~# j& q+ m
  109.   void transmitStageEstablished();- }  g  _0 B$ {. }( D3 l
  110.   void transmitStageTransmitting();
    $ Y2 a! @8 Z) a& o
  111.   void transmitStageFinishing();+ m% k4 z, O# w7 o1 q
  112.   void transmitStageFinished();
    : l% s& |% P: e" z0 p+ n* O
  113. - N7 q( {' W6 z) v4 c" A/ [! _
  114.   uint16_t crc16(uint8_t *buff, uint32_t len);0 L' }1 |& F7 q
  115. 3 G5 _- o( o  y, ~+ i
  116.   virtual Code callback(Status status, uint8_t *buff, uint32_t *len) = 0;, C6 e& C5 m; {; G

  117. , g# ~& \4 Q* w. @4 ~
  118.   virtual uint32_t read(uint8_t *buff, uint32_t len)  = 0;
    6 F' l" o4 R' R$ j* N# w( o
  119.   virtual uint32_t write(uint8_t *buff, uint32_t len) = 0;; T$ ~, r% m7 }

  120. 1 P3 d$ r: ]  E: S+ x) `
  121.   uint32_t timeDivide;
    6 P" V/ f' k# p  C, S: |. Y' ^2 ?
  122.   uint32_t timeMax;2 b3 ?# `2 W) F2 J1 c
  123.   uint32_t errorMax;6 n3 T! K  J; M, l) r5 o

  124. % x" S7 y! f8 {9 l% d& x
  125.   uint32_t timeCount;
    ( Q' \  j, Q+ J8 M" ?* n. G) w
  126.   uint32_t errorCount;
    $ L2 C# i1 q5 m, ~0 o
  127.   uint8_t  dataCount;
    % l; i0 S* o9 N4 [' d

  128. # @+ k1 [/ u8 ~) n6 L/ a  L
  129.   Code  code;7 F8 u; E0 b4 ~$ ~& j3 C4 @7 Y
  130.   Stage stage;
    ! a1 \9 k7 K, S! W- E8 h& Q0 p

  131. 7 |; }9 p6 G$ ~/ P6 G
  132.   uint8_t  rxBuffer[YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD];; |  Y! v5 m# o$ w, _" a* e
  133.   uint8_t  txBuffer[YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD];
    . ^0 x2 e7 W( R2 t* y# ?
  134.   uint32_t rxLength;8 p6 S, i& m  `
  135.   uint32_t txLength;
    , Y  p. s4 B7 R+ z. r2 _- C
  136. };
    ( g( |3 a  r) S" y2 ~5 Y

  137. 5 ~* a" R  b" I2 Z/ j& S$ y0 W* D- @" x
  138. /* Variable declarations -----------------------------------------------------*/7 s5 W# J, F! U8 _! L
  139. /* Variable definitions ------------------------------------------------------*/' p. r/ H9 w9 W! o) X! P
  140. /* Function declarations -----------------------------------------------------*/
    & _: a3 g- t9 v' g5 P6 U5 i  E
  141. /* Function definitions ------------------------------------------------------*/( O* a5 Q. A% c- B( O4 w/ N% d

  142. / Q; q: E1 a) a% I. g
  143. #endif /* __YMODEM_H */2 ~1 F3 V5 W' `" z
复制代码

7 Q% I6 ~# S3 j* @# L6 {6 t      Ymodem.cpp文件) P5 ~+ `6 P# A5 ?- M6 @
  1. /**( U! @9 S" p1 h7 r' O: g# m4 I% D4 {
  2.   ******************************************************************************7 u# j! a1 j% O# G2 F, S
  3.   * @file    Ymodem.cpp
    " {9 ~9 n* ~  s" X5 |4 W7 M) O
  4.   * @author  XinLi* y( ^: u3 C! Y9 X% e
  5.   * @version v1.0) p& E" D. v9 r3 K9 R: E. S
  6.   * @date    21-January-20180 ]$ P$ F) ^2 j6 P6 i( F3 z
  7.   * @brief   Ymodem protocol module source file.6 O, }, z% R/ l/ k  Y4 i
  8.   ******************************************************************************* T  B% k0 d/ \0 B* Q% N
  9.   * @attention
    ! |! ^% N7 P/ S  U! i' T1 _. g! J
  10.   *
    # m' N) f4 ]& `& `6 T
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>% J& I0 x* r8 X- N
  12.   *
    1 _' ]3 \3 |/ A9 R3 i  A
  13.   * This program is free software: you can redistribute it and/or modify& j$ D, E% x* y5 P
  14.   * it under the terms of the GNU General Public License as published by
    9 Q* p, G2 {" \. c$ i: \
  15.   * the Free Software Foundation, either version 3 of the License, or
      m' f! ^3 ^" I  ], @' q# _
  16.   * (at your option) any later version.4 u7 d* _1 `5 _$ Q
  17.   *7 T/ S4 V5 ^, z$ @) v
  18.   * This program is distributed in the hope that it will be useful,! _2 B/ _2 K6 v* `) A2 I! X; P0 |
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of* ]* f' e# v( H6 Y) O
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the" K& d* H# j0 i+ n$ R& s
  21.   * GNU General Public License for more details.) |( p* |$ v! V8 b' T8 ^
  22.   *& H! C' B2 m4 {+ s) L% D
  23.   * You should have received a copy of the GNU General Public License; U1 m& J/ [( l9 j+ B
  24.   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    , W7 m7 a/ F. J$ j
  25.   *
    0 u1 u+ M, B1 V6 }$ \4 q
  26.   ******************************************************************************
    ) m3 ~$ m* g3 u. T6 x' I' S
  27.   */! n# h8 I5 }4 [* {

  28.   h4 R; V. s: |3 K: F& i
  29. /* Header includes -----------------------------------------------------------*/
    / p9 _' j$ ]+ `! {5 D6 _: d. E
  30. #include "Ymodem.h"
    4 P+ [9 H8 z- s0 y$ i% S: o2 W
  31. #include <string.h>
    ) r+ Q$ S: s5 Q: H6 ^' Z3 k# y- f
  32. " `$ U) o- H) E' q$ a9 ]# u8 j
  33. /* Macro definitions ---------------------------------------------------------*/; w5 |5 O/ S- s+ @0 o# ~
  34. /* Type definitions ----------------------------------------------------------*/+ u& }" ^% {/ A) c7 l/ Q; y& l; y: l
  35. /* Variable declarations -----------------------------------------------------*/+ G: s: p" K, K9 E0 t9 H% j
  36. /* Variable definitions ------------------------------------------------------*/# H% P# }5 j9 ]# T2 P
  37. /* Function declarations -----------------------------------------------------*/
    . c8 F/ T! N$ @) W2 \- n# ^
  38. /* Function definitions ------------------------------------------------------*/
    8 k7 L$ s6 G. ]7 g
  39. 2 V5 }5 s. [" ]! T" v
  40. /**
    & v& b) C2 }/ ^& S7 q
  41.   * @brief  Ymodem constructor.* `( V8 I, z: l+ M2 c- V: h
  42.   * @param  [in] timeDivide: The fractional factor of the time the ymodem is called.
    / O5 t8 V! T: \! i9 b6 O8 g: V& x
  43.   * @param  [in] timeMax:    The maximum time when calling the ymodem.; y) @' @9 \; O% I
  44.   * @param  [in] errorMax:   The maximum error count when calling the ymodem.9 u6 _6 e- ?% \% x' n/ D6 H# R
  45.   * @note   The longest waiting time = call time / (@timeDivide + 1) * (@timeMax + 1).7 m, Z. z2 z; O$ Y% v
  46.   * @return None.7 b  r9 a9 ?! E
  47.   */
    + z; V/ F# _( w  z
  48. Ymodem::Ymodem(uint32_t timeDivide, uint32_t timeMax, uint32_t errorMax)# U3 d/ v4 S" Q) d) E
  49. {9 q' e& n( p7 i* ~% X" P
  50.   this->timeDivide = timeDivide;1 p- E( v1 b3 n8 i: m
  51.   this->timeMax    = timeMax;8 v# u" K* h6 i/ p( x# G% n
  52.   this->errorMax   = errorMax;
    2 ~3 L! N8 E0 Q- s( v! f6 }
  53. ' @4 |. p7 ]3 t6 \
  54.   this->timeCount  = 0;" o2 J7 @4 M3 F1 N, u3 d
  55.   this->errorCount = 0;5 B) N5 f- b1 S5 O7 m: K
  56.   this->dataCount  = 0;
    1 L6 I4 _5 Z7 V+ N3 l: z5 M/ n

  57. 7 S* u8 V1 o% O% z; b. T
  58.   this->code       = CodeNone;" S8 {7 {4 H) w7 C
  59.   this->stage      = StageNone;  U, U# N; C# v# j0 @) x# ~! f
  60. }7 d1 U+ L: F: k0 R  R

  61. 2 a& D6 A4 a( u
  62. /**  W# t4 H+ z7 Z! ?
  63.   * @brief  Set the fractional factor of the time the ymodem is called.
    - I( d& Y+ n2 l1 G3 @; e) e. ?/ h
  64.   * @param  [in] timeDivide: The fractional factor of the time the ymodem is called.
    " Y* E  `* Q! C% ~
  65.   * @return None.% P% ?( u) z& C1 J5 }' M8 q3 ?
  66.   */3 s0 o% p: ~0 w. f# t3 _( B. u
  67. void Ymodem::setTimeDivide(uint32_t timeDivide)
    , o+ L6 z5 B  O% n
  68. {( G( w9 u7 P8 E! W  F/ L( `
  69.   this->timeDivide = timeDivide;! ^) W- \- Y0 E1 d0 E* ]4 I
  70. }
    9 s+ @. D: c4 O& i* h' ?+ ]% K* q$ H

  71. ; }1 x1 j) L; p) ]8 Q
  72. /**
    2 w# |  O0 n& P& ?& s
  73.   * @brief  Get the fractional factor of the time the ymodem is called.
    7 z+ p5 c# k0 M1 a' b
  74.   * @param  None.
    6 _  S; i: k; p) W+ G
  75.   * @return The fractional factor of the time the ymodem is called.
    , }' w  s0 I4 Q4 \4 M" j* D
  76.   */1 ]( U; c0 t) _4 P- O
  77. uint32_t Ymodem::getTimeDivide()* ^& l8 C; s% X0 D
  78. {* i. W6 ]. A$ Y6 ^) o
  79.   return timeDivide;) y' M6 Z% ?  I! g: [% h
  80. }
    & L, b. n6 {6 W2 z  J* E

  81. / B8 y- O* L9 i9 ]  d
  82. /**
    2 x' f, N) L1 W/ ?
  83.   * @brief  Set the maximum time when calling the ymodem.+ g( S* A8 ?; q( x5 K- z! R  s
  84.   * @param  [in] timeMax: The maximum time when calling the ymodem.+ `! ~/ q. u* O  T: ~, h
  85.   * @return None.
    0 b: v- u* j7 d. M
  86.   */6 G8 u/ H( j" T" G+ k
  87. void Ymodem::setTimeMax(uint32_t timeMax)6 u1 e$ T# a+ a3 Y
  88. {3 p4 c- X' d, P' h
  89.   this->timeMax = timeMax;
    1 x5 q* l0 c7 `: m- a3 ^5 `1 y
  90. }9 b) `7 X* H. _
  91. ( c; S: Q! a% ]4 B+ k
  92. /**5 j  \) _% r0 ^& A- g
  93.   * @brief  Get the maximum time when calling the ymodem.  X$ @" J2 m% @3 G8 [$ w
  94.   * @param  None.
      r0 o7 i+ }) Q; G; h
  95.   * @return The maximum time when calling the ymodem.
    * \( ]& {9 A3 d1 W1 G. b
  96.   */1 q% G/ R! ]0 M' w8 _  K+ q
  97. uint32_t Ymodem::getTimeMax()
    7 o( ?3 w3 C2 M9 I( |$ n) _* v
  98. {/ E  o: I4 Z: V) F
  99.   return timeMax;
    # y- a  K; T4 G. M; e- D* P
  100. }
    ! c9 k: `- K7 Z" h5 m
  101. * `7 M: m  ~( j3 T  G
  102. /**3 }9 T" B6 ~1 d
  103.   * @brief  Set the maximum error count when calling the ymodem.. s% C) {6 v! y, G
  104.   * @param  [in] errorMax: The maximum error count when calling the ymodem.* K4 b# F3 j) Z- F4 {. I
  105.   * @return None.
    4 U  n4 {5 m# @' M) A
  106.   */" L, u# d6 H& g' S1 E
  107. void Ymodem::setErrorMax(uint32_t errorMax), x2 @+ C0 R! M, f5 p
  108. {% d) q4 u# Y9 B+ B( ?: |
  109.   this->errorMax = errorMax;# M5 D# G1 {' y- ^5 ]! q. W/ ]
  110. }
    ! E0 B, s* g0 I( z( }( f' W+ d

  111. & y% J6 a! z3 i' y3 F) N) j
  112. /**% R7 |5 v* p& J# `: q, S! ]9 r
  113.   * @brief  Get the maximum error count when calling the ymodem.
    6 t  x' N. O" Z6 A! r
  114.   * @param  None.
    6 }( t+ z! \- Q
  115.   * @return The maximum error count when calling the ymodem.
    ) S/ ~) }+ Y1 ~$ H2 N7 N, M
  116.   */0 }; j/ m' e9 X6 {- p, x1 Q" \
  117. uint32_t Ymodem::getErrorMax()
    * w2 L4 u1 ~7 h/ c$ P
  118. {3 `* l6 F1 S- ^" _" N# h3 G
  119.   return errorMax;
    / c* }1 p2 ]* d2 z: R. Y; `$ X. i
  120. }( ^2 `2 S  [/ @; t# ~( ]
  121. 7 f4 }. T: [' A4 O7 d+ `1 f; u2 H8 r
  122. /**5 j3 j/ ^: q2 b. J/ {
  123.   * @brief  Ymodem receive.
      `# T& H$ L+ A2 k( s
  124.   * @param  None.
    ) k& l* k7 v9 l. z: v$ L- r; @
  125.   * @return None.# L$ t8 U# s% G* ~4 A4 }
  126.   */& l/ ]( o6 ^6 j$ a  F, }
  127. void Ymodem::receive()$ d1 h" |' s) @: T" R3 L
  128. {
    , h+ w+ M' r" x; S0 S  E* ~+ P* T
  129.   switch(stage)3 s- }4 L0 E  T0 ^' h% U% J
  130.   {
    3 ?. [* R: c" n7 Y
  131.     case StageNone:
    % g2 F, B/ c; H: L. e
  132.     {# x' H  ^% e0 w
  133.       receiveStageNone();
    3 p) l+ I. ?/ \3 m! ?

  134. $ E% U! J6 ~( v
  135.       break;
    ! `( N( f4 N4 R' y7 t& O9 S
  136.     }# b2 i+ ~6 S$ V; H- S# @6 V& b

  137. % s4 \  X; r3 w/ i4 X
  138.     case StageEstablishing:* W+ P$ o/ R: T" I
  139.     {3 S5 q6 w; u: j1 d3 M" C
  140.       receiveStageEstablishing();
    8 r4 a/ b0 s8 N" C4 H( C/ @2 o

  141. : A$ @7 t6 u* q. I0 }/ r8 i
  142.       break;
    6 ~$ F, i1 M' o! h, I& N
  143.     }* M" [$ m2 s& g8 G$ v- k) P
  144. " W, G+ q/ [! U6 n/ J" B
  145.     case StageEstablished:
    6 V: e7 [# \8 H0 C5 x
  146.     {
    & V$ _9 b) E/ l, ]* d4 ~: ~& ?
  147.       receiveStageEstablished();8 D, [4 a3 H. l/ e1 C
  148. . R) ~4 y* s( r: G+ T. P
  149.       break;
    ) ]/ u' b) E  b3 t0 {
  150.     }; i$ G5 a* Z2 ]8 O
  151. 4 B* I3 R$ |+ e# V
  152.     case StageTransmitting:, ~9 j$ C: s/ m' B* d& B9 R/ m4 o0 m( g
  153.     {
    * f( T+ s2 u& K
  154.       receiveStageTransmitting();& U3 R& \; [/ R. M4 y" a. Q
  155. ; h+ F" U% O% ~: U
  156.       break;
    ( A& Q% }# t8 G+ ]% }/ Q) V- S
  157.     }
    , l3 S/ d6 `) A, }7 B0 K

  158. 0 z5 ~( |+ c; X/ J5 ?0 U
  159.     case StageFinishing:1 y8 q1 F, {+ u3 H  i
  160.     {
    , q$ I! x. |$ N
  161.       receiveStageFinishing();
    8 b* V$ m+ I: o3 K& U

  162. ) K. y" x4 `$ Q) V; i. m+ D/ E
  163.       break;
    & X) @3 l" L3 k- p
  164.     }
    9 @; O. J/ r1 R7 Y

  165. + ?# u# [7 I8 i
  166.     default:' H2 p4 u7 K) D/ G1 @
  167.     {6 O# o! W* N& S; X3 M
  168.       receiveStageFinished();" `" Q1 j4 p( j6 ~
  169.     }
    ) J. Z' X+ E  ~5 c  n7 t/ p
  170.   }
    7 d6 O- R5 ]+ W  M$ Q
  171. }; F5 D+ |# h9 Q

  172. ' p; a' {1 ^  O$ f/ l$ m* s
  173. /**; n# X5 v* U% h' O3 i: Q  ]
  174.   * @brief  Ymodem transmit.
    3 ~  d+ P0 e/ u1 l9 P/ c) n( N
  175.   * @param  None.+ h/ ]7 y; u+ j9 y
  176.   * @return None.
    ; ^8 @3 W, d3 h1 N  I
  177.   */# L0 k( _9 W5 S" G; U3 h
  178. void Ymodem::transmit()
    , f% o  u& d/ b1 @0 m
  179. {
    * U0 T- i' F: D/ q- H- M. d- f1 B
  180.   switch(stage)
    + ]- G3 j1 l' {% S+ ]% D
  181.   {
    ' h- E+ j% N+ ?, W
  182.     case StageNone:
    7 I2 q% }$ ], ~1 a
  183.     {3 O- k/ p  h0 x, E1 l
  184.       transmitStageNone();" n; U) L7 e: w+ P( Z: K

  185. ' v- g& y! t9 t! g/ s7 S! L
  186.       break;
    / }5 D  p; u1 l1 T
  187.     }* F  l2 g* i9 p3 E3 a
  188. % @& d7 V% |6 Q- Y# n. `6 {; D
  189.     case StageEstablishing:
    / n8 n( q4 @1 U! g7 c  x
  190.     {
      b  r* y$ w: I2 j8 O5 s
  191.       transmitStageEstablishing();! u, P' B; F3 p7 W3 E. q/ u

  192. ! x3 ^2 f- F4 {0 d7 f- X
  193.       break;
    " ]+ `  Z/ |, t2 ^3 I2 Y  z4 A
  194.     }6 {( {/ T5 `6 ~" D' g
  195. 0 p6 z& \4 a6 H0 ]5 g% i0 a: U; i
  196.     case StageEstablished:
    3 B; ?: d* [" i0 m% Z4 c# j
  197.     {
    * k4 \7 n% a# L, n$ G; w; z
  198.       transmitStageEstablished();
    - a4 m! s) W& s5 y3 d0 R3 h
  199. 8 t3 q5 N$ }  a2 s; r/ p% c/ ^
  200.       break;
    8 K3 k7 w8 C9 T3 ?! F: o  C* O2 o+ e
  201.     }
    ) V* ]5 B# g2 W% p0 K

  202. 3 |0 q4 o; }/ c$ S' [5 q4 T6 Y
  203.     case StageTransmitting:0 C% [- v+ z' k( w, ]
  204.     {- h* S3 M/ f6 \( @
  205.       transmitStageTransmitting();
    6 f* e( T' A- v' k# G
  206. ! T+ o: @( Y( X* \! @
  207.       break;& D9 y9 s6 H% M7 {; {
  208.     }2 }  D$ o3 @" ]) m* N0 m  m
  209. . A( v8 }5 ~/ G) V
  210.     case StageFinishing:9 J9 k. }; c. d) t
  211.     {
    5 y8 H9 [5 j+ H* h3 j
  212.       transmitStageFinishing();
    : b& I8 s9 m9 D

  213. % J  @: h' h8 `( e% j( L0 t
  214.       break;
    ! T: S9 i$ J. g* s/ R! i+ S
  215.     }
    8 ^, q9 j5 M/ U- ^4 J% p

  216. 8 g3 y+ I' H. K+ f0 l7 n
  217.     default:
      u3 h7 z* q1 u0 v8 {! v# z: v* @
  218.     {
    3 F# u+ j: x# p% \1 Y$ ~
  219.       transmitStageFinished();2 d1 s; T" p. _& h% D
  220.     }
    3 b& U# F. o: h: o! \+ _
  221.   }
    & G3 p+ |! s4 Q* S. _2 t1 S
  222. }( T. S7 \: _( R) J
  223. 2 q6 I! [7 t. K: x3 _1 y- d
  224. /**6 ^) g$ H, ^' d: d
  225.   * @brief  Ymodem abort." P1 h2 v* ]" u- I
  226.   * @param  None.) W) Q$ q% `6 q, D0 ]- c& w5 q
  227.   * @return None.
    ; V1 H, T+ N- E9 c" y( ?
  228.   */+ Z9 v/ y7 f5 `8 v
  229. void Ymodem::abort()7 u/ G, o, q. ]9 o, Q- G9 ]
  230. {
    & I* D9 h) a' T4 y2 J
  231.   timeCount  = 0;% H8 X7 i0 Y, @6 A  P  d; Y3 T
  232.   errorCount = 0;
    8 `* x) t/ C1 Q2 F4 A; w
  233.   dataCount  = 0;' H- e6 i! `1 g( r) a8 Y# i
  234.   code       = CodeNone;# K9 {; \0 P* n! ]
  235.   stage      = StageNone;
    7 F0 L/ t6 ?" p/ V8 r4 Z

  236. 3 A, c/ t$ h* E0 m9 ]6 Y+ F% E
  237.   for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    0 _  \1 T' O- u1 S0 h: M& }" ]
  238.   {/ i% h9 Y7 C* A: o$ F% M
  239.     txBuffer[txLength] = CodeCan;
    / K6 m" ^3 e& h( U- p1 c  q
  240.   }  k" L# D4 Y+ n  G; ?

  241. ) e( U: Q4 B. ^5 e* @. @% u
  242.   write(txBuffer, txLength);
    ; J2 B" Y! E! F9 T% a5 p  C  U
  243. }
    ( M! b( e# N5 w8 f+ W& c
  244. 6 k& z- x# B( o: s8 X
  245. /**
    + R) p- u+ H$ \4 T
  246.   * @brief  Receives a packet of data.' z; L! u3 I+ Z7 x* a( ~# w$ Z
  247.   * @param  None.* d9 [1 A( d8 ]
  248.   * @return Packet type.# H& h+ L' h# n% J6 T9 a
  249.   */
    2 d+ x1 u1 v2 q& `; v: O6 W
  250. Ymodem::Code Ymodem::receivePacket()
    8 G2 [9 M2 v! _3 C  f0 m
  251. {5 m( \7 a/ Q4 t6 w% U/ e7 `
  252.   if(code == CodeNone)* d5 n+ P5 H% G9 _
  253.   {) `" T+ A6 w2 T
  254.     if(read(&(rxBuffer[0]), 1) > 0)+ ?4 |2 D7 U/ S2 {4 V/ x
  255.     {) o) t$ Y% U: F' @6 ^% p
  256.       if(rxBuffer[0] == CodeSoh). P; h$ g" d, c* s
  257.       {3 ~; |4 k3 u0 c9 [6 q9 ^
  258.         uint32_t len = read(&(rxBuffer[1]), YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 1);. V/ g0 M7 ]0 n) H* r6 s
  259. " i1 Y% c8 j2 h! e- ~; ^& _
  260.         if(len < (YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 1))
    ( @$ x8 b* r; L* h5 l
  261.         {
    5 X# j7 D' {2 k  Q
  262.           rxLength = len + 1;
    4 u- N& g* H/ c/ V; g
  263.           code     = CodeSoh;
    ) s: ^/ H; L0 D) R
  264. % G, |! f! ^/ o% ?% ?, J; O( X, l
  265.           return CodeNone;! ?/ d$ l( p5 Z+ q0 p
  266.         }
    % o( s2 w" O) b8 y( Y# n( f1 u
  267.         else
    5 q2 H0 S& q  G/ t8 n; n
  268.         {
    ; B) I' l8 B2 h6 ^3 r0 o
  269.           return CodeSoh;
    9 n  J, t  l4 `0 C8 u& I
  270.         }
    . H4 D- U; K$ [8 ^
  271.       }9 P" O- D) ]# y0 U$ {" U
  272.       else if(rxBuffer[0] == CodeStx)
    : A" ]" q: Y( D3 P! Z: [! Q: w" a
  273.       {
    - B4 u4 A  @% y0 B1 s! z8 x
  274.         uint32_t len = read(&(rxBuffer[1]), YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - 1);* d' @0 z9 ?7 k$ A3 {% Q, @+ V
  275. 2 {  D: l, Y, U) n8 h6 `+ ?. @' n
  276.         if(len < (YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - 1))  \- q1 J; {, [4 [% j- d
  277.         {
    4 R/ N: {+ M3 y  s2 J1 A- q$ }" h
  278.           rxLength = len + 1;
    8 M2 b- I4 ~* y8 N
  279.           code     = CodeStx;
    $ C7 H6 x3 _, j- R( q

  280. ! t. x* O: o: c3 [6 M1 [
  281.           return CodeNone;. s: n5 O/ F( F
  282.         }: D- J& A/ H$ j5 R
  283.         else
    ' X  X" c, @, }/ P$ O0 _8 J( u. ?
  284.         {' ~5 @9 B; ?' c' b! v% v
  285.           return CodeStx;
    , I) _$ d+ c+ L
  286.         }1 ]% h3 M$ a' K* x
  287.       }
    , m# o1 `& B2 a
  288.       else* x9 h& L# f' ?5 c$ H: b: u( m
  289.       {
    # {. `$ A4 z9 D0 N" S! K. q: d
  290.         return (Code)(rxBuffer[0]);
    " K7 ^9 g5 z* I2 A$ ]
  291.       }* ^& b! ?4 m" }! x" G; z9 k" ]4 F
  292.     }
    3 v/ `3 d" X3 t% `0 H" w
  293.     else
    ! g4 ]/ ?' }4 ^- o) E$ }. I( [
  294.     {
    3 X3 f% F! M2 D! u
  295.       return CodeNone;3 k1 N, M8 \0 E. {. E5 q8 P
  296.     }
    % y' ~; H% _; {6 \6 b, t  e! L' C) z, U
  297.   }
    9 e7 @! n( H$ x
  298.   else
    3 @" O) c4 T/ @  a0 W
  299.   {+ R+ @8 R5 f+ ^
  300.     if(code == CodeSoh). E1 o7 Y8 D0 P: N0 ^
  301.     {
    % Q8 O: d6 Y! B; X
  302.       uint32_t len = read(&(rxBuffer[rxLength]), YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - rxLength);6 L& ?+ ^4 @" E4 O. U! q+ o
  303. 2 [- b/ m/ U/ U- T; o1 z5 |! r% d
  304.       if(len < (YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - rxLength))
    1 c4 C3 j% R. n# O7 x' l
  305.       {6 M: T7 ~) W  R# f- ?1 Q) P! x7 O* D7 O
  306.         rxLength += len;
      ]0 ^) n& F6 k- Y" g7 w, _

  307. & \; k. k& K2 {* z; n* Z
  308.         return CodeNone;
    2 t  o+ [0 p2 p
  309.       }
    4 |; H5 _8 B7 T
  310.       else
    0 f: K) I, G3 _" S" R
  311.       {' D: u1 r: t3 ~4 x5 X% _. g
  312.         code = CodeNone;
    ( z) l! L: g* ]0 `6 o! [
  313. " w/ N2 h7 F0 b- X) A- C
  314.         return CodeSoh;+ q9 h1 K) ]) R/ V7 c
  315.       }
    . l' J6 |* L7 _1 T  E9 d: B- j: W
  316.     }
    + s9 _, w9 I4 k6 q
  317.     else if(code == CodeStx)
    * O) M- D, Y# L" ~9 f
  318.     {6 x( ^7 k. e$ B& z0 T% q& @, Z
  319.       uint32_t len = read(&(rxBuffer[rxLength]), YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - rxLength);
    7 S7 O* H! m1 ?! V! ?0 G2 E/ p. c
  320. & m8 P: }+ G0 s! F0 d: n
  321.       if(len < (YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - rxLength))
    # U$ P" _4 s( j3 p0 e( ~
  322.       {1 W; Z: [6 p8 Y$ G4 m" t( Q
  323.         rxLength += len;7 F$ h$ n: J; S. _
  324. 8 t$ @6 K% V- j1 b
  325.         return CodeNone;& `4 X% k9 P& L5 K) k; b
  326.       }) i. u6 |# t7 G, d+ l& S
  327.       else
    + ]+ _! _  g! _( b. ~2 Y
  328.       {
      w8 ~6 T: _6 }$ @& M7 D( n
  329.         code = CodeNone;: a1 B5 a4 F# t4 s3 \: t6 e# i

  330. % e( h9 ~: \6 a" ]. z& ^
  331.         return CodeStx;+ s! a1 H# c* {7 I% @. O8 b
  332.       }
    9 p( c0 n; \2 l7 @
  333.     }
    0 e/ `( V* D) [
  334.     else$ D8 V' C) B& _* r
  335.     {
    : y  R: v/ Z. ?0 T
  336.       code = CodeNone;' y. c- X+ j! ^

  337. , b! U, x# r) @6 A  E3 T
  338.       return CodeNone;! ^0 Q* \8 V& \
  339.     }
    ' Y6 x2 N6 ?/ S
  340.   }
      N& H; _  e6 d$ B
  341. }
    , X  W0 r3 e1 ~6 U
  342. ( {& w- g. a5 \! N: N2 W
  343. /**
    ( {8 S% ]7 w- O2 u
  344.   * @brief  Receive none stage.$ }- j# y/ j; x0 j4 x$ r* Z7 y3 A
  345.   * @param  None.% X7 x) h# |) @& b7 g
  346.   * @return None.
    & V+ T* v* w  Z4 q- c  t
  347.   */
    4 I5 E% ?" [* ?5 ^. Y9 j
  348. void Ymodem::receiveStageNone()5 h1 P! n0 X6 {' }* o6 h
  349. {
    : y/ L# O( `) R& B+ a% T
  350.   timeCount   = 0;9 v0 c6 S; n3 u
  351.   errorCount  = 0;7 i+ [" P& F# L9 H. t. @
  352.   dataCount   = 0;$ E9 ]& {# o+ B7 q' k. U" {( j
  353.   code        = CodeNone;
    + d4 z- L- M" n7 c5 v
  354.   stage       = StageEstablishing;
    - o1 t  U9 l' d: @$ y
  355.   txBuffer[0] = CodeC;& l4 L' n7 H1 `/ p. H
  356.   txLength    = 1;
    ! E. y0 l/ ^! j1 ~( O
  357.   write(txBuffer, txLength);, y( L/ f5 B$ Z* h- l* I
  358. }
    4 B  k- r: q$ T5 Z, M6 g
  359. 0 ?. ~& R1 i- M( V
  360. /**
    / q- S' [3 S& v/ K! u! l% i
  361.   * @brief  Receive establishing stage.2 z5 O0 L0 ?' J
  362.   * @param  None.* ?* s* A+ D& Z3 C  d5 C9 Y/ u
  363.   * @return None.
    1 U: d) _8 \# F6 X7 H9 ~
  364.   */& w) `" Y( v, |# b
  365. void Ymodem::receiveStageEstablishing()3 E. y  `( r! R/ ?7 \, u! T/ ?
  366. {
    5 d" T. V, y' t; ~
  367.   switch(receivePacket())
    - c9 F) B  q9 y  x) N/ F- ~
  368.   {
    , A5 x$ r# x' A- ?
  369.     case CodeSoh:
    6 q* a. T$ Y, O' w+ \
  370.     {
    . J  g6 Y: z/ L3 g
  371.       uint16_t crc = ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 2]) << 8) |0 \# [4 }: B* k1 ^# }8 f8 O
  372.                      ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 1]) << 0);; z# r9 v% G- M% M4 X2 M& k

  373. 2 O9 a1 s! s9 I" ^& q  ~
  374.       if((rxBuffer[1] == 0x00) && (rxBuffer[2] == 0xFF) &&
    9 H  \  P0 L+ W% @- o9 j7 M
  375.          (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_SIZE))). I' y6 W3 B* _3 v  u
  376.       {
    1 Z3 _, I$ B1 X5 l0 C0 u. _
  377.         uint32_t dataLength = YMODEM_PACKET_SIZE;% D" c- s. w6 b# h

  378. / u% M3 f% k; Y
  379.         if(callback(StatusEstablish, &(rxBuffer[YMODEM_PACKET_HEADER]), &dataLength) == CodeAck)* j' s* H% a, J: g
  380.         {
    # b0 C  R6 O! P
  381.           timeCount   = 0;5 d( a$ H4 t  m+ a' W$ f
  382.           errorCount  = 0;
    9 I# c+ T- I+ Z  q1 T
  383.           dataCount   = 0;
    9 a  ^% i- c$ a+ R  O) `2 B
  384.           code        = CodeNone;% y1 Q0 m( [& \6 X' Z
  385.           stage       = StageEstablished;" {/ ]) R6 y2 ]+ e: a2 ~
  386.           txBuffer[0] = CodeAck;/ p/ H* X$ Z+ m) E- x7 X
  387.           txBuffer[1] = CodeC;
    2 G1 W- I1 [- o! Z. O
  388.           txLength    = 2;) ^& M7 P" q0 C
  389.           write(txBuffer, txLength);
    " [1 d! b4 a# P) ?
  390.         }8 I! ~9 _; I) X7 d
  391.         else$ Y/ T/ }9 `4 T1 H6 O% S9 d
  392.         {
    & z7 H6 `4 f- \
  393.           timeCount  = 0;7 w# M6 f7 e/ I& W- u9 @* J
  394.           errorCount = 0;
    # P6 E( v0 D. h' p( O* \3 P
  395.           dataCount  = 0;1 {5 k' d+ x, i
  396.           code       = CodeNone;
    * d7 Z# V! I5 ]
  397.           stage      = StageNone;# r; p; G$ N2 Q% u

  398. $ ~5 j2 i# K4 z8 ^4 Q
  399.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    % w2 g# \" @, ~, J
  400.           {
    0 h+ j2 `( G' K+ M! C2 \+ i0 h( x
  401.             txBuffer[txLength] = CodeCan;
    % ?% i& g. T2 S
  402.           }+ S5 B9 j3 j1 i# F% Y" W

  403. . b  a3 F! Q  }) L* J( N
  404.           write(txBuffer, txLength);( a/ ?: N% L' D" r6 y
  405.         }
    4 T) p: I- a( z
  406.       }
    3 W. c* \2 ]  D5 k: A# K
  407.       else5 H* E( S  {& r
  408.       {( ]- H& r! L! F* Z+ W+ r$ W- n
  409.         errorCount++;4 h6 k% u4 o) V- j3 d
  410. : @9 e: Z9 U& r9 O
  411.         if(errorCount > errorMax)
    9 s  m& v1 n1 c" [
  412.         {
    1 n1 A1 e3 f# r. |6 ?" s9 P2 j
  413.           timeCount  = 0;6 p$ T; u7 ]; [/ T6 L. N) {
  414.           errorCount = 0;
      W# d& X' o% @( O. }: X/ d: }! Y* }
  415.           dataCount  = 0;
    ! S1 b( p, ]+ t" S( F
  416.           code       = CodeNone;3 R6 I7 m6 q7 x, n( }
  417.           stage      = StageNone;6 W6 O: q7 @! V/ q7 e
  418. 0 d& F# f* j) S' H4 o
  419.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)5 E" j0 L& S6 w  d8 G
  420.           {
    1 d# `# _5 P  H6 h& ~* u! P
  421.             txBuffer[txLength] = CodeCan;
    # I( R+ A/ I( ]# X/ H8 X
  422.           }/ F- s* t  k+ n8 i3 z0 }; U1 {  M
  423. ( Q# p8 N, F; |) G5 Q
  424.           write(txBuffer, txLength);, _7 C1 l- R( F9 b8 V
  425.           callback(StatusError, NULL, NULL);0 w% M2 O& F3 [$ Y
  426.         }# X. t8 B+ b/ r& @8 @  z' g6 p* S
  427.         else( Y- z# P7 i0 g/ A) k+ c, m5 x2 B
  428.         {
    , R) X' s3 |1 y1 E6 g' i, E
  429.           txBuffer[0] = CodeC;0 o# l! p7 k, F* I2 t. f* E* E
  430.           txLength    = 1;
    2 j/ o( l, T5 U. F
  431.           write(txBuffer, txLength);
    ; c: v2 r- A# w
  432.         }
    ) c0 C/ W  X: _" p3 c
  433.       }2 ~8 S3 g5 C9 ^4 K

  434. $ @1 J7 ?1 C7 o) K& H
  435.       break;
      J' r4 f8 f4 G5 C3 [2 m) i
  436.     }: B0 J, K. k2 H, i
  437. & @% s) c; Y) F) I
  438.     case CodeA1:
    ; r; E3 M1 V. o+ L9 A
  439.     case CodeA2:
    9 V/ ]( T/ j% N* [+ f
  440.     case CodeCan:
    ) @4 j! K& q5 `! z) R* A& R3 s
  441.     {% z' X4 m- R3 e8 \) z1 ^% O
  442.       timeCount  = 0;
    # t4 {1 ^' D# U9 T, K6 k
  443.       errorCount = 0;# s- p. p+ h5 h$ b$ O. J
  444.       dataCount  = 0;
    ' A7 b1 _7 b2 y+ l5 M) v: A1 U3 T
  445.       code       = CodeNone;
    ! n- n1 d! y6 B0 r! w2 X& c" r
  446.       stage      = StageNone;( j  a- C5 D+ @4 q
  447.       callback(StatusAbort, NULL, NULL);
    1 \" F3 t, `, E% x
  448. ' h* A$ Y6 V- [% w# y: K9 O
  449.       break;
    / D* `; j; x# e, Z% b9 W7 ]
  450.     }/ e+ Z9 C% m5 n
  451. + w4 W( p$ m! e  l0 c' o
  452.     default:
    + Q9 `- P" g( M1 b
  453.     {
    ) E) r) g: c: }0 ^% e- o
  454.       timeCount++;( C+ j& e) e# ^" P& u$ c

  455. ) T6 e/ y; R( @# E) I8 ]
  456.       if((timeCount / (timeDivide + 1)) > timeMax)
    . r3 k* t+ p+ c& n- d2 ]2 G- G( Q
  457.       {
    7 i$ }$ u/ L/ S. C5 o; i
  458.         timeCount  = 0;( H9 r0 q1 U4 C! W5 m( @# J
  459.         errorCount = 0;, `) Z% A, X) I/ l
  460.         dataCount  = 0;
    1 ?- H% \+ [' d+ V1 L7 e, a
  461.         code       = CodeNone;
    , e8 T5 ^. Y! J$ u0 l' b# Z* R
  462.         stage      = StageNone;- s, X$ I6 R( ]
  463. # X' z: [3 ^& C* r+ q  \5 k
  464.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    , `$ X" S) f8 L* y' {1 e
  465.         {
      O6 j5 R) j  U: O
  466.           txBuffer[txLength] = CodeCan;
    # r2 f( O2 P2 W
  467.         }
    5 h; Z  O+ v- @

  468. , w$ y9 ?) t8 Z9 t- r- \9 ^- ~
  469.         write(txBuffer, txLength);$ U( i9 t7 L$ ?/ s, G% b9 D
  470.         callback(StatusTimeout, NULL, NULL);
    % ]( s' f- Y$ S7 r
  471.       }) ~" ^3 G3 r; J5 j) j2 Q" q: d3 ^1 R9 i
  472.       else if((timeCount % (timeDivide + 1)) == 0)
    9 y5 F* W8 `% v/ V" _* }, A; @
  473.       {/ _+ c3 M2 m3 z% s9 ]8 _# O- Z
  474.         txBuffer[0] = CodeC;2 `& r' k) Q, E0 b# D( l7 s4 F
  475.         txLength    = 1;
    2 _: n" l6 o8 U/ D# n
  476.         write(txBuffer, txLength);' L  d/ B7 \) B; Z# h
  477.       }
    * {& H, p; ?1 |  R& \# L  `! J
  478.     }" l/ F- A. w6 e! n+ }* Y6 ~
  479.   }1 V" t5 c! E! v; j3 O  F
  480. }6 D7 z$ _0 ^. y+ m! U
  481. # R2 W" `0 `0 ^2 d& ^2 L- U
  482. /**5 R  [$ b$ x% m; a( P) \/ w5 k
  483.   * @brief  Receive established stage." k: ]3 v& C! p& x, T- S
  484.   * @param  None.  E! i; g* n$ Z, ^2 l
  485.   * @return None.+ h& b2 j7 K* g7 A; Y& ~
  486.   */  ], x& {  B4 L1 |4 C
  487. void Ymodem::receiveStageEstablished()" @: f6 k8 `# o8 L. V
  488. {) T; N) P5 X* T& v
  489.   switch(receivePacket())
    ; X$ |  D7 D: y- N' R6 w2 n
  490.   {
    $ u* P1 z& C  s" h' ^+ @1 z2 S
  491.     case CodeSoh:
    , H; G: `6 H/ [8 F. p  u, X
  492.     {! [7 d( {: H2 |1 R2 i0 F+ b
  493.       uint16_t crc = ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 2]) << 8) |
    0 k$ ~' ^( Q8 f4 Y! z3 p  U+ e0 E$ ~& Y" e
  494.                      ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 1]) << 0);
    5 g3 E1 Y1 m. q: H0 q! G
  495. ( ?2 W# p, r! G5 ~# F/ ]3 D$ u1 |
  496.       if((rxBuffer[1] == 0x00) && (rxBuffer[2] == 0xFF) &&0 l  C1 H" E* t: k- q8 f% d1 ^' O; w
  497.          (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_SIZE)))
    9 J. m6 m2 k7 L9 @% R. i7 ?7 }. f
  498.       {1 v/ D$ R9 Z3 H1 s6 L2 h
  499.         errorCount++;
    " a0 H/ I: v) o9 c2 |& b% k

  500. * u" G+ e+ z2 h5 ]
  501.         if(errorCount > errorMax)
    / N$ I$ \+ V* v) D, _
  502.         {
    ; D0 {# [/ A. N0 h
  503.           timeCount  = 0;/ s+ o+ t$ \; a  j( _
  504.           errorCount = 0;
    8 l4 o2 N. g& f
  505.           dataCount  = 0;
    ( ~3 ^, q7 ]( w
  506.           code       = CodeNone;7 R& n: _* b/ P0 L8 L
  507.           stage      = StageNone;
    % w7 U; v5 \+ j0 N5 ]0 _- k5 R1 b  S  o

  508. / S4 M" N! l5 H' \; G8 C4 s+ t7 |  z
  509.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)& ]) h; @9 ]% C" G, Z
  510.           {
    4 Y2 w# S" X4 x  Z# I5 M
  511.             txBuffer[txLength] = CodeCan;, }4 K, F: g5 J, u+ x
  512.           }& T8 q0 U2 V' P8 C
  513. + x4 B% `& @6 u/ f, S+ b
  514.           write(txBuffer, txLength);5 L) J3 y& E/ S# W" e9 z
  515.           callback(StatusError, NULL, NULL);
    3 h5 b7 l' o8 k
  516.         }
    1 ~7 p; s0 r( S# [
  517.         else
    4 x" F8 h- }; F# g. o" ~
  518.         {
    # d( l, M: a! f" ^! N' U6 A- B
  519.           txBuffer[0] = CodeAck;9 j5 h& T: |: w4 X
  520.           txBuffer[1] = CodeC;
    ) E1 y" E8 p; t) X( `: q
  521.           txLength    = 2;
    / |' ]0 |+ M8 z, K0 c8 E
  522.           write(txBuffer, txLength);: ]' |: y) T6 W9 E9 x; \# v$ y/ J
  523.         }
    , L2 H# R1 F4 \1 _
  524.       }0 @( X: e) [( b7 [4 o
  525.       else if((rxBuffer[1] == 0x01) && (rxBuffer[2] == 0xFE) &&8 [. q8 ^0 I, j* f
  526.               (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_SIZE)))
    : Q0 v+ |+ z7 P$ C4 G1 F
  527.       {3 E. q; W9 ]# k) ^
  528.         uint32_t dataLength = YMODEM_PACKET_SIZE;
    - Z! u& I/ S, B5 \6 K) G7 _- n! Q
  529. ) w7 I  i/ }2 ~
  530.         if(callback(StatusTransmit, &(rxBuffer[YMODEM_PACKET_HEADER]), &dataLength) == CodeAck)" ^' V- Q4 I$ S1 O7 E/ b
  531.         {% u" Z! J8 y: L5 l
  532.           timeCount   = 0;: O" X+ ?& Q1 B5 R. q
  533.           errorCount  = 0;. y; k2 T/ g, X1 s4 e4 Q
  534.           dataCount   = 1;, ~1 w! \% W8 p0 P- {- k# K& G( {
  535.           code        = CodeNone;9 B) Y1 D$ J( |' v+ N3 I1 ~  N. T2 N
  536.           stage       = StageTransmitting;, O. V3 W. p; m, j2 n5 T
  537.           txBuffer[0] = CodeAck;5 \+ O8 Q4 Y) D( Z. n, g
  538.           txLength    = 1;& r' b6 N* `2 M2 E( f
  539.           write(txBuffer, txLength);
    ! O# d, x0 S, K, @* |
  540.         }+ }6 m. H* u- r& |! u; K+ j# R
  541.         else6 ^* [, b" {9 ]9 K( }
  542.         {" A: z# r9 |: j- A% V
  543.           timeCount  = 0;
    ) z6 e+ t3 b1 a9 e2 W$ y
  544.           errorCount = 0;* J7 }$ Q3 @& n5 H1 _7 f5 m. `
  545.           dataCount  = 0;
    * k4 P. C( Z. h3 w, D5 |& o. Y2 L6 D
  546.           code       = CodeNone;
    - k) T+ a; B$ ]& P1 Z1 i+ P, R
  547.           stage      = StageNone;
    ) f, q" G! U  z8 j5 P4 ~& ]
  548. ) {/ n; M% h8 s# X- N- H) c
  549.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)- W1 N3 [# f8 c* b
  550.           {
    5 {8 b& i! C  U* V
  551.             txBuffer[txLength] = CodeCan;
    4 J1 j% O& P+ F  y! n
  552.           }6 V, s# @6 T3 S) ?; B; ~3 W" j

  553. * I, z7 L4 V7 W0 J" l% }) r9 ?
  554.           write(txBuffer, txLength);
    * n! s7 r% S) f  i# U- d7 q2 [
  555.         }5 q0 o/ }) y" E3 J
  556.       }
    / x' Y3 T3 y5 k& I) `* v2 A
  557.       else
    % ^$ b1 S: }, {4 {! T+ k2 S2 ?
  558.       {
    % C- T$ B4 ~' _' F/ g& y! y0 _
  559.         errorCount++;
    5 ]3 s  K( |2 c. `7 H3 O

  560. ) `* V. J( V7 p/ P1 ]$ L
  561.         if(errorCount > errorMax)* y" U! m9 P- c# \) u
  562.         {
    ! q" I$ x9 W# p& A$ x, P% M
  563.           timeCount  = 0;/ s: ^7 Y4 Q6 s9 V/ U4 ^1 X$ e
  564.           errorCount = 0;
      a) k+ W3 b, e3 A" f) n! w
  565.           dataCount  = 0;# s7 b+ z. z4 y" ^9 y% B7 E
  566.           code       = CodeNone;$ {' |1 g$ a2 d! Q) W0 z0 C
  567.           stage      = StageNone;9 B" r- i  T, t8 A5 R! O. K

  568. - m' l1 k- F" s8 v1 }2 M# M
  569.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    . m% M9 @6 s+ K3 u  ~# p
  570.           {
    $ ?4 ^3 S" N  Q7 F( X4 D( U# Y
  571.             txBuffer[txLength] = CodeCan;
    & }  L( @' S% w+ I' a
  572.           }
    # J) u7 K1 g* M8 C$ L# b( {
  573. 1 E% c5 O3 O. E$ @
  574.           write(txBuffer, txLength);
      i+ c8 m8 N- w7 _6 B/ k; \) Q; k
  575.           callback(StatusError, NULL, NULL);- ~9 P( ~( D/ f% A& L3 h" T1 [
  576.         }
    - {! \0 A# c+ j% \8 o
  577.         else
    ( {1 r9 x' _% w8 z5 _  u( u6 n
  578.         {
    7 x1 I. i! N8 B. U& ]
  579.           txBuffer[0] = CodeNak;
    4 ^( `& F( T! K: w0 q; D3 E
  580.           txLength    = 1;
    $ j! V- n& f% h. I
  581.           write(txBuffer, txLength);
    6 K) k# |7 e$ N, Y* k- W
  582.         }, z9 z" _4 D: b- Q) j4 z
  583.       }( R2 k1 n% F; L" U
  584. 0 D, A$ e' [% a, J) p
  585.       break;
    5 s( H$ O! R' H
  586.     }4 ~8 _5 M& ^$ f0 E

  587. 3 X* u* h" \  p8 j
  588.     case CodeStx:
    / V& g8 |" J7 E# F
  589.     {- Z2 E! t, W( Z# v( J- v$ I0 ~7 A1 o
  590.       uint16_t crc = ((uint16_t)(rxBuffer[YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - 2]) << 8) |; `' o7 M" L* K3 B* d& \) o8 K
  591.                      ((uint16_t)(rxBuffer[YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - 1]) << 0);: T+ c9 a4 E1 J# }5 S
  592. % s0 a$ @5 L0 [3 Y+ [' U+ H
  593.       if((rxBuffer[1] == 0x01) && (rxBuffer[2] == 0xFE) &&# Y7 i, X1 N9 d1 d* t
  594.          (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_1K_SIZE))): W& n3 s! Y# \* {
  595.       {
    ; R1 [' F* V/ S+ j
  596.         uint32_t dataLength = YMODEM_PACKET_1K_SIZE;' J8 T7 G5 i+ {0 k' z* W  F$ a# P

  597. + ?+ q0 e: [' p* n' h+ o
  598.         if(callback(StatusTransmit, &(rxBuffer[YMODEM_PACKET_HEADER]), &dataLength) == CodeAck)
    0 b3 i* w3 `" e
  599.         {
    ) Z, k3 x2 u8 w
  600.           timeCount   = 0;# t* x; f: K) H  H9 a- d
  601.           errorCount  = 0;/ P! x3 h9 a' t9 U7 t) N% F
  602.           dataCount   = 1;' T4 P2 b* c& m% P* n' t# C
  603.           code        = CodeNone;
    0 z% Y0 _1 W) n9 d3 z  {, J
  604.           stage       = StageTransmitting;
    2 j1 R  Z! x$ @" J
  605.           txBuffer[0] = CodeAck;
    . P( }, d: c' O9 Z
  606.           txLength    = 1;
    & J, l( R3 r) l/ u7 U
  607.           write(txBuffer, txLength);# f9 W1 C' c& c5 a4 g
  608.         }9 @( _9 N4 ~3 a! M1 t
  609.         else; g, n- Y; |3 o- E, k( ^- H  W
  610.         {* o; V6 x% S0 n  E4 S
  611.           timeCount  = 0;2 O9 s. T1 ^$ d. \( O) y3 p
  612.           errorCount = 0;, }$ [* W& |" S  B0 o+ w6 l
  613.           dataCount  = 0;. s3 T$ [9 A7 `) `; V8 o
  614.           code       = CodeNone;" v" c) \6 D) A- O
  615.           stage      = StageNone;0 v: S# _( G& u3 b. @
  616. 6 h0 R# V! X% u, M1 {! T$ f
  617.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)! W9 ?6 M. U$ `1 h' |* G5 e6 k: j4 C
  618.           {% n7 B+ p! P! i& y2 s& c
  619.             txBuffer[txLength] = CodeCan;. p1 @6 X/ h3 T6 b: x
  620.           }
    . M3 r7 q* q; N
  621. ! b: ?4 k  T8 ^5 L% k
  622.           write(txBuffer, txLength);
    ; c, a' Z7 G$ A, ^
  623.         }
    * J- x; N0 E8 D$ q' b# x# ?
  624.       }9 l5 O4 w9 x2 n7 N. i
  625.       else
    5 k* G+ |% x4 @/ S' x
  626.       {7 y" k: _4 b. Q( C+ j, E% _
  627.         errorCount++;
    ) {2 t' M3 S' D
  628. 2 q0 k$ C8 m5 O+ M
  629.         if(errorCount > errorMax)
    5 t4 g6 n# f5 q
  630.         {4 Q9 R: e+ _9 E5 K2 h% d) R
  631.           timeCount  = 0;
    : I1 {( C  j( E  e! s* F
  632.           errorCount = 0;9 s0 I& ^* [+ P/ K
  633.           dataCount  = 0;
    % M4 I  n' y+ t' c
  634.           code       = CodeNone;
    # a* s% A6 _0 L" E9 M
  635.           stage      = StageNone;
    ) I  l& l  u- e; L! J

  636. 5 Q/ `+ \* w# n; g0 Z
  637.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)' r8 y% _# @4 J' I* U0 c# b$ A7 E
  638.           {
    - t7 J( D2 n$ ~8 c6 W
  639.             txBuffer[txLength] = CodeCan;& {# L* Q: v9 Z' M
  640.           }3 ]3 [, \# g0 y0 O& F

  641. 3 B9 j. I1 t# Q7 u( f! z/ _7 M& t$ ?
  642.           write(txBuffer, txLength);, P* L! H% @& E0 J% C
  643.           callback(StatusError, NULL, NULL);' B1 U* o- H# d: H0 V0 J
  644.         }
    . c, F# P/ ~4 Z) K
  645.         else
    ' W; T- g# P" }) G; g
  646.         {
    * y9 Y( S" o4 b7 U+ j& w3 I
  647.           txBuffer[0] = CodeNak;
    3 z) `1 E7 y7 K$ K0 V
  648.           txLength    = 1;
    5 {6 v* T" |" b4 y" r
  649.           write(txBuffer, txLength);5 i0 T5 J4 n/ i9 Z# L
  650.         }
    ( @  T1 K7 U3 w. P+ G  \5 s
  651.       }; E$ ?0 R: j9 x* [7 Z/ J
  652. / [! M% w) Y( h/ E3 V
  653.       break;
    ( V! j& y3 V7 t. P* n
  654.     }
    , v& p& \# u/ J0 s  p

  655. ) }; j1 V7 D; W2 ^
  656.     case CodeEot:4 {! _+ r( h. b  m& f7 ~3 N4 u
  657.     {
    3 G3 \' ^. v; T& Q8 F! |5 x
  658.       timeCount   = 0;8 H7 F) S6 |+ X! a# g. t% I0 L
  659.       errorCount  = 0;$ Q5 K% j5 A4 Y+ _9 D, w
  660.       dataCount   = 0;* k( y: W! J- t$ n. Z" e
  661.       code        = CodeNone;
    ) G) }. v/ R: G+ F# R
  662.       stage       = StageFinishing;
    3 Z/ g; O" F6 {) [9 V
  663.       txBuffer[0] = CodeNak;* W% [' s4 R8 A/ S+ {8 g/ l' X
  664.       txLength    = 1;
    3 G+ ^* o; Q/ L( r: X3 D' M
  665.       write(txBuffer, txLength);* i. \1 s# C4 g, P

  666. 1 P$ W" }4 e0 y* U- u% y; P
  667.       break;% M8 \: U" }* u3 ~( [
  668.     }% n. r% g2 U! Z# l/ ?5 H, S6 A

  669. 6 x1 g% v0 [9 O
  670.     case CodeA1:
    0 |- S- G. P9 s' b3 t/ K
  671.     case CodeA2:  J' M8 K+ ]3 U+ W6 }
  672.     case CodeCan:/ {3 B" Z7 s+ X& T' y. C3 h( J
  673.     {
    . y9 ^0 G) J* ~$ \: x2 K
  674.       timeCount  = 0;
    ( ^- O+ U6 A! \* f
  675.       errorCount = 0;' B8 E9 b' R, t5 c* O+ f
  676.       dataCount  = 0;+ u) A3 z4 c5 w; J3 G. C% |8 ~
  677.       code       = CodeNone;0 h' f$ e' N6 R2 z2 w
  678.       stage      = StageNone;
      g5 R. c1 {2 r: i+ E- `
  679.       callback(StatusAbort, NULL, NULL);! @5 s5 x" x2 |$ E

  680. 3 f- l. g. n' x% ]' m
  681.       break;4 G4 s: v, z! _$ I) Y: j" [# c
  682.     }6 n, q2 G* g: [1 B

  683. + _" m1 }9 w4 `9 v2 j: G* c
  684.     default:* B( Y5 d, h, P# T$ n
  685.     {; r) N& Z$ p0 j3 o. Y
  686.       timeCount++;
    % E6 r: w: {$ k* W! Z
  687. , F; f  C4 t# y1 s
  688.       if((timeCount / (timeDivide + 1)) > timeMax)
    3 M) E5 t% q7 X; \3 f; m
  689.       {# u1 J1 d% U' W$ x: K6 K
  690.         timeCount  = 0;! m- q9 z0 J9 W+ C- ?5 m0 N3 H' c
  691.         errorCount = 0;$ ]2 H9 B9 b: f, S% l) O
  692.         dataCount  = 0;
    - b0 K' J( Q2 h9 x* p0 {5 \
  693.         code       = CodeNone;  i- ^6 R) Q8 r; K
  694.         stage      = StageNone;
    - P; @0 _" q3 q& p

  695. 0 T: n6 l# G6 o. S
  696.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    / ?4 K  ]( A6 `' x
  697.         {
    ) q- k" u$ w/ I, G$ o* W7 s: d! y
  698.           txBuffer[txLength] = CodeCan;
    * M0 z+ `( d* R0 W+ j/ [
  699.         }) N7 R8 j- u% s. Y
  700. 1 D; X; f' v9 f" }- V/ T
  701.         write(txBuffer, txLength);3 e! F+ h1 N) Y* A0 W- `
  702.         callback(StatusError, NULL, NULL);
    2 y: Q- O; E3 C
  703.       }, Z$ H/ F1 p, z& Q2 N$ O7 p
  704.       else if((timeCount % (timeDivide + 1)) == 0)
    % E( b  Q) l& y& t
  705.       {8 m5 [) W: ~$ H& j: k1 ~4 Q
  706.         txBuffer[0] = CodeNak;2 E# p; K  a, a+ N% \2 f, [5 P; q
  707.         txLength    = 1;
    1 v( B4 K* Z& y! A7 J- D
  708.         write(txBuffer, txLength);
    0 `' R; P8 C* _  G1 s  I0 I7 e
  709.       }+ g6 h: J. X9 V& g3 {
  710.     }
    0 }7 X# f& s  q! M9 S
  711.   }0 d" A* f4 t4 B( L/ ~# e" r+ B" f4 a
  712. }3 `* R! \0 G' ^" j" x% M& Q6 k
  713. $ ^1 h) g4 x* A- h* t+ L, S
  714. /**
    : L+ A) U4 Q: \/ ^, t+ j
  715.   * @brief  Receive transmitting stage.
    ; v5 G4 T! p3 m( w& P  a7 W+ Y- C
  716.   * @param  None.! E' e) K5 H7 R( t) D4 [8 ?  }
  717.   * @return None.7 z% g2 A, x' n) R; `7 [3 w
  718.   */7 i' N! C7 j, Z( y  e& V
  719. void Ymodem::receiveStageTransmitting()6 U# C. O2 w/ q! X4 e  X
  720. {4 s3 b! j! ?+ v$ m
  721.   switch(receivePacket())
    % y  t8 p& ]7 ?% O% h  Y' d3 p
  722.   {
    * K  }9 }, D" ~  f4 z7 S$ \, E
  723.     case CodeSoh:7 Q5 g1 X6 B& l& l
  724.     {. s2 i8 c! v6 n& P
  725.       uint16_t crc = ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 2]) << 8) |
    7 E* ^% f6 C" D! C6 {& {
  726.                      ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 1]) << 0);' K3 ^4 P# P$ s5 t0 L" @; x* v' t
  727. + f* Y9 S! {9 L6 y
  728.       if((rxBuffer[1] == (uint8_t)(dataCount)) && (rxBuffer[2] == (uint8_t)(0xFF - dataCount)) &&
    ( o. {6 y' w. Y
  729.          (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_SIZE)))
    5 f% M. U. G  b* d
  730.       {  T  v; C5 f6 d6 E! t
  731.         errorCount++;$ j5 |( Q! ]3 M4 J: t% j/ j
  732. 8 L1 l  X+ H4 F; g
  733.         if(errorCount > errorMax)
    1 O- |& b* c" j0 X# L
  734.         {
    . b! B2 ?( h9 \9 A4 g! F
  735.           timeCount  = 0;
    ! u1 K/ M# j! d) V1 t+ t) R) G
  736.           errorCount = 0;" Z  O! ?& u3 Y) ^' n- a
  737.           dataCount  = 0;
    5 W$ f& ?- b8 {0 V% F
  738.           code       = CodeNone;8 W( [" x! c4 G9 g  V
  739.           stage      = StageNone;
    9 F1 {* P2 w4 v/ C

  740. 2 N& v% M$ S4 ^! g% ^
  741.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    $ ]6 F2 ?  b* q# _
  742.           {
    7 B; C/ E+ |6 ]! a; l* i& t
  743.             txBuffer[txLength] = CodeCan;' Z: ]- v7 j" Z$ U# l/ }
  744.           }
    8 H  G: m, W  m: Z! d& A
  745. + n0 t: c) _0 k) ~/ y6 c& J
  746.           write(txBuffer, txLength);1 F0 M: j1 M4 }9 e# R
  747.           callback(StatusError, NULL, NULL);
    8 g( Y  N$ ]+ E
  748.         }
    9 T. \. E/ U6 ?
  749.         else
    . Y) q, b" P  J7 c# u3 X
  750.         {
    4 n  F% T( N, n: W6 x( M
  751.           txBuffer[0] = CodeAck;
    * B0 Q+ V* r9 U! ]! G, |
  752.           txLength    = 1;
    2 I* s) f! G6 T, m7 Y- Q/ Z
  753.           write(txBuffer, txLength);  Q) r, o1 Q, P8 t9 ^( Q' `* C5 B
  754.         }7 `/ F- q7 ?' K) r
  755.       }& S" }% f: M% l0 q) s' a' o) c
  756.       else if((rxBuffer[1] == (uint8_t)(dataCount + 1)) && (rxBuffer[2] == (uint8_t)(0xFE - dataCount)) &&
    2 v6 j' v7 ~. h3 H
  757.               (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_SIZE)))
    : d& A: E4 H7 z$ V
  758.       {
    * t( ]$ K% e8 c) H5 J9 m
  759.         uint32_t dataLength = YMODEM_PACKET_SIZE;
    9 w% {: w# g. \+ c8 H" H7 a
  760. - C2 u5 m. j0 H1 S
  761.         if(callback(StatusTransmit, &(rxBuffer[YMODEM_PACKET_HEADER]), &dataLength) == CodeAck)
    ( p6 [  j5 k3 l' _) Q" x
  762.         {
    + p& Q- x) q, ?4 i+ g
  763.           timeCount   = 0;) O+ e8 P, d& O/ @( N
  764.           errorCount  = 0;3 o. c+ ]9 n. ]3 f4 w. T" N& q. [
  765.           dataCount   = dataCount + 1;. I6 r1 {" Z+ ?% v/ [
  766.           code        = CodeNone;: F5 B6 j; H# |! j1 h7 z
  767.           stage       = StageTransmitting;
    3 M9 b% D  k# f8 e* g/ w+ B1 ^
  768.           txBuffer[0] = CodeAck;% P- Q- w4 u& N( [* y
  769.           txLength    = 1;# \# B" N' ]" T/ ~5 b% Z
  770.           write(txBuffer, txLength);
    ; T" f* B9 h! l. X& v) \
  771.         }/ h9 G) E% s. K/ S8 w% [
  772.         else
    8 h; B' I1 @" |4 v. M1 A9 h" s
  773.         {, M  K4 a4 t0 O+ t9 z- f6 r0 J0 G
  774.           timeCount  = 0;
    2 B- H* Z6 Y. G7 U4 J" S: G+ e
  775.           errorCount = 0;3 F' s  k0 ?& Q5 Z  J) J5 |; K% ^. E
  776.           dataCount  = 0;
    ) u% n7 F  d+ u& t
  777.           code       = CodeNone;
    ; h9 u8 O& ~  {8 s" {" b
  778.           stage      = StageNone;
    & j1 [, f$ B8 p
  779. # w- {+ C& ]" Z2 C8 K4 t
  780.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    ( {7 h6 ]- m1 q( C. A
  781.           {
    + G' k: N  y5 X" b' X. R
  782.             txBuffer[txLength] = CodeCan;
    : f7 f% Z* L- G1 `0 ?- J( U
  783.           }3 G* u; P- B) K
  784. . D, X4 N+ O, L
  785.           write(txBuffer, txLength);
    % `1 h1 C: E# N8 j2 p4 _
  786.         }: ]" N2 F; K8 `" l) [) x
  787.       }
    . O0 c4 a) ?! f( x( Z2 `
  788.       else3 Z0 d+ |1 J! I; p/ f' t% O3 p* n  ?& s
  789.       {
    6 o6 }% a! S. S# \- d0 I* i3 P6 |
  790.         errorCount++;
    + K$ Q! g6 s, }6 ?7 o

  791. : q0 c0 A6 ]& r8 L3 Y: A
  792.         if(errorCount > errorMax)0 b7 S% K. s- W0 B* |- r+ A
  793.         {
    ) u' \( q, C( V
  794.           timeCount  = 0;
    : W' w1 G. m0 k$ ?! Z' P
  795.           errorCount = 0;" j& R8 j, P* [+ v* O  a5 @
  796.           dataCount  = 0;
    4 U3 W; Y7 E" f5 V  c% Y
  797.           code       = CodeNone;
    % N5 X  r+ \; f- z8 z' N
  798.           stage      = StageNone;
    ; p4 b; O  M& }! D- A" S
  799. $ F. @( f5 Y, @/ H" u* I
  800.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)" Z% G- J3 F( k3 z; N" b$ p
  801.           {
    " [: \1 D- ^3 K7 V
  802.             txBuffer[txLength] = CodeCan;
    % u$ e6 ^9 ~' `0 p/ ?
  803.           }
    8 P! `* B4 r2 @- r2 [7 I) ]' s
  804. 8 r' M+ A0 X" o$ j& a) P5 j: v7 X
  805.           write(txBuffer, txLength);
    ( \4 j% M/ i, n* U+ d5 I
  806.           callback(StatusError, NULL, NULL);! t1 u$ K. y0 Z' M5 B' z
  807.         }
    ! B, z4 B3 w1 J2 e  f0 k# l" h  I  y" h
  808.         else
    ! W8 \/ ~; h" d6 g" s
  809.         {! G9 \# g3 P0 A( @5 I7 R9 I
  810.           txBuffer[0] = CodeNak;
    ; M* E: N9 j2 L/ v0 x
  811.           txLength    = 1;' R3 f8 z4 y, V1 W
  812.           write(txBuffer, txLength);! p0 A% {! n3 p* e3 ]3 C& p
  813.         }
    ; F4 I0 m! `  x5 q5 Q6 W( b
  814.       }
    ; e& X& e: C+ ^4 l- y  A

  815. : q: N3 Z5 ^" @! Y- v
  816.       break;
    : s! R" s2 I9 k
  817.     }/ V. c& f; g/ P# C6 d

  818. 6 _& v. a& H8 s# p( O' j, J" I$ D
  819.     case CodeStx:, L& a$ I; q' V
  820.     {4 Z' |" u% z5 o' _( K1 b7 B
  821.       uint16_t crc = ((uint16_t)(rxBuffer[YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - 2]) << 8) |4 g2 i! a, c6 b/ l; r
  822.                      ((uint16_t)(rxBuffer[YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - 1]) << 0);
    5 f( e; {/ t$ l8 K/ ?6 Y

  823. 7 c6 P' j: G$ R/ L; V1 x
  824.       if((rxBuffer[1] == (uint8_t)(dataCount)) && (rxBuffer[2] == (uint8_t)(0xFF - dataCount)) &&: i, @/ j  t* ?
  825.          (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_1K_SIZE)))
    / d' @3 t; S" V$ |
  826.       {
    + l* h/ x- f% X) I( i
  827.         errorCount++;" |+ `# O& s8 n' d
  828. # ?1 c6 j+ V* R6 K+ X6 v' c
  829.         if(errorCount > errorMax)
    9 A4 ~  L& H! t' [5 V) u
  830.         {) V. f; u2 I( |' u' _, C4 H
  831.           timeCount  = 0;
    % C2 K0 b9 q8 G7 `/ ]( X
  832.           errorCount = 0;
    2 P7 G( L# p* }" h$ [4 y# Z
  833.           dataCount  = 0;1 ^7 V+ T* G! {1 K) t+ J7 I
  834.           code       = CodeNone;6 n9 j" A  o1 ]1 u
  835.           stage      = StageNone;
    ) |7 T/ G% Z; o, T- r- k. L
  836. + T" ^( l$ v, ]) y) ~
  837.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    ; W1 G3 Y( \) h9 A8 z( f" q; h& p: [
  838.           {- j( C3 M. U6 [7 y4 u
  839.             txBuffer[txLength] = CodeCan;
      \/ _' \/ H; D, c/ [# Y- G5 m
  840.           }
    # R! d( o# B2 d6 o

  841. ; R  Y& i; [* b, g  k7 a
  842.           write(txBuffer, txLength);- n: P" i6 V& V  J4 Y# a
  843.           callback(StatusError, NULL, NULL);* j9 K, S4 _1 K! `5 d
  844.         }
    / A$ v% `* O% b
  845.         else
    , X# k9 @0 k! W1 p+ }" ]6 h7 j
  846.         {4 D9 H! c8 E9 F
  847.           txBuffer[0] = CodeAck;0 W/ A" M( T+ `2 @$ U: L9 [
  848.           txLength    = 1;
    % z. j5 a; Y$ D1 {1 b
  849.           write(txBuffer, txLength);' Q6 {8 R% X4 `4 ^! G
  850.         }. ?6 \! i5 b' C% p/ S
  851.       }
    + ^0 d' N" k$ _4 a, ]! a: Z
  852.       else if((rxBuffer[1] == (uint8_t)(dataCount + 1)) && (rxBuffer[2] == (uint8_t)(0xFE - dataCount)) &&% b' I  _1 Q; N/ e$ c9 w- t5 N
  853.               (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_1K_SIZE)))
    8 b$ P5 Z5 E8 d3 a% {( g
  854.       {
    & A% }1 Y9 {  J5 D& V2 J& }8 S
  855.         uint32_t dataLength = YMODEM_PACKET_1K_SIZE;& e% g' c& [2 ~) W0 [0 `. n& [
  856. ' Y7 ~) ^( ]2 z
  857.         if(callback(StatusTransmit, &(rxBuffer[YMODEM_PACKET_HEADER]), &dataLength) == CodeAck)/ h9 G8 V3 |- k' Z; y" h
  858.         {
    ( g+ h( O  I( E. Z: k
  859.           timeCount   = 0;+ E- k. B5 ^# r; {1 I
  860.           errorCount  = 0;3 I$ f) o$ Q; t" x7 [
  861.           dataCount   = dataCount + 1;( M5 s$ r* P1 w& L
  862.           code        = CodeNone;/ |8 I* N7 P- s. R. f
  863.           stage       = StageTransmitting;7 i9 S& L- p/ N8 j
  864.           txBuffer[0] = CodeAck;
    & O# d. ]4 F; R8 X/ _" [
  865.           txLength    = 1;
    # T& M/ D  W$ f" w
  866.           write(txBuffer, txLength);4 W& m* l4 y( n2 }% s8 r
  867.         }' E( c4 M) `5 D7 A6 s3 Q0 _8 [3 k
  868.         else2 a0 _1 J5 Y1 m; v
  869.         {8 Z% Z" r( w6 N2 Q  m
  870.           timeCount  = 0;3 v: c( c0 I. l3 ^/ V1 x
  871.           errorCount = 0;# A& B. D1 b1 V8 z
  872.           dataCount  = 0;( _" D0 }# G. d( R0 m, P% r; L6 Q! L
  873.           code       = CodeNone;
    8 p7 V1 B- J$ q, W
  874.           stage      = StageNone;5 J9 ]; R/ X( T
  875. . B+ u9 y8 w4 ?. z$ n- ?
  876.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    " r9 j' t" l! O0 ]. B
  877.           {
    : A/ f& {# m: {4 }1 E
  878.             txBuffer[txLength] = CodeCan;
    ( h& h# p7 ]# U4 V
  879.           }
    ) D2 H8 D& F9 }) [% \8 d! u
  880. 4 a9 s0 m8 v3 f" y
  881.           write(txBuffer, txLength);' r& `1 H  a2 H* \" S$ `
  882.         }
    ! E: S  _4 Z7 h% W4 e9 [
  883.       }: P9 n1 }  ~% o$ t  H* L" X/ z
  884.       else
    $ c- h* z; ]7 C) }5 G, T. y& r6 i
  885.       {7 b+ J* h3 e/ x, e& x/ \3 W
  886.         errorCount++;
    ( H( f2 d5 h& s# g4 X, H! D* a
  887. ; r. @( |4 z- R" Z, P* _
  888.         if(errorCount > errorMax)1 P' S5 E0 w5 c) @5 g4 \/ h5 P$ ^
  889.         {6 m$ Q  J1 N6 Y, _, e
  890.           timeCount  = 0;4 z8 \, T' s7 z  V" P, H# u% Y
  891.           errorCount = 0;
    # K) O& m$ J- _0 D
  892.           dataCount  = 0;
    7 E9 C# d5 O8 b8 L
  893.           code       = CodeNone;) p! j% l# q% i# ]+ Q9 I
  894.           stage      = StageNone;
    : k$ z2 }' f' j4 V$ S1 b. V. l! _

  895. 3 t" V+ H: I4 B6 X1 J) m
  896.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    ) {' \+ z( ^$ o2 n
  897.           {
    ) ?2 M# _) f0 f
  898.             txBuffer[txLength] = CodeCan;
      p8 O0 G' _1 M( y" f
  899.           }
    % W+ }+ v8 b8 Y
  900. ! b( e! M( l9 I$ a& k
  901.           write(txBuffer, txLength);
    ( V5 z( R2 U( y& y+ E+ D$ B7 o
  902.           callback(StatusError, NULL, NULL);
    1 X. `5 p, L9 W: l9 c* S7 d
  903.         }8 B- Z; }3 U7 U% `
  904.         else( `" T2 T! d# v( J: J/ v" A, ?: M+ d
  905.         {( h: f6 H; b3 i! j
  906.           txBuffer[0] = CodeNak;
    / @. ~0 j3 {& N
  907.           txLength    = 1;
    + I9 E) ~/ R$ J" ?
  908.           write(txBuffer, txLength);1 F/ S* [. X* t8 e5 @+ m& D
  909.         }4 M) G  ~: O# a3 r& z: z) W; {, \
  910.       }! T$ ?5 R! n. J) b# V

  911.   ~0 I+ b  f( t/ o. V, \7 J1 r4 X6 v! ]
  912.       break;) l, E4 i2 o; `. F7 K
  913.     }$ T" }0 S+ ~* [  v4 E
  914. 8 m, F& {& ?8 N" B
  915.     case CodeEot:
      S2 C2 @: e% R1 u
  916.     {% |" V7 V. l4 h* h
  917.       timeCount   = 0;
    6 v  T" |& }/ \5 `2 D3 I
  918.       errorCount  = 0;
    4 a4 b& x8 f" C" b
  919.       dataCount   = 0;
    % n  L( p# N: {( n, l6 w' Q' H
  920.       code        = CodeNone;, }7 n, g- I1 ?( {8 G
  921.       stage       = StageFinishing;
    2 ^: w% o% D  Q# E1 f0 x7 j
  922.       txBuffer[0] = CodeNak;
    8 p) q1 ]4 A4 o8 N
  923.       txLength    = 1;
    0 U9 \; \2 s4 w: a$ E/ l# v5 [
  924.       write(txBuffer, txLength);, K! ^" j9 \& o3 C% D

  925. 3 g9 V1 K4 y# G2 X4 E* C# }
  926.       break;
    0 b/ O" K& }/ P0 y# T7 Y* N
  927.     }
    1 |4 A' k. g5 P  l  `; D
  928. 2 f- f, S: F6 _: {% Y
  929.     case CodeA1:: s- e1 ^, U, c
  930.     case CodeA2:
    4 B. f% Q" n: U6 u
  931.     case CodeCan:, g4 Q9 ?8 G, K
  932.     {
    2 B) W2 J4 y* c. x
  933.       timeCount  = 0;
    8 f/ x; f; s+ j" _# ^. G2 K. w
  934.       errorCount = 0;
    . g: B) g) [$ H8 C5 @- b
  935.       dataCount  = 0;
    . R) l* a* |8 k# e7 W
  936.       code       = CodeNone;2 L0 d: y& t0 c1 T5 D" g7 T
  937.       stage      = StageNone;
    9 Z, Y% x% G  o
  938.       callback(StatusAbort, NULL, NULL);3 r) B' @" P1 t, U. `$ v# c

  939. 7 u5 K7 ~. D8 N, N  v9 y. v
  940.       break;
    , y+ S9 v2 C7 n; Y* ?1 F  c
  941.     }+ v& b6 `9 E( A& u; N: }

  942. ( L, R8 ^# @0 q9 r) H: B9 H( |" l
  943.     default:9 V5 V! I/ Y# R6 e1 t& ^! M5 J. v
  944.     {9 b( f4 P; c) e) [
  945.       timeCount++;
    6 e0 ^" F  h6 y; Y

  946. " u5 W( Y/ Z" s/ N* n
  947.       if((timeCount / (timeDivide + 1)) > timeMax)- b! x. V' f% z, m2 L3 C
  948.       {
    + W1 t+ M9 \) y& _, v5 f
  949.         timeCount  = 0;
    " ~! V- L; V. }/ }
  950.         errorCount = 0;
    ) l" n7 W: o  H$ E
  951.         dataCount  = 0;$ S6 u) A: d# s. i7 a& B6 K; d9 M
  952.         code       = CodeNone;
    8 Q3 x1 n2 @* K6 |8 \
  953.         stage      = StageNone;( P2 o" ]3 T- m

  954. 6 m' L8 b) n0 V
  955.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    1 Q+ d$ s* s7 u0 o. W% V) p  u
  956.         {* X$ u: ]1 q2 ?. \2 O
  957.           txBuffer[txLength] = CodeCan;: y1 o* {' `& x- R
  958.         }3 c$ S( a4 ]! w1 B& g& F9 s

  959. ' K. ~4 [$ {. D& k. p
  960.         write(txBuffer, txLength);
    % S- X. Q; n' v5 J* y) l5 `9 Q+ b. |
  961.         callback(StatusError, NULL, NULL);% V( B# \2 Y$ ^5 q% Z0 D4 U. W
  962.       }
    ) w5 M5 j1 \; @1 I; s
  963.       else if((timeCount % (timeDivide + 1)) == 0)
    8 O  P0 n& k/ V" ^8 J6 r; `
  964.       {
    * D- C8 V3 R7 V, I1 |  x7 e& x
  965.         txBuffer[0] = CodeNak;
    % ~" g1 C( ]: {; t5 ~5 [8 @2 V6 l- l
  966.         txLength    = 1;
    3 k& g1 ~) h4 l0 g' N
  967.         write(txBuffer, txLength);/ q/ F5 ~( F4 f  \# O
  968.       }3 P& S( {$ C' m9 h5 t
  969.     }
    ; a" L- @$ p* X6 N6 S$ ]
  970.   }6 l( Y+ L7 n' O% \
  971. }
    - Z# N3 L4 k( F' P; S

  972. , m. m. g5 e6 |. V# R
  973. /**8 j. M7 q. _3 N" K: x# P
  974.   * @brief  Receive finishing stage.
    + }, J+ Q0 v! F% v; m
  975.   * @param  None.; t0 M2 W! H; B, e) @4 d4 I
  976.   * @return None.: k( @9 G2 `/ c/ J$ X) ], x
  977.   */
    ( i) ]/ H) e) f6 r* b+ t/ Q
  978. void Ymodem::receiveStageFinishing()
    4 |6 u$ V6 |8 e; T2 ^
  979. {+ [2 P0 S8 s( N2 e& v
  980.   switch(receivePacket())% X' n4 m' d; n- W% H
  981.   {3 t1 {) ^5 j8 _
  982.     case CodeEot:) O2 F* h! Q2 y; Y, ~0 d; n% J3 O
  983.     {; ^  [4 e$ w$ h. Z0 {7 U+ Y- A4 {5 L6 E; m
  984.       timeCount   = 0;
    $ y/ z! B5 l( \6 f$ `, J$ S5 W
  985.       errorCount  = 0;$ V8 G, \5 x0 u- x4 v  y- b$ B( b
  986.       dataCount   = 0;
    ) G% d1 F7 Z/ l
  987.       code        = CodeNone;2 s2 ~" W' G! r6 X
  988.       stage       = StageFinished;% x. G  A/ k/ N% K9 t$ G+ H9 d
  989.       txBuffer[0] = CodeAck;7 g' b4 _2 z; l3 h/ \! j- Q
  990.       txBuffer[1] = CodeC;9 N* o$ n, V/ d4 m- q
  991.       txLength    = 2;% o# S  O$ U/ R) z* Y% F( q
  992.       write(txBuffer, txLength);
    5 r& Z0 |/ U/ E* H

  993. / F& u6 t- M/ V/ T/ F. F; V
  994.       break;
    ( l' ]# ~% N6 t! N( n
  995.     }2 o9 E1 Q% R( L' f4 O9 G# i
  996. ( ^: O0 F$ `5 q; g+ s- z  U) D. c! m
  997.     case CodeA1:
    0 w* O7 v, }( A. _
  998.     case CodeA2:+ V$ D- D, b" n* P$ J
  999.     case CodeCan:1 i. n/ r  U* F" C" [% O. Z) U; `
  1000.     {
    . |  `% Y4 V9 c5 c9 p( s
  1001.       timeCount  = 0;( k! t& M2 K. F4 X4 h" Y  _
  1002.       errorCount = 0;
    9 K. ?6 |0 M7 C& i
  1003.       dataCount  = 0;' r' `. B$ R1 k. f
  1004.       code       = CodeNone;/ u+ G6 C6 b" h  y0 r6 {% p9 H! e/ Y' J
  1005.       stage      = StageNone;
    3 b+ Q. ^6 K& ~& L: V
  1006.       callback(StatusAbort, NULL, NULL);
    ' J% ?- Y4 @& N& v+ V9 M+ a

  1007. ) b# y* S+ V$ _1 K7 X3 S
  1008.       break;, C  ]& s1 _: O; J" U$ h
  1009.     }
    7 R. T% j: z) M; C& v& u
  1010. 5 Z' z# D4 p/ T+ v
  1011.     default:8 D# C$ @, \" J7 o3 |4 V
  1012.     {
    $ g. t: ]4 u# s5 W3 [1 ?% R
  1013.       timeCount++;0 d' ]7 `7 q; v% D. v) }$ [3 [

  1014. : l: o& [! ], h* _" R
  1015.       if((timeCount / (timeDivide + 1)) > timeMax)* K( u# H9 A$ e
  1016.       {
    : n8 S8 W7 b/ Y
  1017.         timeCount  = 0;" u5 a) y& |' A% _- q
  1018.         errorCount = 0;2 \3 l  v- ]( D: [1 h
  1019.         dataCount  = 0;
    % q! W& {4 g/ G: U
  1020.         code       = CodeNone;6 w  h, m& j& N3 p$ p, y
  1021.         stage      = StageNone;- S9 d, d5 n+ r6 ~, @8 |
  1022. ) @- e6 ~- U8 p3 w
  1023.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)9 u: B8 m# R* K) l2 I" |' t
  1024.         {
    : o/ V9 G, v/ y; D( U
  1025.           txBuffer[txLength] = CodeCan;
    ; M) s- t6 z3 ^2 }  b/ t* P7 n5 Z
  1026.         }- p0 B8 J1 }! e: Y7 G2 W  S
  1027. 2 G. W. b5 s- c* }- x
  1028.         write(txBuffer, txLength);* S, u' Z! H1 [+ }1 g
  1029.         callback(StatusError, NULL, NULL);
    / z5 v9 e* ^2 U, Y
  1030.       }
    / T0 W0 P$ }2 f* a5 O/ t% o+ t& N
  1031.       else if((timeCount % (timeDivide + 1)) == 0)/ G( F( H( _2 e+ a- D
  1032.       {
    ! k6 j; P4 r7 ~5 Q( x* X7 v4 j/ L1 D
  1033.         txBuffer[0] = CodeNak;  c4 V3 k' Y3 o, M. Q8 f
  1034.         txLength    = 1;, K1 T5 n5 c7 K" j
  1035.         write(txBuffer, txLength);
    - ]& C; U8 o% n
  1036.       }7 C( i4 f$ h" X$ Q, ?2 g4 V
  1037.     }
    ) G2 ]2 o, w' Y
  1038.   }
    1 ?1 y2 a, [( C6 I$ ?
  1039. }
    6 R# [& y# Q8 d* d! E

  1040. 8 p8 I0 C' |7 T5 ^1 T3 k+ m% M
  1041. /**
    ( D, P( }4 y" N# E- e# N$ S1 n' a. B3 u
  1042.   * @brief  Receive finished stage.0 O) N' {5 b) g0 H& A+ m
  1043.   * @param  None.( \% Q0 K4 p3 I4 t
  1044.   * @return None.
    ) X, L% M/ C/ A( D) K* L% S8 y
  1045.   */2 l+ z) e  W& c' r: `2 l6 J
  1046. void Ymodem::receiveStageFinished()8 c- K9 q  _$ [" F$ s" x: l
  1047. {9 N2 Y4 @! ]% n2 o) y/ D: e" a
  1048.   switch(receivePacket())# u9 x6 K+ F/ C# J
  1049.   {7 ~- c2 i% J; O5 s
  1050.     case CodeSoh:! A3 m) G5 F9 W5 N) {
  1051.     {
    7 a& M# `; n' O' }3 ^
  1052.       uint16_t crc = ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 2]) << 8) |' v8 Z. `& L( y+ P2 o# ~' w7 o
  1053.                      ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 1]) << 0);
    9 P6 O4 w9 r9 b4 r

  1054. ; G6 h/ c# ~3 y) `9 _
  1055.       if((rxBuffer[1] == 0x00) && (rxBuffer[2] == 0xFF) &&
    5 M. ~1 l# T5 d7 e4 A) Z2 F
  1056.          (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_SIZE)))6 _3 Q1 ]8 Q) J2 z
  1057.       {
    $ ]6 D! S+ _7 d
  1058.         timeCount   = 0;+ x  c( V+ m" K" w5 Z/ e, h
  1059.         errorCount  = 0;1 `2 T4 Y* K( q6 `. V
  1060.         dataCount   = 0;# n( c$ D, K) J$ j7 I# t8 a
  1061.         code        = CodeNone;
    2 ]9 o  ~6 o) G5 E5 l4 i+ W
  1062.         stage       = StageNone;
    : d2 z4 \4 E2 ]1 [0 J4 ?1 M& U' [
  1063.         txBuffer[0] = CodeAck;
    % e! R& T7 k0 ?: D6 |$ B& W- U
  1064.         txLength    = 1;
    + V* g  ]* G3 A, W% z3 f
  1065.         write(txBuffer, txLength);' o1 m8 q; g) O+ ]9 r
  1066.         callback(StatusFinish, NULL, NULL);# N7 T  g! z: n4 b
  1067.       }$ q$ n0 c* g% G' w7 I/ t9 s
  1068.       else6 w( r$ k8 X8 [# |9 T2 R
  1069.       {
    5 e! V; q: j2 N+ N: N
  1070.         errorCount++;
    - R4 w7 U: E. p2 ]/ t
  1071. + r& P; ?8 W2 i) a1 o' i2 ?
  1072.         if(errorCount > errorMax)3 }+ u* c4 E6 H$ `- y3 R4 |
  1073.         {) b8 x; F! C* s% Q& W, U
  1074.           timeCount  = 0;3 n7 Y8 w4 b" K  ~
  1075.           errorCount = 0;
    8 b; E% s8 C( ]! q  Z; N
  1076.           dataCount  = 0;
    . }6 \7 r2 a5 ?
  1077.           code       = CodeNone;
    9 _/ y; N. d4 M! s6 t0 I
  1078.           stage      = StageNone;" U( a) Z8 z; o

  1079. - i- Q8 v1 w2 K  F  t. Z
  1080.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    . M& p- t1 I' U, v' d6 g" K
  1081.           {& l: g4 G& z, Y0 O: y% ^' f' e
  1082.             txBuffer[txLength] = CodeCan;
    4 Z4 @% }5 W& y& x
  1083.           }8 B6 q- k4 u7 P2 x/ w* U
  1084. 7 u3 ~: |# b/ L# V/ Z+ X5 s& k
  1085.           write(txBuffer, txLength);
    1 h6 r0 U5 _% U- k+ G
  1086.           callback(StatusError, NULL, NULL);4 {( r8 }3 R$ l# ?5 u
  1087.         }
    + G0 @& L' O5 _4 b
  1088.         else. e3 P8 s- W6 a6 g  V' z
  1089.         {
    0 s4 L5 _+ Z! L* u
  1090.           txBuffer[0] = CodeNak;( P/ c9 e* I& A; v, M
  1091.           txLength    = 1;6 J  P( V, r/ d" G, g
  1092.           write(txBuffer, txLength);
      Y$ E3 T: k) }
  1093.         }
    2 c/ u$ m/ ~7 v; l$ S, C
  1094.       }2 P* [# p2 S1 N' I9 X' ]* e4 L9 \
  1095. 0 D( W/ }% z, P$ x: `
  1096.       break;6 j+ L% n( d6 x" m
  1097.     }
    $ B; S) q, x, j

  1098. - A  y9 r) t" D. {' s
  1099.     case CodeEot:. N5 c* [% |6 z) e
  1100.     {
    1 d! ]' l7 e# i( l5 J
  1101.       errorCount++;3 c, s: W" ?& i: J- k$ _

  1102. 8 h& ?" y. w  R' P$ m
  1103.       if(errorCount > errorMax)& U( ^5 ?* }: ?0 u- a) i! @
  1104.       {: K9 d4 l; Y& Q5 O
  1105.         timeCount  = 0;
    - r0 P% y; B0 d. [0 O
  1106.         errorCount = 0;
    & |% }& U* s2 C2 z
  1107.         dataCount  = 0;
    0 ?; E- a# o! I  r
  1108.         code       = CodeNone;2 n0 C. x% s# e; j
  1109.         stage      = StageNone;
    # v. g" M7 ~" {+ `$ @( ~$ [
  1110. . h0 c3 ]8 {/ A- a' Q0 w2 V
  1111.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)3 A; M1 f$ k/ i6 O, L
  1112.         {3 g( b9 l$ \# ?
  1113.           txBuffer[txLength] = CodeCan;
    % j3 H3 ?6 ~( H2 X$ _3 }
  1114.         }% V7 M, ^, H; J9 \

  1115.   `. z+ _1 }& G  X
  1116.         write(txBuffer, txLength);
    2 E& k+ |1 \8 r5 c, k- r( [
  1117.         callback(StatusError, NULL, NULL);& a5 G' C( x5 g+ r# E
  1118.       }
    + J1 f6 O/ S* o9 p5 R
  1119.       else; _$ ]4 W  {/ z# {0 r
  1120.       {8 S+ U8 Y4 \( ^' h, X3 |
  1121.         txBuffer[0] = CodeAck;
    % y: V1 J( R$ Y& U& s" o
  1122.         txBuffer[1] = CodeC;2 H) n% x6 V4 f' s8 Q7 S
  1123.         txLength    = 2;$ a' L4 y) u0 N: L* `% s
  1124.         write(txBuffer, txLength);+ {5 Q! z$ U! y0 ]  `7 l+ o, [
  1125.       }
    $ l+ Q) k% ~$ s# M1 r" c
  1126. , W: g; N. V! r1 R" y4 Y) a
  1127.       break;, @: A3 T- Y' K+ n% L3 y' z" Q
  1128.     }
    ; U0 O( [8 T1 I

  1129. % O4 O) V5 z6 f5 A4 i/ ?0 E( J) Y
  1130.     case CodeA1:
    6 k; g7 ~/ q2 C
  1131.     case CodeA2:
    3 z9 _' M; c. k  w8 M! r# {
  1132.     case CodeCan:3 g6 ]- ]1 v' a* N+ L. r
  1133.     {* a0 M0 F3 j) c+ q
  1134.       timeCount  = 0;7 I5 H8 W  O1 ]/ O! T9 k
  1135.       errorCount = 0;/ \8 M* f, }2 D+ Q: t
  1136.       dataCount  = 0;
    / B. A! e2 p6 Q+ i$ A1 N
  1137.       code       = CodeNone;
    1 x1 Y( i/ ^6 j0 q2 k$ y( }
  1138.       stage      = StageNone;) e8 V- K: h. v7 }# w
  1139.       callback(StatusAbort, NULL, NULL);
    : W1 c# J0 e- O# G4 K9 A

  1140. 2 ^/ |) }& `6 y+ V; v6 G
  1141.       break;4 z2 k  m; a: S+ @/ ?7 g1 s
  1142.     }/ n5 b; k' {$ j. ?5 }0 O& s( A
  1143. 4 B0 g2 t( F; y% O
  1144.     default:; B4 G8 [) e8 d0 N
  1145.     {# \, \) ?* I1 @0 K" N3 i( V( s
  1146.       timeCount++;
    / B5 q0 v) K3 R6 _
  1147. - P; C( q0 e2 V
  1148.       if((timeCount / (timeDivide + 1)) > timeMax)
      y. e0 s) C" {% E5 h9 ]
  1149.       {
    , ?6 ?+ _" p6 s- e
  1150.         timeCount  = 0;
    + P; }! w/ r- ]* d8 u6 @3 {6 Q, x3 g
  1151.         errorCount = 0;
    $ X0 H7 y% g( f5 k* D
  1152.         dataCount  = 0;
    , ?: h8 g4 V0 {  ^! V
  1153.         code       = CodeNone;5 {. r  t3 B4 m( M6 z' k
  1154.         stage      = StageNone;. L  T$ Q3 P$ K4 `, v4 X/ B

  1155. ( Z; y" L% H0 V+ M1 Y$ G
  1156.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)& I. s0 |8 s/ C  ~: p. C
  1157.         {6 q; }) L! }+ m; ^8 a: Z: F8 k
  1158.           txBuffer[txLength] = CodeCan;2 I; w6 c# d* F4 T
  1159.         }
    " R; V+ W5 C( Z6 x, q# b3 H/ z  n
  1160.   L8 f& _2 g1 W3 ^  o8 w6 ]; q) m
  1161.         write(txBuffer, txLength);
    9 I) _3 @- {# i( w/ _$ p# F
  1162.         callback(StatusError, NULL, NULL);8 |* x9 T. V- O/ w: k
  1163.       }
    ; n) i6 n+ H# z# }. B+ l+ W
  1164.       else if((timeCount % (timeDivide + 1)) == 0)! y; i: M& L/ O- }/ s2 h, Q
  1165.       {. m; w' Q% U# P3 m5 I
  1166.         txBuffer[0] = CodeNak;
    & G" Y6 }0 F# q1 u/ K5 k& m' R
  1167.         txLength    = 1;& G% U, {* a4 s) T0 [% {6 Q
  1168.         write(txBuffer, txLength);3 N. t; E3 u, m. d* x  W0 o/ _
  1169.       }' r: z6 b# A  \. s7 M) `3 x
  1170.     }) w9 C6 G5 ?4 ?5 S
  1171.   }
    8 Y5 m9 q" M1 G+ n2 Q$ n
  1172. }
    ( c9 {: d6 j3 i! C1 q* v
  1173. % h2 z" `3 j8 e! t7 v/ K3 }
  1174. /**
    " u( P7 p: _! U' {
  1175.   * @brief  Transmit none stage.  P9 J- Q7 X/ i+ J" k# O8 [+ p8 T, a( J
  1176.   * @param  None.
    5 d8 `0 ?! [+ a) L' ]
  1177.   * @return None.& z( D9 j' N7 M. D- Y) o1 H. }
  1178.   */1 }. P% m0 [& E
  1179. void Ymodem::transmitStageNone()" S3 K8 w8 l9 B6 u1 t5 I
  1180. {
    + g+ k) P0 ]- C5 L4 J: s: V  |: Y
  1181.   timeCount   = 0;
    4 R4 o! O" F, P% R9 U
  1182.   errorCount  = 0;% G. c! _% q( O: j& h
  1183.   dataCount   = 0;7 f1 d+ Z) E9 O9 z! f
  1184.   code        = CodeNone;
    : ^+ i& D! [8 A. }
  1185.   stage       = StageEstablishing;
    ! |3 U: F1 _' M9 \  P' z
  1186. }
    . d& t, `5 P( Q8 F! I" U

  1187. 0 ?3 @* r1 \, e: S9 F
  1188. /**
    0 |( X# ]1 h. s- \# O; b/ h: {
  1189.   * @brief  Transmit establishing stage.
    9 q, u6 x7 L3 x7 f
  1190.   * @param  None.
    + l6 `: U! v/ d0 \
  1191.   * @return None.
    , {3 Y  C% c7 X: X
  1192.   */
      D9 a1 G3 S, T$ y. _
  1193. void Ymodem::transmitStageEstablishing()
    ; N4 b4 a8 x' i& L+ c, z7 x
  1194. {* X: q3 b/ \0 i3 Z/ E$ g: t. b5 T
  1195.   switch(receivePacket())9 o. N$ _8 o; R: d" C/ j( g; w
  1196.   {# b% \/ }2 H3 K3 b  i- \
  1197.     case CodeC:
    $ ]7 n: N# s# C. u3 c) [
  1198.     {
    , b, B7 E  f4 u% S5 R* b
  1199.       memset(&(txBuffer[YMODEM_PACKET_HEADER]), NULL, YMODEM_PACKET_SIZE);
    ' o( |2 b0 d# p/ i2 {- w

  1200. / X% r5 N  }! u$ s
  1201.       if(callback(StatusEstablish, &(txBuffer[YMODEM_PACKET_HEADER]), &(txLength)) == CodeAck)+ |4 I4 G& M* J/ l
  1202.       {
    : Q- R, w% H$ x
  1203.         uint16_t crc = crc16(&(txBuffer[YMODEM_PACKET_HEADER]), txLength);$ r5 [2 e: ^! I( {- ~

  1204. # n8 v0 X& m3 y1 \2 N6 W  M
  1205.         timeCount                                       = 0;, C, ^% l0 }- u; L
  1206.         errorCount                                      = 0;5 x( M( e6 L; t0 e/ w" J, o
  1207.         dataCount                                       = 0;
    # R- m( E; ^8 k+ j
  1208.         code                                            = CodeNone;+ t$ m) ]7 d  \9 Z
  1209.         stage                                           = StageEstablished;% C# |& s, X, j! B& T
  1210.         txBuffer[0]                                     = CodeSoh;
    4 _4 ^9 O7 x8 n9 b2 h) F$ b
  1211.         txBuffer[1]                                     = 0x00;( D3 ^. i6 K& G2 t5 |6 K
  1212.         txBuffer[2]                                     = 0xFF;* I5 s2 A# J0 c; l; @7 H" G4 }3 B
  1213.         txBuffer[txLength + YMODEM_PACKET_OVERHEAD - 2] = (uint8_t)(crc >> 8);
    / }$ Q- ~* a. K2 d( z3 N
  1214.         txBuffer[txLength + YMODEM_PACKET_OVERHEAD - 1] = (uint8_t)(crc >> 0);6 j/ ?+ r1 F. D. g& m! u
  1215.         txLength                                        = txLength + YMODEM_PACKET_OVERHEAD;
    ; m6 S/ q/ l5 m( m; X% d" a
  1216.         write(txBuffer, txLength);
    3 v- b- a' C# ?5 Z2 \
  1217.       }
    % _0 m( n5 _9 Q+ b4 N
  1218.       else1 x# k" r6 a9 N) b$ R
  1219.       {. h8 r* R2 o0 i" K
  1220.         timeCount  = 0;  @; ?, s  x2 F: w  ]8 e
  1221.         errorCount = 0;" s8 G% ~! b. t  ~, f
  1222.         dataCount  = 0;2 J4 S0 }% X+ I( f( ~) e2 w+ X: h2 M
  1223.         code       = CodeNone;& H$ I( I2 A& D1 T- C
  1224.         stage      = StageNone;! e& O5 D2 V, [
  1225. : m7 e/ F3 D, f. h. v7 I( ~$ h
  1226.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    3 i- [) L- e$ O: w9 w& U
  1227.         {; x/ q  o3 L+ m, n' _/ M. p
  1228.           txBuffer[txLength] = CodeCan;
    6 r) k- `4 ]8 {$ @
  1229.         }
    ( q4 \; i$ q8 `! `7 ]
  1230. 2 y" M, P; u5 o% U
  1231.         write(txBuffer, txLength);
    0 a: {0 z/ V! S% y
  1232.       }" L- G/ W5 |+ L5 h" c- l6 c+ C
  1233. 8 U4 y7 x+ ]( N+ P2 f# \
  1234.       break;
      z3 V/ t( ?; ^7 b* R
  1235.     }; ]$ T! j# }9 r+ c

  1236. 6 i/ P4 T: V& v5 z0 ~/ Y& y5 I4 A" a
  1237.     case CodeA1:
    % @. ^% p4 e* L0 a3 B
  1238.     case CodeA2:
    $ ~& s4 r: j5 u8 G2 c8 h. C
  1239.     case CodeCan:
    ' r4 P" Z- m3 T0 n  G" w1 k
  1240.     {; u( r8 D/ i1 y: p  a
  1241.       timeCount  = 0;
    : u0 K; c% d8 }! C' p' v3 a
  1242.       errorCount = 0;
    , \; [; b1 S2 O( e* a' `
  1243.       dataCount  = 0;
    # @, O3 E; E) B$ Q& m& k7 v9 V5 ~
  1244.       code       = CodeNone;8 J; {7 |( v& F' Y/ Z
  1245.       stage      = StageNone;0 [& F( R. r1 M7 `7 W
  1246.       callback(StatusAbort, NULL, NULL);
    4 Q' w5 z8 e9 K1 p+ N" N, l
  1247.   K# h3 L8 @! N7 P% t$ F0 K
  1248.       break;5 Q, d/ A# E5 ~7 K" H7 ?9 Y
  1249.     }1 n; w: D' a% Z+ G% D8 n1 n

  1250. " d$ _$ X: _& U3 M
  1251.     default:/ _8 E% o9 J/ N1 K
  1252.     {9 J+ Y7 h7 R  H& M' S' f( R
  1253.       timeCount++;
    - `4 u2 B6 O* T
  1254. ; v. O* J9 W; _' w) o$ U% v
  1255.       if((timeCount / (timeDivide + 1)) > timeMax)+ Y, @. ^# k  h6 y8 B/ S
  1256.       {2 _( m+ D6 S6 C" E& x
  1257.         timeCount  = 0;; R- T0 @2 N3 t9 A  Z- K  t% D- `
  1258.         errorCount = 0;9 M* c) ~: a6 B+ {
  1259.         dataCount  = 0;1 W) ^+ X# A: C' [! K2 R
  1260.         code       = CodeNone;- `6 ?2 p9 R: X
  1261.         stage      = StageNone;
      s6 H6 K7 J3 i4 j5 m
  1262. 0 L6 z# K3 Q" D+ h5 e7 i$ o# X3 q
  1263.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    - a2 a$ F- D  C
  1264.         {
    7 o7 R5 }3 d5 ~5 N! d' D' s" g
  1265.           txBuffer[txLength] = CodeCan;
    # C8 z2 k) \- X! d
  1266.         }
    - {& I3 [* A6 _+ G  ?  P

  1267. / K6 d& t6 J  S" A- R9 L) f$ a$ Z
  1268.         write(txBuffer, txLength);
    ) D$ @( A7 a! N, O& M7 |6 s2 Y8 G# A
  1269.         callback(StatusTimeout, NULL, NULL);
    2 k9 S, s; U7 k
  1270.       }
    - ^8 s, N: [$ C0 S% o
  1271.     }
    * @  ^% m6 s, @- h9 M
  1272.   }
    % c- b! E5 x% x; k7 P
  1273. }7 M0 t% T9 M& i1 ~1 V
  1274. : y4 \. l5 ^5 h; j, r: G% ]6 {
  1275. /**$ u; w% D7 p- Q5 k' U  G% R
  1276.   * @brief  Transmit established stage.
    7 T+ s1 F; t# V0 Z
  1277.   * @param  None.: W1 [+ W1 `5 r0 x; P1 _/ T) m, ^
  1278.   * @return None.
    9 j; r; L6 p& f" T3 y# }" s' T) E1 z
  1279.   */) R- K1 U/ D& F
  1280. void Ymodem::transmitStageEstablished(); r/ @3 [5 o% Y, F) L: }- }; q: D8 H
  1281. {
    8 q5 z& J- R- w
  1282.   switch(receivePacket())5 j1 W0 y, i+ x* W5 T: }
  1283.   {; C, P4 t& }8 M1 ]8 X0 d! m
  1284.     case CodeNak:1 }% U9 J' k2 o4 O5 [; k! c' l
  1285.     {
    ! x2 |" w& }& O! |) a
  1286.       errorCount++;
    1 e1 \4 U. R2 [9 \- K% b9 Z7 O) |

  1287. 9 E6 [. @( w, D7 T2 g
  1288.       if(errorCount > errorMax)
    1 Y8 u8 e% a8 V; v9 U9 a
  1289.       {) B/ r. ^# v# {, {
  1290.         timeCount  = 0;
    . p( z  N' {) }
  1291.         errorCount = 0;
      \7 {/ x7 H% O
  1292.         dataCount  = 0;
    8 f5 O1 X) ?2 U4 h6 ]! A/ S% `# \  {
  1293.         code       = CodeNone;
    ' z$ m8 f" J+ z: E, ~8 r/ J
  1294.         stage      = StageNone;" I+ t, D! h3 f- Q+ ~! Z
  1295. ; r% X6 a# A& R0 e! X- f+ U2 U1 @- ]
  1296.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    : P# }  o# \" t+ b: E0 ?
  1297.         {
      V' X' J/ d  m7 l1 E( w) X
  1298.           txBuffer[txLength] = CodeCan;
    ( y8 g* `: u6 q4 d( }
  1299.         }$ n5 o# F( l  Y- b# D1 K* e
  1300. + R% Q8 v) C3 p5 h3 }/ r; t! w* y
  1301.         write(txBuffer, txLength);/ X0 N% j0 T. `: |% t! [# P3 X
  1302.         callback(StatusError, NULL, NULL);9 @8 A4 C* v" M* r6 a
  1303.       }
    * |9 F6 d& |! L" Z, h( d: `
  1304.       else
    * Y% L. d' h# y  }2 i* r  Y
  1305.       {. M3 Y$ N- z& Q- O$ M9 O/ B2 W: E
  1306.         write(txBuffer, txLength);# [3 }. `9 {5 q5 c
  1307.       }
    - i7 x* Z+ @2 s0 R) |( q# t8 Z
  1308. * ]& X: J, z; q
  1309.       break;
    . F, k$ g( p2 w0 D0 |
  1310.     }
    ' T8 @2 I+ p1 c1 ~1 D
  1311. 3 ?  W5 X6 H# C
  1312.     case CodeC:
    0 U# m8 V3 g3 h# F, ]. R
  1313.     {8 f# b) z9 X5 u
  1314.       errorCount++;
    6 E6 {/ I: f8 `: _0 A+ K

  1315. 5 T  j3 d$ I! \7 y6 r+ \9 E
  1316.       if(errorCount > errorMax)
    - z+ Y$ K* z: z, ]2 u
  1317.       {
    % v( z& n6 K8 X
  1318.         timeCount  = 0;0 _5 \6 f3 E  y
  1319.         errorCount = 0;
      k4 Z. @  [$ f  n: b3 K" y- R
  1320.         dataCount  = 0;" S6 B% Z3 W6 C5 o3 D; s
  1321.         code       = CodeNone;
    % n' o1 p3 ]+ T& H$ S5 F
  1322.         stage      = StageNone;
    & m- G% W, O; P- b) z5 v! h

  1323. 8 t% Q' m; M/ J/ m) C/ F: l. o2 ]
  1324.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)4 Z6 V3 z# G" ^" a
  1325.         {
    ; N6 l4 [0 v3 K, B% F0 [$ t, ]
  1326.           txBuffer[txLength] = CodeCan;4 e( L0 k1 p4 ^9 }  d* V# x
  1327.         }& \* ]7 u; H4 X# }
  1328. * d% H  [- H, R. P0 \
  1329.         write(txBuffer, txLength);
    1 I3 o* {6 W+ A, Z" k! Y( B
  1330.         callback(StatusError, NULL, NULL);
    $ X' m: j( O9 h
  1331.       }
    - K' m7 j& B+ v9 O  x
  1332.       else1 F( y' h( b5 s3 p- t! D
  1333.       {
    7 a1 |2 |3 m6 I0 d" E6 p
  1334.         timeCount  = 0;
      q& H; D$ Z* {% f8 @9 j4 ^
  1335.         errorCount = 0;; ?+ C1 t' J; v$ I. l/ N# x. e
  1336.         dataCount  = dataCount;; [$ n/ X, o- a. r
  1337.         code       = CodeNone;/ i8 v6 ?3 n# {0 L4 M' I: w1 K9 g. |
  1338.         stage      = (Stage)(stage + dataCount);
    ' N7 o4 a; q( n( f7 _
  1339.         write(txBuffer, txLength);
    / Q0 @4 L/ H# \5 M) U9 U
  1340.       }- I9 n$ Z9 M: k% t/ b

  1341. ; y$ }% |" t$ t1 l
  1342.       break;* m4 T& x1 U) l6 g2 j
  1343.     }
    7 r/ w' B' i' E& w$ Q/ Y

  1344. ; v0 P' e: X. k  J8 Z
  1345.     case CodeAck:
    5 W% y; Y; I- r* v
  1346.     {
    2 K! }0 r1 o4 q2 ], E
  1347.       memset(&(txBuffer[YMODEM_PACKET_HEADER]), NULL, YMODEM_PACKET_1K_SIZE);* Q) Q. L- Y+ z3 b

  1348. 9 k9 H( S2 |3 l
  1349.       switch(callback(StatusTransmit, &(txBuffer[YMODEM_PACKET_HEADER]), &(txLength))), Y; G. f; r/ F; H
  1350.       {
    ' b% X2 h$ J" p4 C7 t- C
  1351.         case CodeAck:* @7 m6 S8 ~) R9 J2 B5 }( ^2 i
  1352.         {$ b( N4 L( k) Q+ n. a- y
  1353.           uint16_t crc = crc16(&(txBuffer[YMODEM_PACKET_HEADER]), txLength);
    ( D7 O0 |1 b8 G; O9 z; T0 R
  1354. . t* n: z# H2 z) P; k: t9 _1 b
  1355.           timeCount                                       = 0;+ K, W8 L5 f  u5 Q
  1356.           errorCount                                      = 0;9 \  e4 z7 Q. O9 C6 c  y- y9 O( r
  1357.           dataCount                                       = 1;
    3 s1 d9 n! d% f
  1358.           code                                            = CodeNone;" F) {5 V/ Q& b/ z
  1359.           stage                                           = StageEstablished;4 ]# ]! E0 r1 ]
  1360.           txBuffer[0]                                     = txLength > YMODEM_PACKET_SIZE ? CodeStx : CodeSoh;% w7 W. \: A, b5 m) I! q4 x8 c+ b% O
  1361.           txBuffer[1]                                     = 0x01;& d( O- b* C( K
  1362.           txBuffer[2]                                     = 0xFE;+ x7 C  ^( N# v5 Q( P
  1363.           txBuffer[txLength + YMODEM_PACKET_OVERHEAD - 2] = (uint8_t)(crc >> 8);0 w; r& u; F- e! V! _
  1364.           txBuffer[txLength + YMODEM_PACKET_OVERHEAD - 1] = (uint8_t)(crc >> 0);
    2 c( {/ V) D' @2 M, `9 B- ?7 f% G, j
  1365.           txLength                                        = txLength + YMODEM_PACKET_OVERHEAD;- v# ^; Y, h1 z: e4 y
  1366. 3 L: g  V0 c0 g
  1367.           break;
    8 ^3 s/ l8 ~+ ~% ?: o
  1368.         }
    ) a8 G0 I9 R7 U1 O

  1369. / H. E, Y% A# m
  1370.         case CodeEot:
    1 r3 k& B0 b/ E2 {9 }
  1371.         {
    3 e8 i7 j8 h9 L& a, F
  1372.           timeCount   = 0;8 Y$ F; h1 ?1 a' h' i4 S2 E
  1373.           errorCount  = 0;
    0 A7 l7 \% c5 O
  1374.           dataCount   = 2;
    8 X1 M4 N8 R; j7 M% V+ v  m2 c
  1375.           code        = CodeNone;; j- d7 ~) E$ e/ m5 a0 y
  1376.           stage       = StageEstablished;( w7 s& o. |9 h# ^& O# W
  1377.           txBuffer[0] = CodeEot;" \8 U$ B/ H; }5 u* u
  1378.           txLength    = 1;
    8 p% K/ Z& z7 d, {+ z# Q9 o8 X' n0 \
  1379.           write(txBuffer, txLength);" o7 q5 `6 E; s; O
  1380. # k/ b* E7 V! P( s7 _
  1381.           break;( |& I2 W6 z2 O1 x
  1382.         }
    - y7 X! X' s; h4 d+ j; u; x9 f
  1383. % j4 B9 U& J) G6 s, c: M$ ~" C6 Q
  1384.         default:
    ' t# J: z/ Z5 `# O
  1385.         {
    2 T, ]7 s: R" X% B7 f" p
  1386.           timeCount  = 0;
    8 z) b4 f6 m4 s& C6 q+ U
  1387.           errorCount = 0;* J) G# g* A$ P
  1388.           dataCount  = 0;
    6 w8 t7 Z! f4 C; _* F
  1389.           code       = CodeNone;
    8 {$ j- U- e0 I; l# |4 L. [- P" A
  1390.           stage      = StageNone;$ k5 y% _# @/ Z" h: Z7 t8 x
  1391. 9 [1 \7 S' F8 B- M
  1392.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)+ h& s" r* L; w  Z
  1393.           {
    & K1 ]# ~, l. F, E5 D5 I2 [
  1394.             txBuffer[txLength] = CodeCan;
    - L3 O( t( K' \; r8 M
  1395.           }4 P9 n- g/ ?) O( t- R% X( d( ~- g

  1396. . S  w) i# `% R& i8 ~  T' k
  1397.           write(txBuffer, txLength);: X5 ]* W$ F6 }5 G& Z( [2 v
  1398.         }
    $ L$ {/ I. _. c4 I8 Z
  1399.       }
    ' k( e% k8 Q; i) ~

  1400. 1 z2 E2 [: Q1 M6 m9 y/ @/ T
  1401.       break;+ [' x4 ~% _$ k. x, Y0 H
  1402.     }
    ; |0 n% U; q7 _
  1403. 1 M9 r! _8 u( z6 f
  1404.     case CodeA1:' {0 m* \# r6 ^$ X, r0 W0 N3 H
  1405.     case CodeA2:
    5 R6 Y4 T" e* C3 F% Y1 n; Y. z
  1406.     case CodeCan:$ B& T0 `' T( U3 g2 d
  1407.     {
    # Z3 U2 g4 b- @. ^) M, I6 J* L
  1408.       timeCount  = 0;7 i5 d% Q5 ]+ Q3 N4 }; }
  1409.       errorCount = 0;; A0 G  g+ D, H% }
  1410.       dataCount  = 0;* V" T& p' V* {6 s
  1411.       code       = CodeNone;
    ) J( z+ O0 I+ @: y
  1412.       stage      = StageNone;, Q+ z7 M2 A4 O8 F; h/ C8 |
  1413.       callback(StatusAbort, NULL, NULL);
    7 D# @  R7 k0 o
  1414.   v# C! B; g1 |! m& W) U! y
  1415.       break;& u$ J% n8 c- e& R/ O9 F
  1416.     }
    2 S6 l4 Z5 V: n# m9 g! h

  1417. , f3 Z) P' N$ ?
  1418.     default:0 I3 R( e8 g) O& O* d' l6 v* ?
  1419.     {
    # K# r5 b( \9 T: B6 m9 a/ K3 A
  1420.       timeCount++;
    & }1 C# w4 x1 \

  1421. . [0 F# i) r. S) H
  1422.       if((timeCount / (timeDivide + 1)) > timeMax)
    % m* A3 ]. P/ n& f, t
  1423.       {8 \9 [' j# ^! m) m
  1424.         timeCount  = 0;
    ' x  m; U. H- j4 @, B# c
  1425.         errorCount = 0;0 ?3 Q/ s2 j  h2 {& Z" v
  1426.         dataCount  = 0;: i: r( j+ y% x: g
  1427.         code       = CodeNone;
    & b5 j/ F0 k9 D4 [( m: R) l
  1428.         stage      = StageNone;
    + L1 P' g* T; ~
  1429. 7 V% i: z3 {( `8 G# ]+ n
  1430.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)' ^; \- B* u# U# [( o3 ~! g& b8 A. ]
  1431.         {
    ) S2 [, L- q9 ^9 e7 K
  1432.           txBuffer[txLength] = CodeCan;
      L( Z# ]$ c: ?  v
  1433.         }8 k9 ~9 D3 `/ ?0 e& C0 }

  1434. # l: C5 A3 {" z0 i
  1435.         write(txBuffer, txLength);
    9 p, p% O% W& x+ p' i/ m
  1436.         callback(StatusError, NULL, NULL);; h1 O0 z/ v$ ^. z# }9 [4 I2 ]
  1437.       }
    ' X: P0 x6 \& V1 Z, t6 j! ]4 r/ m
  1438.       else if((timeCount % (timeDivide + 1)) == 0)6 U! S# x/ s# {5 c  E1 Y9 J
  1439.       {
    0 V: _1 u& Y6 ^
  1440.         write(txBuffer, txLength);
    ; X$ }$ v/ B/ Q
  1441.       }
    % |# u% J# v8 G+ M2 J
  1442.     }
    5 [6 }# u1 t& [" }* y( v
  1443.   }
    / e9 ^$ b( K& Z* _2 V
  1444. }* i2 g: U& h' n/ Y- O
  1445. ; Z% `6 n+ i. }) H
  1446. /**
    0 {* ^9 S& p2 d4 Q9 f
  1447.   * @brief  Transmit transmitting stage.6 G6 f: q3 j! d  c$ h
  1448.   * @param  None.. @  J: b' }) f8 Z- O% t; ?; X
  1449.   * @return None.
    ) t" |  v; ?* `3 u
  1450.   */# i1 e8 G; m' ?( C2 v2 M
  1451. void Ymodem::transmitStageTransmitting(): u0 i4 O4 Y4 Z; v5 @4 ~/ x
  1452. {& C+ R% I) }* d5 w; p  z% |4 c' a
  1453.   switch(receivePacket())2 s3 Y; z! m, S: u4 e; ^: |
  1454.   {( s% u3 _" Z  w6 A
  1455.     case CodeNak:
    " ^+ P1 D0 `1 [7 W9 s, O* B
  1456.     {
    6 d1 @4 u- u. [
  1457.       errorCount++;2 H% R3 Y* k! {/ i/ x" j* S+ I
  1458. 1 v4 S7 |, i% l3 R: I
  1459.       if(errorCount > errorMax)* Y; Y5 \% j* p
  1460.       {; p  S( U% ^. P$ R
  1461.         timeCount  = 0;+ I/ ^- m3 N. |, q$ Y/ H
  1462.         errorCount = 0;0 e" M" M1 Y! @( S2 r
  1463.         dataCount  = 0;
    # |, {/ R5 v1 b1 Z
  1464.         code       = CodeNone;9 f# u# t+ K( b& _2 e8 d
  1465.         stage      = StageNone;
    / v( \7 z6 a1 h4 z

  1466. . c  u3 D8 s9 y
  1467.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)0 v1 P' h& m# k  k" o7 l- ^
  1468.         {' k; U  I0 j8 B9 v) K" j6 p2 B5 X
  1469.           txBuffer[txLength] = CodeCan;
    , z/ E8 \# Z1 M+ z
  1470.         }
    6 J6 g5 s5 w# K# c: o# v5 B
  1471. 2 f9 B- h0 r' A& F4 v; e
  1472.         write(txBuffer, txLength);: U% T. \3 |* q& I8 Y, n5 x
  1473.         callback(StatusError, NULL, NULL);+ g- \0 b2 o( q6 q
  1474.       }, D) C! Q- D- C; T3 X# u
  1475.       else
    2 q+ e7 x' W7 a" M; s) y% G  S
  1476.       {8 _% V$ o0 k) t
  1477.         write(txBuffer, txLength);
    9 Y: e7 v+ z$ O3 R" F  y- |) B
  1478.       }8 E2 Q: t; b0 A# N: W

  1479. 5 W* s8 R1 @+ N% R$ d8 T8 U
  1480.       break;
    / J  b! S8 I( O2 V% ^3 F$ `
  1481.     }
    $ Z: `/ b* ^0 w

  1482. ; A4 z* N# }. q, M* z5 v. z8 N8 `
  1483.     case CodeAck:
    + y7 j) \0 n; m* P  A! E/ ^* w2 ~$ X
  1484.     {
    ( }7 `4 A: E# k( R8 k; J" M# I
  1485.       memset(&(txBuffer[YMODEM_PACKET_HEADER]), NULL, YMODEM_PACKET_1K_SIZE);
    4 V1 p1 w! r' T! d7 @+ `  P+ L
  1486. 6 V  F! g0 L3 B! M5 M5 \9 j
  1487.       switch(callback(StatusTransmit, &(txBuffer[YMODEM_PACKET_HEADER]), &(txLength)))1 e  t0 T: R3 `, K8 N& \. T+ F
  1488.       {" ]; D3 @, A3 @9 Z4 r  N
  1489.         case CodeAck:1 H8 P: `. r: s: a7 R" E
  1490.         {
    . C3 v- h- Q& u2 j8 m/ I5 y5 K
  1491.           uint16_t crc = crc16(&(txBuffer[YMODEM_PACKET_HEADER]), txLength);
    " m: L; d% U' }

  1492. : ~& ]  T) D# ^/ g5 {  z
  1493.           timeCount                                       = 0;
    - y2 t- _+ f. J2 C
  1494.           errorCount                                      = 0;
    ( M2 h5 V6 f1 @* s
  1495.           dataCount                                       = dataCount + 1;1 i& ?8 R6 f( x$ ^0 N  I: c
  1496.           code                                            = CodeNone;5 L6 d& R7 Y$ T
  1497.           stage                                           = StageTransmitting;9 s9 C) U) `6 R" G' x  C5 V" j4 O
  1498.           txBuffer[0]                                     = txLength > YMODEM_PACKET_SIZE ? CodeStx : CodeSoh;  `0 D! ]& i6 {/ s, c
  1499.           txBuffer[1]                                     = dataCount;
    ) o8 {5 F$ w2 j0 d1 a1 j  w
  1500.           txBuffer[2]                                     = 0xFF - dataCount;- |& z0 u: N; Y! h/ j1 _- e
  1501.           txBuffer[txLength + YMODEM_PACKET_OVERHEAD - 2] = (uint8_t)(crc >> 8);
    4 e8 @/ F6 Q& G5 Q& L
  1502.           txBuffer[txLength + YMODEM_PACKET_OVERHEAD - 1] = (uint8_t)(crc >> 0);3 ]6 U' e- ~2 u8 B* w( h
  1503.           txLength                                        = txLength + YMODEM_PACKET_OVERHEAD;! q7 b+ }% Q1 N: ?6 t
  1504.           write(txBuffer, txLength);
    6 ?8 i" k( y1 m9 I4 x" d, G

  1505. % {& p2 ~6 C; N9 r$ R$ h5 n
  1506.           break;
    # v) ~0 {8 a7 V- l
  1507.         }
    * v) j& y% U4 [- M& c) i! L

  1508. 5 s9 u& Y& o0 S7 N" U& ]; v
  1509.         case CodeEot:- x; U# H8 X8 U& W9 _2 H
  1510.         {/ S9 @4 {1 @9 G
  1511.           timeCount   = 0;
    # K3 H  [) v/ G2 l' u( v3 O
  1512.           errorCount  = 0;
    , D, L4 f& k3 Z8 ^3 w. q; _# d
  1513.           dataCount   = 0;
    0 [* r9 B4 W+ c+ a
  1514.           code        = CodeNone;3 O4 p! i5 {+ ^/ ]* L
  1515.           stage       = StageFinishing;/ o" L: q/ r) [( g
  1516.           txBuffer[0] = CodeEot;: W7 W/ z1 {" i
  1517.           txLength    = 1;4 h2 X8 ^# Y& X% M* D: s& R& f
  1518.           write(txBuffer, txLength);9 b2 E* u; s0 [3 v9 }  ^' ^" j

  1519.   s' q- V/ u- I) i- Y3 P7 ]
  1520.           break;; n' C4 n% o6 Z4 \5 {5 ?. ]
  1521.         }3 L; R+ @. g. o/ s  A
  1522. 5 F5 [  N) b8 X. [
  1523.         default:3 Q9 |' `+ m4 S. D
  1524.         {& F/ t) g: X: ^5 k" {
  1525.           timeCount  = 0;
    8 {) u: }3 ?* e# p1 M7 V
  1526.           errorCount = 0;) _2 d) b! @1 l) d9 S- Y! z3 s3 c
  1527.           dataCount  = 0;% x) r' e0 r( Z' \
  1528.           code       = CodeNone;
    ( G$ p5 o4 K" M5 X. a( A& H# R
  1529.           stage      = StageNone;1 ]9 P2 ^0 e8 Q

  1530. , }4 M+ y1 F1 J5 C+ [+ \- v# c
  1531.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)# o7 h9 i, B) B  x
  1532.           {
    ) C3 m# C8 [- O( [0 t* R, v: T, x
  1533.             txBuffer[txLength] = CodeCan;
    9 w0 X  r5 w( d+ [, d
  1534.           }
    2 T0 g5 q2 l! `
  1535. 1 j4 h0 D: n6 U# m6 X9 N! r9 j
  1536.           write(txBuffer, txLength);
    . L: t# G4 s6 _7 h2 l! k0 G7 h
  1537.         }
    4 }9 \& Q8 n) R4 n
  1538.       }5 u: o1 U6 s' m/ {5 ^

  1539. 6 a! x' @; @& Y% q9 k
  1540.       break;  u# X( O7 _9 {. c
  1541.     }
    ! q' p% {  U& U7 d0 h7 W3 w1 }" }

  1542. ! d/ G* i: a2 B2 W+ B: R1 T2 G
  1543.     case CodeA1:. @. x/ A* r& o' z
  1544.     case CodeA2:
    , Q7 F/ b/ N1 {: S
  1545.     case CodeCan:
    3 Q, ?8 A& b  A" z8 k3 G
  1546.     {0 I5 j" \- O. t% k! e# p$ Q
  1547.       timeCount  = 0;0 j: r% a' n; n* r% A; X* t% e" e
  1548.       errorCount = 0;, q, [2 t) Q* C' \: z1 F+ h/ a4 T
  1549.       dataCount  = 0;
    - ]8 i5 L9 b$ q% M4 G/ @* B1 w- M
  1550.       code       = CodeNone;
    3 z0 i8 f# w/ {7 F/ ~4 u+ M7 r2 J
  1551.       stage      = StageNone;2 n; v* B7 V3 ^& K
  1552.       callback(StatusAbort, NULL, NULL);0 ~9 ]: k3 W) ~, n% g

  1553. * \  y& V# h' w2 _1 }
  1554.       break;- `( i, G- }8 l/ l
  1555.     }% x0 d& ?9 W6 X2 |

  1556. 0 F1 w5 w& x) x& [9 K7 ?
  1557.     default:$ d& j: D6 M0 ~% g( m
  1558.     {
    . ]; |/ D3 {# \# H. O3 X
  1559.       timeCount++;
    ; r7 D6 S5 ?  |- f

  1560. ) O- W! g1 O: P
  1561.       if((timeCount / (timeDivide + 1)) > timeMax)
    5 v1 u* }4 u7 D3 `
  1562.       {
    5 B; ~, Q5 C# \% J
  1563.         timeCount  = 0;
    ' a1 E% F6 |  q0 N. [" H- r
  1564.         errorCount = 0;
    $ T5 ^9 F% a, a! f% }# o
  1565.         dataCount  = 0;
    ) }' k9 y% |3 c5 c0 v9 W) r2 e5 e
  1566.         code       = CodeNone;
    . p& i1 C) Z6 i& d( K
  1567.         stage      = StageNone;1 U/ x8 z* M+ k$ u2 V9 \6 I* _7 p
  1568. 8 {6 e2 }7 s& i' [3 X; L. e5 S
  1569.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++): ~" x: v( v: Z# q
  1570.         {
    $ k- ]. l2 u/ E: `( H1 [1 [
  1571.           txBuffer[txLength] = CodeCan;8 h) q. @- X: |* H$ G8 J, ]
  1572.         }" l! m# T- z  \' U3 u: g- n8 n! `

  1573. " o# I7 N' e- O& r% J! Y
  1574.         write(txBuffer, txLength);8 M8 P/ c' R5 l! x7 h* d- f
  1575.         callback(StatusError, NULL, NULL);
    ' b" i' ^$ z; ]+ v+ I$ E
  1576.       }
    + B1 H! F# r) o$ Q; z: `
  1577.       else if((timeCount % (timeDivide + 1)) == 0), p# {& r! U0 g9 j' ^/ \) U
  1578.       {" G) p8 C9 n' ]" b% o" f
  1579.         write(txBuffer, txLength);
    4 _7 o. l/ H7 x7 j
  1580.       }: v+ ~" K0 {6 x( Z3 M' R2 n
  1581.     }
    5 u: e" V+ D1 a+ J/ [& r5 x- _
  1582.   }' R9 x/ B8 `& y% m( {$ x- F! m
  1583. }5 g; ]4 d- U6 S; l3 \4 o4 w6 j! x

  1584. ( O2 a! N) R% |" }: D' M
  1585. /**
      D( n8 i" v: {: {# F
  1586.   * @brief  Transmit finishing stage.
    # M8 x8 _: O3 C, T
  1587.   * @param  None.
    + F- x; j4 r, i( P
  1588.   * @return None.
    / C( O4 C0 \9 m& g% I( C
  1589.   */! t0 F1 k$ {) u/ I
  1590. void Ymodem::transmitStageFinishing(): N% S& Y. C: H) I% ]
  1591. {
    / h! L$ h+ }" z5 [, F
  1592.   switch(receivePacket())% N' [( J; @2 ?6 T) a* G' s) r. x
  1593.   {
    6 b% {! A1 C# Y& [
  1594.     case CodeNak:7 D2 t8 C4 V# j" Z# R9 x
  1595.     {$ T! ?$ l* A! f+ o
  1596.       timeCount   = 0;5 t0 R3 `' r5 U7 |4 n
  1597.       errorCount  = 0;
    + ?& A4 V3 H2 C, i/ Q; r
  1598.       dataCount   = 0;
    * M6 f% _" ]  l; T: z0 i9 y. R2 x
  1599.       code        = CodeNone;7 s$ K$ M. ?5 k( h
  1600.       stage       = StageFinishing;
    1 D$ c' g: `- F2 _
  1601.       txBuffer[0] = CodeEot;
    1 G/ v- w8 r" _* v! E
  1602.       txLength    = 1;
    8 K& h! h  n2 c  v" y$ p
  1603.       write(txBuffer, txLength);
    4 K" U/ g2 a( v/ ^, ]) `8 h2 g7 e

  1604. ' \  B. V1 ~2 J& M' Z4 A
  1605.       break;
    + \0 F7 h9 _* k) ]
  1606.     }
    , R8 Y6 r, Y0 Q7 p' E
  1607. ( D; M  L% \  R
  1608.     case CodeC:
    9 [9 e0 v; b) I1 n0 p3 {7 u/ e
  1609.     {
    , G8 w/ c/ N% G" O: N* O
  1610.       memset(&(txBuffer[YMODEM_PACKET_HEADER]), NULL, YMODEM_PACKET_SIZE);$ ^$ \" t' d2 r% t
  1611.       uint16_t crc = crc16(&(txBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_SIZE);  g. \! G- b" g4 k" f
  1612. 5 D# T( M* n+ K. J4 t6 ^
  1613.       timeCount                                                 = 0;. g& Y4 t: i% r1 g% @
  1614.       errorCount                                                = 0;
    " ~7 @0 x% Q/ x7 Y0 c( k6 O' `
  1615.       dataCount                                                 = 0;
    & n$ e+ j- i, v, s8 f
  1616.       code                                                      = CodeNone;) n5 B: H/ c) m" _$ ^
  1617.       stage                                                     = StageFinished;! q- ]- h* G2 H( _& g
  1618.       txBuffer[0]                                               = CodeSoh;" z  j, R$ C0 \/ \
  1619.       txBuffer[1]                                               = 0x00;
    2 A0 {4 v. S) M7 F! H0 [& ^
  1620.       txBuffer[2]                                               = 0xFF;
    2 U1 ~0 w0 z4 P, Q# I. V* f9 a. k
  1621.       txBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 2] = (uint8_t)(crc >> 8);
    1 n/ F# n7 @; v  k% {; \* E! |/ Y
  1622.       txBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 1] = (uint8_t)(crc >> 0);
    0 E0 @+ R8 x- L9 x
  1623.       txLength                                                  = YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD;. V5 o, ]1 u8 x9 |- c
  1624.       write(txBuffer, txLength);
    0 r: Q# D4 r* i2 z! V; {/ \

  1625. " J1 z  O* h3 d& t
  1626.       break;9 ^' t0 B1 h1 F0 {- t/ l1 }: V" a. u: l% g
  1627.     }  @( o! @) R0 u' I* J

  1628. / T/ ~  |8 t& T3 K9 d4 x
  1629.     case CodeA1:
    , _0 I, J) ?: K. h* x: ]) y
  1630.     case CodeA2:- U! L. W2 `7 A
  1631.     case CodeCan:: I0 Y. F# M3 H0 v! e0 V& }- L  W
  1632.     {
    ; _6 ^/ S! Y9 D# y& z
  1633.       timeCount  = 0;
    . S+ h8 Z' _( K& {
  1634.       errorCount = 0;
    2 O' p( q) ?+ V% ~! q. d
  1635.       dataCount  = 0;% {) W# Y- K6 f
  1636.       code       = CodeNone;0 I4 h3 h( q( m* {
  1637.       stage      = StageNone;5 H) X  U. C' k! n, I
  1638.       callback(StatusAbort, NULL, NULL);/ u1 M5 K/ H5 g% s
  1639. / P: P' }: d- H3 P7 t
  1640.       break;& {$ e& n  Y& M6 _/ `% x+ x6 X5 W+ K
  1641.     }6 ^9 V# {) X1 I. ~0 ?& h0 h1 w! {5 N

  1642. 3 x" |" X) C7 h  D, k
  1643.     default:
    6 \% v" x+ }( e8 a$ B
  1644.     {' {! q# o3 h, |: f
  1645.       timeCount++;+ j$ X) {2 O3 L. O! J: k& m
  1646. 7 F  q( \7 P9 T( l6 j
  1647.       if((timeCount / (timeDivide + 1)) > timeMax)  T( W: H, w% f. B& p( R4 {
  1648.       {& p5 S. a' M  f' z
  1649.         timeCount  = 0;
    6 z0 Q* ]3 L( d0 R" g
  1650.         errorCount = 0;2 p. b6 ^/ \) {( N5 Q
  1651.         dataCount  = 0;
    2 P! N5 P7 R" L. G& b! r/ ]4 e7 r
  1652.         code       = CodeNone;0 {! C. {9 b) B* b- h8 g
  1653.         stage      = StageNone;
    ; @6 r; F/ y5 l6 H- r% T' y5 l2 p+ T
  1654. 5 m+ A0 G0 \. Z: \! ~
  1655.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    4 l5 a3 T- j1 ]! g* b1 C
  1656.         {* U7 e0 q& I$ |8 G% c
  1657.           txBuffer[txLength] = CodeCan;
    ' o( V$ V# I7 D: R5 [( R; s2 e
  1658.         }7 P% x. F( g0 Y* C) e# |8 n2 i6 A

  1659. : g! ]; U) j0 ?+ S
  1660.         write(txBuffer, txLength);/ o9 N8 ?! n* B: L9 k; J# A- K, |
  1661.         callback(StatusError, NULL, NULL);
    , h1 y8 q; g. i' W/ F  }
  1662.       }: W9 X6 R( I- v& t6 ]8 |9 O
  1663.       else if((timeCount % (timeDivide + 1)) == 0)) T/ z: G' t5 p1 P/ \+ J# w
  1664.       {
    ( a5 k7 D$ D4 z0 u
  1665.         write(txBuffer, txLength);% L3 I  J2 q+ u9 h3 U7 U: ^
  1666.       }
    * T& V% v: \: ~; @' z$ K
  1667.     }
    . [" H; E  Y4 a, j1 Z1 C, V
  1668.   }, J1 J2 ?. ^5 Z
  1669. }3 o4 e3 u& _6 P2 E; B! c' ^  j4 i

  1670. 4 w/ N8 `% E. `! S
  1671. /**
    2 q% `' U; m, A( e( a$ j
  1672.   * @brief  Transmit finished stage.
    5 K" J7 a5 A: L2 z% l9 S4 o
  1673.   * @param  None.
      z! \5 z3 k# H4 v' J  B5 k6 |( x3 V
  1674.   * @return None." e: e* z5 B9 g: O, {6 Q- @
  1675.   */
    0 P0 r7 j) v& r
  1676. void Ymodem::transmitStageFinished()
    2 o/ n( j3 m# k
  1677. {
    8 y" y: @  h# v
  1678.   switch(receivePacket())
    ' n4 Q1 ]9 W! ~+ ?! G- t
  1679.   {
    ! O2 `: O# E4 L6 l* V6 A
  1680.     case CodeC:
    & C8 @+ l6 J* w% j
  1681.     case CodeNak:: b4 R( i! |' b* ~+ Z& u
  1682.     {
    ! o2 w- C  P& T6 b# O( Y/ D
  1683.       errorCount++;+ K' T% [3 R. l, {/ J6 j/ V/ \
  1684. 3 n* a# [1 K0 F
  1685.       if(errorCount > errorMax)0 V# j. i! a/ I) a% b
  1686.       {* i9 B" P  L  f3 \" J. W* p2 Y+ D
  1687.         timeCount  = 0;1 t7 a, C- p1 L5 e  D0 E
  1688.         errorCount = 0;+ T4 G9 ~* v; W5 R6 l
  1689.         dataCount  = 0;
    % X6 f& O! _: G* O+ K4 i
  1690.         code       = CodeNone;
    # U( Q) i" m) u* i) q
  1691.         stage      = StageNone;
    + m4 O8 A- i5 @
  1692. 5 @1 T, S, n  R+ J# x
  1693.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    ' s7 e9 B) s% v* R3 V
  1694.         {& F+ J3 Y6 g9 c+ y
  1695.           txBuffer[txLength] = CodeCan;' S2 s  X7 T; E* c
  1696.         }5 ?2 _# l- v( @! N8 F

  1697. 4 H' \( X' ~- E6 P
  1698.         write(txBuffer, txLength);
    2 P$ {8 h0 l( x+ c# k! [
  1699.         callback(StatusError, NULL, NULL);9 F4 e. J8 h6 c6 Z2 f7 O
  1700.       }
    ! \+ E! P: R: @2 y* t
  1701.       else8 h# u! j+ K  A
  1702.       {
    # v1 H' z& M& P' G
  1703.         write(txBuffer, txLength);
    ; z4 X) w$ M+ o; X  {  p
  1704.       }# W4 F  o, p2 S1 |

  1705. 2 j. [: h" p; `" D$ S
  1706.       break;
    ( N7 C3 w! x, ^& D3 c5 [
  1707.     }+ I# B! t" E" O. \4 m, b6 _
  1708. 1 a$ u. B! c& v. H: S
  1709.     case CodeAck:' K9 P8 Y, I+ \9 ?
  1710.     {
    ( W6 K% L( {$ y6 D" `
  1711.       timeCount  = 0;
    8 S. ~3 ?, J( E$ w: ~* |8 X% g
  1712.       errorCount = 0;' n! a4 G4 S! k7 [0 m' p% U
  1713.       dataCount  = 0;
    % g% |( l" f. R6 C2 G( p
  1714.       code       = CodeNone;& z9 u( e8 _' f/ e" C2 Y! W: q+ k
  1715.       stage      = StageNone;
    # D2 a2 C6 H. F. W* B8 P6 c7 n* r
  1716.       callback(StatusFinish, NULL, NULL);& Q( @) d3 {$ }3 j
  1717. $ n( M6 m* ]% `" z* f3 A
  1718.       break;3 H0 @0 x) O" _4 j* {
  1719.     }; l& m7 g9 p8 M# ~5 [5 \

  1720. # s" G4 v8 v/ j6 K  a
  1721.     case CodeA1:0 i, J3 ~8 R6 ^  w
  1722.     case CodeA2:
    ( G, ?$ `, D. G! I0 p
  1723.     case CodeCan:
    0 {4 j; R% v: Y6 x- A0 c
  1724.     {- l+ h! F' F9 m$ u
  1725.       timeCount  = 0;
    ) `2 }& Q" p0 w# D
  1726.       errorCount = 0;; B$ `; ]% H7 E% \, G6 B2 \# _7 k
  1727.       dataCount  = 0;
    ! p- D0 Y- o# G7 _5 _
  1728.       code       = CodeNone;9 N6 a, Q2 D/ ~2 |6 {' S' e
  1729.       stage      = StageNone;
    , [# `$ {  |2 S/ J* @
  1730.       callback(StatusAbort, NULL, NULL);
    3 ?5 E# r# H1 P7 W2 W: w2 r" j
  1731. 8 r, b0 I& `" R$ U9 u/ R( \5 r$ ], e; a
  1732.       break;0 O, u. ~7 {, C
  1733.     }
    # X  }6 a. i7 b) z
  1734. ! o, r7 m! J4 k4 @3 u  B. e6 u
  1735.     default:
    ( b' U; s$ |/ `/ h0 q  \/ D) v. O, k  Z
  1736.     {/ @7 |9 p2 t; Q: }
  1737.       timeCount++;: n* F  M5 f4 W8 h2 E

  1738. $ d: S: Y' C; X. R+ s
  1739.       if((timeCount / (timeDivide + 1)) > timeMax)
    $ e+ Z8 M0 m2 X. p0 ~) Y) E
  1740.       {, i$ p$ k3 X* B. [
  1741.         timeCount  = 0;
    # n% d0 i3 `+ V3 H# s1 G
  1742.         errorCount = 0;2 v4 m; b2 x6 Y( s& Q% H! Z
  1743.         dataCount  = 0;' I+ A4 `" P$ r$ b
  1744.         code       = CodeNone;
    ( {7 g. d, k( }" x+ L0 d
  1745.         stage      = StageNone;% }( I* O4 u: ?4 j8 [; T8 ^0 V
  1746. / _1 \! d( P$ p7 h
  1747.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)$ ]" ~) w- J% K0 c
  1748.         {
    . u! R2 f0 }7 h  m
  1749.           txBuffer[txLength] = CodeCan;0 ?0 x4 _" _& q0 m3 |& t
  1750.         }
    / K3 w2 J4 G% o) R9 E9 P" m
  1751. 8 V% l/ I3 _; z4 r4 u7 j0 Q$ }
  1752.         write(txBuffer, txLength);
    + K4 [0 ^% Q* n2 E3 v* o
  1753.         callback(StatusError, NULL, NULL);) ]& l% S( W6 z4 ?/ y
  1754.       }1 Z- a% t3 n; {( u  w( M9 C2 v6 X
  1755.       else if((timeCount % (timeDivide + 1)) == 0)
    2 n( a  @$ `' v- u% s
  1756.       {
    7 ]' K1 b4 s8 C( P9 r; A
  1757.         write(txBuffer, txLength);- `- ^9 y+ a" n/ v# _  I( L# U! D; i
  1758.       }
    ' R2 S& {9 F/ C( Y: U) }
  1759.     }# a1 M6 y/ u, T
  1760.   }
    1 L" D2 ]. T1 x0 O% E$ ]7 b
  1761. }# N/ R# G& E2 i. g' }! G- A
  1762. 9 z: N  w4 E: D) p  M1 r; y5 B
  1763. /**
    ' V) ~* L) G$ f8 m/ e
  1764.   * @brief  Calculate CRC16 checksum.* y8 ~/ I/ t% [; y
  1765.   * @param  [in] buff: The data to be calculated.
    / m7 O) {' u/ u% f( V
  1766.   * @param  [in] len:  The length of the data to be calculated.) E. M0 w9 n2 l6 M
  1767.   * @return Calculated CRC16 checksum.
    # ]) f! Z/ g4 N+ u
  1768.   */
    $ f3 c! Z* x& |# A
  1769. uint16_t Ymodem::crc16(uint8_t *buff, uint32_t len)
    9 ~: ?) N0 {% d
  1770. {- @+ J- Z% q' n# }5 H
  1771.   uint16_t crc = 0;/ A6 A7 @" m, h  ?, z! r
  1772. ; _/ N5 ^6 @8 s9 h2 J- x2 F2 E7 n
  1773.   while(len--)" }5 M( y( W$ g8 S  M& @  B+ h
  1774.   {
    $ d" O) T) I4 _9 G' ?0 H/ ^: A- x) ]1 k
  1775.     crc ^= (uint16_t)(*(buff++)) << 8;+ y. \% _3 T5 _1 O! A4 }4 `; @

  1776. 5 K3 q: o, b) i! C6 }
  1777.     for(int i = 0; i < 8; i++)
    0 s0 a& M2 ]: f, r5 @- p, s
  1778.     {/ L+ b  l. A$ t: {- z" {. v
  1779.       if(crc & 0x8000)
    # ]; [3 A! q7 ~+ u: Z
  1780.       {7 ~' X3 x9 _8 _: h& }& G* v) P
  1781.         crc = (crc << 1) ^ 0x1021;4 L" g) H0 {  ?1 l# D: S
  1782.       }
    8 B. C3 x; c5 P2 [* j1 ~1 @7 H; W
  1783.       else% D. @  e* a9 Q" _; ?
  1784.       {
    # z7 M  L6 B# F' c% i
  1785.         crc = crc << 1;
    6 }, i  T- }& I* m' k
  1786.       }
    7 e& I1 [$ c1 }: t
  1787.     }
    " R+ H5 f  U5 @. s1 G
  1788.   }
    4 v/ t6 }! P& E
  1789. * G& K3 r4 N6 Y( y% U; y
  1790.   return crc;
    ; j2 K$ c5 J6 U, r, _* v% w$ _! S! E
  1791. }
    $ b% c5 G" h) Z
复制代码

: }; V4 e! O9 _# B2 `- q0 |0 J. ?
; v+ n1 A" d5 n9 g: n
" A  T8 S- M  v5 h
$ P1 z; x( A0 Z8 g5 }
, @4 T8 M# T! L! A' B/ v$ Z
收藏 1 评论11 发布时间:2018-3-6 22:28

举报

11个回答
XinLiYF 回答时间:2018-3-6 22:30:39
      YmodemFileReceive.h文件
) e$ Q+ {* M& k! h, i- R
  1. #ifndef YMODEMFILERECEIVE_H
    ) j  ]: G0 `. {3 q
  2. #define YMODEMFILERECEIVE_H3 G) B/ P* R% C; ~! Y9 Y

  3. % {$ u6 i+ f, ]
  4. #include <QFile>' b3 r% x( {' e" _% o
  5. #include <QTimer>
    5 s8 ^. r7 ~4 e  v+ t# v
  6. #include <QObject>( t7 z7 ?# p  b$ B4 s  W! E
  7. #include <QSerialPort>- ^- m3 D- }- `5 J6 V; n6 N
  8. #include "Ymodem.h"
    # e0 R+ m5 r: e

  9. 9 T3 u8 R  t% I, t6 n- s+ e8 K: R
  10. class YmodemFileReceive : public QObject, public Ymodem
    - e! ^) X( Z# i, k* ?
  11. {) @; S9 k4 R  s* y
  12.     Q_OBJECT
    9 c- x6 k1 \! _

  13. : O4 S2 N% ~2 U: M2 P" a$ Q
  14. public:
    ( H+ u$ @$ U: b0 N, m
  15.     explicit YmodemFileReceive(QObject *parent = 0);
    6 U& x6 ^. D$ x9 o2 T6 B7 r3 V# x; `
  16.     ~YmodemFileReceive();
    * v5 c. u4 {$ Z
  17. + t; s- f! ?( ?5 R& h8 c8 |+ H
  18.     void setFilePath(const QString &path);! F4 O+ o6 ]# b9 e. J+ f' Q

  19. $ f$ S" ~; L7 K  q) v* _
  20.     void setPortName(const QString &name);- a4 P; \, U! @; s' ~$ d
  21.     void setPortBaudRate(qint32 baudrate);( x. ^2 w4 c. q7 H0 t; E/ M
  22. $ n* f4 `: k0 D' w: c9 ^
  23.     bool startReceive();9 `9 f( f  t8 P9 t4 x* g- }
  24.     void stopReceive();
    * C7 A1 ?4 n0 v8 m, m5 }

  25.   X# l) \- D4 D! y+ J
  26.     int getReceiveProgress();
    : V. ?( X+ Y. n) F, o5 i4 g
  27.     Status getReceiveStatus();
    # t- I2 P. l& }9 {
  28. & C! p% I+ e2 l3 A7 B
  29. signals:4 e7 v0 x( }) e! F6 x" {
  30.     void receiveProgress(int progress);; Q6 u5 n0 f# M# I/ @0 ?
  31.     void receiveStatus(YmodemFileReceive::Status status);
    ' @2 l( P: A5 y$ y' K. }# `/ F4 ]

  32.   c. g* Q0 R+ e# L7 A; v
  33. private slots:
    . h- ~! m; I: N, K& Q2 L  x
  34.     void readTimeOut();) M. O2 A$ G; f9 [% \" E5 z6 |9 J
  35.     void writeTimeOut();2 X0 }* K2 g* e8 p( F/ u" Z
  36. ( p4 Q) F1 E2 b4 N
  37. private:
    : V% [2 R1 z6 q6 u+ I0 [3 I
  38.     Code callback(Status status, uint8_t *buff, uint32_t *len);! m6 z, s) ]. w

  39. $ d8 G5 L% ]8 z+ ^% U% F
  40.     uint32_t read(uint8_t *buff, uint32_t len);5 H6 E5 b( f3 K6 k' m! ?* |0 w
  41.     uint32_t write(uint8_t *buff, uint32_t len);4 z) I2 c/ O' Y$ `
  42. 1 V- {; p6 R3 }
  43.     QFile       *file;
    - l5 ]  s) Q) s9 }; t( h
  44.     QTimer      *readTimer;1 k$ ?5 |, x1 F: l  K: S
  45.     QTimer      *writeTimer;
    ; W: J4 q  O6 [9 [5 Z5 n# {# T
  46.     QSerialPort *serialPort;' j2 u% R! S9 i! ?

  47. 6 ?+ J) k6 A3 K& @
  48.     int      progress;
    4 u' [8 R& |0 i: I# m
  49.     Status   status;$ [! L+ G& O" S
  50.     QString  filePath;
    3 N4 u; a9 |: O' c
  51.     QString  fileName;
    , L. o( s9 Z4 d! Z9 I# K% K
  52.     uint64_t fileSize;
    # e% q2 o/ [, B$ c7 L  i' H# q( a
  53.     uint64_t fileCount;
      N4 I8 _+ F+ w$ A( x: V4 X
  54. };
    . B# ~, D' P0 I! f# U/ X

  55. 1 H% t* \3 ^) L$ [
  56. #endif // YMODEMFILERECEIVE_H) b; e  s+ S5 l; l/ ~$ i6 @: m- F9 ^/ G
复制代码

. g& D  c- z1 n+ k      YmodemFileReceive.cpp文件, I8 |& Y  h% N
  1. #include "YmodemFileReceive.h", `5 H& ^# q; Z  W  f* K
  2.   C' y0 S* _. |3 ~
  3. #define READ_TIME_OUT   (10)$ J% m. O( ^- @0 w
  4. #define WRITE_TIME_OUT  (100)
    2 o1 ]& S- ?- N; B7 }4 I4 f
  5. ! X2 r7 e1 r+ ^2 {: [
  6. YmodemFileReceive::YmodemFileReceive(QObject *parent) :
    " o* _: `8 K6 J+ x. G
  7.     QObject(parent),
    ) r. a7 L. q: c6 x* ?
  8.     file(new QFile),
    0 D& B* u# x5 J# S" }' o3 m
  9.     readTimer(new QTimer),
    4 y1 e+ k8 O" C" w: K
  10.     writeTimer(new QTimer),
    % r1 f2 s& `% Q
  11.     serialPort(new QSerialPort)
    0 l9 Z1 a7 \/ Z9 @* O8 G  r8 S7 y
  12. {, k0 s/ _1 n$ c, y; o: M( x$ Z( N
  13.     setTimeDivide(499);
    # d7 h% U7 u- \  Q& a' o' X7 ?( N
  14.     setTimeMax(5);' I  o( F# c8 A' I# S
  15.     setErrorMax(999);/ [9 X+ c1 k! b# B/ p2 j
  16. & {  c/ l' J; R# j' ]: V
  17.     serialPort->setPortName("COM1");3 X9 }' h  J% U, v
  18.     serialPort->setBaudRate(115200);! ?6 y3 v+ A- f" d" }/ I: t1 q
  19.     serialPort->setDataBits(QSerialPort::Data8);+ f/ J* F0 ]& h. f1 M# c' b
  20.     serialPort->setStopBits(QSerialPort::OneStop);
    ! |3 J- L- o7 w, w  R
  21.     serialPort->setParity(QSerialPort::NoParity);
      b: g8 H5 h0 O( X6 u. P+ P- `
  22.     serialPort->setFlowControl(QSerialPort::NoFlowControl);9 x* d- @3 |$ Y$ j2 W- ]0 R
  23. ) }) i. M( Y. i
  24.     connect(readTimer, SIGNAL(timeout()), this, SLOT(readTimeOut()));
    , j( A- c* z5 q. s  L
  25.     connect(writeTimer, SIGNAL(timeout()), this, SLOT(writeTimeOut()));
    - }! N4 I6 @" g* U" K/ g
  26. }1 T/ _  y7 a# }3 x. L& x

  27. 2 @9 ~' D. Q2 Z; l! b
  28. YmodemFileReceive::~YmodemFileReceive()
    ) l! ]& @. T' N! M1 \" y) @! K! W+ e
  29. {9 x5 C! Z  w0 j# ]8 Y3 z: {! ~$ |
  30.     delete file;
    ' M$ m) |/ W% A' U* j, J6 B
  31.     delete readTimer;
    : A1 \7 o: d& K+ l# l/ p" ]1 M
  32.     delete writeTimer;
    5 a1 S5 z$ @' T0 u# K; G
  33.     delete serialPort;
    ( W" q0 D2 T5 r* f& o! x! X
  34. }
    & l, b- E# n7 x
  35. " X' H/ x* f5 D3 V, ~1 ~! @
  36. void YmodemFileReceive::setFilePath(const QString &path)
    + _/ x# o$ N! E0 f
  37. {; Y# \8 _: Y4 R! Z
  38.     filePath = path + "/";
    ( o9 V4 ~7 h  |4 F9 s
  39. }
    * a; l. ]1 k) \9 q) t; c

  40. # a, F5 S: P4 a' D' c" d
  41. void YmodemFileReceive::setPortName(const QString &name); W+ J6 A7 Y; Q- \! S$ r% ]
  42. {/ s$ [2 r" j3 z1 }" y
  43.     serialPort->setPortName(name);
    * j; P" W7 r' G$ \: _0 z
  44. }9 I4 `0 ^  y. X# {% ], G' k
  45. 6 Y# k( ^. J; L1 h0 ]
  46. void YmodemFileReceive::setPortBaudRate(qint32 baudrate)
    # b! r# E: z# {2 `) m
  47. {
    5 p" k* T; G4 }8 {  C9 b
  48.     serialPort->setBaudRate(baudrate);- {/ E& R- n4 j& v2 H
  49. }
    ; x$ D8 Z3 a7 B# u  t0 b, R% t

  50. ; A# U' Q& L, W" g+ p8 x
  51. bool YmodemFileReceive::startReceive()
    6 g- k+ V, H6 [9 w% u( {
  52. {
    + L! R2 l: {2 t4 V' F2 d; L3 V
  53.     progress = 0;
    4 q* p9 k, |- c8 I6 A2 r
  54.     status   = StatusEstablish;
    , v1 H2 n* G% R: L3 A4 v# C

  55. 8 z/ c' x1 j# D8 q4 f2 J$ A
  56.     if(serialPort->open(QSerialPort::ReadWrite) == true)
    3 R" U, e6 w( P* K9 s
  57.     {+ l# i9 I- d0 q9 ^% N4 G4 m
  58.         readTimer->start(READ_TIME_OUT);6 O/ |( z$ F# Q3 q
  59. 8 B1 a! E/ L/ p- t) C0 x
  60.         return true;
    5 E4 h6 \0 @0 f; F9 B
  61.     }
    ; P) U! Z  S* p2 E- c
  62.     else7 p8 U! z- m3 f& T$ ~  n) C
  63.     {7 C4 x- ?( n; A
  64.         return false;
    4 x( X9 h2 I# J, H/ d
  65.     }5 X% ~6 }# S5 t4 P) A! T
  66. }
    : G5 K: M3 p. U

  67. 8 D6 c. h3 m& s" ^9 L
  68. void YmodemFileReceive::stopReceive()
    4 |7 w( C# G' _) r5 \1 {+ h, ?
  69. {
    ) N9 {7 z* W8 L( n  f5 J
  70.     file->close();; h8 c. |# s: V3 _% v
  71.     abort();  E! e- ^( J7 v+ h) K
  72.     status = StatusAbort;
    % v0 x4 w8 ~  {5 |$ M' Z
  73.     writeTimer->start(WRITE_TIME_OUT);; Y7 e. o0 L  v
  74. }
    / m$ i9 y9 [! V* r9 p: g8 `
  75. % D1 @3 `- X, c3 _( U3 W9 Y
  76. int YmodemFileReceive::getReceiveProgress()
    + ?/ a) x  x& x* \
  77. {
    * n# _/ }0 j) O( ~. i" W; M
  78.     return progress;8 C1 Q$ l4 x7 L' F! D* r
  79. }
    7 s1 S( w& d7 c. }: t

  80. & d' q5 Y+ r5 Q6 a7 Q3 ^' p# J
  81. Ymodem::Status YmodemFileReceive::getReceiveStatus()3 G- t9 X, Q( G" C; o3 z
  82. {4 f! I; W% @/ o
  83.     return status;% Z0 D% I  h1 ]$ d9 t
  84. }  q& Y( n! j& ]/ J2 ]" e% m* i
  85. 4 m& i, w$ w$ l; d0 q0 Z/ g
  86. void YmodemFileReceive::readTimeOut()
    : P) A9 b& @# T' w8 M) w, a$ ^
  87. {
    # }) P- G) B, T1 ~( H2 g5 s
  88.     readTimer->stop();
    - o- m( Y$ E+ x2 i; B* {
  89. ' ^8 Y# p6 w# f8 B  o. E; e/ y5 _0 r
  90.     receive();- n. o; {' G$ {/ l! j' m

  91. - E( p1 \( |4 {  T/ z+ \! @2 Y# p
  92.     if((status == StatusEstablish) || (status == StatusTransmit))
    - v9 V. H  ~5 \; V$ v2 n: t
  93.     {
    / c) I' V% T- `/ w
  94.         readTimer->start(READ_TIME_OUT);
    3 j  R$ i( a5 K
  95.     }& ?/ {5 m7 R! w( w
  96. }
    ' T# N5 _1 y: r. t

  97. # L' |1 d. q% F) o5 J+ y7 v
  98. void YmodemFileReceive::writeTimeOut()) n: t) f& W; ~
  99. {
    4 |& d( o* e8 a* z0 m4 C& l4 x8 _0 z2 n4 E
  100.     writeTimer->stop();1 p! U$ W6 G0 }
  101.     serialPort->close();
    2 e: ?, d( L* M3 [0 W3 B9 m: ]3 {; p5 B
  102.     receiveStatus(status);# }4 T4 K/ D7 D
  103. }) w4 ^5 u- H- _0 O/ _1 ~

  104. 4 \3 r* q; m  b, R# ]8 K: l( t
  105. Ymodem::Code YmodemFileReceive::callback(Status status, uint8_t *buff, uint32_t *len)
    2 H" V3 F$ S+ W
  106. {
    4 k2 Y/ H- s2 n: w% j- `4 t: m
  107.     switch(status)% a) ^8 f, k7 D2 l$ Y
  108.     {1 |5 `3 M; e& q7 W- w
  109.         case StatusEstablish:- K: K6 S1 M' z6 ]% f2 d
  110.         {4 W8 J  W2 f7 T$ B0 q5 j
  111.             if(buff[0] != 0)
    9 `) T7 b2 |# Q5 a, c; D; p7 E, {
  112.             {0 P9 G9 n/ v* k
  113.                 int  i         =  0;, K" Q+ m4 h/ N6 O
  114.                 char name[128] = {0};
    1 p! H2 u! K, K9 r; M& c( t, ^
  115.                 char size[128] = {0};
    0 U* k1 v& \, B" Z6 M! D) @9 r
  116. ) z$ w' R  M$ h- [" M6 s
  117.                 for(int j = 0; buff[i] != 0; i++, j++)
    * g  {6 w  D6 q/ ^$ z
  118.                 {
    6 V9 k: l) K  \
  119.                     name[j] = buff[i];
    8 m& t7 O% H" o$ N+ R5 v" a
  120.                 }: a' i/ G' [& m: B
  121. ! r, U' W" i/ A- m7 D
  122.                 i++;
    * I6 g4 i5 J% A  Z2 ?
  123. 0 T% Z( R2 s# {! W0 [3 N
  124.                 for(int j = 0; buff[i] != 0; i++, j++)& d& @+ w7 W* l! k
  125.                 {; y5 h* W6 e- F$ P  i4 |# }
  126.                     size[j] = buff[i];
    5 Z! o( g6 m" u5 u# L  b
  127.                 }
    6 `  W) A, H0 j5 ^& c
  128. + D0 o* d& W/ t
  129.                 fileName  = QString::fromLocal8Bit(name);
    % @, ~- P( c: d' R: y" R' T' z  z* ]
  130.                 fileSize  = QString(size).toULongLong();7 X% i4 D' W% l7 w! v# G
  131.                 fileCount = 0;' B) M! d$ o9 ~8 W0 ?

  132. 0 R0 C, N5 b7 V
  133.                 file->setFileName(filePath + fileName);
    4 g5 ?# Y( Y6 f+ g: `1 w3 B" Z2 o
  134. % C" }4 a; h% z( ?
  135.                 if(file->open(QFile::WriteOnly) == true)' E1 f; \- Y. q, ~
  136.                 {
    + r3 ~# u3 X8 z. {& C9 {
  137.                     YmodemFileReceive::status = StatusEstablish;
    . {* {( M+ M: r( X% V& a9 D
  138. 5 o: v- X' a) ?9 ?* Q/ b* A8 ^- n
  139.                     receiveStatus(StatusEstablish);
    + O5 `- f: I6 r: g3 J

  140. 4 J2 ?8 n& O9 U3 `8 }  ]# U
  141.                     return CodeAck;  Z! @% f4 F+ [- }1 Y  t' ]& Z$ f
  142.                 }% o6 O) u8 u, G- W2 m) Z. G5 g
  143.                 else
    ) O* U7 B5 s  {/ p# Y
  144.                 {
    & d) G5 b, H# X$ @& p/ d
  145.                     YmodemFileReceive::status = StatusError;
    4 u% p5 U. W# V+ H
  146. * N; ^6 s' a  P% Q" O- G2 I/ y
  147.                     writeTimer->start(WRITE_TIME_OUT);8 c- h" u; W  d$ I
  148. , E/ l, t4 T- S8 F6 n
  149.                     return CodeCan;3 w+ C+ f% p+ ^# s. V
  150.                 }
    - l, l: _' Q/ C7 H: e& v) X
  151.             }  ^- {+ j  x' [# h+ _
  152.             else
    # J% J, m" z) ^" x, \
  153.             {
    6 o# D- F/ |% U3 N
  154.                 YmodemFileReceive::status = StatusError;7 q; a. U6 H- |4 t; y& l& u

  155. 4 J2 T0 N2 |* U0 M, q
  156.                 writeTimer->start(WRITE_TIME_OUT);& o1 f2 a, g; N: L7 r5 v' Z
  157. $ i- m4 P: n5 J: n
  158.                 return CodeCan;
    * ]& y5 z+ w# x5 u2 q
  159.             }8 @+ ^' v% ], ?. ]6 G2 s
  160.         }1 C/ H# ~4 n% ^* i3 s6 D* Q

  161. ! d9 O+ O- b" E2 a1 ^
  162.         case StatusTransmit:- J( w2 q+ g3 L& y
  163.         {1 A6 n( j# ^4 R1 a' F2 i  h* q; x
  164.             if((fileSize - fileCount) > *len)2 Z5 C3 ]" b! c
  165.             {. a% F; D3 k. G7 e9 e+ ~4 A
  166.                 file->write((char *)buff, *len);
    4 ?8 n. B( ?" i5 z. F

  167. ' i. m/ ~2 ~5 s) w. e' T; X; _
  168.                 fileCount += *len;
    0 x! U8 I/ Q2 g5 ^0 t! [" F% x
  169.             }$ @. I. B3 `3 e- l* q7 _! F
  170.             else. V/ n8 v3 f0 Y' d- U
  171.             {5 P. V. i/ M1 |" E% G
  172.                 file->write((char *)buff, fileSize - fileCount);
    * j; Y5 ?" b8 h

  173. % k4 q, a( N- }. C
  174.                 fileCount += fileSize - fileCount;
    & J; s/ ]. X* ^  T6 R# ~6 @1 }
  175.             }% q7 A) m* o3 _5 f

  176. - B2 O3 t# c1 Q
  177.             progress = (int)(fileCount * 100 / fileSize);% C+ ^- I# \$ g. c, W

  178. $ @& H  e$ x/ J# o
  179.             YmodemFileReceive::status = StatusTransmit;
    # A. {3 \' P2 h9 C6 R6 k) ]* F

  180. / J3 F9 H3 L$ U8 ^
  181.             receiveProgress(progress);! ~+ ]% f9 }% X' _5 O
  182.             receiveStatus(StatusTransmit);, T" S% ?) L! G$ D
  183. * ~, N8 K8 e/ g3 O& I3 z' o- s, V
  184.             return CodeAck;
    0 {  k3 O( p9 l$ ]- T
  185.         }0 T0 x" Y" [$ m7 N  i1 ^/ n

  186. 2 h' h# n. r1 R) A
  187.         case StatusFinish:" N7 H$ q! `/ x$ k$ W$ Q7 C
  188.         {; i$ l3 v% ?$ c. U
  189.             file->close();
    : I& I( f; B) a

  190.   N/ s0 X* J: q" J& K
  191.             YmodemFileReceive::status = StatusFinish;
    ! [/ r5 v4 o) Z3 `
  192. $ f! S: p- _0 U) s% F& \% n4 u+ ?* |
  193.             writeTimer->start(WRITE_TIME_OUT);" M* r/ z# I0 C7 I

  194. : o( y1 s! m7 L; i1 Z0 C' q
  195.             return CodeAck;. ~/ d, ^6 {; X2 R
  196.         }% [! |- M! e0 t9 V2 Y
  197. 1 h) E; G& z) k2 B+ |' b5 U: C
  198.         case StatusAbort:
    9 @$ t3 j! e9 t& a
  199.         {
    4 o6 N, T; a5 i; \% D+ b* j. L
  200.             file->close();
    5 [/ D" Z  f2 }  Y4 V& J/ S
  201.   J: ^+ d; r0 S$ ~$ d1 }; Q& |; M
  202.             YmodemFileReceive::status = StatusAbort;; d, J. d/ Q- v/ ~/ e+ w

  203. 2 Y' B, q% ~9 H7 k6 f( Z5 j" _( r. p
  204.             writeTimer->start(WRITE_TIME_OUT);
      T2 F/ h" ^3 [# m: d

  205. / y  N7 l# v( w: A/ G, W
  206.             return CodeCan;
    + G; Y6 G* A& j: ]* t6 C
  207.         }8 l1 g# n6 |. T" F% U# W# a

  208. 4 V* k; U% \2 ?6 s* V' h& c
  209.         case StatusTimeout:
    * X) G. G5 P6 f: r* K, m. D, ?# |# P& |4 ~
  210.         {, x4 s6 ?. h4 c% t, ~' F
  211.             YmodemFileReceive::status = StatusTimeout;8 E7 w) b/ g7 d0 _5 f5 B

  212. ( D. f& B# ^5 G/ {: ?! R9 B; u
  213.             writeTimer->start(WRITE_TIME_OUT);
    - {/ f! Y$ L$ R1 J9 h" R
  214. + u; `2 y. {& s2 N# _+ Q! E
  215.             return CodeCan;/ b" j0 A; o- y; F. Q: g
  216.         }
    ( g, K6 a) `4 `5 p: Z' ^
  217. , F! ~2 c7 B2 C- ~! t/ g/ V  w
  218.         default:2 ]4 `' F+ I: Q( ^; P% Z% t
  219.         {: v# }. z- h% e$ ^& W
  220.             file->close();% H/ {6 @, F3 ^$ ~: B" n

  221. ( Z4 K: f5 o- l* E6 x  n/ C
  222.             YmodemFileReceive::status = StatusError;
      \, H) O( r7 U; o" l" ~+ z* B
  223. 5 k# P2 V) k- U7 _* Z' R& T( t
  224.             writeTimer->start(WRITE_TIME_OUT);5 D2 D% y* m( l, z5 F" c5 ^

  225. 6 Y. P7 i% r% y$ l6 {9 N. m
  226.             return CodeCan;0 S$ D( v7 m" \% T) ]
  227.         }
    6 H) ?: u. S- h4 C
  228.     }
    8 k/ a) C$ t/ n" P& O- m/ D
  229. }0 G2 j( |( y0 \  Q8 r6 m
  230. + Q7 P% M# h( ]1 b7 _$ d
  231. uint32_t YmodemFileReceive::read(uint8_t *buff, uint32_t len)
    7 H/ a$ C3 p0 a  [/ k) y% k
  232. {3 V* i- P. y, C
  233.     return serialPort->read((char *)buff, len);
    ' l% I7 p/ |$ W, ?4 }
  234. }
    5 s) t. |1 n2 W0 p, K& ]1 X7 x5 |. Z
  235. : x$ M8 G" a0 K  j: C" m/ j! e
  236. uint32_t YmodemFileReceive::write(uint8_t *buff, uint32_t len)
    2 X4 g! q0 ~! l
  237. {
    % L9 P: W  h3 ^. ~) F& g0 Y: L- i
  238.     return serialPort->write((char *)buff, len);
    9 B3 \5 e5 K1 [
  239. }
    ! n( V& ]  j% o0 S
复制代码
$ v; v1 z- c1 [& @8 ~; [1 D
& |% Z' n9 |$ k( E) R' v
7 Q! J& n- [. e; D- ?: }) s# C

) s; ~8 ?, k0 N! `
% w  ]1 i' N1 ]/ Z5 m# C9 v. W
XinLiYF 回答时间:2018-3-6 22:31:26
      YmodemFileTransmit.h文件" |" ~6 E4 W$ r3 H  z
  1. #ifndef YMODEMFILETRANSMIT_H
    7 }% e, p* l& g9 I' X# u
  2. #define YMODEMFILETRANSMIT_H
    8 n# s1 k  j, L: b7 `3 `1 m: a' `8 ~

  3. 2 V" ^* c2 A8 @; x/ \' _# ^0 [' V
  4. #include <QFile>9 P4 L0 A# x' }3 I; T
  5. #include <QTimer>) h, I  r, I1 e: K. R. \% t8 |
  6. #include <QObject>
    , ?/ j" k# x' P, X1 G
  7. #include <QSerialPort>
    " ?# ?* t0 Z7 ^) b6 D
  8. #include "Ymodem.h"
    ' j# s) X8 s$ }% ?( ]: Z1 ~3 J

  9. / t8 m5 \1 b9 ?
  10. class YmodemFileTransmit : public QObject, public Ymodem$ |5 V& B/ y& d4 d5 Z/ w& v$ ~0 D( ~
  11. {2 a" ^6 g4 Z$ e+ |
  12.     Q_OBJECT1 F/ B9 Y- B; Y
  13. 8 w( q% @. l; Y/ p. M7 X( {+ @  [0 Q
  14. public:
    ) s$ v+ M% P7 h2 ~
  15.     explicit YmodemFileTransmit(QObject *parent = 0);
    - J2 N( J/ u, c2 N8 V' `! w
  16.     ~YmodemFileTransmit();6 E; M1 S; g1 K1 P4 ?9 [" ?& Q

  17. / T- V  ]7 U- S3 z5 d
  18.     void setFileName(const QString &name);# E1 D, M( f# j; a' J( h# m

  19. 6 _) J& T# t' d0 a. f+ f7 L, s
  20.     void setPortName(const QString &name);. a$ E5 f7 {: f9 Z/ T% ]
  21.     void setPortBaudRate(qint32 baudrate);
    6 B  M3 f! r9 b7 L' m

  22. , F' L( |! V5 n: Z1 [
  23.     bool startTransmit();  r* d/ z" q8 a$ i$ A! d) T
  24.     void stopTransmit();" o! X( [3 f: x! t# Y2 O

  25. ) i) v1 u: ~8 e& x7 Z; C
  26.     int getTransmitProgress();
    " ^% Z& j  z- t: E1 n1 J: B- G) C
  27.     Status getTransmitStatus();
    6 o4 i% B1 W* x- ?! t5 T* j$ R

  28. 6 ]2 q0 v8 A: ?# ^# a$ U7 ~. c3 }
  29. signals:
    * U7 k  t5 C9 ]( L% Q
  30.     void transmitProgress(int progress);
    9 Y5 y/ x  O+ G2 Y6 M, c
  31.     void transmitStatus(YmodemFileTransmit::Status status);, |2 m* Z& d2 ~( ]6 s
  32. ' o8 t# _/ l5 Z
  33. private slots:4 k) h& Q3 [5 Z  i8 i
  34.     void readTimeOut();
    5 e2 C8 E+ c/ u5 H
  35.     void writeTimeOut();
    7 p0 Y. C( L* R' i; S, x/ ]

  36. - a) l6 o+ H5 O% L; U
  37. private:8 k* T7 h5 n) \; u# [# F( @
  38.     Code callback(Status status, uint8_t *buff, uint32_t *len);) j+ G+ ~8 |; ~/ w6 k8 k
  39. + G( {5 o9 Q. q! q2 M/ j- j
  40.     uint32_t read(uint8_t *buff, uint32_t len);6 A2 k8 P  @! e2 j5 w; h
  41.     uint32_t write(uint8_t *buff, uint32_t len);* m* K9 O1 O- ^4 E: z" t  }& p& [
  42. : b5 H7 y" F  i; l( s2 ~* H" F* }: c
  43.     QFile       *file;
    1 Y1 L: y! g* `9 X, i) }. J; Y
  44.     QTimer      *readTimer;5 Z& |1 [1 y( v  p) G( }
  45.     QTimer      *writeTimer;
    ( L3 W4 E1 g: E2 s
  46.     QSerialPort *serialPort;
    ! L) v" m& {- C

  47. & X3 o( X* \6 B( q  @: u3 Q% O
  48.     int      progress;% D  m4 u1 {$ A
  49.     Status   status;" t9 j( I. i! z, E: o* G
  50.     uint64_t fileSize;
    1 U( Z; s- _( C9 X5 Z+ e7 W' j
  51.     uint64_t fileCount;/ M  l" f8 o1 p
  52. };1 R8 I( A2 v4 u* }1 O

  53. ; x# G! E; m. G3 Q6 B8 R
  54. #endif // YMODEMFILETRANSMIT_H# n! L4 k% y0 A  ^+ }) L$ f- P: x
复制代码

0 [# Y8 Y+ ~1 q# t, ~( W% E      YmodemFileTransmit.cpp文件
! _; ~/ b! a; C4 m7 D6 ?0 ~  \
  1. #include "YmodemFileTransmit.h"
    $ l# j2 C# k3 G3 k
  2. #include <QFileInfo>
      J/ ^( c2 G! S2 T# o
  3.   J( ~. c  P' S# F2 L* ~  v  s" I9 b
  4. #define READ_TIME_OUT   (10)
    2 D9 [5 G4 `3 w8 a/ G, ~
  5. #define WRITE_TIME_OUT  (100): f( g; w9 N  Z6 z
  6. - N) [1 K- M; H
  7. YmodemFileTransmit::YmodemFileTransmit(QObject *parent) :2 G( c6 d# l+ }0 W4 _
  8.     QObject(parent),/ q8 C& `( y( j! l5 V7 L* v
  9.     file(new QFile),
    * w# b5 e5 Q6 H% |4 }
  10.     readTimer(new QTimer),# K" t- `* d1 g/ p7 F' ^* s* k
  11.     writeTimer(new QTimer),( [' E4 o/ W! \4 I+ n0 V
  12.     serialPort(new QSerialPort)
    + T! _5 l4 s: E' W& P( C/ x
  13. {5 s9 s# c  w6 Y8 |/ P! ~3 }
  14.     setTimeDivide(499);
    . {! l4 ~3 q# h! p" k5 c  ]& e: H
  15.     setTimeMax(5);
    1 `1 {- h( @4 w( ]* @# l
  16.     setErrorMax(999);, j1 E: n* A" Z

  17.   j1 ~- v; e8 c+ M# x
  18.     serialPort->setPortName("COM1");& c; [( Y4 g* y: ~" Q
  19.     serialPort->setBaudRate(115200);
    " M  |, _. o$ d9 r+ N9 n
  20.     serialPort->setDataBits(QSerialPort::Data8);0 b$ U- `* G# E! d
  21.     serialPort->setStopBits(QSerialPort::OneStop);, d. G5 y% d6 s( Z& C
  22.     serialPort->setParity(QSerialPort::NoParity);# ~5 Q' v* N) [) L
  23.     serialPort->setFlowControl(QSerialPort::NoFlowControl);6 v/ E: p- |. T& b
  24. 3 F7 F/ X3 o+ i% Z
  25.     connect(readTimer, SIGNAL(timeout()), this, SLOT(readTimeOut()));
    8 e" u1 M$ w" L- F  h  g
  26.     connect(writeTimer, SIGNAL(timeout()), this, SLOT(writeTimeOut()));
    # x2 \, \5 I8 W
  27. }1 U/ {5 n# I9 i; P# N% |7 r/ |
  28. 4 e) c4 |. ^) N4 ~( n5 @
  29. YmodemFileTransmit::~YmodemFileTransmit()
    * q3 G: k( B6 F& l" [
  30. {; @6 _" p$ {# B  l9 t$ Y
  31.     delete file;
    ' y3 m' Y7 }: r! p
  32.     delete readTimer;
    7 a1 p. k; }$ k' y- x
  33.     delete writeTimer;3 B' P0 P' s7 I/ {: a
  34.     delete serialPort;
    % z* D5 X6 _1 i+ @; n
  35. }! X- \" |' u3 V2 }! ]) c- D  X/ C
  36. . x- M( e( r# W. s7 V; f
  37. void YmodemFileTransmit::setFileName(const QString &name)
    " ]3 E2 j" F3 a9 G9 i
  38. {. s2 `$ Z2 B! u6 _8 X3 w
  39.     file->setFileName(name);
    ; R6 S% E' ~# y  A8 M( f
  40. }' w* l# k. i/ U) y# V
  41. 1 ~4 J/ T% w) \; @1 I
  42. void YmodemFileTransmit::setPortName(const QString &name)- b" ?2 k, k; g) m! `
  43. {
    , C- v( @) u: J2 x2 x3 F
  44.     serialPort->setPortName(name);; [$ Q; r+ U1 y9 G  C& t; f3 Q
  45. }' a) Q4 V* A6 D9 ?& q

  46. & d% S" S+ y1 b4 L4 N
  47. void YmodemFileTransmit::setPortBaudRate(qint32 baudrate)4 w; ?" ]6 _3 |% ^7 h5 u% ?
  48. {
    - s) J- {) w5 P: J
  49.     serialPort->setBaudRate(baudrate);
    * a8 R) s: q% o- B: R
  50. }
    6 n; Q& N* }! k

  51. , r; i" N7 c9 h. ?. B5 D, N) m
  52. bool YmodemFileTransmit::startTransmit()+ Y4 x9 _% q% |) A% s8 Y- ?
  53. {
    9 \2 \2 t  r# O2 W/ t, P) y
  54.     progress = 0;
    * l$ L. F2 d4 ?) I1 Y
  55.     status   = StatusEstablish;
    . [- V7 \5 z* R/ C$ g, z* }
  56. * E$ j: z! S4 D" f) ~
  57.     if(serialPort->open(QSerialPort::ReadWrite) == true)
    8 W: j/ C  S# w. H
  58.     {+ O/ S  ]1 X" m+ R' s' x
  59.         readTimer->start(READ_TIME_OUT);8 E1 M; V, i/ p# v6 O6 l/ _
  60. ' b8 B1 f0 [( s* j9 L+ s! g
  61.         return true;& f7 t9 |9 G3 p; ^( ?
  62.     }* S9 H5 C$ Z* x; [: W7 _1 |
  63.     else
    ! f; m+ d3 L, Y: m5 p: s, q
  64.     {: L% D, |3 I' }2 k
  65.         return false;
    3 F0 E2 v" w# ]* A6 [( \2 [4 m, X
  66.     }. d* u& E0 w4 w# p
  67. }! {+ C, I7 n! a$ ^* H9 E5 s

  68. 5 W  L4 ~* u2 h) K' {$ ~
  69. void YmodemFileTransmit::stopTransmit()
    1 d5 ^* k) _0 B3 I" |1 i, B4 I/ B+ q  k
  70. {, W  s9 [3 Z  ]0 W
  71.     file->close();! t1 G: z' ^; l! r
  72.     abort();' Y1 D( U$ C4 F0 W/ v5 E6 M
  73.     status = StatusAbort;
    # q: Y: N/ e+ m- E) h2 @8 q
  74.     writeTimer->start(WRITE_TIME_OUT);
    & Y! a- ~' g/ I+ w! V2 S: ~# O/ t
  75. }
    0 N( _' z% m9 p) G: R

  76. & j( M- r3 y1 Q. E: d/ A
  77. int YmodemFileTransmit::getTransmitProgress()) ~' A( ^, r7 r& ?/ s6 L( ^
  78. {
    * x  O# [# T' F' G7 L4 N
  79.     return progress;4 \# e9 @" x" Z3 n
  80. }
    + H4 S" Z' J6 j( L( C& M8 j  I1 ]( L

  81. 9 \0 T2 ]8 ]6 X) V
  82. Ymodem::Status YmodemFileTransmit::getTransmitStatus()
    , X- f$ h/ x7 ?. s: X9 [
  83. {+ w) @% {; ]7 T3 k
  84.     return status;
    0 i4 ?( X6 B1 ~1 p, B% o
  85. }
    / O/ K5 q2 H0 ]9 ]6 X" e

  86.   F* |# E' c/ I0 V- f$ ^/ r  f! A% P
  87. void YmodemFileTransmit::readTimeOut()
    ' F% l" q% Z9 C0 E2 t5 L* q* {
  88. {
    & z7 r: A( ^# V7 H. o0 q
  89.     readTimer->stop();
    # u+ q; _* j7 n$ }6 s6 W
  90.   @" D7 S" z, S( b
  91.     transmit();% k7 K9 F! z/ ^8 K1 S

  92. - _3 r% z9 }$ ~! |6 Q1 W
  93.     if((status == StatusEstablish) || (status == StatusTransmit))
    : B- m: A9 Q" y# n
  94.     {
    % }: t* L0 l) L0 L2 n0 c
  95.         readTimer->start(READ_TIME_OUT);
    7 c' p! C" H" N
  96.     }- ]' W) M6 {' S7 B# `
  97. }
    ( h# C1 x" }0 K9 h& l2 \

  98. 5 f4 e$ s+ ~" |4 F7 \
  99. void YmodemFileTransmit::writeTimeOut()9 j1 c. q6 T4 U8 r# D. c5 k; t
  100. {' d" {, L& x# {# Q
  101.     writeTimer->stop();3 y7 q) j% L( V; W  r7 _/ A- Z  _
  102.     serialPort->close();
    * q5 n! ]9 E2 ~1 V% ^
  103.     transmitStatus(status);
    4 P2 J$ o; o' F7 u7 n
  104. }$ F9 e$ n5 w  q% r* i3 g9 r9 ]

  105. : u1 Z& F" D' d  _0 o0 t: t
  106. Ymodem::Code YmodemFileTransmit::callback(Status status, uint8_t *buff, uint32_t *len): [' S$ t) L+ E& G6 e3 W/ w
  107. {
    - \) K( b' Y. b
  108.     switch(status)5 u& {- W$ w0 T2 |8 g  Q
  109.     {3 F" S( d7 h" K4 U9 [1 A( |
  110.         case StatusEstablish:1 M5 N% ]$ @- z* f1 b! j) ]( t/ ?
  111.         {) g1 f4 `" N0 f8 `1 D
  112.             if(file->open(QFile::ReadOnly) == true)+ T- Q' u! ~6 d0 D6 D
  113.             {
    % F: c$ R+ h) G6 Z5 u8 q0 R
  114.                 QFileInfo fileInfo(*file);% K$ K; j9 I4 G) X6 T) z

  115.   C% d1 r3 F' |' ~* u
  116.                 fileSize  = fileInfo.size();/ `  c! b, o7 D. Y" U; g5 _
  117.                 fileCount = 0;- G2 u& y( F  ^* }1 I, W+ G7 y

  118. " Z* E$ E0 W0 R' `3 [% ]
  119.                 strcpy((char *)buff, fileInfo.fileName().toLocal8Bit().data());5 x( [$ w" Z9 j) X' X4 j  p3 n
  120.                 strcpy((char *)buff + fileInfo.fileName().toLocal8Bit().size() + 1, QByteArray::number(fileInfo.size()).data());
    ( _1 V1 v3 q8 l: c! T/ s
  121. ' Q+ D) r  D. b
  122.                 *len = YMODEM_PACKET_SIZE;
    6 Q- e1 C, A% @' w; q

  123. ) u. R7 v6 |- A+ Q- s8 w
  124.                 YmodemFileTransmit::status = StatusEstablish;5 ~4 g. R2 S  g1 g7 N8 O
  125. 6 a. l: A0 {3 B
  126.                 transmitStatus(StatusEstablish);
    5 O# f8 y+ f7 n$ }

  127. ( ]4 @) Y4 d6 T) @  L6 a" e7 w, j! p
  128.                 return CodeAck;
    9 L/ _( z' p- n9 s9 ]1 X. G# w0 j4 ]
  129.             }7 R6 j0 J5 T; r1 F( S& x1 i
  130.             else( `/ C$ r. \/ c5 a+ S) y
  131.             {
    3 _. u. t9 j& {/ O% F% D
  132.                 YmodemFileTransmit::status = StatusError;
    " Z+ q; L& j, b3 |$ m
  133. 4 t* T- H" ~, s+ f; u. H
  134.                 writeTimer->start(WRITE_TIME_OUT);" M) o& F  y$ i& C5 F

  135. 8 Z- z2 c2 W2 @# q
  136.                 return CodeCan;
    ( R7 i, F- @  u$ K/ x
  137.             }$ H; h. E7 g" y5 q; d
  138.         }4 j/ p1 p7 g' k2 f( S8 q2 Y  ^

  139. / L( W* o3 h% z: s9 D
  140.         case StatusTransmit:2 S1 l* n2 b3 _, B
  141.         {
    * y; v, V5 h( [" d7 R
  142.             if(fileSize != fileCount); F. Q: e! s: f# L
  143.             {
    1 g+ S* d3 t5 f* D  N% _. B  d! C
  144.                 if((fileSize - fileCount) > YMODEM_PACKET_SIZE)% W4 G  k4 H% g, F; H* Y
  145.                 {- ]! k0 L" x2 i5 w6 v0 o3 ~* h2 B
  146.                     fileCount += file->read((char *)buff, YMODEM_PACKET_1K_SIZE);4 n& f# Q1 r0 `: o

  147. * }9 R9 n+ I+ I, l4 j
  148.                     *len = YMODEM_PACKET_1K_SIZE;; P# X0 A5 A$ w5 d
  149.                 }9 C- F* @+ q$ i/ R9 R( x2 E* n
  150.                 else
    5 h7 E5 N4 d; _3 t/ C
  151.                 {5 ?0 f) b! S# v) e# E7 M% v
  152.                     fileCount += file->read((char *)buff, YMODEM_PACKET_SIZE);
    5 b: O0 {# Y- R2 G+ S" j

  153. 9 Q5 i: g, U# Y. f9 \" D
  154.                     *len = YMODEM_PACKET_SIZE;) H* L5 b4 K4 L7 z9 V. p
  155.                 }
    2 p8 P% r) p4 ?. Q

  156. 9 E, z& D& P5 [. D
  157.                 progress = (int)(fileCount * 100 / fileSize);8 M& S( o1 ?& K' i! o% R

  158. 8 k" K) h5 G$ a+ H: G  o6 k( H2 w
  159.                 YmodemFileTransmit::status = StatusTransmit;
    8 K7 |6 g' u5 O

  160. / }. Y3 S& L( s( o3 ]
  161.                 transmitProgress(progress);5 D) w& U: U$ k* ]8 K
  162.                 transmitStatus(StatusTransmit);
    8 x; s! b+ w& h5 F4 }8 `
  163. 7 O7 J! }8 z5 j: c& K- [; |
  164.                 return CodeAck;
      K: j& N+ s) l! k8 t5 ]) z7 s
  165.             }
    ! p) v$ w2 b6 {1 |  r8 o
  166.             else; G  r8 K! b. }8 r7 `
  167.             {1 W* w( v0 c$ I$ ~, I1 E
  168.                 YmodemFileTransmit::status = StatusTransmit;& ]  O5 S2 }/ z& _, G! U+ C& `. ?
  169. $ J; ]7 k4 o3 }3 R9 q* b
  170.                 transmitStatus(StatusTransmit);$ ]: i, D9 s" ]1 k

  171. 1 A/ |0 g# S1 t, w, l7 n3 x2 M5 P
  172.                 return CodeEot;( ]4 v7 O( D! z! T* F, O2 h
  173.             }/ n2 x4 H( w* }) p
  174.         }
    5 G+ i2 W* ~; w1 h6 G4 |. |$ e
  175. " v6 z5 y$ \5 |: X( o  I, M0 s7 {
  176.         case StatusFinish:
    5 R& N8 Q3 T* n% v7 d; ], R
  177.         {" u3 w% w% L% ]$ d+ v
  178.             file->close();3 l3 @( s0 x4 A# }

  179. , c- M- r( v* j  O( s
  180.             YmodemFileTransmit::status = StatusFinish;2 w9 q7 N9 b  B; r" r* I9 T/ ?& a
  181. 4 @+ N: j5 x/ N5 |% W9 l
  182.             writeTimer->start(WRITE_TIME_OUT);& {$ p6 G% i( C; }+ d8 ?

  183. # W' A( `5 _; ^, [
  184.             return CodeAck;
    0 E8 b, _4 ^# P2 I+ n, C9 M6 L* l
  185.         }9 i& z  ?# X+ L) a& ~
  186. + U4 w5 y5 J* z8 C% q
  187.         case StatusAbort:$ N1 H) I  Q# ?: n( j) V) b
  188.         {
    * \2 ^) r  \+ ^  j9 l2 ]
  189.             file->close();+ V  n% K: ^  H4 P: u% Q
  190. 3 b# N  X( t+ p3 {, f) X
  191.             YmodemFileTransmit::status = StatusAbort;) Z/ |8 E8 D: K
  192. . v: f* f7 b) o0 Q+ ^
  193.             writeTimer->start(WRITE_TIME_OUT);
    ) m% \, D( @* m$ G) `
  194. " {. T! _3 Q5 @3 J
  195.             return CodeCan;
    2 O! }0 J* o. Q
  196.         }
    3 ~' x% p0 T! ], P

  197. # b0 {) R" _6 i& v0 e
  198.         case StatusTimeout:  Q5 {; u) t* M0 [# S/ C
  199.         {( z6 u7 t) `1 c& ?# @
  200.             YmodemFileTransmit::status = StatusTimeout;
    3 x- D4 e' B6 `( P, n. a

  201. ) R9 z  x3 z  Z% j/ E7 V
  202.             writeTimer->start(WRITE_TIME_OUT);, F- p# q% V. l1 A  v% f3 i3 I
  203. 0 Y% t  T$ L, q6 d5 ?2 f! l6 D
  204.             return CodeCan;0 R# r$ @' I' l6 R, R- W- ?8 x- r
  205.         }
    0 I3 S: c  G- L( h; O$ C. b
  206. 8 g5 k" |6 X  S& P6 D0 ?; s
  207.         default:5 Z: c, b0 m% W, K2 R1 I. _( D% B! ~
  208.         {
    * S8 I, H: g3 L2 `1 w1 t) d# [
  209.             file->close();3 J- U6 W; ~  l* e& I

  210. 5 u/ G4 e  _" W- ~% _
  211.             YmodemFileTransmit::status = StatusError;2 J' N" d0 U- D, I5 {2 d
  212. 5 V$ V2 S' h( R# d( |
  213.             writeTimer->start(WRITE_TIME_OUT);
    5 o, Y4 ~; \) G
  214. 3 p' t7 d* ~! r
  215.             return CodeCan;
    " ]1 y- k8 n- a. U8 S6 @5 Z+ e
  216.         }
    . G( x, U+ k2 S1 U. u3 e0 ~
  217.     }7 Z- K* P# z- u  a8 {- z' V2 G$ A
  218. }
    % x/ r7 `8 j) @
  219. # \6 e6 E+ S6 i  S' {* G6 Z5 a3 V
  220. uint32_t YmodemFileTransmit::read(uint8_t *buff, uint32_t len)
    ! O+ p$ V9 U$ m/ g
  221. {8 K- P" V+ a* W! g' O
  222.     return serialPort->read((char *)buff, len);
    * Q+ Z. e) j2 _7 C. t
  223. }
    ! f5 R; p1 l  T( W

  224. 6 r+ B; Y. s) l
  225. uint32_t YmodemFileTransmit::write(uint8_t *buff, uint32_t len)$ d$ Q( R  F: E9 m1 z0 o
  226. {$ I( o+ x/ ^1 V; U0 x0 O$ v
  227.     return serialPort->write((char *)buff, len);
    ) W( i4 r: x/ s# a
  228. }
    ! C  J% W$ h0 g( H; t% D8 |
复制代码

/ S2 k! D+ D( M' C+ Z
0 @' ~* B: T) j. u! I+ J' T3 Z8 b" g* d

" P7 L# ~. J- F. A1 G# Q- T% n
2 h0 K* c/ N) `- Z
XinLiYF 回答时间:2018-3-6 22:32:05
      widget.ui文件
% Q1 L8 }/ N) J- z5 b- w$ }
  1. <?xml version="1.0" encoding="UTF-8"?>
    ; a$ t# h, f, R7 Z4 i/ }( x9 k! ]! k
  2. <ui version="4.0">6 r9 v  z' U2 _3 ~, S# @
  3. <class>Widget</class>
    : k% M1 w3 z, N3 J
  4. <widget class="QWidget" name="Widget">* V3 A) a% B' p) \* Z5 s
  5.   <property name="geometry">7 |# f4 W3 D# \/ r+ b
  6.    <rect>8 F+ [/ S, F( I; n0 h/ J
  7.     <x>0</x>
    3 A2 G( H! R& n+ U# b, I1 g4 O/ I
  8.     <y>0</y>
    . k) R6 n3 o" g7 }. p* G4 {
  9.     <width>444</width>
    - _* G4 a+ E, Q; M% p0 p
  10.     <height>255</height>) I1 \( f8 i5 \$ |
  11.    </rect>9 g! J2 H9 G2 v. A8 S
  12.   </property>
    ( h  X% O3 w( t6 L2 ^0 k, Z: k
  13.   <property name="minimumSize">
    / h$ ]& x! |# b5 G9 g: m! R' y
  14.    <size>
    0 ?* D9 X7 B6 b
  15.     <width>444</width>
    + c( W3 d; O0 v9 h# U
  16.     <height>255</height>8 q5 P0 @/ \  O1 K' k/ P
  17.    </size>. [$ r. z) U  o/ L! J, j0 A
  18.   </property>8 [  h+ `; L# b* \6 T- H6 |  T
  19.   <property name="maximumSize">
    ' `) u! t6 w' o, z( B
  20.    <size>2 d; h* g0 U- r
  21.     <width>444</width>9 j! A! v. p% X
  22.     <height>255</height>
    % Q, M- X: X. @3 g) |& x  Q' H
  23.    </size>
    3 i# i1 L4 u  D1 v+ D
  24.   </property>0 a5 M8 V3 y4 I- d* e3 T
  25.   <property name="windowTitle">
    8 }- [9 D' h& B
  26.    <string>SerialPortYmodem</string>; C6 X% j3 q% D) y9 _: _: |
  27.   </property>7 |/ D8 {1 M% t/ `1 k4 O
  28.   <layout class="QVBoxLayout" name="verticalLayout_3">% m7 y- b5 Q6 s& N
  29.    <item>
    6 R+ M8 m7 T. q0 T5 a0 x/ r& e
  30.     <widget class="QGroupBox" name="groupBox">& {, V8 K; g8 I2 o5 ?
  31.      <property name="title">
    , s% c: o. Q! a# t. F" J
  32.       <string>串口配置</string>
    0 V4 z7 L; k% `. B$ y4 }# R' a& E7 l
  33.      </property>
    # b1 M) [2 L; Q! S  @
  34.      <layout class="QHBoxLayout" name="horizontalLayout">- }$ v1 [& Z' H# O4 M# p
  35.       <item>
    2 M. n4 S! L7 c* Q) E
  36.        <widget class="QLabel" name="label">
    1 P; g' {$ v/ k+ x. v8 ?
  37.         <property name="text">7 S# m: F+ |9 O4 ?, e) z4 l
  38.          <string>端口:</string>; e# p% _, s1 u, D
  39.         </property>, S+ k1 j  _5 G9 b
  40.        </widget>7 F# S" Z2 n  o
  41.       </item>
    - C4 _/ p7 F0 D
  42.       <item>9 f2 Q" `0 E* L+ J( E2 j  @
  43.        <widget class="QComboBox" name="comPort">
    9 f) v' R6 |3 g  B# N6 g) R
  44.         <property name="maxVisibleItems"># q6 w9 @5 G2 b4 p# G' o
  45.          <number>12</number>4 E  x: x1 i6 s: I- w
  46.         </property>
    ! v- {7 O  |/ B. W* {* a
  47.        </widget>
    ; l6 O9 G3 I* o
  48.       </item>
    7 R  L: |+ v. _7 V
  49.       <item>
    " ~* v& O. Q: u/ _7 _2 l% g% W- L
  50.        <spacer name="horizontalSpacer">
    " z0 D- J  i2 G2 F
  51.         <property name="orientation">0 B. a; ^+ ^: b/ H1 h
  52.          <enum>Qt::Horizontal</enum>7 r. T9 G4 J; b5 X- Z. Y
  53.         </property>* h1 e. A( @; I  A$ w# M
  54.         <property name="sizeHint" stdset="0">
    " X" P5 V0 W! L$ M
  55.          <size>
    # E& q, q4 {( E; X
  56.           <width>40</width>& S8 d  E9 Z+ [- f) [
  57.           <height>20</height>0 o! x" n( _" F8 F/ E# |# Y
  58.          </size>+ L4 y  g, c" W) f) t7 H* @
  59.         </property>
    4 [3 F7 t( T; _# e5 ^1 y: R
  60.        </spacer>2 f; n, o+ u# T' C/ {: a+ P
  61.       </item>; ?6 L! ~- y# }4 k) X
  62.       <item>
      x' C" H! d: `; Z
  63.        <widget class="QLabel" name="label_2">
    9 r2 C/ T; ^* x  v7 F) q2 ?
  64.         <property name="text">8 P2 O+ W! l& t7 E! N/ \; \
  65.          <string>波特率:</string>& q3 ?+ u/ Q$ Z7 _( d0 {
  66.         </property>7 m! B3 H; ]2 j4 z
  67.        </widget>
    $ [) t( a+ m& P/ S
  68.       </item>9 w/ }: j5 [; z1 V
  69.       <item>
    8 J# N: a  [7 Z! h, d
  70.        <widget class="QComboBox" name="comBaudRate">
    9 Y" O' R3 d- S0 j2 P8 C/ h" T
  71.         <property name="currentText">3 e' e3 v2 X/ l; @  v
  72.          <string>115200</string>
    7 o4 w! _  s: p1 ~- v
  73.         </property>
    9 ?5 B8 K( r. m3 n: g$ ]
  74.         <property name="currentIndex">0 ]$ ^* i' _& S
  75.          <number>3</number>
    + Q0 v! X7 i, p; O9 ~9 H4 k# C
  76.         </property>
    ! h+ w; `# @/ o  Q; t- K6 _
  77.         <property name="maxVisibleItems">. ~6 P* d; C7 U
  78.          <number>12</number>
    9 `' T6 T( |3 G( ]) x+ q7 h
  79.         </property>& x" `3 U6 s9 y1 Y
  80.         <item>2 E. y/ x+ W5 k7 o$ r; h% ?
  81.          <property name="text">; V  `, a% ?8 w: D) A7 l; l
  82.           <string>921600</string>
    + Z7 c. I9 J0 ?! {, q$ ~0 Z% `
  83.          </property>: G( U8 T  V5 Z6 m7 V+ u% ^+ j4 {9 q
  84.         </item>
    ) _1 x# M7 w5 p1 C  ~; V
  85.         <item>
    ; v# b6 B% B5 h6 S3 \
  86.          <property name="text">5 G. B1 @% P) f8 t; U
  87.           <string>460800</string>' s" ]& W, u. x/ X4 m6 {
  88.          </property>. j1 ^6 }1 n" ?4 @5 ^4 v; G8 ?5 F
  89.         </item>
    8 @2 N9 w6 V6 m5 b7 w: @; Z
  90.         <item>9 @7 @. f9 r, N" E  E
  91.          <property name="text">) p0 h8 j/ X" v/ a4 [
  92.           <string>230400</string>
    $ S$ \$ P: W. Q% o  s0 v5 D
  93.          </property>( c8 X% p  ?2 k5 K
  94.         </item>% f. x1 U! J2 l. J. X% ~+ U3 d
  95.         <item>& U* f5 }& a0 W" ~( Q( t
  96.          <property name="text">
    ! s2 Z) e- S& B1 r
  97.           <string>115200</string>
    . L& F+ |2 ^9 ]+ B% l9 X
  98.          </property>
    4 l' {* I' S0 _- E) d8 Y$ J" b
  99.         </item>0 c3 L4 l2 v; U2 r& \6 ?3 T
  100.         <item>5 f0 U4 l: x+ ^/ |5 {) C& Z
  101.          <property name="text">/ N9 }5 q, q1 y) F
  102.           <string>57600</string>0 n* R5 q: b% F6 E! v
  103.          </property>
    ( W. v8 U3 o1 l- ^6 Z/ h
  104.         </item>
    1 b6 p) ^: v$ h6 P/ Q$ i4 L
  105.         <item>' `' u$ |% n" s9 B
  106.          <property name="text">
    & E8 \" A4 `' Z7 N$ m
  107.           <string>38400</string>
    & n3 ]9 s3 X' r( t" k
  108.          </property>" R! H* @! Q  N. N6 d# P
  109.         </item>
    7 |+ x& E3 ^, ~! P* m, Q
  110.         <item>' ~- C# P6 H5 w  F
  111.          <property name="text">9 k4 h  Z$ _. r! f! Y
  112.           <string>19200</string>
    ; D* _) l) W9 P( H' h0 R
  113.          </property>+ }- J1 i2 R' I7 d6 c7 m
  114.         </item>
    # ^+ Z* a. F3 g
  115.         <item># f7 W& F, e. }$ M( S& P
  116.          <property name="text">+ ^( [3 L+ Q+ H# b3 y
  117.           <string>9600</string>) t  ]8 b' Z# O
  118.          </property>" l. V6 `  u1 R/ D
  119.         </item>6 R; g: d# p9 `
  120.         <item>
    9 D9 e8 [, F% m+ @2 t
  121.          <property name="text">8 [- p. f3 ^! {8 `2 z
  122.           <string>4800</string>
    ! K- g+ ^9 U4 O8 o4 r& V" b
  123.          </property>
    ( y2 |8 v, E2 t7 e! Z  B, `
  124.         </item>
    ) X: F4 h1 V9 |
  125.         <item>
    % e6 f) f7 ^8 A/ Z
  126.          <property name="text">
    . J" I) Q- m5 t9 E( r+ C- B7 _
  127.           <string>2400</string>
    : N6 t; z" A: r
  128.          </property>: G' f# D6 j, s- c; ]5 C6 h9 w
  129.         </item>
    4 I; }8 O8 \8 V6 F
  130.         <item>
    # L: j  m, j7 _
  131.          <property name="text">2 M- e3 s) o1 A4 w( c
  132.           <string>1200</string>
    / F" l4 F2 }/ ^  I! j$ j$ ~$ q
  133.          </property>0 @( W1 ?! B7 W& C& K: X
  134.         </item>
    # Y. c, c# k3 D6 w: R
  135.        </widget>8 i$ u9 |# `! z1 D, m$ C: W6 U6 L
  136.       </item>$ |8 w5 A9 l' [+ P/ K0 y8 I, d/ g2 S. k
  137.       <item>
    6 Z$ j; ~" d+ S3 _: e! q
  138.        <spacer name="horizontalSpacer_2">
    3 B5 f! o; f: K1 g/ A1 k6 X
  139.         <property name="orientation">
    7 B0 H& _5 g2 e. K
  140.          <enum>Qt::Horizontal</enum>
    8 I( O; O& }" s2 ~' c
  141.         </property>
    . j" ~; O# X' `" _3 o: H- v& ^5 J
  142.         <property name="sizeHint" stdset="0">! @, A" v( r* U1 n& [
  143.          <size>  N) F! ^) i; r, c- N. U
  144.           <width>40</width>
    + K4 |! k6 L& D5 x3 x8 A5 E
  145.           <height>20</height>
    & C2 l) Y- Z. A: _
  146.          </size>
    $ j7 ]0 _" _; ]
  147.         </property>8 X$ g) r, v  y( {) E  X5 A
  148.        </spacer>1 {# X$ F$ z. `! q7 N- S, [
  149.       </item>
    " r  j6 {# y2 o+ e% U
  150.       <item>* S$ f0 C* [3 Y1 {; T" e1 V* A
  151.        <widget class="QPushButton" name="comButton">( x7 r' p' M: b) U7 @2 t9 f1 r
  152.         <property name="text">
      C# |, {: W- J0 J! X% S
  153.          <string>打开</string>' A' b+ G/ Z- _* L! U
  154.         </property>/ I  z. O5 ?( P! M* e; l- H
  155.        </widget>* |+ q1 F3 ^5 E) {0 }
  156.       </item>3 D4 _) f4 q- a& d( y7 w
  157.      </layout>
    5 E0 ^, c2 K4 S+ o' \* Y7 ^
  158.     </widget>
    - d' y" K' N* y1 z6 ^, Y
  159.    </item>
    : o5 T' Y6 E! n
  160.    <item>" G# a" k* Q* b  B1 r
  161.     <widget class="QGroupBox" name="groupBox_2">9 w, c' [2 p! |7 s. Z. B
  162.      <property name="title">6 G* R  |4 H3 S2 t
  163.       <string>文件发送</string>
    2 H0 W# B: j" J: [; N, Y
  164.      </property>2 x6 D7 ~8 k. @' M8 j3 ?( ?
  165.      <layout class="QVBoxLayout" name="verticalLayout">
    $ K. C0 c  m+ P
  166.       <item>
    , F8 V+ Y( \* W2 c' g2 m! n3 ~
  167.        <layout class="QHBoxLayout" name="horizontalLayout_2">
    / l# E! [* ~+ |; S7 e8 Q
  168.         <item>  M' `1 \, P* u. ]  F
  169.          <widget class="QLabel" name="label_3">
    6 y5 [6 ~* X& W! o( b3 h
  170.           <property name="text">: e  c1 a( |, d9 ]- e" ~/ _( H
  171.            <string>文件路径:</string># A, A; s0 X( I; o8 ^  O7 {7 {
  172.           </property>9 r1 _" s: r. q. Q
  173.          </widget>
    7 p8 G  T1 [6 D& C( R+ V+ ]( Y% J
  174.         </item>
    ) L1 r5 I* N- h- T2 m
  175.         <item>5 t3 C5 X3 G$ y9 _" j' x5 |
  176.          <widget class="QLineEdit" name="transmitPath">6 a6 t5 o4 K" d8 Y, i
  177.           <property name="readOnly">& @# f$ C7 _9 R' y
  178.            <bool>true</bool>( M8 a) t! f7 f, u0 `- x8 M( W
  179.           </property>
    , m$ `7 z/ F7 e2 d: }" S- G
  180.          </widget>" X2 S9 A4 I" v  m
  181.         </item>
    # e5 F& e( h% W# t* Y( T
  182.         <item>- d2 h& x5 d" F' \+ b, s
  183.          <widget class="QPushButton" name="transmitBrowse">
    - Q2 X. b4 \1 g
  184.           <property name="enabled">
    8 o) K) s9 b- F" i/ m+ }4 b
  185.            <bool>false</bool>
    - Y6 c/ J. m6 \
  186.           </property>
    % ], B& x1 l) W1 V$ ^' T% w* g8 e
  187.           <property name="text">6 t8 u& ?7 R+ q$ G
  188.            <string>浏览...</string>! D2 X3 ~, U; v/ m! A
  189.           </property>
    7 B" K* Z) v5 I8 h, o6 P2 y
  190.          </widget>3 j; a0 b3 n( C6 I/ x
  191.         </item>9 O8 B( A4 Q* U; ~0 L
  192.         <item>4 W4 d: ?" L; \* ^  e% ~% M
  193.          <widget class="QPushButton" name="transmitButton">; y: R* v; i/ L, p% k; u
  194.           <property name="enabled">
    ! f: P: {" o1 ]2 U9 z2 \
  195.            <bool>false</bool>& B  Z/ |! `5 Z, A& Z# L* D- S
  196.           </property>
    # `, J% H7 I- \& g3 T3 u
  197.           <property name="text">! L. R: @( h3 ]4 C, r
  198.            <string>发送</string>4 e% e$ U8 E% T2 s& W. \
  199.           </property>2 Z1 Z( A0 L; f4 Z$ X) P
  200.          </widget>
    # P4 m& Y, `! R/ ^( a  a7 ^3 x
  201.         </item>& E3 D+ n! a3 M$ k* `
  202.        </layout>( S+ r. f: S$ e4 b; j9 F
  203.       </item>
    * P2 i% h) l# q( f" K6 [6 z6 C" x
  204.       <item>4 [8 |; X( b% ~
  205.        <layout class="QHBoxLayout" name="horizontalLayout_3">
    ) W, c% C" D3 W) x5 }6 T; @
  206.         <item>( ]0 k, D, ]: ~( }
  207.          <widget class="QLabel" name="label_5">
    / S' J  A+ |2 Y/ m  H2 S0 }- x
  208.           <property name="text">3 J4 T) X: a1 A0 H9 m7 s
  209.            <string>传输进度:</string>- _9 ^! c  F6 {8 B! ?0 K
  210.           </property>' q3 ?0 Y* _( @
  211.          </widget>
    ; p$ Z* O7 M$ b* D+ E
  212.         </item>5 J& K* }6 w9 h2 n" O
  213.         <item>
    / K# o8 ~. Q# u. i
  214.          <widget class="QProgressBar" name="transmitProgress">
    # I  o% K5 L  M1 g* e2 L
  215.           <property name="value">$ ~7 u' D0 _0 |
  216.            <number>0</number>1 o. m1 e* x6 t4 o% N" e
  217.           </property>
    3 i  t' j& f: u4 x- e' ^% L: o& u
  218.          </widget>
    5 Y3 Y$ H% d( D& \. `$ x
  219.         </item>! r  U8 e5 G; |/ y7 H4 k
  220.        </layout>% h- F9 V2 Y) }% l4 E4 j
  221.       </item>* Y! V% d  ]5 V
  222.      </layout>: G, _8 i) d) M4 Y. R" g+ ^2 e
  223.     </widget>1 K$ E  t6 b! w7 |) m) a
  224.    </item>! _, F% N9 l* {2 U
  225.    <item>, E7 _- s6 v" S% c+ a
  226.     <widget class="QGroupBox" name="groupBox_3">% v; e# P+ j; e- f2 O7 B1 M  P5 }
  227.      <property name="title">
    ; F9 k6 w5 V8 |; @! x$ _
  228.       <string>文件接收</string>
    / z- h( F$ i' ~7 k  O
  229.      </property>5 {( J" w9 \: {& I
  230.      <layout class="QVBoxLayout" name="verticalLayout_2">
    ! ]; V+ }& W- F5 G* L- ~% T: h+ M
  231.       <item>) r1 x+ W* B& T; Q2 R2 [- M
  232.        <layout class="QHBoxLayout" name="horizontalLayout_4">- D8 P- A+ t! ?( w$ |+ _2 P
  233.         <item>0 }, C- c) d/ a- n/ Z7 U' i) s
  234.          <widget class="QLabel" name="label_4">
    5 Q7 `7 p5 {( e3 u' U
  235.           <property name="text">
    : U( K8 ?+ M5 n' n( e
  236.            <string>文件路径:</string>
    . y! R3 z( A/ x' G% K; V( y
  237.           </property>
    / Q: Z. A2 a" X; o1 V  _
  238.          </widget>
    9 v1 c. H9 l, u1 b+ k9 S
  239.         </item>
    5 {. ^& `# j8 O/ d3 U8 J2 ~
  240.         <item>- [& o  x& Y8 r: F$ V
  241.          <widget class="QLineEdit" name="receivePath">
    . T; d: R0 u& c! H" t7 E) e
  242.           <property name="readOnly">9 ]# z/ B9 i; t. {
  243.            <bool>true</bool>3 E( q6 W2 C' Y- g
  244.           </property>
    9 |* z. Y3 z! A; |: M
  245.          </widget>
    6 z' ~5 A  m; g8 K8 ]
  246.         </item>
    + {; B: Z' p+ j  T( g) G" G8 ]
  247.         <item>6 f4 [; S9 D- s: r5 o5 w! ^7 s1 E
  248.          <widget class="QPushButton" name="receiveBrowse">
    # Z4 x- n" X/ |) s! B
  249.           <property name="enabled">
    , ^# y. O1 e; }7 c, p
  250.            <bool>false</bool>
    " @0 {7 ]( x" r
  251.           </property>
    ; J' q2 {" \2 {/ \' H# Y/ y
  252.           <property name="text">
    1 U- k& }# F0 `3 y! L: ~
  253.            <string>浏览...</string>
    6 g8 m9 i; r  p( h- z' T6 v
  254.           </property>
    ' f$ G7 Q8 H2 J9 \( s
  255.          </widget>
    : y+ d% Z, D/ k* P! k
  256.         </item>& q$ F+ d, ?! Q6 B9 V; @" o* n
  257.         <item>4 H# l% q0 f6 Q8 x1 ~
  258.          <widget class="QPushButton" name="receiveButton">$ K( J; o3 A2 Y1 D+ q8 ?4 o
  259.           <property name="enabled">( @9 e& _4 e8 A, I
  260.            <bool>false</bool>
    & ?0 P7 ~7 }9 t) ^$ |; ^
  261.           </property>
    ( N# K3 |& J/ o" |+ X
  262.           <property name="text">
    2 M& w4 z' J7 q5 z5 ^. n
  263.            <string>接收</string>6 N/ ?! ]2 x6 X$ r& {& ?
  264.           </property>$ C) b! E9 A' w
  265.          </widget>1 e7 K+ G9 R9 N- u0 `+ I
  266.         </item>$ V$ n# d2 t8 l" y, u/ m3 g
  267.        </layout>
    , I/ @8 b5 q! ]0 G# l
  268.       </item>
    ( @) G  H/ p% C# n# @
  269.       <item>& ?1 h" ?6 z" D9 h: B7 j8 p
  270.        <layout class="QHBoxLayout" name="horizontalLayout_5">
    % t! p# r( A7 Q+ f$ E$ Y7 F
  271.         <item>5 X/ V% E; v3 s! ]/ v2 P: {
  272.          <widget class="QLabel" name="label_6">4 }0 S& `) v4 G: h0 |- u
  273.           <property name="text">2 b  T- K7 A0 ]2 K, v2 D
  274.            <string>传输进度:</string>
    % p- N. S/ k$ D
  275.           </property>& s8 A9 B0 p0 v/ C
  276.          </widget>6 [" E1 @% W2 b2 }, n3 w
  277.         </item>9 m* s: C" T/ w3 U$ F6 n' A4 l
  278.         <item>
    6 c9 L0 r/ J/ @  y# l( b0 L
  279.          <widget class="QProgressBar" name="receiveProgress">
    # I# [: ?. |2 a% l7 F/ h  T
  280.           <property name="value">
    # {; X8 m  z  a: p1 Q0 C
  281.            <number>0</number>
    1 E+ s. y7 c; V. c
  282.           </property>/ k" S5 @* B$ k
  283.          </widget>
    - X3 ^9 |6 k0 Q4 H6 [- T, g
  284.         </item>
    , @1 d, l8 u" |4 I4 ]; i# H
  285.        </layout>
    4 f/ q& {3 P+ z& q8 l# o2 v
  286.       </item>
    8 [9 A, U. j  N4 m( m7 i2 C
  287.      </layout>3 @+ ]8 q2 S! D: j5 X2 Z
  288.     </widget>
    3 n0 {4 }9 S8 O. m3 ]0 x/ ~
  289.    </item>& _' `# {: B5 E) c, s9 h7 o  Z6 ?
  290.   </layout>
    3 \7 i$ c8 j+ d" `+ O
  291. </widget>
    ' e; n, B& O; ^
  292. <layoutdefault spacing="6" margin="11"/># P( J7 [8 }# F  _- ^. @
  293. <resources/>/ ]' S$ C7 K' X
  294. <connections/>
      C7 Z  ?* T* |  P
  295. </ui>
    * T) d4 _% C9 u; e. h7 ]7 L
复制代码

; ]$ g6 Z! i8 X, @" K      widget.h文件
7 X; y0 P+ |/ \* Q( s
  1. #ifndef WIDGET_H
      \2 V8 d4 B' ^% I6 `
  2. #define WIDGET_H. y6 ^+ O: \* l& `' i0 a

  3. / [, q5 I6 l; {8 s( I
  4. #include <QWidget>* P% y( a% ~" S3 c, w4 h( M
  5. #include "YmodemFileTransmit.h"% i- Y/ i  J% `  U' Q5 c
  6. #include "YmodemFileReceive.h"
    5 W' ?  D1 Q/ l/ i! A0 h
  7. ( O. L; P( A# X  w4 P
  8. namespace Ui {* @7 Q( r! ~2 V% D; T
  9. class Widget;7 J3 t: g! D0 m! r+ R
  10. }; |! D4 B" \& q. M- z  c! }$ n7 Q

  11. 0 Q8 ?4 G  t. H( z5 K. Q* R
  12. class Widget : public QWidget- |* g9 a1 B; g- t( U1 A
  13. {/ z- t4 v9 ~4 |2 L6 v4 \
  14.     Q_OBJECT
    : f4 `: q& ?- p; @+ P
  15. , Q: S7 B3 ]( j' a: E" N
  16. public:8 A' n0 B1 O' m4 h: L. L5 \* O
  17.     explicit Widget(QWidget *parent = 0);& z! f9 Y  W8 ?
  18.     ~Widget();
    7 C3 t& G3 q( S4 g2 [
  19. & L8 f! {- O- Q$ D
  20. private slots:
    0 L& I! r$ i( z* d0 H( V- {
  21.     void on_comButton_clicked();
    & U. C5 k, t  f/ G' |) A1 G( |
  22.     void on_transmitBrowse_clicked();
    2 C: o3 N7 b! F* V) _5 r7 s
  23.     void on_receiveBrowse_clicked();
    : u, l! P1 S/ |3 M- i; [) q
  24.     void on_transmitButton_clicked();
    ; n" I, r- T$ ~* J8 `: ]9 X
  25.     void on_receiveButton_clicked();
    9 Q4 J4 p0 O' e' F8 d! p
  26.     void transmitProgress(int progress);
    , g* r+ J( L0 K
  27.     void receiveProgress(int progress);+ g/ C6 F# c, M8 Z% A
  28.     void transmitStatus(YmodemFileTransmit::Status status);* P4 H3 \: Z5 J- c  X3 F* y3 [
  29.     void receiveStatus(YmodemFileReceive::Status status);
    9 }- `6 B; Y" `, L
  30. 4 }; ^- q1 X8 T7 i# ^* F$ h4 t9 i
  31. private:" X8 ?1 |: A: X
  32.     Ui::Widget *ui;+ n+ }4 ?( O1 a3 A6 q2 [. q' ^
  33.     QSerialPort *serialPort;& I, e, k5 I7 R" Y6 X9 u
  34.     YmodemFileTransmit *ymodemFileTransmit;9 J& R$ T8 R- o! I* U7 u! u
  35.     YmodemFileReceive *ymodemFileReceive;
    " r' T% B6 M+ S1 ^
  36. * T. H5 ?- k4 E8 M% q3 |: G
  37.     bool transmitButtonStatus;. ?: _2 n! P; l0 X0 f, t
  38.     bool receiveButtonStatus;
    / R) ]9 k, g3 r8 N; Y- C
  39. };
      F8 E; m$ h$ t0 u

  40. 0 R( H! w" I! I4 M2 y$ u0 n
  41. #endif // WIDGET_H
    " u2 i1 n& l. T5 \" a) J( }
复制代码

1 I3 t+ d! o# B7 R( ]2 K, J* n      widget.cpp文件
4 ~" O" S/ p6 U0 h1 n) O0 M, {
  1. #include "widget.h"
    , d* R  T2 ~; [$ ]* X! t* \
  2. #include "ui_widget.h"
    2 R+ }" ~& B3 J7 q! x" K5 w
  3. #include <QMessageBox>7 _( H* ^9 j$ ]3 g
  4. #include <QFileDialog>. |' M8 c- A( f: p
  5. #include <QSerialPortInfo>
    2 a. v' r, L4 P1 l/ q
  6. $ v% r- Q5 n  H% R/ a
  7. Widget::Widget(QWidget *parent) :
    # c* c, A6 ]9 F: `) q9 \+ A' E
  8.     QWidget(parent),% m6 V5 i+ h" X
  9.     ui(new Ui::Widget),
    " O" ?" ?9 s* B4 {' K2 ?$ }
  10.     serialPort(new QSerialPort),
    . w: T- P% q( v/ i
  11.     ymodemFileTransmit(new YmodemFileTransmit),
    7 ?2 i7 K1 J/ x
  12.     ymodemFileReceive(new YmodemFileReceive)0 q( `7 T4 ^% G+ n# E
  13. {% \: j; c% c  g' f( e% C/ x
  14.     transmitButtonStatus = false;
    2 A) d8 ^% G& p* C. g
  15.     receiveButtonStatus  = false;5 c3 I7 z# X) ^* R2 E* q( s
  16. & v! F) o7 X, S
  17.     ui->setupUi(this);
    0 v2 v7 o/ \5 ]' d3 d
  18. 1 ?& C# F, \. K
  19.     QSerialPortInfo serialPortInfo;8 @& a  d% L2 t4 A% W, J$ Q: F( i0 S
  20. $ }! e5 O6 X; t! v. U+ n! G
  21.     foreach(serialPortInfo, QSerialPortInfo::availablePorts())
    , F% ^$ {5 a9 _  o* O  M8 D
  22.     {2 k$ K, W  G0 s( O4 D" A
  23.         ui->comPort->addItem(serialPortInfo.portName());
    0 ~5 P; A0 Z9 v9 Q- {, o& P
  24.     }$ Q5 \, Y. [) V$ Y) n; _0 o

  25. # ]9 G# z0 M: U$ R$ h/ s
  26.     serialPort->setPortName("COM1");/ ?: Q# O4 |+ e$ e4 @) n
  27.     serialPort->setBaudRate(115200);
    ) C; f$ M# j# y8 a0 S- U7 c8 _
  28.     serialPort->setDataBits(QSerialPort::Data8);1 h+ j$ ]" g' T) w
  29.     serialPort->setStopBits(QSerialPort::OneStop);
    1 m% D8 i, v& y4 S9 J3 ~, Q
  30.     serialPort->setParity(QSerialPort::NoParity);7 }9 M# f5 @# N# C% N( X" G
  31.     serialPort->setFlowControl(QSerialPort::NoFlowControl);3 T% n/ V% d* X4 F
  32. ) u+ c7 `% N( c# g% A# I% Y
  33.     connect(ymodemFileTransmit, SIGNAL(transmitProgress(int)), this, SLOT(transmitProgress(int)));+ O1 r, P6 r8 t  x$ _' L' n
  34.     connect(ymodemFileReceive, SIGNAL(receiveProgress(int)), this, SLOT(receiveProgress(int)));
    7 B6 s( u  B# k* B6 s' U2 Z

  35. 3 ^( k1 V% ?6 s
  36.    connect(ymodemFileTransmit, * A! g) @  G  |3 z
  37. SIGNAL(transmitStatus(YmodemFileTransmit::Status)), this,
    8 L: t& ]  @- I2 u
  38. SLOT(transmitStatus(YmodemFileTransmit::Status)));8 W  C3 i6 W9 T2 e" ?+ H) f
  39.     5 [0 z! P3 R  D/ R: j
  40. connect(ymodemFileReceive,
    ! p) r& X  L( X( s# ]/ g( Y
  41. SIGNAL(receiveStatus(YmodemFileReceive::Status)), this, ( @* M: e/ S7 H1 y+ ?
  42. SLOT(receiveStatus(YmodemFileReceive::Status)));
      C- o5 ], b/ t- I5 O1 C
  43. }
    / Q; z7 c1 i( W0 ^& r. H) }, q
  44. " o" I/ |8 `9 D; H
  45. Widget::~Widget()
    * M% I/ p+ O$ Z
  46. {: ^/ c( W; H# P- t" E
  47.     delete ui;
    ! g# t1 a8 }# ?" M$ q% T0 v7 B! l* }# s$ y
  48.     delete serialPort;' {# C  o7 F) o0 I( A6 o5 ~! ?- ~0 g
  49.     delete ymodemFileTransmit;/ O9 q+ o5 ]  @9 f* d2 Z* B
  50.     delete ymodemFileReceive;
    * y1 i4 M4 M1 Q( A: c: |
  51. }9 D- z& x/ h% X8 A4 r1 x
  52. 0 \1 R1 I0 C' q6 z
  53. void Widget::on_comButton_clicked()9 I% ]% a" D6 N: k( Z
  54. {
    ; n$ H6 ^6 l# j8 K3 c
  55.     static bool button_status = false;: n  X7 k& z0 ^- d9 [6 f
  56. $ ~9 Q  A6 Z% V7 [* u! V
  57.     if(button_status == false)! b0 ^( i, t" y* t! ^, T. b
  58.     {
    * W6 S( R3 q  B" u
  59.         serialPort->setPortName(ui->comPort->currentText());+ K" t# z9 Q& J' S7 m2 q
  60.         serialPort->setBaudRate(ui->comBaudRate->currentText().toInt());
    4 b% j) o6 j, v, k& h# b! m( I
  61. , b- F; a, E* L
  62.         if(serialPort->open(QSerialPort::ReadWrite) == true)
    0 I2 {5 u. d# c0 `8 {
  63.         {( N# }$ N" b8 X3 F7 i3 `$ _- s0 V; [; ^
  64.             button_status = true;* B6 @8 n# f, f( K9 b( Z* B
  65. ' \! x4 _* b6 D2 y1 l, Z
  66.             ui->comPort->setDisabled(true);& Z+ y# A9 o7 \  F4 U; H$ T# @
  67.             ui->comBaudRate->setDisabled(true);
    ) w3 t3 o. t# w/ M: c; ^, n2 P2 `5 a6 K
  68.             ui->comButton->setText(u8"关闭串口");" V+ r6 P1 C8 m- Q- G  ]
  69. 9 w. z2 \  V+ T' h+ F; ^- g) a
  70.             ui->transmitBrowse->setEnabled(true);
    - W8 K+ V6 @3 T& H2 |
  71.             ui->receiveBrowse->setEnabled(true);
    8 I/ E& y1 U: d$ @2 g3 {" h

  72. , j9 i' Y3 G+ o4 f# M4 {
  73.             if(ui->transmitPath->text().isEmpty() != true)
    ' P! |4 S/ D: h2 `
  74.             {! E/ n& O* }! y- e/ b
  75.                 ui->transmitButton->setEnabled(true);& R' ]8 n5 C) x# @, z5 y, X
  76.             }5 u& P* _+ \9 M+ m% k9 \

  77. " b7 y* H, I5 ~
  78.             if(ui->receivePath->text().isEmpty() != true)+ O8 p; T! Q! z1 X+ _
  79.             {: [4 j% ~4 R- p. w
  80.                 ui->receiveButton->setEnabled(true);
    ( E$ h- M9 V6 t) c; V
  81.             }' w+ i, Y  ~: ~$ O1 O! ?: i
  82.         }5 k/ j& ?# `* o/ |
  83.         else, \; M. L' ^$ J: r0 o! g) ~
  84.         {$ Q$ u- F3 R* ~& O8 d, s4 ]
  85.             QMessageBox::warning(this, u8"串口打开失败", u8"请检查串口是否已被占用!", u8"关闭");
    5 @( m( x  u! W- B8 e$ ~
  86.         }
    4 W' Z. T& w6 c
  87.     }
    / f, W$ [2 z* ]
  88.     else  u- c( n! k- Q# M/ @+ d
  89.     {' Q# r1 F! p" w, {( v, A
  90.         button_status = false;7 Y! ~6 _' ?3 V6 c9 n% |
  91. / J1 N. e! G- G6 x+ J! j
  92.         serialPort->close();/ {" @% ^2 {* ]
  93. 6 p9 e" y0 D  a
  94.         ui->comPort->setEnabled(true);
    4 @) D3 c5 \& t# P
  95.         ui->comBaudRate->setEnabled(true);5 B7 i0 z2 ^4 y3 Z/ ?
  96.         ui->comButton->setText(u8"打开串口");
    # o$ Z& m, W: \, }$ \
  97. ; p2 \1 ?* }. V) Y9 W: ^
  98.         ui->transmitBrowse->setDisabled(true);; P0 m7 k' s7 H' F$ H4 V* s
  99.         ui->transmitButton->setDisabled(true);
    / D- B0 s  q" y6 K* n4 @- O

  100. & w4 s; \/ @+ H+ n% T& h" K- c! ?
  101.         ui->receiveBrowse->setDisabled(true);
    $ J# M; T2 p" P: e
  102.         ui->receiveButton->setDisabled(true);. O. S8 E* P6 \/ y+ {
  103.     }
    ) m. ~- r9 M$ @/ {. T
  104. }* O* S/ e& r5 I& c5 X9 }
  105. ) M' U8 b; |& m
  106. void Widget::on_transmitBrowse_clicked()
    " o! d. Z/ h$ {- E6 B
  107. {! P# @9 D% G' z9 e- Z1 g8 \  e
  108.     ui->transmitPath->setText(QFileDialog::getOpenFileName(this, u8"打开文件", ".", u8"任意文件 (*.*)"));& h3 }. e9 H% P( H
  109. % E( J" a9 |& a7 c  m! h
  110.     if(ui->transmitPath->text().isEmpty() != true)2 {' o" C0 G: O0 v: g
  111.     {4 e2 H! ~7 m4 i0 ]( M( j  G2 B  h% A
  112.         ui->transmitButton->setEnabled(true);4 V" M  Z, L  e6 t2 }
  113.     }! a4 t& Q' \8 Z3 I$ ~3 M. v7 t
  114.     else
    9 A- Z" I6 }9 ?- M# l* Y
  115.     {( J, R! M6 r6 y
  116.         ui->transmitButton->setDisabled(true);
    " `; W; ~! q! h; Z
  117.     }
    - u5 G+ c: A) ^: K; \, P
  118. }  s0 G& `; X4 g

  119. 1 y% t3 |+ T7 `# A3 H
  120. void Widget::on_receiveBrowse_clicked()( n1 W' E- o7 S" C3 M
  121. {- g9 B# r* z; \( T, ~6 [( D/ T
  122.     ui->receivePath->setText(QFileDialog::getExistingDirectory(this, u8"选择目录", ".", QFileDialog::ShowDirsOnly));
    9 }( Y( \8 ^3 s# ]+ X

  123. * Y. u* }, ^' U$ B1 X- f
  124.     if(ui->receivePath->text().isEmpty() != true)
    ) L4 A6 X% g7 T' R1 s8 U' Q
  125.     {. q) V8 L- I% ]8 O
  126.         ui->receiveButton->setEnabled(true);
    3 s; L$ |" T' l7 h, N1 J, J. R! d6 L
  127.     }& {2 Q+ E9 b% B. k" X
  128.     else
    ) }8 E' }) u+ y6 l7 w
  129.     {
    - B3 _& k4 [& Q; i1 R0 F1 m
  130.         ui->receiveButton->setDisabled(true);
    " ?/ c8 }% W- X/ a7 R- d, q9 L
  131.     }
    6 ~9 {. D* q4 `8 o
  132. }+ W+ Z5 C  d4 ]8 y+ n
  133. & X$ w4 Y) d0 I
  134. void Widget::on_transmitButton_clicked()
    ; {# q1 k# c  D
  135. {
    ( D0 x/ L$ \; o1 U4 p# P* a
  136.     if(transmitButtonStatus == false)$ s. T) a7 ?6 f9 i
  137.     {
    1 l/ s+ U! d5 h! H- K' n
  138.         serialPort->close();
    6 l+ {: |! s8 K) I8 g' `6 P) N& K  x

  139. ! z$ @: d3 e1 V& K$ a
  140.         ymodemFileTransmit->setFileName(ui->transmitPath->text());
    ' J  O* l, Z1 |% Y( q
  141.         ymodemFileTransmit->setPortName(ui->comPort->currentText());
    $ ~+ y; d1 Y) V) |! t/ U: Q) Q
  142.         ymodemFileTransmit->setPortBaudRate(ui->comBaudRate->currentText().toInt());
    3 D9 u/ `6 b6 ?% V7 x2 a

  143. 0 S4 d% j1 S' s" v
  144.         if(ymodemFileTransmit->startTransmit() == true); v% S: R% s2 k
  145.         {
    + Y1 T) Y' L- _! j- H/ [6 k
  146.             transmitButtonStatus = true;1 Q3 p5 P1 J) J8 q1 X0 U5 L; p

  147. * M" H* G* @, B7 h! }
  148.             ui->comButton->setDisabled(true);. j0 R8 K) s6 d# N
  149. 4 V) Q! C& N/ L# ~
  150.             ui->receiveBrowse->setDisabled(true);' e6 z( q' K9 u" u0 D6 S
  151.             ui->receiveButton->setDisabled(true);! n) n) y2 m( K$ [# }( N& h

  152. $ Y9 k/ K. z5 o8 Q- X& S; |
  153.             ui->transmitBrowse->setDisabled(true);9 K% R8 {7 S* u9 }
  154.             ui->transmitButton->setText(u8"取消");
    3 A0 b. Y/ {4 @- S' A6 @
  155.             ui->transmitProgress->setValue(0);3 z* V" ^; B- b5 F
  156.         }" D& T. l+ x- v1 ^2 Q9 \% F
  157.         else
    5 w* K" u' m" ]8 c, q- r* B* {& j
  158.         {
    9 {  N2 e9 O8 B6 }$ _' t
  159.             QMessageBox::warning(this, u8"失败", u8"文件发送失败!", u8"关闭");* Z* Z$ D8 s3 c  q5 z' X5 M' U( N# M
  160.         }0 @. f2 V- E1 B2 t% h$ {
  161.     }
    8 H0 Q6 b3 T" x& E) K
  162.     else8 @" s: {' h1 t% Q' {
  163.     {0 o0 z8 d/ \! {9 d- q* O' Y9 b7 G
  164.         ymodemFileTransmit->stopTransmit();+ ]) R) e5 @% R# l1 ~
  165.     }
    ( A7 ~2 k% X$ U: N9 J% |/ z
  166. }' n# I, S: r: n/ E7 V0 U
  167. ! p+ b4 o  H) ?: B  p) ^
  168. void Widget::on_receiveButton_clicked()
    1 ~/ t8 u. A/ U
  169. {7 ~6 e3 O  Y! G8 R. m/ L0 `, q
  170.     if(receiveButtonStatus == false)
    8 H9 ]* Q! N. o
  171.     {' w& T5 V# @7 Q/ K
  172.         serialPort->close();
    ; P3 }0 W2 \& p
  173. 1 P2 A% I2 K. q. K" ~* |7 k
  174.         ymodemFileReceive->setFilePath(ui->receivePath->text());
    - |( i, ?% L+ E4 u3 c/ v7 i7 [
  175.         ymodemFileReceive->setPortName(ui->comPort->currentText());
    $ o9 M1 ?* o" L) q) v
  176.         ymodemFileReceive->setPortBaudRate(ui->comBaudRate->currentText().toInt());
    ) f5 o# i3 Q% f& N0 {8 A( b. H

  177. $ ^; H6 j- A! W9 |
  178.         if(ymodemFileReceive->startReceive() == true)
    3 m( G0 _9 y. n/ ]8 Q
  179.         {
    % d2 v5 y  k3 I; R& A  \
  180.             receiveButtonStatus = true;/ k7 q( M9 r9 u: I6 \2 r, r" m
  181. + H1 [- \- z& j
  182.             ui->comButton->setDisabled(true);
    * w% K3 }: o  k  u( O% X: b+ e5 z
  183. - p6 ^- g0 M$ M0 Q3 D
  184.             ui->transmitBrowse->setDisabled(true);
    . K' C  f' N/ J
  185.             ui->transmitButton->setDisabled(true);; H  v) P1 @0 |& G* z7 s

  186. 6 e/ m% d4 |8 h+ C. ~
  187.             ui->receiveBrowse->setDisabled(true);! b) R8 ]' S6 ?( x
  188.             ui->receiveButton->setText(u8"取消");( A% d  v7 h% y' x
  189.             ui->receiveProgress->setValue(0);' f" a( G% h/ [: L; ]& L) H/ W7 ?
  190.         }3 n0 h3 L' ^  N% O" m; R! P' D
  191.         else/ g  G$ R; S7 n1 L% v2 D6 o
  192.         {
    2 X& i, x/ a' d/ Y# d
  193.             QMessageBox::warning(this, u8"失败", u8"文件接收失败!", u8"关闭");' T$ G7 K* M  \8 G7 y* f7 k
  194.         }
    " |6 k, h/ L& |& C/ |2 x0 T
  195.     }
    / o9 _; i  U' G/ S
  196.     else% l6 C9 V; n. i9 q% |
  197.     {
    ) ^& B- M% U$ |/ p" R% k% Z% n; c* a" ^
  198.         ymodemFileReceive->stopReceive();& J+ `( e/ o  G7 B% S
  199.     }
    6 V/ [0 U5 L3 j- e: a0 v) _4 M
  200. }
    8 T% K4 h  A5 ^. ?- ?9 w, {, ]

  201. 6 }( D1 ]+ K8 H/ C1 F
  202. void Widget::transmitProgress(int progress)# K) J7 @+ n+ d. j( T/ R1 a
  203. {
    9 b6 H. `. K% |5 g( s
  204.     ui->transmitProgress->setValue(progress);
    ( U4 u- G9 {1 d3 w5 k
  205. }( T% [& Z. d& M# B( z% W( G
  206. ( g+ ?. N- P1 e  P$ p% |% E
  207. void Widget::receiveProgress(int progress)
    ; Z( X3 y# l# b; M# g3 v
  208. {
    . i# h) {8 v9 Q6 p% K" [2 N
  209.     ui->receiveProgress->setValue(progress);* M: Y8 e2 z) ]- i
  210. }
    % e1 \* A8 E* y7 K0 [" e

  211. 4 A% F9 u7 [# x# X
  212. void Widget::transmitStatus(Ymodem::Status status)
    , i1 l: j( i* H9 {- w' z
  213. {
    ' _" |6 V- F3 T3 Z! A
  214.     switch(status)
    3 j! N3 ]1 a- _% t9 _
  215.     {7 E( d( q' J9 R/ ?6 ~# S) Z% z
  216.         case YmodemFileTransmit::StatusEstablish:
    5 J! A" Y, A4 z* ~& H4 U
  217.         {
    0 f( z( O  I8 m9 A* V6 Z
  218.             break;
    , o7 ^& y+ E$ U) b- E
  219.         }4 v; Q' `9 T5 p. V2 I; [
  220. & n- ?% I$ [- E% K5 Y) `: C
  221.         case YmodemFileTransmit::StatusTransmit:. i0 B! q, W# _0 w8 Z
  222.         {! q; R% \9 A3 G4 z; c# E
  223.             break;
    " ^$ ~1 J9 }% `0 O5 |- |
  224.         }, c% v# w0 ?+ }) ?3 ~' C/ n

  225. , g# S6 a% w2 O0 n
  226.         case YmodemFileTransmit::StatusFinish:* V" v3 }  S5 N* b$ O( F' \
  227.         {  a" ^% y2 H2 R* r" X6 {1 b6 M0 i
  228.             transmitButtonStatus = false;, _& t: n, w; n9 i- d
  229. . M) n& Y# p6 d4 h/ I" L
  230.             ui->comButton->setEnabled(true);
    4 f! y' s0 x4 [# `+ f

  231. * p( b9 x* n' a) J0 v/ r( g
  232.             ui->receiveBrowse->setEnabled(true);: }: h" y9 e& [( k
  233. ; Y2 G6 J8 R  U2 |( M0 h% K$ O
  234.             if(ui->receivePath->text().isEmpty() != true)
    1 s; M3 F8 \* k) o
  235.             {
    ! E2 ~( h* B3 m5 P) k: V$ B
  236.                 ui->receiveButton->setEnabled(true);
    , _) n9 W; ]5 |9 O% Q7 _
  237.             }4 P! u/ k# {+ r! m
  238. ! i1 }, k5 J6 U% ~
  239.             ui->transmitBrowse->setEnabled(true);
    5 e! m" z* `' [5 f; r  A
  240.             ui->transmitButton->setText(u8"发送");' r- H1 X- @0 S# F& D* t
  241. " D6 z! X+ U7 o+ K: p: D$ ^
  242.             QMessageBox::warning(this, u8"成功", u8"文件发送成功!", u8"关闭");
    & M. N( b2 g- u$ r

  243. " f* q# ]3 ~$ o& w, j
  244.             break;
    9 _5 W: g/ V- G5 P; O8 O
  245.         }
    4 W  T8 t. r: N- k7 @
  246. / r$ ]0 D$ j) M4 `- w
  247.         case YmodemFileTransmit::StatusAbort:! ?4 C( y5 d) L  n
  248.         {
    * b* {( j. B4 P# q+ m; n
  249.             transmitButtonStatus = false;
    , T4 y7 I0 W# q! Y( F6 k

  250.   [# j% H% J; O$ p4 U- o
  251.             ui->comButton->setEnabled(true);' T2 v2 V( z# u  U: p
  252. ! s2 V' m  [, ^+ q! f
  253.             ui->receiveBrowse->setEnabled(true);
    & K2 @+ \8 A$ A4 Z
  254. # L. i: A( v' g
  255.             if(ui->receivePath->text().isEmpty() != true)
    ! O" s5 ~; u- Z
  256.             {
    5 c8 i# ~$ q7 h" U4 n
  257.                 ui->receiveButton->setEnabled(true);
    / _6 D; L. J0 k% o) `
  258.             }
      b6 M) Q% H3 s: }( j/ P) m0 [
  259. . j* z, U; D' Z. B% ^0 J
  260.             ui->transmitBrowse->setEnabled(true);
    6 U7 v% Y/ ?  H! J0 L% S0 }
  261.             ui->transmitButton->setText(u8"发送");
    2 j, m! y$ Q0 L5 T9 h* F
  262. % c2 ^8 _6 c8 n- d& X
  263.             QMessageBox::warning(this, u8"失败", u8"文件发送失败!", u8"关闭");1 b( S3 ^3 E* M/ m) c1 D. e. r
  264. 8 c5 I/ V# ~' P# l' l
  265.             break;
    + h0 C( z3 q; L* O2 F. @1 ]
  266.         }% R- {- B+ m; r) {5 \' x2 K% }
  267. 7 r, Y9 o7 _; I3 W9 T2 g
  268.         case YmodemFileTransmit::StatusTimeout:/ ]! J1 N( |5 D' ^; }; [
  269.         {. Q3 j0 K+ N7 @! X0 V
  270.             transmitButtonStatus = false;
    ! t0 @8 w9 n' J

  271. + y: V( k+ N; n
  272.             ui->comButton->setEnabled(true);
    # s  D' c& r5 `, m) J+ G* Y; F

  273. 3 h- f2 }: {! |
  274.             ui->receiveBrowse->setEnabled(true);
    ) R* a+ @0 A4 `+ ^2 x

  275. * V8 {. B! H8 r" q- a9 B
  276.             if(ui->receivePath->text().isEmpty() != true), i! x" z: w6 k3 U, _
  277.             {
    . P, H! s1 r! s9 p
  278.                 ui->receiveButton->setEnabled(true);9 |0 V+ Z) \' g# G4 u: K3 J
  279.             }
    * h, t3 u% D3 ]0 v
  280. % E) l. V# L$ M4 N# b
  281.             ui->transmitBrowse->setEnabled(true);2 S: Z- M; L/ s) z
  282.             ui->transmitButton->setText(u8"发送");( a  i& u1 I/ }, G9 H$ C" M
  283. 3 Y* R' P- {1 }0 _, |$ v# k8 h& n
  284.             QMessageBox::warning(this, u8"失败", u8"文件发送失败!", u8"关闭");
    % U4 I8 M$ P; i; l# g& \9 ~: O
  285. # y% S  }% M0 |$ R
  286.             break;6 V% \7 c  V6 H
  287.         }
    & B/ w2 B9 E/ i* e

  288. # |3 }. |5 p) _" c
  289.         default:( V/ T4 H% T1 C# d, D1 {3 Y4 z/ `" b
  290.         {  x% q  @& V2 O( `/ k/ q
  291.             transmitButtonStatus = false;
    % S/ N! t8 F  M" Y8 n, h
  292. : B( ?3 C) `% e- J  Z; s/ j
  293.             ui->comButton->setEnabled(true);7 F# Q% a" ^, g1 P$ E: Q0 N. Z% ]
  294. * ^8 [, R2 j0 g8 S# p
  295.             ui->receiveBrowse->setEnabled(true);6 S8 O7 [9 V: m" b( F
  296. . p$ ?5 i* _  `3 x4 p
  297.             if(ui->receivePath->text().isEmpty() != true)8 ]. U3 y% T; b, b" {9 u
  298.             {' t" }# I9 Q( b0 ^* l$ b
  299.                 ui->receiveButton->setEnabled(true);
    % F) W( R0 u7 H- _/ M6 `
  300.             }
    " m, T  R5 Z* G  p4 {& Z7 d

  301. 3 u2 |0 S+ \1 _% t
  302.             ui->transmitBrowse->setEnabled(true);
    , m7 X7 g) a6 z  T  c
  303.             ui->transmitButton->setText(u8"发送");- V3 b, c0 n$ w& }9 t' I
  304. 8 ?4 R+ g" @3 L) @& U4 g0 m( m/ Z
  305.             QMessageBox::warning(this, u8"失败", u8"文件发送失败!", u8"关闭");
    . A3 B2 F" }& \8 {/ _
  306.         }
    # E; I/ v2 }  g  t+ Y6 t
  307.     }6 X7 r& ~- [2 u
  308. }+ @, c8 U1 Y& q! J! N

  309. # m7 b: D/ Y4 Q; Z3 t4 Q3 V
  310. void Widget::receiveStatus(YmodemFileReceive::Status status)
      |' I/ `# @! ?* S
  311. {
    ( u4 z/ U( s4 _/ w/ d
  312.     switch(status)7 U: |! d: G. ]4 k( ?
  313.     {
    + U& l% e& N$ j8 D% ?4 E8 _  l/ d
  314.         case YmodemFileReceive::StatusEstablish:4 H8 A8 R- i* C- @4 ]) i
  315.         {( ^0 ~3 e  h$ J# S1 x. y
  316.             break;5 l) t2 L% m/ O5 N* F
  317.         }6 C4 u9 X/ t+ ]: l

  318. 8 z; o# O$ \" Z6 z  z  S
  319.         case YmodemFileReceive::StatusTransmit:
    ! e8 _( ^  }" d' O5 L3 j$ F
  320.         {
    & I& g2 {( ]5 ]9 k1 z3 D5 p* T
  321.             break;
    ( p* S! Q1 }6 b
  322.         }
    " ~0 h" V; U, @, @7 B
  323. 6 L5 y1 B" v5 w( Z2 P5 p  _! I
  324.         case YmodemFileReceive::StatusFinish:
    7 Z# U% N; g1 p; Z- Z  ]+ h
  325.         {
    ; Y, ~6 y4 a2 ~+ H$ b8 s( i
  326.             receiveButtonStatus = false;
    ( l- r5 F6 Y" w( p" |& ^  F
  327. 0 X( `' c+ C' k$ l/ C$ p4 g
  328.             ui->comButton->setEnabled(true);1 ?3 F8 f9 |' j- T  s
  329. ' v$ B9 B7 f0 _2 G( S- _
  330.             ui->transmitBrowse->setEnabled(true);$ w: g2 c7 U  o4 N( a/ v

  331. . x9 m' b3 d8 e; G
  332.             if(ui->transmitPath->text().isEmpty() != true)
    4 Q* R* L) V0 D. z" U8 T6 E
  333.             {$ k- v- U+ E3 A% y/ Z
  334.                 ui->transmitButton->setEnabled(true);
      V. M: C) Y% s! z6 y4 C
  335.             }. F9 H( \( A7 h* C/ C+ w
  336. & a( {6 e4 u$ @! [7 m
  337.             ui->receiveBrowse->setEnabled(true);
    ! _3 C; _% `$ \# j' c6 c8 {- v
  338.             ui->receiveButton->setText(u8"接收");6 s- V  ?4 C. Z: J
  339. ( |. G+ \0 g( z8 [$ V% |
  340.             QMessageBox::warning(this, u8"成功", u8"文件接收成功!", u8"关闭");
    9 T# B% b5 x! \

  341. # f! ^$ u% T) x
  342.             break;
    5 u' W* N( Y% r2 q
  343.         }
    , p; A# i% h* m

  344. ' @$ g) J9 P2 g3 K0 s: b% R
  345.         case YmodemFileReceive::StatusAbort:9 n" u. O% V2 t. a( O* u
  346.         {$ ~. `; X$ K- S6 m* _
  347.             receiveButtonStatus = false;' m& m9 V( l! n7 }
  348. 9 q& Q& |0 ]) P2 V% |
  349.             ui->comButton->setEnabled(true);* q) y8 `3 l1 P' ]

  350. ( {- P0 T9 E6 O; u6 A
  351.             ui->transmitBrowse->setEnabled(true);
    # p& z7 ]9 t* J( E& u9 l

  352.   ~4 ~- P$ P. b3 y
  353.             if(ui->transmitPath->text().isEmpty() != true)
    0 \3 g/ K( B2 k/ V7 f8 S
  354.             {
    " |' l1 C* V, y9 ^( [9 k- [. p
  355.                 ui->transmitButton->setEnabled(true);
    ! b, l. L2 U5 G. Q4 e) Z0 h( B
  356.             }$ ?1 h0 z  e( n/ N) D; P

  357. ! c8 L6 t! ]& S0 R1 M' a# f! K% L
  358.             ui->receiveBrowse->setEnabled(true);- |* V* P9 U/ R2 R! g
  359.             ui->receiveButton->setText(u8"接收");
    ! a( S" V8 \& Y0 f

  360. # c3 U( s1 `- }
  361.             QMessageBox::warning(this, u8"失败", u8"文件接收失败!", u8"关闭");
    ! v0 e" f2 o% v2 T
  362. ( K5 U9 o# {5 e4 a4 i2 v
  363.             break;
    $ l+ y8 `8 V; _
  364.         }3 y# a- R9 u/ P9 j

  365. : d; b7 G  [# j$ Q% b1 S
  366.         case YmodemFileReceive::StatusTimeout:4 |4 P# X/ C. o* d+ N9 v& [3 ]
  367.         {
    $ F0 L8 h3 [. G; v$ F. Q& r6 z
  368.             receiveButtonStatus = false;9 _& \' L0 }( I; }* g' n! T
  369. # e$ U' b+ Z+ t
  370.             ui->comButton->setEnabled(true);; l& b, W- a# f
  371. 6 _# w# N& b% ]3 B4 ~  y
  372.             ui->transmitBrowse->setEnabled(true);
    4 ]3 j) T5 A/ v* A- u- L. s

  373. . T: ]6 w" Z5 N+ ?) ^* R& J
  374.             if(ui->transmitPath->text().isEmpty() != true)
    - d! [' ?& ]" E/ _; Z9 w4 i9 m
  375.             {5 S% S! k! r3 V% N' G) N: y0 ]5 I" I
  376.                 ui->transmitButton->setEnabled(true);# r* `! `* A3 j
  377.             }3 Q5 o$ z8 ]6 y3 a; k1 t3 f; g

  378. ' U- ]4 `# [3 g. D; u1 d% S7 s7 i% d" W% U
  379.             ui->receiveBrowse->setEnabled(true);
    , G; |# Y$ U8 y- z! \# T
  380.             ui->receiveButton->setText(u8"接收");
    + c9 g% F7 X1 E( O' d# y' E" J

  381. + |, a& @& F- D3 X6 z7 ~! G! a: Q
  382.             QMessageBox::warning(this, u8"失败", u8"文件接收失败!", u8"关闭");
    . [4 _" ~$ p( I5 Z2 d4 I2 m
  383. ' b! x, Z  j4 A  y
  384.             break;
    ! U9 z' Z- z. g% Z' h6 t
  385.         }
    2 s3 L& V; ?0 K/ t1 ]6 j7 I
  386. 3 }( s+ A2 z' _% [) D
  387.         default:! m6 J4 W$ F6 Z! B
  388.         {1 e6 Q0 ]+ q) @" |
  389.             receiveButtonStatus = false;& s/ g% n: w% I* Z8 e

  390. : P9 s1 m8 \& T, T! J
  391.             ui->comButton->setEnabled(true);
    7 z* ]& {6 \7 o9 Q) @
  392. ( G: z- A4 K& y- o
  393.             ui->transmitBrowse->setEnabled(true);
    6 |- C* L2 O- [" U8 f

  394. # @& f  A' \6 O2 U. Y/ a/ g( z
  395.             if(ui->transmitPath->text().isEmpty() != true)
    1 A( r+ Z* U" A
  396.             {
    ' m  d% N0 o) ]+ ^1 x  a' f
  397.                 ui->transmitButton->setEnabled(true);
    . v( Q8 @6 A$ h9 c4 c) g
  398.             }2 D1 Y! U" g2 `2 {( P2 W, U
  399. % R. i' r+ \, ]
  400.             ui->receiveBrowse->setEnabled(true);& N# r+ e2 v2 _( F2 a( P+ k
  401.             ui->receiveButton->setText(u8"接收");, V/ }/ s* D3 m# ~
  402. 7 U9 Y( o' ~1 d. }
  403.             QMessageBox::warning(this, u8"失败", u8"文件接收失败!", u8"关闭");
    $ o4 l# J& E" i# G3 [' S& B
  404.         }$ @) u% S: m; C; F5 D
  405.     }
    # w1 u' W) I$ |( P- C
  406. }
    8 m- e  c  d) O! H% Y
复制代码

6 [4 m7 a! y$ k2 D: j6 q& V; J3 ~4 B, e- B6 P* L1 y

- d4 @! Y: m' F2 |1 f: U5 T1 X' X3 E+ T5 d) _, `+ L) ^
. l. v. l  L9 S" G' Q
! q8 r4 n1 R; Z5 r9 U2 Z: K0 G, F
XinLiYF 回答时间:2018-3-6 22:32:40
      main.cpp文件
& d; Q" n# y$ J9 E8 h% Q
  1. #include "widget.h"' v2 i' v4 X0 p8 \) S8 E
  2. #include <QApplication>( V4 s/ I( }: ~7 {* Q
  3. " l7 m' `) e3 P+ `' f1 {% P7 Y
  4. int main(int argc, char *argv[])4 v  F5 E  p. h8 q" r
  5. {1 R+ `# O  ?6 n" T
  6.     QApplication a(argc, argv);5 _1 }1 P2 `4 U3 Q
  7.     Widget w;7 O8 l5 M* f# A  }, [
  8.     w.show();
    * N) k  K, ~7 V2 H2 W

  9. . Q7 t0 Y" W! h! Z% M  G/ X( e
  10.     return a.exec();
    3 |6 i. w4 l8 s, f1 U  H  }
  11. }$ s3 A' i$ y7 O2 ?
复制代码
$ o9 D  B3 q0 z; _! Q; i
      SerialPortYmodem.pro文件
2 u. M4 I1 i2 M6 c3 ^
  1. #-------------------------------------------------
    ; z+ e5 x% P3 v6 f% _
  2. #
    7 k7 k) d9 L: M8 s' Q* }" H0 F2 d
  3. # Project created by QtCreator 2018-01-20T23:00:46
    0 D/ H0 u; o! A; y
  4. #' T! m* I* ^- Z% Y3 K% X& N
  5. #-------------------------------------------------
    ' ]' b4 \+ W1 _2 O: m# D

  6. ) K+ D3 L( n5 \0 c  P2 o; {! E8 h
  7. QT       += core gui6 f$ w. T& g2 p) C: v! a
  8. QT       += serialport8 \1 V3 ?" L9 y& O8 I) G/ \

  9. 9 N* U( f9 s' l
  10. greaterThan(QT_MAJOR_VERSION, 4): QT += widgets! l' U. d3 E; Q4 @9 Y7 i7 S3 n9 {

  11. 7 U6 y9 M: L1 e" e  H5 h6 {. e7 L9 P& j
  12. TARGET = SerialPortYmodem  Q. \$ ^- D5 {
  13. TEMPLATE = app' \, v# }+ ^) k$ V) U; h# {: h# T* s

  14. 1 z, m- C0 V+ l) K2 A* D
  15. # The following define makes your compiler emit warnings if you use# D' `0 z- v$ }! G5 _0 J2 Q
  16. # any feature of Qt which as been marked as deprecated (the exact warnings* Y' e! \1 B9 _6 c5 H; O: r8 ?! R
  17. # depend on your compiler). Please consult the documentation of the
    - z% a$ H0 Y+ K3 C4 ~7 n2 u
  18. # deprecated API in order to know how to port your code away from it.: _# O6 l/ R% N
  19. DEFINES += QT_DEPRECATED_WARNINGS
    $ d2 g1 S6 N3 |) d
  20. 1 ]9 o2 t( f/ ]& i& B" ?; K
  21. # You can also make your code fail to compile if you use deprecated APIs.; V* |# n2 p# r% [. t5 Z
  22. # In order to do so, uncomment the following line.
    2 a- m' P$ i% Y* _; T
  23. # You can also select to disable deprecated APIs only up to a certain version of Qt.
    - }5 I% ~; @+ E4 t0 Y
  24. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0( D7 ]4 r" t# v& N1 B, @3 T* u3 w) Y

  25. 2 s7 U2 ^; E) K

  26. 5 B9 m' w8 T! S
  27. SOURCES += main.cpp\8 o+ A4 U# z5 u" {# F2 H+ h& ~1 r4 t8 p
  28.         widget.cpp \- p" G2 A, Q5 A; u! Q
  29.     YmodemFileReceive.cpp \. u2 W8 K+ s+ Z; \
  30.     Ymodem.cpp \. j( ]+ h. s: ^, Z+ Y3 G/ s6 \+ x& O
  31.     YmodemFileTransmit.cpp7 m% \; X0 ]; O9 f
  32.   F( p0 F  e* {" C/ o$ q6 i( C
  33. HEADERS  += widget.h \- f6 n! f1 Z: _- Q9 B# ^. P: U# m3 n' E
  34.     Ymodem.h \1 u2 o* _. U5 y- k! d) d. C( h
  35.     YmodemFileReceive.h \
    % N" e0 J/ E/ \3 S' S# G6 [, n( k
  36.     YmodemFileTransmit.h3 P' `3 C# I! B, S
  37. - O. r' w8 D) I' |' t- F3 u  _) e% b
  38. FORMS    += widget.ui" M# S9 \# h2 c* m% L  w
  39. 6 o+ Z; y# \) E- c" X
  40. RC_ICONS = SerialPortYmodem.ico
    5 G- y! C% w" g: o" q( M: n! ?
复制代码

$ s+ i: g$ o: p      SerialPortYmodem.ico文件# v5 S) D7 ^: g- M) ~
3 n& g: x) P8 |* k7 n- Z
3,运行效果
4 |1 u6 q; M: ]. e3 t
3 N2 W! Y( P1 A7 P

6 l) P& b  w7 D6 J2 G) M# \( k! u: O' P; v; u2 G( H) e! B

0 G2 u; h2 j0 o8 `9 A
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& |) `* b# G& Q7 Y/ E% |+ y
请教,单片机端如何处理呢?
% o* R6 g9 ~% i" p& A% J! T
可以移植到单片机上,文件的接收和发送都支持。
Kevin_G 回答时间:2018-12-26 09:46:05
收藏
huangchao09 回答时间:2019-3-24 20:37:59
多谢楼主共享

所属标签

相似分享

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