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

YMODEM协议串口文件传输

[复制链接]
XinLiYF 发布时间:2018-3-6 22:28
YMODEM协议串口文件传输
GitHub仓库:http://github.com/XinLiGitHub/SerialPortYmodem
( ~# L0 i0 G) X5 e+ k+ MPS:博文不再更新,后续更新会在GitHub仓库进行。# [" z: m* N4 i% y, I7 U
* [# S$ D9 ^# J& ~# r7 k( M* V( c: G
3 x, i4 z# B4 B3 Y5 _* w( w
    串口通过YMODEM协议进行文件传输。程序中涉及到YMODEM协议知识,详细介绍见维基百科[YMODEM](http://en.wikipedia.org/wiki/YMODEM)。& @8 _( F8 V2 D9 I0 d. g4 r5 B

7 Q# n. |- F0 t0 Z. R. S4 e1,开发环境
. F7 Y* Q4 S$ ]      1,框架:Qt 5.7.19 @& A  M' C1 w6 ^
: H3 P( v! P! m9 L+ n/ P, n
      2,编译器:MSVC2015_64bit
$ y5 f9 F  ?! f

# c- w6 g  R" X7 J% J      3,IDE:Qt Creator 4.2.0 社区版
. W/ r' G! d& t/ W      4,操作系统:Windows 10 专业版
: f/ ^/ ]! _- [4 a7 w0 {8 n6 `# ^) ~. K/ x; C* i! _
2,程序源码# Q# R# z' a2 k3 e5 \
      Ymodem.h文件
2 i$ O# E2 K8 ]. m" W' b
  1. /**
      M/ J2 }9 h6 z. N' A. M& D
  2.   ******************************************************************************
    & Q" a8 x$ m* V
  3.   * @file    Ymodem.h- l& c' ~/ X9 Y! \, r! U5 J
  4.   * @author  XinLi, |" [4 h+ {2 t: K0 u
  5.   * @version v1.0
    . I9 j  A6 F4 _4 M
  6.   * @date    21-January-2018
      \3 @8 ]7 L! d4 X+ Y
  7.   * @brief   Header file for Ymodem.cpp module.
    2 s3 M! c" s& @# Y7 K+ p( g( F
  8.   ******************************************************************************
    1 C, U$ ~7 |( H
  9.   * @attention
    : k6 }+ x* P4 z+ p  H- y
  10.   *+ Y8 N8 V! D7 ?  q. m" w. h. K9 g' C
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>* V) S8 L, T. \4 R2 q" Q, ~
  12.   *
    . `& U2 W1 o) ?- K' X
  13.   * This program is free software: you can redistribute it and/or modify4 Y' z6 z0 K2 M; t
  14.   * it under the terms of the GNU General Public License as published by/ _  g5 D. j3 x: B$ _* }9 S
  15.   * the Free Software Foundation, either version 3 of the License, or
    ; w: v8 H1 P! H0 q& [$ {5 R, ^
  16.   * (at your option) any later version.
    9 |! K  N( D8 ]4 k
  17.   *
    % X2 ?" M; K' e, O2 F
  18.   * This program is distributed in the hope that it will be useful,
    $ a1 N% p, o; X$ j4 t& m
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of- Y5 g0 C- C1 N# V* Y
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the7 W% v& G7 I, J3 u: R& \9 C5 Q
  21.   * GNU General Public License for more details.
      E# q- g7 E, c# P* ?3 J
  22.   *
    ( k, W- M( V$ w# L5 p) L# S
  23.   * You should have received a copy of the GNU General Public License7 T& F4 w" i! ]
  24.   * along with this program.  If not, see <http://www.gnu.org/licenses/>." g; h1 T" }! [) F
  25.   *! f7 X8 X0 A* d' p& A4 N* l) d
  26.   ******************************************************************************7 @& Q+ l" W6 L/ [$ \; f
  27.   */' N2 S1 x5 v( y5 s8 S
  28. / n1 ?0 x# f6 b; H/ W
  29. #ifndef __YMODEM_H
    7 _2 \" n8 ~# K8 O0 U
  30. #define __YMODEM_H6 ]4 i" ^* n2 m; C

  31. 5 R2 i9 p' g4 A  e1 Y5 N) t
  32. /* Header includes -----------------------------------------------------------*/
    6 {8 C0 @6 r$ j* ]  v  Z& |. i7 j
  33. #include <stdint.h>
    ! i1 x4 q3 c  S: v) Q

  34. ( a* v7 H# S+ i0 x
  35. /* Macro definitions ---------------------------------------------------------*/6 ?: Z- T$ I: `0 z1 ?
  36. #define YMODEM_PACKET_HEADER    (3)
    ; S" c, z+ k- |8 ^1 K- V
  37. #define YMODEM_PACKET_TRAILER   (2)% O" I4 }1 [% k9 ^
  38. #define YMODEM_PACKET_OVERHEAD  (YMODEM_PACKET_HEADER + YMODEM_PACKET_TRAILER)
    6 {4 _- D5 j3 n9 f+ W; \9 P9 _. Z
  39. #define YMODEM_PACKET_SIZE      (128). |! b2 M/ n( I3 g
  40. #define YMODEM_PACKET_1K_SIZE   (1024)5 q5 A4 ?1 p6 u& ~

  41. $ E5 C: f2 h' l3 {& V
  42. #define YMODEM_CODE_CAN_NUMBER  (5)6 r+ O% }7 M/ B# O" [7 h2 G$ F
  43. * g9 p* f) H7 {3 r3 M
  44. /* Type definitions ----------------------------------------------------------*/! D$ z5 ~2 u5 m6 i# ?9 z$ |
  45. class Ymodem& n3 d3 ?7 d% Z' n
  46. {
    % y2 G* \1 y  D) G- ]1 m9 Y! C
  47. public:  n- [& D' B" {
  48.   enum Code* t2 N4 Z, W+ X! u& b# T
  49.   {
    - Z- o0 [& T* o. c7 @9 {3 ~
  50.     CodeNone = 0x00,
    " J* R7 _" W( l5 n- `3 r
  51.     CodeSoh  = 0x01,
    ' P$ K) N6 q% Q8 _% \& b# P) [
  52.     CodeStx  = 0x02,' N# l* K- V% H/ a$ }1 j
  53.     CodeEot  = 0x04,7 g5 E# N' t+ `0 U/ S3 E( F" @
  54.     CodeAck  = 0x06,
    1 W1 S7 L" b% i
  55.     CodeNak  = 0x15,3 D2 _9 `! Z* K4 C
  56.     CodeCan  = 0x18," l  O7 U( u7 z. J
  57.     CodeC    = 0x43,) U' x3 J! Z- z2 a$ n' M* k
  58.     CodeA1   = 0x41,
    % v$ q/ [0 W  D' s8 l
  59.     CodeA2   = 0x61
      n7 z% H; D  k  W5 P# a, _
  60.   };
    & e+ E- W7 q* q6 {; j

  61. 3 c/ F) q! M$ `
  62.   enum Stage% V. T7 p, x/ w
  63.   {
    9 ^4 z* e8 ?4 P& Q" }" I
  64.     StageNone,1 w5 w/ W9 H5 F1 M
  65.     StageEstablishing,
    " W) d; O. k. e2 Y7 V: t; k, z
  66.     StageEstablished,' q1 t2 M" O2 L* w/ ^$ \. s
  67.     StageTransmitting,7 T9 s" m/ a- z2 m( C* ^3 t
  68.     StageFinishing,8 d; q2 _% P5 c3 y* O# G* A
  69.     StageFinished0 `) B& R  e/ @6 y
  70.   };/ v% m, }0 ~: L4 p
  71. 3 e, ^: b0 L, S# }. F  ~* }
  72.   enum Status
    & A2 ?+ K' D6 P( c
  73.   {  V9 I; ]- b7 }, @8 e$ c2 n
  74.     StatusEstablish,$ I, y: L/ Q: g  _  X  ^0 w# D
  75.     StatusTransmit,) R7 ~1 h/ X& r' n& [7 M' {6 v6 {
  76.     StatusFinish,3 d  o' v' Z3 L1 W# \3 c
  77.     StatusAbort,# R# d  g1 d! B$ R
  78.     StatusTimeout,2 E$ t3 Q0 I8 ~$ L' `5 G' A, J
  79.     StatusError3 u' i/ w. Y0 [
  80.   };
    . D9 n) F) `" h- K5 m  L, e

  81. / W$ M- ]+ I& d
  82.   Ymodem(uint32_t timeDivide = 499, uint32_t timeMax = 5, uint32_t errorMax = 999);
    8 c2 S" p8 l( t9 w: R; G4 b

  83. 7 i2 ]( J# c( x' h0 t- \
  84.   void setTimeDivide(uint32_t timeDivide);
    ( h5 l4 q/ N9 J1 B" F; v" k4 Q
  85.   uint32_t getTimeDivide();+ i+ }* C# n! W/ e

  86. . n9 x# b6 S+ t
  87.   void setTimeMax(uint32_t timeMax);
    1 v6 `, E1 k6 ~- i
  88.   uint32_t getTimeMax();3 k# p+ I7 M/ y$ o6 @2 z

  89. & ^: f, f" V5 g4 Q4 \. E
  90.   void setErrorMax(uint32_t errorMax);
      e9 q3 c% v6 ?: E* L+ K
  91.   uint32_t getErrorMax();
    ( j0 t6 y$ l- q8 X! |

  92. & q2 S& }  f+ d, y4 p  b1 L
  93.   void receive();/ p7 x0 n3 q$ X0 k7 [) E% Z
  94.   void transmit();! x5 a3 X. a, I* V% i3 l2 @
  95.   void abort();5 R# h3 C5 ^, [  K2 A, v* \0 w1 C

  96. " r0 x: {" A; b% g" X
  97. private:
      s1 N1 B8 e7 i) `6 R
  98.   Code receivePacket();
    , H8 D) I& m- p+ I- c- k  `0 w
  99. 8 r2 d# }! N0 J) a" T2 X  e
  100.   void receiveStageNone();  g8 U) J9 L' f5 i3 J- z$ [
  101.   void receiveStageEstablishing();
    ) A( Y" p0 \8 }! C4 X- E
  102.   void receiveStageEstablished();9 R" S9 T4 j/ r, W
  103.   void receiveStageTransmitting();
    5 g( W5 y" d$ p- I
  104.   void receiveStageFinishing();
    9 G/ T/ M4 a0 f8 Z- Q
  105.   void receiveStageFinished();
    ' }" I: B3 H# k. j) l
  106. 7 l& Z. x5 P& B0 p1 E5 G
  107.   void transmitStageNone();
    ' l" G9 b, v7 h$ J
  108.   void transmitStageEstablishing();* R" Q( y/ @% N; K  }- B+ }
  109.   void transmitStageEstablished();
    , e5 @5 x  W7 I, H
  110.   void transmitStageTransmitting();& U) e) i7 a3 g9 y6 _
  111.   void transmitStageFinishing();+ p( b0 I: Y' v
  112.   void transmitStageFinished();  o% D2 |/ F" t) q& x2 P

  113. 8 c# n$ R4 d! l8 L( D
  114.   uint16_t crc16(uint8_t *buff, uint32_t len);$ ^& n  Z( I4 Z( g' i
  115.   S' X/ q% r1 T6 B% Y7 n. h
  116.   virtual Code callback(Status status, uint8_t *buff, uint32_t *len) = 0;
    ' y# K; `0 Z4 |9 O) N
  117. 7 K5 }" p. o( E- U' H
  118.   virtual uint32_t read(uint8_t *buff, uint32_t len)  = 0;
    " s- i) G, `" d1 l" b6 Z" j
  119.   virtual uint32_t write(uint8_t *buff, uint32_t len) = 0;/ X; H7 O. I1 d" L/ j% b. |: e6 d. x
  120. ( y7 p  d: E4 D8 B
  121.   uint32_t timeDivide;0 C1 ^' P5 J0 u, t& L# w3 k4 `8 l
  122.   uint32_t timeMax;
    9 }5 K7 k0 b* O, A9 h
  123.   uint32_t errorMax;
    2 P, Q  X2 D$ S: `2 Z
  124. * ~/ H0 i/ u, @) Z
  125.   uint32_t timeCount;" c9 x' G4 ~0 E
  126.   uint32_t errorCount;- u; M0 G7 |! ]- U, S( C* [& p
  127.   uint8_t  dataCount;
    ) v  l9 ~! V8 A8 Z0 j

  128. 0 C. D; r) o- e
  129.   Code  code;3 @$ q( n7 {8 t
  130.   Stage stage;
    & I7 ^' ?/ n% w) O- a0 a1 J

  131. ) s4 N. r7 i* a
  132.   uint8_t  rxBuffer[YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD];
    - _4 ~: A) S- G5 }8 I& Q+ Y' m
  133.   uint8_t  txBuffer[YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD];3 S8 \+ a4 u6 w# l! K8 C
  134.   uint32_t rxLength;4 [' T5 Y8 U7 b! S2 r  ^# @9 o1 _
  135.   uint32_t txLength;+ M3 |: K' O( S4 z2 _  ~; B- l
  136. };
    # u- r7 i7 M5 W# M+ ]! Q' R: n

  137. ; S3 |' D5 U: s: O
  138. /* Variable declarations -----------------------------------------------------*/
    7 X" M- R) Z; Y2 _7 B. D
  139. /* Variable definitions ------------------------------------------------------*/8 {3 q9 Z# R. e# k3 u
  140. /* Function declarations -----------------------------------------------------*/- E, C, ~( ~( C& N9 v1 D
  141. /* Function definitions ------------------------------------------------------*/  y. ?/ l  {* u- n( j" d
  142. 0 `7 [" @: v" N
  143. #endif /* __YMODEM_H */
    ' @9 i; ]- I/ i4 h) A
复制代码
! R$ a3 O9 w+ w+ P
      Ymodem.cpp文件
, f# g9 Q+ t1 _( Q8 A+ ]" R
  1. /**
    * O! Z  G0 A" w& h
  2.   ******************************************************************************; Z5 \/ ?% b$ F2 Q0 A( ]
  3.   * @file    Ymodem.cpp) H5 J' m0 N9 n+ n( L
  4.   * @author  XinLi
    9 Q2 Q6 ^1 c) t" s
  5.   * @version v1.0* E  s+ M4 U7 l3 m0 _# e% W
  6.   * @date    21-January-20187 r+ n1 I9 l- F: X* ]% Q. W: c
  7.   * @brief   Ymodem protocol module source file.7 j8 ^1 ^6 a' S+ h
  8.   ******************************************************************************
    ' p- l, c4 y6 s# L2 e* m& e
  9.   * @attention! _7 V4 a% Q: e8 k. U% K( J
  10.   *% b) h* Z' {; J+ X
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>/ Q/ b% v6 r9 H$ h( m1 X
  12.   *# G+ X; \8 o; K: I! ?) r
  13.   * This program is free software: you can redistribute it and/or modify+ g/ c7 `# c' r, E- e2 G: h
  14.   * it under the terms of the GNU General Public License as published by  ~7 E! Y6 p. g
  15.   * the Free Software Foundation, either version 3 of the License, or
    7 l0 z! V( O5 B' b- k( F
  16.   * (at your option) any later version.
    , Y. F5 o% ~, c% d0 }1 m3 G; n
  17.   *
    1 P/ p; H2 S+ c+ S2 S6 q7 n6 K, E* W
  18.   * This program is distributed in the hope that it will be useful,
    + C7 `4 T0 Z+ I) h7 J. V% G
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of5 h0 p2 g  ~( s) ^- }, }; q
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the( @3 x2 @! k/ @, ~8 M
  21.   * GNU General Public License for more details.3 X: Z% m3 g  D- Z
  22.   *
    ; S) \8 u$ }+ D* J0 D- n, I; U
  23.   * You should have received a copy of the GNU General Public License
    ' m. Y9 x& ?, ~, \
  24.   * along with this program.  If not, see <http://www.gnu.org/licenses/>.- G& t6 m( x  F9 ~5 l1 ^
  25.   *4 i0 P% q' f, r
  26.   ******************************************************************************6 A( K2 H" p" {
  27.   */+ E7 X9 P! L9 @/ x0 y$ }+ ?

  28. + S$ @! K6 W" h
  29. /* Header includes -----------------------------------------------------------*/: d1 L" p7 P9 j2 ^% k
  30. #include "Ymodem.h"* v% E' L5 s. L: n, C$ Y% z) f
  31. #include <string.h>
    2 ^4 B9 H( {% v/ q  X8 E+ U$ y$ |% n  o

  32. ( p" v) H9 F% o1 P6 f( V
  33. /* Macro definitions ---------------------------------------------------------*/$ g: `& {$ T* a) K+ M$ ~
  34. /* Type definitions ----------------------------------------------------------*/+ F: r2 [. y! z4 r2 |0 h
  35. /* Variable declarations -----------------------------------------------------*/- p  ?3 s& k7 }) [7 f8 z( B
  36. /* Variable definitions ------------------------------------------------------*/! ?/ h- X+ D* W* R4 C* {  H
  37. /* Function declarations -----------------------------------------------------*/5 e: f$ Z9 a4 j3 P* ^. N
  38. /* Function definitions ------------------------------------------------------*/
    2 f5 t$ U" k$ \" s

  39. * d. S& S! ]. v. b/ i3 ~; J
  40. /**% [- S- C6 k' L7 G2 D2 }4 _, D
  41.   * @brief  Ymodem constructor.3 _3 h4 G2 ~9 z! K& G3 X) o
  42.   * @param  [in] timeDivide: The fractional factor of the time the ymodem is called.' z% D1 R- b. L
  43.   * @param  [in] timeMax:    The maximum time when calling the ymodem.
    ( ^5 n! p. e3 x2 I2 v* H! u! ~7 T
  44.   * @param  [in] errorMax:   The maximum error count when calling the ymodem.
    1 E6 R" {* J% C- M  X, c
  45.   * @note   The longest waiting time = call time / (@timeDivide + 1) * (@timeMax + 1).: q/ @1 L" w7 {5 w1 \3 b
  46.   * @return None.0 X, N8 D; X8 ~% A
  47.   */
    , N$ `, s5 u; ?2 c2 |+ e
  48. Ymodem::Ymodem(uint32_t timeDivide, uint32_t timeMax, uint32_t errorMax)
    , F/ `4 b6 {7 y0 E5 o/ O  I
  49. {9 L( U% ~5 d2 i" X9 u1 J0 p
  50.   this->timeDivide = timeDivide;+ s$ j9 w0 p/ v9 G& ^5 u7 k! A
  51.   this->timeMax    = timeMax;2 X. e" k' b  ^: A5 j$ x' h8 {
  52.   this->errorMax   = errorMax;, b7 ~9 j. w$ @6 B" V' k

  53. 9 F( b+ R8 H3 @8 H5 ]9 I
  54.   this->timeCount  = 0;
    + {( O  @7 g: H# t6 Z
  55.   this->errorCount = 0;2 L- t0 ]# @% M; S8 |
  56.   this->dataCount  = 0;7 ~1 H9 \3 i/ L, f; {3 C) x# ?

  57. 8 Z9 M- {/ K" ]7 A7 ?
  58.   this->code       = CodeNone;4 u7 t$ b+ u" ]5 N' K: @
  59.   this->stage      = StageNone;
    2 s0 `( D7 @/ N7 I- B
  60. }
    % J4 [  q% U- Y  P/ e6 U

  61. / Z! [0 k- K+ J/ l2 P) \+ {
  62. /**5 H( V, _0 \. @: q: `/ [' V
  63.   * @brief  Set the fractional factor of the time the ymodem is called.
    ' k3 p& T% r; z
  64.   * @param  [in] timeDivide: The fractional factor of the time the ymodem is called.
    0 {0 m: x* s6 q" s: r4 H
  65.   * @return None.+ s# W& Q, O' Z/ R3 w- h0 V
  66.   */
    ' V$ a  F: d6 Q7 T' w5 F
  67. void Ymodem::setTimeDivide(uint32_t timeDivide)% y: C  |, Z$ Y) u3 U5 k) q
  68. {
    ' z: e; G  Z3 P' @! w; c
  69.   this->timeDivide = timeDivide;+ l) M& p+ O- V% \4 y
  70. }0 z. c' Q2 a3 u2 J

  71. 5 f2 r: g: b& j6 @$ Q" ^
  72. /**# ?6 Z5 v2 V2 g4 i% t
  73.   * @brief  Get the fractional factor of the time the ymodem is called.
    9 U) U9 x$ W% m( {/ J% u0 v: n. Y
  74.   * @param  None.
    - T9 Z7 m; a' }- ]$ _
  75.   * @return The fractional factor of the time the ymodem is called.
    ) V5 k, F) \( A
  76.   */
    " M' H6 T" ?3 M  H8 n. c8 N
  77. uint32_t Ymodem::getTimeDivide()7 x- I& j0 Y3 j! ?# ]; B
  78. {
    ! a/ C' b# z6 {: O4 w0 B& L
  79.   return timeDivide;( X4 _3 b. A' n# ]3 v
  80. }( C# O! K! v! k, t

  81. 2 ^. Z* f/ s* ^
  82. /**
    2 R  U9 t  A+ k$ X
  83.   * @brief  Set the maximum time when calling the ymodem.
    $ `7 x9 @2 c1 Z$ ~+ C9 X$ r1 @5 C
  84.   * @param  [in] timeMax: The maximum time when calling the ymodem.
    / ^9 Z  w; e1 J+ v' o
  85.   * @return None.4 s7 X' n  p: k0 U( y2 }
  86.   */& j6 L" ~1 @3 d! ^4 i3 q3 ^8 `0 M  Y
  87. void Ymodem::setTimeMax(uint32_t timeMax)
    $ {2 b! ^3 b# L
  88. {
    % N* R* M% g3 Z3 _5 J
  89.   this->timeMax = timeMax;
    4 h/ v7 d# \$ }4 h
  90. }
    ) q# D4 J+ z$ C+ O
  91. 2 R9 z' Q, U! t& i* M& O/ n$ v# w, Z
  92. /**
    5 Z3 Z* y' `. w6 O  d- h
  93.   * @brief  Get the maximum time when calling the ymodem.
    6 F4 G) T3 t, W+ q
  94.   * @param  None.+ ?# O' k6 h! E0 _
  95.   * @return The maximum time when calling the ymodem.
    # h0 N9 g) J4 A' b. a
  96.   */
      ~7 X5 _5 R& u* B
  97. uint32_t Ymodem::getTimeMax()
    & _/ E& ]. h& z5 c# E* q
  98. {
    7 D" m( x( N% Z* A, ?3 |
  99.   return timeMax;
    ' {  [( i1 L6 a# u
  100. }
    9 c7 g# O7 ~3 }8 [  P0 F" @
  101. + Y8 V, Y$ w1 i$ {; m
  102. /**' M2 J* T) P$ G( M
  103.   * @brief  Set the maximum error count when calling the ymodem.
    ) t6 i7 o/ F6 f) f3 k
  104.   * @param  [in] errorMax: The maximum error count when calling the ymodem.4 s: G; Y5 }" d) K5 f2 p
  105.   * @return None.+ n1 [+ J) \" s/ L7 l, X) X; ?: W
  106.   */
    # j8 I& H6 z/ F3 ~  n8 L  d- k
  107. void Ymodem::setErrorMax(uint32_t errorMax)
    " |0 C: `; W% s% ~
  108. {, M* @; G+ A' k: G2 N! U1 w
  109.   this->errorMax = errorMax;+ ]- [& ], c. ]4 u( Z" ^3 c
  110. }( n' j1 Q- S* ]. o" u4 h4 r
  111. " y5 ?3 ^1 d4 R  B
  112. /**% z" m" n( K. q3 B/ [
  113.   * @brief  Get the maximum error count when calling the ymodem.& `6 T6 r. ?  ?! ]* v% b! D( S
  114.   * @param  None.
    + o  r& n8 P) U8 y- r# ]
  115.   * @return The maximum error count when calling the ymodem.
    ' i) C$ Z: E# \1 F6 i6 u9 J1 B
  116.   */1 t+ w+ V% a% r' R1 n5 ?
  117. uint32_t Ymodem::getErrorMax()
    % j& i+ W1 T6 O; N  F! R, ^; M! y7 K
  118. {
    $ U' e: h3 T/ F+ B7 B4 M
  119.   return errorMax;
    0 W4 p3 u0 g2 U+ X5 Q# {/ d
  120. }; d* I0 T+ R6 S
  121. ( `! r+ W7 V3 h- s5 c  G3 n; q% R" p
  122. /**
    : Z, I9 R1 W; p1 V* s
  123.   * @brief  Ymodem receive./ G; ?& o" Y; p( C5 f7 a
  124.   * @param  None.2 [$ T# ]( R. w6 i) c" O( H
  125.   * @return None.
    $ r2 r+ I5 K* Q1 y! F) u
  126.   *// D* }" n3 `  q3 K: E
  127. void Ymodem::receive()
    ' P( W# @1 y+ e7 X/ F  R! M
  128. {( I% d& [+ c: ~9 Z
  129.   switch(stage). S* r# R* ^( R
  130.   {) V) J& D! C( k3 j
  131.     case StageNone:0 @& q# {2 l( q1 Y, i* M
  132.     {
      g: v7 k' Q. [) \- y
  133.       receiveStageNone();" j$ s. L# p& ], L# M! h0 j- Q

  134. " T3 A4 o; s8 c6 c& m3 k. i6 R3 \
  135.       break;
    $ a. v% m* k$ h" \& j4 |
  136.     }
    6 I7 u! [+ U( l
  137. : R7 q; r/ O+ X
  138.     case StageEstablishing:
    $ w5 c: G7 H8 C1 I& u! V  i( Q
  139.     {1 e, F: g( m7 h7 N
  140.       receiveStageEstablishing();& ]+ [2 P0 l0 K2 u/ }
  141. 2 b, j2 h0 |% a! Q# b
  142.       break;
    ! @, G/ y9 M6 \- V& m2 Z& y
  143.     }
    2 }4 Z2 k( Z$ L2 b: l4 P
  144. 3 n* O; N: F+ c, c  X( {
  145.     case StageEstablished:
    $ I; u' Z, O& A# s, Q! }
  146.     {
    , h# \4 L2 _. a( }/ x& ?
  147.       receiveStageEstablished();% n- i4 ^) J) C- l; \# B. u

  148. % o. F8 h" ~) g! e4 `& k
  149.       break;
    ' N/ N# p* q+ S. P5 B2 ^- b
  150.     }
    5 m9 j; x, ?; F! X
  151. % X+ n; |4 Q% [0 r+ [+ V% y
  152.     case StageTransmitting:1 a2 T* \7 X* z; \8 Y
  153.     {' z+ ?# H8 ?' t8 R8 s  |( }
  154.       receiveStageTransmitting();
    ) z# t5 g9 K: K4 r8 K

  155. & a" H# i( ]4 q" ?
  156.       break;
      Z& U) `% V2 e5 D# F/ A' _
  157.     }
    , _5 @7 w2 a5 @9 G) ?
  158. " Z7 [) Y$ K7 Q; [) U$ M
  159.     case StageFinishing:
    / h* x; d2 }* d
  160.     {
    ' [# ~; X" P% ], l: Q
  161.       receiveStageFinishing();; U  c' h+ p; Y
  162. # o3 v' H& o( {- W! q
  163.       break;: ^# q8 Y' F) r' q+ P9 E: R2 V
  164.     }
    ( K+ W: Y- V! _/ I) i# s  D

  165. 9 o* A5 Q- W- q! _3 {  r, b. m
  166.     default:
    8 g2 q4 y. x, G2 `; k
  167.     {1 h7 _- V" S8 `  E2 V" J
  168.       receiveStageFinished();
    + [$ g7 q8 o1 g6 ~  @, {2 c
  169.     }
    2 W0 @6 d3 M6 J& y: R1 T; g
  170.   }& U/ w+ m  c8 z
  171. }
    & l, J$ W2 I. g% i& }1 ~, l$ }
  172. 1 H4 U3 ^+ M; z. o3 E
  173. /**
    # X. A! ~; `* E" a
  174.   * @brief  Ymodem transmit.
    6 L' n" o. ^, V. _0 z/ S" ^
  175.   * @param  None.9 r' f; k% F* [' ]  z5 W' S$ c) r1 v* z
  176.   * @return None.
    ; k- E, l' x% A$ u6 R
  177.   */
    - i9 X8 B2 Z% y2 z
  178. void Ymodem::transmit()5 J# T2 ^" @: f3 r
  179. {1 F# D- M* R% A! _! D" ^0 L
  180.   switch(stage)
    8 E4 Q6 D2 p8 h- u, ]0 Q  h5 J
  181.   {
    1 ^2 g, X! m' y+ y7 A
  182.     case StageNone:
    1 s* |% _  c8 W+ h5 i+ ]% n% }
  183.     {
    # F! Z; X( O1 I' N
  184.       transmitStageNone();
    9 I: e4 z, z4 ^; N: B' E# S
  185. ( Y$ Z+ P3 `# t) d
  186.       break;
    7 ~1 j- }1 U: w/ \% Y/ G
  187.     }( E2 ~4 L. h% x, x
  188. 1 K6 T4 h, X( H- B( E9 g
  189.     case StageEstablishing:
    ) M, \5 E" Z# @2 B
  190.     {9 m& I/ l1 K9 X5 D, [
  191.       transmitStageEstablishing();# f* l; g" Z* l, r& x: Q

  192. + m* ]- T( X/ D0 V# v4 f
  193.       break;
    / h+ B: f8 g& f! q# K8 Z
  194.     }
    * V4 `  _& j% s7 z% G  P; |3 W
  195. ( B# |/ K& i  K) y6 o* {
  196.     case StageEstablished:& s( z' }; S+ i
  197.     {/ t- t( _/ I. ?  `
  198.       transmitStageEstablished();: B+ r' e; A9 e: ^3 }) G6 y  j/ k

  199. ) _& l4 m7 A! z
  200.       break;
    / l& d4 e: @' K6 u
  201.     }% K/ E, g3 S, l) F) Q: B
  202. 9 \7 T. E, h4 O& m
  203.     case StageTransmitting:- q: {9 t2 `' t) [
  204.     {
    & ^% d3 R2 j  l
  205.       transmitStageTransmitting();4 m/ p4 Q4 f, l  m

  206. ) r/ K6 ^. ?, D- y4 I7 d
  207.       break;
    5 B% \' A# n( d! W, I4 B
  208.     }3 v7 b# A: F0 u" W/ ?  H
  209. & i. c+ t: L! Q6 F! J5 L
  210.     case StageFinishing:, t; c3 X, E% H
  211.     {$ _9 p, p/ I9 t+ V5 x8 n% c
  212.       transmitStageFinishing();
    , P6 d- j6 D, d9 ^3 `* ?4 E4 B
  213. ) ~. B0 |& K9 o+ P* @& ^2 q) j
  214.       break;9 j  @) ^4 J' x8 V7 n: h( N
  215.     }
    9 `: {* d# p" {: N% Q1 ?
  216. 4 s3 A4 o. h' w/ m$ A
  217.     default:6 h- O9 c+ M6 v6 }; P' J5 d1 z
  218.     {
      J2 C2 ^9 J7 H) V  f8 ]) t, R! `# |
  219.       transmitStageFinished();$ n, r. I) m8 l& @  N+ L6 U; j1 P
  220.     }$ x) V! L* w9 Q6 m
  221.   }! k$ v: E  }0 v! m
  222. }2 l# P6 p: G1 K3 j7 M; d  |. K
  223. 4 d, `! A' @3 o9 k3 V0 ]. y
  224. /**  P# n8 P" O1 T
  225.   * @brief  Ymodem abort.: s6 b( @9 j# D. V. G* p! ?% p( r
  226.   * @param  None.5 I- `$ F& p; n" W! a* [) q5 n
  227.   * @return None.! c0 e  G+ X: J# q# p
  228.   */
    % l* X7 e% A0 w
  229. void Ymodem::abort()0 ?& i5 C* G9 B
  230. {. Z, _; y# R, Z4 Q
  231.   timeCount  = 0;$ _$ r. C' d, k1 D
  232.   errorCount = 0;, b( k3 v8 E7 A2 s2 R" C4 H$ J
  233.   dataCount  = 0;
    3 M9 I- s' ^* [3 z
  234.   code       = CodeNone;( E' M6 H6 N7 O$ h9 Q/ a. d$ [& Y
  235.   stage      = StageNone;
    % _; F0 n4 Z5 U& \& Q

  236. ) x, v1 G0 T; _- E
  237.   for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)3 o/ l$ J: K. k8 R2 s0 ?
  238.   {! B9 k% s9 v+ I1 t/ I  Z
  239.     txBuffer[txLength] = CodeCan;
    ( a% ^% H$ J: s$ O
  240.   }
    6 _2 z- o5 n. N. P
  241. 0 y# z2 Q' A& N, `; M; }
  242.   write(txBuffer, txLength);
    % e9 {; D1 K5 f  \
  243. }, u9 K+ |  q( k, D$ e1 h
  244. ( W& A- O& P- ^0 [% G
  245. /**& {+ s* r' O3 W* w* O2 D
  246.   * @brief  Receives a packet of data.
    * U9 `  j0 r& C$ P7 m# T4 s( H( N
  247.   * @param  None.
    " L1 k! ^) X( o+ M, [
  248.   * @return Packet type.
    - S8 _. c3 {1 k6 _: {) d
  249.   */( J9 W1 R7 D& Q# {, M: }
  250. Ymodem::Code Ymodem::receivePacket()
    8 U0 W$ A6 j  A
  251. {
    4 m" I4 k2 T- ?/ R$ h5 _5 E# V% u& \% ?
  252.   if(code == CodeNone)
    " L  c5 y0 F; E7 h8 s, j
  253.   {( T* c- a4 R- L5 _) a: L
  254.     if(read(&(rxBuffer[0]), 1) > 0)
    ( S* V* Z* b5 L3 }
  255.     {
    $ E3 t" N$ q2 t4 c0 o1 E! B( ]0 @9 m  p
  256.       if(rxBuffer[0] == CodeSoh)
    1 c- X+ C* M0 A3 g' c4 J
  257.       {7 C! M( y( K6 Y* I
  258.         uint32_t len = read(&(rxBuffer[1]), YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 1);
    * O) N  m. d3 D  g$ L
  259. $ C1 L9 Q% Z: Y
  260.         if(len < (YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 1))
    % N. v  B" Q( h" n; N
  261.         {
    4 j! n6 Q& R7 t
  262.           rxLength = len + 1;
      P1 w+ M6 \. O
  263.           code     = CodeSoh;
    2 n, l% r1 k2 ]. P1 _

  264. - Q7 ^; `# Y% ^* I
  265.           return CodeNone;. _0 t) G/ |& D/ ]( c9 }# u$ w
  266.         }
    # o4 O  c5 H8 v3 Z. y# ]8 _
  267.         else4 n8 |, Z4 T% e' ]9 o1 G
  268.         {
    " }* l% t5 G+ w1 Z0 |
  269.           return CodeSoh;
    9 z) |6 l. s, ]4 a9 a
  270.         }  j6 d0 K6 P% O; y
  271.       }
    7 N& E5 i3 L2 s) l. X" N5 ~) u
  272.       else if(rxBuffer[0] == CodeStx)
    * j9 b* n# i$ Y, G) |
  273.       {! X4 j6 ~. ^* A" i9 P8 c! c
  274.         uint32_t len = read(&(rxBuffer[1]), YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - 1);) f' x8 v' ?) U1 w* y5 _

  275. - y1 |. J5 g$ G2 C
  276.         if(len < (YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - 1))
    ( x" E% S* k4 ]$ w! L7 E! ~
  277.         {1 _4 d) z& |- u, B6 S3 l
  278.           rxLength = len + 1;
    8 K! e' {, w+ h4 l
  279.           code     = CodeStx;9 k3 E& a& W' q: U$ p/ ?

  280. 1 v: @5 J2 _& W
  281.           return CodeNone;
    ( W! s2 F2 H, D4 o
  282.         }
    1 V  Q6 R$ y: ?; f. H  G9 y. g; G
  283.         else
    7 D  k+ k+ E: x4 z
  284.         {3 _% O# V8 R/ Y7 {* M* P. }
  285.           return CodeStx;. h8 d0 f) E. f  ^+ A) Y6 }
  286.         }
    7 a' H6 X) z6 Q3 v. X( ^) Y0 G
  287.       }
    ) I2 z! d/ Y9 L. u" q$ `
  288.       else: {/ O6 B  `; r8 |6 i
  289.       {
    ' e7 J% G% |( s6 _2 P( F
  290.         return (Code)(rxBuffer[0]);
    9 ^; @1 b8 B% M& \5 a( P
  291.       }
    ) d) f5 R0 G2 d7 Q# Q" d( w
  292.     }$ `" t2 S: f+ n8 g
  293.     else
    % X8 P; _0 v* B( K* G
  294.     {
    0 M+ P; `5 G% J$ V2 c
  295.       return CodeNone;! K, ]$ o0 e9 Q) D
  296.     }8 i' Y+ y' [1 b0 j( n+ p
  297.   }9 Z) ]/ H: Z4 S' v/ }5 ~, e: X
  298.   else
    . F6 F2 N1 s: Q" b  V/ g
  299.   {( ^  V2 d# H& s( \$ M
  300.     if(code == CodeSoh)
    " }7 i' V9 I8 n$ @1 d( U' a! x
  301.     {
    ' q( ^" S/ y2 l9 `2 K' K
  302.       uint32_t len = read(&(rxBuffer[rxLength]), YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - rxLength);
    4 b9 B* Q+ q8 Z
  303. * e! R) \% `; s3 y8 Q% a. @
  304.       if(len < (YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - rxLength))
    7 K% A7 \% [7 l& _& I; W  M4 k0 B
  305.       {+ }, w+ Z  j  }
  306.         rxLength += len;! g6 U" Q# F' `: J/ l* k& P

  307. ; t8 ?3 a) M$ D5 }& u
  308.         return CodeNone;6 K" x9 N1 \; g4 n% o# t9 t- P
  309.       }
    8 c! s$ r3 R+ `. {/ ~( O, C
  310.       else
    - p- m% I0 `% y0 g! \' `0 Q
  311.       {& l3 f0 V- j- {; b8 |
  312.         code = CodeNone;
    4 k: i( a) H# F! q( X, k8 |
  313. $ q9 Y+ s/ d8 _2 ?- M6 P! ?
  314.         return CodeSoh;
    4 H) D8 q. [1 }" _
  315.       }
    ) |& L2 t: y; Y0 g+ o
  316.     }9 S7 }. Z+ d2 {
  317.     else if(code == CodeStx)+ i% I+ \" ?9 K: G$ j
  318.     {. R& D0 ?2 }- _2 _2 o4 N1 U
  319.       uint32_t len = read(&(rxBuffer[rxLength]), YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - rxLength);
    2 M; o$ H$ m- D; B
  320. - `$ |, V! V% H' C# `$ S
  321.       if(len < (YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - rxLength)). M) M( b2 a2 m' i
  322.       {
    1 z* E: W. e+ x/ {# w4 L8 W
  323.         rxLength += len;
    6 N! y1 K' ^! t& Q
  324. 4 H+ t) t/ O) |0 c- y
  325.         return CodeNone;# f5 i/ J. p# @, _7 k' {
  326.       }
    9 W7 w" Z" K% G2 H
  327.       else
    6 u* y: H1 _- D9 t7 ^  a- ?4 ~, b
  328.       {1 x: x( _' c6 K
  329.         code = CodeNone;
    0 D& V* O( U! y
  330. 3 j; Z3 ~: [3 D
  331.         return CodeStx;
    6 j) ?0 _7 b, |% T9 M
  332.       }& \5 j9 O* Q% }
  333.     }& `3 Z) I$ h3 A
  334.     else
    % g# a# _! c1 C+ x& m# \. X$ R: R
  335.     {1 \' m9 e* q$ T) d4 A5 L
  336.       code = CodeNone;
    / E; T" Y) Y: h: }

  337. 0 j. K  u* T( O
  338.       return CodeNone;
    ( m2 y+ P5 E" B! N; a
  339.     }
    4 O2 }  l; ~. S% r7 v, @+ r
  340.   }7 ^  ?6 W; `0 s' I: O& o5 |
  341. }. V& N% Z# |( J, }, o
  342. , l; \! M9 K; n% ]; g3 M; S
  343. /**
    % z9 ^' w1 s* A+ M2 a3 a- ]: Q$ w
  344.   * @brief  Receive none stage.
    ' ^/ A" N- `0 [- k: E
  345.   * @param  None.. j7 c. h2 K% S6 q$ g1 O
  346.   * @return None.
    * j) t  c# Y3 _* `6 O3 n/ O+ k
  347.   */! A' V. E, l+ c
  348. void Ymodem::receiveStageNone()
    2 a, B+ [1 g- M2 X9 ?
  349. {* P* x6 W% q, d. N& f% A
  350.   timeCount   = 0;
    7 S0 `" v5 R: c3 C1 ]
  351.   errorCount  = 0;
    9 ~& }% i: n1 g: l. x$ m+ [+ O
  352.   dataCount   = 0;
    ) [# a5 B2 O4 O9 {( C+ e
  353.   code        = CodeNone;
    " [, q. f: _) D2 |( f) d" N
  354.   stage       = StageEstablishing;, T* Q4 G% p9 [5 }/ n
  355.   txBuffer[0] = CodeC;
    $ Q* t( }/ u4 I
  356.   txLength    = 1;
    ' M* g( S4 E% Y6 m
  357.   write(txBuffer, txLength);
    ) J2 t1 }- Q1 ^  w4 E" N, A: P, y
  358. }5 }! E( C# M9 ?' _# N4 ^- R

  359. 8 e3 Z% i2 k! F" J
  360. /**
    8 m# a- T* ]7 N& K& n( c2 s$ y
  361.   * @brief  Receive establishing stage.3 g2 g$ h; P  h; S
  362.   * @param  None.
    1 u3 ~" g4 T8 i9 `7 M2 R: d( O
  363.   * @return None.
    - q( ~* F7 L3 d+ o+ F6 Z) X
  364.   */6 |7 u( V4 C# c
  365. void Ymodem::receiveStageEstablishing(); e, B( ?# J  ], J% c0 w- o# b
  366. {6 J/ _' J" ?" i, ?  ~! X# D
  367.   switch(receivePacket())
    - y" E) X' e* U
  368.   {" a- `4 u$ Z/ j  h: r
  369.     case CodeSoh:" }' k+ Z* b5 T& ~0 g6 K
  370.     {
    ( Z6 C5 S+ j/ J1 n# u; s% z% P
  371.       uint16_t crc = ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 2]) << 8) |
    9 _, K! q: Q! {9 l: I  t: g: u
  372.                      ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 1]) << 0);: S3 Q8 p  R) A

  373. 2 x$ c5 M# h2 I
  374.       if((rxBuffer[1] == 0x00) && (rxBuffer[2] == 0xFF) &&- l& `0 ~2 X- R# ^3 c2 Y5 h
  375.          (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_SIZE)))
    ) ]  d  F7 c. G! w8 E; _4 N
  376.       {
    # C. d8 k; Z. `1 O0 `8 `) F0 f
  377.         uint32_t dataLength = YMODEM_PACKET_SIZE;
    ' c, a7 H% d" s+ E

  378. % \7 B$ J  b+ d6 U, D. l
  379.         if(callback(StatusEstablish, &(rxBuffer[YMODEM_PACKET_HEADER]), &dataLength) == CodeAck). s& d  f" W+ o7 c+ }
  380.         {# ~9 t$ J0 i$ O
  381.           timeCount   = 0;& r+ n2 `4 m  H* R
  382.           errorCount  = 0;
    ' y- i/ v; D. E. I+ H
  383.           dataCount   = 0;; c# c. x  Q1 h5 C  p
  384.           code        = CodeNone;
    , C! X" f" B4 ?
  385.           stage       = StageEstablished;' c+ I" G6 G4 f" l8 F
  386.           txBuffer[0] = CodeAck;
    # O1 V6 g3 |" B% j# ~5 o
  387.           txBuffer[1] = CodeC;/ C7 {% t6 G" N6 R. {! ?4 k
  388.           txLength    = 2;
    " i) D1 n6 G- n" M
  389.           write(txBuffer, txLength);7 s2 x3 @9 b8 G, }. G' \. p- D
  390.         }
    * R& E3 P; l5 e% q' X: L
  391.         else
    1 [4 g& M/ e. p! u4 R) X  e
  392.         {
    " z( G8 q& z% b7 r2 H
  393.           timeCount  = 0;
    1 o% {5 D# x5 z8 K% Z* ?  h
  394.           errorCount = 0;
    % M8 |6 o/ \8 U; k: {  k. P- Y2 H
  395.           dataCount  = 0;
    # K; d" X2 W$ r) F5 O/ n
  396.           code       = CodeNone;& P$ b5 [- o, }
  397.           stage      = StageNone;; L  F$ T- b3 n" @- B0 ?
  398. ) \( }7 y8 i6 e; ~7 i6 M2 j
  399.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)6 k" l5 w, [6 {' N; y6 A' x
  400.           {
    . Q  Y! Z; c. C5 C: I3 A9 @8 J# |% n
  401.             txBuffer[txLength] = CodeCan;4 s: G6 z  h4 w0 A4 s
  402.           }+ e" T9 _! E6 \6 N1 T

  403. & O6 R! M5 A1 j
  404.           write(txBuffer, txLength);/ S1 i* G( p4 V3 N. J( H
  405.         }
    9 G6 l; Z5 B, P$ w) f3 M4 r
  406.       }
    . s1 e  a8 e+ E
  407.       else- j# @9 f9 v$ S2 B
  408.       {$ D0 r( d! m, B% T/ ]7 \
  409.         errorCount++;( ~+ h0 i) T0 u! m( I8 F
  410. $ k2 I( V9 R7 n8 G- B7 F) E6 d
  411.         if(errorCount > errorMax)9 Y: [" A+ m/ z/ G8 ^6 A
  412.         {; k$ |: Z. y) ?0 R5 a( O; E: T5 H7 n
  413.           timeCount  = 0;
    1 S) |/ z: i* P& [9 [+ l. i4 Z8 B
  414.           errorCount = 0;. }# h- D4 s- D/ U
  415.           dataCount  = 0;
    9 R7 `! O- v; J0 R( S% o0 I# c
  416.           code       = CodeNone;2 c! W( s6 U3 K& s# x
  417.           stage      = StageNone;
    2 _; g3 Y+ Q0 W) a* q

  418. % w8 e3 h+ ?% D/ R$ F
  419.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)& t& D) ~2 m1 N
  420.           {
    - L! N- E$ b( ~7 n/ P
  421.             txBuffer[txLength] = CodeCan;
    ; F8 P* s5 s( p3 N# ^5 j
  422.           }" X0 \( ?2 l  G3 }# G% d! f
  423. & h& Y$ e0 T4 R/ Z% e
  424.           write(txBuffer, txLength);
    - e  S' L1 q1 ~- \
  425.           callback(StatusError, NULL, NULL);! P- r7 O1 \' [- `2 v5 H
  426.         }6 _4 y7 J- ]& Z1 q% s
  427.         else
    " V# e' _# o/ f
  428.         {
    5 o( {* K$ e& _9 M
  429.           txBuffer[0] = CodeC;
    + O/ E1 M4 Q9 u
  430.           txLength    = 1;( s& P1 U/ Q2 Z8 Y
  431.           write(txBuffer, txLength);
    ! w, e6 l4 o- v3 \
  432.         }& K: x5 }/ h" K! C8 \
  433.       }) E) {* c* |. `1 h% m9 Q

  434. / J/ R1 J7 [7 o
  435.       break;0 w1 m& J7 X6 f' Q) p8 E
  436.     }
    1 _# |5 i! p* G  n
  437. 7 f7 \6 S8 z6 P- \" N
  438.     case CodeA1:
    ' B4 S1 y/ z# a; h$ s- t4 e5 }1 k2 A
  439.     case CodeA2:
    " @- G' N# w1 i* C) X
  440.     case CodeCan:
    8 K! J" u0 e. a. O! a. H* m9 k0 X: g9 L
  441.     {
    * D* M7 W7 h& b0 O- b, s% H
  442.       timeCount  = 0;
    - Y- B" P+ e# G
  443.       errorCount = 0;* R+ b4 x+ ^. A) r1 b
  444.       dataCount  = 0;
    - G. G  `. [, z; D, L
  445.       code       = CodeNone;
    % Z1 e2 `3 Z, s3 ^# o1 g4 H
  446.       stage      = StageNone;6 ]6 j( x2 n6 r, u7 n
  447.       callback(StatusAbort, NULL, NULL);
    ' H5 ~, v* i% k9 }7 E/ B: T) F6 O& i, I

  448. 1 A, ^0 K3 M3 f, |  ~' ]  N# T$ X
  449.       break;( ]' N  K2 ~, v- p: ~# s" A4 G
  450.     }" {! Y0 M2 a# |! \) I) f7 j3 T3 z
  451. $ y) |% C- W3 u5 ~. G1 S* T8 c
  452.     default:1 @7 N% ~. X( a0 L
  453.     {
    3 f# ^! f, Z4 m7 m% D  M/ k8 I
  454.       timeCount++;
    / f9 D+ s  J" [5 z! S6 ]
  455. % M8 s/ g7 [- R. S- P' S0 i
  456.       if((timeCount / (timeDivide + 1)) > timeMax)+ X* Y$ V+ x( p1 f/ |
  457.       {
    / c4 u  N; g. C, }0 ~6 A
  458.         timeCount  = 0;
    ) s( {4 w/ W6 f  W7 r
  459.         errorCount = 0;
    * o$ P1 D0 d. |# _: x
  460.         dataCount  = 0;! d9 I- p0 [" T4 T
  461.         code       = CodeNone;" p5 z( v, H2 q" d& a; f
  462.         stage      = StageNone;
    2 @' z& ~; E+ P! K, p+ }5 z3 D

  463. 5 [/ c1 ?  R' ?; q6 c% Q
  464.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)4 e& o" ^& {* T1 H0 n# p% T8 R
  465.         {7 f- ^& t8 W. R- J) S
  466.           txBuffer[txLength] = CodeCan;
    , \4 P% U- A# s% u' z
  467.         }
    8 P0 E; X' J7 S2 P1 r; g3 T) c
  468. & L, c+ B8 S0 Z6 ?
  469.         write(txBuffer, txLength);
    ' x' ]( C: S/ u2 c1 z5 @
  470.         callback(StatusTimeout, NULL, NULL);8 `; r- n( `- D
  471.       }* o6 @' @3 F" \3 C! r
  472.       else if((timeCount % (timeDivide + 1)) == 0)8 D( w; [' ?7 `; G% Z7 ^6 y
  473.       {
      e/ U& {& {. @) g* @
  474.         txBuffer[0] = CodeC;
    # {4 g* p$ L3 a. z- F
  475.         txLength    = 1;
    7 X+ L) L; r. F% i: M- \7 G; b( j8 I
  476.         write(txBuffer, txLength);% N2 o9 T4 Z. {; y2 Y5 V8 @" n
  477.       }0 W3 R4 _, p# a2 H
  478.     }. B- ?3 @9 f. m, ?/ ]1 S
  479.   }
    ' }: X! {# _% L2 f+ f
  480. }+ J  ]! N2 N7 e" v: g7 {1 N/ }+ y

  481. ) r5 M' s# ?6 h' h# \* t
  482. /**
    ; T# D3 S" D2 p1 M" L
  483.   * @brief  Receive established stage.
    ( @  T7 c: u2 x% \
  484.   * @param  None.' T$ N. G8 A; e+ h) q
  485.   * @return None.# V4 a; N% p0 R9 {( O3 l3 r; i
  486.   */
    4 K* m/ j, W5 |( s8 g
  487. void Ymodem::receiveStageEstablished()
    & U9 ]' s" \% n! J% j& t
  488. {
    % H; J6 z# |) Q+ V% o
  489.   switch(receivePacket())1 I# A# n& |# p% }5 H* H
  490.   {
    " J( D: c: ~9 z; o1 H8 g
  491.     case CodeSoh:. m- x+ o/ |2 ?2 @3 M
  492.     {, {! I7 p2 O6 ]7 T
  493.       uint16_t crc = ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 2]) << 8) |
    * y0 ^8 ?9 f8 Z& f2 C  W6 P2 F
  494.                      ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 1]) << 0);
    ; t( x. E% c- }9 v$ w

  495.   t# R7 c" _: U& P7 ?1 ~  g2 y
  496.       if((rxBuffer[1] == 0x00) && (rxBuffer[2] == 0xFF) &&: X( t( V5 V  V6 }3 C6 W5 k3 M
  497.          (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_SIZE)))
    * N; n+ ?+ h$ w' z6 r* L
  498.       {0 k' X# d- ]  v% ~9 ~) N3 E* _5 m
  499.         errorCount++;( |* Z+ K+ C7 a3 W# ?0 i$ n) m% {

  500. " Z1 H( }0 z" X3 q; c  s
  501.         if(errorCount > errorMax)
    9 h, B6 C: q9 K
  502.         {
    7 o$ @; A2 N# a1 K' y# `
  503.           timeCount  = 0;/ C, \, X4 F; S3 i4 s3 X2 @
  504.           errorCount = 0;
      S- p% B* |2 z
  505.           dataCount  = 0;
    2 m8 f7 _0 B" A$ {& f2 z3 ~+ w
  506.           code       = CodeNone;
    * Q8 W4 y% ?4 _! Y8 u: x6 u* J0 M
  507.           stage      = StageNone;( e- y8 a9 R# K3 O, Z0 {

  508. / j# t& z9 ]) _$ l: _
  509.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)( o7 n' e3 d, h2 c# V
  510.           {
    + p- S6 B8 S, |/ D- Z4 C% s$ W7 Y
  511.             txBuffer[txLength] = CodeCan;+ O  I. A4 [- q" N
  512.           }
    9 _5 W$ y( E. l+ d
  513. 2 a) o" ^9 z& S, F$ z
  514.           write(txBuffer, txLength);
    6 c# I4 E" T8 o- h8 C
  515.           callback(StatusError, NULL, NULL);* a( B; E" @5 t  c9 ~3 E
  516.         }
    ; [2 `- p! I, X! `2 W, o
  517.         else) D, m1 Z6 ]& ^& P: f- }5 e$ I
  518.         {
    2 P8 w" Y6 l+ {+ J: X4 b, s3 m
  519.           txBuffer[0] = CodeAck;
    : Z/ L2 h- V# Q# i6 J! e" c
  520.           txBuffer[1] = CodeC;
    4 `: Y1 m+ ~. {  i) y
  521.           txLength    = 2;3 H* Z! v7 {- j8 H# Q" G
  522.           write(txBuffer, txLength);! F+ }( T) x  ^2 N. `' q: v
  523.         }
    5 C- l5 m- C. {: [9 p
  524.       }
    * p6 t) j6 U" k
  525.       else if((rxBuffer[1] == 0x01) && (rxBuffer[2] == 0xFE) &&$ s( F( u9 ^- I" Z4 H2 e4 \
  526.               (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_SIZE)))
    / J) D: W9 D9 c$ s% z9 G
  527.       {) o3 b4 ]7 }: G; T5 t: X6 p
  528.         uint32_t dataLength = YMODEM_PACKET_SIZE;
    / s: [3 s# w; h0 ]& x$ x: z1 N
  529. * k6 C4 y& I" s# o* S! ]
  530.         if(callback(StatusTransmit, &(rxBuffer[YMODEM_PACKET_HEADER]), &dataLength) == CodeAck)
    . [0 F, H" b; O3 Z* k4 y
  531.         {3 L2 ^% P. y1 l' N4 ]
  532.           timeCount   = 0;8 N, A: Y% c6 b- \, O$ {
  533.           errorCount  = 0;
    3 ?. [2 U' T0 L: E$ f# u
  534.           dataCount   = 1;
    1 \( Q4 Q  J& H  s/ K0 N7 }
  535.           code        = CodeNone;8 f) d  c- c0 X+ u! ]0 a; n; F
  536.           stage       = StageTransmitting;! C1 M& q2 b. b& ]
  537.           txBuffer[0] = CodeAck;
    # y; T) }- u* ]+ j$ G. W
  538.           txLength    = 1;
    ; n5 C& h, s: _- a
  539.           write(txBuffer, txLength);+ B. V+ j4 I7 A; {7 E4 v  {1 x: k
  540.         }- _* ^. ~  d! U0 a! Z3 j. d
  541.         else
    / ?  N/ Y* r1 {; V/ y
  542.         {* `1 z: B  M4 |  P% m# }6 o
  543.           timeCount  = 0;
    1 d' \: I! G- W4 X2 k2 R& J/ k
  544.           errorCount = 0;
    0 G  `6 ]) b- I* _
  545.           dataCount  = 0;0 ~! n4 T5 \' ~" I9 q, T
  546.           code       = CodeNone;
    $ b1 \+ ?4 @" w9 {# J" h
  547.           stage      = StageNone;; r4 J) ^/ m1 C1 \5 d
  548. % i5 c+ k  k' g
  549.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)* p  B; i! e' l- ]/ |* Z
  550.           {( p( Q1 F" t3 O& u! t
  551.             txBuffer[txLength] = CodeCan;
    6 E: ?" v& K; A4 b
  552.           }: c" u, \4 H4 S
  553. ; O3 p. S! p5 P! \5 K
  554.           write(txBuffer, txLength);$ b0 V0 C; v/ e4 G5 S  k
  555.         }' x0 i& I! q8 ~$ l& e
  556.       }: I1 q/ u  x  b% ~, ~& y/ R  J3 }
  557.       else
    5 e$ o8 g* h' q  _0 ]9 [, n
  558.       {
    4 s$ }7 Q7 u% u; _
  559.         errorCount++;
    # [% c6 q0 I8 I5 S) h
  560. # h3 z4 k) C% k
  561.         if(errorCount > errorMax)
    4 {7 V! o) Z5 S: `% e! R
  562.         {
    # s  n6 F: }- p7 ^3 a( x! e$ [" A
  563.           timeCount  = 0;. d4 [/ S, T2 y; x! [' V. X
  564.           errorCount = 0;
    8 l: g( h0 G6 ^5 ?
  565.           dataCount  = 0;
    1 Y, C8 J; }# s* H# a
  566.           code       = CodeNone;  M; ?( f, X: z1 U7 _1 a8 c5 e
  567.           stage      = StageNone;
    $ i3 c8 r- ~, f. D( C5 Y+ p

  568. ; h# t( c  D! L' s4 O- |0 ~  _
  569.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)1 J5 ], s4 B0 q
  570.           {
    3 \8 ~% q- l1 _- a3 l' M0 F2 k
  571.             txBuffer[txLength] = CodeCan;# H) X! A; p5 {, p; n5 m: J6 V8 q
  572.           }. n% m' T$ _  f1 W

  573. 8 F. n& B) p4 Y, V- B- g5 g
  574.           write(txBuffer, txLength);7 i2 T" Z4 v9 k+ ^3 j5 _
  575.           callback(StatusError, NULL, NULL);
    1 g1 J+ n8 s- C) Q4 m+ Z4 v, g
  576.         }1 Y: Y& s+ Y5 E% o# @6 Q- n
  577.         else: ?4 c0 J; P1 N) N% Z6 G
  578.         {
    # w& f, A& G2 D7 A0 l& [
  579.           txBuffer[0] = CodeNak;
    - b  a) J$ v5 ^: a. L& R1 \
  580.           txLength    = 1;
    $ }0 e" E1 b  }8 R8 K$ L
  581.           write(txBuffer, txLength);0 i. Z6 g9 d! D7 m
  582.         }. }, J/ \! z0 }9 T  F5 H% y
  583.       }' |: L. W3 U& p- C$ u5 S2 y
  584. # m7 w, f' l+ o$ E8 i9 Z% U* C
  585.       break;, ^: _7 ]! P3 l! c; {: L
  586.     }
    # I  C# Q8 W. c# d7 [
  587. # h7 @! p: @5 F6 [: \  w! H3 w
  588.     case CodeStx:1 b3 j2 b5 r! T
  589.     {& M% W: \; |# W! r, b  r: w/ b
  590.       uint16_t crc = ((uint16_t)(rxBuffer[YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - 2]) << 8) |6 P+ L% F6 s4 Y7 p  b7 N: k" x
  591.                      ((uint16_t)(rxBuffer[YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - 1]) << 0);3 x  `. x* Z; q- i, A
  592. 4 Z9 N6 q! r- o; t! {/ G4 y8 B
  593.       if((rxBuffer[1] == 0x01) && (rxBuffer[2] == 0xFE) &&
    1 m5 _" P/ i% i% a0 y
  594.          (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_1K_SIZE)))8 j$ n7 ^+ U$ T, x9 `2 T. F4 H
  595.       {: u7 y/ z. M" g3 X. f  _6 [* t
  596.         uint32_t dataLength = YMODEM_PACKET_1K_SIZE;/ T, O( o7 u, X2 ~5 f
  597. ( ]2 `5 q( Y" J2 N' w' X
  598.         if(callback(StatusTransmit, &(rxBuffer[YMODEM_PACKET_HEADER]), &dataLength) == CodeAck)7 I: ?+ N" o8 \8 N
  599.         {
    - P( b  Y0 F& f) B) ]
  600.           timeCount   = 0;
    ' d- O0 g+ M( u* O
  601.           errorCount  = 0;* u3 E8 P: f8 h- Z& n8 S% J
  602.           dataCount   = 1;
    4 N, }8 P5 b, ^
  603.           code        = CodeNone;) X  {5 ?  M9 [, V8 P% k2 t; }* i! E
  604.           stage       = StageTransmitting;
    2 X7 D3 Z, }4 Y4 m0 l2 `
  605.           txBuffer[0] = CodeAck;$ @8 e- E4 d- Y2 c, h" B
  606.           txLength    = 1;
    ! f2 N+ A3 L( ]
  607.           write(txBuffer, txLength);
    2 s1 _% \0 Y7 `: H% j6 Z& L
  608.         }
    ; a' g$ P2 E6 ~/ ?3 c/ |
  609.         else4 t3 Z0 H- E& e- s  O. w- T, A
  610.         {
    + ?3 G0 |. y" J/ o. `
  611.           timeCount  = 0;
    " p7 L/ _9 V* j3 L
  612.           errorCount = 0;9 h$ Z: T; l0 T' f
  613.           dataCount  = 0;* j/ J# a* X# R, w& W0 H' K
  614.           code       = CodeNone;8 V2 u2 _# u( o0 s
  615.           stage      = StageNone;
      v3 Z" [+ i% }. U, h
  616. / s% y' W2 }3 o5 w+ r+ X
  617.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    4 S, `0 d1 r; L" c: i
  618.           {6 J4 E  ?8 L: y/ d) V5 H
  619.             txBuffer[txLength] = CodeCan;
    / ^9 Y7 w  ^" G" i0 |3 R
  620.           }
    , P8 c5 E) i. w, ]/ [

  621. & O; N* c  p, ^' r6 y: A; O
  622.           write(txBuffer, txLength);1 v% Q  n# t% J6 M+ A
  623.         }
    4 t) M* c  c8 f  v2 V9 M
  624.       }
    8 C1 ~7 P; l" |/ _1 Q$ Q
  625.       else, u5 `& I" {5 k
  626.       {
    2 X" }, l. O/ P2 v! [! z! f5 H
  627.         errorCount++;
    0 z& J! c# G' B; l

  628. ( ~2 E1 p) Q. c" |: S  C4 }# l
  629.         if(errorCount > errorMax)2 \2 r1 O. P- A. `/ Y3 c! v5 M1 H
  630.         {
    ) {1 K0 x" V1 \8 p2 q: W
  631.           timeCount  = 0;0 `5 p, Y9 C9 Y5 Z! W( f/ l
  632.           errorCount = 0;1 W% }+ ]3 G! T* t( M# r" v
  633.           dataCount  = 0;
    8 [- R  n# d# f9 q
  634.           code       = CodeNone;* P1 L$ C& g# i  `- ~# p
  635.           stage      = StageNone;
    3 T7 G/ W, c, Q+ G9 `

  636. 8 b" \- M. e* V% v$ a
  637.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    & c' Z% m% p  O
  638.           {
    ; s* w9 [7 n# {5 d& c
  639.             txBuffer[txLength] = CodeCan;. O. k) M9 @: ?8 f& ]2 K
  640.           }
    $ W1 c% l- G; g) O# _/ L) V) J
  641. 5 @! w4 ^7 ?! W/ {& l. _
  642.           write(txBuffer, txLength);
    4 t. H3 e) `( m+ C; T1 k
  643.           callback(StatusError, NULL, NULL);
    7 l* t% l' K6 W& E9 G. K
  644.         }
      }) G  i! D- n$ y% b7 {' W# E
  645.         else
    8 f. O; ~2 K8 Z9 s' u: h
  646.         {
    : b+ k, n7 G5 C4 ?- p1 ~3 T& s
  647.           txBuffer[0] = CodeNak;
    ( x1 @8 t2 r( c6 ^
  648.           txLength    = 1;
    . }0 B# _, ]' x6 U# P$ i
  649.           write(txBuffer, txLength);. l5 n* Y7 J, C0 P1 M6 ~3 \
  650.         }8 O3 V  z3 M8 m' g* e
  651.       }
    ! a. H3 F$ `0 Q( O1 l

  652. # m6 b# ?( ]9 U8 W5 q1 m2 k
  653.       break;
    ' F$ `1 O/ X) a7 |
  654.     }
    / n# Z; t! }! _" A
  655. ; h2 f9 Z0 _# S# j! z8 U
  656.     case CodeEot:
    + E  v2 C  A$ @, W
  657.     {) m. A% ]; U' c- V
  658.       timeCount   = 0;
    & ]# C# J0 A- B  v
  659.       errorCount  = 0;' e* q/ L- \4 O3 A7 z9 e$ A
  660.       dataCount   = 0;3 J; m4 U4 C- `2 f; G4 G& }
  661.       code        = CodeNone;
    ) @# ^" [# w0 @# S$ [* {
  662.       stage       = StageFinishing;/ T* L1 e% T7 h
  663.       txBuffer[0] = CodeNak;
    ) Y: @; o+ m) {/ W: J% J4 e
  664.       txLength    = 1;; T) v& T# I( y; c
  665.       write(txBuffer, txLength);
    2 }5 Q8 G% x! P# ?7 C) Z

  666. 3 b: p# p6 B5 E0 R; g( b/ ?
  667.       break;( e3 r% G: S5 P+ B3 V3 V+ D; M
  668.     }4 M, c: N+ t3 k7 }9 r
  669. , G1 `+ R+ ^0 O, i3 B5 n2 t( u+ m1 K
  670.     case CodeA1:
    ! H* h1 H3 l; x) F2 _" {5 k
  671.     case CodeA2:
    0 ~. x' R: m0 ^# n9 J
  672.     case CodeCan:
    ) \* |9 N. d" i  }
  673.     {
    5 u  q. F; B% T) o- Q2 u  C
  674.       timeCount  = 0;/ |: e1 x( D( w
  675.       errorCount = 0;
    * D+ P% e! v7 l/ h0 c1 T# D
  676.       dataCount  = 0;1 b8 z  n1 f# {! V( `
  677.       code       = CodeNone;
    / [( ?% A; S: J( L/ Y& C
  678.       stage      = StageNone;6 F( ]( B$ w7 S% ?/ R( n
  679.       callback(StatusAbort, NULL, NULL);
    ! Y' {- |- ^$ h* L+ X4 E* d) _

  680. 2 X2 l& Q$ v3 L  F
  681.       break;! M% a1 s$ p2 [( Q1 f, d
  682.     }4 ^5 K3 b) v. N- t  e7 \$ x
  683.   f9 N* b: ]# Q; E  w* t
  684.     default:
      K  {4 G# K( V( z8 e6 \, y
  685.     {' o5 K4 J, K! O, F5 P0 a7 \3 h7 M
  686.       timeCount++;" a9 p8 d. ]$ F8 T. m7 B& M
  687. 9 J% F( i! Z2 W& i. Y6 V2 M9 |" d5 j
  688.       if((timeCount / (timeDivide + 1)) > timeMax)
    . u% S: f) P( S. t
  689.       {' r+ Y+ f7 N7 x( y$ [
  690.         timeCount  = 0;
    9 k7 \0 t5 L8 m, m
  691.         errorCount = 0;9 T: J& K& g* C" Z  W6 w: f6 |
  692.         dataCount  = 0;1 W- L$ [* |# t% Y  @1 K& s/ x
  693.         code       = CodeNone;% R- S- }; m4 {( x6 d) o
  694.         stage      = StageNone;7 A( i4 D/ h5 b6 H/ y0 E- b

  695. , J  x4 u; T  Z/ Z
  696.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    , `& M# H0 w" [+ [- `" m7 N# L
  697.         {6 c% t8 V2 T; p0 ]
  698.           txBuffer[txLength] = CodeCan;+ K, G! D* S2 k4 ~5 X$ M
  699.         }
    ; [7 m8 `( h6 y3 @0 Z6 x
  700. ' S) J" {8 g' C# L
  701.         write(txBuffer, txLength);
    6 c$ }7 j7 k* s- S5 s& J  v
  702.         callback(StatusError, NULL, NULL);5 I$ z6 T/ p- X, L1 V1 z
  703.       }
    ( G+ n% w7 o" ^, J, K; {! ~4 g
  704.       else if((timeCount % (timeDivide + 1)) == 0)( {* ^1 ~, z1 ]  |9 T
  705.       {4 S. v5 p, u' u
  706.         txBuffer[0] = CodeNak;. m4 j3 Q) @* ]' v/ `7 M
  707.         txLength    = 1;. E. z( S8 R8 C2 I. c- Q! h
  708.         write(txBuffer, txLength);5 Y1 I6 @: N0 }7 g9 v; r' F
  709.       }
    0 n, o& Q; ?; N1 a  m8 p) ?5 l4 i
  710.     }
    & A2 o9 q" ~- ^5 K( x
  711.   }
    . N- v5 B' G! b+ Q
  712. }* A  w  K, |8 B8 P

  713. * }. u% R; S+ S6 A4 X
  714. /**/ m4 Z! C& @) h* d
  715.   * @brief  Receive transmitting stage.
      x/ q" f: D! F" k; p' s; \
  716.   * @param  None.
    ( v  [- O+ `! c3 p9 Y: @
  717.   * @return None.: Q1 w$ G" K* t# C. c0 B
  718.   */
    & Y; _7 k$ Z  ?* f( b
  719. void Ymodem::receiveStageTransmitting()
    3 W9 s) m5 f. L. a
  720. {: ^, V- z9 x; g$ B: j% S9 s1 \1 ~
  721.   switch(receivePacket())
    $ l; m( ^# @+ {  q
  722.   {5 j" r9 ?9 L8 U" G, W1 k0 t0 [
  723.     case CodeSoh:
    & o: |, k: E- \* e5 a1 G
  724.     {
    ' b& j, x4 L7 ?
  725.       uint16_t crc = ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 2]) << 8) |
    . s9 i1 f# U5 A) C8 C& @  l6 R$ m+ B
  726.                      ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 1]) << 0);0 z! g# b+ d0 U! B4 a; @% h
  727. * |! B: Q3 |, o3 N4 m' G
  728.       if((rxBuffer[1] == (uint8_t)(dataCount)) && (rxBuffer[2] == (uint8_t)(0xFF - dataCount)) &&$ L& Q/ U  z& B( K
  729.          (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_SIZE)))8 S8 U, f" q4 F( M
  730.       {3 |+ [; J/ G# P
  731.         errorCount++;
    - D& t& ~3 n# Y# {$ z
  732. 3 Y1 L- e% `  f) W* t
  733.         if(errorCount > errorMax)9 q' ]% f' `/ R4 n9 {7 s2 T8 b
  734.         {
    9 m) m: L% P$ N& I% H/ x! ^
  735.           timeCount  = 0;
    ) {+ U* n6 @9 X4 z: H6 d
  736.           errorCount = 0;1 ]6 ]* i* @3 R; y/ G
  737.           dataCount  = 0;2 _4 T( i3 ?9 y) w* s7 r& k+ |
  738.           code       = CodeNone;1 G! s" L, n& m% I9 x" U2 A" F$ v
  739.           stage      = StageNone;, ?9 o: p; N# L- O5 Z. }; H8 W

  740. " o$ E5 M+ ]' P" t3 [3 Q+ L2 M
  741.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)% n  m( A$ `' W' O4 Y7 ]
  742.           {; b) L& m, ^2 o" C2 Y
  743.             txBuffer[txLength] = CodeCan;
    , f) `( ?: v7 i6 z' l8 m( a
  744.           }
    # R9 M& _; l( J6 S

  745. $ t6 w9 l  Q$ M+ d' }9 O% K+ B& O
  746.           write(txBuffer, txLength);! p4 T) R$ B) ^$ @! Y
  747.           callback(StatusError, NULL, NULL);* Z$ K' O# R5 C) J3 X
  748.         }8 @3 b/ O3 A! b  r0 ?& e! w7 ^* q! `
  749.         else* N+ ?4 \) j" W/ c
  750.         {+ |) \/ Z; ~, G  W/ b5 B
  751.           txBuffer[0] = CodeAck;
    / x7 U& e3 P! v4 r
  752.           txLength    = 1;
    ( |8 J$ a* _* ]# x4 x
  753.           write(txBuffer, txLength);
    $ U" M3 M0 @) }8 A6 S/ X
  754.         }; ~- \* D  M% A8 g! `7 }
  755.       }; H+ X$ T% w' ?( A5 }$ l: g
  756.       else if((rxBuffer[1] == (uint8_t)(dataCount + 1)) && (rxBuffer[2] == (uint8_t)(0xFE - dataCount)) &&# ?" G1 a! i- u9 U
  757.               (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_SIZE)))3 n8 M7 e3 K, f. y. d
  758.       {
    , }) H- e6 ?. M6 @% {
  759.         uint32_t dataLength = YMODEM_PACKET_SIZE;
    3 U) P3 ]+ I" k) C( O* _& |

  760. 5 w  y) L! {9 }5 f: [# y
  761.         if(callback(StatusTransmit, &(rxBuffer[YMODEM_PACKET_HEADER]), &dataLength) == CodeAck)
    " X2 _- J9 ?9 ^; ?9 q4 A  V* R
  762.         {
    . B' Z9 b& X3 w* y
  763.           timeCount   = 0;4 [2 b' k+ j6 n& J2 a
  764.           errorCount  = 0;
    ; V( M$ j4 }) G1 f- Y( ]" S6 X. }
  765.           dataCount   = dataCount + 1;, P% d  ?, h6 m. w
  766.           code        = CodeNone;
      `' l0 Q) \% _' P
  767.           stage       = StageTransmitting;
    * Y+ m9 M3 C6 C6 G9 z0 I
  768.           txBuffer[0] = CodeAck;
    3 A" |6 H+ L& i1 F7 U' v: I3 a
  769.           txLength    = 1;6 ]: P, y6 w: M; c4 h+ `
  770.           write(txBuffer, txLength);% G- k% O' K9 E$ q9 o
  771.         }) N, V6 A" G7 y4 }
  772.         else" E* C- G% B/ U! ^. B
  773.         {
    * v, R6 `# O9 V  C+ D' m# d
  774.           timeCount  = 0;
    * A8 \( r. g' T+ ^
  775.           errorCount = 0;0 J. |* F, p% Z% w: D
  776.           dataCount  = 0;3 r  Q0 G! o' H. S1 D) g
  777.           code       = CodeNone;
    ! y1 x& t/ ^" N4 L
  778.           stage      = StageNone;
    - y& W! }2 K) p
  779. 4 e7 O/ _. y2 f& B: B. |3 W
  780.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    7 P3 d8 ^, q( k$ m
  781.           {! d3 Q2 b% o1 Q( |) a3 X6 K2 n1 {
  782.             txBuffer[txLength] = CodeCan;
    * u/ Y4 l4 s% a% b: B: N  f/ Y  r
  783.           }# ]# N3 r& K9 T4 P% R/ s$ X
  784. / y/ A4 |. R) K, I
  785.           write(txBuffer, txLength);
    6 E% N9 J4 C, r6 e
  786.         }
    5 v+ F8 |- A" C8 \& E/ @
  787.       }
    4 @9 l/ c, @4 O, }
  788.       else9 P$ M) z5 \& n
  789.       {
    ) r/ R  A7 Y4 s8 t6 I# m' _* ?
  790.         errorCount++;
    1 @2 M8 s% x2 ~
  791. " i* r, S5 u) l
  792.         if(errorCount > errorMax)$ h- E" N$ j9 _+ T( g2 z$ M
  793.         {
    , |& p, d/ |0 R" H, y; ]) Z
  794.           timeCount  = 0;
    4 S2 W. ~/ Z- c! G, k7 m- J
  795.           errorCount = 0;+ P8 Z+ X  o6 `% h( Y4 i
  796.           dataCount  = 0;
    " M& A5 t+ B- i/ ~
  797.           code       = CodeNone;
    ( d! e* V( h. D# O- S
  798.           stage      = StageNone;
    + ?: K4 ~' l" F* S2 w
  799. 1 s; e4 V! T$ `$ |6 U9 x5 H2 J1 \/ ?
  800.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)/ _7 L' L/ h; U( {/ X
  801.           {
    * g5 \- O# \4 L8 n0 P
  802.             txBuffer[txLength] = CodeCan;5 B0 V: Y. W  R& P
  803.           }
    " a. v+ x  T0 D" b

  804. * O( j3 t! I4 |; ?8 G) }
  805.           write(txBuffer, txLength);. k  o& S1 Y& o6 G/ R; X
  806.           callback(StatusError, NULL, NULL);
    + V* c# v; }4 i; L1 X, A0 [
  807.         }+ i% y+ u2 Q7 `
  808.         else
    0 t4 K1 V6 a+ o6 @2 E( z) e. ?) x
  809.         {
    6 b+ P: e. K! [( R  w% S
  810.           txBuffer[0] = CodeNak;
    3 n, W5 g7 r2 _- o# G2 S0 M  ?' `
  811.           txLength    = 1;- E2 k' m0 O2 Z0 K  m3 i# K
  812.           write(txBuffer, txLength);
    " |# A# T4 T7 S) o6 _
  813.         }8 i/ x& ]9 _( n' T
  814.       }; a' }6 u  |5 R

  815. ! J! Y* ]* G3 o' C
  816.       break;
    3 i8 h1 ?& M. x
  817.     }7 h" _& W, T- w  h
  818. " G8 X- b/ S2 K) P& x8 f9 v5 p  ~; |
  819.     case CodeStx:
    . Q3 b  Z' R4 T7 x
  820.     {
    , k- p3 e  V3 q" Z
  821.       uint16_t crc = ((uint16_t)(rxBuffer[YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - 2]) << 8) |, l; y8 T9 _  z  S
  822.                      ((uint16_t)(rxBuffer[YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - 1]) << 0);7 v& y6 |6 a, j# ]5 |

  823. ; I% T0 t. U/ z0 i6 W: r. W
  824.       if((rxBuffer[1] == (uint8_t)(dataCount)) && (rxBuffer[2] == (uint8_t)(0xFF - dataCount)) &&3 ]# c9 F2 z" W1 M" i; ?3 h
  825.          (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_1K_SIZE)))
    - K" z: f+ X( l/ l
  826.       {/ Y9 _7 O/ \1 o" N' `8 |- J% z" A
  827.         errorCount++;
    7 d$ h" f) B8 t

  828. ( A7 i6 k6 V/ |
  829.         if(errorCount > errorMax)& W# |: ^% {" J/ ^" a4 B& M
  830.         {
    $ y' Y2 G$ M$ S( j9 m
  831.           timeCount  = 0;$ ~, Y7 n1 \% O5 `8 o/ E+ f
  832.           errorCount = 0;
    * }+ o% h9 x2 Q% w
  833.           dataCount  = 0;
    ! @- q% v" C6 q
  834.           code       = CodeNone;. G( l' e: p+ ~! A/ _
  835.           stage      = StageNone;
    ; _2 I2 J6 T: x+ b! i  @5 u
  836. 2 Y9 i: P* D6 v* `- J/ A
  837.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)& X1 B/ s+ ?$ H& u
  838.           {
      k% I3 S2 i" V" o0 |
  839.             txBuffer[txLength] = CodeCan;5 O9 h* Y* R; H) x
  840.           }7 u/ [4 t" v# z% |  {# T9 H, b
  841. 2 [# H* f% A. y6 d! I* F8 s
  842.           write(txBuffer, txLength);; ?( c! N. E$ A# j
  843.           callback(StatusError, NULL, NULL);
    ) J  }1 u4 h! K+ H* O( c
  844.         }
    # d6 Q& c; @0 O2 K0 i2 U
  845.         else7 e) T1 a& G& t4 U  ^9 g& _
  846.         {
    - t) O. }* S# D) `
  847.           txBuffer[0] = CodeAck;3 Z5 d, r) h) s6 ^* d- o) z9 A
  848.           txLength    = 1;5 _) e% [6 t% P: s4 ^9 Q+ u
  849.           write(txBuffer, txLength);
    + K- {' v3 I  w, s: {* ~- [6 Y
  850.         }) z% F, B, J, a; I' G7 Z
  851.       }
    . i5 H/ w1 L& W' D
  852.       else if((rxBuffer[1] == (uint8_t)(dataCount + 1)) && (rxBuffer[2] == (uint8_t)(0xFE - dataCount)) &&3 J. e3 W' P5 b8 z9 A
  853.               (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_1K_SIZE)))
    ! y  `5 N* k  R9 |  ?! D* }; D
  854.       {
    - S% W; c* g) S3 O
  855.         uint32_t dataLength = YMODEM_PACKET_1K_SIZE;' j. s3 J7 E1 z: Q, p1 j; z$ J* C

  856. ( k  F  r  O' a% L
  857.         if(callback(StatusTransmit, &(rxBuffer[YMODEM_PACKET_HEADER]), &dataLength) == CodeAck)1 M3 D1 T' ~! I' }4 T2 Y
  858.         {
    8 h' J8 f7 A" N7 b
  859.           timeCount   = 0;0 J: f" {$ F6 O" g3 \2 c5 n
  860.           errorCount  = 0;
    0 u, P! C  z1 f0 z% T
  861.           dataCount   = dataCount + 1;
    + t- B7 ]! \: C  G
  862.           code        = CodeNone;. B- w7 m8 F( |" c- J! h( [) m
  863.           stage       = StageTransmitting;
    6 `' W3 }& ]' o* T
  864.           txBuffer[0] = CodeAck;$ g7 l0 k3 v$ F! Z/ g2 W" T, |
  865.           txLength    = 1;# w6 x, s# ?3 Y' K. W) K* j
  866.           write(txBuffer, txLength);  g- D' `% d0 u  X- T9 r
  867.         }' D3 l9 ^4 J9 g7 M  ~
  868.         else
    7 n; n/ B! q0 O4 e  _" S
  869.         {
    & `0 U: M  I$ [* z; V
  870.           timeCount  = 0;
    - f, z8 g$ y! D/ t& C  ]
  871.           errorCount = 0;
    7 d2 T( ]4 f& A- s
  872.           dataCount  = 0;, f4 q3 V, V! S7 O7 [. n- [* ~: G
  873.           code       = CodeNone;' ?) N+ ]* T. x
  874.           stage      = StageNone;
    2 A# U. T* |& B4 l+ d
  875. , c, o# a$ q7 P" ~
  876.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    1 z; l$ _9 O( b) h" ~
  877.           {
    4 y5 y2 j% [6 g' m; D0 e
  878.             txBuffer[txLength] = CodeCan;( a, _2 t1 k$ B( r( F9 }5 }; B
  879.           }
    " n. Z0 z( \% B( ~+ m8 ^8 h

  880. 3 R/ ?3 |4 |* p3 g8 M& F% h: L: q
  881.           write(txBuffer, txLength);
    7 k* W  H+ L8 P
  882.         }+ g0 y* I! e& S- U
  883.       }
    & n0 ?) z! e; ~, f; _
  884.       else& n( t( [% W3 ], i( ?
  885.       {" @$ l+ U* n2 B# @" C* V1 C
  886.         errorCount++;
    & \1 q/ r8 n7 z1 L: i2 [

  887. 0 U, r& Q/ y2 s& s! G7 c; I: R( z
  888.         if(errorCount > errorMax)
    / I  Z, L5 z  n. w
  889.         {2 ?9 p; @. r" t% d2 N/ O! u3 ?- c
  890.           timeCount  = 0;
    & r5 s+ [. Z, c) @
  891.           errorCount = 0;7 z- m  h  `0 }9 ^; s5 s
  892.           dataCount  = 0;9 X( B  A% i: C+ h* b" i
  893.           code       = CodeNone;& `: U+ j2 W; D: k4 X/ {; \
  894.           stage      = StageNone;
    , m  _5 N0 D6 _/ k

  895. 5 H- w! r  t6 y1 e% x; u& P7 b7 g
  896.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    # i+ [, I/ Z1 j0 f
  897.           {5 l5 N3 c" B, ^" U- t! [
  898.             txBuffer[txLength] = CodeCan;) S, ~* o$ R) o7 S+ X' {
  899.           }
    ' U7 u7 t6 j! u$ v9 B
  900. 5 K% K( b, T2 z1 t7 s
  901.           write(txBuffer, txLength);
    2 }; ?) J, S! i) B" v. C
  902.           callback(StatusError, NULL, NULL);/ s: M4 q2 T. j, a. K8 {5 T
  903.         }
    # T, a3 w) a# S. }
  904.         else
    + M$ w9 ~$ i) G; \& m
  905.         {
    ( e- |+ o1 N! N8 E% h. ^
  906.           txBuffer[0] = CodeNak;
    # {( G3 B5 V; Y0 E  `3 Z8 C! k
  907.           txLength    = 1;
    3 z2 ]1 C: t( w/ k1 }" v, d
  908.           write(txBuffer, txLength);
    , U* T- ~5 ~. d* E# U- V) T
  909.         }
    7 N8 |$ ]5 M5 H& S* X3 s. U- n- G
  910.       }
    : k6 `9 T; T# H# L2 m- R- d, Q. A

  911. ; K# ?0 d5 N7 m
  912.       break;/ a1 O4 T& h* i7 A! r- V- \: W/ {
  913.     }& I( z/ R- y  `3 y
  914. ! `. F0 m  L5 V2 _9 R
  915.     case CodeEot:
    ; S! F: B% H7 R$ Q
  916.     {/ M7 e% J" i5 r# Y. r9 A% \" n2 J
  917.       timeCount   = 0;
    % U$ R5 R5 d  @* \: ]
  918.       errorCount  = 0;
    8 g6 H: H/ T4 z
  919.       dataCount   = 0;! n, Y3 d0 n; s7 V- W5 M; |5 B! `
  920.       code        = CodeNone;
    9 y$ Z  J4 x2 v: C0 ]! c) n% v
  921.       stage       = StageFinishing;3 H/ L/ p1 G6 o8 X$ H, c
  922.       txBuffer[0] = CodeNak;/ x$ J) M9 P; o( `
  923.       txLength    = 1;
    5 E* M8 }+ z. k/ ]3 ^' M8 w
  924.       write(txBuffer, txLength);2 i& [! i1 C. H  Y9 Z, |  B

  925. 2 z& ?& x9 B( ~# [6 K3 y
  926.       break;4 s" o% q3 P5 Z. C3 T& u
  927.     }0 v1 c7 b' v# i3 A- e) j) y
  928. # n5 O8 z! {. @
  929.     case CodeA1:
    8 M0 w: e4 Z  s2 X/ }7 v% @* }$ o
  930.     case CodeA2:% b! F# I  Y0 r
  931.     case CodeCan:  l5 D$ _  |) a% H  `9 m& X. c
  932.     {
    # a$ S# H2 D; |
  933.       timeCount  = 0;7 M9 f, g* `: P" W& U1 R0 M9 v
  934.       errorCount = 0;
    : V+ U* g: k$ w1 ^8 P
  935.       dataCount  = 0;
    ' l7 o1 a6 g4 O4 ~
  936.       code       = CodeNone;& V9 r) r- q. q0 d7 y
  937.       stage      = StageNone;5 p! ~- v% b5 ?  S8 f. Q
  938.       callback(StatusAbort, NULL, NULL);
    + ^- Z/ \& b, Q* }! v

  939. 6 p1 }3 K6 y8 E3 x9 a2 c
  940.       break;
    0 W1 M& X* M* w' F: E
  941.     }" `; M0 m. g2 l: ]
  942. & i) b% Z) d6 ^9 C! {( w1 {7 ?) ]  g
  943.     default:  R. ]( v. T% {% H: `% z% R
  944.     {
    & V  W2 C# n& G+ k
  945.       timeCount++;
    3 c. S( j# m) Q  }8 }
  946. 3 _! o& `# w% y* e0 `5 R) `; [7 D% K+ B
  947.       if((timeCount / (timeDivide + 1)) > timeMax)
    4 n! U( ]* q0 I0 J  Z
  948.       {
    / d" b  @' V9 e
  949.         timeCount  = 0;: o: |' z0 B* m
  950.         errorCount = 0;9 c; j! J' x8 O% b/ h0 x
  951.         dataCount  = 0;' Z6 E, j) F; @( L% R
  952.         code       = CodeNone;" u0 U7 k# d* R
  953.         stage      = StageNone;
    & u' c; y+ L3 s+ S. p. {7 @

  954. % }, @3 b, U) V2 j: x' j6 i
  955.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    3 u) p9 |0 Y0 w4 G& T0 Q7 a$ k3 }
  956.         {* d. \) P9 [) C* o2 M
  957.           txBuffer[txLength] = CodeCan;/ N9 ]$ f$ ]0 ^: b# j+ D
  958.         }
    ! x- o7 b0 v% h" I, ]
  959. $ y9 X+ l) z2 Q' M# S! X
  960.         write(txBuffer, txLength);7 F" P1 ~. j2 S
  961.         callback(StatusError, NULL, NULL);% s. g* t& D& H% M3 @
  962.       }
      G9 s' I8 \& F' x  E5 P" s" ?
  963.       else if((timeCount % (timeDivide + 1)) == 0)
    + g9 s9 h3 s! T% o8 l4 W$ ?
  964.       {
    % @, \6 J# O9 _
  965.         txBuffer[0] = CodeNak;
    / Q5 O) v- j% j2 \9 w
  966.         txLength    = 1;
    # s( {& }0 r; g5 k
  967.         write(txBuffer, txLength);
    ' E8 y3 t$ n/ B" ?% S- _
  968.       }
    4 L( I0 |' ?& U4 n, A
  969.     }: C: V; I6 h( z9 [6 W* B7 N# \3 F7 ~& u
  970.   }0 i* d, H. d8 V& ~
  971. }5 T5 x0 g1 f* S0 z; E! G% y
  972. ; ?6 [3 X) s3 Y* l
  973. /**
    ; U; u3 V3 R5 \' m7 h, [
  974.   * @brief  Receive finishing stage.8 G4 _0 k7 u1 @; V* k5 o" j6 S3 b
  975.   * @param  None.
    # U  G/ k* B+ c" K' ^7 K* w
  976.   * @return None.
    2 c9 v1 D" f) y8 m/ ?
  977.   */% d! T- h0 i3 D: c0 K5 a, D
  978. void Ymodem::receiveStageFinishing()
    % H' \* ^$ U/ n  Z
  979. {8 Q+ U! T) K0 n
  980.   switch(receivePacket())
    ; m. S. r/ V1 f/ G5 `1 M8 Z
  981.   {
    ; F* z1 w0 @: L* b$ `
  982.     case CodeEot:
    % z3 H1 B" e; a2 O
  983.     {1 \6 U2 a3 t2 b' c, S
  984.       timeCount   = 0;' g- R+ m4 Z+ b* c& ]5 {! ^: y' k) C
  985.       errorCount  = 0;
    7 F- E# N+ K" B( x  ?* b
  986.       dataCount   = 0;$ c5 b. A8 {- R( \3 [7 Q+ T+ `- H
  987.       code        = CodeNone;
    . S, I2 n$ U. Z, z9 [; y
  988.       stage       = StageFinished;
    ! z% q$ |) p8 ?1 L: W
  989.       txBuffer[0] = CodeAck;
    " e% q- @( L9 J: p9 l( `
  990.       txBuffer[1] = CodeC;+ j" c& |6 f4 N$ }+ }
  991.       txLength    = 2;+ F1 R% |# `9 E* g
  992.       write(txBuffer, txLength);
    ! r1 O. Q6 J/ l* B/ l
  993. " H( U+ l4 U7 R2 c- s4 F, g
  994.       break;
    $ }( m6 L2 \; Q
  995.     }
    $ w( b7 W& Q) B/ _: K$ a# e
  996. & v* }& Z3 u7 _* i
  997.     case CodeA1:
    2 K5 d! s# x- A+ `
  998.     case CodeA2:1 i2 P6 ]& n$ t% f( T- a6 R! E# c
  999.     case CodeCan:
    ( P9 J) s6 j% E- _* j, H
  1000.     {/ [" q3 i; B0 V2 H2 G: G' |
  1001.       timeCount  = 0;
      n0 A) v* A3 B& B9 c# s9 U
  1002.       errorCount = 0;" o9 \3 z+ ]5 Y- G/ P
  1003.       dataCount  = 0;
    0 i3 U0 _3 e4 n
  1004.       code       = CodeNone;
    % [+ O) d9 L4 m0 H' b
  1005.       stage      = StageNone;1 C$ `, }* _0 ~+ e/ r4 [
  1006.       callback(StatusAbort, NULL, NULL);
    & i. O' k& K6 u# z+ w* D

  1007. 4 z2 [) p9 n# j: H% s  }
  1008.       break;( m8 A  k% ]0 p+ z
  1009.     }
    7 }% _( ^# \" E! h

  1010. " _8 A# b: J  `
  1011.     default:
    $ L. u4 F' f5 a* j' {& S% w, n" n
  1012.     {
    7 w8 H3 G, h9 R( j  F. a
  1013.       timeCount++;
    + L0 E3 A* g9 b3 z  m

  1014. / P) m& W, H' {% J: B
  1015.       if((timeCount / (timeDivide + 1)) > timeMax)
    5 G# ^0 c( N- e" w
  1016.       {
    6 c% p1 g$ v2 D# f( e7 z% ~
  1017.         timeCount  = 0;
    6 b7 V$ K; ?% I& z1 ~; y
  1018.         errorCount = 0;1 c" X' q! _+ Y+ r8 N2 S
  1019.         dataCount  = 0;: Y0 c' b; {1 w" N
  1020.         code       = CodeNone;
    ' J  {9 q: H: w; \+ a
  1021.         stage      = StageNone;
    0 _+ Y  q6 I0 I! k# l5 q; Z8 d

  1022. : Z! I; v' j5 d* n4 j
  1023.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    ( q3 Z  l: _( N& e! c
  1024.         {; I; h2 f! p: }8 ?+ l
  1025.           txBuffer[txLength] = CodeCan;' }: N5 k" U! u9 q) B  m7 p! Q# ]0 K
  1026.         }
    4 f7 R' d2 |; I. o6 y' X% q
  1027. ( S1 O& F% \& M# l$ `
  1028.         write(txBuffer, txLength);
    - l" D  F: u! K- W; G% P: M  Y% D4 l( |
  1029.         callback(StatusError, NULL, NULL);6 j' }& G2 ^0 p0 I" ?2 o, p! g
  1030.       }
    8 X  U* Z# ]  C# o" E. t
  1031.       else if((timeCount % (timeDivide + 1)) == 0)
    ) X8 y2 x- J( |7 p6 G, X
  1032.       {
    % Z1 S; I& V4 |& Q6 D: q, |
  1033.         txBuffer[0] = CodeNak;
    ' e# ^' L, C: n5 j
  1034.         txLength    = 1;6 j3 i9 @% A( ?; U* U
  1035.         write(txBuffer, txLength);; ?0 f- Y& \. Y. u5 u6 b& J0 G
  1036.       }
    2 K4 @' x2 B& K6 q, m$ L' m( k
  1037.     }
    / u" t: S5 r6 c0 q
  1038.   }7 A  b% t# x; y
  1039. }
    9 e) W* @% B. a8 e6 ?

  1040. ! J: N( X5 y# x) m9 L
  1041. /**: r* V3 n! z7 N5 Q
  1042.   * @brief  Receive finished stage.
    0 p& m4 T5 l( N4 [7 w' |/ _
  1043.   * @param  None.9 h* Y) ~" u5 S' v4 I: T" ~1 |. o
  1044.   * @return None.- t) L5 O6 }1 f% m
  1045.   */& d- f% \! Q& v2 O) n. z2 `! A( q8 x
  1046. void Ymodem::receiveStageFinished()
    5 u  C5 |: M# v
  1047. {) ?7 K  B. K- q+ v' I
  1048.   switch(receivePacket())
    $ D7 }6 V8 R; L1 U( z% I1 E9 p
  1049.   {2 ~- `% D6 `. @0 K2 y& s
  1050.     case CodeSoh:$ f  w8 F8 `- ~& F
  1051.     {1 n1 B7 N) c0 A' @! E# C% D" @5 r
  1052.       uint16_t crc = ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 2]) << 8) |7 X0 y, \7 e0 ^: U7 S7 S
  1053.                      ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 1]) << 0);! }2 r6 ]: a( s5 j3 C

  1054. , D' y% R# a% z6 ?4 Y! J: |1 o
  1055.       if((rxBuffer[1] == 0x00) && (rxBuffer[2] == 0xFF) &&
    ! N  s3 r/ ^& `+ x; r+ ^
  1056.          (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_SIZE)))
    % r4 v1 [: `4 n5 t: l( {
  1057.       {
    2 b: L  R! T8 `$ |0 |9 _& C" e
  1058.         timeCount   = 0;
    9 s( b! d5 \  j  b9 l
  1059.         errorCount  = 0;
    2 j/ i( B. x$ `* }! N4 ?% D
  1060.         dataCount   = 0;
    0 L2 I& D8 s) ~% Y* E6 i/ w4 k
  1061.         code        = CodeNone;: u9 ]8 c/ t; p6 z% q- A
  1062.         stage       = StageNone;) e$ y9 ?- y; P: `9 a5 j
  1063.         txBuffer[0] = CodeAck;. O9 v3 F+ M' b( N' H
  1064.         txLength    = 1;2 ^( x. q; y9 O/ u) B! T; j" l+ f$ R: i
  1065.         write(txBuffer, txLength);! q4 v  b/ y% M0 `
  1066.         callback(StatusFinish, NULL, NULL);" t/ t3 A+ x7 v2 J/ i
  1067.       }, @/ I0 k: c- ~! n2 y5 }
  1068.       else
    " G7 h/ M" h2 H' w! I; s
  1069.       {
    * m4 L9 [6 o2 Y, i& ?; V
  1070.         errorCount++;
    % p: J5 Y3 n: K2 x

  1071. % m: O$ y6 w' [0 }, m7 D
  1072.         if(errorCount > errorMax): h4 ~' y4 a! N0 E8 L8 E
  1073.         {
    4 d& U# y8 A  M( c0 `$ ~
  1074.           timeCount  = 0;
    ( Q* S  j8 l8 d) M7 `
  1075.           errorCount = 0;) `7 o0 S  I# }, Z/ x" O& q% {% q
  1076.           dataCount  = 0;
    & W0 U& B  S8 F
  1077.           code       = CodeNone;4 ]( ~$ q8 |7 s& @7 C% q% M
  1078.           stage      = StageNone;
    ; W/ [' S$ D- v2 H

  1079. & v) U8 |% G7 X8 d6 x& \
  1080.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    ) g" J6 Q7 D! s* g) W1 V, J" i" n
  1081.           {
    2 u: N: ~$ B5 R% u/ ]2 q9 I6 }* L
  1082.             txBuffer[txLength] = CodeCan;/ h0 _4 B9 |' _) R; H' U
  1083.           }0 ^, W4 p+ d# j" E
  1084. + ?& H1 E2 N. h7 C: W( j% |
  1085.           write(txBuffer, txLength);6 T/ t% v$ s8 i
  1086.           callback(StatusError, NULL, NULL);
    ! S$ z( G% f% W' F0 M
  1087.         }
    " n& V  V, e" D8 T
  1088.         else8 a' C: I2 L" w
  1089.         {
    1 z& l# S3 k% _" G9 d* T3 ^3 Y0 t9 x
  1090.           txBuffer[0] = CodeNak;
    8 s( f0 U! r6 p$ n: f( k
  1091.           txLength    = 1;0 L) E1 K; N. W8 u& I
  1092.           write(txBuffer, txLength);
    % J* C2 _) `. m
  1093.         }5 _: @) F& Z; s. e( K
  1094.       }1 |$ Y2 f' L2 q0 D. k

  1095. ' l$ Z2 E, H+ C8 w% J" w6 V
  1096.       break;
    . V) h$ s3 a* k- a
  1097.     }* z1 b  v% M" d2 C  d1 e

  1098. % o( ~. W4 W4 X; ~& J0 K2 y
  1099.     case CodeEot:
    ( }+ _# R. a, ^/ v9 E! R
  1100.     {
    # r, p% J& U3 W0 {
  1101.       errorCount++;
    6 ?! h' E+ E: r

  1102. + [0 W/ }# h/ E3 M+ A5 |
  1103.       if(errorCount > errorMax)
    7 m( }" x, @6 Q  F% G
  1104.       {$ |$ j8 o6 K: `, g# G
  1105.         timeCount  = 0;2 t. ]. f& z7 G/ A
  1106.         errorCount = 0;4 K5 P5 p: Z8 Q( t8 @
  1107.         dataCount  = 0;
    2 K: ~) g' N7 Q4 l$ T
  1108.         code       = CodeNone;
    ) U' {0 W) O3 ?$ z0 [+ _5 V3 E
  1109.         stage      = StageNone;  W) Y( b# q( B5 y8 O' m, ~
  1110. 9 D6 P) ^; ^- i% @4 y9 c3 K3 a- y
  1111.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)" E. `8 n( U& i
  1112.         {5 ]' Q9 v- w# u, d5 A$ T8 I
  1113.           txBuffer[txLength] = CodeCan;
    2 [2 ]3 u2 x, {$ y/ J7 }% r3 j
  1114.         }
    1 r' E# k# B, Z4 g5 [# F  V
  1115. ! m. L3 s/ N. B/ ?, p6 m
  1116.         write(txBuffer, txLength);) k3 E" h7 h! v% y+ F5 H! @8 q
  1117.         callback(StatusError, NULL, NULL);
    3 B1 v2 Y. v& q  w3 t0 ?+ W. M
  1118.       }
    ) h+ w, T2 G, K6 b
  1119.       else
    $ I$ l0 d8 b3 ]/ Y5 u" _3 M5 e
  1120.       {! p" q: d, t# X! a) q
  1121.         txBuffer[0] = CodeAck;" q: D* ^: J; R- C" T
  1122.         txBuffer[1] = CodeC;
    6 W1 v6 o- O  \7 l' _
  1123.         txLength    = 2;7 F1 ?9 \* s5 O! U
  1124.         write(txBuffer, txLength);
    # @: ]6 G9 f8 h/ H
  1125.       }0 C7 D, S% |5 K# b8 H) a

  1126. ; Y* }! U+ X8 k0 B' n% R
  1127.       break;
      Z, a$ S* k* A$ |! c2 H
  1128.     }* K9 p& o7 c: j# T* S5 g2 t
  1129. + A/ ^$ P* k# B5 T' Y4 ^. A; p: l
  1130.     case CodeA1:
    : t; F5 r" w) R3 m& ?. a  I9 ^
  1131.     case CodeA2:. l; J  J5 u" k% k- c3 g, k: ~2 L6 n
  1132.     case CodeCan:% l: v1 f) F$ D7 _
  1133.     {' m# i" _' e( ]: k. t
  1134.       timeCount  = 0;- @. z* q) x) |6 d( Y
  1135.       errorCount = 0;" O9 g4 n( \8 M9 z2 L+ f
  1136.       dataCount  = 0;
    + x+ L2 R% O1 P4 D
  1137.       code       = CodeNone;
    5 V! Y! n3 M! _- L( r4 l& O! ]7 Q# z# L
  1138.       stage      = StageNone;  ?$ ~" k/ {. {8 ?1 d5 E- h
  1139.       callback(StatusAbort, NULL, NULL);
    2 O% T& g6 h9 y  ]0 x) n9 ]
  1140. 6 f! I% p3 T. \6 A0 f
  1141.       break;$ N3 a# A$ @! A2 F
  1142.     }. K. i: Z+ N$ m5 R* [, J% [
  1143. + i/ c8 }& @4 ~) P
  1144.     default:
    # ]2 a# J5 J8 ]$ N3 p* x
  1145.     {
    " M4 c& @3 Q( Y3 G# M. o8 Q% L
  1146.       timeCount++;
    2 e5 N' Y3 N% n% G

  1147.   ~0 |$ Z. c6 Y% }  a0 L
  1148.       if((timeCount / (timeDivide + 1)) > timeMax)1 X% R5 |2 A9 {* y# S
  1149.       {
    0 b/ f* U7 a3 ^8 I0 d' g
  1150.         timeCount  = 0;
    - t. Y# V, R8 W
  1151.         errorCount = 0;
    & Z% |( M% D, X% I; V
  1152.         dataCount  = 0;' M1 r$ {1 x6 k& {1 J: K
  1153.         code       = CodeNone;9 ^; [9 y& a6 q
  1154.         stage      = StageNone;) _2 {- B7 u5 H; j: Z% y6 O
  1155. 8 i9 A# P% P' N0 `
  1156.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    $ l/ C1 A( M2 }' j" X! k; t7 p
  1157.         {" X5 |. w- R1 {* q/ R
  1158.           txBuffer[txLength] = CodeCan;$ \, h5 Y/ i5 X/ }
  1159.         }
    - B% @+ j, j4 h% G. U( \: a
  1160. . _% m! X! Y; j& k! p
  1161.         write(txBuffer, txLength);
    . l+ x, m8 ~- \/ ~3 e( r6 L- P
  1162.         callback(StatusError, NULL, NULL);$ Q8 R. ]( D" b: z# y; z
  1163.       }4 F! q5 z. D0 v
  1164.       else if((timeCount % (timeDivide + 1)) == 0)
    : M( i( n: M2 z% a+ m
  1165.       {5 I$ {9 t& T8 V/ s
  1166.         txBuffer[0] = CodeNak;0 U2 b  O$ J( F8 w
  1167.         txLength    = 1;
    2 N  R9 e& r! x% U
  1168.         write(txBuffer, txLength);& a/ J3 w9 J: R: t7 b2 ]" O4 Z6 j; @
  1169.       }
    6 H7 l3 t) h3 p2 r
  1170.     }
    % I, P" ^8 H! ~9 ^$ B) W, w
  1171.   }$ O( O4 P5 I, _# z' @4 @* h
  1172. }
    , s6 k3 q' o0 M. V3 N$ r# x
  1173. 2 O) {" d, I: p) a$ I- q3 I# f
  1174. /**
    " u. d9 m9 v: l" i
  1175.   * @brief  Transmit none stage.
    % N$ U3 y( I, P6 ^+ j' z/ S, M
  1176.   * @param  None.+ Z. s! n4 r! u+ O, U
  1177.   * @return None.8 A$ {6 \6 ^8 \6 q
  1178.   */
    4 Y0 B8 C2 N' |/ F
  1179. void Ymodem::transmitStageNone()
    $ K& b: F1 @& x2 T, H  m  `
  1180. {$ }& d. M% U% [* [: u- Z. l; Y: o, G+ Q
  1181.   timeCount   = 0;: w. M9 S" @3 j9 P/ y& T
  1182.   errorCount  = 0;$ K5 F' P& c/ e$ T% Q
  1183.   dataCount   = 0;
    & U/ P. Z. y% |1 K) a3 r
  1184.   code        = CodeNone;7 r& {4 _4 K- x6 ?
  1185.   stage       = StageEstablishing;' u8 E! |, N/ f/ V2 t5 b. t8 y% P3 x
  1186. }
    9 w3 d4 i2 V- h- g% A

  1187. : ]+ K3 ^8 |- I" ?: q3 ?
  1188. /**- C9 ^( z* q6 |
  1189.   * @brief  Transmit establishing stage.
    . P8 A$ R0 ?+ u' O
  1190.   * @param  None.  \2 K2 E" N( P1 }9 F1 E% s
  1191.   * @return None.2 C' \8 ?# P6 N5 \2 }8 [9 m
  1192.   */
    ( I4 O) T! i6 \' Y1 ~& d8 {9 m
  1193. void Ymodem::transmitStageEstablishing()
    2 l5 _; N% Z* x9 J4 l8 N
  1194. {
    ( l3 P7 K9 L& o% [) q
  1195.   switch(receivePacket())
    ; [1 z3 a& O  b0 F9 D: W! ^
  1196.   {
    " _+ g& j7 N: t/ J4 o! {
  1197.     case CodeC:) {/ \' _( R0 p& m. Z$ E' t) z+ V: O
  1198.     {
    - u1 m  l$ x1 b+ H6 x* z
  1199.       memset(&(txBuffer[YMODEM_PACKET_HEADER]), NULL, YMODEM_PACKET_SIZE);  u4 P" d; k6 i

  1200. : Z8 v4 |& \+ Q6 Y8 Y
  1201.       if(callback(StatusEstablish, &(txBuffer[YMODEM_PACKET_HEADER]), &(txLength)) == CodeAck)0 M6 u3 s; Q0 Q9 T" R  q) r& K3 s
  1202.       {
    - A( M+ I0 c. A9 W
  1203.         uint16_t crc = crc16(&(txBuffer[YMODEM_PACKET_HEADER]), txLength);
    0 g: Y- Y1 f0 p1 \

  1204. ; p% R3 Y7 k: f4 _: @: X& l$ ?: f
  1205.         timeCount                                       = 0;1 l0 v% Q" S5 k* [6 p
  1206.         errorCount                                      = 0;
    , u6 {; X! o8 F9 C0 {4 S& ]+ x
  1207.         dataCount                                       = 0;
    1 ~- k7 R0 j) r" x
  1208.         code                                            = CodeNone;
    3 @; k1 k& Q  t3 n1 B6 T# z
  1209.         stage                                           = StageEstablished;
    1 [. h" A$ q* \. B: A+ N: Q
  1210.         txBuffer[0]                                     = CodeSoh;3 e1 x4 r0 W( Q+ U
  1211.         txBuffer[1]                                     = 0x00;; W; t/ \) p3 c( {! z4 z, X
  1212.         txBuffer[2]                                     = 0xFF;* Y% V1 T/ I: l( m& t" U$ B" W: ]$ Q
  1213.         txBuffer[txLength + YMODEM_PACKET_OVERHEAD - 2] = (uint8_t)(crc >> 8);
    # U3 n, }8 i: d0 N* }" u" L- u  M6 A
  1214.         txBuffer[txLength + YMODEM_PACKET_OVERHEAD - 1] = (uint8_t)(crc >> 0);1 _& a6 M6 p8 h+ k% j$ y
  1215.         txLength                                        = txLength + YMODEM_PACKET_OVERHEAD;
    4 S- J7 ~3 p5 W4 ]
  1216.         write(txBuffer, txLength);
    8 D9 [1 R, g6 d
  1217.       }; [$ q9 H! U& m  H+ }
  1218.       else' A$ P8 g7 z; H
  1219.       {
    7 i6 l- S3 U* E" Z# J
  1220.         timeCount  = 0;
    5 E( e0 t' k2 B( V9 t
  1221.         errorCount = 0;
    $ `. ?1 c2 B% R% B. S6 U
  1222.         dataCount  = 0;
    - H* J2 ~  d% Y$ V( |! @
  1223.         code       = CodeNone;
    ( W/ F2 O1 r: o/ y1 b) ~
  1224.         stage      = StageNone;
    2 _/ I/ _2 p1 k! t* i8 Y6 g. f- H

  1225. % V* S" w/ `3 E0 e+ m6 P% U  L
  1226.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)$ m+ \3 `2 ~/ f1 F; j) G
  1227.         {
    " y# d" g/ X5 g
  1228.           txBuffer[txLength] = CodeCan;2 V# G; j4 |0 E
  1229.         }4 h5 d6 f% \  {8 V0 c

  1230. # j( h7 Q* Y9 W/ A) A* J) w7 @
  1231.         write(txBuffer, txLength);: L5 n7 ?; V) u  y# ~- _
  1232.       }
    2 I' @# c6 q0 `
  1233. 5 f/ F, ]8 H- c* J1 A
  1234.       break;
    - O  F# I" P1 s% ~# V& _8 Q
  1235.     }( o+ c# }4 k" f9 c* |
  1236. + h( L& T) n) A& m$ n) a
  1237.     case CodeA1:& F/ V; d; b, X, V' t8 r  s3 e
  1238.     case CodeA2:
    0 ?$ x! j; [5 Q# h; B7 L
  1239.     case CodeCan:
    / M3 D# G* _9 m) e4 g: L
  1240.     {
    3 U4 `5 @- _- e2 }3 i) T! @# U
  1241.       timeCount  = 0;
    . I+ D% @' U9 ?' }3 X2 ?4 M4 s1 M
  1242.       errorCount = 0;. a3 w6 a/ y" K
  1243.       dataCount  = 0;
    . z- `( E& a' C0 J- M6 m5 i
  1244.       code       = CodeNone;
    ( B* @; s; G* A
  1245.       stage      = StageNone;- m: h# z: Z4 B+ y
  1246.       callback(StatusAbort, NULL, NULL);- a0 J. b( m  }
  1247. 8 e+ {9 Q" T1 U8 ?* @
  1248.       break;
    6 T2 F# Q% E: q! D
  1249.     }
    4 r# w/ B. R5 \/ T9 q# C+ p
  1250. ' `: Z# @. w* v/ H) w
  1251.     default:! h  l6 v( p. P* e! q" P' r& O( B
  1252.     {
    $ _; B  q( F' y9 D! U9 w3 D; f
  1253.       timeCount++;
    ) \. `8 K5 e0 M6 _, j

  1254.   O; P2 n# `0 O& Y7 @1 S
  1255.       if((timeCount / (timeDivide + 1)) > timeMax)" ~! N* I6 l  @
  1256.       {* a. q/ J+ E* y; Y
  1257.         timeCount  = 0;, J  _* B6 R& l6 l& `  E
  1258.         errorCount = 0;
    - i# g1 u% Y6 R3 E: o" d% {
  1259.         dataCount  = 0;
    ' L* @* I% Z% ]! a
  1260.         code       = CodeNone;
    ! W. R' \4 _/ Y5 q' n1 @
  1261.         stage      = StageNone;
    2 T3 v' d) }2 ?; [' l! q7 G
  1262. . R1 _( p; q* K& M) p. D# y+ p
  1263.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)1 n0 B: W( A8 h! `
  1264.         {2 j; S4 M  _7 c
  1265.           txBuffer[txLength] = CodeCan;4 F+ t2 x& l( u7 b9 v
  1266.         }$ K8 \3 S) m6 Z4 t+ e4 b

  1267. # f: }1 Z* }. P- v4 {* D
  1268.         write(txBuffer, txLength);
    ( y# q) J; {1 v0 X% }& E) o' g0 h
  1269.         callback(StatusTimeout, NULL, NULL);
    8 `) X( ?- a  M/ e
  1270.       }% W. a! b$ V, i5 T0 l* [0 R) J
  1271.     }
    * ]! n( z4 a5 X9 i
  1272.   }
    3 _; j4 F4 j# ^- |7 [- y2 i
  1273. }. W8 O7 P7 k5 T, D4 v) ]) c+ A' R
  1274. 4 x' f$ _: U$ k3 y7 S
  1275. /**) K6 m% n: R% Z/ m
  1276.   * @brief  Transmit established stage.2 c, ?9 N, g" c' K' r& W. f
  1277.   * @param  None.9 i& ?& J% y3 u
  1278.   * @return None.
    " ^9 W8 Q( A! U
  1279.   */" O$ h! T5 t# G5 ^; I: R4 f
  1280. void Ymodem::transmitStageEstablished()0 K9 k# v, p8 ]7 r/ d/ f: C
  1281. {
    0 T# ]' E. r+ l
  1282.   switch(receivePacket())
    8 N! G- F2 }  {
  1283.   {
    . N) m: y/ {8 N1 \0 k3 g$ o  f
  1284.     case CodeNak:4 a# u# [) g' s* l. m& b, Q: F
  1285.     {& X% e) c5 d4 x6 |2 F( e- G
  1286.       errorCount++;
    ( r9 e0 U, i  O: o8 R
  1287. 8 N4 K8 _7 o% O3 E- `! ?8 N( g+ Y
  1288.       if(errorCount > errorMax)* m: d6 A, S# `- R8 f2 }, R4 L9 z
  1289.       {: q& t# b9 A+ q" r
  1290.         timeCount  = 0;6 X$ ~4 m# V0 r
  1291.         errorCount = 0;8 s' f& [! [. h! l9 ]# Q$ _
  1292.         dataCount  = 0;1 E& Q+ ]- k' }: P1 a4 g
  1293.         code       = CodeNone;
    % d8 o, C8 ~( f+ I  I
  1294.         stage      = StageNone;# B! c7 X) ?, `& ?" r

  1295. 6 l! W: a8 t9 b: h0 W6 s
  1296.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
      @! W7 b4 E6 J# x9 t
  1297.         {& e* c9 n# l# R2 N2 V
  1298.           txBuffer[txLength] = CodeCan;; c& x) {% x; q6 r% C) }
  1299.         }4 a1 o* V4 b! O1 g  j
  1300. 1 i, J' I" u& @/ Y! k/ L6 X
  1301.         write(txBuffer, txLength);, N! a; b/ Y9 K; l
  1302.         callback(StatusError, NULL, NULL);' o5 t  N4 O' t& x
  1303.       }0 `5 P1 Q, {/ E2 k9 B& K; t7 m
  1304.       else
    / i7 J! v) L- x- a
  1305.       {9 R/ j. z6 U4 f; C" s% C  a" l
  1306.         write(txBuffer, txLength);
    2 Y" C8 y0 S" u1 X$ r% O
  1307.       }
    8 s6 e- z9 F' E- v( n2 v
  1308. $ N, O- d$ R1 g; {+ [, o
  1309.       break;
    4 A+ G- L4 b8 |+ ]9 x  F
  1310.     }
    ' x* g9 }% H3 E/ f# @/ r
  1311. # q8 c: V+ J& C% h) p  g
  1312.     case CodeC:
    3 }: U7 E3 ^8 c+ L! S6 V. x
  1313.     {
    ( i% q+ [/ j1 F! w
  1314.       errorCount++;+ Y- q: L. s% }0 N" S

  1315.   H  F( q; ^) D& l# s7 v& K1 y0 r
  1316.       if(errorCount > errorMax)
      Y# b, Y4 R1 T4 |. O
  1317.       {3 Z! B5 Y1 ?" u
  1318.         timeCount  = 0;
    & Q; R  p. D, Y4 z, f
  1319.         errorCount = 0;
    4 ~) c) [( m6 ]. o6 d; m
  1320.         dataCount  = 0;
    8 z. |8 W7 k; {/ Y/ c4 D' @# }$ }4 ]
  1321.         code       = CodeNone;( w  x, z' Q* k3 |5 [. W6 c
  1322.         stage      = StageNone;5 J: _9 D2 I7 m) g- Z0 Y1 G
  1323. 7 A: h- s. z; ?' w
  1324.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++); a# b9 ^" f4 h- i" z( z+ i( k$ F
  1325.         {5 R$ r' g; A) P1 A
  1326.           txBuffer[txLength] = CodeCan;
    $ c+ `& O) L. f7 n6 v3 j/ h* w8 W
  1327.         }
    . P* L9 [# l+ {% r3 o
  1328. 4 f- L) n7 I4 s% S( h
  1329.         write(txBuffer, txLength);
    4 E3 V% }% V2 l. g
  1330.         callback(StatusError, NULL, NULL);) W" S7 \/ h1 f2 a
  1331.       }2 y! Q, g. {, C% T
  1332.       else0 B4 X( l7 o! \$ ?4 R' l
  1333.       {
    2 I; P9 y- e9 H4 i; w) [
  1334.         timeCount  = 0;4 {. Q6 C. h$ E  @  S
  1335.         errorCount = 0;9 N0 L) Q, x1 t! D& h
  1336.         dataCount  = dataCount;
    ) e2 J  |- d8 `$ T: d
  1337.         code       = CodeNone;
    9 ^) E+ g- Y/ c5 K( X
  1338.         stage      = (Stage)(stage + dataCount);( @! C' Q( i8 H$ N' k+ `5 q" S
  1339.         write(txBuffer, txLength);
    " z3 g6 l4 s% ~! o( G* v
  1340.       }
    * j! w  N6 A5 s( E) @

  1341. 2 E: @; e" f! z" Q: F
  1342.       break;
    6 Y( Z+ }; u/ G7 J" I0 ?1 g
  1343.     }
    6 C9 E3 F! o, J; O3 D; ~
  1344. 5 l% R/ M9 F% v! [* S  I
  1345.     case CodeAck:
    8 V! L; Q# v: P, O; L. g% k
  1346.     {( w" {/ W: ^0 ^8 Y" I4 }1 U" U
  1347.       memset(&(txBuffer[YMODEM_PACKET_HEADER]), NULL, YMODEM_PACKET_1K_SIZE);
    - b; d1 E) b' E- {
  1348. 5 q) L9 t" e. {3 o* f5 L4 A  b: g4 `
  1349.       switch(callback(StatusTransmit, &(txBuffer[YMODEM_PACKET_HEADER]), &(txLength)))- m5 [* H: L! y" p  N
  1350.       {7 j  N' R' d2 ]2 m
  1351.         case CodeAck:
    3 c  C$ B2 B9 A1 g3 i
  1352.         {* I' J2 z& H/ s3 \) ]* q; h
  1353.           uint16_t crc = crc16(&(txBuffer[YMODEM_PACKET_HEADER]), txLength);
    ) r# f2 _, v2 V1 U2 D- q

  1354. & o4 h# z0 {& W; A# o
  1355.           timeCount                                       = 0;/ S5 P5 Q) n9 q; {
  1356.           errorCount                                      = 0;
    & X, W. M$ B( h4 J; l+ u
  1357.           dataCount                                       = 1;
    7 e8 h4 q* g* O- y4 d- v& Y4 A
  1358.           code                                            = CodeNone;
    * V, _8 _1 Q+ `( n" S( h0 R
  1359.           stage                                           = StageEstablished;
    2 T% Z: X( b+ Z: @' [+ B: L! _
  1360.           txBuffer[0]                                     = txLength > YMODEM_PACKET_SIZE ? CodeStx : CodeSoh;
    2 F, |+ Q; ~5 b" W6 ^( M: P# ]
  1361.           txBuffer[1]                                     = 0x01;
      Z: D7 N% q% P# ~5 I2 i
  1362.           txBuffer[2]                                     = 0xFE;
    / [) i. M' k) S$ F, O
  1363.           txBuffer[txLength + YMODEM_PACKET_OVERHEAD - 2] = (uint8_t)(crc >> 8);! s; R0 E3 Z+ B; Y
  1364.           txBuffer[txLength + YMODEM_PACKET_OVERHEAD - 1] = (uint8_t)(crc >> 0);
    7 F9 {/ I( o9 {
  1365.           txLength                                        = txLength + YMODEM_PACKET_OVERHEAD;
    9 c; o$ o. v# H# {$ n# \
  1366. $ i2 E3 A4 X9 q& b% `: S" v. O& x
  1367.           break;! F) L2 \5 j+ L% v
  1368.         }
    ) U6 d, m2 J6 Z

  1369. 4 U' e- B# }# x4 l1 P2 }
  1370.         case CodeEot:; `, y$ Q5 u  |, ^
  1371.         {7 d5 i* A& k+ X
  1372.           timeCount   = 0;+ j& p/ p  R7 }/ V* S2 O, y2 N
  1373.           errorCount  = 0;
    5 `$ P, ]/ }# x; G+ f# u
  1374.           dataCount   = 2;
    $ k0 ~, T  o7 A: c
  1375.           code        = CodeNone;
    3 C: k0 O+ I& K  P0 A; E) Q! Z
  1376.           stage       = StageEstablished;, ^* Z" S+ j: i+ C3 U7 b
  1377.           txBuffer[0] = CodeEot;5 v. j7 S, X8 E) B6 a: Z! ~
  1378.           txLength    = 1;
    ; N3 e- e9 h0 I; c0 b- s: L. o/ g
  1379.           write(txBuffer, txLength);! v5 t" g. D) e9 u7 V
  1380. ; G4 P8 [+ n5 M8 T. |
  1381.           break;
    ! j1 N+ D# Q# d
  1382.         }6 G. r& ~: i9 ~
  1383. + X% \; s! |, W( X# h1 Z- t1 `
  1384.         default:& D" a. v/ U% s  C5 R: J* A; w
  1385.         {
    2 w/ O0 W+ |$ @7 E* y3 l- ?6 g+ x
  1386.           timeCount  = 0;
      B/ C1 ~& w* Z6 ^. n3 z3 I5 r, R
  1387.           errorCount = 0;
    ( ]) d- ]9 ^, k. j$ E
  1388.           dataCount  = 0;6 y& k" v, p, |1 w" o6 i% k2 }' |- d
  1389.           code       = CodeNone;
    9 |0 m1 ?# Z& t0 V: T) _, u" D
  1390.           stage      = StageNone;
    2 I" `5 a" `8 Y. O
  1391. 4 e  G: E: X# D$ F& R
  1392.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)8 Y  c- y" \& L
  1393.           {+ h% V7 y- y- Q1 Q6 o6 v' L, d$ h
  1394.             txBuffer[txLength] = CodeCan;1 |# \. k& E0 C/ H+ P
  1395.           }
    6 h  d: n0 x' r' h

  1396. 0 s6 r+ h) j! V" L
  1397.           write(txBuffer, txLength);
    8 [" g- I" Y1 m) X2 Y; ~- i" v
  1398.         }% @2 ]& |9 `" o( G
  1399.       }  a# q% E' H$ B* M; Y

  1400. 9 M- Z) l) `% o" X
  1401.       break;7 R- `: B# s: p' A9 s7 @- v7 j$ t
  1402.     }
    5 Z  @* ~6 {3 n2 x. y+ e

  1403. + K' `3 @1 X0 t! a/ a  j. D1 I' Z: I* k" A
  1404.     case CodeA1:
    , ^% z+ k) I8 r6 h( o
  1405.     case CodeA2:& ~) q/ L' @8 Z* J
  1406.     case CodeCan:( g$ J# ]+ s  S: A, I! \
  1407.     {; V: b8 B8 b2 c/ ~9 M+ V" C
  1408.       timeCount  = 0;
    ( Y. |: {/ F0 v9 g; H- H3 b+ k
  1409.       errorCount = 0;
    3 Q) s  a$ [0 N& z! `% ?
  1410.       dataCount  = 0;- R3 o- O7 w9 I: @
  1411.       code       = CodeNone;" [0 v7 _) a4 A7 {; h
  1412.       stage      = StageNone;
    * Q0 T4 a. M6 _/ s( ]$ M
  1413.       callback(StatusAbort, NULL, NULL);# j- C* W3 h5 l3 |! [# i0 \; v. @+ ~
  1414. $ ~% o2 y7 V  x
  1415.       break;+ O, l! ]: y0 x# q0 S1 ^# p
  1416.     }
    + {2 C# K, W8 D, K* z' A

  1417. 2 S% m6 ]2 t8 i, {
  1418.     default:
    % Z1 g  N7 |! _/ f
  1419.     {
    % P( @0 Z$ R6 o* r
  1420.       timeCount++;6 ^* a" U# i; {2 B  F8 D
  1421. & r+ G8 Q/ [+ a6 a
  1422.       if((timeCount / (timeDivide + 1)) > timeMax)
    6 k; u; d7 H" j
  1423.       {. `4 {1 {  _; U
  1424.         timeCount  = 0;
    5 X# w6 X7 W9 Y2 z. S
  1425.         errorCount = 0;
    3 E  }6 a7 q6 {' O) P1 I2 j! L
  1426.         dataCount  = 0;
    / n7 I7 s" ~) l4 k
  1427.         code       = CodeNone;9 p) O" m' F" B. A1 Q
  1428.         stage      = StageNone;
    + J1 c4 t/ x& i: B$ P. o* h

  1429. 7 g) ^2 @) @8 y) X# c, i" g
  1430.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    1 P3 I9 X# Z1 A! ^9 ^6 @! L
  1431.         {
    - ~7 m) p' P; x7 W
  1432.           txBuffer[txLength] = CodeCan;; t. A$ |8 e. @# n2 m! o
  1433.         }
    * l+ W8 ^# A0 f+ D
  1434. 7 ~8 D% {. s- Z5 T/ |
  1435.         write(txBuffer, txLength);
    , f" }: G8 e( `" E. Q8 k
  1436.         callback(StatusError, NULL, NULL);9 M) w) L8 w7 w3 ^8 w# P; V
  1437.       }
    . B4 [( A3 l# h" [1 g8 g
  1438.       else if((timeCount % (timeDivide + 1)) == 0): L; o. J# y& ^9 ], X
  1439.       {! w3 [/ u) e# e) M, A& E
  1440.         write(txBuffer, txLength);
    ) M: z( @+ m# N; i1 c
  1441.       }
    $ J+ B2 v  w) v  B- B: Q" Q% `
  1442.     }: ]! n+ {7 o9 E) D& q
  1443.   }$ y) {( |9 P, K+ r3 X5 `
  1444. }
    $ D* }  s6 K& C3 R; x! ?
  1445. 4 L; Q$ t8 c. U( o$ p. l
  1446. /**: f' f3 ]& V  n. D6 k2 h
  1447.   * @brief  Transmit transmitting stage.5 S4 J- X! s. G& g  L* ?
  1448.   * @param  None.
    + x5 g! U( y4 }, M' v5 a' C4 B
  1449.   * @return None.7 V% x! E$ U! i% v) A9 u5 s
  1450.   */6 ^6 ^, W3 H1 |) n
  1451. void Ymodem::transmitStageTransmitting()
    , @. y' l# z2 l8 u4 z2 y# D
  1452. {
    , @' Z, I4 H: P- ?6 A- ?
  1453.   switch(receivePacket())5 R3 C# `( J( B. @5 Q9 X
  1454.   {
    + x( Z; T$ M9 {" F6 o
  1455.     case CodeNak:7 f" ~( ?2 {+ N; S+ z
  1456.     {
    + t% W4 m7 U' \8 q# X2 \. i, ?
  1457.       errorCount++;5 y- j7 e! ^8 m' f' w/ }, f# m0 F
  1458. ! I- c, {2 W4 K) s
  1459.       if(errorCount > errorMax)
    # O5 }0 Q1 v1 T/ P) D9 j
  1460.       {- Z8 z" F2 }- L! r/ {( O
  1461.         timeCount  = 0;
    8 v( L* I; R# h" y
  1462.         errorCount = 0;/ C! l2 Y- {7 n, H
  1463.         dataCount  = 0;
    7 z2 o- t$ N3 _# G( N9 H4 h
  1464.         code       = CodeNone;
    3 _' J3 [0 g# o) b$ d- _& Q
  1465.         stage      = StageNone;6 K4 N+ x  j! z
  1466. 8 V' _9 x8 `3 E
  1467.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    5 U- A8 o7 N/ f+ A% Z
  1468.         {
    ( r: S1 _' f& \& f9 l$ R' Q
  1469.           txBuffer[txLength] = CodeCan;4 U4 w, S# M: {: _
  1470.         }1 h9 u) z5 t0 e8 ^# f

  1471. - T4 {! s& k% e; U
  1472.         write(txBuffer, txLength);
    + S' L+ N9 `' {/ n9 j/ f
  1473.         callback(StatusError, NULL, NULL);& L) R8 Z# \$ j7 S1 n& B  C" Q
  1474.       }
    ) j9 Y" ^  u! K0 u. ?- J- y" m
  1475.       else/ R7 q5 }# E$ F" d5 R+ U
  1476.       {  u  o9 Y, M9 k" G3 h9 H
  1477.         write(txBuffer, txLength);
    * E5 G& ]1 ^# a$ m; l2 E! X+ [
  1478.       }
    4 B& ~! d* o0 S4 Z0 S
  1479. & \0 n% o) |% o) Z2 d% R
  1480.       break;2 f9 ~& T' h8 F& P, e% B) v
  1481.     }. n4 i$ r2 X$ a( \. s* G8 r

  1482. 8 t7 K5 i9 N2 o2 B
  1483.     case CodeAck:
    + b) C2 g) z# Z+ i! J- R6 k
  1484.     {
    1 S- ?% M  _9 G$ u: d3 p- K
  1485.       memset(&(txBuffer[YMODEM_PACKET_HEADER]), NULL, YMODEM_PACKET_1K_SIZE);
    6 G! X  x* k1 ?" I7 k4 }& t

  1486. " \9 x/ c& V# _# y
  1487.       switch(callback(StatusTransmit, &(txBuffer[YMODEM_PACKET_HEADER]), &(txLength)))
      l  e: V/ `# d3 M9 X- h
  1488.       {% m* |$ E3 Y! Y6 _! E
  1489.         case CodeAck:
    4 z3 b$ G. d% V  B+ I
  1490.         {1 d& c; P3 ?& A7 D/ M- s6 k( M
  1491.           uint16_t crc = crc16(&(txBuffer[YMODEM_PACKET_HEADER]), txLength);- S2 Q* {- i6 U- @3 V
  1492. 7 N( N9 ]5 t& {) l. [$ z
  1493.           timeCount                                       = 0;% Y8 Y: g, i% i  l6 u2 |
  1494.           errorCount                                      = 0;) q& z% U% ^* y$ A5 I: E! t# p
  1495.           dataCount                                       = dataCount + 1;
    $ {0 \: O" {3 E+ n0 e$ E  V
  1496.           code                                            = CodeNone;
    $ r7 D, K) w8 E; B
  1497.           stage                                           = StageTransmitting;# j& f8 \; h; c$ P2 b
  1498.           txBuffer[0]                                     = txLength > YMODEM_PACKET_SIZE ? CodeStx : CodeSoh;) Q& a) V2 b* j+ ]4 }+ }
  1499.           txBuffer[1]                                     = dataCount;
    / U) |* I* ~, W0 }. t+ N2 O3 G
  1500.           txBuffer[2]                                     = 0xFF - dataCount;& b( h' ^% D* u! Y; w4 U
  1501.           txBuffer[txLength + YMODEM_PACKET_OVERHEAD - 2] = (uint8_t)(crc >> 8);6 \( Q/ u. B1 G4 L( I9 Q
  1502.           txBuffer[txLength + YMODEM_PACKET_OVERHEAD - 1] = (uint8_t)(crc >> 0);2 m! a2 z6 z$ t
  1503.           txLength                                        = txLength + YMODEM_PACKET_OVERHEAD;/ o" x7 v. n+ S% _
  1504.           write(txBuffer, txLength);  f+ W+ x) m& _; F, C
  1505. , w' Z3 B8 d0 w4 V% p: s2 V
  1506.           break;+ G# I. g$ _$ @3 z( Y* J5 [
  1507.         }/ e0 m: D3 b) A, E% ~
  1508. " o% g% O5 j. N/ q$ p; k& }
  1509.         case CodeEot:
    8 D3 G2 s% i( M+ _1 [3 J
  1510.         {) t6 ]1 F! y+ X; N0 Z+ n
  1511.           timeCount   = 0;
    + J0 y& h% d4 h* ~. z% `0 t8 P
  1512.           errorCount  = 0;, R# G5 Z! }2 }; c2 B
  1513.           dataCount   = 0;
    $ i: J% c* P. b' \$ r5 K! V
  1514.           code        = CodeNone;
    % F/ ^+ z* [" T! V  M
  1515.           stage       = StageFinishing;) q) e$ V1 ?! x
  1516.           txBuffer[0] = CodeEot;
    4 \. h4 P  d3 @% b- M% j8 d
  1517.           txLength    = 1;
    7 d$ x( y0 }* S. x0 d0 x8 c
  1518.           write(txBuffer, txLength);
    " B- L( v* ]+ S4 Z7 x
  1519. 2 M/ n, m. [/ ]3 _( J
  1520.           break;; X: d4 |# |; G' V% d; E
  1521.         }4 X$ ^, Q5 g% C  w

  1522. 1 B9 }' ?9 s9 d1 m" T
  1523.         default:
    ; s% A: L4 p; a8 \
  1524.         {
    & R/ N% |$ m4 z$ ^& Y6 {5 L& Y( N
  1525.           timeCount  = 0;( l) w5 S: B! D. }* Q& D
  1526.           errorCount = 0;
    " J4 v0 {2 n  M, I  m* A. s0 x
  1527.           dataCount  = 0;
    2 @4 n- x3 T5 d) s  I( u6 A3 D/ O. L
  1528.           code       = CodeNone;
    # R$ F$ \" A" ?
  1529.           stage      = StageNone;) j( n, i" S0 g: U* p5 a/ f
  1530. & G& O2 O, V& \9 `" m
  1531.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    " p) Q) ^: y/ Y$ a& a" j. f
  1532.           {
    7 s# Q6 @7 K2 _/ T6 f
  1533.             txBuffer[txLength] = CodeCan;
    $ P0 s% M  ]" W2 V
  1534.           }2 M9 v) l* \* s9 {& \
  1535. ; A8 _" ?% g9 F3 m. A
  1536.           write(txBuffer, txLength);
    $ a# U' O5 z& t* a
  1537.         }, L: I; _+ T( T; x$ I% R) u( B' H! h
  1538.       }
    $ y' C. [% U+ Z. E. Q+ d+ M1 t

  1539. ( ^9 G# E& T: }
  1540.       break;1 S" x' }+ d; B2 R9 S
  1541.     }
    5 T6 q- Q+ e6 X8 y) l, ~; r

  1542. 6 D% I# W; P: O% T5 Q
  1543.     case CodeA1:
    0 D& x7 G0 N7 G
  1544.     case CodeA2:
    1 D1 v9 C% Q2 N7 d# u, b
  1545.     case CodeCan:
    1 M  Q% v1 N! L7 D
  1546.     {
    * k% ~: o6 s7 S0 q% u
  1547.       timeCount  = 0;
    - n& n# x, `& K* i5 m
  1548.       errorCount = 0;
    - d6 p& Y- ~& j7 h& D1 p8 `: a
  1549.       dataCount  = 0;
    ; E- j4 O8 @. ]7 x5 S5 i) g
  1550.       code       = CodeNone;
    ; E# U- E8 {1 D0 B3 Z$ _$ ], U: E
  1551.       stage      = StageNone;: B6 M! Z6 `# K- e/ ~, h. S
  1552.       callback(StatusAbort, NULL, NULL);$ h- x1 l! @( ~3 Y3 n
  1553. 9 i8 Z" Y/ f: `: O0 P
  1554.       break;2 Y/ r6 b1 _- q
  1555.     }
    3 y. H+ z/ `5 h0 b
  1556. 3 n' z9 B" a* h
  1557.     default:
    7 ^* a6 F$ }5 ^- ]
  1558.     {
    ) o$ E4 ~4 u% \/ K/ h5 W2 ^0 E
  1559.       timeCount++;
    # q8 E% w" z3 T$ {0 U

  1560. 7 h& W9 r% ^/ k0 i* `
  1561.       if((timeCount / (timeDivide + 1)) > timeMax)
    - q6 O- N. M# ~* J/ \
  1562.       {5 m' i0 z2 C9 u( E/ N
  1563.         timeCount  = 0;6 R; u7 u/ ~* a' {( j. @$ k
  1564.         errorCount = 0;
    4 n9 i# u- s; E: o2 n
  1565.         dataCount  = 0;
    2 m- D8 T% i( @, @, B8 L
  1566.         code       = CodeNone;
    $ h* Q9 H7 Q0 ]
  1567.         stage      = StageNone;1 j8 h! O' X& g3 V( o5 ^) P

  1568. 1 y7 a9 Q- [4 v3 Y: M% i
  1569.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)+ i% P2 U% M4 [$ P. C. }
  1570.         {
    + i9 P9 D# {6 ?( ~* n
  1571.           txBuffer[txLength] = CodeCan;0 m/ c1 g1 ?* H7 ?; y3 q% ]
  1572.         }
    2 h" J& F0 v8 T4 }' F. N5 |

  1573.   n6 E0 F; a( G' w; s$ V. }' q
  1574.         write(txBuffer, txLength);
    * p' m& ?. R  G% _+ F" M9 V
  1575.         callback(StatusError, NULL, NULL);: @8 Y0 U9 s$ k" O0 y
  1576.       }, p) \" V, i" q3 p3 _0 m) X
  1577.       else if((timeCount % (timeDivide + 1)) == 0)
    5 e6 C$ [: ]8 y! N
  1578.       {' Y9 b. S: |9 X
  1579.         write(txBuffer, txLength);
    4 \1 V% C: v% C# @
  1580.       }
      U- _$ P, _- m. t- C
  1581.     }
    % a6 L5 Q$ y6 D: p4 r
  1582.   }
    ' K3 C5 |1 }0 |2 ^3 w: D/ z3 r
  1583. }% Y9 \) \( t0 E& Q
  1584. ; E4 T* W1 o9 S
  1585. /**' V; k) X* B' ]& q( ?
  1586.   * @brief  Transmit finishing stage.
    ( q: A% W. b8 G" d- ~3 P# O
  1587.   * @param  None.
    $ c' A+ ]& `: L
  1588.   * @return None.
      v: t4 G0 L% S; T  K) _
  1589.   */
      j' {: \% V9 R. g: [- d
  1590. void Ymodem::transmitStageFinishing()
    " {% g& G6 X) l
  1591. {
    * k, u( }  W% U+ o2 k
  1592.   switch(receivePacket())
    5 l) h/ ?0 T2 j
  1593.   {5 ~* o0 g1 W! O/ {
  1594.     case CodeNak:1 d9 u+ w/ z0 ?& Z+ X
  1595.     {3 l, m! M9 j- S, `2 {9 i: s
  1596.       timeCount   = 0;; o* x* j, l' ?# z& Z* J
  1597.       errorCount  = 0;5 B$ S+ E6 Z* ~1 S
  1598.       dataCount   = 0;- X" \# q  s" Q3 X1 V$ }9 D
  1599.       code        = CodeNone;& P2 k4 Z  f/ M( o; M* i6 k, l& V8 y
  1600.       stage       = StageFinishing;
    9 x* t1 w/ i3 E  N% ^8 ~
  1601.       txBuffer[0] = CodeEot;4 [( q7 J! ?: F5 i7 d0 h; N
  1602.       txLength    = 1;
    / B: C8 u2 u/ I. H. _  H0 [' g
  1603.       write(txBuffer, txLength);6 {/ m3 l+ J( n2 k* e# a

  1604. 9 O) u3 T- k, m/ v
  1605.       break;
    ; |5 @' @9 Q- j" ~& U2 S- m6 Y
  1606.     }2 h1 y. g% k6 L2 O
  1607. # U+ l* w% c3 g4 c
  1608.     case CodeC:
    . T: D; T( ]' W: @8 y/ A
  1609.     {
    6 d7 l( A9 o/ y: d( i; `  P
  1610.       memset(&(txBuffer[YMODEM_PACKET_HEADER]), NULL, YMODEM_PACKET_SIZE);
    # F& j$ z5 d& R1 o0 P
  1611.       uint16_t crc = crc16(&(txBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_SIZE);
    0 r' T2 e7 C, n# f

  1612. ; P6 o9 W/ _5 U2 r9 L! }
  1613.       timeCount                                                 = 0;4 ~$ z9 A. i9 V! _5 x
  1614.       errorCount                                                = 0;
    ( I2 e0 @- g; J5 \- ?
  1615.       dataCount                                                 = 0;6 c8 _9 `/ e9 o2 ?/ x8 J
  1616.       code                                                      = CodeNone;2 Q! T7 z4 D  \& l# g2 V1 n& e7 E
  1617.       stage                                                     = StageFinished;6 M, r8 {& ~% x# p3 c4 M
  1618.       txBuffer[0]                                               = CodeSoh;
    / J4 [8 @9 R/ t0 I
  1619.       txBuffer[1]                                               = 0x00;: |! B. a! o- x  A3 e
  1620.       txBuffer[2]                                               = 0xFF;
    1 |% R2 j3 _6 i, q* b
  1621.       txBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 2] = (uint8_t)(crc >> 8);
    ; n) s  _' i- T# m3 V5 M
  1622.       txBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 1] = (uint8_t)(crc >> 0);1 N; P5 S( S+ g/ `, W
  1623.       txLength                                                  = YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD;
    2 b/ R1 v% N+ \
  1624.       write(txBuffer, txLength);
    / r  r2 x/ _$ T/ ]$ X6 J

  1625. 6 P7 f. l0 b2 h
  1626.       break;
    $ Y  x' ]- i; B6 x
  1627.     }" C7 E( M+ d. I5 `2 ~  U9 Y

  1628. & a7 ?: F- N4 R
  1629.     case CodeA1:( ?! E  Q- ]+ C0 w! z7 N  M
  1630.     case CodeA2:  [+ H7 I5 X6 |' c2 u+ y. M
  1631.     case CodeCan:" `9 l0 n: I' n
  1632.     {) j6 B9 I* H1 E' [: a, p
  1633.       timeCount  = 0;
    6 g; g6 R% F% @. b2 [
  1634.       errorCount = 0;5 g6 Y. q/ q7 {$ j( R8 T. w; h% I" `, t
  1635.       dataCount  = 0;+ u& w. G" G& Z$ T( O2 v6 G- S
  1636.       code       = CodeNone;
    9 ?5 I# I0 }; {: z
  1637.       stage      = StageNone;" G/ G( x' |+ F
  1638.       callback(StatusAbort, NULL, NULL);
    9 l6 A3 B  k* H/ D

  1639. 2 X' i0 L+ a2 X
  1640.       break;
    7 z/ N, i* d* A" N3 L' [# V
  1641.     }
    7 t: ]# w0 l6 z4 I6 m! v5 s

  1642. 0 u/ N" H6 z& i* o
  1643.     default:1 W1 d# G$ a4 s/ X6 m2 n, K6 H3 W
  1644.     {
    & F% Y9 f9 M! c5 M+ C8 u
  1645.       timeCount++;
    3 f& `$ V4 V9 o0 b$ @" L/ b

  1646. 9 G3 }( R/ V, m
  1647.       if((timeCount / (timeDivide + 1)) > timeMax)
    + u% x' ]1 S0 c; G1 x/ f
  1648.       {% z) W" d) ?. p) \; h, v7 N+ \4 R6 }0 e
  1649.         timeCount  = 0;" Q) s4 J4 W- _- c
  1650.         errorCount = 0;
    7 o" g% h5 B3 F2 m# [/ V
  1651.         dataCount  = 0;
    ( X5 }" J/ t1 s
  1652.         code       = CodeNone;, h+ c; N- b2 Q* J5 p6 E3 S1 Q
  1653.         stage      = StageNone;- R+ v* R, D' |, N

  1654. ! N* v/ o. h, h6 [/ q- F9 b
  1655.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)- f+ Q2 n, J9 q# c6 ^  s  S' N
  1656.         {
    1 `9 u# @6 X6 R* N% _+ a) ^1 R% Z" P
  1657.           txBuffer[txLength] = CodeCan;
    % K$ b9 ?+ t& ^2 M& k$ f5 m) O$ E
  1658.         }% H7 d; Y" [" T

  1659. ; ~/ d, ]6 B3 {, n/ w' \* [
  1660.         write(txBuffer, txLength);/ }, F5 Y9 U; e7 L* z8 b
  1661.         callback(StatusError, NULL, NULL);+ a; I% Y* P+ K2 b
  1662.       }- E' b. M; d! b, s
  1663.       else if((timeCount % (timeDivide + 1)) == 0)
    ) A( ^8 v4 |  X
  1664.       {
    0 R$ B0 A+ C. b. S. i
  1665.         write(txBuffer, txLength);
    ' i$ S: W9 p8 t+ m
  1666.       }
    ; F: f9 N! S) q
  1667.     }2 P0 a5 V5 _7 G
  1668.   }6 K8 r0 _% o/ i0 Q
  1669. }3 C3 N) s( {8 g

  1670. 3 ?3 w9 H( @  J  I: j- l
  1671. /**
    & K0 D- i6 C$ ?' m% k$ `1 t
  1672.   * @brief  Transmit finished stage.
    % v5 ?7 m- V5 S, ^: T
  1673.   * @param  None.
    : ~* J# _3 a& [! o0 D# M/ Z. D
  1674.   * @return None.: s2 h6 a* E: {3 ^
  1675.   */7 l2 I* I3 X5 x" g
  1676. void Ymodem::transmitStageFinished()0 J! P! `4 @: l) i4 R1 i
  1677. {
    + a% L2 d6 D/ o7 L8 S  d
  1678.   switch(receivePacket())& f. x* o% E8 @+ l
  1679.   {
    6 H' J2 d  b, n) ~! {) n; _7 }1 f
  1680.     case CodeC:3 n* Y' z9 e7 g( T
  1681.     case CodeNak:
    / [. _' F+ Y) E/ H2 Y. t7 J
  1682.     {
    9 b0 d; }: M1 `/ A0 t9 Q
  1683.       errorCount++;1 F- c# h# r' J( c

  1684. " x6 j4 M7 F) E
  1685.       if(errorCount > errorMax)3 J! g- _; b" a. O3 x
  1686.       {
    $ L. B  @3 P8 @# H$ S- c6 y
  1687.         timeCount  = 0;0 A# I$ j* X5 v5 O( H
  1688.         errorCount = 0;
    3 w+ }: s) I" j. z! l: i
  1689.         dataCount  = 0;
    , q% o# W3 w, N: q
  1690.         code       = CodeNone;; |3 v/ v4 q+ }6 W; k8 C
  1691.         stage      = StageNone;$ N( o' c: T4 s( Z

  1692. 6 v2 v' e/ s9 w: X+ z
  1693.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)" v/ g$ i% w" n; f
  1694.         {$ W$ P2 _7 _# D  f8 `; y
  1695.           txBuffer[txLength] = CodeCan;
    ! d) f5 u9 k( U& J1 c
  1696.         }8 k; t  `( H% ^. s0 Z3 _3 U

  1697. & N% D- i( n2 ^, x, z6 H- c3 g
  1698.         write(txBuffer, txLength);* ^- I1 P( [$ `7 |, Z
  1699.         callback(StatusError, NULL, NULL);
    - `& Y% k* j4 ]
  1700.       }9 O4 @" u0 X) x! x+ B0 {* j
  1701.       else& j; X* \* ]$ \: Z7 m& |
  1702.       {
    4 ]1 u8 T7 b. v: h2 p
  1703.         write(txBuffer, txLength);
    1 @/ i4 o3 r8 ^8 w& Y9 A; }, A
  1704.       }! j! l! W! W4 z7 l# S& P

  1705. 7 _, w: f# I* e3 I+ R
  1706.       break;
    0 ]1 m" N5 u! g# k+ g4 T+ Q
  1707.     }2 t! |/ }5 U/ c& ?& e/ O/ k

  1708. 8 J. S  c% W6 q& u
  1709.     case CodeAck:
    + s+ P& Z0 p& W- t
  1710.     {
    , V! s& M4 _& P4 G
  1711.       timeCount  = 0;; Q" F2 ]2 U; m2 |9 x
  1712.       errorCount = 0;
    $ Q; }% S# _3 ~
  1713.       dataCount  = 0;
    " s* d$ J8 {5 n. ]+ M) |
  1714.       code       = CodeNone;
    9 a3 t" L: K3 M1 ?: g1 `( Z7 a
  1715.       stage      = StageNone;, U6 X: s! S( d: m
  1716.       callback(StatusFinish, NULL, NULL);
    & u8 W, W8 g9 i
  1717. $ c# U+ u. B0 @& X7 y, H6 K
  1718.       break;6 N& Y* F1 f9 X  A  b
  1719.     }
    . q0 |6 I1 L; |9 l* w
  1720. / n: j% m% I4 a' w" P
  1721.     case CodeA1:0 {) i$ ^. N* S$ s& L0 @$ N
  1722.     case CodeA2:% S& a4 Z' B% X- t. C
  1723.     case CodeCan:
    ; U5 U: m; @, J( x2 G# t* |
  1724.     {4 U8 n! l( p; `3 t2 c
  1725.       timeCount  = 0;
    1 g* ~+ Q6 Z9 m$ r5 H) A0 g
  1726.       errorCount = 0;& A: t% T6 f' C' ^, d9 i/ d: P
  1727.       dataCount  = 0;
    0 X8 k8 U8 P4 O+ ]
  1728.       code       = CodeNone;5 ^2 `8 R  h8 L! X0 y9 z+ R
  1729.       stage      = StageNone;
    / r  t' q$ |" B  i1 }
  1730.       callback(StatusAbort, NULL, NULL);
    6 \3 S, V( U4 v+ g. L, {2 z
  1731. 2 X+ a; W! h7 g5 s
  1732.       break;
    8 f8 n5 j9 r. X3 C4 m
  1733.     }8 j9 f+ W  A- V6 ?! @2 `* K

  1734. * n5 c) F! N; T7 s9 ~/ w
  1735.     default:
    ; p$ H) F% A! `& }3 t# d) i  `
  1736.     {) ]6 b. r1 Y1 B! V# h, |4 b8 |
  1737.       timeCount++;
    0 Z! E8 I! E* p$ h; m7 n1 g
  1738. % O; Y, Z) r* c. u/ n  Z' L
  1739.       if((timeCount / (timeDivide + 1)) > timeMax)2 F$ r2 t0 T. T  {
  1740.       {
    / v7 q7 ?) M# U: `
  1741.         timeCount  = 0;
    3 d' k$ O& `" Y; A
  1742.         errorCount = 0;% |) }: ^& Y# A; V$ _/ o# i
  1743.         dataCount  = 0;- D  t. H# b0 }4 x. t. R
  1744.         code       = CodeNone;
    / W( j5 v" Z  ?3 _" y4 C; y
  1745.         stage      = StageNone;
    7 t+ C& ]' Z* N6 ?2 p5 z

  1746. 6 [9 G& U  J" _# \. q
  1747.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    , i' s0 j  f2 ^9 e: E
  1748.         {; R+ x. _, D* {3 ?5 n
  1749.           txBuffer[txLength] = CodeCan;  p! L. R9 `" S
  1750.         }
    ) T$ X7 s4 \0 S( o9 z

  1751. / V/ n7 F8 F$ [- r; y+ M
  1752.         write(txBuffer, txLength);
    , D: b! u6 r1 x' D% B3 u- q
  1753.         callback(StatusError, NULL, NULL);* ^/ W2 @. C4 y3 |3 Y
  1754.       }1 e% m/ p4 Z- s; \6 P* S. h, F
  1755.       else if((timeCount % (timeDivide + 1)) == 0)
    ; z+ d% f" w( V, U3 F4 y( P$ ^
  1756.       {  T  A6 o, W! n! B, P
  1757.         write(txBuffer, txLength);
      g2 v7 T! {# z1 z* a3 f& H
  1758.       }
    7 `7 O( Q% Q3 g: r  U" S
  1759.     }
    " H) g( S* F' f) Q& t$ Z
  1760.   }  d, E( q& i* V7 h: _
  1761. }: ?3 d4 B5 K5 X) H9 e

  1762. ' H1 u! c8 K% M& A- B; m. B
  1763. /**
    ) t3 o" n2 T3 u5 G, ^5 }
  1764.   * @brief  Calculate CRC16 checksum.
    6 |3 ~0 h' |6 [2 Z. s, x" w
  1765.   * @param  [in] buff: The data to be calculated.: d4 |& R- ?# D/ |
  1766.   * @param  [in] len:  The length of the data to be calculated.
      g7 L2 \' _# j( w! `  d# b. z
  1767.   * @return Calculated CRC16 checksum.* m( @/ b4 r" Z8 x
  1768.   */
    1 D* R9 N0 v% D& Q) r0 ^! j7 u; Y/ @
  1769. uint16_t Ymodem::crc16(uint8_t *buff, uint32_t len)) E, C  t" B& J
  1770. {
    $ N6 w$ S/ n; |8 M0 s
  1771.   uint16_t crc = 0;
    & F3 e& x- X3 R( f# T, N- m# D
  1772. : r. ?& Q; h# S; U' _! c
  1773.   while(len--)6 r5 ?# F, |. @
  1774.   {& L6 s6 s' e8 Y
  1775.     crc ^= (uint16_t)(*(buff++)) << 8;" N3 w; a  ~* c: o
  1776. 3 t  W- a& c* q6 t
  1777.     for(int i = 0; i < 8; i++)
    " X8 Q6 A! i6 x/ L
  1778.     {
    ( |5 A0 k  |4 k+ U+ m1 E
  1779.       if(crc & 0x8000), Y2 _4 u) z' p- Q
  1780.       {
    3 j0 G* A8 I* M0 O0 A
  1781.         crc = (crc << 1) ^ 0x1021;
    , ]8 h: ]$ }' W. R7 V
  1782.       }
    ! m2 z4 \# P. V+ m! H" B
  1783.       else! _( |$ K! k2 B0 a. E$ M) }; N
  1784.       {+ ^/ L0 \# C  Y" D9 M3 B3 d
  1785.         crc = crc << 1;% t5 \1 O9 @+ ~
  1786.       }
    2 Q2 x0 N7 r2 F0 k
  1787.     }
    ( o: V# S( t: P( H1 \& V2 a
  1788.   }& h) y8 n  [4 k1 I: M9 s! g5 l

  1789. 4 _- Z# R) s5 G# z; Y) j  }+ j
  1790.   return crc;
    ) D- B* q+ j7 Z8 {
  1791. }3 H6 T9 R$ _. v, g+ M6 q; F$ \
复制代码
$ r( t! V8 _9 X- t, \( s5 Q

+ R; a. H7 D  @& I/ ?
) G" E7 X% d8 H) x( z! Q; }2 q( c
5 k; z* c2 r. \" o& Z0 u7 E" g5 A; d0 ~3 c
收藏 1 评论11 发布时间:2018-3-6 22:28

举报

11个回答
XinLiYF 回答时间:2018-3-6 22:30:39
      YmodemFileReceive.h文件7 ~* _' V7 m3 S7 {4 j' v
  1. #ifndef YMODEMFILERECEIVE_H
      d/ Y! ^* ^8 A7 \4 f" F
  2. #define YMODEMFILERECEIVE_H* ^. h0 s) ^% h8 ~8 R  m
  3. ' r; u+ {- c. f$ W' j+ @
  4. #include <QFile>7 M# I5 x$ Q$ ]) f) R* l' s: b7 J
  5. #include <QTimer>
    , v3 Q) V' f) a8 H
  6. #include <QObject>
    8 ]4 _1 _5 Y& q
  7. #include <QSerialPort>  M# \3 `* Y  J8 k
  8. #include "Ymodem.h"+ R, w) J5 x% h+ b6 D, a& b  V5 H
  9. ) l7 s, z( t2 e% [4 {7 M: A: g
  10. class YmodemFileReceive : public QObject, public Ymodem
    : f9 h! T& L' O8 W( M1 `( a
  11. {
    ! s# [) X" i$ A
  12.     Q_OBJECT4 J9 ?2 F3 h1 @$ h: e* [1 s- e* j

  13. % |6 k: \  j0 U
  14. public:3 W$ A) H- h5 b  ^
  15.     explicit YmodemFileReceive(QObject *parent = 0);
    ! L" u8 @4 D  S2 H+ G
  16.     ~YmodemFileReceive();
    - V  o3 Y) H: z% S) r# R
  17. . E, o) ?  u3 {- @
  18.     void setFilePath(const QString &path);
    3 l; I1 X$ R) M: i1 }- f

  19. . O1 @: q; A* e9 O! ]# |
  20.     void setPortName(const QString &name);* T; w  \0 C. e
  21.     void setPortBaudRate(qint32 baudrate);3 G3 C9 K7 @5 R2 W, d

  22. $ H. F( X8 r( k8 W* C
  23.     bool startReceive();
    % w! g- X/ K, H, p9 O) Z
  24.     void stopReceive();8 {# @& \! o' Y% W/ @: x; o
  25. 0 m9 ~. y7 A9 O. c# R6 v6 w
  26.     int getReceiveProgress();
      `# n9 S# k5 @! d
  27.     Status getReceiveStatus();" x( m: j9 T$ v& q5 ^
  28. ( D% h  x7 _% _/ r- y' d
  29. signals:+ ^3 w+ H; q/ Y! n
  30.     void receiveProgress(int progress);
    6 O  V3 S. W" J; S- Y0 X( L) V
  31.     void receiveStatus(YmodemFileReceive::Status status);
    2 c! t# u. N5 @1 T& U6 J+ ^, I* \
  32. ! G# b9 Y: R- A7 c
  33. private slots:
    0 }7 ?0 {% b" P- E$ z5 b' n
  34.     void readTimeOut();
    ( p5 {- w% X1 {0 C) U" Z
  35.     void writeTimeOut();9 u9 |+ J6 w* r

  36. 9 n7 y0 Y: ?+ r. j( {% q
  37. private:
    ' q; y, S7 C9 R/ }3 m/ ]2 L( B" V
  38.     Code callback(Status status, uint8_t *buff, uint32_t *len);
    $ Y- h* Y! J$ U2 b+ d) a

  39. & ?* ^# C! g& x" ?, Z4 a
  40.     uint32_t read(uint8_t *buff, uint32_t len);
    5 g7 L: [6 t& V) r* f
  41.     uint32_t write(uint8_t *buff, uint32_t len);
      B: P- h- Q% A0 {

  42. $ q/ ^9 p  W. W0 W$ g
  43.     QFile       *file;
    1 g8 H* N9 s/ u) W
  44.     QTimer      *readTimer;
    1 a6 [/ C2 w& ]* Z. e$ l; C) h
  45.     QTimer      *writeTimer;
    / z* I/ o/ y2 B2 |1 p  u
  46.     QSerialPort *serialPort;
    5 w0 b' `+ c; h# i, B" V- y  Y0 U

  47. % c- l( ^9 `4 n5 T: Z
  48.     int      progress;
    2 Q8 q4 P! E) ~9 F  i2 n
  49.     Status   status;
      K2 {) t6 j* f% c
  50.     QString  filePath;
    ! x7 V. I: M8 C  r$ L9 D1 i
  51.     QString  fileName;0 M6 w5 h, ^$ a4 ~* Q
  52.     uint64_t fileSize;
    ' H. {* J5 Y9 }' D* g+ j( c
  53.     uint64_t fileCount;/ R6 |5 n5 Z% q" K5 N$ W
  54. };; w* v9 ~7 I: `, U* N

  55. : x7 A+ C5 i, G# I& |# i
  56. #endif // YMODEMFILERECEIVE_H
    + T  z% x- I% g
复制代码

9 v0 E: v- C2 h2 I( c- k4 _      YmodemFileReceive.cpp文件
( o9 A* K  c- ^( y
  1. #include "YmodemFileReceive.h"
    # T) t1 q0 L* X% C4 J* [- |
  2. + m' e1 M) R$ Q3 {- W! U
  3. #define READ_TIME_OUT   (10)1 x1 e' u, p3 |# v' [
  4. #define WRITE_TIME_OUT  (100)4 R' [9 N+ Z, G+ ^5 O2 G9 T7 ^

  5. * B+ Z1 d+ X% O/ _
  6. YmodemFileReceive::YmodemFileReceive(QObject *parent) :/ |- b- O# K7 p" I" z! ^$ O
  7.     QObject(parent),
    % Y# \8 P. q7 N( x& u% @% Q
  8.     file(new QFile),
    0 ]6 [: O; r+ r* P  P2 Z9 g5 @! d
  9.     readTimer(new QTimer),
    & Z" O6 @% @0 ], I- ~
  10.     writeTimer(new QTimer),
    ( t3 k5 k6 ?( g) i* o
  11.     serialPort(new QSerialPort)- F+ N- r& a+ u. K& h  ]; M- Z
  12. {
    " N. _5 D1 B% d9 z) S) @1 h. @: k
  13.     setTimeDivide(499);& u+ S, Q0 E3 s: W' }
  14.     setTimeMax(5);, q; O9 S# L; y( G" n
  15.     setErrorMax(999);" H5 s0 p3 e4 a7 X9 W
  16. , |* t6 W1 r. m% O% s
  17.     serialPort->setPortName("COM1");. d* X, e/ Y( g# a
  18.     serialPort->setBaudRate(115200);( {1 e6 |6 G1 k
  19.     serialPort->setDataBits(QSerialPort::Data8);
    2 y4 G. W# y1 }$ x5 ~; z9 A4 V
  20.     serialPort->setStopBits(QSerialPort::OneStop);
    * H# u$ E% z1 _3 H9 W
  21.     serialPort->setParity(QSerialPort::NoParity);0 _7 l! n' R8 [, }) v5 ^, r
  22.     serialPort->setFlowControl(QSerialPort::NoFlowControl);
    8 g# B3 b' p, h/ @' E" k) g' f
  23. ( F7 |6 J9 {+ P8 w* b2 m0 h
  24.     connect(readTimer, SIGNAL(timeout()), this, SLOT(readTimeOut()));! O$ _1 Z0 _% g. j
  25.     connect(writeTimer, SIGNAL(timeout()), this, SLOT(writeTimeOut()));
    , G/ q6 I0 p+ s( l" y* K
  26. }/ G4 F) L( f: j$ k6 f6 {  Y! m
  27. / Z/ g/ P0 F' q( g" M. {# l. k! C
  28. YmodemFileReceive::~YmodemFileReceive()
    " u) F* o) r  g" e
  29. {" U2 X2 r8 T+ C* p7 g* Y9 ?
  30.     delete file;/ x- C' H; n0 R" h0 n
  31.     delete readTimer;
    ) A2 f& v  x- {- n$ D% Q
  32.     delete writeTimer;
    3 q+ t; C; C4 A* T; j
  33.     delete serialPort;6 N+ N6 ~: m3 P7 N1 I
  34. }0 Z! p& o$ X( v- |0 n
  35. . a* @2 M  V3 f+ c
  36. void YmodemFileReceive::setFilePath(const QString &path)
    5 x; m' z+ a% n7 B' ]' o! ~3 [
  37. {1 \* O+ a& ^& V( d9 Y0 ]
  38.     filePath = path + "/";1 P9 l+ S( ?( }2 m5 ^, {7 v/ |
  39. }+ P8 m0 K" d/ ~- Z

  40. : m, T  H2 \1 f! k+ y* X+ g
  41. void YmodemFileReceive::setPortName(const QString &name). M2 i/ d& w% J% @
  42. {7 K9 W' N# J6 t  w* Z& z$ k5 Y9 o
  43.     serialPort->setPortName(name);3 y9 d5 S: I# k3 Q- o4 x
  44. }0 C7 G; W9 K0 k; H3 y
  45. : I' C0 e% d. v& \& F$ H$ h' k; J
  46. void YmodemFileReceive::setPortBaudRate(qint32 baudrate)8 o/ B% X' Z: p2 a
  47. {
    # M. U; G. w+ x& Z. h0 K
  48.     serialPort->setBaudRate(baudrate);% [8 _5 `/ K4 Q1 U) g* ~# L+ }. c5 g
  49. }5 D: j0 X  ]/ W* D' z( r5 n

  50. ' i0 e( s1 [: U, f( A8 G
  51. bool YmodemFileReceive::startReceive()5 P' Y$ f  G! X
  52. {
    0 ?( G' H( S4 i7 L/ q$ ~1 e
  53.     progress = 0;
    / S9 C. ]  [) H# \$ j, A% C; _
  54.     status   = StatusEstablish;& S$ b# h3 `. k

  55. 3 q3 w" N1 n4 V' y$ D! C  T  q
  56.     if(serialPort->open(QSerialPort::ReadWrite) == true)  Q6 \8 g* E  c
  57.     {
    . \& V( T- ^2 _( J
  58.         readTimer->start(READ_TIME_OUT);
      u8 p% |6 l4 o  y

  59. 1 E. G. M+ G! ^. w  x( L' V( S! D
  60.         return true;
    3 Y7 {6 e! m% }2 ]1 m
  61.     }" X% \& c6 B) ^$ j& U
  62.     else
    7 z2 o4 P# ~: e' H0 q- T
  63.     {
    ! O  M( }/ m/ S8 q$ x
  64.         return false;- t! _! H" s4 I! _$ O
  65.     }# Q' L8 S# W& b$ t7 L
  66. }
    $ _+ ?/ ~+ P1 ^4 z8 ^

  67. 2 g+ d* n" [6 l* X, Q7 L
  68. void YmodemFileReceive::stopReceive()6 C% X; I' Z0 ?9 C0 p
  69. {
    6 N8 C3 ?9 Y, E0 {' B
  70.     file->close();
    1 i" I6 X. I  t0 U
  71.     abort();" l" M& m- @2 A( N8 h' j$ ]
  72.     status = StatusAbort;
    . v( V# M8 J, j2 _4 A; ]
  73.     writeTimer->start(WRITE_TIME_OUT);
    " v( F& S+ k. Y! r" \- Z
  74. }
    9 z* q) ]" B+ p

  75. 2 d8 G$ k7 a7 ^
  76. int YmodemFileReceive::getReceiveProgress()
    ' Z8 _) a3 r3 d9 A0 S3 L# z
  77. {$ n4 Z# }% L1 H
  78.     return progress;/ y3 P# h  ^; o& x9 M# o
  79. }
    $ o0 u# S& V3 i1 c

  80. . y& T: w& D8 ?8 W4 y: h0 `6 d
  81. Ymodem::Status YmodemFileReceive::getReceiveStatus()- S1 L, v1 k& Z& m" ~7 r+ O5 {( y
  82. {
    3 l- \; [! A' I! y5 S6 N5 \- T
  83.     return status;
    / h8 v: O( U+ d% V9 u; t+ N5 }
  84. }
    $ c5 b* _6 X4 f* ?& }

  85. & e4 l5 r$ O  k! I0 _4 c) M
  86. void YmodemFileReceive::readTimeOut()
    0 i+ I$ ^" F, G4 W9 L0 n+ I  W1 E2 e
  87. {
    5 I: T9 n6 J1 z. I8 k. v- U  X
  88.     readTimer->stop();
    9 p4 Z7 g9 y' m( Q% ?$ p  b" S# r
  89. 6 O$ p, x: k* u& E! M- i" O
  90.     receive();0 i! o+ a( l5 [2 N  z

  91. % p& K1 d0 t2 W0 X$ D, l5 D# A
  92.     if((status == StatusEstablish) || (status == StatusTransmit))8 \( u5 J6 y1 a! M
  93.     {+ k* j7 m: Z2 u
  94.         readTimer->start(READ_TIME_OUT);+ S! M2 d2 e* C1 O2 f0 M
  95.     }
    . `3 c" _4 p0 Y) R6 S; E$ \
  96. }6 ~% _( E, X. {' W# Q- s) W* U
  97. ) {$ s: j; [, V2 G
  98. void YmodemFileReceive::writeTimeOut()
    & X" X. d4 e& Q
  99. {
    4 e/ E; S% H( f
  100.     writeTimer->stop();
    - ]2 G3 w, y1 i! L  a; k0 a, e0 X: p
  101.     serialPort->close();% U$ A! e1 ^9 J" Z" q
  102.     receiveStatus(status);+ K( c( b# l6 w, ?  T
  103. }7 x2 T& Y5 O! }: W) ?/ T

  104. " X. J9 Y1 ~# p. A: `$ F
  105. Ymodem::Code YmodemFileReceive::callback(Status status, uint8_t *buff, uint32_t *len)1 ~+ O4 D  [5 J( g7 C( |1 s& A. B9 |
  106. {
    # P! L4 M3 |# p3 R: t! Z$ x/ U
  107.     switch(status)! q- K5 O3 v6 U+ y# q3 S2 `+ g
  108.     {
    2 s; g4 _8 {, B( W8 O$ m
  109.         case StatusEstablish:* Z8 D. `3 x& _" C* d* {
  110.         {
    + \2 h! n% S" v3 x0 w
  111.             if(buff[0] != 0); p, ?% ?- M! M" J, O; {% }! a0 W! g
  112.             {
    ) {  \' c  y9 O# S) Q" W
  113.                 int  i         =  0;  ^! ?8 o! o1 s) a% _( V
  114.                 char name[128] = {0};
    5 y. a2 j  `; Q' v
  115.                 char size[128] = {0};
    * ]. b6 J' R. N. Y
  116. , t; n; A" b( j2 a8 e6 u% V, K5 I
  117.                 for(int j = 0; buff[i] != 0; i++, j++)
    5 g8 w# b0 ^1 O0 G8 B
  118.                 {! x) _" w7 H+ Z# e" z5 Q; v
  119.                     name[j] = buff[i];
    6 n4 c5 H, I) T
  120.                 }2 ~7 F; r6 c! \

  121. , \* q9 L  ]0 e2 |/ B8 l
  122.                 i++;
    3 D' }" Z, F5 \
  123.   \( C1 ?% F9 B" ?
  124.                 for(int j = 0; buff[i] != 0; i++, j++)
    ! A9 f# [+ e; W5 I  F5 k
  125.                 {
    , X& ^# C. ~8 }2 w7 Q3 r
  126.                     size[j] = buff[i];1 Y  @% s9 {) r
  127.                 }6 Y4 t1 M$ c2 M3 S9 I
  128. + s: w6 ?5 V  [
  129.                 fileName  = QString::fromLocal8Bit(name);% J, r( g) H  H0 ~9 v1 w7 Z- [
  130.                 fileSize  = QString(size).toULongLong();& u* J$ `; D9 C% M4 {
  131.                 fileCount = 0;$ L( [& Z( e- I' o8 M3 E8 m

  132. 1 {9 m7 A, M9 \6 x( g( B% k
  133.                 file->setFileName(filePath + fileName);
    5 ?  |1 W; C$ ^, U; S& k3 ]
  134. . ]1 @* `6 L- e! ]5 d- Z- K
  135.                 if(file->open(QFile::WriteOnly) == true)
    . O7 y5 T$ C4 [' n: [2 b6 Z
  136.                 {5 X$ J1 A: c  \
  137.                     YmodemFileReceive::status = StatusEstablish;* ]& a. |( m" ?( n" R

  138. 5 B! h# H# ^0 g4 S$ L# Y+ V
  139.                     receiveStatus(StatusEstablish);2 s. k3 o0 ?4 }! F
  140. & P1 e- A( _: w$ Y( v6 w
  141.                     return CodeAck;
    % \- t  L5 a$ w$ H3 f
  142.                 }
    % G: m7 m# B, I+ U" X+ g# E
  143.                 else+ B, j. ]/ u- x% c* S9 x& t
  144.                 {- b# A3 V; h9 |* q6 A
  145.                     YmodemFileReceive::status = StatusError;
    , D) ?* E1 F/ q* X; h5 r

  146. 0 v% _4 p- k. O
  147.                     writeTimer->start(WRITE_TIME_OUT);
    " ~# {( Z( f$ q

  148. 2 K. F3 M# A% N. m* _
  149.                     return CodeCan;  k& s) A& H* B* [
  150.                 }% ]* P* _1 O# {2 f* ^
  151.             }! S4 U: m+ z0 [5 `
  152.             else
    1 i) N. D5 o! }" C$ I
  153.             {
      ^; ~2 `# a: P" d6 |' y8 M5 v" n
  154.                 YmodemFileReceive::status = StatusError;
    7 `; T! l+ m7 m2 A. `$ e

  155. " |; Y6 a$ M+ B% T( u$ Y7 e0 \
  156.                 writeTimer->start(WRITE_TIME_OUT);
    ; ~9 N  j$ X5 x- G  w
  157. 1 m3 s8 y. ]5 z1 d
  158.                 return CodeCan;
      i1 V% _7 v1 W
  159.             }
    8 V) i  g; H1 x# }2 D; }
  160.         }* i* ]3 i" c7 ]# K' ~) h6 b
  161. % [% s& z* O( {- I: U( y
  162.         case StatusTransmit:# @/ @! g/ t9 o& o% v: X+ j
  163.         {* P$ I% h& w7 L: V& c9 t
  164.             if((fileSize - fileCount) > *len)
    $ U7 w) @' ~0 ?+ u
  165.             {
    2 ?1 f/ X( g' U' @
  166.                 file->write((char *)buff, *len);
    0 C% s# f7 Q! Q6 U1 z* E# L8 t+ R

  167. ; q7 g% s( V; }$ w) i' f
  168.                 fileCount += *len;
    ' o) a% V% m6 `1 ]
  169.             }
    * f9 T0 s+ X2 d/ B0 }( R
  170.             else( E7 r2 y& k9 G$ w- B
  171.             {2 p( V( ^* r/ g3 Y$ ~0 ~. |
  172.                 file->write((char *)buff, fileSize - fileCount);
    9 |# Y' H8 z* H4 u" b- t+ ^
  173. . z# T) X' r8 p+ s" R) `4 x
  174.                 fileCount += fileSize - fileCount;
    * j" D* B: W# Q. P5 q* V  y
  175.             }4 `! b' o/ F" m, l) T4 Y  I

  176. 6 Y. x" z* a3 g7 O- S
  177.             progress = (int)(fileCount * 100 / fileSize);$ i  S  h+ s7 J& {+ {

  178. 9 m. H$ V, @1 U0 k" U
  179.             YmodemFileReceive::status = StatusTransmit;
    ( B+ x: |, i. C

  180. 6 _4 v( j: c6 i- m
  181.             receiveProgress(progress);
    & M" \# S$ u# Q3 x! q
  182.             receiveStatus(StatusTransmit);) P9 |, s6 I) Z# {/ f
  183. 4 ?$ o2 G3 O+ I" E9 s
  184.             return CodeAck;
    * m& ]; A1 B/ w7 B0 ]9 W, c
  185.         }8 y4 F) W/ y: }- |% @

  186. " M. r9 l0 k* x
  187.         case StatusFinish:$ \; L! e0 D. l% m3 L% ?
  188.         {
    3 g# W/ T) c$ S/ |( l
  189.             file->close();+ ~! e9 U7 c/ c: J5 X& O% b, o3 ]
  190.   Y5 S+ c  j3 x% C$ O0 Z* y  r
  191.             YmodemFileReceive::status = StatusFinish;* L) t: G8 H' P0 X- C6 o$ m$ E

  192. / l/ N  m4 g% t7 |
  193.             writeTimer->start(WRITE_TIME_OUT);
    / a0 ?& y9 J% }" w1 l

  194. 0 o- z: M5 N9 g* L
  195.             return CodeAck;; V. ?8 z+ T# _
  196.         }
    & T) L! x$ L! m

  197. & T% ^: Y% k3 a/ \+ k
  198.         case StatusAbort:
    6 p" H. k& X4 D5 h2 x% u
  199.         {, w) B5 l; i1 g
  200.             file->close();
    8 k" H/ m+ R9 \7 v1 f5 l4 R
  201. % K/ X& m% k- i$ k! W
  202.             YmodemFileReceive::status = StatusAbort;
    : O: x: y- j/ n! ]& `/ ~

  203. 6 e# @7 Q. y! m  H7 f
  204.             writeTimer->start(WRITE_TIME_OUT);5 }9 k. q( L! w/ B2 [; _

  205. ) U2 I/ D' |6 [1 k
  206.             return CodeCan;4 S, k7 D2 J5 f) J: O) T% i; t: l5 n
  207.         }; O! B! E2 T! |( d& {* }
  208. 0 {/ x+ g1 m1 P0 r( P: r
  209.         case StatusTimeout:
    & o1 w7 |. p% i7 T! `$ O8 f9 D
  210.         {/ l8 @% g- y* @, j! C+ |; m6 b# \! n
  211.             YmodemFileReceive::status = StatusTimeout;# U* z; U- d' i# D5 y1 U9 u

  212. 9 Y& t! U$ H& r$ ~7 o  b. P
  213.             writeTimer->start(WRITE_TIME_OUT);
    $ R9 V4 P$ y. o  i  v5 `# O" }
  214. " x/ p" S# J9 s. M3 A7 E
  215.             return CodeCan;' u: m' Z9 @& f- ^9 K- I* }4 E
  216.         }/ w6 `+ l: F/ b" T2 E! G. ~# @

  217. 1 N4 \( e7 e( a6 Z8 @* [
  218.         default:1 T$ D% I) K1 @  j
  219.         {& `8 R# L9 U2 @$ A, M* c
  220.             file->close();! g% z/ ~7 V2 I7 g

  221. 7 F% h" l* I) f' T7 j
  222.             YmodemFileReceive::status = StatusError;' y, c  S; d+ U5 i2 J0 w

  223. ; `" \2 j1 J6 z! w; L/ z6 A
  224.             writeTimer->start(WRITE_TIME_OUT);3 J! Z/ L$ T& z: l5 K: h& u4 E4 F
  225. $ r$ h! [; s- P7 u# M
  226.             return CodeCan;$ w" G) Q/ O0 r7 B- D: r
  227.         }( c) U) ]$ i) r. x
  228.     }2 T% `. u, i+ p3 J7 [
  229. }
    , T- H; X. E1 B2 t6 e- i' y4 Y
  230. $ O0 k( V7 r  X% a
  231. uint32_t YmodemFileReceive::read(uint8_t *buff, uint32_t len)5 n# ?( v" C8 n1 s5 B. ?
  232. {
    6 h# n9 L/ i1 W8 U
  233.     return serialPort->read((char *)buff, len);: P/ |7 V! `; u3 U  A) ]
  234. }
    * v: F% i0 v2 l. Y* i0 n& [/ w
  235. 5 I4 g+ y& P/ [3 ?7 M
  236. uint32_t YmodemFileReceive::write(uint8_t *buff, uint32_t len)
    % k) ^4 {) @% T- z
  237. {" D& R$ N6 ]% O& l
  238.     return serialPort->write((char *)buff, len);9 o7 c" X1 t9 }9 o  [, e( N6 W; Y
  239. }: F$ l4 d# b1 ?) ~
复制代码
: u/ d3 ?$ O# z# R  h1 Z

( f  A6 M" ^8 |- y& [0 h2 \1 f* o( B
3 y0 s# }# c. g: B# T  M0 Q& W
8 o4 M* {$ D" J0 X0 O6 C/ I6 z
XinLiYF 回答时间:2018-3-6 22:31:26
      YmodemFileTransmit.h文件
. k. C$ B( y- M$ Q9 F
  1. #ifndef YMODEMFILETRANSMIT_H
    % e- _# j, `+ ~) ]7 j+ m
  2. #define YMODEMFILETRANSMIT_H
      p6 B5 o9 l: T' R5 K& S$ }
  3. 1 Y$ J1 }6 u: H6 G2 j
  4. #include <QFile>
    # G' K4 m# }( q+ z; u3 Q- Q9 }; v+ ^
  5. #include <QTimer># c: B+ k, T! Y8 ?
  6. #include <QObject>- w& u( H0 I3 a) s: p6 ?, a0 X
  7. #include <QSerialPort>
    : j, d6 A" S: B3 a! c# t; q
  8. #include "Ymodem.h"
    . o+ P& @9 o( J6 q# T  ]! g. M- }! G

  9. 9 S  O( w  D7 [8 c) k( A
  10. class YmodemFileTransmit : public QObject, public Ymodem
    ) _4 e; z' z3 v% X1 G3 t
  11. {1 [# t5 l* f& A" A% q
  12.     Q_OBJECT
    : \/ P# J# i% q7 B( V

  13. : h* o' Y0 w; Q4 c! x; c
  14. public:
    * J! u( |) k+ Q/ ]
  15.     explicit YmodemFileTransmit(QObject *parent = 0);0 E5 i( b% Y& F% q/ Z
  16.     ~YmodemFileTransmit();
    * C$ _: ^2 T4 X7 C; G# V
  17. ( N2 f; L3 i1 |1 C: T8 ~2 f' X
  18.     void setFileName(const QString &name);% W, U3 g) U) R5 L8 `; L
  19. $ i& L5 K5 Y& X% D. D1 O1 L
  20.     void setPortName(const QString &name);. Z8 O, q8 S5 ]" j& g* G
  21.     void setPortBaudRate(qint32 baudrate);
    4 ?; m% ?$ h- x, o$ I+ [; l3 z

  22. 4 P4 Z. s8 b! J9 n* D
  23.     bool startTransmit();
    - P; Z  f2 J; [, w( g# ?& T% N
  24.     void stopTransmit();( g  }4 X( I0 B* [

  25. . n3 i: r2 c1 B7 P2 a- j+ d+ O
  26.     int getTransmitProgress();" g: e! k- m: _% t8 u) S6 A
  27.     Status getTransmitStatus();% U% A6 ?) O: T* Q6 y

  28. ) w/ }+ R- G; ]4 S7 R7 O  r5 _
  29. signals:0 Y% p! M% S& `' I% {: P  @9 C$ ]
  30.     void transmitProgress(int progress);
    * P" Z* R( D0 w$ I' \9 |9 ]1 J
  31.     void transmitStatus(YmodemFileTransmit::Status status);
    6 R6 P8 G$ @+ O. }' P; r
  32. ) ?, J0 A4 j1 O  P1 C' B* @8 Z( U
  33. private slots:- Z- O& L& J% X* Y9 h& f2 R
  34.     void readTimeOut();
    1 U" `5 Y0 o! r7 r9 Z
  35.     void writeTimeOut();
    ! ]  }4 U- `# d9 W5 Z

  36. : ?+ u/ F* s* O7 [2 D3 L! a
  37. private:
    3 f3 S" V9 x' ~- i- H: D
  38.     Code callback(Status status, uint8_t *buff, uint32_t *len);
    3 S& m- i; p8 l) x5 ]

  39. 6 R. }" ~, f) n' ~- h% c7 U" I
  40.     uint32_t read(uint8_t *buff, uint32_t len);" ]! b1 _  X. E# Y. i7 F
  41.     uint32_t write(uint8_t *buff, uint32_t len);
    ! ^2 h5 R# X# L9 B. n( V) S

  42. 2 m% r5 a) E+ j
  43.     QFile       *file;3 A+ U9 `  @1 t1 N
  44.     QTimer      *readTimer;
    ( g/ @0 o3 G" c# ]0 R5 J5 g
  45.     QTimer      *writeTimer;
    ' H# i8 c1 _  Y( g2 ]2 W
  46.     QSerialPort *serialPort;
    2 a/ Z9 |6 `5 W+ F% [/ a7 j
  47. 0 l" Z" Y4 i/ }' R4 l. [. o  R
  48.     int      progress;. @# h7 U  n+ q: V4 R: q& l. b
  49.     Status   status;  m; ~# U$ X7 X" l0 y8 O; X5 i
  50.     uint64_t fileSize;" k1 A5 k" y' Z- I+ z0 v) \. U( F
  51.     uint64_t fileCount;
    4 s6 D# j6 {( n6 P# {( \* O
  52. };$ Q$ L9 `5 Z" ]- u

  53. 7 w' ]' z9 k  I" ?9 G1 d
  54. #endif // YMODEMFILETRANSMIT_H3 g8 S. U- r5 Q; T2 J+ ]
复制代码
; Q* |8 a% @  J6 n8 y! `
      YmodemFileTransmit.cpp文件0 w& \' O5 B; \+ y1 S
  1. #include "YmodemFileTransmit.h"/ @/ _4 Q5 A" H3 S: z
  2. #include <QFileInfo>5 l$ o* I: c. q. G8 V. i
  3. 8 f/ n4 }3 ^8 h" w" P
  4. #define READ_TIME_OUT   (10)! I$ B, g' N8 R5 E. W+ c7 i
  5. #define WRITE_TIME_OUT  (100). q. [0 _, H1 Y: f
  6. 8 x! m: c/ i2 Z9 v
  7. YmodemFileTransmit::YmodemFileTransmit(QObject *parent) :4 G& i8 f, }6 @, `- y. D
  8.     QObject(parent),6 N4 B( ]  K+ _/ l) n4 ?
  9.     file(new QFile),
    % J4 ~7 x* o% [
  10.     readTimer(new QTimer),
    1 z% i2 ]2 {0 G9 K- \8 b5 @2 f. q
  11.     writeTimer(new QTimer),2 D, s$ H8 C7 y' J2 Q( C6 D
  12.     serialPort(new QSerialPort)
    1 K- _/ t* G& p6 v9 R6 ]/ v
  13. {
    % ^, o3 B& i. R" `; u$ e0 Z
  14.     setTimeDivide(499);
    ( x2 q" P( u0 a  ]
  15.     setTimeMax(5);4 F5 d. A" X5 _2 D
  16.     setErrorMax(999);- R3 W" r$ {7 d- p

  17. ! j! k% C, [+ q7 `
  18.     serialPort->setPortName("COM1");
    : v# K- w5 ]3 z
  19.     serialPort->setBaudRate(115200);* p: f* u8 Z- e: n$ F4 r
  20.     serialPort->setDataBits(QSerialPort::Data8);
    % N. }  e3 M3 o6 o5 k$ F" l
  21.     serialPort->setStopBits(QSerialPort::OneStop);
    ) }# {4 H9 F- n4 T) d
  22.     serialPort->setParity(QSerialPort::NoParity);
      ^$ b# y  ?. y2 a
  23.     serialPort->setFlowControl(QSerialPort::NoFlowControl);5 A( C1 w! _5 {' N$ H7 [
  24. # K% @5 S5 J7 k. C5 W. C4 F6 \
  25.     connect(readTimer, SIGNAL(timeout()), this, SLOT(readTimeOut()));5 P8 e/ W$ ?* ?: p- G
  26.     connect(writeTimer, SIGNAL(timeout()), this, SLOT(writeTimeOut()));
    - W" p) L8 Y( l; D3 ^3 k  b
  27. }
    / S; G# T' z  T

  28. 3 c8 v- G: A9 u+ q
  29. YmodemFileTransmit::~YmodemFileTransmit()+ z* j  j, q* P9 p, u& `$ Y- Q4 J5 g
  30. {
    ! c7 U8 q3 D5 \' T9 f: I
  31.     delete file;/ N+ ~7 T( b1 X, s" |; u- O1 U8 C
  32.     delete readTimer;$ v. k' S/ p/ ]) G0 g3 R
  33.     delete writeTimer;7 E+ S7 D, T( }3 b# h: R3 O
  34.     delete serialPort;" N! d; d- o3 M9 i
  35. }9 _  G6 Z7 ]9 \9 U) e
  36. $ \2 M! V9 |- ^' T7 C
  37. void YmodemFileTransmit::setFileName(const QString &name)* u6 N& B- X0 a. y/ q
  38. {6 B8 w5 j) T2 z0 S  L1 M
  39.     file->setFileName(name);
    4 z/ J) M' W# h6 K. J, v) p, O1 B
  40. }
    : g" n" ~/ U0 y9 X% G
  41. . n% Q. s6 ]$ ]! [4 Y% j
  42. void YmodemFileTransmit::setPortName(const QString &name)8 Z; [0 n1 A8 k: u2 N
  43. {
    - E+ S8 w7 G/ P* w( n
  44.     serialPort->setPortName(name);
    2 ~& \0 J: {5 @1 |) M) n: \5 ~) M
  45. }0 X" v: F5 y* L. ?0 ^/ }

  46. ) t  b5 x8 l. s! M2 U
  47. void YmodemFileTransmit::setPortBaudRate(qint32 baudrate)
    7 [  y+ }2 u7 @( ^1 A
  48. {
    5 ~( i& Y5 {" k% n% S8 m
  49.     serialPort->setBaudRate(baudrate);
    / I. D. F/ G$ {) @, r) b
  50. }+ [: h3 ~  q0 a

  51. . A( ~8 w$ p1 X7 ]
  52. bool YmodemFileTransmit::startTransmit(). e0 ~* {' F3 g  j) z
  53. {
    6 u  V8 ?  @# f. \; ^
  54.     progress = 0;% V, }+ ?9 U* P  ^  ?# O2 K2 B- z' U
  55.     status   = StatusEstablish;7 n: B0 W6 q* n9 W5 [3 o& K
  56. * E- Y4 z0 c" K7 K
  57.     if(serialPort->open(QSerialPort::ReadWrite) == true)
    0 S. |! v  K) i) |" f3 L
  58.     {
    0 k  S+ [5 e' \. U
  59.         readTimer->start(READ_TIME_OUT);, T$ d9 a+ S( \" Z( [9 |
  60.   H  M0 q" w: L) \4 q. W1 }
  61.         return true;
    - R% s, B# I- e% r
  62.     }
    : Z6 S0 Y6 R& G4 m% B
  63.     else
    3 L8 C( l+ ]# ^5 j8 h; {! g
  64.     {- u* Q4 a/ U8 K1 `, Q
  65.         return false;
    1 r/ y; S  F% c: c
  66.     }. w  ^9 a2 q5 n3 S9 _, S
  67. }1 R+ M) J9 ]" p; w; P

  68. # v( X7 ]% ]2 D
  69. void YmodemFileTransmit::stopTransmit()
    . }- s; X/ K8 \/ {1 O
  70. {! ?* [" w+ c8 r
  71.     file->close();
    & W3 T! _. W% e+ e% g8 i! H, R
  72.     abort();. @, r0 Y' {: ~) H" Z# J$ _. q
  73.     status = StatusAbort;
    % r' m7 v; G1 D* e9 W
  74.     writeTimer->start(WRITE_TIME_OUT);, q+ ^4 N- i' }* h
  75. }6 S. Y( J5 g# P/ X7 L; ^) k+ n

  76. 2 _* z+ s' K! t- f- p* J7 M+ H* U4 N
  77. int YmodemFileTransmit::getTransmitProgress()
    " X- G1 \; Q0 n8 s3 N8 e/ ^
  78. {# i6 G. X+ K( ?* d5 f3 t' H$ r6 q
  79.     return progress;. I8 N2 }% _+ _7 ^
  80. }1 ~) J0 \* {5 j1 P
  81. 9 G0 s+ \; Y- s+ o# }) g
  82. Ymodem::Status YmodemFileTransmit::getTransmitStatus()
    5 @' J0 B% Y! X- R- s
  83. {
    1 z$ x' I* j! K; V  A( r: K
  84.     return status;4 l; i3 e+ U2 q+ L. N' [. w
  85. }
    1 n5 ]: ~2 z' f# s0 X0 @) v
  86. 0 W3 _; Q2 U: P+ o
  87. void YmodemFileTransmit::readTimeOut(): m  N5 t" y: M- L7 x
  88. {
    # D) ?* C) V, T7 }# l, x+ S3 p6 A
  89.     readTimer->stop();, u" R5 _7 a2 @5 ^

  90. ! l5 U; Q7 B: g; t! X- D: ?+ O2 f
  91.     transmit();
    ' i1 _' t! X6 A9 Q8 J! M, `* I
  92. ) n! f+ {, z9 d, D+ o4 f. a- E
  93.     if((status == StatusEstablish) || (status == StatusTransmit))
    4 m: B3 @' o6 p) l
  94.     {
    ' M4 }: Z" r+ X8 u% d
  95.         readTimer->start(READ_TIME_OUT);
    ( M! ]$ e3 A8 X" ~" ^
  96.     }' ~- X; |5 X# j/ P( ~) A+ B3 @
  97. }
    ) p$ C- d! P9 {, U' |+ a
  98. * Z) J; Q# y/ Y" _; X+ K( ]" H5 I
  99. void YmodemFileTransmit::writeTimeOut()! h9 n$ }1 A0 A* G
  100. {9 c. e$ [& Q- c$ R& k' ]& Z, d* |
  101.     writeTimer->stop();
    , F0 \9 C1 S, `3 y( R, z
  102.     serialPort->close();
    . ?" U3 N. d9 q2 a+ c5 r5 i& k
  103.     transmitStatus(status);! E% e; I0 S2 n; w: D# _
  104. }
    2 B8 P. _7 Y( c2 I  D( ]0 ]5 M; J

  105. * H6 w: {- ], j2 g. g( j! J0 R
  106. Ymodem::Code YmodemFileTransmit::callback(Status status, uint8_t *buff, uint32_t *len). ^3 {( s, Q/ m* _1 r( s! O
  107. {' B% |8 {: a9 R$ U. H4 U
  108.     switch(status)
    ( K7 M! f$ B- v7 j2 G: s8 a
  109.     {
    3 A  i0 t' ?2 {# A% c  t' }
  110.         case StatusEstablish:& v! J5 G) w  p, k. }
  111.         {) ]) X* W6 @( ]+ w
  112.             if(file->open(QFile::ReadOnly) == true)
    1 k# a( m- \; F( `
  113.             {
    : n" X! l6 `7 e6 u5 Z: X
  114.                 QFileInfo fileInfo(*file);
    & p0 b' X1 w6 |
  115. + ~( H( J! W1 l
  116.                 fileSize  = fileInfo.size();
    4 u; w( \  Y$ F7 A8 j
  117.                 fileCount = 0;
    ' Q/ e- y, Y: C, b

  118.   h3 {8 J' K$ A+ U! l" g
  119.                 strcpy((char *)buff, fileInfo.fileName().toLocal8Bit().data());- @: b' ?; G, Y. R1 R7 B. G. K* \; X
  120.                 strcpy((char *)buff + fileInfo.fileName().toLocal8Bit().size() + 1, QByteArray::number(fileInfo.size()).data());
    9 `1 i7 r" L' E6 a, k

  121. ' e! n  K( Q1 g' B
  122.                 *len = YMODEM_PACKET_SIZE;' A' K. n' \: u1 n8 b
  123. : @0 F) [- i* Y$ S. F* x
  124.                 YmodemFileTransmit::status = StatusEstablish;1 `/ H2 W( D. Z; \( y- ?0 N; N3 s

  125. - D4 r: X: m% N- ?2 `' q
  126.                 transmitStatus(StatusEstablish);
    1 e6 u: E, W4 G4 @" y
  127. - a$ z3 q) N8 A; A! }+ g+ U9 g
  128.                 return CodeAck;
    % u6 z, t# u' ~" M' X3 X2 `# D; O  _
  129.             }
    6 A/ [0 e8 j, P( o/ F3 y2 I4 r
  130.             else
    & k9 M7 F8 w* g; r+ h9 B
  131.             {
    0 c, w% t8 n9 o- Q
  132.                 YmodemFileTransmit::status = StatusError;
    # W" X3 {# W, A9 j6 U3 k

  133. ) {/ I$ A1 b4 U" ^3 p
  134.                 writeTimer->start(WRITE_TIME_OUT);
    , V! g! G6 s4 V5 d

  135. % I+ |* U' j5 Q( v& T5 w
  136.                 return CodeCan;
    5 ]& z7 m% \+ [# R, y
  137.             }
    ) I' j* L7 p6 h) b4 M% g! p
  138.         }% k0 ?* ]$ z' O6 a2 b* F
  139. 8 c5 t! o7 r% u1 A* e
  140.         case StatusTransmit:/ Q9 v% p0 d( [7 ?6 N& C
  141.         {
    2 |+ K4 o- u: o& t7 V
  142.             if(fileSize != fileCount)
    3 O. q1 R6 @4 n$ M% e: n" }
  143.             {
    - t: g- |* W0 r/ s( w' d) }
  144.                 if((fileSize - fileCount) > YMODEM_PACKET_SIZE)
    4 m, D7 G& t. V( {
  145.                 {
    2 d3 `5 I7 ^8 {' }  }# N' C. _. q
  146.                     fileCount += file->read((char *)buff, YMODEM_PACKET_1K_SIZE);
    % s; V# ]8 C4 `5 c0 x
  147. 7 T7 I' N# J% q
  148.                     *len = YMODEM_PACKET_1K_SIZE;/ b+ ~& q' ]7 C& }2 o
  149.                 }7 I5 h: B' @# g% F
  150.                 else
    + c# A. S& l8 ~, _- v! l$ Q; x
  151.                 {/ }2 k. P1 K: t2 C
  152.                     fileCount += file->read((char *)buff, YMODEM_PACKET_SIZE);7 M9 B( \! n7 I: s: G- P; Y3 n
  153. ( l! P: N5 C  M8 I1 W- N9 S+ F
  154.                     *len = YMODEM_PACKET_SIZE;
    & U) Z9 h* {: W& N+ }' J
  155.                 }
    / t, ]: O+ O( b  f9 Y" l# a
  156. - c0 G. a+ i5 Q
  157.                 progress = (int)(fileCount * 100 / fileSize);. U. {. y8 d6 G2 [
  158. 1 d$ N- F5 m. G! o# {8 g
  159.                 YmodemFileTransmit::status = StatusTransmit;
    - b# |  g1 a- l: y; W& n
  160. , w; x' s( I% b2 G8 S
  161.                 transmitProgress(progress);* M( y% a& i6 c1 @
  162.                 transmitStatus(StatusTransmit);
    * f, e/ T/ T! \9 c0 m$ p4 _
  163. 3 h% ~3 G3 L6 E; u7 M7 z
  164.                 return CodeAck;; a# P3 {1 I% h% [8 z, f
  165.             }
    0 A, O# B2 j6 }. q$ m. [
  166.             else
    7 D2 N; k  ]# c& A5 K7 ^% {! A
  167.             {2 @; S7 _  j' U  }% `6 m
  168.                 YmodemFileTransmit::status = StatusTransmit;) W) C) S! V( h

  169. 6 m4 Z/ k7 m4 o5 X% _. Y( |
  170.                 transmitStatus(StatusTransmit);
    " d) K7 y9 M4 ~& R+ q4 G

  171. + p7 w; g; O6 n' S: v
  172.                 return CodeEot;* N6 E# g- O' f) y  J' ^
  173.             }
    ( }# ^& `" x3 O- _9 l
  174.         }' v5 Z2 b9 @- F. Q
  175.   B4 M" D" A% T# e2 A% S
  176.         case StatusFinish:3 R7 R7 T! k2 M: L4 K* A3 K% K+ ~% R
  177.         {
    + n+ f( ~- O6 P" M% O9 g
  178.             file->close();
    1 d* |7 L; d( L) \- o' I
  179. & \/ y! S. G* @3 d$ f' g- L
  180.             YmodemFileTransmit::status = StatusFinish;' |: d2 V( x4 ~" H2 J) s

  181. . F, i2 s0 T6 a7 i; v& Z  W
  182.             writeTimer->start(WRITE_TIME_OUT);
    ) \9 G& h) @; {* w, m
  183. , v/ W8 M- E2 F# ]
  184.             return CodeAck;4 h5 N8 b# ]9 N: B
  185.         }: R. L+ L/ C" \' F4 l4 `
  186. 1 U! I5 S- O, ~% m+ a
  187.         case StatusAbort:
    $ s, [$ E" J' @' }1 o
  188.         {
    # n# M, h; l  u: M- c( h
  189.             file->close();# J* H& g" L7 X1 d

  190. 6 r0 m1 G( }5 D" E3 b- E1 r
  191.             YmodemFileTransmit::status = StatusAbort;/ ^* X. A' h' K# O; \
  192. 2 s8 R, I6 f0 [5 F( ?' \
  193.             writeTimer->start(WRITE_TIME_OUT);
    1 n% Q3 F7 w3 o" m+ `! Q* W
  194. 0 P" D; T3 S% c/ a; P" d1 H
  195.             return CodeCan;# I5 |1 c% `+ F; v
  196.         }
    ' k# O* y+ N0 F! z
  197. 4 `4 N1 Q  c2 x$ |0 ]4 H
  198.         case StatusTimeout:" E) l- B. z! f, G  O! `: q/ v
  199.         {+ f6 R' v( z% C1 m
  200.             YmodemFileTransmit::status = StatusTimeout;) o, o9 l  u; X0 j# K' D% M( L7 }

  201. ! o/ u/ e$ C9 |$ ?1 W
  202.             writeTimer->start(WRITE_TIME_OUT);
    $ p0 w4 c; J/ ]
  203. - F, |9 ^7 q& I
  204.             return CodeCan;
    - ^2 t* @. _2 M
  205.         }
    8 I6 ~8 E' B! R) p0 S; U& P" u0 U

  206. / h1 _' t' Z% a# r/ K! `$ T3 x
  207.         default:
    0 `4 ^/ o& w+ l/ \# L5 c* k
  208.         {
    3 @7 G$ F! B/ C4 O
  209.             file->close();$ A) K5 a6 P: e: B! [
  210. 2 [# o. l  m# ?* V8 }8 U3 ]
  211.             YmodemFileTransmit::status = StatusError;
    2 u3 C: K( E* T5 g* A7 r

  212. & n0 o8 U4 m2 `* f0 `
  213.             writeTimer->start(WRITE_TIME_OUT);
    : |; W% ~! h# Y6 T9 p% ~
  214. , C% G* s( O, W
  215.             return CodeCan;; K; Q1 `7 Y1 }. g/ s
  216.         }/ k" S/ o3 _, L4 d1 [
  217.     }: |9 [( U9 h% O# J5 Z
  218. }* |  K+ s  Y* ^

  219. 0 O% J# B$ w8 q5 c
  220. uint32_t YmodemFileTransmit::read(uint8_t *buff, uint32_t len)
    - K6 j, l7 a1 x
  221. {
    4 l  o, ~9 B+ X: W  U
  222.     return serialPort->read((char *)buff, len);
    . P3 c. r, B% W/ W9 D' g, V  x, ^" D! c
  223. }1 n% G  z! K+ K+ b* l& S, ]" C
  224. 7 j' o0 N  h9 Z$ A
  225. uint32_t YmodemFileTransmit::write(uint8_t *buff, uint32_t len)# m$ V* [7 ?: b% o7 g$ k% l
  226. {
    ; V5 j4 }7 Q5 L) Y
  227.     return serialPort->write((char *)buff, len);
    ( x3 t* c! y) ^$ s- i( {$ g4 g
  228. }
    ! p/ L1 p. B! B  U
复制代码

) U6 U, R7 R( @" ?4 y( ^) t: n% C( v, W6 p5 E# u' s1 ]

3 h" b# I2 `9 F$ @  \
" h6 H& @1 \' k1 B
  j, {. M5 `& X0 T
XinLiYF 回答时间:2018-3-6 22:32:05
      widget.ui文件
5 U9 \$ D. J! |3 u# a8 o; ?, f
  1. <?xml version="1.0" encoding="UTF-8"?>, D# c+ F: t5 f
  2. <ui version="4.0">
    1 W; C& j8 f* h$ R* ]
  3. <class>Widget</class>
    6 C3 z5 g' C# g/ l$ [2 f
  4. <widget class="QWidget" name="Widget">: t7 d6 J7 G2 U- r! ?% X
  5.   <property name="geometry">/ k' Q; Z; ^( A' D
  6.    <rect>% A' H" K+ Q; {/ D5 [6 J
  7.     <x>0</x>" b7 ?( w' m, T( A6 W1 N0 f( e0 o8 F
  8.     <y>0</y>
    9 g7 ], j- J9 {" f3 E; h- O+ v/ d1 W
  9.     <width>444</width># p/ r( g0 y. i$ E+ V- a$ }4 V+ p
  10.     <height>255</height>
    1 b6 D# {; v1 T. T! `6 f. m
  11.    </rect>, S" `8 v8 K$ G/ Q
  12.   </property>
    , o: W8 U% A0 ~5 ^0 t5 J
  13.   <property name="minimumSize">& n0 K3 {4 E$ f8 |0 V
  14.    <size>8 V; V/ k1 n$ R
  15.     <width>444</width>' q8 {" J4 C5 a( `5 L
  16.     <height>255</height># X; d( d0 j* k7 @$ q- {1 z
  17.    </size>
    / k- l$ x$ P) d2 l8 ~8 ^
  18.   </property># f7 p4 g' G) ~. O( F
  19.   <property name="maximumSize">, [; g! x" S2 _# V9 ~
  20.    <size>5 w. Y# S5 g0 ^. d' _7 d1 G8 h% O
  21.     <width>444</width>
    7 K& g7 a7 \7 z/ K0 {  [
  22.     <height>255</height>* @+ l" ^$ s2 W
  23.    </size>
    . o. T% @' o1 Y* O
  24.   </property>
    ; e$ q* }3 H5 V( Q0 }/ n& r8 E
  25.   <property name="windowTitle">
    4 q0 |8 ?& G+ n0 ~) y* ?; B
  26.    <string>SerialPortYmodem</string>
      s0 q  G& K% p3 ~  O6 B
  27.   </property>, n9 t. U. ]6 ?$ `8 p* P
  28.   <layout class="QVBoxLayout" name="verticalLayout_3">8 M4 A" @" p8 }7 [# M( {6 T6 j
  29.    <item>
    . R# b/ g8 O6 o# R
  30.     <widget class="QGroupBox" name="groupBox">
    6 Z$ Z1 d- ]$ e8 _
  31.      <property name="title">) a- E4 D1 g  Q1 Q7 ~5 D- Y
  32.       <string>串口配置</string>
    0 M. {6 z* @8 ~
  33.      </property>6 x6 w9 R7 [! ]5 {; W
  34.      <layout class="QHBoxLayout" name="horizontalLayout">
    , ?, {  o7 `' a( {0 t6 \  ~# q
  35.       <item># l+ i( E- T$ E3 G
  36.        <widget class="QLabel" name="label">
    8 q8 Q5 N$ {( h5 p6 e( H- x5 [
  37.         <property name="text">
    , v. ^) _8 B$ o: i1 S
  38.          <string>端口:</string>; v  Y0 R, U  z' k0 v3 p+ O% o
  39.         </property>% }. f" `( {% ]3 Y, X
  40.        </widget>/ `6 h& n8 z; x' N
  41.       </item>
      c3 f# m! J1 |# H) v/ @, O8 b
  42.       <item>
    ; w" W' u( t! O/ k1 ^% O' \9 Y2 \" R" X2 I
  43.        <widget class="QComboBox" name="comPort">
    ! S' H1 V. y! }. Y' F( W# N, X/ Q! N
  44.         <property name="maxVisibleItems">
    ; Y7 r. y- Z; f* G2 ~
  45.          <number>12</number>
    6 r: K( {$ I6 x; K9 T4 X( [
  46.         </property>: I7 s2 n" {5 P1 s4 K1 a
  47.        </widget>( ^9 [1 z1 f. b  a. u5 p  O
  48.       </item>
    $ |. j, U1 T; L& s# G  ~: |; C( u
  49.       <item>3 W) t# ]6 g+ Y+ j. `
  50.        <spacer name="horizontalSpacer">
    + H0 J# g2 z8 T: t9 ]
  51.         <property name="orientation">/ h: l9 Z+ \7 N; h6 G2 c$ f) H* P3 m
  52.          <enum>Qt::Horizontal</enum>1 r! T4 ]) F; x: {
  53.         </property>& u' h% S; b: V! h
  54.         <property name="sizeHint" stdset="0">
    ; a/ I) X' U9 {! y
  55.          <size>6 S$ L" V  L' J/ c4 x0 U1 ?' L
  56.           <width>40</width>
    ) O+ @& R4 X8 X: Z8 {
  57.           <height>20</height>
    / U* V, J5 ?+ c2 X
  58.          </size>1 |! j# }% Y# o8 T3 o5 `- C( Z7 m
  59.         </property>5 m* C" e- V% c
  60.        </spacer>1 f3 f2 f* }1 k  g3 D2 ]( j
  61.       </item>
    " _7 r! h% ?" K1 @2 Q
  62.       <item>
    , h3 H4 L+ e; H  m- W
  63.        <widget class="QLabel" name="label_2">
    ( O1 I5 O* ^( R+ o0 U  P  c! {
  64.         <property name="text">
    6 k2 d* R4 J* i3 ], R
  65.          <string>波特率:</string>
    * T/ K5 x& @( f( ^/ W- f5 F' U
  66.         </property>6 e9 `( X! s' Q- k3 c7 s( s# s
  67.        </widget>1 P, f$ b# W: F1 D7 b1 {4 D! x$ i, F$ W
  68.       </item>
    + Q8 D3 t- Z% w3 E$ E9 F- {
  69.       <item>9 w4 O& G4 W& A, A" F" d' G) C0 u
  70.        <widget class="QComboBox" name="comBaudRate">' F0 G- ^; w2 Z( Q8 ^$ a0 n
  71.         <property name="currentText">4 X  r( H2 n" A3 ]- B% h
  72.          <string>115200</string>
      v% ?$ J' E: u4 ^
  73.         </property>0 [+ e1 T( H  j! X8 s
  74.         <property name="currentIndex">: E. ?2 A3 W! F4 `+ R9 d5 I
  75.          <number>3</number>
    # _3 A8 k; s+ V3 Q& m, d
  76.         </property>
    % h# N# P6 f) {# ^4 K% G4 g
  77.         <property name="maxVisibleItems">* r; `9 _3 D* R5 Y1 ?2 y( a) s  B
  78.          <number>12</number>
    + Y1 M* Z. C7 j( l5 K
  79.         </property>* f) g  d& k/ [. o( u) F
  80.         <item>
    + \( `& g1 j) I8 u$ H
  81.          <property name="text">; Q4 L. N; u/ t) `# G5 }
  82.           <string>921600</string>( @, T$ y1 P" W/ H) }  y
  83.          </property>- [# C, G$ h' }% A- l! K0 Z
  84.         </item>; b& N8 n: |0 [5 X8 x
  85.         <item>
    6 y$ Z' y: G1 @8 y( B7 O
  86.          <property name="text">
    : L- N3 l2 \9 ?7 ]+ K# `% J, v
  87.           <string>460800</string>0 d6 D% G1 @2 s3 s( R
  88.          </property>; f5 R8 |1 [/ H4 i
  89.         </item>2 o5 b- K2 g+ j! n  G* o
  90.         <item>
    * [6 x8 ^. g, L% M( x% Q
  91.          <property name="text">
    & |+ p% T. l) ^: k( q6 M* d( U
  92.           <string>230400</string>
    . m: L/ S# s$ @, U6 }: I" v
  93.          </property>( `4 t6 a# a0 i
  94.         </item>: m4 h: B+ R/ E1 o1 h
  95.         <item>- {  L7 E9 k0 l0 O* c
  96.          <property name="text">3 c6 d2 d$ b3 W" |: F$ ^
  97.           <string>115200</string>, z4 V1 G9 n! p) s
  98.          </property>
    % n4 F! [3 B2 Z* I5 \, W
  99.         </item>, l! v2 }/ i3 U% b
  100.         <item>
    8 m+ l( R* V! t$ W
  101.          <property name="text">0 z/ o5 ^$ Z- [! D# h
  102.           <string>57600</string>: [% x8 e1 _4 G% O' _+ y# U
  103.          </property>
    ) c7 o* W2 X& k+ q  Y
  104.         </item>
    % q7 s' c7 @4 E8 Q+ O/ y
  105.         <item>
      n+ ?, I9 L+ y& F! l, N
  106.          <property name="text">
    ( d+ F( [4 k' g% e. s
  107.           <string>38400</string>; B" w& [+ v8 _. P+ {+ ]) s* y
  108.          </property>
    / X4 n) W5 f+ r$ _; l" m
  109.         </item>" x  R& R/ q& l  w
  110.         <item>$ d( X4 `% K2 H3 |, |6 @3 P& k
  111.          <property name="text">
    # A. @5 L- z% \7 l6 N
  112.           <string>19200</string>
    6 p' F$ U1 Y' E5 f# Z% P
  113.          </property>
    % B4 \' k% u3 m2 d
  114.         </item>4 l- N: V$ Z9 _( I
  115.         <item>" p. Y# R. Q% {' r$ C: N! F
  116.          <property name="text">
    & Q9 X0 L+ |# z% X( ^  Z- g
  117.           <string>9600</string>2 U8 n/ {" y' H' n8 e
  118.          </property>5 k9 S! w9 |( Q* A* y( `# \" O" Z
  119.         </item>
    $ X# K! s- M8 z3 [, p" ]
  120.         <item>
    - x% O2 R$ s$ x
  121.          <property name="text">& `! c7 d" O9 J7 E1 ~: `
  122.           <string>4800</string>
    & r& a1 I. z6 Z; d7 R5 {
  123.          </property>2 N. M/ S$ h7 ?. b$ M
  124.         </item>% ^& U2 p( j- @2 S1 _
  125.         <item>! J# U) B$ A( I& t- M  R: W9 D
  126.          <property name="text">& e% w: i( d  K  I0 T$ i
  127.           <string>2400</string>
    & J7 A: c0 _# {% O+ x( z: P/ u
  128.          </property>1 s6 [& P2 i8 V
  129.         </item>9 I. j2 R1 j" L+ O
  130.         <item>. b# K: t" [5 E" q0 s8 \
  131.          <property name="text"># X. E/ P/ X, Q$ n. B; z, R' u
  132.           <string>1200</string>' `1 A; p5 e& W0 F* `
  133.          </property>. B& }' v5 J$ w2 f: a1 ?% G/ A( M
  134.         </item>
    2 G; t3 u0 {9 O- {
  135.        </widget>
    0 R$ J- [8 i% x
  136.       </item>0 S' h+ `; a; h6 s/ x. p6 d" I3 w9 y
  137.       <item>. h- W' b% ~. r% P
  138.        <spacer name="horizontalSpacer_2">
    ; K( B! A5 w2 n% _* a/ k1 |
  139.         <property name="orientation">  s7 T$ M. g8 }
  140.          <enum>Qt::Horizontal</enum>
    # Z' h/ _2 m3 X2 {: y
  141.         </property>
    9 ?  C. x; i2 m+ G6 W) x/ ?  }
  142.         <property name="sizeHint" stdset="0">' H5 `" p+ Q, p8 f/ o: Z1 k
  143.          <size>) _8 C( d* T, }8 S
  144.           <width>40</width>
    / d& R( Q/ \. _8 Z) X
  145.           <height>20</height>8 a* l7 O  H4 |# Q
  146.          </size>
    # K/ ~6 F& V/ l4 H' r+ Y
  147.         </property>
    7 C4 ^% W! {- M; @+ B. o
  148.        </spacer>6 h) D. o) Q# S$ `6 q8 j; H) W
  149.       </item>% l2 ?8 _0 d; J. r' A! c
  150.       <item>
    ' s. j2 \' ~  b6 M
  151.        <widget class="QPushButton" name="comButton">( t9 z* B* ~1 ?
  152.         <property name="text">! G7 G8 P1 A  P- h" O
  153.          <string>打开</string>
    , M2 O1 M* ^8 m
  154.         </property>6 A& |$ A% p: g" I' N! R  _
  155.        </widget>) l( ^1 }* r! M) y$ b
  156.       </item>' s; m# }2 b  ^* }# |/ {  v
  157.      </layout># P7 G  U% H6 E4 X
  158.     </widget>
    * o* A! w* A! c& M* q8 ?- q$ }
  159.    </item>
    2 Z. F$ Z+ D' |) u  t8 Y
  160.    <item># S5 D  V/ m/ [# V% @, }4 |, M
  161.     <widget class="QGroupBox" name="groupBox_2">
    ( m. Y: D8 D2 v' k% ^
  162.      <property name="title">+ x7 S; ^( }$ g, ~& [5 I9 n, L
  163.       <string>文件发送</string>
    % j  G$ R1 b8 b; H8 Z' V$ ^
  164.      </property>1 }+ E0 j3 z/ e8 d- a
  165.      <layout class="QVBoxLayout" name="verticalLayout">
    % N8 t0 M) d% X9 U# ^2 E* n* h
  166.       <item>1 G( A8 \; ?' }# a5 {7 P
  167.        <layout class="QHBoxLayout" name="horizontalLayout_2">
    # A, @4 Z' a( k: G2 @1 O: [
  168.         <item>5 s3 w" b& h9 P9 \4 f3 U8 j' O
  169.          <widget class="QLabel" name="label_3">1 [' q6 M3 x7 ?( F- {: P& m
  170.           <property name="text">6 H! @; I" L5 l5 X# F8 M, G8 ^
  171.            <string>文件路径:</string>2 v6 i  G1 y( y
  172.           </property>
    0 k: ], H% ]" I  @0 `1 L1 |0 I
  173.          </widget># k8 [  ?& ?$ c7 Z. t8 x: O+ {: g) |
  174.         </item>
    8 t, J" ~5 C7 r- ?% |
  175.         <item>( ?$ `8 j$ n4 B! ?
  176.          <widget class="QLineEdit" name="transmitPath">
    4 y& n5 c: p7 P# a# I( c
  177.           <property name="readOnly">
    6 u* r# x$ z: j0 ?
  178.            <bool>true</bool>) Y% C, a, Z& U$ u% O
  179.           </property>
    9 z& N$ [/ o, @; D* u
  180.          </widget>
    % s- U6 Q/ K, a$ @1 L3 A1 X
  181.         </item>9 A) l# ]; d! K  Y/ h& x1 T
  182.         <item>
    ( u, v. z( w' P
  183.          <widget class="QPushButton" name="transmitBrowse">
    4 m) _7 K+ |9 c
  184.           <property name="enabled">
    7 V5 C* v7 R  n8 w/ O$ p2 d) g  A! y9 m
  185.            <bool>false</bool>
    7 ^* C3 q+ ~0 I. G- K5 ~7 }
  186.           </property>
    6 S8 [# e0 \; ?
  187.           <property name="text">$ r( b; E  f4 g
  188.            <string>浏览...</string>
      ]8 Z$ G! w: ^3 U2 X8 a
  189.           </property>
    4 ]3 Q8 i; h! B$ `2 Y: e  e4 J" v
  190.          </widget>5 V% {5 B. ]4 x8 o
  191.         </item>
    ' {+ l% J; L8 Q
  192.         <item>
    6 |, l) [5 a' e6 l1 u. G! h
  193.          <widget class="QPushButton" name="transmitButton">+ L+ t$ M/ t3 I2 h9 a; A
  194.           <property name="enabled">& h" ^2 i' j- Q2 Y7 I1 }( x
  195.            <bool>false</bool>
    * s4 ?  C* J/ X( |4 H8 b' R
  196.           </property>
    + `4 N- p  d5 B
  197.           <property name="text">* k5 Q8 S! o1 p# s" i
  198.            <string>发送</string>
    0 T+ U$ p% I4 J* N8 a" D$ y1 o) x+ P
  199.           </property>
    * d- _# y0 S, n4 c
  200.          </widget>
    : t8 `  l. ~" [9 _6 f! a" q, |7 e
  201.         </item>& g/ ^* |% I. W  ?
  202.        </layout>
    $ c- b0 |5 T& v" {" m* x, q/ ^
  203.       </item>
    - ~7 ^4 @% L2 _  f& ~# i6 P
  204.       <item>
    8 f4 v3 E# P$ e# h
  205.        <layout class="QHBoxLayout" name="horizontalLayout_3">/ q* U; N8 L5 X
  206.         <item>- u5 q) J% X' _" E  [4 ?5 E! O
  207.          <widget class="QLabel" name="label_5">
    * k8 ^$ ~1 A! [- k
  208.           <property name="text">4 X5 L% _9 t8 ~$ z* `% y. V
  209.            <string>传输进度:</string>/ s1 I! r4 l' t  g5 Y" ^0 c( v
  210.           </property>% X+ U% I, m5 ~. }' v1 r3 |
  211.          </widget>2 A: ^( u  T+ B: n7 e& w, L
  212.         </item>2 \7 i1 H7 m( D/ S
  213.         <item>
    - `! `6 `4 \4 I5 i. X
  214.          <widget class="QProgressBar" name="transmitProgress">/ W8 B4 ~; Q  B' i
  215.           <property name="value">
    % |, O2 Y/ E& ~7 r. T4 i9 Z8 X
  216.            <number>0</number>
    : _* g% s; B* }! ]: ?
  217.           </property>
    ! v* \7 Y* N1 m7 K. J( y2 k8 }
  218.          </widget>
    * M9 Q, ]* D" @% \! h/ t
  219.         </item>
    / Q5 `/ a$ a- }8 c
  220.        </layout>$ w. i1 G' d3 v* J' R
  221.       </item>
    8 g" d0 l- s4 @3 b3 q
  222.      </layout>
    4 `& @$ K- ]: z/ Z
  223.     </widget>
    : U9 c/ ~; h! @* j& G
  224.    </item>
    : N$ w5 d9 f- d6 B8 L! i( l
  225.    <item>
    + j" W2 }# {6 R
  226.     <widget class="QGroupBox" name="groupBox_3">
    : p7 n. V( L- }, J( h, t
  227.      <property name="title">
    # h- F- g1 q: h0 D6 A/ U5 a8 _6 y
  228.       <string>文件接收</string>4 L/ h1 ?! _; h7 n3 H$ M7 ^  W9 S
  229.      </property>% L) J5 h) r+ G8 y! E6 r  l" k. |  A% x
  230.      <layout class="QVBoxLayout" name="verticalLayout_2">7 r+ x( x% E5 S% V9 A
  231.       <item>  j$ s" k/ ?) G" b% ^' r7 O6 m8 {
  232.        <layout class="QHBoxLayout" name="horizontalLayout_4">
    3 K: o- I/ y" v6 f
  233.         <item>
    % t/ l) Y$ h' U$ k. U
  234.          <widget class="QLabel" name="label_4">
    4 J5 ]2 o; e- U5 A
  235.           <property name="text">+ l7 D$ Q, N& W7 I! H
  236.            <string>文件路径:</string>8 Y! l' b; S7 s, I
  237.           </property>$ ]/ W" R# d% d7 O; n! N
  238.          </widget>) }/ e, N- Y0 R6 E  c
  239.         </item>& y5 T/ w; x1 I8 |' O( I
  240.         <item>
    8 y7 W* z+ i* B% G5 F$ J
  241.          <widget class="QLineEdit" name="receivePath">
    - j+ p5 U- g: G' B
  242.           <property name="readOnly">
    ) }6 K6 ?. g( N/ R& z
  243.            <bool>true</bool>
      ^! r$ @7 t1 a1 g  I& ]
  244.           </property>
    4 m+ T) i" o/ r! |! c% g
  245.          </widget>3 j* X: S* z3 D2 q7 X6 S
  246.         </item>
    + B! V! E8 i6 ~4 U$ K, F+ x3 m
  247.         <item>
    , ~  |; y# J( p; ]( N9 v5 v" X" M
  248.          <widget class="QPushButton" name="receiveBrowse">
    ( f8 P6 x! M+ z1 b0 ?
  249.           <property name="enabled">
    " w, ~0 s8 T( G& N+ L
  250.            <bool>false</bool>
    4 Y! z; F/ O; F* k
  251.           </property>5 t. @  W9 t1 c6 k7 Q: Q- Z/ u
  252.           <property name="text">/ J  a# j+ t/ T2 i8 P
  253.            <string>浏览...</string>, b; `# [' C2 f( v3 `2 o
  254.           </property>
    1 y8 J% Z. P$ _& f3 z' C. G* Q
  255.          </widget>
    / b' \( w! v, X+ k0 v) d0 ?
  256.         </item>
    3 K7 d4 q: _3 e- t) m
  257.         <item>
    ; P, W2 P5 S# c
  258.          <widget class="QPushButton" name="receiveButton">
    4 R2 e( g6 G7 ~7 z7 u! Q
  259.           <property name="enabled">) a% P% U. U( ^% g# s( ~
  260.            <bool>false</bool>6 J- B# @* B* f) a
  261.           </property>- h8 A! O% R' g+ Z) j) o7 p
  262.           <property name="text">- ]: w+ \$ x6 G
  263.            <string>接收</string>
    - o( D& b1 n# u/ I. P# v! ~. o/ v
  264.           </property>
    ; b0 I# m3 B$ K6 Z: Z9 s
  265.          </widget>
    : k( c+ ]/ a* ?# L% \
  266.         </item>
    2 T# I3 \1 f8 r* l
  267.        </layout>
    # j2 p7 h# _3 O
  268.       </item>
    / z* u) _2 d: e
  269.       <item>
    ) T6 M5 b) \% b' L: P5 [! }
  270.        <layout class="QHBoxLayout" name="horizontalLayout_5">/ `4 S' r8 ^, k
  271.         <item>4 N& f& L: [# L0 D& @! V( U
  272.          <widget class="QLabel" name="label_6">) r' R& [" ]$ h% K( @
  273.           <property name="text"># l# f' r) c/ `' x" k
  274.            <string>传输进度:</string>
    2 i' B' f4 h0 H$ r5 ~
  275.           </property>3 M+ R$ h6 i" @# K6 n1 D
  276.          </widget>
    - n" e* l. \" X0 F
  277.         </item>  `' o( V/ ?! v/ I4 }
  278.         <item>
      R) e! R1 f- y# M% Q
  279.          <widget class="QProgressBar" name="receiveProgress">5 ^; K2 w: w1 w
  280.           <property name="value">3 p7 l% L$ n) Z9 H. t
  281.            <number>0</number>
    ' v/ ], g: |1 x0 w1 l- I/ L: Y
  282.           </property>
    0 ]7 F9 Z  K& F8 F( L: c% k* F! r
  283.          </widget>8 w* A$ z* {( X* p& q+ Q
  284.         </item>
    & b* d% c. F; x4 L# B3 H1 {
  285.        </layout>; m, V7 `- t, A- V$ H, M
  286.       </item>1 @: C- [' _+ Q6 G
  287.      </layout>
    ! _' a1 V- r% C" m2 P
  288.     </widget>( w' v: N" z" P" m8 [
  289.    </item>) J4 s  |+ x* c- c9 V7 A
  290.   </layout>* W; J# R4 b, d
  291. </widget>! X; F' @4 P& n
  292. <layoutdefault spacing="6" margin="11"/>
    $ ?3 `7 Y; o4 w4 o% P7 {4 R! Z
  293. <resources/>
      k+ p% U: x( s. z' ]5 i. `3 n
  294. <connections/>8 d1 G7 E( a1 |8 z! A; Y! t6 [8 v
  295. </ui>
    / Q- e1 [/ w8 I. n; I
复制代码

& M: a1 r# \3 N( x$ X      widget.h文件
+ _8 I) w2 ^0 C3 ?* N3 N* S$ s
  1. #ifndef WIDGET_H$ [8 L% ]$ F5 {, f" O9 O( |, N
  2. #define WIDGET_H- T6 X6 T0 \% \" t) Y

  3. 5 q6 x& y8 l- B8 l8 J5 Y0 y% Y
  4. #include <QWidget>
    5 ^9 r8 [& Z. [8 ]  N
  5. #include "YmodemFileTransmit.h"
    ; _* z' \3 F  T5 l1 u5 P  W! z2 ?: R- w
  6. #include "YmodemFileReceive.h"
    ; Y& m; U) S/ |0 y! E
  7. - c8 ~" F# N6 ]& A* a
  8. namespace Ui {5 h0 n5 T+ `( u( R" F$ C$ |& ^7 v
  9. class Widget;3 k& A& G; G2 p0 A
  10. }2 ]$ f. Q3 @% _6 M
  11. * A. ]& ^/ R7 d  B8 y9 F2 E# Y1 z* ]
  12. class Widget : public QWidget( W1 Z0 u* l7 B5 ~8 h& c! A) c
  13. {/ ^: C5 Z4 R( {/ a/ C! ]5 r& h$ j
  14.     Q_OBJECT" }. }/ h- ^0 h: o2 F  e

  15. 2 @$ a! J! _' ]
  16. public:
    ! f$ a  k+ ~/ p7 K
  17.     explicit Widget(QWidget *parent = 0);
    - V7 ^$ h3 S% B3 f2 W
  18.     ~Widget();/ p3 \6 O/ M# I0 B4 p! y, F: E' j

  19. - k* j- K' {9 L+ v# D- q
  20. private slots:6 a  {7 C; D1 w8 d1 G/ R2 J1 R
  21.     void on_comButton_clicked();: W: }" k: P7 e1 X
  22.     void on_transmitBrowse_clicked();  O9 Z; s  x) e4 `( Q  k- M) K; _; h: ~* p+ L
  23.     void on_receiveBrowse_clicked();
    9 ]# m$ l) Y3 {9 e6 K0 ^5 s
  24.     void on_transmitButton_clicked();+ k" t1 @$ X- K1 `' V: C1 Z- O
  25.     void on_receiveButton_clicked();
    2 I* S4 z9 m! v6 }8 y
  26.     void transmitProgress(int progress);
    7 t  o8 `. p) N4 r) r
  27.     void receiveProgress(int progress);
    : M5 S3 E% _9 K
  28.     void transmitStatus(YmodemFileTransmit::Status status);2 I) I" K5 t2 m' d! ^' `& h
  29.     void receiveStatus(YmodemFileReceive::Status status);" k' h# m5 |/ n; C) R9 Z( ^/ Z& _
  30. 9 |" w, t6 D2 b- h1 _0 ~
  31. private:
    $ u* X; s3 _# \/ \" N7 v( v6 ?
  32.     Ui::Widget *ui;( o- Q$ r- I7 C9 s) r
  33.     QSerialPort *serialPort;
    / d" c( _) W8 P' L0 s* G! ^
  34.     YmodemFileTransmit *ymodemFileTransmit;( s0 l, }" `* i5 @5 s5 q6 g
  35.     YmodemFileReceive *ymodemFileReceive;
    * C  t: d4 s; z/ E
  36.   k% w9 T2 K/ U1 \4 u  F9 d" Z2 [
  37.     bool transmitButtonStatus;2 l9 i5 x, x) a% m6 ~  \1 X4 ]5 J
  38.     bool receiveButtonStatus;* Q, {4 \* e' y0 m
  39. };
    6 N6 H( ^  X: U* E" t2 m) C

  40. 2 G1 S% i' ?. v. j( B
  41. #endif // WIDGET_H1 w* M4 q3 F5 X+ i( O# p+ V/ E
复制代码
; [/ @# C* k+ r0 d5 D
      widget.cpp文件
! e7 G& m) e! e8 B. G! C
  1. #include "widget.h") o% b* [- \+ x) c" U# m- G5 w
  2. #include "ui_widget.h"4 p8 W9 X# b! f1 ~
  3. #include <QMessageBox>9 S' ?4 c( L2 k1 E
  4. #include <QFileDialog>" Z, R) a( d( k/ v4 L5 C8 V
  5. #include <QSerialPortInfo>- J1 u0 e. Q1 s

  6. % J  W1 r! Z( Q3 c* z
  7. Widget::Widget(QWidget *parent) :( o: `- t" ?1 J# [
  8.     QWidget(parent),3 r. H$ W5 o) h6 ?7 j2 h
  9.     ui(new Ui::Widget),) D2 B/ Q$ r4 G/ r
  10.     serialPort(new QSerialPort),
    6 K% w7 b* @. [: u0 z
  11.     ymodemFileTransmit(new YmodemFileTransmit),( p: j1 _9 f$ J1 J" F
  12.     ymodemFileReceive(new YmodemFileReceive)
    ! a( Q* w5 [  q4 {! L4 F, ]
  13. {; Y+ v. M$ @2 i" Q) J
  14.     transmitButtonStatus = false;( c$ Z& g2 i6 Y# l' }4 w& T6 h
  15.     receiveButtonStatus  = false;/ S$ g" u1 D; {3 M
  16. , g, Q7 Q  \. F' A: o" z4 B; V4 ^
  17.     ui->setupUi(this);
    7 j- K/ f) m  A# J8 Z: @
  18. ; R7 i$ ?5 o& A6 l
  19.     QSerialPortInfo serialPortInfo;
    ! \( O( M& Z8 O% F& h( [  t6 ?
  20. . ^& D7 y& z! K/ P
  21.     foreach(serialPortInfo, QSerialPortInfo::availablePorts())
    * G" x; |0 N0 h( x  z
  22.     {$ d; K7 w% v8 o7 K+ [8 J
  23.         ui->comPort->addItem(serialPortInfo.portName());8 }+ l+ f& r3 z# F: B% w* o( V
  24.     }, {! C+ y! h! W( j" A; U) Z

  25. ' N3 b) F8 p& F: o
  26.     serialPort->setPortName("COM1");) o1 U3 V" l" O" k
  27.     serialPort->setBaudRate(115200);
    . K$ V, o4 i1 L% W. N
  28.     serialPort->setDataBits(QSerialPort::Data8);
    0 p! i( O/ Q8 a* b  x
  29.     serialPort->setStopBits(QSerialPort::OneStop);9 i# K9 u1 h3 k9 {5 l
  30.     serialPort->setParity(QSerialPort::NoParity);2 a- I2 z- W; |2 a; c6 T5 m
  31.     serialPort->setFlowControl(QSerialPort::NoFlowControl);8 K& e0 G; ^' d' H" k

  32. ) k5 a1 d* K/ d8 R/ s, `
  33.     connect(ymodemFileTransmit, SIGNAL(transmitProgress(int)), this, SLOT(transmitProgress(int)));
    # k3 T; a$ g. r
  34.     connect(ymodemFileReceive, SIGNAL(receiveProgress(int)), this, SLOT(receiveProgress(int)));
    * g# Q2 X7 ]0 M5 X& C4 N
  35. 7 l( j; z2 p5 n- q  y: C3 e  x
  36.    connect(ymodemFileTransmit, " {6 _& f% R; w# X& w
  37. SIGNAL(transmitStatus(YmodemFileTransmit::Status)), this, 2 J" M" [) W2 h: Q* u
  38. SLOT(transmitStatus(YmodemFileTransmit::Status)));
    + u( L6 _9 y# ?- [& t& f) @  P3 q
  39.    
    / y6 S5 H% z. Z1 L/ ]4 u4 A
  40. connect(ymodemFileReceive,
    & E1 e$ @4 C' L: y6 O
  41. SIGNAL(receiveStatus(YmodemFileReceive::Status)), this, " I& P! \* k1 e* y* \! t' ?8 J" d
  42. SLOT(receiveStatus(YmodemFileReceive::Status)));' A- l3 L" N! R
  43. }* S' {  n6 q2 W7 I9 F; A8 Y/ @
  44. : C, T. ~8 e  w; g
  45. Widget::~Widget()/ O0 Y. n2 h; R7 `( {3 D) e4 H+ o
  46. {
    " }& W7 m  Y' l9 D5 ^6 @% @( b
  47.     delete ui;- ]- x5 b+ v5 o1 ~5 t7 I# z
  48.     delete serialPort;
    6 N5 a% L: \# u$ m( R9 P4 `
  49.     delete ymodemFileTransmit;
    " `5 o6 J+ Z) N: x
  50.     delete ymodemFileReceive;
    0 P0 n9 \" k& R! Y: R% d2 N
  51. }
    1 G0 Y! c6 E" c# a+ z2 b5 `2 A( w

  52. " _6 `2 F! A0 ^6 J
  53. void Widget::on_comButton_clicked()5 l* ~1 M7 K; F4 w
  54. {/ U( V! [2 K, I
  55.     static bool button_status = false;8 [/ Y, `* f/ M- C+ D" E& A

  56. / [% A( B& {: U' J' P" o1 w
  57.     if(button_status == false)6 L% }) d) Z* n, Y# r
  58.     {
    9 ]' v7 @2 d8 `3 h
  59.         serialPort->setPortName(ui->comPort->currentText());- m. X  V, H% o  J" `8 F
  60.         serialPort->setBaudRate(ui->comBaudRate->currentText().toInt());  ]' T+ e0 d& l4 s
  61. . J0 i# q7 l2 e5 ^8 P5 Y4 _3 G
  62.         if(serialPort->open(QSerialPort::ReadWrite) == true); b  P" G6 |2 d! s
  63.         {
    : c' `; N+ e& G3 z8 \% l4 [
  64.             button_status = true;
    9 M7 m9 Z/ ~3 F

  65. % h8 s' j  ^6 v
  66.             ui->comPort->setDisabled(true);- o) O. P  m( B% e& n% ?* d
  67.             ui->comBaudRate->setDisabled(true);% e9 `* P5 U& n7 r; i
  68.             ui->comButton->setText(u8"关闭串口");5 G1 l3 f/ B; K+ r- o" D$ y

  69. 0 S; I- `7 Q- a, D: K0 V  ]  C
  70.             ui->transmitBrowse->setEnabled(true);
    ( i* f% N$ }" b3 |/ E* \
  71.             ui->receiveBrowse->setEnabled(true);0 r1 f  x% T0 u/ O6 G

  72. ) y  u( D( i4 i
  73.             if(ui->transmitPath->text().isEmpty() != true)
    ( f, m2 h: V2 n
  74.             {) e8 f. `+ P8 K
  75.                 ui->transmitButton->setEnabled(true);6 |7 _# K- v2 V9 T
  76.             }0 u3 Y; [  Q# Y' q( S3 f
  77. " z: }/ j/ o8 D2 [. s0 q2 o
  78.             if(ui->receivePath->text().isEmpty() != true)2 l0 B: ~9 I2 v+ z* K
  79.             {/ R' n# C0 k1 j3 w3 ]- u
  80.                 ui->receiveButton->setEnabled(true);
    5 d6 N5 v! }7 U/ W
  81.             }
    ( U) U3 E, h% ?2 N9 u, V- |3 m
  82.         }
    9 ~, {" o$ l& O) u) B
  83.         else
    : r- W: T8 A9 Y, A5 \0 `% T
  84.         {
    ( L% |( T) B" c6 y& ~7 [0 R
  85.             QMessageBox::warning(this, u8"串口打开失败", u8"请检查串口是否已被占用!", u8"关闭");
    5 e8 g' U0 D6 g7 Z8 j1 ]
  86.         }
    % d3 z, |$ N7 {* d/ {) }. ~
  87.     }1 N- {7 {7 r- S: w7 d' Y0 L
  88.     else* P) v! C. D; `, K) I
  89.     {- \/ f7 ^$ N. r- |: u8 f+ Q$ m) j
  90.         button_status = false;2 d% \) V# l0 n4 f, m6 z

  91.   s4 [; p# @( A$ e, }# R
  92.         serialPort->close();+ c& N! F- l! `3 J2 z/ A% P
  93.   x6 G; B' Z) }! _
  94.         ui->comPort->setEnabled(true);
    " o2 [* O: F% R. p" C
  95.         ui->comBaudRate->setEnabled(true);% q8 i/ m) c7 _) j2 P
  96.         ui->comButton->setText(u8"打开串口");* B, P( f5 o- ]+ J' m7 T: J
  97. , ~. k; O/ d  _) ]. [- D) F3 u
  98.         ui->transmitBrowse->setDisabled(true);$ h7 r* W  Q) p3 Z
  99.         ui->transmitButton->setDisabled(true);8 v9 k6 w( t1 R

  100. ! X4 Y2 k+ J# a3 _
  101.         ui->receiveBrowse->setDisabled(true);1 k9 }" F5 M( s1 W3 @% L* G
  102.         ui->receiveButton->setDisabled(true);
    / R1 O3 U/ G5 v2 c6 v
  103.     }4 z9 K/ [5 q3 H  F# \
  104. }
    7 Z8 N% Z4 J; s8 @: f! G
  105. / A5 q8 L" A# i' i
  106. void Widget::on_transmitBrowse_clicked()
    4 v* |4 ?3 V5 d) u  b" ?: v$ A" o
  107. {
    , ?6 t: P/ A! E; x9 [7 A: B
  108.     ui->transmitPath->setText(QFileDialog::getOpenFileName(this, u8"打开文件", ".", u8"任意文件 (*.*)"));
    8 x! j: i: F. B# U3 i
  109. ' `3 C' S# [  c* ^* D& v
  110.     if(ui->transmitPath->text().isEmpty() != true)
    . N6 p- T8 s4 a. y* k, V1 m1 G! N. h$ y
  111.     {
    ( q( N# N  Q8 e) d" N, @* l
  112.         ui->transmitButton->setEnabled(true);
    5 f' J& ]+ y- T& i5 G3 y
  113.     }
    / @4 Y; ]4 j. G' h( i
  114.     else
    . Y. ]0 I7 B: n* J. B5 q
  115.     {
    1 O) h3 D! {9 T' C$ }
  116.         ui->transmitButton->setDisabled(true);
    & }9 f5 z( F" _2 N0 R7 r
  117.     }8 O9 \4 F+ `6 u& R7 x
  118. }+ v" a5 s1 `9 X  q# X$ Y/ l  c

  119. % D/ K+ _6 Y9 I* x( d2 O
  120. void Widget::on_receiveBrowse_clicked()+ t+ J7 c' X( h6 P$ A7 g& ?( W
  121. {
    * u3 |- i( B- R8 T: o
  122.     ui->receivePath->setText(QFileDialog::getExistingDirectory(this, u8"选择目录", ".", QFileDialog::ShowDirsOnly));
    ; |+ v5 T. Y/ o8 x( T

  123. / v' f; e# m! M2 b# D7 U: H
  124.     if(ui->receivePath->text().isEmpty() != true)
    " r7 c" x% X* u) D
  125.     {
    7 O5 H  @8 i- C) y, K
  126.         ui->receiveButton->setEnabled(true);# \  k9 ^% c1 ~/ {# U" ]) W- U
  127.     }
    # o8 L+ F0 i1 H) C7 i- L& \, C2 G
  128.     else
    ' m' X& \1 Y9 N
  129.     {
    ' d  R' e) Y" @( h& {
  130.         ui->receiveButton->setDisabled(true);6 y/ I/ ^8 h* ~# v; _
  131.     }$ i6 E5 V( z3 h, k5 N
  132. }
      L2 f+ m8 O0 @! n4 `
  133. 2 G7 z3 H' J2 K" F
  134. void Widget::on_transmitButton_clicked(). \  m; S' `5 M6 C- Z
  135. {
    2 Y. Y' ?7 n0 a$ q  ]
  136.     if(transmitButtonStatus == false)7 J/ }: L: [1 |& [7 x$ v9 J5 G4 F+ |
  137.     {
    ! J* w' s, m; A  V0 v4 k, c
  138.         serialPort->close();
    2 D" j7 w- h# g
  139. % _* f2 i2 c8 i2 f) @% ~' i
  140.         ymodemFileTransmit->setFileName(ui->transmitPath->text());& r+ p- R  i) h8 i
  141.         ymodemFileTransmit->setPortName(ui->comPort->currentText());
    4 q1 m+ Y) w$ z, ~3 D" D5 ]3 O
  142.         ymodemFileTransmit->setPortBaudRate(ui->comBaudRate->currentText().toInt());* {# i' O8 K: I

  143. 5 Q9 g: J" j$ w. S9 |; ]
  144.         if(ymodemFileTransmit->startTransmit() == true)
    ( o6 y& g/ `4 Q& C) Z. a
  145.         {1 e  ~. F4 r/ ^* t' h
  146.             transmitButtonStatus = true;
    . M! _: U7 l- N, ^2 z4 I0 h8 w
  147. " \$ d' d' [  L  K
  148.             ui->comButton->setDisabled(true);
    . ^% B- e- J! R& [# A$ P6 e- D
  149. - ?9 n2 \$ O$ ?6 i8 Z! ~, j
  150.             ui->receiveBrowse->setDisabled(true);
    - {, P9 Y, g) g* ?  T
  151.             ui->receiveButton->setDisabled(true);
    " H" v  U/ p& {% w2 H% L

  152. ; N: s* W6 e: G
  153.             ui->transmitBrowse->setDisabled(true);7 w& v+ m: ~  U% v3 p
  154.             ui->transmitButton->setText(u8"取消");
    * D+ X) [* h% x/ }; x
  155.             ui->transmitProgress->setValue(0);
    * |+ G6 S, v% s, q# q6 Z9 {# V
  156.         }
    $ s) x. C9 {/ W& d5 M& l* \
  157.         else
    " r3 V8 Z. x6 m- p% n
  158.         {
    " h. @1 t( ?( L' e, c( D$ u8 ]
  159.             QMessageBox::warning(this, u8"失败", u8"文件发送失败!", u8"关闭");
    & q. ]7 Y( ~' B" y
  160.         }- i( t$ h$ V* V& v  n$ f/ k
  161.     }
    / c' v0 M! O8 D0 ~0 ?: c' ]  M
  162.     else9 V3 `# z$ m9 R5 G
  163.     {
    2 D3 F% U9 h& ^1 {; h
  164.         ymodemFileTransmit->stopTransmit();
    $ G4 @$ c% n) ]2 o
  165.     }" Z5 ^5 C/ o, U/ E
  166. }
    : S" Y! \  G$ |* q1 H/ s
  167. ( Q5 O% Z' `  {! a$ V
  168. void Widget::on_receiveButton_clicked()+ a3 r3 R, j7 L$ |0 @
  169. {2 b9 M' t' E7 ~5 k& }# |
  170.     if(receiveButtonStatus == false)# A' b" f2 o+ M! N+ P' d8 V( {3 w
  171.     {
    1 ]) C" z: v! c5 y2 H
  172.         serialPort->close();4 d9 l) y5 `% R, p0 Q

  173. 9 h1 |" C3 W  I1 T
  174.         ymodemFileReceive->setFilePath(ui->receivePath->text());
    ' v+ {  e* G% e9 N# J- B
  175.         ymodemFileReceive->setPortName(ui->comPort->currentText());
    0 n- Z5 ^7 J. E: r' F- ^- e- j
  176.         ymodemFileReceive->setPortBaudRate(ui->comBaudRate->currentText().toInt());
    * M8 Y8 V. M/ A; v7 _/ O
  177. . h" b: r5 J: U8 P- x' R: n
  178.         if(ymodemFileReceive->startReceive() == true)5 F4 C8 V) l% ^( r
  179.         {
    2 w' `& {3 p8 T1 v$ ~" F
  180.             receiveButtonStatus = true;7 Q( c  b' b4 D3 w; S
  181. 0 L9 \: w1 i, o! @- g+ F
  182.             ui->comButton->setDisabled(true);
    . e# n3 p7 M9 _5 n( L6 T8 O9 |
  183. 1 y7 t3 i- d8 K& g' a
  184.             ui->transmitBrowse->setDisabled(true);, e" e1 F3 z3 o. }
  185.             ui->transmitButton->setDisabled(true);0 D3 l5 Z9 N+ @3 T8 z

  186. & B3 `1 `) N" Q% x0 L: @+ }
  187.             ui->receiveBrowse->setDisabled(true);: j/ A- h# e1 Q# I0 v, O  {/ n  F9 f( {2 ]
  188.             ui->receiveButton->setText(u8"取消");' F- F( H; H) y& n( m
  189.             ui->receiveProgress->setValue(0);
    : T7 }( x9 r9 }6 x. I% Y3 |
  190.         }
    ( |2 G* f- L& T" M& _0 S
  191.         else4 U  w3 |  W6 q* S
  192.         {
    . n6 z' v' {' d* P) B( H
  193.             QMessageBox::warning(this, u8"失败", u8"文件接收失败!", u8"关闭");
    3 [) R- s; B& Q- e' a+ E
  194.         }  y2 R* N; W4 K& Z5 W, ~
  195.     }0 j  r7 H) `" p9 A5 P/ b* R
  196.     else* m0 M5 I& F# z: [/ S
  197.     {
    5 a" F) k$ t5 B. q# O, R+ t
  198.         ymodemFileReceive->stopReceive();
    ' J% o5 z: `5 {, S
  199.     }
    * s# i: J( f- A0 p' U
  200. }. S, r! E2 f+ ~. S; |; c4 p

  201. " a6 d8 ]& i+ E1 ^0 I
  202. void Widget::transmitProgress(int progress)
    8 d& p% d6 m' [$ c6 w
  203. {8 B3 e" M2 K$ Y$ A- b; m) l
  204.     ui->transmitProgress->setValue(progress);
    ( T# |( c0 d$ N* q3 B
  205. }
    3 B/ Q0 s5 Q% \" a! z

  206. $ M2 t, i- ?: u% ~
  207. void Widget::receiveProgress(int progress)
    1 s7 w5 c8 Q3 B9 c$ N7 U- t
  208. {
    3 z. n% f4 d, J' d8 p& r
  209.     ui->receiveProgress->setValue(progress);+ a) r1 x3 C: ^2 p7 b  x3 ^/ N& z
  210. }/ X% a# |- m* O& q/ w# e

  211. 4 @) _  j: N! T; c; O5 b& r# x+ N
  212. void Widget::transmitStatus(Ymodem::Status status)
    # J- \( V* N& p, ^
  213. {
    2 ?  @8 L4 N! P+ S7 ~) z4 e7 H; E
  214.     switch(status)
    " s% H# C' R! z2 c4 c' T  Q
  215.     {/ ]* \( I- W+ ]1 k1 L0 C6 Q2 Y
  216.         case YmodemFileTransmit::StatusEstablish:
    9 z8 X; X4 w- P8 L1 d
  217.         {- U0 N; t9 j9 P' t
  218.             break;
    - R3 X! ]+ X# L' F  d
  219.         }" Z; A3 V7 C8 L2 R
  220. 3 N/ o6 {+ n4 _
  221.         case YmodemFileTransmit::StatusTransmit:$ ~( y' m% R: k" b1 o0 Z/ _
  222.         {: ?, f) y; _& y: q0 U2 k( Z
  223.             break;6 K. Q# m) x. o
  224.         }. j/ M9 @! v4 b6 `# W- i8 }
  225. ' T, l+ c9 H- ~) ~# V% o) i) k
  226.         case YmodemFileTransmit::StatusFinish:
    & \" Y, Z4 u0 Y2 N: t/ Q
  227.         {0 H+ W+ F% y" B# P" [
  228.             transmitButtonStatus = false;3 c" q' D% |/ m8 L, E' R' u5 T

  229. - x6 D' C( w2 D0 v" l2 S1 d0 o
  230.             ui->comButton->setEnabled(true);
    7 y4 N& r; h; K8 a4 X  a

  231. ; F3 d! \+ l  G6 M" [2 L1 N
  232.             ui->receiveBrowse->setEnabled(true);
      S9 V' N% }7 H+ X& ?) J
  233. 0 Q! o; p& g7 A
  234.             if(ui->receivePath->text().isEmpty() != true)( j% L4 }. \4 k: B* ^% `
  235.             {
    & u* D7 I" ?( D9 F8 G; W: F
  236.                 ui->receiveButton->setEnabled(true);; J9 b# A, _0 z! T, n" W* a
  237.             }, E. l% g9 W, c  m1 N6 H4 o  r# ~

  238. " f! N, o. m4 z
  239.             ui->transmitBrowse->setEnabled(true);
    % J: l. @" X/ m7 {
  240.             ui->transmitButton->setText(u8"发送");4 u# K) u+ n- ^" q" Z6 [2 H
  241. ; c& V+ y0 \4 X
  242.             QMessageBox::warning(this, u8"成功", u8"文件发送成功!", u8"关闭");" Y) M  N! S/ p# Q2 J4 `9 H
  243. & _7 U% a  {1 Q9 F: P: L7 \" |+ D
  244.             break;
    4 e, r: [& U) W8 S7 H
  245.         }
    1 [3 j: Q) J) C5 T- m) ]* G+ x

  246. " H. P- Z+ }- y0 s. c, K( v
  247.         case YmodemFileTransmit::StatusAbort:
    & [- B: j. r( I1 s6 h
  248.         {. E$ a5 p: S; F- p6 V7 J
  249.             transmitButtonStatus = false;
    2 U; J0 q% F! n- k; O4 ?

  250. + E4 O, m9 ^/ R- R  d& m  g6 z8 @( ?: q
  251.             ui->comButton->setEnabled(true);
    * e: O! K( `; ~

  252. - h1 N6 m. d& E8 g8 o
  253.             ui->receiveBrowse->setEnabled(true);
    & w. x. G$ B: {6 c- ~5 U
  254. ; e/ j6 f1 X9 l4 r. C+ Z
  255.             if(ui->receivePath->text().isEmpty() != true)
    6 R/ ]8 Y) ]# P% _/ Q
  256.             {
      ?3 ?- }- L* F& W+ r, ]+ T
  257.                 ui->receiveButton->setEnabled(true);
    2 A9 Q8 B& u! I  N9 A
  258.             }
    + \0 u: E) b. Y* q! \6 k2 r

  259. 7 \( ^, @+ K7 G# s* [. w
  260.             ui->transmitBrowse->setEnabled(true);- O/ \) d# |4 j& s0 F; m+ ^+ A
  261.             ui->transmitButton->setText(u8"发送");4 D  _  W- @" V! l
  262. ! h$ ?( m1 h* L( ?
  263.             QMessageBox::warning(this, u8"失败", u8"文件发送失败!", u8"关闭");% b4 _8 o+ Q* g+ a

  264. # v5 ]& @1 J. L4 O9 f0 t3 ~2 v
  265.             break;- P: I, m' X4 }3 f$ t3 k/ A. j4 |% g  G$ X
  266.         }
    ; z3 L! }) C! \" E7 H9 |

  267. 6 k7 {& y1 Y( b, n& _7 e' ]( ^! Y
  268.         case YmodemFileTransmit::StatusTimeout:; l& f% y* X: N  B. ]3 x" ]
  269.         {, I& y8 F6 `2 `- k4 Q$ B- K
  270.             transmitButtonStatus = false;) }: y5 |4 f5 W2 V; d0 |; I
  271. ) V, b. |5 k) Q6 h
  272.             ui->comButton->setEnabled(true);
    5 a9 [1 j. }9 Z4 Y7 }
  273. . S7 Q  u; Y" \# a  F" w
  274.             ui->receiveBrowse->setEnabled(true);
    ( [9 B! \/ X* M
  275. % l: q$ m6 {5 i: @$ }! Y7 Q7 [
  276.             if(ui->receivePath->text().isEmpty() != true)" x# w/ |8 _5 i% x0 W$ v2 E
  277.             {) r. `3 M% O6 a# k' l" D: k
  278.                 ui->receiveButton->setEnabled(true);5 F( c7 J$ p  O* C: U, z
  279.             }0 Q, o, X; r( @1 J

  280. 2 N( J* g) q+ L  y1 Y1 [
  281.             ui->transmitBrowse->setEnabled(true);
    6 `- W2 p) G4 c$ o0 v* O: _
  282.             ui->transmitButton->setText(u8"发送");
    5 I) z7 z- I; l+ e
  283. ( c" V# b& Z. i3 `
  284.             QMessageBox::warning(this, u8"失败", u8"文件发送失败!", u8"关闭");) |4 d4 u6 }- J. c

  285. - x* C* r6 p0 M  y+ c( y
  286.             break;+ N" Y$ ], w) K2 N7 C, l
  287.         }
    5 g" R& [1 y( g% D7 K

  288. ! T) o( U; C' j1 |+ ]# y
  289.         default:
    ; S2 g- {( ]/ @" ^& h! @7 I! ~
  290.         {
    6 L5 u6 K6 F9 \! c+ k
  291.             transmitButtonStatus = false;
    9 D% e& o& j( u* N, F

  292. % z4 R6 e# r7 J8 D6 }( d
  293.             ui->comButton->setEnabled(true);* \3 d6 k% R0 ]( Z8 t

  294. ) P2 N6 y' s: s/ s0 D" Y
  295.             ui->receiveBrowse->setEnabled(true);
      b5 i' D" \1 M- q; [6 h8 K0 F/ m- i

  296. % l% j- o+ H2 a9 e2 B- L3 |0 U* ^, Q; F/ ^
  297.             if(ui->receivePath->text().isEmpty() != true)
    ' i8 B$ n, ^1 h. a( @& E9 ~
  298.             {  F" L* n* X- }7 O  B0 `
  299.                 ui->receiveButton->setEnabled(true);
    0 T  ?5 _6 D3 d. `
  300.             }# F2 p8 o: w9 m( ?

  301. 0 h/ G8 m: U' w0 @( ]
  302.             ui->transmitBrowse->setEnabled(true);- g4 T/ `7 b$ {3 Z0 E' I* f
  303.             ui->transmitButton->setText(u8"发送");
    % L, l; P3 i: P9 O: r9 j& }
  304. / a% O% F+ p* v! r
  305.             QMessageBox::warning(this, u8"失败", u8"文件发送失败!", u8"关闭");& R- j7 t% B& T2 t6 S& F
  306.         }7 L6 Q1 ?2 p* h. w) `
  307.     }
    * Y, ]' h/ F3 |! R/ g! B
  308. }
    # z# Q9 L4 b9 M4 t  i/ e( G2 f
  309. % u3 |$ B) i4 V* X  h9 x
  310. void Widget::receiveStatus(YmodemFileReceive::Status status)
    2 q6 ~: y# e! {( ~
  311. {
    " X  _" e2 O! L" ]/ w
  312.     switch(status)8 P6 x/ k: ~: U5 W0 N7 i
  313.     {
    * _3 }5 ~# ?1 V( ]  c2 t
  314.         case YmodemFileReceive::StatusEstablish:
    $ y& c* H! i& m+ r; q/ j1 c
  315.         {: U2 |, j) u! I
  316.             break;
    : L* A: B) j( w/ F# _
  317.         }/ l4 x5 Q7 w1 z. B% n) z
  318. " G# {# ^+ y. s
  319.         case YmodemFileReceive::StatusTransmit:) R0 Q2 W% n* e- S
  320.         {
    ! u/ a6 F* `% I( e$ a1 ?9 y" {; D
  321.             break;1 D8 o% V: o& K! w
  322.         }
    / Z: P# G' d* ]8 x; T) a( I5 b

  323. 5 x$ M! A# m- {
  324.         case YmodemFileReceive::StatusFinish:! t# A: x3 @- f* N
  325.         {
    - c- k4 ?0 ]0 o5 g. |
  326.             receiveButtonStatus = false;) N. ]/ w% ~" h3 Z0 b

  327. $ p# }& b5 f4 ~0 V$ O' O' Z2 R# t
  328.             ui->comButton->setEnabled(true);
    9 v) Q7 w/ J, r; Z" N- n
  329. % ]0 W2 l* ^: R4 z
  330.             ui->transmitBrowse->setEnabled(true);5 @1 M3 T% w$ Q. N
  331. 0 a0 y3 y- e8 P; m0 w
  332.             if(ui->transmitPath->text().isEmpty() != true): Y$ x0 z, c2 O& F# {
  333.             {: y5 S# W: ^) T
  334.                 ui->transmitButton->setEnabled(true);
    $ Z$ y3 b3 K7 a# j# L
  335.             }/ \4 h2 S! v- }9 g8 r. _

  336. ) K, _- X" R3 h( ?
  337.             ui->receiveBrowse->setEnabled(true);
    2 q  `+ g+ ]3 y
  338.             ui->receiveButton->setText(u8"接收");: V) G, v" L- O" d* P7 W( z) z) p
  339. % a  _/ ]& l& O# T
  340.             QMessageBox::warning(this, u8"成功", u8"文件接收成功!", u8"关闭");
    4 j$ q! ?; Y& b: D- B) E) x8 s# ~. D
  341. 5 I# }, u# \$ r0 x5 J7 S" L
  342.             break;
    6 b, J$ ]7 ?; m# o0 |, F% T+ N
  343.         }
    9 |+ e( Z: h, L& b

  344. % x+ a7 l( r$ @( _
  345.         case YmodemFileReceive::StatusAbort:/ U5 O7 L1 r* T- Y6 l) U7 R
  346.         {
    ( D- a, \# W# ~/ q# K# h
  347.             receiveButtonStatus = false;
    6 Q/ O7 k- i' Q( U% }$ I

  348. 8 @& y3 I0 ^$ T. L+ Y
  349.             ui->comButton->setEnabled(true);* b! L( Q  N% Y1 h( z$ y
  350. 3 A4 a* ]3 M- l7 X, D: C  |2 S) w
  351.             ui->transmitBrowse->setEnabled(true);
    $ B. p6 t9 L, l3 }" h9 g

  352. + m, ~  w! |! W# p% n  C) S9 I
  353.             if(ui->transmitPath->text().isEmpty() != true)" `% J( T0 h0 Z
  354.             {* G* x! R  n7 E* B
  355.                 ui->transmitButton->setEnabled(true);
    * N7 @2 d5 n7 ?% Y* c5 b7 ^, K1 P
  356.             }* w2 g( @; C  o$ q. U! u" T) i

  357. ( D: q" ^  k7 {. M: J+ [+ t
  358.             ui->receiveBrowse->setEnabled(true);9 M  P# G% t/ A
  359.             ui->receiveButton->setText(u8"接收");
    2 [- [9 z# g# u* m6 H( e
  360. 8 k: ?% t, P9 @9 {) L! x: K6 o
  361.             QMessageBox::warning(this, u8"失败", u8"文件接收失败!", u8"关闭");3 N: i: |  B/ \: Q$ R6 `

  362. , E  s/ \6 m- L! D% k  i0 K0 d
  363.             break;! v8 O2 h" V- e, \- M7 ~# V( T
  364.         }+ x; _- a& ?6 @+ ]4 B
  365. 3 P0 r5 x6 d  ]; g7 C1 U5 w2 C& P
  366.         case YmodemFileReceive::StatusTimeout:
    ! ~6 K3 L9 h  s: O
  367.         {+ s  H3 f% w% G4 i, O
  368.             receiveButtonStatus = false;- q8 b% D& J& d+ S. w5 s6 P

  369. 1 p) N7 c, O" F- r/ ~
  370.             ui->comButton->setEnabled(true);
    & h: p2 W2 t9 p7 W+ B

  371. + ?$ W' y) B! D. @1 m/ s# h( b6 p
  372.             ui->transmitBrowse->setEnabled(true);
    : b: J. c* G" N0 q* M0 ]7 d

  373. ! f( \) I2 S+ U9 |5 M
  374.             if(ui->transmitPath->text().isEmpty() != true)
    7 d" u- \& C- o; C5 D
  375.             {1 m- g' f1 z* B8 Y0 U- E* E
  376.                 ui->transmitButton->setEnabled(true);- _2 R: D3 j% i
  377.             }
    ! n# [2 b+ @$ [) c. S2 T

  378. / @; l( S, L/ r3 f+ Y: T+ A
  379.             ui->receiveBrowse->setEnabled(true);
    / l: w  Y* Q# s3 t, p: \% ^
  380.             ui->receiveButton->setText(u8"接收");
    / V2 E: q" D# o

  381. ; W0 L8 X& q. ~; g; b/ c, ]
  382.             QMessageBox::warning(this, u8"失败", u8"文件接收失败!", u8"关闭");! [& r! \: F$ W& p( i( ^
  383. $ u4 j( O3 N* J0 c9 b7 G* J& ]
  384.             break;
    ' u- a( c1 r7 ~/ P) h' `7 d
  385.         }6 v. L! g2 B7 x' V- j8 ]; d

  386.   c0 u. p& Q. q* v/ G9 I; u# d& m
  387.         default:1 P; S; T6 M+ y, y2 B7 T
  388.         {
    & d, x5 @4 P! n2 g$ G4 z& ]& O# c
  389.             receiveButtonStatus = false;( t* o% t6 H, K9 m1 g9 i: R

  390. 5 Q# Q/ r& I/ C; @
  391.             ui->comButton->setEnabled(true);
    8 Z0 Q$ H9 W; ~4 F4 U

  392. % N* C" D6 D2 A+ R" g, k% C
  393.             ui->transmitBrowse->setEnabled(true);5 u" Q0 O! L5 H5 s$ ?
  394. 7 ?, X3 T, a+ T; L/ A0 _2 N8 {
  395.             if(ui->transmitPath->text().isEmpty() != true)  f' a2 [( J9 T5 d" Z
  396.             {! O  e- F. T: ~6 Y% @5 U4 E
  397.                 ui->transmitButton->setEnabled(true);
    9 @; X+ H0 ?  c- k
  398.             }: {" V* W# ^8 k2 q9 {& s

  399. 0 h2 t, t$ A  V% ]
  400.             ui->receiveBrowse->setEnabled(true);- P/ _0 Q) K2 ]* G/ O6 n
  401.             ui->receiveButton->setText(u8"接收");
    + J3 g: Q4 c. c% Y- V! L# ~  [& C
  402. + E8 e1 }2 Y. Q4 D$ K5 h
  403.             QMessageBox::warning(this, u8"失败", u8"文件接收失败!", u8"关闭");
    , A( l6 W5 R. v4 R6 @0 L7 u2 C
  404.         }
    2 R/ x* |$ t* S( X  e, F
  405.     }: _$ \. U" K, O1 j4 A% u! O( {
  406. }7 ~6 ?7 |* x4 Y! N; r
复制代码

7 P+ m' U3 L: Q
/ N& j0 Q, ?! I+ O. O7 _+ {) A' h2 x

. T: H" [: ~1 m! Y9 X; X
3 a6 T$ O& C8 b) R9 @1 y
4 y# Y; p3 a  p3 M. ?; V
XinLiYF 回答时间:2018-3-6 22:32:40
      main.cpp文件- M7 r* j) ^" n& c& n1 w
  1. #include "widget.h"+ W2 ?. I% W7 I2 Q
  2. #include <QApplication>  z8 d# o5 q) ~# \
  3. 1 k0 k+ p/ j# B0 \8 E
  4. int main(int argc, char *argv[])
    + ?2 C$ A: t. `% p, Y  s+ y4 H9 l. U
  5. {! U2 g8 r0 J1 L& o& M2 j
  6.     QApplication a(argc, argv);
    ' Q- u  `6 n$ h/ y6 B" g2 n2 k( I
  7.     Widget w;
    ! N% Q4 k; \7 l7 A6 c% X8 I' |; G) _
  8.     w.show();3 \- r- B7 G8 I4 Q' ]1 M! z
  9. 8 B7 U( `& _" E" r
  10.     return a.exec();: f! s+ C2 C* G0 g3 o+ q4 g
  11. }4 b/ G: m  B  a) D( C' H
复制代码
2 i. f- N/ O* V
      SerialPortYmodem.pro文件) O& X. p) G* u8 D+ U' p
  1. #-------------------------------------------------1 }, d  e; b# }
  2. #( x' H. T9 ]; h9 V" {
  3. # Project created by QtCreator 2018-01-20T23:00:46( Q" S& b" ~2 n+ k2 M# w+ B9 L! P
  4. #
    * ]- F  z' T$ i* N1 O, A
  5. #-------------------------------------------------
    4 j- F3 a4 g2 H- y* c
  6. 1 w2 v7 k9 p5 |/ n
  7. QT       += core gui; ^0 z  u) e1 Z
  8. QT       += serialport
    & j; i6 m, n: {3 }$ _, `( q
  9. ' A9 }$ f7 h* h8 H2 A
  10. greaterThan(QT_MAJOR_VERSION, 4): QT += widgets" U5 ?, Z/ p2 H* D; b

  11. 5 y; C- E: Y  G! E' {5 b) ]2 k! K
  12. TARGET = SerialPortYmodem
    3 W% K- g  ?# L# r* k; a
  13. TEMPLATE = app
    & D  k4 u7 \9 p% Z/ w& Z$ N

  14. ! x- e$ @* M3 m8 m5 V$ s: P
  15. # The following define makes your compiler emit warnings if you use9 y1 D/ A4 N+ C4 Z/ a
  16. # any feature of Qt which as been marked as deprecated (the exact warnings
    # j/ d$ X" T! Q
  17. # depend on your compiler). Please consult the documentation of the% b) W+ Z/ J. Y, }& c- L2 O, l
  18. # deprecated API in order to know how to port your code away from it.
    + ?! `4 M7 C* R% H
  19. DEFINES += QT_DEPRECATED_WARNINGS8 J+ O2 C4 T. v8 Z9 w: T8 w  k  \. l
  20. ( R  b7 A1 u1 s
  21. # You can also make your code fail to compile if you use deprecated APIs.& H. X6 n$ w- P  v: `/ [4 C
  22. # In order to do so, uncomment the following line.' V# g1 }. k) o1 r
  23. # You can also select to disable deprecated APIs only up to a certain version of Qt./ Z) h3 W2 U5 l% y
  24. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0( n& C9 S! m' ]/ z+ M

  25. 3 f0 K2 J, y! J

  26. # V4 r  }7 \4 w( w  g( `
  27. SOURCES += main.cpp\
    2 T# S* l, a; s, j9 M
  28.         widget.cpp \
    9 c) S$ e% K' \" B7 }9 P" e- ^5 Q
  29.     YmodemFileReceive.cpp \. ^- \( ]# W' j1 X
  30.     Ymodem.cpp \, D% l! B6 F2 _. v, O$ A
  31.     YmodemFileTransmit.cpp
    8 b: f  P! O5 A9 m8 L
  32. ' S  @- l! h* s! Z8 F; ]
  33. HEADERS  += widget.h \
    % }9 F. g0 Y% N+ C* B! f& B0 U' A0 R
  34.     Ymodem.h \  o/ ?: T* H6 E2 W) M& C: N) n
  35.     YmodemFileReceive.h \
    . X' Q& M( O7 n( J8 L$ C
  36.     YmodemFileTransmit.h$ H+ i% I, C" ?) q: B# f% S  t. P

  37. ; @# R0 t0 U9 {6 o# }- S& X# j8 H
  38. FORMS    += widget.ui
    , h$ f( [' O# h# u
  39. 7 N# P! F8 O( U; F6 g7 M! }# D
  40. RC_ICONS = SerialPortYmodem.ico
    % B9 ^% ^8 F& H$ X
复制代码

" E3 O- ^! j8 B+ }, F0 v      SerialPortYmodem.ico文件
) ]+ f; g# L. r! N. k  V

) O: N7 A7 Z9 f: |' Z3 z3,运行效果+ O; _7 {  m" r

1 h; G# `. m# `/ L/ M& c0 [+ `5 a
3 I# M2 x& Q( d6 z$ i
/ V& ]4 w+ J; F& ^1 r. b* h, W
7 t' {  X4 K0 _6 Y% I1 @8 E- m$ x! [
XinLiYF 回答时间:2018-3-6 22:33:09
可以用来做用户程序升级的上位机软件。GitHub仓库有工程,还有资料。
anobodykey 回答时间:2018-3-7 09:21:37
感谢楼主分享
shuihehe 回答时间:2018-8-13 15:37:45
网络在线升级的技术资料呢?
any012 回答时间:2018-12-19 14:03:21
请教,单片机端如何处理呢?
XinLiYF 回答时间:2018-12-22 17:06:17
any012 发表于 2018-12-19 14:035 I8 N' Z$ p7 p+ w, v! v
请教,单片机端如何处理呢?
) {, a% m* X# o! _3 `- I
可以移植到单片机上,文件的接收和发送都支持。
Kevin_G 回答时间:2018-12-26 09:46:05
收藏
huangchao09 回答时间:2019-3-24 20:37:59
多谢楼主共享

所属标签

相似分享

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