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

YMODEM协议串口文件传输

[复制链接]
XinLiYF 发布时间:2018-3-6 01:56
YMODEM协议串口文件传输
GitHub仓库:http://github.com/XinLiGitHub/SerialPortYmodem; F- P8 X7 J  D  _- z" ~
PS:博文不再更新,后续更新会在GitHub仓库进行。( j( G# |* F9 _+ e% j+ g

# R5 g7 E" e$ F0 W( A, X2 ^5 H2 [

% d2 A& Q, R; t9 E7 @/ z    串口通过YMODEM协议进行文件传输。程序中涉及到YMODEM协议知识,详细介绍见维基百科[YMODEM](http://en.wikipedia.org/wiki/YMODEM)。
& w, h( t$ X' c- D/ u
* ]' B9 y3 x# v: V1,开发环境% t* o$ R$ ]' K$ h( {1 `# |
      1,框架:Qt 5.7.1% ^5 ]( g  S( o. G  ]

0 R% t. e# d; k1 c! U  _      2,编译器:MSVC2015_64bit8 V6 l/ n. I# h" k) C" \. b
4 |' F  g; b9 e% @
      3,IDE:Qt Creator 4.2.0 社区版+ }  V' a3 t; L7 [8 T/ a( L0 ]' J
      4,操作系统:Windows 10 专业版
2 {5 A/ ^9 H: q( m
: T0 d2 }1 V& U3 r) \$ u: v0 ?- d) C2,程序源码
' n) s) \& u( D9 F  O6 @      Ymodem.h文件6 }* x& l4 e+ A1 q, A2 p. l+ O
  1. /**
    + B3 X6 u9 g+ g- h9 C
  2.   ******************************************************************************" K! Z' _  m+ n! [8 I1 t
  3.   * @file    Ymodem.h
    ! v4 y5 ~# E* V( i
  4.   * @author  XinLi. I7 u& o- P  {* v$ R8 X9 y. o* q. b% W
  5.   * @version v1.0
    ! |2 G  C: K% h  m* y1 _
  6.   * @date    21-January-2018+ Z  J) s. F1 T: r. p  l
  7.   * @brief   Header file for Ymodem.cpp module.
    . C' x- P4 a% H& l1 F) }0 x
  8.   ******************************************************************************
    * o8 v, v/ p- E
  9.   * @attention' ]  W  B6 {( l& |7 A7 n4 w6 Y
  10.   *. P' o' V* P' a  L+ a1 e, [7 o
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>
    ( H( s3 D. |& [" G; G5 T' N" s) w0 l' I1 |
  12.   *) A/ o1 x0 Z! S
  13.   * This program is free software: you can redistribute it and/or modify. s& N4 t5 K1 T1 _3 k
  14.   * it under the terms of the GNU General Public License as published by
    ) _3 i2 h' z6 J$ x
  15.   * the Free Software Foundation, either version 3 of the License, or4 g% U6 r5 ]( q  }
  16.   * (at your option) any later version.
    6 B1 k) V! |, r) d0 U
  17.   *
    # [9 K4 H6 L5 T. k$ O
  18.   * This program is distributed in the hope that it will be useful,: U$ x$ e' ?+ F/ o( a0 i
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    4 k. ~2 k- @1 e3 d2 V& E( m
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    : i) F( J7 X5 R% B7 E  p
  21.   * GNU General Public License for more details.: A6 J# ?. G" k5 M" ?
  22.   *
    # v) a) t/ i$ y# M  X. y5 p
  23.   * You should have received a copy of the GNU General Public License$ v' R5 v5 N% [2 Y- |' \8 {  X- K
  24.   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    5 i# [' Y" N. ^/ F6 b% J  o  }) ?1 c4 j$ e
  25.   *- z( Y' p2 \) q! F
  26.   ******************************************************************************
    2 W# X- z# C6 Y( @: q
  27.   */1 v4 N# \: n* d" |7 M$ t
  28. * D, b6 k, Q, E: o% X1 I
  29. #ifndef __YMODEM_H9 a+ c! A: {  @) s  P+ |& b0 [
  30. #define __YMODEM_H- T6 n. L; @$ g
  31. 2 s" M3 @$ d& a8 Q$ C; R- o! |
  32. /* Header includes -----------------------------------------------------------*/
    ( f1 u& U  g) f7 \( J
  33. #include <stdint.h>
    - R  b$ o+ z" M* R

  34. 9 O5 e' P! |) E& a2 b" f
  35. /* Macro definitions ---------------------------------------------------------*/) X, U# l7 E4 p& M
  36. #define YMODEM_PACKET_HEADER    (3)
    2 S9 A/ g) F$ D6 T
  37. #define YMODEM_PACKET_TRAILER   (2); r1 C7 F+ X0 ~! _
  38. #define YMODEM_PACKET_OVERHEAD  (YMODEM_PACKET_HEADER + YMODEM_PACKET_TRAILER)
    8 U+ G6 |) h8 G3 V
  39. #define YMODEM_PACKET_SIZE      (128)1 N- \& U' i  o2 O0 p2 i3 d
  40. #define YMODEM_PACKET_1K_SIZE   (1024)
    6 Q/ e, ]% m( K6 w9 V3 ^3 m

  41. , x2 B3 j( `6 ~! D, V8 Z
  42. #define YMODEM_CODE_CAN_NUMBER  (5)
    8 O( z5 i5 n% }; a" b
  43. ! f2 n' ^% o1 X' T- Z
  44. /* Type definitions ----------------------------------------------------------*/
    * t# \9 l( M- T! w2 ^
  45. class Ymodem
    $ _6 f2 F* j; e) U( v
  46. {
    - o& K) m8 q8 A% p8 S7 M- M
  47. public:
    " s$ `" N+ k2 C* |- l( ~
  48.   enum Code. u9 ~6 [* p. J0 W3 l
  49.   {
    ' E) t5 u* z# ^2 t1 O
  50.     CodeNone = 0x00,
    9 f( b6 }# R  o3 U2 M- b# V- X0 M
  51.     CodeSoh  = 0x01,
    : j  b% q! n6 i4 l9 j$ `
  52.     CodeStx  = 0x02,
    7 B) O" W5 `6 @! e
  53.     CodeEot  = 0x04,
    2 r4 s, s$ ?' m+ F9 @% L/ h7 S# r  r
  54.     CodeAck  = 0x06,
    " Y; R, k% E6 N5 {& X2 g
  55.     CodeNak  = 0x15,' K8 S/ r8 X/ W& X% a
  56.     CodeCan  = 0x18,- |) T& A6 B1 @4 ^
  57.     CodeC    = 0x43,
    7 ~& c- @& y4 Z- R0 C
  58.     CodeA1   = 0x41,6 y+ y0 h. u" V6 y' ]6 J
  59.     CodeA2   = 0x61+ H; s# b; m# X4 ?. ]
  60.   };" G( q5 B( _, E" e2 [/ F

  61. , i- ]0 Q% a- q3 f+ ~
  62.   enum Stage$ X; i% w* T2 y
  63.   {
    , F* }# U' Y5 y$ C& p
  64.     StageNone,6 \' S+ J& ^+ Z$ z& ]
  65.     StageEstablishing,
    ) Y. @" R4 O; t( g/ _' n' G
  66.     StageEstablished,
    , r1 v7 X2 B; A6 C1 u; `3 z
  67.     StageTransmitting,3 q2 F  k* Z4 W' ^8 O
  68.     StageFinishing,
    : K8 B& o1 I4 J* o- x3 m: f
  69.     StageFinished4 @' S4 J6 S& S. W* a" V
  70.   };- Q, h  Y4 m/ o2 S; f
  71. - C, @+ |5 v5 j; ]4 [/ t" l
  72.   enum Status6 ?; ^/ ?; |' ^' v5 Q
  73.   {
    $ f+ B9 e; {) l
  74.     StatusEstablish,& t3 a% o) D+ j- c9 o9 |0 U$ E3 S3 g; g
  75.     StatusTransmit,# P# ]4 Y+ b) v: O2 A0 G
  76.     StatusFinish,
    1 V2 a! g6 e8 u
  77.     StatusAbort,& i* {* l& R9 ~
  78.     StatusTimeout,5 c, B  V& r3 z7 X6 z: V
  79.     StatusError
    7 H0 R. C" M9 l* T% p7 P
  80.   };  k9 H0 S& C, N# z3 }1 y3 g- g, F

  81. $ E9 D! `  }/ Q& F$ G+ S8 H6 `
  82.   Ymodem(uint32_t timeDivide = 499, uint32_t timeMax = 5, uint32_t errorMax = 999);! f# l$ c( K( P) w& j. Q& a. t% Q
  83. 7 i: r  g' o1 N- u8 O" B; a3 M( h1 E
  84.   void setTimeDivide(uint32_t timeDivide);* ~/ ?0 [3 F6 A9 n2 B. |' z
  85.   uint32_t getTimeDivide();
    : F0 X1 B: w. x4 ~
  86. & w6 p* E" j" c) S9 p1 u7 I
  87.   void setTimeMax(uint32_t timeMax);
    5 r5 h4 T. K# b' K& E5 p0 g2 F. l" h
  88.   uint32_t getTimeMax();
    8 t% f# w( g  R* A/ H3 v

  89. / I% T  ?0 X1 X5 y0 w
  90.   void setErrorMax(uint32_t errorMax);
    8 @: E4 K4 ~' t3 D. z6 O' K0 k
  91.   uint32_t getErrorMax();1 T' z8 K* u/ p. \, ?0 O9 p
  92. 9 l' {  f, f. H' Z! O- C& R
  93.   void receive();
    5 k8 Z' m  o4 C7 j
  94.   void transmit();
    8 U, X5 A) `. h! J. Q- ]* a2 w
  95.   void abort();
    $ O: V) Y9 E- B! p: ]/ P
  96. $ u- u  N) N+ A& B
  97. private:
    + H- J" y- [' ^7 c' P& e# p9 Q& u
  98.   Code receivePacket();
    / V8 ~7 W+ L( c
  99. , U- I) d& B. J; o3 A
  100.   void receiveStageNone();
    ; d% F4 o4 @( _' ^# ^( E2 L+ Z
  101.   void receiveStageEstablishing();
    ) v8 v/ d* d, k! a$ m
  102.   void receiveStageEstablished();
    " a8 ^4 X5 _+ ]* S9 |% i
  103.   void receiveStageTransmitting();
    : \& U2 s, A: G: Q
  104.   void receiveStageFinishing();
    1 n7 Y9 q+ A2 `; a) Q( r. {4 G
  105.   void receiveStageFinished();
    - `/ C8 U" _7 y4 R! N  ~
  106. , f* [, c* a% j/ p: ~# ]
  107.   void transmitStageNone();: `4 Z4 M  u) z7 l( r
  108.   void transmitStageEstablishing();9 b: V# {5 I3 i$ @0 Q6 V0 ?
  109.   void transmitStageEstablished();
      S5 g5 `% M4 `
  110.   void transmitStageTransmitting();" J0 {, L, {. p6 m: Y" s* q7 e1 h
  111.   void transmitStageFinishing();
    7 u" m- |7 N7 V# X: r3 P% `9 N
  112.   void transmitStageFinished();
    - B! F% S9 X9 H# w3 r

  113. 4 ^/ l# _; C! p; Y% c$ r
  114.   uint16_t crc16(uint8_t *buff, uint32_t len);
    + w( S4 U" f3 ^! q
  115. # ^4 x8 {, ]9 X4 H
  116.   virtual Code callback(Status status, uint8_t *buff, uint32_t *len) = 0;, C1 M+ x3 L* V

  117. ; c$ l: F; A, D. l+ f
  118.   virtual uint32_t read(uint8_t *buff, uint32_t len)  = 0;
    : z% j) o( B! `" M- H/ m3 `
  119.   virtual uint32_t write(uint8_t *buff, uint32_t len) = 0;. E* ?4 R# a( g! [1 S

  120. - s) j9 h$ b' N$ |/ h
  121.   uint32_t timeDivide;2 h- k# U+ \! Y, a4 i
  122.   uint32_t timeMax;
    - T7 g! g; [, K' T  G
  123.   uint32_t errorMax;
    5 J! @* b4 Q6 X) H- J
  124. 7 P; Y, i% g, Q7 Q
  125.   uint32_t timeCount;
    $ |7 W( Y/ M& l! b6 l* }- F
  126.   uint32_t errorCount;
    3 I3 _. R* X% x, t$ i
  127.   uint8_t  dataCount;* q% i1 \/ w4 I! q( c# F& b: n# C
  128. 3 O; G6 V+ s4 f6 C- K
  129.   Code  code;
    # X* K3 Y6 ?5 b- }: L6 Y1 d4 i% ?
  130.   Stage stage;& w- o% o( `- e6 S

  131. ( p* t' G9 P4 c
  132.   uint8_t  rxBuffer[YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD];
    8 J$ h: Y: m& }  @2 r/ G
  133.   uint8_t  txBuffer[YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD];( R4 g/ ]1 V- C! J& N: n
  134.   uint32_t rxLength;- ~! Z  C4 p: v
  135.   uint32_t txLength;, Q) ]. d) @/ s! Z! a2 q3 r$ r: ^' p
  136. };" h3 w' w# x5 T( {2 O5 }7 X

  137. $ L1 a* ?3 \& C1 s
  138. /* Variable declarations -----------------------------------------------------*/1 m! Y; k& c4 {- X. n
  139. /* Variable definitions ------------------------------------------------------*/
    ) G) r" p- M1 @  o
  140. /* Function declarations -----------------------------------------------------*/
    1 B, q3 e" q' b- z
  141. /* Function definitions ------------------------------------------------------*/8 R. s$ {& N/ V5 _: ^" S: O' }

  142. , _; z' B% e0 f' j2 }7 E) E
  143. #endif /* __YMODEM_H */. H' v( K$ t, t* u) J& t
复制代码

2 z, W" {! r2 l1 r4 ~$ }% {      Ymodem.cpp文件" y. T/ V% K5 E9 q+ R  ~* `
  1. /**
    1 n2 d* q* m  T
  2.   ******************************************************************************1 p3 X' F; ?5 m" v
  3.   * @file    Ymodem.cpp; _8 ~' L' Y% H) a* Q. K
  4.   * @author  XinLi) X5 W. ^& C/ J& J$ Z/ @
  5.   * @version v1.05 T6 v* {( g. k3 L
  6.   * @date    21-January-2018
    ! E* g$ V3 K1 l
  7.   * @brief   Ymodem protocol module source file.5 K% D- {) H+ S4 u  ~
  8.   ******************************************************************************- n2 Y( h6 p$ R. E+ W. t
  9.   * @attention
    3 t& n& x1 ^" d/ w
  10.   *
    + a- {. e3 Q- z9 u
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>
    * P* N" r5 X# B7 K4 k& O
  12.   *3 {: a: U8 B* V: }
  13.   * This program is free software: you can redistribute it and/or modify9 R+ W. Z- n+ ~- B, x4 p' K
  14.   * it under the terms of the GNU General Public License as published by2 k/ u$ Y: }  H' N# ?2 B
  15.   * the Free Software Foundation, either version 3 of the License, or1 U! p/ V  q1 n. ^, v
  16.   * (at your option) any later version.
    / G+ G- H3 D, h
  17.   *
    * |4 W4 l1 E* p
  18.   * This program is distributed in the hope that it will be useful,% o* O0 B3 D9 [- I; F
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of/ ]2 D, A9 }( `9 V4 Y' x5 ^) l
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the1 l+ S8 O0 P( Y1 F: R; k
  21.   * GNU General Public License for more details.
    6 ?; s) d( [; T" C6 X
  22.   ** _: d3 w8 Z2 {: ^/ P+ A
  23.   * You should have received a copy of the GNU General Public License, E% F5 I1 q, L% p4 K
  24.   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    # i+ F; u0 T1 ~& U1 |- \: L7 J
  25.   *
    , {9 H+ d! U! I
  26.   ******************************************************************************
    # T7 S; B& B) W
  27.   */! t: W! V3 r) K

  28. 6 U$ S, e! L+ x0 c/ y! `/ h( R+ c
  29. /* Header includes -----------------------------------------------------------*/
    % ~$ P; |+ o* ]" t1 W  v
  30. #include "Ymodem.h"
    - X3 _! d0 Z1 i# j1 \* G
  31. #include <string.h>/ x" ?2 K& w) S( w. r& i# M/ Y- ?
  32. $ J( T: e+ D  p/ U1 V
  33. /* Macro definitions ---------------------------------------------------------*/
    ) f$ X) M; s+ F& j( {
  34. /* Type definitions ----------------------------------------------------------*/
    8 I& x; r5 M; K+ Y
  35. /* Variable declarations -----------------------------------------------------*/
    9 K, b+ j$ j3 G
  36. /* Variable definitions ------------------------------------------------------*/
    7 v" L5 o* I" Y- U# ?3 w1 k$ \
  37. /* Function declarations -----------------------------------------------------*/: x( D% {" V# I; J& ~
  38. /* Function definitions ------------------------------------------------------*/0 M1 j, f2 Q+ E4 L' X) y3 N, U& Q

  39. + [; c# ]- H6 N/ h3 k1 L/ Q
  40. /**
    1 a2 K' O( ~! {; J
  41.   * @brief  Ymodem constructor.3 E7 a' a' _/ K5 k. {( K
  42.   * @param  [in] timeDivide: The fractional factor of the time the ymodem is called.
    + C; @  {( S1 n% A: I
  43.   * @param  [in] timeMax:    The maximum time when calling the ymodem.9 Z8 B# z7 w' O8 s. u& R
  44.   * @param  [in] errorMax:   The maximum error count when calling the ymodem.
    ; d+ q. S& _6 h4 I* @, z/ X
  45.   * @note   The longest waiting time = call time / (@timeDivide + 1) * (@timeMax + 1).
    . y# o# a" s" P- m5 c: V
  46.   * @return None.
    : h: ?( B$ F* X% y& P, i
  47.   */
    ) i7 k6 u: A- I% d
  48. Ymodem::Ymodem(uint32_t timeDivide, uint32_t timeMax, uint32_t errorMax)4 h4 p+ G3 X5 x; j
  49. {# Z7 r  V. w* Y  U
  50.   this->timeDivide = timeDivide;
    + [' `- k$ L9 n& r
  51.   this->timeMax    = timeMax;
    8 a4 u& a$ e+ }" i  G9 x
  52.   this->errorMax   = errorMax;
    8 g; h6 T2 d( c( {" M1 E/ t

  53. + V7 f, E9 `5 ?6 A9 f/ o  l1 n- f
  54.   this->timeCount  = 0;; i2 A. j/ l2 \
  55.   this->errorCount = 0;
    9 I- E# i5 g( W( j- i
  56.   this->dataCount  = 0;
    % e0 A; Z& e2 L% Z+ |1 b/ x
  57. . [  c/ D1 f# J
  58.   this->code       = CodeNone;
    4 O" I) a, w, h( l1 u
  59.   this->stage      = StageNone;6 K6 }1 \, n  R4 _1 h3 U/ {  X% T
  60. }
    4 G/ }& G8 H" g1 r- j+ t# ~; x
  61. . K8 x# \! ]; n: x
  62. /**
    ; S$ d5 d# X3 ^  D7 |
  63.   * @brief  Set the fractional factor of the time the ymodem is called.
    0 ~4 l% G6 j5 _- g6 t! I
  64.   * @param  [in] timeDivide: The fractional factor of the time the ymodem is called.
    ) Q% g. e5 V6 t. `0 U3 a' L5 w
  65.   * @return None.
    ( I) v3 \' R" ~, l
  66.   */& k1 L1 Z' C5 c( d5 ?
  67. void Ymodem::setTimeDivide(uint32_t timeDivide)
    4 `( n$ G- F) L/ M3 g
  68. {
    4 x2 P7 A4 o$ y( e% M
  69.   this->timeDivide = timeDivide;
    & x& d( `$ r+ v" c
  70. }8 ^8 N3 x2 a5 p) C

  71. : G0 X# u) L+ l7 F' D- N5 P/ Y
  72. /**
    ; t7 _  y5 y* |2 [; P# D: W8 X: R$ [
  73.   * @brief  Get the fractional factor of the time the ymodem is called.
    5 m1 ~. r/ h/ J
  74.   * @param  None.( e' h$ ?) n4 g, M7 m
  75.   * @return The fractional factor of the time the ymodem is called.6 U  [8 ]* O( C% C  G: T
  76.   */, R" {$ @; J  y: }/ C4 v
  77. uint32_t Ymodem::getTimeDivide()' M0 K: f; p- R- h; ?0 O
  78. {# F. Z. K( t( P9 Q2 Q
  79.   return timeDivide;$ q) R4 s7 z; Q2 C* F2 n
  80. }
    ) F, e! D! O8 J9 E
  81. 5 y% W' x8 ^) H/ u6 L9 N: P* A
  82. /**
    ! L+ t8 c* `* b$ z* _7 a3 n
  83.   * @brief  Set the maximum time when calling the ymodem.: R8 q$ K! [2 Z  a
  84.   * @param  [in] timeMax: The maximum time when calling the ymodem.( W" o. h: L4 N! V. r5 Y  s
  85.   * @return None.$ b" R5 m/ p; O* G* B; a
  86.   */
    6 z% ?' y' a& r6 Q  |5 A
  87. void Ymodem::setTimeMax(uint32_t timeMax). @# @' m& @. ~8 o8 W& g9 v" h& t
  88. {3 |$ M# B$ }4 y! d% H
  89.   this->timeMax = timeMax;  y3 s+ M" v3 E0 }
  90. }
    , K. @2 Y5 J3 m! J$ v# N. M

  91. ( l8 `: q) J3 O  h0 m  b- B
  92. /**
      T/ b/ c# t" a$ {
  93.   * @brief  Get the maximum time when calling the ymodem.
    . a! @* T1 ~# Y  \) T& o
  94.   * @param  None.4 L: m1 i! [* O3 M, A
  95.   * @return The maximum time when calling the ymodem.
    # v5 i" J# @; G0 h0 {
  96.   */
    ; W; x% w, o" X. D  p
  97. uint32_t Ymodem::getTimeMax()
    6 F0 j! Y0 K) `" C9 @
  98. {
    1 U! I4 c3 i2 a+ g. @: O* e* L
  99.   return timeMax;; g2 h6 `% {2 a
  100. }
    / j* d+ A# a4 q: J- }
  101. $ ~, X2 C8 L! @+ g4 |) R
  102. /**
    0 c) X: c' x: {2 f) y! g
  103.   * @brief  Set the maximum error count when calling the ymodem.
    / Z6 [4 D! Q: P: C( s, a/ i8 O
  104.   * @param  [in] errorMax: The maximum error count when calling the ymodem.
    . l% c8 R3 B/ r' J9 Y4 g& U
  105.   * @return None.; Z- s+ B. z; Y: y; y0 W9 T
  106.   */& Y0 c, G6 t: p0 i
  107. void Ymodem::setErrorMax(uint32_t errorMax)8 m( C4 c+ \2 A5 \' y9 z5 [
  108. {9 H3 x. [3 D' C! `" l6 k
  109.   this->errorMax = errorMax;
    2 \% @; ^! O8 ^6 x& Z. D
  110. }
    : ?: H! n$ a* Q( t1 J3 |3 d

  111. " c' L5 Y5 c; G7 ~6 c& Y
  112. /**- ^% z, n5 D# o& ]% s3 t
  113.   * @brief  Get the maximum error count when calling the ymodem., r3 M' P9 f4 I
  114.   * @param  None.
    / [* {$ `( i+ ?$ Q" {! ^5 }
  115.   * @return The maximum error count when calling the ymodem.  x8 P8 S- |8 ^$ A! m: w5 u
  116.   */
    : u& m# b, k5 o. L9 C3 B8 Q
  117. uint32_t Ymodem::getErrorMax()9 B  R0 ]9 b% k" p. L. v
  118. {$ p* ^6 X# ?: C6 E/ N' [/ U5 [
  119.   return errorMax;
    - Z9 L6 r/ ?1 Z: _
  120. }
    - b$ A  O$ m* P- ?- v0 U6 q! _0 z
  121. ; U" r, `3 X) c$ b. ^
  122. /**( o3 [& b, f& I% w! J
  123.   * @brief  Ymodem receive.+ g- u% X, @+ w7 C" s* I4 V
  124.   * @param  None.) K, z, P; n+ A3 u! Y6 U
  125.   * @return None.
    ! U& v: O, G! ~4 @5 N: C* m
  126.   */
    ; ^6 w  A, ?$ n# {
  127. void Ymodem::receive()' M0 F& ~0 n$ O
  128. {# T2 s' [) c) m( w% c  E; S* u: ]$ p
  129.   switch(stage)9 ]6 E, [/ E; t+ H
  130.   {* Y/ c3 G; x$ Z; Q2 ~( C6 ~. s
  131.     case StageNone:7 S8 N, f6 U5 A/ N5 _! \/ B
  132.     {. K" k! ~+ T. C0 \7 j4 s3 d, ]# u
  133.       receiveStageNone();
      p& a# Q& W3 d
  134. 4 b, g1 b; j& V; j
  135.       break;
    ) L5 @2 {3 J+ A: ^% ^( D! i( N
  136.     }
    4 U: J/ f) r$ ?  D& k
  137. 3 a3 q/ c) h2 I* t
  138.     case StageEstablishing:
    : R0 j5 X* R* \
  139.     {1 W9 ^) f+ p7 N# B! o7 Z9 h
  140.       receiveStageEstablishing();9 t  W5 L/ B) _) h7 M
  141. 0 z9 x: w; q* N1 I4 t
  142.       break;
    8 y% M7 `2 J# Z: |: a8 s& }
  143.     }
    % m, I8 K+ u# A! q4 D

  144. ( y0 p% f' h0 J0 @
  145.     case StageEstablished:' U& @# Q# |4 Z, a
  146.     {) H7 _8 u. F% r' C. s& ]
  147.       receiveStageEstablished();
    ( ~5 E- z& @; ~, u# c

  148. ! q' M4 g, A$ m, p/ ~0 w
  149.       break;3 d) s% G  C# |$ D& \8 A4 f1 E2 u
  150.     }
    . k& l0 A0 r3 o% J8 w: P

  151. 1 U+ ~9 S* ]! `, \# O
  152.     case StageTransmitting:
    1 z1 b" m$ V& @0 }0 W; S5 u5 k
  153.     {# c. ]2 |" {; a* S! ]1 v
  154.       receiveStageTransmitting();" h$ O8 n, g! O  J1 q

  155. 2 s1 ~9 i3 |* ~' |1 K
  156.       break;
    7 n5 w7 C$ v3 U- g1 T9 D
  157.     }/ f+ [4 c4 e. l% G

  158. # E9 z$ n, Z9 Z4 u
  159.     case StageFinishing:
    ) W% x) N, G' k. j6 C) U
  160.     {! y6 r, f9 s% |( c9 u
  161.       receiveStageFinishing();9 e' U5 s% C  V8 J/ L! T
  162. ) h; c9 s+ m* h0 h  k
  163.       break;
    & Y6 j" L% f4 l; N0 A8 E6 w
  164.     }
    ' Q( O+ T% z+ l5 H
  165. 4 c" {% A# d0 T6 x
  166.     default:
    6 H: u3 B) ]- v
  167.     {! @! }: r/ L2 H9 N2 @! E2 f: N3 R9 l& g* a
  168.       receiveStageFinished();
    - n$ v# r* t: R  l$ w* B
  169.     }
    3 F$ Z6 u: V: i
  170.   }7 P# \( ]( R6 C% `
  171. }5 b7 |7 p0 P0 O+ T7 E
  172.   R; u* x( |0 m( @
  173. /**' f9 u# k5 R$ H; X" [0 L% }  Y
  174.   * @brief  Ymodem transmit.
    + Y+ X1 A# ]' Y( A+ @% y% O# ~
  175.   * @param  None.2 x; K, p1 h) A0 o6 }
  176.   * @return None.
    5 g: o7 }$ J) ^: p1 Q+ i4 t9 q$ e
  177.   */1 r3 \; F) e% V/ b6 r
  178. void Ymodem::transmit()7 F& Q: u: z, x" [( Y/ J" k/ J0 f
  179. {2 R0 K+ T% m( Z! t' M
  180.   switch(stage)) ^; W. p- J/ l: I
  181.   {+ I2 I# ~4 Z3 U  w, q: P
  182.     case StageNone:& k" X2 A5 L; r" ~
  183.     {
    * |4 Q  r' O2 c6 g/ @
  184.       transmitStageNone();
    8 }* J2 L* y, W& H* A" W: ^- w6 a7 |
  185. ; M9 F8 l* x* K  P2 \7 m
  186.       break;0 [/ Y! @, W) X
  187.     }
    : [- A7 H+ D) j5 W- `

  188. $ I% X$ ]2 x: z$ U) \: z$ m
  189.     case StageEstablishing:
    # b5 u% {% }/ Y5 ]. a7 h
  190.     {
    , z+ l9 B/ L* G  R9 J; Z
  191.       transmitStageEstablishing();
    , M  K4 _: M5 C4 T9 b7 [3 |6 V

  192. ; v" c! Q  Y2 E; i8 C
  193.       break;/ S, q3 u. y. c
  194.     }& |* Q) l! `# k$ v2 h* C/ X
  195. 6 b5 g& z0 ^$ g! W9 G5 j$ X
  196.     case StageEstablished:6 f5 u; D  {) {* q& ]! A
  197.     {
    6 _4 u7 A5 I9 v, R* s
  198.       transmitStageEstablished();4 H% T- c+ ~) H  r3 B) l5 }
  199. : f6 c" K, f( y4 r" {5 y2 U! B
  200.       break;
    * j" u- y2 G( c, c
  201.     }
    ! x! @& |2 f' w- J9 ]; n% e9 d6 c0 T

  202. - J/ `: `5 i  ]) T) M
  203.     case StageTransmitting:
    . ~1 ~" c& f) X" P3 a! P% }
  204.     {. w9 y' o8 }4 S: I  Q  D9 |; r: k
  205.       transmitStageTransmitting();5 z2 F4 Q9 r+ x+ j9 _/ Q, U

  206. 8 L& S# B, B, X5 c7 @4 y3 n5 E% F4 H4 `: a
  207.       break;
    " c- s: U: J" k. P9 ^" B: g
  208.     }7 G0 d* p; _8 x- b3 t& a" U# |

  209. 1 s& F4 y- o6 R4 T
  210.     case StageFinishing:
    $ C1 J! }! g+ E4 h- v! T9 n0 x
  211.     {
    ; w. ]9 m6 G6 y: u: Y' v
  212.       transmitStageFinishing();' n& T+ G1 Z# R# W. j$ P1 v+ _

  213.   u' f( H3 D7 f" R, \" f" x( h$ I3 J
  214.       break;% X% ~9 O- M- c6 P
  215.     }
    6 s/ R8 C( T. M  @6 }9 j# [
  216. ! [5 A& u# S; H. g& m) c. x
  217.     default:6 N3 B. o7 g# M9 r- S7 G
  218.     {8 V, O6 \  C: P4 a
  219.       transmitStageFinished();
    # U1 e. B- z$ b% w( S
  220.     }2 W7 p9 ~- L$ Y8 u6 \) {" ~+ ^9 I: H
  221.   }; _; h" G  M+ x! b
  222. }/ X, S1 W; L7 V

  223. 4 i) N6 r4 ^& q3 H% ]
  224. /**
    6 Y! D- s) O) |% g) P: `3 p
  225.   * @brief  Ymodem abort.
    9 |, U) C7 v+ D8 I
  226.   * @param  None.6 G* F* ?* a2 d2 x8 x
  227.   * @return None.7 m" d3 n0 J, p2 T: _- C
  228.   */9 W) H/ z( A4 `2 d' n9 p- |
  229. void Ymodem::abort()
    + k; |4 h! W! n1 W' u
  230. {" B! `' ^( n0 G: s  K
  231.   timeCount  = 0;3 q7 O  I. k0 _" O
  232.   errorCount = 0;
    8 o& ?2 h  R9 t/ n. g8 K$ h3 q
  233.   dataCount  = 0;, i, m: X: E! [9 r& c, S
  234.   code       = CodeNone;5 Q2 w% s8 W0 G+ r, g7 v( A1 `, F
  235.   stage      = StageNone;5 k% V  ]4 `( _0 P0 M. _7 F' r

  236. 3 h6 S; I4 r+ \/ }; W/ L
  237.   for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)2 ^+ X; G# v+ K3 Q1 h, i$ ^
  238.   {" w6 Y  k6 O( v5 s0 W& w
  239.     txBuffer[txLength] = CodeCan;$ J) e( L6 v- b( s: S
  240.   }  t9 l0 X7 c# T# Z9 B7 \

  241. & T2 C( |0 Q; p
  242.   write(txBuffer, txLength);
    $ m0 S- Q/ V, E* j, p
  243. }$ r! Q9 ?9 s2 I

  244. 6 ]1 k1 m+ b# a5 P( L7 G) X
  245. /**
    ( }( l( q1 a. V/ C2 Y$ q) o
  246.   * @brief  Receives a packet of data.
    $ q; u7 \" |9 {" p1 i1 A) q+ P
  247.   * @param  None.  P7 [4 e! x, n
  248.   * @return Packet type.8 m7 _% X% ^5 }
  249.   */% R, `) h4 R, W" p1 [; B
  250. Ymodem::Code Ymodem::receivePacket()% v# [# F% J" ^8 O, N3 K1 `# q
  251. {. }) @; Z, |2 H, V( b, J
  252.   if(code == CodeNone)
    ' ~; |, v, c; h4 g3 H9 g
  253.   {5 ~3 p  I$ D1 V4 z
  254.     if(read(&(rxBuffer[0]), 1) > 0)
    + }- O2 H: B% @0 w) P7 o
  255.     {$ A# p8 x* n7 ^
  256.       if(rxBuffer[0] == CodeSoh)
    1 P: |  N# r& Q8 n! O7 E4 S% _/ }  t
  257.       {
    7 x/ w' D9 }& J5 o% v2 Y  q
  258.         uint32_t len = read(&(rxBuffer[1]), YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 1);" ~5 I- l  S. A- w' l

  259. 6 n* S2 N3 [: E: M6 b2 N2 \
  260.         if(len < (YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 1))
    , H- s+ ^* E; d6 R7 E
  261.         {
    / S; w5 X# ?9 \
  262.           rxLength = len + 1;; b% H: b/ c: K
  263.           code     = CodeSoh;
    1 E) S. L; d0 s
  264. ( C# F" X8 U" \  {4 D
  265.           return CodeNone;/ @( Z0 b: S  v% U# O8 [" H
  266.         }
    # E# M) k0 m; ]9 E  J7 L: V
  267.         else
    ( |, C0 ]! Z+ s% \; J0 {; i
  268.         {
    1 }8 g+ b% k. I, j1 {, v
  269.           return CodeSoh;; _' Y& P7 [& \
  270.         }5 B( H# t( @: i) a* _3 r* q. p
  271.       }7 x( R' L9 A6 A, I4 C
  272.       else if(rxBuffer[0] == CodeStx)
    ( {$ d; \) T$ x; B
  273.       {
    - J) f8 W, h$ s4 m7 r% y# j( s
  274.         uint32_t len = read(&(rxBuffer[1]), YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - 1);) c& I1 P3 J4 D4 ?& z

  275. # U& l/ I- h' R" I5 C
  276.         if(len < (YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - 1))
    * b7 u' I0 H6 z( Q) b- f4 e
  277.         {5 C& c: l4 G- s
  278.           rxLength = len + 1;
    9 i* `' R1 k; u
  279.           code     = CodeStx;
    7 j9 o& T- `& }2 z
  280. 6 n: S! C9 f& o7 l# Y
  281.           return CodeNone;
    ! a* M) S" a9 @* m' Q! y
  282.         }
    6 C$ H5 v! W! Z* R; o5 `) K% [
  283.         else
    + C, W, w8 [' s7 f% `2 }
  284.         {; r4 }$ g9 f4 _" E3 N
  285.           return CodeStx;
      w( M. S& v: g7 z' z
  286.         }
    : f# [2 l8 y" t' N# W6 X# o
  287.       }9 j% X0 Y9 v7 N
  288.       else% \8 ?: ^  y; i" }8 u) m" P* ]1 x7 a
  289.       {
    + \/ B$ ~1 V& V7 ?4 T2 I" I
  290.         return (Code)(rxBuffer[0]);
    ( O0 A; W% Y/ ~& t6 s) p
  291.       }+ h8 ^  Z+ u2 ~5 Y0 v! R' I
  292.     }9 [  z3 d* Q6 G/ W) g/ z8 e. [
  293.     else
      ^8 A) ^! Q. d( X5 Q% X3 B
  294.     {
    & y* M0 E7 U# x+ J+ t+ B/ U
  295.       return CodeNone;
    / w7 d+ b7 b1 `9 F7 ^) d0 e
  296.     }' j! G8 g2 r4 a( h& m$ ^$ y
  297.   }
    5 U0 e: g, `9 Y5 B) _+ Z' Y  {# G; q
  298.   else
    " W1 _) P3 O" O$ a9 H
  299.   {
    ( R& {* X/ T6 f* b9 R
  300.     if(code == CodeSoh)
    + q* G3 G2 P  K" B# E
  301.     {
    7 S# u% B% h: O2 l$ n- p& _
  302.       uint32_t len = read(&(rxBuffer[rxLength]), YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - rxLength);/ ]% }; T3 t! q% b

  303. & q  E8 r# J3 k7 k! J
  304.       if(len < (YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - rxLength))
    - `$ k5 u% b0 O* L
  305.       {
    4 a8 u3 z* U* A! F" M
  306.         rxLength += len;; `: C: `# `# J+ X% z
  307. , h9 y' A5 Q5 t
  308.         return CodeNone;+ h4 v+ |7 D' V
  309.       }# Y- [" D7 X3 O% ^' M, K
  310.       else, b4 l) n1 ?& A7 r1 U# H; ]
  311.       {
    7 N7 e) u% D- x4 y
  312.         code = CodeNone;$ {4 w( V& V% q8 ~+ w/ E
  313. 6 ~6 t  o1 a' H/ A
  314.         return CodeSoh;
    * Y) o, ]3 H# T; g( b
  315.       }
      g' p& M  ^0 u/ F7 W. x$ y  j; ?
  316.     }
    & h& z) s/ o  k; o" P9 x3 f. B
  317.     else if(code == CodeStx)
    - j; ^+ s5 F7 A" e
  318.     {5 \3 t" M9 C0 X" W! K6 E& ^$ C3 Q
  319.       uint32_t len = read(&(rxBuffer[rxLength]), YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - rxLength);
    , R: I' ?* z7 |' I# ~

  320. 2 O4 v7 s, ^! @# }( {
  321.       if(len < (YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - rxLength))
    ' R' q5 s" a& f# {  E5 u* l# _
  322.       {
    7 F2 C( N) H! z8 ~/ m
  323.         rxLength += len;( b. Z3 D" p% b8 g- D

  324. ! G( ]+ q3 T/ y  `" R( c
  325.         return CodeNone;
    6 G# B+ X2 N# v6 W
  326.       }. g6 t5 I8 [8 }; l: f) z1 q+ t
  327.       else4 Y# B% O; T- J1 I
  328.       {% H: p: {& a% p& }9 c
  329.         code = CodeNone;7 P: s3 V! m+ k! N
  330. * h/ c% W3 G" _; ^# s
  331.         return CodeStx;
    ' t# A; x& R. B6 L
  332.       }
    3 _! S  u! w- d" e, _
  333.     }
      H% ~9 S1 u" x9 a( }
  334.     else
    9 V& m* v* f+ m; W
  335.     {# x5 T! A$ J- K1 T3 e$ V0 b- b
  336.       code = CodeNone;8 g# k0 n1 j+ f6 ~  c9 }

  337. % ^% z5 C# u8 \/ Z/ x
  338.       return CodeNone;
    % ^. L& R% A) R/ s! l  E0 ?! M
  339.     }
    , s. X% W& W/ J) R
  340.   }/ E) D" p0 H8 o; m4 @$ R8 i! l
  341. }. r* ?, c0 r) X2 L3 G3 u) J6 i

  342. $ j# D& [* T* y
  343. /**3 O( u4 `+ p) H1 @5 |8 `5 e5 e9 [+ k
  344.   * @brief  Receive none stage.! m8 R* k0 ]# L+ s' I
  345.   * @param  None.. R: ~' s" L% E+ {  R/ K5 y$ P: X
  346.   * @return None.; P% @( Y7 k' {- g
  347.   */# ^: D/ b1 R$ a4 y6 u) w$ |
  348. void Ymodem::receiveStageNone()8 u+ M& B; i: |
  349. {
    % g2 N& ]: c7 l/ S( n
  350.   timeCount   = 0;
    ( e( f7 e1 F6 c" d
  351.   errorCount  = 0;0 p$ X) f. `; X, u
  352.   dataCount   = 0;. z# a) R6 C6 W
  353.   code        = CodeNone;
    ! L7 y) x: w: v$ _$ s% P; Y# _% N& g
  354.   stage       = StageEstablishing;$ z- m. p2 L; i8 L+ ~
  355.   txBuffer[0] = CodeC;
    - Q3 Z; u0 n" q% J
  356.   txLength    = 1;
    8 M4 O; J8 d; d  W, H( J
  357.   write(txBuffer, txLength);% B! f+ c: s9 q- i2 e) j
  358. }( ^) N5 ?! h# k. I1 G8 N" o
  359. ) i( {" q* }! L1 N: j
  360. /**2 D+ M, B$ D6 `2 @; z7 ~
  361.   * @brief  Receive establishing stage.
    ! S; H' s: G, }) L' g5 I5 P
  362.   * @param  None.5 `9 n0 X2 `! @( P- _* S6 ^
  363.   * @return None.4 G8 L' \- `' Z+ Y0 j4 f; Z/ V
  364.   */
    ' b* ?0 S2 P- ]" c& h
  365. void Ymodem::receiveStageEstablishing()
    6 R7 M, Q5 b7 }  t' ^9 f9 N; r! D
  366. {
    # O) B5 A: L/ ?& }0 U5 \
  367.   switch(receivePacket())
    1 X( W3 w' I6 m4 o+ @0 f
  368.   {7 D+ r- S) K' n% M+ K$ ~1 h' K
  369.     case CodeSoh:6 Y; H9 A" ]% u! b  H+ ?
  370.     {
    - Y$ B9 q( d3 [0 K- d
  371.       uint16_t crc = ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 2]) << 8) |( Q& N' G! C& L; D' t
  372.                      ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 1]) << 0);, C* ]" u! \7 p* f
  373. # w/ L' b5 W2 U
  374.       if((rxBuffer[1] == 0x00) && (rxBuffer[2] == 0xFF) &&* J/ |: z7 j2 h0 @  x" L; G0 y$ g/ w
  375.          (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_SIZE)))
    ) B" I8 }$ o& s6 P- ~) E
  376.       {
    : q1 h* O2 k% d4 F
  377.         uint32_t dataLength = YMODEM_PACKET_SIZE;
    % y! B4 D1 v3 H2 F, O8 w5 A1 A

  378. ! t, ?7 S9 I# K
  379.         if(callback(StatusEstablish, &(rxBuffer[YMODEM_PACKET_HEADER]), &dataLength) == CodeAck)
    $ E4 O/ d8 H: H4 H
  380.         {' C5 X, m' S* o+ u: k4 j
  381.           timeCount   = 0;
    6 c  ?: P9 N2 `% i4 O6 ?( R" a
  382.           errorCount  = 0;
    : b8 x. a8 S# @# k% ~
  383.           dataCount   = 0;, [7 W& g/ n7 k: ?- g8 h
  384.           code        = CodeNone;  s# p4 _. T/ i0 ^5 O+ Y5 |
  385.           stage       = StageEstablished;+ }( d& k3 }+ I9 y) N0 h
  386.           txBuffer[0] = CodeAck;) C3 p9 _) D* f8 v- X* M  g
  387.           txBuffer[1] = CodeC;2 D" X1 a9 r1 e8 e1 ?9 g
  388.           txLength    = 2;: ]* E  U$ ?: N, T
  389.           write(txBuffer, txLength);. L/ O0 ~# X+ a0 T( S9 B1 @
  390.         }: K  v8 `/ H: C2 L) k
  391.         else
    ; K- ~# [) }2 K
  392.         {+ O! Y1 X! a! e. o- r
  393.           timeCount  = 0;4 v' P6 p5 \8 M6 ?7 j/ s" v
  394.           errorCount = 0;
    $ k9 ^! T1 B% q) D  {
  395.           dataCount  = 0;# y; z  y' Z& |; u4 J" o+ h. _4 A
  396.           code       = CodeNone;
    % E% N6 q3 N, |# i; L
  397.           stage      = StageNone;$ \2 ]. D9 N' [. F/ D7 h: E

  398. * c0 S. r; Y: u, |
  399.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++): c; y  ?& k0 Z: P$ c
  400.           {
    1 O6 E: y" d( F- E
  401.             txBuffer[txLength] = CodeCan;
    * ?: B9 F& f: e' U* W2 R* [
  402.           }
    3 `% T; R# L2 N, t4 _3 M. Y5 A
  403. 3 I, S4 B, F7 N1 _! B
  404.           write(txBuffer, txLength);1 J4 Z* ~; u$ X+ h/ ]
  405.         }' i) [" n+ h9 M) c
  406.       }2 L% t& J0 V3 b. P% X, j9 e
  407.       else
    ; T9 g4 n9 Q" U$ n" T
  408.       {
    ) j. s. J5 b* w1 S4 M
  409.         errorCount++;
    $ D) k$ ^: n) {9 |

  410. ' }/ C! p! a% g8 {3 N1 |
  411.         if(errorCount > errorMax)
    ( w9 k, M& j3 y" t
  412.         {! |, Q" @+ ?# q( e' B
  413.           timeCount  = 0;
    ) e" \9 B9 ~; Z5 L) `( {
  414.           errorCount = 0;, m$ @' C- R0 s
  415.           dataCount  = 0;
    , I: `3 T/ R1 I% K2 d* @
  416.           code       = CodeNone;; g/ x' J" H, Y! F7 x
  417.           stage      = StageNone;
    + o! g: |! L' J+ ~
  418. 2 R# O8 n% k, g' U: w9 Z
  419.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)) X* L  {) }" f7 V: O
  420.           {
    - _( p. H0 \9 h7 `8 W, [  z
  421.             txBuffer[txLength] = CodeCan;
    0 F" p  e) O9 N, Z" e
  422.           }; @+ L- {; g3 G$ ~
  423. % G0 J5 Z, `$ X2 w
  424.           write(txBuffer, txLength);7 K. V3 f) D' J0 P: d
  425.           callback(StatusError, NULL, NULL);7 t6 M$ f; @, `5 @2 i: ~
  426.         }% G3 ]5 l; s/ R/ Z) T) L1 z: |
  427.         else
    $ N6 b# s. G! l) m9 P' _% y
  428.         {
    & s! W0 p( B" P1 I+ M  ?6 M
  429.           txBuffer[0] = CodeC;
    4 B0 b  M2 a, t5 [, M* C1 M
  430.           txLength    = 1;
    * e( ^  f- G0 P
  431.           write(txBuffer, txLength);& g* o; Z, i% X7 E6 v+ f9 J( P
  432.         }
    0 W3 k/ a; O( _* z  C& q' \' ]/ ~
  433.       }
    6 x  B: Y# Z( F  C; P

  434. : |$ s$ a2 y- K' G! @
  435.       break;
    0 t% y% M9 G1 }, Z+ z
  436.     }1 P2 E2 k& p: }8 @

  437. " C, z) T6 Y0 M7 Y8 f+ @9 `! {4 X
  438.     case CodeA1:
    8 H  X1 t% ^! v- w  G) P
  439.     case CodeA2:
    / Q- u+ b# o/ w$ s6 u
  440.     case CodeCan:+ P! \' n, M2 M' d5 g& a& }& f  V
  441.     {
    / U/ r  r9 f( W: u3 o* H
  442.       timeCount  = 0;) d1 i5 j4 c5 [* ~* M# ]
  443.       errorCount = 0;
    4 ]" ?) V. y( |  n8 Y/ M) h
  444.       dataCount  = 0;  [+ X) F$ E/ R) T- t+ y* D
  445.       code       = CodeNone;
    , j. f: @1 B# T3 o, o, l( t' b
  446.       stage      = StageNone;
    % S+ }  T4 w  E# d! h# |: }6 M4 {
  447.       callback(StatusAbort, NULL, NULL);
    ( `! o  k2 X$ N8 o8 v. [1 v

  448. 6 V  K* y1 G! w+ s. \) {3 ]3 g
  449.       break;
    5 h+ t' b1 A1 I% d  j
  450.     }. t) E5 \6 \% V" l- D

  451. 6 V# t# d3 O$ d0 _
  452.     default:8 P. B6 O  ?. W5 e* r% e) F
  453.     {
    9 m; e+ G, O4 r  b' Z. n' e
  454.       timeCount++;7 ]: B3 ?: ~! [; ^, ~' n* |

  455. 1 I  c' P* T' x5 c! B$ r* H
  456.       if((timeCount / (timeDivide + 1)) > timeMax)' n0 d9 B: K8 {3 ?6 [. w0 n
  457.       {+ C3 t' x/ T4 A5 c
  458.         timeCount  = 0;
    3 ^4 D+ B/ A! i# D" G' j- I: M
  459.         errorCount = 0;6 o5 `3 J$ ]$ z8 ]4 ?5 Q
  460.         dataCount  = 0;
    ; E% e( o1 r+ E  |4 R
  461.         code       = CodeNone;
    8 ?8 M0 e" w# n
  462.         stage      = StageNone;
    2 T( p. {; U- I+ @7 @) L& d! P

  463. 7 M- T/ N9 {* ~( k/ ^/ k
  464.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)4 q( A, a& o3 `2 ?9 T1 S
  465.         {% z) m3 T( S: I4 x
  466.           txBuffer[txLength] = CodeCan;( @$ A8 k# j8 l* J% z2 a' V- Z
  467.         }
    ; @# a) l3 S& `) ?3 B
  468. * X+ Q+ s7 j+ Y: U/ ?* [+ N& q
  469.         write(txBuffer, txLength);
    # n+ t2 ?/ |& }+ y5 p9 V2 F
  470.         callback(StatusTimeout, NULL, NULL);' u% d8 H, f5 a7 ^1 w. O
  471.       }! h" M) r$ l9 h  d
  472.       else if((timeCount % (timeDivide + 1)) == 0): h% l, B, v/ x2 Q
  473.       {
    ' A4 A* Y! W* \& s# F* p
  474.         txBuffer[0] = CodeC;8 E! B; B5 m" B5 d  i
  475.         txLength    = 1;$ P* z' E) N/ {% I$ k& L
  476.         write(txBuffer, txLength);9 q; u0 C* }/ ~2 h( l0 @4 w8 y; q
  477.       }
    + E' ]) E; S- q( d# A
  478.     }
    ; t' F7 w* ]8 F. n+ v
  479.   }
    $ c" m# B+ Q; V) K8 s
  480. }" b4 A& f. Q* [3 O
  481. ( ?: @1 c$ V" w7 J
  482. /**! k4 J" U" Y4 ~
  483.   * @brief  Receive established stage.
    8 H" U: R- N* X: i+ n6 S
  484.   * @param  None.
    , o6 u! ]' i) p% d
  485.   * @return None.- i: K2 _: S9 h; V9 ?2 Y' R& g
  486.   */
    ( x8 S) Q. [3 s3 E5 U, _
  487. void Ymodem::receiveStageEstablished()" J7 a' Q, ~: g1 |: r9 U
  488. {
    4 {3 Q$ m2 S+ G9 D) \. s3 `
  489.   switch(receivePacket())
    / q% w3 b0 z+ a0 {  T, f
  490.   {
    4 a' k/ c# \- I# N, w+ o
  491.     case CodeSoh:% B3 o) }/ x! \# }2 J8 i
  492.     {
    9 T7 H* p# W5 Z4 }) l
  493.       uint16_t crc = ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 2]) << 8) |6 F9 W$ y' M; f9 X% X7 c
  494.                      ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 1]) << 0);9 J' Y3 `. p. v, n8 ~& ~- q7 J# [
  495.   u% g# w- }/ j, B
  496.       if((rxBuffer[1] == 0x00) && (rxBuffer[2] == 0xFF) &&  f! ?, X1 i6 H8 _; `3 S
  497.          (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_SIZE)))
    8 ^6 l9 d# q! e+ y( @4 Y
  498.       {
    8 l# o  s# h6 n, L
  499.         errorCount++;, D1 J5 j- m# h2 o/ u0 B% n! J( ~
  500. 4 s  P! Q. u3 z
  501.         if(errorCount > errorMax)
    * U% M6 b0 {; v
  502.         {
      E! h0 I, C% i6 N; }
  503.           timeCount  = 0;
    4 ]* }7 M. J5 {. {; M8 y2 i& r
  504.           errorCount = 0;* a! X! N& J0 Y" G
  505.           dataCount  = 0;& W. y7 u! w- @7 Q9 ]: ^7 J
  506.           code       = CodeNone;
    & G# p1 ~% Q1 A1 c
  507.           stage      = StageNone;# q4 }# [: l# V
  508. 8 i8 o; |3 S8 Q( P8 p+ H/ k/ A
  509.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
      u7 p% _$ }# D0 Z: I! e# j
  510.           {
    + o4 p; v( N) |/ r
  511.             txBuffer[txLength] = CodeCan;
    6 P4 N+ p% F. d2 t
  512.           }7 R9 P0 f0 U  \  I/ J+ @) A1 Q
  513. / }$ L! w$ s! X7 V3 t( V
  514.           write(txBuffer, txLength);/ h2 [3 f3 u+ f+ E
  515.           callback(StatusError, NULL, NULL);/ M+ _' w' r* r8 q
  516.         }9 ^/ m" P) k- `* p3 K# a9 c# D2 _
  517.         else
    % m, Z& _* z! T4 u, l* y1 f5 M
  518.         {/ P" U4 @+ U: s& p) Z) e! t# `
  519.           txBuffer[0] = CodeAck;' R; m* Q# \3 X/ B" e9 d
  520.           txBuffer[1] = CodeC;' ^4 X% _1 C* q
  521.           txLength    = 2;" R* r4 M6 I2 q; {$ H0 d
  522.           write(txBuffer, txLength);
    . v2 r8 O1 D( l) q7 c+ y
  523.         }
    " R: U: {) b; p$ O0 P
  524.       }. K$ ~2 \8 ]" s2 g. m, t
  525.       else if((rxBuffer[1] == 0x01) && (rxBuffer[2] == 0xFE) &&  H6 j4 Z& E2 p- W* a0 \( P
  526.               (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_SIZE))): }* c( O2 T  I0 a4 U
  527.       {
    / t9 B  a3 I) ~3 A0 ~3 ~
  528.         uint32_t dataLength = YMODEM_PACKET_SIZE;
    * u' a5 e2 u. e8 r' \

  529. & H% P, w5 V+ ]& W* ]
  530.         if(callback(StatusTransmit, &(rxBuffer[YMODEM_PACKET_HEADER]), &dataLength) == CodeAck)# A4 z4 C. j0 {/ a" c4 O
  531.         {
    ( m9 a* L: T$ P
  532.           timeCount   = 0;- p# l4 A' J) E8 k+ d& |
  533.           errorCount  = 0;
    3 K! D9 P# Y: c/ h8 u: T
  534.           dataCount   = 1;/ I% i8 t% c# G& @: u( O
  535.           code        = CodeNone;: Y3 v' t$ W0 I
  536.           stage       = StageTransmitting;
    ! N. ]" V- ^5 d' E/ [9 D3 F& ~) _; X
  537.           txBuffer[0] = CodeAck;
    9 N) s. @: p/ Z! n: n2 x
  538.           txLength    = 1;
    8 J+ T2 X+ U- Z( y: e0 _
  539.           write(txBuffer, txLength);
    ; D  h3 @' ~6 v" _4 \6 z
  540.         }
    & D1 l2 `' F, s) E
  541.         else
    $ `6 P3 H* S% b) p' Z
  542.         {
    , L. d( y1 M' d
  543.           timeCount  = 0;
    : e4 p0 F0 j, h
  544.           errorCount = 0;
    1 S, v" M; k5 F6 ^- r
  545.           dataCount  = 0;
    1 q+ Q0 _0 H3 w' C$ o' [1 z
  546.           code       = CodeNone;
    7 r8 y9 `% x( b+ L
  547.           stage      = StageNone;
    2 ^; Y/ U5 ?: t- f
  548. 0 B7 Y4 b* I; D9 j" g! l1 e; ^
  549.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    2 y5 L; @$ O2 ~4 H4 @$ R7 m5 n
  550.           {6 t$ M# h$ B9 F1 E& I" {
  551.             txBuffer[txLength] = CodeCan;
    / [2 O3 G* M6 U$ G. l- M
  552.           }
    7 a) \; j: g6 ~* ^$ l  |

  553. 3 V  q4 g% P4 ~- a6 e  F
  554.           write(txBuffer, txLength);
    $ ~# H; `1 V4 d" C8 h% K* N
  555.         }: i) y, N# n2 t! `
  556.       }/ W; a$ H; m9 n
  557.       else8 z2 ^2 x4 c' l, @8 C/ |# C
  558.       {$ A9 L9 O& J" b) p
  559.         errorCount++;
    5 X0 T* [: H) S, R6 Z* D/ n5 Y

  560. 6 R6 A5 }" u+ C5 U5 f- t( |& }9 l
  561.         if(errorCount > errorMax), t  i( I5 I4 G
  562.         {
    $ Z' @9 m" C6 s3 b, p+ k" z
  563.           timeCount  = 0;9 q  S. D( ?& D! p0 @/ C$ b
  564.           errorCount = 0;
    / l& J4 q& U1 h' O3 w
  565.           dataCount  = 0;
    1 g& J7 n1 S  a4 p. ]
  566.           code       = CodeNone;
    7 w9 o" E. j8 E! |# M! f
  567.           stage      = StageNone;8 |3 Q; `; [: W9 d& B

  568. # `5 H1 M% R4 U8 ^
  569.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    ) H3 l6 A2 h& l1 X& O/ a' \
  570.           {
    % |- L* y9 Z: I% W! D% V) p
  571.             txBuffer[txLength] = CodeCan;
    + r+ ~1 w( T, B- K7 N' E
  572.           }( j- {/ E: u9 k- B3 \

  573. & y# N! S4 X& i/ M
  574.           write(txBuffer, txLength);7 f- `5 Z% w3 n8 V: E
  575.           callback(StatusError, NULL, NULL);  i8 Y6 W0 a0 V+ D3 F, A
  576.         }
    ( h. B/ E: S# y3 E# J( r
  577.         else/ M  f6 O. L8 f( P. h7 k
  578.         {3 q. r: M/ `& Q- v% n* x3 W
  579.           txBuffer[0] = CodeNak;" b( b' b' j# r: b8 }7 `% K' {1 _
  580.           txLength    = 1;4 B3 E! c* l3 o* f) a$ ^+ D
  581.           write(txBuffer, txLength);
    ; M, C% b5 Q7 \4 v8 g/ h% {
  582.         }0 P) K8 }* c' A; f* n7 n+ b9 ?; N
  583.       }, V; |# x+ y7 ?5 Q2 ?+ Z& Z
  584. 7 R# H/ Y. U5 m# I* x- J; \9 n
  585.       break;
    ) J+ S  j  A$ w6 U5 s
  586.     }& O3 e  ^& O( B! {" \0 M7 ~

  587. + r+ z$ M) S3 k
  588.     case CodeStx:
    8 D, W( a) p" o, ^
  589.     {( l3 x7 s+ r8 }7 J( |
  590.       uint16_t crc = ((uint16_t)(rxBuffer[YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - 2]) << 8) |
    * v  G2 Z( N, Z( ~2 A7 M1 W! S1 d3 V
  591.                      ((uint16_t)(rxBuffer[YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - 1]) << 0);
    : y5 K9 j% @) _, a8 N6 M  q; _
  592. $ S6 ^, U) E" u8 S# B
  593.       if((rxBuffer[1] == 0x01) && (rxBuffer[2] == 0xFE) &&
    ( v$ A: d" M: G: Z3 j7 n6 w: U$ @
  594.          (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_1K_SIZE)))
    2 P! x9 }. L' ]6 z5 z7 r1 A! r
  595.       {. x2 E/ f2 E: S, _  ^6 i& H
  596.         uint32_t dataLength = YMODEM_PACKET_1K_SIZE;
    ! K) Z8 t6 P2 h/ H' W) f: @

  597. 4 [9 V: q" ]  a3 O) R
  598.         if(callback(StatusTransmit, &(rxBuffer[YMODEM_PACKET_HEADER]), &dataLength) == CodeAck)& r+ T3 _7 c: S7 e% T! s
  599.         {% \- \5 D) `$ B
  600.           timeCount   = 0;
    , u. `) E4 K0 X, L6 o: `# o
  601.           errorCount  = 0;$ f4 e" b) w5 u. V
  602.           dataCount   = 1;* Q5 ]9 X# i- \( c4 ~7 V. q$ J
  603.           code        = CodeNone;
    4 s/ P$ L* p1 N) U) c) w" J
  604.           stage       = StageTransmitting;
    % Z- f) o" A9 T
  605.           txBuffer[0] = CodeAck;
    ' z9 V4 A* _# v3 E# W8 w# n
  606.           txLength    = 1;) Q2 j# S2 D( E$ j3 G: m2 \! ^
  607.           write(txBuffer, txLength);+ q3 O- f' |2 H8 }" `6 x. J' P
  608.         }
    8 b. z' c" R" R7 z, b1 n3 G
  609.         else: W$ v: {8 _, |  k2 b: G9 M7 {
  610.         {
    . t* z0 t( R- F- J/ J
  611.           timeCount  = 0;
    , b: N2 f0 L6 h  k
  612.           errorCount = 0;
    ' G  a  P: r0 f6 F$ U% Z" ]
  613.           dataCount  = 0;' Z  r4 b* g! y0 D, T
  614.           code       = CodeNone;
    8 c& K# z- ^* r/ b, J9 {
  615.           stage      = StageNone;) c: A' u" d; @" h
  616. / _, Z; N: l' ?$ ^& G( u
  617.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    $ J8 i9 z' D, m, A; _: r% v, G
  618.           {( e% g! I4 i# |$ d
  619.             txBuffer[txLength] = CodeCan;" t/ ^1 m6 S; J% S% r" Q/ y, N. X
  620.           }: b* k$ J0 v. }* u/ i! ~
  621. ( R7 M# O  K) p' W
  622.           write(txBuffer, txLength);! t& {8 l2 ?2 p5 ?
  623.         }" g( g; E3 t, O! u  r( i
  624.       }
    0 {* U( d- G6 ~0 E* F! e
  625.       else
    4 q$ s4 u4 E) S. }' B2 g
  626.       {2 n8 w1 `, C' X3 x7 S6 Q& @; \
  627.         errorCount++;
    2 N, \: X7 k  X" q% h+ j
  628. 7 B6 V4 U# V2 |( i, w1 A: v& W
  629.         if(errorCount > errorMax)# ?8 d  B8 e8 x: Z5 j
  630.         {2 O8 @0 ?; X# C$ W
  631.           timeCount  = 0;
    5 L& g& U1 c. B5 c1 y3 K+ X# V
  632.           errorCount = 0;& @( O& v5 M7 Z; s8 L3 z; T
  633.           dataCount  = 0;
    ' S- @! w, A6 m+ k: {. T
  634.           code       = CodeNone;4 m; ~9 ?8 j/ T) |3 u+ a
  635.           stage      = StageNone;5 U- R3 l/ m/ q$ s! i  ^- P% |
  636. ' ^4 g+ e/ E) G, f, Y+ R$ ?* A
  637.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)* J- s6 c% {; S* x( j9 v
  638.           {
    7 Z8 _$ G" J! E" C6 f
  639.             txBuffer[txLength] = CodeCan;
    $ N8 f, p9 `% Z  M
  640.           }
    - j& O: P8 v; e( ~; p# S1 ^
  641. ! i6 K3 g' H) W' R; `0 e
  642.           write(txBuffer, txLength);, R* j8 ?+ v6 l' @: t
  643.           callback(StatusError, NULL, NULL);
    ( k9 [. X# z% p( d5 Z& o6 e1 o9 E
  644.         }1 @2 B$ i" p. t1 p
  645.         else3 L2 T2 n/ G% J+ a$ S& M7 X
  646.         {
    - K% G1 h9 [$ I( S4 \. H+ U
  647.           txBuffer[0] = CodeNak;
    * Q% i6 k2 g2 I  P. @
  648.           txLength    = 1;6 ~$ S& A! j  ~7 i9 H# h# \2 y3 E
  649.           write(txBuffer, txLength);
    5 S9 a; N) Y- k+ m# y" C" Y- `! M( q
  650.         }: m. O" f7 I8 F
  651.       }
      S6 e% V8 w, L/ Q2 w8 h7 o
  652. 1 f2 z/ I% ^! O% f
  653.       break;- W* ]' ~, y1 T- ^7 r* n
  654.     }
    6 f! c5 x0 J0 A. ~

  655. / M) J; F1 M, I6 r
  656.     case CodeEot:, t* Z5 }1 e- [  b
  657.     {
    5 l' b4 V8 c+ m3 L
  658.       timeCount   = 0;
    : \  ~2 `9 H6 B" ?6 G
  659.       errorCount  = 0;
    ) ^8 P! x& ?, |' @5 P
  660.       dataCount   = 0;- d& E* |; o$ P( x5 U3 N( I" ~
  661.       code        = CodeNone;* P! M, _! t; k  h. T
  662.       stage       = StageFinishing;
    , w6 J) _/ b' k* f
  663.       txBuffer[0] = CodeNak;( o  A) r6 R4 d0 w* ~) ?
  664.       txLength    = 1;
    * t# \- e, I$ m5 x* f7 y
  665.       write(txBuffer, txLength);
    ( }9 s. z" }  ]
  666. + `( j' g* @* y  u4 K1 i, T
  667.       break;7 C4 T4 E$ D# G. s" _& T& V" t, A6 L& V
  668.     }
    6 o' t# J: ^/ w8 t) p: H
  669. & L% H# v' W8 g+ z- P
  670.     case CodeA1:
    ! C$ R+ J9 m+ j, G1 U) G
  671.     case CodeA2:
    $ O: ^1 }! h3 u8 o) o4 A% J- W/ V
  672.     case CodeCan:* ~- ^* t+ X' X  [6 E6 i
  673.     {
    , f6 E1 M$ d5 g* e, x
  674.       timeCount  = 0;7 T. U$ f, g, N9 g- g% b" ]2 g
  675.       errorCount = 0;; t5 h; U9 N+ n/ ~$ L2 P" t8 `; X
  676.       dataCount  = 0;
    3 Z( x! Q, G5 X2 [! L; Z
  677.       code       = CodeNone;: C) Q  {7 y& h
  678.       stage      = StageNone;
    ( K* L" _  n4 ]2 {
  679.       callback(StatusAbort, NULL, NULL);9 E) \) t, Q# }8 z, w/ W
  680. / R! J; ?2 q& k( b2 x0 o* S
  681.       break;2 b  m+ ]! f' L) H* x: m
  682.     }
    * ]: A* A1 f. b" ?
  683. . [$ `, ]) G3 n' Z' x
  684.     default:: b; @/ x8 _& \  @4 k
  685.     {
    . b0 b" k6 U. m% r/ n+ g% h7 O4 q" A
  686.       timeCount++;
    4 r  U8 y3 }  Z" }& s- l8 u9 {" S
  687. " v# l2 P" n) y
  688.       if((timeCount / (timeDivide + 1)) > timeMax)
    0 a( s. r6 {+ w; `( L4 m
  689.       {+ k" t6 }1 Z6 B! n' M
  690.         timeCount  = 0;
    : }2 A2 `9 x3 `- y( g* Q
  691.         errorCount = 0;
    4 E! V* i& u# w0 y3 s
  692.         dataCount  = 0;. f; c" _3 w" l6 }! J# ^
  693.         code       = CodeNone;
    ) {7 @  j  m1 |. x
  694.         stage      = StageNone;3 c5 k) @: Z" H6 R% h

  695. ! T: F# g8 S0 o: N8 Q
  696.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)! H! @. z1 _% [
  697.         {
    $ Z* i& M' b% ~% P1 V2 S
  698.           txBuffer[txLength] = CodeCan;
    6 Q$ _( T& ?9 a1 U- k7 O
  699.         }; ^0 D6 X# G0 n4 Q5 N

  700. $ u) {9 y2 p4 A0 X! z1 U# g
  701.         write(txBuffer, txLength);- b" l! m0 k# l/ n) O) k3 y, W+ c$ u
  702.         callback(StatusError, NULL, NULL);: p& H( X/ C% M" g6 R# h. q
  703.       }
    * E8 T5 M; ]3 O) J  T
  704.       else if((timeCount % (timeDivide + 1)) == 0)' [1 l5 @$ T, {1 Z
  705.       {
    . f6 |4 t' z6 K) w5 `
  706.         txBuffer[0] = CodeNak;" D: F4 G4 ^' ?) B8 N  n
  707.         txLength    = 1;
    , d7 w7 X5 n/ a& Z, w5 S1 E5 T
  708.         write(txBuffer, txLength);
    ; \; O1 `8 ~* O3 s1 @
  709.       }( D' \  p/ `: Y
  710.     }
    & Q9 y/ O0 B8 m
  711.   }  n2 v" b$ J2 E! m3 k1 ?
  712. }
    & L0 o  Z7 V# k1 o- g
  713.   k4 l' ]' F7 |6 v  ^
  714. /**
    % _) a0 D& i4 C
  715.   * @brief  Receive transmitting stage.. x' K) o8 W7 g5 h0 `2 p6 y
  716.   * @param  None.
    $ @2 g2 O3 r  l( y# [
  717.   * @return None.
    ) W! H0 j5 o) d7 c1 [1 c9 {/ Z3 O4 B+ s
  718.   */
    # y' E/ n4 z6 @% c" T4 i
  719. void Ymodem::receiveStageTransmitting()
    4 Q' E  l& k2 Z2 V
  720. {
      }% v( Y6 R. y
  721.   switch(receivePacket())3 E; \: a5 q2 l% R& Y# w6 U9 [( j0 w
  722.   {
    2 \8 f4 Y; T4 J( Q7 r
  723.     case CodeSoh:0 ~* W4 r, C4 Y1 m& \( n* t; J0 R
  724.     {0 f. a6 r# w- Y0 c( ^! ~! Z
  725.       uint16_t crc = ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 2]) << 8) |
    " G) p* S! h' }& ?& c1 z3 }6 _6 O
  726.                      ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 1]) << 0);' R6 g! |8 [3 O) s% B

  727. 7 [! e8 v1 m5 t* J% W5 T1 i& O5 j
  728.       if((rxBuffer[1] == (uint8_t)(dataCount)) && (rxBuffer[2] == (uint8_t)(0xFF - dataCount)) &&
    " n. l2 k9 P0 K* D+ k% o
  729.          (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_SIZE)))' Q' c# l' |8 N' _. g
  730.       {
    ; y6 b! i* M+ i9 y2 h( P
  731.         errorCount++;
    & C+ @( i: e$ p7 X2 b) M

  732. - S8 E  @% }/ X
  733.         if(errorCount > errorMax)
    / H+ X. ~5 N2 ?8 Q! @- e4 H
  734.         {
    ; t; a! |. _* K0 j
  735.           timeCount  = 0;
      d, l5 j) {2 S. c9 j4 ]5 L
  736.           errorCount = 0;
    1 T: I& m4 e$ H+ b
  737.           dataCount  = 0;- `. T* q9 {% @% N8 Q
  738.           code       = CodeNone;9 t* M# e! ^, q. N4 T, n
  739.           stage      = StageNone;4 H) W% {9 N; p$ H0 G9 C
  740. 5 y) |& ~0 B! |9 R& D/ P9 ?. \
  741.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)5 O" j5 l: C/ j4 r( B0 U* ^1 _* T
  742.           {3 @* N( F& ^8 r, m/ V6 h
  743.             txBuffer[txLength] = CodeCan;+ M% x; P+ m! {$ C- `& l
  744.           }
    3 j  d  E; \# N
  745. 3 R7 x& H* m6 |5 L: [; j
  746.           write(txBuffer, txLength);( Y& k" z0 Y. e. z' l: _( z
  747.           callback(StatusError, NULL, NULL);
    / R' s, h& B- c% Y+ {; a
  748.         }
    3 G6 h* _* c* B
  749.         else
    5 r' M( r8 {+ ?
  750.         {
    / O5 X; i2 K+ X$ x! q/ c: E" _  W4 W
  751.           txBuffer[0] = CodeAck;% y" z2 o! b% d, Z5 Q2 p/ @
  752.           txLength    = 1;! a% {/ C1 i1 l4 o( p( Z
  753.           write(txBuffer, txLength);
      T. X# x$ n7 v
  754.         }' X5 J0 i& e- U
  755.       }6 b- W( ^; ]  Q3 F* t8 I
  756.       else if((rxBuffer[1] == (uint8_t)(dataCount + 1)) && (rxBuffer[2] == (uint8_t)(0xFE - dataCount)) &&
    ! k& a% J" l9 T2 s  k
  757.               (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_SIZE)))/ r* k9 I) P* S% }6 X
  758.       {
    1 A* E- E' _$ w6 m( K
  759.         uint32_t dataLength = YMODEM_PACKET_SIZE;
    * G. g$ @: @  ]7 G; \0 M

  760. , b7 i- v. Y5 y
  761.         if(callback(StatusTransmit, &(rxBuffer[YMODEM_PACKET_HEADER]), &dataLength) == CodeAck)
    ; n# U  B( v- C0 t6 @) e" \1 q8 R
  762.         {
    % Z& K& y% a) P0 @1 o+ P
  763.           timeCount   = 0;
    # P( D8 }( Q- \
  764.           errorCount  = 0;
    + |+ N* {0 S4 f
  765.           dataCount   = dataCount + 1;) q$ D+ h1 p7 V. j) q1 e0 q, M
  766.           code        = CodeNone;
    ! Q) ]9 [2 F$ |
  767.           stage       = StageTransmitting;  z7 Z# u; Y! [- J" N( l. f1 R8 s
  768.           txBuffer[0] = CodeAck;
    " t/ h: a3 H8 `- M6 ^
  769.           txLength    = 1;$ S9 W" J, {3 m, c+ C+ E9 }
  770.           write(txBuffer, txLength);$ g* P/ S& K/ G# p7 ^0 }
  771.         }
    6 f8 R0 f4 w2 x5 G8 }$ k$ m- h
  772.         else$ ^3 d7 p2 m' E9 }$ `, F
  773.         {
    3 i2 b# X6 b: t. r' V( J9 |
  774.           timeCount  = 0;
    / U5 n4 T! ~/ |/ k" K/ t: C4 a# x
  775.           errorCount = 0;
    , {. [4 M, f+ R- W7 C
  776.           dataCount  = 0;2 `; w4 Y  o4 L# e, E
  777.           code       = CodeNone;
    ' K" p" {; y! }  Y$ m
  778.           stage      = StageNone;
    ; P& h9 ~4 e, n, P8 K* ^

  779.   c8 M0 x1 k' K9 \
  780.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    4 l; J' n8 G1 L
  781.           {+ T$ ]: h1 _6 m3 D, r' {# S4 m
  782.             txBuffer[txLength] = CodeCan;
    9 s# s: ^& |1 X# l# p) ~, J; ]+ c" ?
  783.           }: @% n  r2 M6 s6 E; R
  784. * t9 A, R) F- d2 a6 @' L
  785.           write(txBuffer, txLength);
    2 d0 D" F  `2 _8 k
  786.         }
    0 c/ i% `: }) r; F5 p  ]' m/ ?2 S6 Y
  787.       }8 F# ]% L% K# a7 A
  788.       else% i) u' c" b  z0 i, K! n" D8 |
  789.       {
    8 b6 }$ e" U( p8 {. C' U
  790.         errorCount++;6 p# H  C9 A1 I) D
  791. + `! ]! {2 q$ x, R, ~8 G' e
  792.         if(errorCount > errorMax)- n/ y) m% y9 z' F0 s
  793.         {1 O7 n  A2 w: q, i& z
  794.           timeCount  = 0;
    $ q7 {) g7 U! {5 m2 ^- Y8 w# ^, ?
  795.           errorCount = 0;' e- [. U, L9 v% N$ g( C  T8 j$ a  V+ ~/ Q
  796.           dataCount  = 0;! P9 W* f, @7 p: o- g2 A1 M
  797.           code       = CodeNone;
    ; H* A2 X. }7 ]; z) k. o
  798.           stage      = StageNone;9 S- A! y" l' j5 G5 ]
  799. % b  X" T) K3 z
  800.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)* E! Q! x; O$ l" L! z$ B, Q
  801.           {; I+ g5 ]* u+ F. Y9 l2 d' Y8 k7 j- p
  802.             txBuffer[txLength] = CodeCan;
    # d/ V' S; S5 q# D8 y
  803.           }
    + k1 u0 c0 h' Z+ N

  804. 6 V  A9 o7 p! ~6 v* D9 g
  805.           write(txBuffer, txLength);
    ; @) e2 u/ W& N' R
  806.           callback(StatusError, NULL, NULL);" B5 X  W- K: H  J1 I: p* c
  807.         }
    0 k6 _& v) Y2 F' O
  808.         else
    2 b# X$ d2 T# m" b$ A/ V
  809.         {
    / D5 N4 n8 W1 Q2 w: B
  810.           txBuffer[0] = CodeNak;. \9 \4 L5 F. _' c) Q- D& [% q
  811.           txLength    = 1;
    $ |' I' z* A- _1 I% v% d
  812.           write(txBuffer, txLength);
    ' @: |; M) E+ {6 S
  813.         }" ~" c! j, w1 c" L5 x+ J. q
  814.       }) {. V& O. `% y; K2 v- Z8 E

  815. . n8 e/ ?' J# r7 r4 ^+ d7 L
  816.       break;
    8 v8 e$ N% n, q# [
  817.     }. S0 O0 d/ B+ A5 t4 {  n
  818. ; ^, i# t, H& Q  n
  819.     case CodeStx:& x) |) E" J$ n6 e8 Z  P( t
  820.     {
    7 p# a# D3 i- G, g) I
  821.       uint16_t crc = ((uint16_t)(rxBuffer[YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - 2]) << 8) |
    ( a/ r1 y; ~7 M
  822.                      ((uint16_t)(rxBuffer[YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - 1]) << 0);$ O) P; o" e  E% b* K' j/ Q
  823. 5 O2 D4 _7 Q" ~9 B4 Z
  824.       if((rxBuffer[1] == (uint8_t)(dataCount)) && (rxBuffer[2] == (uint8_t)(0xFF - dataCount)) &&$ J9 y! Y; ]( G
  825.          (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_1K_SIZE)))
    8 K. T6 y3 ?  b6 G
  826.       {
    ! h5 y: N$ `7 u% {- X8 u' r4 H
  827.         errorCount++;0 ?! ?8 c3 V/ C  M8 y
  828.   P  c$ T0 U8 o9 t- {
  829.         if(errorCount > errorMax)  }4 \& ^* D: i. U3 c$ I0 w" p, X
  830.         {
    ( K7 l' ~) r7 z  X( s
  831.           timeCount  = 0;7 a2 B  y5 [" L; g+ {' ?& Z
  832.           errorCount = 0;0 v& }, Q$ K' M$ f' w& l2 ], W9 |
  833.           dataCount  = 0;& c( J6 D* Q2 O0 l& P
  834.           code       = CodeNone;
    7 A+ a. F% P' _2 O; S# J
  835.           stage      = StageNone;  ?6 a5 E. j  c3 I; m2 O

  836. & ]1 m. e! E9 `- P6 _
  837.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)' @/ I$ _1 L) r* F) M: ]
  838.           {" C# \$ @. s+ G4 b# ]) N1 o8 e
  839.             txBuffer[txLength] = CodeCan;- u' f6 V3 {& o* M
  840.           }
    % j* p8 l' F; M% Y, z2 B7 U0 A' Y

  841. * L" T& J9 X* y* y9 P2 c4 i& A
  842.           write(txBuffer, txLength);
    * |$ b6 ]3 S; I. t6 {9 h. k
  843.           callback(StatusError, NULL, NULL);, T( _, }5 ^6 Y1 o8 e. |& @
  844.         }
    4 U" ^# `5 ]2 Q" U# C: c
  845.         else. A, e5 _& {% X* l( o; D
  846.         {7 F' C* e7 H  m6 p+ P8 ]. R  C- ]- A
  847.           txBuffer[0] = CodeAck;
    8 F7 `% Y7 K; r1 q8 u, ^
  848.           txLength    = 1;
    0 I1 \4 `  l  f/ R1 u/ T1 w
  849.           write(txBuffer, txLength);4 ~2 M  V$ t1 e% z7 F4 s! v
  850.         }
    9 d3 a4 U$ K. X
  851.       }
    / X' G3 g# h! t9 D. F
  852.       else if((rxBuffer[1] == (uint8_t)(dataCount + 1)) && (rxBuffer[2] == (uint8_t)(0xFE - dataCount)) &&. Y% O7 x  Z+ z6 J/ t1 v$ F  P2 o9 k, ^
  853.               (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_1K_SIZE))): C5 V2 Y( m9 W/ h/ M+ l9 e
  854.       {5 `4 q" G/ d, |1 H* Q' R; e
  855.         uint32_t dataLength = YMODEM_PACKET_1K_SIZE;
    - k, p8 J7 n1 W5 ?5 O3 d
  856.   |% o$ u8 L- X+ X# E
  857.         if(callback(StatusTransmit, &(rxBuffer[YMODEM_PACKET_HEADER]), &dataLength) == CodeAck)
    # L; i5 n( l& x8 Z" I
  858.         {
    & _+ D" O- @& D$ L; ^2 _. b# W
  859.           timeCount   = 0;9 [& x1 k' b5 Q
  860.           errorCount  = 0;/ S+ K6 H) o3 ~! g. `, I2 P8 e# S
  861.           dataCount   = dataCount + 1;
      |! e& k) \' s8 a3 r. t+ U
  862.           code        = CodeNone;
    & C; Z+ {; k; E7 d2 Q9 j! {4 T6 p
  863.           stage       = StageTransmitting;; v! e5 d7 ?/ V7 B
  864.           txBuffer[0] = CodeAck;7 i5 m0 I7 M5 |) ?1 N
  865.           txLength    = 1;
    - ?' Z% E9 |/ W9 L
  866.           write(txBuffer, txLength);
    0 L3 |" l9 E4 R& s/ W' y
  867.         }
    3 G: ]) \0 l0 Q) v" V! [
  868.         else, u. s1 C2 J9 S
  869.         {
    1 y: T2 l. `' T, O
  870.           timeCount  = 0;
    . @$ I6 {" {6 K
  871.           errorCount = 0;
    8 X/ F: \9 N; @% U1 ]+ h
  872.           dataCount  = 0;
    8 j/ k# C" J  x) G; ?7 F# u. g; i  d
  873.           code       = CodeNone;
    4 {; s# W+ X) Z* |
  874.           stage      = StageNone;, ]; W: R" \% E; i9 q9 _

  875. 0 C/ r9 r. z: k( {$ `
  876.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++); _. U& o7 V1 \/ R# }
  877.           {1 ]2 A1 H6 ]* _! {4 B* a. U
  878.             txBuffer[txLength] = CodeCan;
    & v) }- |& n% @+ P  H: r
  879.           }
    $ J" K+ M8 t* _+ B
  880. ' I- ?  K9 C* [) g
  881.           write(txBuffer, txLength);" j0 \. U4 ~$ U6 g; C9 L. U
  882.         }- q) @2 K2 x0 K5 j+ V: x6 w
  883.       }. W" X/ E3 u5 @  [1 C( w1 ~
  884.       else
    ) B  ]. c5 k! o0 ~
  885.       {
    2 g6 r+ o4 B, S) H. B
  886.         errorCount++;! g+ m8 a$ F- g# C, ~( M4 d8 c

  887. % M' C: _8 X/ w0 p5 O& i
  888.         if(errorCount > errorMax)5 o, H- y7 H, H5 ?
  889.         {
    6 g% n/ M# K0 }7 B
  890.           timeCount  = 0;! G$ f, K7 ^, t. k/ j9 k+ ]7 e
  891.           errorCount = 0;
    ! `* x  ~( F" N( j9 ?8 U+ R1 D
  892.           dataCount  = 0;! l. w& x9 V& B7 e; w" I6 j
  893.           code       = CodeNone;
    # y6 J4 c+ {+ M9 n" D0 z
  894.           stage      = StageNone;
    9 n, G* i& T, e- D6 e& z6 N

  895. / ~, {$ j% j# W
  896.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    8 q. E' @  Q- E0 g. `& m/ B( a4 R2 o
  897.           {
    , N  p8 A: k4 Z1 P
  898.             txBuffer[txLength] = CodeCan;( K6 i# p. w  [) |1 K% B
  899.           }" U$ w9 n) U( M1 m

  900. 1 p! O' l7 e7 d
  901.           write(txBuffer, txLength);
    " I* T. S+ g4 O
  902.           callback(StatusError, NULL, NULL);
    1 R! n8 P$ t- v/ e  d
  903.         }
    7 e  O8 L0 H1 m
  904.         else3 p' Q, k, [# O- B
  905.         {
    * b; N( z5 a# Q, N. I
  906.           txBuffer[0] = CodeNak;
    3 ^4 a8 ^) O% N) m+ [
  907.           txLength    = 1;1 c/ e+ ]8 Y3 o) q) A
  908.           write(txBuffer, txLength);
    7 F2 u1 u8 W, l, n$ p2 u. o
  909.         }" m" x3 A( i7 m" |
  910.       }
    + ^! ]9 V. C3 D2 Y2 R6 h
  911.   l3 V. C; Q5 p
  912.       break;
    , M4 q2 C/ `$ N0 \7 @$ }! s
  913.     }' I3 z: i% P1 {# A$ o

  914. 2 z9 g5 I, {3 H' V7 A5 {8 m8 z
  915.     case CodeEot:
    ' `4 ]+ b. f3 g; m
  916.     {  k; Z1 @; O. k( V
  917.       timeCount   = 0;) f9 d. D( B6 q
  918.       errorCount  = 0;
    + Q) p6 w; ^; z$ t
  919.       dataCount   = 0;
    ) ]: Q9 {' f/ L- ?4 x) b. e# \! v
  920.       code        = CodeNone;* [8 N% o: q2 `* E$ l
  921.       stage       = StageFinishing;
    . c9 n# ~  G  c, }
  922.       txBuffer[0] = CodeNak;
    4 t6 _, J! ~/ N
  923.       txLength    = 1;
    3 R, f- L- A& ^) d, C0 K
  924.       write(txBuffer, txLength);2 s, i( X( z  U! j, y" J
  925. 7 r' E2 R+ R% A3 I8 I. y
  926.       break;0 h8 Q+ A) L1 N0 S6 _. e+ ]
  927.     }
    1 U  E( c  Y# @+ x( B+ g' {

  928. ) h+ i  X% `, w
  929.     case CodeA1:
    + I; \" x9 k- i& y
  930.     case CodeA2:) N4 D( I: o" C4 K9 Y
  931.     case CodeCan:5 ?8 D* U7 e0 v2 x
  932.     {
    5 J! i& w4 k7 T) u; @1 d+ }# _" R
  933.       timeCount  = 0;
    7 x4 Q" _$ `" s, u
  934.       errorCount = 0;7 b  i. Q5 B7 i+ M/ w7 w& @
  935.       dataCount  = 0;  I; {, h6 Q, N2 u& M' v( m
  936.       code       = CodeNone;2 U/ ]) h' p& k! M9 W6 p& U
  937.       stage      = StageNone;$ B1 ^9 [7 T8 y& C. }- x
  938.       callback(StatusAbort, NULL, NULL);- P/ O) b- V3 _- @) B! m; n4 O

  939. ; K/ {6 x$ W# S, A! h
  940.       break;
    - r1 C) r8 g- P) J' Z* R
  941.     }; u) R- n) K/ `+ A7 t/ o; ]6 i

  942. 1 o% I1 I1 K) B4 M; e' F; _
  943.     default:
    9 g& X- S9 G8 ^9 N8 L
  944.     {7 d* N1 j+ i* r1 ]7 Z
  945.       timeCount++;
      E3 E, a" M6 z# I% m/ d" N9 h
  946. ( v2 @: w" V4 m4 \) Q
  947.       if((timeCount / (timeDivide + 1)) > timeMax)* j8 K. c8 s, H( m
  948.       {. V) g- l$ h* J3 h6 V& n
  949.         timeCount  = 0;
    ) V. j  u$ \+ |$ X6 ]
  950.         errorCount = 0;
    , }# j  E  A  g& v6 K: O
  951.         dataCount  = 0;6 n3 S" M$ S& B) ~5 C$ A
  952.         code       = CodeNone;( \& H- R3 ]6 f' r0 E7 Z
  953.         stage      = StageNone;* H3 U1 ^/ N# X: P

  954. 8 g4 {: F0 @8 t. I8 \
  955.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    6 o0 U5 Z! K* Z; j8 |
  956.         {
    / ~/ P/ |& u/ n
  957.           txBuffer[txLength] = CodeCan;
    ) W, H( o' {' J8 j7 M
  958.         }7 \# }$ [% ?0 X* c6 _* w- r4 m6 ~

  959. ( m  r, s8 t8 r+ {. a; o0 K
  960.         write(txBuffer, txLength);9 W) D4 Y7 r4 t0 @7 z) _$ X) d
  961.         callback(StatusError, NULL, NULL);! G. {9 r8 J1 ^( p$ a% g
  962.       }; R9 I' N* C% p# ^, {) H+ k
  963.       else if((timeCount % (timeDivide + 1)) == 0)
    0 m, ~3 I; I5 |" G6 q7 {( R) B
  964.       {- F' ]$ Z- U3 A! M
  965.         txBuffer[0] = CodeNak;+ V: `& X6 I6 U5 b
  966.         txLength    = 1;
      a! J6 W: F% [7 \+ C( M
  967.         write(txBuffer, txLength);7 @' }4 c* J4 `; m$ {
  968.       }
    / ~& D1 q6 A. ?
  969.     }
    6 i+ }& z" H- L( E4 q2 _
  970.   }
    4 d2 L# I9 b4 ]* G7 A  I& I) J; r
  971. }
    $ R+ Q8 V; `/ F) [+ O# i4 t( b; u+ N
  972. # e. h$ T* ]# k8 l
  973. /**
    * C0 M+ m7 D9 w( G! v, |
  974.   * @brief  Receive finishing stage.. t5 c# L( E3 P) G  _
  975.   * @param  None.) r2 |2 ~6 }5 X; |
  976.   * @return None.
    6 P5 W: u$ A0 x$ p0 o! l
  977.   */
    ! d: r6 `- V& z0 k
  978. void Ymodem::receiveStageFinishing()
    ; b. x4 f" d' _0 _
  979. {/ o' ^  Q7 A2 u9 o! K
  980.   switch(receivePacket())
    / |8 t0 Q7 F& D( I% b/ V8 g5 V
  981.   {* W; p2 M3 ?0 Q# @7 {  R2 }7 Q
  982.     case CodeEot:8 a9 v( J. G5 r4 j
  983.     {& R' Q6 U' e2 S- K
  984.       timeCount   = 0;
    ' I6 N2 j4 ]* y2 C2 c- _
  985.       errorCount  = 0;
    % Q  ?" G) U, X3 C4 w: g) i
  986.       dataCount   = 0;" C% ?6 F8 U9 M$ C  i
  987.       code        = CodeNone;
    : K- Y' l% l- T$ t7 q
  988.       stage       = StageFinished;
    ; F4 b% C3 f# m: ?3 m
  989.       txBuffer[0] = CodeAck;
      m$ _5 U9 Y8 a  d4 C  A2 X0 R5 l: n
  990.       txBuffer[1] = CodeC;
    8 l/ S2 R6 t* s( A& o
  991.       txLength    = 2;
    + a. t$ f5 y% `3 K7 [; U# X
  992.       write(txBuffer, txLength);
    0 I7 {( g( H0 O% G
  993. 1 I# J/ d, m* H1 ?" [
  994.       break;
    + X* A! P; s0 ^5 i/ m0 z' K: y
  995.     }
      `" {2 G2 @( \! M
  996. ' g* m+ m: v9 b/ Q7 t' K: X
  997.     case CodeA1:: @0 Z/ ^; |6 G3 a! U- h* n
  998.     case CodeA2:( X% }2 T1 }9 {- g3 T" j, R" ]
  999.     case CodeCan:
    ' S# k4 r, b5 M1 i4 c( V
  1000.     {* P2 @8 z$ R9 `& w
  1001.       timeCount  = 0;
    + A+ n  y' x1 @7 K! i  N
  1002.       errorCount = 0;
    * W3 x% Y% L& K( w% u8 O
  1003.       dataCount  = 0;$ g( |. b' e' |5 p8 g9 M& V) k6 N, p1 H
  1004.       code       = CodeNone;7 T0 W4 e! N. D' I  e. s* a* `
  1005.       stage      = StageNone;6 M- z$ J9 S# ^# X" a
  1006.       callback(StatusAbort, NULL, NULL);4 O# J- @- ?: W* t

  1007. # J& u6 {; q5 w# j+ v* _% U+ Z) G& W
  1008.       break;* S9 l  x4 _$ P( ~7 g
  1009.     }
    0 Q: N: @  S1 r  j. Z9 g

  1010. ; w$ v( l: e1 _/ l
  1011.     default:* k- D  u: i# u7 @* F
  1012.     {4 @0 t  a; P# R( W8 T# H" i, u. }
  1013.       timeCount++;
    0 ~( |' J! Y1 j1 K: x
  1014. $ ^1 F. t/ R! V; J6 J
  1015.       if((timeCount / (timeDivide + 1)) > timeMax)
    # Q) Q$ a: e# I/ {
  1016.       {
    . k6 K" R% [4 B, O" k
  1017.         timeCount  = 0;
    : c- h8 P$ ?5 N+ X$ G3 G" W7 ~; f
  1018.         errorCount = 0;
    % Z, f* ]2 f$ h8 {* q" C
  1019.         dataCount  = 0;! c. |( b  Q, O
  1020.         code       = CodeNone;
    * o4 A6 r; t; Q$ L2 }5 |
  1021.         stage      = StageNone;9 V, s6 v0 X2 |5 n: n

  1022. # F! |! P# T- B' ]7 I
  1023.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    6 H. `$ a8 T0 i* I# _. a
  1024.         {
    , b+ V' j) r9 A7 A+ S- |( _
  1025.           txBuffer[txLength] = CodeCan;
    , x  r( U8 U, a3 }/ s- l
  1026.         }
    4 u& j& ]1 G4 I

  1027. & a$ q9 v/ Q: y$ M3 h
  1028.         write(txBuffer, txLength);
    , @, [/ h8 c9 A. m" H% h
  1029.         callback(StatusError, NULL, NULL);$ H2 c8 S' ~; a9 R( C4 J
  1030.       }
    & N" d9 }: M8 ^( d4 y2 h  x
  1031.       else if((timeCount % (timeDivide + 1)) == 0)
      T5 b8 h; l9 ?5 f8 i% ?
  1032.       {& S/ M( L' y; A5 [) s0 j) X
  1033.         txBuffer[0] = CodeNak;' m, `" E7 h8 ^5 x4 u: C  s6 o
  1034.         txLength    = 1;
    7 \" {. x- I4 |5 t0 c* q
  1035.         write(txBuffer, txLength);
    2 P; K1 S% q. D, u
  1036.       }
    % D. _4 z5 w) }3 k" P: v
  1037.     }7 H8 X5 E: E) k* G% S
  1038.   }
    ! i2 V( ^" @) |# K0 A- P
  1039. }9 C; c* j0 Z* m- {1 q$ o
  1040. 3 D( z$ u. @& S$ g+ D8 q8 U# I
  1041. /**
    + L! h$ u% z5 H2 H5 e4 D, o
  1042.   * @brief  Receive finished stage.& o0 _+ i  J  J  N
  1043.   * @param  None.* f$ e: i4 s6 k4 E
  1044.   * @return None.9 ^5 r- \/ H+ D7 a8 z' J
  1045.   */% b9 L' }( K7 I7 Z: b- ]# c
  1046. void Ymodem::receiveStageFinished()
    3 B8 ~9 ?0 m7 u2 U8 x: ~
  1047. {% J0 Z4 \7 e% N- ?7 _  {2 e. Q" e
  1048.   switch(receivePacket())3 X1 ]( [3 ^& Y; }* w
  1049.   {5 v8 ]. K' |. Z) l
  1050.     case CodeSoh:
    + b: Q/ J: L" X" ]5 t; |0 \' ^1 f
  1051.     {
    & M& Z  ^$ T9 P1 v4 q- P
  1052.       uint16_t crc = ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 2]) << 8) |
    + y( r: k! V2 r
  1053.                      ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 1]) << 0);
    . G% O% L/ [- V+ b5 y) a% A  @) C
  1054. ' o. {* l4 j1 A
  1055.       if((rxBuffer[1] == 0x00) && (rxBuffer[2] == 0xFF) &&4 v# }" F* x. V& L2 ]
  1056.          (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_SIZE)))- F1 S; t; p$ ^: c+ A$ k
  1057.       {
      C& `: O9 J9 }/ V
  1058.         timeCount   = 0;
    " N8 Q8 O" H7 _7 \: q. t
  1059.         errorCount  = 0;
    ( U! V# G: R/ A' p8 Z, E$ }
  1060.         dataCount   = 0;
    6 ?% b1 z& @# o4 d4 U8 J
  1061.         code        = CodeNone;5 z- _4 r5 c& w0 O
  1062.         stage       = StageNone;9 c  E' h: v; f2 P' s: b
  1063.         txBuffer[0] = CodeAck;
    " R" \& d, R" G- s) p
  1064.         txLength    = 1;
    - m" x" i& L* O# E7 E0 F4 W% }# B% y
  1065.         write(txBuffer, txLength);
    4 [* u% R) |5 b/ D& _
  1066.         callback(StatusFinish, NULL, NULL);% [, N3 ^- z& ]
  1067.       }" \" v5 m1 `  Z/ @3 q* M! _2 O7 i
  1068.       else
    ' a$ d& `2 ]% T% C
  1069.       {
    . R0 I; a, ]0 M
  1070.         errorCount++;
    # |( \7 A) i: U
  1071.   h% r* A' I$ o7 C1 M. p
  1072.         if(errorCount > errorMax)
    8 X9 T7 U) ^3 q, W
  1073.         {. _5 M6 Z6 L3 ?8 V- g; ~/ W
  1074.           timeCount  = 0;
    2 T. ~+ W* f$ o$ l. `  X5 J
  1075.           errorCount = 0;: A+ {9 D# s, C  _. S/ Y
  1076.           dataCount  = 0;! O5 I0 W/ J0 I+ ~! o( @9 d7 C
  1077.           code       = CodeNone;
    ( T# d5 R( n" o0 [& C2 K
  1078.           stage      = StageNone;3 ^2 `; z; c- Q( p: {  V* G. p, I( _" w

  1079. 5 W4 B; ?# X8 t2 l, q- Q0 @1 U5 `5 m0 L
  1080.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    " `- M" ~  T, S* |8 I
  1081.           {) {6 A, _& v8 V3 E2 L! w2 s0 d
  1082.             txBuffer[txLength] = CodeCan;1 }3 @  s5 d. Q! \8 L% q- q% c, S: x
  1083.           }
    ' U6 T! o  U' o, g  P+ u2 D' X
  1084. + S6 H5 j* g4 p  p
  1085.           write(txBuffer, txLength);
    - P) a" Q7 T) L& M+ c( j
  1086.           callback(StatusError, NULL, NULL);
    $ c5 J4 m$ L& G& G
  1087.         }
    & t7 Y) b/ m& B# f
  1088.         else% ]$ p( Y6 i7 Z& `0 x8 Y
  1089.         {
    : R* h1 f* V/ j2 n8 A
  1090.           txBuffer[0] = CodeNak;
    8 e2 b1 h2 z1 |' w9 ]% |0 P
  1091.           txLength    = 1;' b9 X8 ^2 b; ]
  1092.           write(txBuffer, txLength);
    9 u0 q$ B/ O2 T9 X7 z
  1093.         }
    8 X: m, n; {" r: U# w" B
  1094.       }
    4 \" {: w' K, `
  1095. ; c- X$ J# L  x' e
  1096.       break;
    % w9 k- S7 k1 Q3 I+ K
  1097.     }5 G1 r6 O& O* A

  1098.   [9 z* h9 E8 ]6 g+ n
  1099.     case CodeEot:& S8 n& f0 `! b8 t  h/ Y
  1100.     {# Z' O. h- y9 L% ?9 q
  1101.       errorCount++;
    2 m+ k1 C( c3 I% i5 f
  1102. 7 r& p! ?; z$ H0 X
  1103.       if(errorCount > errorMax)( I; f) [" O% q9 e
  1104.       {
    5 F, O" S: l: H# g4 e; o; H/ w
  1105.         timeCount  = 0;- }6 |$ D2 E. w& [) h
  1106.         errorCount = 0;
    0 \  ]0 X# ~& }: O1 p( E$ S0 u
  1107.         dataCount  = 0;  c/ N5 X/ i5 v& N6 m0 I/ j
  1108.         code       = CodeNone;+ b# z- u, Z0 Q, L6 w+ h- y5 a  j9 P1 A
  1109.         stage      = StageNone;
    5 y% s4 W. [. t/ d( J

  1110. & c* ~4 h4 q+ E! e
  1111.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    # M1 n9 u' ?" w( L. P9 `
  1112.         {
    ! C# |$ g0 {! g3 g- r
  1113.           txBuffer[txLength] = CodeCan;
    : E) d9 o9 }0 S3 g" X0 L  ^
  1114.         }" U' s% C, c. v6 c8 [. X  R/ b
  1115. % Q4 Z9 l# z! R& s) g. O
  1116.         write(txBuffer, txLength);
    2 q; w  j! T9 c$ U
  1117.         callback(StatusError, NULL, NULL);2 L* Z9 c& C" N) k& X$ U
  1118.       }
    - \, v0 j% D" M$ o+ Z0 E
  1119.       else9 I& R* y; D4 ?' O) t
  1120.       {
    & B3 p; P, T, I2 I
  1121.         txBuffer[0] = CodeAck;
    3 R( J/ a# }% E! L8 \7 H( j
  1122.         txBuffer[1] = CodeC;9 X/ u. L0 Q( _$ a! Y
  1123.         txLength    = 2;
    & G9 G5 p7 F* R2 H" O
  1124.         write(txBuffer, txLength);5 m8 B6 K9 n& i" z3 Y
  1125.       }
      D" ?) u5 S& o! W4 [

  1126. 7 \/ J6 v3 c0 _( G+ J4 h7 x1 t
  1127.       break;
    7 `$ D" O" X+ T: w' J  k4 w. u/ b
  1128.     }% L7 _. `# D0 n& @! q. l: V0 O
  1129. & g6 ]! F# P* U; ~4 R3 N/ H
  1130.     case CodeA1:% Y8 N3 h* y4 i, S
  1131.     case CodeA2:( `4 D9 r6 z! F" X
  1132.     case CodeCan:
      Q) H# a0 v$ U$ h  j6 I
  1133.     {
    . Z# ]  n% J6 q4 B
  1134.       timeCount  = 0;
    0 H' L: a9 g% t, p
  1135.       errorCount = 0;6 g  ~/ \. }' D! _
  1136.       dataCount  = 0;
    7 y  Z6 o5 p4 P: d: Z
  1137.       code       = CodeNone;
    $ O0 U! i" A7 ~' H' g  R
  1138.       stage      = StageNone;' A5 X" D: p- l- |" h4 v
  1139.       callback(StatusAbort, NULL, NULL);
    2 @/ ?( t. A4 v

  1140. , `0 u3 q! k1 D
  1141.       break;
    ( k: G* W) x3 N2 c8 {1 J0 q  S- M% O5 p4 W
  1142.     }
    0 C7 g3 G/ ?) m% a+ i/ x

  1143. . K4 X" Y8 A. I9 q' K% ^  _# O" }  R
  1144.     default:/ A: e$ U& e* q* R1 @' {6 T
  1145.     {7 N% ]  ?' a- z4 m
  1146.       timeCount++;
    0 u, d8 P! q. U6 C
  1147. ! D7 U# c3 {  ~. d- w+ H1 t
  1148.       if((timeCount / (timeDivide + 1)) > timeMax)( z# a( U# C. V  }
  1149.       {
    * Q) N" J4 k; r0 G+ s0 Q- b7 F
  1150.         timeCount  = 0;
    0 I& t: F+ h1 @# f. A5 C; B6 H. `
  1151.         errorCount = 0;
    ' O% i' g) ]1 s! i9 G$ k) O' H
  1152.         dataCount  = 0;
    6 r. l( `# y$ v- x& B2 M
  1153.         code       = CodeNone;
    1 U. t$ Y. I9 e  p$ ^
  1154.         stage      = StageNone;
    1 Q2 z6 s# k, d+ U  o3 [# ^/ D& K
  1155. 3 `6 R6 T* k" ?3 U+ A
  1156.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)# }& S, W: h- d; C, n: a) p
  1157.         {
    6 g6 h+ d8 T4 F9 R0 Q7 [
  1158.           txBuffer[txLength] = CodeCan;
    / Q& V# l7 T! O( r4 S8 [) b
  1159.         }
    & f2 [( L" H5 V8 n/ p5 E3 r

  1160. # [% Y! }3 S/ Q1 f
  1161.         write(txBuffer, txLength);
    + b  h6 ]9 d) u1 E8 Y; U
  1162.         callback(StatusError, NULL, NULL);
    0 o+ |, D3 J# x1 z( U
  1163.       }- y( H  J0 Z7 ^6 i% t+ L# w
  1164.       else if((timeCount % (timeDivide + 1)) == 0)
    0 v! v4 I  |( ^. D! }
  1165.       {4 A! a0 ^/ M: s0 o% X9 O6 c; a  A
  1166.         txBuffer[0] = CodeNak;
    : r* @2 P( ?. {3 Z$ ~9 W  H
  1167.         txLength    = 1;
    3 D3 D# t2 ]+ h$ @# M
  1168.         write(txBuffer, txLength);; c) Z% E3 d! b; n9 s, s- y
  1169.       }
    9 L" t& _8 p9 o, A, n3 I$ W
  1170.     }3 N0 |. p$ g( x/ o; I
  1171.   }& Q& \1 S- F$ t
  1172. }/ v1 W8 L- e: f+ }* Q1 [; u1 \

  1173. ; w' d3 V% `& P. U: C7 \( e
  1174. /**
    & b( r" Y; D6 [$ p$ K6 z) {7 p' |
  1175.   * @brief  Transmit none stage.
    ' I* h. ^5 T2 _
  1176.   * @param  None.) j; D! Y" d1 f% F, u/ N8 i
  1177.   * @return None.
    1 w1 j6 p2 s3 Z" ?: n7 P
  1178.   */4 f; C8 x2 k8 D1 W. t4 l& \, P
  1179. void Ymodem::transmitStageNone()$ R6 w4 o9 i6 N( F
  1180. {1 V' e; P4 o  j! T
  1181.   timeCount   = 0;
    9 I' |( }, l( U& v9 }  u5 q
  1182.   errorCount  = 0;
    4 `% S6 a2 T. w$ @+ r" e% J
  1183.   dataCount   = 0;
    ; E4 M  N" S# v2 K
  1184.   code        = CodeNone;
    5 ]5 h6 d+ b9 x
  1185.   stage       = StageEstablishing;
    ! _5 p5 `4 X( R! b
  1186. }
    % j5 ^* F9 P3 D( O: Y) y7 e! j7 ~

  1187. 0 q' V+ g1 t" \: x! L
  1188. /**
    5 N! b+ ], A( v. a
  1189.   * @brief  Transmit establishing stage.: y! o/ I# l) \; z# b
  1190.   * @param  None.
    ' T% {  T7 q* x2 x8 m% e
  1191.   * @return None.
    $ r( T  v" w7 T  f& d
  1192.   */" ?6 c7 ^- j7 _; Z& O& g
  1193. void Ymodem::transmitStageEstablishing()1 A# j  J! `, z2 x) x2 a; n
  1194. {3 d# U: O4 s( I3 [
  1195.   switch(receivePacket())
    ' \5 d2 j4 k5 I0 B% k
  1196.   {7 m) y7 p; C2 B% x
  1197.     case CodeC:
      @2 V7 j5 l; c  _' N2 F  d
  1198.     {, Q2 m' M2 |5 h5 ^/ J( e5 t. L) S8 E7 {
  1199.       memset(&(txBuffer[YMODEM_PACKET_HEADER]), NULL, YMODEM_PACKET_SIZE);5 s0 b! v; r. u* X# L
  1200. " h) g4 [, k2 K3 k  X
  1201.       if(callback(StatusEstablish, &(txBuffer[YMODEM_PACKET_HEADER]), &(txLength)) == CodeAck)) U+ z6 |; H, t& W6 f
  1202.       {% C# C' ?! p& h9 Y
  1203.         uint16_t crc = crc16(&(txBuffer[YMODEM_PACKET_HEADER]), txLength);
    3 F. p' b% ]5 [) x) ]4 v

  1204. - Y$ L3 b6 f1 f3 ^" B
  1205.         timeCount                                       = 0;
    ) l/ J* s) R$ x5 O
  1206.         errorCount                                      = 0;
    : m0 q0 h7 H6 W3 g! q9 o' N
  1207.         dataCount                                       = 0;
    % I  n' T+ X+ ~9 u, ^7 W/ ~
  1208.         code                                            = CodeNone;
    0 v2 {. S; E* h7 z9 |& r- \
  1209.         stage                                           = StageEstablished;! \- T3 }+ K. f5 I! S) a4 T+ F0 V8 A
  1210.         txBuffer[0]                                     = CodeSoh;
    ! v, V1 |0 f$ C$ Y* S! \/ n6 X
  1211.         txBuffer[1]                                     = 0x00;/ ^" M# y, e* F( ^3 ~
  1212.         txBuffer[2]                                     = 0xFF;
    , C. a1 K* l( v
  1213.         txBuffer[txLength + YMODEM_PACKET_OVERHEAD - 2] = (uint8_t)(crc >> 8);5 @& _8 w2 P' B! d1 b
  1214.         txBuffer[txLength + YMODEM_PACKET_OVERHEAD - 1] = (uint8_t)(crc >> 0);& y# a+ F. Y! K' V
  1215.         txLength                                        = txLength + YMODEM_PACKET_OVERHEAD;
    * v- U3 B& R* Q
  1216.         write(txBuffer, txLength);2 a/ ]) z' v. R0 M! S2 _0 c
  1217.       }# }( T$ A7 @6 `5 o
  1218.       else
    " f2 p' l3 Z" X! |3 Y+ k, z+ S
  1219.       {
    / }: Q! X) _. T( y- R# d; {; `
  1220.         timeCount  = 0;9 X4 g& z1 ]& t
  1221.         errorCount = 0;
    6 i, Q- d  j& z9 }
  1222.         dataCount  = 0;% G. f! r, |+ k  J4 ?7 X
  1223.         code       = CodeNone;" Q8 g) W" _) v6 M# h
  1224.         stage      = StageNone;/ n  J- H6 K8 X
  1225. # r6 Q' N3 v  b9 Y- F" T+ ]+ o' U) W( g
  1226.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    / t$ i" K6 w: X6 a
  1227.         {
    , B3 u" `# ~: _8 [
  1228.           txBuffer[txLength] = CodeCan;: B7 B+ K+ v1 S2 _# |
  1229.         }1 A) T+ Z0 e6 D1 U6 T) G

  1230. . ]8 K3 a7 W$ [5 Y0 q
  1231.         write(txBuffer, txLength);/ [# N( [9 p' A% J: Z5 f
  1232.       }
    : H$ C/ ~3 Y" j7 F% X1 b

  1233. $ ^1 f' k9 h3 }( h8 b$ i
  1234.       break;
    - @1 c* F7 S$ B6 F+ }
  1235.     }* O4 r; w* _) B7 m( |

  1236. 2 Y4 b+ N6 d. }& D& o2 k
  1237.     case CodeA1:
    ; Z2 Q% E6 T, r3 ?
  1238.     case CodeA2:, r; P  x% n. y0 x8 |; U  A
  1239.     case CodeCan:
    " L" [0 M# ?$ k, K2 s  e$ x* l
  1240.     {
    3 C4 G1 M1 d- S' a& [
  1241.       timeCount  = 0;) Q! c! c1 b0 u$ L+ `. i% t6 W1 y- r" B
  1242.       errorCount = 0;
    ; @4 E4 @! z! y- g: J
  1243.       dataCount  = 0;* t: J" ?+ f" R+ M8 P1 r6 f
  1244.       code       = CodeNone;
    ) g* M* W6 L7 o: E6 D& q$ E" r
  1245.       stage      = StageNone;! o* q- z2 ~7 `# U
  1246.       callback(StatusAbort, NULL, NULL);! \. W- b6 t5 s0 l! H7 W3 W/ Q

  1247. " k( G) o2 w. |; G# E. m2 N2 R! U
  1248.       break;
    8 O. t) |5 q& D& @
  1249.     }
    # E& m8 Y0 `# {% [/ A4 U8 y

  1250. + Q' X2 m5 Q( W- ~- p* K
  1251.     default:, r$ h- P4 f) W+ q: m% }! C
  1252.     {* V. R5 o. Z& A: E9 t+ e+ o
  1253.       timeCount++;
    - g4 y# K3 m5 q( B* H+ H( w/ [% ~; W

  1254. : y3 @% T5 t9 o, Y% t# h  H& u
  1255.       if((timeCount / (timeDivide + 1)) > timeMax)
    1 f5 y7 `5 F: a, z% k/ j8 w
  1256.       {! p5 E8 C2 J; t6 f. b
  1257.         timeCount  = 0;
    9 j3 \+ p$ M, N) R& Y0 Q! W
  1258.         errorCount = 0;
    " b$ q3 G3 y! T" l
  1259.         dataCount  = 0;6 w6 [5 k5 P/ f$ w: _1 ?4 F$ p
  1260.         code       = CodeNone;
    + [& [; ^! k: \# T% w
  1261.         stage      = StageNone;
    ( O2 v5 u3 c0 M/ U- K, i4 G
  1262. + P( k' {. a6 m: r! c4 u3 G
  1263.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++); g# z- M) L$ D' Y! K
  1264.         {. c9 R2 Y6 X8 r9 e
  1265.           txBuffer[txLength] = CodeCan;
    / Q0 Y4 ]* m6 D: j5 i4 W
  1266.         }' n! b( w5 d: U- b9 h3 e

  1267. 8 `; R, L. q4 c  u
  1268.         write(txBuffer, txLength);9 J, Y) Y* N5 D4 H! Q
  1269.         callback(StatusTimeout, NULL, NULL);
    # u& F* d# \- ^' L
  1270.       }
    & R! J# x" K0 k6 F  X
  1271.     }
    % I6 @$ p2 s+ J; k  A6 o3 j
  1272.   }
      m1 w+ w9 T* _  T$ q9 @! s
  1273. }
    1 C8 a) j% B0 U& V) b8 p1 ]: o0 E

  1274. 8 m! y8 v" o; z# x. P
  1275. /**
    8 I' U" `7 [# X7 [* e; W; ]/ O
  1276.   * @brief  Transmit established stage.
    : U# x) Y, d* X3 j% u! w5 o
  1277.   * @param  None.9 e- L6 }5 R% Q
  1278.   * @return None.
    ! K9 X' l3 C/ }4 q& ^% w' L
  1279.   */
    - A5 R. ?, h1 J" a
  1280. void Ymodem::transmitStageEstablished()
    9 d! m" M4 G  `6 x+ b5 t
  1281. {5 \. w/ [$ h" v1 n: q
  1282.   switch(receivePacket())4 t, }3 h$ l8 ^$ y
  1283.   {9 U2 y0 C' r7 D# X4 X: y
  1284.     case CodeNak:
    * \$ @8 J" X* ~  k! a4 g5 Z. G' o
  1285.     {7 @0 a" `) V- K
  1286.       errorCount++;
    : D2 U! ]& f7 n' ^

  1287. 9 ?, U: T5 x# b$ V1 ]7 l( y
  1288.       if(errorCount > errorMax)5 _& a& w( J5 ^" @* ?% t
  1289.       {
      S, Y+ ?, }: A9 L
  1290.         timeCount  = 0;
    2 U& ]: I& Z) Y8 ]- z5 ~
  1291.         errorCount = 0;( Y8 V. i8 m' }
  1292.         dataCount  = 0;* f; o; Z  g0 K) H( B' ?+ y) x
  1293.         code       = CodeNone;5 N$ X0 Z7 M3 L6 X
  1294.         stage      = StageNone;9 I* w/ ]$ E* q, p$ M' d$ e* A
  1295. / F7 A2 h4 J' z. S$ \5 G
  1296.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)/ c+ Y5 Z8 b( P  j9 [# v6 a
  1297.         {
    / W  y% a- `0 t/ d5 T" M- g
  1298.           txBuffer[txLength] = CodeCan;# U8 \- O( l  ^9 |+ A. d, M0 H
  1299.         }" g1 D  }4 w/ i
  1300. 2 m7 x# I% }3 S0 |/ o: k: ^, h5 s
  1301.         write(txBuffer, txLength);3 q1 F) h8 p0 T. i6 \0 o( |; n9 h
  1302.         callback(StatusError, NULL, NULL);
    , a" ?; t! h. B8 c% N
  1303.       }
    8 p8 L; u+ }+ J. {8 Y7 U
  1304.       else' y5 m# I/ X) L( h) x
  1305.       {! [* l, {& d8 x( T: m
  1306.         write(txBuffer, txLength);( O7 |) a, D& _* I0 \8 l$ Z7 z9 r- @
  1307.       }
    # l& h, Y+ d6 G. Y+ b5 k# R2 W
  1308. 2 z9 ^( S: n) [0 l4 K: |
  1309.       break;; e5 a8 ]: t! w: @9 w
  1310.     }$ U% T: Z. e5 x1 V, R7 P: `) P
  1311. : M# c$ d1 l# b2 b
  1312.     case CodeC:$ c7 N/ e8 Y& R% r$ o6 J( i
  1313.     {1 a" u3 N) P3 D6 D, V, X2 X
  1314.       errorCount++;- \7 U9 w& e5 d. |2 V

  1315. , k5 z5 f. o2 S0 a
  1316.       if(errorCount > errorMax)
    - k+ Q+ o5 ?8 S+ k
  1317.       {* B7 V' [, [, c: q) T. o
  1318.         timeCount  = 0;: A) f; m' @* a4 i) r% [# w; g
  1319.         errorCount = 0;
      ?# W: X# q' v% Z
  1320.         dataCount  = 0;4 g: y0 o) [- u/ j( B5 u
  1321.         code       = CodeNone;* M% k- o; `: e0 x8 T* \' \! o4 A
  1322.         stage      = StageNone;
    7 V. S$ f1 V) l) e; k
  1323. 1 J6 n% y4 T, Q9 a' G
  1324.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)9 u# f. X0 L2 a5 m1 M
  1325.         {- }; t" ?! V5 O- f5 t: e
  1326.           txBuffer[txLength] = CodeCan;' v: b* ^, P4 h- F
  1327.         }. ?7 o! a$ @( T( v# P# w

  1328.   [$ ]& s5 {" [% U+ b7 \' M0 i
  1329.         write(txBuffer, txLength);- ~5 q8 d6 G- i4 |/ e
  1330.         callback(StatusError, NULL, NULL);
    ) Z( b& u) X8 b" g7 _8 m! w
  1331.       }- Y& r! f' c  ^8 k7 ?) B
  1332.       else
    8 Z6 r. E0 m* [/ N4 I( ]
  1333.       {* |! S. H: q$ x" J, W; s
  1334.         timeCount  = 0;
    9 O4 G3 l/ Q  [  A/ w, i1 v
  1335.         errorCount = 0;
    $ `* C& P4 p5 {  ^  Y/ j
  1336.         dataCount  = dataCount;
    4 R! C5 w6 {- _1 M1 c
  1337.         code       = CodeNone;
    + f  x. R6 |: `
  1338.         stage      = (Stage)(stage + dataCount);
    5 W* `% h. N, G  C  K9 l% a
  1339.         write(txBuffer, txLength);
    7 F- r3 g' c# l& K' [, |  W
  1340.       }
    ; I0 Z+ M5 _9 S, w! J8 n, Z) D

  1341. ( t; s1 _5 @% j- i/ [! t
  1342.       break;
    5 B, E; u7 M7 j" h- O7 [# I
  1343.     }
    ' G. ~1 }, P. f- D6 u# l

  1344. . G9 f2 O9 N& H1 r
  1345.     case CodeAck:( O( u% D( {+ d4 B: C) {
  1346.     {- i3 b( r; n  I, ~
  1347.       memset(&(txBuffer[YMODEM_PACKET_HEADER]), NULL, YMODEM_PACKET_1K_SIZE);
    2 g1 b: {4 M& I- }: E4 k

  1348. $ c) E# f8 v( [8 c: {
  1349.       switch(callback(StatusTransmit, &(txBuffer[YMODEM_PACKET_HEADER]), &(txLength)))
      ?$ q, m/ x5 c
  1350.       {2 }7 H; I* R8 _
  1351.         case CodeAck:
    ' M: }& O( J: J& Z
  1352.         {5 [6 i/ k0 o0 |
  1353.           uint16_t crc = crc16(&(txBuffer[YMODEM_PACKET_HEADER]), txLength);& k9 v5 B8 j9 G

  1354. ! ^7 W5 s8 i0 V# l
  1355.           timeCount                                       = 0;
    2 B; D( o# O6 y, `" L: U% r: m4 h
  1356.           errorCount                                      = 0;9 _- |! y. p4 y# h. {
  1357.           dataCount                                       = 1;
    ' r4 E/ ]3 R  e1 Y3 X, H& p
  1358.           code                                            = CodeNone;" f# q$ j$ T6 ^# @5 ^2 K) S
  1359.           stage                                           = StageEstablished;
    8 ^. L  j# g! A4 S* g" C
  1360.           txBuffer[0]                                     = txLength > YMODEM_PACKET_SIZE ? CodeStx : CodeSoh;  {$ G# ]# j" e. m- V
  1361.           txBuffer[1]                                     = 0x01;: }, H) C5 G  K$ i
  1362.           txBuffer[2]                                     = 0xFE;+ x4 K, q* a0 Y1 |) \
  1363.           txBuffer[txLength + YMODEM_PACKET_OVERHEAD - 2] = (uint8_t)(crc >> 8);
    ) G1 n$ w2 T7 m6 W: k
  1364.           txBuffer[txLength + YMODEM_PACKET_OVERHEAD - 1] = (uint8_t)(crc >> 0);7 G" ^# f5 D7 b3 V6 k$ |
  1365.           txLength                                        = txLength + YMODEM_PACKET_OVERHEAD;  W% Q$ w" u* r# `: b

  1366. 9 W" d; o" C; m& U8 m. {+ K
  1367.           break;
    ( F5 K/ j! d  O
  1368.         }$ J& C# z7 L. V7 x
  1369. ! R9 j" }& S' L* R( q/ D
  1370.         case CodeEot:# J7 }8 M- w/ i7 \4 u
  1371.         {
    8 l, |5 @( f7 ^, R
  1372.           timeCount   = 0;
    1 B1 ?2 k. }% M+ b! h$ x& E
  1373.           errorCount  = 0;+ ?3 F2 l2 }2 G. W
  1374.           dataCount   = 2;
    ; p+ {* M4 V* r0 V+ Z
  1375.           code        = CodeNone;
    ) U# A  z0 v; D8 v
  1376.           stage       = StageEstablished;2 ~. M( L' h9 k: M5 q0 k5 {5 y: x
  1377.           txBuffer[0] = CodeEot;1 z4 C% a. `" j- J7 J- p' n+ x
  1378.           txLength    = 1;
    7 a' Y7 y6 i. v6 A; r
  1379.           write(txBuffer, txLength);- T7 x: `7 J+ T8 p  q$ l

  1380. / w8 r, U$ F/ L: u
  1381.           break;
    4 p7 G8 l; |" e* f  c+ m
  1382.         }2 w$ F4 N7 X' _( {( ?7 o) q
  1383. 5 g- a$ @& l+ Y" D( p: a0 U
  1384.         default:
    $ v7 Q$ c% T9 }
  1385.         {
    ) @" V( v! i# m: c# \( U
  1386.           timeCount  = 0;! k% Z5 K6 j3 ]7 Y5 W9 ~: ~, z& ~
  1387.           errorCount = 0;& t0 Z5 Y. f* J. m9 V
  1388.           dataCount  = 0;
    . r4 p6 \1 g7 ]* w4 M7 k; B
  1389.           code       = CodeNone;
    3 L5 {7 i* j5 [& I% \2 a
  1390.           stage      = StageNone;6 n9 [  Q5 s6 G' ^

  1391. 6 |! _7 h% p: |/ C) Y0 R3 J; ?
  1392.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)/ h6 ~. o1 f  r
  1393.           {
    % x2 F" D4 e9 F, y$ G& g
  1394.             txBuffer[txLength] = CodeCan;+ Y2 O6 {$ A' V1 V3 t
  1395.           }$ A: [; j" b" m; G* N1 Y5 v+ |
  1396. - ?2 E' z1 s: b% z! v$ f6 Q$ P
  1397.           write(txBuffer, txLength);1 H% Z6 r. J* `
  1398.         }
    ) |4 f6 ?& Y8 G$ d9 y& W
  1399.       }
    ( {- d! _; ]/ y  C) l

  1400. 9 k/ S3 e$ Q7 Y- x" O2 ^
  1401.       break;
    * N" ], a, x+ K$ h+ K
  1402.     }0 {% \8 y4 K& q+ K4 }0 m9 C
  1403.   E; Y/ S/ G6 [: }. D
  1404.     case CodeA1:
    5 ?; H8 x  n5 A  ]: M% z
  1405.     case CodeA2:* w$ A3 H9 f) @# [' ]& E0 u
  1406.     case CodeCan:
    ! Y* Z$ {% B- t7 e) z8 U
  1407.     {
    ( l' \) z% W5 \1 K: X
  1408.       timeCount  = 0;
    6 S1 E/ E7 H2 f- V8 c6 X
  1409.       errorCount = 0;" p$ B' Z( r7 P! m; r9 F3 ~+ G( h
  1410.       dataCount  = 0;& ~/ [. f( p; A- D" _
  1411.       code       = CodeNone;; K# a# Z# }& x& i" K
  1412.       stage      = StageNone;1 W2 h' F5 k# u& ^: k; \2 T+ u
  1413.       callback(StatusAbort, NULL, NULL);0 Y" u, k3 S2 g% \& H

  1414. , S+ r0 g8 Y$ S# i' C; T' e
  1415.       break;
    # Y# O# V) U5 u) B2 U& A; z
  1416.     }
    * h4 r: G1 |8 j- s+ X
  1417. 0 a7 F$ O" f$ c! P& ]
  1418.     default:. D3 B4 C# W5 S  {9 p* {$ ]
  1419.     {' `' L. E$ Q& h2 ^$ |
  1420.       timeCount++;; E/ h, ~0 R3 Y+ S5 _
  1421. : W5 M8 F0 d1 Z; D  J6 x4 U
  1422.       if((timeCount / (timeDivide + 1)) > timeMax)
    ' G. S0 n9 U% ]4 e
  1423.       {% A% C, R7 D" k
  1424.         timeCount  = 0;6 B0 L9 d1 C# F5 I
  1425.         errorCount = 0;
    & O& S6 a# m& n$ R
  1426.         dataCount  = 0;1 I( r8 b! N# c4 Y
  1427.         code       = CodeNone;
    9 s+ u) b* ~( x: d0 r% n
  1428.         stage      = StageNone;
    - w2 L; u5 h- T! G" P
  1429. : f0 D" s  C' D* l- z
  1430.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)" @5 n  i6 o; I" }/ V
  1431.         {' m% ]3 W- r  `$ s7 U7 F
  1432.           txBuffer[txLength] = CodeCan;8 S. i+ ?% p9 O) _$ P5 Y: b7 P
  1433.         }/ U& a3 O+ {( O& x, l. Z- |  E

  1434. # t3 [5 W3 V5 H
  1435.         write(txBuffer, txLength);# {& L2 K( m7 U
  1436.         callback(StatusError, NULL, NULL);  e8 y, z- S3 y; D& [7 Q$ d; ^4 \
  1437.       }# K! ]- R+ j% r
  1438.       else if((timeCount % (timeDivide + 1)) == 0)
    $ k6 e* H6 H* I& y, {! Y9 [. S
  1439.       {" Q* b9 B" v  [! I; y  I' O# W
  1440.         write(txBuffer, txLength);
    6 i3 f* _# S6 g# G. p
  1441.       }
    6 E2 S# B5 C. o: P' k. I
  1442.     }
    3 u4 ?5 _! A+ e* u/ ]' s' D
  1443.   }
    " i% O* D+ n$ W! U& f! C
  1444. }5 z0 H9 O) t4 ]2 l# T: D
  1445. . c7 H. f: ?6 ]1 W
  1446. /**' {3 X# K  A$ y4 g" E. {5 ?5 h- s% u
  1447.   * @brief  Transmit transmitting stage.* R4 G8 W& A+ n, g, U
  1448.   * @param  None." A" X4 I4 H. K& h4 X
  1449.   * @return None.
    ! \3 N3 F' m6 ]" ^
  1450.   */
    # g# A, V1 _, a
  1451. void Ymodem::transmitStageTransmitting()
    4 C+ x6 F- M* L2 q
  1452. {
    7 P5 u/ e# X; H6 o- R% x$ S
  1453.   switch(receivePacket())- O+ j+ }5 s) f& A: P
  1454.   {, L: K: N5 }' N
  1455.     case CodeNak:  L1 \: K/ r2 R4 B- n8 B+ a
  1456.     {* s2 |' e/ q# X; u2 T$ I! i8 X# `
  1457.       errorCount++;% m' }* b" g  r, H, }; J' `  _
  1458. * i  m" f1 b. h! m5 w9 n( V' M0 L
  1459.       if(errorCount > errorMax)
    & _' q8 \! p$ k+ Q4 y% D
  1460.       {4 S& E9 R% }2 a! f$ V/ M! |
  1461.         timeCount  = 0;0 _1 {0 v/ |" G: K# v
  1462.         errorCount = 0;
    * |+ N! M+ W; {1 h
  1463.         dataCount  = 0;4 z, q- C* m& q6 X9 y  _& |! P0 a
  1464.         code       = CodeNone;7 @  h  S% H8 \6 {9 N
  1465.         stage      = StageNone;
    0 e  ]# i8 |  N
  1466. " T9 a6 ^4 z. Y% @% e* Z) S
  1467.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)) z: w7 q( G9 _) l. y" \
  1468.         {$ V8 I9 T* \* O1 c7 A3 e0 U/ X
  1469.           txBuffer[txLength] = CodeCan;) W7 K; P* }8 |
  1470.         }
    " O6 f+ s3 ^; Q8 n4 N- m" G- ?3 B4 x

  1471. 5 C3 d+ n1 n6 u/ G4 d6 o
  1472.         write(txBuffer, txLength);
    - E- y  q3 l) t2 _0 O; G) E3 Z: \
  1473.         callback(StatusError, NULL, NULL);
    ) Z' B. f/ x. C8 ^  K# Y
  1474.       }: a% r* c- M. X2 S3 h8 [
  1475.       else, @% T. [& j1 f( Z2 J
  1476.       {0 ?/ ^, z- A  x/ y/ m
  1477.         write(txBuffer, txLength);( S3 l( |1 P* O' c1 I% b
  1478.       }. \- ~+ b) ], ^2 r% f, R
  1479. ' ~/ c5 g/ y9 {
  1480.       break;
    2 P4 L( T3 N* L- p) s: z- S1 O
  1481.     }
    * ~/ K1 y7 R! \, R+ R! m

  1482. - b6 `  u3 S/ A% G" O6 N% a
  1483.     case CodeAck:- T9 |4 _7 z/ H) G
  1484.     {6 ?1 s1 \9 p3 a5 B6 D" c
  1485.       memset(&(txBuffer[YMODEM_PACKET_HEADER]), NULL, YMODEM_PACKET_1K_SIZE);$ M: y/ f, U3 N1 z1 w( F$ h2 h
  1486. # d9 M: a# h5 m( {/ v' @
  1487.       switch(callback(StatusTransmit, &(txBuffer[YMODEM_PACKET_HEADER]), &(txLength)))
    2 N1 X7 ~* B+ @- E
  1488.       {
    ) M8 h9 Y. Y) ~+ X
  1489.         case CodeAck:$ f: Y+ @7 N: d  y% D) `
  1490.         {
    # Y. g" ]% r2 H* M! \9 `& K
  1491.           uint16_t crc = crc16(&(txBuffer[YMODEM_PACKET_HEADER]), txLength);
    , z% S/ a$ M& N7 G5 z( P
  1492. 8 u- d1 X/ q; A! y( X7 E
  1493.           timeCount                                       = 0;
    - z+ Q+ q) T' m5 t" e* C
  1494.           errorCount                                      = 0;7 j7 m0 u! T& h2 i$ s
  1495.           dataCount                                       = dataCount + 1;
    4 H/ T, t; k0 C" z9 a6 y$ N" O
  1496.           code                                            = CodeNone;
    4 i6 u, S& V6 X
  1497.           stage                                           = StageTransmitting;1 C5 R2 Z8 W5 W) r2 i; E
  1498.           txBuffer[0]                                     = txLength > YMODEM_PACKET_SIZE ? CodeStx : CodeSoh;: j' r( g8 G# ?  A/ `/ o: ~  k
  1499.           txBuffer[1]                                     = dataCount;
    # S$ x% A0 Q& C6 R9 j
  1500.           txBuffer[2]                                     = 0xFF - dataCount;" T" j& r9 f$ `9 n8 \
  1501.           txBuffer[txLength + YMODEM_PACKET_OVERHEAD - 2] = (uint8_t)(crc >> 8);( l. M6 i( a2 G% t
  1502.           txBuffer[txLength + YMODEM_PACKET_OVERHEAD - 1] = (uint8_t)(crc >> 0);( N# ^: T% p+ S: G
  1503.           txLength                                        = txLength + YMODEM_PACKET_OVERHEAD;
    - }3 d% v7 R: X
  1504.           write(txBuffer, txLength);
    , R4 O9 J( T$ ^& e$ P$ a$ x9 \

  1505. & t( P2 N; c: j( _1 Y3 W& O
  1506.           break;
    ' j7 b  u6 n  g* ~, g
  1507.         }( D4 F8 `# z' g' e+ |5 n$ R

  1508. - ]( b& W; F9 k6 T2 \, }$ p1 o
  1509.         case CodeEot:2 ]; l! y6 I/ X# s
  1510.         {9 O6 d! t; F6 Q* B& [  G- {
  1511.           timeCount   = 0;7 u8 V4 b7 i2 t0 C
  1512.           errorCount  = 0;
    * d! x7 D$ H/ c( M# w3 @; w
  1513.           dataCount   = 0;
    & }* b9 \! C' N: f* B# A* W
  1514.           code        = CodeNone;
    9 f) {, p2 i( S
  1515.           stage       = StageFinishing;3 _. j: t0 v) M
  1516.           txBuffer[0] = CodeEot;* M# U8 g3 J4 h0 v: m
  1517.           txLength    = 1;
    ' y% z/ d" [! x$ Q! o
  1518.           write(txBuffer, txLength);8 S0 y$ ^3 `( U

  1519. 4 p) K" W! U  ?2 P# g3 f+ g) I
  1520.           break;
    - u$ R7 U" c3 E8 i
  1521.         }* i3 {3 K; Q2 h* ^

  1522. 1 Y* f% Z  A: ~% f; x- R3 |2 ?1 @
  1523.         default:
    . I; p+ I/ g- e/ ^! I
  1524.         {9 o& H  Z1 r& _' R
  1525.           timeCount  = 0;
    * ?6 D7 G7 }8 u9 y
  1526.           errorCount = 0;6 D3 X2 W, e& o3 C% \4 ~
  1527.           dataCount  = 0;9 _0 v" s+ `2 {
  1528.           code       = CodeNone;1 ^" E9 N% S  h6 C
  1529.           stage      = StageNone;
    # `9 Z# j+ k$ a

  1530. ) I- y8 k0 P. o$ r/ x% U- \
  1531.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    ; e7 U: \9 C: V
  1532.           {0 Z; C8 u& a2 w* j& m( U
  1533.             txBuffer[txLength] = CodeCan;
    # Y3 w( b0 H, c. b6 y5 S
  1534.           }* T0 U6 ^: a9 ?/ @! J( x* d
  1535. % c* h" z' p6 {+ n+ |! t
  1536.           write(txBuffer, txLength);
    ' s# M9 q% {5 U
  1537.         }
    3 K9 \! m3 o8 Q  P: r. A
  1538.       }
    2 }- h) {7 u8 h5 s3 B
  1539. % R) J2 e; w1 N
  1540.       break;
    ; l$ Q+ s- ~' m% [; ]3 c' V: u
  1541.     }9 y) H6 X" G, z8 j9 a

  1542. ) [6 j6 |; P+ n8 Z* O$ R, w
  1543.     case CodeA1:
    8 L0 p3 h  D2 c7 u1 w5 N2 \6 e
  1544.     case CodeA2:3 i* {- r5 l: R" Z& |8 `7 \
  1545.     case CodeCan:
    " e3 H- I) u  ~% b5 O
  1546.     {
    ; e3 M8 C7 V$ T; [% z' _
  1547.       timeCount  = 0;
      N: x, n4 N' T, N9 d# ?+ H/ v
  1548.       errorCount = 0;. k6 D' ]2 Z  h
  1549.       dataCount  = 0;
    : j, K) U  F$ v5 p- L8 ?
  1550.       code       = CodeNone;
    0 ?9 `- F. ~0 G' B% q
  1551.       stage      = StageNone;
    8 {; `2 @6 B/ W1 N, O. Q2 d5 L
  1552.       callback(StatusAbort, NULL, NULL);5 Z% F8 S) k/ b! y  y* z
  1553. " r1 Y' u: k, [  B! ~
  1554.       break;
    7 w/ w1 g- X" @; M7 c4 R; u
  1555.     }6 r* x/ ~( m3 @6 S/ o

  1556. 4 I) Y3 _' x* `/ e
  1557.     default:) W$ a7 E% }9 r$ u# c5 b" W3 [' f
  1558.     {4 @# f. t+ _1 x1 m- Q
  1559.       timeCount++;
    7 i" ]+ g  A& |# ^
  1560. 0 \0 {, u0 @  a- d& }# v: p3 a3 @. j
  1561.       if((timeCount / (timeDivide + 1)) > timeMax)
    & C0 l. q! S$ D1 p5 b8 d7 o
  1562.       {
    ; M$ S/ X4 _$ [2 Q( k: k
  1563.         timeCount  = 0;5 Y% }3 N  |: j4 E! u
  1564.         errorCount = 0;
    3 l5 M  d! U) V! s% j6 B
  1565.         dataCount  = 0;
    , o. b2 [5 |5 B3 M" d; y/ E' i2 B
  1566.         code       = CodeNone;$ R0 J$ ^" ~4 w- T
  1567.         stage      = StageNone;
    4 o" c+ }$ G: p! b4 L
  1568. $ |- w  Y' D* E
  1569.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)7 \& E3 o( E/ i0 _0 C8 X
  1570.         {
    $ R0 }/ n8 m" q7 U  ?
  1571.           txBuffer[txLength] = CodeCan;. E0 q& a; m1 I) }5 P  P9 V
  1572.         }- W" a% ^) g) C* m
  1573. % {& ^) Y0 v, B4 [
  1574.         write(txBuffer, txLength);8 K5 e, |3 _! A, e% v9 {; R
  1575.         callback(StatusError, NULL, NULL);  d& R. Q( m* m
  1576.       }9 B" t0 ~' n$ b, R
  1577.       else if((timeCount % (timeDivide + 1)) == 0)" G% L" s( A. B- @( o
  1578.       {
    9 E( p6 c5 d! A! U) q
  1579.         write(txBuffer, txLength);
    + A  w0 J! D# g5 G
  1580.       }2 h; V2 q  U; f, @" i
  1581.     }
    - m: y! E0 P$ |7 y; U
  1582.   }
    1 l3 h" ]0 v9 ~  f+ P6 S8 N
  1583. }) m& b- @; o! H9 z5 W/ X3 u( N& B$ V

  1584. * ]9 X. E. u/ Y" ?  P5 s4 L* d! I$ Z
  1585. /**, x$ o( ?1 a6 v
  1586.   * @brief  Transmit finishing stage.. R& M. x% O; a. }; v
  1587.   * @param  None.6 v/ i' r' L( z0 ]4 O
  1588.   * @return None.
      P# ?6 [) U2 Y# e* g
  1589.   */
    + t. ?7 x: c. b8 ?8 @
  1590. void Ymodem::transmitStageFinishing()3 g: @2 t, j) m/ R
  1591. {2 l0 H( h+ v* P5 F7 [( L0 H
  1592.   switch(receivePacket())
    " k6 j+ C/ h. d4 M
  1593.   {
    ; m- w! z- p) e9 p
  1594.     case CodeNak:
    : j- r) P) h% [, p9 b" s. O- k5 h; |
  1595.     {& s2 ]# o* i% l
  1596.       timeCount   = 0;7 n4 L2 j8 B4 U' ]- u  U) t' R, g, t
  1597.       errorCount  = 0;
    & \3 f3 i, @; D
  1598.       dataCount   = 0;
    , Y& p: U' l. X9 i8 c! _: H
  1599.       code        = CodeNone;
    8 A  D; d( u% \5 T8 q
  1600.       stage       = StageFinishing;7 |% r4 m/ ?( b3 x8 Z4 e
  1601.       txBuffer[0] = CodeEot;- Q& {2 M7 L% _1 `' d6 ^3 `( }9 ]
  1602.       txLength    = 1;4 o# c) b+ [! R6 ^! V5 |' n
  1603.       write(txBuffer, txLength);4 ~8 c( _5 K4 X7 y) U$ o

  1604. : ~/ D9 ?  D4 d$ ]# k
  1605.       break;) t9 _9 {  H$ c; |( H/ ]7 k
  1606.     }
    / {( Y1 G  o1 o7 M% ]

  1607. ; K# ~  p0 |$ W4 E$ C
  1608.     case CodeC:2 |! G+ r7 |2 ~1 X' y
  1609.     {
      @2 A! S9 W" o$ T; r/ z
  1610.       memset(&(txBuffer[YMODEM_PACKET_HEADER]), NULL, YMODEM_PACKET_SIZE);
    . j  H2 |+ ^% x6 Q+ `; l6 W/ X7 r
  1611.       uint16_t crc = crc16(&(txBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_SIZE);
    , y4 [% Z2 [' A) j) [# {
  1612. 4 R3 n0 U" ]. S1 e# X2 y9 S* }. O# \
  1613.       timeCount                                                 = 0;% {6 C0 A' I7 W2 \0 |
  1614.       errorCount                                                = 0;# P0 }/ I2 D# M  Z/ p5 v
  1615.       dataCount                                                 = 0;' f+ u) W4 `7 S4 p2 R: o; q& i
  1616.       code                                                      = CodeNone;
    2 r0 J0 ~+ S  ^! W: w
  1617.       stage                                                     = StageFinished;
    3 X' O+ J1 @* E/ X
  1618.       txBuffer[0]                                               = CodeSoh;
    * ]1 a0 o- ^. [2 Q: B+ |
  1619.       txBuffer[1]                                               = 0x00;
    # O! v/ M4 s  R
  1620.       txBuffer[2]                                               = 0xFF;8 S: d: `, _* e( h: {
  1621.       txBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 2] = (uint8_t)(crc >> 8);
    / s" J- a2 ?! u
  1622.       txBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 1] = (uint8_t)(crc >> 0);
    9 e2 h9 M0 K: |: [. i
  1623.       txLength                                                  = YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD;
    9 I; B  C" ]9 G1 ?
  1624.       write(txBuffer, txLength);5 ]& Y6 b( A6 a# E4 b- J

  1625. , `' A, _' h3 n& h) v
  1626.       break;; Y1 ~. k9 D& l, i
  1627.     }, k- O& i" w! D, C
  1628. 7 _9 d5 v8 b3 f0 y3 Q. t
  1629.     case CodeA1:
    3 L: u* C: A9 e) |# \$ q
  1630.     case CodeA2:
    / `. z: t% H( X5 m$ |
  1631.     case CodeCan:) I& r( {. P" Y4 Y  ]$ i
  1632.     {( R3 V* V: F' C* Z2 z+ A0 J9 ^6 D
  1633.       timeCount  = 0;, `- l' Y; o3 V. |3 z' g
  1634.       errorCount = 0;! p0 {1 \# v2 U) f% ^5 L
  1635.       dataCount  = 0;
    ) P: O4 Z! s7 a+ \
  1636.       code       = CodeNone;' W& Y# N( k+ s9 c& ?6 K7 p
  1637.       stage      = StageNone;
    , u1 _# ~6 V- S1 ~6 U
  1638.       callback(StatusAbort, NULL, NULL);( l3 L% ?4 j' p
  1639. * {. ~& r5 o/ q
  1640.       break;  O! Q. q* S1 J4 Y* l' R8 V4 c
  1641.     }' e6 t+ n3 ^+ f5 `

  1642. 1 a# F# v2 A4 g$ L6 K
  1643.     default:
    - f3 s* i( |. ?/ v1 |, _
  1644.     {
    * ^0 }4 i' L6 J, c
  1645.       timeCount++;6 `5 q: u; q, X' m
  1646. * F2 U- j  y- z6 z1 b" \3 f. _. R8 n% p
  1647.       if((timeCount / (timeDivide + 1)) > timeMax)
    & ~) \3 l4 ~7 t  _8 n: K. W
  1648.       {0 a) m' E% \# K( ?& u6 |
  1649.         timeCount  = 0;% o/ G8 F3 g- h* H" ^& a
  1650.         errorCount = 0;
    9 C7 p; \" t4 E* \( w
  1651.         dataCount  = 0;0 f) Y) b6 k7 y- t! w! e" b" n
  1652.         code       = CodeNone;; q8 s& Y7 V2 M, n6 w: O, |2 o
  1653.         stage      = StageNone;- e0 |9 ^8 I" y
  1654. $ }: C% k) n1 v# f
  1655.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    / x- ~! M0 o' c3 ]% c7 R
  1656.         {
    3 w% z* m8 |0 a0 d# U8 B' g) E: S( ?
  1657.           txBuffer[txLength] = CodeCan;  y4 G3 b. y  _( q
  1658.         }
    : C# f4 K5 J: R# L5 a' H

  1659. , s. i0 g8 X' ]/ g' T% A
  1660.         write(txBuffer, txLength);8 F. H3 A0 S/ p9 L- ?. [
  1661.         callback(StatusError, NULL, NULL);
    # J  f% y8 [2 O) S1 c
  1662.       }
    ' t) K8 r8 {! G3 J! s; z+ b; \
  1663.       else if((timeCount % (timeDivide + 1)) == 0)
    6 |- R0 u! |2 {, s& k: F4 q
  1664.       {* F7 S6 ~! o$ k' S1 Z( w# j
  1665.         write(txBuffer, txLength);
    6 W' Z/ q1 O, ^8 u2 h+ u& V7 d9 E
  1666.       }6 E) W6 {, Y1 B  w  ^6 g: U
  1667.     }7 B& Y6 D  _8 i" {4 n% @$ R
  1668.   }% _$ n4 t" o4 N& s2 O( w8 w. h, O
  1669. }
    % W+ s* S9 [* p

  1670. 0 W6 l! c5 M; C0 A- I8 J/ C. d
  1671. /**4 L$ b/ I/ D, P8 e. r( S& E
  1672.   * @brief  Transmit finished stage.  T( W2 d9 ~* B, H! H
  1673.   * @param  None.+ v  P6 v$ @3 Q% t1 O1 \* }
  1674.   * @return None.0 C7 T) S6 _  J
  1675.   */! O! q6 W6 H3 x
  1676. void Ymodem::transmitStageFinished()
    " c& N; F( K! T0 \2 x; F1 ?
  1677. {2 s3 T& `/ [: T. N9 G
  1678.   switch(receivePacket())  G3 W) m# O7 l6 \! Z0 w% ?" m) b
  1679.   {' G+ R% K+ d$ i3 b1 ~* T1 B: D
  1680.     case CodeC:
    . G7 i$ o6 L* o# c. Q
  1681.     case CodeNak:
    " m' N# \, C* n3 Q
  1682.     {! _' |& k9 g, {; u4 A
  1683.       errorCount++;
    $ [; f1 r2 C2 v  K# s% u/ H

  1684. 6 P9 j# ~( d- ]: r2 E; c  \. k* A
  1685.       if(errorCount > errorMax)3 I6 ?  |" _# r2 w7 z8 E" {
  1686.       {
    # _1 q2 o; c8 @5 U4 M& \
  1687.         timeCount  = 0;
    : h. y$ y2 A/ y6 {6 b6 ]$ l" m* P
  1688.         errorCount = 0;
    5 G, a5 M1 g& N) K6 H5 w
  1689.         dataCount  = 0;* |6 M& D$ \! ?8 E: a
  1690.         code       = CodeNone;% ~; p. @7 x4 e: N: N, Q
  1691.         stage      = StageNone;7 v7 `2 c" Y8 c+ \5 s& \! D

  1692. ( u2 h8 i% @7 ]  M7 i
  1693.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)' M+ u: q2 i% T1 g
  1694.         {
    ( c0 e7 p7 x4 E3 ?3 ~8 v* J( J
  1695.           txBuffer[txLength] = CodeCan;
    5 b. V5 f% r, _% M
  1696.         }3 I; k% M- [5 J6 V* J( m! y

  1697. 2 b; [7 g! T5 _' _. ~
  1698.         write(txBuffer, txLength);, {4 Y9 B1 F$ e
  1699.         callback(StatusError, NULL, NULL);
    0 m! l  R7 F  u; Q8 z2 O0 `
  1700.       }
    ) p2 I% l+ ?- `$ G+ A
  1701.       else9 k# r# F; u0 V1 Z3 a6 s! d- |; v
  1702.       {
    ! j( N5 p; `2 C, I- C7 b
  1703.         write(txBuffer, txLength);) o4 h' b" n! R4 b& W
  1704.       }
    / P9 w" {: a6 @! n$ t8 y. `
  1705. # A7 u! k7 o6 W1 d  R9 }
  1706.       break;
    3 b, m  m; r/ K  P( w$ y
  1707.     }
    8 h8 }- I2 I5 u5 [, Q$ X% X

  1708. * n: e& P# N1 F& ^) m$ I$ q8 y7 O
  1709.     case CodeAck:
    2 F. g( n, `5 F
  1710.     {
    6 ~# p* C: ]% j: H
  1711.       timeCount  = 0;
    " G4 t4 B9 R; `) z8 [5 j2 @. ^0 V
  1712.       errorCount = 0;' p" N4 j8 c, i+ p0 \
  1713.       dataCount  = 0;
    : s! h; W6 P& \. e8 y: L% h
  1714.       code       = CodeNone;
    2 ?: Z& k9 p! r1 u: L' \
  1715.       stage      = StageNone;
      T8 }. N* N7 W
  1716.       callback(StatusFinish, NULL, NULL);' t8 q5 ]  l6 i% e& B; K

  1717. 0 {3 J& \9 w" c* X
  1718.       break;
    - l# X6 A8 p, p3 {5 Y& f% m
  1719.     }
    " _: H- d" W2 t! m+ k5 X+ |% Y

  1720. % h. ^' o3 e3 p& r1 H- [* V
  1721.     case CodeA1:
    / y8 r; C9 H: E/ F! F( ?
  1722.     case CodeA2:$ s1 V7 b; d& ~- u* d
  1723.     case CodeCan:
    1 Z% \9 `" L% v" [2 W' O) k' b
  1724.     {
    ( Y% I' N0 x/ A9 v2 C7 N' A% {: m
  1725.       timeCount  = 0;: ^' @3 t3 m" t8 p
  1726.       errorCount = 0;
    1 U) J/ `6 f1 S% }  }
  1727.       dataCount  = 0;
    . y# _# O- s; B. b: i- v7 s
  1728.       code       = CodeNone;
    1 }$ w# j0 {. l. p% l' q. g
  1729.       stage      = StageNone;
    # R; d9 T+ W; ?; T
  1730.       callback(StatusAbort, NULL, NULL);
    ; P6 U2 }' n- ?: D, `! s
  1731. / z. v& U/ v. E* m
  1732.       break;+ X: b7 @( \5 F- M+ {! i; k, S
  1733.     }. }& H( F: T5 Z6 O* K
  1734. , j% A& G- G+ K% N8 g6 f. @2 {6 _
  1735.     default:# \) W( X$ a( ~" ^( v
  1736.     {
    ) u3 D  O: z7 Z
  1737.       timeCount++;0 `* r1 }& V. h5 }& a. S3 h, H

  1738. 1 \+ |3 ~! H1 K" l+ t5 W
  1739.       if((timeCount / (timeDivide + 1)) > timeMax)
    ! m. M% O! @7 v0 W# [- o7 D2 N
  1740.       {! |0 U+ T9 C# d" G: \8 {- n
  1741.         timeCount  = 0;
    - b! q6 Z+ [. }9 \: [) n6 z! q
  1742.         errorCount = 0;
    ( w4 H% Y0 u) N5 R/ M
  1743.         dataCount  = 0;
    4 |' G! J* ^/ k* E; B4 A
  1744.         code       = CodeNone;
    $ q2 o9 n8 u2 {
  1745.         stage      = StageNone;8 A; D* M5 E3 C, q! t- l: m3 u

  1746. ; p1 u! _6 l$ |4 ]$ E1 W7 y
  1747.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    6 _' T" H, ]: K3 E! \: d
  1748.         {
    / T# E, v4 u" M. K/ d3 p7 U4 H3 L" ^- b) i
  1749.           txBuffer[txLength] = CodeCan;' }/ q" T' w' f& t$ |- T& k
  1750.         }% F1 B! i) w2 t

  1751.   p; e# ~* E% Y$ Q. o1 A4 V0 b
  1752.         write(txBuffer, txLength);
    8 ?; V6 J5 _/ z, }2 I, y* l, e
  1753.         callback(StatusError, NULL, NULL);' ]& V8 {/ W; c# B5 H, z$ l
  1754.       }
    : j3 `& N: F1 H' g/ O4 P. h
  1755.       else if((timeCount % (timeDivide + 1)) == 0)
    % i/ X- Y) N+ S- K5 a$ e
  1756.       {
    0 I8 T5 F- b3 O# c! ?8 `
  1757.         write(txBuffer, txLength);9 F1 ^# B5 L) {1 d
  1758.       }
    ) J9 s7 K6 J8 _" Q5 T, F$ w
  1759.     }
    * g$ c" R0 u% A. w! ?/ r7 Z) W$ Q) U
  1760.   }
    9 v7 Q5 K! n0 R) Q( W$ V
  1761. }  X7 H. O* o* x$ F" _
  1762. 4 h2 v+ n( {8 ^( I2 O, }
  1763. /**8 U5 H0 k/ s* U: o$ _" }
  1764.   * @brief  Calculate CRC16 checksum.
    7 O3 r5 ?% Z+ C0 y; ]4 {) e, c
  1765.   * @param  [in] buff: The data to be calculated.+ h5 X$ B4 _# j" O, M
  1766.   * @param  [in] len:  The length of the data to be calculated.( A2 k3 s& ^0 C+ v- w* S, T
  1767.   * @return Calculated CRC16 checksum.
    ( }8 P" X( d0 ^0 ^# N- b: V+ t  G
  1768.   */
    3 j; o6 k) w. v. |: g9 c/ O! M* r
  1769. uint16_t Ymodem::crc16(uint8_t *buff, uint32_t len)
    ' c( b% {/ q( p) M% [$ S  n
  1770. {( e3 y% P8 p2 [# N8 @
  1771.   uint16_t crc = 0;
    8 i8 t5 O1 I' e8 f

  1772. & {7 O5 A) G; N  i: s2 c$ V
  1773.   while(len--)
    % Z# K* X3 N/ m, U$ x( H% j5 e; ?
  1774.   {
    : S* `4 p1 h$ |' e$ A- W" m; G
  1775.     crc ^= (uint16_t)(*(buff++)) << 8;
      g6 h6 Z6 g6 a( F0 }4 m5 k
  1776. 6 R- C6 ~% I- u$ i8 r! \' ~9 l0 Q
  1777.     for(int i = 0; i < 8; i++)
    - \, T  T! m$ {
  1778.     {
    / [7 S$ S6 ]8 J. c7 o% \
  1779.       if(crc & 0x8000)' n% ]: {& i% @7 k' O
  1780.       {& `; W* p$ ^( i1 e% r1 R3 U  S% G
  1781.         crc = (crc << 1) ^ 0x1021;
    / F/ l- z/ w$ |* ]; f. i
  1782.       }- E1 ~  L1 H9 x
  1783.       else6 E# o  `  B. V! r( @+ F
  1784.       {8 ~* k  Y/ G9 h7 X
  1785.         crc = crc << 1;
    / j  F- \3 ^0 S. t2 S, w, Q
  1786.       }3 m: e/ G* I' _( X
  1787.     }
    * Z4 g+ s# m+ S" u) W2 a( K( W
  1788.   }6 P, i  T$ b; X
  1789. 6 }' C0 ~- h, ?
  1790.   return crc;: j1 }5 ~5 H# t4 o+ [1 ^- Z
  1791. }  \6 n5 Q5 o. Z& A6 T  T' H; l$ v
复制代码

  D$ z4 n+ B( {5 s1 V( b/ U1 p4 [) b9 ~3 b" K
+ J. }- _1 h, u. Z6 _
7 T  a* d4 a5 ?" |

评分

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

查看全部评分

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

举报

10个回答
XinLiYF 回答时间:2018-3-6 01:58:43
      YmodemFileReceive.h文件
1 a; d* \7 H: v# p+ C( H* m
  1. #ifndef YMODEMFILERECEIVE_H, P8 A& W9 E; _) Y" l6 p8 h
  2. #define YMODEMFILERECEIVE_H
    2 m# l) k( d: _1 z& O
  3. 4 @$ A# C, p9 d( l
  4. #include <QFile>
    0 j" v: v( n. J. s
  5. #include <QTimer>
    7 m2 |$ @$ I* `- x8 t
  6. #include <QObject>, r- t# i7 U+ i- m' U- L
  7. #include <QSerialPort>& W) u" i# a! p# `7 Z1 `7 h' t
  8. #include "Ymodem.h"
    1 @* B- l% e. M# w8 X. @" {1 q
  9. & o; m3 b! O& ?, Q
  10. class YmodemFileReceive : public QObject, public Ymodem
    3 O( R' e) H( Q$ t
  11. {6 p/ x" j: H; p5 W9 Z# n
  12.     Q_OBJECT
    # V, w; I/ t  F3 n5 f) W" Q# p! d( J
  13. $ w1 c8 |# c6 X
  14. public:
    ( n9 m% x3 _" I
  15.     explicit YmodemFileReceive(QObject *parent = 0);
    $ S2 v4 W, N4 x: P( {. i
  16.     ~YmodemFileReceive();& ]/ j1 V' i% _# c( ?

  17. 2 k/ O8 A4 M/ b6 n' Y
  18.     void setFilePath(const QString &path);, m; \# ?( V: n& X# [
  19.   T2 }! C6 v+ M' P
  20.     void setPortName(const QString &name);2 x( `/ y. T3 N( ]4 S7 \! i
  21.     void setPortBaudRate(qint32 baudrate);4 P* c+ Q( F" w) N- Y; W. {- K/ y
  22.   n2 |8 Y+ z7 j5 o; b
  23.     bool startReceive();
    ' O) f7 c& J& v  R* z
  24.     void stopReceive();, O  N8 @/ h+ x- a- h
  25. : i' d6 U8 O( |- p
  26.     int getReceiveProgress();5 }7 G% V: V/ K# c1 c2 u9 c
  27.     Status getReceiveStatus();( d  O, B  @7 c/ n8 N; f- s
  28. 1 o* P; O9 L6 {
  29. signals:
    % x0 g2 s7 l8 Y' D) E. n0 A9 Y
  30.     void receiveProgress(int progress);
    * L3 v% B2 ]- v; E0 _
  31.     void receiveStatus(YmodemFileReceive::Status status);: k3 k, w$ Y" N% H
  32. , e0 {2 x+ w8 |7 h0 S) K1 i
  33. private slots:
    7 {' c& @9 @' B$ A" K6 Y
  34.     void readTimeOut();8 C8 Q5 f' J2 S/ [3 N6 L
  35.     void writeTimeOut();6 G; N# @2 h5 W/ `$ |/ c

  36. 5 T9 X' j, l3 G. n' I  H& n
  37. private:7 j# e; h1 O: t( ~" v
  38.     Code callback(Status status, uint8_t *buff, uint32_t *len);
    . b* G9 }% ~7 f& N% C3 P4 `
  39. $ h* H( [. P; f3 J0 [+ c4 u
  40.     uint32_t read(uint8_t *buff, uint32_t len);+ x1 C) w. a! _* q' a+ H# f& c
  41.     uint32_t write(uint8_t *buff, uint32_t len);
    / t4 \1 ?% V- K& _% \6 b8 G

  42. 6 z+ Z9 p* s- H$ [3 V7 \
  43.     QFile       *file;! _2 O- ^9 R" c, d1 N
  44.     QTimer      *readTimer;" c& m- ?* Y5 \/ V1 ~
  45.     QTimer      *writeTimer;
      O+ [: |5 S% z0 g
  46.     QSerialPort *serialPort;
    , l6 H( F6 i( N# r

  47. ; S# s5 a0 k' F6 g  {
  48.     int      progress;& z! Q) b. ?. a0 q7 a
  49.     Status   status;! S9 Y" k- u7 N& m, t1 ~' g7 V4 I, K
  50.     QString  filePath;
    ' h1 t: f5 J2 L: x( V2 }* W3 }
  51.     QString  fileName;
    $ [0 U- g  V7 o+ J2 J* A4 x
  52.     uint64_t fileSize;
    / A! x1 n) w5 `' T0 @: g0 `
  53.     uint64_t fileCount;: a7 @+ M3 M' K2 s4 E7 r& t- X
  54. };% C! ?9 X. Y0 Q: V0 ~1 y
  55. " q4 K: q; K' f4 g5 T+ \
  56. #endif // YMODEMFILERECEIVE_H
    # Z6 m) e) g8 ?7 I5 y7 V0 Y0 m
复制代码

, ]/ Y1 \/ ^1 c$ F+ \6 v. _2 L      YmodemFileReceive.cpp文件' I% B0 r- w# [  Q2 _2 J8 k$ n
  1. #include "YmodemFileReceive.h"1 v' M! N5 f  W9 q0 g9 M; T/ X7 @
  2. 9 Z1 t- S3 W; u
  3. #define READ_TIME_OUT   (10)' x5 k# H% i5 g, V! G# L5 ?' `
  4. #define WRITE_TIME_OUT  (100)
    5 t, Q/ L! M1 m0 g- j9 k& ^+ h
  5. & Y8 \6 k3 u; V) f/ ]5 |
  6. YmodemFileReceive::YmodemFileReceive(QObject *parent) :7 I7 d7 P8 p8 x/ I( w
  7.     QObject(parent),9 @2 j: f3 i" b% Z& N& A0 k
  8.     file(new QFile),+ m9 L7 m" U- \7 ]# U9 X7 z
  9.     readTimer(new QTimer),. {7 T6 o$ P5 Y6 E/ ]! a7 C
  10.     writeTimer(new QTimer),
    $ L' m$ \8 s' s+ G3 y
  11.     serialPort(new QSerialPort)0 B& s6 ^/ @& N% \3 S3 }! A  x& h
  12. {
    9 O" d  |4 E! m
  13.     setTimeDivide(499);4 k) I) D' i  _8 F
  14.     setTimeMax(5);
    . f$ p3 b; V) ]% I, [
  15.     setErrorMax(999);
    3 ?& M0 w( w- d5 f7 C, ]* e) ?

  16. 6 L# A# W( V1 H' X7 m  e
  17.     serialPort->setPortName("COM1");. O' D; q3 o7 v" d
  18.     serialPort->setBaudRate(115200);4 L/ D- V9 i9 _9 B
  19.     serialPort->setDataBits(QSerialPort::Data8);
    ! Q. O% X- c  c" I- ~
  20.     serialPort->setStopBits(QSerialPort::OneStop);
    * b1 X( A% v  K2 _& `8 {
  21.     serialPort->setParity(QSerialPort::NoParity);) Y" X. W) p2 E$ H$ S
  22.     serialPort->setFlowControl(QSerialPort::NoFlowControl);2 A, a$ Z( g. O8 Q$ |9 e
  23. ) r. B2 G8 V) ]4 j. }* D5 {; D6 G
  24.     connect(readTimer, SIGNAL(timeout()), this, SLOT(readTimeOut()));
    8 g- M( L/ g- K6 F( l
  25.     connect(writeTimer, SIGNAL(timeout()), this, SLOT(writeTimeOut()));5 [8 t) v3 W! f+ y% _; e0 m
  26. }1 s, T" x- U2 b9 ?0 \

  27. # S6 T: \' s2 e- B( `2 B- T
  28. YmodemFileReceive::~YmodemFileReceive(): M# A  x' u9 b/ I
  29. {6 F( s) `$ C! i5 `: k
  30.     delete file;
    - V; r" N* a/ k" {( L$ H/ ]
  31.     delete readTimer;9 @6 C) K9 w& q" @
  32.     delete writeTimer;+ J, }$ N6 P# Y) C/ U4 _
  33.     delete serialPort;; u) f; G- U0 o4 e3 [6 y
  34. }
    7 X( `% v2 A8 C: G
  35. 3 v. |6 p; P7 J5 h& Q  l" B5 u, V7 d
  36. void YmodemFileReceive::setFilePath(const QString &path)  e6 G# D6 q8 i) p7 h4 L5 G
  37. {
    # n1 l2 L0 i  k# [
  38.     filePath = path + "/";
    ' \0 x5 t7 r7 {. n; I/ a1 J
  39. }
    ) [) Y3 `6 [; R

  40. ) n$ B1 z8 H) \7 u% U$ z
  41. void YmodemFileReceive::setPortName(const QString &name), ]5 V; [1 v9 |$ m$ g- g
  42. {
    # Q/ r. @# i4 o/ S: ]
  43.     serialPort->setPortName(name);6 A$ q( y5 s# Y* m) x5 y
  44. }
    , U) A! s& p* j: G) N* X

  45. - f4 b- G6 D& z# T
  46. void YmodemFileReceive::setPortBaudRate(qint32 baudrate)
    7 r' X% y7 I0 `" j- ]$ i
  47. {
    , j; P3 P  |9 G! Z' C) a- u& k
  48.     serialPort->setBaudRate(baudrate);
    9 z: m  M  k+ T5 [5 K  f: l
  49. }3 I( l. y* F  K
  50. & f/ s( R1 c0 \9 |3 e% X  r8 u& ?
  51. bool YmodemFileReceive::startReceive()2 Z: F9 J+ L, v0 J) A: S/ p6 x
  52. {- }7 \0 d2 }! a" n' L  s. m6 s
  53.     progress = 0;
    $ _9 @) T' N. z1 G9 m1 A
  54.     status   = StatusEstablish;# V' _' \6 M& [; q7 p. E/ P! k& X" b

  55. 3 a4 M0 T# v; F
  56.     if(serialPort->open(QSerialPort::ReadWrite) == true)1 g1 n1 ?# X& l& f0 ?3 X' D
  57.     {* \: n: @' o* y2 l$ g
  58.         readTimer->start(READ_TIME_OUT);* M8 k! g- [/ u* U

  59. 1 q- W' `: i5 p% H( R4 S; ]
  60.         return true;+ t! s( M3 Q$ x9 }8 ~$ I  B4 ^( d) @
  61.     }) A' \1 m& H& ~4 q* U( \4 F) L% s" U/ v. W
  62.     else
    - }4 Q( N+ `! h
  63.     {" W- r& A5 n2 D3 W3 F
  64.         return false;
    + _* f6 j5 j" `7 h3 B' Q
  65.     }" J+ Z% U) R- ?2 y# D
  66. }
    / ~8 O$ F5 [% w/ _

  67.   C: d) m+ ^9 F' T6 h% B- u
  68. void YmodemFileReceive::stopReceive()
    # [8 i: L* f( d, w' r. X9 Y) g( P
  69. {3 f  {' Z1 D3 M0 d$ n
  70.     file->close();/ U% u1 S; _* q' Y- i
  71.     abort();
    0 \8 w* i' E9 D
  72.     status = StatusAbort;
    / }+ J4 [: T! X4 Q6 d4 r- C$ O: V
  73.     writeTimer->start(WRITE_TIME_OUT);
    1 }$ \. p4 h) y3 t+ p
  74. }
    1 B; ?7 T" R% ]( ~5 E2 e; V
  75. $ U, U, [; z2 `1 W! p$ r$ @
  76. int YmodemFileReceive::getReceiveProgress()0 w6 }3 r! j# l2 b
  77. {
      }; X0 H3 v8 C# M8 T
  78.     return progress;! o2 r( u* T; M4 R
  79. }
    - F' H  Y& L, W, |- ~
  80. 6 I  D9 e* E5 F2 j  D
  81. Ymodem::Status YmodemFileReceive::getReceiveStatus()1 y$ \4 H. C# X* b8 b5 {# y
  82. {
    4 ], f2 h+ K2 M+ V# |5 ^/ Y6 t6 I3 ^* w
  83.     return status;
    - J/ H' A/ `7 P3 Y
  84. }
    % G+ a& s$ j$ [8 o
  85. " V! Z" m7 m3 }: Y4 V) o7 Q
  86. void YmodemFileReceive::readTimeOut()8 D0 f1 N7 q, U
  87. {
    ' n0 H/ j: f3 x* V6 P9 z% i
  88.     readTimer->stop();( Y+ V3 J: v  x( b6 P+ F4 [4 ~# X
  89. + V8 L) `- H9 }& Z# w, a) j' t
  90.     receive();9 x7 W# S/ p) M" ?6 a

  91. 1 X. z# @7 J2 `/ k5 v) V
  92.     if((status == StatusEstablish) || (status == StatusTransmit))
    9 p' M; U1 e8 Y5 y% M2 R
  93.     {
    1 u, o. K3 g9 [% T/ B; l6 D0 k
  94.         readTimer->start(READ_TIME_OUT);
    0 s8 w4 T4 O/ F) `. q' ?1 z
  95.     }
    # G9 p$ V1 h. V$ {5 ^; H
  96. }/ m$ U/ q: {* b) j3 @

  97. 1 m4 d4 l* j$ Q  ^
  98. void YmodemFileReceive::writeTimeOut(). ^7 o- B! k0 s1 v
  99. {
    4 |0 a8 x. f8 F
  100.     writeTimer->stop();) d2 X& S' s! L! z0 b* I9 [7 }
  101.     serialPort->close();( B. }: ]/ b# S+ k4 t
  102.     receiveStatus(status);
    % }7 l9 g9 j" s# z
  103. }; X. |2 D. {% y

  104. . q# [' s6 K  C" p' p
  105. Ymodem::Code YmodemFileReceive::callback(Status status, uint8_t *buff, uint32_t *len)
    3 \! o- J& o$ f/ H
  106. {
    8 X, l* c9 c7 x  D  C, H8 u7 A( E
  107.     switch(status)
    - \7 ~# G- b6 d. |! s  ]
  108.     {
    % l1 c; {: g& k; q2 r  ?
  109.         case StatusEstablish:( b7 H2 w( X3 H3 {% ^( h
  110.         {
    6 |; \# B7 A5 M* W& ?" ~- ?2 k
  111.             if(buff[0] != 0)' ]& @: u  A$ r/ a. l3 T: J2 M
  112.             {( h) k$ D5 Q2 R3 A' z; f4 h5 j
  113.                 int  i         =  0;4 r) [3 l5 V! ?; _
  114.                 char name[128] = {0};9 V7 S( V1 s8 I- X
  115.                 char size[128] = {0};
    $ j& y, P, K! u6 p3 I% O: J

  116. + L0 `7 c7 E  x: P" e
  117.                 for(int j = 0; buff[i] != 0; i++, j++)0 S. A6 {/ w/ S; [& t  j
  118.                 {% u0 _3 Q% E$ }" x; p- D$ N0 @! c
  119.                     name[j] = buff[i];
    & n& b1 ^' L% \+ Z1 V
  120.                 }% H; H$ N1 A7 u; ]/ _# Y1 Y6 D' q

  121. 3 Y8 X/ a% u' c8 I
  122.                 i++;
    / S- I, P' k; {3 P- t5 k/ Q8 `
  123. * I/ {+ E# ~, A
  124.                 for(int j = 0; buff[i] != 0; i++, j++)
    ; s1 G0 q' q# E5 Q: G$ q
  125.                 {
    ) y2 @; y/ Z/ ]; u
  126.                     size[j] = buff[i];7 b3 X1 H2 t9 u- v0 Y$ v. k
  127.                 }
    , |. R$ }% R4 b- f2 s, Q' L; [( y

  128. . H) s# k; ]" _1 ]5 C5 Y! Z9 A
  129.                 fileName  = QString::fromLocal8Bit(name);. t8 E' G* Y: z, G- d2 |; X
  130.                 fileSize  = QString(size).toULongLong();
    ) o6 s% s% ~0 P
  131.                 fileCount = 0;7 z5 l! q% {; D7 L, E
  132. 7 J* N. K5 B, R% A( g, Y
  133.                 file->setFileName(filePath + fileName);
    0 Z/ g" y/ Y  ?
  134. : p' o) D9 ]6 S0 d0 w
  135.                 if(file->open(QFile::WriteOnly) == true)
    + H3 a1 v5 J6 C9 N
  136.                 {  M! z/ k9 d4 s( H2 M1 K; M
  137.                     YmodemFileReceive::status = StatusEstablish;& S$ K0 e+ {, N- S
  138. 7 O4 `( o- N- S% {: x1 R8 }" g- }
  139.                     receiveStatus(StatusEstablish);$ t( U0 U. s0 \5 K" m

  140. # S. F+ @7 z5 w4 ?6 s. I
  141.                     return CodeAck;: D5 l+ C: I9 s" |  m! s# Q) b: {
  142.                 }
    & C2 M5 g, O% i* s, e( }6 ~
  143.                 else% N4 r: V- L# \5 |1 r2 V7 {
  144.                 {
    & b# z9 ^! _' k0 k* R
  145.                     YmodemFileReceive::status = StatusError;
    ) c6 M6 J7 D9 W; c7 ~* y

  146. 3 w% L9 \$ }, L, @
  147.                     writeTimer->start(WRITE_TIME_OUT);6 f4 {# }8 M: k( Z7 F

  148. / y& g! j  o& A. y4 }3 C6 ~! Q% a
  149.                     return CodeCan;
    ' f( @9 A: a: k/ k7 ^8 M
  150.                 }
    $ c- W. @+ Z% m  F9 t6 L8 l, s! c
  151.             }
    * A1 X  |% f  m, k* w
  152.             else, F/ b8 X! c0 \8 n1 D2 P' J
  153.             {( O9 K- G& O8 r8 ]1 l" o' V8 R
  154.                 YmodemFileReceive::status = StatusError;# `8 ]4 `/ k& V& R8 J, Y/ y9 t

  155. ; N( ]/ s/ K  q: {! |
  156.                 writeTimer->start(WRITE_TIME_OUT);3 v( D7 b4 u0 Z3 e% X
  157. ; E) \$ S! r) [! a- g# t* U1 X
  158.                 return CodeCan;
    7 s0 ?  p, ~, Y+ O8 n3 e+ C; z
  159.             }6 p/ w  B: h' F
  160.         }
    $ R( l6 D& ~0 @
  161. $ E+ n0 b) L$ r% {% }+ r7 @+ F. {) ~
  162.         case StatusTransmit:7 r$ L% ^  Z  |1 {  j
  163.         {
    $ y% J& V5 g& L  X% C
  164.             if((fileSize - fileCount) > *len)
    2 Z; V. P6 D, @6 f) s8 S6 z0 m
  165.             {+ A: _* Q# \- \  A; h# j
  166.                 file->write((char *)buff, *len);* |) U& N: x) B% {4 n# A2 S- ]
  167. 4 ~# f4 `' a, Q9 s& v
  168.                 fileCount += *len;6 v, a3 f4 ]: e  K
  169.             }" ~( R7 ?+ {* W' H; o
  170.             else' I) q" `( h6 ^; a- l
  171.             {# {+ t8 r+ Z( w. D7 g6 C
  172.                 file->write((char *)buff, fileSize - fileCount);) }: D; f# c: C
  173. : e3 P* H% v2 @& w8 R
  174.                 fileCount += fileSize - fileCount;. l5 a/ @; n& G4 l# ]
  175.             }
    9 B* f) |- @. |4 x
  176. ' N( R6 s& x: o0 w: C7 r$ N
  177.             progress = (int)(fileCount * 100 / fileSize);
    : u0 S$ j+ h: E- e$ X

  178. + Z+ y7 S0 z3 i
  179.             YmodemFileReceive::status = StatusTransmit;
    6 G. H( P9 X- \
  180. ; ^+ P# W+ x2 ~! B
  181.             receiveProgress(progress);8 H5 m3 z& k3 U, i: y, [2 ]
  182.             receiveStatus(StatusTransmit);0 A2 a8 W3 B' A
  183. - I* L8 N& b( @2 {4 w
  184.             return CodeAck;! T7 ?& [2 R! l2 {( ~
  185.         }
    ' I: B: W8 T* ~: A4 H

  186. ; `2 ^; W% m9 S$ s* L  y) @
  187.         case StatusFinish:$ Z9 C0 D* [# r6 Z4 s
  188.         {5 J: z6 E% v- W+ e  O
  189.             file->close();
    5 J. M* w- j: l7 l7 T, A

  190. % w; A+ F, [7 e) k) G0 b+ C& X& \0 N
  191.             YmodemFileReceive::status = StatusFinish;
    8 Z9 W7 D+ a: j. `6 _, g

  192. . @4 G4 Y  I0 \6 E. T
  193.             writeTimer->start(WRITE_TIME_OUT);
    # y6 G6 U* K+ @. T0 K( Y
  194. ( y3 e7 p# M/ f% c1 p! \+ e* V
  195.             return CodeAck;4 y4 `5 F, N5 D! m' f, G* D% U
  196.         }& @5 V9 s; ?5 |, M

  197. ' M6 r: O; |2 S' Z
  198.         case StatusAbort:
    # f  K: l0 c- _9 r6 r
  199.         {& _/ C/ u. ~) T
  200.             file->close();
    " W, l+ Q; N5 Y0 T2 F
  201. & b6 z+ i3 Z: U: Z9 C( r, k  i
  202.             YmodemFileReceive::status = StatusAbort;
    " U/ F/ }: ]( h4 q3 _/ q
  203. 9 \+ C( ^3 w/ _& u, l1 j
  204.             writeTimer->start(WRITE_TIME_OUT);
    4 x( I/ B$ P3 j( P* d
  205. % u$ P. W: Q) f" w3 J2 D
  206.             return CodeCan;
      E2 f! T3 c0 g  z8 q
  207.         }9 ]# E; A( f6 G, \3 ^
  208.   |* c; O: \9 L! G1 Y
  209.         case StatusTimeout:
    * K3 m3 l1 X* \( u. O
  210.         {
    7 ~  A3 P' [( H% [
  211.             YmodemFileReceive::status = StatusTimeout;2 v) c( Z5 h( c& N2 ]9 O

  212. $ {* Q4 J" B1 n* A
  213.             writeTimer->start(WRITE_TIME_OUT);, G) H; K$ P1 _

  214. ( y- W( J( g: J/ d
  215.             return CodeCan;
    ; o* Q" M8 d6 h3 _" d* J/ M
  216.         }* V6 p* A* P$ F( j* h6 }8 p

  217. # d$ a" y4 Y1 r% v
  218.         default:1 {' w8 b4 f% Z8 K- a
  219.         {
    5 j" x6 ?( Y/ Z2 n9 R
  220.             file->close();5 Y: v/ G7 \- i+ z1 E
  221. ( _( E( k# c' H
  222.             YmodemFileReceive::status = StatusError;
    + [1 Z2 Y0 ~# ?' P# {; [
  223. 8 L, R4 e" b6 x$ y; h
  224.             writeTimer->start(WRITE_TIME_OUT);
    * |' I: o: d7 e1 |* x
  225. $ Q* a7 p, [$ q
  226.             return CodeCan;# y1 g. _7 \3 ^* i2 @
  227.         }
    & U4 X( T) Y5 h& @  N( V
  228.     }
    - g7 ]; z: H8 V
  229. }
    ( P* t6 x; M$ F' }  ]6 ?

  230. , {5 L0 _% R% c" I% R
  231. uint32_t YmodemFileReceive::read(uint8_t *buff, uint32_t len)4 f; {+ j0 x# P
  232. {. p% `9 B, U) t7 q8 N: C
  233.     return serialPort->read((char *)buff, len);
    & K$ x: p( O! @! ?* X& K" w2 t
  234. }7 [8 T9 a) w- c$ D6 a8 Q# i

  235. 9 [( a( {9 M9 D: o# i% t
  236. uint32_t YmodemFileReceive::write(uint8_t *buff, uint32_t len). w  Y9 J1 _8 o8 x- B& E+ o5 ]
  237. {/ s, Y( Q5 l% H8 v1 r$ Q% a
  238.     return serialPort->write((char *)buff, len);+ J  Q, `: z# ]* G) f8 w* D
  239. }
    ' ^' r( M8 y5 }+ G$ {' r
复制代码
+ @- O. C9 y& p" s1 d
5 a# |# s2 ^% a, L) s8 `8 ~1 B4 J% |
4 z1 z) Q2 d8 L$ ~* d6 D- i/ a
/ l+ L- h. U& q3 N% @
XinLiYF 回答时间:2018-3-6 02:00:03
      YmodemFileTransmit.h文件- z! y, x7 E+ E$ N, G( C- m/ C
  1. #ifndef YMODEMFILETRANSMIT_H
    ) H  K4 c' N& s# K! ^  S+ p3 u
  2. #define YMODEMFILETRANSMIT_H
    1 |5 M! @1 \3 u8 L/ }9 J% D, _4 y
  3. 3 o$ f$ W4 Y# m- Q$ {
  4. #include <QFile>+ O- N+ F5 |/ H+ i
  5. #include <QTimer>3 D& b# R  @1 ?6 f$ ~
  6. #include <QObject>
    0 {. E; }$ U7 F( V' K7 l
  7. #include <QSerialPort>* i$ e8 w+ B; }. u! w
  8. #include "Ymodem.h"
    4 ^$ u( s) B: m

  9. 7 I0 m0 |% C0 c% J3 u
  10. class YmodemFileTransmit : public QObject, public Ymodem1 H2 ], X+ G/ ^+ [5 }' T0 q1 C5 b
  11. {
    6 ]- `2 M; G  m; X0 v- u
  12.     Q_OBJECT6 r; K+ r* g0 a
  13. , t7 Y: v. ]6 L& K* f! G
  14. public:
    + [! Y9 x4 W: e! E# [
  15.     explicit YmodemFileTransmit(QObject *parent = 0);
    + X! V0 q! [1 B3 k3 w: X$ Y+ e
  16.     ~YmodemFileTransmit();; W. k* U  h( w9 |/ b

  17. . y8 R: R0 F2 T
  18.     void setFileName(const QString &name);
    & Y9 H5 L7 x2 y  B1 R  G/ K' t

  19. 9 q2 V: m# V* c3 u6 U8 b
  20.     void setPortName(const QString &name);) |3 ^: K# n( z& g! W/ A4 R
  21.     void setPortBaudRate(qint32 baudrate);
    + |0 ~3 B) v8 N; t; g
  22. 0 p9 b+ a3 \4 V- L
  23.     bool startTransmit();- l$ O5 M2 A  p% y7 T2 ~6 X0 K
  24.     void stopTransmit();  R" n- x2 Q: ]

  25. ! ^6 q. p+ P# m: G: u$ R  U& {
  26.     int getTransmitProgress();$ j1 j2 P* {( h" y7 o5 B1 U* p) x
  27.     Status getTransmitStatus();
    3 }6 c$ u, V7 |; E+ O" p  R
  28. 7 f3 o" i. i) ~& x6 U8 z+ `! _
  29. signals:
    7 f* ~$ ]" B* S# S; O- b' w
  30.     void transmitProgress(int progress);2 s# F- C$ g* m4 Y! |5 s
  31.     void transmitStatus(YmodemFileTransmit::Status status);- v7 `$ |# m. k

  32. . G) @2 m& `( g8 t/ G! K& h
  33. private slots:  X- q6 ]/ Z, t+ G* i* P  {
  34.     void readTimeOut();5 b5 {) G8 L0 _; g
  35.     void writeTimeOut();  s% H% k& C. _+ J$ b
  36. + X; c/ `4 M! t+ _9 o; P) z
  37. private:* k- G  \" W& k) w3 j- R
  38.     Code callback(Status status, uint8_t *buff, uint32_t *len);6 [- h8 A* @0 ?2 w

  39. 5 e# y) I( c3 _) [2 q( G
  40.     uint32_t read(uint8_t *buff, uint32_t len);
    + J, X- H+ f- D& K/ O
  41.     uint32_t write(uint8_t *buff, uint32_t len);$ `1 k8 G% x* Y! x
  42. 7 t0 Z' \; C/ p) k6 j) w; {$ q
  43.     QFile       *file;, f' B: t9 M, V7 H) G3 h# t- a6 p
  44.     QTimer      *readTimer;3 E0 l& Q# d: C7 U0 b% x1 ^: G0 o; o
  45.     QTimer      *writeTimer;5 O5 d9 F1 ?: T: v% z2 x
  46.     QSerialPort *serialPort;
    ) [- ~6 K" x  {/ q
  47. % M, z0 N: @2 Y8 w& I
  48.     int      progress;8 d' b- B# f" P. r) Z1 c
  49.     Status   status;" h3 ^0 ?" K7 U* {" y- ]- a
  50.     uint64_t fileSize;4 K3 ], O1 a, m- Z2 |
  51.     uint64_t fileCount;
    ) D& h8 X% u6 I  T' E0 ]
  52. };
    & ?- f# j: O" Y% j" w
  53. 1 Z5 `/ j( P; O! ^* U* w9 L
  54. #endif // YMODEMFILETRANSMIT_H
    1 G1 M) q; l2 Z8 X/ X3 H' g! z' V
复制代码

+ K8 T) h0 S$ f0 h, a      YmodemFileTransmit.cpp文件7 I5 E8 T2 r# U' a  t" O
  1. #include "YmodemFileTransmit.h"; ?8 D3 \% U+ c# t) W8 {
  2. #include <QFileInfo>
    # A% r! ^) y+ R" L5 D5 K' ]. u* r7 u3 z
  3. / q1 z: i7 S: Q
  4. #define READ_TIME_OUT   (10)
    " C# z& B; Z5 V
  5. #define WRITE_TIME_OUT  (100)
    ( f9 P4 e9 x+ `# e) Z7 E
  6. ) l8 M1 t* O& z, t
  7. YmodemFileTransmit::YmodemFileTransmit(QObject *parent) :( z( ?/ h. Q/ R7 W% H( F/ e  q7 W
  8.     QObject(parent),# o; c  I1 ^) O2 R' v
  9.     file(new QFile),
    ! H% e0 j; M! K' ^
  10.     readTimer(new QTimer),
    1 D- T, s7 q4 Z! K6 Q, B0 S
  11.     writeTimer(new QTimer),
    2 Z" l$ A& F5 S4 S- P$ {
  12.     serialPort(new QSerialPort)5 N) V& @* x0 r& W! ?$ C1 e
  13. {
    * g& c+ c4 d2 Y, g
  14.     setTimeDivide(499);  t+ ~. b3 ~) }0 {
  15.     setTimeMax(5);# X+ ^8 s1 ]5 [) S0 K2 A2 J7 p
  16.     setErrorMax(999);$ `: \# C' r3 U/ D

  17. * p2 O" T$ p: M' u8 ]# d4 O
  18.     serialPort->setPortName("COM1");
    " h' j9 t4 [; S& D+ g8 A; o
  19.     serialPort->setBaudRate(115200);
    0 O" L, O" e  I# t+ `2 h! F
  20.     serialPort->setDataBits(QSerialPort::Data8);; g: x) e1 w" y& F; i0 R
  21.     serialPort->setStopBits(QSerialPort::OneStop);
    ' B" m. X1 j/ f# s  U9 H  n
  22.     serialPort->setParity(QSerialPort::NoParity);" B3 N" J$ E% Z: [, c% D
  23.     serialPort->setFlowControl(QSerialPort::NoFlowControl);3 m6 L  x: i# W& |; b+ `+ h

  24. 5 U& n3 k3 Y  N; Y" q
  25.     connect(readTimer, SIGNAL(timeout()), this, SLOT(readTimeOut()));! ^' o# v- E: b3 o7 V3 I; a4 T  Q
  26.     connect(writeTimer, SIGNAL(timeout()), this, SLOT(writeTimeOut()));: S& L# Y. A$ R3 w" |
  27. }
    ! D& N$ b- H4 f( G# }

  28. 0 @; H. @% c+ P: Z2 N, {- M, ?7 i
  29. YmodemFileTransmit::~YmodemFileTransmit(), g0 M  O, }+ ]; N
  30. {
    / |% e- c8 ~3 s# G
  31.     delete file;
    0 h2 S$ |  g, P  y. s
  32.     delete readTimer;
    2 G' T# b+ l: W  `  J" _9 F6 F7 z
  33.     delete writeTimer;
    # r. f3 M  F/ {* F
  34.     delete serialPort;
    % t2 T, o! e, G# @" a8 m4 {/ X3 z
  35. }" i0 N& x& S( l: X# V6 [

  36. ; w% C1 d5 o5 S: ?+ @& m
  37. void YmodemFileTransmit::setFileName(const QString &name)
    6 u. F5 u) X' L$ t$ w" p* d
  38. {$ G+ p# ?( f7 }: M" g% V9 T
  39.     file->setFileName(name);. V" _! S6 j# r, k9 l6 r
  40. }& M$ U, U3 M+ M7 Y" ^( u

  41. 6 E( Z2 U5 _( L6 j9 G
  42. void YmodemFileTransmit::setPortName(const QString &name)
    , ~. o  o8 k7 X8 h# `" l. m) i; G
  43. {$ O: T2 m0 X7 z" f
  44.     serialPort->setPortName(name);
    - ~  [: j' A9 x3 j/ ^
  45. }
    ) f  J/ t) Y$ Q: h3 d
  46. ( m  Q  M( c( E: w2 W
  47. void YmodemFileTransmit::setPortBaudRate(qint32 baudrate)
    2 `  w. \" s+ j
  48. {/ l1 M* I- m  s5 L9 b
  49.     serialPort->setBaudRate(baudrate);. y. j6 S( n- D3 F# D- K! P4 x2 u
  50. }
    2 z2 j, E8 ~8 N1 e0 k% x
  51. , L1 q0 t" c, Q: ?( c& G
  52. bool YmodemFileTransmit::startTransmit()
    4 Z* b( T- E' c1 }( F/ P
  53. {
    ) `" q$ R, N* o: J
  54.     progress = 0;
    ' i4 d. m" [2 B0 I4 f
  55.     status   = StatusEstablish;7 z$ V6 d5 j9 y# x0 r8 l7 f  K; p

  56. / m+ _9 ~( G- r
  57.     if(serialPort->open(QSerialPort::ReadWrite) == true)
    " Z. I( i+ F7 H6 t* k1 \0 w
  58.     {
      v9 Z. [6 F% P- d% I  u
  59.         readTimer->start(READ_TIME_OUT);9 J2 }( f( `7 z! X9 j
  60. ( S+ [. {, Z2 R( T
  61.         return true;, j7 u8 [; h3 _1 e; W  j
  62.     }% b9 d! C8 ~5 {
  63.     else" j; ?  |3 f9 ^) T- E# j, L# ]
  64.     {5 \. `9 p, E/ ]' Q5 }: ]
  65.         return false;1 Y0 J: F- V$ N6 A/ Q* q+ F0 G
  66.     }+ R+ z* \$ ]  r3 b7 m1 Z% G2 P
  67. }! i, u8 _; m. v0 n6 P- I4 D- o

  68. 7 i) m3 J- I8 c
  69. void YmodemFileTransmit::stopTransmit()
    1 P3 a* X3 x, p1 |' s. k* x
  70. {( g' u0 e6 w" _
  71.     file->close();
    & L) R' H5 R7 u( E2 }. O  _6 Q
  72.     abort();
    5 J# e/ T4 f. o. M) X1 q
  73.     status = StatusAbort;  M' W+ L, R- H
  74.     writeTimer->start(WRITE_TIME_OUT);; ^2 O6 T% q* V! R0 G
  75. }1 n7 H+ C: T8 L% [* P

  76. ( t8 g8 j5 E+ P6 }9 T, C2 z
  77. int YmodemFileTransmit::getTransmitProgress()6 s0 v! U4 |; z
  78. {* |, c: s% x  `4 j# ~1 K: W$ v
  79.     return progress;
    3 t+ |9 r7 d) E
  80. }: F+ O  e2 j$ r9 w3 Y
  81. % k  p9 l* K% `: `% K0 T6 W
  82. Ymodem::Status YmodemFileTransmit::getTransmitStatus()
    7 U5 f& M* D4 r# N
  83. {7 ^: ~* G; E3 L! `. B# K
  84.     return status;3 O. B0 k# X8 ]0 M
  85. }
    + n# v  d* d: M' V4 J3 u. @. B

  86. ; i2 I2 o" Z) A# _1 G3 ^1 i
  87. void YmodemFileTransmit::readTimeOut()9 U% o' L( P7 N% o8 L0 u$ |
  88. {
    0 V: j7 r6 u5 l- e
  89.     readTimer->stop();
    3 o4 U9 |4 v% V7 E

  90. - B% M1 P) y% `0 V
  91.     transmit();
    . x4 H: L5 j4 h0 D* y% |$ |+ d5 r
  92. ! A7 X( q9 a) x3 S; N) P* q
  93.     if((status == StatusEstablish) || (status == StatusTransmit))" }+ e( q9 }- i* _
  94.     {7 C& ?8 ^. X1 d! a8 u
  95.         readTimer->start(READ_TIME_OUT);
    1 h; i4 {% \8 [' \: y( R) Y
  96.     }/ s& q5 ^1 y" U) U; a: S' |
  97. }  W% {3 C2 e8 n& g

  98. 2 Q- ^! G, t, [& U' |
  99. void YmodemFileTransmit::writeTimeOut()* A$ j7 J0 m- {3 v
  100. {
    / i: g8 C; L# _! @: ], R) v
  101.     writeTimer->stop();/ ^3 D# B9 o! L, ~! @
  102.     serialPort->close();
    ) |" b9 w) f- @; u
  103.     transmitStatus(status);4 F9 h0 _) h* }  i
  104. }
    # h* k+ I( m2 V: `2 Q8 h- t

  105. 8 ~' ~/ a0 `6 Q  o; {
  106. Ymodem::Code YmodemFileTransmit::callback(Status status, uint8_t *buff, uint32_t *len)
    # o. ^) i. D  `3 j, i  S; K! m
  107. {; ~# \6 O) o: h& [9 s! ^4 E& d1 F
  108.     switch(status)4 v' p* S! y& o3 V- {
  109.     {' J3 {- W: c* w) }9 Q2 l2 q5 u
  110.         case StatusEstablish:1 n$ q) A; ], m( r0 H, o
  111.         {9 W: b* F* |$ r/ U) F" N% ^
  112.             if(file->open(QFile::ReadOnly) == true)8 y% R) c# q  l1 a
  113.             {
    % @* N1 y9 U2 `5 \6 c4 q
  114.                 QFileInfo fileInfo(*file);
    / o( S3 V' E- K9 ^" V  g9 r. S

  115. $ i7 K- i) X+ k. X$ b" u% Y
  116.                 fileSize  = fileInfo.size();
    & P6 b  u' F3 ~
  117.                 fileCount = 0;  S0 C8 L" i4 i) R1 B* R' h
  118. ) c) ^; A3 _" y% l! T( Y
  119.                 strcpy((char *)buff, fileInfo.fileName().toLocal8Bit().data());
    ; C. n" h$ w: T; |  ]- S  _
  120.                 strcpy((char *)buff + fileInfo.fileName().toLocal8Bit().size() + 1, QByteArray::number(fileInfo.size()).data());
    7 }0 V- v3 A) U7 H6 w( v, s) D) L

  121. " {. T+ A/ C' l5 n
  122.                 *len = YMODEM_PACKET_SIZE;) w' }" x. k3 G; G
  123. & U/ U; Y5 A* ]
  124.                 YmodemFileTransmit::status = StatusEstablish;
    # h) M; d$ |/ |

  125. ; e4 T/ @0 u" u
  126.                 transmitStatus(StatusEstablish);! t) U! o0 g1 k& ^/ v1 `

  127. # F: ]* D* V/ q) Y3 R+ T
  128.                 return CodeAck;
    7 I" @3 V, ~: |( J
  129.             }
    4 E6 {. J; l" E
  130.             else; F8 ?5 s1 |+ m" y* s5 \3 W
  131.             {  u  @9 c' m  |, i) S0 X8 g$ }9 w; }4 m7 J
  132.                 YmodemFileTransmit::status = StatusError;( x, V; G8 p0 e5 t
  133. $ B. W# d% t" |6 b3 a, O1 w
  134.                 writeTimer->start(WRITE_TIME_OUT);
    + B; a0 G6 y8 K& {7 G8 U

  135. ' Q# q" s1 y0 C6 w4 _$ T5 W9 o9 }
  136.                 return CodeCan;% C: c  k: }: H, _/ u, f: j* }
  137.             }- Z, W4 n( D" P7 t
  138.         }  N. B9 C& }8 u; d* N+ a
  139. 2 R4 R4 I, Q$ C) F0 i; D
  140.         case StatusTransmit:
    6 X! \9 q9 i0 |1 h
  141.         {3 p- `6 e3 r7 \: |# u$ X3 }4 H0 @
  142.             if(fileSize != fileCount)
    + v/ ]: ^+ ^% f0 R) g# [
  143.             {
    2 ?" Y+ k; \+ s/ R& `0 X4 _
  144.                 if((fileSize - fileCount) > YMODEM_PACKET_SIZE)6 w9 u+ m; k: d) z, G  N
  145.                 {
    . L8 s3 j. d9 O
  146.                     fileCount += file->read((char *)buff, YMODEM_PACKET_1K_SIZE);( Y% L3 D) S5 M! z  E+ |- b

  147. 8 `! }$ ?  @3 ^: E
  148.                     *len = YMODEM_PACKET_1K_SIZE;8 t# O0 N* q. Q5 `- C$ U0 @  u1 ^
  149.                 }
    # e- U9 D3 T! r# @
  150.                 else
    , q, d9 _7 F" z& S+ e8 P, c5 j
  151.                 {8 w& C3 _. h( x+ A3 i5 @2 V
  152.                     fileCount += file->read((char *)buff, YMODEM_PACKET_SIZE);8 O) J" `2 Z2 ~( X5 e

  153. 4 `1 \2 X" x! k0 n4 U
  154.                     *len = YMODEM_PACKET_SIZE;8 w; |) N( x  H; U: @, D
  155.                 }
    ' Z' \2 M. o3 d9 v
  156. 2 J3 _$ w  e7 A/ r5 |+ X
  157.                 progress = (int)(fileCount * 100 / fileSize);; Q3 x3 T' E) h: w& E& m5 P( |& A8 P
  158. 9 N0 [9 M* Q! y9 \! c
  159.                 YmodemFileTransmit::status = StatusTransmit;  p; s; [; Z$ S' ]
  160. 2 ]9 ?) r1 Z* S/ N
  161.                 transmitProgress(progress);
    4 B( t$ @8 F2 Y$ K% W1 v9 N; p
  162.                 transmitStatus(StatusTransmit);! p$ x) X' [- R  d* q4 o

  163. ! R8 j# F. `- w) x8 B  T* o* a' N
  164.                 return CodeAck;. {. h# F8 c* V7 g" d4 h! L+ p8 S
  165.             }
    - u. J9 p- s% ^* f3 `0 B
  166.             else
    1 N% M% ^' J+ r4 M6 W5 _7 _7 N
  167.             {9 r. }( D4 S0 y* L" P
  168.                 YmodemFileTransmit::status = StatusTransmit;
    + Q8 g% i' c# j, i

  169. 5 `5 T) n$ z5 \4 a6 R6 P$ V
  170.                 transmitStatus(StatusTransmit);
    3 w7 F( f. F* B0 J
  171. 8 ]1 i) z0 {* n5 a; J  K. m9 K0 |) d
  172.                 return CodeEot;3 v3 O. t( _& L7 V# ~8 j
  173.             }
    3 \+ E. E5 P2 S- D7 c1 ~" D0 B( A* W
  174.         }
    # D8 b# r3 S! w; {

  175. / C+ y- }( r7 t' N0 g2 H2 g+ b
  176.         case StatusFinish:1 v8 l$ s/ _8 [, B- J6 r
  177.         {
    $ Z& ]0 O: I) p+ O, W
  178.             file->close();. C2 }+ h, k" _) r( U, ^( i! Q
  179. 7 e# M# ?, E/ P  K1 E( [
  180.             YmodemFileTransmit::status = StatusFinish;: k" e/ X  v3 h; \; n. q/ H4 U

  181. 1 |6 z! u7 ?' t/ F7 _2 }* h
  182.             writeTimer->start(WRITE_TIME_OUT);
    ! i6 a6 R& ]- G$ D, e
  183. 1 t+ T3 a& x, k! |% E/ G
  184.             return CodeAck;
    , u7 X/ H$ A* K; w" ]  ]3 P) d
  185.         }5 a) q$ @: s. k
  186. , C4 k0 H2 ^8 j( c/ N
  187.         case StatusAbort:
    2 P7 @' C& G. ~- n
  188.         {
    9 g4 d, y) W8 i# W2 s! A
  189.             file->close();
    % B2 C( H0 t. C! ?
  190. 2 f% Z! m! C% S! [  L, y9 Z7 U5 r
  191.             YmodemFileTransmit::status = StatusAbort;
    ) J9 S5 s& r) z0 `
  192. * S( K3 w1 W6 z; z9 _
  193.             writeTimer->start(WRITE_TIME_OUT);
    . ?: @3 ~7 z3 I. i
  194. 3 V; b5 |8 P/ b) S
  195.             return CodeCan;
    % Z1 i' b2 ^! K+ r5 j
  196.         }# ], O. I: D) ?1 z) \
  197. " ~- u/ E8 Q* Z7 Q/ }3 i1 L7 f
  198.         case StatusTimeout:
    ! Y3 C# Y/ `2 N( K. v8 G
  199.         {  Z8 }7 [+ [7 X
  200.             YmodemFileTransmit::status = StatusTimeout;6 I# z+ G( s; ^' b! F2 f3 c. U
  201. : I& F+ J- d8 r6 C
  202.             writeTimer->start(WRITE_TIME_OUT);7 X8 Z) O" |8 T+ v

  203. 2 U! i2 ^% J1 X9 O+ A; c8 ^: L  _
  204.             return CodeCan;
    ! }8 u: w/ ]9 P) B
  205.         }+ n  b  Q. _3 q2 n6 b

  206. 4 V# w8 F: C5 I! P6 R) ]
  207.         default:
      N2 [) n  V& P% h9 ]# \
  208.         {
    ' ~8 D9 P. C, z7 i0 D
  209.             file->close();
    / i4 p0 K  d3 s9 d  K$ h6 K0 C
  210. ' T8 A; k. x$ n, L8 R& G: K  i
  211.             YmodemFileTransmit::status = StatusError;  {/ N8 S3 d+ D/ x$ M' r/ N

  212. . k* O% Q, n0 ]! E/ X# ^+ y) M. N5 o
  213.             writeTimer->start(WRITE_TIME_OUT);( m1 T) q2 p( N) ^* \% h- l7 B

  214. 9 p5 M& D" p( H) P+ g' @- F$ l
  215.             return CodeCan;' Q4 c3 @! d# b! i8 W9 K' O% N* C; O
  216.         }
    8 q5 `$ G+ Z$ L
  217.     }+ u1 S% m% @/ H' h. g: ?. i
  218. }
    4 M0 Q/ E' A: ~* ~: {2 Z
  219. - X- N& q9 W! n, ?$ L  N# L/ G
  220. uint32_t YmodemFileTransmit::read(uint8_t *buff, uint32_t len)
    % E4 m! v% q+ b2 N
  221. {9 ~9 B" n) d  r& {/ f
  222.     return serialPort->read((char *)buff, len);
    4 @( {$ C% Y+ \8 @% U+ Y
  223. }
    ' d! A# }- s5 H" d0 m/ F
  224. 4 U$ X: l+ W. H0 S' l( `
  225. uint32_t YmodemFileTransmit::write(uint8_t *buff, uint32_t len)
    0 E6 H" f* T6 L; a% J$ W
  226. {
    ( n5 ~! I+ j; O/ l5 K
  227.     return serialPort->write((char *)buff, len);9 ]4 m( W# |5 }9 W' u! R
  228. }
      D; J- V% P! G
复制代码

+ c; t, e: I+ Y
4 ]2 M. c; j! h; j# c3 M- h. p: G
& i. M% g  S+ z4 x% P6 W# Z% b; l" J
; [. b% D5 z$ g6 g; ?6 R
XinLiYF 回答时间:2018-3-6 02:02:04
      widget.ui文件
# O- a9 S; V: T; u2 W& ]
  1. <?xml version="1.0" encoding="UTF-8"?>
    % N! _/ A9 ?8 B* j' \; U  H
  2. <ui version="4.0">$ Z5 `2 C/ c+ F8 E. f2 D  I3 Z
  3. <class>Widget</class>
    # J2 e% ]  h( O& O/ Y
  4. <widget class="QWidget" name="Widget">
    5 t7 u; f  ]" w0 P8 P) _
  5.   <property name="geometry">4 W6 b0 j$ Q) M0 v2 T8 b7 i7 z& l
  6.    <rect>
    ; A. t! a6 r/ z
  7.     <x>0</x>
    ( M+ r, `( P7 ?% A; a1 W8 l2 m1 R
  8.     <y>0</y>
    ' y. o! i% ~7 A! \+ C: n
  9.     <width>444</width>, E6 I* D; b4 }
  10.     <height>255</height>
    4 Z4 ?2 A2 _& s, l. B. Q/ {& P
  11.    </rect>
    ' m& d( v. ]) ?+ \& e- W& p0 J" a
  12.   </property>
    / V' \" T+ T$ H! f: I* w; J! A: ]
  13.   <property name="minimumSize">4 {& ^+ y8 t" _  w2 {
  14.    <size>. j; ^2 K) W' L, V* d
  15.     <width>444</width>& }: n; P/ ?% a8 G
  16.     <height>255</height>. R+ ?1 `: S5 {; ?8 V5 v
  17.    </size># o1 A; N* K# b9 a  G3 J( `
  18.   </property>3 i# k* f: m0 Q/ |
  19.   <property name="maximumSize">
    % V' i0 {* Z. G/ U% ?0 i" l* L
  20.    <size>
    * s  _: K7 z# G1 b# P
  21.     <width>444</width>$ [* Y" W( f& S$ z5 q# E$ }0 H7 c" m
  22.     <height>255</height>) D( d" P; H2 }4 l+ z4 Z# Z5 l3 G
  23.    </size>
    ! B0 x, w) |' x6 C- _
  24.   </property>
    ( z; Z. c' G  ^/ }5 ?
  25.   <property name="windowTitle">5 a+ t, Y' l5 G
  26.    <string>SerialPortYmodem</string>
    7 k7 ^( E# J( U! w+ \) \- K
  27.   </property>
    8 `8 B3 ^2 o% B% ~2 q5 {" ]4 }0 Y
  28.   <layout class="QVBoxLayout" name="verticalLayout_3">- y2 d% E7 j) r! l  t+ J
  29.    <item>$ k8 I( x3 l8 f, p" V2 d  L
  30.     <widget class="QGroupBox" name="groupBox">
    ' v* h3 V; R' Q# r; x& g
  31.      <property name="title">
    3 f4 Y7 z- p4 c2 ~" R# O' i4 N
  32.       <string>串口配置</string>
    , R0 l: H& V4 w& j: o0 C9 q
  33.      </property>
    : X* C/ f* ~; z" ]: O; b
  34.      <layout class="QHBoxLayout" name="horizontalLayout">8 `3 S$ s; ^& X( x0 m
  35.       <item>' |6 A( J; e9 p7 m
  36.        <widget class="QLabel" name="label">- d7 }3 [# h5 @2 P8 x
  37.         <property name="text">
    " i7 d, x. D! J2 L% v
  38.          <string>端口:</string>
    6 D: S; W) j# k* X. M' D# q
  39.         </property>
    , Z& [8 x- J4 J/ u- s' O% r( s
  40.        </widget>
    3 i2 _. K4 Q: L. l: C3 e6 _) k
  41.       </item>+ ~- x& a- C) \8 }* d
  42.       <item>* Q0 J) Z2 H; c& ^! f4 s
  43.        <widget class="QComboBox" name="comPort">4 D. |' f* d5 {8 j2 v
  44.         <property name="maxVisibleItems">" u$ A+ }3 g3 K2 @
  45.          <number>12</number>
    2 V, s, h! i  Q9 ?
  46.         </property>/ r1 e! P0 M. V
  47.        </widget>. s- N1 q# }) u# a
  48.       </item>
    # Y$ x# `% g; t+ V+ F
  49.       <item>; F" B( P2 L  N. k, g
  50.        <spacer name="horizontalSpacer">0 Y# j5 C- K% m/ F" T
  51.         <property name="orientation">
    $ x8 \* R7 Z: w8 Y
  52.          <enum>Qt::Horizontal</enum>0 c$ [: P) j, b4 D' h) w: E; }
  53.         </property>
    " r7 y2 A- B* R* S
  54.         <property name="sizeHint" stdset="0">9 x, ^( Q8 W5 c. U4 g' ?
  55.          <size>: p9 E' Y2 H) C1 b3 w
  56.           <width>40</width>9 I# y. @& {1 r! b! t3 e6 O2 ]+ Q
  57.           <height>20</height>
    / H+ e  w7 V  r1 U5 h7 ?& e# _
  58.          </size>( p- I/ F$ ]7 G+ `, L/ w- F. D
  59.         </property>
    ' t" L. g# ]9 \6 b* R( \
  60.        </spacer>
    : H' C8 T$ |" ^6 N
  61.       </item>
    ( i! r. A& p1 l2 s% Q8 W7 ^
  62.       <item>
    - H; @4 K2 `+ o  b* I
  63.        <widget class="QLabel" name="label_2">
      j5 Z( D6 @; o0 k2 b
  64.         <property name="text">
    7 N7 J' G5 I, s! Z
  65.          <string>波特率:</string>' B7 l) e0 ^2 a9 \2 y( Y
  66.         </property>( _. j# p' w: R, s/ f) [' L9 |
  67.        </widget>3 n7 E" R7 q  W" O. D% U2 v
  68.       </item>- k* G! {* o  M& t/ w
  69.       <item>
    ' c! a3 C2 {* a2 z
  70.        <widget class="QComboBox" name="comBaudRate">+ H# V9 |8 ^: F0 ]# X6 |
  71.         <property name="currentText">( {% ^4 [  L2 H& }. d
  72.          <string>115200</string># |( b3 h/ m$ `7 q$ Y' g
  73.         </property>
    " ~1 j2 K  q0 }4 s" F
  74.         <property name="currentIndex">
    3 K* z& a3 Q* w$ r1 F1 k6 Y
  75.          <number>3</number>3 ~" w* H% T$ D* B
  76.         </property>  D, j0 [2 z& a3 L  F
  77.         <property name="maxVisibleItems">$ k; s9 |. j$ e+ H
  78.          <number>12</number>- a% R: I' {& y# h9 E( R
  79.         </property>' `+ r+ @) U" u) |
  80.         <item>
    % I! t% w0 r) Z) F3 _5 `
  81.          <property name="text">
    , G; z* N' k9 s$ E$ E) A# ~
  82.           <string>921600</string>( m& _& M% ]( B- K9 b
  83.          </property>5 y/ A  Z6 o, W5 f
  84.         </item>
    0 _% m, }0 z! z0 P3 o6 {  _
  85.         <item>8 U0 w+ T6 f" f, b( g4 U# k
  86.          <property name="text">
    - J7 Q7 x: z8 x
  87.           <string>460800</string>
    8 y7 c: W& w5 E' H7 D4 N/ S9 W
  88.          </property>
    : D7 a7 V( f6 ~: S. R4 z8 z
  89.         </item>  w- e- g$ P  j6 s) U
  90.         <item>
    ; }0 r7 F. s& f. \' N8 A% T
  91.          <property name="text">) _7 [, m; a, g# p
  92.           <string>230400</string>
    1 ]0 N- U- T' @0 Y! R# g. u
  93.          </property>; i3 b, T  A. h  o, U& j
  94.         </item>7 L5 n- J( U% I8 D# ^. Z
  95.         <item>, M6 f+ u- w/ h8 E
  96.          <property name="text">& ]! j4 o8 b* v& K0 A% j1 L6 e
  97.           <string>115200</string>  ]4 t' E. j$ r1 f3 ^; f
  98.          </property>
    4 t* ~2 W7 p. c$ U( B
  99.         </item>; u2 i, _6 o/ t6 r$ I3 @
  100.         <item>
    / Y' _% o5 O' }; v7 b) b7 V) s
  101.          <property name="text">
    ; X  S' Q6 R; z* E
  102.           <string>57600</string>) o% r+ g8 P) }+ D
  103.          </property>* u1 |) F0 \8 a/ S
  104.         </item>) d8 a* T2 O! X
  105.         <item>
    * O: p; G, j! s3 [, }1 S
  106.          <property name="text">
    5 `  O5 u' r, _& P
  107.           <string>38400</string>
    6 Y; @, B+ y1 \2 {: @  \* n* Y$ q
  108.          </property>" Y! U5 v5 `. C- b( E& f" u
  109.         </item>
    ) I9 h& j/ M5 R: X. r9 V
  110.         <item>
    3 o1 O$ K6 V9 z' c( |" `0 i* g$ Z( n% O
  111.          <property name="text">" i# s: ~. \' X. M! z4 [
  112.           <string>19200</string>0 n- A# D& f0 p4 T( y& Y
  113.          </property>' p4 Z2 K" d0 N: |
  114.         </item>7 i' _7 D5 c! i( R, p1 X, x' O
  115.         <item>) ^- t( b* {- a* Y4 d1 a+ M3 M  |7 J% i
  116.          <property name="text">
    # n% J' D- z& b. l
  117.           <string>9600</string>
    # _% X  V1 x, x+ a
  118.          </property>; M' x; }3 P, j% Z) K6 w
  119.         </item>
    9 m0 \% R: w3 a+ G3 A
  120.         <item>
    3 b/ ~9 G0 i  V6 C9 Y) P: s3 s
  121.          <property name="text">
    . h/ U( T- t1 e
  122.           <string>4800</string>8 \. T! n! O* @" n2 @
  123.          </property>1 v4 f5 H6 J. ?. ~0 B+ [
  124.         </item>
    & C- E! Y% }6 |9 V" \
  125.         <item>
      ^; {3 f8 p0 [' @' y2 D
  126.          <property name="text">
    ; h  h2 U$ z7 m" X' B4 ^+ y; o6 `! f& J
  127.           <string>2400</string>
    * F) U6 ]2 d4 F& U1 G5 O
  128.          </property>
    3 F) V5 E! c4 g3 Q( F
  129.         </item>$ c0 R. h, H/ f+ A5 a
  130.         <item>
    ) P" D  @; e: E1 u  f' k9 X9 ~
  131.          <property name="text">1 M4 Q# j, z6 Z: H+ h
  132.           <string>1200</string>
    3 {& A1 b" h) K  c- v
  133.          </property>
    ( s) N1 ^% Q& u8 o0 x2 W
  134.         </item>
    4 ~" @8 h  E2 `1 m0 W
  135.        </widget>3 a2 V5 C, f% D" ]+ ]
  136.       </item>' k+ g, d/ Y4 ^6 O
  137.       <item>
    5 c, S5 R( x' h& w3 _- z1 z
  138.        <spacer name="horizontalSpacer_2">5 J  o& ~3 R& l( `) z4 B2 U; z' I. d1 C
  139.         <property name="orientation">
    8 y, x3 b8 b$ B  U
  140.          <enum>Qt::Horizontal</enum>
    ! j# k7 Q3 ~5 v' Y( E
  141.         </property>
    3 F7 r. U0 V8 D9 o
  142.         <property name="sizeHint" stdset="0">
    * o0 ]  W- W8 Y) F, b- q
  143.          <size>" }: v+ {3 l$ t9 |
  144.           <width>40</width>
    * ~' A2 ?1 h0 t" E# y
  145.           <height>20</height>
    & D- S/ |  ]* ]' H. m
  146.          </size>. T) r- W& h! v# ?+ j8 r
  147.         </property>- Q2 A% `  {; U, }4 R
  148.        </spacer>. d" A; ?- K+ {* n- {
  149.       </item>  C0 D- J: y# P8 J. C
  150.       <item>- k0 i- M. W6 R& c: B
  151.        <widget class="QPushButton" name="comButton">6 E& b" F+ G1 F
  152.         <property name="text">
    0 v$ p0 k; L* ]  w2 E
  153.          <string>打开</string>
    ' x$ S2 L% c& g1 B
  154.         </property>
    & x6 |+ P6 s# A7 g2 M
  155.        </widget>
    * w; K3 `. f: K* b$ q  S) N( T2 H1 ?$ V
  156.       </item>! m, p% F3 r5 d. t% G
  157.      </layout>2 g" t4 E1 S) y  i( D
  158.     </widget>
    / N) q: s) P  a, R. O- _5 }4 g
  159.    </item>3 _. I* M/ @! v# A
  160.    <item>3 _3 `2 f: R; F6 F# o
  161.     <widget class="QGroupBox" name="groupBox_2">
    ! j1 `& X( @! j1 i
  162.      <property name="title">
    & d& @! F8 |9 V. G7 W9 b& S
  163.       <string>文件发送</string>
    ) o. D0 T+ c( \1 T: O! n. v
  164.      </property>
    6 B* q% i: p" i- j5 W: X* b
  165.      <layout class="QVBoxLayout" name="verticalLayout">
    4 d- i1 f: i1 t: V$ O$ v# m
  166.       <item>: E) i  Y& M& D
  167.        <layout class="QHBoxLayout" name="horizontalLayout_2">
    . }% U3 F% [6 e; c$ Q
  168.         <item>: l# k  ~7 C7 L1 Z& w+ E4 d8 m
  169.          <widget class="QLabel" name="label_3">& b  v' x+ @, {8 c8 M
  170.           <property name="text">2 \1 ^1 l& Z1 N# D' u5 O
  171.            <string>文件路径:</string>3 b- Q1 g; w# \9 w* p& k
  172.           </property>
    ; q* ?* h  e) K! m
  173.          </widget>$ {) m0 p* g; o/ I/ }+ e
  174.         </item>
    ; c4 o5 d  V! I+ `$ W& V% q
  175.         <item>. X1 P% g% a5 S! T
  176.          <widget class="QLineEdit" name="transmitPath">% l, H- d1 c- V7 ~; T! C
  177.           <property name="readOnly">
    ( r; t0 N% t* H! L: T
  178.            <bool>true</bool>
    ; Y5 r% e7 R9 S+ h6 ~7 b( j: l. ?
  179.           </property>1 P, @4 G( H/ F  i+ a; q
  180.          </widget>
    / y$ W+ X/ o" h
  181.         </item>
    0 t1 Q. w, h% ^' U9 `) g: A
  182.         <item>( O9 o& |4 ], O
  183.          <widget class="QPushButton" name="transmitBrowse">6 N' d8 j0 M/ I- U$ Z% n
  184.           <property name="enabled">
    7 g# L# _6 O5 d) _1 H
  185.            <bool>false</bool>* w+ `6 ?+ H2 ]  L
  186.           </property>+ E" q/ o' Z0 g3 P8 }4 E" p. }4 ^
  187.           <property name="text">
      G& G. t1 @# h4 y
  188.            <string>浏览...</string>* u3 l/ {+ ~0 D3 K
  189.           </property>
    6 s+ c4 }# z& ]$ G) H
  190.          </widget>
    % y- I. o% Y0 e; e. C  x  n: O
  191.         </item>3 i6 J) T7 O" d' H1 n0 I/ [
  192.         <item>
    9 A. k3 I5 x' ~( o
  193.          <widget class="QPushButton" name="transmitButton">, v. _7 }0 x7 D7 y- ?' h" r
  194.           <property name="enabled">
    . G& C& \9 K/ g% H
  195.            <bool>false</bool>
    : V' _2 m- u( j
  196.           </property>
    ) E+ e5 S9 \. }' g
  197.           <property name="text">, F1 `. u. I0 p
  198.            <string>发送</string>
    + h7 I' X4 N) A
  199.           </property>& z1 u, f8 d% |
  200.          </widget>
    0 I3 ~1 D2 ?( A( X
  201.         </item>; K  B( O0 c7 t" i. B" c/ p" j! X5 _
  202.        </layout>: Y6 k: |6 P+ o
  203.       </item>1 z/ E5 E% O& A& Y6 L3 ^- P
  204.       <item>! Q; T3 k) o* S! A5 B
  205.        <layout class="QHBoxLayout" name="horizontalLayout_3">7 l: q! ]2 I# u
  206.         <item>; O0 ^3 n! E) Y5 w
  207.          <widget class="QLabel" name="label_5">
    - c  a0 i' }2 C; k. H
  208.           <property name="text">' I( X' k/ e& P. }5 M5 S. t! N9 I# v- s
  209.            <string>传输进度:</string>
    " _7 L% V, A3 a; O) S
  210.           </property>9 P" x( i0 L  a2 u& ~& y) o1 ]
  211.          </widget>
    5 \, U) R3 C5 c# d2 g' w, D* z* W6 h
  212.         </item>* {: L$ ^- K+ V, P4 Q# l0 y
  213.         <item>
    , `6 }5 u3 [' A2 }4 Y( \: M) z1 J
  214.          <widget class="QProgressBar" name="transmitProgress">
    1 |; o! \" F( l( ]& I  F9 H
  215.           <property name="value">$ x2 O# {% g+ \9 Z/ j% e0 s/ i
  216.            <number>0</number>
    . ?6 o* }% ]( C. {: }& F
  217.           </property># k& i* ~8 [2 q5 |9 P
  218.          </widget>
    ' e% g% h! S6 ]4 R# Y
  219.         </item>
    + l$ ]# g- e; m- p9 }' N' t
  220.        </layout>/ A  v& H; c/ d) o
  221.       </item>
    * t8 c! ?  x3 o6 q' Q/ ?$ O
  222.      </layout>/ Y  O- b3 I2 |' ^9 S
  223.     </widget>
    % k5 W$ l1 W9 n2 F  H# G& [( \
  224.    </item>% ]1 {2 L! ]" O
  225.    <item>
    5 M& L8 d% t4 Y; d( Y3 G+ Z8 L
  226.     <widget class="QGroupBox" name="groupBox_3">
    ! ?4 I, K% r& f# K, A' ^
  227.      <property name="title">
    9 k% s4 a; i; G
  228.       <string>文件接收</string>
    % F! i( r% m4 I$ F  t
  229.      </property>' `5 z. R8 {4 n
  230.      <layout class="QVBoxLayout" name="verticalLayout_2">
    / F1 w  |' t5 {
  231.       <item>
    - S. @/ c9 ^4 K+ t# D3 ^7 A
  232.        <layout class="QHBoxLayout" name="horizontalLayout_4">
    ( J  i7 d1 m+ g
  233.         <item>
    7 ^! _. z3 C" f! B6 Y
  234.          <widget class="QLabel" name="label_4">
    ' A1 k% I% e8 l6 g" ~  R4 o
  235.           <property name="text">
    $ t% k' X6 A# S& P
  236.            <string>文件路径:</string>
    5 U- D1 h1 s. S8 G& a! Q
  237.           </property>6 [5 D$ b3 }+ k" F: [( _
  238.          </widget>
    2 u7 d5 P( G) |$ ]" W- _3 f
  239.         </item>
    + k# o6 h/ D: x# t- e6 y9 L
  240.         <item># J. ~8 T. t' U! L6 i) {2 S( J
  241.          <widget class="QLineEdit" name="receivePath">
    / O" n/ i) h2 ?( L+ L
  242.           <property name="readOnly">7 c. c# `$ O/ o- _* w1 C
  243.            <bool>true</bool>
    8 E% t5 @8 @% w; w" ~
  244.           </property>! \' `9 n: `1 S; g9 J$ v/ U% j
  245.          </widget>
    % s  a/ G. P2 G* J2 p
  246.         </item>
    6 ?2 v  p1 ~) B; ?: X& }# h! x3 ^
  247.         <item>
    7 j( c6 Q5 h4 @
  248.          <widget class="QPushButton" name="receiveBrowse">: a  w9 e% U: \
  249.           <property name="enabled">
    , l5 F2 V6 y( F* l
  250.            <bool>false</bool>6 g4 r# b3 r! G" A
  251.           </property>' H3 X, J' T& G' ^5 J  d. p2 Y
  252.           <property name="text">
    " b8 T# m6 u8 b) a
  253.            <string>浏览...</string>+ y2 f" E! W' Z& q: a
  254.           </property>
    , x9 i% R+ U. E$ m4 Q
  255.          </widget>' \$ c$ U3 s& Z4 q- g
  256.         </item>
    : |" F/ G1 Z; s& r$ k' p- o& x$ ?8 H
  257.         <item>
      W7 \+ a. X9 E) f, U" B* Y
  258.          <widget class="QPushButton" name="receiveButton">; d  p; J9 Y1 H! n* N0 _3 N6 M1 [
  259.           <property name="enabled">
    ' G2 X* M1 N6 ^5 |' s
  260.            <bool>false</bool>
    * }* j  {6 G" f7 ^
  261.           </property># u8 ^1 l& |% F6 u2 i$ n/ y
  262.           <property name="text">
    " O# N$ p. s1 ~& @& e
  263.            <string>接收</string>
    ( v# [) F  r) z$ c- E; w. O* _9 _$ Q
  264.           </property>8 l5 O+ c3 T6 b1 @' b8 g
  265.          </widget>
    . }4 ]( O; |3 n4 Q
  266.         </item>
    4 H4 J, E6 x  T. G' v3 c
  267.        </layout>* z4 Y' s4 }. h
  268.       </item>
    8 R  D6 h/ [  d) N
  269.       <item>
    * l# C; p! x5 ]6 f& Q
  270.        <layout class="QHBoxLayout" name="horizontalLayout_5">
    & Y5 i9 W1 h) F6 a* _# w6 c- c
  271.         <item>3 g; U. {. J: R* u; e/ j. k" r
  272.          <widget class="QLabel" name="label_6">
    3 n2 P9 F* k' m1 N& t$ Y0 T8 A# h
  273.           <property name="text">2 D8 E6 f4 _1 D1 V9 [. c
  274.            <string>传输进度:</string>
    % t0 Q1 L$ L4 `
  275.           </property>& p' ^, k, ]1 y  G3 I! g) [* t
  276.          </widget>
    % d, E- U; n1 N! V- G: V
  277.         </item>& |3 V* L1 V* Y
  278.         <item>8 b( Y- y) g* c1 M! b1 a6 A& j
  279.          <widget class="QProgressBar" name="receiveProgress">% E! H9 e/ b0 Z' t
  280.           <property name="value">$ v0 O) P+ }, j2 p4 r+ k) d
  281.            <number>0</number>" _. R% O$ u! G$ h( Z
  282.           </property>/ H: ~1 x0 s" x3 p3 h7 J& h
  283.          </widget>
    0 W/ ~+ s2 ?3 M5 O& ^. L) Y
  284.         </item>
    ) P7 I, B5 O4 ~( c
  285.        </layout>: _/ N* E* Z9 {
  286.       </item>$ Z( w6 z6 _3 L" y9 x7 z+ o) j9 b
  287.      </layout>
    6 L" B  X6 j3 w4 g) W
  288.     </widget>8 U. G1 i# b5 D/ s) ~
  289.    </item>7 H" m6 q- G" J5 q7 ]. Y( w
  290.   </layout>, Q/ }! e7 }$ p+ E, C0 @
  291. </widget>
    7 S$ q% S5 s2 W# C
  292. <layoutdefault spacing="6" margin="11"/>
    9 g! _6 Q& |3 e3 |
  293. <resources/>4 z; F1 Q8 G7 `- T, h/ N
  294. <connections/>, R1 p9 s3 x; m  f* S0 P
  295. </ui>
    - y$ p* }  T+ D0 s( u+ R  R9 k
复制代码
0 e" \8 t0 g* V% a5 Y* d; X
      widget.h文件: M% f- `1 i9 @0 D) n2 O
  1. #ifndef WIDGET_H( D- j. \) M& f( i* f, v  W
  2. #define WIDGET_H
    + t' K( n+ e1 z- K4 h7 y
  3. : S; o0 a  F4 s, r; F% z8 t( r
  4. #include <QWidget>
    ) M8 f; B& k1 \1 @9 x
  5. #include "YmodemFileTransmit.h"
    7 G! q( `* f4 ?' w# p3 e' ?
  6. #include "YmodemFileReceive.h"
    3 S& j- H" @" M$ V

  7. % y4 F/ N8 A: Q& G, T6 F4 A
  8. namespace Ui {' s) \. N2 b- f' e3 G" ~( W
  9. class Widget;
    7 v6 I+ d0 E0 m# ?2 w6 [. V; W
  10. }3 p! X5 z: \9 l
  11. # F& z9 O" i4 t$ K
  12. class Widget : public QWidget
      ]7 w- _7 b# B# d8 J9 x" N
  13. {
    ! @- C. V3 a4 {* |
  14.     Q_OBJECT  R2 f- b9 x% Q5 M2 l: E
  15. . W2 @$ V# \7 J9 I7 ^: E
  16. public:
    % Q, d+ Y, `7 ]$ x9 E
  17.     explicit Widget(QWidget *parent = 0);1 b- u  h7 o7 O
  18.     ~Widget();- P" Z2 ]& a6 J! e6 s

  19. # ?6 t4 a& t% Q& n/ {0 o
  20. private slots:
    6 [: R% }1 ~6 n1 ]; h* ~
  21.     void on_comButton_clicked();* i+ ~4 x% `$ Q/ ?
  22.     void on_transmitBrowse_clicked();
    4 M2 T( o. Z* o* G
  23.     void on_receiveBrowse_clicked();
    0 k. W) ], j' J3 ?5 B( W
  24.     void on_transmitButton_clicked();' B5 v' K7 X3 E: p6 d! n# |% A
  25.     void on_receiveButton_clicked();4 \3 `6 D/ p. \# T, H( r# v7 d- q
  26.     void transmitProgress(int progress);
    ; A/ R2 U8 q8 i6 I+ M
  27.     void receiveProgress(int progress);1 L& [8 _) q0 a5 z  e
  28.     void transmitStatus(YmodemFileTransmit::Status status);4 q* z" E: l) d; I
  29.     void receiveStatus(YmodemFileReceive::Status status);" a+ ?# x! J3 H5 g/ V
  30. 1 M& C% \( _7 S
  31. private:
    ) q! `5 v- Q% y9 F5 e7 M! m% T
  32.     Ui::Widget *ui;
    , {9 h1 Q7 q9 w8 l2 n( t6 S% `
  33.     QSerialPort *serialPort;/ v3 M, S" {1 u
  34.     YmodemFileTransmit *ymodemFileTransmit;( }! ]' {/ O* e3 S, s. r* L: g
  35.     YmodemFileReceive *ymodemFileReceive;
    " Q0 f; l4 O, k) m* g( a9 c  e

  36. / f! @1 d5 F* T, W3 y6 j5 z
  37.     bool transmitButtonStatus;
      N3 O" g6 O8 G0 H) j4 U' g
  38.     bool receiveButtonStatus;
    9 p3 W& E8 t0 X# h+ d" A
  39. };
    * z2 n8 W' f: b# Z1 C

  40. 4 X/ f% m8 e! @. j
  41. #endif // WIDGET_H, x  ]! r+ @1 j' a
复制代码
  S; k. g5 a- K
      widget.cpp文件3 k+ x, W+ V' T1 _' ]& F7 _4 o
  1. #include "widget.h"* U2 y7 j, i& G$ I. b3 k
  2. #include "ui_widget.h"+ N' H. E# N6 M, m0 Z" X
  3. #include <QMessageBox>$ k$ d  h5 ]: |
  4. #include <QFileDialog>
    ; N% L, ]$ M) b6 ^4 A2 B& I. z0 y
  5. #include <QSerialPortInfo>
    : ~* V& h+ K- S% B# ^6 T

  6. 0 {* W3 l$ C4 f0 ]& ]6 [
  7. Widget::Widget(QWidget *parent) :! V+ a& }: t2 L
  8.     QWidget(parent),
    4 N" S7 }6 I+ N+ v
  9.     ui(new Ui::Widget),
    3 q# y/ _% q' ?' I8 l# M! U
  10.     serialPort(new QSerialPort),7 q& A: Z( \. L+ F9 g$ [) s
  11.     ymodemFileTransmit(new YmodemFileTransmit),: y5 m' l: H3 w$ X. L. E
  12.     ymodemFileReceive(new YmodemFileReceive)
    & ]$ F* H1 e. ?' p' t
  13. {, S8 s$ P$ w% I+ z) B4 K1 R' P7 E% a
  14.     transmitButtonStatus = false;! D) b$ P6 L, \4 B, _9 L  ]3 e
  15.     receiveButtonStatus  = false;+ e; w5 M0 l, n3 a( k/ t. Q
  16. 0 a( j, z5 {+ E' l8 F! Q1 F) R& @
  17.     ui->setupUi(this);8 l4 {, e9 ]* a; j9 e' d0 g
  18. " ~7 f& }3 J) f+ }8 B0 E; n' ]
  19.     QSerialPortInfo serialPortInfo;4 l3 j5 H$ \# k3 X
  20. # N( y: S* }$ I4 z) d
  21.     foreach(serialPortInfo, QSerialPortInfo::availablePorts())  D0 Z& n! q+ s
  22.     {
    ( M$ A& v1 J7 W0 b
  23.         ui->comPort->addItem(serialPortInfo.portName());0 Q2 a2 J) N; Y- u
  24.     }
    7 m2 l- L) G% ~: W) q
  25. + n8 ?9 V4 q# C
  26.     serialPort->setPortName("COM1");
    % w, D8 J  _- v2 P2 [" W2 Z3 l& y
  27.     serialPort->setBaudRate(115200);, c9 a5 z& U( _6 ?' r4 B1 d
  28.     serialPort->setDataBits(QSerialPort::Data8);
    ( w2 y- g" }8 k, \
  29.     serialPort->setStopBits(QSerialPort::OneStop);; }5 ]8 k5 i# W; F; U9 s( A
  30.     serialPort->setParity(QSerialPort::NoParity);! u+ G% y) q, I( G
  31.     serialPort->setFlowControl(QSerialPort::NoFlowControl);
    0 c' ~; z; n/ w7 Z1 `( }

  32. - }" S3 O! R8 k8 ?0 t
  33.     connect(ymodemFileTransmit, SIGNAL(transmitProgress(int)), this, SLOT(transmitProgress(int)));& t9 Z: L& Z& {/ H  m8 {; m5 y
  34.     connect(ymodemFileReceive, SIGNAL(receiveProgress(int)), this, SLOT(receiveProgress(int)));" i4 y, g0 I" Y  c
  35.     connect(ymodemFileTransmit, SIGNAL(transmitStatus(YmodemFileTransmit::Status)), this, SLOT(transmitStatus(YmodemFileTransmit::Status)));
    1 g3 U9 O9 a& R* c2 r& @
  36.     connect(ymodemFileReceive, SIGNAL(receiveStatus(YmodemFileReceive::Status)), this, SLOT(receiveStatus(YmodemFileReceive::Status)));
    4 L5 A  k7 {5 }1 @& Q
  37. }
    - q( F1 L' H- f5 S+ ^5 G- ]: `
  38. 2 `3 |" G$ K8 k8 I1 k' B
  39. Widget::~Widget()
    1 ^) u! _) r. W2 M% c, |
  40. {  |" H5 \5 j/ D
  41.     delete ui;
    7 R8 |/ n  g- u0 F7 D
  42.     delete serialPort;
    # z' Q/ v; p2 k0 K4 q
  43.     delete ymodemFileTransmit;( W) E% v! W& Y: P0 J& ]/ d
  44.     delete ymodemFileReceive;
    1 k2 I3 p1 e. [: M. a$ ]
  45. }
    3 e( [% @1 o! `) M

  46. - M- ]4 N, ~6 @2 n/ A* \) o
  47. void Widget::on_comButton_clicked()
    / Q! P. i/ Q- p7 `! J" m) R
  48. {
    8 \9 o0 q6 z3 g8 X- [2 n  B6 B5 O
  49.     static bool button_status = false;9 c  ?" z, @: U) n/ U

  50.   g( L7 k7 Z! P0 e
  51.     if(button_status == false)
    - U* O3 j2 d0 W& Y! c7 f% N- A
  52.     {
    * _  B9 K# H1 j
  53.         serialPort->setPortName(ui->comPort->currentText());
    ! T6 y& @" T! x$ y1 V4 `
  54.         serialPort->setBaudRate(ui->comBaudRate->currentText().toInt());
    " n# e6 _; _# V- `0 G

  55. 0 h; b1 h& \, [/ ~5 {1 ]
  56.         if(serialPort->open(QSerialPort::ReadWrite) == true)
    # D! E& m. g% h/ C* {+ @9 p
  57.         {
    4 ~. y/ Q  C+ ?* B- B
  58.             button_status = true;
    & l7 \, \6 B8 d8 c
  59. 4 o9 ^) v# d" ^! N; x8 b% p0 @4 h
  60.             ui->comPort->setDisabled(true);
    ( D0 Y* V$ ?$ D1 H
  61.             ui->comBaudRate->setDisabled(true);
    : D4 {% D' ?& q7 z
  62.             ui->comButton->setText(u8"关闭串口");" G" U( c5 i9 n9 ]- I" h
  63. 5 A7 W& e) K8 n$ Y# D
  64.             ui->transmitBrowse->setEnabled(true);9 p# M5 w2 d- k" V
  65.             ui->receiveBrowse->setEnabled(true);
    & G5 T1 f9 ?9 L  `  K
  66. & Y+ }" e& N& g7 b0 O* Q% Z
  67.             if(ui->transmitPath->text().isEmpty() != true)0 J# y/ O2 P/ W0 Q% k$ I
  68.             {0 @3 S% P* G7 z" f
  69.                 ui->transmitButton->setEnabled(true);7 _2 P9 O7 o5 v7 v
  70.             }9 g0 E6 Z8 Q4 ]; u2 S# ]8 i
  71. / m$ l3 H; p* r. B2 l# |$ _
  72.             if(ui->receivePath->text().isEmpty() != true)
      }5 |% n/ z2 V9 ?* o  ]
  73.             {9 D1 M4 F+ Z: x& M7 e: }. ]
  74.                 ui->receiveButton->setEnabled(true);% n3 i8 o, c. e% r
  75.             }
    : Q! Z/ q7 Z0 T
  76.         }
    ' r* F, `. L5 p9 K1 Y  n0 G. W3 j
  77.         else/ P$ k7 s( P# `! Z& \
  78.         {8 [! i. Q$ C& A) x4 a
  79.             QMessageBox::warning(this, u8"串口打开失败", u8"请检查串口是否已被占用!", u8"关闭");; m$ H1 G3 D: @( y
  80.         }/ H, d" r4 i- {, z; o5 f# L7 i
  81.     }- q9 V) I/ j! x
  82.     else
    . q9 G0 W& h( @7 l" Y1 F4 y
  83.     {
    / m! _/ n" G) X8 ?( o- F+ f+ I1 I
  84.         button_status = false;
    ; I3 s( _0 P- y' O- A. m- C; I& K  U
  85. 4 W0 h7 W4 Y9 Z
  86.         serialPort->close();
    % R* q. h0 I1 Z, Y4 o
  87. 6 F6 L/ G, {0 Q$ w
  88.         ui->comPort->setEnabled(true);5 J7 d% a! u1 ?
  89.         ui->comBaudRate->setEnabled(true);
      n: ~: H; f" N8 J) U+ s% y
  90.         ui->comButton->setText(u8"打开串口");) x4 q' M4 Z' o& _5 Y/ \

  91. & ~1 G7 s9 z! R' c% Z& T+ ^0 f
  92.         ui->transmitBrowse->setDisabled(true);& l7 C- y! f# f
  93.         ui->transmitButton->setDisabled(true);
    . l2 t" y8 H" W, m
  94.   S% H( x6 M) E" m# l1 i2 Y6 F
  95.         ui->receiveBrowse->setDisabled(true);
    : m! ~  s9 a9 ^
  96.         ui->receiveButton->setDisabled(true);' d3 s% X) T9 X
  97.     }
    1 l7 C) w8 ^4 Q  }4 U
  98. }
    6 y" Y9 q/ w. ?* o8 h' y" M

  99.   W0 F8 h  E9 S) t8 z: G% Z
  100. void Widget::on_transmitBrowse_clicked()
    1 e& Y# n0 j. X/ w9 Z8 e
  101. {
    * g8 J' V, v; _6 N
  102.     ui->transmitPath->setText(QFileDialog::getOpenFileName(this, u8"打开文件", ".", u8"任意文件 (*.*)"));
    , `) Y1 a) ]4 k- W) x; d
  103. 9 {, h; ?  _* S$ A
  104.     if(ui->transmitPath->text().isEmpty() != true)
    ; U' Y' j0 _6 {) r. T" ]
  105.     {! M0 o* N1 n/ c3 H6 d0 H
  106.         ui->transmitButton->setEnabled(true);2 p8 ^7 _0 k& I& x0 ?
  107.     }
    7 U. P  l6 A0 C
  108.     else
    $ [. P$ @. Z8 G4 b7 ~
  109.     {, T) ~% }$ @4 E3 g/ [( p) |
  110.         ui->transmitButton->setDisabled(true);/ ~( ]5 ^" |3 t6 S) r
  111.     }
    : n8 k1 A  P5 u' e7 `: e
  112. }
    5 K( L5 H" I& a/ K
  113. / X0 [- n& h: y
  114. void Widget::on_receiveBrowse_clicked()
    9 c  p0 y! t4 \4 f6 `! H# P
  115. {
    0 j3 [' F3 {! c( D0 |
  116.     ui->receivePath->setText(QFileDialog::getExistingDirectory(this, u8"选择目录", ".", QFileDialog::ShowDirsOnly));
    + m; o1 Y# d9 B# u4 z9 M, h

  117. ! i+ X3 F) s$ R) E
  118.     if(ui->receivePath->text().isEmpty() != true)
    % e% [6 F( g% B& i7 Z
  119.     {
    6 ^$ ~$ @( }( h7 n; w4 U: W- w
  120.         ui->receiveButton->setEnabled(true);3 z7 r" Q; Q9 M  \0 r" ?& Q% I
  121.     }( N4 l# [0 ], G$ L
  122.     else! K0 v* {+ {8 I+ w& Z. L& I
  123.     {: ?9 a$ \! L# Q8 ]
  124.         ui->receiveButton->setDisabled(true);
    ' n' _0 l' z+ S$ J1 ^. B2 O
  125.     }
    6 v( t9 P$ Y$ b1 a: D/ [5 L. l
  126. }% b) g8 O, ~& P7 x6 B/ T

  127. + c) h# p+ i9 [9 u; G' J
  128. void Widget::on_transmitButton_clicked()
    7 h' d( y- ]# \$ r1 e" b
  129. {( t4 P) l! C, d6 U7 U
  130.     if(transmitButtonStatus == false)/ O+ P* [. i5 F0 ~
  131.     {7 P( U+ W9 b0 u% c, u, m
  132.         serialPort->close();
    3 l/ I- C! @9 S' |7 N- {

  133. # i6 ~! q: L$ i5 ~4 b0 {
  134.         ymodemFileTransmit->setFileName(ui->transmitPath->text());8 ^7 i: N& p4 A4 l& p
  135.         ymodemFileTransmit->setPortName(ui->comPort->currentText());
    ( ^7 c9 l: g9 R7 @* p# E* E" B, T
  136.         ymodemFileTransmit->setPortBaudRate(ui->comBaudRate->currentText().toInt());$ u% |' d3 N; G9 z6 f
  137. 2 n* }. [8 `& V5 J2 R) z
  138.         if(ymodemFileTransmit->startTransmit() == true). D$ d& U6 x* B' s% \
  139.         {5 J0 o) @0 j8 L8 z5 O
  140.             transmitButtonStatus = true;0 G' x/ M1 f. k- |4 k+ }2 W. ], {! B
  141. $ D1 h. H2 C5 z6 a' |4 \
  142.             ui->comButton->setDisabled(true);
    ! m0 Z, v" K, b. ?2 K& S9 J$ l7 V
  143. / N( j. q; S! k
  144.             ui->receiveBrowse->setDisabled(true);
    % @% f, o$ d5 A4 O  \0 B- X" s
  145.             ui->receiveButton->setDisabled(true);
    9 K3 [5 Q1 \5 I9 {: V" T/ N
  146. $ v! g$ V5 G8 @7 ?$ x4 r7 W; M
  147.             ui->transmitBrowse->setDisabled(true);
    7 X2 |7 e1 l: B, u8 _
  148.             ui->transmitButton->setText(u8"取消");
    ! A0 R# X: F4 N+ Y' E" i
  149.             ui->transmitProgress->setValue(0);
    6 K* A% _9 v1 C6 K
  150.         }
    2 u5 \1 D, H6 ^# _
  151.         else
    6 O+ X- t; Z, V7 ^7 O
  152.         {/ {0 `# `6 H1 Z4 N$ A0 J
  153.             QMessageBox::warning(this, u8"失败", u8"文件发送失败!", u8"关闭");
    2 C5 a$ `4 B& h9 t# Y
  154.         }6 F) o/ N, r7 g8 e2 Z" C% e4 F, V- v
  155.     }& p2 H5 J: J6 f
  156.     else/ U& ~2 K  `6 s0 A6 e6 I' T
  157.     {- W; N3 J: O/ B& ]" c# q
  158.         ymodemFileTransmit->stopTransmit();6 ]5 h0 r0 P9 W+ @" }
  159.     }* \! M# x  R3 W0 B9 y: z
  160. }3 I& c8 C- h1 z' }
  161. ' s2 d( i6 j9 v* O& n; w
  162. void Widget::on_receiveButton_clicked()( g- o3 T: F' }) O
  163. {) s' `. r+ B* b9 w7 X7 ?
  164.     if(receiveButtonStatus == false)
    ' S. I8 y* c5 Q& y
  165.     {4 ?9 r" T% E! m- ]3 H
  166.         serialPort->close();
    6 J+ ]3 r0 L6 N3 [

  167. 3 k0 q9 K: R9 ?. w. b  P
  168.         ymodemFileReceive->setFilePath(ui->receivePath->text());) f' S1 G; k. l# w/ ^/ i) E
  169.         ymodemFileReceive->setPortName(ui->comPort->currentText());
    ( _3 q) s* v6 U$ S8 s
  170.         ymodemFileReceive->setPortBaudRate(ui->comBaudRate->currentText().toInt());+ R3 p- |$ P8 ^- ?' ^
  171. / s7 M6 x, A6 o  V
  172.         if(ymodemFileReceive->startReceive() == true)
    # L, K9 D! ]) F. D$ o* Z
  173.         {
    * @( Z$ O3 A( L7 I8 W5 w2 N* b
  174.             receiveButtonStatus = true;
    # H* S+ f' v  k! ?
  175. - W* Y: C3 O5 U0 A& y- Z4 @, n
  176.             ui->comButton->setDisabled(true);8 i# Z" Z! h" l6 \# m/ k7 ?- Z, R
  177. 4 c0 z. A+ q! ?9 E
  178.             ui->transmitBrowse->setDisabled(true);
    : ^# m+ u- g: J3 {! O
  179.             ui->transmitButton->setDisabled(true);
    % V# `% d; ^* B  D( y

  180. 9 F. O1 ?+ U$ K
  181.             ui->receiveBrowse->setDisabled(true);0 j8 I7 _( n* F$ J
  182.             ui->receiveButton->setText(u8"取消");
    5 k) t. D+ i# C0 H& Y! M; I1 B, T! a4 L
  183.             ui->receiveProgress->setValue(0);% Z7 n% k5 f) \3 l
  184.         }* k3 i0 G& H! d! ~
  185.         else: ?4 F3 n2 V7 u2 F
  186.         {
    : u5 K3 f' l0 @; I% ~
  187.             QMessageBox::warning(this, u8"失败", u8"文件接收失败!", u8"关闭");* }6 B: Z+ _$ e1 U+ g+ A* A
  188.         }
    ; S: P) X3 J: F, H1 Z/ T5 n
  189.     }
    : y7 a. e. t8 s. p) l
  190.     else
    + A9 a/ _9 r0 Q5 U* Z& c- q+ p
  191.     {7 T- ~7 o# j% a
  192.         ymodemFileReceive->stopReceive();0 g2 J1 N1 b8 s  `' [( X5 r
  193.     }& b$ K# M9 T& {- g, p
  194. }
    # R: K8 h6 i# n# I, F: L
  195. 1 W& L9 D. I% C+ O8 z( T* b
  196. void Widget::transmitProgress(int progress)% V% A2 e$ L- u3 z" B
  197. {0 I: @$ \& G; E( t( s, u, z' Y
  198.     ui->transmitProgress->setValue(progress);
      d6 A4 p* ?, A2 F: y
  199. }$ Y: @) [$ L+ W$ Z

  200. 6 ^8 N, {, L3 M$ v1 Y$ @# E
  201. void Widget::receiveProgress(int progress)
    ) {# c- I' c3 q6 ?
  202. {; R! \, p) x2 |  c* C2 n$ e$ z% l
  203.     ui->receiveProgress->setValue(progress);9 j& |( ~* l$ A/ l0 d; x' N6 L3 ]
  204. }! X' M# T4 l9 z% I: o7 R
  205. 2 E7 A, ^. K2 M9 v! m
  206. void Widget::transmitStatus(Ymodem::Status status)5 p# Q; c/ q# R7 i$ A8 O/ T. @
  207. {. S# @3 }' h, S5 L
  208.     switch(status). ^+ H. L3 L! H
  209.     {
    ' C2 H: m+ ]' [: c6 Q) K
  210.         case YmodemFileTransmit::StatusEstablish:
    6 {; ^0 W, N( u5 X7 g& t9 L4 c
  211.         {. V9 a9 t# y% B2 ~$ E% S1 Y* E
  212.             break;& ?5 a5 M, E- u( `: l* {, Z
  213.         }
    + V. G1 V4 a/ Z: k; D

  214. 2 x! Q& k8 F$ z
  215.         case YmodemFileTransmit::StatusTransmit:
    & ?( p1 V, z+ \7 J
  216.         {3 ^, e9 E) B8 ]2 `1 R! W8 u
  217.             break;
    $ P1 w4 Y) F  ]: u- K/ ^: h. t5 I
  218.         }
    & ~7 n. p  x) p3 H2 p
  219. 4 z7 g1 _0 q6 ?; V/ [2 P0 ?! ~
  220.         case YmodemFileTransmit::StatusFinish:( B3 C) G% O# g! F/ x+ L
  221.         {
    $ P+ `; p4 N4 V5 f
  222.             transmitButtonStatus = false;
    4 o3 G. U4 C. v9 |
  223. # ]3 a! i* h/ j8 h. }
  224.             ui->comButton->setEnabled(true);; k4 a; N; F. b2 [

  225. 3 ^# s. {6 P8 l, v5 W2 T% ?. n0 E
  226.             ui->receiveBrowse->setEnabled(true);
    * O8 F+ J2 j4 i3 q) J6 n0 R

  227. - n4 M6 S! D# J
  228.             if(ui->receivePath->text().isEmpty() != true)" l# Q1 u( N; m+ w
  229.             {4 U- q3 J; D2 o
  230.                 ui->receiveButton->setEnabled(true);
    $ X! ?* j  d1 T" `# H" W
  231.             }
    $ L0 y) p  }, \- p/ C

  232. ! B: a+ {4 ^$ c0 i  V6 L  {3 U' _
  233.             ui->transmitBrowse->setEnabled(true);! v. I( l, B# C7 I( `2 a, J# e
  234.             ui->transmitButton->setText(u8"发送");  @0 V; H) t( @; o( C7 A
  235. % O! F* R6 c/ F, u$ v2 j# B( k  g! E% z
  236.             QMessageBox::warning(this, u8"成功", u8"文件发送成功!", u8"关闭");
    . }: `, }4 Z( H* X' L5 p/ M
  237. 3 b: x; M& y- O- y5 D
  238.             break;' T! ]) @. |7 K) r) C, _4 i9 C
  239.         }6 a3 m% C( J  v

  240. 3 F9 O/ k0 I- k9 f: R6 M
  241.         case YmodemFileTransmit::StatusAbort:& z9 i6 W$ T0 ?) H0 r0 I
  242.         {$ z" d5 k, S/ c: k7 ?9 x, t2 w; `
  243.             transmitButtonStatus = false;
    3 P) i- k4 ]  D) M! {& r

  244. 0 O; W2 U, {9 F* g, G
  245.             ui->comButton->setEnabled(true);1 S: {5 V- @0 |/ o, T1 C, \

  246. 8 Q1 t; e3 N) i
  247.             ui->receiveBrowse->setEnabled(true);* m. M6 x  _- D9 T: p

  248. , e9 }6 _; a. s  ~. W
  249.             if(ui->receivePath->text().isEmpty() != true)
    . ^  l2 R5 }9 z, |
  250.             {
    5 ~' x/ C' f4 v$ w, x( n: o
  251.                 ui->receiveButton->setEnabled(true);- q+ H0 |0 v. Z0 |0 ?
  252.             }
    ( N) q% L& \1 }/ X
  253. 7 ]$ v+ W7 `, g8 O- M) H
  254.             ui->transmitBrowse->setEnabled(true);6 k4 s2 l, x8 h: j2 `( Q5 I
  255.             ui->transmitButton->setText(u8"发送");
    * l" C+ ~; U: }( I. m
  256. - K- R0 w. Y" y9 T3 C% h$ d5 e
  257.             QMessageBox::warning(this, u8"失败", u8"文件发送失败!", u8"关闭");
    / J$ G" q3 [) Y9 K$ S: S7 H# g. A' `
  258. . }$ |6 T* b) P8 D  {& Y# G; k
  259.             break;
    " L0 U  `- o# K+ \  f# H+ B
  260.         }
    0 g1 |" c. v4 h3 R0 i' V9 Z
  261. ' Q) ~7 r; z- s( G8 ?
  262.         case YmodemFileTransmit::StatusTimeout:9 @0 N! f9 d5 Q  E( i# t; A, y/ F
  263.         {3 d5 l6 ^4 X, o3 K& ~
  264.             transmitButtonStatus = false;1 @) \! C0 ?( t( i) q. m2 j/ c8 `

  265. ) B' h* C. {/ K1 V$ L) Y( d
  266.             ui->comButton->setEnabled(true);2 |0 n2 P" Z( a& [+ N5 K1 u/ y

  267. # F4 M# k3 H1 @6 ]6 W, L
  268.             ui->receiveBrowse->setEnabled(true);4 d* C9 y: |. E* d2 w: z; z9 J
  269. ) j) k. E5 y: J- I
  270.             if(ui->receivePath->text().isEmpty() != true)0 N+ D; I/ [0 z" \5 R
  271.             {
    0 b! \/ r! n$ w; e. p
  272.                 ui->receiveButton->setEnabled(true);$ J3 C3 Y) F6 v# C3 p
  273.             }
    & H* S/ Z7 Y$ I$ |! }
  274. 8 P9 s$ D# g6 \
  275.             ui->transmitBrowse->setEnabled(true);
    ) K" j. k& g7 w( Z7 G* G3 u
  276.             ui->transmitButton->setText(u8"发送");
    5 m: @' V* |: P9 w

  277. ; \- X. S$ }1 m4 {& J! T
  278.             QMessageBox::warning(this, u8"失败", u8"文件发送失败!", u8"关闭");
    0 q* d( _+ ~8 Z% c# `

  279. ( `+ N, I0 n: ]: I7 c
  280.             break;
    - z1 s+ h! {- j( _
  281.         }( ]/ N4 {1 z3 L9 n3 I" [3 k6 S
  282. # _3 f4 V: y: M& S7 U/ b
  283.         default:3 h. V6 @  P1 s! j7 P+ m
  284.         {
    0 r3 c! L; t& M2 ^; A! ^
  285.             transmitButtonStatus = false;
    $ C1 P# o/ R- `, R$ x

  286. , ^. F  g  |8 S' _  T2 N$ p
  287.             ui->comButton->setEnabled(true);
    ' L& b9 c& [$ C! E

  288. 7 z+ z0 v: @. I. I4 B; m# H2 J9 g7 D( y
  289.             ui->receiveBrowse->setEnabled(true);7 e1 {, ?  L. K* T& g1 h- u
  290.   T4 ~$ E, H: E" d  a4 n  Z
  291.             if(ui->receivePath->text().isEmpty() != true)" `8 @/ h) e* r8 d# i' A
  292.             {
    6 h, w( W( X+ d5 `% v- i" q
  293.                 ui->receiveButton->setEnabled(true);6 E, T" I& K( k( r6 z
  294.             }5 I- V0 S4 s( w, q) p. P3 P

  295. ( s0 S  m' k' p, P! l" G+ V
  296.             ui->transmitBrowse->setEnabled(true);
    " s2 c( U' Y: B
  297.             ui->transmitButton->setText(u8"发送");
    6 m' _: e- m, _: E2 y7 x5 T

  298. 2 r" s2 d0 v7 y* K6 r
  299.             QMessageBox::warning(this, u8"失败", u8"文件发送失败!", u8"关闭");
    . @& t* i2 Z# N6 N) I
  300.         }9 w4 q- d( L, r6 M9 X, k
  301.     }
    5 i- e( G& o7 Q7 H% U" f
  302. }: i5 v* i" ], s
  303. $ `" r% b) @5 d" U1 h
  304. void Widget::receiveStatus(YmodemFileReceive::Status status)
    ( z) M/ B. W, g& A: ?# Z
  305. {+ \. a% H: [6 l! {7 t) J2 E* b8 i
  306.     switch(status)0 J. g: R4 @4 a6 O+ \
  307.     {
    $ D& v: G9 z9 j. E& e8 w
  308.         case YmodemFileReceive::StatusEstablish:
    . a: }8 l; i3 G4 H% A& N
  309.         {
      Q; C% T( e7 D4 P* I) ^; x+ M
  310.             break;
    " N, x: g9 w# n$ U! c
  311.         }1 J. ~# D5 `% B

  312. . @4 z7 g# N& T' E- s
  313.         case YmodemFileReceive::StatusTransmit:
    * L1 m2 K, l9 V) y
  314.         {+ x; _0 W+ g, ]: ~+ K
  315.             break;
    - _$ r: K3 R  w4 D' Z$ h5 N
  316.         }
    8 e9 o4 j6 S/ Z7 |4 Q( Q/ z- k

  317. 0 R' k8 M1 u! |2 U1 l) a
  318.         case YmodemFileReceive::StatusFinish:
    ( b; u3 U$ P2 d* S/ G9 n3 U
  319.         {( q; Z3 \+ ]* O) C
  320.             receiveButtonStatus = false;
    + O. h7 ?, }7 q6 W  I5 L

  321. : R8 W; o7 y! S: x) {7 R  B" `3 l
  322.             ui->comButton->setEnabled(true);& z* h7 b1 w0 w: o( f- K) x" S/ \
  323. . u) E. E* o$ I0 y& f
  324.             ui->transmitBrowse->setEnabled(true);
    5 i/ d; I) s1 Q

  325. ! {! U& N) w1 O: y
  326.             if(ui->transmitPath->text().isEmpty() != true)0 ?! D' e) J* a% F5 S
  327.             {' a. W. J9 ^; z
  328.                 ui->transmitButton->setEnabled(true);
    1 p0 {) L, M' ]7 V
  329.             }
    6 {- ^* O- M! u2 Q6 a4 y
  330.   q, ^  o! T5 J
  331.             ui->receiveBrowse->setEnabled(true);* }% N/ |% V5 g/ F0 u" g
  332.             ui->receiveButton->setText(u8"接收");8 a9 n* `) y& Z; Q' `& Q( W

  333. 8 B* B2 R" i- a6 n/ j/ o
  334.             QMessageBox::warning(this, u8"成功", u8"文件接收成功!", u8"关闭");; S$ U) j4 U7 g
  335. ) c: ]% v' i/ M8 f) ?
  336.             break;
    ' _3 m, i7 r/ ^7 o2 l
  337.         }
    & R: e/ u8 |  W2 c: p
  338. " w0 q0 ?& T* |1 v! L+ ?2 y6 M
  339.         case YmodemFileReceive::StatusAbort:3 \) b: ], j% {2 e
  340.         {, V0 S) o! p+ l" @
  341.             receiveButtonStatus = false;( c6 e( x7 s' W5 \) w9 D

  342. , u5 d) F# Z" W5 ?: @
  343.             ui->comButton->setEnabled(true);3 k# X+ R$ o7 m( P
  344. 3 R9 ]( ?9 d( z9 h  ?. r
  345.             ui->transmitBrowse->setEnabled(true);
    , [1 e! ?" K& G; q2 S3 {) j: Q8 V

  346. & V4 u% O- k3 j: Q% P3 k% h6 q" r
  347.             if(ui->transmitPath->text().isEmpty() != true)4 i. ~' j3 E2 o  M2 Q7 {/ e( d
  348.             {
    1 C) F* N4 Q0 X" U/ e' p$ t
  349.                 ui->transmitButton->setEnabled(true);
    5 h1 Q: I, j8 w, W7 Y; D8 T* `' a# p7 \. O
  350.             }( Y+ [2 f. W# I
  351. % P& _1 X5 d9 h* c/ I6 y) y
  352.             ui->receiveBrowse->setEnabled(true);
    9 ^+ n) W4 v  ~: T4 V/ z! N7 `
  353.             ui->receiveButton->setText(u8"接收");3 I2 L0 {+ b% j) O: p- S
  354.   P4 K; @) _$ \! d" E+ H& y+ v
  355.             QMessageBox::warning(this, u8"失败", u8"文件接收失败!", u8"关闭");
    ) O3 M! L$ z- y- Z% n0 ^  D* B
  356. / b' a3 y: i/ B: v3 F
  357.             break;. G; \% F; q2 |$ h4 ]  W7 Z5 L
  358.         }
    . C% P1 U3 s- ?

  359. # Y: v) ^1 W- K
  360.         case YmodemFileReceive::StatusTimeout:1 _0 X5 o6 k; G1 j" l
  361.         {
    * q; V' v. p1 B- K: K3 K- W8 y
  362.             receiveButtonStatus = false;
    ; t/ u7 y: C- g$ g" |
  363. " q2 Y9 A, N2 P. p/ }
  364.             ui->comButton->setEnabled(true);
      `/ N8 S+ R) I3 s9 t, n2 a/ f0 J

  365. 6 ^: h" t4 D' @/ {. \* |% _
  366.             ui->transmitBrowse->setEnabled(true);
    1 o5 p% O* `' S

  367. 0 a0 _' t) y& c3 @9 D% A
  368.             if(ui->transmitPath->text().isEmpty() != true)
    8 [, H+ W8 W0 R. v4 A2 t' ~
  369.             {
    " ^& w9 L1 Z6 Y- E& t- o5 D
  370.                 ui->transmitButton->setEnabled(true);
    " f( G% h1 X2 ~5 q( g
  371.             }3 c: k+ A6 x9 n9 h* [4 t4 @1 r) V  g
  372. 0 `9 @6 |# a8 @$ k
  373.             ui->receiveBrowse->setEnabled(true);# W9 R' @0 a% c1 X0 C# Y1 M
  374.             ui->receiveButton->setText(u8"接收");7 p+ S. q# g" m' N

  375. 3 g, I8 X) L2 ^3 N6 y% f
  376.             QMessageBox::warning(this, u8"失败", u8"文件接收失败!", u8"关闭");  P: p1 D1 u1 f, c" v' u# u
  377. 8 j3 i% W5 q# {% n2 V
  378.             break;# O# i4 G6 t- }: U. Y/ N. F2 M( A
  379.         }
    ! w: i8 ?+ g% x! n, v. f
  380. # y" h6 V6 Z* S: `5 t
  381.         default:
    , x3 J" K6 ^2 T9 ]. d
  382.         {
    ) `! H+ l* P! s$ e$ L
  383.             receiveButtonStatus = false;  w5 N. |4 t8 z: a9 [

  384. ) Q: }% w4 Z7 l1 g
  385.             ui->comButton->setEnabled(true);+ k5 v4 u+ n: z- ?$ K3 B7 K+ G

  386. 4 v% ^: Z- Z$ G: g5 d0 p
  387.             ui->transmitBrowse->setEnabled(true);; o6 f2 o$ q+ k1 L
  388. # w+ C" V7 T. J7 V7 x
  389.             if(ui->transmitPath->text().isEmpty() != true)
    + B) S, G7 c1 A2 P! J" g& {; z
  390.             {3 I* S* b# ^3 I0 M7 I9 Y' Y; G
  391.                 ui->transmitButton->setEnabled(true);- b/ z$ c. R* C' R( K
  392.             }* d/ Q; R- D/ G( s. @% B, D

  393.   i$ ^/ [& t& @( Q, H
  394.             ui->receiveBrowse->setEnabled(true);+ B( E- q5 ^# H4 V4 u9 l. |
  395.             ui->receiveButton->setText(u8"接收");8 M5 y- z: X/ u/ _& Y( r7 z  \
  396. ' w2 k! L4 A; E# v1 p4 c" h
  397.             QMessageBox::warning(this, u8"失败", u8"文件接收失败!", u8"关闭");- w/ Y$ i0 l: M/ r6 V
  398.         }, X& r: y( m/ D0 p: f
  399.     }: h; U; d0 O. s, P$ T' ?* [6 Y. g
  400. }' [+ C' |( P" m$ l' U- p) ^7 j
复制代码
# ]# g; v1 ]; R1 E0 N* b' Z6 C

! d- I% ~! S9 t9 J8 H1 e' ~9 Y( g' U6 S3 y& ^

* @) l1 e4 P# a: {9 d. k- }. M- W" U
XinLiYF 回答时间:2018-3-6 02:04:00
      main.cpp文件( P1 |5 Q- x9 j2 O  h: c
  1. #include "widget.h". \2 W7 N+ N4 U0 j- T4 o
  2. #include <QApplication>( d- T" m+ P4 s4 h

  3. , U$ p+ p0 R  p# Y9 l" N
  4. int main(int argc, char *argv[])
    5 ^3 Z4 k6 r  T+ `% ]$ J$ j
  5. {
      [. J6 x) I, }9 x5 ^% p* P
  6.     QApplication a(argc, argv);
    , T3 K9 N$ a" ]6 G
  7.     Widget w;
    # G5 C9 e( q2 C' Y1 \
  8.     w.show();! K" z/ J) S  K
  9. - H) R# G3 l4 q
  10.     return a.exec();4 }3 x' J$ z; ~. C0 I$ g
  11. }& m1 t8 V" D  \5 x/ m
复制代码
) I5 t! {" I3 y  D
      SerialPortYmodem.pro文件7 e; W- Y# ]) F
  1. #-------------------------------------------------
    : v* m3 G9 r! m: a4 L
  2. #
    : ^- `) Q2 b' W: I
  3. # Project created by QtCreator 2018-01-20T23:00:46
    + u  r: j' w; M9 I$ m4 ^
  4. #3 s9 @6 _! g) Q6 n& P
  5. #-------------------------------------------------
    9 K5 j& Q* N  B
  6. & G8 p; y/ X& t; G) @" C
  7. QT       += core gui6 A5 w! B2 y% r3 E- \8 @# \* X
  8. QT       += serialport8 F/ a/ ]$ m" K0 K! F- P
  9. 6 J( T8 R8 h2 l
  10. greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
    0 j0 U9 i: I0 ~% ^2 t
  11. 1 c9 M& M2 t0 n  e% `6 t
  12. TARGET = SerialPortYmodem6 e( E# a7 H3 {2 {0 e0 v8 Q9 u
  13. TEMPLATE = app, u8 F  Y5 F1 z; A9 F
  14. , T# g8 T9 L# ]. x$ k
  15. # The following define makes your compiler emit warnings if you use
    * W! w2 v& m9 p5 N- m3 C
  16. # any feature of Qt which as been marked as deprecated (the exact warnings
    , Z5 X1 [) Z$ r) K# \
  17. # depend on your compiler). Please consult the documentation of the
    + u' a5 L- q: F$ M/ M  ~( X4 e. M
  18. # deprecated API in order to know how to port your code away from it.
    : G  m  M: [0 ~0 L
  19. DEFINES += QT_DEPRECATED_WARNINGS* x. Y3 w  O- @1 `7 s+ e  H( c* L

  20. / [( b4 W6 b0 F( ?# \1 L
  21. # You can also make your code fail to compile if you use deprecated APIs.
    * }0 Q0 Q) v( J
  22. # In order to do so, uncomment the following line.
    2 i; t( y0 x  n6 k; A0 d
  23. # You can also select to disable deprecated APIs only up to a certain version of Qt.7 M( ]" d1 w  h; \2 e, T* G7 b' Y
  24. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.00 J( \/ F$ M6 a& b& M$ I
  25. $ W! O! x+ Z" s1 w2 y

  26. 1 N0 p2 f, }! B+ t9 C: j# G0 r
  27. SOURCES += main.cpp\
    + ?9 m% t- f, g% L* U0 C
  28.         widget.cpp \
    8 o6 Q  A. l$ L  B4 R; a# ^0 A
  29.     YmodemFileReceive.cpp \
    8 v" e. h6 k7 \+ m: N" C
  30.     Ymodem.cpp \
    + ~' l  n' v8 F$ T2 J( s
  31.     YmodemFileTransmit.cpp
    - w/ z' @! p% g: N% U
  32. - ?5 T7 j3 k- |. f( L
  33. HEADERS  += widget.h \
    3 S" t0 r: m  D9 S; _: {
  34.     Ymodem.h \
    1 \/ Z2 w% q: {  J8 {
  35.     YmodemFileReceive.h \! ^' O8 S$ v, ^
  36.     YmodemFileTransmit.h. u5 A* n) z. a
  37. 0 N5 d6 V  o% m- m
  38. FORMS    += widget.ui
    4 s) E4 k9 ]. [$ q( E# v* {, h

  39. ! I, [! T9 V/ D( a; _$ a! Y6 I4 e
  40. RC_ICONS = SerialPortYmodem.ico
    8 b6 E. a0 k$ U1 y, a4 G4 Y' b- T
复制代码

2 n# `( V2 O( y      SerialPortYmodem.ico文件
- [+ d( k# `% h( X$ q
" c) l& O1 l$ _& \5 T  z8 B
3,运行效果& h, X1 o" W: Y' {5 q1 Z6 m
/ y) W2 ?6 p3 W% n; a9 F# J

) @) W! |$ H+ r# t& u1 o* x3 q# ^+ a" s9 ]. S4 Q6 e
hello_bug 回答时间:2018-3-6 11:12:43
好凶猛的代码。。
XinLiYF 回答时间:2018-3-6 11:24:49
hello_bug 发表于 2018-3-6 11:12
$ }  w/ q2 H5 H$ @好凶猛的代码。。

. u4 Z9 Q! p. U! \( d+ r; D+ b
XinLiYF 回答时间:2018-3-6 13:16:18
可以用来做用户程序升级的上位机软件。
MrJiu 回答时间:2018-3-6 13:49:12
最好是变成文件比较好。。。关键部分讲解一下,贴上来,就更好了!!!!
XinLiYF 回答时间:2018-3-6 16:14:22
MrJiu 发表于 2018-3-6 13:49
9 N6 k9 r0 e! t" ~* Z& B$ m最好是变成文件比较好。。。关键部分讲解一下,贴上来,就更好了!!!! ...
! W- J' e$ V$ {5 X- z* W
GitHub仓库有工程,还有资料。
zero99 回答时间:2018-3-9 14:41:08
感谢分享,已汇总到3月技术原创:  f7 ^( J5 ^' f, J+ v0 M- l
https://www.stmcu.org.cn/module/forum/thread-615031-1-1.html

所属标签

相似分享

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