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

YMODEM协议串口文件传输

[复制链接]
XinLiYF 发布时间:2018-3-6 22:28
YMODEM协议串口文件传输
GitHub仓库:http://github.com/XinLiGitHub/SerialPortYmodem* I9 [, C) J  [& {+ a2 i4 j% b
PS:博文不再更新,后续更新会在GitHub仓库进行。. Y5 y% c! O6 E1 t
; ^6 O; c: \$ }! E

9 K2 L- e# s) a' x  k- z7 E    串口通过YMODEM协议进行文件传输。程序中涉及到YMODEM协议知识,详细介绍见维基百科[YMODEM](http://en.wikipedia.org/wiki/YMODEM)。9 A1 X" R. S3 r; N- W/ U
! E$ r. T/ R, ^! M( N0 Q$ `
1,开发环境
, B5 o' K' T2 k4 i2 L      1,框架:Qt 5.7.1
: I' q. M. `, x" o! S6 B* a8 v

% C# z) [+ n' V' N1 {$ i. d      2,编译器:MSVC2015_64bit, E* c6 N7 @0 U3 u- ^8 J4 I3 e

: `" e( X/ l% G& I      3,IDE:Qt Creator 4.2.0 社区版
  c1 j+ P* x, @. ~9 b      4,操作系统:Windows 10 专业版
7 {$ [# F' Y% [
0 C; _+ p9 V; v. k( I2,程序源码
3 S  C/ G7 {  I* v* m9 n      Ymodem.h文件0 s1 ?+ U1 d/ V" W( ?+ n
  1. /**
    + ^- X. h$ r' K7 V
  2.   ******************************************************************************
    7 K7 ?9 C" C* a2 L
  3.   * @file    Ymodem.h3 x1 W) a" \- x1 j# u4 T4 t
  4.   * @author  XinLi
    : s7 ^1 S3 r5 |0 |3 h% [
  5.   * @version v1.0
    , H# U  m. c$ [* d: T
  6.   * @date    21-January-2018
    , M/ _, J& ~; `" T" z0 A3 A2 u
  7.   * @brief   Header file for Ymodem.cpp module.
    5 B3 X1 N9 v% j; L, P, f
  8.   ******************************************************************************: v" R/ B# \  t
  9.   * @attention2 i% l- m8 {% @/ S
  10.   *3 u' e8 x5 m3 a8 |8 J  W
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>
    ' w' V& a6 t' x' s5 N: D+ V2 N
  12.   *$ r2 [: s" K* x" Q
  13.   * This program is free software: you can redistribute it and/or modify
    0 G# C9 X: v: s9 c+ O9 {" \5 I
  14.   * it under the terms of the GNU General Public License as published by" e/ x" r6 m" P( b  w
  15.   * the Free Software Foundation, either version 3 of the License, or2 _; H2 Z2 Q$ U  h5 o# @( L/ R+ r
  16.   * (at your option) any later version.
    9 Q4 K' V# ?1 x% o
  17.   *# S* m! U) b# o" e' A( T
  18.   * This program is distributed in the hope that it will be useful,) N4 K1 L: j+ n" B0 W, @" F% u
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of' `1 m$ I5 W' N2 I: z, M* D
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the# T) Y) K* T: a6 `
  21.   * GNU General Public License for more details.
    . y5 z, V9 H6 M2 [7 b
  22.   *
    8 k- L2 I, @% _& ~+ d
  23.   * You should have received a copy of the GNU General Public License/ B+ o5 A6 F+ G7 n+ ^( b7 J- z+ J
  24.   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    - @- y  E7 j$ C5 I2 ]9 Y& w2 h
  25.   *
    8 j; d& E& ~+ D6 ?  g% ^3 ^
  26.   ******************************************************************************
    * J: s( J8 ~% x: Y- p
  27.   */
    . w3 p9 K0 D' v# J
  28. $ t/ `8 b7 d" Q  M- u
  29. #ifndef __YMODEM_H- b4 t, g0 y8 o9 k5 L
  30. #define __YMODEM_H( F) i. n0 r: O. k9 V5 [# d" k
  31. , c. k7 R: @: _0 O* Z7 ~
  32. /* Header includes -----------------------------------------------------------*/) |0 `& S9 F8 E& {
  33. #include <stdint.h>& w- P3 e* t8 T# d4 V0 x' a* j
  34. . I9 z0 ^8 D6 c* L* ^# N
  35. /* Macro definitions ---------------------------------------------------------*/
    2 ~8 L5 \- z/ W* F
  36. #define YMODEM_PACKET_HEADER    (3)
    3 N& T7 M8 {" Q. [# `2 Z# N$ f
  37. #define YMODEM_PACKET_TRAILER   (2)
    6 {' ^4 [( U) c2 _: a( o  p+ r' l2 n
  38. #define YMODEM_PACKET_OVERHEAD  (YMODEM_PACKET_HEADER + YMODEM_PACKET_TRAILER)
    % \- T2 d1 d) Z2 T
  39. #define YMODEM_PACKET_SIZE      (128)
    7 }0 `2 Y/ f( f
  40. #define YMODEM_PACKET_1K_SIZE   (1024)
    7 T' U5 U; `9 B
  41. 4 b; B  k$ t, [% c. T$ s% b; K
  42. #define YMODEM_CODE_CAN_NUMBER  (5)
    , l4 t+ ?, s6 h. \6 ^
  43. 2 V( t% E) }& Z, X, f. N6 k6 _
  44. /* Type definitions ----------------------------------------------------------*/
    , C6 O: |* A( ^+ b3 A
  45. class Ymodem
    1 H5 h3 O* F( S( j3 l
  46. {
    3 [& I/ ?, T' u  C; L5 I3 ?( G
  47. public:& d" m9 ~( Z7 r
  48.   enum Code
    9 V+ {% S" {5 |. v- ^# e
  49.   {
      C- c1 }* Z3 R, [
  50.     CodeNone = 0x00,
    6 P: s" V6 T$ F- }
  51.     CodeSoh  = 0x01,
    1 D$ F6 e2 ]; e, P: m7 J
  52.     CodeStx  = 0x02,/ v1 M: ]; h7 R+ _
  53.     CodeEot  = 0x04,
    . E0 t) e# G9 X+ A) O; l: g
  54.     CodeAck  = 0x06,: J. A& J" Z) W, {
  55.     CodeNak  = 0x15,
    * S$ {( m: E% J* J
  56.     CodeCan  = 0x18,' b) V& c# i0 S
  57.     CodeC    = 0x43,
    ) z# O: `4 ~9 c8 P, {
  58.     CodeA1   = 0x41,4 R9 ^2 O9 _& ]
  59.     CodeA2   = 0x61( o8 N) @$ p) {. x1 {& s
  60.   };; A# v: A; Z" E& n/ b

  61. 5 v( F6 k( v2 D# G& e: ?( J
  62.   enum Stage
    2 z. ]8 X; @# j% t2 f
  63.   {
    7 j4 m( T* f* v! ]3 K
  64.     StageNone,# _' P. I( p, L/ R7 @
  65.     StageEstablishing,
    : P0 r' ^; o: {* q+ X
  66.     StageEstablished,- z( v5 P5 c! ~" C' M* u- i
  67.     StageTransmitting,
    ) u) B! L" l, ], [* {
  68.     StageFinishing,
    # e. V2 v4 v' a( @) ?
  69.     StageFinished3 M9 R/ j7 l* T+ y, q- ^
  70.   };0 R( m  H1 H' S+ j1 P

  71. 8 |* t- {7 A% `2 a
  72.   enum Status0 l# N$ G9 o, H( z' \1 K
  73.   {
    1 q- y7 O& j$ k
  74.     StatusEstablish,
    6 L/ p% t; P3 V! z0 d4 S" [
  75.     StatusTransmit,
    . Z! l4 e# u) H/ |! a
  76.     StatusFinish,
    * B) z: G0 `  e1 ~5 h1 y
  77.     StatusAbort,
    " }% `3 C$ M7 G" p, ?9 g, L
  78.     StatusTimeout,& n! d9 d6 p9 i- s+ x2 y& i
  79.     StatusError$ a2 k; r& l- s# h* ?/ ]
  80.   };
    3 j+ c( }: K  v2 B% _, c* |# g5 B

  81. - h0 G2 L/ I2 e+ p' S+ s. x3 f
  82.   Ymodem(uint32_t timeDivide = 499, uint32_t timeMax = 5, uint32_t errorMax = 999);
    , R/ \, R- ]0 q2 ]. @" T
  83.   {1 c9 J* _) X# _) J5 t+ j
  84.   void setTimeDivide(uint32_t timeDivide);0 t- u1 [' l4 C9 i/ a+ ?6 I
  85.   uint32_t getTimeDivide();, v5 a; P. t2 b2 q& ]1 A7 W

  86. - h# Z2 M" A3 {# F, [) N% [9 q' ~
  87.   void setTimeMax(uint32_t timeMax);/ z' v; r2 c/ B& U$ D8 }, I2 q* M
  88.   uint32_t getTimeMax();
    ) m( H/ Y8 p5 P, r1 `

  89.   P/ k* g6 ~. W' O; x( |- M7 ?/ e
  90.   void setErrorMax(uint32_t errorMax);
    3 n2 \( [: A- Y" u7 u  L% W
  91.   uint32_t getErrorMax();2 K( D* ^' n* W* q7 b8 j& O0 B

  92. 4 a( ^: }6 J  F
  93.   void receive();
    9 Z/ P0 u  e' a, Q$ B: H/ E
  94.   void transmit();2 e' O3 @6 a$ |  C8 v# o/ I' r" e
  95.   void abort();
    & }2 i; D  u: W7 e8 ^- w
  96. / T- T" J+ i/ U2 g" c3 y
  97. private:
    5 W  T2 U5 y: a5 R$ O3 x' Q
  98.   Code receivePacket();8 g/ b) f+ P8 G8 j

  99. 6 J( U. g) g- j8 g% a  W6 P
  100.   void receiveStageNone();
    3 K4 t- A" U  U. h
  101.   void receiveStageEstablishing();/ q! H8 \; f0 D, i
  102.   void receiveStageEstablished();8 r7 O$ b# a: _7 ]% M$ ^  a
  103.   void receiveStageTransmitting();
    4 m6 p" h9 y9 T) o3 `4 p3 k
  104.   void receiveStageFinishing();$ i4 w7 p0 W7 ~# y5 s  o/ B
  105.   void receiveStageFinished();
    7 n8 T7 @  m% K8 H% t5 W4 o+ j- B
  106. 4 E3 w; H# Y# [% L7 S5 I
  107.   void transmitStageNone();
    ; v! C# u9 B' H. P
  108.   void transmitStageEstablishing();) H2 V$ c3 ?0 b, k
  109.   void transmitStageEstablished();+ Q& |( C7 M, o6 G$ {
  110.   void transmitStageTransmitting();1 o! Q3 ?2 h2 f0 Y, ]( s
  111.   void transmitStageFinishing();% g0 b9 b: b5 D4 V
  112.   void transmitStageFinished();
    ; {% ?/ o  Y0 f5 c  f
  113. - G" @' T6 K  Y8 A# p
  114.   uint16_t crc16(uint8_t *buff, uint32_t len);9 A! _! B* O' \1 F7 N# T

  115. ( o! e5 f- E. N
  116.   virtual Code callback(Status status, uint8_t *buff, uint32_t *len) = 0;
    1 t$ Z- o) Y$ [( l3 ]
  117. # X, M, r/ J" }0 }8 b5 w1 s
  118.   virtual uint32_t read(uint8_t *buff, uint32_t len)  = 0;. O* a( }* u. c. l# ?. {
  119.   virtual uint32_t write(uint8_t *buff, uint32_t len) = 0;2 w9 Z6 u( H, L2 |; c9 ^

  120. ! S6 J% h' w7 t6 Z
  121.   uint32_t timeDivide;/ f" d7 ~' e6 c' O! a6 e- U
  122.   uint32_t timeMax;3 [0 B( |4 U: m+ L9 s" Q: ^
  123.   uint32_t errorMax;. B- u! W7 m4 U1 o3 S' g
  124. 8 Q# V$ d2 ~" R; k( Y; O3 X
  125.   uint32_t timeCount;
    2 u3 B$ l6 [! o) s" v5 p
  126.   uint32_t errorCount;7 Y( ^8 l8 f" s$ f1 ~
  127.   uint8_t  dataCount;; p8 [4 d0 _- [7 |6 G4 I" w* f: B5 d* y

  128. # X/ `9 l3 P$ V* ]: |& @% x
  129.   Code  code;9 r" d4 S0 B; c$ ?& k7 p: `& T" m: j
  130.   Stage stage;
    7 l' J: G0 x) ^+ ^- m9 ^! E% E
  131. + S0 O* f2 B- c3 T1 O0 `
  132.   uint8_t  rxBuffer[YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD];5 m) t: y8 x5 I* k* X2 g: k* e( {
  133.   uint8_t  txBuffer[YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD];
    & Y2 }6 f% A: }- a
  134.   uint32_t rxLength;
    / p  a) d+ k$ I) \
  135.   uint32_t txLength;" j2 O: ?" @2 E& A& X
  136. };
    & _& u4 a, `# H% T8 ~1 R
  137. & {% D1 c4 J: V0 K5 u. b( U$ i
  138. /* Variable declarations -----------------------------------------------------*/
    4 A1 I3 V1 D- }: z5 _
  139. /* Variable definitions ------------------------------------------------------*/
    7 W, h7 O: [$ d: u% Q0 ^' i# ]
  140. /* Function declarations -----------------------------------------------------*/
    , S+ W# u- c6 z. T
  141. /* Function definitions ------------------------------------------------------*// H8 m8 Y+ e# T9 o* i

  142. 8 `( X. k, E7 d7 l2 e! m
  143. #endif /* __YMODEM_H */. r: E# n% Z1 B% j& b7 V6 ?! K
复制代码
2 R5 i- {9 u9 @( u
      Ymodem.cpp文件
* H/ r' W& G+ W6 e7 k
  1. /**# k0 h2 D1 l  U( k/ r
  2.   ******************************************************************************, H! N! c1 a# F4 o- f
  3.   * @file    Ymodem.cpp
    4 b$ n) f) K" d% l. A
  4.   * @author  XinLi
    ( v# K5 Q6 Z0 G7 k' \
  5.   * @version v1.0/ I% n7 g. T1 T4 t4 V# l  d1 t
  6.   * @date    21-January-2018* T' g: ~1 _2 @
  7.   * @brief   Ymodem protocol module source file.
    ; D8 \1 Q9 O& w' k
  8.   ******************************************************************************' `, }' C5 ?% G$ E& S7 r
  9.   * @attention- u+ M9 ~, A# @" s: i. ~* e- X; u
  10.   *  J, V4 W" x% |  D" l; e" d
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>
    6 S, @, W: \# {3 F. @
  12.   *
    & e$ s, y) s! ?9 f' O7 Y9 @
  13.   * This program is free software: you can redistribute it and/or modify" F5 x3 O8 h' I
  14.   * it under the terms of the GNU General Public License as published by. ?  x5 A3 M& g$ q& @3 H; A
  15.   * the Free Software Foundation, either version 3 of the License, or
    ! H0 H7 x$ w4 u7 g: ]1 d
  16.   * (at your option) any later version.
    + I% G- X% q6 H9 Z  s! ]; g
  17.   *: S- D- O5 Q+ r" L# w% Q
  18.   * This program is distributed in the hope that it will be useful,
    5 K7 F# c2 |2 u& N2 Q
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of% m  P  l& q+ A! M
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the% u% k7 e) Y: o" Q- x
  21.   * GNU General Public License for more details.3 S) A  Q+ X) t+ _$ b6 Y
  22.   *( C3 c% X9 |4 _6 f7 H5 p; V+ I3 ~
  23.   * You should have received a copy of the GNU General Public License) U" J: _& g/ c' }" \) F
  24.   * along with this program.  If not, see <http://www.gnu.org/licenses/>.4 F, A. \& M0 q- q
  25.   *
    3 U1 T- w7 ^! [1 r
  26.   ******************************************************************************0 K/ h+ x( f! ]
  27.   */
      K. g7 P( h3 z# Z# ~

  28. ) f3 N9 u6 ?$ L/ ~1 ~6 s$ ]
  29. /* Header includes -----------------------------------------------------------*/$ U1 \7 r1 B: ?
  30. #include "Ymodem.h"
    6 n2 X# t0 [, D8 M
  31. #include <string.h>
    ! x- q( |% }) ]4 d6 r5 s' r
  32. , O& Y* t$ b' G6 A- \
  33. /* Macro definitions ---------------------------------------------------------*/4 D  q" f1 b2 V" t; j
  34. /* Type definitions ----------------------------------------------------------*/
    : h; T( Y3 P3 r1 ?3 @5 e* P. L1 P+ G
  35. /* Variable declarations -----------------------------------------------------*/2 A* ?6 x+ u( n; r# d! ^
  36. /* Variable definitions ------------------------------------------------------*/
    . g& f" i  o9 L; o# y1 G, L: K# K. `
  37. /* Function declarations -----------------------------------------------------*/
    * p9 B1 Z, `+ A$ q
  38. /* Function definitions ------------------------------------------------------*/
    9 A, K/ A$ `- ?7 Y7 O, U' u

  39. ( I1 X3 z, _- l8 E; e
  40. /**
    . z1 F) S. K# u8 s
  41.   * @brief  Ymodem constructor.
    9 C% R5 _9 t) O7 \. ?
  42.   * @param  [in] timeDivide: The fractional factor of the time the ymodem is called.- Q4 F/ p6 a; x& I' c0 d
  43.   * @param  [in] timeMax:    The maximum time when calling the ymodem.
    % g" d, K( L; A
  44.   * @param  [in] errorMax:   The maximum error count when calling the ymodem.% S. d: S2 B4 a) r9 v. A
  45.   * @note   The longest waiting time = call time / (@timeDivide + 1) * (@timeMax + 1).
    % a+ |! ?0 O9 G+ y
  46.   * @return None.' t# [4 x# u5 i, r+ q
  47.   */
    9 H; ~0 K# h  t
  48. Ymodem::Ymodem(uint32_t timeDivide, uint32_t timeMax, uint32_t errorMax)
    8 {5 C8 E; a, N8 _  k
  49. {
    % T$ E3 ?8 d' @( m) z: s8 X
  50.   this->timeDivide = timeDivide;" P/ J8 u. }5 ^
  51.   this->timeMax    = timeMax;( q- v. O% t/ Y  r$ F; {! _- n
  52.   this->errorMax   = errorMax;
      L: D% s/ L& L& ~5 a4 b
  53. ; R- N; l7 t  I: x6 A
  54.   this->timeCount  = 0;1 H  x( S) X" K- P: O
  55.   this->errorCount = 0;0 y& c+ j6 q# Z! |5 u
  56.   this->dataCount  = 0;( `9 x2 T+ C3 f

  57. - ^6 |9 @$ {3 r  {( ]. `
  58.   this->code       = CodeNone;0 Z7 I( h+ L3 v8 Z" g2 y
  59.   this->stage      = StageNone;
    % T4 a1 d6 h" V
  60. }" J% g8 d+ g' r$ O# `& f: H: q

  61. ! }2 C% x- k) Z  O
  62. /**& |# ^$ d8 ?$ G+ e
  63.   * @brief  Set the fractional factor of the time the ymodem is called.
    7 T% I9 H0 C/ O- z1 Y7 @: ]
  64.   * @param  [in] timeDivide: The fractional factor of the time the ymodem is called.
    % ?4 U4 Z6 N& ]! }# t. q
  65.   * @return None.0 U2 O4 l. G  j8 W6 A+ o2 l: a- Y
  66.   */
    0 E! g5 E( D& E& S2 {% l
  67. void Ymodem::setTimeDivide(uint32_t timeDivide)
    0 @) L4 k1 y. b( @0 }7 U% W2 V
  68. {* {, J6 l! f  q8 c1 j
  69.   this->timeDivide = timeDivide;5 q) i- E. S/ D# Z
  70. }
    7 X- i/ e8 Q; ]% d- f& B

  71. 2 ^: m+ k$ c, v1 C! f/ w/ y
  72. /**
    / ^3 i! o* K& g
  73.   * @brief  Get the fractional factor of the time the ymodem is called.) ?5 n$ D# f2 P
  74.   * @param  None." Z( M# g8 \6 t" x2 `
  75.   * @return The fractional factor of the time the ymodem is called.2 x. n$ e" K) ~  G( ?4 t! {
  76.   */
    6 H+ ]$ P* o/ {8 q3 z* f# G
  77. uint32_t Ymodem::getTimeDivide()2 O7 ^. B- n  o) n6 n+ d
  78. {  [  k0 y+ d0 r! m
  79.   return timeDivide;5 U  h& K, L1 K4 \8 U# f
  80. }
    , M) e% u6 a/ s2 h$ o6 r$ j) P

  81. 1 F+ a# D! d3 G
  82. /**' m( l* ^5 X. a8 w. t7 H9 R0 r
  83.   * @brief  Set the maximum time when calling the ymodem.
    * h0 ?# m1 t* l" {! \7 H
  84.   * @param  [in] timeMax: The maximum time when calling the ymodem.
    & x1 Y3 z2 N( i( B) z* k
  85.   * @return None.
    5 P. ]2 k# d8 @4 [6 t  V4 r) F
  86.   */0 H8 v( l2 o- M. I
  87. void Ymodem::setTimeMax(uint32_t timeMax)5 P; z  k5 x+ M" V: |' \3 v5 u7 k
  88. {
    # n. C' E# Q2 L6 L- G* I) v6 d
  89.   this->timeMax = timeMax;3 c: e) S" [4 B" K. p# k
  90. }5 I1 F8 g+ \6 e
  91. , P7 K( L  H$ q! V) j
  92. /**
    3 `  O& U" i4 m+ B; x
  93.   * @brief  Get the maximum time when calling the ymodem.
    * S9 G% d. N2 s
  94.   * @param  None.
    , O# R- s# c* W8 o; h
  95.   * @return The maximum time when calling the ymodem.) S6 v3 I, z/ q& u) g6 R
  96.   */
    8 V6 ?4 h6 [; e! ]& ^6 z( x
  97. uint32_t Ymodem::getTimeMax()
    ' l8 K+ V3 @5 v) q. F" L) S
  98. {
    . N+ z' g# W) F. s  V+ I
  99.   return timeMax;
    $ Z" |% A( ?% U0 x8 C$ Z9 e! ?" t
  100. }0 A4 {( Q: _- t! ?
  101. % J7 {  e- T7 z4 W5 q' j
  102. /**5 B  B# p; ?5 y" e- m
  103.   * @brief  Set the maximum error count when calling the ymodem.
    * j6 A& {3 _  K. d- g6 h# ]- F
  104.   * @param  [in] errorMax: The maximum error count when calling the ymodem.1 `4 N: f8 t0 G4 C! a5 |+ m
  105.   * @return None.: w' n3 r2 {* k( X$ a, n0 l
  106.   */( |5 s" z/ l9 a3 a) l2 G
  107. void Ymodem::setErrorMax(uint32_t errorMax)5 h# _3 h6 B1 |5 Q7 g
  108. {
    * p# u/ P& l% |& |) a. l0 j  B% f
  109.   this->errorMax = errorMax;
    6 N) Y8 m/ o* D3 Q. m6 j. a! [
  110. }0 x6 ]& `" b, W* d/ u6 m

  111. ' \+ c, B  w- p. U2 {1 c/ R
  112. /**
    9 v7 ?! e5 q* B- H% _
  113.   * @brief  Get the maximum error count when calling the ymodem.- d4 k6 r2 b  ~, r- R- Z
  114.   * @param  None.8 i9 d* u8 ~. r* _1 z; ]7 @+ h
  115.   * @return The maximum error count when calling the ymodem.
    : A6 D/ N2 U# u) Z8 j/ o
  116.   */
    ! x/ {6 T9 k/ I
  117. uint32_t Ymodem::getErrorMax()
    ( v2 O( |/ q+ x
  118. {
    # d; I6 L# b8 r
  119.   return errorMax;# Y$ ~! f% O' U, B$ }
  120. }, ]& q6 y: o( f7 ?) d- B6 G0 b
  121. 2 o4 w: j' y- g$ S: v
  122. /**; J* o+ w- G4 T; K1 J/ y9 o2 L
  123.   * @brief  Ymodem receive.4 k- S; u, E% r
  124.   * @param  None.9 L) O2 Z* D* y$ M' V8 |5 n
  125.   * @return None./ |1 [6 t; i0 {% |8 A4 U  n
  126.   */2 ]3 z: H/ @& c% K2 P% C6 _
  127. void Ymodem::receive()
    ) A9 b9 `' e# U7 |! L' e' ?  n
  128. {
    3 J/ Q% Z* Q- i# Y+ D
  129.   switch(stage)1 p5 G4 X( \" f
  130.   {$ D9 [' v  D1 n  G/ w5 P
  131.     case StageNone:. X" t' w3 Z' L' g6 ?( l( B+ T8 N! u0 {
  132.     {
    - O* ~1 @" b& d$ u
  133.       receiveStageNone();
    8 I# v, b( [8 S7 L. n4 O
  134. : w$ t5 W! n5 ~) o
  135.       break;
    3 ^) U# K6 A. Z. r# x* e% C8 ^/ Z7 W
  136.     }( d8 D! E* L/ ~* p; s4 B' {% ~
  137.   F7 t# S" c" D( f% ~
  138.     case StageEstablishing:& n" P3 T1 d( H
  139.     {: s# ?. q. ?4 o& R
  140.       receiveStageEstablishing();2 w! M" p- {8 E9 N
  141. - w) G/ D5 w/ g. d, ^( ?) s
  142.       break;
    & N! n- d3 n  B8 o- {
  143.     }7 e- w) b& L1 u( [# f& ~

  144. 9 {5 x  S. Q9 Y! @7 H# q1 U( G3 f
  145.     case StageEstablished:: u. i, @$ F9 n% z/ m
  146.     {$ O# Y" b- d, a! [
  147.       receiveStageEstablished();
    3 J1 A5 V7 f/ i5 j- d

  148. % E. M9 ~5 d/ a$ E! O9 }9 s: {
  149.       break;
    ( x7 G* e) @2 z5 _$ x* X
  150.     }2 u2 B0 `' }8 }1 ?3 j, a6 Y
  151. 9 |! u( X+ h5 d- C0 F
  152.     case StageTransmitting:8 e. I+ T% k" A4 ^
  153.     {$ o. O% \+ f* l. R) o
  154.       receiveStageTransmitting();
    * L+ N" ~: n& F+ _2 B
  155. * t4 m" B5 o" R( T# s7 F+ G
  156.       break;  x$ x. b: ?" d! V" \
  157.     }
    * Y$ T9 v7 f9 E" u' a- t

  158. 3 O) n1 z5 ]( s- V, Y% d8 k
  159.     case StageFinishing:
    . m% c4 m  N4 o
  160.     {
    ! q0 U1 r& X# j: K: J7 Q! K0 R
  161.       receiveStageFinishing();
    # Y7 W' T9 p6 Y

  162. ) @/ _- f" x  g3 R* J
  163.       break;
    0 u2 C; Z) s' Z# z9 ^# ^; j" R
  164.     }
    9 T4 B8 }% S2 W; p0 h

  165. ' P! P6 y9 G  X" v, |( C  g0 {
  166.     default:6 E; {+ |  j1 y' Z
  167.     {% o2 b6 O& }2 l1 g: I+ m2 L+ Z+ S
  168.       receiveStageFinished();$ B" Y  y, _1 Z4 [
  169.     }% U; G- _0 i2 H. X- J3 \
  170.   }
    ' j2 A5 A6 A% x$ _
  171. }; ~3 {" }9 ?/ @  l& l5 v

  172. ! v' F" O4 U; `- W2 I: p4 @
  173. /**% K/ ~- k( l2 F! v
  174.   * @brief  Ymodem transmit.
    3 {2 I2 f4 F5 ]: z; U) l
  175.   * @param  None./ h3 y1 G! u7 W
  176.   * @return None.
    + e2 H: m8 F- r
  177.   */  ~& H+ P" \# l4 y; H% T
  178. void Ymodem::transmit(); @0 R$ F1 T) f+ z: v! }$ N: s+ u6 w
  179. {
    # R2 b" S( o& h" g% X6 N" Y
  180.   switch(stage)
    & ^( r# v9 g$ F+ f$ o. T8 n
  181.   {
    1 H7 n9 Z. y- s
  182.     case StageNone:& c: v+ i8 v- l2 o1 k; ^% Q9 y
  183.     {
    7 Q$ p3 x2 K4 X$ A+ y2 C
  184.       transmitStageNone();
    5 S) J- `  V& ^3 m0 f
  185. 7 ~' L! H* u# C
  186.       break;
    7 }/ b" W9 @' Z9 `  p
  187.     }
    . Q4 m) s/ c. _# \
  188. 1 t* o9 x9 B5 K! v" v7 s  M  }, @
  189.     case StageEstablishing:) V& w2 }/ N) T4 H' C1 P
  190.     {( p9 h2 @2 f+ S, k1 F# Z4 k9 z! p
  191.       transmitStageEstablishing();
    * x1 L, R+ r% b) m6 ~

  192. , _0 n' q# z$ l" c2 w
  193.       break;
    ; h1 D1 f# @! f" D$ E+ |" |
  194.     }
    . p1 T: a4 P+ J  a3 T
  195. 6 X4 P2 }: `; V
  196.     case StageEstablished:
    3 ]: i6 A& Z" f
  197.     {
    9 w* i  W/ y' Z. Q1 M% q
  198.       transmitStageEstablished();9 m2 @, Q* `, j

  199. 4 q3 I& `# K0 v$ h5 {# s5 Q
  200.       break;
    . [( k  d! Y8 \, x8 _
  201.     }$ c$ L) u5 f; y2 a. I# u# s
  202. 9 p5 y0 z6 x' G
  203.     case StageTransmitting:
    ) y( N0 i5 H( W4 b' i8 j
  204.     {" ~$ y+ Z6 j2 x
  205.       transmitStageTransmitting();; `/ P* z: Q0 g9 F) Z! C
  206. ( r- w) X  G/ A1 D! B' b1 L
  207.       break;+ L( ^8 N. _6 T
  208.     }
    3 w0 @& w; U! [' v1 {$ Z  S

  209. ; w$ d7 w1 _/ {/ @, S; q+ {
  210.     case StageFinishing:: I. }, u* c0 m4 p
  211.     {4 t( |; K& z8 `
  212.       transmitStageFinishing();
    9 K+ L4 b7 k9 ?/ j, r

  213. 1 |8 K5 D% F' N0 t; K' C$ s
  214.       break;2 K1 _9 l9 o# ~$ ^& E+ q" v( n
  215.     }% {! w/ E  f& P1 {  \6 O% ?
  216. : H* F: ?; q4 N( \8 ?8 \: C
  217.     default:
    $ p1 u8 n$ l6 c* ]
  218.     {/ B2 c8 [( H7 U9 ?; I* U
  219.       transmitStageFinished();1 Z4 n% e7 U2 n% V7 ~7 Z
  220.     }( [% n* j: K  J1 R1 A
  221.   }8 R8 e1 y5 e6 O# }" X, ~7 [
  222. }
    1 K0 f+ N  j2 m7 j/ i! ?. P

  223. & ?' m% l3 U& g9 ~+ |) {9 h
  224. /**
    5 c4 Z% \3 l3 d- P) c
  225.   * @brief  Ymodem abort.
    / w1 q" S; N1 c4 N- e& s8 f5 O9 X
  226.   * @param  None.9 X* Q* b7 |- @5 p! ?% M
  227.   * @return None.5 R8 Z5 s$ M+ J- h8 }
  228.   */" d% F+ n+ F' C: c3 n: Z5 _
  229. void Ymodem::abort()7 c1 q) I5 u1 G& r
  230. {  ]$ O: i' t' |2 S" a8 N4 }" [
  231.   timeCount  = 0;
    4 j1 D" p, w  b) W) U
  232.   errorCount = 0;
    2 }3 \/ W# L1 ^
  233.   dataCount  = 0;
    ; D  C! K  n" }' B
  234.   code       = CodeNone;
    2 b* L7 J4 K7 C! H1 j7 v$ s1 t: K
  235.   stage      = StageNone;
    0 H% b6 K% I6 a' N

  236. 0 o$ E! Q( p' E- _; ~+ ?) A$ u  N7 m
  237.   for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)4 ^3 a. u# t. ~% {' C6 c+ {
  238.   {9 `* Z! d" Q7 k) O
  239.     txBuffer[txLength] = CodeCan;* P* D: `  C& T
  240.   }( A# s. ]" v5 s) B
  241. 1 L9 X1 r6 j5 s! Z2 I" G
  242.   write(txBuffer, txLength);
    0 g+ E3 Y+ ]6 H) \5 u" {/ r: a' F, i
  243. }
    8 Y. h5 m) C: m

  244. 5 @4 r' |! {$ o4 u! E, l
  245. /**% I; g$ s" G& K4 k4 z" |0 k
  246.   * @brief  Receives a packet of data.
    ; v2 k  {  f( q: Q2 P0 Q& A
  247.   * @param  None.
    3 z9 U7 Z- Y- u2 @0 m! T4 V! F
  248.   * @return Packet type.3 ~& W" v1 {. X6 G" A$ T. T* c
  249.   */$ |* _& A& g4 P8 K0 p6 m
  250. Ymodem::Code Ymodem::receivePacket()
    4 Z7 w4 m- M, R+ T0 Q
  251. {* F, n6 |4 S# g& h: h
  252.   if(code == CodeNone)7 r, q, C9 g+ {) {( R# D
  253.   {
    ) X. J. z; e0 X+ o6 G
  254.     if(read(&(rxBuffer[0]), 1) > 0)1 K4 g1 z0 b5 N. W
  255.     {4 K% C0 N) o: a& t" D! S  r
  256.       if(rxBuffer[0] == CodeSoh)
    ' X' g- {& x' s# S% h3 M0 J: X/ s. U
  257.       {$ v# X. S. b( L# O! `
  258.         uint32_t len = read(&(rxBuffer[1]), YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 1);' }  I9 i- W6 R- [' l! @3 a' i

  259. - t9 G6 w2 ^- u+ s
  260.         if(len < (YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 1))
    5 V& Q8 {' _3 D4 @
  261.         {
    ; c" K8 B+ h7 x
  262.           rxLength = len + 1;
    , \: f, e; Z, k
  263.           code     = CodeSoh;4 Q0 v9 \0 R1 R8 y6 R
  264. 7 i8 d) B4 _$ Z$ n
  265.           return CodeNone;
    7 G# a  O$ V3 J' i% ~
  266.         }; B) `2 y! w& b* \, e/ E/ j
  267.         else
    ( y8 F5 M# d9 L# m9 x& U
  268.         {/ U3 [1 D) G+ {' L: N9 E5 y
  269.           return CodeSoh;* i0 Q9 W3 H! s5 D4 G' V
  270.         }2 p: U( \0 N# J
  271.       }
    0 a! r" Y6 R; {& \+ V: r/ t
  272.       else if(rxBuffer[0] == CodeStx)3 L8 O- Q' J% j9 g3 A
  273.       {7 w! Q8 c9 ^3 k1 k6 l/ q
  274.         uint32_t len = read(&(rxBuffer[1]), YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - 1);5 ^% ^4 n6 E5 D6 U: ]* L
  275. 4 n* w3 [- B8 Z+ l' u& s3 T0 _8 l
  276.         if(len < (YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - 1))4 s7 O* m* x% Y4 N' k5 P+ O
  277.         {7 Y& c& F0 m/ i  K$ I2 x3 l
  278.           rxLength = len + 1;
    0 J; v' I9 b: A6 p
  279.           code     = CodeStx;& c" u$ W( b$ w9 j

  280. , q3 v4 ?% [! Z3 k8 }6 P; x
  281.           return CodeNone;
    0 j; y- |! O* f& I9 [
  282.         }
    0 _7 q! U" c. b5 D+ [, C0 E8 f
  283.         else+ L5 D) N4 s# H* y) K: A
  284.         {
    3 h3 C. ]1 t( A; y
  285.           return CodeStx;2 d- u3 q8 f6 k) k
  286.         }9 y: q4 x* f$ y# R1 c8 G. a
  287.       }6 s( |/ c9 [; v" r  k+ [
  288.       else
      g+ J  q4 f" A+ j& r. x
  289.       {
    : c3 D. ]' m' z5 D. ^4 b
  290.         return (Code)(rxBuffer[0]);, M% B; i. ~; ~  W8 H! M3 ~% Z
  291.       }
    * _' f$ }# o( j) ^/ h
  292.     }
    7 s# q9 [; M$ c
  293.     else0 X' ^! w; Q% `; K- e
  294.     {2 U  M3 t, e) x, j- O/ x
  295.       return CodeNone;
    : m4 H0 O. [: N7 r
  296.     }
    1 F! z* h- d5 N8 k4 Z, M& r. s
  297.   }4 A8 q) S: q; e4 g* }
  298.   else
    $ l# H. v  K( g) F& F0 V% W" c
  299.   {* B, Z, z/ X2 ]% w
  300.     if(code == CodeSoh)4 S! P! L7 c+ O2 k( U2 ?3 c
  301.     {* I3 i+ ^, r+ Q& H* @4 m4 j
  302.       uint32_t len = read(&(rxBuffer[rxLength]), YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - rxLength);6 \* p# a) s3 t, g/ k, _& _1 x! n

  303. 4 I$ e. s( q, g: d2 x1 ]) w3 [
  304.       if(len < (YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - rxLength)): ]7 D3 i2 O! m+ @
  305.       {  Q. h, r; t: J: t7 c  M( Y0 A; _
  306.         rxLength += len;
    ) i& ?& e0 t" p' G$ u( @% s
  307. ; H$ j# Y# P- C0 D
  308.         return CodeNone;
    - d# w0 q6 V; S) s' `: L& K# ?3 ~
  309.       }
    1 ^5 R2 _- x4 C
  310.       else
    1 c6 ~. R+ l2 h+ u( `" }) A& C* e
  311.       {
    . o. y2 Y, t4 n) f
  312.         code = CodeNone;/ L/ O/ d2 ]* c) O5 B: c0 I0 b- E

  313. 4 Q1 [) X3 V3 H6 z: A
  314.         return CodeSoh;
    9 A, F/ K/ B& T" [
  315.       }( I$ v* F/ }+ t7 o5 s8 N2 z2 o9 i5 V+ U
  316.     }
    + J4 t  F( z% ^- V7 x" y/ W5 }
  317.     else if(code == CodeStx)+ L1 ?+ s8 I- }% E: @# \8 f8 ~7 n
  318.     {; W& ~/ ^0 R" s; \/ w
  319.       uint32_t len = read(&(rxBuffer[rxLength]), YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - rxLength);8 a7 X2 k( n0 a
  320. " L: R3 d8 P0 b
  321.       if(len < (YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - rxLength))7 C8 }: w7 w8 B; y+ B& U3 ]+ P
  322.       {
    ' S' M9 `. ?. O  W
  323.         rxLength += len;, F& P* l5 M% o

  324. 4 b" F5 Q- q2 L8 c9 U
  325.         return CodeNone;
    2 i, P) h7 V: ~* b0 h
  326.       }" b  z9 a5 I1 u" K9 P
  327.       else
    - n" F* o, [* P" W& t
  328.       {7 O' h3 K* b0 i% N( Q4 d" I
  329.         code = CodeNone;
    ; X3 ~: ~" k2 \5 N. e/ ^+ v2 f
  330. 5 d0 b9 f/ Q) q" k. r
  331.         return CodeStx;, `* W, }3 K" v
  332.       }
    8 Y) n- p/ F! ?
  333.     }
    , v$ C0 E: T/ I0 X! y1 o
  334.     else
    6 U5 I5 }8 m2 S
  335.     {/ o( [0 a7 z) Z* x$ ~
  336.       code = CodeNone;
    0 P" W- d4 Q, I% q
  337. & q6 ^  O+ [4 z. f% e! z/ w
  338.       return CodeNone;
    : K) @. b1 _& p& x- l9 ^
  339.     }
    9 w/ g- w1 l1 \- s+ p0 _% G
  340.   }* r4 `- B/ Y7 }. `/ d! i4 y- N& B
  341. }# v8 V  P$ v" {" |9 _. H

  342. ! ]2 c6 C) n# S( e
  343. /**; a& M: m! i% A6 B% C; i
  344.   * @brief  Receive none stage.; p" c+ `' [% V( M+ R
  345.   * @param  None.+ b& Z/ i# w" v# f$ U. m
  346.   * @return None.
    % E9 e& C9 [* m- \4 Q6 u8 O
  347.   */
    4 o$ ?3 U9 x3 Q' Y
  348. void Ymodem::receiveStageNone()
    , S0 F0 y# x8 S( R& e& B' A; c  Q
  349. {
    $ H  ^' f+ B8 e8 l1 E3 V. w* I
  350.   timeCount   = 0;
    ) R- E' n/ p  o* ~/ @4 Z
  351.   errorCount  = 0;
    : l, ^# C2 a- s6 Q( O- T1 w
  352.   dataCount   = 0;/ f6 ^% e; u( P9 @% e
  353.   code        = CodeNone;
    2 d$ k& ?: g3 k5 _$ M
  354.   stage       = StageEstablishing;! u) ]5 a& z* [/ t0 C
  355.   txBuffer[0] = CodeC;
    ; A" n/ u6 ]6 E; S
  356.   txLength    = 1;2 h9 c6 c0 t  a3 S3 m7 I: y, \
  357.   write(txBuffer, txLength);
    ( ], q( f2 j1 m% P+ |5 J$ A, |! M/ V
  358. }4 p$ {: c; N, }; P6 i- M
  359. % x% ]3 Q: q2 Z$ ^1 h
  360. /**
    3 r4 a0 W6 v8 K' `, l! J2 w
  361.   * @brief  Receive establishing stage.5 e( |9 y! j# G  T% c: Y+ V
  362.   * @param  None.
    ! D* x+ g9 X+ p' D0 W9 S, ?6 }
  363.   * @return None.9 X  B& {" S( u, F+ V. W
  364.   */5 Q8 c" a* p7 z  D5 X  G
  365. void Ymodem::receiveStageEstablishing()0 b& d( \+ i5 x* n! i
  366. {
    & b, Z9 P7 u( s: h* J8 H: {
  367.   switch(receivePacket())* p3 F. ~0 c; I/ W
  368.   {$ @$ W! `2 o4 g! q6 Y/ R2 G" Q
  369.     case CodeSoh:* x+ j! q1 Y0 y  _" j* E
  370.     {
    8 G$ a" v$ k; P1 c/ W: c6 }8 E/ i
  371.       uint16_t crc = ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 2]) << 8) |& h" K( v; e0 R; U- `
  372.                      ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 1]) << 0);
    + @! S& ~& P8 w

  373. + ^; _+ s2 G! G' I* P+ I* _
  374.       if((rxBuffer[1] == 0x00) && (rxBuffer[2] == 0xFF) &&- X" _6 M: v7 V# u/ V
  375.          (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_SIZE))). z' i/ b! o5 D0 P/ d8 T. _
  376.       {, f& s8 ^2 K3 G' h
  377.         uint32_t dataLength = YMODEM_PACKET_SIZE;* h  w* H" U' y6 M+ g: Q8 p+ y: Y
  378. & v  i* Z- f* y; H/ P  g! U" ~/ `$ N
  379.         if(callback(StatusEstablish, &(rxBuffer[YMODEM_PACKET_HEADER]), &dataLength) == CodeAck)) \6 T% ^: O2 s- M4 X1 D
  380.         {: d# }0 E. x9 {( O0 H2 A( c* a6 S
  381.           timeCount   = 0;
    ! d5 j. C7 {4 t$ w" u
  382.           errorCount  = 0;$ U( }4 G3 M: X( N& G9 \
  383.           dataCount   = 0;8 L1 u8 X# _; N8 n# K
  384.           code        = CodeNone;/ e  n1 a' i9 d
  385.           stage       = StageEstablished;
    ( j( t9 K8 F* T+ [4 B* }- i
  386.           txBuffer[0] = CodeAck;
    1 Y- h1 o, r: @* g# G/ e
  387.           txBuffer[1] = CodeC;5 t+ S3 o: ?1 T: S- L8 J& a0 }
  388.           txLength    = 2;
    7 A' V9 h, k; J  T
  389.           write(txBuffer, txLength);8 m& z4 A% Y% r, y, ~, w& z  d
  390.         }3 z+ G! m6 o/ {7 R
  391.         else: u. h$ J' P, [8 \
  392.         {9 w  x, j, i5 u1 P1 o
  393.           timeCount  = 0;
    # ~' e) R1 D- z5 M
  394.           errorCount = 0;
    / a0 g% L3 Y7 p/ T& _2 a8 Z
  395.           dataCount  = 0;
    5 ^$ V7 b# S* Y9 M3 l) k
  396.           code       = CodeNone;3 w1 S: m* y9 j% q0 v& W
  397.           stage      = StageNone;
    8 ^# M; I: N8 V; f  E) `
  398. 0 n% t5 O% ]. m3 ~3 W/ D  L3 w
  399.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    ! h0 |# c* i- @' V% G: N
  400.           {
    + s, M# r+ L/ @6 e
  401.             txBuffer[txLength] = CodeCan;
    1 K, h& X* n( A' ^$ @3 z! x
  402.           }7 [5 b  z' D3 c: Z) a; i* i1 N% I
  403. 8 P" h, ?; W3 v& B
  404.           write(txBuffer, txLength);! e5 h1 q: R" z
  405.         }% d; V! a4 ]4 n! Q; N4 a
  406.       }
    + _' j! c0 @; l6 h. A0 M
  407.       else
    1 R1 @  l$ s# S: Q. R7 T3 [
  408.       {
    ( `! E& S* {7 [, {, B5 [
  409.         errorCount++;
    ( j- |1 o9 r9 `" M/ K# p; [/ b
  410. 1 Q- T3 E- Y8 R5 q
  411.         if(errorCount > errorMax)1 E- @) y8 t' M- b2 C1 F3 E
  412.         {
    ) M/ v5 w: D- N5 ]0 F
  413.           timeCount  = 0;" d4 ~% c* P, p0 z  b3 @% {1 f
  414.           errorCount = 0;
    - |( G% ]7 E. Q
  415.           dataCount  = 0;
    % [2 @3 x; a6 T: L) {1 g$ }
  416.           code       = CodeNone;  g, g8 m# G( ]! @9 x" r5 J, X; C
  417.           stage      = StageNone;8 h( p* U+ J! N  B+ @  M

  418. 0 C; z# v5 N8 u& L/ a3 }, D
  419.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    8 n) Q. b( ^; h4 X* u+ S
  420.           {# _. A$ H7 d* n+ l2 a0 b% u( V
  421.             txBuffer[txLength] = CodeCan;
    ! x* X. I& R" T& x
  422.           }& p0 B* y2 ~0 l3 s+ z

  423. 3 k1 P5 X' m: G1 e$ v$ ^7 @2 Y% X
  424.           write(txBuffer, txLength);* q4 Y* t; F5 V- {8 Q/ w
  425.           callback(StatusError, NULL, NULL);& E5 ^; x( A' O# E. m
  426.         }! s: C$ ^4 G3 p
  427.         else* G* K. w; Q* z
  428.         {( U6 ?* W$ C9 w% ^
  429.           txBuffer[0] = CodeC;
    3 [. i  M5 }) e. ^5 @( n
  430.           txLength    = 1;
    8 }& C2 @% ~" q$ l+ E$ \7 T& l# s, b
  431.           write(txBuffer, txLength);. \/ Z' J) N# Y0 K& h, s
  432.         }; F6 ^6 i  ^4 ^, |
  433.       }8 q/ r) ^5 T0 K( Y6 Q* A5 _3 ^; y
  434. 1 R% p& O. T$ i, t, J/ t
  435.       break;
    2 Z6 M' k. ]5 p$ o, b# K. {
  436.     }
    0 ^8 Z! \# K  b1 M+ q! m. f9 n" S6 ~; C
  437. 2 b9 Z# W- g0 L3 E( s7 X; ~
  438.     case CodeA1:/ ]- H! r4 t. M) E: C/ `3 t
  439.     case CodeA2:5 n  c" |5 w0 h0 S$ x
  440.     case CodeCan:) Z& d! @/ [1 p% m; D* d
  441.     {
    0 Z' T+ m  h* T5 }- S* `
  442.       timeCount  = 0;# h9 V* U$ K* n" B1 _/ C
  443.       errorCount = 0;
    2 S; K. F* F! U. _; e& g
  444.       dataCount  = 0;
    . Y1 b' Y3 b2 ]
  445.       code       = CodeNone;/ B2 h/ s7 n) M! a- @9 n( _3 J
  446.       stage      = StageNone;
    3 a, ^. p5 o, ?' X% ?' J: `. F( h; o
  447.       callback(StatusAbort, NULL, NULL);
    8 y; \( g! o9 |( p
  448. 1 G/ l$ v) U4 x/ Y8 y
  449.       break;
    ) M' W+ G! `* x6 }! i5 ]
  450.     }
    / e6 t: U$ H: Q6 e# D8 n
  451. : \5 j9 N; {! \) L5 K7 y3 e9 H% V
  452.     default:- d# O: l+ E( t3 f# g
  453.     {1 R+ |  A. ^0 v: ]' x1 W$ |
  454.       timeCount++;
    6 w7 e3 ~3 R8 |4 D* T+ h
  455. ! m" _$ t3 Z* |/ S3 w5 J
  456.       if((timeCount / (timeDivide + 1)) > timeMax)8 o% t+ {/ A3 }! w- w0 x) m
  457.       {
    + x: I5 c$ R/ n7 r- S9 `3 ^
  458.         timeCount  = 0;
      R1 J9 v) n" n* r- j' c* |2 ^& o
  459.         errorCount = 0;7 E8 P8 e9 L3 {& V' r
  460.         dataCount  = 0;3 M- s3 z1 q$ k
  461.         code       = CodeNone;/ S: P( X+ Y* U( A
  462.         stage      = StageNone;
    % z1 l/ c+ R2 l
  463. 8 M. ^. A" y( b+ g& E8 o7 [
  464.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    2 ?  A6 H7 L. F/ ]: ?# n
  465.         {# P1 v* p: r( w( P$ y/ U$ T; D
  466.           txBuffer[txLength] = CodeCan;( Q) Z5 X, [5 S5 s" T4 `
  467.         }& k% i$ [: s" H2 ^% o7 o! ?

  468. % n; u4 d3 T! s5 q
  469.         write(txBuffer, txLength);
    $ h; V- K* H- z( K, H
  470.         callback(StatusTimeout, NULL, NULL);
    ' C/ J# k5 p- z% N/ i3 T4 ?: x
  471.       }
    3 {, T5 F5 N6 i, `, @; Y4 e9 E8 ~
  472.       else if((timeCount % (timeDivide + 1)) == 0), d8 ?4 w+ ^. V2 `3 Z8 ?- g7 M
  473.       {8 Z  C# h3 t7 _6 `; n# Z
  474.         txBuffer[0] = CodeC;
    4 ~1 ^: u- ^" E$ w
  475.         txLength    = 1;1 i' ^4 [: J8 a# x
  476.         write(txBuffer, txLength);
    9 w5 c, g) Y- T2 u6 b
  477.       }
    + |! z; j# V( Z) E! W
  478.     }3 n, L  W- U* }) O9 I6 Q
  479.   }/ \+ U0 r- g6 c6 c1 R1 N9 [
  480. }) A; W/ }8 ?$ v& J
  481.   I4 x% j7 G. Y
  482. /**5 a, W4 \+ r' [6 d# M( S
  483.   * @brief  Receive established stage.6 F0 ~. Y$ o7 e  y2 M6 m( p
  484.   * @param  None.
    5 Q" ]+ o2 x. e: v' z, V
  485.   * @return None.# z3 w- u9 O, S; E1 i/ ]4 O- a3 |8 |
  486.   */& X2 F1 s- Z  y: ]6 \. ?
  487. void Ymodem::receiveStageEstablished()
    ( x8 c' w; e& p/ c/ y( Z
  488. {
    " E0 E0 b+ _2 ^- E7 V
  489.   switch(receivePacket())
    3 Y5 d0 a& N; H0 ?! T
  490.   {1 ?% ^; W- D& D9 j4 c
  491.     case CodeSoh:( G4 |* @  F" L( \
  492.     {
    0 _9 p: c7 [$ E' z& N9 r
  493.       uint16_t crc = ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 2]) << 8) |( f( Y% A5 R" E- A
  494.                      ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 1]) << 0);
    , q5 [2 c& h0 X0 U3 c! }( V
  495. 4 ^1 e7 l0 L: K  J
  496.       if((rxBuffer[1] == 0x00) && (rxBuffer[2] == 0xFF) &&. w/ [7 b$ a8 I. L, F9 Y- e8 u$ E
  497.          (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_SIZE)))+ S8 ^/ j; f- X. K2 L7 h0 s
  498.       {
    9 z" [5 W7 Q' _3 V- r! @8 O" l
  499.         errorCount++;
    + E" e# F3 g1 U  d% N

  500. ! ~0 [; v+ s5 W) e2 P4 ]7 `
  501.         if(errorCount > errorMax)- M+ X% i' r) B0 C& G9 A. e
  502.         {/ s0 P; U' N5 a1 P! u7 V. W# M; Q
  503.           timeCount  = 0;
    , d4 C5 T# O2 p  A
  504.           errorCount = 0;- u6 t# c7 m% g  r2 T
  505.           dataCount  = 0;9 q$ e5 d" O- s' }
  506.           code       = CodeNone;7 Y( c/ J3 _# q6 z
  507.           stage      = StageNone;
    % V0 ]& h3 Q. }, a3 H% ~0 B4 I2 e
  508. ' N8 }8 S6 I# f
  509.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)4 W8 O8 k- {" U1 P! j4 f
  510.           {
    - k, w# P# m2 i& X( T* \
  511.             txBuffer[txLength] = CodeCan;* q0 f2 p) S: g1 x. d
  512.           }
    5 c2 K1 e' F  \: d+ B! S( ~
  513. ( i& T5 M! X. \9 a: O( |1 v
  514.           write(txBuffer, txLength);
    3 p; M8 b1 n4 e" {( |2 i7 w1 i
  515.           callback(StatusError, NULL, NULL);+ _3 m: P7 F6 P( e# B
  516.         }
    * B; n5 K5 H! N7 D! {
  517.         else, |  F4 u! ^+ B
  518.         {6 P+ \! z) t# I
  519.           txBuffer[0] = CodeAck;
    0 h0 c: a/ }7 q
  520.           txBuffer[1] = CodeC;
    , Y9 C' t, g2 f
  521.           txLength    = 2;+ n/ b- a( _$ F3 V3 d, X
  522.           write(txBuffer, txLength);/ V7 C, @/ ?2 u! g
  523.         }
    4 ?; f& e* W! B6 E7 G- X6 L/ G
  524.       }$ j8 d6 i# {4 |1 m. ]8 o
  525.       else if((rxBuffer[1] == 0x01) && (rxBuffer[2] == 0xFE) &&, L9 t6 b2 _$ M
  526.               (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_SIZE)))
    - g/ L* |( U7 @3 y) N* W3 P
  527.       {% g. g" t' c7 q) z2 r1 B
  528.         uint32_t dataLength = YMODEM_PACKET_SIZE;( f( u# k( z2 J: n' J" R& F/ w3 v
  529. , z5 U' B9 K7 H2 s9 x& ?
  530.         if(callback(StatusTransmit, &(rxBuffer[YMODEM_PACKET_HEADER]), &dataLength) == CodeAck)
    ' C2 n, \) S8 {' X6 Z# j
  531.         {4 U) \+ P, q3 d; D
  532.           timeCount   = 0;
    $ C9 y, Q3 x- ^: ]
  533.           errorCount  = 0;( J1 v' F" ^" f* N! ~* _
  534.           dataCount   = 1;
    - I! n  N  k4 Z5 c+ ^6 x
  535.           code        = CodeNone;
    % @" T- h0 [/ \" L7 t! C; q9 l% w3 G
  536.           stage       = StageTransmitting;0 [/ J% P, g$ D  V! w! M
  537.           txBuffer[0] = CodeAck;
    ( O4 r6 ^% O) T" V
  538.           txLength    = 1;
    & @# u3 ]( f" T, L
  539.           write(txBuffer, txLength);  ]! M  `; h$ C: S1 I& B1 X
  540.         }
    + r" z! i" I4 s1 ~  H8 n
  541.         else
    # P" V- B( R( S6 a6 _
  542.         {
    $ L6 M& _0 F8 H0 G
  543.           timeCount  = 0;
    * g* d6 s5 E1 G9 [1 j& ?$ ]
  544.           errorCount = 0;, u  l2 v9 h) k& k
  545.           dataCount  = 0;
    / h8 L+ Q2 l; b( J
  546.           code       = CodeNone;/ _- u  A- K! j, f6 q' `
  547.           stage      = StageNone;" Y. p! b7 l& C3 J( m
  548. 1 @6 ?# }* |: v& X
  549.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    ' I# [- a% G+ P% U. ?* t# i
  550.           {
    : P1 i& t4 x! ^7 e3 C% G4 u9 ]& B/ o
  551.             txBuffer[txLength] = CodeCan;
    3 f, G3 M/ |5 y0 M! j! Y
  552.           }
    : ?4 }, J4 U1 h/ b- b- z# ~4 \4 E" j

  553. + Y4 V2 T) V! d  l! [4 S/ n0 {
  554.           write(txBuffer, txLength);3 N* H$ n0 _, y  B1 q
  555.         }
    5 r8 Y" M7 N( S. D1 Z" ?
  556.       }8 \. S- k7 e" |1 S
  557.       else
    & M5 `' h0 |$ C8 S
  558.       {, _, w1 ^1 Y7 n( e
  559.         errorCount++;
    5 N% l( O8 {( s# C8 C+ [/ h# G
  560. 3 k1 P6 Z* `0 X* Z5 ]
  561.         if(errorCount > errorMax)
    - I! Y% l0 Z  {) q8 D8 N- C
  562.         {# U5 p" v. y) ^1 X9 ~% s
  563.           timeCount  = 0;- B1 R0 O. j/ T* v: t! N4 u3 P
  564.           errorCount = 0;3 G# w5 P9 X6 n) J4 F) b- Q7 j
  565.           dataCount  = 0;! a& t: y2 y1 {2 M
  566.           code       = CodeNone;, g8 T. ^; T/ R/ m9 j: `
  567.           stage      = StageNone;
      e/ d  ]) Y, ?; G: S6 b
  568. : h4 [* @3 Y8 n, K  @
  569.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    9 _7 R/ ?7 A; N/ y
  570.           {4 Z- C% H# E" i  @7 W; ~
  571.             txBuffer[txLength] = CodeCan;
    + T7 Z. V% z( \
  572.           }; v8 u7 Z, F) E& `0 W3 X+ B3 u
  573. ( J0 `' Z1 i! K# @7 ^
  574.           write(txBuffer, txLength);( F9 e9 d& I3 _" m# I  k
  575.           callback(StatusError, NULL, NULL);
    : v# ?! B8 M. k9 m4 V
  576.         }+ T6 X$ G2 O5 z. ]5 y& k! I
  577.         else5 k1 n3 ^& t4 ?1 E. L: m
  578.         {
      r; r1 ^5 I; v: z* W
  579.           txBuffer[0] = CodeNak;1 P0 ?7 Z) E4 d. \7 Y) L
  580.           txLength    = 1;2 t+ [' N; u' R; _) z% t9 [1 C4 l( G
  581.           write(txBuffer, txLength);8 m  t; g( e$ A9 H. j' C$ k- A( H
  582.         }
    ' r* a& w( `, ^
  583.       }
    8 x) [  ?$ l# n; Q6 h) E. Y
  584. $ Y- Q0 Q' P& {7 K9 k
  585.       break;7 ], F9 M* @8 L; ]3 S8 }
  586.     }
    * _1 e8 W; L9 M2 W3 J$ O

  587. ! Y& x& S$ k, p
  588.     case CodeStx:
      m9 k% T, F- `9 x3 x' g
  589.     {
    " \. \2 o* H$ d' N* w
  590.       uint16_t crc = ((uint16_t)(rxBuffer[YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - 2]) << 8) |* u! O& Q4 e$ u- R4 G4 c# E9 [
  591.                      ((uint16_t)(rxBuffer[YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - 1]) << 0);
    ; z* \  _7 O1 L: B6 G2 n
  592. % p6 H" K! h% Y0 V( Y' x* q7 U. `& j
  593.       if((rxBuffer[1] == 0x01) && (rxBuffer[2] == 0xFE) &&( y  L: T% [3 p' v. Y- V
  594.          (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_1K_SIZE)))# Q8 z: c# R3 F( @4 A$ m  L6 B
  595.       {
    6 T2 K& D+ n: T- }9 {4 \, e: k
  596.         uint32_t dataLength = YMODEM_PACKET_1K_SIZE;
    $ E) W; \- I, X) s( Y
  597.   D- c9 }9 U6 J9 L2 `7 Z
  598.         if(callback(StatusTransmit, &(rxBuffer[YMODEM_PACKET_HEADER]), &dataLength) == CodeAck)1 W# `! L4 B( c2 V6 q( T
  599.         {
      v( P" C6 P/ q2 x" P, }1 Y4 D8 [0 h* ~
  600.           timeCount   = 0;
    + N2 h, Y' c! g7 ]/ U
  601.           errorCount  = 0;
    - t3 K* V$ d5 {, C
  602.           dataCount   = 1;7 j( B8 I) G3 u
  603.           code        = CodeNone;, _; l+ E7 z$ V/ ]% J: r
  604.           stage       = StageTransmitting;
    ; p% N# h  r: S4 m2 G9 t+ A9 |
  605.           txBuffer[0] = CodeAck;2 w4 K, h" N- M4 t9 O
  606.           txLength    = 1;
    7 U% {& Q4 T7 k3 L3 h$ I
  607.           write(txBuffer, txLength);* F5 f- Y2 u) P3 V# W
  608.         }
    . N7 p2 @. a# ?7 I9 h' O; x$ l
  609.         else1 }6 W) a$ t  L: e9 n% t( V
  610.         {
    $ c9 n& u( _" U8 t. n! I
  611.           timeCount  = 0;! n$ @5 w- b8 E
  612.           errorCount = 0;
    ; ~8 k# t6 L0 B: W5 Z& ]) _
  613.           dataCount  = 0;
    7 A* P' l# [. U! T1 L; I7 M+ y
  614.           code       = CodeNone;
    * i. m6 n: w) n1 A# T
  615.           stage      = StageNone;
    6 n; j* P$ ^, j% z
  616. 4 e7 h7 q9 B! d
  617.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)- \# t! o" X' }" W
  618.           {  p6 \. e' q$ A8 \' T& X1 r4 a
  619.             txBuffer[txLength] = CodeCan;
    $ B# o" O* g9 ^
  620.           }
    * N1 @4 \% I- ^% S

  621.   U2 v  Y( _! k# c1 b
  622.           write(txBuffer, txLength);
    8 r$ a% A; T  g$ {
  623.         }
    8 u, K7 A$ L8 o7 d4 s
  624.       }
    8 v' h- @, S7 f! f* O" \/ Z
  625.       else
    6 B6 `9 ^) G% ?
  626.       {$ `4 P. d# |: x4 B7 ^( c& Y
  627.         errorCount++;6 J# l1 L4 o0 E
  628. 4 Y, {8 I3 y7 p6 `; ~
  629.         if(errorCount > errorMax)
    : R9 \0 g8 h, g" Q9 v
  630.         {
      L, X, R! e& B
  631.           timeCount  = 0;: Z4 x  m/ O4 s" u) k$ n
  632.           errorCount = 0;+ \6 q: L+ X" d
  633.           dataCount  = 0;% @1 o/ V8 P3 a8 E' {3 I
  634.           code       = CodeNone;
    * b1 K2 w6 ]5 `& ?
  635.           stage      = StageNone;
    . R, p& R: b( F& r- C- c

  636. 3 L  g7 E$ e0 `0 y3 K4 e' L
  637.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)" T- p5 o9 C$ Z- Q
  638.           {
    . H" u6 J# e0 p: x
  639.             txBuffer[txLength] = CodeCan;
    , q+ H* I- _% G* [. H; I
  640.           }
    , u+ j* j( k+ }1 ]4 `
  641. ' U! i/ d. |8 p: X4 X# L% V
  642.           write(txBuffer, txLength);
    3 A: Z; p6 W  u6 j/ V% |4 C/ L" Q& I
  643.           callback(StatusError, NULL, NULL);" T: T7 {5 {7 [: h* M6 J8 h
  644.         }
    " ~$ M* L1 x; S5 Q# h. l
  645.         else
      p; M% k+ n. ?! u3 m) X2 x& i
  646.         {; W; I+ |2 P, w3 A/ w; m
  647.           txBuffer[0] = CodeNak;
    7 ]$ r$ Y9 S" I% i. z4 o' [# Y1 \
  648.           txLength    = 1;
    : l3 V" y! Z$ I% U2 ]
  649.           write(txBuffer, txLength);9 p% H4 X, x( R" H, i- E/ p
  650.         }
    + t) j; I" P! }& @  X! P
  651.       }# n4 H( R# ?# g; _

  652. * n- @. _) V! v3 y' R6 {) X8 `
  653.       break;
    0 t# t. i  b$ P6 u2 ]" K4 H
  654.     }
    2 j& ~+ e3 j6 Y+ w+ l4 D

  655. ; g" I3 _8 K+ H! K( Z2 S6 q
  656.     case CodeEot:5 l% P8 y( u5 Y* ?: z: I
  657.     {4 w, i* U5 n7 |* @* H4 `
  658.       timeCount   = 0;
    ( H7 E, D4 k' v/ w& p+ ~
  659.       errorCount  = 0;
    9 h/ X) F  R1 Z/ ~% |) r8 k
  660.       dataCount   = 0;
    # C9 X' f% J0 I* R) w
  661.       code        = CodeNone;* ?) C- |" j' @' @5 L/ z' P
  662.       stage       = StageFinishing;8 v3 E+ u7 P$ A  p4 C
  663.       txBuffer[0] = CodeNak;1 \) v% T* R  g" i
  664.       txLength    = 1;
    + Q& F; G- k! y! S- K6 k
  665.       write(txBuffer, txLength);. q5 F0 j7 @. B" T; T$ s

  666. ! P5 Y) w6 r( g, }, u
  667.       break;
    5 p# T' D, N6 y8 z6 p1 t
  668.     }
    3 X* }+ q6 \4 s: V- ]5 S

  669. 1 X- c" C. z5 e. r. F& o
  670.     case CodeA1:
    ( X; |& K- d1 w# u5 B
  671.     case CodeA2:
    8 W+ K. I' _$ \
  672.     case CodeCan:2 P* O* e. z2 l# T% I$ T
  673.     {
    - ]$ f) w0 @0 _7 Q& ?/ z
  674.       timeCount  = 0;% M! H! `* W- H2 Y. J3 s& p9 d: _
  675.       errorCount = 0;6 U* W; _5 X) g; O
  676.       dataCount  = 0;
    ! s$ z; u" g3 v! ?/ A
  677.       code       = CodeNone;0 @4 G3 {- y5 {, r: e
  678.       stage      = StageNone;& c7 V0 d; Q5 E9 B, D  o8 a
  679.       callback(StatusAbort, NULL, NULL);- u, J) ]6 m. Z  \
  680. ' T8 j+ J% Y, @. R! o
  681.       break;
    . |. \$ S- r! ]9 [9 }
  682.     }
    . ~2 G, O' P3 [) u) o, J# t% w( T6 {1 G
  683. / J# t' t9 I8 \, _7 ?( r  o2 t
  684.     default:
    4 b* l/ L8 u$ x2 n: K
  685.     {
    3 @8 D) t0 P( m, C) |, d3 I
  686.       timeCount++;# w3 |7 F; @1 o& j- S& u7 c

  687. 1 q" P7 _* Q$ K8 z& g  B
  688.       if((timeCount / (timeDivide + 1)) > timeMax), z6 Z4 d# @1 B0 h) `
  689.       {! d! E7 t' Q6 S
  690.         timeCount  = 0;
    , N8 d6 }# d' E) J3 U+ `+ K+ z
  691.         errorCount = 0;
    8 \" ~  q1 @& a' Z7 B
  692.         dataCount  = 0;
    , N; v2 ~' y5 I
  693.         code       = CodeNone;
    4 L1 [6 F  V: s+ R5 r3 c) j
  694.         stage      = StageNone;- s- k0 \. `; p5 ^2 }

  695. 8 t* T( i9 }+ B4 J3 K: q7 @1 s) E
  696.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)+ N$ A9 s5 H8 B) A1 e4 }
  697.         {# _. O. i7 e) U+ E0 x# e
  698.           txBuffer[txLength] = CodeCan;5 }  E% M; }% r* g, T5 N7 C
  699.         }  j+ o+ `! V5 a
  700. ! M5 F: ^/ ]& h5 Q7 S: F
  701.         write(txBuffer, txLength);
    4 ^4 m; d$ @: G5 o& [8 o
  702.         callback(StatusError, NULL, NULL);$ b4 A, b/ F( Q! k, W) i) a
  703.       }3 |" ?$ k" `; t6 {) v- Z9 I
  704.       else if((timeCount % (timeDivide + 1)) == 0)
    3 ^. y. l7 ]3 e9 L! e1 ]& r
  705.       {% u' ?6 w( s  ]$ T: F; R
  706.         txBuffer[0] = CodeNak;
    1 T5 M/ M6 M% @0 U
  707.         txLength    = 1;3 }" m' g2 F; a; n) S0 H
  708.         write(txBuffer, txLength);+ K  r% N/ c  K# J+ P5 O
  709.       }
    * ^$ D/ v8 H* S. C
  710.     }3 L! u- g5 @; s: a+ o5 l
  711.   }
    4 r8 N$ C9 |' o0 Y5 H& O9 u
  712. }5 Z8 H# T+ p% Q, S# P2 g

  713. & U* J7 N$ E( h2 r+ m0 P
  714. /**
    ' b% W1 I% g! F
  715.   * @brief  Receive transmitting stage.
    3 u6 v; f0 u! Q1 o" G2 R* X  p
  716.   * @param  None.
    - e3 y& r6 k4 {0 q+ [. A
  717.   * @return None.6 X2 `/ M! f) {% p  }
  718.   */2 r! H* [/ j/ i  E' d1 G
  719. void Ymodem::receiveStageTransmitting()6 i* M2 g0 t! w2 Z) y- N. @
  720. {
    ; I, j' l; c% g
  721.   switch(receivePacket())
    3 X* e+ F1 y2 x  r% ~+ P6 V
  722.   {7 \+ b) I7 a5 S9 m
  723.     case CodeSoh:
    0 V1 ^) U' J: M* B# `" c  X( H
  724.     {
    7 X; m2 l: q2 D3 F& p, T9 {+ V+ ?
  725.       uint16_t crc = ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 2]) << 8) |
    $ G8 n& i; x% \2 E3 j, H3 ?
  726.                      ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 1]) << 0);
    - D* ]; y& f$ \# `: C

  727. / L8 u; n! f. A9 [4 J
  728.       if((rxBuffer[1] == (uint8_t)(dataCount)) && (rxBuffer[2] == (uint8_t)(0xFF - dataCount)) &&  `* j# f- \2 U; x  s3 @& L
  729.          (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_SIZE)))
      X% M0 K8 [9 H" _/ {# v
  730.       {
    # n6 b  p) t3 y. r4 s  R
  731.         errorCount++;3 J3 n) b4 ]/ B9 F
  732. + {2 o( k$ k4 `" X% |3 h- N9 I3 d
  733.         if(errorCount > errorMax)9 x, U. a, J+ {' c1 m' v$ t
  734.         {4 P* y# f2 D4 o- S! _* n$ V
  735.           timeCount  = 0;
    6 i8 b+ z1 m) i4 \
  736.           errorCount = 0;
      O% `# }  v& N* R, T; L
  737.           dataCount  = 0;$ ^5 h2 r. g# F+ N, q' |- E
  738.           code       = CodeNone;  g! L, a2 B8 u+ }0 N! \) C' I: a
  739.           stage      = StageNone;
    7 a1 Z4 H2 j( |+ h( I; s) H. o+ J
  740. . y& c- c7 t' U* O& `  o: B
  741.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    4 Y! Y5 L2 C6 [/ M$ ^
  742.           {
    2 ?  x% J# W6 l" A, e( i
  743.             txBuffer[txLength] = CodeCan;. m; f. N# i7 j2 i8 T$ l( m7 |0 m
  744.           }$ F5 U& ~* @4 a$ K, K6 m
  745. # N7 Q8 D" O, h  J- |0 p7 Y
  746.           write(txBuffer, txLength);1 ~& i- ^7 [' d, {9 C
  747.           callback(StatusError, NULL, NULL);$ d# C7 d1 w4 }; D
  748.         }; G( s1 B  T! b' ?
  749.         else; U- P6 {8 [. u
  750.         {
    - q3 o: _' S4 X' ?4 j; m* U
  751.           txBuffer[0] = CodeAck;# ]) f1 S9 W" K/ N
  752.           txLength    = 1;+ m' \! h! y! I7 F. M3 X5 J1 A
  753.           write(txBuffer, txLength);7 h, `- y# |1 U$ h/ v
  754.         }
    + c$ F. m: p, |$ Y0 a
  755.       }
    8 V* h: ~1 \, a& f( H9 O
  756.       else if((rxBuffer[1] == (uint8_t)(dataCount + 1)) && (rxBuffer[2] == (uint8_t)(0xFE - dataCount)) &&
    5 `( S+ I0 B% Z
  757.               (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_SIZE)))
    0 b; o. z$ ?$ d2 }( {/ ~
  758.       {
    : ]% ^# U7 }( A) z: O$ J6 q5 l# ?
  759.         uint32_t dataLength = YMODEM_PACKET_SIZE;
    / j- z0 q4 i, }" z7 b: [2 @; l

  760. ; x( J; p9 F) S  W+ Y& C6 l+ ]
  761.         if(callback(StatusTransmit, &(rxBuffer[YMODEM_PACKET_HEADER]), &dataLength) == CodeAck): c! c4 d. l# l9 a; s
  762.         {
    3 ]( @/ q* z$ j" l9 D  h! b# |
  763.           timeCount   = 0;
    6 ^6 R8 q, r: }! n
  764.           errorCount  = 0;
    / [/ v2 D) H0 {( \9 ^
  765.           dataCount   = dataCount + 1;
    ) a# M, w9 @# ?- V
  766.           code        = CodeNone;
    $ s) |* |* u: H3 r7 y
  767.           stage       = StageTransmitting;- t# w. O- Q/ W( a% O9 T
  768.           txBuffer[0] = CodeAck;* W1 \) j1 e3 _2 l) }- q
  769.           txLength    = 1;
    , O$ T- H( `/ W5 V
  770.           write(txBuffer, txLength);
    1 ?* x1 w( J0 r
  771.         }: p5 W  J( N3 V, t: d
  772.         else3 L. s5 v5 W3 J1 F3 g
  773.         {$ S5 e# u9 m8 b; t7 |, {7 Z8 u
  774.           timeCount  = 0;' l9 |/ ^2 b# m; }1 B0 I1 d
  775.           errorCount = 0;0 D' O% ?% C) M) }% c+ L5 ~8 w
  776.           dataCount  = 0;1 {. G! |) v9 M* I4 Y
  777.           code       = CodeNone;% R1 {7 |7 z1 X9 h& X, G; G
  778.           stage      = StageNone;
    ; E8 u5 V$ T' N  f0 Z( }. m6 F4 ]4 @
  779. , ^6 \( Q' X5 g9 F- _6 x& ]0 c
  780.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    ) f6 c; u! w8 e, \1 J
  781.           {7 q/ D2 ]6 U0 z5 d4 s, V0 H
  782.             txBuffer[txLength] = CodeCan;+ S, f/ _6 i* _: D0 a+ b  n
  783.           }! s8 P& e; b" o% a" T

  784. / }( ?" @& F- Z! }* Z6 @7 I3 D' g
  785.           write(txBuffer, txLength);! Q, I4 `5 _% u. O8 `0 H
  786.         }
    / s2 c6 N  a" ], Y! P  p& w! R
  787.       }# R7 F! N# h9 S+ Q9 ~- Y0 B$ X$ o
  788.       else" ^. j* @+ t' T: _/ ^* d  _" r4 ?7 F
  789.       {4 u8 g+ l" t- F' S
  790.         errorCount++;- V3 s3 t* n4 C6 \
  791. 6 X9 q) {2 v6 x' @- S' e, T
  792.         if(errorCount > errorMax)# K7 P& ?) s, o7 G1 p' d" \3 P
  793.         {
    6 Z6 l8 M8 T0 l. w. [  C* i
  794.           timeCount  = 0;
    0 l! W+ X0 A' s  p9 I) b
  795.           errorCount = 0;
    ' ]: V1 s$ m: g7 x  h
  796.           dataCount  = 0;
    / C. \2 r* F3 L6 z
  797.           code       = CodeNone;
    ' A. ?5 v# B( g2 C5 P! D. X% W
  798.           stage      = StageNone;% ?7 V/ N1 R* o) @# @" A5 c

  799. * J3 M1 s4 Z% \) f' O! t
  800.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)9 C6 |* Q, |3 i- }: o# m$ h- s
  801.           {
    , a3 w3 z6 V) A) [& z0 N2 t/ C
  802.             txBuffer[txLength] = CodeCan;
    $ R8 Y$ N* z. f7 y
  803.           }' Y# C+ f0 B3 y, O
  804. + Z, O0 M! v( B4 j8 w( Q; J; k
  805.           write(txBuffer, txLength);: i$ G: t3 H. Y
  806.           callback(StatusError, NULL, NULL);  b4 X) V& Q3 I* a5 ^
  807.         }
      m8 c( m3 M  V
  808.         else
    ; a0 @: {: @3 [0 ^5 S0 Z4 u
  809.         {3 z5 F! N) `* ~& f# {$ H
  810.           txBuffer[0] = CodeNak;8 d3 v8 `1 W/ }5 a9 u$ n
  811.           txLength    = 1;4 B1 D& T/ P. T- x8 `: B/ j+ t- O
  812.           write(txBuffer, txLength);6 r/ K3 k0 t. S# t7 s$ Y
  813.         }. P) E# c; @+ F. f5 K4 b# b
  814.       }
    . N4 p; V: r5 _5 w- o: {  K

  815. ) u: V! a$ l$ G$ Z3 X# a/ ?: q
  816.       break;
    # Q. o$ D* F( u  k. }2 b
  817.     }- o9 I  w& q, ^. f- N& H( P
  818. " z  e4 g* I, Q6 h. u; W. U5 \
  819.     case CodeStx:
    1 O' |  a' s$ V6 a4 W2 G& Q% K
  820.     {! M$ K* a+ F: ^! N) i4 \# `
  821.       uint16_t crc = ((uint16_t)(rxBuffer[YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - 2]) << 8) |
    " V: L; M% c* x9 X( N- ]
  822.                      ((uint16_t)(rxBuffer[YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - 1]) << 0);
    9 P$ m0 ~8 n1 u. x  O3 |6 K
  823. ' ^5 _4 ~7 I4 T5 u/ e
  824.       if((rxBuffer[1] == (uint8_t)(dataCount)) && (rxBuffer[2] == (uint8_t)(0xFF - dataCount)) &&
    : K$ `- z9 l0 d! m" V" i
  825.          (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_1K_SIZE)))
    + W/ l! r, ~3 I% F& u
  826.       {
    $ E9 [  }/ t4 u$ Q2 e
  827.         errorCount++;: }& }3 I* V5 l* P; i
  828. $ U& e* a' j. }# |6 F1 E) b* F; T
  829.         if(errorCount > errorMax)6 q& z: M/ J4 A- D5 _: a: }1 l
  830.         {: |6 {, L; o% \% |# U
  831.           timeCount  = 0;
    , y+ r4 Q9 L) |' e
  832.           errorCount = 0;; b$ j9 \7 c" R( p
  833.           dataCount  = 0;
    0 A* p% ?" j' `8 E) H! p1 M# a6 z
  834.           code       = CodeNone;
    / a6 R# D2 J' s6 z
  835.           stage      = StageNone;: r0 C/ P) G% l. c% u9 C
  836. ; P/ _) N1 d6 R
  837.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    6 M( Q" C. T0 j& o7 v
  838.           {
    ; t! w) y3 k9 a; `
  839.             txBuffer[txLength] = CodeCan;
    6 y- Y: ^. }" B9 \( w
  840.           }: h3 m5 f2 \, L5 F

  841. + i% d/ R; r8 W* P9 r
  842.           write(txBuffer, txLength);1 `& c% K1 D0 Q
  843.           callback(StatusError, NULL, NULL);# d% p5 ]- j# u6 }0 v
  844.         }" k! N! @' a8 C% c
  845.         else" |6 I' [, v3 r) J2 @- C! f$ o
  846.         {' I# Z9 X# c1 s$ b5 g
  847.           txBuffer[0] = CodeAck;
    6 M( V/ X! l; M9 ]' C% ?
  848.           txLength    = 1;
    4 Z  ?* h" E5 \8 O9 V) a5 e; V- H
  849.           write(txBuffer, txLength);
    7 O' s- Z- P5 Y' V
  850.         }
    & ?! a; \. G% y. d0 t
  851.       }
    / ?2 [6 X5 h  q$ G; U1 ~
  852.       else if((rxBuffer[1] == (uint8_t)(dataCount + 1)) && (rxBuffer[2] == (uint8_t)(0xFE - dataCount)) &&1 A1 l  G/ m( Z1 s/ D+ j' A8 q
  853.               (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_1K_SIZE)))
    $ _& s' P+ E" `9 P
  854.       {
    - D' |" l! J- F
  855.         uint32_t dataLength = YMODEM_PACKET_1K_SIZE;+ x9 b8 D' v. J6 S# j7 L) \# w& i, n

  856. 2 b- B; G6 A" p5 U! Z
  857.         if(callback(StatusTransmit, &(rxBuffer[YMODEM_PACKET_HEADER]), &dataLength) == CodeAck)
    * X0 L5 [$ x  D' g
  858.         {
    " U3 U1 G* V: |
  859.           timeCount   = 0;
    + D# n' A6 A6 v) _
  860.           errorCount  = 0;3 |- e( H, k2 @4 W* e4 I
  861.           dataCount   = dataCount + 1;
    7 B; O7 L* j9 P" I# [* A
  862.           code        = CodeNone;8 O" }  \: E" D3 C3 i/ @5 X
  863.           stage       = StageTransmitting;/ Z8 v9 M' s" S( ~" p
  864.           txBuffer[0] = CodeAck;
    & u, L7 P6 l. n2 G- w
  865.           txLength    = 1;$ M$ c0 P9 ~# v% M' ?0 [1 [
  866.           write(txBuffer, txLength);
    ' K/ v: n% E, l9 Y
  867.         }
    + O  [! r& K# [: ]/ j
  868.         else% M* ^/ K+ O- n3 {+ e2 Y
  869.         {: b" e9 I1 d, q1 n+ t
  870.           timeCount  = 0;0 Y! o* O7 h& {7 S# w
  871.           errorCount = 0;
    ! i! L, C' j; r
  872.           dataCount  = 0;' ~1 o) X) w: o4 i+ D* f% L, _/ A
  873.           code       = CodeNone;5 M3 U, Y& n( R# d
  874.           stage      = StageNone;3 c. y' \" O3 L
  875. ; q0 i1 N: u! B4 p( m
  876.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)1 R+ H0 e/ j1 D
  877.           {
    & `$ X' C; U9 `( @1 z4 l
  878.             txBuffer[txLength] = CodeCan;; ?7 L) H  r" k, Y; Y
  879.           }' |9 w6 O" }' a/ L( _" q

  880. 0 Z0 j' u4 Q* n" o8 _. y
  881.           write(txBuffer, txLength);
    , J/ a7 G2 u1 |: ]. m+ x( O* p, f
  882.         }
    # F* G. U& I) c% g0 D6 ^
  883.       }
      w+ @$ _$ j4 F( z$ _
  884.       else0 ?1 b1 }" t8 U& @* z
  885.       {
    $ i6 R; b2 [0 S, \2 p3 Y8 Q4 |) s0 v' e
  886.         errorCount++;
    9 V2 f4 \( g" `

  887. + B2 Y" E3 G6 u  Y/ Y# y6 n( i5 h
  888.         if(errorCount > errorMax)
    , U4 Z9 J2 h  s
  889.         {  |: M% V! T& ^! x" W
  890.           timeCount  = 0;; t5 F/ Y0 M2 n4 u8 }) D
  891.           errorCount = 0;
    " J: Y1 `" X% U
  892.           dataCount  = 0;. @# n7 ?) E" F7 O7 t+ A
  893.           code       = CodeNone;
    & L1 I' G0 J6 j& C
  894.           stage      = StageNone;
    # a" G; Q0 r; {6 p. u/ O

  895. . ]0 E$ o/ z) D1 R6 G3 l
  896.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    ; a& l& b: x  Y5 X6 I+ l( T6 Z4 C
  897.           {
    ) W( y  U) ^8 U" {/ ?. q
  898.             txBuffer[txLength] = CodeCan;
    8 G1 x0 l; y0 E" A
  899.           }
    ; r9 M9 Y8 m9 Q* _7 [. X2 n4 @
  900. # C/ u- d2 c1 A4 K( o
  901.           write(txBuffer, txLength);
    2 J$ U6 Q0 z) ~# j7 s- C! r
  902.           callback(StatusError, NULL, NULL);) @! [/ N) h& A
  903.         }0 m# m3 t2 z  e+ |9 Q- r3 T
  904.         else* U1 i7 ~/ {! y" V" t5 T+ z
  905.         {
    % j# }3 x0 ~$ w
  906.           txBuffer[0] = CodeNak;
    0 j5 O8 H( |% Y& K6 x
  907.           txLength    = 1;1 w; e0 \+ b) h* S6 I) g5 a
  908.           write(txBuffer, txLength);% n! i. s+ B: a4 i
  909.         }5 q- y% `+ u. x5 h
  910.       }
      `  {, y+ k1 B8 a8 c) d* V! q
  911. % O5 i9 X# `5 y/ H5 S
  912.       break;
    6 O" N+ f8 f8 m0 {. K2 L  r% T( r
  913.     }9 T4 |) F( q1 s2 K9 a

  914. 6 y* p& ~" A6 r  Q
  915.     case CodeEot:; R2 d6 B: n- s, l/ C
  916.     {
    , E1 g. e  |) u% c
  917.       timeCount   = 0;# t1 k2 E+ Y. j1 [9 g6 {
  918.       errorCount  = 0;' C$ I' q8 R# J2 @0 t4 l7 e
  919.       dataCount   = 0;
    . p5 w( T) H4 V5 v2 S; o: H1 F
  920.       code        = CodeNone;
    * Z, W$ X1 |% C* ^7 e& S6 M8 Y( O
  921.       stage       = StageFinishing;
    4 D; ]" r; |  |4 N* `
  922.       txBuffer[0] = CodeNak;- v4 I- x4 a* K" O0 J0 [. e
  923.       txLength    = 1;
    2 m' b3 d1 p) S& A. w
  924.       write(txBuffer, txLength);
    3 s. f' J0 E  c2 U4 |- _) i  \4 o

  925. 5 h8 w& v: P: h" Y, v1 O7 |
  926.       break;3 @; N$ c8 o# n& o1 I# E
  927.     }
    * Q; C. @; i, S) I' Y4 I4 m

  928. ' t! [0 h8 A- ]7 ]
  929.     case CodeA1:
    + }- `4 X/ `' |6 C7 ]/ c) {# D
  930.     case CodeA2:+ e7 G% a0 s4 j: P! ?& i9 H2 V& y
  931.     case CodeCan:% P8 A9 r( A) t* u2 v# d
  932.     {
    % A; \5 \+ s$ v  o4 w" V/ H
  933.       timeCount  = 0;: p: R" u  f3 R
  934.       errorCount = 0;
    4 S$ }; }% q) z5 l6 Q  D
  935.       dataCount  = 0;# Z, e( V. L- Q9 u' ~8 H
  936.       code       = CodeNone;
    ; s- b6 o; g. e- I3 w/ k9 n
  937.       stage      = StageNone;
    / z  V( _+ ~) F  w/ D" y: i1 u
  938.       callback(StatusAbort, NULL, NULL);# i4 \  G; v% D: ]4 j

  939. 3 M$ l7 ~) H2 y$ W
  940.       break;
    ( J. K4 N5 y; ]6 _% T  M
  941.     }( H, C. F; {0 A" x! b7 P+ ^

  942. 1 e, a/ {  I* ^5 s8 w
  943.     default:
    6 V. U* p. H8 I. H
  944.     {9 z" Y$ c& F( s9 Z& ?' [! b$ r5 T
  945.       timeCount++;/ ]4 S6 K! s' ?; U
  946. - O$ r* }; i, s, A
  947.       if((timeCount / (timeDivide + 1)) > timeMax)
    % c! k1 ?3 I) K( {6 [. m
  948.       {
    3 `& G# [! V8 k3 _, ]
  949.         timeCount  = 0;" N) w4 S  o& ~- W/ h! E
  950.         errorCount = 0;* |! |& x* g1 h0 p+ a( p! E
  951.         dataCount  = 0;
    2 R' ~" ?5 u. F& g! t. ~
  952.         code       = CodeNone;
    * Z, D% d% N' m! f/ q3 [
  953.         stage      = StageNone;7 l; c  \# X, Q) v  T- U
  954. 2 Y0 }3 U) I7 u6 `
  955.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    & p9 d' G& {3 L* a- G: C+ J
  956.         {% M0 W6 I, n  h8 \8 j
  957.           txBuffer[txLength] = CodeCan;7 O* F% v' ~9 ]9 _
  958.         }
    & i8 L/ ~. Q0 x! r6 P" K

  959. 8 g7 i. A, ~: Q5 D  G
  960.         write(txBuffer, txLength);
    / P0 |6 N" q9 X7 M& D' Z
  961.         callback(StatusError, NULL, NULL);
    + @/ z" Z- W5 n7 _
  962.       }- ~. T- n( F3 k3 A  J3 p6 t* W
  963.       else if((timeCount % (timeDivide + 1)) == 0)$ o# M1 d' y- J; @
  964.       {  d: Q9 P( f; b' L5 A, o2 u
  965.         txBuffer[0] = CodeNak;4 u. k. e( S( Y- m
  966.         txLength    = 1;" A" y" O2 s2 V" m6 J
  967.         write(txBuffer, txLength);
    9 M- |- o: n$ L9 X) _/ m' T# _( b
  968.       }( g2 N' r0 Q* u6 V
  969.     }4 C2 g/ A9 Z$ I) w! {: c
  970.   }
    ' b: s% j. H  Y  C: L, e) D! s
  971. }8 A2 ~0 H9 n; p# J- u$ G

  972. 1 @3 b4 z$ b9 Q: y7 w! \7 F
  973. /**
    * j- N4 X) |+ G$ f
  974.   * @brief  Receive finishing stage.
    9 W5 J* M5 e$ u( [9 ~& g8 b
  975.   * @param  None.
    4 p9 A- A+ X0 a9 g7 Q
  976.   * @return None.
    1 t0 p1 U* _1 U9 ^7 W
  977.   */. l) I& Y$ e: C; k9 G
  978. void Ymodem::receiveStageFinishing()
    + l* a! ~5 H# d! t/ P, B
  979. {
    , F: S7 _) H9 b2 y& \+ W
  980.   switch(receivePacket())7 ?8 Q4 S" Z1 c: d) B
  981.   {
    : E6 t( B1 m' a; M& V: ]* G
  982.     case CodeEot:- ^$ Q6 t/ [& }6 ~, H
  983.     {; L, E. k4 j$ }4 J) N7 Q  {
  984.       timeCount   = 0;) V/ @3 S$ [3 T: U3 E7 U
  985.       errorCount  = 0;! {4 x3 _- P, b& I
  986.       dataCount   = 0;
    $ y$ Z) z6 V9 i+ [
  987.       code        = CodeNone;: }9 @: Z  m# l9 A7 i
  988.       stage       = StageFinished;/ Q, c8 {4 I. s
  989.       txBuffer[0] = CodeAck;; M# T6 r  ]+ S8 k5 R
  990.       txBuffer[1] = CodeC;. Y8 N8 y5 Q2 Z, [: H% z( `
  991.       txLength    = 2;" W' X8 {* i& C
  992.       write(txBuffer, txLength);
    ) O5 l! G6 B: t( ?
  993. ( l) N# \, ?, ?, V! i) Q0 r1 D# A0 @
  994.       break;# v, ?: W5 W; @2 G6 F- Q, D
  995.     }5 q% }1 s; U- D3 h- j. ~3 S
  996. 5 g2 z& ?) ?; C" H- {; }( q9 h
  997.     case CodeA1:0 N! D( v* I! a4 x4 K2 i' G/ o
  998.     case CodeA2:
    6 p  l  J3 j/ ~) S  y* B4 l3 E: |5 d
  999.     case CodeCan:8 z* t, `( e; E! z
  1000.     {
    % b' w! J) t. f2 b& O
  1001.       timeCount  = 0;
    5 L$ k  j1 g! `- ?
  1002.       errorCount = 0;% H  c. U7 }3 W( H& X6 J
  1003.       dataCount  = 0;. }6 \  P9 o) H7 y
  1004.       code       = CodeNone;6 v" }  F2 X# x0 K! ?$ m' J1 j
  1005.       stage      = StageNone;
    & d1 b! }$ R: g  n- ]* k
  1006.       callback(StatusAbort, NULL, NULL);
    : Z9 K' S0 m* R/ L
  1007. ! a+ X2 v6 X. ?( Q# g3 z
  1008.       break;- M* ~$ r: i3 ]. e
  1009.     }
    1 |# J/ b7 t$ s% y/ ~( v3 o
  1010. 0 a" V7 z2 f9 f/ J, S$ k  _  {
  1011.     default:1 a% A. k1 @9 v5 r& l2 I" P2 Z# M
  1012.     {
    - y2 \* g. @( ]
  1013.       timeCount++;; E  R# }) X& D- {! M5 m. Q
  1014. 1 o* T$ v  g( |6 C
  1015.       if((timeCount / (timeDivide + 1)) > timeMax)
    / \  r/ y' V1 @% F
  1016.       {
    ) z; l: i) \( b
  1017.         timeCount  = 0;
    $ M: D# J6 Q: h
  1018.         errorCount = 0;  o" ~- |% V. s. O4 g0 @3 w
  1019.         dataCount  = 0;
    ) }+ y, i6 J0 b- I- s
  1020.         code       = CodeNone;
    2 ~1 d3 y0 N% ^5 f, u- E
  1021.         stage      = StageNone;
    6 ~8 Z- j* g8 l+ a

  1022. 6 b) w; T8 L% K) l" B" J
  1023.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    5 e5 ~  z9 }! P# ~
  1024.         {
    . ?/ ^9 N( N, _8 m# H" Z
  1025.           txBuffer[txLength] = CodeCan;* i2 C/ v$ w" E
  1026.         }
    , r5 J1 f8 A! D' t6 V
  1027. 3 q1 J1 ], L- `: ?1 Y
  1028.         write(txBuffer, txLength);* B$ i* n. j3 F* O* K
  1029.         callback(StatusError, NULL, NULL);
    # l2 w) o' ?4 I6 Q1 M6 N9 |' K- [
  1030.       }
    , h3 k$ Q6 [8 W3 D) k
  1031.       else if((timeCount % (timeDivide + 1)) == 0)2 H; L3 [! K% h! D. c
  1032.       {
    2 X2 u0 {6 Y' }9 y4 Z2 m
  1033.         txBuffer[0] = CodeNak;
    # f4 G5 f* k' Y8 i: {" u. P
  1034.         txLength    = 1;, x5 Q! K  g( ^# Z/ E0 @3 H
  1035.         write(txBuffer, txLength);9 t. z# R& `4 p' G5 n6 g4 g: W
  1036.       }; C+ @: I; q  w8 s) W) d" K. P
  1037.     }/ F- x, v. d4 o% Q+ {7 ?  b! O
  1038.   }
    9 F9 f* N% c4 I: ^
  1039. }
    , i: u7 G$ d- Y: U$ r
  1040. : v- t! b* }: o/ M! N' }
  1041. /**
    ( h$ n/ ]9 A; o9 r) G# C
  1042.   * @brief  Receive finished stage." s6 |8 A9 I/ ~
  1043.   * @param  None.
    / P$ o) a& z: o
  1044.   * @return None.
    # s+ D) W1 d0 a! u! j" \1 z
  1045.   */
    8 D' }+ J" F' @1 R1 {
  1046. void Ymodem::receiveStageFinished()
    5 c$ r& R' f% P' w# B1 P* r
  1047. {
    % f" w$ k$ Y% m# E' H" ]
  1048.   switch(receivePacket()): B& s" N0 w. ~
  1049.   {
    & \- v  X% G" |5 T+ r
  1050.     case CodeSoh:
    % l1 n# m, ?, a, V, G; q2 o
  1051.     {
    : M3 Q. V8 F- x9 c, K
  1052.       uint16_t crc = ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 2]) << 8) |3 O* T2 K* H. H/ k2 D/ t% B
  1053.                      ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 1]) << 0);( I" }9 O. g! R) u8 [2 R" m
  1054. : J; `" T8 c  ~9 e  n. D
  1055.       if((rxBuffer[1] == 0x00) && (rxBuffer[2] == 0xFF) &&
    ' V1 J  `1 ?* t2 _
  1056.          (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_SIZE))), R6 ^: J7 ]+ t% @' K4 t4 r( _! I
  1057.       {) V" V+ @0 @  b' c; B7 z
  1058.         timeCount   = 0;0 G4 ~* ?' `/ E1 m8 q
  1059.         errorCount  = 0;9 X9 I- I% m$ S2 d, {
  1060.         dataCount   = 0;
    : I2 z7 s. l+ K7 K' }
  1061.         code        = CodeNone;6 V- q  f& l3 `! b4 z+ M5 ^
  1062.         stage       = StageNone;
    - p1 `& G# {' s" ~
  1063.         txBuffer[0] = CodeAck;
    ; q' T0 b: h5 X8 S
  1064.         txLength    = 1;
    ) x: x' k0 K3 s# i/ s
  1065.         write(txBuffer, txLength);. {4 @: }% g9 e6 A
  1066.         callback(StatusFinish, NULL, NULL);
    / x; E! y2 z& @9 e( E
  1067.       }
    2 X# Z" B# E& Y
  1068.       else
    ( \  A8 J; H6 W1 q( g/ b$ H
  1069.       {
    . p) r- d: `8 W- d
  1070.         errorCount++;
    ( F! {  U' k+ f+ O) ~' O5 A+ O

  1071. 2 e8 e- |; u! T2 x% k$ z: b
  1072.         if(errorCount > errorMax)
    + S' @, {  Z8 p7 Y/ H+ q3 C( U0 d
  1073.         {; V, R7 y  P& ?% Z
  1074.           timeCount  = 0;
    * o' q( ]5 b$ @) v
  1075.           errorCount = 0;
    - |+ _0 O1 c& t% D: a5 J  k$ q
  1076.           dataCount  = 0;
    & H+ }& B5 E4 n1 k# C
  1077.           code       = CodeNone;
    6 N2 V- r5 {! Z* N. `: u9 |% p
  1078.           stage      = StageNone;
    ) X* h4 h6 t- p

  1079. # _9 J2 i/ z5 o# G1 `* n8 `* v
  1080.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    ( n# _( r: m0 ~) t# M4 c
  1081.           {' }  v- p8 j9 M9 Z7 b1 F! d
  1082.             txBuffer[txLength] = CodeCan;9 G8 a1 S0 y8 {9 k$ \, B! ^0 C* Q
  1083.           }5 g- E5 e& u1 u$ U- R0 G. q

  1084. / o! ~/ s! P/ r2 q' I+ ~: E- d
  1085.           write(txBuffer, txLength);6 D: u2 D' ?$ f: b; g8 b& p
  1086.           callback(StatusError, NULL, NULL);
    1 ?0 \0 K6 W$ S* K
  1087.         }
    6 {4 ^7 U) g9 ]: ^
  1088.         else2 Q6 ^3 B, e/ ]4 o* n
  1089.         {& w) u$ _. z0 g+ J
  1090.           txBuffer[0] = CodeNak;, y' q* Y" S' l! i
  1091.           txLength    = 1;
    5 ~* a3 m3 E7 w; C  x4 l) _
  1092.           write(txBuffer, txLength);: G* d7 I1 O" ^4 C5 N+ ~. O2 j3 S
  1093.         }
    / r7 ~+ _, Y( G& f0 p
  1094.       }
    9 O, l3 R% ?0 y* ~

  1095. $ r6 u* t( H/ B+ v- {3 f9 x+ D
  1096.       break;5 Y4 z! l- _+ b' @8 ^% _
  1097.     }1 @$ n" _. U) e& X, o; C

  1098. # S% H* x& y0 d4 x! Y, u4 `7 c7 s
  1099.     case CodeEot:
    - R7 z) C: z" l5 M1 O
  1100.     {
    1 I6 m: w9 h) z9 d, H- J9 o/ T
  1101.       errorCount++;
    & W3 U7 {! K" ^5 d

  1102. 6 j; y" A- p4 ^9 _1 A$ V/ s% m  g6 E' y
  1103.       if(errorCount > errorMax)' W! i$ Q1 p; z
  1104.       {6 J) w  U; U: `, D- s5 E/ K
  1105.         timeCount  = 0;- v" K$ T5 K( O4 n/ P
  1106.         errorCount = 0;* i3 k$ n! {  p% p; n$ ~
  1107.         dataCount  = 0;
    & [8 z+ M  ]+ Y% h+ o2 ?
  1108.         code       = CodeNone;
    / _( Z6 b0 g  C& ~
  1109.         stage      = StageNone;7 \- M" u8 f0 l- s

  1110. & Q0 t9 y' e* @* h4 {' R2 O
  1111.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    ! g; u# q( k  _8 K: _% d, h
  1112.         {
    % s& y! X6 A1 x+ l
  1113.           txBuffer[txLength] = CodeCan;
    2 W# k- z  ]: C* k- P+ z8 U
  1114.         }* Q. X. s& c& j: R3 @6 }# ^* X

  1115. $ r( {$ E) |' D% \1 V3 c' P
  1116.         write(txBuffer, txLength);' D5 c# ~5 e0 J% C
  1117.         callback(StatusError, NULL, NULL);
    " z* U* p8 L* @$ O; w9 K; Z/ U
  1118.       }
    + y( G8 X. U' a/ H  p
  1119.       else( e; T. G5 c% s: ?) o/ f. t
  1120.       {6 |5 ?4 }! c: d
  1121.         txBuffer[0] = CodeAck;
    0 F! m! `/ u/ B9 b% c
  1122.         txBuffer[1] = CodeC;
    : ~/ B! w5 a6 C+ C/ r$ I
  1123.         txLength    = 2;' K- `' g2 q9 p4 i4 m
  1124.         write(txBuffer, txLength);, V+ N" S1 i1 h& L- Z
  1125.       }
    ! m, E+ X8 G3 G3 b8 O+ g
  1126.   M& o& T  d' i  t. F% C
  1127.       break;& F8 F( u* H, }1 H/ L
  1128.     }
    7 H6 \' W. p. f: N; k3 x+ N" R

  1129. ' v4 |1 Z, c* S
  1130.     case CodeA1:
    0 U$ ^, E- b" S: S+ R' s
  1131.     case CodeA2:
    " D- U/ A- @) K, a  G
  1132.     case CodeCan:$ m/ i& Q/ Y) U) O# v. Y% c. R$ q
  1133.     {
    2 r) B/ }9 c5 j5 M; _: V
  1134.       timeCount  = 0;
    7 J0 }0 a$ q8 L0 W0 s+ f: J
  1135.       errorCount = 0;; x6 z) I6 Q4 j, E  `
  1136.       dataCount  = 0;
    ! I6 S; w( L; j( G. Y
  1137.       code       = CodeNone;
    * _8 s& a! ^" I- X* d
  1138.       stage      = StageNone;! ]* D- V+ k4 s/ ?, H
  1139.       callback(StatusAbort, NULL, NULL);# D: e3 F& g$ X- n4 |+ h' B+ d% L8 V3 J

  1140. 7 G) c1 O% q) `7 ]6 R6 T8 T( Q0 U
  1141.       break;
    , ~" F' I8 A: u
  1142.     }
    ' @0 |& I/ ^# `4 b) z
  1143. . G- N" Y4 B& [& G) n3 u: x
  1144.     default:' r5 i5 a. x, M
  1145.     {1 \8 ?( i& x. t
  1146.       timeCount++;* x. \+ R: `8 ?1 b8 B* f: _3 s
  1147. ( E: t& W5 k. D5 e. T% s% o
  1148.       if((timeCount / (timeDivide + 1)) > timeMax)
    + X/ [) J% u5 y" j8 ]
  1149.       {
      v, b2 J. L+ M8 j
  1150.         timeCount  = 0;' X0 @3 {  }/ v/ z
  1151.         errorCount = 0;8 n( s& _; i. |4 ~* }5 {; b
  1152.         dataCount  = 0;
    $ F3 e7 h4 h! v. J
  1153.         code       = CodeNone;
    ! ]6 d8 \, n7 R+ E" B- c
  1154.         stage      = StageNone;8 `3 {/ ^% O$ d0 a' d& C8 p8 i) w

  1155. : U* F) T9 q& w% G
  1156.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    3 \2 g9 w9 d; p0 w' I
  1157.         {
    . J) N7 L+ ~/ c0 q. O) z, P
  1158.           txBuffer[txLength] = CodeCan;) P4 S7 b" g& T
  1159.         }7 t7 y' W3 C% _

  1160. 2 k& H0 o  U% @3 R; Q" f
  1161.         write(txBuffer, txLength);. b& F) o+ q% w8 }1 F% i) v7 v) r/ ~
  1162.         callback(StatusError, NULL, NULL);2 h0 V* M8 A0 w1 X2 W+ p
  1163.       }' ^" |; M! u. G( d6 ]
  1164.       else if((timeCount % (timeDivide + 1)) == 0)' E9 {; v5 z5 j$ [
  1165.       {
    9 v9 F: o1 ?( t( o( E5 }0 q. @
  1166.         txBuffer[0] = CodeNak;
      x' E  ?, D6 C2 n! Y" L
  1167.         txLength    = 1;
    4 k) j, H( h1 c/ J, }2 n
  1168.         write(txBuffer, txLength);
    , T( I& V1 h; p' z
  1169.       }
    9 @; A2 U, @; F1 |2 X4 `; {: H
  1170.     }- g  H. S! D4 `8 i$ u
  1171.   }
    - X7 t) r' J& Z) ?% P
  1172. }/ M7 O* P. Q5 O2 ]/ W) E; V

  1173. $ Z9 I, \; @& K1 Q" a3 q) G5 K5 t
  1174. /**
    $ }6 f% S2 @* w8 h7 [; ]
  1175.   * @brief  Transmit none stage.
    $ U8 q' ~" ^$ U3 W  d2 O3 }% N
  1176.   * @param  None.1 [  p" T4 O5 U6 v
  1177.   * @return None.. C' \  L3 F' b7 t
  1178.   */. I1 m9 J/ K" ^4 i! `, x$ b
  1179. void Ymodem::transmitStageNone()
    - R6 u& J$ l7 d8 D3 ^4 Y& v
  1180. {# [2 T' N& }- n4 J
  1181.   timeCount   = 0;
    : A/ N6 O. }$ E
  1182.   errorCount  = 0;
    : ~+ u: t3 M. Q9 r7 I2 }
  1183.   dataCount   = 0;
    9 W( O  F4 m0 g! y6 K$ D. m0 V
  1184.   code        = CodeNone;% }6 Q. R5 {4 J' a4 v8 G0 o4 H
  1185.   stage       = StageEstablishing;) G  P8 o( d' h. m( w  i: J, s
  1186. }
    * G! U$ B% l) B( H: f# {  W3 v
  1187. , F# G+ `, A; M7 a( }
  1188. /**
    + a7 l1 b9 h$ l/ L  _/ C
  1189.   * @brief  Transmit establishing stage.
    4 ]  q; j' Y  Q  i2 r* j3 m8 M
  1190.   * @param  None.2 o- e9 w/ ^* d" @
  1191.   * @return None.. _" p! O. f, S, X' x7 y
  1192.   */
    " Q* c% a5 I, K) ~
  1193. void Ymodem::transmitStageEstablishing()5 ^" k8 s6 j( g% V: I$ C3 y. Q  U
  1194. {
    7 U9 d2 j8 N% C0 Q7 ~
  1195.   switch(receivePacket())- `$ N& q9 ]/ h& Z% W
  1196.   {) {& a; v( q5 C3 t8 t) W( n
  1197.     case CodeC:
    7 p. K* u0 z& w3 Y8 w( a/ X5 i
  1198.     {" R' j9 }4 O, A, w
  1199.       memset(&(txBuffer[YMODEM_PACKET_HEADER]), NULL, YMODEM_PACKET_SIZE);% {: ^& I+ @8 ]; Q. N
  1200. / K/ r4 n' \: _8 L! r
  1201.       if(callback(StatusEstablish, &(txBuffer[YMODEM_PACKET_HEADER]), &(txLength)) == CodeAck)
    & u- G# z+ f: R  v0 Q4 }
  1202.       {: Z+ B$ N% K( w' \+ r0 v& U) A
  1203.         uint16_t crc = crc16(&(txBuffer[YMODEM_PACKET_HEADER]), txLength);
    1 V+ T. P7 e4 S  L, e) W

  1204. ' u9 S. s/ q- R3 e
  1205.         timeCount                                       = 0;* g' U; y2 U' T% j. l
  1206.         errorCount                                      = 0;
    % c$ `' [  |! z# @" ~* P/ ^! W
  1207.         dataCount                                       = 0;5 m" ?% w4 b# p4 Z) z0 e
  1208.         code                                            = CodeNone;! s% ^7 v, {4 H* |9 |9 c
  1209.         stage                                           = StageEstablished;
    9 ]* q6 k% n% n( Q3 a0 }$ H  O
  1210.         txBuffer[0]                                     = CodeSoh;' Z  c4 d+ o7 z0 s' @0 S6 w' J2 ]
  1211.         txBuffer[1]                                     = 0x00;
    & l! P% f& q) m+ S/ @
  1212.         txBuffer[2]                                     = 0xFF;
    1 a  a& K4 f# B) ?- c5 @0 z! P
  1213.         txBuffer[txLength + YMODEM_PACKET_OVERHEAD - 2] = (uint8_t)(crc >> 8);! [3 o7 d  P. T: L- t
  1214.         txBuffer[txLength + YMODEM_PACKET_OVERHEAD - 1] = (uint8_t)(crc >> 0);9 P) R9 u' o$ S6 A/ ]( _, E8 l" Q/ i8 c2 q
  1215.         txLength                                        = txLength + YMODEM_PACKET_OVERHEAD;* E. N& E' f6 T" \1 Y
  1216.         write(txBuffer, txLength);
    , e/ C6 ^. m9 D8 ~5 \4 m
  1217.       }! z4 U2 w; ~. E$ X* [/ v
  1218.       else9 Y; K- U" e# O* Q# D6 L# R
  1219.       {
    ; M5 k0 ]4 p( A/ j0 I6 ^9 T
  1220.         timeCount  = 0;
    ( e5 h( K( b$ \; F5 t
  1221.         errorCount = 0;" Y7 e4 N0 t) G3 J
  1222.         dataCount  = 0;3 N- L6 F" d) `# @5 P, P% L5 l
  1223.         code       = CodeNone;
    : _4 A) x, z4 f! [) N8 X2 ?
  1224.         stage      = StageNone;0 b+ l3 e0 H3 [; |* t  X; ~! l
  1225. - y. H. M9 x% k* ~, P
  1226.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)4 L" Y# ^' j. Z/ _
  1227.         {9 q" z3 i5 u/ L$ {' |+ n4 ]5 w
  1228.           txBuffer[txLength] = CodeCan;
    0 D' B0 d. o: D* [5 R7 F
  1229.         }
    , c7 \$ c: K% e; p7 [
  1230. & n/ ]/ w+ H8 o5 V! _  B2 K& L
  1231.         write(txBuffer, txLength);- Y+ _1 Y  t* o( S
  1232.       }# s5 i5 Y( C: F8 G+ y4 n
  1233. * B8 l5 ?" G+ T& `. V5 f
  1234.       break;
    4 v, K7 U, S1 l! w" A
  1235.     }* T" X0 U, N  T  L3 ]9 S( X

  1236. . e4 [3 [# C( ~) ~6 g+ l& X
  1237.     case CodeA1:
    * t% |9 U+ {. P; k( o
  1238.     case CodeA2:
    8 o, D3 n$ g2 @8 W% T/ O
  1239.     case CodeCan:0 q1 ]. h5 u* \, e. D& w& I
  1240.     {' U1 L7 g+ ]$ }$ ?& R3 E
  1241.       timeCount  = 0;* J/ B5 [" F7 E' |6 O  n, F
  1242.       errorCount = 0;! O0 k3 }  q: `  W9 c
  1243.       dataCount  = 0;
    ; e0 {" N8 ]2 s+ S; ?& d
  1244.       code       = CodeNone;& |1 }" Z" q, W! v0 v+ R0 O
  1245.       stage      = StageNone;& w" D* [$ Z: p
  1246.       callback(StatusAbort, NULL, NULL);* G  F7 |' ?; `! n- j) g

  1247. 3 b2 _. i! o1 f0 b& K+ J
  1248.       break;
    7 }" d3 u- N) N. G5 J
  1249.     }3 f+ }1 u: W" \7 _8 n# u

  1250. 9 H8 r5 V8 K  }7 x" b5 `. e
  1251.     default:$ J+ m* c' Q/ I2 t0 Q) Z; N1 _2 e
  1252.     {# {3 G  ~. z+ d" i4 @5 B4 u
  1253.       timeCount++;9 Y& \% ^. B# j

  1254. 0 N* ]; \! X, W2 y1 m! z
  1255.       if((timeCount / (timeDivide + 1)) > timeMax)
    " A! D4 a% s% ?* l) ^
  1256.       {9 T3 d& u+ R4 D# ]0 q4 s: o6 W
  1257.         timeCount  = 0;
    # L: k5 ?2 a4 }
  1258.         errorCount = 0;! \% @$ k! y5 X& x1 K
  1259.         dataCount  = 0;$ L, [7 a5 Q9 c$ |
  1260.         code       = CodeNone;
    8 k6 z1 u' V$ ^: X4 J/ ^/ X8 U( c
  1261.         stage      = StageNone;; r3 C; u  H# W
  1262. 2 |7 J7 S5 s2 z% N7 v
  1263.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)1 ?8 K% G: w! [- o
  1264.         {! e9 L/ j* p* u& f) M  ?# {
  1265.           txBuffer[txLength] = CodeCan;; ^. t& v7 d. ~7 T5 }- v( h
  1266.         }
    7 P5 ^. u% h5 q* q5 u
  1267. : O6 @3 Y/ N' ^3 `3 q& Q, S# m
  1268.         write(txBuffer, txLength);
    7 n4 d3 U4 b$ u) l8 u/ }+ j  n# g
  1269.         callback(StatusTimeout, NULL, NULL);8 {0 y/ Q' P8 h+ |# y
  1270.       }
    6 l, s# J* [& X3 s  q( z  y% L
  1271.     }
    2 J+ r. R1 J9 ?' x' Q
  1272.   }
    # H* w$ C! C% I' m2 M
  1273. }
    % R% m6 M' K1 F. v9 J+ N, w* U2 g
  1274. : m: {2 V1 C/ \  G8 j
  1275. /**
    + K& ^0 {4 y$ r; Y1 L0 `; ~7 x
  1276.   * @brief  Transmit established stage.
    4 n- f7 K% w! @0 O0 h
  1277.   * @param  None.* @- D% R) V# v3 [# v, S
  1278.   * @return None.7 j  i: Y% {/ i
  1279.   */
    ' }: H+ u& Q8 Y, r
  1280. void Ymodem::transmitStageEstablished()
    ; ~; [$ h* ?& Y! E
  1281. {
    . R- ^6 n: h+ b- Z4 @6 q, @: d; ?
  1282.   switch(receivePacket())
    0 r- e0 K- {+ d3 ]( _
  1283.   {
    # `' h0 O4 t! Z  N
  1284.     case CodeNak:
    % I  w. D- |% C1 ]
  1285.     {
    8 \# |8 J2 Z" W0 k9 o! ?/ x2 E
  1286.       errorCount++;+ k; ?+ j4 v& g- G
  1287. $ L2 f5 z; F: c5 b5 b- Y/ D1 e
  1288.       if(errorCount > errorMax). b( w$ D" \0 E% {0 y
  1289.       {' ]( h, Q# n& v9 Z
  1290.         timeCount  = 0;
    # Q5 T3 x1 _5 o
  1291.         errorCount = 0;
    1 s! j1 F0 e. V
  1292.         dataCount  = 0;
    / \! j! t" F" p9 [3 X
  1293.         code       = CodeNone;5 S9 @* D+ h" T9 Z) p$ }
  1294.         stage      = StageNone;
    / e2 r) r/ g$ E% L  }. c: r7 R
  1295. $ f  Q2 t, X2 E3 J+ x+ Z8 T; H/ t6 z9 y
  1296.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    5 B/ `8 }5 Y0 R5 O) ]
  1297.         {0 }9 O% N9 w% ]. X7 t9 V; e  [
  1298.           txBuffer[txLength] = CodeCan;
    2 Q5 a1 C) J0 o1 X# `# |1 E
  1299.         }
    " I! V& U& f5 O) X( _# S# a7 k

  1300. # P1 k1 o/ z" i+ T4 t% _& o" V
  1301.         write(txBuffer, txLength);
    $ o+ x  K  }; G$ M! k# M) l
  1302.         callback(StatusError, NULL, NULL);+ J3 V1 ?8 `$ D. P) Q9 u
  1303.       }
    5 G% ^" O+ ~- X( u; q8 K
  1304.       else
    9 K% @2 F, }$ [  W3 C8 Q. z% M- H( b) w
  1305.       {
    & g3 ?, F0 Z. F. \  d( I$ n6 \
  1306.         write(txBuffer, txLength);
    - n* y" c% X: M, F5 z% A
  1307.       }
    9 [$ K; ]9 F8 w/ V

  1308. * K7 b+ t  V4 @& C% z' [+ H
  1309.       break;
    0 c; z$ D6 Q( M' U; ^  h
  1310.     }
    , R/ @4 v. R6 x7 \% T+ \
  1311. - B$ |/ b  }* }+ z0 a
  1312.     case CodeC:
    " j8 c4 `0 D, \% K+ |- p( A
  1313.     {! R2 ]. z' K* L" U/ F" C$ `
  1314.       errorCount++;
    $ A8 X; c3 [( i! s, a

  1315. " Y6 Y1 Z' u9 l5 G2 m
  1316.       if(errorCount > errorMax)8 {8 E9 e8 {6 y. y4 ^
  1317.       {
    , z  E' x- V9 U
  1318.         timeCount  = 0;& q8 e6 K4 n0 ~1 G2 l# d
  1319.         errorCount = 0;
      L: W% K; u( Y( b& G6 F3 R
  1320.         dataCount  = 0;) F; B6 f" [9 X$ X
  1321.         code       = CodeNone;8 r  x- Y, |2 G! {) E) N
  1322.         stage      = StageNone;0 w; T) G8 W) u+ p* E4 g

  1323. $ h' t' v' ]! X7 B8 @% r
  1324.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    $ ], b' m1 E* y& D4 T% S/ u: N
  1325.         {
    - c8 u: b0 a+ {: T2 i- [
  1326.           txBuffer[txLength] = CodeCan;
    ' K$ b4 o; Y; g; D& q
  1327.         }
    ; E  m, W3 V: K8 _6 W$ }

  1328. 2 S3 u4 I" {, @* ~# g' _9 ~
  1329.         write(txBuffer, txLength);& u- ?0 S, M; j& p$ F
  1330.         callback(StatusError, NULL, NULL);
    ) A9 P5 `& y  F2 w' Y* x
  1331.       }
    ; j9 W( b; y0 D& t  @3 F% i
  1332.       else
    # w1 O/ y$ _" j2 d# }3 E' ?
  1333.       {
    # c+ v# v- p$ X' o
  1334.         timeCount  = 0;6 V' W: J3 t' n' E
  1335.         errorCount = 0;
      Y# M5 m  N& r1 e+ b$ {/ G
  1336.         dataCount  = dataCount;
    : U3 e3 i0 i  \  L
  1337.         code       = CodeNone;
    5 I' D" E: t1 s+ I$ N
  1338.         stage      = (Stage)(stage + dataCount);
    * [% Z& Z: e- P, o: d/ m
  1339.         write(txBuffer, txLength);
    2 N- G* E! R% R$ x
  1340.       }
    " [, p1 s4 {" Z( h; ^

  1341. & H3 u! L+ U# C! {0 }
  1342.       break;  j; V7 ]' {; B% t% k$ m
  1343.     }- A  h. G9 N9 h* n, b( X
  1344. * y- {1 N- L1 h5 `2 q
  1345.     case CodeAck:3 x. m) |- \$ q, M
  1346.     {
    ; u% |: w/ n2 x  [/ z
  1347.       memset(&(txBuffer[YMODEM_PACKET_HEADER]), NULL, YMODEM_PACKET_1K_SIZE);! S5 u7 i! w# T1 @  o

  1348. : _3 [+ |; Y3 d4 }5 e" O2 H
  1349.       switch(callback(StatusTransmit, &(txBuffer[YMODEM_PACKET_HEADER]), &(txLength)))
    / C; H3 A1 C" V: Y. J
  1350.       {, q8 G' k9 g0 C- k4 M4 V! Q
  1351.         case CodeAck:
    9 h3 Z7 b9 m/ k' K/ _
  1352.         {
    7 p# e) D  R0 s  f% V0 T6 e0 M
  1353.           uint16_t crc = crc16(&(txBuffer[YMODEM_PACKET_HEADER]), txLength);
    ) r: j2 F% q6 f

  1354. 4 [" B# y# ]* X" }% A
  1355.           timeCount                                       = 0;1 B$ B6 b* f# j9 j  {" E% O
  1356.           errorCount                                      = 0;4 q8 ]5 Q# l% Y  _0 f
  1357.           dataCount                                       = 1;; A1 O% v9 q- B+ P- a9 x  e8 [* z
  1358.           code                                            = CodeNone;5 J0 }$ N1 f! i( o, e! \$ B
  1359.           stage                                           = StageEstablished;
    , f) E0 y9 c3 w, H' l
  1360.           txBuffer[0]                                     = txLength > YMODEM_PACKET_SIZE ? CodeStx : CodeSoh;
    ; y* ^5 e- r5 M
  1361.           txBuffer[1]                                     = 0x01;
    + V& Q$ ?: [5 ?/ H4 p& S
  1362.           txBuffer[2]                                     = 0xFE;4 |% H; B. u4 x
  1363.           txBuffer[txLength + YMODEM_PACKET_OVERHEAD - 2] = (uint8_t)(crc >> 8);( W4 x8 D6 q. |) g1 p4 L
  1364.           txBuffer[txLength + YMODEM_PACKET_OVERHEAD - 1] = (uint8_t)(crc >> 0);6 |4 z2 g$ \( m& u# C9 e
  1365.           txLength                                        = txLength + YMODEM_PACKET_OVERHEAD;
    % n& I0 ^" g6 i) x1 y( p
  1366. 4 B( {+ }0 J- z/ ~/ q0 x
  1367.           break;
    8 w7 s( ?& p! o; d" u* C5 j
  1368.         }6 p1 M$ S% ]5 s

  1369. , X  c# T" h1 }0 Y5 R! Y
  1370.         case CodeEot:; }1 l+ i& X* K/ o) S' u  E8 L1 `  e: N
  1371.         {
    2 a% W- z; }/ a# f" b
  1372.           timeCount   = 0;/ Q; n6 ?. H; I% l
  1373.           errorCount  = 0;
    $ }& R* V6 u& p+ P3 d; {
  1374.           dataCount   = 2;
    $ c& H6 b" p& ?8 k/ Z
  1375.           code        = CodeNone;
    2 r. {' `# w( ?& Y4 f) e" U" x; }
  1376.           stage       = StageEstablished;- T9 f/ T; W; q8 f8 k9 \  M+ M
  1377.           txBuffer[0] = CodeEot;/ {- J, x- h$ n3 m
  1378.           txLength    = 1;
    $ K+ j: w8 z! X
  1379.           write(txBuffer, txLength);4 a4 T* I% L  T$ l, a
  1380. 2 \; j; H0 I. q% ?% s7 y8 |
  1381.           break;5 \% S/ i- l: ^& g
  1382.         }
    % L. I  j4 x) D! r! j9 g
  1383. 0 f" l" r  z' J
  1384.         default:
    3 t+ |; {% H7 i
  1385.         {
    ! `2 |8 Y7 Q0 L5 u' R
  1386.           timeCount  = 0;( y) R. k3 c2 [; T% q6 {- p& ^) e; H
  1387.           errorCount = 0;( u9 p9 s& D2 |8 |2 e0 ?: Q4 D
  1388.           dataCount  = 0;
    + F+ u1 y0 S$ Y$ B2 I
  1389.           code       = CodeNone;
    + Y# D, w: A# S3 v3 ?! a4 c
  1390.           stage      = StageNone;" f" V" P0 P) p1 b% w2 ?) A  k
  1391. . ?$ C6 L  m6 ]$ |6 G7 E5 ~
  1392.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    ( {/ K) u" a( A% {4 `* E: d4 [2 t
  1393.           {
    ' U$ u5 K" \- R5 S& v& d% _0 c' x: A
  1394.             txBuffer[txLength] = CodeCan;0 A3 R: Z% m/ I# D, V
  1395.           }& X" D7 a5 m% }$ h! a

  1396. 7 i6 A% a# s' Y' A. p
  1397.           write(txBuffer, txLength);+ T% F; R8 A( N% H  F( U. e) d
  1398.         }5 S/ B1 V( D- v8 F+ i
  1399.       }6 E0 a5 W3 p& a5 Y0 v$ k

  1400. 9 g3 w8 V2 D2 K! k5 C9 E
  1401.       break;# I/ Z+ k7 h7 I8 S( _; r
  1402.     }' B' r  u% J6 g% L( N. n6 {4 |

  1403. $ W* _& l" j* }3 x
  1404.     case CodeA1:
    0 k5 p0 _# m) X6 h4 k$ P
  1405.     case CodeA2:
    ! c# n& G; w$ V1 x5 p! b# j
  1406.     case CodeCan:+ G2 I; Z) E4 \/ Q/ S
  1407.     {" a) q$ Q; A9 p- u  w) N) J
  1408.       timeCount  = 0;
    ) L. N: Q: H- ], e4 {. l5 P9 s% _
  1409.       errorCount = 0;1 _% |: g) M  g* t4 H% g8 e! i7 w
  1410.       dataCount  = 0;
    9 R  c2 l& o! t/ g2 r. \& W$ |
  1411.       code       = CodeNone;( ^, Q9 K5 l; k! i3 d& Y
  1412.       stage      = StageNone;( @4 ^' L4 h% ]0 K3 {
  1413.       callback(StatusAbort, NULL, NULL);
    $ g: ^2 c  w, A! I8 j9 }2 w

  1414. ; E0 f, _! g; s: g  C
  1415.       break;
    $ X* ^9 E5 L" i% F( _
  1416.     }
    * C& I% u& o! t. v* S

  1417. 6 g8 K3 p  g8 b
  1418.     default:
    + f2 O9 `  G6 H5 i  q+ @; j
  1419.     {0 N# l" d' ?- r* F
  1420.       timeCount++;. L  y! o; h$ n. W6 U

  1421. 1 {. h' \4 L* r, Z) Y
  1422.       if((timeCount / (timeDivide + 1)) > timeMax)
    ( d# x; ~& {% T! r/ U+ d
  1423.       {
    1 y% W3 ^1 `, }
  1424.         timeCount  = 0;- N# l7 X' S2 L% m. Z7 H
  1425.         errorCount = 0;8 F+ P' x* j* s1 y
  1426.         dataCount  = 0;
    , V/ ~6 G1 I3 O9 U8 V: c
  1427.         code       = CodeNone;" ]- B4 B. U# t# `0 A! p7 |, o
  1428.         stage      = StageNone;
    * k. N% Y% c# m7 P6 m

  1429. / n! r$ e& t% w- W$ P- _
  1430.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    * f2 P; e2 a" c. Y* O
  1431.         {
    1 @4 y2 U9 o9 s3 F5 z/ y
  1432.           txBuffer[txLength] = CodeCan;
    6 i* H. |5 r4 A+ B# A3 P! ~
  1433.         }
    8 w! f6 W* l9 ]* r0 S* @0 R
  1434. 5 c% O6 _# H7 _
  1435.         write(txBuffer, txLength);: J* h' I& F. Y2 L* C
  1436.         callback(StatusError, NULL, NULL);
    ; ?0 G8 b' }& G2 m6 ^" E" ?9 {
  1437.       }/ F9 _: M# d4 n, B) R& l" l) c. t
  1438.       else if((timeCount % (timeDivide + 1)) == 0)$ |6 M3 ~! H; o
  1439.       {: B: ~8 Z. U, T# L! D: Z, ?* D
  1440.         write(txBuffer, txLength);
    4 z5 {+ H! S8 X; H" q
  1441.       }5 I- T/ d1 O1 i1 H; o
  1442.     }
    1 a! R: d6 l7 {( M/ w/ x* [4 ?) I# O
  1443.   }! r2 l  b7 J* A- r2 L; [9 I0 v
  1444. }
    ) w+ W$ y4 `$ Y; f7 `; c
  1445. : x1 X7 U3 U0 ]+ A/ h# W; \
  1446. /**) o8 V  B5 q, j3 K5 v. e( d3 ?
  1447.   * @brief  Transmit transmitting stage.
    2 x  [" L! O; c' d
  1448.   * @param  None.
    1 l. K2 m; q5 d
  1449.   * @return None.7 j, _) h0 `) ], }* E$ S- R3 X
  1450.   */8 O  w$ ~2 }" M; ]: U# O
  1451. void Ymodem::transmitStageTransmitting(). U/ l6 I; F5 z) Z5 N
  1452. {
    % Q3 I; ]" u5 ?
  1453.   switch(receivePacket())& O( i* o  N  c- X" u
  1454.   {
    2 p% d, a/ V- H
  1455.     case CodeNak:! j  e+ n* e( A4 h8 _+ V+ [. I
  1456.     {% V1 ]# @6 Z. V9 c5 t) i# t* V' m
  1457.       errorCount++;
    ; ~; `$ p. Z4 U) H
  1458. ; m' p* D0 s' S1 h7 ~! C" x8 S" g
  1459.       if(errorCount > errorMax)
    . w/ }# C% _4 ^" C' Y  j
  1460.       {
    7 D- }8 I2 }7 Z* r+ i# \0 }
  1461.         timeCount  = 0;% O' ]" u8 w: U  |. D
  1462.         errorCount = 0;0 [& a* A6 ]& w& ?: R7 P0 @( q
  1463.         dataCount  = 0;
    & E) q5 W' P& I4 F' G1 }) E
  1464.         code       = CodeNone;
    4 [4 E8 y6 K0 n& n7 t3 W3 @
  1465.         stage      = StageNone;/ F' R9 K2 \7 |) ~/ Q! |5 K

  1466. / f4 k' E0 U- J2 @
  1467.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    2 Z" P0 h9 w, O. M7 F0 w( k
  1468.         {
      y- N9 D0 B) y7 ^
  1469.           txBuffer[txLength] = CodeCan;
    & d3 B$ ?9 \7 V) D0 e
  1470.         }
    & }0 {; [) k2 V* l* ^* E! a- E

  1471. $ g$ e+ n" F0 w; z. h
  1472.         write(txBuffer, txLength);
    $ n! e! p7 z8 O  J) u  R
  1473.         callback(StatusError, NULL, NULL);7 z6 l3 R& j: a! z  G
  1474.       }4 m* N- y* l( t$ M
  1475.       else: C; I1 X/ x' s- X6 Q; x8 P3 f
  1476.       {
    % n  [' a  C4 ^  i" ]: ~
  1477.         write(txBuffer, txLength);$ f; E0 m8 s* j  N& M
  1478.       }
    0 z( H- y  n7 i/ T; D5 l! N* S# `
  1479. - h' r6 F2 P- c- p
  1480.       break;- F2 q/ M8 g8 n0 ^' X
  1481.     }$ v& ^: a. Z& F, {+ M" ?' U

  1482. & U2 q( ~: R, K) ?5 h/ c6 ^
  1483.     case CodeAck:
    * M- ~0 n5 s& o& x& H9 M
  1484.     {
    - m" b$ }2 s, O  {9 R
  1485.       memset(&(txBuffer[YMODEM_PACKET_HEADER]), NULL, YMODEM_PACKET_1K_SIZE);
    9 i, Y" c1 _2 i5 D6 G; y- L

  1486. 2 W7 `1 n' V& Z
  1487.       switch(callback(StatusTransmit, &(txBuffer[YMODEM_PACKET_HEADER]), &(txLength)))
    # {( Z( o2 s( @  \0 s' w/ _
  1488.       {+ \9 B9 O/ q8 n- L- T
  1489.         case CodeAck:6 h; U$ l+ H) h0 T8 \/ b3 {( a# {4 V
  1490.         {" P. G. {) u. Z3 Q
  1491.           uint16_t crc = crc16(&(txBuffer[YMODEM_PACKET_HEADER]), txLength);) O; D) V7 O& C6 Y$ n9 a

  1492. 1 `  k& \. Z# n% \9 z+ s
  1493.           timeCount                                       = 0;0 V! ~: @4 y% F% _1 s3 p
  1494.           errorCount                                      = 0;
    9 R$ v6 w9 G7 u/ |: }" ~
  1495.           dataCount                                       = dataCount + 1;
    % T: z( f8 R: p; ~
  1496.           code                                            = CodeNone;" C5 k, q- ?  y5 p
  1497.           stage                                           = StageTransmitting;  K  c: q9 M6 g! V3 f
  1498.           txBuffer[0]                                     = txLength > YMODEM_PACKET_SIZE ? CodeStx : CodeSoh;
    , M. H+ p4 G3 A9 b2 S
  1499.           txBuffer[1]                                     = dataCount;" y* B7 ?& i, H. U$ P" [
  1500.           txBuffer[2]                                     = 0xFF - dataCount;6 i. q# B( K6 @; j
  1501.           txBuffer[txLength + YMODEM_PACKET_OVERHEAD - 2] = (uint8_t)(crc >> 8);" U# Z' L, z- _5 d" @7 {3 e
  1502.           txBuffer[txLength + YMODEM_PACKET_OVERHEAD - 1] = (uint8_t)(crc >> 0);& c- r: n. K; k8 n6 `/ D
  1503.           txLength                                        = txLength + YMODEM_PACKET_OVERHEAD;! c& s+ j: {5 \0 o7 c  Z5 y7 M1 B
  1504.           write(txBuffer, txLength);
    / i( O' D& T+ n6 {  a

  1505. ; I9 Q9 s8 w6 S
  1506.           break;
    # N; s" O- W) I5 u
  1507.         }; k4 ~* s3 v0 U$ C& R  F6 B( d

  1508. 8 A% C+ q0 l& _9 \; W, c" _6 b
  1509.         case CodeEot:
    : l" m$ q1 Q; `- u" [% D' n" r
  1510.         {" F, q9 I5 _* [& D; x7 h
  1511.           timeCount   = 0;
    / C/ C8 e5 _  _' g6 P1 t0 [
  1512.           errorCount  = 0;
    ) d9 k3 E. m* k, E( g: [/ f) o
  1513.           dataCount   = 0;
    . s5 n7 m4 C# w3 ?: Y
  1514.           code        = CodeNone;
    ; P+ d# ?: o. W
  1515.           stage       = StageFinishing;& ?& f) P$ ^! _7 x6 S3 d" \+ |
  1516.           txBuffer[0] = CodeEot;- _1 `- K* |9 P0 D; B' r
  1517.           txLength    = 1;
    1 E6 v6 Q+ ~. z0 H
  1518.           write(txBuffer, txLength);
    : r  D7 c/ h( k4 z% w
  1519. 4 I7 H, h+ \) ?6 M  S! ?
  1520.           break;
    - h; R0 P6 M5 v8 T% g4 t5 i
  1521.         }
    / p: g0 m% y$ `: P8 r# C; A% d
  1522. 3 @+ o$ m9 ?! s* v2 i) r
  1523.         default:
    % \2 G( s+ b4 z+ y# V  i
  1524.         {
    2 u9 b* l4 U( u; i4 `
  1525.           timeCount  = 0;
    0 ^3 X, n6 l+ P! L  P2 i: V
  1526.           errorCount = 0;: ~  p# E1 K  ~. {+ J8 Q% r
  1527.           dataCount  = 0;9 v. r, k/ x* d* n: C
  1528.           code       = CodeNone;+ v. H2 ~' U: H) G1 x! |$ m
  1529.           stage      = StageNone;
    2 e; d5 D% v+ g
  1530. ! Q2 _6 F0 N* T$ H
  1531.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)- F) L  ^- W3 ?9 L9 K4 k
  1532.           {
    ! ]! w+ ~. D; |  F5 r2 H. W
  1533.             txBuffer[txLength] = CodeCan;
    4 r" E  g$ k3 Q& m& ^4 I) n9 m
  1534.           }$ b6 Q3 u* u! s* M! H  E" L

  1535. $ v* t8 [3 z; T5 w2 ~. z( u
  1536.           write(txBuffer, txLength);9 Q9 H9 d6 z3 m; B% i
  1537.         }7 a) k: f& M% p4 y4 X
  1538.       }
    5 K/ a) \  C2 a/ G" Z

  1539. 6 g+ B+ v( C% n0 y, c* ?
  1540.       break;
    1 [" M5 S* {1 Z3 _2 f- k5 _
  1541.     }5 V4 h" F) V0 |5 E6 s3 Z$ x
  1542. & p/ G5 e) q3 ~; `/ P
  1543.     case CodeA1:. o# A5 O+ Z) [, h
  1544.     case CodeA2:& ?9 K5 I' U! J. ?6 ]; g$ i
  1545.     case CodeCan:8 [6 P/ @0 L( V- s7 V: `
  1546.     {  s9 C8 L1 k  J8 o" ~; q* R0 G
  1547.       timeCount  = 0;$ y% l( }9 X5 _( D8 ^1 _
  1548.       errorCount = 0;
    % K5 @  ^, _/ G+ d3 |" v  j
  1549.       dataCount  = 0;
    1 h1 y' s& w3 w
  1550.       code       = CodeNone;
    0 C( c1 \5 L  X) ?+ f) N" K
  1551.       stage      = StageNone;
    ! g% l$ B/ V* ^6 ^2 l) G
  1552.       callback(StatusAbort, NULL, NULL);! n/ G. Q- U. }  l$ j4 F/ M* [
  1553. 1 A% j5 q0 G6 B; l
  1554.       break;
    4 Y/ V- ], [+ M
  1555.     }
    8 a5 b0 G) U& G. q- a$ W

  1556. 6 Y( ]- h' \" t
  1557.     default:" V  B, d* O5 D1 u4 E- M
  1558.     {
    , F: P: c3 C$ X  A$ _, U
  1559.       timeCount++;
    . u# D" Q) g) A% s
  1560. 7 K$ o/ o5 b+ C" ?
  1561.       if((timeCount / (timeDivide + 1)) > timeMax)! {2 c" m" p0 d* E; w9 O7 N2 U
  1562.       {
    ! o# ^" U: u- _5 b
  1563.         timeCount  = 0;, M+ l- Q2 D: c- _7 J5 r, G: M
  1564.         errorCount = 0;
    4 w5 c1 z3 I+ o
  1565.         dataCount  = 0;
    / k/ x& ?/ p/ K
  1566.         code       = CodeNone;8 F8 y% E/ B3 g/ k! {+ m  B  r6 f
  1567.         stage      = StageNone;# S( B+ t' Z! S" a, O, S

  1568. . }7 x" m! ~$ o* ?2 g9 m( q% S: U  d
  1569.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)( c7 L7 s$ Q0 t3 k
  1570.         {
    ; t9 q2 e/ L0 H0 g( O
  1571.           txBuffer[txLength] = CodeCan;: n4 C/ y1 o1 C# k3 w/ L1 X
  1572.         }/ _1 E( C$ ?6 E+ A" \' p; Z1 ?

  1573.   S' X) u; d) d+ e4 p+ x
  1574.         write(txBuffer, txLength);3 P1 V. c; M) X% E7 y6 j1 |4 M! E
  1575.         callback(StatusError, NULL, NULL);2 |/ d& `$ D3 f
  1576.       }
    ( Z  Q% c9 g# B8 \# A. h) ~$ A0 H' O
  1577.       else if((timeCount % (timeDivide + 1)) == 0)
    7 \( |4 _: U! B2 y$ w
  1578.       {
    ; i4 n/ a  u4 ?, B* _8 E
  1579.         write(txBuffer, txLength);
    : A2 _+ m: ?: i( H7 r
  1580.       }  v& o2 M! b+ Y' t; T0 O
  1581.     }6 ]- E% s! K9 {+ M& ^; j% f: ]
  1582.   }
    % R6 t7 x3 Z. v
  1583. }: K0 R0 C: T9 L( t/ N, A
  1584. ( u/ d0 D9 o: ?
  1585. /**
    : S) M- ^, e: M! R: O: {
  1586.   * @brief  Transmit finishing stage.
    5 ?7 x' G8 m$ W+ m1 r: v
  1587.   * @param  None.$ W. M5 a/ ]3 t  w0 f# T
  1588.   * @return None.$ S! e. \9 z8 w+ p5 Z- G" \
  1589.   */
    / v4 ~0 ^- |$ \# ]
  1590. void Ymodem::transmitStageFinishing()( p' B& ~; w8 [( ~9 W. V
  1591. {
    0 x' p7 d. ?5 }% Y* d7 w2 \8 Q# e
  1592.   switch(receivePacket())
    , |3 ?  t  a! U" V
  1593.   {
    . [3 z# }% t6 D5 m' U+ D  |$ m
  1594.     case CodeNak:
    ' m! \0 N+ _7 K% E* k
  1595.     {
    : D" s2 c- z" z6 h. e1 V
  1596.       timeCount   = 0;
    2 Y  _8 y) V( y* P) J
  1597.       errorCount  = 0;; v% G; Z8 s- M! y8 b+ M/ X
  1598.       dataCount   = 0;
    / D, V5 O* I6 V: @5 R) V2 A& k5 C* k
  1599.       code        = CodeNone;
    4 ^) F6 E& d) D) `7 k6 ^2 M
  1600.       stage       = StageFinishing;
    ) Y4 f2 ^) k: q( I9 O
  1601.       txBuffer[0] = CodeEot;
    # m. F5 y9 e+ h. R% F
  1602.       txLength    = 1;
      U" ?- E7 N1 T7 V6 i
  1603.       write(txBuffer, txLength);
    2 k, x6 }6 @4 j' g2 ^
  1604. ) s7 l, c( W1 I; k% @* S2 L
  1605.       break;6 \; }5 h8 P* ?" O9 ^; v
  1606.     }
    : u; a5 |( F5 f
  1607. 5 m# x& B$ Y# M3 F4 ^
  1608.     case CodeC:) k  R$ E4 g1 ^: W
  1609.     {- Y' U$ L& D8 ^! ~' Y5 b6 Q7 m
  1610.       memset(&(txBuffer[YMODEM_PACKET_HEADER]), NULL, YMODEM_PACKET_SIZE);: F7 J/ o# N0 c. x" {
  1611.       uint16_t crc = crc16(&(txBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_SIZE);
    $ m: ?# Q/ \8 c: F& \$ t

  1612. 0 l) q& K! C: V) k4 y$ e7 p
  1613.       timeCount                                                 = 0;
    % m* g- z( F9 z: F+ A
  1614.       errorCount                                                = 0;3 f3 L+ D6 z8 ~( J
  1615.       dataCount                                                 = 0;' S/ o  w! B$ C& [/ v
  1616.       code                                                      = CodeNone;
    / C1 l- j+ e# t. y+ j7 L
  1617.       stage                                                     = StageFinished;% r' M: l% B+ ]: I/ M
  1618.       txBuffer[0]                                               = CodeSoh;
    & Y, x4 ]$ e  b: G- j
  1619.       txBuffer[1]                                               = 0x00;8 g0 X* K* v6 z; v7 _4 v8 }* d
  1620.       txBuffer[2]                                               = 0xFF;+ b5 W) f, j. b. q! ]- g
  1621.       txBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 2] = (uint8_t)(crc >> 8);/ r. s" F' ?9 c5 M( x9 _6 @
  1622.       txBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 1] = (uint8_t)(crc >> 0);
    4 ]: m$ H( T: V. u& A& q. s  a
  1623.       txLength                                                  = YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD;
    : G- _9 @3 b3 X- M
  1624.       write(txBuffer, txLength);; g5 ?' l9 r1 _$ Y' ^1 H  [

  1625. 4 a9 ^( T& z! x+ ^7 c) J$ h
  1626.       break;5 x" ^1 s, L. A' h
  1627.     }
    4 H/ D; b1 l" L/ U
  1628. : t# z% x$ C, e. z; O: c6 \
  1629.     case CodeA1:! ^9 k) s* J/ @- l+ n1 s
  1630.     case CodeA2:
    ; B7 q. ?6 o' O) z0 {- l
  1631.     case CodeCan:9 ^, U! A& O( V
  1632.     {& @1 U" U) \* X( a7 Y) I: g
  1633.       timeCount  = 0;. b5 {) n+ y  d- \
  1634.       errorCount = 0;
    , F  k6 s% k' i) d1 \
  1635.       dataCount  = 0;" \! @  d: G9 ?
  1636.       code       = CodeNone;3 [. R2 L' H/ @$ J
  1637.       stage      = StageNone;
    ' h0 N* X# v! W. r) L
  1638.       callback(StatusAbort, NULL, NULL);) j, R1 @4 x. K6 F2 m
  1639. ) g; F( C% g+ v5 S
  1640.       break;
    ( A- T7 n! S4 x" i
  1641.     }1 N- |, u# p/ k
  1642. 8 ~0 J( S! X4 a, \/ m5 m
  1643.     default:/ f6 X( I6 N) N* Z0 a0 ]
  1644.     {
    / g9 [4 r" H% {  x2 @, M% x- G$ r
  1645.       timeCount++;
    ' Q8 R3 s! e/ c5 I

  1646. , r2 S( g0 T% |
  1647.       if((timeCount / (timeDivide + 1)) > timeMax)
    $ P) Q6 d& M+ g7 `
  1648.       {) ?. j$ q: ?3 T- X; \- G1 m
  1649.         timeCount  = 0;
    . X; K/ w7 b, W# b1 J0 C% w8 J
  1650.         errorCount = 0;- K+ G4 s! o2 B6 L- x
  1651.         dataCount  = 0;! I' R2 H7 G8 k$ f. x
  1652.         code       = CodeNone;  u; Z* b& [& n% |$ }
  1653.         stage      = StageNone;" T1 L2 W' ~( v& ]% O
  1654. 5 ?" V! g+ f- ~5 E1 f  s9 E
  1655.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    & ^/ A; W$ k) o! ?
  1656.         {
    & f' A7 p5 O, {- J4 z- B
  1657.           txBuffer[txLength] = CodeCan;
    % u' A' u3 K7 M9 Z. b
  1658.         }
    - G( r% ^% R) |4 a
  1659. * B& [( |/ G/ N" \
  1660.         write(txBuffer, txLength);
    3 l- R$ S' y  A2 e# F. V: H
  1661.         callback(StatusError, NULL, NULL);
    ; R8 o. k7 C' e! t
  1662.       }, q% K0 g7 D! k% _
  1663.       else if((timeCount % (timeDivide + 1)) == 0)& b: l* n; G4 t- I, j
  1664.       {
    6 v# W, h% Z9 C* D# N! C
  1665.         write(txBuffer, txLength);
    8 _) y1 M3 g% Z0 A
  1666.       }
    # N# |& J% a3 h% M0 I- o
  1667.     }
    ! `9 [/ g' o3 X+ h! s
  1668.   }/ l2 G1 y5 C8 |# }
  1669. }4 I6 I) v$ q$ n- u1 Z- n0 g

  1670. 4 O& w% i& W: j) ^  F
  1671. /**
    0 i/ H% r; G# y! B
  1672.   * @brief  Transmit finished stage.6 h$ K, c3 @' f( B7 X! A" t
  1673.   * @param  None.
    + `3 V5 F2 W1 x% |; i+ ?# c
  1674.   * @return None.: T4 [9 G  T" U; L: E) L7 N" ^+ A7 z! F
  1675.   */
    ( a5 K- a& A+ q
  1676. void Ymodem::transmitStageFinished()0 y7 G3 p) {0 N; P0 ^2 x
  1677. {) h7 P: s% q. l: x7 f" T
  1678.   switch(receivePacket())
    * G% S: G) Q( n" n
  1679.   {2 M, M. c9 R" V0 A7 D
  1680.     case CodeC:, ]- s$ p5 ]( K+ W5 a
  1681.     case CodeNak:
    5 w( M" E# M- v! }# Y% P
  1682.     {
    7 k, g2 A6 L: L* e
  1683.       errorCount++;7 a. u/ k5 t, c

  1684. 5 E* |- ~; |$ W! I  C# V
  1685.       if(errorCount > errorMax)+ {: ^0 Z- ^  Q, b. i& f4 l
  1686.       {
    2 \0 t! p3 s  W
  1687.         timeCount  = 0;
    ! U& |. m7 I7 v
  1688.         errorCount = 0;
    : @, q4 ?  M2 H  j
  1689.         dataCount  = 0;
    1 |* O9 N& e3 \3 G" M, s* {
  1690.         code       = CodeNone;
    9 C; i: I8 @& u% S6 u
  1691.         stage      = StageNone;
    2 d# l% {; s; n  Y6 ]3 ]
  1692. 0 |% L5 l2 r8 N/ m2 t
  1693.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    . [# s6 b# j8 Q& \
  1694.         {* E/ D: C3 l; e+ b
  1695.           txBuffer[txLength] = CodeCan;; i" j. w7 n5 r
  1696.         }
    . O6 {( m+ ]4 }2 ~

  1697. ; H9 A4 Y8 N0 E- _
  1698.         write(txBuffer, txLength);5 Z$ I: N4 u9 o
  1699.         callback(StatusError, NULL, NULL);! f' ~+ d) M0 D# k: W
  1700.       }3 e1 I2 N- K; J. e3 ]9 i) `
  1701.       else+ o, i" y0 v9 q" X1 m, @5 F
  1702.       {
    ) K* o8 ~. b& c$ I" L% T
  1703.         write(txBuffer, txLength);
      C- k( c+ A3 |' ~6 g
  1704.       }: T$ M8 t& i+ v, N
  1705. % k/ L% T8 v- r! Z, m7 M9 g$ F0 p/ [
  1706.       break;
    * }8 y" z# l) o7 g% F7 ]( L6 P
  1707.     }6 ]% p2 c6 G0 C5 o4 p. M" s4 T

  1708. - a' [* s" e' Z5 P0 q. n& ]7 \
  1709.     case CodeAck:
    # ]5 @  P9 Z2 A8 L! y$ t; p
  1710.     {
    5 ]% ?: I+ z& X! J! F6 {: o
  1711.       timeCount  = 0;6 c. c# ]/ \3 ?7 R+ l1 d
  1712.       errorCount = 0;- q$ |2 N' y: s* Y& K  u
  1713.       dataCount  = 0;
    1 j$ d. Z; Y1 u
  1714.       code       = CodeNone;
    5 D, r5 q+ _) k5 X
  1715.       stage      = StageNone;
    . s, o) s% b. k( v% A3 s
  1716.       callback(StatusFinish, NULL, NULL);7 D6 k) {- x6 k* o0 v3 M+ t% I

  1717. 5 [/ l8 @' M& ]" @2 u& j
  1718.       break;
    9 H+ Z4 q- T) F5 W3 z/ Q
  1719.     }" ]' W4 k5 e) r0 `

  1720. 9 s; m) x% V4 C8 T% H
  1721.     case CodeA1:. ?2 C- _& @- R/ C) M
  1722.     case CodeA2:  R* F1 Y6 c- c
  1723.     case CodeCan:3 O( V. w$ P- F8 O5 H& @- I* |3 ?
  1724.     {$ J3 O0 Q/ t' ^. J6 Q) e3 d5 Y
  1725.       timeCount  = 0;
    # w6 l+ V% X+ Y0 l' [. q+ ^8 y6 w
  1726.       errorCount = 0;$ z' z3 L$ c8 _
  1727.       dataCount  = 0;
    ' g3 P3 N  G% m- X9 ?7 O9 m
  1728.       code       = CodeNone;
    ; N! g; o% t3 y& }7 a) k* d6 N
  1729.       stage      = StageNone;
    8 C% F- P1 ^% M: k* t
  1730.       callback(StatusAbort, NULL, NULL);, [# P, _( S' U& N! G

  1731. , ?& v$ o1 T1 ], \
  1732.       break;
    4 V" A3 E9 F( S, U1 \" [) p
  1733.     }- z. P: h8 c. `3 t; y. L9 q
  1734. / f8 ]+ x5 l9 y7 Q3 Z
  1735.     default:# c$ X7 R; ^7 o2 |+ I
  1736.     {
      d7 l$ u# v1 L' b
  1737.       timeCount++;
    $ h& f4 [# Q# ^# _; B8 F$ N
  1738. 1 O: B4 @& \0 Y5 o2 C* c- v) Z
  1739.       if((timeCount / (timeDivide + 1)) > timeMax), H+ h% x9 w+ P! u1 m
  1740.       {
    0 D, n, Z4 g9 ?; i- N2 \
  1741.         timeCount  = 0;4 o1 _5 O+ a) }0 p2 \
  1742.         errorCount = 0;8 y' W+ q; J) b
  1743.         dataCount  = 0;& Q& V% l  f6 a9 x" X9 {* `
  1744.         code       = CodeNone;
    / f# h0 x1 d1 j% Y" J4 I
  1745.         stage      = StageNone;+ s! a4 d3 {' g1 }. Q& D
  1746. * @; m* H! ]1 d/ A
  1747.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)8 z# l& a7 R  _3 E- z
  1748.         {6 u- c: b" T# Z/ v
  1749.           txBuffer[txLength] = CodeCan;/ @- l. y. p; r' n4 n6 d  k
  1750.         }
    : G+ e- s+ t/ Z6 I. k
  1751. 7 a" t0 g0 n1 l, [* v
  1752.         write(txBuffer, txLength);( o- M3 ]+ P! ~: t% H
  1753.         callback(StatusError, NULL, NULL);6 S# G# r( [- r6 Y* ]' W6 E
  1754.       }
    ! b1 _7 m- q: [; R& l( x& T
  1755.       else if((timeCount % (timeDivide + 1)) == 0)
    # h9 Z$ m' d0 ~4 J/ e+ M+ o
  1756.       {
    ' J. D% d8 f+ G- O
  1757.         write(txBuffer, txLength);/ Q  ?7 V& I/ b; D- [2 i: s8 n
  1758.       }1 X! l, q: I0 C- j
  1759.     }
    - |; @: H8 z( H! u7 z2 Q, b
  1760.   }: |) i3 ^9 e% f6 `) _
  1761. }
    / `0 x9 A6 y1 t' ?; ?1 J
  1762. + {( Z% }4 M+ c" l
  1763. /**
    % A& ]7 D: d/ |' t
  1764.   * @brief  Calculate CRC16 checksum.7 G1 H0 q5 B# V1 v- P) D" R* u
  1765.   * @param  [in] buff: The data to be calculated.+ `" f# n5 p+ v0 p+ ?& r1 g
  1766.   * @param  [in] len:  The length of the data to be calculated.( u1 c0 }( R4 c/ Q' O7 L4 r
  1767.   * @return Calculated CRC16 checksum., T9 M! f  v- i/ S3 t  k4 H
  1768.   */
    6 ?) ^. Z7 |# O. V: U: w7 P. s9 D
  1769. uint16_t Ymodem::crc16(uint8_t *buff, uint32_t len): D, D7 N+ a# ^( `
  1770. {- ?+ y$ _8 ]) r( X6 G% Y
  1771.   uint16_t crc = 0;
    / p8 a! K+ L3 A  K
  1772. 1 E- \" W/ Z+ Q- F+ @1 s" H
  1773.   while(len--)
    * ]6 r4 W8 |2 K3 o
  1774.   {
    : T! \3 q5 w" V- f% W: b+ U
  1775.     crc ^= (uint16_t)(*(buff++)) << 8;
    + l' i* s  C1 I5 y

  1776. . Q; F5 h  }4 r  J5 |: g4 [
  1777.     for(int i = 0; i < 8; i++)) A4 U- l3 u7 P/ y0 m: y' \* X. u
  1778.     {
    + H  X+ k6 F+ h5 @" ~2 I
  1779.       if(crc & 0x8000)
    . `- ^& O* {2 F. w) s. @4 X+ O
  1780.       {- M$ s. S  A+ b+ b
  1781.         crc = (crc << 1) ^ 0x1021;
    % ?( |& [5 G5 K  p
  1782.       }) ~, M( c' ~2 {& R
  1783.       else
      f) Y" x5 u2 I
  1784.       {% t% l4 h- D6 [% ]( A" f1 Z
  1785.         crc = crc << 1;4 X7 k2 p$ t  ?8 n& s1 C
  1786.       }# b9 Y+ l6 l  U
  1787.     }
    2 X, R0 Q( ]2 q8 V2 ]3 J3 e0 Z
  1788.   }- v+ ?8 f0 A4 G7 C! o& L8 g; W" H2 {
  1789.   C" F, [+ k' B' ~% T; u
  1790.   return crc;6 |0 A3 H/ s+ {% v" p+ C  C- i
  1791. }
      X! t) s, K1 r+ [# z
复制代码

; X: [5 a' B8 @; t, A. E* Z
  B- U: S- Q  s; u3 \
5 Q$ o! c  p  V# `* v3 v$ |$ n4 `4 n- R( ^
1 j, @: R& N2 V" f
收藏 1 评论11 发布时间:2018-3-6 22:28

举报

11个回答
XinLiYF 回答时间:2018-3-6 22:30:39
      YmodemFileReceive.h文件7 e0 k9 M5 b1 o- }! U( U6 ]) z9 b$ m
  1. #ifndef YMODEMFILERECEIVE_H
    $ G) D- ~( s$ f+ l
  2. #define YMODEMFILERECEIVE_H
    , I% o; _) K# I* r' \1 V

  3. . d1 ]& H: e& o. W0 t( F
  4. #include <QFile>: H& |: D$ K" R5 {9 Y0 d
  5. #include <QTimer># d2 p- w5 _# ^3 H0 }- B& r
  6. #include <QObject>+ I% q7 c4 l( m
  7. #include <QSerialPort>3 I, d+ B1 `. Q, L
  8. #include "Ymodem.h"
    1 s9 F2 d3 \/ ?# c: D3 K* E

  9. ! k! B! b3 b5 c0 ~: d
  10. class YmodemFileReceive : public QObject, public Ymodem3 B: B! [7 r$ b/ C, v
  11. {% X3 U# i8 _) J  Y7 G
  12.     Q_OBJECT
    ! `8 O+ b. T" @( S, F$ T# G

  13. * G3 m( R0 s! M) _
  14. public:6 R; o0 q. @; X$ V3 Y: c
  15.     explicit YmodemFileReceive(QObject *parent = 0);% A; V% R8 i: S. K
  16.     ~YmodemFileReceive();  e' e5 U4 y9 o; U# _' ~
  17. . s* e( o8 t) P6 K5 U
  18.     void setFilePath(const QString &path);0 c0 x# P' o; c2 b) E) T  K
  19. 8 f9 c1 S) ~) v4 R, `8 A3 Y; O3 }9 l
  20.     void setPortName(const QString &name);9 H& L1 j/ o- h4 K
  21.     void setPortBaudRate(qint32 baudrate);
    . _* S( H9 u+ Q) A1 z

  22. ; z/ q) F9 @$ R  [
  23.     bool startReceive();( A; M: f0 Q3 ]- \
  24.     void stopReceive();
    % W( s; H7 W$ ~# k5 i

  25. 7 v: M% v* d6 ]- m: x/ U
  26.     int getReceiveProgress();7 a& U. j+ j5 Z- O! ~! n
  27.     Status getReceiveStatus();1 {& f+ N: e% Z; O7 C# h' p
  28. 2 L% i) _; W* p$ E# h
  29. signals:7 O: j( x2 [9 C% x
  30.     void receiveProgress(int progress);
    / J% f. j- Y, \1 E& r" P& b
  31.     void receiveStatus(YmodemFileReceive::Status status);
    0 C+ W/ }9 ?* _+ }/ x
  32. 3 |" t9 [) M- o' @
  33. private slots:
    ! R/ k" t: V. Q' \+ o% A" @) J$ `
  34.     void readTimeOut();
    $ N) u4 |0 y5 n: F' L3 J  K
  35.     void writeTimeOut();" w: G  ?6 `0 Q% @2 S, Z

  36. 5 v0 V0 S, R" O' a' p# U
  37. private:
    ; |- R% P  w7 G
  38.     Code callback(Status status, uint8_t *buff, uint32_t *len);
    2 a+ x4 p4 J/ P  M& T6 o) g. S

  39. 1 ], ]3 ~" X' z% n$ n2 o( H, G( v
  40.     uint32_t read(uint8_t *buff, uint32_t len);0 D+ U7 l% f: n; `6 Z3 @
  41.     uint32_t write(uint8_t *buff, uint32_t len);
    ' X4 w  m! `% ^7 s" W& L3 J

  42. : M3 g# z" f' A" [* e  K) {
  43.     QFile       *file;; |9 ~, g: h  z# o
  44.     QTimer      *readTimer;
    4 J0 `: p/ i. g* y) C; L; z7 O2 n, i
  45.     QTimer      *writeTimer;# g2 w6 H0 d3 T7 K2 w* _( K: g  F( ?
  46.     QSerialPort *serialPort;
    6 x- \1 X2 s8 e9 d# b0 [" y7 B

  47. 0 C. C+ P( m8 M- m( t
  48.     int      progress;
    6 {& k9 Y7 v/ T# K& w
  49.     Status   status;. \& `5 n" E4 T+ B! S! w6 D
  50.     QString  filePath;
    " p) k7 S/ z3 b; F
  51.     QString  fileName;
    ; a; G# r3 k4 t! l& h
  52.     uint64_t fileSize;
    ; D" n- |9 u8 n' m+ p% B) J
  53.     uint64_t fileCount;
    7 ^  Z  A% V0 v1 o# z
  54. };
    * U$ H0 Z5 x4 u1 g
  55.   e9 X6 Z1 R' `6 [* o
  56. #endif // YMODEMFILERECEIVE_H
    7 s: V2 }  }1 o8 ^2 Z
复制代码
# @0 y0 G0 q1 N, z% A; ^2 G6 L6 }
      YmodemFileReceive.cpp文件* g1 ~% n' n1 _" O% q6 u
  1. #include "YmodemFileReceive.h"- L: u- a6 d$ u; [
  2. ) _& _, x1 }1 p# ~" O8 ?& D+ \
  3. #define READ_TIME_OUT   (10)
    0 M9 N  n0 x+ v4 _
  4. #define WRITE_TIME_OUT  (100)% P3 m6 ^3 C& C$ F
  5. # X! W5 }) q# J
  6. YmodemFileReceive::YmodemFileReceive(QObject *parent) :
    $ S1 Z; ~: N+ M6 W7 ~9 H; T' V9 f, j
  7.     QObject(parent),. l' b0 F7 P* D2 Y( b5 A
  8.     file(new QFile),
    ! s& q' [1 U" j# n+ F- v
  9.     readTimer(new QTimer),, H) I7 \- q" J6 k2 G! X* R8 c
  10.     writeTimer(new QTimer),
    % l+ r- {+ v* j1 }6 X) n" U
  11.     serialPort(new QSerialPort)+ H) I) B3 ^$ C7 \* Q
  12. {
    $ S1 e5 |( L( s9 B- P
  13.     setTimeDivide(499);
    , W8 w. m! {( p  _# W6 N, G2 ~
  14.     setTimeMax(5);
    ' v5 z1 o" V7 q
  15.     setErrorMax(999);4 ?$ Z6 g% f4 P# ]2 Z' Y& v' }

  16. 9 c- S# ]* h: i" r+ x5 w2 l$ R# Y
  17.     serialPort->setPortName("COM1");) |$ Q# I( J4 X- U6 ?
  18.     serialPort->setBaudRate(115200);+ q' d0 w9 @. c  V$ a
  19.     serialPort->setDataBits(QSerialPort::Data8);
    5 D; ~4 G/ ^( u$ k) X7 B% V* a! l
  20.     serialPort->setStopBits(QSerialPort::OneStop);" E- p8 F8 e1 O
  21.     serialPort->setParity(QSerialPort::NoParity);: G* h' S7 q2 p5 ]9 M
  22.     serialPort->setFlowControl(QSerialPort::NoFlowControl);
    7 {$ y% r/ S0 p, h3 b
  23. 7 r$ M4 M0 c# C1 O( l2 v
  24.     connect(readTimer, SIGNAL(timeout()), this, SLOT(readTimeOut()));/ q0 }" ?! {) a: Z% N9 d3 J, Y6 h# l
  25.     connect(writeTimer, SIGNAL(timeout()), this, SLOT(writeTimeOut()));" B5 E; _* O$ P8 ~: f
  26. }. x) T8 J8 G# I' x+ r% {5 d' ]! M. n9 B  z

  27. ; I1 f) T9 q) N5 D$ A* ?
  28. YmodemFileReceive::~YmodemFileReceive(); }9 t3 h& p! D0 Y" {
  29. {
    + X# \- A0 w. v
  30.     delete file;# Q# V  `* ?% p: P. p% H9 G
  31.     delete readTimer;
    0 X. h' k4 B5 Y5 x$ X
  32.     delete writeTimer;3 W9 A$ b8 K: x3 G& e& M
  33.     delete serialPort;
    ; |0 F5 m  c9 ]/ W$ b, x0 Y
  34. }* S! L& A: R- v$ V9 F+ F. |0 C
  35. 6 B3 Z5 L4 _# }; e+ L
  36. void YmodemFileReceive::setFilePath(const QString &path)4 O: k5 Z! J8 P& j3 {  C- @
  37. {# M6 c5 Q/ s1 x/ y8 y0 t
  38.     filePath = path + "/";
    # K- A/ W& T9 J2 ^9 B! a3 `- j
  39. }
    6 y4 \  ~) N5 o
  40.   l- |8 h; F: x8 e0 d# i4 x
  41. void YmodemFileReceive::setPortName(const QString &name)) v, w  V9 u3 i9 d& m
  42. {
    ) W( p( J" P  `" p6 V
  43.     serialPort->setPortName(name);
    / E. Q& Q+ Q+ x$ v
  44. }
    5 ?- c3 ~: z' c2 h, Y

  45. 9 M) v6 |4 e- l3 g7 K) d$ X- E
  46. void YmodemFileReceive::setPortBaudRate(qint32 baudrate)6 E" T" j: Z% q0 b( W1 f+ w* X7 |( L' s
  47. {
    5 X! j9 |9 z6 ?% ?  k* g
  48.     serialPort->setBaudRate(baudrate);
    6 e/ |5 z) {7 b3 [
  49. }4 j. Q4 k7 S- z3 b
  50. 8 F' g/ h' u6 R% E( g
  51. bool YmodemFileReceive::startReceive()" \0 z8 h% D4 G( _
  52. {
    4 F1 P- O5 O( _# R( z
  53.     progress = 0;
    - B+ v" \2 ]. r. e
  54.     status   = StatusEstablish;2 N/ ]# F2 e" P, T, Y

  55. 6 z$ H# f. m0 R' ~0 J
  56.     if(serialPort->open(QSerialPort::ReadWrite) == true)( g- w+ |0 o& D
  57.     {6 F/ O" ~  |6 }1 ~* T, x5 d. v
  58.         readTimer->start(READ_TIME_OUT);
    ' y. V+ z4 W$ j
  59. * U: {: I+ b* C8 U
  60.         return true;
    2 x* J: z# N8 H/ d) G1 m# L. ]
  61.     }
    ! U- W2 N- k8 G% I/ ]$ b. Z
  62.     else- i7 U3 _2 |  t- Q( _
  63.     {
      d) M1 S. j' j' o: Y0 o
  64.         return false;% U; T9 H. n5 M4 q+ \1 {. A
  65.     }. z3 A* N: z' D3 P' s$ L. S
  66. }9 o5 V- P4 q) {& _
  67. : v8 g1 [4 M; H% a( e
  68. void YmodemFileReceive::stopReceive()! i1 X" P' f. b. ^3 h+ a, |
  69. {
    1 ~% K) H! D! U! L' K. ]
  70.     file->close();0 F( Z: @; t" ^0 d) G! {
  71.     abort();
    , K! l: u- @2 ~4 X
  72.     status = StatusAbort;: X- K) Z' Y  b# b+ X
  73.     writeTimer->start(WRITE_TIME_OUT);1 m+ T% a) G% N# g; v- u
  74. }
    % Q( L$ ^! E, @8 [  j  m
  75. ; L9 x. Q) ^/ q$ `- c4 V
  76. int YmodemFileReceive::getReceiveProgress()# b. H! j) P9 C+ G7 ^* @
  77. {4 P; C; C1 @& h! R, a
  78.     return progress;
    / G% q! L& H) H
  79. }
    $ e; x1 {6 E. ^  t+ z) ~
  80. , V4 R- Q1 ~5 q2 M# ^
  81. Ymodem::Status YmodemFileReceive::getReceiveStatus(): F$ w8 x7 M8 f4 F
  82. {" a6 Q3 H5 n' E' @
  83.     return status;3 \/ p; k. Q2 U' }. t& P7 J: c
  84. }
    + K( v/ ^, h5 c

  85. ; c* |1 x7 c& E" p: m3 ^% i7 w$ w
  86. void YmodemFileReceive::readTimeOut()4 P8 B" M  ^$ I7 t/ Y+ n7 S0 i+ ?
  87. {
    0 e  f0 D) u0 R6 m! K6 F
  88.     readTimer->stop();
    ' j# Q: T( X$ G: d5 X
  89. + ]+ ^( }! c+ U+ g9 s$ \$ J. [
  90.     receive();3 F5 y0 R" O8 A' |0 y

  91. : y% C; ?8 X' [# u: V1 e
  92.     if((status == StatusEstablish) || (status == StatusTransmit))4 d* J3 \$ a% |2 ]
  93.     {/ E/ _: x  g( o- @/ }7 A: s1 b
  94.         readTimer->start(READ_TIME_OUT);
    0 G: p# m* Q9 r2 p* r
  95.     }
    0 g, D: J4 z6 g$ h) a5 I% u/ v
  96. }$ K2 `' @) q, ?# H1 q+ Q$ i, A! S
  97. 2 z* m; c; X# ?$ C" G
  98. void YmodemFileReceive::writeTimeOut()
      y4 t% R" H3 p1 Z
  99. {  v; M/ ~, \1 X9 B% Q) ~1 w" r
  100.     writeTimer->stop();
    7 ?2 E0 ?$ w2 @" ]- j( ~* y; V( r
  101.     serialPort->close();& `  L' Y# b8 T% ^& [9 {' h
  102.     receiveStatus(status);& Y* J1 z' {: e7 ]1 U6 F  k. d4 {
  103. }
    1 s0 p: U4 U  ]3 _
  104. # \. ]6 S5 b3 t8 a' U0 j
  105. Ymodem::Code YmodemFileReceive::callback(Status status, uint8_t *buff, uint32_t *len)
    0 N/ D5 ]% x0 n' |
  106. {' G' m% n7 `  Q0 |
  107.     switch(status)
    0 \$ ?7 T6 i# A
  108.     {
    8 s8 s0 G3 p! f! {# b" O8 |2 A
  109.         case StatusEstablish:8 T* j, d1 a1 Y: l9 ]3 l5 G
  110.         {& i  k( J" \: I( A" K
  111.             if(buff[0] != 0)
    + J+ ]% V* p- O, G7 e
  112.             {/ J$ Q. r4 b3 N7 s* V' _; ~% Q
  113.                 int  i         =  0;& A, Q$ n- p% A5 `0 c! D, g
  114.                 char name[128] = {0};$ {+ T+ G+ o$ r5 y4 i; n: y3 ~
  115.                 char size[128] = {0};2 b3 w. z0 q5 b8 l) M$ e2 J$ w
  116. * _% C4 }: g! U+ k! ?" l
  117.                 for(int j = 0; buff[i] != 0; i++, j++)
    7 \/ {' g% S2 @. X/ ]
  118.                 {" ]2 W9 z9 F0 l! J
  119.                     name[j] = buff[i];
    + l1 {8 y9 H1 s7 I  C4 u& C$ p
  120.                 }% U9 d9 O7 B: B( q# Z

  121. $ V0 a1 O- p5 }7 A; c* v. {2 U
  122.                 i++;
    1 N" u' i1 E3 y

  123. 6 G( J  V8 r) y* H* T: t
  124.                 for(int j = 0; buff[i] != 0; i++, j++)- L& _4 D: A- p# m+ `* j$ I6 ]
  125.                 {. X; ^# T- R# U2 D4 [" ?
  126.                     size[j] = buff[i];) Z; s2 l: R3 ~2 J( @# s2 u
  127.                 }
    8 V/ x" H' a. R1 P$ F

  128. 6 l2 J. w; K  |4 H
  129.                 fileName  = QString::fromLocal8Bit(name);( ?! T8 V& O# s  k$ m4 n2 q1 B
  130.                 fileSize  = QString(size).toULongLong();; V  y( R  {. a' Q9 Z. a
  131.                 fileCount = 0;
    + H, K# Z( a1 j  T4 N7 n  |/ |
  132. / h/ s& ?. ~0 D+ L8 y
  133.                 file->setFileName(filePath + fileName);
    : b, q  a$ r; P( Z" o$ V! O$ K3 @
  134. # G6 w% I1 j7 Z2 N3 s2 u) I
  135.                 if(file->open(QFile::WriteOnly) == true)" e- q6 _! \% T/ k2 P$ y
  136.                 {
    1 l0 E! a6 I7 Q+ D. }: Z
  137.                     YmodemFileReceive::status = StatusEstablish;5 J1 n* @2 z+ e7 L3 G6 k

  138. 8 M! N, f, _4 Y; C# \  ^: l
  139.                     receiveStatus(StatusEstablish);
    7 |2 Y$ H) O2 W, Q- P' N( y

  140. - S9 N% c8 z$ x5 U
  141.                     return CodeAck;
    ' M2 R$ V  z2 H& K  \
  142.                 }! m6 j( H# y- V! J. z
  143.                 else8 `8 T  d7 I5 f4 C4 l- k
  144.                 {! v, _0 T4 w, L' h* ^
  145.                     YmodemFileReceive::status = StatusError;
    * m0 v2 i) ~/ c0 G
  146. " s' S3 s9 l7 Z
  147.                     writeTimer->start(WRITE_TIME_OUT);* E( z% ~6 a9 z
  148. 6 K( Y5 _$ {, ?
  149.                     return CodeCan;5 w$ \. ~4 w' y3 y5 [
  150.                 }9 Y& H9 d+ f$ e' H
  151.             }6 `7 }8 k9 K6 C8 C: m
  152.             else1 Q  Y4 V' g5 b# n
  153.             {$ E; I, L) V" s9 J
  154.                 YmodemFileReceive::status = StatusError;/ N4 n7 M" U; m8 J

  155. ! @( c8 G2 f) E+ ~( Y8 K) X% }; d
  156.                 writeTimer->start(WRITE_TIME_OUT);6 ~8 n# v& o; k0 a( n5 c
  157. 3 g: W# G# C0 I5 ^- M& U7 V
  158.                 return CodeCan;  P  b6 o6 c0 V; x( o, u7 v3 @
  159.             }3 B; G( ]& c0 v8 r9 E8 S% U
  160.         }" S9 i: Z7 Z3 y5 j

  161. ' e4 \/ Y- W1 B% ?! e5 t2 I
  162.         case StatusTransmit:
    ! m* G, m' [# h3 e+ b! h
  163.         {
    2 V) [  f" P: l# S0 X& ~. H. d
  164.             if((fileSize - fileCount) > *len)
    & n6 M) |* Q) o7 ~- m
  165.             {/ D% r- ]( r6 m( f
  166.                 file->write((char *)buff, *len);
    1 ?- n: V; Z2 R4 Z$ E6 ?) E

  167. 6 L# w' v7 c4 m% y+ j! P7 D- N
  168.                 fileCount += *len;' M3 A& _$ ?1 n6 v# g
  169.             }
    1 j2 O, h6 E" d$ L% v
  170.             else
    / F& g" s, w4 z4 @; U% r; q
  171.             {( c1 z7 @4 G" c9 }" }2 |' S" K
  172.                 file->write((char *)buff, fileSize - fileCount);
    . v" a# p2 e, C, h! q1 v
  173. # P2 L3 Q. e3 L' N, |" w& l
  174.                 fileCount += fileSize - fileCount;' a5 |3 W. N7 i! B; [
  175.             }
    . u  C5 q# i* Q- k: _

  176. ; H9 F' p5 O9 ?& ~! V& t& F) O* l9 W
  177.             progress = (int)(fileCount * 100 / fileSize);
    * w: U3 p/ `: C5 C& {9 N

  178. " z* n) b) i0 v( c: B
  179.             YmodemFileReceive::status = StatusTransmit;
    6 [& r% i3 M! y( s4 H- {6 M

  180.   o3 Z6 ^, w- E! x# ^8 ^/ S& q
  181.             receiveProgress(progress);- x4 b0 J! ~; h# i! K  O& r& W
  182.             receiveStatus(StatusTransmit);
    0 a& S! O, G" X

  183. ( b7 h7 {# R& T
  184.             return CodeAck;7 t& n4 j0 |3 M) w
  185.         }9 X9 H7 u0 q5 p1 {" o: {# P) \

  186. ' J6 U! V9 r  M
  187.         case StatusFinish:
    / T) T3 h5 Y8 J" I3 h& L$ q
  188.         {
    3 A# O) M. |/ d) v# `0 m
  189.             file->close();
    # }1 Z; H# W4 P4 r! ?
  190. - W1 B; K9 G. J! O' q# l
  191.             YmodemFileReceive::status = StatusFinish;3 [* M: K: C3 Y( S
  192. * S1 a) h7 `! O$ e5 J
  193.             writeTimer->start(WRITE_TIME_OUT);! O/ s6 T9 I' \

  194. ) d, i& N) J) k( j8 \( G
  195.             return CodeAck;
    * e( A) l6 W3 n$ |4 ?0 e) K% \
  196.         }
    : F: C- O! k+ V6 S

  197. ) y" m8 z- h/ ?" C1 c
  198.         case StatusAbort:  o& p1 n  ?& t  ^) _) P
  199.         {0 K0 ~( d* m9 ]6 w4 o, S
  200.             file->close();) m1 \' c) h' \* p/ i
  201. - Y7 ~2 ~2 X5 o1 {- \# {4 m$ f$ z
  202.             YmodemFileReceive::status = StatusAbort;' j: s4 ?  S# S/ v% |- ~  h% w

  203. $ l# \) o- l' ^4 n1 G- X: a
  204.             writeTimer->start(WRITE_TIME_OUT);
    $ V% {! Y4 o: b5 S$ e6 q% A5 z
  205. 9 C6 f; ~) x5 d) e" C
  206.             return CodeCan;" w; B3 E5 r' E! L" B
  207.         }- L6 u2 r, G" \/ P/ r
  208. ) W4 D0 q/ r& ]# F( b
  209.         case StatusTimeout:$ u* p# `9 n8 v% T
  210.         {
    $ m( E3 N7 F' g
  211.             YmodemFileReceive::status = StatusTimeout;
    9 X& u; A. g6 Z% n
  212. 1 y3 [5 B  c, X6 S& T' A
  213.             writeTimer->start(WRITE_TIME_OUT);4 a3 ]& V1 `, d; L( U

  214. % \2 ]( |+ @1 \* ~
  215.             return CodeCan;5 j6 O9 o6 B' Z3 j5 y
  216.         }0 F: I; j" R8 {! ~

  217.   P7 I. f2 B0 o: o
  218.         default:
    % Q6 ]8 \5 b& I- K
  219.         {9 B1 R6 @% A& P4 H
  220.             file->close();: `+ Y& }( ?; L. |0 T5 A
  221. , J  ~$ A! F- X7 e6 L& N7 l
  222.             YmodemFileReceive::status = StatusError;
    & C! K  e/ ~( v, _4 x; Z- u
  223. ' H9 F" X; Z( F3 A2 t' ]
  224.             writeTimer->start(WRITE_TIME_OUT);9 t3 P9 m) x1 c& \, d

  225. 8 _# H, J/ z9 o6 U
  226.             return CodeCan;
    ' F! X- Z  Q3 p& K8 [, _# I
  227.         }0 c# l2 G% A8 p; T2 L# P
  228.     }
    3 w/ H- u4 M& V1 Q: I! \8 y) P. Z
  229. }  b8 `0 X6 i$ o5 l

  230. * x- F3 M: T% v! }5 [
  231. uint32_t YmodemFileReceive::read(uint8_t *buff, uint32_t len)
    & \% q6 g! P2 ?! c! y; B+ m) B
  232. {
    8 s# ?- u$ B: F: x
  233.     return serialPort->read((char *)buff, len);
    8 i6 N' f) @9 B# u. M- e0 {& Z
  234. }
    $ h) @+ ^1 }2 Z/ D$ F+ j/ |- y
  235. + q5 `( w/ c  n4 W: f( G. F* t
  236. uint32_t YmodemFileReceive::write(uint8_t *buff, uint32_t len)
    9 e' V% U! O" Q( A) ~
  237. {
    ! ^, G8 O8 L' h" S1 H3 R" l0 ^: E
  238.     return serialPort->write((char *)buff, len);& r, `) L2 a7 G3 J# v8 O( j
  239. }
    ) ]+ H! T& C$ m9 |7 g8 _
复制代码

4 h1 b1 U! M( d% ^( {. h0 l  w) k9 j. x, V* k+ z

! p6 g% m$ i$ s3 X
9 {: P8 H3 D1 p4 |- z7 }; l& C2 \$ @; m8 N# }! x9 ?# m
XinLiYF 回答时间:2018-3-6 22:31:26
      YmodemFileTransmit.h文件3 U1 i" ~3 ?" c8 u
  1. #ifndef YMODEMFILETRANSMIT_H- ]% U5 ?! d4 y/ w. C7 r
  2. #define YMODEMFILETRANSMIT_H1 I/ i  H" u3 p/ V0 E0 ]7 W
  3. . _3 }/ i! p7 }7 \9 K4 M' W# F
  4. #include <QFile>$ ^' r0 W2 n. m+ I1 D: B
  5. #include <QTimer>; s, _5 V. s* k; v, x' A9 X
  6. #include <QObject>
    % r5 ]! P5 v/ }) a9 z
  7. #include <QSerialPort>
    ' U! P7 ~( S: I) K; P5 @, {- s
  8. #include "Ymodem.h"
    % T4 g0 U4 z4 c7 O/ Z1 p
  9. 3 f" Z! q3 s' ?! I
  10. class YmodemFileTransmit : public QObject, public Ymodem5 S3 e! N) S1 a* \) d$ M. I
  11. {
    ( v. x2 m2 T9 Z' u* a7 f( M, D
  12.     Q_OBJECT
    % V  f1 I1 N7 v; D7 b/ b2 n5 C( V

  13. . O1 _& f. L/ n/ {3 l& \
  14. public:
    / y4 A6 a% }+ [7 S3 q" u
  15.     explicit YmodemFileTransmit(QObject *parent = 0);
    ' C. r) R5 ^1 I
  16.     ~YmodemFileTransmit();% _# i9 Q( m% Q( E

  17. 1 `' T$ I/ q, i6 U' K  b' {
  18.     void setFileName(const QString &name);
    . k# D+ w9 U$ Q3 v7 v1 ]

  19. # V0 S: o- O# ]% J( [% i
  20.     void setPortName(const QString &name);
      m' J/ L) v9 {9 K
  21.     void setPortBaudRate(qint32 baudrate);
    - `1 a6 _+ Y% J& B% |& J, N

  22. 8 }: m  l4 ]. m0 [- d0 Q
  23.     bool startTransmit();
    + a9 o8 r2 S4 Y" U4 N8 n# ?
  24.     void stopTransmit();+ e5 j( Q, \' U

  25. 1 ~3 I7 |/ m$ I) ]
  26.     int getTransmitProgress();
    / T! [+ S* E/ Y# |2 M- i
  27.     Status getTransmitStatus();/ t$ E, B  v2 Q

  28. ( f: @+ u+ _& q* f! j
  29. signals:' B$ P# z8 @# l2 \5 A
  30.     void transmitProgress(int progress);6 [3 E# r' A' {9 E) x7 M
  31.     void transmitStatus(YmodemFileTransmit::Status status);
    / o' X$ e- x( {/ W) R# V+ c' e

  32. * i( T8 }2 K# L
  33. private slots:
    7 V! |4 X$ C/ g& K5 c; ^' D# L
  34.     void readTimeOut();; s  [  }; C% r3 Q5 Z* T8 @* y4 C
  35.     void writeTimeOut();
    ) w. I) X# d/ O- e9 m. `- ?4 A
  36. . Q6 ]: r% x$ E, d7 X- P: L8 e
  37. private:6 p3 ~. X4 I7 j+ ]. ^) w0 z- {- o6 H
  38.     Code callback(Status status, uint8_t *buff, uint32_t *len);
    8 @! P5 B" o8 w5 x5 H

  39. # j; m6 w) {! A
  40.     uint32_t read(uint8_t *buff, uint32_t len);7 _1 N' ~! K, a
  41.     uint32_t write(uint8_t *buff, uint32_t len);
    - ~4 X9 C  l  Q' a

  42. & V! [0 A& s2 T8 }% M
  43.     QFile       *file;
    . h; ~7 g* [4 x, U' P
  44.     QTimer      *readTimer;- |' c0 J7 a! c* R/ z. n/ l
  45.     QTimer      *writeTimer;
    3 K4 h* @/ L! y) z$ A
  46.     QSerialPort *serialPort;
    ( u, }( f2 Y: o

  47. & y8 i& L6 [# C# ]1 Z) _* ^
  48.     int      progress;# D6 v/ p* |' ?4 t: ]' E9 \
  49.     Status   status;0 Q: r& P  [$ g! b- R1 b
  50.     uint64_t fileSize;% E: L0 }5 U8 R; ~$ X# V4 b+ ?# @
  51.     uint64_t fileCount;/ k1 L) K1 ~- W7 k2 g8 i' [
  52. };! v1 T# y/ L  o# E0 g% O, Y
  53. 8 A  Z' Z' t5 Z* g& x7 B
  54. #endif // YMODEMFILETRANSMIT_H
    * v; m; E3 B! D9 P+ I! }" ^6 J
复制代码
# Y+ M& h) _% O4 T
      YmodemFileTransmit.cpp文件% {# T. B9 _& N$ T9 J) S
  1. #include "YmodemFileTransmit.h"
    ! s& X% u+ ~6 d" ?  w& E5 [6 Q
  2. #include <QFileInfo>
    * K+ W1 u* g! R9 l

  3. 1 Z3 Q: @1 h$ Q' J' R
  4. #define READ_TIME_OUT   (10), P7 X/ b: A2 ?6 G  _
  5. #define WRITE_TIME_OUT  (100): ?! R8 N6 I) t+ V
  6. 7 ~: Y$ e& L' Y
  7. YmodemFileTransmit::YmodemFileTransmit(QObject *parent) :
    ! ]% f' t& i( o  R
  8.     QObject(parent),
    1 N7 L$ |; y7 I& \7 T+ A) ~# m
  9.     file(new QFile),6 N, d/ |. v9 [% t8 [' M7 \) \# b
  10.     readTimer(new QTimer),
    : V* B' W0 `9 P7 ~; q5 z8 [- j
  11.     writeTimer(new QTimer),4 _4 Q* F, T$ j! {3 r
  12.     serialPort(new QSerialPort)
    ; \4 s) i3 Q2 U! q8 F
  13. {
    6 a7 T( H, F$ p  {  b6 ^/ M
  14.     setTimeDivide(499);
    2 G) N9 F) M- Q6 s/ v& W' ]+ }
  15.     setTimeMax(5);
    - I9 w+ `6 w5 {* E8 u+ X
  16.     setErrorMax(999);; O$ G& g( d& F/ U$ A

  17. 7 b4 Y+ c* A; ~
  18.     serialPort->setPortName("COM1");9 c, h9 L1 C. ?
  19.     serialPort->setBaudRate(115200);! C/ |' x: P9 J3 C- b) h
  20.     serialPort->setDataBits(QSerialPort::Data8);" Y# E8 O' V$ {
  21.     serialPort->setStopBits(QSerialPort::OneStop);
    ) ]+ M5 q) N9 s2 `2 D
  22.     serialPort->setParity(QSerialPort::NoParity);& G" A0 N8 Y1 E; {! G; n
  23.     serialPort->setFlowControl(QSerialPort::NoFlowControl);
    + Q$ V- o/ u! {# J

  24. # Q% O# f* }+ D, g
  25.     connect(readTimer, SIGNAL(timeout()), this, SLOT(readTimeOut()));
    ' q! g$ o( M: C/ T5 ^; {
  26.     connect(writeTimer, SIGNAL(timeout()), this, SLOT(writeTimeOut()));$ d! k2 _  N% l
  27. }7 R$ |8 I) l6 Q" u% F
  28. $ S$ f) x$ o0 \" f$ J
  29. YmodemFileTransmit::~YmodemFileTransmit()# {& n: j- L# K& i
  30. {( u. {- {2 Z/ I  ]- a0 c; C
  31.     delete file;, k& a# C/ t3 X' V
  32.     delete readTimer;. r9 O8 K0 T" `7 O* U; m. _# `
  33.     delete writeTimer;
    ' \; L1 w( U' ~2 b, f+ x9 P
  34.     delete serialPort;
    . d2 Q6 R0 ^6 m0 k1 B/ z
  35. }8 P( v. w  `+ E8 m$ M; H& m

  36. 4 Y4 W* Z+ D& y+ a
  37. void YmodemFileTransmit::setFileName(const QString &name)) [7 r' W5 E  u) k* K! J
  38. {: [( E7 _7 T3 |8 O9 g0 V
  39.     file->setFileName(name);! D4 k! I& j5 D( |6 V5 @( ?& u
  40. }' u/ }9 w# |. Y. O. a0 q- N' W5 e- h8 {

  41. $ ]8 Z+ c7 [9 f, j, I
  42. void YmodemFileTransmit::setPortName(const QString &name)  \8 @; A* E- f  k4 ]0 O. ]+ L- r
  43. {
    4 h' V( Y. J, R8 V8 W; G3 b
  44.     serialPort->setPortName(name);3 E8 ]2 _: E+ n, D6 k$ q, U' w
  45. }
    1 \; p6 c  g7 z: l3 _6 [- k7 l, F( v
  46. 7 s6 j* P7 B3 \# R
  47. void YmodemFileTransmit::setPortBaudRate(qint32 baudrate)
    4 s/ V+ x; w! K/ X# N2 c
  48. {& i# O4 ?, ]& P( F# P0 o
  49.     serialPort->setBaudRate(baudrate);
    4 x! ^1 S; [- w& r% o; N8 N* w, n. j
  50. }6 N% j6 s9 Z+ }, s6 r/ W
  51. # n/ G2 W' W( J) U" D
  52. bool YmodemFileTransmit::startTransmit()
    . [2 L, A' y  ~2 g
  53. {8 v, I4 S/ d) Z; W- y& `
  54.     progress = 0;# [( |% l6 e1 {. l: i, f! V
  55.     status   = StatusEstablish;
    ' i+ Z# [. G% J$ v) K! x0 s
  56. . r& Y( i$ x' ^* [0 M! Y* {
  57.     if(serialPort->open(QSerialPort::ReadWrite) == true)
    " O! Y5 j4 V1 Z
  58.     {) V9 Z7 L. f- s& O# H
  59.         readTimer->start(READ_TIME_OUT);2 X; ]8 h* r4 r/ d

  60. ! W* M+ ~' G4 S; s
  61.         return true;$ k3 W+ `5 i/ f  E5 z6 c! Z
  62.     }
    2 ^1 }2 Q5 L: H2 `2 b
  63.     else
    & b6 ~+ V" m( z# ~: _) ]) {3 t4 J
  64.     {/ k' Q# L  u" Q* K% P: W% P" B
  65.         return false;+ N& S% l: r1 J. b! N
  66.     }
    * W( [, G. x# w. q) [7 L
  67. }! R3 k3 N5 t( l. y/ t$ _: W

  68. $ f% ~5 H0 {% A9 J: {# x0 l
  69. void YmodemFileTransmit::stopTransmit()
    ; F( B! j+ P8 C5 e8 M- }8 z. P
  70. {) s' Z+ f: h8 [" h0 V5 {5 }; h, E) v
  71.     file->close();% D; b& t6 W% C/ y
  72.     abort();
    5 Y! J7 E4 s  K$ o+ z( I7 u
  73.     status = StatusAbort;
    . L' Q. f( ]# a; T8 J0 N
  74.     writeTimer->start(WRITE_TIME_OUT);
    . a& A  h+ A" a3 b- p, p. W" g
  75. }2 X# _$ _# M% G
  76. * B9 ]+ K6 f% N% X3 O" d
  77. int YmodemFileTransmit::getTransmitProgress()
    - o+ g  u' ?: p5 A+ R5 E7 p  ]
  78. {
    ! J4 v4 l+ [1 X, }
  79.     return progress;3 A' T2 \0 y0 P' o
  80. }( c5 u' d7 v' K+ ]2 y" Y

  81. 4 Z7 z8 L* ^0 _
  82. Ymodem::Status YmodemFileTransmit::getTransmitStatus()0 u  ?& N2 I6 E/ p1 J
  83. {# L  I6 k  J: A/ j0 P$ o* T0 e
  84.     return status;- }4 X1 d7 [) C2 {! e  t
  85. }
    $ \( G' _5 s, c
  86.   K  D; G3 r& \0 @* ]! o
  87. void YmodemFileTransmit::readTimeOut(). B% C3 N, C: {$ y
  88. {4 A+ b0 ]4 f  ~- O. }
  89.     readTimer->stop();
    + r" N/ ^( P+ _+ D  b( J$ J* H
  90. 6 w4 b$ r8 f8 C* B7 Q; a, ^* S
  91.     transmit();
    , |8 Y- C  y' e! R
  92. + h6 [# Z9 d; E0 ~1 _
  93.     if((status == StatusEstablish) || (status == StatusTransmit))
    6 v  {8 v7 q; E: x! I) c
  94.     {
    3 Q) `3 U) z6 W8 U+ Q! i
  95.         readTimer->start(READ_TIME_OUT);! n% ?* `6 r+ g! o( B
  96.     }7 B8 |% X6 w0 k8 V1 D( J, m) E
  97. }
    ) J3 ?- u) B& L" m! }( |

  98. 9 |) S# \/ X7 N0 O
  99. void YmodemFileTransmit::writeTimeOut()
      G3 E( O( `! P2 v1 M" v' N! P
  100. {/ [- v* u  g; _. S: b
  101.     writeTimer->stop();( l# d9 Z0 f, O7 w
  102.     serialPort->close();+ L6 h; k' r$ C
  103.     transmitStatus(status);7 a8 X% L1 W9 j- R( F  D
  104. }6 e% p  J& h* \# ^

  105. % d  ~3 o0 y7 d9 K6 X9 q# n  v
  106. Ymodem::Code YmodemFileTransmit::callback(Status status, uint8_t *buff, uint32_t *len)/ Y6 `( W( ~! U  ?+ V: L
  107. {
    1 T2 p- k: A3 F2 f* r/ I4 N
  108.     switch(status)5 ^4 Z: B# v# g+ j
  109.     {, P* C% @9 u; G* o+ e6 L
  110.         case StatusEstablish:
    4 W: a2 \" N0 E3 X7 g
  111.         {8 I+ F: C0 L! j0 q
  112.             if(file->open(QFile::ReadOnly) == true)
    : s) V5 N( ]6 B( r
  113.             {
    ; y0 ?' J8 g9 T  T) v+ s
  114.                 QFileInfo fileInfo(*file);
    ( f6 u( ~6 u, Q& l( Y$ U
  115. 8 b# j! I6 |$ L4 m5 ?+ P; `7 H
  116.                 fileSize  = fileInfo.size();
    ' W4 @2 m, \7 Y1 m5 R. g3 w# x" O% Q
  117.                 fileCount = 0;
    9 ?2 O, D+ M; `/ p

  118. . B* j$ h* r3 j; \* g# d" b
  119.                 strcpy((char *)buff, fileInfo.fileName().toLocal8Bit().data());
    ) p; \* ?" x( X0 s- g, O/ ^% n
  120.                 strcpy((char *)buff + fileInfo.fileName().toLocal8Bit().size() + 1, QByteArray::number(fileInfo.size()).data());
    * v; }$ q% y3 D3 l
  121. & o$ C* q/ y' m& f0 N- O9 e: A* \; Z
  122.                 *len = YMODEM_PACKET_SIZE;
    : {  s% P$ L- \! j1 Z5 w! d% x
  123. / v  G: c1 U# {% W& O
  124.                 YmodemFileTransmit::status = StatusEstablish;
    5 [0 |- [, N, i

  125.   h  ?8 @0 O% ~5 r5 K
  126.                 transmitStatus(StatusEstablish);! _$ H6 u* F4 o# Z: j+ j, ^

  127. * }! z/ j% q7 M+ s9 n
  128.                 return CodeAck;
    * T8 ^1 W2 J: \/ @* L4 z
  129.             }
    % {/ r' I2 i; j
  130.             else# X' j3 o9 I* e4 @/ N2 }! s
  131.             {
    2 w! ?$ R: L7 x2 z/ f
  132.                 YmodemFileTransmit::status = StatusError;
    0 ?1 v1 G9 B$ E% U& Z

  133. ; H9 p/ @4 @; m6 ]" s% g3 L
  134.                 writeTimer->start(WRITE_TIME_OUT);
    . z7 E% G/ ^/ x6 ?, d
  135. . ^$ y+ J" }* j
  136.                 return CodeCan;. |5 p9 L' `6 h" Z) ^9 w* e9 p
  137.             }( D, S* @. w- M# j
  138.         }" X& ^% y  D3 }& c
  139. ) M9 b+ O% X; Z$ q4 C
  140.         case StatusTransmit:
    7 a6 _7 Q. ?7 O
  141.         {# d  L) H9 v! ~* X; t& n% {
  142.             if(fileSize != fileCount)3 [* e3 A+ m, B  ]0 w2 Q- d) a: ?# ~* E
  143.             {7 x8 q- n. k- A1 r" x/ F7 O
  144.                 if((fileSize - fileCount) > YMODEM_PACKET_SIZE)
    4 |# d- w+ L: p9 I& \" X
  145.                 {
    6 d0 Q2 {/ _; c2 B
  146.                     fileCount += file->read((char *)buff, YMODEM_PACKET_1K_SIZE);
    : N" _2 c" h2 y" j9 n, H
  147. , ~" |5 D) J8 i5 q
  148.                     *len = YMODEM_PACKET_1K_SIZE;
    6 }' `" c& l" j& }% }) `
  149.                 }- B! B& f* n# P) r# y. S0 R
  150.                 else( {+ C: D! Z- r& F
  151.                 {5 T* l2 t4 k) D6 q$ m# t
  152.                     fileCount += file->read((char *)buff, YMODEM_PACKET_SIZE);/ G7 N4 e3 `0 B) G
  153. & _3 A. ?2 H) T
  154.                     *len = YMODEM_PACKET_SIZE;
    7 r' ?- ~* I* m5 r( o. M1 t
  155.                 }
    % y) O: l1 ~& x' E4 A, m

  156. . v. T$ a7 v% B( W
  157.                 progress = (int)(fileCount * 100 / fileSize);4 f2 o) A8 v9 o" h! g" E
  158. 3 M* Y, Q' a# z( {
  159.                 YmodemFileTransmit::status = StatusTransmit;
    9 R- C8 c8 }: S6 X! u

  160. 2 u) g3 p* u  \* u3 D1 U7 ^6 ?
  161.                 transmitProgress(progress);
    , J( M) p: r* r- `* z4 T
  162.                 transmitStatus(StatusTransmit);
    ! v& {, A$ F) f/ q8 Y4 F

  163. 8 |! a4 u" x2 ?# W/ L! w
  164.                 return CodeAck;  d7 @: B8 C6 F3 k9 B
  165.             }4 W! o, n3 U( o- ?# {) b0 v0 \' m
  166.             else
    2 y* A- J- L6 T
  167.             {
    7 x0 i6 a0 n" r1 U" L1 `! P
  168.                 YmodemFileTransmit::status = StatusTransmit;
    4 q, @* \0 F& t; n& v

  169. 7 \8 d+ A% C8 f7 {; n) }' u
  170.                 transmitStatus(StatusTransmit);
    4 i6 g+ {; W8 ?4 k) ~0 d5 l7 C

  171. 5 }. ^1 c! Q0 O
  172.                 return CodeEot;
    ! G/ x$ X& I; e/ m8 B& V7 n
  173.             }
    ) J0 k" \3 v# q' R/ m
  174.         }" Y4 L! }' a% z+ J1 G: P

  175. 2 M3 y3 D, n9 t! F( |" I
  176.         case StatusFinish:
    ; X( b4 q6 z6 i4 o! l
  177.         {
    0 [3 \6 A2 r/ V
  178.             file->close();
    ) l2 c2 \0 H0 F; O/ _

  179. , d9 D" |$ P1 r' G( \% G$ _7 n% w9 X
  180.             YmodemFileTransmit::status = StatusFinish;
    : U  ?  ~* X8 P! Z, c+ D8 U2 `

  181. & D0 v* B8 H  p" h* H
  182.             writeTimer->start(WRITE_TIME_OUT);
    7 E+ `! `( e5 W4 U7 ?

  183. 8 ~2 _$ E: q" L6 j, z- I* T9 c$ V% D* T
  184.             return CodeAck;
    ; X) j( A' j+ R8 f0 ~9 \! E
  185.         }
    0 U$ c3 e4 q/ @8 e# i( M
  186. $ o# R, w; B$ I/ `0 j9 O
  187.         case StatusAbort:
    9 T8 w- H+ r0 W6 ?; g( b
  188.         {
      e3 c$ Q( i8 I( ]
  189.             file->close();
    2 e, v1 |" P$ u7 X) d

  190. - t& @2 |# ]! O* l  }" F$ M
  191.             YmodemFileTransmit::status = StatusAbort;$ M$ G4 k$ a) J# k3 c9 j, v( ^0 n

  192. ' w+ y  Y4 L! Q3 k* O9 j( G
  193.             writeTimer->start(WRITE_TIME_OUT);
    1 H  e5 W. H  a- [/ K: t

  194. ' G1 d* C$ C$ W, F1 w: U9 l/ j
  195.             return CodeCan;
    & C8 {* O) A5 @9 X4 j( A6 U' l
  196.         }
    2 k" I! S( i7 \( e$ T/ V0 `

  197. * e  N% k9 q( @/ \, O
  198.         case StatusTimeout:
    / k/ A5 C$ A& c/ ]/ ~
  199.         {& Z" u/ _+ l; C0 k  @: l
  200.             YmodemFileTransmit::status = StatusTimeout;9 F1 L' c$ K1 V" p

  201. + V- Q* J" n" e: ^
  202.             writeTimer->start(WRITE_TIME_OUT);
    , l! q" o% c  q9 _/ T
  203. 1 A8 n$ O. ^1 {3 d( u- U/ O1 R
  204.             return CodeCan;
    $ K- g" ~% ]' M
  205.         }4 x2 h! h5 c2 x
  206. ' A4 ^8 Z  Y" O; e3 E9 b, w# ]
  207.         default:( b+ Q2 E5 I( I' Y- i
  208.         {4 g4 ]! Y# s* ^
  209.             file->close();) B+ e) `- E& @' A' T. D3 c
  210. 1 m+ ~. p* j7 X9 A6 y" g  c
  211.             YmodemFileTransmit::status = StatusError;1 g- l6 I4 j+ ~$ `5 G7 s* t3 j" V

  212. " R& J$ o; f7 h2 w, d1 S/ C1 @
  213.             writeTimer->start(WRITE_TIME_OUT);
    : A/ E% p; f( `

  214. ) z1 u0 I( ~( W# x: C
  215.             return CodeCan;
    - B; ~% @, B2 F0 B
  216.         }' V! H) S9 ~; {4 n7 R
  217.     }
    * S- J5 R6 f! G# C& F* r
  218. }7 F& x# [4 L6 W3 O  N1 v0 Q# J
  219. * ~% t1 Q; |8 r6 d* }& K
  220. uint32_t YmodemFileTransmit::read(uint8_t *buff, uint32_t len)
    6 o! v0 r# o; h1 S
  221. {2 i3 @: }( \. [3 E" C5 C
  222.     return serialPort->read((char *)buff, len);
    . V2 }; }0 E+ R$ ^1 A
  223. }7 |" Q1 W# ?# E  R

  224. 0 Q5 T& _" M1 b+ a! p  a
  225. uint32_t YmodemFileTransmit::write(uint8_t *buff, uint32_t len)
    7 \! V, J( O- I
  226. {
    0 A% h  @+ }' `6 z1 I$ W0 k
  227.     return serialPort->write((char *)buff, len);6 g6 z" [0 ~6 I! i1 U: W
  228. }9 g$ b8 t2 c' J( b6 ?1 Q
复制代码

, @7 x: t8 ]% H1 Q( K' I  Y  a) [: ]3 c* w4 A  m* v
1 |& X4 b9 {! k& h: s: n1 p
7 X5 o, u  t* s2 K

: a& W  N8 [; T1 {
XinLiYF 回答时间:2018-3-6 22:32:05
      widget.ui文件- E  c) k$ Q6 U0 z& t
  1. <?xml version="1.0" encoding="UTF-8"?>
    : F6 `+ n% u7 S+ R# x8 U
  2. <ui version="4.0">
    3 X* H9 U8 r+ r5 K5 ~6 F
  3. <class>Widget</class>
    3 I5 U5 A  I& x7 p) ?4 p: X3 I0 k( ]
  4. <widget class="QWidget" name="Widget">( Z) k* W8 Q+ o* r0 |: D* v- P, _
  5.   <property name="geometry">
    3 n! G- F1 k" C" e
  6.    <rect>
    0 d. K0 T5 Q9 A5 j/ r* o7 _# M! o0 Z
  7.     <x>0</x>+ R& E6 ^- D, E- C' ]
  8.     <y>0</y>1 d4 R* M' y  R" J5 a
  9.     <width>444</width>& P9 i- a2 o7 r- `
  10.     <height>255</height>8 U. Y6 Z5 N8 T( H
  11.    </rect>5 U0 n9 y6 p* E8 [5 G
  12.   </property>0 @: m. b; r) `( A
  13.   <property name="minimumSize">
    - C5 }# a" T/ I
  14.    <size>4 ^2 v( [7 b# @  @/ i
  15.     <width>444</width>- [& @2 P& H6 c# y1 S5 d
  16.     <height>255</height>0 l5 V6 Z6 f% P7 _( Q; ?3 Q
  17.    </size>/ x1 }& n: M: _1 F8 e% p; J
  18.   </property>
    ) k& n/ _' r, c& Q+ ]
  19.   <property name="maximumSize">
    8 K$ M9 D# D9 S7 U9 P9 K! Q
  20.    <size>
    1 h) L; S5 t$ }6 X, p1 C
  21.     <width>444</width>
    ) k- N5 t( T: P# T) a$ d
  22.     <height>255</height>
    ! U7 H! h1 D2 _
  23.    </size>& z3 W% c1 x/ E7 y! R% q8 E- L! m
  24.   </property>+ Y1 X) J4 J7 x8 U1 @: I
  25.   <property name="windowTitle">
    2 G" z# `1 I  t
  26.    <string>SerialPortYmodem</string>5 s. ^& k: I& n: ?% }8 y# R
  27.   </property>" f% P) b6 o! W% z/ h  V- l6 B6 Y
  28.   <layout class="QVBoxLayout" name="verticalLayout_3">5 H$ `1 b( g* }- Q9 j. o  x
  29.    <item>
    ) |- `4 x" k& \6 H% J
  30.     <widget class="QGroupBox" name="groupBox">
    ) C' D4 h# e+ n7 t0 r8 G
  31.      <property name="title">2 E1 f9 C" }+ g7 N
  32.       <string>串口配置</string>5 z2 E" J& W$ b1 Z9 B
  33.      </property>
    & b  z, V! c! D- |; L( W" y: g
  34.      <layout class="QHBoxLayout" name="horizontalLayout">
    8 M  J2 j1 H/ G9 q# O
  35.       <item>5 p! m) v: _6 z0 Z3 _
  36.        <widget class="QLabel" name="label">7 v+ Q+ I7 X& B* B
  37.         <property name="text">' z; B9 r7 C- k# g2 `$ m  Z
  38.          <string>端口:</string>
    + q+ c8 j/ I( \& G! s
  39.         </property>2 i( c3 Q' U9 M* `; n
  40.        </widget>2 o& s9 |. q$ M/ K
  41.       </item>" V$ x9 j! ?2 e/ V/ Y3 k2 `6 J( L
  42.       <item>6 f8 A' B! S, Y* X" ]+ n
  43.        <widget class="QComboBox" name="comPort">
    ( d3 y( W7 _. i
  44.         <property name="maxVisibleItems">
    8 E# U3 a; P8 d( y3 L
  45.          <number>12</number>
    % g( U; Q. U% @% c$ R
  46.         </property>$ t! h& {1 c# S8 g
  47.        </widget>
    . f; v- _9 a. R5 V) E4 r& o
  48.       </item>! x) a; f' k" ?) a. `
  49.       <item>+ Q+ f; c" j: y$ n) R& L
  50.        <spacer name="horizontalSpacer">
    4 j8 r" e9 B4 r. S1 g2 P  A
  51.         <property name="orientation">
    " I1 f' T$ E' D7 N5 [. ?# H0 S9 q
  52.          <enum>Qt::Horizontal</enum>+ M- e, O& c* ^. V8 \
  53.         </property>
    # K0 d9 {* V1 u/ j. `
  54.         <property name="sizeHint" stdset="0">0 E, e& k7 V$ C0 u
  55.          <size>
    # D1 h0 t) Y( T' F
  56.           <width>40</width>
    1 k' @! e  `! w7 {
  57.           <height>20</height>* M0 {' x& n5 S4 f) J) p8 [
  58.          </size>
    ; E; x! Z6 R" l4 l
  59.         </property>8 Y8 d: O: [& i+ F" v$ V
  60.        </spacer>
    , z- g) ]4 e* j6 h' k4 s! o$ D
  61.       </item>2 A8 {5 Q& v6 r& b+ H
  62.       <item>
    / \% `  X- q7 I" r+ @' w
  63.        <widget class="QLabel" name="label_2">
    ! Q! l( [5 r  X- [5 p0 q
  64.         <property name="text">  P( x/ w  I) d* _
  65.          <string>波特率:</string>0 F8 W$ N5 |! W2 @0 P$ v9 p
  66.         </property>: M. ~* d/ x3 K# i  o' v, J# W# Q
  67.        </widget>& }% q& [9 d7 d4 f0 }
  68.       </item>: B$ z2 H6 X$ k* W
  69.       <item>
    6 i( f& f4 C8 W
  70.        <widget class="QComboBox" name="comBaudRate">6 R8 E2 _/ L/ L# d# u0 G% M
  71.         <property name="currentText">
    " B% p# L1 Q9 r2 c' i) y
  72.          <string>115200</string>
    2 b5 j8 C8 h; k
  73.         </property>4 K9 m- E8 k8 E! B* {
  74.         <property name="currentIndex">3 x$ m- C- A- F7 I
  75.          <number>3</number>/ {! N& b; ?! b5 x3 N
  76.         </property>8 P# X0 L. X# r1 g* o
  77.         <property name="maxVisibleItems">* p+ p6 E& w! F# b
  78.          <number>12</number>4 c! W- y- s$ N+ x7 e0 H. D
  79.         </property>7 _) v) n; d! ]; t( ~& J
  80.         <item>
    $ l3 l6 f0 G: \
  81.          <property name="text">
    ; g% _5 A) X9 F& `; l7 ?
  82.           <string>921600</string>
    ' U+ S. }) k) ^: ]* y. K. q* T
  83.          </property>1 F* I0 [7 K- A6 ?5 M
  84.         </item>
    ( r# d5 E) o" M& ]( D% |- U' b4 `$ \
  85.         <item>
    6 C/ j7 t4 z' `" P* g
  86.          <property name="text">
    . W0 O( D- T% n7 Z
  87.           <string>460800</string>
    4 L3 t5 T, H3 j0 ~9 i
  88.          </property>
      s. m3 {. G6 ^* e8 R* F5 x, H
  89.         </item>
    + Q# `% B9 e2 ?- E
  90.         <item>+ n3 p% o. {; ^
  91.          <property name="text"># N' m- R* Y5 j) \2 f
  92.           <string>230400</string>$ j( O/ z" g. {9 y$ h$ \
  93.          </property>
    4 r1 b1 g% P" O7 w& F( Z
  94.         </item>
    2 y+ n$ P. S4 ^6 l' J8 S, |9 Z# T
  95.         <item>
    / g- ^$ {& y' A) j0 P7 E/ y" G
  96.          <property name="text">
    : w" ]) U1 d: Y+ ?3 T7 f
  97.           <string>115200</string>
    # H2 F) e( r- j0 w4 p
  98.          </property>
    ! z6 v* U% x" p% `1 t, C
  99.         </item>
    ( H$ v1 q& U  @3 `" J
  100.         <item>8 f, {" K+ Q. Z, _) j; C
  101.          <property name="text">5 C( Z/ Q/ u  E2 V, R2 p2 g% x0 M
  102.           <string>57600</string>
    ( e( l# K3 `9 I# `& I" P
  103.          </property>
    4 Q$ z& M6 o+ U: q" v4 E
  104.         </item>( V2 ~; Z8 Z  H  B7 j; Z& @: u3 U
  105.         <item>
    % v" o& b) f6 ^3 K; i  ]
  106.          <property name="text">
    8 y/ A" C, X% _. u9 A* X8 M
  107.           <string>38400</string>4 ]  ^9 P3 g  X9 p( Q
  108.          </property>6 P" S, B. u6 ?
  109.         </item>7 _* q  k, R$ `7 k- O# `
  110.         <item>
    / o+ r' p- U# Z+ j. j* q* T
  111.          <property name="text">
    9 o& F+ M# Y1 [) m% [
  112.           <string>19200</string>
    7 f9 o* a5 C: |, }( j3 `
  113.          </property>. ?7 m. t) a  A3 r# W3 S7 P: x6 o' c  Z+ q
  114.         </item>
    . N* B( l4 r0 C4 C
  115.         <item>; Y9 G/ t* x2 s" G  `. l! [
  116.          <property name="text">" @% |. \; S/ F
  117.           <string>9600</string>" K7 O8 r5 w# _
  118.          </property>
    4 x1 f- C0 C4 l1 [
  119.         </item>
    " Q3 p' y2 z9 y3 C* s9 N
  120.         <item>
    ( s& y' N* R- _  m" X" U" b/ N" e
  121.          <property name="text">
    & w5 `% ?0 M3 i6 x# u1 G9 o
  122.           <string>4800</string>2 f' v/ i3 g4 i" Z+ g- b( `5 M
  123.          </property>0 |  B* Q8 M8 O3 g# R
  124.         </item>
    : y* v  v, V2 ]
  125.         <item>
    * o5 W; \! R# A
  126.          <property name="text">
    ' U* |/ n, c& \2 u( q  ~: F
  127.           <string>2400</string># T3 s' L3 K1 u4 `
  128.          </property>6 w$ ^1 ?- v% b+ @7 E4 f
  129.         </item>
    $ s( J/ Q  W$ a" @9 l6 y- e. E( w& @
  130.         <item>
    3 |5 N( ]! [  }3 b2 p% T) Z+ J
  131.          <property name="text">
    ' D) c' {+ \( z2 h" \. @4 Q
  132.           <string>1200</string>
    5 B$ i0 v* s2 s* r+ [
  133.          </property>
    4 V) u( ~8 i. ~/ s& J
  134.         </item>
    " U# K; _+ D! L$ V/ |- K% i( a
  135.        </widget>/ W! C: n: {# z- D" `& y
  136.       </item>+ Y# {+ O0 T) E% c: a# ^
  137.       <item>
    ' l9 z7 [( e- j- I
  138.        <spacer name="horizontalSpacer_2">
    9 b* _7 \$ x4 t% R5 G4 \
  139.         <property name="orientation">
    ' K& ?7 _0 x+ l! F
  140.          <enum>Qt::Horizontal</enum>" e2 ]2 Y+ l' ~) Z% K
  141.         </property>
    7 S9 I& R7 K3 r0 ^. ~% n6 E
  142.         <property name="sizeHint" stdset="0">
    # Q( ~$ n" k' h: b$ S7 p: f) K
  143.          <size>
    # L- a% D' _" t0 ~. |2 C
  144.           <width>40</width>
    ; q( o, A1 l( m7 n2 J' {! \9 K7 m
  145.           <height>20</height>) t$ ~- P, b& T, m1 t1 O, v
  146.          </size>2 Q+ T! q. D" F/ l+ j
  147.         </property>
    5 t/ d% n* @$ ?! ?! k* `
  148.        </spacer>' ]6 W; f5 G" t
  149.       </item>2 n! R# e; [  r* Z/ @6 Z
  150.       <item>
    + g. M9 B; g- W
  151.        <widget class="QPushButton" name="comButton">9 l! Q0 |8 u. {# U
  152.         <property name="text">( x# l* N8 a. M9 O
  153.          <string>打开</string>: U0 K8 n1 _$ q- |" q& b% }
  154.         </property>1 p  n/ ~) Z7 p& C. }% |7 @+ b
  155.        </widget>' z8 F7 Y2 f/ o: b" U
  156.       </item>' `- D) e0 F2 }& |
  157.      </layout>, w$ d, J9 H) H9 `
  158.     </widget>% K  m; \, Q; M' A; l# K9 ~
  159.    </item>
    * z5 f) `, ]% Y! G0 @7 x2 v. v
  160.    <item>
    " V. r4 C8 t/ Y4 p$ i1 N$ T) c
  161.     <widget class="QGroupBox" name="groupBox_2">' Q) i2 A0 A! f  U
  162.      <property name="title">2 h+ E% {+ ~; `8 r$ D
  163.       <string>文件发送</string>
    ; F* x& }- ?) ]8 i
  164.      </property>
    . |; ~0 B0 n1 Q' \/ p
  165.      <layout class="QVBoxLayout" name="verticalLayout"># _' a) k, K: r8 S9 {, n+ A
  166.       <item>% p* U+ M& A0 z$ f
  167.        <layout class="QHBoxLayout" name="horizontalLayout_2">- y0 x' V: Y, @3 Z" E8 R7 u% e  |
  168.         <item>& J- ?, c* ^$ N. H4 d* I6 q  l
  169.          <widget class="QLabel" name="label_3">" Z, a$ Y. u! M# ~5 u
  170.           <property name="text">) d; V) O1 ~# G7 V! ^- s. G" d. J
  171.            <string>文件路径:</string>
    + U8 o( w  {/ k& _5 O* E
  172.           </property>
    8 s, x/ ~9 T* M
  173.          </widget>
    2 ~% X3 t9 E3 g/ E4 G
  174.         </item>- h9 R3 ?, Z% l* {! b# A
  175.         <item>8 `3 o# B0 r- S" R4 b
  176.          <widget class="QLineEdit" name="transmitPath">
    5 {" z/ M2 P+ p" U# z5 T# t
  177.           <property name="readOnly">- T- J8 Q* _6 M9 l" _+ k3 @
  178.            <bool>true</bool>
    , M4 x0 r4 U* q) c+ R2 ]# b
  179.           </property>' s; U7 o0 Q. {% E' I  q/ |( S
  180.          </widget>/ M. _+ u: [9 S1 k) X0 F1 i
  181.         </item>% M! b, j  I& l! x/ N; s
  182.         <item>
    ! H* u9 Z9 d# w7 K+ J. M
  183.          <widget class="QPushButton" name="transmitBrowse">
    : ^) L9 g; y# r
  184.           <property name="enabled">' C' B- n$ k0 ]$ B
  185.            <bool>false</bool>9 o! [* ^3 g% J$ a( p" j
  186.           </property>8 D8 C6 b7 s( i: X+ R! z* s
  187.           <property name="text">
    6 F% A% {( u" k( ?3 Y4 |
  188.            <string>浏览...</string>7 i9 w: s* t3 ]9 O  i+ F
  189.           </property>
    0 J8 o) d3 L+ r& x1 V$ F
  190.          </widget>: q8 W, Z  @& Y. K
  191.         </item>
    " }* j' }! e5 z
  192.         <item>
    . M! L; f3 b  Z" p8 i- V
  193.          <widget class="QPushButton" name="transmitButton">
    - f) J3 S8 b( W$ z% D7 ~
  194.           <property name="enabled">4 S) Z3 G$ [  v
  195.            <bool>false</bool>7 x& y6 i/ X; |9 V6 S, X
  196.           </property>
    3 i2 i: O$ p0 N5 g
  197.           <property name="text">
    # U  ]: A: x( `2 r( ^7 W
  198.            <string>发送</string>8 _2 ^& ]' x% z' @' s6 H0 I
  199.           </property>
    5 B2 ?) F3 D4 O/ K/ R7 a5 G6 c
  200.          </widget>
    # o! Z: `1 B# t7 P$ b, k8 {
  201.         </item>3 V/ }- i5 B* D' ^, a7 X& i
  202.        </layout>7 n- C  V8 H2 }+ r) Z7 {
  203.       </item>
    1 J  `$ ?1 f8 F; |% C
  204.       <item>
    2 Y% Q) d1 `+ D& q9 R# _( w* p
  205.        <layout class="QHBoxLayout" name="horizontalLayout_3">9 \3 h1 O4 v" O2 z
  206.         <item>
    " }  \: j+ @, b! h& d1 v
  207.          <widget class="QLabel" name="label_5">
    5 ?$ {$ s( y" x
  208.           <property name="text">
    : {) R2 K0 U4 j! z# n* ~0 e0 u
  209.            <string>传输进度:</string>
    0 l" y! d8 c/ T$ ~
  210.           </property>
    & U, o4 [& X# D: X. z1 N
  211.          </widget>
    * m3 m4 z4 h: N  V
  212.         </item>
    * R9 Y8 L. W( q0 Q- j  v  b5 e( N# R
  213.         <item>" l9 ]6 s+ c7 z) L' V2 k/ `/ n
  214.          <widget class="QProgressBar" name="transmitProgress">
    0 K3 X+ Y  q: @" ]. s0 y
  215.           <property name="value">; r  U  t( T4 r+ t
  216.            <number>0</number>, @4 T5 H3 O4 g  z5 i
  217.           </property>
    ( x; f9 Q6 N$ L2 c1 ^  N
  218.          </widget>
    # k1 I& l( i' u1 M
  219.         </item>& F6 [& l! j+ e' ^! L( W1 g
  220.        </layout>
    ! _* v; }  M6 w$ b3 R$ b
  221.       </item>( k5 Y) C# w% U
  222.      </layout>4 I1 X# Y8 ~/ r  y* o* c9 F8 k
  223.     </widget># ^+ v# \! [* Y+ T6 G+ e
  224.    </item>; d. Y2 W" t+ P4 l! m" i+ c, s% r
  225.    <item>
    2 t. A( ?, P8 Q( n% X3 H
  226.     <widget class="QGroupBox" name="groupBox_3">, [; N7 u, S9 v0 i. b; b
  227.      <property name="title">. X! ^0 E2 L3 f- H/ e: W7 L
  228.       <string>文件接收</string>
    ! F) j, F/ e8 Q* Q! \
  229.      </property>( `9 n) H: L* I/ `' K: J' O
  230.      <layout class="QVBoxLayout" name="verticalLayout_2">
    4 n5 ~5 F' O& A& x, A
  231.       <item>
    , r: p# E* Q6 A4 m. T
  232.        <layout class="QHBoxLayout" name="horizontalLayout_4">( @7 }0 e3 s' _# X' z3 l
  233.         <item>
    0 z5 `% w- m/ X+ h7 P' ~
  234.          <widget class="QLabel" name="label_4">0 H# I# q: `% w( `2 }
  235.           <property name="text">
    9 X6 a) h; T1 g. K
  236.            <string>文件路径:</string>
    " J% M4 w  r* H2 a5 f
  237.           </property>
    , h1 m0 p! Q' ^3 i5 O3 J4 `
  238.          </widget>
    , c& W3 S! n" N  V5 `# D9 ]
  239.         </item>& N2 f6 z+ H+ u( V& b9 a7 A( g6 t. p
  240.         <item>
    # B5 g  u, ~9 z
  241.          <widget class="QLineEdit" name="receivePath">
    9 V* k2 }! G" {7 A: F- u
  242.           <property name="readOnly">
    ) ?" I  u' E# [/ `9 I% g! K
  243.            <bool>true</bool>
      j% `4 H0 L9 G; R% v% \5 B
  244.           </property>5 @* v6 Y! Q0 t' F: T% H% L" q$ e
  245.          </widget>5 c7 x/ ?+ k0 I  F: `4 W7 ~
  246.         </item>/ }1 K9 p' l9 p8 B$ ^
  247.         <item>
    & N& f) {( D1 m' `
  248.          <widget class="QPushButton" name="receiveBrowse">- P/ i  @6 _0 W
  249.           <property name="enabled">9 z3 _  l7 A1 l9 `; b
  250.            <bool>false</bool>9 H# x$ w/ K2 e* y& m: B! o
  251.           </property>
      c( ]6 n* d1 s4 _3 o3 Y
  252.           <property name="text">
    4 a) ~# d- E* o! i: m- P# W: k
  253.            <string>浏览...</string>
    3 a' a: L% A  h
  254.           </property>
      Q; z5 ]9 U& }* i  N1 a' a
  255.          </widget>
      m' w1 W  ^: q8 m# H/ O  w
  256.         </item>
    3 Y! D2 F- G2 _6 O4 [
  257.         <item>  A, P5 c0 c  L" _! u* K
  258.          <widget class="QPushButton" name="receiveButton">
    - d" y' d+ E8 |8 ]
  259.           <property name="enabled">  \  t3 b  q/ b. \
  260.            <bool>false</bool>, K8 B8 N+ v6 K$ S9 N6 J  ^" b7 e
  261.           </property>
    4 V8 n" x( P. ^  f- X$ n6 B
  262.           <property name="text">
    6 Z: {5 B- b& S2 t2 U
  263.            <string>接收</string>- M4 \: Y, K/ d8 O
  264.           </property>* E: ?# e+ G; a. {% J
  265.          </widget>9 s2 y; C6 E) o  e- m
  266.         </item>
    4 e4 y' f* e4 W) @( T5 h
  267.        </layout>2 C2 d7 M8 r) C5 G: U
  268.       </item>
    $ X9 d+ I3 y/ A& `9 O  r
  269.       <item>
    : k4 k: c. G0 q' P
  270.        <layout class="QHBoxLayout" name="horizontalLayout_5">* i, E# S' o5 }" I2 @7 E1 b
  271.         <item>
    ( M5 U& h, S$ S
  272.          <widget class="QLabel" name="label_6">) m+ D$ `. F+ K9 w' y* ?
  273.           <property name="text">
    ) @9 a2 B4 A5 p; e8 p4 d+ g" T
  274.            <string>传输进度:</string>; N7 U. I/ x. Y6 {" `7 b
  275.           </property>
    3 t, c" l) s1 W5 Q
  276.          </widget>. z4 l" N# a- u$ x2 P
  277.         </item>
    . Z  b! ^1 }8 w, E/ r% Y# C0 d2 W7 F4 _
  278.         <item>
    $ Y/ r: w' g+ h/ K
  279.          <widget class="QProgressBar" name="receiveProgress">
      g3 Z) u: a# D8 n) |7 G
  280.           <property name="value">
    ' m! B7 ]9 i& ^) v( [
  281.            <number>0</number>
    & F! \( o0 k" k' t# m5 u& G
  282.           </property>; |# U- F+ _- D- i# X, }: s
  283.          </widget>
    2 l$ m6 \( L5 D/ x/ K; h
  284.         </item>* ^* n/ Y5 V) K" h
  285.        </layout>! N' W# H3 M" u& p
  286.       </item>
      l  ~. \3 b) D. m% F
  287.      </layout>$ l+ h6 I) k( r6 |' K3 I( z: X1 a
  288.     </widget>  f+ c1 S2 g* Y' M  M
  289.    </item>5 p$ T, \. `* F0 y4 |+ e. G
  290.   </layout>
    : c) U7 Y- ~6 T% u* _
  291. </widget>
    ; y2 D2 O  T6 d/ O; A6 Z2 l/ L) k, |
  292. <layoutdefault spacing="6" margin="11"/>
    6 ]: s1 X, Y8 i) v
  293. <resources/>
    , o* |8 a$ B5 N% K% @
  294. <connections/>
    1 s7 N" }: s( F* a) G* r/ x& l7 E3 [( S
  295. </ui>8 F8 G1 j+ r7 _. l" N
复制代码

* |! m8 c! b' u5 a8 w, t# y" H      widget.h文件
4 t2 b9 H) t4 X. z+ u% _4 ~
  1. #ifndef WIDGET_H
    . q, L: y  J6 {0 P* q, H5 o
  2. #define WIDGET_H
    * m0 \' |, [( A, m, U( s! x3 i
  3. 4 Q; D) @6 [  U( x! l& r! e
  4. #include <QWidget>) Q- O; U0 u1 [9 w
  5. #include "YmodemFileTransmit.h"
    6 j# x4 ]9 C$ G: i% U4 b% C
  6. #include "YmodemFileReceive.h"
    - t4 p1 k; b9 I* T- _$ s
  7. ) f. t4 m- [; Z( k8 _
  8. namespace Ui {# N1 w  S7 v/ Q- p
  9. class Widget;
    ! q" B+ d' r- s& r: p' h$ E* z
  10. }3 h9 ~8 w! V# a% R) l8 W

  11. ! Q/ B+ {+ B1 j5 a1 s8 h
  12. class Widget : public QWidget4 x" S) j, L. }! }$ O
  13. {
    1 M$ h* c0 {8 z0 \3 l8 A0 l; @1 Q
  14.     Q_OBJECT
    $ R/ ]; c6 \. ?) i8 n* I

  15. , M$ I9 s2 x& S- N
  16. public:5 _: o3 h$ Z+ `" p8 K- R
  17.     explicit Widget(QWidget *parent = 0);  O9 q# f6 @% A
  18.     ~Widget();; F- t7 H" J# u$ s  h# I- w3 l

  19. 9 a8 |* s4 R7 n8 E! h
  20. private slots:+ A# P5 F5 \6 D  Y3 W+ h: m$ X7 R/ Q
  21.     void on_comButton_clicked();6 h9 ?# r! H# D% L0 V
  22.     void on_transmitBrowse_clicked();2 s- [1 Y3 y4 G7 T% w
  23.     void on_receiveBrowse_clicked();% y& L* M/ _) N$ i6 m  }9 N
  24.     void on_transmitButton_clicked();) Y' ~& I0 ^4 R. ?: r- L, S
  25.     void on_receiveButton_clicked();2 z; y/ G$ A  ]! d
  26.     void transmitProgress(int progress);1 J$ a3 v- x( u2 C, a2 @
  27.     void receiveProgress(int progress);+ ]$ T# e/ E. }" N3 m, [, L, L8 f- ~
  28.     void transmitStatus(YmodemFileTransmit::Status status);
    8 A2 Z) e1 }, \$ }" Y, l4 g
  29.     void receiveStatus(YmodemFileReceive::Status status);1 z5 i! z0 F+ p: `- C- T- c) V
  30. 6 @  i2 l* Q- }# W# E
  31. private:
    8 M2 @8 J+ @# p( y
  32.     Ui::Widget *ui;
    ; H5 Y6 A* S6 k' B1 H. s( i
  33.     QSerialPort *serialPort;/ J. J8 d: o+ U' u
  34.     YmodemFileTransmit *ymodemFileTransmit;
    : ?* ?: p7 r8 W  q
  35.     YmodemFileReceive *ymodemFileReceive;% i) V1 q& z7 i& B3 n5 Y

  36. " |8 ~3 Q9 n: I$ F: ?& F) w7 G8 G
  37.     bool transmitButtonStatus;
    3 V$ }. n/ S0 @# I
  38.     bool receiveButtonStatus;
    + Q3 p* f. o8 f+ r
  39. };1 Y% F; O7 e6 S0 x! y* n0 z3 U

  40. % t# z# U0 d' r' w' k# G% v' t
  41. #endif // WIDGET_H
    & N0 r- [; Y* x: y
复制代码

4 ~1 W5 x0 L8 {2 L5 Q      widget.cpp文件
+ o+ M. c) Z/ r; l3 Y8 G
  1. #include "widget.h"
    * }/ i) L  q6 q; [" k) p3 o- ~( a( }9 |
  2. #include "ui_widget.h"& y2 X0 H# _3 y. S4 U: o# ?
  3. #include <QMessageBox>* p+ ^% ?2 i3 T  |
  4. #include <QFileDialog>3 T) E2 G! K4 ]; F7 H* n# V$ M
  5. #include <QSerialPortInfo>
    ( T3 e; U* q: B( w: D1 g) g
  6. . n% Q) S4 M8 Q; ~
  7. Widget::Widget(QWidget *parent) :
    " G4 S2 k$ V% k3 Q! ^. h8 Z
  8.     QWidget(parent),
    8 r( n' B9 p  f4 r
  9.     ui(new Ui::Widget),
    : N9 h# j; `  h* T
  10.     serialPort(new QSerialPort),5 z. z' P/ v( \; }3 u) s
  11.     ymodemFileTransmit(new YmodemFileTransmit),
    1 H( [7 @2 T* E( G5 j! W2 Y/ `7 z
  12.     ymodemFileReceive(new YmodemFileReceive)/ p2 I* a( F, ~' `5 G
  13. {
    ; z9 y1 |% g2 Y3 g, _" ?
  14.     transmitButtonStatus = false;
    7 V: j; B- Z& o9 a! I
  15.     receiveButtonStatus  = false;8 }0 w- @- ]& q# w. n( |
  16. 4 p5 H; c/ C& l; n
  17.     ui->setupUi(this);
      q9 K5 P; [1 q

  18. 9 W: v" p0 z: s9 a7 j. W
  19.     QSerialPortInfo serialPortInfo;% M+ i" [, L9 C+ [% J5 f
  20. 3 j' e4 e  C) X& C* x
  21.     foreach(serialPortInfo, QSerialPortInfo::availablePorts())
    / L4 v5 W* Y6 g
  22.     {
    , Y- @& L: d7 s5 c; @
  23.         ui->comPort->addItem(serialPortInfo.portName());$ n; W) s( f# D
  24.     }
    " L, w5 {9 g. s2 |. n

  25. 9 B" [1 n; r3 v: ?1 |
  26.     serialPort->setPortName("COM1");
    7 a# k# `5 ~( L& K1 h0 F8 s2 B
  27.     serialPort->setBaudRate(115200);9 z( m! B7 u* F+ j$ S" y' P  f3 w
  28.     serialPort->setDataBits(QSerialPort::Data8);9 J. x( V$ w. K4 n& D! p- \
  29.     serialPort->setStopBits(QSerialPort::OneStop);+ F2 R% f; e. ?$ H% d
  30.     serialPort->setParity(QSerialPort::NoParity);/ G: @, C) U' S8 U
  31.     serialPort->setFlowControl(QSerialPort::NoFlowControl);
    ( I) j" a3 h( ?  m# _
  32. % m' N2 X5 G0 \% \/ ~
  33.     connect(ymodemFileTransmit, SIGNAL(transmitProgress(int)), this, SLOT(transmitProgress(int)));
    4 {" p8 a8 a, N/ h- E# i
  34.     connect(ymodemFileReceive, SIGNAL(receiveProgress(int)), this, SLOT(receiveProgress(int)));
    / Z( {; Q- ~8 h

  35. 2 S4 R+ e2 X$ i
  36.    connect(ymodemFileTransmit, ; L) l' I5 Y" w/ J
  37. SIGNAL(transmitStatus(YmodemFileTransmit::Status)), this,
    / V1 ^3 t5 b+ v# c
  38. SLOT(transmitStatus(YmodemFileTransmit::Status)));+ B  y6 Q3 @* n" X& r
  39.    
    & Q0 R3 o2 A5 ]' G
  40. connect(ymodemFileReceive,
      Q( s9 A+ S9 U# A
  41. SIGNAL(receiveStatus(YmodemFileReceive::Status)), this,
    - C( x1 W  N# `  \  F; z/ S, N
  42. SLOT(receiveStatus(YmodemFileReceive::Status)));
    ; G% H: W6 r  s
  43. }
    " ]1 E5 I' b; Y/ k8 J; B- z

  44. : A" e7 m! _! r, t. w5 Y/ J
  45. Widget::~Widget()
    & _: b$ D, x0 d' J/ d3 Y
  46. {* q2 o/ k6 \6 Z6 R4 ]6 _0 p
  47.     delete ui;
    7 V& u7 Z1 i) K- n
  48.     delete serialPort;
    ) k( A/ Y, a; O; N+ A$ l
  49.     delete ymodemFileTransmit;$ Y9 J' H6 Y# v  G
  50.     delete ymodemFileReceive;, _8 f$ j# d% v+ v5 k1 N) ]
  51. }
    0 O7 c# _: q# O$ ?9 I

  52.   C( i9 {$ K" R+ A1 |4 X0 N
  53. void Widget::on_comButton_clicked()
    ; m8 r( V0 i* o! r# O
  54. {
    7 {: N" C  G" w. `' y
  55.     static bool button_status = false;
    + @8 s, g1 Z! ?1 t/ U& \
  56. : w$ o$ |5 K8 A9 g2 m( h6 c4 f
  57.     if(button_status == false)/ U  i/ u# w2 f  e8 p
  58.     {
    # F5 U; `) u- r9 L# E, e
  59.         serialPort->setPortName(ui->comPort->currentText());8 }5 p: K* x& H- ?7 d9 n, I
  60.         serialPort->setBaudRate(ui->comBaudRate->currentText().toInt());
    % v9 [+ I. F$ G$ W; H

  61. ' [( F: S) ~7 k
  62.         if(serialPort->open(QSerialPort::ReadWrite) == true)! p% d" D9 g( ^2 v+ i+ P, P
  63.         {
    / Q, }& \$ v* z, E- s
  64.             button_status = true;% ^5 p5 ]/ q5 [* v& i- j) i" p4 U
  65. , b' q7 [4 W8 U& C/ E1 o% m
  66.             ui->comPort->setDisabled(true);+ t2 G' R/ F' O+ n
  67.             ui->comBaudRate->setDisabled(true);
    ' g4 a+ e$ r$ g5 c* P
  68.             ui->comButton->setText(u8"关闭串口");/ S# t/ S) @( U

  69. ; |$ n6 A2 k' W( X4 j
  70.             ui->transmitBrowse->setEnabled(true);$ f4 \% V4 V. Q% x2 T
  71.             ui->receiveBrowse->setEnabled(true);. v$ m7 G+ L. W- E7 [2 k" S' `

  72. $ o/ ]9 M0 ?! E$ C+ ^
  73.             if(ui->transmitPath->text().isEmpty() != true)
    ) f# B; v( l3 M
  74.             {
    5 ]% ]: O& `3 S$ o
  75.                 ui->transmitButton->setEnabled(true);" d' R& X6 }! z/ i: K. E# s) q
  76.             }
    $ o$ d& r9 o9 C0 r
  77. + E% x5 ]% \" P. w( H
  78.             if(ui->receivePath->text().isEmpty() != true)
    5 h3 N5 [; }. \4 ]; c) g
  79.             {
    3 k( N, n4 o! T7 Z& h
  80.                 ui->receiveButton->setEnabled(true);4 R- J7 f  N* z! `
  81.             }
    * r6 h5 m+ }2 Y6 `/ Y, ]$ @
  82.         }6 U3 U: _6 d$ t3 b1 [+ H' N' j
  83.         else
    % d; @  l* h+ d: o' a$ q  z
  84.         {
    . W% ~6 [3 o- q+ l- [( C- u( d
  85.             QMessageBox::warning(this, u8"串口打开失败", u8"请检查串口是否已被占用!", u8"关闭");( U5 w- B! O6 }% T* @5 v- ?$ J% p
  86.         }
    3 S; }3 [7 o$ M& `+ F
  87.     }$ E8 h  ]$ j+ s$ p4 ?
  88.     else
    - f  l% f' l9 X% c8 A5 g2 X
  89.     {
    ' j( r1 P  _9 a* k& g$ L) ]2 U. @
  90.         button_status = false;
      V& w% K. j# f" a/ h, I! ~* a

  91. ! D9 B. T" w% d* {0 _/ p$ O
  92.         serialPort->close();
    1 U  c) V( }; T1 S, A/ G( U
  93. 0 m- S8 Q! R' }5 s
  94.         ui->comPort->setEnabled(true);% E* T* k$ U$ o% |) q6 ~) E6 t1 ]4 K. s
  95.         ui->comBaudRate->setEnabled(true);) e4 P- T- `0 u" h! }# W
  96.         ui->comButton->setText(u8"打开串口");
    ! j% V# A! B# i. h. j

  97. 6 A( Z' F; s8 ?* w$ r
  98.         ui->transmitBrowse->setDisabled(true);/ R$ e* K, E/ Z9 W3 V
  99.         ui->transmitButton->setDisabled(true);4 F" ]7 [5 h4 w) ~9 k( f
  100. , H) T/ r% q9 }, Z) l
  101.         ui->receiveBrowse->setDisabled(true);# C5 j; J9 Q; c3 c! l# ?, n
  102.         ui->receiveButton->setDisabled(true);
    ) c. J5 }2 D* c3 s1 {* s) _5 A
  103.     }* _' u( D2 _" P  ~
  104. }
    ' v' P: Q* U4 I; j( J- g1 [6 y5 e- w
  105. 9 k& I; i! |+ C" n# I
  106. void Widget::on_transmitBrowse_clicked()( m, E  @: y7 o  @- V. k: ~
  107. {  A. P1 R. |! z; P
  108.     ui->transmitPath->setText(QFileDialog::getOpenFileName(this, u8"打开文件", ".", u8"任意文件 (*.*)"));
    3 N) w$ D6 X( E# d+ G& e

  109. - G: Q9 S$ t) O- E9 g2 c1 B
  110.     if(ui->transmitPath->text().isEmpty() != true)
    9 d4 |7 V3 c/ s6 x1 C
  111.     {4 y- o. [3 E  b$ g2 `) X  w
  112.         ui->transmitButton->setEnabled(true);
    : S9 P3 R- L# ^# W
  113.     }
    5 N( J3 ~2 @& m4 B6 k' I( O& F$ w
  114.     else
    & ~; N2 N2 i4 @" \* k3 s8 }) C
  115.     {* g2 \7 `9 M; l+ t% T
  116.         ui->transmitButton->setDisabled(true);' E# F0 |5 ?# ^) S4 [, f* F
  117.     }5 m6 f9 s7 {, k4 U6 d/ Y
  118. }
    : }( s1 N  x( c# m

  119. 4 T! j; K( r$ J- n4 b
  120. void Widget::on_receiveBrowse_clicked()
    5 {% d# e: r* [+ q6 M% k% t
  121. {' w- S$ I& r  I! d- w; f
  122.     ui->receivePath->setText(QFileDialog::getExistingDirectory(this, u8"选择目录", ".", QFileDialog::ShowDirsOnly));
    / s7 A( y1 W/ s& a0 a0 y. W( m

  123. ! M9 E9 p7 ^5 O/ v4 p
  124.     if(ui->receivePath->text().isEmpty() != true)
    8 |' K) W/ i0 X) w* E/ m0 a- e
  125.     {& M8 \1 l% [. I. i) t
  126.         ui->receiveButton->setEnabled(true);
    ' E% Z/ ^2 L# H1 Z
  127.     }/ E/ s! C' t& Z, ?% \0 T
  128.     else" h6 s. I- }9 A/ I
  129.     {  L  b6 c$ p, W+ S& H6 P. i+ Z
  130.         ui->receiveButton->setDisabled(true);, }: `9 l* b5 \: L* \
  131.     }+ H6 y( T5 V% u, M8 _" _
  132. }
    9 V( W- t2 `! w- |( @+ b
  133. ' ]8 K+ q7 q" ]) O
  134. void Widget::on_transmitButton_clicked()0 b1 G, F/ g2 y. j( ~  T
  135. {$ \  {8 U( Z7 B8 y4 Z
  136.     if(transmitButtonStatus == false)- U# x" {  [7 u( J* F$ l, o' K
  137.     {8 _! ~. J9 O. W  q# G
  138.         serialPort->close();4 l# i) l' i- }$ Z
  139. 4 s8 q" i2 T. X7 l' s" ^9 B2 Y
  140.         ymodemFileTransmit->setFileName(ui->transmitPath->text());
    2 F0 S% R7 a3 Z: I# [6 j' X
  141.         ymodemFileTransmit->setPortName(ui->comPort->currentText());& x, [! J0 t. t" k/ M" D
  142.         ymodemFileTransmit->setPortBaudRate(ui->comBaudRate->currentText().toInt());0 D3 d( p: i- k* v5 h

  143. 3 f: W5 F' I2 V+ V* i; w) n2 m
  144.         if(ymodemFileTransmit->startTransmit() == true)' k  T" V* y0 u, \4 u( i8 V
  145.         {
    ( N' l* l" s: t4 j2 j# {+ n8 G* T
  146.             transmitButtonStatus = true;
    ; C+ w9 R5 b+ |  j3 {

  147. 9 J; E9 j/ Y, ?; Y
  148.             ui->comButton->setDisabled(true);) f) p4 y  V' e  X, J" d0 T. o
  149. 5 O% A% R9 Z3 e
  150.             ui->receiveBrowse->setDisabled(true);  O3 k* i, N3 `; _  F
  151.             ui->receiveButton->setDisabled(true);
    5 m# n5 E4 O6 h* f4 }
  152. $ S/ e4 R4 h1 x" {7 U* F& ]$ a0 d
  153.             ui->transmitBrowse->setDisabled(true);( Z* I6 w  e" {! |7 e" |9 `  x
  154.             ui->transmitButton->setText(u8"取消");
    ( G2 j; ]; A* N1 h9 M  Q3 u
  155.             ui->transmitProgress->setValue(0);
    ! Y6 _4 ?' L: h' O  |5 D! P- `
  156.         }
    1 j, r( y8 x, k$ ?5 }. y* X1 C
  157.         else
    : t# H, ?0 j9 o% _2 e
  158.         {
    0 O: l) |( N" [
  159.             QMessageBox::warning(this, u8"失败", u8"文件发送失败!", u8"关闭");/ C5 b% O& M. K2 ?% P+ M  i& G
  160.         }, r: d. _& V! i8 S% G9 g
  161.     }$ v* _8 p$ [1 s: r6 K
  162.     else& \' K$ r2 H8 i4 C
  163.     {
    " Q( P" Q7 M  {$ \$ c, O+ E
  164.         ymodemFileTransmit->stopTransmit();' [# k8 n% f' o- v' [. E" d
  165.     }6 P0 ?1 r& J* k, J$ L6 G8 b! ^3 n
  166. }
    ! {" f; |3 ^4 e

  167. 4 _, A5 i0 ?  N1 m
  168. void Widget::on_receiveButton_clicked()
    + i. V1 R! W" W: @- M1 z
  169. {
    $ S* f" c; p3 m; o; ^
  170.     if(receiveButtonStatus == false)
    0 ~, i' e+ W; b8 P) ?& C
  171.     {
    ; v+ V2 [& B& |1 O$ t
  172.         serialPort->close();
    8 L6 x. g4 E1 J
  173. * U% ?. H: J1 Y1 Y) B4 Y
  174.         ymodemFileReceive->setFilePath(ui->receivePath->text());
    7 C; c( n2 d* O7 Q
  175.         ymodemFileReceive->setPortName(ui->comPort->currentText());+ R7 i1 U. i, U" ^$ `( y
  176.         ymodemFileReceive->setPortBaudRate(ui->comBaudRate->currentText().toInt());
    / A: S6 A- S% t8 c

  177. 8 C# x# K5 R: `4 g' n+ b( L0 r& T
  178.         if(ymodemFileReceive->startReceive() == true)
    7 {# ]; w8 J4 f5 N7 k2 w
  179.         {
    - {3 h0 `; ], [( h
  180.             receiveButtonStatus = true;6 S9 Q5 y7 _  J; I
  181. - L- m6 K, t; L  f0 x$ v
  182.             ui->comButton->setDisabled(true);  k( ~. Q7 `: I. g, P7 {, P4 E, O
  183. ! Y! [/ H) L2 P. G- ?
  184.             ui->transmitBrowse->setDisabled(true);2 G+ P! B% Y8 O& d$ K+ V) S! Z
  185.             ui->transmitButton->setDisabled(true);2 Y" ^8 e" |$ t+ B
  186. 7 @1 J3 C5 `  H& z% _: _
  187.             ui->receiveBrowse->setDisabled(true);
    2 e# v' v! _/ Q
  188.             ui->receiveButton->setText(u8"取消");9 ]; ]6 T! ]5 ~5 d5 Y
  189.             ui->receiveProgress->setValue(0);5 n% Y" ]# _/ J) i, {% A
  190.         }
    $ X2 S& ?2 S1 _: Q! k8 r9 k# k
  191.         else
    * |/ h! y; h! J2 l
  192.         {
    / O5 Q. @7 e+ p# a
  193.             QMessageBox::warning(this, u8"失败", u8"文件接收失败!", u8"关闭");/ H1 e7 M! N) L# m  o
  194.         }2 ^, N& M  R- s
  195.     }+ b1 X2 x5 i; p: k
  196.     else1 I4 f6 f' O+ F8 X( b
  197.     {4 n! r: K2 O$ \0 p# a, Y
  198.         ymodemFileReceive->stopReceive();
    ' J' p6 ^2 h, E7 C8 P
  199.     }
    ! E* u* `1 [, u3 m
  200. }  `3 q& @: f4 U; a% E) y2 r% V/ e3 I
  201. 6 }$ V# w+ H, P* m1 u$ U
  202. void Widget::transmitProgress(int progress)6 j. z+ M* G% N. X% ~4 }
  203. {) O3 z$ I1 \: v8 l2 q3 K
  204.     ui->transmitProgress->setValue(progress);- M" J9 Y8 Q% G3 i; u
  205. }
    9 C' S4 Z1 }6 `  B. O. p  ~. R: i
  206.   p7 r1 g  ]+ d3 P2 M+ y0 g
  207. void Widget::receiveProgress(int progress): U1 U' F( S2 `2 j2 k" m% B1 V
  208. {* C! i& D$ Z6 P0 ?
  209.     ui->receiveProgress->setValue(progress);
    ' j* D/ I4 G  m0 I4 T
  210. }9 c1 y+ v$ [2 U! o0 q

  211. 8 Z0 a7 `4 k- G0 X4 i* i) D
  212. void Widget::transmitStatus(Ymodem::Status status)
    ( A1 h, ]' _, m3 Y- z6 m  y
  213. {( r* q, Z0 R6 e6 }' b' v* Y( F
  214.     switch(status)
    6 W' R- C2 r# Z) b- ?, d
  215.     {
    : Q- h( o7 i  P; q+ S) ^
  216.         case YmodemFileTransmit::StatusEstablish:
    ( ~! |1 o, `/ P" j
  217.         {7 u8 e! X% G  _+ h6 M: U
  218.             break;% m! j: d2 X; u; C" B/ o, r
  219.         }. P: V8 I  @4 Z+ E7 U0 V0 _% u0 y

  220. - M- J: ~- S, a( Z- g
  221.         case YmodemFileTransmit::StatusTransmit:
    5 j) F; F) A0 S1 T
  222.         {
    6 T8 w. ]9 `  f( q+ F# r
  223.             break;& \% U% O8 Z5 u7 d& ^5 m
  224.         }! d0 T: F" h9 o4 y

  225. $ ]% [1 r& T; D. J5 G- o8 V& i  ]
  226.         case YmodemFileTransmit::StatusFinish:
    " ?0 L2 z3 R9 u: P# t# o0 Z4 q$ m8 H
  227.         {
    2 R' Y5 |! B3 _' L7 s+ j3 F2 h! \* p# S
  228.             transmitButtonStatus = false;
    + q' M1 [  r& U  a3 {' P
  229. 1 H- U# g5 o( J* Z
  230.             ui->comButton->setEnabled(true);5 u4 O# e8 J9 i0 V4 K/ Z
  231. - B7 @0 S* q1 K/ p/ G: H$ s
  232.             ui->receiveBrowse->setEnabled(true);( ?% g2 A* D! d! ?! m  i9 \. S
  233. 1 ]% L/ N' s. \! j
  234.             if(ui->receivePath->text().isEmpty() != true)
    , u/ u% Q% r/ M4 ~  S
  235.             {
    5 l1 @! ~7 k3 v
  236.                 ui->receiveButton->setEnabled(true);
    . }, H8 g1 O/ p. R! a  |4 N- }
  237.             }: E9 K3 w8 u1 G2 W
  238. + B, ]9 t, D$ @( R
  239.             ui->transmitBrowse->setEnabled(true);
    " f" m7 N' J4 i# [
  240.             ui->transmitButton->setText(u8"发送");
    4 ^2 D) y- Z- v. A5 X

  241. 8 Z! d+ Z& w8 t- a/ ^1 I
  242.             QMessageBox::warning(this, u8"成功", u8"文件发送成功!", u8"关闭");
    ; z  q7 W- H: c: v: f) b

  243. & @$ P+ t: Y6 [% b
  244.             break;5 B5 s! l$ I  R
  245.         }6 g& R$ L6 W% [" h6 c) b
  246. ! j. |. P+ q: W% [6 h
  247.         case YmodemFileTransmit::StatusAbort:. y1 G- E! [/ I0 P5 k2 T+ I
  248.         {! e9 o; W1 L1 z" {" q0 m
  249.             transmitButtonStatus = false;
    $ V2 W* B) |+ B1 X
  250. 0 Z; L# B. u2 D1 k
  251.             ui->comButton->setEnabled(true);: x: `% U1 r0 U/ j3 P
  252. , [6 @# K" r' z% N" g
  253.             ui->receiveBrowse->setEnabled(true);$ u" d2 c1 I- @5 G2 C8 }

  254. 3 H  T$ |9 ?" v' R3 C2 @
  255.             if(ui->receivePath->text().isEmpty() != true)% l$ r% v- W1 i) ^7 t, ?' X6 X; R7 N
  256.             {
    9 _. a8 e* L6 \7 n( |
  257.                 ui->receiveButton->setEnabled(true);7 i: X1 o, w( P  e
  258.             }- ~' t2 b- _1 [* V+ x7 s7 k5 L

  259. ) X: y3 ?- c* s+ }4 i
  260.             ui->transmitBrowse->setEnabled(true);8 x' a* Y% V7 O8 C( [- p% a
  261.             ui->transmitButton->setText(u8"发送");
    / O: _3 j' {( o6 X: s

  262. * ^. r# V1 M' h, A$ y3 o
  263.             QMessageBox::warning(this, u8"失败", u8"文件发送失败!", u8"关闭");/ p) y: E, d$ w" x- W5 E- B
  264. - i2 j5 @" W) k4 `: |9 k6 ^  }
  265.             break;# w  `' ^6 i. ^. M$ t+ R- ^
  266.         }6 }2 ]: }) ]" f2 T0 s5 K

  267. + {, P0 |& O" u; }; T3 _3 b. l7 q
  268.         case YmodemFileTransmit::StatusTimeout:
    7 z  H/ q6 D, L4 r3 n  f8 g! L) i
  269.         {0 F# s/ n6 V& F" Q6 R
  270.             transmitButtonStatus = false;# W' j9 ^, o" m4 E

  271. : }2 f* }# _4 `* e. s2 w  R
  272.             ui->comButton->setEnabled(true);
      F: `4 _( o8 t8 i3 Q3 f, h

  273. 8 o% h7 d$ m/ s0 m/ X( m
  274.             ui->receiveBrowse->setEnabled(true);6 [0 K, |5 ~2 i9 Q# \, L& S
  275. $ `0 _) K; a0 U- {1 ~. _5 ~6 [& j
  276.             if(ui->receivePath->text().isEmpty() != true)
    $ b  R- `1 n3 r; j3 v
  277.             {
    $ l$ U( E2 V) R* ]0 j, l2 T
  278.                 ui->receiveButton->setEnabled(true);
    * ]2 P" x% ?8 l5 ?- S
  279.             }
    - F/ G! a0 Z( a6 A4 i" X
  280. & Q3 i* n+ s2 T6 z
  281.             ui->transmitBrowse->setEnabled(true);$ g' z! K$ }: o6 X* H& `- @* |/ t
  282.             ui->transmitButton->setText(u8"发送");
    5 R  O5 d% h( r' D1 a1 _4 r
  283. # p0 Q  l5 P7 y6 ~3 C
  284.             QMessageBox::warning(this, u8"失败", u8"文件发送失败!", u8"关闭");% g" O  z( E5 |) y' |+ Q2 Y* p( t

  285. ! W  q' d2 j& H
  286.             break;
    % ^( z- j2 |& ^
  287.         }+ f+ J5 |0 ?. H4 |$ K
  288. , ]/ E3 Q  y) g1 [$ U8 \7 I1 m* H
  289.         default:
    ' S: _5 P7 T$ J1 K7 D) W
  290.         {6 g) \! @  w0 {- }0 K7 V
  291.             transmitButtonStatus = false;
    0 q7 w  X) v9 u; U

  292. 3 s( p: ~5 u( T6 a1 b
  293.             ui->comButton->setEnabled(true);
    ! N; v1 v- }8 W2 n

  294. 0 N5 X, e5 U. K& s+ N. w6 g4 a
  295.             ui->receiveBrowse->setEnabled(true);  \$ F, ]+ H* X+ `( I, m

  296. & }# q& n' T3 x: h* y7 e
  297.             if(ui->receivePath->text().isEmpty() != true)
      m/ t/ Q" a. ?, D+ ^* W
  298.             {
    " ^% a5 R1 j8 {9 ]3 Q" M! J* J
  299.                 ui->receiveButton->setEnabled(true);
    ' d1 `1 j2 G+ v& V
  300.             }! u3 H6 l7 L+ v; ~5 x
  301. 0 L1 f% a- A$ j6 R
  302.             ui->transmitBrowse->setEnabled(true);
    $ ^, ]$ \" ]) i/ c4 G
  303.             ui->transmitButton->setText(u8"发送");
      |7 b$ \7 ]0 o$ i( n6 O4 M- S4 R  ?

  304. ) v6 u3 Z' n1 q2 I
  305.             QMessageBox::warning(this, u8"失败", u8"文件发送失败!", u8"关闭");
    / l/ f7 O' I& m# E
  306.         }" u6 o6 A& b$ h" x# w
  307.     }
    ' [9 s* r- w( Z4 V% N, [! A* S! b
  308. }2 z) C9 ]' l, a  x

  309. 3 h3 X% }; H4 {9 v2 h( \+ a' w: I
  310. void Widget::receiveStatus(YmodemFileReceive::Status status)
    ( {1 \/ ?* b! j0 E/ O
  311. {
    - d( A" x* I3 j5 x4 H; c' |
  312.     switch(status)
    - k+ r1 D' w' M" `# Y
  313.     {
    # M+ F2 z9 i: _
  314.         case YmodemFileReceive::StatusEstablish:
    . x/ z  z3 i3 l. R5 u  N
  315.         {8 e1 L9 L9 J$ u/ I% f: E! U
  316.             break;  v, _" \' @) B, q, T" H
  317.         }
    & n: p* H. M, m$ ^! w) q

  318. . l# n. S/ h) C* U
  319.         case YmodemFileReceive::StatusTransmit:
    ( {: G0 _/ N4 ]6 B7 x5 g1 M1 I
  320.         {
    ' ~0 e! N9 B" R! H" h  K6 w
  321.             break;* @9 m$ o! \6 ]* W. a4 U
  322.         }
    + d$ W' }/ a2 d# W2 {3 B

  323. % `$ H+ t/ N/ |4 l
  324.         case YmodemFileReceive::StatusFinish:
    ' C. ]0 z( m9 @6 U
  325.         {
    " {' Y- }% W) W
  326.             receiveButtonStatus = false;; r) T% F. U# i

  327. % X, Y/ v0 j/ S0 R/ S
  328.             ui->comButton->setEnabled(true);8 r6 h3 O; j  J% L
  329. 0 _% u: D0 J! i6 b
  330.             ui->transmitBrowse->setEnabled(true);
    + c7 ?& T) {/ K. X# a; w3 D8 ~
  331. 2 b" ]1 k% B% k3 A$ p: y% O) z
  332.             if(ui->transmitPath->text().isEmpty() != true)! D! d- `$ ]. b) N
  333.             {8 y$ `1 m0 m" h& j# k- ], k
  334.                 ui->transmitButton->setEnabled(true);
    5 S: a9 r- f/ i  |6 O) G( R9 @
  335.             }7 G( \5 D3 T! s" Y, i5 z8 Y
  336. " t2 C) I& ?& l( S& i6 ]. j$ [
  337.             ui->receiveBrowse->setEnabled(true);" A6 O7 h/ O# L0 ?7 ]
  338.             ui->receiveButton->setText(u8"接收");
    + ^  ]& W( k- c- X; c, e5 t
  339. 7 V5 A6 E# y  A% X3 D8 s
  340.             QMessageBox::warning(this, u8"成功", u8"文件接收成功!", u8"关闭");4 `) [& M: r) u$ L' X0 h: N5 C

  341. 8 V: T$ u5 u; d* T8 a
  342.             break;/ A" V: a1 D5 ^. U+ r! X/ h* s
  343.         }
    / s- [* i( C* |) @- N" I
  344. $ l4 k. `, |% ?# Z3 b2 T, n/ B
  345.         case YmodemFileReceive::StatusAbort:
    ) u( R$ k6 V0 j& ?- m
  346.         {
    / P; F! Z/ j- [, p3 I+ z+ o
  347.             receiveButtonStatus = false;
    4 [7 R1 h$ Q! B& k) O- U
  348. : G! O7 z8 M2 D( o0 [5 G; G5 U
  349.             ui->comButton->setEnabled(true);
    3 l: z0 f& J1 O6 q- f) r

  350. ) C6 S9 A, V3 U- P4 @7 Z
  351.             ui->transmitBrowse->setEnabled(true);8 B  n, |6 t$ e" @- }) I2 `5 B
  352. ; q4 K/ x, q  G& T) X$ N2 ^, P
  353.             if(ui->transmitPath->text().isEmpty() != true)
    5 G6 Z4 B9 C, d; P: l5 s
  354.             {/ a* L* k9 g' W# }$ F2 f6 i: ^7 @
  355.                 ui->transmitButton->setEnabled(true);
    % V+ O4 X% t' o9 K' D
  356.             }; h9 D/ k7 {: D0 |' B0 o- r' ?

  357. + w  x5 W) L% j7 D$ q
  358.             ui->receiveBrowse->setEnabled(true);
    0 ~5 |& F. X& {
  359.             ui->receiveButton->setText(u8"接收");/ H% D6 ?1 j- i- s/ e: o* [( d
  360. 5 j7 a# o" h9 s$ m
  361.             QMessageBox::warning(this, u8"失败", u8"文件接收失败!", u8"关闭");0 H8 A* A$ ~. u

  362. ' \( t( }0 Q5 ~7 `6 S, t6 ]( }
  363.             break;! L2 D" D+ r+ M; p' L2 T: V
  364.         }
    4 J8 ^* K$ }5 t3 [7 K5 ]" m2 m
  365. ) O! L5 o2 `! g3 j* n0 \) J# k5 O
  366.         case YmodemFileReceive::StatusTimeout:
    6 K+ |2 n1 u* ^8 ^' a
  367.         {
    0 c" J! f: S9 J! [8 ^
  368.             receiveButtonStatus = false;
    9 q% L' Y% A  U1 t/ ?$ a
  369. 2 @. Q: z1 U! Y+ H& y+ X3 \
  370.             ui->comButton->setEnabled(true);
    5 a/ ^+ x. K; Y* n  |' {

  371. $ c! M% Q8 R) m& p, Z
  372.             ui->transmitBrowse->setEnabled(true);" {# l' R. _/ I0 }; N

  373. , S1 N$ s4 H8 `4 g4 [8 }0 R* |' y0 B
  374.             if(ui->transmitPath->text().isEmpty() != true)9 l( a6 \! w& ~: H  A( ]
  375.             {! q! Q  @1 c/ x% m7 b
  376.                 ui->transmitButton->setEnabled(true);
      i7 a$ n$ @8 ^6 {' ]# _( k3 z
  377.             }, U5 ]( J2 B7 L5 U0 ]# D
  378. ) l8 v. J4 T: s9 H2 t- c
  379.             ui->receiveBrowse->setEnabled(true);
    7 e4 _3 L* v! B, o
  380.             ui->receiveButton->setText(u8"接收");( W& T! j9 d8 n4 c; B

  381. & H) Q3 B% O0 q  F" E7 G
  382.             QMessageBox::warning(this, u8"失败", u8"文件接收失败!", u8"关闭");# ]7 |+ i% n+ F- f5 k& z
  383. 5 S1 Y  v( G5 \: o1 W
  384.             break;
    6 N% K" c, }* d3 Q; P6 V
  385.         }3 W5 V" z& k% l+ k5 M: P& h
  386. ; `! r3 h& U4 ?" ^
  387.         default:
    6 S) P, Y" }! s# Q% ~
  388.         {
      w7 T" w/ n2 Y  B+ K$ s
  389.             receiveButtonStatus = false;
    4 k6 G; h" m2 G/ M6 L% }# g

  390. * j" v# _, ^' A# V1 l2 }
  391.             ui->comButton->setEnabled(true);
    3 g  ^8 `$ k  e
  392. & T: H0 Q0 D  Q8 `3 ^* j" s- H3 D
  393.             ui->transmitBrowse->setEnabled(true);6 i8 X3 [% v% A8 b) z
  394. , Y7 r' I, w+ T# |( P5 b
  395.             if(ui->transmitPath->text().isEmpty() != true)
    ( L0 I' t- b  ~5 T& e9 d
  396.             {9 H1 P" V" M) ^
  397.                 ui->transmitButton->setEnabled(true);1 h8 W' v! y1 \% B+ R
  398.             }* W! m1 f7 a! X

  399. ' J- \: s7 i1 M! D  T& _- |
  400.             ui->receiveBrowse->setEnabled(true);' C8 W, F+ a$ G4 D4 x
  401.             ui->receiveButton->setText(u8"接收");8 H( K0 l8 Q3 A7 r3 Y
  402. - a' @$ Q% f( B' U3 m& `) G
  403.             QMessageBox::warning(this, u8"失败", u8"文件接收失败!", u8"关闭");' P) U0 N3 S% _& n7 g
  404.         }
    2 q4 v' k$ F2 F5 @
  405.     }. x1 G5 d- f0 @0 U7 H* G
  406. }
    : C3 u8 I. \# B- b  \  F% L
复制代码
4 \  `. I- Z5 T& @. s: u2 J

+ W( s3 w# e& y' K4 w" Y  X, {% l6 A/ f; E3 Y+ L

* \+ ^) R) ^( T- t. o" N3 w
! W+ q+ _; u0 ]
# ^5 u, p3 g( h8 u7 [
XinLiYF 回答时间:2018-3-6 22:32:40
      main.cpp文件
/ Q' @$ q' E) ]/ m8 r: b) Z
  1. #include "widget.h"" X/ c4 I9 _- U; o! K# d
  2. #include <QApplication>
    6 g6 R, @& d( ?" x# v
  3. ! p# k" Q3 L9 n
  4. int main(int argc, char *argv[])
    : Q" E6 c' w4 D  G9 |! }
  5. {
    ( ^1 `) w' t9 @
  6.     QApplication a(argc, argv);
    : Z+ n5 U2 R  y" V9 o' i8 D, X( B
  7.     Widget w;; }+ F5 ]' T1 F2 d; s
  8.     w.show();
    # Z2 E* ^# ~5 U  m# o4 E

  9. 5 I1 Q; t8 N$ g7 _& ?1 N" y# Z6 C/ y
  10.     return a.exec();
    4 z4 d  l  p1 L7 l' k$ f
  11. }
    ; {6 _' z' e  \2 `7 L& \
复制代码

! _7 v5 A1 I2 o      SerialPortYmodem.pro文件
4 a, U' S$ i$ L( N8 p3 J/ U) H2 B
  1. #-------------------------------------------------
    : p6 s+ [4 \) l, _( L; {
  2. #
    * w' c, R5 N- [/ l5 k% C2 A7 B
  3. # Project created by QtCreator 2018-01-20T23:00:46' C9 z9 T$ ]7 d/ |( [1 T, Z- S
  4. #
    ' F- Q- j' x; r) m  n; t8 ~
  5. #-------------------------------------------------
    1 i: i6 {% N/ P$ C+ ]& _0 p

  6. 2 K5 ]8 I+ b/ P% d8 C: W
  7. QT       += core gui* j/ P, _* h& Y, Y
  8. QT       += serialport
    9 @" i8 J) M; I' I2 b% [
  9. $ O/ G2 }, g7 ]! e0 {' V6 G* w( q9 U& a) i
  10. greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
    ; ]+ a7 K( G. |* H  \

  11. 7 C7 w0 X2 S9 Z9 h. h
  12. TARGET = SerialPortYmodem( ~% z5 U" G9 ]# ~' n
  13. TEMPLATE = app
    - y; T% d7 `7 r& G

  14. # u1 B3 f" z; y# ]" H6 \/ M
  15. # The following define makes your compiler emit warnings if you use
    ' N) t& _% l: e3 B
  16. # any feature of Qt which as been marked as deprecated (the exact warnings/ {3 h+ n6 ]8 [! J; A$ Y+ G( a
  17. # depend on your compiler). Please consult the documentation of the6 f  N6 d, R/ d9 H
  18. # deprecated API in order to know how to port your code away from it.
    " O1 c* r, {) [* k
  19. DEFINES += QT_DEPRECATED_WARNINGS
    & b! t8 v4 F1 I( k
  20. % [7 g7 J/ J- [2 G# Q4 g; o
  21. # You can also make your code fail to compile if you use deprecated APIs.
    ( a2 @5 _2 {; q: i
  22. # In order to do so, uncomment the following line.
    5 U2 U( ~- C) j$ _
  23. # You can also select to disable deprecated APIs only up to a certain version of Qt.
    / I0 O0 n( f. n
  24. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
    / y, l. G9 t, G& k8 q/ M
  25. ) ^. S: I- [! ^8 r% `) `" ~5 O7 U) Z' U, S
  26. % \0 G- H% O+ ^, V
  27. SOURCES += main.cpp\, t& `  k" Y5 Q5 E0 ^4 s1 s; D- f
  28.         widget.cpp \: Z% ~' t0 {6 `2 e. Y( m  q
  29.     YmodemFileReceive.cpp \
    ' t9 d! B3 {; E8 \! J9 R1 I
  30.     Ymodem.cpp \" h& x* ?. R! Y+ W3 k% O
  31.     YmodemFileTransmit.cpp8 q$ w$ z' H- A

  32. % i, W; i  C$ M# _
  33. HEADERS  += widget.h \8 j/ w4 x7 \0 s
  34.     Ymodem.h \
    3 C$ ^# x3 }* L/ ~, Z* k
  35.     YmodemFileReceive.h \3 \' B8 N) {" d4 E  {9 r( N
  36.     YmodemFileTransmit.h
    & c3 S+ Q- r- f2 ^( R
  37. 4 L, j3 l2 M6 q2 d2 S
  38. FORMS    += widget.ui
    ' m" g+ g4 @" V; Q  s; t6 L

  39. 8 n) {$ I* |: d9 P: b4 _7 |* V
  40. RC_ICONS = SerialPortYmodem.ico3 V- X  L7 b1 [* w
复制代码

; a# F/ r6 ?; h4 C; w      SerialPortYmodem.ico文件% @1 e- H- Y$ A  ^+ @% [) R
$ [$ P* e) O3 y( l; h5 U
3,运行效果# e2 C" |/ e0 Q. ?( T5 s

: q1 `+ G9 S. A, [2 q0 V! `1 T# X* z7 ]$ r. c# B

1 r; `" x+ x. Q4 H* `
% p: u, i+ ]3 ~$ ~) _
XinLiYF 回答时间:2018-3-6 22:33:09
可以用来做用户程序升级的上位机软件。GitHub仓库有工程,还有资料。
anobodykey 回答时间:2018-3-7 09:21:37
感谢楼主分享
shuihehe 回答时间:2018-8-13 15:37:45
网络在线升级的技术资料呢?
any012 回答时间:2018-12-19 14:03:21
请教,单片机端如何处理呢?
XinLiYF 回答时间:2018-12-22 17:06:17
any012 发表于 2018-12-19 14:03) T" e3 W5 u/ Y' N- a6 n* Q
请教,单片机端如何处理呢?

  W& n8 N- C& Z6 U! K可以移植到单片机上,文件的接收和发送都支持。
Kevin_G 回答时间:2018-12-26 09:46:05
收藏
huangchao09 回答时间:2019-3-24 20:37:59
多谢楼主共享

所属标签

相似分享

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