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

YMODEM协议串口文件传输

[复制链接]
XinLiYF 发布时间:2018-3-6 22:28
YMODEM协议串口文件传输
GitHub仓库:http://github.com/XinLiGitHub/SerialPortYmodem( t. u. A5 D. m3 l: L" B" \* Z
PS:博文不再更新,后续更新会在GitHub仓库进行。! }* f9 F- f, h) @

9 Z0 K6 m  ^/ r: o0 W; [# D( w
6 P( m8 w, k5 Y% s3 H5 r
    串口通过YMODEM协议进行文件传输。程序中涉及到YMODEM协议知识,详细介绍见维基百科[YMODEM](http://en.wikipedia.org/wiki/YMODEM)。; N2 u8 L9 \6 s* M

* w+ t: ^* p" ?  R1,开发环境
! r5 |0 |* E: k! ?3 X) X! _      1,框架:Qt 5.7.11 J( b# }! _! e% u
8 D( S& X# T8 K. |# [5 q. M3 w
      2,编译器:MSVC2015_64bit
9 V2 n3 U$ g4 {; t. x
! l$ |" A1 }8 \7 l
      3,IDE:Qt Creator 4.2.0 社区版7 d; t6 K, N% J, M
      4,操作系统:Windows 10 专业版
6 z  A- l& c6 w
( Z6 a' O) J* _# Y% n$ e  G5 O! x2,程序源码5 u% |. k+ }3 n8 c3 Y" S# b/ {
      Ymodem.h文件
/ U# ^* y  p( ?$ K, a5 `6 h
  1. /**& f# a7 B) t/ D$ \) o
  2.   ******************************************************************************* T5 f( ^' W; H
  3.   * @file    Ymodem.h
    8 R% q- P# L3 J' \, s) C! p; t
  4.   * @author  XinLi, b/ M8 L/ w9 k1 H: I0 D
  5.   * @version v1.0* g0 {  t$ o) F) y( \0 K1 T  c
  6.   * @date    21-January-2018* x8 F* Z0 o! [
  7.   * @brief   Header file for Ymodem.cpp module.7 C, h% R3 b% v7 n0 ]) \  A1 \
  8.   ******************************************************************************
    ; d, N/ H8 M. X' M5 q: p
  9.   * @attention
    0 K. B3 ?3 M2 _7 Q  P
  10.   *
    8 g) N! W5 I7 G2 U, w5 Y; m8 b' |* E* E
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>
    8 c0 X9 \* J$ r9 {1 q% H" j9 c
  12.   *
    9 T' {5 s, b  P# D* |: T! d
  13.   * This program is free software: you can redistribute it and/or modify
    ) u3 |" f% }, J/ L' q6 k6 F
  14.   * it under the terms of the GNU General Public License as published by
      Q. \+ V' A# @% _8 _$ S% A5 @
  15.   * the Free Software Foundation, either version 3 of the License, or8 O% w4 j8 R4 t1 V$ G
  16.   * (at your option) any later version.
    7 L2 a6 {2 T$ ?4 q4 [
  17.   *- e& N8 m' |0 h0 O9 Z
  18.   * This program is distributed in the hope that it will be useful,% f# ^: Y* L. u% W6 D6 q: r% z" H
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of! a& G$ N2 z1 s3 k
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    ! k3 W) y# c1 e
  21.   * GNU General Public License for more details.9 M5 l" ^  y/ R$ m6 t% r7 c
  22.   *
    + F  O+ V3 O1 ]3 g
  23.   * You should have received a copy of the GNU General Public License5 P/ [% T# T6 Y, o! |  B" n! a
  24.   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    & h8 G4 R9 [# e" ?# M* \
  25.   *- c- m' \& e( S2 X* _
  26.   ******************************************************************************/ x8 b  V' o, d: Z' Q
  27.   */! T$ _% e/ W# S3 V$ `; R. L! N2 e# ~
  28. ; U) w& a5 V7 z
  29. #ifndef __YMODEM_H8 ^1 y# S; R+ B8 _! j
  30. #define __YMODEM_H
    ( c, T' a! t. U1 ?
  31. 5 j6 Y( M# }4 E5 P6 y5 G
  32. /* Header includes -----------------------------------------------------------*// z4 j3 T  U" O& v' {) q
  33. #include <stdint.h>
    3 A4 r0 F/ o$ n$ H2 z: r- D
  34. 2 K: \9 R& W5 d& v
  35. /* Macro definitions ---------------------------------------------------------*/
    7 ^: E/ ]# R. j% E% H8 [0 }& D
  36. #define YMODEM_PACKET_HEADER    (3)7 X! @" @- P# ?' L% z- m& w9 g$ @
  37. #define YMODEM_PACKET_TRAILER   (2)3 C$ Z; m: |) y. @, ]1 v* v, ~
  38. #define YMODEM_PACKET_OVERHEAD  (YMODEM_PACKET_HEADER + YMODEM_PACKET_TRAILER)
    9 n7 y: K1 n( c4 D6 b7 E5 s
  39. #define YMODEM_PACKET_SIZE      (128)# b. N; I  Y( z/ R; L7 e
  40. #define YMODEM_PACKET_1K_SIZE   (1024)) E1 ~  A- {6 B! J
  41. " C% v" b; G' {- v- Q0 K- a
  42. #define YMODEM_CODE_CAN_NUMBER  (5). m: X! I: U# v) v. B. F
  43. 6 j+ ]) @7 Z  x0 |, x: k
  44. /* Type definitions ----------------------------------------------------------*/6 }0 x1 y6 j! A! m/ m; u7 V
  45. class Ymodem$ o& ~0 }0 o6 [/ p, v# |! T
  46. {, D+ d1 r& g8 F5 |" c7 E* y
  47. public:
    & h: s! [: m$ q/ t. c9 b
  48.   enum Code$ f" H" a, j/ W, l+ u1 P. Q
  49.   {2 h2 W( m4 d2 N5 i9 o5 f- @
  50.     CodeNone = 0x00,) m. e. O7 o+ e) q
  51.     CodeSoh  = 0x01,( S% d- ]7 k3 z- @* x4 k# ]
  52.     CodeStx  = 0x02,2 Z, z3 D5 n. H. v3 h) O4 O
  53.     CodeEot  = 0x04,
    9 ~- N- k, P5 g/ Z9 |  I* M) R# w
  54.     CodeAck  = 0x06,
    6 t5 D; [% _/ l% m/ [
  55.     CodeNak  = 0x15,
    ' [* F+ _+ C% n$ _
  56.     CodeCan  = 0x18,$ C- P7 y$ l/ D7 e
  57.     CodeC    = 0x43,
    ! j0 t6 T* o8 Q
  58.     CodeA1   = 0x41,- R& b, T3 {4 z9 R0 A& y
  59.     CodeA2   = 0x61/ u: A: Q3 P2 j* T# F
  60.   };
    * }% g5 a0 L! ?7 V9 y$ w9 ]

  61. ; E4 |9 Q' t. @
  62.   enum Stage
    : r( O! e" \6 O; v6 d# k: B0 d% S
  63.   {- a9 @3 @6 n- a$ l+ t; r$ S# I
  64.     StageNone,
    " n- L- D1 P1 X& N3 M
  65.     StageEstablishing,
    $ ?" X4 R1 A4 W2 v4 M) i
  66.     StageEstablished,$ D, B  [/ k# d, }
  67.     StageTransmitting,
    ' t- S; X+ b& w. d
  68.     StageFinishing,
    . B/ G8 j- v+ n! K) I
  69.     StageFinished3 l6 m+ N) z/ ^
  70.   };
    5 \& r2 x: q4 t
  71. & p& V( R3 n- ]9 U
  72.   enum Status
    9 K, P+ K$ J* w1 G* }5 R. x" A* b
  73.   {
    % o$ n/ _, k( @
  74.     StatusEstablish,- H: t% ?7 V4 f
  75.     StatusTransmit,+ x0 m5 i) q3 F6 Z& ~
  76.     StatusFinish,
    * y( a2 d2 `" _. P9 c
  77.     StatusAbort,
    1 k* S1 O$ i9 T% ^) C
  78.     StatusTimeout,, M( h( g. e; j& f$ C$ h
  79.     StatusError
    : b# d0 M) U3 L# P/ G
  80.   };. I: T" k0 M! ^, o6 \. U

  81. ) v% N4 z; I; Y: k$ @
  82.   Ymodem(uint32_t timeDivide = 499, uint32_t timeMax = 5, uint32_t errorMax = 999);1 p1 I5 r+ Q: K" Q
  83. 0 t: c+ [7 x' Q! @' j* w2 G
  84.   void setTimeDivide(uint32_t timeDivide);
    # d$ t; @+ {5 `; ^2 U% i
  85.   uint32_t getTimeDivide();
    $ k% {, K* Z! s. J6 I/ J
  86. / X6 O: ?5 ]2 y* T- |) V
  87.   void setTimeMax(uint32_t timeMax);, r1 i7 h% w: A3 w
  88.   uint32_t getTimeMax();
    # Q6 e7 ?' s9 s9 c; S1 H& e

  89. / L3 z/ O2 j8 J" H! |
  90.   void setErrorMax(uint32_t errorMax);1 U4 c) N; O. m. k" a/ U! z
  91.   uint32_t getErrorMax();
    3 o7 }: h* \. f- ~6 I6 `+ i9 O

  92. 4 R# d9 u4 h6 ^% u
  93.   void receive();
    ! K- [: e9 [- R; r/ i. W. n
  94.   void transmit();/ U2 p4 K/ E1 V; g
  95.   void abort();* Y* J$ C1 m; [
  96. 9 A  @7 X5 @6 @% p! o2 W8 N( S4 N9 q
  97. private:8 M' V/ e5 a* G3 t' k
  98.   Code receivePacket();: e& A* ?& N% e+ P1 Z; R
  99. 3 l. J0 ~0 D  Q  |' H& i& D
  100.   void receiveStageNone();
    9 L4 ?$ v1 {9 _" H, i  W
  101.   void receiveStageEstablishing();
    , D% F/ X- F' t( f
  102.   void receiveStageEstablished();7 z& J& Q3 `4 K9 }4 k1 \0 g
  103.   void receiveStageTransmitting();
    2 ?6 |+ a: T% i5 |
  104.   void receiveStageFinishing();& E7 }- d3 y* T4 x( Q! Z: Z
  105.   void receiveStageFinished();& t+ b% G# x; z7 {) Y
  106. ; n" Z7 L6 j) F- _+ E
  107.   void transmitStageNone();/ }' |* T+ l" I
  108.   void transmitStageEstablishing();
    9 F6 x" @3 ]2 l7 y
  109.   void transmitStageEstablished();+ s/ L) r( y' t9 z- n' @7 m
  110.   void transmitStageTransmitting();
    0 U! D" ~5 P/ x9 o. `$ ^0 Z& r
  111.   void transmitStageFinishing();
    $ A: _# Q! c3 i- D
  112.   void transmitStageFinished();1 T9 Q( R0 a) H+ X; e7 i6 [

  113. . k, o9 w; r1 I" `
  114.   uint16_t crc16(uint8_t *buff, uint32_t len);
    + l& x* H* _3 [, z
  115. 2 j# N# M; L+ Y  [( O
  116.   virtual Code callback(Status status, uint8_t *buff, uint32_t *len) = 0;
    2 `$ K8 `' z  j. t; X" l0 k
  117. 8 O: L. l9 ]0 C1 T' B
  118.   virtual uint32_t read(uint8_t *buff, uint32_t len)  = 0;
    ; O; l3 I  J! o! P! X" l7 h
  119.   virtual uint32_t write(uint8_t *buff, uint32_t len) = 0;
    " ^* e5 Y' u, z- ]+ y* e- [

  120. ) R0 e8 S1 l1 a  l1 e4 e
  121.   uint32_t timeDivide;
    $ @) a0 Q4 h1 V+ o0 ~
  122.   uint32_t timeMax;! W% m: t  i! `
  123.   uint32_t errorMax;
    ( d8 i, i3 s' Q+ h8 J! ~
  124. + `/ h0 \( R5 z& y4 p) Q, Q
  125.   uint32_t timeCount;
    * i  C2 ^; m) P. g# P+ X2 |
  126.   uint32_t errorCount;
    + L$ x* {, s: o& i8 [- n
  127.   uint8_t  dataCount;. j& G; y8 |9 e+ I: L

  128. ; P  I" }- Q$ G/ X
  129.   Code  code;( S, n- x0 O0 R2 m+ ?) D
  130.   Stage stage;2 H. E* m3 J  p6 I
  131. . c! y! [) ^5 M
  132.   uint8_t  rxBuffer[YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD];
    ! F5 P9 M& z+ K3 T. `) T: M3 M
  133.   uint8_t  txBuffer[YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD];
    - Y7 R/ {. V, Z8 p
  134.   uint32_t rxLength;& z" \+ f# E+ F; M' o9 }
  135.   uint32_t txLength;
    ( |5 T# m4 [7 L  o; I1 v) F
  136. };; o. m+ k8 W( P* r

  137. & }# Z! _" Z4 q( K
  138. /* Variable declarations -----------------------------------------------------*/
    5 m  x, r, ?) H1 n
  139. /* Variable definitions ------------------------------------------------------*/
    4 V2 J" x- ~0 q* i! {( p0 Y+ h
  140. /* Function declarations -----------------------------------------------------*/# d7 b3 }' b8 u% r6 A
  141. /* Function definitions ------------------------------------------------------*/5 @: t( R6 u9 u% \4 P

  142. " T! C; j: B. d, N2 M- i# c& u
  143. #endif /* __YMODEM_H */  C/ E. h: c* C7 @! F
复制代码
) S4 A6 K' ^$ V& R  a2 E/ ?
      Ymodem.cpp文件6 l6 v1 c4 I5 b" L  C/ Q  z
  1. /**
    + x, ]6 C% l) @# `' A& E
  2.   ******************************************************************************
    - M, N& ~6 T% K# k0 b6 i
  3.   * @file    Ymodem.cpp( G( T3 J) w8 n; a2 e
  4.   * @author  XinLi
    5 x3 @" i1 ?# b: f7 ?' y3 }
  5.   * @version v1.08 m# w: v2 P+ W  y+ B
  6.   * @date    21-January-2018
    ! i# M0 Q. G* `6 x9 E
  7.   * @brief   Ymodem protocol module source file., S' h! j' ^0 B% \: K" Z
  8.   ******************************************************************************, z8 R; T" j) i2 u; k* t7 u
  9.   * @attention
    9 T& r* b7 I  G7 q7 ]( r
  10.   *
    + _2 K' W2 w, |8 z! C3 r
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>8 R" O9 m4 ~3 Y: C* }! a4 p
  12.   *
    ; \, b5 y# z- p4 ^- \
  13.   * This program is free software: you can redistribute it and/or modify& K' t# P3 J4 E
  14.   * it under the terms of the GNU General Public License as published by! D1 J3 ?# q- c, ^9 H
  15.   * the Free Software Foundation, either version 3 of the License, or$ d6 P: i' ?% T7 N$ n/ O% b
  16.   * (at your option) any later version.
    / z% r1 i' a1 U/ U) _
  17.   *& M0 s1 U# M7 d) ~' c7 N6 r* G/ y
  18.   * This program is distributed in the hope that it will be useful," r# W9 c6 T* o3 A1 c4 y8 W- I
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    , W9 Q$ n. X; ^  n& z+ I: }
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the& \" H) g& m( W! G8 F
  21.   * GNU General Public License for more details.
    3 k6 k  Y3 m( P6 }" p! C: u
  22.   *. o% o' d3 S- ~! d' \
  23.   * You should have received a copy of the GNU General Public License- D6 q9 z1 X- {6 g+ V( v6 s- r
  24.   * along with this program.  If not, see <http://www.gnu.org/licenses/>.5 k3 k4 Y- H# T+ w: M
  25.   */ W4 `6 Y0 ^% Z+ H! |0 L8 W
  26.   ******************************************************************************+ b/ X. H, R( L" P  H' Q
  27.   *// K$ b' x5 J( \; J. k0 W: i; {

  28. & p+ y; g+ |8 ^1 C
  29. /* Header includes -----------------------------------------------------------*/
    6 V9 p/ r" H% A6 M% L& Y
  30. #include "Ymodem.h"
    5 w, k) D" Z3 u& H- l6 S# L
  31. #include <string.h>9 b7 n: G% o9 i- r* E

  32. ' q# b5 g2 \6 r
  33. /* Macro definitions ---------------------------------------------------------*/
    ' e  W- E. |( _/ @; x
  34. /* Type definitions ----------------------------------------------------------*/' i( }) g# d3 a/ v* e( X' t( S+ r
  35. /* Variable declarations -----------------------------------------------------*/7 `0 S0 ^. F; ^$ H% o
  36. /* Variable definitions ------------------------------------------------------*/  b$ p% B# K" e% Q' ?, L+ F
  37. /* Function declarations -----------------------------------------------------*/0 @; R5 Z& ?/ P% x% j% V, l6 o/ @0 K
  38. /* Function definitions ------------------------------------------------------*/! m/ c5 K; T; k
  39. 1 B# |' e1 o+ B) Y  f' R% m
  40. /**
    5 u: \* I  O( i- s
  41.   * @brief  Ymodem constructor.1 k$ h- t% \( ?+ p  H1 T5 S1 I
  42.   * @param  [in] timeDivide: The fractional factor of the time the ymodem is called.
    : e/ v" |& b1 }; f4 X, ^7 S3 h
  43.   * @param  [in] timeMax:    The maximum time when calling the ymodem.( @1 G% K8 D( `' F# }9 P" g+ R
  44.   * @param  [in] errorMax:   The maximum error count when calling the ymodem.- w: I! N7 M0 u# m* u: y
  45.   * @note   The longest waiting time = call time / (@timeDivide + 1) * (@timeMax + 1).6 D7 u. G" }: C' I
  46.   * @return None.+ {5 f( L7 Y  G4 L3 h
  47.   */
    , s# f8 J- i% e/ }9 P% S' a
  48. Ymodem::Ymodem(uint32_t timeDivide, uint32_t timeMax, uint32_t errorMax)& g7 C: t! R0 X: ~" S6 M" l3 X
  49. {& G) }6 g& ~4 m1 P7 ~
  50.   this->timeDivide = timeDivide;
    9 q6 M$ J5 a! n' V* K
  51.   this->timeMax    = timeMax;
    9 A1 Z" l. X8 p' ~$ a
  52.   this->errorMax   = errorMax;
    ! H7 }( q5 [! ~/ ]  C4 v
  53. ' M. @; Y( w( ~3 u! t, v1 s: A
  54.   this->timeCount  = 0;
      }4 n4 Y9 a4 E
  55.   this->errorCount = 0;
    5 S# e6 F* `9 k8 X" K
  56.   this->dataCount  = 0;
    ; P8 A1 h- M' Z1 m  F7 z

  57. 2 r4 I, ^; [$ S
  58.   this->code       = CodeNone;
    # L3 V5 v" d# e$ b9 e! Q
  59.   this->stage      = StageNone;# \& ]. s. R6 g% S+ S
  60. }
    $ O8 w7 P5 l2 T" O# x. u

  61. % C( ~$ M; u" Q; E$ _! h, K
  62. /**
    % [7 N* J( e: C9 F9 [8 U
  63.   * @brief  Set the fractional factor of the time the ymodem is called.
    $ p# @. w# q0 j6 v* Q
  64.   * @param  [in] timeDivide: The fractional factor of the time the ymodem is called.
    / R' b' c* Y0 |0 D$ ~+ L: \
  65.   * @return None.
    8 u; Z6 K4 g8 o/ e% E! M3 x% F
  66.   */
    $ W& o8 v: ?6 ?. P/ \2 `
  67. void Ymodem::setTimeDivide(uint32_t timeDivide)% ?( i3 Z+ h% u8 ?8 r) h7 @
  68. {/ G7 ]  \5 t; U: j+ {. H, s1 U
  69.   this->timeDivide = timeDivide;
    & W7 W1 ?$ R# |& `1 V1 T. J2 o! \
  70. }
    $ c$ H& }  c% K; f4 S( V
  71. . F7 r% r- v- E0 K) I/ u! S
  72. /**3 D5 x8 d; t+ E# Y. G! Y
  73.   * @brief  Get the fractional factor of the time the ymodem is called.
    9 g1 T9 |- }6 Y2 R' |2 O  I
  74.   * @param  None.( l. {. V9 _# }+ g  \+ k7 a3 m/ x& q
  75.   * @return The fractional factor of the time the ymodem is called.
    $ z, n3 f9 s+ H1 X! |# O
  76.   */  z# ?1 e4 l% q, a6 P- Y
  77. uint32_t Ymodem::getTimeDivide()8 T( S) G, k, S+ h9 h0 w0 k
  78. {
    & j6 u3 X5 Z* C. b% |
  79.   return timeDivide;7 n# z! G5 k6 S. N! J
  80. }  T+ x0 v: e/ E
  81. ' H8 t  u8 `. J
  82. /**6 L7 S2 \8 ?5 [, a. k' X
  83.   * @brief  Set the maximum time when calling the ymodem.
    2 P5 A/ _. `8 F' h# x" a( J0 g
  84.   * @param  [in] timeMax: The maximum time when calling the ymodem.. B3 \4 H0 Q4 n6 v: j; h; u3 a
  85.   * @return None.
    ! G4 I- J( @$ f) k
  86.   */
    & G+ k- Y; [) j0 J0 h% _9 R
  87. void Ymodem::setTimeMax(uint32_t timeMax)
    7 n+ Z* l) p2 t9 C7 j: W1 O
  88. {- I5 G" T, y7 f# [3 r% |7 }
  89.   this->timeMax = timeMax;+ w9 E& ]5 G0 k) D
  90. }0 K$ r' S" E. V% G4 g  \9 d

  91. ) B6 m, |1 W' r+ ]# Q  g; t
  92. /**2 h: [1 ^3 m1 o( x  h+ V- Y
  93.   * @brief  Get the maximum time when calling the ymodem., ~& o) D& v" W6 q  G# ~* i% ~
  94.   * @param  None.+ f3 W0 a! `) v% D8 R) D/ z
  95.   * @return The maximum time when calling the ymodem.
    % T9 r/ l$ d0 j0 T1 p% F: G
  96.   */
    * b  G9 _6 A0 {, U
  97. uint32_t Ymodem::getTimeMax()
    / D  x8 Y  ?/ \( h2 }) @  t* m
  98. {7 P* u9 n3 {) j) q5 |5 [! H' H" |
  99.   return timeMax;
    3 p/ m; \- t7 j9 [* z2 K8 G2 ~% p
  100. }
      X5 C3 V9 U7 @8 j+ d4 _, f

  101. # H0 c7 C! O  V7 A4 a4 e! `
  102. /**
    ( ^( V) O& a5 e8 A
  103.   * @brief  Set the maximum error count when calling the ymodem.
    7 G/ r* _" z" m' E) [) {
  104.   * @param  [in] errorMax: The maximum error count when calling the ymodem.
    : l; g! u9 i  ]7 Z) E
  105.   * @return None.! X  ]" Q) {, ]/ e" n' g
  106.   */1 l, ~. j. s9 ~7 N
  107. void Ymodem::setErrorMax(uint32_t errorMax)$ ?/ M# b8 \' }' N* J! d3 f$ S
  108. {' H8 ^4 |" |, ~( B
  109.   this->errorMax = errorMax;2 T5 f4 G- F/ v8 [3 F
  110. }1 i4 K; [2 _4 a, [+ E
  111. ' Q' N: }* F* G3 p% N, u
  112. /**
    9 W) Y. j1 q+ q4 z3 z
  113.   * @brief  Get the maximum error count when calling the ymodem.
    + Z- p. U% ?5 ~, x# `
  114.   * @param  None.
    / s. {( H" X: G; S: N% Q) d4 h
  115.   * @return The maximum error count when calling the ymodem.
    ; W' p# V4 Y2 n" N  t' A1 t5 d
  116.   */# O2 x- H: i( c9 f3 u# |2 j
  117. uint32_t Ymodem::getErrorMax()" @) x" S2 S4 h; O1 `9 n: P0 z. j
  118. {
    . f2 M) K- }& W9 @, D* F9 ^8 Y/ r; `
  119.   return errorMax;& `- k/ m; t8 g! n9 R* D
  120. }
    2 n7 ?1 H3 b3 I" P
  121. & T# |! |% e; N7 O; ?( [% I8 J
  122. /**
    8 r2 P# c- V. m' l' X
  123.   * @brief  Ymodem receive.0 f( C; j0 j( ]! n4 C$ Y& D
  124.   * @param  None.# q3 n3 M! \* T
  125.   * @return None.7 f& f9 L/ _- z: f
  126.   */
    / b  Q: t4 x. |. k% A
  127. void Ymodem::receive()
    " p. W) Y7 _. ^8 h/ G. [$ R
  128. {
    1 _$ u/ |1 l4 d1 H+ [
  129.   switch(stage)
    7 l5 U) s& {- _* G# f/ k& |* y  j
  130.   {6 w4 }: J7 K* \' ~% C  b- a
  131.     case StageNone:" Y9 v# h! n4 W0 O2 }
  132.     {! S; d+ C3 S0 H/ A* E
  133.       receiveStageNone();0 q  l# U# f; F: X' w

  134. 3 M7 V0 g6 H6 D' B1 j) ~% r% j
  135.       break;
    : u6 Y$ i; Z; C4 B0 u/ b4 X  \
  136.     }
    6 [5 O+ j; G3 f
  137. - w, g( [, F* E+ u, X% }
  138.     case StageEstablishing:
    2 O' ^8 x. G2 }( n2 b
  139.     {
    . Y% V7 x4 Y, y; W3 N
  140.       receiveStageEstablishing();
    ) L, E& s8 s) |# e  w$ ^+ d
  141. 6 V0 w" l/ K1 G- {
  142.       break;
    ( ~6 ]7 C% g* B, h, W/ B
  143.     }7 f- F2 V7 V7 J* O( b

  144. " F# e* s# @& a/ r. @. N% W$ S
  145.     case StageEstablished:# {1 B; c4 E6 T7 w
  146.     {& Z& [, ^; @* m: E
  147.       receiveStageEstablished();
    2 C! v) V$ C& d% b% w" d3 `0 \
  148. # ^/ \+ X4 I( L+ a. M0 e
  149.       break;* K$ h8 j; {4 R8 [
  150.     }
    ( A9 E7 y& g& I% I  W
  151. , B$ q. d+ n/ L6 C& B/ k$ u+ S& D
  152.     case StageTransmitting:% ]7 z% i( i) H  G8 u
  153.     {& W% k6 g8 f: s7 T% B, T
  154.       receiveStageTransmitting();
    4 b0 w" v1 a% q3 ^$ M1 k, G5 Z
  155. 3 p! y( [( M* s  {- l/ E/ b1 L; }
  156.       break;
    ' y7 v) ~3 ]0 I3 ~$ j0 V3 d8 J
  157.     }
    3 [" j9 o" E% z
  158. / E; {* G/ d" g$ z$ L
  159.     case StageFinishing:
    0 r$ D( F. m' x  X4 \3 X( F
  160.     {
    ' x# k& \- h. C" U
  161.       receiveStageFinishing();
    : s, B; e3 B3 r5 @
  162. 4 S& t* X5 N) ^: u% K2 h9 _
  163.       break;
    / F/ O* f# W1 v6 B$ p% a
  164.     }6 ~; z+ E# `. o, e. w0 H+ |) _
  165. 1 ]% N4 c7 ^8 A
  166.     default:
    4 D2 \$ g8 y! W+ X2 I* N# E4 F
  167.     {- E5 l% \2 N" |8 Z
  168.       receiveStageFinished();
    9 L7 H. K2 q; d. y/ k; ]- P
  169.     }1 J/ x3 H, p+ h/ p
  170.   }
    % A* e* |8 h2 j
  171. }
    ) i4 N6 m( g+ V. y. B* S9 t  {
  172. ! B* z6 B, L! t: M0 U
  173. /**
    8 e, h$ D  R+ E+ e$ L
  174.   * @brief  Ymodem transmit.
    $ j: K" W; p& P1 P  p6 C, U
  175.   * @param  None.
    - \$ |% z( H3 W+ |$ q2 \
  176.   * @return None.0 B* `- J2 d& o" X) b" F1 V: d9 ^
  177.   */
    - I, C6 q/ E0 e$ ]
  178. void Ymodem::transmit()
    * x% s- b4 v4 j1 |8 t
  179. {
    % d0 B; |. g0 H
  180.   switch(stage)/ J* _5 y7 J  j* J' I6 O& x
  181.   {
    . L( m) `( q; Z- e' P( i
  182.     case StageNone:0 t. w7 y& }, L# o
  183.     {
    + x. _, h: P1 d; c! D! ?
  184.       transmitStageNone();
    : A$ h& t6 {( @" h4 k0 T

  185. 5 y6 U& X0 C; s. x7 N
  186.       break;
    & A! h. \% i( F1 u& U6 X. q5 l$ ~# h
  187.     }  T3 p' H# M# h: S4 M5 p
  188. ( V% t5 ]) c% F+ I4 G( D
  189.     case StageEstablishing:; ^' _! }+ `' @
  190.     {
    . u: k% J/ B; p5 I8 L. h, y7 ^
  191.       transmitStageEstablishing();
    ; R5 f- |6 n" w6 n1 S

  192. ) f4 r& w9 {' D: d* R+ G" e
  193.       break;! z; w! ]- w0 m' o; K4 U+ N
  194.     }
    % p, Q8 b7 b, y. s
  195. $ U- X8 }) D* V! n" s
  196.     case StageEstablished:; j/ u9 T8 m! n- A# I
  197.     {
    : b; I/ \" v8 G6 N4 a2 w0 u" b- a# k
  198.       transmitStageEstablished();
    ) H% f1 m. N7 }" e( s) V
  199. 5 Y" v  H" T8 i+ p+ g
  200.       break;" C6 a  e# Z- c' L1 n
  201.     }: s& O) X3 b- |2 M1 \; b
  202. ; f8 U0 m+ @1 I
  203.     case StageTransmitting:$ m# o, W0 u6 p& e
  204.     {
    2 r- z. u9 p( D5 P2 N# y
  205.       transmitStageTransmitting();7 f( ^/ W: v9 d% x& z4 {
  206. " o! R$ r4 i: Q  e
  207.       break;
    2 i" E+ w! v+ p
  208.     }' V7 Z4 y$ n- \6 n' @' F
  209. . A) z  U8 U% H+ A
  210.     case StageFinishing:, ^( y( ~, t$ C4 N" j
  211.     {
    8 V' O7 T' W; T+ X
  212.       transmitStageFinishing();! z% z4 l: |0 G" [/ c- r: z# T

  213. % m) d2 @9 G8 `) t
  214.       break;
    9 I9 c  v- ^* m
  215.     }
    . X4 `7 P7 B' K
  216. 7 f( \% V8 Q7 ~
  217.     default:
    . j* u. l) z7 T% O( |# c
  218.     {- v) r+ `) i4 `
  219.       transmitStageFinished();& @1 ]# [0 `$ Z. b
  220.     }- c* G: l3 S7 l4 A5 a5 K; u" q
  221.   }; F4 l* F* ^3 y# |/ c) ?7 a% m9 v
  222. }
    " D( U. _9 [; o' o9 W# Y3 G- T1 A( E
  223. ! L& l: J, h, Z0 t; W9 C
  224. /**
    ; i! l& a9 I( A* }9 R( B1 Y4 Z( S
  225.   * @brief  Ymodem abort.
    ( T4 l, e, [; S8 h$ ]0 s8 ~8 S$ G9 D
  226.   * @param  None.
      e# R& |4 V+ ]
  227.   * @return None.1 `8 k# L  D, L  N- C
  228.   */6 a; {- _# s8 w" ^8 x' I
  229. void Ymodem::abort()
    - j% |- B1 k% F1 s2 l/ ?
  230. {  ~% {, i5 ]! t4 J& W
  231.   timeCount  = 0;
    & s; x7 {: j9 e; y0 S6 w# Q
  232.   errorCount = 0;9 i% [8 K; p- h0 [2 t
  233.   dataCount  = 0;8 H  j  e4 A  t! X6 n( R, O
  234.   code       = CodeNone;6 a. U8 G2 ]+ |; K% I
  235.   stage      = StageNone;
    " r3 _+ f# e2 j/ g0 L. f

  236. 7 w6 K% ^9 K+ v
  237.   for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    4 I$ X" Q6 p4 U6 V9 L; b; d
  238.   {
    $ e5 [- }" q1 S3 W1 s& a
  239.     txBuffer[txLength] = CodeCan;
    ; A8 s7 s$ L+ s# `. O5 l
  240.   }1 S: y8 b( }% v: L

  241. ' n, a$ v7 g; w$ Q5 D
  242.   write(txBuffer, txLength);
    ; }/ J" W" M9 H: w
  243. }
    5 x# x# E3 a3 F2 s5 ^9 c
  244. ! a! {7 G1 ]- B6 I( _
  245. /**
    2 z6 @3 u% K/ p) ^7 A& D
  246.   * @brief  Receives a packet of data.! v$ j, q9 t. p
  247.   * @param  None./ i  T& D0 N# p! o1 n) R
  248.   * @return Packet type.5 p  u6 d* f2 b. D% Y9 C
  249.   */- W2 N9 I( P' ?6 }% I6 S" g- |" V/ a* i
  250. Ymodem::Code Ymodem::receivePacket()
    5 I6 J) M1 ~& b- Q. X$ Y
  251. {- K$ m+ O3 ]2 _, T! Y8 y
  252.   if(code == CodeNone)
    6 T& H3 o1 Z9 c, }5 ~# @
  253.   {1 t  Z6 F% F: P
  254.     if(read(&(rxBuffer[0]), 1) > 0)- l0 p# n) t! q/ w( ^8 i
  255.     {
    2 Z" N. V% n$ T3 L$ h( p
  256.       if(rxBuffer[0] == CodeSoh)! K& O9 g4 K. n. O5 H6 [+ o' ]
  257.       {
    6 n: h! Z& A; M6 e2 k0 N
  258.         uint32_t len = read(&(rxBuffer[1]), YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 1);, K$ |0 v, j1 {0 t0 m
  259. 7 q7 ^* a( c# {$ h) X7 p
  260.         if(len < (YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 1))6 N4 \2 Y' N4 Q5 U7 Z  c
  261.         {
    # Y6 R$ p' m: M0 W  r3 n
  262.           rxLength = len + 1;
    & @/ L: d+ M6 T. W6 a$ t
  263.           code     = CodeSoh;
      g' G: p1 o+ |6 ~7 W. b( `

  264. 1 d0 {( s: X9 M6 W( p
  265.           return CodeNone;
    9 Q; b, O8 X4 m! C0 P, u
  266.         }
    ; |( z; a+ ]- B' S- |; P) b
  267.         else/ g3 C# |1 K/ ~; g' z3 g* @' X
  268.         {
    7 L, ~2 F4 J4 R8 Z0 k# ?: A8 W
  269.           return CodeSoh;
    & @! G( @* e9 T# b1 }/ ]
  270.         }* t! B4 w, G+ @) Y' o
  271.       }
    5 S: Y  r: o) c' D1 b: }
  272.       else if(rxBuffer[0] == CodeStx)  y# ?9 S3 N$ }7 ]
  273.       {/ y7 v6 ~! ]# y3 q
  274.         uint32_t len = read(&(rxBuffer[1]), YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - 1);
    ! t+ p8 Z; c4 }! P! I
  275. 2 b+ q6 D# S3 z3 g9 @4 X! D/ x
  276.         if(len < (YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - 1))6 W$ a$ a; e2 X& @  q
  277.         {. K, K& B! ~9 V8 w
  278.           rxLength = len + 1;
    . Z% f6 J8 @7 s' U" S
  279.           code     = CodeStx;7 Q' E; D1 W- [6 O
  280. . t7 |' k% U) A: ?/ P$ t6 B+ G
  281.           return CodeNone;
    - j% S5 E1 ?/ O9 F# D
  282.         }9 @1 P  f# M6 q- p# `
  283.         else1 T2 ?0 Q% T, b4 j
  284.         {
    " E3 N3 T6 g& q9 I4 ?. s7 f  x! J
  285.           return CodeStx;9 q3 L6 m, L& Y/ v9 s6 y
  286.         }
    4 v! [9 x1 s" S
  287.       }% F- p2 G4 z/ v) j5 l2 D0 ]2 s/ O
  288.       else9 r6 C9 z, p& J" F0 `, j, p8 \
  289.       {8 r; V8 b' U5 q8 b$ P  V& E. A
  290.         return (Code)(rxBuffer[0]);0 t" t* B! n( `) a2 c
  291.       }
      q, g# c0 k7 |0 p- d7 F
  292.     }
    3 Q  [; r+ q5 l) D8 {, [0 H
  293.     else
    % i; Q9 g8 s/ y" N# m# N. u4 D0 s
  294.     {
    4 U; x, `+ [' [
  295.       return CodeNone;
      H$ m3 d( B' f6 l# R$ [
  296.     }
    % |+ S* T8 }- W5 V) a7 K
  297.   }
    ) u/ O7 m- \+ b) m
  298.   else
      s1 K, a+ J3 }! X
  299.   {! K& f, U6 e1 j: X
  300.     if(code == CodeSoh)
    " R: R3 B: P1 v
  301.     {" E' \0 C' F$ Z
  302.       uint32_t len = read(&(rxBuffer[rxLength]), YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - rxLength);
    1 v& n3 f6 t+ B2 O7 }

  303. ; l7 N  Z) q9 o: V, M
  304.       if(len < (YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - rxLength))
    . z) o/ l7 f' k2 ~- z5 p
  305.       {
    ) K5 {3 l9 G) q5 K3 U1 S8 B0 h
  306.         rxLength += len;/ y3 f; j6 G# d0 j2 \1 F
  307. + G! E2 L# m/ g' M) M. x3 ], k
  308.         return CodeNone;5 G9 M0 e  ]% P# e# R1 c7 y$ O
  309.       }# A8 O4 Y3 b$ a& @4 r$ D/ x
  310.       else* P, _, z- q4 q3 [7 _6 H7 R
  311.       {
    3 j5 v1 U" Q1 l) K( T0 s7 R( L
  312.         code = CodeNone;
    # w7 c4 g3 k  m# x# n/ e- [, |1 k3 y
  313. & c. r# [% x: @1 Q7 d
  314.         return CodeSoh;. |- Y/ [0 ]+ x1 n$ N( N
  315.       }
    : }+ w" h; B* j2 o- q9 @
  316.     }
    # G8 a( y, u( i3 u
  317.     else if(code == CodeStx)
    ( b" y$ |  a  O% g) `: y: R4 j4 e
  318.     {
    5 {8 L) l' V( Z  v& x* o
  319.       uint32_t len = read(&(rxBuffer[rxLength]), YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - rxLength);
    0 ?* I* R7 _+ ~; X2 i& t9 h# g

  320. " {7 K& O2 u2 }8 Y( X% \$ E
  321.       if(len < (YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - rxLength))
    8 c5 D1 p" g, f, `
  322.       {
    ! v) _& Q) U/ M* F2 I
  323.         rxLength += len;
    " G& z) \( @. I5 x" o
  324. 7 f! ~: S+ v& l! E! y7 s% |
  325.         return CodeNone;% V3 {: U9 _, @: p
  326.       }" `& }& K2 H  w  o
  327.       else( G/ ]2 S9 J! V1 x
  328.       {& M  S8 U+ \" l2 u) N2 `
  329.         code = CodeNone;
    ! ]) ~, P. ^8 G1 i0 O, T. s: C! E" L/ W7 M
  330. ) l8 G: l& c4 J. }
  331.         return CodeStx;: J( n& M7 E4 j( R' E
  332.       }
    , u! K8 R2 e9 C6 Z7 S5 K" w3 U% f
  333.     }
    * V, O, [/ \4 E$ X+ V% \
  334.     else5 A3 i0 o& K6 b' }) m
  335.     {6 k* P: S5 Z) `
  336.       code = CodeNone;6 C' I! K2 U$ M5 C9 B

  337. : L# g" H* D) B7 Y! M
  338.       return CodeNone;' E  K# J$ t  s6 n" X, a
  339.     }& v3 L2 v; b7 {0 H9 k
  340.   }
    ' _4 H9 {6 V2 Z' Y: P) p
  341. }! s% E1 i+ t4 G5 d7 w+ o6 i
  342. ( T& a( U" G- j9 ~0 N( [1 T$ s
  343. /**, G7 Y! a' \- ~5 r. O% N
  344.   * @brief  Receive none stage.6 _/ s% C. n8 c0 u6 ]% G0 n, @
  345.   * @param  None.
    " [0 f* {4 a  f/ _
  346.   * @return None.
    ( n! C% k+ {: |; ?8 K* ?
  347.   */1 |8 t$ g' @8 ^& \& |9 {2 I
  348. void Ymodem::receiveStageNone()* M* K( `- W9 A" s4 P
  349. {
    . _8 y( s9 H) I4 h) N
  350.   timeCount   = 0;
    . U, ?  M. {2 c0 J) n
  351.   errorCount  = 0;
    . \( P1 J0 N8 X: }6 o( e. ~
  352.   dataCount   = 0;
    5 O4 w3 I( Y! A
  353.   code        = CodeNone;4 T1 q/ J' M0 V" V6 r' g
  354.   stage       = StageEstablishing;
    4 A% X) Y- N: q2 S$ u4 _) g5 a: x
  355.   txBuffer[0] = CodeC;3 H) ]) b! `; X6 Q0 Y" s
  356.   txLength    = 1;
    8 n/ R9 l; c" \7 q4 r+ U
  357.   write(txBuffer, txLength);
    7 m, d6 @* [6 L6 I+ F5 N
  358. }, A& P2 O8 X# `5 n, e! s  L6 z
  359. 4 o$ L, h+ Z+ v7 B" R
  360. /**, C  }: H* L" q) Z4 S& D7 t
  361.   * @brief  Receive establishing stage.7 n- V) }: o1 [# I" S
  362.   * @param  None.! N5 `, z/ j- z3 ^- w+ N: h* N
  363.   * @return None.
    4 |$ T5 c" I* s! x& I
  364.   */
    ( ]3 S  M5 O4 z5 U- A) ^
  365. void Ymodem::receiveStageEstablishing()2 J" B0 m7 m* l
  366. {+ Y% l( X: W/ g" D4 C
  367.   switch(receivePacket())1 t( Z* j) @  X" N% Y$ }0 J% V
  368.   {3 V" u2 n8 u# Y4 w& z! D( F2 t
  369.     case CodeSoh:
    + H* j, e3 M- P, J8 t
  370.     {% d  P1 h- T# ^: K
  371.       uint16_t crc = ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 2]) << 8) |- m# B9 B( U' {& t
  372.                      ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 1]) << 0);* i* N9 b2 {* i  r% s

  373. ; k" J) V; @. N$ k) w
  374.       if((rxBuffer[1] == 0x00) && (rxBuffer[2] == 0xFF) &&
    ! ]6 w5 y  U2 b4 j. o
  375.          (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_SIZE)))* R6 `1 C( L$ ~( i4 H7 ?/ G+ B
  376.       {
    + R4 l, h4 p/ Q) ^; E
  377.         uint32_t dataLength = YMODEM_PACKET_SIZE;
    4 \* ?6 |2 w5 r$ z

  378. ( `$ |% E- ^9 o( }. p5 p) y
  379.         if(callback(StatusEstablish, &(rxBuffer[YMODEM_PACKET_HEADER]), &dataLength) == CodeAck)) g$ V( U9 {+ p) o% t4 e; ]" q* b$ h  C
  380.         {
    + V( Q; N9 f$ ]
  381.           timeCount   = 0;
    ' g! [2 o2 {! K$ ~: ~& @* _! W
  382.           errorCount  = 0;6 L# Z2 F* v5 U9 L! q7 {4 a% ^
  383.           dataCount   = 0;
    " ]# L4 \8 C- _
  384.           code        = CodeNone;: ~0 \3 G; o$ \' s" H" e% M7 A
  385.           stage       = StageEstablished;( c( p/ \* c4 k2 @6 o
  386.           txBuffer[0] = CodeAck;
    6 g0 W) @2 V6 j
  387.           txBuffer[1] = CodeC;
    ' T0 {% o7 S( O) P
  388.           txLength    = 2;2 R- @$ U% W% p
  389.           write(txBuffer, txLength);8 T  G. Q7 k$ y. K, E* I5 q/ J- h
  390.         }
      Z9 Q+ t$ |2 A2 \- J' r+ A0 @
  391.         else3 }3 Q+ {% J3 \( N- f1 k8 V
  392.         {
    % x4 \! i0 ^+ E6 F& m
  393.           timeCount  = 0;# d# H. Y9 B! J8 q- h4 r/ B+ D
  394.           errorCount = 0;( R/ O1 c1 f/ w# N2 L' X
  395.           dataCount  = 0;
    ) ]$ \! i! I8 c) z+ F0 x* Z1 M, _, x
  396.           code       = CodeNone;
    4 S4 W2 p' _; m! g1 F5 G6 i
  397.           stage      = StageNone;+ {% O; _# v8 Q! N6 @: V% C, J

  398. 4 h) k  T5 L$ B' `
  399.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)6 W7 G% K9 n$ J# O
  400.           {! q. U0 Y& q8 R& `; Z3 _2 o3 U" ?
  401.             txBuffer[txLength] = CodeCan;3 h( A* I! W6 D
  402.           }
    " Z6 ]3 K4 _7 ^% l4 V
  403. / z" X7 p4 ^8 ^* g2 i  F
  404.           write(txBuffer, txLength);
    3 z1 G8 X% ~3 {$ c3 V
  405.         }1 q: `( l9 Y. `
  406.       }2 T5 o. I6 T) u
  407.       else
    6 a5 D) I9 }) \
  408.       {2 B  S& _& E" K9 R
  409.         errorCount++;" [8 T+ i# X( s4 b' x% \9 n. b8 t

  410. # w# |3 [* H2 U7 ]
  411.         if(errorCount > errorMax)" g7 h* ?6 w  j; x) ~  T& b
  412.         {, a/ Y+ @6 s0 S1 N- N5 T
  413.           timeCount  = 0;
    $ S: R( X) |" \( ^: m) d
  414.           errorCount = 0;) y. i! \6 u( N3 d# {* [: W
  415.           dataCount  = 0;+ ?8 y+ C* M6 M  ^& u/ @
  416.           code       = CodeNone;
    ! a" @- ?7 v& G0 _& r
  417.           stage      = StageNone;) U7 E+ [8 ^- |# l

  418. 7 w, L( @" f* d; F
  419.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)4 e4 o4 b' S; I2 c9 b" g
  420.           {
    % H! N3 H9 }4 f! Z, n
  421.             txBuffer[txLength] = CodeCan;
    + _7 b0 z* d  {# `: V" H- B  Y3 ^
  422.           }$ w" D# I- b1 \7 F! h- z) ^) F( w& g

  423. 6 B( r7 T5 T4 p0 k
  424.           write(txBuffer, txLength);
    " E, |5 Z& T( I7 m0 H' x; X' J
  425.           callback(StatusError, NULL, NULL);- u! d0 D/ i/ h& T# ^* r
  426.         }
    % Y7 f9 r# g8 [3 Z; k$ U5 A
  427.         else4 r: V0 E9 F) u% I! O
  428.         {$ }0 g% B: j5 o) {4 `
  429.           txBuffer[0] = CodeC;
    9 t; P" g5 Y/ o4 N+ B) }
  430.           txLength    = 1;
    0 s) P' v. i3 z7 `
  431.           write(txBuffer, txLength);
    4 ~+ s. q$ Q# k% y8 F7 e
  432.         }
    4 h+ p2 H5 b' }' M& E1 c1 c8 G4 Q- i" T
  433.       }
    7 c  H) E1 S3 |) v1 D. D/ ]; B
  434. - X* _2 d( i* W
  435.       break;
    % v3 W3 ], e) Z
  436.     }
    4 C, [1 a2 Q# z7 i- q

  437. 9 r9 t& `. L- x3 e
  438.     case CodeA1:
    & ^# q# V; s. n% }9 f
  439.     case CodeA2:
    / ~, U, [' \  I( m8 B$ A
  440.     case CodeCan:
    ( x9 ~# E1 I, \& C8 S
  441.     {8 y/ b0 ~5 \$ m
  442.       timeCount  = 0;
    + s8 P( s9 C4 V4 B
  443.       errorCount = 0;
    7 |' U1 C; a; U* t# ~. s% z& s/ Q
  444.       dataCount  = 0;
    + |8 ]/ j" T9 r3 @) c: `
  445.       code       = CodeNone;
    * ]0 ]' J! J2 U' k# S; c
  446.       stage      = StageNone;# v! \0 i) N5 B% D; Y
  447.       callback(StatusAbort, NULL, NULL);
    " G9 p! V. E8 @% ~  f
  448. , `: a$ O7 M. b/ {8 y
  449.       break;
      d" \* j- ^" J, k; h' O
  450.     }. A+ p1 }( K% b7 F6 E
  451. 3 k* G& w5 }' Q0 e; `8 A- {# {
  452.     default:
    2 x: K3 Q; E% w: c9 z
  453.     {
    3 e6 ~! w  i3 ]7 h
  454.       timeCount++;# i. c# r4 h4 f. H1 Y
  455. 9 |' X4 i0 {; Y$ |8 Y$ d& q0 O0 D
  456.       if((timeCount / (timeDivide + 1)) > timeMax)
    , z  Y4 b  h: j4 k
  457.       {
    + M( S1 {) S0 V3 k3 C$ ~2 X0 W
  458.         timeCount  = 0;
    % ~1 H* T+ g2 t9 y8 i( c$ G
  459.         errorCount = 0;$ E9 x) a1 z  b% T5 l
  460.         dataCount  = 0;3 e8 B$ U, \# e: Y+ ~: q$ x% ~
  461.         code       = CodeNone;! \7 A& y3 p4 l1 M; P
  462.         stage      = StageNone;& U9 Y' c4 W/ e' i1 X

  463. $ X2 A5 a' R% |& R
  464.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)/ F6 |8 _3 b( z$ q( k( H- T* f
  465.         {2 l/ h0 {+ L2 b' _9 u0 v% e
  466.           txBuffer[txLength] = CodeCan;
    & I; d# w+ ]8 K
  467.         }2 i2 i  H. r# a% @3 q6 x: e( V1 z+ n3 Y

  468. * R" ^7 F" q/ ^: x
  469.         write(txBuffer, txLength);
    5 }. G9 @2 k9 H1 K# G1 U
  470.         callback(StatusTimeout, NULL, NULL);
    : q/ ~7 }& @% Y1 E1 A9 t. y
  471.       }
    % c" K1 ]( a" ^2 }# a' y# P
  472.       else if((timeCount % (timeDivide + 1)) == 0)2 r1 B9 g/ ^) e* w# H) W
  473.       {
    . m% Y$ c) Z- u) ]
  474.         txBuffer[0] = CodeC;
    $ x, r* L" V) e+ C: q6 S' `
  475.         txLength    = 1;
    4 i% _0 U$ X! m, h8 x0 G
  476.         write(txBuffer, txLength);
    + b6 Z8 x5 O5 W/ _
  477.       }
    ( q2 J% F2 o0 ?* u
  478.     }
    " T6 z" ?! b( `* h# a$ i6 g7 N
  479.   }1 S$ h& x4 E& C3 Z: O
  480. }8 c1 G8 M) }' H. O' r5 P) t
  481. 0 `( t: d! I3 P  u
  482. /*** o% I8 D! }, q
  483.   * @brief  Receive established stage.7 x- d. q7 _7 ^0 n1 q6 M* c
  484.   * @param  None.4 |, |# p  u2 a0 r# _) M! ]% [
  485.   * @return None.7 w  m4 P1 h! G* S  m1 ^
  486.   */! [7 k' D% z8 i% I- G2 M
  487. void Ymodem::receiveStageEstablished()
    . ^7 Y( b/ U  u' v6 i" T9 t# q! t" }
  488. {: k% w3 J" Z; z- U0 I$ _; v2 f
  489.   switch(receivePacket())# z1 E2 m2 e; V( n
  490.   {/ c$ ^2 t2 `9 h
  491.     case CodeSoh:+ }) B4 }, z6 T: z% ~' c+ Y0 Z- f
  492.     {; z" L6 r- L- Q5 y' l4 l& |
  493.       uint16_t crc = ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 2]) << 8) |5 r/ f, J( b" O7 T1 S$ V- s
  494.                      ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 1]) << 0);7 L  \; O* Q2 {- I9 S; q/ c
  495. 8 h. G) z3 t8 U/ s* L* J
  496.       if((rxBuffer[1] == 0x00) && (rxBuffer[2] == 0xFF) &&3 h7 ]4 J5 J8 A
  497.          (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_SIZE)))1 T6 T9 u0 k+ E' Q+ E; _
  498.       {" P0 G" z+ F1 W" R$ U
  499.         errorCount++;" E5 I3 e# P+ t
  500. ' C" o/ p2 |1 K0 E( i3 A
  501.         if(errorCount > errorMax)
    6 p  d/ i+ e' n
  502.         {. w  L$ Q9 ^+ w, ^2 J- [4 E
  503.           timeCount  = 0;" d2 u* a  z! Y6 s1 Q
  504.           errorCount = 0;
    " V7 ]1 _( y( x" g* g; e) F$ M
  505.           dataCount  = 0;
    & g( w2 E, `' Y5 L8 k
  506.           code       = CodeNone;# m0 r; \4 O! N; I% y
  507.           stage      = StageNone;
    ( _* q- q3 ?* m+ Q+ e# k& \. }- H
  508. 0 B; E. S2 F5 C/ ~1 k0 ~/ I
  509.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)  i4 v! V$ u, W1 L0 g1 U. v
  510.           {* _, a- y( ?! x8 h( o8 {) |. T
  511.             txBuffer[txLength] = CodeCan;
    - d: o( }) [& i% k
  512.           }+ J8 y4 G: s' P" \; i
  513. 2 G$ v8 `, f4 P& x/ i9 D! C
  514.           write(txBuffer, txLength);, O( }" \9 u+ w+ i* j$ T  q0 B
  515.           callback(StatusError, NULL, NULL);
    7 ^1 {4 z( `- _* v7 W9 U$ x( P
  516.         }, G! c: e# s+ W3 @1 g' M
  517.         else
    2 e  f/ U3 H; D  j- ?3 _
  518.         {2 p) _- d$ q5 ]
  519.           txBuffer[0] = CodeAck;
    ; y7 z; b. [3 \( I8 |
  520.           txBuffer[1] = CodeC;8 q$ G/ A6 u4 E. T( i+ L
  521.           txLength    = 2;
    ' ^7 A, ^( g9 a* R) C  y8 z
  522.           write(txBuffer, txLength);
    ; y; ]/ Q7 t3 x0 K4 j& @4 u$ c0 O
  523.         }
    9 V  z" ?. d8 Y- n! ?: n
  524.       }0 {. g, v/ O2 G, Q' M
  525.       else if((rxBuffer[1] == 0x01) && (rxBuffer[2] == 0xFE) &&
    ' P; Q8 Z3 |' D3 m$ {1 ^/ `+ |
  526.               (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_SIZE)))
    ! z+ T6 P7 f: b% z6 g% n
  527.       {
    & H; r: p% ~, R. L5 [
  528.         uint32_t dataLength = YMODEM_PACKET_SIZE;
    ' z0 F- ^: F3 H& E7 T6 }

  529. 7 O5 Y3 i; P4 s- f
  530.         if(callback(StatusTransmit, &(rxBuffer[YMODEM_PACKET_HEADER]), &dataLength) == CodeAck)4 l0 L; C' P) w+ A2 r! Y* R
  531.         {
    & J8 \) }, A) u% `# m8 P' ?$ F
  532.           timeCount   = 0;5 I4 ]7 T0 j! k$ W
  533.           errorCount  = 0;
    " s! B; N. }% V/ X+ o0 S% p
  534.           dataCount   = 1;
    1 p9 w' Q# W0 o6 A2 Q& v( |
  535.           code        = CodeNone;0 P& e% C, W/ L- n
  536.           stage       = StageTransmitting;
    ) v5 f5 @* g- w# {: u# }) x3 B" e
  537.           txBuffer[0] = CodeAck;* M& G  Y9 g7 p7 C0 B
  538.           txLength    = 1;! i) s6 ^/ H" L4 z' |# a! l
  539.           write(txBuffer, txLength);
    3 X6 N# p  D- `5 u* a
  540.         }
    : ^4 p2 Q; h9 D) u5 r
  541.         else
    - V+ c. V5 l! g1 ^
  542.         {) ~/ P2 t! X0 q% ^8 U
  543.           timeCount  = 0;1 w/ W; X$ k) t6 R" J: c+ }  g+ p6 D
  544.           errorCount = 0;* e+ Y+ a; O, m# G$ _  p" |
  545.           dataCount  = 0;
    ) v7 O" G* k5 w, \/ b+ M! b
  546.           code       = CodeNone;
    + b& R7 l. I" ^
  547.           stage      = StageNone;
    / u/ S) X# v3 ]3 w: K

  548. ; A. j3 f+ v& U, f* {! I
  549.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++): e$ K5 Y; W" m6 z" @: s
  550.           {
    % a5 ^* j) i" |3 T
  551.             txBuffer[txLength] = CodeCan;) }9 A' h( |  I, C& f% n/ q. n
  552.           }
    8 H( i9 @- I9 m9 R; S7 F
  553.   y: f8 u0 l/ V* M
  554.           write(txBuffer, txLength);
    ( U& [6 p& C# E7 r3 l. L
  555.         }- A& u, j7 N+ B' T* y8 v3 s
  556.       }9 i# U% K. _0 j) V9 L, E
  557.       else
    2 R/ b; [& V+ }
  558.       {
    ) F& }- z2 V" N" C
  559.         errorCount++;" {! P; ~6 s/ B% O8 K. y
  560. ! N+ e3 [0 }' @
  561.         if(errorCount > errorMax). `$ S* X) z/ M3 d1 c: s
  562.         {, f7 J/ e; N6 P6 R' a$ E$ A0 w  [
  563.           timeCount  = 0;: y7 l* H" D" a6 o
  564.           errorCount = 0;; @" ]( y+ w5 e. B3 H1 C) @- l# U
  565.           dataCount  = 0;
    1 ]9 [5 [1 n8 n% c! K
  566.           code       = CodeNone;
    5 e/ t9 o" j- S9 |% s% E$ M
  567.           stage      = StageNone;$ Y" f* S/ J6 Q5 g! ~+ S

  568. 0 h) {; ^+ c& i
  569.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)$ R4 }8 W2 e( B: B
  570.           {
    , }' F8 D$ n$ K* O% l- p
  571.             txBuffer[txLength] = CodeCan;
    - i3 w4 Z' x  p9 a4 C8 `# L
  572.           }$ w0 Z2 a  s3 a# L

  573. / I0 S5 z6 v; V4 e3 C
  574.           write(txBuffer, txLength);
    ! v& @+ `" b& l# h: X* L! l
  575.           callback(StatusError, NULL, NULL);
    ) h. \9 [" D# w! p9 D( N7 N9 y
  576.         }- G3 S( }0 O) W' L
  577.         else& k9 U- N8 }- S, k- A8 J
  578.         {
    $ \% e' t1 E7 q1 E
  579.           txBuffer[0] = CodeNak;
    3 F/ w0 ^" T( S& c
  580.           txLength    = 1;
    9 A3 _* ^( \* p# O1 Z
  581.           write(txBuffer, txLength);
    2 O. S# o4 ^; a% _8 g% o6 a
  582.         }  F; Z& L- ~6 n& z0 r
  583.       }
    " X+ \3 X& ^% z" l% K! Y
  584. / `, z: L; o/ ~5 g7 W( i
  585.       break;8 E/ q6 G8 w) [. ?# L
  586.     }
      ^- h4 M& D& j6 W4 ?. S" o) [

  587. " I' ]& B- w2 J5 m  x
  588.     case CodeStx:
    8 t6 v# {$ S5 i* F! F5 ~
  589.     {
    ' J* F* z0 K2 L2 e$ t
  590.       uint16_t crc = ((uint16_t)(rxBuffer[YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - 2]) << 8) |
    " O. d6 r7 n3 U4 v
  591.                      ((uint16_t)(rxBuffer[YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - 1]) << 0);$ W! B$ b- a. ?" J
  592. & B  b  j7 X) b$ Y( r
  593.       if((rxBuffer[1] == 0x01) && (rxBuffer[2] == 0xFE) &&
    + l$ B7 f0 V4 S7 v7 r
  594.          (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_1K_SIZE)))
    : B/ T$ u+ E" j: D9 a- p( V
  595.       {# o$ P4 M0 I0 c5 n. B4 ^- g
  596.         uint32_t dataLength = YMODEM_PACKET_1K_SIZE;
    , ^; Z" Y. _1 x, m- Y5 ^

  597. / G) B2 z9 ?: G! w# r
  598.         if(callback(StatusTransmit, &(rxBuffer[YMODEM_PACKET_HEADER]), &dataLength) == CodeAck)
    " p3 L; s( U/ B. \8 o
  599.         {
    " Q) g7 q! N. D( P
  600.           timeCount   = 0;" F' v4 h/ g( d' E1 K' P
  601.           errorCount  = 0;
    ' s3 L( k- l7 l/ {2 x( R3 |3 s
  602.           dataCount   = 1;0 }4 w- H* S2 `* T3 e
  603.           code        = CodeNone;, P. S- \9 [$ G6 z4 W' Z4 I' u
  604.           stage       = StageTransmitting;
    ; y1 j; |* a7 q# G; n+ L* F
  605.           txBuffer[0] = CodeAck;8 _' Y! s" F$ {: E
  606.           txLength    = 1;' @) q5 j: I2 {! O8 V6 d* T
  607.           write(txBuffer, txLength);/ B  {$ i; L4 t; |9 j0 Q1 W, t
  608.         }& x2 Z  v; o4 |8 J
  609.         else
    % R2 J1 _$ C1 L1 ?6 B/ C) j; w
  610.         {
    9 [  b, ^5 g8 G
  611.           timeCount  = 0;4 h( |+ d/ o" w& o0 @+ M# o
  612.           errorCount = 0;( Q* e$ I+ ?2 J
  613.           dataCount  = 0;. N! o3 h, v) ?0 v3 v$ x& G
  614.           code       = CodeNone;. ~5 W% e% ~! O/ y/ V4 F: K
  615.           stage      = StageNone;1 ?0 t3 x( o& J. `5 I- |% S% h2 O

  616. ; j& d4 G! f, f2 x* V
  617.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)0 o6 T- ], r2 D3 [9 u$ w
  618.           {+ C6 j. S; ~% n; q
  619.             txBuffer[txLength] = CodeCan;
    1 i' S/ H+ v% \* [
  620.           }
    ) e0 p( \- P& G5 Z; s
  621. . U, \5 ~: z" W8 e8 b
  622.           write(txBuffer, txLength);
    . @. x* N4 b2 j; N9 I' l3 b; X
  623.         }* `6 D% J  Q8 N; M" k) F0 u
  624.       }( M" `% p. R" {; J( d/ V) }2 a
  625.       else/ J4 x8 t: f" l. `
  626.       {" m  h; _2 F+ G
  627.         errorCount++;5 d$ N' X$ t8 Z: a* ]1 o$ c

  628. . {3 g5 B3 R6 M8 l8 W6 I7 O4 h
  629.         if(errorCount > errorMax)
    + {. A. Q8 V4 L( M% N6 Q0 u
  630.         {
    " c7 n: X, f) s, s' o$ b0 |6 d+ h
  631.           timeCount  = 0;( e# ]. j/ T- R: a
  632.           errorCount = 0;
    9 ^. v+ U7 I/ h* a& s. e
  633.           dataCount  = 0;
    % e  e  I& [! O: _; f/ F" f% W
  634.           code       = CodeNone;
    1 L, l5 R  J% r- W* M; I* h
  635.           stage      = StageNone;/ h7 Y( v4 s! |2 s  T; J! g
  636. $ @0 p$ `) S# w; o
  637.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)' c/ ~# z% s% o( e
  638.           {
    . m  ^( F$ m, u8 y: P7 S+ J# t# e
  639.             txBuffer[txLength] = CodeCan;
    4 g! |4 D, a; Q
  640.           }
    , Y$ U" b9 a5 f# x- G0 S) o1 u8 f6 c

  641. : |& h9 Y( e4 @+ P* N
  642.           write(txBuffer, txLength);- D' q: N; @7 p6 O, v8 o
  643.           callback(StatusError, NULL, NULL);
      M8 s1 C$ X$ ~2 ]; Z
  644.         }
    ( h" `# ?8 e# g  n" K) k& M5 `- H
  645.         else
    , _* e  |+ B+ \5 ~6 }# X8 g" S) Q
  646.         {+ q) A1 F. ^/ {
  647.           txBuffer[0] = CodeNak;2 G& _6 h$ X" G) K9 g9 g
  648.           txLength    = 1;7 X. u8 @# F) b2 v, c7 M
  649.           write(txBuffer, txLength);8 l. l7 k% A8 K% h& i1 m8 E6 A
  650.         }
    3 u) P  S, j$ t: R7 N
  651.       }
    - R5 |& F% N5 W" Z1 e" \8 q

  652. 4 A2 i7 X; `$ Q  b! i$ ^
  653.       break;
    * s( }( f  r) F% l, ]( `
  654.     }
    1 V' o9 m* A4 I0 X2 j: l4 G  v. Q% G

  655. + X3 j8 S' G: `5 q8 _
  656.     case CodeEot:' E& Q$ f: c, ~1 S
  657.     {( A: j) L  |3 F+ L6 O9 l
  658.       timeCount   = 0;
    0 R: S" z* J+ d4 M& g: A, c8 n
  659.       errorCount  = 0;
    & p' f8 G! I' R) z
  660.       dataCount   = 0;
    $ ~# Y5 U+ ~" W- E) W
  661.       code        = CodeNone;
    7 Q: ~* ^. l1 w2 p% D. s
  662.       stage       = StageFinishing;
    $ h: A- q9 t% v! @0 s" I
  663.       txBuffer[0] = CodeNak;
    + T  N! I1 u8 ^2 F
  664.       txLength    = 1;+ d! z2 \- N# `0 O  c# b% X/ k5 k
  665.       write(txBuffer, txLength);
    ' B/ _+ J! h3 U9 Q% W

  666. 7 y% h; a. |. `- D
  667.       break;
    & Q4 `4 H6 B. t, O4 m
  668.     }
    $ T" g1 e7 P' V0 z
  669. - o6 g5 }( o% h, `6 |% R
  670.     case CodeA1:, r" u' X6 \) e+ X
  671.     case CodeA2:
    8 ]% U) q* I3 t7 o5 ^9 m
  672.     case CodeCan:( W0 Z- e' ]0 R2 \6 Z
  673.     {/ |  a/ ]% h9 D5 v& k3 h4 [% }* W
  674.       timeCount  = 0;
    : z, E$ I& k+ V& P4 y
  675.       errorCount = 0;6 i4 u3 o' u3 j# D
  676.       dataCount  = 0;
    9 O* |" d  I4 h5 K) d5 d
  677.       code       = CodeNone;4 J8 Z6 f) G3 l5 `$ d
  678.       stage      = StageNone;
    # L) B( v$ k0 V& }2 v" f" x
  679.       callback(StatusAbort, NULL, NULL);# P' B: q/ P  F' I! l
  680. 4 j) o. \* H  `: x' F& @+ a
  681.       break;3 x# |5 n8 D/ y( L  f
  682.     }
    : o  s! v" D9 |+ B4 w2 E. H

  683. $ u* v* H5 F1 p, V
  684.     default:6 K) C! P$ j9 h: X
  685.     {7 Y. i/ g% J9 B+ W6 Y- f- {; z
  686.       timeCount++;" w5 p7 ^6 T8 O0 s" [

  687. ' h; Y: f  {/ H0 q, V( m; Z  e
  688.       if((timeCount / (timeDivide + 1)) > timeMax)
    6 ?/ V7 g$ L" L# q
  689.       {
    ) z' u; _: L% k7 y
  690.         timeCount  = 0;4 i0 s0 H! r- {: d/ H
  691.         errorCount = 0;
    : {: U, F/ u# b, {5 J
  692.         dataCount  = 0;) H0 C  @7 M5 Z" y$ r
  693.         code       = CodeNone;: J9 K5 P" i/ A% e2 }9 H
  694.         stage      = StageNone;; i1 c- {, E# `

  695. ) r- u. y6 G8 x  F/ w( G+ ?
  696.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)4 F8 V9 Q8 @! e
  697.         {1 i+ Z, `7 L4 q' X/ M  E
  698.           txBuffer[txLength] = CodeCan;
    * E7 K# f. T; U' o8 j& S9 Q; [
  699.         }; T3 U: a& C1 V  `$ K

  700. ' g0 V+ O5 t9 k- M
  701.         write(txBuffer, txLength);! q) o% D% _0 R% Z+ n
  702.         callback(StatusError, NULL, NULL);3 |4 V1 a: a! o. P
  703.       }" Q# N( B2 ^: g! e  Z
  704.       else if((timeCount % (timeDivide + 1)) == 0)3 {! s8 ~7 ^/ n
  705.       {7 a4 m  A2 v0 C/ i0 t
  706.         txBuffer[0] = CodeNak;+ X0 B; F% W/ ?( S2 v4 A' |% _/ S
  707.         txLength    = 1;9 f/ B6 Y5 s6 |/ R: I* `3 {  {
  708.         write(txBuffer, txLength);
    1 @( c# [+ K+ h
  709.       }: f: @; S# p3 H+ L/ x
  710.     }* t: x# A) J4 ^6 M; l$ t
  711.   }
    8 _1 r: ]5 {1 Q% ]
  712. }& r% m* d5 n* _' ?2 g. {
  713. 5 v- u( p! w5 x/ W4 o
  714. /**
    6 W# X+ K# k, d% S& J, t6 n( @
  715.   * @brief  Receive transmitting stage.
    - B2 {3 O$ D9 u! c, F4 L6 S0 R
  716.   * @param  None.
    ' J& w1 _; @/ a4 Q2 |' e
  717.   * @return None.
    8 W9 z6 V" j/ V8 [7 C
  718.   */
    5 v& S' }! ^+ c* k/ n9 o
  719. void Ymodem::receiveStageTransmitting()
    $ Y# u- |* w) A9 N1 W2 H! ^1 m
  720. {4 R/ Q; u) J6 T) P2 K
  721.   switch(receivePacket())3 L% u5 K* ?- p- \& m/ L
  722.   {
    " u4 s) O8 |4 Z
  723.     case CodeSoh:
    : `3 N7 g1 t7 O5 E3 N: P
  724.     {
    3 D+ f' z, `8 Q9 v/ g& P6 B
  725.       uint16_t crc = ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 2]) << 8) |, Q) y+ i4 u& M. K/ o/ h
  726.                      ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 1]) << 0);
    . j8 a" E- E; I6 a( q1 y2 _
  727. : F5 m" V% c* s8 h9 J
  728.       if((rxBuffer[1] == (uint8_t)(dataCount)) && (rxBuffer[2] == (uint8_t)(0xFF - dataCount)) &&; s- ]$ n; E3 @2 }# I# K. N) _
  729.          (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_SIZE)))
    ; I$ Q$ Y* S% e$ G
  730.       {
    8 B2 ~9 i( B% K! L6 u  Y/ V8 k) c
  731.         errorCount++;
    0 T$ [  o' f! e, k0 {6 c
  732. ; `* Z  t# L" q8 `9 Z
  733.         if(errorCount > errorMax)
    - ^; y4 l* N9 W/ S! [; ?9 H8 q
  734.         {+ t' t& l( _3 C- \% e9 S6 ]
  735.           timeCount  = 0;
    3 B3 X- w* Y1 [$ {5 w1 B$ D' N
  736.           errorCount = 0;- d: S# O. z3 g: u4 y: r! h/ c# n
  737.           dataCount  = 0;2 D5 n  C0 R/ ~8 R
  738.           code       = CodeNone;2 f4 Z2 D* n4 a/ N- H0 x
  739.           stage      = StageNone;
    & b2 E7 I: _! X5 i
  740. # ^4 J. c# O6 e& p0 ~
  741.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    + U, C; p$ }7 Y4 F3 z4 z
  742.           {  n9 d7 i3 w+ K" ^5 `
  743.             txBuffer[txLength] = CodeCan;4 x5 i- z" z5 v' x3 H
  744.           }
    6 w) l% k* c  e1 L8 I

  745. 5 @# V4 p* N, f; ^# K. L4 i5 l: y" {
  746.           write(txBuffer, txLength);' |0 W& B7 f; |, s% Y8 t- t
  747.           callback(StatusError, NULL, NULL);
    , V, D: U: g6 P
  748.         }5 g7 E, K4 Z8 a3 G0 z$ C; |, T
  749.         else
    . x* U4 D  w9 Q. [- p# f" U
  750.         {1 I( U9 h; C6 \. L8 F3 ?; {- H
  751.           txBuffer[0] = CodeAck;
    % L1 l$ {$ p% R4 i$ ]" ?2 l7 ~
  752.           txLength    = 1;0 H' Y  Y. L  o0 R
  753.           write(txBuffer, txLength);+ F% L( R4 D+ w+ P) m6 ^
  754.         }
    . ?2 I( r8 k  q- g6 I
  755.       }* h1 d4 F( {8 r/ e* |: r8 c
  756.       else if((rxBuffer[1] == (uint8_t)(dataCount + 1)) && (rxBuffer[2] == (uint8_t)(0xFE - dataCount)) &&' a# M! [2 K/ G% t. W) q, K2 z) }
  757.               (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_SIZE)))
    ( {" n% w6 k# [/ E) }! S
  758.       {$ |9 [. [- h" R. q
  759.         uint32_t dataLength = YMODEM_PACKET_SIZE;9 s  r& |' ~; X3 g
  760. : e0 [2 `- A# \- Y5 @* T
  761.         if(callback(StatusTransmit, &(rxBuffer[YMODEM_PACKET_HEADER]), &dataLength) == CodeAck)
    5 I/ h* u$ B  _8 s4 S2 k
  762.         {0 F5 h/ Z1 }# R8 f
  763.           timeCount   = 0;. m* r3 O" x5 g
  764.           errorCount  = 0;
    $ h' h* m/ l) O, X
  765.           dataCount   = dataCount + 1;
    ) J+ u  Z4 n3 G$ W, v0 D, |  F2 K
  766.           code        = CodeNone;8 s1 j! _( t1 K( ~' B4 ]4 J% X
  767.           stage       = StageTransmitting;
    - O$ I4 i6 V- r4 _  Q4 e4 l# z
  768.           txBuffer[0] = CodeAck;0 |0 ^2 A! G7 [3 N3 h2 x& _
  769.           txLength    = 1;
      P" d2 @* T' S  z7 [
  770.           write(txBuffer, txLength);! ]4 f- f/ O5 ~7 `2 n; Z! l0 _
  771.         }
    2 F( R$ @! n, g4 g
  772.         else
    8 G; v" N% `$ ]5 M1 |
  773.         {
    # P1 n$ ~2 \( k) p
  774.           timeCount  = 0;+ O/ A% |' x( H/ e& h3 x3 i
  775.           errorCount = 0;5 }, H! p# Z6 b! [% w/ x+ k
  776.           dataCount  = 0;
    6 Z% _; q7 J' ]+ M* z+ X8 d" t
  777.           code       = CodeNone;
    / ~6 r  i& ^4 g2 d% T
  778.           stage      = StageNone;# ]' C( S2 P' P* F7 v
  779. 6 }( ]- I! F. A( f+ j
  780.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    ' V  }. \" B6 B# e
  781.           {- F$ \# Q7 d0 `% [/ ]
  782.             txBuffer[txLength] = CodeCan;' x6 B- c: g6 ~/ f
  783.           }
    " A; d* x( p& R; A: {
  784. 4 k( ~- g6 y& Y0 P
  785.           write(txBuffer, txLength);
    1 r$ ]! F3 d; e6 E. u
  786.         }
    / R8 ]3 Y, k: Z" w+ M' @
  787.       }
    # T  R: [/ P, A, Y/ T6 s
  788.       else9 g8 D  i. h" Y! X3 F
  789.       {; c2 r8 L3 a/ o& M
  790.         errorCount++;
    1 B; j: ]$ K+ r/ h1 l; ?. v' ]
  791. / g& h0 n: o& i6 a% R$ n& _
  792.         if(errorCount > errorMax)2 `' C: g) G2 s. n
  793.         {' u2 l/ p! z1 H9 u( F" N# W7 d
  794.           timeCount  = 0;* ~4 E/ D: t) N1 U. [' i* s* Q
  795.           errorCount = 0;
    / r+ y, f; N3 F0 F2 s, {
  796.           dataCount  = 0;4 i. T+ Z" v* }5 b# u
  797.           code       = CodeNone;: s2 u2 i" P: S
  798.           stage      = StageNone;
    , X4 B5 u& [& V" b  K- z

  799. " ?+ K% [# H0 C/ {+ h
  800.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    2 M) R& i" S7 ~: q# d4 Q
  801.           {$ [  ~, O% E( B  A
  802.             txBuffer[txLength] = CodeCan;
    ! `; b9 K; ?! _' U9 M$ I
  803.           }8 l' X4 \) F8 x: n9 M% z

  804. 2 N  o: N6 ^- i) r
  805.           write(txBuffer, txLength);/ N( |, l8 u" G; a) R5 q
  806.           callback(StatusError, NULL, NULL);; O6 R+ H5 X$ a$ x8 E, P
  807.         }
    $ j$ m; K$ ~0 d; K
  808.         else
    : e) L7 e/ G- @+ P3 x
  809.         {* |; F2 y  o8 r1 c" W9 r
  810.           txBuffer[0] = CodeNak;( P6 ~* X: H4 i. L0 d
  811.           txLength    = 1;% R+ b4 I" \" A6 g: r3 h. V+ O
  812.           write(txBuffer, txLength);
    0 E/ e, O7 E7 `
  813.         }
    & \, C; E* C) s, D0 ?1 _5 @
  814.       }7 o! `  u! p* R/ s
  815. * d5 \) K  b, Z
  816.       break;% b3 ?+ p, v3 K) y* h) o
  817.     }) q0 G  S8 s4 q2 i3 B- @, k3 [' M% s
  818. : K* d" H- h- X) G( L
  819.     case CodeStx:2 d7 P! z2 k4 W- C
  820.     {# A; c+ y3 H. d  P! o$ v6 l" x
  821.       uint16_t crc = ((uint16_t)(rxBuffer[YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - 2]) << 8) |& ]. T- N9 N: L+ T( Y
  822.                      ((uint16_t)(rxBuffer[YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - 1]) << 0);0 b8 \3 ~: e7 p$ u5 W# D% y

  823. ! x- m8 M2 V& }' F9 k1 \! w
  824.       if((rxBuffer[1] == (uint8_t)(dataCount)) && (rxBuffer[2] == (uint8_t)(0xFF - dataCount)) &&  Q9 N! A5 j/ M( i+ u
  825.          (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_1K_SIZE)))
    ; c$ ~5 m/ |! z, o4 E
  826.       {
    ( s" R% u6 W) E7 G7 B" n4 D$ g0 ?
  827.         errorCount++;
    1 {! h- s( i( ?/ C! p0 \' d
  828. 8 U+ |6 y) r( i! U1 P; G
  829.         if(errorCount > errorMax)
    : C4 q) a: X. ~+ V" n
  830.         {& ?6 j# J3 |# y$ ~( f) P
  831.           timeCount  = 0;+ X  g, P# t  S' G, y& r3 s
  832.           errorCount = 0;$ w: r: [8 q# J7 G# \. }$ M
  833.           dataCount  = 0;
    " ~# g3 z8 Y8 @: j; O
  834.           code       = CodeNone;
    4 d7 Y# h0 _0 q# g. m. c; X
  835.           stage      = StageNone;& \/ D7 S/ c3 [% F6 J  [
  836. 0 Z. `5 Z' t, t8 `! K" G
  837.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)/ e/ b8 }3 D- X9 ~" A
  838.           {2 z4 p  h  J$ g+ {0 s  X
  839.             txBuffer[txLength] = CodeCan;; ?, u" w* n) U8 r, k8 l
  840.           }
    " m9 U, v  D! P7 r! C( M6 `
  841. 2 T& o4 P7 D7 y* Z3 [
  842.           write(txBuffer, txLength);/ q( L6 C- c  H" `, x1 t
  843.           callback(StatusError, NULL, NULL);
    : D8 S4 Z) A! n$ t7 b! m
  844.         }# y# |* f* C, J' \- m# X
  845.         else
    2 ?2 A2 X* w' ]7 N$ {
  846.         {
    - b5 ]$ _4 Z/ P9 c, [& m  x: ~$ c
  847.           txBuffer[0] = CodeAck;
    7 j: y* q  D" M1 _( e: d6 L
  848.           txLength    = 1;! L9 A2 K6 g! P5 i
  849.           write(txBuffer, txLength);! j% ]' D7 |  ^# L
  850.         }
    0 E# P, r+ R7 f: G2 ?+ ?: j
  851.       }. Q7 U8 n: R, f8 m+ ^( f  ]
  852.       else if((rxBuffer[1] == (uint8_t)(dataCount + 1)) && (rxBuffer[2] == (uint8_t)(0xFE - dataCount)) &&
    2 p2 {4 e+ D5 V+ s
  853.               (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_1K_SIZE)))" T1 d5 N- o1 L' d; @1 a
  854.       {
    ; q( ]! h. L! u& O
  855.         uint32_t dataLength = YMODEM_PACKET_1K_SIZE;) }4 `) z1 {% E; D) t; c
  856. , ]" W5 e' f/ @$ Y  E! x9 f
  857.         if(callback(StatusTransmit, &(rxBuffer[YMODEM_PACKET_HEADER]), &dataLength) == CodeAck)
    ' [! c( `/ [' B$ F8 T
  858.         {
    + o- H- c; Q. t, x- }
  859.           timeCount   = 0;) Z- ?( P% n/ j+ {
  860.           errorCount  = 0;
    8 N/ b* V! J; T! j% |- M$ O- }. \
  861.           dataCount   = dataCount + 1;" ?( v) k2 r1 H$ ^3 O1 w
  862.           code        = CodeNone;
    7 P% `8 z# ~" u( `. l. i! q0 k
  863.           stage       = StageTransmitting;9 d1 p% H' i  o$ a" H. m
  864.           txBuffer[0] = CodeAck;8 L9 b% Q1 ]/ h. g$ r
  865.           txLength    = 1;$ S& s7 z" l/ P8 U. T
  866.           write(txBuffer, txLength);( i0 y1 Q( C6 j2 X
  867.         }
    & |8 T/ M6 m' N! [  g
  868.         else% `4 p, c- s8 g  g( ~
  869.         {
    ) M( ]2 ?& B. A+ ]! X
  870.           timeCount  = 0;
    8 o6 v/ B1 _! T( Q
  871.           errorCount = 0;- N3 N: [' m( v' ~3 v% v
  872.           dataCount  = 0;
    / R& A: Q$ C. Y9 ]
  873.           code       = CodeNone;
    + ~" Y" v  R3 P7 _
  874.           stage      = StageNone;& W) u7 |7 s% Q. h2 c' @* ~. F- E

  875. ) }: u) P% x" _- @6 |4 U5 M' N
  876.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++). U! }, g$ c3 F1 w$ \1 O
  877.           {8 v: r; o# v. B# p
  878.             txBuffer[txLength] = CodeCan;( o; l& i* m7 I( v9 @- V! K
  879.           }0 O9 Q' p8 y% v7 Z' z

  880. 3 y5 Q+ T8 M5 c. G) c: f
  881.           write(txBuffer, txLength);7 r. t: Q- _5 V+ H8 O6 F; @
  882.         }- ]* }, I2 y% j4 L% H# ?( I. u
  883.       }
    , Q$ v. i5 d. g
  884.       else
    2 C: i) f8 |$ h0 c/ r& D
  885.       {
    7 ?$ O8 T: L7 ~- x" N, C
  886.         errorCount++;
    * g) I% z, X3 l; o& S

  887. 5 Y; O- t" U% N( H/ X8 c; }4 |
  888.         if(errorCount > errorMax)* H4 G  d. [, [4 S7 a8 F1 ]
  889.         {
    6 _/ y2 o' @7 h
  890.           timeCount  = 0;
    # C5 a/ d0 O+ _5 s; k* i2 W
  891.           errorCount = 0;
    ( Y0 z  r% @5 f2 S
  892.           dataCount  = 0;
    5 z' U' w+ \! D; b. O" N
  893.           code       = CodeNone;' o0 O) e$ Q3 Q% A9 P( k
  894.           stage      = StageNone;7 f8 n$ \( }$ W# @1 N

  895. , V8 P7 r9 v* N+ i
  896.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)7 N6 O9 H# B' ~8 a2 ]6 p: w( x
  897.           {
    & q' {, V9 w5 A+ X* }, S$ P
  898.             txBuffer[txLength] = CodeCan;; O) U; Z- y' E* q2 `* F( ?! S7 Q
  899.           }
    * q4 }  h" Y0 u6 i) t9 W

  900. ' }. f+ J" g9 ]
  901.           write(txBuffer, txLength);0 {5 [1 c- l4 N4 Y' p( F* S
  902.           callback(StatusError, NULL, NULL);. a9 x5 Y8 x' O' @" v( p
  903.         }
    . d; N$ p. w* z. Y# ^5 z5 j
  904.         else+ q- P9 `9 a- a( a1 i; v# b
  905.         {
    ) q. K2 S. |/ r4 G
  906.           txBuffer[0] = CodeNak;
    / F1 y/ A, f" z& x6 w9 g
  907.           txLength    = 1;
    . U* C! @- j  ?0 d3 }9 d& T
  908.           write(txBuffer, txLength);+ ]; b0 ]4 V/ K" M* L" H
  909.         }
    1 j4 @* a3 i* Y, i4 ^
  910.       }! U1 d( B, k' M2 l! F( b! k# l
  911. ! a( ?8 ~  T5 F7 u
  912.       break;
    & |  C5 @- \) y1 R% f
  913.     }9 ~3 q* h0 _! ]1 w

  914. 9 [% i5 {8 |# Z$ @- ]
  915.     case CodeEot:
    , \5 A$ e( c) _- T) @' ^
  916.     {% r$ Z" g8 T" ^8 L1 L( I3 `  }
  917.       timeCount   = 0;
    : H4 v: Z5 [+ A2 @
  918.       errorCount  = 0;( I. [1 ~0 o  [" v6 w4 {% Q5 X4 p- [1 @
  919.       dataCount   = 0;
    " h; d6 y3 o) e, j/ p9 @$ y# x
  920.       code        = CodeNone;
    6 G% X4 i0 ?7 Q. O1 G' Q
  921.       stage       = StageFinishing;* N5 Y- J+ ^) I& u9 M: @& b4 e3 u
  922.       txBuffer[0] = CodeNak;
    9 c7 _( i& l) W9 g! x$ ]
  923.       txLength    = 1;
    8 D, ?- D9 D4 |
  924.       write(txBuffer, txLength);
    . W% Q- n5 w+ J& g) R8 @$ b3 @$ Z' y

  925. 0 X2 b" ]3 E+ V
  926.       break;; A9 B% j' A1 ?2 p: [: Y
  927.     }9 |# N$ a6 d( O  V2 u
  928. 4 q9 `5 e, ?1 Z
  929.     case CodeA1:% ^0 X; @7 y, e2 ^" M; E4 d5 i% j" |7 V
  930.     case CodeA2:
    $ [2 q2 `; S) ]
  931.     case CodeCan:6 R7 J1 X" ]9 A, s
  932.     {
    4 P+ m# Q# D  j! Q! N
  933.       timeCount  = 0;5 t5 f- f6 r: V. A2 s* G
  934.       errorCount = 0;  \) W* {% J7 }
  935.       dataCount  = 0;; f$ V- N8 o  D* l. L( s( ]5 m  |
  936.       code       = CodeNone;
    * ^' y4 Q# D0 p* g. L: A1 e+ m; j: X
  937.       stage      = StageNone;
    2 m) }! V3 }6 Z! S1 w% u0 W
  938.       callback(StatusAbort, NULL, NULL);
    ( ?; C. l: b6 M" ~
  939. 7 x% C, D5 I5 S" \* p9 Y0 o
  940.       break;
    + x, |4 @. }6 S9 R. v
  941.     }
    - u/ y1 c5 ?4 x& d$ f6 [+ k

  942. ! ^, U, X% k9 A' f/ v5 b6 g
  943.     default:. e' r( I) V2 c. p1 K9 w. w9 b, K; o
  944.     {
    5 @" c7 o+ `+ X6 y. f4 k" d- \+ S
  945.       timeCount++;; p! E+ X$ f7 l$ x7 e

  946. $ V6 ]  L2 A+ y0 _( T
  947.       if((timeCount / (timeDivide + 1)) > timeMax)
    4 r  s$ t; W; _
  948.       {
      y3 L* D, c' N2 o7 e" s0 v
  949.         timeCount  = 0;, o, j) @" k2 z, W9 @+ [
  950.         errorCount = 0;, V+ v: Y4 [) f. F( v
  951.         dataCount  = 0;. X! \+ V1 C. X$ I, r
  952.         code       = CodeNone;
    5 j* y' w% p( V9 A6 E( `
  953.         stage      = StageNone;. S' N% e  j2 ~6 e8 Q  H+ _

  954. 9 ]3 b- i) w$ }4 H2 O/ X0 V) V
  955.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    ' ]* Q$ ?# N# P, L; G
  956.         {9 [) R$ @' @' l" s# ]" s$ D/ C3 I
  957.           txBuffer[txLength] = CodeCan;
    " ?9 V1 F6 J' `; |! p
  958.         }3 k" y/ G. v+ m# X- M

  959. 2 s) O" M- }' P* \: T# Y
  960.         write(txBuffer, txLength);( n" H" T2 V, ]# e6 N: g! Z
  961.         callback(StatusError, NULL, NULL);
    3 R8 u9 S. B6 m% W8 }! |
  962.       }
    - o2 P; f! L) Q$ a1 T6 E" D! p
  963.       else if((timeCount % (timeDivide + 1)) == 0)
    - p# C5 n2 ?. P1 C9 t& }0 P
  964.       {1 M5 w, D; `4 t+ \; R
  965.         txBuffer[0] = CodeNak;
    4 t( F- S+ p3 \/ w
  966.         txLength    = 1;6 T+ u) g) w' e4 g9 ?
  967.         write(txBuffer, txLength);2 A' l3 \  f9 }% o
  968.       }
    & l0 \6 H" g. a3 L# E- N- \, W
  969.     }+ S& O( Q0 z' w/ @0 n7 t
  970.   }
    ' v8 k( U2 D' X* t% D. U
  971. }
    : |  C6 D' J, u- ?
  972. ' |! n3 K, F, O. ?1 O& {4 }& a1 _; m
  973. /**
    " ?* G/ ]/ U. U' D5 C/ g2 i
  974.   * @brief  Receive finishing stage.
    + _! n7 o' _! K
  975.   * @param  None.
    - q& I& ?# m5 A2 L: ~0 |% c
  976.   * @return None.
    1 T. g9 v8 s/ V9 l) s1 s
  977.   */* _3 Y% w+ U* ]  ?( U' x
  978. void Ymodem::receiveStageFinishing()
    ; `) I4 O% I) F2 a$ V! Y4 a& X
  979. {
    ( l  |. K9 {; S- e! _
  980.   switch(receivePacket())
    8 ]5 D' e% M- ]
  981.   {" D9 T# v: K2 m0 b' c, q
  982.     case CodeEot:1 l/ H2 Y2 u  [' M5 z
  983.     {4 x' _. {3 H- j" W# @- _3 s$ q
  984.       timeCount   = 0;3 w3 c/ m$ ~5 s1 O- ?* L
  985.       errorCount  = 0;0 V8 }+ B$ O; z; P
  986.       dataCount   = 0;( L$ Z8 Q2 E2 {/ c
  987.       code        = CodeNone;
    6 n( G2 N2 |0 t: k
  988.       stage       = StageFinished;
    1 B9 N1 f0 c$ c4 X- j8 ~; D! d
  989.       txBuffer[0] = CodeAck;
    & b1 ?8 O* Q2 z6 I0 {
  990.       txBuffer[1] = CodeC;
    7 u: E( |2 q, A7 t
  991.       txLength    = 2;6 q6 t6 r" D7 v. Y5 x* D8 j2 g
  992.       write(txBuffer, txLength);: w5 d) u% H6 {- Z
  993. & Z  i3 w4 k; b1 v1 g
  994.       break;
    ( m+ X* Y3 K. l$ C6 e! C
  995.     }
      e: E1 h6 W$ C! H9 O
  996. / L! Q, |* f0 S( E
  997.     case CodeA1:; e' J7 C- @1 ^$ s% u: g
  998.     case CodeA2:
    * x# z# A$ d3 Q. J# ?5 L8 ?
  999.     case CodeCan:, j, Y! v( }4 X5 N, i1 K
  1000.     {  g* a' s6 y2 f8 F9 D4 o
  1001.       timeCount  = 0;3 Z+ F! d- ]6 R
  1002.       errorCount = 0;' _; X5 ^/ u* w7 d6 |
  1003.       dataCount  = 0;
    # _! s$ T* ~6 }: x
  1004.       code       = CodeNone;
    9 s0 b' B) y, z8 B- @' x$ T
  1005.       stage      = StageNone;
    + `+ B. I) i5 x5 W/ A% C0 `
  1006.       callback(StatusAbort, NULL, NULL);
    + b& \$ A6 f! S* U
  1007. ; q: g: c/ ~& ~  f" s% r: Y8 e
  1008.       break;
    . q7 y( g0 r9 N( p
  1009.     }
      O7 a$ }$ ?& h, k. N
  1010. 3 b: S7 p3 Y7 b, E9 l% z- {. {
  1011.     default:
    : c. D! ^" j( C# C: E, h
  1012.     {( u: K  e; d! X# R7 a) O" U
  1013.       timeCount++;  S% O8 _. u5 ~

  1014. / B5 g% S; U+ r1 _6 v5 d5 a
  1015.       if((timeCount / (timeDivide + 1)) > timeMax)5 K% ~8 @& @* l2 ~  W
  1016.       {. A4 ]3 i' I4 [
  1017.         timeCount  = 0;6 a4 P. S( v( o5 Q! ?
  1018.         errorCount = 0;
    4 t8 D, O2 p+ l* T; s3 F. w1 l5 Z
  1019.         dataCount  = 0;2 ^9 m4 O# t; J9 L# E0 `- i
  1020.         code       = CodeNone;
    & A# q& d2 r3 c: J6 `" T! u
  1021.         stage      = StageNone;
    ' S/ w+ d& I3 C, i$ I% \

  1022. 4 U0 E! v, j( q2 N
  1023.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++): J! T! S* h( ^6 {3 L
  1024.         {3 L+ `$ C* S$ H4 S
  1025.           txBuffer[txLength] = CodeCan;1 _/ ^1 N% Z" u- c3 a" G
  1026.         }# y- X0 D" Q6 m0 B9 U7 T

  1027. % d4 z+ S4 |: s
  1028.         write(txBuffer, txLength);
    & E7 ^# Q# s7 d& A
  1029.         callback(StatusError, NULL, NULL);4 B# c! p6 r. ~* I
  1030.       }# ]& c8 H, `4 D* F" c: G$ A. w
  1031.       else if((timeCount % (timeDivide + 1)) == 0)
    2 W) _4 d0 X" r$ M1 I8 G; {1 y" ^
  1032.       {
    . R6 ?; S. k8 x; t  t7 @
  1033.         txBuffer[0] = CodeNak;5 c0 M6 @# z  |8 c8 \0 I
  1034.         txLength    = 1;
    $ a# d, L8 k# R( r8 ?7 s* {7 t
  1035.         write(txBuffer, txLength);
    4 W( N" s7 x& X) F9 ?
  1036.       }
    % g' D" s0 v" U
  1037.     }
    3 M2 Q) G% f* o" X1 E' f* Y1 h: e
  1038.   }" i/ v! ]  \7 J4 |* ]9 I
  1039. }
    ) z# L* I3 q, F  n) c  g

  1040. - w5 p0 u+ K, T' b. Y6 f
  1041. /**
    % U  ]& r  _5 t" I4 `
  1042.   * @brief  Receive finished stage.2 g+ R5 [2 m& X! Z. s
  1043.   * @param  None.  d( ~; d* A+ k3 n% z' b( K0 T- s
  1044.   * @return None.
    4 w+ B) _- q7 o9 G( t8 [! K/ M
  1045.   */% {1 W; U/ A+ W1 k+ D
  1046. void Ymodem::receiveStageFinished()
      e' _+ R3 X! S* Q
  1047. {
    0 N+ r7 A2 Z! \7 X/ N
  1048.   switch(receivePacket())$ q% f, A. C$ L! ^6 E: J
  1049.   {7 @) k; f/ }0 j% k% k! K$ D+ a* c% d
  1050.     case CodeSoh:( ?' K+ p  |- z% m2 y# K4 ?4 c3 }( {+ z
  1051.     {
    ; {$ Y" J  \* ^$ r
  1052.       uint16_t crc = ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 2]) << 8) |  n+ m: g3 j& s8 W4 p
  1053.                      ((uint16_t)(rxBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 1]) << 0);# ~" O4 ^! {8 v) p

  1054. & C  @2 M1 |- q% u/ E5 \
  1055.       if((rxBuffer[1] == 0x00) && (rxBuffer[2] == 0xFF) &&
    / |2 y3 X9 H' {' {/ r
  1056.          (crc == crc16(&(rxBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_SIZE)))
    $ U6 A1 Z2 E2 _( r4 x
  1057.       {: |) m2 ?0 L& G& M3 i- o
  1058.         timeCount   = 0;# E* G6 V& d% m, b# b- {( h0 T
  1059.         errorCount  = 0;' w* ~- n2 i2 [7 J7 @5 [; V' {+ n8 W! u( A
  1060.         dataCount   = 0;& s$ O8 J+ B6 t2 E. A
  1061.         code        = CodeNone;
    * R4 @# M1 A; r' Z9 w! P' o$ @) `  P. b4 V
  1062.         stage       = StageNone;
    6 O2 t# E* O9 W* ~+ t/ r
  1063.         txBuffer[0] = CodeAck;
    , O/ W: F9 Q6 p8 W) z
  1064.         txLength    = 1;4 u# l! |$ g8 y- f7 r( f& i: j" A. L- m
  1065.         write(txBuffer, txLength);. T6 u" }" O9 [5 h$ O
  1066.         callback(StatusFinish, NULL, NULL);5 T/ O) Y2 B4 n/ E9 B$ ~0 I8 H$ W
  1067.       }) f! _1 c. W4 @7 p
  1068.       else0 e6 O$ `( N! y# _& X- |6 V3 \
  1069.       {7 D5 N, a% y/ H
  1070.         errorCount++;
    4 V3 e, q- V, m0 R5 D* z
  1071. ; r# m. ?) @1 M3 B4 h- ^
  1072.         if(errorCount > errorMax)$ d+ L% |7 l* W/ o
  1073.         {  h% A* I5 a2 j8 D& A  a/ K
  1074.           timeCount  = 0;7 q. r/ T. G, V3 ~- |9 J0 f
  1075.           errorCount = 0;7 j8 S, G( E3 V) ]
  1076.           dataCount  = 0;
    ( H) r  P0 m# k8 B. z  B. p
  1077.           code       = CodeNone;9 i! n# w8 Y, l4 C5 O
  1078.           stage      = StageNone;3 `0 x9 U+ M9 ?6 h6 \% i
  1079. ' d; z/ L! X% }6 R  T
  1080.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    2 \* _9 d2 d* r2 J3 D8 Q3 @
  1081.           {
    * ]6 H4 z" N) a3 W7 I3 G
  1082.             txBuffer[txLength] = CodeCan;) p  J3 {5 v1 L& e- k
  1083.           }7 }% N& Z0 D/ ^  e8 [# Y, Y
  1084. ! \0 v% X2 G  a4 p3 J. E
  1085.           write(txBuffer, txLength);, w; x, w3 a2 W' u
  1086.           callback(StatusError, NULL, NULL);
    9 I4 b' \8 ^" |, ]$ e" G
  1087.         }& z# a  s% r9 x# m  p9 I9 d/ Z
  1088.         else
    * A- A9 d  a# q5 @
  1089.         {, ~$ J2 a' ~! ^! u+ b
  1090.           txBuffer[0] = CodeNak;
    5 K: T4 L) h, Y4 X' R
  1091.           txLength    = 1;
    , O' y( P% s& e9 y( ]8 m
  1092.           write(txBuffer, txLength);
    6 r' h  U& x. L$ i8 Z: J
  1093.         }, M0 w9 e4 f8 R' ^9 V
  1094.       }
    - R, M6 p1 M  v: x( l$ B
  1095. " X2 }; U6 d6 N) d
  1096.       break;
    2 d) Q3 l" d  ~
  1097.     }3 t1 @5 g; |$ Y1 E& e7 |. d% u6 s( w$ u

  1098. ' B  G) n( A! w( V2 e# U# }5 U- P
  1099.     case CodeEot:0 M4 Y: M2 `$ P) ?; T; a8 x) f, E
  1100.     {
    ( g4 t9 @8 D9 z5 W
  1101.       errorCount++;# ]# Z% j8 j) F# x$ Y9 w% f2 d

  1102. % B" S0 m+ H! a
  1103.       if(errorCount > errorMax); e2 W4 B' K6 g5 t9 p6 Z
  1104.       {
    + a8 f% t4 e) v( O0 w. X
  1105.         timeCount  = 0;+ A% a& x2 S5 L
  1106.         errorCount = 0;# G3 |8 Q* ~6 j" L7 C7 B
  1107.         dataCount  = 0;! ^. C2 A/ }3 E+ C1 r  k
  1108.         code       = CodeNone;
    + o& V/ f$ O4 c9 U9 T+ |/ s' A
  1109.         stage      = StageNone;; R5 j; P6 `7 T9 l# R# S0 ^  T3 Y

  1110. 8 S' E6 _6 C" @3 t
  1111.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)0 [8 d) ]" ?7 x; ?  M' e; b
  1112.         {: F$ E  c9 k7 {) J5 H
  1113.           txBuffer[txLength] = CodeCan;
      f; F5 f% C' o% L; \) c9 J
  1114.         }
    9 a* X0 S; ^; |0 a2 q8 s" q0 |
  1115. 7 [& }5 B* S- V
  1116.         write(txBuffer, txLength);/ l, F$ ?4 A7 J2 j( E
  1117.         callback(StatusError, NULL, NULL);
    8 S+ K# P" `3 D
  1118.       }. }* Q& c- C' I
  1119.       else: B5 W: M5 K' y- }+ I! ?8 g
  1120.       {6 L0 N, L" s! \3 G( m) `2 |
  1121.         txBuffer[0] = CodeAck;
    - j8 r" V4 e- i  A0 b
  1122.         txBuffer[1] = CodeC;
    & F8 ^4 G' G/ }6 B- x$ Q$ p
  1123.         txLength    = 2;+ L1 H8 t; ?4 d. b- Z
  1124.         write(txBuffer, txLength);
    " r& w) ]' C1 u% |5 M& ?* u* U
  1125.       }
    # g2 h! d% Z" I
  1126. & g5 i4 e8 @+ c
  1127.       break;
    ! I1 I1 f* w5 N1 V7 t+ p
  1128.     }$ q* p8 R& d) |1 u+ S5 p

  1129. 4 F" u4 O  S& F) W! ?- a0 H
  1130.     case CodeA1:4 I' j( m' u5 S
  1131.     case CodeA2:" q4 j0 r( R* h' [  I
  1132.     case CodeCan:# o- Z) P3 e6 l. s# r* w
  1133.     {
    6 J# g6 A8 Z2 f* ^5 ~) V$ A: J
  1134.       timeCount  = 0;# B$ N: T( J- U; t! }0 k! h
  1135.       errorCount = 0;
    ! E' @3 h5 f+ P0 W  y
  1136.       dataCount  = 0;* v7 K. ^5 Y: F+ @9 }, s0 o3 v
  1137.       code       = CodeNone;
    3 D0 _& E# d7 K( G/ W: C
  1138.       stage      = StageNone;* [7 j3 B- o; @' y8 ~2 [8 g
  1139.       callback(StatusAbort, NULL, NULL);
    $ h( G/ j) Q7 g, W2 O( o# E
  1140. & G! q7 s  R) `  _7 a
  1141.       break;- K$ i  ~' A/ y
  1142.     }( `) `6 \# U! X' I/ }  `  ?. |

  1143. . J0 o0 o% M. w7 L9 y) n" v4 ^
  1144.     default:
    8 _2 K9 O# h$ w6 W& ]6 b
  1145.     {
      m6 r9 }7 M- J6 X% o
  1146.       timeCount++;4 z/ [5 B5 A3 E, N. I

  1147. 0 V2 i, x& D  o% e
  1148.       if((timeCount / (timeDivide + 1)) > timeMax)* h' V: J- s& x1 L3 \
  1149.       {
    + |6 j; j! u1 h: j+ B! y* v
  1150.         timeCount  = 0;
    " d. u# ]- W0 T
  1151.         errorCount = 0;; H+ d! L1 r. }6 S% W
  1152.         dataCount  = 0;0 y4 L" A2 A% \- x! j: R- B. n& n
  1153.         code       = CodeNone;
    + `! h1 M5 F( O$ k) [& [  Y) g0 H* e
  1154.         stage      = StageNone;
      ^1 H7 T9 M! }9 ?2 ^9 k

  1155. 9 e5 n& X5 L0 J  ]& o6 ~( N6 P7 i: X- E
  1156.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++). i: E6 h# N5 c1 ]/ S
  1157.         {- o3 A' W# r! R. C2 K  k# C" H
  1158.           txBuffer[txLength] = CodeCan;
    7 ]+ ^1 z* x( ?, A5 {# r
  1159.         }; l9 ^& q5 d( M8 Z- @: E: P

  1160. " m7 ^9 p1 z( T& g7 \: d& D6 b
  1161.         write(txBuffer, txLength);0 B' J4 E9 C$ I* l/ P
  1162.         callback(StatusError, NULL, NULL);. B- q- o0 }' g9 ~7 h9 }
  1163.       }
    2 n: S2 E/ Q$ L# x) J
  1164.       else if((timeCount % (timeDivide + 1)) == 0)0 R+ L! l1 T6 `; I4 Q! q
  1165.       {* o* {# o5 F, j; S
  1166.         txBuffer[0] = CodeNak;2 T: [9 Z" a, a1 }- t( h
  1167.         txLength    = 1;$ \5 }9 _3 }/ ]7 }
  1168.         write(txBuffer, txLength);, g( R( `8 t" l8 u% x+ y& A
  1169.       }( T8 V3 o! O9 \, S$ s& b1 ^2 O
  1170.     }4 V) c4 s9 _6 M% D" @  `6 C1 M% G" t
  1171.   }
    ' x6 N4 J& @( [2 w9 b
  1172. }- R8 h1 p/ b# h; P, t! [& v

  1173. $ _2 u" a. c% W# `# d
  1174. /**
      t. [- r1 I/ h) c0 u+ t' [
  1175.   * @brief  Transmit none stage.
    ) `* @  o- I& S% {
  1176.   * @param  None.
    , O# k% X) ^7 T7 p8 K
  1177.   * @return None.
    . T. ?6 {) a. \
  1178.   */9 a2 _7 E; _7 ]* b0 s7 F1 t. v
  1179. void Ymodem::transmitStageNone()
    & m+ k, O) Z# N! D0 \3 P1 i
  1180. {" i9 R! Y* x' ^+ p
  1181.   timeCount   = 0;
    & ?7 b2 S3 W; E! Z: H
  1182.   errorCount  = 0;
    9 C# i2 N( y: U" g4 J4 F; _
  1183.   dataCount   = 0;
    % M/ E: ]% c' M9 x, T/ M
  1184.   code        = CodeNone;1 h) o: }; v; U2 Z/ D6 W1 H
  1185.   stage       = StageEstablishing;
    $ t/ Z4 s5 F9 y2 {2 Q
  1186. }) v! n; b$ T. i5 Z/ \+ N" ~! p

  1187. 5 ~& V. K0 q  f5 {7 ^
  1188. /**
    + `+ e  t; a6 J& p. I9 G8 C
  1189.   * @brief  Transmit establishing stage.
    ' s+ e7 h4 w+ M9 F. a) d# K
  1190.   * @param  None./ |/ m5 S1 b7 p5 x+ x
  1191.   * @return None.% J- p( m. _3 o* l' {
  1192.   */
    ( s& W' J8 M! e! S+ F' O1 x/ [
  1193. void Ymodem::transmitStageEstablishing()
    + ^' q! A  n' j/ ?/ y/ W5 [4 }
  1194. {
    ' u% e( I8 P  F2 S. U
  1195.   switch(receivePacket())
    ' h- J# Y' P- s$ c; f0 M6 ]2 a
  1196.   {$ [  Q$ T4 \8 k% Z# p3 i  L7 f
  1197.     case CodeC:
    : d% ?  }3 V# y
  1198.     {
    ( `' ^0 e; q( ]  h- |, y
  1199.       memset(&(txBuffer[YMODEM_PACKET_HEADER]), NULL, YMODEM_PACKET_SIZE);# u6 f% K1 r7 h1 Z

  1200. ( O& I' c: _5 _! d$ N
  1201.       if(callback(StatusEstablish, &(txBuffer[YMODEM_PACKET_HEADER]), &(txLength)) == CodeAck)
    9 j+ X4 e! A% G* N% J( n
  1202.       {
    9 j" w+ C. N+ [" d! }
  1203.         uint16_t crc = crc16(&(txBuffer[YMODEM_PACKET_HEADER]), txLength);
    4 V* ~. S& b# N" ^. p5 W: O! H
  1204. 9 [) @/ u2 Z5 @; e
  1205.         timeCount                                       = 0;
    ( Q) R; D$ I3 X! B0 i$ l6 M
  1206.         errorCount                                      = 0;
    6 N: K" P- R4 r! Y( Q3 R2 r
  1207.         dataCount                                       = 0;' {" K: U4 x3 s" v1 ^8 w
  1208.         code                                            = CodeNone;7 V9 P: g' S  ]( u
  1209.         stage                                           = StageEstablished;
    . V/ a4 A+ M4 i) m! x8 {/ S
  1210.         txBuffer[0]                                     = CodeSoh;
    ) m' t  b$ M7 U% I- \
  1211.         txBuffer[1]                                     = 0x00;
    $ E8 P1 V  |- w) ~/ i2 }
  1212.         txBuffer[2]                                     = 0xFF;6 [  q. P4 c6 w
  1213.         txBuffer[txLength + YMODEM_PACKET_OVERHEAD - 2] = (uint8_t)(crc >> 8);5 D% N* c( h; b) V
  1214.         txBuffer[txLength + YMODEM_PACKET_OVERHEAD - 1] = (uint8_t)(crc >> 0);4 V0 P- X: g: M7 V
  1215.         txLength                                        = txLength + YMODEM_PACKET_OVERHEAD;+ Y; g" Y3 b, r6 H9 H
  1216.         write(txBuffer, txLength);
      G, r: T5 T: U+ e$ o
  1217.       }
      G% q3 _) X6 j- k# ^" ?
  1218.       else& u6 K4 t6 J" W7 ^" x
  1219.       {4 v" h3 q2 p9 I0 ]8 K9 ]
  1220.         timeCount  = 0;7 Y6 U- ?) `/ m" t
  1221.         errorCount = 0;" i* D+ K! m3 e% h* P0 W
  1222.         dataCount  = 0;  _+ r+ j" B7 u, m# F' E4 T
  1223.         code       = CodeNone;4 w8 T2 i. F8 `6 A
  1224.         stage      = StageNone;
    6 B0 [9 x- m' f$ m

  1225. : R( N2 `, @0 z9 M+ N8 z% n
  1226.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)% C& D1 c/ N, j0 g7 ?1 g  x
  1227.         {
    6 j$ `4 B4 W# w' F, a# Y
  1228.           txBuffer[txLength] = CodeCan;
    , ~  I$ t# h5 Q! R; [
  1229.         }
    ! z7 A4 v3 J: r3 t
  1230. 2 M  V- `) v8 u/ J: W2 T
  1231.         write(txBuffer, txLength);
    % ^( b/ y; p- m# }9 Y
  1232.       }
    * _# {% G5 H2 `/ M! L* m

  1233. * y2 _0 M4 o8 b) B, H" `4 d3 X; d
  1234.       break;
    ; y7 t' V2 l/ R
  1235.     }; @$ M# K: d* M. O! K( k6 N

  1236. 2 b) e0 o8 F# f: [; Y
  1237.     case CodeA1:5 I* Q+ j+ S1 e1 x" D! h
  1238.     case CodeA2:9 w5 \5 j  c  ^. J( ?1 }2 ^
  1239.     case CodeCan:
    . ~8 R- b' l/ o9 _  Y
  1240.     {& }2 ]: m) O2 e/ t" R( o% {9 f& I) X# }
  1241.       timeCount  = 0;" q3 I8 d6 r$ R& {2 D4 G8 d2 o$ ^' E
  1242.       errorCount = 0;* ~% Y; N4 z& z  N* g
  1243.       dataCount  = 0;
    5 t% ^/ X& U: \  M5 u1 V
  1244.       code       = CodeNone;0 X6 |% R( f) v! T# [: A7 P
  1245.       stage      = StageNone;
    $ R# k, A( \" r+ x, a
  1246.       callback(StatusAbort, NULL, NULL);
    ) R2 p6 o$ q4 `- z
  1247. % }' Q2 ?  }, {( k0 s
  1248.       break;
    9 u* h0 c. U. w  C; n1 Z
  1249.     }
    : y. B6 |1 ]: w$ O# t

  1250. " d6 O9 {; b/ q+ f
  1251.     default:
    ) S3 y, D# `, F7 X5 A7 p
  1252.     {" J8 k7 H7 q- d. d/ E7 @
  1253.       timeCount++;
    0 ~& c1 k9 r# _  x% ?! j  q: g7 U$ L# n

  1254. ; |2 b0 N) q. n. d, h9 f& m; P
  1255.       if((timeCount / (timeDivide + 1)) > timeMax)
    7 g/ u( }8 b9 l9 V- C
  1256.       {
    - G! `9 o0 [8 |  B+ K# r' v
  1257.         timeCount  = 0;9 t) _, s+ s* M
  1258.         errorCount = 0;
    & {/ R# g# D4 B8 A0 O" V& X
  1259.         dataCount  = 0;
    ; ?, ^2 y5 F3 W$ B
  1260.         code       = CodeNone;
    ( `1 ?* Z! X3 l# q' u, y
  1261.         stage      = StageNone;
    8 r( f/ t6 W) u' {3 [

  1262. 7 t5 W/ |3 ]8 ?' ~
  1263.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)8 N4 M5 Z8 Q6 T6 L' T0 ]; w+ I
  1264.         {
    . J' H6 {  D$ E6 Q8 n: h+ \
  1265.           txBuffer[txLength] = CodeCan;
    : p! @" l; j+ [) ]+ }' z. x
  1266.         }
    " Y; Q, v4 s2 f+ S. c0 h
  1267. 2 o7 ]  a3 t$ z& n- t# o
  1268.         write(txBuffer, txLength);
    : q" f8 |6 O0 R& z( s3 g: f
  1269.         callback(StatusTimeout, NULL, NULL);
    3 r) S) L9 o9 }* a- W0 B
  1270.       }6 l$ o1 G# P* w8 I! x1 q8 p& [* @
  1271.     }- m: _( e' A( F
  1272.   }
    $ [$ Z" G% m3 r" B8 x# b- n% T
  1273. }. \  [/ W8 E. u3 f3 T7 g
  1274. ' O6 v; V6 A# a+ K- Y4 [, L
  1275. /**; Z8 ]1 G; v3 ~
  1276.   * @brief  Transmit established stage.+ D- a# ?  y7 R' y$ B+ V
  1277.   * @param  None.& y) g' ?* C! b; Q1 ]4 l+ j
  1278.   * @return None.
    4 {0 E0 A2 A* l
  1279.   */2 }) u  U( [" g1 K8 J' ^
  1280. void Ymodem::transmitStageEstablished()
    $ S; O& o/ W% [' A
  1281. {% X0 x; J0 X2 E: i4 W+ M8 C
  1282.   switch(receivePacket())
    1 y6 x/ r8 \# v) W
  1283.   {* V/ \0 }  G% ^$ ^: B- q
  1284.     case CodeNak:
    9 ^8 o2 T( E+ |/ d
  1285.     {
    ( n. a8 p( F+ x' m
  1286.       errorCount++;
    1 o% w6 G7 }5 \% T' z" F
  1287. ; j2 L. ^8 I4 C9 {  }1 t
  1288.       if(errorCount > errorMax)
    ( f+ ]4 |5 F/ P; e: N
  1289.       {8 p- F4 K2 Z& }- Q) T5 q2 J
  1290.         timeCount  = 0;+ B, T! B0 V6 {  J+ Q
  1291.         errorCount = 0;
    . _' z9 v7 m2 e$ R- X
  1292.         dataCount  = 0;
    ; A' {$ K8 d% ~
  1293.         code       = CodeNone;
    , b" U$ K2 H$ H5 `8 P- v$ U
  1294.         stage      = StageNone;
    ! Q8 k/ A% c2 E; B

  1295. : F$ A: l/ A" ~& o8 J
  1296.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)1 G5 `8 r- k2 n# \) R* e* T/ w+ \
  1297.         {
    # a" I* _! B$ R, ~  V$ K
  1298.           txBuffer[txLength] = CodeCan;$ ^/ f+ `$ W/ P9 R
  1299.         }
    ! n' V0 ]8 w. k# H0 k, W

  1300. ! b/ ^) ?+ e$ k7 ]; T5 C; Q4 |. y
  1301.         write(txBuffer, txLength);8 @: N. D+ c9 R& b
  1302.         callback(StatusError, NULL, NULL);4 O5 H- L7 u) B9 R
  1303.       }& H# M" {8 B" C8 R
  1304.       else
    * k% \/ |, r. D4 E: f) n- [& p
  1305.       {
    / H  b8 t2 s) z' g: a+ h: I
  1306.         write(txBuffer, txLength);" f# e6 p4 M# T1 j6 G
  1307.       }
    + O  t" T6 I6 u$ I8 p
  1308. 1 h( T: f% Y% m6 G$ \$ B* g2 K
  1309.       break;
    ! W; v% h7 d* K! d' }* ~
  1310.     }
    . M( d7 l" y5 V+ J9 Q. A5 l! |

  1311. * r, m1 D# [, x2 h5 ]2 S
  1312.     case CodeC:$ I2 \; R' s7 J) g' o9 O
  1313.     {3 J( f( Z* c- ~7 Z
  1314.       errorCount++;
    2 r& h2 n- y. K0 B

  1315. 4 g$ u" j8 H, V' E9 F( h9 @  e
  1316.       if(errorCount > errorMax)
    7 o/ p& t! \8 t: e* c
  1317.       {+ L: O3 K. |9 [# n6 G
  1318.         timeCount  = 0;
    ; ]9 N1 [8 @: @
  1319.         errorCount = 0;
      L5 e! a# g+ j' b8 N8 U
  1320.         dataCount  = 0;' l# R* |# b) |% v& |* r$ u( h
  1321.         code       = CodeNone;
    / _( i. Z4 F2 c5 @. C0 N: Y
  1322.         stage      = StageNone;
      M, m2 ]* w, d' F3 ?( Z; E: M
  1323. ! G1 o2 \4 I( i. `) X" X
  1324.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)0 R! w. K% Q" G5 y' N
  1325.         {) _% u5 @" r" ?& M
  1326.           txBuffer[txLength] = CodeCan;
    $ r$ m- ~) r0 m8 ^7 F' y' Q
  1327.         }3 U# ]+ G4 n0 y6 }$ J
  1328. $ S  H' V, l% X) U0 }5 I
  1329.         write(txBuffer, txLength);5 W7 {( M5 }; i
  1330.         callback(StatusError, NULL, NULL);: i/ r) D4 P* q- Q" a2 w
  1331.       }
    5 f7 A5 @$ D8 N- }" ?0 G$ j( A
  1332.       else' n# @! J) ~# f/ P4 j
  1333.       {. `9 O. G/ m  z# h
  1334.         timeCount  = 0;
    ; [+ Y5 s& B& `8 H4 R8 E1 s
  1335.         errorCount = 0;, S4 N& A; v! X: k
  1336.         dataCount  = dataCount;
    & e& w/ D( ?8 P* ?  `, k
  1337.         code       = CodeNone;" x" t8 K+ O& k" o# c3 R
  1338.         stage      = (Stage)(stage + dataCount);
    8 i7 \- g5 e! ~  A3 Q7 S4 H
  1339.         write(txBuffer, txLength);
    3 S( s$ c8 G4 p9 Q
  1340.       }: }" o7 b+ d' l' n
  1341. 7 n2 K5 M% r# u% _, v
  1342.       break;$ m- o3 q3 E6 r7 w
  1343.     }
    : Y+ t; L4 n) u

  1344. 2 e+ d4 P/ o; v3 B5 Z
  1345.     case CodeAck:  b3 y( m9 o% h
  1346.     {
    $ {$ ]' h9 X2 m# h  |* Q) q" l5 k
  1347.       memset(&(txBuffer[YMODEM_PACKET_HEADER]), NULL, YMODEM_PACKET_1K_SIZE);
    # e* c! z7 L, H  @# l! D2 ^1 G1 R5 {
  1348.   A6 w+ [& E/ a& y( u, A9 f( l
  1349.       switch(callback(StatusTransmit, &(txBuffer[YMODEM_PACKET_HEADER]), &(txLength)))! q, z0 Q/ @1 s- W6 ~$ H
  1350.       {# x- e6 E% h: d1 ]& x# T; p
  1351.         case CodeAck:
    - b( g' E+ i! |+ G0 ~
  1352.         {1 k8 ^+ N9 L1 `9 T  M
  1353.           uint16_t crc = crc16(&(txBuffer[YMODEM_PACKET_HEADER]), txLength);
    3 g; X# ~1 @7 u/ z$ S! l

  1354. " F3 E, u$ I1 e. i5 _
  1355.           timeCount                                       = 0;
      J; ]/ n; e' U8 I6 h
  1356.           errorCount                                      = 0;/ a) }/ `: W$ G4 E0 o$ f) W' v
  1357.           dataCount                                       = 1;; E5 T* E! K( ~$ M
  1358.           code                                            = CodeNone;2 m: x8 d* M9 k; J' m
  1359.           stage                                           = StageEstablished;9 a  f, u; j2 x& ~5 A
  1360.           txBuffer[0]                                     = txLength > YMODEM_PACKET_SIZE ? CodeStx : CodeSoh;
    ; A6 O# Y. k9 D6 z" T
  1361.           txBuffer[1]                                     = 0x01;
    0 @  n. ~) T3 s" [) J& b) W" P
  1362.           txBuffer[2]                                     = 0xFE;
    3 l" m/ M6 E7 r+ P5 ?
  1363.           txBuffer[txLength + YMODEM_PACKET_OVERHEAD - 2] = (uint8_t)(crc >> 8);
    ) b$ L# p& F! o$ l" n. N: [
  1364.           txBuffer[txLength + YMODEM_PACKET_OVERHEAD - 1] = (uint8_t)(crc >> 0);2 A' }5 S! D5 ~) y: Q1 P, c
  1365.           txLength                                        = txLength + YMODEM_PACKET_OVERHEAD;
      W# m% @2 h1 K; b+ j% l
  1366. + a% h$ }( b, R
  1367.           break;
    " z) I2 b" e8 }# \! b, j; w! E
  1368.         }
    ) e+ e. Z: r8 |  i

  1369. $ o- ]$ I7 i* h& N* q& R
  1370.         case CodeEot:5 G6 X6 g8 A" q' S
  1371.         {
    " y, k/ z5 O' s, L# H- R
  1372.           timeCount   = 0;$ c5 d/ J( Y2 L# Z- i! p' a1 [
  1373.           errorCount  = 0;* ]3 `# H/ B" o9 _- s1 ~+ x+ _
  1374.           dataCount   = 2;
    , c1 `4 o' ]5 @5 s; [9 h! H
  1375.           code        = CodeNone;
    $ v3 h" o+ w8 R# \$ O
  1376.           stage       = StageEstablished;: V( y  w( l! a# ~8 c, e
  1377.           txBuffer[0] = CodeEot;
    0 M" J7 r% B6 T( A3 N
  1378.           txLength    = 1;
    & b# p5 I7 S2 s9 _/ }# y4 w! I
  1379.           write(txBuffer, txLength);5 _# Y( W- R' F4 o6 u+ d/ R
  1380. ) |6 T5 K" [9 ]5 N* S- r
  1381.           break;6 R) P+ z# `) K; D4 Y% p7 D4 D
  1382.         }
    ) n; S# \4 ~- v% K7 n, N1 n9 B

  1383. 7 }% X9 A3 G- {+ P; R
  1384.         default:
    , l' ?4 D$ o& C! m8 v8 i# E& z* q
  1385.         {
    ; q# ?2 U& z) i& R
  1386.           timeCount  = 0;! i4 Y  c6 \) k0 A
  1387.           errorCount = 0;, y; f! Y! a: P8 B; Y$ \# S% W' }
  1388.           dataCount  = 0;
    0 z; C( @1 v3 l9 s: Y* q8 m
  1389.           code       = CodeNone;7 ^/ a7 q1 n: ~3 t- b2 X6 P- e
  1390.           stage      = StageNone;
    ! o$ z1 \: `+ M6 Q- N
  1391. % o( M' z7 A; ~" I; [* P# B
  1392.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)# E9 e7 }) i" h% _4 i! Q. W6 N
  1393.           {4 E- _; v& I3 g" U
  1394.             txBuffer[txLength] = CodeCan;
    . K; i3 o' @0 R( Y9 S
  1395.           }
    + K) B& ~8 A. A2 u

  1396. 1 T3 W$ q/ F! _% c0 ^4 K; M" \& A. C
  1397.           write(txBuffer, txLength);' u# u% V5 D; f9 U$ z3 c0 m: ?
  1398.         }) m, o5 J' X/ D' \! m* L
  1399.       }
    " @1 I1 _9 w' B+ p, C

  1400. ; t! Y' Z7 P, _+ u7 }/ b0 u
  1401.       break;
    : h! L& t( f0 x- p0 _9 e
  1402.     }% i( J% i8 Y1 r5 @2 O
  1403. 9 [  o& e7 `# N9 s# T& K" a7 f
  1404.     case CodeA1:
    ! ]+ Y6 K% X. A. S- y+ C( j7 }$ Q2 K
  1405.     case CodeA2:
    ! u- X- j3 b. D
  1406.     case CodeCan:( s/ N8 D8 J4 J% g, n  D
  1407.     {$ K" y/ d! s9 o
  1408.       timeCount  = 0;+ N$ b. ?$ H% M4 j/ \  v
  1409.       errorCount = 0;0 G3 O% o1 Y  K5 @
  1410.       dataCount  = 0;
    * V* Z5 c% r% q1 B: D
  1411.       code       = CodeNone;
      N  y8 u7 d! j) i* _* q4 ]& V) S2 E
  1412.       stage      = StageNone;. q! c$ O8 B% P" G# Y. E
  1413.       callback(StatusAbort, NULL, NULL);* j! n. ^' z4 T% Q9 J+ z! E# ~& n
  1414. 4 |! \& c5 s/ k- \5 I' M7 c+ o* |6 O% r% u
  1415.       break;( w. g/ g( c" ]( `
  1416.     }; M' t% U% F3 b. @1 _/ w. }
  1417. ; t$ q7 ~& b* E# }$ _
  1418.     default:
    . U! d5 C! D7 C) K
  1419.     {" }& A/ a3 w5 ?' ]
  1420.       timeCount++;6 V) `& d# E1 {, v* z$ H4 q
  1421. & i" J) b0 Y# m4 I
  1422.       if((timeCount / (timeDivide + 1)) > timeMax)
    ( v4 B% \& e. L
  1423.       {
    ! X0 U: D9 |2 _4 F7 o+ ^
  1424.         timeCount  = 0;- ]( j- V+ m$ {# C  r
  1425.         errorCount = 0;
    , ^0 F9 N) b1 |1 E' ]
  1426.         dataCount  = 0;& m! _8 L2 P6 K! m7 M
  1427.         code       = CodeNone;$ J. }' g% h3 ^% p
  1428.         stage      = StageNone;
    2 y( z4 E; G% Z: P6 H
  1429.   m) I0 q" }! i
  1430.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    : a" W% O9 [5 ^. K
  1431.         {
    5 b1 n  E# j9 {
  1432.           txBuffer[txLength] = CodeCan;$ Y/ Y/ v; z/ t1 b' z( P4 b) D
  1433.         }0 V. E' h0 I4 M6 k* J4 L

  1434. $ r/ n! i1 R$ E9 c6 m/ _& W
  1435.         write(txBuffer, txLength);
    ! M: _! a$ n7 G5 {# M6 C  I
  1436.         callback(StatusError, NULL, NULL);
    + a( }6 G0 S/ \( ^
  1437.       }
    % Z/ t* x, d6 Q# N/ C
  1438.       else if((timeCount % (timeDivide + 1)) == 0)0 M' W4 E7 [3 k2 L. P
  1439.       {
    $ N0 A* J5 s& S5 Q7 w
  1440.         write(txBuffer, txLength);
    4 ^: A6 }2 k" e, M: U
  1441.       }8 Y2 F* X5 M0 p- H8 F9 ~
  1442.     }
    2 x, P0 P; k, |9 `% z9 S
  1443.   }! M! ~; }) j) n! E4 q+ e+ I
  1444. }. O1 O( i: y8 ?0 s0 m* A7 ~

  1445. % s8 W% r$ a, h# z+ G+ ~4 L" F$ N
  1446. /**7 r& K' }  n* f' q; g- G" N
  1447.   * @brief  Transmit transmitting stage.
    ! _/ `4 j2 S2 N# r1 @4 ^- S* J
  1448.   * @param  None., h2 H4 X; o: a9 E) i. {; V9 }: A
  1449.   * @return None.
    $ `& ~( O6 `4 m2 I$ N
  1450.   *// K2 S: x6 G+ A; c
  1451. void Ymodem::transmitStageTransmitting()
    4 U6 Z' u6 z/ m% ^0 R5 |
  1452. {
    2 U# ]( p0 z3 Y3 Z  h+ K: u0 O
  1453.   switch(receivePacket()), V2 ~( s4 o! K( m% u9 `& \; S
  1454.   {. l/ Z% t' K/ Z# q
  1455.     case CodeNak:7 v8 ~6 d/ e0 m% I' F; D
  1456.     {8 S5 @) H5 J7 @/ }
  1457.       errorCount++;
    6 \8 I: ?! D& f6 K3 }0 _3 A$ U3 ~6 B
  1458. 7 e( ]$ n* D, f3 ]+ E
  1459.       if(errorCount > errorMax)8 F! T1 F" y0 e
  1460.       {: f& G8 |6 d% d& k1 y
  1461.         timeCount  = 0;5 b* g' w/ }, H. G% m- o) J
  1462.         errorCount = 0;
    ! [. R# m$ x0 N* x; R! Z6 ^8 N
  1463.         dataCount  = 0;4 i$ e/ y+ [/ f0 H8 n" d$ V
  1464.         code       = CodeNone;% w9 Q) m0 ?! f- m
  1465.         stage      = StageNone;
    1 `  D2 S' ~5 t9 ~8 x- _4 m

  1466. # {" u  A/ W5 `$ q6 S. }
  1467.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)7 u- G& i2 @& ]( Z- O' g7 G3 M# k5 }
  1468.         {
    . u$ C3 G- M- v. z
  1469.           txBuffer[txLength] = CodeCan;- ^4 ?; R! J8 K* ]4 M5 Z: F
  1470.         }4 Q3 |" K; q, r6 T
  1471. 4 J8 t6 @; x# c2 n* B" A1 @5 [
  1472.         write(txBuffer, txLength);
    0 Y) N6 n6 p2 y
  1473.         callback(StatusError, NULL, NULL);
    ! x5 E9 F4 R, |7 r( k1 S
  1474.       }% |& v  O# j  e' E! J
  1475.       else: H/ w8 m, b; B! m  C1 `
  1476.       {% P0 f! B& }. A$ o/ h
  1477.         write(txBuffer, txLength);
    8 m3 B& v! _; ~0 ?5 x4 |
  1478.       }
    ( R- p4 E6 N# m, T; y3 G5 O
  1479. 0 V* \. a- e& L
  1480.       break;
    5 g( t, Z/ p& v% ?
  1481.     }
    " i$ q& Z. B/ p$ l0 N/ n
  1482. - W; S% p  w. N9 U$ }# o
  1483.     case CodeAck:! m: o1 x" s. c1 x/ e3 b
  1484.     {3 R7 D6 \2 |. z# g7 r/ z" I8 Q
  1485.       memset(&(txBuffer[YMODEM_PACKET_HEADER]), NULL, YMODEM_PACKET_1K_SIZE);( t) \7 T( t1 `' q
  1486. , H0 l/ T6 ~( J$ B
  1487.       switch(callback(StatusTransmit, &(txBuffer[YMODEM_PACKET_HEADER]), &(txLength)))
    # h/ Q* L7 g/ B" o* f* O2 v, Y! |
  1488.       {. m4 \6 v( B( i+ u/ E0 P  [; j/ s- m
  1489.         case CodeAck:
    & |8 o1 u3 A; {# b
  1490.         {- V8 j/ u, m7 V. i5 j# X
  1491.           uint16_t crc = crc16(&(txBuffer[YMODEM_PACKET_HEADER]), txLength);, V% p' H0 ^- Y; `* J! U6 N: ~7 V

  1492. + U1 H/ q1 r* O; q9 @2 ]1 {
  1493.           timeCount                                       = 0;; r% Y7 S( g# h  W, x  Y0 B
  1494.           errorCount                                      = 0;; ~$ u/ X8 [2 [2 V7 g
  1495.           dataCount                                       = dataCount + 1;% F' \% C3 E0 }2 V* c) Y
  1496.           code                                            = CodeNone;
    % i2 N$ V1 n* R9 C  {" l
  1497.           stage                                           = StageTransmitting;
    5 |  u+ R! g4 l* [6 X7 T
  1498.           txBuffer[0]                                     = txLength > YMODEM_PACKET_SIZE ? CodeStx : CodeSoh;
    : M  r) |' A- D" p& x' Y- V
  1499.           txBuffer[1]                                     = dataCount;
    ! h* E  g" m! I/ F& O9 }# s
  1500.           txBuffer[2]                                     = 0xFF - dataCount;$ l, s$ Y( Q3 ~. V7 j
  1501.           txBuffer[txLength + YMODEM_PACKET_OVERHEAD - 2] = (uint8_t)(crc >> 8);
    7 I7 L; C. L6 d, V9 ~
  1502.           txBuffer[txLength + YMODEM_PACKET_OVERHEAD - 1] = (uint8_t)(crc >> 0);" w- D% y  s; _2 J% c4 V
  1503.           txLength                                        = txLength + YMODEM_PACKET_OVERHEAD;# p- X+ k7 P  S9 s& U3 _
  1504.           write(txBuffer, txLength);
    6 N$ p) C+ r! x/ f& B7 ?
  1505. & K+ d$ H* L* o
  1506.           break;
    * A5 R- ]4 z1 g2 B* @+ }) W/ Z/ o
  1507.         }2 q) [+ Z7 W( ?1 ~. }$ [) N

  1508. " I1 l6 w" r& G8 X$ }* h1 S0 D
  1509.         case CodeEot:
    + y% j! u+ A* d! m5 [! M2 s2 h3 M" w
  1510.         {
    ; t$ B, O2 ]. a6 Z% B
  1511.           timeCount   = 0;
    9 S& I1 ]( m. l6 f' ]/ Y6 v8 E) [
  1512.           errorCount  = 0;9 O( V. Z) x7 @3 l. l
  1513.           dataCount   = 0;
    - ], k6 L6 I( C. i9 A3 \9 i
  1514.           code        = CodeNone;4 g1 q8 C) {1 B, R7 [. a  L
  1515.           stage       = StageFinishing;3 `1 {# V5 w! w" Q$ `. O( v5 ~
  1516.           txBuffer[0] = CodeEot;* E6 T( R' O% B
  1517.           txLength    = 1;
    4 n5 R" q$ t! i: l4 Y1 g
  1518.           write(txBuffer, txLength);
    ! @! n2 b3 b& ^
  1519. 7 l- X6 r( \! U# [6 v/ n
  1520.           break;' s- a9 V4 b; y  Q; j
  1521.         }
    6 N& S9 _( t9 U- c

  1522. # }$ m8 E% L4 q' X! g, g' q
  1523.         default:9 h6 B2 I. u5 r- N+ X" N" p
  1524.         {
    - t5 t( G- X5 ]3 Z, E. O
  1525.           timeCount  = 0;
    / {7 G- _$ k; J$ w& \5 k5 t* T
  1526.           errorCount = 0;9 F, W6 _: i2 u0 l& W  n3 o: |
  1527.           dataCount  = 0;8 Q# G9 i9 Z) Z. _) }% j
  1528.           code       = CodeNone;
    4 @8 V: o# k$ m
  1529.           stage      = StageNone;8 G. p8 M+ K: s7 [. e4 b2 Z
  1530. - s5 t; v1 f" S) q# p/ s8 ~( s6 p9 d
  1531.           for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    8 ]6 R1 {$ h2 n
  1532.           {
    2 r  a# w; \& G9 w5 s, q7 Z' ~% v2 ]
  1533.             txBuffer[txLength] = CodeCan;
    % e: U5 L: r/ q5 s
  1534.           }
    2 M% o% k+ z0 s3 X5 C! O
  1535. . [2 b: i' k0 u' c& y
  1536.           write(txBuffer, txLength);
    $ L1 r2 p3 ?, i  C
  1537.         }
    1 u& X5 W5 R3 z8 S0 a6 {) C. t, P" ?
  1538.       }
    , ]) F  g# B9 E9 Y) T

  1539. % G8 K! D- U3 Q. O9 h/ M/ E2 i1 m
  1540.       break;
    9 g4 |: A1 f# G
  1541.     }" ~9 K2 A1 r. d+ o" W' q

  1542. % E" \# B' Y8 p, i: f4 O& N3 ]
  1543.     case CodeA1:; k- T& `# J3 b) L2 K: r
  1544.     case CodeA2:: T9 q- d. A+ z9 c* a
  1545.     case CodeCan:4 n; s2 x6 a4 w# X. U6 o* v' u
  1546.     {2 }# L3 S9 y' S) G, W# C
  1547.       timeCount  = 0;) B. U/ \' c: r* H
  1548.       errorCount = 0;4 W) ~/ w$ \  ?* k2 {  J2 c
  1549.       dataCount  = 0;
    1 e$ Q/ l2 [5 \+ i( x+ M4 J
  1550.       code       = CodeNone;8 P  S: j# a, ^' P' g4 r' H. ^% W9 B2 u
  1551.       stage      = StageNone;& [; D! S$ Y, y5 c
  1552.       callback(StatusAbort, NULL, NULL);. l5 d3 J  c' [( ]. E; {/ Q. K

  1553. ( Z$ I1 C! B  s- d0 ^
  1554.       break;& v2 v* S& H; ?0 q
  1555.     }- {; \: ]1 g* u0 _1 G% Z

  1556. " w% {  F( ?5 q5 x8 Y5 ~
  1557.     default:1 B) ^+ x' ^8 e
  1558.     {1 C$ ^/ W2 Q  n4 x# ]
  1559.       timeCount++;& G+ r. J; k- P, j. A4 G+ A8 o

  1560. 9 e" M1 v3 `# X# a8 P7 b1 S5 V
  1561.       if((timeCount / (timeDivide + 1)) > timeMax)
    1 L/ R4 Q5 F1 B& A. @
  1562.       {/ j$ T4 j& {( X3 p8 T2 E2 f" f
  1563.         timeCount  = 0;
    2 ^- A; I+ D+ T* W
  1564.         errorCount = 0;- i* B: ]; ]4 S9 \+ S; {* Q" k! T
  1565.         dataCount  = 0;
    / X6 d  r, X; ]& N
  1566.         code       = CodeNone;! N- G, F5 v. r4 ~" C( i; y2 S
  1567.         stage      = StageNone;4 L# R& U0 g2 v# d
  1568. & v* m, @( F1 U# H( S
  1569.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    $ g& P6 G4 G) h3 }3 p
  1570.         {
    5 s" }/ q2 I8 q! z( |, n9 ^
  1571.           txBuffer[txLength] = CodeCan;
    ' f" I. ]8 |& K. v3 u2 P
  1572.         }
    . ]/ C4 |- Z* w, g! s  Q5 v

  1573. - x0 _/ J; B) R6 N
  1574.         write(txBuffer, txLength);( D* o3 i' Y' |- A. f
  1575.         callback(StatusError, NULL, NULL);, I! R2 H7 y* T2 F1 `! S
  1576.       }
    ; P- R3 M; L% A3 |: o
  1577.       else if((timeCount % (timeDivide + 1)) == 0)
    # N9 [5 {% s/ g& R, B2 P, a
  1578.       {5 x% Y1 q" P+ H. ^7 j
  1579.         write(txBuffer, txLength);6 f; @1 v! _! b9 i  u/ S8 o
  1580.       }
    ' X/ }$ P$ K& l% N; m( T0 i2 ]$ b
  1581.     }
    9 D9 w! ~, R4 D1 {6 T: D' Q+ \
  1582.   }
    2 K5 o: D6 D# O9 y; z
  1583. }
    * }) k& c: J. T6 V& |, p# c
  1584. " d2 a! y5 [$ ^  q, m
  1585. /**& S3 b2 j  o/ _( |0 K
  1586.   * @brief  Transmit finishing stage.6 k" k0 K4 J, U' S7 d: t$ Y$ f
  1587.   * @param  None.
      t+ c: Z+ D" P- d6 v' h
  1588.   * @return None.
    ; V* X. P* i) h! _* W/ Q$ f* B6 ]
  1589.   */- _: G& B- T8 `$ H$ j) u' f
  1590. void Ymodem::transmitStageFinishing()
    ( q) W" z, Q5 m: j9 W
  1591. {
    6 I5 [- s8 ^0 @! b$ z0 B# J& Z
  1592.   switch(receivePacket())
    , h5 ]/ I0 H5 a# K7 H+ u3 L: o
  1593.   {8 y  x% Y1 D- v% e1 l
  1594.     case CodeNak:+ T. t" b0 c; S/ s8 y; H1 Q
  1595.     {! T( S$ e! V1 a  t% h% q, j/ O
  1596.       timeCount   = 0;; r" c& j' R/ c
  1597.       errorCount  = 0;0 ?* Q: c2 y" @/ N/ ~
  1598.       dataCount   = 0;
    6 A) m! y! O4 k  M
  1599.       code        = CodeNone;% d& _7 i  z& _: H6 `, h
  1600.       stage       = StageFinishing;! L( n' J8 v2 P1 o: |: P
  1601.       txBuffer[0] = CodeEot;
    & f( ^. N/ p* G- k
  1602.       txLength    = 1;
    3 ?, I/ X  z3 D7 f2 Q' ~$ w, a
  1603.       write(txBuffer, txLength);2 g& u/ ]: [: j9 g0 V

  1604. 4 w8 E3 d$ {/ |" X4 g+ U
  1605.       break;
    6 Z2 D/ R0 e+ W+ s# y8 R& L8 j0 r6 D
  1606.     }; _$ O! [; ?* ~2 R: c* S: z
  1607. ! y1 \2 u+ V* s9 [" z2 I
  1608.     case CodeC:, ^5 q) x" U+ S. q. N5 z
  1609.     {& g& C: v, C  }+ H; j- f3 \' E/ Y
  1610.       memset(&(txBuffer[YMODEM_PACKET_HEADER]), NULL, YMODEM_PACKET_SIZE);
    . d4 C2 ]. D  M4 M/ I
  1611.       uint16_t crc = crc16(&(txBuffer[YMODEM_PACKET_HEADER]), YMODEM_PACKET_SIZE);# ]' E, e4 r6 b

  1612. ' s* Y% U$ g* k0 l. D
  1613.       timeCount                                                 = 0;
    % o) d& {7 m3 W! x' Y
  1614.       errorCount                                                = 0;
    $ S/ u& T2 b% \) }1 S$ o
  1615.       dataCount                                                 = 0;  o% p1 |2 s! v; n9 I2 X) W$ ]
  1616.       code                                                      = CodeNone;
    , V6 ^1 G9 I- Q
  1617.       stage                                                     = StageFinished;7 M' @- k) j" i# A8 R. I
  1618.       txBuffer[0]                                               = CodeSoh;
    / P5 {  A* S4 H- m3 j. |1 q
  1619.       txBuffer[1]                                               = 0x00;9 Q$ Q/ Z9 ^! e; F1 q; p
  1620.       txBuffer[2]                                               = 0xFF;
    & [' v1 q8 P- W/ X! ^6 _
  1621.       txBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 2] = (uint8_t)(crc >> 8);& r# r& \% j/ F
  1622.       txBuffer[YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 1] = (uint8_t)(crc >> 0);
    5 v( k# {$ e* l1 l
  1623.       txLength                                                  = YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD;) O% k8 L6 o- p. m2 B5 C
  1624.       write(txBuffer, txLength);' s6 C0 C6 w1 R, d; h* p
  1625. $ W4 }; p; E3 ]% @
  1626.       break;6 W6 k% B6 F2 s9 \! C9 k; M
  1627.     }+ \0 R" {5 k9 H6 [. D# S
  1628. . i* ^; P, ?# x" n
  1629.     case CodeA1:
    / a: K5 o& |9 B
  1630.     case CodeA2:, E4 C+ f' E  E
  1631.     case CodeCan:
    9 f2 x' o: C; d8 n# e' a, h  G
  1632.     {" q& @6 a' P! ^, V" D
  1633.       timeCount  = 0;
    9 i6 O) u( n) E( }- A! a
  1634.       errorCount = 0;& c9 c8 x' p& L" v
  1635.       dataCount  = 0;+ T( n, X, c# J3 }1 L3 |% V
  1636.       code       = CodeNone;
    - x  p5 ^" l6 |
  1637.       stage      = StageNone;
    # n: F* z! J4 ]' S) U, }7 i
  1638.       callback(StatusAbort, NULL, NULL);5 _8 q4 t( S$ \: R% e$ B

  1639. ' z% l& B5 c3 k3 x+ h# ?) b3 r
  1640.       break;' E  r. h- W0 X3 ]" M' i, a
  1641.     }) g2 [/ G& ~! x7 o2 \. [7 u, _- h

  1642. ' S/ U  K' j1 `* V3 x0 c  R
  1643.     default:
    ' {3 p: z' F( s9 f6 y+ j% f, A
  1644.     {
    ; N3 ?! A: N4 X' X; C2 H
  1645.       timeCount++;- D! o# A* k7 n% ?* u# h
  1646. : U6 p% N2 W" B$ Q0 j" q
  1647.       if((timeCount / (timeDivide + 1)) > timeMax)$ }  i3 I3 }* N
  1648.       {
    # D3 c' \* W+ c/ B1 }: F
  1649.         timeCount  = 0;
    8 |* \: n% [% o# V' B* f
  1650.         errorCount = 0;  l# `: a; s( |. F/ Y/ ]% T4 V2 {; Z
  1651.         dataCount  = 0;8 x7 [; u7 g+ ~+ ^! |
  1652.         code       = CodeNone;
    # ?4 {: h: A8 A& C) U4 c9 n
  1653.         stage      = StageNone;  d% E) K- O' R6 U- U( s! q1 t
  1654. 3 T  F* r1 w% z/ ]5 [% |
  1655.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)9 S4 {! q0 ^. `2 L/ i, }% R
  1656.         {& y5 e  ]& b* B3 T: [" b7 C
  1657.           txBuffer[txLength] = CodeCan;9 |* x+ P, n8 j9 m$ p9 w8 s+ s
  1658.         }0 n/ p: z! i) Y

  1659. 7 L9 A$ M. W; ~
  1660.         write(txBuffer, txLength);
    8 M, s: B% W- o. g4 M
  1661.         callback(StatusError, NULL, NULL);8 Y' ~1 I- R3 |0 c+ F3 \6 R
  1662.       }; O! ~& c8 {! i6 U/ |
  1663.       else if((timeCount % (timeDivide + 1)) == 0)
    % z# P3 `; m$ G) O  l  }" ^1 }  S6 d
  1664.       {2 b9 K) ~& P3 }& i, K
  1665.         write(txBuffer, txLength);2 v2 t8 t/ _5 u5 V2 I
  1666.       }
    ( D7 t4 J4 P+ O! i' V
  1667.     }, d6 D/ E- g6 r+ |9 e
  1668.   }" ?6 }' V+ u2 Y& ?
  1669. }' F7 B. @6 s4 N$ T8 M+ n

  1670. 4 t$ v0 l' J8 x
  1671. /**6 o2 X# e0 ~0 A3 u5 K8 P8 n' G
  1672.   * @brief  Transmit finished stage.  {5 ^9 n& p1 h7 U# e
  1673.   * @param  None.0 M. l  S  r' \6 v6 F4 `
  1674.   * @return None.
    * `% T- ?5 V- S
  1675.   */
    2 n" n( z* y) I1 y' e0 E& C
  1676. void Ymodem::transmitStageFinished(); F5 c+ O+ a# f6 g& g5 {4 |
  1677. {/ Q/ R# Y4 ]8 n, x7 m# c
  1678.   switch(receivePacket())$ o- |: S, k0 T& d
  1679.   {
    6 R8 E6 d- H+ u( Q- s) [
  1680.     case CodeC:
      {1 ?6 L3 e7 J# Z1 |1 U+ |
  1681.     case CodeNak:$ B: y; V- v5 W  T9 D* i! R
  1682.     {3 _! j( j" ]! w
  1683.       errorCount++;
    5 d6 B& z& Y4 o4 ^& Q' `- @% }- w

  1684. " f2 a: M3 M- f: [1 E
  1685.       if(errorCount > errorMax)
    0 c2 M$ I: X; g4 B& ^+ F; m
  1686.       {6 U5 I5 M0 I/ l  K. B2 J1 I( X
  1687.         timeCount  = 0;$ A1 A* K& m( H$ g; C, u9 T
  1688.         errorCount = 0;/ H; D  C7 [* n0 z# l
  1689.         dataCount  = 0;8 D0 V, G# [! K4 e7 S  }& w5 Z
  1690.         code       = CodeNone;% v! q' X) ^* m& y" R3 J
  1691.         stage      = StageNone;0 k7 Y7 T/ Y% F+ E/ Z

  1692. 5 W: b1 E1 o- `/ C) W
  1693.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)+ g$ e' W0 Q- P8 e6 f7 z
  1694.         {
    $ x, N) N6 R- h- K! l! X
  1695.           txBuffer[txLength] = CodeCan;5 S- `1 ?0 D, h; @1 {3 A& s
  1696.         }
    3 H+ x: r5 f, j; S2 h; Y: H

  1697. 1 C* }" p6 v% j' a& w! V
  1698.         write(txBuffer, txLength);- F+ m5 [" l0 {8 }+ t# a, S
  1699.         callback(StatusError, NULL, NULL);
    9 S, `3 m8 U6 g
  1700.       }% y& ~7 Q  y( P- T6 ^# B
  1701.       else+ s; a, E9 l% `% s
  1702.       {
    2 S. z' |% g3 i( c2 S
  1703.         write(txBuffer, txLength);
    3 y5 ?7 ^( _0 p0 A4 F) [( f! q
  1704.       }" |2 Y. f5 V6 J! w' _% h9 g) y1 G
  1705. 2 n" n3 F6 e6 J) k! S. M4 \
  1706.       break;6 N" U/ ]1 L+ V* u9 s4 q: a/ E, |
  1707.     }6 C$ v5 C6 o9 ?
  1708. / ?' r& F+ |. i; i
  1709.     case CodeAck:/ J) H0 ]; `' f& ^
  1710.     {* a- S& v! M& v% a) I  V
  1711.       timeCount  = 0;2 m7 b/ Q" s+ X, X7 y
  1712.       errorCount = 0;
    # s- A1 @; y" g. f
  1713.       dataCount  = 0;
    , `+ n! Q$ w, U$ {" _" w
  1714.       code       = CodeNone;
    $ @1 O% j" I$ z/ B/ ?) I8 F
  1715.       stage      = StageNone;
    + A$ K! T; w* O
  1716.       callback(StatusFinish, NULL, NULL);
    4 I' _( A6 ~8 F4 R6 ~, x, j

  1717. ( Z" B6 w1 C) ~1 i. T# u0 {3 O
  1718.       break;6 L- m; k' y: _8 F9 P6 o$ C
  1719.     }! S6 z, ?1 H6 u- C" V! m- e6 j" O

  1720. - B. i5 p. F5 s- ?# X
  1721.     case CodeA1:4 s' s& L" s9 `3 A
  1722.     case CodeA2:
    9 Z; l& k( C4 ?) B8 c" j
  1723.     case CodeCan:
    7 R! \" H6 r5 Y/ }4 u
  1724.     {  E% L2 J0 I, l
  1725.       timeCount  = 0;, r& O  |- b- V) b& _0 I
  1726.       errorCount = 0;
    + G4 v9 f7 P+ d& u7 S6 _$ l( P& g9 B! p- x
  1727.       dataCount  = 0;
    0 q/ I' X0 M# F
  1728.       code       = CodeNone;
    & E; r9 |+ o. A3 @# {2 d. k9 e3 Y7 H( ~
  1729.       stage      = StageNone;5 k: U% c  j$ |
  1730.       callback(StatusAbort, NULL, NULL);2 w- x7 a: Y3 k! M4 a3 [$ c9 U' G' `
  1731. : @7 n3 c  }, \
  1732.       break;
    ) J& G+ c( ]# \! ]. k- K
  1733.     }
    ' D$ |7 X% ?" B

  1734. 7 M" L$ @  v# v2 ?# o: V: |
  1735.     default:$ W8 a1 r% ~& K, J7 p  ~' N9 Y% m
  1736.     {5 e. [& S4 t7 `, {% r( s# R- ^
  1737.       timeCount++;
    ! f7 g. M; L8 G4 h8 t+ m$ E
  1738. 4 q; t9 p! i9 H
  1739.       if((timeCount / (timeDivide + 1)) > timeMax)  G! T. Z! }" j& x
  1740.       {
    6 @9 Q/ F& F7 h3 u/ j
  1741.         timeCount  = 0;
    6 E( ]) u/ G( Y, D4 q: a) @
  1742.         errorCount = 0;
    " F7 L, \3 P0 A: N; C2 N; U( X
  1743.         dataCount  = 0;
    ( Y1 D7 v* T; Y! v' N/ T
  1744.         code       = CodeNone;
    3 n* z( L4 K1 Q4 Z" o/ j
  1745.         stage      = StageNone;
    4 }4 D$ z, g( A* ~
  1746. # k( H# [, ]; w/ D' U. F3 F( _
  1747.         for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)
    9 O; @5 n. ?. a, S& ]+ V
  1748.         {
    8 H8 i5 D; H8 X( h- M2 e( @
  1749.           txBuffer[txLength] = CodeCan;( _  I, N, c4 f4 \) d
  1750.         }- I) r! ?! O4 u5 D$ L5 Q7 g

  1751. ' G" L( ?2 m" \; B4 c) z' j
  1752.         write(txBuffer, txLength);. S: g+ G% M9 H" `. m7 Y
  1753.         callback(StatusError, NULL, NULL);7 \) x5 f/ n  W8 X7 o/ C
  1754.       }* @* @" X' d5 c1 p, o2 |
  1755.       else if((timeCount % (timeDivide + 1)) == 0)% l! v9 d7 r2 J
  1756.       {
    0 F! Q$ u. K4 Q6 b8 _
  1757.         write(txBuffer, txLength);
    " k! ]& }7 N0 f) p5 [: G
  1758.       }# X# q, |6 ~$ {+ K
  1759.     }; ^* |5 v& J3 M, A* }
  1760.   }/ W, e* V3 R6 z, T7 o' t
  1761. }
    # ^- H6 s3 e$ E2 |
  1762. ! I" {, `) }+ }1 X
  1763. /**
    . l1 D6 k" Y4 Q4 |6 w9 H' W. z0 Y( i
  1764.   * @brief  Calculate CRC16 checksum.
    # O; ^% H* m8 |( }3 C) L+ j7 @
  1765.   * @param  [in] buff: The data to be calculated./ ?( U; O1 V/ T% X' h5 }4 m3 r
  1766.   * @param  [in] len:  The length of the data to be calculated.9 K* M+ c7 O- ~7 Y  N
  1767.   * @return Calculated CRC16 checksum.+ c/ Y; x: b$ y
  1768.   */) f- N6 }3 h0 X7 p. S
  1769. uint16_t Ymodem::crc16(uint8_t *buff, uint32_t len)
    ' S: e' p5 W- @. ?0 [# k* W  u& ^
  1770. {3 i2 n' R6 p* C* Z. l; A! {4 F# z
  1771.   uint16_t crc = 0;
    * t# J# I7 @3 s5 Y  F0 f8 C3 j  {
  1772. ! y  H. N) I# V+ G) B0 d. P
  1773.   while(len--)0 f9 `" N2 G! t$ ^+ X
  1774.   {
    5 \+ d! k0 b: B
  1775.     crc ^= (uint16_t)(*(buff++)) << 8;% {( o/ @3 E* Y1 ^/ @, B
  1776. / m( K7 j1 v# i8 l7 \0 d* V
  1777.     for(int i = 0; i < 8; i++)
    ) f3 l& h3 s& Y5 D
  1778.     {
    - I5 ]. i3 ]. o1 d" P" b7 N
  1779.       if(crc & 0x8000)3 Q. O/ n1 `" _* G7 r8 E5 ?
  1780.       {
    : Z* U( s, l$ o% S8 y4 d' p, ?0 D' w
  1781.         crc = (crc << 1) ^ 0x1021;: z0 I4 k' L8 m: h, ?; E/ r
  1782.       }+ ^4 L) o' s* D
  1783.       else. M5 n2 N& @+ g' n$ n6 m
  1784.       {
    . Q: [0 |" C6 [- _: v& }; E
  1785.         crc = crc << 1;7 @5 X4 J" t, {- ]" ^
  1786.       }6 Q) n9 {, v: I' }1 C5 d1 t+ I' M
  1787.     }
    + z7 \  j$ d) `2 H8 r
  1788.   }
    5 L1 a7 z. s5 D; c, S+ f9 _, M

  1789. / b/ l- a" b* l/ U1 u6 v3 Y
  1790.   return crc;! U' A+ _  F( n: A3 K& c. |8 K
  1791. }4 O/ \+ ^+ U* L0 n( v- [
复制代码
5 l. T" E( Y( m! h! G
  j& f" E- l1 ?0 ~8 i

) a5 k+ d' _$ j9 O: T! `
5 d$ S- v: p' m
, |5 `4 |8 O' x: ]; P. ]# ~' N/ j, k
收藏 1 评论11 发布时间:2018-3-6 22:28

举报

11个回答
XinLiYF 回答时间:2018-3-6 22:30:39
      YmodemFileReceive.h文件
5 n" N* a$ Q! I7 x1 i% v
  1. #ifndef YMODEMFILERECEIVE_H
    9 ?4 P0 E/ U; }4 ?
  2. #define YMODEMFILERECEIVE_H
    # U: b0 [2 i0 n

  3. ' J! Z& b2 v4 b$ ?3 H
  4. #include <QFile>( V6 L' |8 y1 u  J
  5. #include <QTimer>& i! \. t3 O& H3 h' R
  6. #include <QObject>5 V3 Z( _9 r, ?
  7. #include <QSerialPort>
      ^7 c# e5 i) ~: _$ d( _' p
  8. #include "Ymodem.h"
    5 l7 C8 Y7 n$ W7 y) k6 Y" h
  9. 7 u; v' M0 G( B- b) j
  10. class YmodemFileReceive : public QObject, public Ymodem: R( ?3 }3 Z, n* V
  11. {
    , p9 P$ Q$ n7 [3 ^% ^  p
  12.     Q_OBJECT7 K# {0 U% j! d, c+ P4 R( n

  13. 9 E1 R7 v( W2 E
  14. public:4 F# `2 t! e6 x& C
  15.     explicit YmodemFileReceive(QObject *parent = 0);
    & `  w6 `6 g$ y; Q) ~
  16.     ~YmodemFileReceive();
    . _. D: y2 }& p& s- Z) u) z

  17. ( [* ?0 X) U  Z: n5 j6 {
  18.     void setFilePath(const QString &path);
    / z$ F* O" x6 W; Q
  19. / |( n: n6 |1 R3 ^% P7 P1 \) @
  20.     void setPortName(const QString &name);
    . y) ^% F& L0 `7 }
  21.     void setPortBaudRate(qint32 baudrate);$ [/ Z1 r) b1 t3 B2 m3 {$ B9 _

  22. , {9 X5 g( y" B+ M1 w6 @9 X) g
  23.     bool startReceive();
    ' U9 V+ n1 [8 O% {+ i: t- L
  24.     void stopReceive();0 O$ h$ x  i6 v, I. `% x

  25. . S2 Z; Y# m8 I3 l/ Q1 d7 U
  26.     int getReceiveProgress();5 Y- r+ @3 J+ T4 l0 L/ k( w
  27.     Status getReceiveStatus();: `. X" W8 Z5 P

  28. 5 e1 w, S: R4 Y( Y
  29. signals:
    / L3 F$ C1 k1 T9 ?# S9 I1 E! ]
  30.     void receiveProgress(int progress);
    & ?) S8 z% {7 a# t( K/ ~7 ~2 }
  31.     void receiveStatus(YmodemFileReceive::Status status);
    ' q9 I$ f5 d9 k' f

  32. / I7 x! L% O$ o- z& ~0 A
  33. private slots:! K# \: j$ M7 }. I$ w% M$ f! n8 g' w
  34.     void readTimeOut();- i  f: k; V$ K* |
  35.     void writeTimeOut();
    $ P* p! i2 q; z. |

  36. - z$ V  s6 L" L; \% C% c. t
  37. private:
    - x6 `# s. g2 v9 q
  38.     Code callback(Status status, uint8_t *buff, uint32_t *len);7 ~9 @+ ]: q3 T" C6 r1 B/ p

  39. % M7 J8 W3 X! u5 o$ o: V6 P7 b
  40.     uint32_t read(uint8_t *buff, uint32_t len);* X$ J8 P8 ~) j8 R9 G
  41.     uint32_t write(uint8_t *buff, uint32_t len);1 w2 T5 z4 Z5 T
  42. ) s  S7 ~5 W& K6 `- L3 {. ?! W
  43.     QFile       *file;
    / i/ R- u2 R! V
  44.     QTimer      *readTimer;
    ( k  M+ i- H  r
  45.     QTimer      *writeTimer;
    / a  T- V5 l/ J% p& j, u
  46.     QSerialPort *serialPort;3 T3 d, Z$ _: `. ~0 T5 Z
  47. - H/ @9 G5 R0 s- o
  48.     int      progress;4 g7 {6 f# p1 z0 y, G! \5 U: ?# Y
  49.     Status   status;
    % _" F5 k, I: d) d. H
  50.     QString  filePath;# e  b' P! T, F* j- A
  51.     QString  fileName;
    + m' I, L: v; q7 S0 e
  52.     uint64_t fileSize;, A6 B+ S. A, [6 W% q
  53.     uint64_t fileCount;
    / v- a! T. {; g% k8 n5 a6 g! ~
  54. };
    ( b" N; D) W6 K& @: o; _

  55. / p: U8 K3 B" Q$ c" ~, f; R( _
  56. #endif // YMODEMFILERECEIVE_H. H* h" H  B) F; I% s
复制代码

% i* m9 u& `1 {6 Q+ Q      YmodemFileReceive.cpp文件0 i+ H/ y6 @, J& ~4 d: t' z
  1. #include "YmodemFileReceive.h"
    + X$ h, a) I1 I- G% }1 b* m
  2. ; l6 V+ L, G- [9 r
  3. #define READ_TIME_OUT   (10)
    + ^4 t( U6 n, a; {
  4. #define WRITE_TIME_OUT  (100)
    4 D3 L4 y( W. r( \
  5. 3 ^; }# Z, g8 e, ?
  6. YmodemFileReceive::YmodemFileReceive(QObject *parent) :
    ; D% F; i. F+ @- |
  7.     QObject(parent),) j- f6 c% t- x: N; {! S
  8.     file(new QFile),
    7 M3 G0 O6 H" v6 x- L
  9.     readTimer(new QTimer),
    % A' @+ s; m  v- i
  10.     writeTimer(new QTimer),! J. \& N9 W9 ^; [- A  t3 ~/ f# f8 ~
  11.     serialPort(new QSerialPort): B2 y% z& z: T* T+ @. b
  12. {
    ' v( N7 s# ?' ^6 ^3 \# w  P% ?
  13.     setTimeDivide(499);# ]( e! t! z! R, y( a
  14.     setTimeMax(5);
    & N& ?4 \0 N; r7 s& w/ |* E! I/ F1 Y
  15.     setErrorMax(999);( P8 T) R& J! @9 E0 s+ W; `/ y. N
  16. % A/ i, f, t# \( U, `
  17.     serialPort->setPortName("COM1");' f5 y0 G5 ^- u. ]$ Y1 Y
  18.     serialPort->setBaudRate(115200);
    1 i$ m/ m- W# r
  19.     serialPort->setDataBits(QSerialPort::Data8);
    : L% R/ [% j7 H7 t4 u; s9 ?
  20.     serialPort->setStopBits(QSerialPort::OneStop);# {. m- M8 i. d1 m, j) h1 v
  21.     serialPort->setParity(QSerialPort::NoParity);. R$ N- h# M" Y# N6 p/ V
  22.     serialPort->setFlowControl(QSerialPort::NoFlowControl);
    2 C% e+ `. I6 G1 f8 X* ~
  23. ' B# h! X" m$ ^; c! T8 N" s
  24.     connect(readTimer, SIGNAL(timeout()), this, SLOT(readTimeOut()));5 |3 n9 @+ R3 L7 ?- c
  25.     connect(writeTimer, SIGNAL(timeout()), this, SLOT(writeTimeOut()));* `! \, n: L- s# {5 B* B+ S: T( O
  26. }
    4 C  n. U! |: X
  27. + U! c: n& u9 w! R1 D/ E5 U) c! H
  28. YmodemFileReceive::~YmodemFileReceive()  l5 O' t; H" t! ]0 k3 ~
  29. {. Z) E0 N+ h' A* i
  30.     delete file;
    3 x: `4 J, f$ T  q; ^7 C! b
  31.     delete readTimer;  z  i, [+ i6 L* n
  32.     delete writeTimer;
    8 A0 u# K6 j0 s: X3 G8 G
  33.     delete serialPort;( U: I: r# Y$ c8 p# V& I9 @5 M  R
  34. }
    4 x& c3 G, @5 W* M5 s; u2 l

  35. # Y: ^! \8 r( Q
  36. void YmodemFileReceive::setFilePath(const QString &path)6 x- s+ [+ P8 {  O% e5 F
  37. {; n2 [  w1 O: v% j' b' l8 \' ~
  38.     filePath = path + "/";3 f7 G) z6 M; o9 u+ h! C& p3 T% {* g
  39. }
    " b4 [7 Z5 k8 |, U$ k
  40. & n" \) N1 E5 L5 }* k
  41. void YmodemFileReceive::setPortName(const QString &name)
    * ]$ A- W! L. ^; s8 J7 a! L
  42. {8 a) {! o# l, R2 ?
  43.     serialPort->setPortName(name);
    0 U3 V& ], m0 R1 G. L$ l
  44. }
    5 z9 D& @/ t2 v/ a& r5 G7 |  k
  45. 0 d9 g  B5 C( y, o) X7 M
  46. void YmodemFileReceive::setPortBaudRate(qint32 baudrate)  e6 A3 W; [7 X- G5 t3 G
  47. {
      W; ?5 @# o" g4 V, e- D
  48.     serialPort->setBaudRate(baudrate);7 m5 T3 o8 [# Z9 _
  49. }# n9 d/ B: M' E6 }! l! j
  50. ' u( ?8 P  f( w' A  A6 w7 h
  51. bool YmodemFileReceive::startReceive()' Q6 L+ R- G7 h* Z' P6 ?
  52. {
    2 v- q& a) Y/ J' L
  53.     progress = 0;
    / _6 ]- \7 e/ L3 m. D/ w& c; k
  54.     status   = StatusEstablish;: A; {' W9 |0 c$ b+ i

  55. . z' ~8 U$ l; p3 @
  56.     if(serialPort->open(QSerialPort::ReadWrite) == true)" h$ G1 b" X3 t8 L" A
  57.     {
    & g' E9 L6 O" h! ?- y& d* Q4 p
  58.         readTimer->start(READ_TIME_OUT);
    3 ?8 V4 N! L/ q

  59. % v/ b: j: m: u- x+ T* x
  60.         return true;( H5 J. u  ]# k  I, R* l
  61.     }
    5 F1 Q$ k* W; T9 r9 _7 Z
  62.     else
    $ W& n$ R$ A, n
  63.     {3 }/ e! N0 x/ p) v
  64.         return false;
    7 a- K$ q# b0 H( _1 ?% V2 |9 U
  65.     }
    9 _. `" U& w5 j- F8 r8 n" O4 S
  66. }6 p: v' X6 L- ^0 D3 q

  67. 7 l+ ~$ s& N8 c; j" I/ T2 b8 V  T
  68. void YmodemFileReceive::stopReceive()2 D; b& J3 O  v9 a
  69. {
    ) u1 L& r8 l) i
  70.     file->close();6 o, N/ M! ]  [& N1 J. V" ~
  71.     abort();/ M$ ]* V( |0 U2 `6 J
  72.     status = StatusAbort;
    - m+ S8 A) @' b3 ~0 w! ?1 U( d
  73.     writeTimer->start(WRITE_TIME_OUT);
    ' O8 c- k+ a5 ~) K
  74. }
    ) m: a" _. I8 q3 i$ g& d0 s+ ]

  75.   v9 M) P& h0 J3 S; W3 @* \
  76. int YmodemFileReceive::getReceiveProgress()) v- |4 {+ L4 y4 b
  77. {$ g' }3 H  ^5 J) I9 }& S
  78.     return progress;
    4 l( `2 X* k7 ~" `- t5 t* M
  79. }2 U& \; K7 |, u8 W

  80. 5 {/ v! M5 D- ]1 b
  81. Ymodem::Status YmodemFileReceive::getReceiveStatus()
    ) b/ a8 V" M2 [6 p
  82. {. o1 {6 D8 j+ n& j1 C4 f
  83.     return status;+ X6 I' ?: ?. G. {& j
  84. }
    9 {4 S7 s% v/ {- E2 O
  85. 7 `" `9 ?, A' w% H4 |
  86. void YmodemFileReceive::readTimeOut()
    0 R4 O5 @/ e8 m4 j. z- n6 v
  87. {
    / {, }0 _. U# N, u. M8 ?( l  q
  88.     readTimer->stop();% b# _& z3 W% {$ u8 k
  89. $ e2 u) t# \5 z( A
  90.     receive();
    % k( `% g& `* R4 ]; F
  91. 7 y: ~" B: @. D% [( Z; R7 m
  92.     if((status == StatusEstablish) || (status == StatusTransmit))
    & n( `/ g: A: U; G* r
  93.     {
    3 m$ i# K  _9 _- Y! p2 [5 G
  94.         readTimer->start(READ_TIME_OUT);
    6 |% c; U7 R  x# }' N% r) q
  95.     }9 i2 H9 k" e  l9 {1 k  }5 D
  96. }2 T. @  V9 [. k2 Z2 H" R
  97. 0 o% e, K$ N+ u/ i
  98. void YmodemFileReceive::writeTimeOut()
    8 w. O7 R7 ?- R
  99. {
    + j( M) x: `% k9 t8 c3 r6 j! `
  100.     writeTimer->stop();( C9 o1 N$ h. A& M2 s% S5 g
  101.     serialPort->close();+ F: Z! ~1 _2 N0 m/ o$ L
  102.     receiveStatus(status);: S/ Y( c# m( B. M' ~
  103. }5 S/ I: ?, x6 e
  104. 7 N1 h3 n. t6 p# G& O- g" m2 {
  105. Ymodem::Code YmodemFileReceive::callback(Status status, uint8_t *buff, uint32_t *len)# c+ [7 _$ ~% n# B
  106. {* k+ R# Z# a* E" B5 Y% t
  107.     switch(status)
    2 Q0 |  [4 B$ F# `
  108.     {* G+ E- F7 Y# G. n' W
  109.         case StatusEstablish:
    ! Q- ^8 E1 I- |
  110.         {) Z* y# O; H) e% K" n5 _" Z
  111.             if(buff[0] != 0)6 z# W" Q5 H3 }- K
  112.             {
    & u& C# E% l* b% O
  113.                 int  i         =  0;: p# P6 l; O# e0 F5 B) X
  114.                 char name[128] = {0};( o3 ]4 {% y- L$ W$ r( }
  115.                 char size[128] = {0};
    ' z/ O& z) X0 j0 \

  116. $ |* W/ h# x  X% p, a) C  O
  117.                 for(int j = 0; buff[i] != 0; i++, j++)+ y/ t7 G/ g9 Q9 z+ M: K) a
  118.                 {
    2 h2 U0 ]/ @5 h9 H! U1 Q3 Y& L3 |
  119.                     name[j] = buff[i];
    9 F: |; o  F  D2 r  ]( `/ N
  120.                 }+ A* g  A% P3 |9 u2 f' C
  121. ( \& A; E# S: v3 G+ D. }% Z
  122.                 i++;/ t; X# i% v' M7 n, Y

  123. + ^6 j* S/ f( h) P- u9 l) n
  124.                 for(int j = 0; buff[i] != 0; i++, j++)
    5 E( P+ f8 P0 M8 F
  125.                 {
    9 w7 q! i/ Q9 q& r8 g/ _+ k! }
  126.                     size[j] = buff[i];% P8 A& r( l+ F1 h0 ^4 J
  127.                 }8 \* _0 _5 l  g4 V
  128. ) V' C+ Y' W/ r1 E3 t! b( f1 ^( s2 u- N
  129.                 fileName  = QString::fromLocal8Bit(name);
    8 M8 w3 o3 G+ F7 R
  130.                 fileSize  = QString(size).toULongLong();3 h, f3 D$ n8 k; r
  131.                 fileCount = 0;- }4 R6 j* X$ j5 N
  132. 5 G' @+ f$ O6 E6 O4 s* c* m' c
  133.                 file->setFileName(filePath + fileName);
    % g7 L: L# U9 ?0 }) T
  134. ; D) s2 G. z# Y( X# P
  135.                 if(file->open(QFile::WriteOnly) == true)4 c% P4 {2 t0 K. L% `4 w
  136.                 {* ?7 ]! t8 q! `. R7 r0 e; ~6 ?  D  j
  137.                     YmodemFileReceive::status = StatusEstablish;
    9 y& |" z- P- s4 S" b& j: A6 R
  138. 6 }$ }$ h% S$ ]( D
  139.                     receiveStatus(StatusEstablish);) i# C! Z  ~+ y' t; r- r
  140.   I8 ?) l9 D* x8 ^8 c5 R) h
  141.                     return CodeAck;9 F% X8 u2 J# w. X, R4 H  G
  142.                 }, J& P5 H+ c! D- I$ y4 j
  143.                 else" u9 K; r  X! K% S4 h
  144.                 {# d- `/ q3 U( L
  145.                     YmodemFileReceive::status = StatusError;
      e! W' z- i7 O7 L: B; j5 b0 l

  146. : A# H8 ~9 w) {3 w- q9 j, c: T
  147.                     writeTimer->start(WRITE_TIME_OUT);- I9 \7 J/ A) v
  148. 4 k/ |: F" o- ^# _3 H, c) \
  149.                     return CodeCan;
    9 f0 J5 P' t2 Y* ?
  150.                 }
    / i% u: b; \# u8 g6 z  j1 L# M6 D
  151.             }9 ?# |, ^: Y% R) x
  152.             else8 s0 ?9 t: U( h% B! D; ~' g
  153.             {6 G: S5 @0 c* N: B
  154.                 YmodemFileReceive::status = StatusError;
    4 O2 X2 n4 h/ K& Y$ M4 Z% |" P

  155. 8 g+ n; J/ \, L1 }/ X
  156.                 writeTimer->start(WRITE_TIME_OUT);. u$ A; a* f* C

  157. 4 P7 s; ]1 {% r6 m' ^$ n
  158.                 return CodeCan;
    ; k) v; ~: a* X8 w1 A% l- m
  159.             }
    * x2 b5 Z* D# h( M
  160.         }
    * o* Q* r0 n  k$ Z* W0 ], A

  161. . M% V9 |9 h, R! W. _6 L0 C, X
  162.         case StatusTransmit:
    7 I  K  {: m( E; Z9 ~# j5 W  G& u
  163.         {, H0 h/ M; Z2 C! [4 m
  164.             if((fileSize - fileCount) > *len)4 B1 ~6 n4 T) `0 d7 m7 Q
  165.             {
    # K- S$ G! s2 F
  166.                 file->write((char *)buff, *len);5 l5 u# L5 S* L( R  @
  167. # L; o9 U  m7 q( }1 R% z3 b6 [
  168.                 fileCount += *len;
    $ l2 S7 [3 D; |) Z# \2 S) H4 j8 T
  169.             }
    0 W0 h% J" S, N/ V
  170.             else7 S1 b  {9 I- Z3 J' L% R1 d
  171.             {
    . C7 \! m7 S3 y8 F4 @+ Q
  172.                 file->write((char *)buff, fileSize - fileCount);
    ) ]1 }9 K$ n# L) b0 P7 R( N2 j
  173. ' E: G1 @/ Y  j/ A0 v+ j2 _
  174.                 fileCount += fileSize - fileCount;
    ( i% U2 J% o: L# V1 t
  175.             }: v. W$ y5 e/ M0 S) O7 F
  176. 0 j& f3 k9 w1 A- Y8 r. k" ^1 y) f  I8 n
  177.             progress = (int)(fileCount * 100 / fileSize);* @# W9 u$ L$ N: l% x
  178. # ]# N8 }) F, q3 ?
  179.             YmodemFileReceive::status = StatusTransmit;/ Q' _4 Y& i* G. c/ _/ \0 F
  180. 6 P7 z( ?" {7 P1 D1 L9 k
  181.             receiveProgress(progress);  N2 f8 w+ S3 j$ }2 z  e' R2 J
  182.             receiveStatus(StatusTransmit);- K5 c8 S( H: _- p0 r7 S& O/ L

  183. . I1 {: N& X0 \1 [' {. Q, d
  184.             return CodeAck;
    5 M0 Y  M" B8 c1 F+ R# ~0 X+ H/ G
  185.         }5 D; w% a" ^9 q3 h0 [  W9 c

  186. # C( q! b3 z4 d, b2 V: N7 f
  187.         case StatusFinish:+ \4 G& x4 S) p
  188.         {
    1 U2 q4 M$ r6 L& g, K
  189.             file->close();
    / w6 @) Z) B+ H  E2 J$ J
  190. ; I$ O  ~/ m/ ?* V  G! K: w$ T
  191.             YmodemFileReceive::status = StatusFinish;
    2 |5 b" P& o8 g4 u

  192. " n4 z4 f5 h( d) [( l
  193.             writeTimer->start(WRITE_TIME_OUT);
    % i0 J. o4 ^, \! [! G( F

  194. , s) `: l4 N3 ?# A
  195.             return CodeAck;1 E' J% e9 b, I+ c5 J" k9 l# N" ?( [9 f
  196.         }
    - h- K5 o$ y& a6 {" ^
  197. * z8 k5 r* M1 _% e5 Q3 M$ H9 J
  198.         case StatusAbort:
    ! C% x9 }7 @/ C2 E( y& A1 \
  199.         {! x% z! C7 C- g$ I  z
  200.             file->close();
    6 j0 @. t) k6 j& i7 Y
  201. . ?6 @# [) f7 P+ O
  202.             YmodemFileReceive::status = StatusAbort;5 ~* Z) _: \. C; s7 U3 D* h, d

  203. * b$ J6 J4 V& g' s! |$ X+ }- |" x
  204.             writeTimer->start(WRITE_TIME_OUT);
    * ?$ f: G5 X5 x* ~& ]5 V' J: y
  205. 6 A& x- S" m8 p( Z
  206.             return CodeCan;5 Y( }3 s* c+ h$ v: I& q
  207.         }0 w# s# d8 q- U: M
  208. ) w* t: ]: j$ |' f5 z- }( s
  209.         case StatusTimeout:
    ' Y+ R2 z( [5 \/ s
  210.         {0 a; ?" {  ]& y# o( z9 q# h
  211.             YmodemFileReceive::status = StatusTimeout;" Y  g1 Y6 \$ u0 \2 W" q. I& g

  212. 0 G9 A  I) `- d$ z+ Y) X6 F
  213.             writeTimer->start(WRITE_TIME_OUT);
    0 ~" q; E/ n+ [
  214. 1 c. A0 {% ]4 M7 ]! @! {
  215.             return CodeCan;
    9 C4 n$ b6 ?; l+ o0 P' ?6 ]8 T
  216.         }3 _9 j( r0 z2 O. V  ?
  217.   n  b" A1 }  T; w1 \( P, U
  218.         default:
    1 Q; G8 I; V: S
  219.         {- M( x+ d( E) h
  220.             file->close();
    9 ?2 }/ n9 i3 S- s- g$ ]
  221. ) L: O, M% }$ ^: E* v; I: n
  222.             YmodemFileReceive::status = StatusError;
    0 m' s2 y: X2 E* ]- u, ^0 e. n
  223. ( q7 H5 p9 T4 |# B( X* R
  224.             writeTimer->start(WRITE_TIME_OUT);
    ; E: e/ _' X. r9 B
  225. % _5 O6 |- \! }! ]: \) x
  226.             return CodeCan;- L/ z  t  M- v
  227.         }) h4 [; _3 d5 c# t
  228.     }8 D' q) p" D& d+ y  T' s1 V, f) x& {
  229. }
    9 [/ Z9 j1 s7 B$ D  r

  230. . Q; t2 J& A" f) }0 e  E
  231. uint32_t YmodemFileReceive::read(uint8_t *buff, uint32_t len)0 k0 a- f: E" a
  232. {
    2 D0 }* B, C" b! G: x( x7 ^+ j7 G
  233.     return serialPort->read((char *)buff, len);& d- Y& d- R+ O1 K: n( k. |
  234. }1 @% D9 X/ o0 R  g4 K9 i+ m) G

  235. 1 L( c' g! \! D
  236. uint32_t YmodemFileReceive::write(uint8_t *buff, uint32_t len)
    # _5 Q$ C1 j+ t' \8 Z! n7 L, ~2 y- X
  237. {3 ~+ f0 V$ O# r4 m% v8 ~: g
  238.     return serialPort->write((char *)buff, len);1 j; a* D7 Q% `8 Z7 L% j" r7 n
  239. }
    . S# |1 |' ~" t" ]5 o2 I/ i
复制代码
6 b6 C( s6 e2 M( M
. D/ H/ i* c7 t& c

4 j9 g+ D4 K2 B+ ^/ C) g$ G8 l* s0 V/ e. k8 t
6 ^, r6 f$ y, X% R( Y3 |
XinLiYF 回答时间:2018-3-6 22:31:26
      YmodemFileTransmit.h文件
* A8 c/ H, D5 y* z. G6 D1 u
  1. #ifndef YMODEMFILETRANSMIT_H9 O  q: ^* x" P& {9 V# ?
  2. #define YMODEMFILETRANSMIT_H2 O' z/ T6 b& S4 c( G
  3. % s, b. [8 h4 d1 ?- ^4 B  z  C
  4. #include <QFile>
    4 H4 J5 V; z$ O. \5 X
  5. #include <QTimer>
    5 l+ F! X, ]2 K& E
  6. #include <QObject>
      R$ U$ \( Y3 Y! Z7 V
  7. #include <QSerialPort># N/ |+ F6 u7 B* L4 `
  8. #include "Ymodem.h"3 j6 I( z- E3 G9 g  o

  9.   b9 W/ _6 x0 b& E3 ]
  10. class YmodemFileTransmit : public QObject, public Ymodem
    % a+ p9 c) r$ _
  11. {' S- L" m2 v: ]9 @/ w/ r( ^  v0 p
  12.     Q_OBJECT
    * l! [9 t* _* b8 ?* q8 u1 ?5 L7 ]
  13. ( q0 R9 V$ e  I" N0 p
  14. public:
    / a! A/ i( ]3 D0 O# j
  15.     explicit YmodemFileTransmit(QObject *parent = 0);
    , ~! \5 y0 S' }6 s' F
  16.     ~YmodemFileTransmit();/ d8 Q9 m4 }2 W  ~4 O
  17. ) l1 r7 e! v: H  }% O' T! I
  18.     void setFileName(const QString &name);
    ) M$ J* n$ |2 c5 e  \7 j$ C- y

  19. / q( K' O$ G3 `# M& _- Q2 H
  20.     void setPortName(const QString &name);4 e! E8 L; x2 g7 ~0 H
  21.     void setPortBaudRate(qint32 baudrate);4 Q1 S$ A$ |% `4 l* G  p! ~: J. z, L
  22. ! x! G4 s/ U- b8 ]% S9 U) {
  23.     bool startTransmit();+ u$ f+ c) u) u! N. Q: |6 L8 r
  24.     void stopTransmit();
    3 N7 w0 S" m' ~; h1 T: F8 S4 h

  25. 6 G4 {3 }5 y5 M. c0 _- I# f
  26.     int getTransmitProgress();
    # S9 A2 l9 D' o# A% j2 w
  27.     Status getTransmitStatus();
    ) S. L, [, M. ~2 L5 x& }
  28. 6 j* Z+ Z9 _8 ?; ^1 G
  29. signals:
    ' N( P# v8 T- m! p5 H5 D
  30.     void transmitProgress(int progress);
    " g2 R% a* I& L( E0 b8 F
  31.     void transmitStatus(YmodemFileTransmit::Status status);* A5 t. z7 i5 f8 }6 O

  32. ! C% |5 T- |) m$ F: s
  33. private slots:7 v6 T" g) }9 z+ w' e
  34.     void readTimeOut();" c6 k- K0 h9 u0 i9 L7 r9 V
  35.     void writeTimeOut();
    3 `) ?& K' |5 t3 O: {

  36. 3 r7 f/ H2 R1 |6 k6 a
  37. private:
    2 x# c( C) }+ L4 w0 L; \
  38.     Code callback(Status status, uint8_t *buff, uint32_t *len);8 a' i: o6 R: Z4 q

  39. 7 @: m2 w5 y/ d) N4 u5 M
  40.     uint32_t read(uint8_t *buff, uint32_t len);$ {; i+ r5 {4 r; @9 v
  41.     uint32_t write(uint8_t *buff, uint32_t len);
    * K" H0 `: u0 q4 V) ?$ B: K

  42. 3 U- Z. G6 `) h# l. Y0 V- @
  43.     QFile       *file;
    5 V2 O3 J1 ^% Q( o+ f: U
  44.     QTimer      *readTimer;
    2 o5 v- P+ ]' q1 x, X/ @, e: U
  45.     QTimer      *writeTimer;3 G6 o( v' u: U: E
  46.     QSerialPort *serialPort;2 v! P% B7 n6 `' J
  47. 7 m: B, q) S! |2 X% O. Z( }
  48.     int      progress;
    * h& J" U9 H" Y& P; z3 V
  49.     Status   status;
    7 m! @7 [! M+ |$ T) N7 R
  50.     uint64_t fileSize;
    " v6 B$ [# `5 o7 [
  51.     uint64_t fileCount;
    5 o- ^8 t6 ~5 p3 I
  52. };
    8 Z) J0 V, Z0 E1 |8 k8 m7 I

  53. - O+ B; X, k# s/ H& h; `/ i# z' d
  54. #endif // YMODEMFILETRANSMIT_H
    ) q" K9 ]7 g- a% P
复制代码
3 u7 D% x3 b; ~6 N
      YmodemFileTransmit.cpp文件; v$ q. ~8 E) {& y  ?
  1. #include "YmodemFileTransmit.h"
    9 h! f1 P  {; f6 Q. Z- @( U5 a; H
  2. #include <QFileInfo>8 t1 Y" f+ d1 Y0 |7 ]
  3. % E- N& K* h7 i
  4. #define READ_TIME_OUT   (10)$ g7 v1 I# _% f& e  I- g2 z# Z
  5. #define WRITE_TIME_OUT  (100)3 a  V, t0 {2 R
  6. 9 O9 Q/ g$ o2 F! E
  7. YmodemFileTransmit::YmodemFileTransmit(QObject *parent) :: Y. y$ B7 N+ ?
  8.     QObject(parent),+ n) i# w' ~) {; c, a: ?  g
  9.     file(new QFile),. E  R. j5 M9 ^
  10.     readTimer(new QTimer),
    & `, ]: ]) k5 y! \' [$ s
  11.     writeTimer(new QTimer),
    8 W; M: \1 {2 A* ?- n& a2 {, s
  12.     serialPort(new QSerialPort). w/ {2 T$ _7 R5 a. m
  13. {
    ' Z! s7 R3 x- y) H
  14.     setTimeDivide(499);/ k8 ~  E6 ~* |3 e
  15.     setTimeMax(5);2 I2 G" A9 v; x, K$ s, {2 U
  16.     setErrorMax(999);" ~: |/ Y* q1 x  S9 e
  17. ' ~9 I5 w2 h' p. J9 u1 s* ^
  18.     serialPort->setPortName("COM1");' g* u5 t5 S  K* _  p& Z( M
  19.     serialPort->setBaudRate(115200);
    1 X2 Z: U* @. J
  20.     serialPort->setDataBits(QSerialPort::Data8);+ |6 W" Z# R% \
  21.     serialPort->setStopBits(QSerialPort::OneStop);" d! {5 \" s) I: V: y' {
  22.     serialPort->setParity(QSerialPort::NoParity);. p8 b( S5 _0 C/ R
  23.     serialPort->setFlowControl(QSerialPort::NoFlowControl);
    . W; F/ b3 P  {; G$ W# \5 G+ S
  24. 8 F  e; s! d$ V
  25.     connect(readTimer, SIGNAL(timeout()), this, SLOT(readTimeOut()));& L9 U1 }3 P5 X/ b
  26.     connect(writeTimer, SIGNAL(timeout()), this, SLOT(writeTimeOut()));
    $ w* l0 m  k+ E
  27. }
    ) {2 w+ o( d; z4 j

  28. ' C1 l3 ?  D$ e0 @; A
  29. YmodemFileTransmit::~YmodemFileTransmit()- W; J: [  s4 o4 m) J
  30. {
    8 z0 P/ V; c3 J9 b+ W4 G' {$ k8 Q
  31.     delete file;
    $ \% A( _. M2 T2 H3 d7 g2 T0 c2 i
  32.     delete readTimer;
    6 Z# @# u2 I1 c0 B) `- M8 _" n
  33.     delete writeTimer;2 i8 o* y- r& v
  34.     delete serialPort;
    & k4 C+ D' j- P* O, F( Y
  35. }, E  g$ z5 {, l* V
  36. 2 ?% x. ]7 R0 j1 Y  B2 P: h& V; j; z
  37. void YmodemFileTransmit::setFileName(const QString &name)" H' b+ V5 M; y& q5 |8 N
  38. {
    # c. b1 v# j* J3 {
  39.     file->setFileName(name);
    + p& o! `8 ~( C: |! L
  40. }
    $ q8 q  C$ b. j5 y7 Y
  41.   \* o9 l, N6 d9 A
  42. void YmodemFileTransmit::setPortName(const QString &name)
    2 R" q+ O9 _  I$ G0 `' y4 |
  43. {! q" s5 J- ]. ]9 i
  44.     serialPort->setPortName(name);
    * ]! W* c+ Q1 L' S- l4 j
  45. }2 y- |! e' `4 e+ Y" _. `
  46. . ?  C$ Z: }  E7 {& }) T- ]9 T- H0 r) E
  47. void YmodemFileTransmit::setPortBaudRate(qint32 baudrate)6 |4 P  O9 a9 C$ m, i! Q
  48. {
    , a! ?% Y0 `0 i( K
  49.     serialPort->setBaudRate(baudrate);
    3 Z8 T1 b- Q8 p$ o! x1 g
  50. }
    : {& R! c5 b+ g4 u. F" U
  51.   W; K7 {; o; H/ T; q
  52. bool YmodemFileTransmit::startTransmit(), @. D1 E( R+ C
  53. {
    - _1 l" l3 {% Y0 v* u% J. d5 }. h
  54.     progress = 0;! Z+ q- }4 G! D2 v: b
  55.     status   = StatusEstablish;; [, M( X  l2 f2 W5 a: p

  56. . p6 \9 j+ k/ F, c2 \% Z: f
  57.     if(serialPort->open(QSerialPort::ReadWrite) == true)
    $ u+ Q1 C) U! S! R$ E& K
  58.     {
    " s& R' P7 s7 d. B: O# p; p: {
  59.         readTimer->start(READ_TIME_OUT);9 ?2 H( f5 k5 D

  60. $ k7 ?) u+ x2 n. U; D
  61.         return true;
    5 C9 f+ Z1 _3 n! u
  62.     }
    ' `" z% [' q) X' H- E/ v
  63.     else
      y" o# a. \0 Z+ t3 M& E
  64.     {
    2 B" L* Z, z" u6 v' j* Q2 l
  65.         return false;
    4 I) n( ^+ G7 Y; k% Q* q6 a
  66.     }
    : h9 ~9 q3 x" R6 I7 D" _& M+ y$ ~
  67. }7 ?* Y- e) q9 h5 _
  68. / `7 |) T1 R- w
  69. void YmodemFileTransmit::stopTransmit()
    # f9 ^$ X/ o  n2 b
  70. {0 U! V/ L  e+ ~" _' Q4 G1 t- ]
  71.     file->close();9 ^) B6 I0 T3 _4 [3 R
  72.     abort();
    $ S2 @2 v6 V5 P0 D3 p( ~' X0 u
  73.     status = StatusAbort;+ g& z. K9 H( V7 R8 |
  74.     writeTimer->start(WRITE_TIME_OUT);" @$ Q; v$ q$ o1 i# g) {, K
  75. }# M  ]7 q" n/ x; }* P! H
  76. # K9 b2 J+ h3 i" e; p  ?
  77. int YmodemFileTransmit::getTransmitProgress()
    5 u6 ]6 U2 |$ W/ d) q8 n. x
  78. {5 ^9 X2 [7 B% h& f/ n
  79.     return progress;
    + q. U$ }8 |7 j3 ~5 w" m! N6 G
  80. }5 L( Y( I9 m1 n# @
  81. + Q- y- s( w+ P) _8 y# F% h
  82. Ymodem::Status YmodemFileTransmit::getTransmitStatus()
    ' P- d! C2 c' R
  83. {
    8 b( ]6 a: t/ p& d( ^* m
  84.     return status;
      h& ^- m& G. p5 t' K
  85. }
    & D5 Z% i9 b; R7 t
  86. / X7 U+ ?) o# r% l; k3 r
  87. void YmodemFileTransmit::readTimeOut()( r1 n) l' }# T- K" ]/ R" u$ `1 j
  88. {
    & ~! b( U' e7 l+ G  S. X
  89.     readTimer->stop();
    ! R3 A4 R( z1 V

  90. + {; A# _: H# A5 |; ?& N
  91.     transmit();- `, e0 R  W4 q5 E& F2 `- l/ P

  92. 5 Z! r7 D# ~4 C' V  Y
  93.     if((status == StatusEstablish) || (status == StatusTransmit)): D! U8 ^' I/ t0 u
  94.     {. g1 b9 H. M& L2 a4 ~$ o
  95.         readTimer->start(READ_TIME_OUT);
    4 a" u- n+ l. x) u. H  d
  96.     }
    9 y; f: Z; Z+ ]7 q9 j/ K6 c, a
  97. }1 R/ ]# w, w* y2 }4 N$ A1 y

  98. 9 t! k; N2 C6 g. N. a  l* ?6 ?% c
  99. void YmodemFileTransmit::writeTimeOut()
    : Q$ T4 }/ \! P/ k. |+ W- V1 q
  100. {
    & x' E; R( D* B6 k, m& ^
  101.     writeTimer->stop();0 t; i( x3 N6 Z) P( }0 `; m$ I
  102.     serialPort->close();
      T- p9 [3 W* y7 w$ G% q
  103.     transmitStatus(status);
    / b$ [- `4 P( a9 `: |
  104. }- a7 \" Q. G8 M/ x
  105. 7 y* P$ {( J. Y- V
  106. Ymodem::Code YmodemFileTransmit::callback(Status status, uint8_t *buff, uint32_t *len)
    7 x# u% Y5 c" [. ?9 y
  107. {
    5 t2 R4 R5 R. s$ w  j0 _! Q
  108.     switch(status)
    - N5 o" Q* B0 |6 Y, t+ t
  109.     {
    * n! F6 {! O" u
  110.         case StatusEstablish:" v  G3 Z. c5 X& F% @9 z0 b
  111.         {
    ! N1 A0 o7 I6 M- W: w1 v
  112.             if(file->open(QFile::ReadOnly) == true)
    3 m; F3 Q1 f/ l$ _- O
  113.             {
    . M% B) v0 v; h, c8 G
  114.                 QFileInfo fileInfo(*file);
    : r. [  H( ^' ?# e

  115. 3 d7 Q; y. E6 U- @6 G9 M8 K
  116.                 fileSize  = fileInfo.size();
    8 y: M8 A7 F$ z0 @( T' V! ?$ L
  117.                 fileCount = 0;
    % N3 e3 y/ Z9 |
  118. ) G% q( @" N/ i7 n& [
  119.                 strcpy((char *)buff, fileInfo.fileName().toLocal8Bit().data());& m% j  K8 {3 w& W; ~! s
  120.                 strcpy((char *)buff + fileInfo.fileName().toLocal8Bit().size() + 1, QByteArray::number(fileInfo.size()).data());
    # b' t) h8 j: f3 `1 ~% F6 o

  121. 4 T5 W9 h" F2 l' }9 W; [
  122.                 *len = YMODEM_PACKET_SIZE;
    * d5 p3 D/ [8 S) |- |
  123. 0 ~- E, W: U# G& |: h
  124.                 YmodemFileTransmit::status = StatusEstablish;( i6 i8 L  U1 l: L- o! F) P

  125. 9 g9 `( Q; m, B" U
  126.                 transmitStatus(StatusEstablish);
    % d/ z; J: S# r% u
  127. 4 R5 T" n6 u6 r' J. t
  128.                 return CodeAck;9 k! C/ A0 k! u7 e$ G, c! S; N
  129.             }, n5 a5 A! N3 s# [
  130.             else% J6 ^0 Y# P# s; y" l& H/ K
  131.             {
    8 X! \$ `8 `, W: c, m- @4 ^
  132.                 YmodemFileTransmit::status = StatusError;8 `' ]" @4 K1 a4 Q% x
  133. 1 G* g6 T4 d' C3 c" o4 T7 M
  134.                 writeTimer->start(WRITE_TIME_OUT);
      e6 ~! [8 I/ q( U/ A
  135. - V! s$ w9 E2 X6 k4 A
  136.                 return CodeCan;
    3 q! T  d) r: c9 u/ g
  137.             }+ a4 [( {8 k' k, s! u4 h" y1 W
  138.         }
    . |) y) t; P9 n3 B
  139. 0 b$ O! s* o+ X0 Y$ ^+ |" q
  140.         case StatusTransmit:, ^! `8 h/ q, n
  141.         {
    4 \  b( F# E2 B$ t$ s% e/ B, n
  142.             if(fileSize != fileCount)
    ; V0 M0 B, A& f9 k- L% @0 M9 Z
  143.             {
    ( H4 |/ Y6 N- F8 b
  144.                 if((fileSize - fileCount) > YMODEM_PACKET_SIZE)8 c. i  m3 ^+ F* T8 ^, h
  145.                 {
    0 ^, s6 {; z/ @) M% Q: l
  146.                     fileCount += file->read((char *)buff, YMODEM_PACKET_1K_SIZE);) b( Y; ?2 E/ w" ^, l

  147. 3 K  t7 J& b* |
  148.                     *len = YMODEM_PACKET_1K_SIZE;
    ( K* G4 R/ z  S" z; a
  149.                 }# o- s! z2 l, J6 H. ^/ k
  150.                 else
    3 k( s' @: H& Q; I' j3 J
  151.                 {3 e# b+ x+ {, g, Q2 W/ p
  152.                     fileCount += file->read((char *)buff, YMODEM_PACKET_SIZE);# L# K( b8 }' ^/ H7 G) [

  153. # H: a' b7 w0 R7 f! w5 V  s" s
  154.                     *len = YMODEM_PACKET_SIZE;
    $ \0 P8 f( `0 o# A- Y) k4 f
  155.                 }6 B3 ?8 v7 @# F6 u( z/ K% ?
  156. 2 K# ]4 f9 B  C& B' I  e& l
  157.                 progress = (int)(fileCount * 100 / fileSize);% P* q! n* ?  ?0 Q4 N9 J/ K/ p* G
  158. 5 `, o7 p8 [3 p. B" A- S0 n
  159.                 YmodemFileTransmit::status = StatusTransmit;
    , G5 g' z- K+ d1 S# N
  160. % i' }5 r* e- C
  161.                 transmitProgress(progress);
    + P' e& W' m: I' _# l, N/ M+ V; N
  162.                 transmitStatus(StatusTransmit);
    8 `* J- j1 n! q5 s/ X+ e3 a
  163. $ j; w4 ]- C& D" Q+ @# }# k3 e  H1 _
  164.                 return CodeAck;
    1 [3 w; G9 E. ~% V) j2 v( C4 n
  165.             }, L7 W1 L' H' ]. N5 H& J
  166.             else1 C  P6 D  M9 R3 O/ V
  167.             {
    ; e- `5 d  J+ f1 ?3 C: c( h5 E, Q# d
  168.                 YmodemFileTransmit::status = StatusTransmit;0 k5 p- }- }  t+ w* H
  169. , u7 _, ]& e7 [. q5 K) j" \  @4 V* T
  170.                 transmitStatus(StatusTransmit);
    / G0 j) ~2 S! ?/ Y' T
  171. 7 Z. [  j4 m$ X2 F6 Z( O- S
  172.                 return CodeEot;2 U+ ~! J3 V1 Q+ s  \9 q8 m
  173.             }6 e, N' R9 q; O7 `' U5 \5 j
  174.         }
    $ @" I5 Z* @2 G$ q& I7 p

  175. . d; f& }# W# O/ e7 z+ D2 M
  176.         case StatusFinish:
    7 W  `6 a9 }6 P) N$ M, y
  177.         {( O! |+ n  N7 u& U2 E1 [
  178.             file->close();
    & w) @2 q  ~( z' R) R
  179. ! ?8 H! t4 T9 G
  180.             YmodemFileTransmit::status = StatusFinish;
      i7 K- _9 }7 ]3 U0 ?8 R
  181. $ |/ s' }: M' I3 C: Z0 |
  182.             writeTimer->start(WRITE_TIME_OUT);
    " P" P. |1 l  H% M2 T, ?3 x* G/ w
  183. ; ]9 H& X& K/ k4 r( R  I" z
  184.             return CodeAck;: ~( Q2 ^8 _5 n! ]
  185.         }% S; c1 V$ `0 ~, r: N! V. t% f* ^; ?! G/ @

  186. 8 A' }6 d% i/ p3 r6 L1 r
  187.         case StatusAbort:' V. b/ {4 ?0 O
  188.         {) X- Y' A1 b2 Y. {( R" ]# r$ l: d
  189.             file->close();
    / Y8 v  R  Q- L
  190. ! N8 Z/ I( Z. M; r/ h4 c
  191.             YmodemFileTransmit::status = StatusAbort;! r  G& X% E. X, |* }

  192. $ V! _( T; Y) ?* z- m! E; j
  193.             writeTimer->start(WRITE_TIME_OUT);
    9 r' n4 `/ o- X. M

  194. ( T/ L) t5 ~1 [1 u  X& a" Q
  195.             return CodeCan;
    7 B0 [, Y) t# Q% M& s; \$ q: T9 ~: R+ F
  196.         }5 H( X% J0 Z. e0 G2 @

  197. + Z9 ~9 a0 H4 f3 A4 H& I& N. w+ q
  198.         case StatusTimeout:2 T) a! _! p8 @. e
  199.         {
    4 k  r. k. B2 ^6 A; ~1 M
  200.             YmodemFileTransmit::status = StatusTimeout;
    ' \- t+ P3 w! _
  201. $ `2 w4 u# T+ g5 g' C+ g2 ~: ?1 _" l
  202.             writeTimer->start(WRITE_TIME_OUT);' r1 K* i5 X$ s( u6 l& {! t9 u

  203. & }  i5 p% p# w) h
  204.             return CodeCan;
    , D$ k$ J" p) v9 W5 X; b
  205.         }
    1 k/ y% O( E+ C% L, v1 I$ G; r. ]

  206. ' o, }2 u( e! S: c, r. I% D7 I
  207.         default:9 r# [: A4 l2 w! {
  208.         {
    4 F5 x: u3 M2 S% C% T! o" n
  209.             file->close();
    : w9 f) B& q0 Q8 e5 }/ m$ q
  210. ) {  F7 {5 T! Z0 m( c+ I  D  C' F
  211.             YmodemFileTransmit::status = StatusError;& i( v8 F5 w. Y3 b7 N6 q) C. y% x

  212. % v& X! w, S2 t( C7 W
  213.             writeTimer->start(WRITE_TIME_OUT);' H3 \" ?( i6 }- H) v* R

  214. & O" z# H: P# f! T2 u2 ?, F
  215.             return CodeCan;+ f: S' C5 u: j3 \
  216.         }
    4 A5 i8 r: f4 T$ S- r
  217.     }! S' r2 m3 g: A7 h
  218. }6 j0 h) U7 M8 P, H. u5 i

  219. 4 E' F" _' M, K4 I* {
  220. uint32_t YmodemFileTransmit::read(uint8_t *buff, uint32_t len); @+ |9 J) P6 Y3 |, d- w8 W+ @1 q
  221. {
    - u" F8 n4 Y7 M0 A, H0 D
  222.     return serialPort->read((char *)buff, len);
    4 I7 W3 C& G/ n1 @7 O! H
  223. }% u7 f& o( q& P5 U% F
  224. 5 s: C. D' H; y
  225. uint32_t YmodemFileTransmit::write(uint8_t *buff, uint32_t len)
    4 K7 ?" p6 A) e& A- X9 F) a1 o/ x
  226. {9 A1 a. f3 p, ^6 a. ~  t! ?
  227.     return serialPort->write((char *)buff, len);
    5 w) b4 B- K: N0 j, b, p' c# v8 A
  228. }
    ' ]6 m3 M3 D: R0 M% [  G, p8 X
复制代码
" s* O) M2 |& m& z7 @

" X" @6 T. S2 O5 [  D; e
$ |  U6 N+ D  |8 V% E2 u; L' J9 j, J2 h- r
- h, M( t/ k, t8 P
XinLiYF 回答时间:2018-3-6 22:32:05
      widget.ui文件) \- `# S3 W0 a4 Y! x. R
  1. <?xml version="1.0" encoding="UTF-8"?>$ o7 o# t0 X# t! ]  _' i
  2. <ui version="4.0">
    ) u# R2 G- B' P* X' i' Y
  3. <class>Widget</class>
    - n  @4 p+ R7 o9 y
  4. <widget class="QWidget" name="Widget">
    9 Z4 S" D" \* |2 ~
  5.   <property name="geometry">' A8 U- m. R/ y* s$ ]
  6.    <rect>
    , X) a. K: g  R7 _' R# g0 I/ `( w
  7.     <x>0</x>+ M8 E, B' ~# h5 X9 m1 M
  8.     <y>0</y>
    . b0 W7 L8 M! E9 A" i
  9.     <width>444</width>$ M; W' d" n3 M+ ~+ t
  10.     <height>255</height>
    3 a4 U! C; N. a1 D' ^
  11.    </rect>$ @" c" f$ e0 g' E. d# Y5 e
  12.   </property>+ G3 j5 r: o/ Z) |. _& n3 ?4 N; J, q
  13.   <property name="minimumSize">$ G% ?" c' q4 U; c
  14.    <size>) |* S7 q! t8 @' _2 E0 M
  15.     <width>444</width>
    % b; n3 Y5 X( V6 G* m" G4 S2 z
  16.     <height>255</height># w7 E' N0 E5 [" S* Q
  17.    </size>
    3 O% z! G0 y' b
  18.   </property>
    & h+ \0 p9 H7 j3 g/ j
  19.   <property name="maximumSize">% {: \: Y9 l6 z, J: R! L
  20.    <size>3 O) M- H0 Y6 X) A; D' ]" L
  21.     <width>444</width>
    9 M/ W. `) x7 T$ G+ R: q; F
  22.     <height>255</height>+ _/ v) ^/ Q6 x8 X# D) D
  23.    </size>/ N7 b, p0 S, @8 g' V7 Q
  24.   </property>
    8 g) O4 K* E: I* F6 v: x
  25.   <property name="windowTitle">2 Y( s& k$ w7 o; \7 S9 Y4 I4 n- S
  26.    <string>SerialPortYmodem</string>
      \7 l" b  [& G* y" ?9 V
  27.   </property>  _0 L" w* q5 q
  28.   <layout class="QVBoxLayout" name="verticalLayout_3">
    % g& o; t0 z( j" ]8 Q; K0 l1 U
  29.    <item>; O! j* z9 {2 P
  30.     <widget class="QGroupBox" name="groupBox">
    8 N2 }3 `$ q( L) @, X
  31.      <property name="title">
    % I; m' G+ l* o+ G% \( a5 O! m
  32.       <string>串口配置</string>3 F  @5 A* U$ u# B( I8 u' T4 _
  33.      </property>& j, u- `- D) C& N8 q1 i- _
  34.      <layout class="QHBoxLayout" name="horizontalLayout">
    * W: P( R, [: d1 S/ q
  35.       <item>. w0 A1 j1 F) j
  36.        <widget class="QLabel" name="label">
    ! ?" a* O1 o$ N( I9 L' M
  37.         <property name="text">
    2 b/ N' ]  X6 p9 L( V. D8 ]
  38.          <string>端口:</string>, U+ y- q" q5 J5 P* i( j
  39.         </property>5 A$ H. e8 q+ Q8 l+ ]' U; K
  40.        </widget>" d: R4 V9 W0 R9 g
  41.       </item>
    7 g3 T6 B- v; e! N  v! |
  42.       <item>
    * |/ @. A+ s. W, Q) F
  43.        <widget class="QComboBox" name="comPort">
    2 h1 I! ?7 f3 x7 m. q! @( f
  44.         <property name="maxVisibleItems">1 u8 |% B6 N; d/ t0 Y* r
  45.          <number>12</number>2 c3 @6 K) N& O2 S
  46.         </property>9 A  [8 g9 N3 Y/ `
  47.        </widget>1 J4 q# E9 x* N; }2 L
  48.       </item>
    7 D0 A) P  L2 r: |4 H% |" t- }) h
  49.       <item>1 m2 o4 m+ e1 g
  50.        <spacer name="horizontalSpacer">
    5 J7 Q9 Y8 C. F" R0 M, I
  51.         <property name="orientation">
    ) L  X  x4 \# S- l
  52.          <enum>Qt::Horizontal</enum>
    6 A: H7 e6 X/ q  L0 p! x
  53.         </property>
    9 O5 A, ?' Q( g/ t; ~- H
  54.         <property name="sizeHint" stdset="0">
    / j1 }9 u" d" i# n
  55.          <size>4 Q" |8 b5 L. F/ U- w
  56.           <width>40</width>2 O( @: C6 C! {
  57.           <height>20</height>
    + U: w* J4 l4 j1 J. u* u
  58.          </size>( }. x) b8 v3 D; a  P9 ^# I0 Y
  59.         </property>
    ; h: I* y) W' X+ j4 P& [
  60.        </spacer>
    % g: @( e. I+ I6 F% d) S" a
  61.       </item>- F) a& A4 E( ?9 Q. ~
  62.       <item>
    - b4 c6 x. k% x- R/ }
  63.        <widget class="QLabel" name="label_2">5 i  }" R$ ^0 I% x; j" O& L* I# Q
  64.         <property name="text">
    & W7 D3 N$ _; {0 i6 p
  65.          <string>波特率:</string>
    3 D- B2 A+ ^, V1 G! `0 W+ h8 p3 J
  66.         </property>2 K$ x5 c$ g+ l7 ?
  67.        </widget>" B" d& \2 @# Q, E
  68.       </item>
    . d! l% G1 x' T- S
  69.       <item>
    # `, X! t2 E& R. U2 H( T5 p$ Z) o
  70.        <widget class="QComboBox" name="comBaudRate">
    % E) [3 j8 `! J- q- W/ `) l& Q9 ?1 D
  71.         <property name="currentText">
    " i& ]: v; a' ^5 O
  72.          <string>115200</string>
    9 u+ N" j! l3 h
  73.         </property>+ }6 o* u" n1 ]6 C& g4 z
  74.         <property name="currentIndex">7 k7 W' S8 b# H8 l! w, U: h! M
  75.          <number>3</number># X7 U. O- B" B6 _- i; l! v
  76.         </property>; n1 ^; y& T; m% S$ r  F( E( T) h
  77.         <property name="maxVisibleItems">
    4 t& ~) h1 a$ f5 L) K9 q# K3 l* u/ p
  78.          <number>12</number>$ A- _% o2 N# n, f7 {/ g! {
  79.         </property>  H- h8 ?- U2 i" O& F3 ~6 R& `; C
  80.         <item>
    # i, \# \  u- |
  81.          <property name="text">
    5 v* X% ?" _+ f& h3 ^+ Y% {
  82.           <string>921600</string>
    $ Y) f2 f  c3 p* \
  83.          </property>. Y- }7 ]$ D: m2 m& O
  84.         </item>
    : M, d, p2 h  ^8 s$ J5 ?
  85.         <item>
    " Z" h2 l" U( h' D
  86.          <property name="text">7 C/ D  g2 O# H8 N  O$ a$ _5 o2 a
  87.           <string>460800</string>* V4 S1 {1 R# K# E; J/ `
  88.          </property>- _! h8 ^; A$ ^, U. J' t
  89.         </item>
    . C  B9 i' u. Z- I
  90.         <item>  s  s& J6 }2 x( [- p/ w8 ~
  91.          <property name="text">
    2 i- C+ h9 I% h3 F
  92.           <string>230400</string>
    2 s* n# e; q7 D: ]- V4 b. j
  93.          </property>
    ) ]- p- d- l  W- c' I
  94.         </item>
    ' |9 _) A  @/ `1 U1 Z+ [. B: n
  95.         <item>* G" d/ m. A+ M7 L9 l! e
  96.          <property name="text">
    - @( |* ^0 a0 E1 Q6 u0 h
  97.           <string>115200</string>
    * a% o" E- t3 Z; {" ]
  98.          </property>2 Q. k- ~0 A0 _7 G' v6 A6 [0 n" u
  99.         </item>5 J! d0 K) }! G* B# k2 l( J/ f
  100.         <item>4 q6 m' c. {+ T9 E, t- P
  101.          <property name="text">
    1 C! j- K* _. K4 K( H) d5 j1 c( J
  102.           <string>57600</string>$ H/ e9 [) e2 n$ H+ `' T" U" d
  103.          </property>6 N9 @& S1 T' N: j0 @6 ^% ?
  104.         </item>4 @! F$ Z. ?6 x0 s
  105.         <item>
    ! Z4 Z7 e, P- h; M
  106.          <property name="text">
    ; Q$ w- D5 d% X2 m$ m6 |0 V
  107.           <string>38400</string>
    $ i$ ?& ^9 R5 U2 V6 q7 X
  108.          </property>
    . e. Z' J9 U( |
  109.         </item>. I- x/ [/ Q: {  X
  110.         <item>, b7 B0 P' a1 k% c7 D6 u# b( D) A
  111.          <property name="text">& o! \* n! M3 V+ A
  112.           <string>19200</string>, B2 ]- {$ D" Q& H
  113.          </property>
    ! W* B" \# q  O) a
  114.         </item>! k/ J& Q+ s" u2 @8 B
  115.         <item>3 h# O! u/ C. t9 c& |4 m- I
  116.          <property name="text">
      G2 E. T+ G8 j3 G
  117.           <string>9600</string>4 F* U: u: `/ W8 I, [
  118.          </property>
    5 q$ x" [7 i3 P$ B/ h
  119.         </item>
    ( O2 h+ n- ^/ S$ e
  120.         <item>
    $ Y1 ?, x; {0 ?
  121.          <property name="text">! N6 \7 M1 Z$ w+ |
  122.           <string>4800</string>
    - x0 b6 v& _" ~- Q2 k
  123.          </property>
    ' _$ j/ I: h4 G; N
  124.         </item>
    & l* I- m2 [$ X
  125.         <item>
      g5 M$ f- @$ s; u5 W
  126.          <property name="text">4 s# ~' @  I9 r7 z5 @
  127.           <string>2400</string>
    3 x- q3 f! q$ H+ u- j
  128.          </property>9 B/ \: c% \* d# w% I
  129.         </item>* Y+ @4 F2 `$ O  J4 o
  130.         <item>
    ! C4 e5 n/ M1 J! H; [" B
  131.          <property name="text">
    4 |1 u# k5 y6 }% J
  132.           <string>1200</string>+ b/ X7 Y# u% h% S' e1 }$ o
  133.          </property>
      H; b' g. ]5 e5 F; t, T
  134.         </item>' T6 S1 @  z9 ^; x0 k
  135.        </widget>
    2 b9 G9 f5 Y, ~$ Y9 U7 o
  136.       </item>/ Y, L6 ]! L$ V7 {/ U
  137.       <item>1 t$ _# }- I+ \, F
  138.        <spacer name="horizontalSpacer_2">- \3 r% B* W% N) l3 z- s5 V/ \
  139.         <property name="orientation">( N! O1 Q5 y4 }, K
  140.          <enum>Qt::Horizontal</enum>
    * G4 n+ {9 H, B9 {) q; z
  141.         </property>$ U: X3 r+ b7 H- d1 ^
  142.         <property name="sizeHint" stdset="0">6 [$ B: @5 p  ~0 _8 W
  143.          <size>
    % o- a2 f8 v2 x. N& Z& y& a
  144.           <width>40</width>
    ) y! ^1 s  N" M! Y  C
  145.           <height>20</height>% _6 ^, t, D3 C. ]' A' b, m- K0 e1 }/ f
  146.          </size>
    & @/ B' C7 V! K) F" n$ v
  147.         </property>  m6 c0 n# E; f
  148.        </spacer>  G6 q  @1 N1 ~# f$ S5 _% G
  149.       </item>! \' ^4 o) y6 D" O, b9 B5 [& b5 W1 \
  150.       <item>
    7 L  a( l: \" x! v3 |+ C/ g
  151.        <widget class="QPushButton" name="comButton">4 @% C4 D- E8 T% `
  152.         <property name="text">
    7 f. l0 @3 N/ s# l& _; A
  153.          <string>打开</string>5 b" P2 K0 F8 `
  154.         </property>
    % k  c$ N8 f0 a& A: o0 @. H4 I
  155.        </widget>! y- q4 D" b+ W% v: h6 l
  156.       </item>
    " y8 ?' K6 p8 v3 T) M" u/ f$ [# F2 R
  157.      </layout>
    ! @8 ?* L0 w0 {0 g0 o0 M
  158.     </widget>+ l; ^1 F' s* j# U8 H
  159.    </item>& ^; Y; H, h1 V$ X/ u
  160.    <item>% l2 u- v9 F  u9 ^+ U% C) v
  161.     <widget class="QGroupBox" name="groupBox_2">1 Q+ ?8 P+ v/ @6 s+ Z4 [
  162.      <property name="title">
    2 J. i: Z, m* c0 @6 `, T. _
  163.       <string>文件发送</string>
    3 |# v0 o; m* ?3 `; Y0 w# P
  164.      </property>1 W5 }- v# e1 d  i) W/ b; c3 t
  165.      <layout class="QVBoxLayout" name="verticalLayout">
    0 d: |5 Z: V! T, L% _
  166.       <item>( G# P1 K% F& Z. e" W6 e
  167.        <layout class="QHBoxLayout" name="horizontalLayout_2">: K( c8 @# t& _- g+ I/ A
  168.         <item>: A  f8 q/ b/ D6 H$ ]  I# e: \
  169.          <widget class="QLabel" name="label_3">( t  P! j: Q, I- _, [
  170.           <property name="text">
    7 J, k. F" U+ N& O* N
  171.            <string>文件路径:</string>
    / r7 M+ ]6 E  I9 F
  172.           </property>
    4 r; B; q9 D1 M0 A
  173.          </widget>
    . s; z( H! \# Q* s  l0 ^$ M: j0 s7 Z
  174.         </item>6 f+ C0 G1 ?( I3 s
  175.         <item>
    7 Q; l8 o9 [5 `8 E4 T2 A3 G
  176.          <widget class="QLineEdit" name="transmitPath">
    & M+ H3 }9 ]9 ~" u2 D8 p2 L: F
  177.           <property name="readOnly">
    * M3 k% _$ J4 |, z8 v3 e
  178.            <bool>true</bool>
    " L! ?/ w1 c6 p: ?
  179.           </property>$ K3 E, G8 Z# X, J& U
  180.          </widget>/ T5 N# X7 {) P- @( b8 b
  181.         </item>6 n# H: {' b$ K' ?; d9 a
  182.         <item>
    6 O" B( B. ~* a5 `. B9 G
  183.          <widget class="QPushButton" name="transmitBrowse">& ?' g  E7 ^1 \- X* X3 d6 t
  184.           <property name="enabled">0 t; T; l5 p5 V5 J# g
  185.            <bool>false</bool>; i% |* I" }& R+ u7 q# X, S
  186.           </property>
    9 w7 }6 ]% ]/ X! i* P: P
  187.           <property name="text">
    6 c3 |# s8 S( D2 o% s& ?
  188.            <string>浏览...</string>% X9 e  L1 h" Q6 O" T+ l" @' \& \
  189.           </property>/ B: q( D( S. m% `' q( |/ e
  190.          </widget>
    5 ^* s9 b. Q( o* @& n
  191.         </item>- d# b2 v! {/ y4 v9 B" g. @" X) d3 r
  192.         <item>( Y0 s' ^; l$ d: ~, i$ u( \
  193.          <widget class="QPushButton" name="transmitButton">/ L: p  q% P$ c. I; J( l* o6 f! U
  194.           <property name="enabled">- k/ d& t1 Y# `
  195.            <bool>false</bool>
    / k1 u3 `6 u4 ~. D
  196.           </property>
    " `4 S: X6 Q. Q) m0 M$ j- b: i+ W) t
  197.           <property name="text">+ Z4 S- v* A) K8 b
  198.            <string>发送</string>& x; e5 F& i+ a5 \' t* Q" R4 Q& l& n
  199.           </property>
    * P. j. s1 \% _/ x# V; v2 Z7 V/ B1 C
  200.          </widget>
    9 y% x0 f/ {: r0 [
  201.         </item>
    , y& z# o& i: P, T4 {
  202.        </layout>. j8 {+ ?. C3 a( _) r
  203.       </item>, J3 c+ v6 e3 H0 K/ u5 m  }
  204.       <item>4 H# H+ q; Y4 `5 [/ O, \
  205.        <layout class="QHBoxLayout" name="horizontalLayout_3">3 t5 s5 S- i: {
  206.         <item>) l7 w2 n0 w1 P4 ~0 {$ W! }2 \# w
  207.          <widget class="QLabel" name="label_5">
    1 d9 a0 Y  t+ u) s# L
  208.           <property name="text">, j, M  }- w' |: F( d1 Q! [8 w% s
  209.            <string>传输进度:</string>
    ; }4 b0 T' {8 u' B8 {
  210.           </property>! ]+ v0 u+ P6 @  M- h4 Y0 T6 H
  211.          </widget>4 {9 i; E2 W3 M( s
  212.         </item>) k3 O' v+ v+ D9 ~  N
  213.         <item>. d  [4 F1 L# B: s
  214.          <widget class="QProgressBar" name="transmitProgress">
      R9 @8 @/ }  n$ e+ l- t) C1 V4 S
  215.           <property name="value">. v" `) L$ F% F; S" w* a) ]  ]& c
  216.            <number>0</number>1 ]4 l: i4 O( W8 ?( A
  217.           </property>' v5 n% c. _' h5 Y
  218.          </widget>
    . z: C2 P5 U  W, b
  219.         </item>- H3 L- \* V2 ?) n2 X" B: `: |6 y
  220.        </layout>" H: l$ z* V3 s% }) i% ]
  221.       </item>9 S4 [9 Y6 i" o7 y2 E
  222.      </layout>. m! J  V) g$ t  f' F
  223.     </widget>
    0 `8 a; f2 f7 o
  224.    </item>
    # y' F+ D0 R# w
  225.    <item>8 c7 n  @! w+ n6 E1 S' o; L
  226.     <widget class="QGroupBox" name="groupBox_3">8 Y* c6 A7 d' Y7 t
  227.      <property name="title">8 s2 k9 N+ p- y1 T
  228.       <string>文件接收</string>
    5 [1 s1 p& L9 T. z/ s& Q
  229.      </property>4 E1 }  P! t5 z) u
  230.      <layout class="QVBoxLayout" name="verticalLayout_2">4 s7 [( ]# C; s2 @2 ^
  231.       <item># k/ x2 z: y( P0 i# B/ E
  232.        <layout class="QHBoxLayout" name="horizontalLayout_4">
    : i0 Y6 C- c5 D9 C; W7 a
  233.         <item>
    3 W0 W) x: U5 c: p, {% b
  234.          <widget class="QLabel" name="label_4">$ Z% ]6 O; P! e7 O" L
  235.           <property name="text">8 l4 Y2 d8 `9 r" w
  236.            <string>文件路径:</string>
    & `! X# K" C! b6 ^, N3 o. P4 @/ P
  237.           </property>  J$ I& A2 `8 b+ E  o' \1 a. {9 G% k
  238.          </widget>( g, X8 x* ^% ~( u  ~
  239.         </item>
    2 H5 b8 ]5 {0 v3 D4 Y
  240.         <item>5 {# F$ _$ F. u8 \; r
  241.          <widget class="QLineEdit" name="receivePath">9 G5 E: r* O' K5 N9 E
  242.           <property name="readOnly">
    9 n4 h0 q$ J3 Y- z0 e) `. p% Y2 M
  243.            <bool>true</bool>& W: n/ d6 i+ ?- \. o
  244.           </property>
    , @1 A4 g2 E# y* m1 Y1 n3 W$ `6 Q
  245.          </widget>
    9 [/ w- z. N+ |) A
  246.         </item>
    - q+ a5 J4 [1 ]3 \
  247.         <item>
    6 r: b7 w; b; H
  248.          <widget class="QPushButton" name="receiveBrowse">
    7 a* M, X+ j- r- a- \/ V0 p- _
  249.           <property name="enabled">* v) i. m. x4 t$ n2 u- x0 N
  250.            <bool>false</bool>
    : U; K: I: k* k3 _& y1 g  Z
  251.           </property>+ Y/ o$ f4 U# ^! ]6 M4 {0 d! ^" Q8 Z
  252.           <property name="text">9 @8 E  R% b5 g
  253.            <string>浏览...</string>
    2 m. d. o3 [/ L
  254.           </property>
    $ P2 Y* |, P7 f& M
  255.          </widget>4 R! a* Z5 {9 r) U  U
  256.         </item>; F& w6 q8 z7 L
  257.         <item>; r4 g7 [& s2 k7 X
  258.          <widget class="QPushButton" name="receiveButton">
    4 B/ Q# b. X. g7 s6 Q
  259.           <property name="enabled">
    : C1 a$ T" ?& V$ @4 D
  260.            <bool>false</bool>
    8 }+ k( F+ Y% y5 g( F
  261.           </property>  G& R: F9 Y5 B/ _4 E, W
  262.           <property name="text">0 a6 K: o2 m6 K) W6 ]9 S, l
  263.            <string>接收</string>( E1 |7 s% {0 A5 t+ n' {
  264.           </property>
    7 \3 s0 p$ r) V
  265.          </widget>
    , B2 E0 j2 g# K; p
  266.         </item>" M3 y$ D" A! X5 e/ [8 a* }
  267.        </layout>+ _  X" ^, H1 _8 D, W' @
  268.       </item>
    + y, b; C5 [1 O' w4 M! `% y
  269.       <item>
    . y$ Q% G8 l8 [2 A
  270.        <layout class="QHBoxLayout" name="horizontalLayout_5">( t3 P' r; I& e$ m) u7 T: g( x
  271.         <item>
    8 n& c& T' V) r" `& p: a; I' s- J+ V( V
  272.          <widget class="QLabel" name="label_6">7 ~% b4 u3 X2 w/ P  L$ x
  273.           <property name="text">6 N7 w! _! J, J0 z
  274.            <string>传输进度:</string>2 @2 c- c( ~4 x7 w* _' y, h' c7 V
  275.           </property>$ h/ W( _4 @& q
  276.          </widget>
    . J& N0 ]7 e( G7 I" M" t4 n
  277.         </item>
    , v" M2 z+ J2 ]( D9 ?
  278.         <item>
    - U; W5 m  x5 l* x' C
  279.          <widget class="QProgressBar" name="receiveProgress">$ p! I) Z8 x) e/ d2 A4 E$ W
  280.           <property name="value">+ o5 z8 ~: c: L. e9 |, q
  281.            <number>0</number>1 h* h* C( A& F
  282.           </property>
    4 s, X) W. X* g# Y
  283.          </widget>& {1 \6 @: ?4 \2 |; N7 L
  284.         </item>
    ; F- M1 Y* a+ B+ U9 p
  285.        </layout>) j0 n8 b& T" K
  286.       </item>0 f- u+ ^5 w) }, G0 m. B! [0 M
  287.      </layout>$ a+ L. I* _& j' {: B+ c7 w. n3 D; X
  288.     </widget>( O8 r3 g( V' u, I
  289.    </item>
    , B' M/ G/ {. O! ^, B1 L* a
  290.   </layout>
    + q+ N, k# I4 s1 ~# n
  291. </widget>7 e! q6 o) T, M5 n
  292. <layoutdefault spacing="6" margin="11"/>
    ; ]6 c: Q9 {+ }/ d+ |3 e" R
  293. <resources/>' K- I/ G" Y$ |
  294. <connections/>5 J2 ]7 a' o# M7 b5 O2 \) s& d
  295. </ui>
    ; C* y3 y, m, ^
复制代码
6 ]( H$ r  L; Q# F2 C; e' x
      widget.h文件0 v+ E0 r/ C8 Y
  1. #ifndef WIDGET_H
    ! ?  S" T7 }5 d- d
  2. #define WIDGET_H
    . ~2 U# U; D0 N. {- t1 s
  3. 2 i7 R) z/ Z) i
  4. #include <QWidget>
    1 y5 N6 y# D" ~. b* v( Y
  5. #include "YmodemFileTransmit.h"
      u# `& a2 \/ j0 ?
  6. #include "YmodemFileReceive.h"
    7 W8 w' _( b( f/ K3 s" z2 P) |

  7. 4 H* X, f; y. O4 d7 Q" ^8 n) o
  8. namespace Ui {8 |6 `6 ^/ k1 m$ `  }/ b
  9. class Widget;, r( @& I5 c( n/ a' j
  10. }8 f: K1 r1 U& e( O

  11. 6 \( J! B" d, c* }# S3 o& R- E% e
  12. class Widget : public QWidget1 J( _" V7 m& Q3 [8 V: H3 p
  13. {; `6 W5 V- J% E2 y) I% @2 _: {
  14.     Q_OBJECT: d1 k  [; u5 Q# R! H, j$ Y" [
  15. 3 v+ `' i8 x& R( [4 _
  16. public:
    + n7 D4 s6 ~0 f% U' C5 Z& `
  17.     explicit Widget(QWidget *parent = 0);8 U* x; E1 Y1 ~. Z* V
  18.     ~Widget();6 K" Q1 C. F) p* s9 e9 C
  19. 0 K+ a  M) }5 N* h, m
  20. private slots:( _, Q& J$ S9 m2 Q( {8 S
  21.     void on_comButton_clicked();( \  a3 w0 I& h% D: a4 ~
  22.     void on_transmitBrowse_clicked();/ `7 g8 g4 O4 w. T
  23.     void on_receiveBrowse_clicked();4 ?; K2 }" K2 N% P1 b0 L3 ^6 Q
  24.     void on_transmitButton_clicked();
    0 E. [) y% y6 C9 e
  25.     void on_receiveButton_clicked();- s) `4 f: t) \2 r
  26.     void transmitProgress(int progress);" e* ^  F3 [! K+ u) Y6 H
  27.     void receiveProgress(int progress);% P6 `8 n) S5 @) y; r
  28.     void transmitStatus(YmodemFileTransmit::Status status);
    6 w! J! F6 c; r5 r: _' L
  29.     void receiveStatus(YmodemFileReceive::Status status);5 E* C# \* U& S1 o) I3 \4 X
  30. . K2 t- ?4 G* H  o2 n4 T- q
  31. private:
    ; E; J3 |4 X2 }4 T8 I1 X
  32.     Ui::Widget *ui;" e% K% J0 A- q% p: e" e* M1 y
  33.     QSerialPort *serialPort;
    1 K- i2 u9 W( T6 {  C) s
  34.     YmodemFileTransmit *ymodemFileTransmit;- \$ E1 t: X) p1 \% ^/ G0 f: t
  35.     YmodemFileReceive *ymodemFileReceive;* b8 [4 ~# K3 m8 r

  36. 1 ^2 m& d3 }7 e" b  U+ ^" O# C
  37.     bool transmitButtonStatus;" C* ]0 z3 w) f  m! s+ S
  38.     bool receiveButtonStatus;
    8 |8 F7 x! v6 c6 L/ r
  39. };
    ; f+ n( q7 W8 {9 S9 o& p' z8 O

  40. 8 x1 m  N4 B- v& U
  41. #endif // WIDGET_H
    1 p7 r$ V( Q7 _1 m( ]5 x
复制代码
0 K2 ^( Q; v* Y9 V0 o- d' N
      widget.cpp文件
+ z6 V, q  n  t* o4 O6 n& U$ V
  1. #include "widget.h"/ K- H0 f: ~. _& G* A% T
  2. #include "ui_widget.h"
    8 q0 |! X* m, @. r
  3. #include <QMessageBox># v& h* H. E: k* g& c
  4. #include <QFileDialog>
    - r% q; H- K8 Q3 P9 b
  5. #include <QSerialPortInfo>+ P/ Q( {  W* D* l% o6 |
  6. 7 G$ x' W6 k! a: i* w
  7. Widget::Widget(QWidget *parent) :$ _  E1 L$ u# C$ S1 F) C! [
  8.     QWidget(parent),
    * \- m2 q4 s  a! L. p( U# ^) ^
  9.     ui(new Ui::Widget),' h$ ^$ Q% l1 P9 Z
  10.     serialPort(new QSerialPort),1 T1 u2 U& `7 O; L5 s
  11.     ymodemFileTransmit(new YmodemFileTransmit),
    ' b0 C/ j/ B# ?. a" e+ G
  12.     ymodemFileReceive(new YmodemFileReceive)
    + F$ T8 [; b0 W* P  P
  13. {" Y# K& \( m0 w1 W' r' }
  14.     transmitButtonStatus = false;+ C. c4 D1 l. Y" I
  15.     receiveButtonStatus  = false;
    $ ^' g7 P; l! C

  16. 3 u; E( y% ^  n2 O. L
  17.     ui->setupUi(this);) g) z/ [" G- V8 s2 ]: f

  18. 0 a! A! I1 ~. r. e- }0 P4 m- ^  y" u- W
  19.     QSerialPortInfo serialPortInfo;
    8 }& l% P, a/ x
  20. ( D5 j( E1 M% @6 R4 M& p- E
  21.     foreach(serialPortInfo, QSerialPortInfo::availablePorts())
    * k. W  K# F5 v  n  O- _  Q$ }4 ]
  22.     {
    ' E# o4 v' C" [& L7 @  [1 r
  23.         ui->comPort->addItem(serialPortInfo.portName());
    3 e/ e+ T, }, X4 N. G: h. x1 b
  24.     }  o- N: h; R2 ^. Y$ U" B" y2 K

  25. 5 N% b  V) ?" K6 B( |8 x3 c+ E9 M
  26.     serialPort->setPortName("COM1");7 e0 n" R1 E8 I! y' h
  27.     serialPort->setBaudRate(115200);$ d+ F% s% c' h8 H7 S7 N9 G
  28.     serialPort->setDataBits(QSerialPort::Data8);
    ; u0 ]5 r! x1 M7 ]
  29.     serialPort->setStopBits(QSerialPort::OneStop);5 H& I4 J: s; |1 O: _# ^
  30.     serialPort->setParity(QSerialPort::NoParity);% n# q7 s0 U" ?
  31.     serialPort->setFlowControl(QSerialPort::NoFlowControl);( T. ?7 W' b6 t0 D# D  d9 i

  32. 0 h; e* J" j2 h$ B5 n. ^  k
  33.     connect(ymodemFileTransmit, SIGNAL(transmitProgress(int)), this, SLOT(transmitProgress(int)));
    . u8 L4 c- L2 j1 r/ u! m3 t. ]
  34.     connect(ymodemFileReceive, SIGNAL(receiveProgress(int)), this, SLOT(receiveProgress(int)));1 d( j2 y! t2 a$ q. F) O0 T
  35. 0 O( n& {3 ^; \6 Y, C- C' t. n
  36.    connect(ymodemFileTransmit,
    - `2 |9 g& d. c0 U3 ]
  37. SIGNAL(transmitStatus(YmodemFileTransmit::Status)), this,
    # o8 _" `& u: ^- s
  38. SLOT(transmitStatus(YmodemFileTransmit::Status)));2 H3 H7 R6 b( B% j+ F3 F
  39.    
    8 Q$ z  j' n; C; f) g% j& p
  40. connect(ymodemFileReceive,
    6 J/ Z1 z# }3 J4 K' ?! @  a
  41. SIGNAL(receiveStatus(YmodemFileReceive::Status)), this, * C4 v: w& G; ^
  42. SLOT(receiveStatus(YmodemFileReceive::Status)));
    " W6 ]& O) t- p) K& Z; P4 D
  43. }
    + f' r# u9 r8 y6 |
  44. 1 l. a- h' V, ?6 a
  45. Widget::~Widget()
    7 B1 o6 c5 b1 y0 z9 `
  46. {
    . n* T; E3 p6 u' c. x3 ?  d
  47.     delete ui;& y0 E- O4 X: ?* h# R8 E" e
  48.     delete serialPort;
    3 a0 f7 C: r0 y& f- [
  49.     delete ymodemFileTransmit;1 z% R3 S* w5 b1 N
  50.     delete ymodemFileReceive;
    ; W. r" @  _5 \& e+ X7 q. [2 l
  51. }
    & y. J0 I  s% l% U9 T
  52. 2 m' [5 H! y% s8 O/ l5 o
  53. void Widget::on_comButton_clicked()
    - z6 C3 L  R$ C( C; A
  54. {9 u" C- x2 P% C
  55.     static bool button_status = false;
    ' a2 K. R: r7 N( _# O7 w

  56. 4 b! c/ @: p( S
  57.     if(button_status == false)9 m1 X. F. U- a$ B: `3 C
  58.     {
    2 C" `+ G! g" b/ B# p
  59.         serialPort->setPortName(ui->comPort->currentText());
    5 v+ E4 v+ M* S' d
  60.         serialPort->setBaudRate(ui->comBaudRate->currentText().toInt());6 U& T+ V0 h" J1 r/ Y

  61. 0 y  Z7 D- y1 F* u8 K% l
  62.         if(serialPort->open(QSerialPort::ReadWrite) == true)* h% w# j6 V  K' C3 F8 n. }+ \5 @; ^& @
  63.         {" |( J7 [8 {  u0 ]/ C8 ]
  64.             button_status = true;
    ( R3 G' |- Q4 K# h8 ~

  65. 6 t9 ~4 D2 S5 T( x
  66.             ui->comPort->setDisabled(true);9 M" S2 g' ~) Y' J: h+ W
  67.             ui->comBaudRate->setDisabled(true);/ w7 l3 I* B* V8 \
  68.             ui->comButton->setText(u8"关闭串口");
    , k* C5 B# W# A  A. ~, {

  69. * Q  c+ ^0 |- \
  70.             ui->transmitBrowse->setEnabled(true);6 a9 U4 V0 W8 ~% |
  71.             ui->receiveBrowse->setEnabled(true);( L) {( v( L0 J+ z' e2 B

  72. 4 G2 R+ O& {% I* o+ a
  73.             if(ui->transmitPath->text().isEmpty() != true)
    " E: u* J, R8 ?, _8 f
  74.             {* d3 p$ l. J" D/ [
  75.                 ui->transmitButton->setEnabled(true);' I0 h5 H0 C8 D, @( Y
  76.             }
    2 S' Y8 p" q# \" k7 f" D1 l
  77. 8 _! V' m# Z) c
  78.             if(ui->receivePath->text().isEmpty() != true)
    ' B) D) X, W9 {
  79.             {( p  h( a6 E: X7 i( E1 o3 X
  80.                 ui->receiveButton->setEnabled(true);
    " c, P5 |% T6 R) r
  81.             }) C- i' U4 ^2 a
  82.         }
    ) ], S" O+ V+ \6 R; m4 {9 _( J
  83.         else
    1 S" I& c* i9 ?9 `4 v
  84.         {. h1 b% I2 u' ]- Q4 F2 g
  85.             QMessageBox::warning(this, u8"串口打开失败", u8"请检查串口是否已被占用!", u8"关闭");
    3 t, E1 ?0 j4 e7 {
  86.         }
    5 C8 G: j  S, G# t
  87.     }
    3 H9 q# g( u) N4 _! r
  88.     else% N, s8 h3 T/ b- M, @& Y! H
  89.     {" M2 Y/ }3 c% f8 `" e
  90.         button_status = false;5 O" f- b2 s( S) u

  91. 6 ]8 ^  i7 T8 Y, j$ O7 f1 G
  92.         serialPort->close();, s5 ]- T& c3 |2 N. D
  93. 7 o, A" `- `) G
  94.         ui->comPort->setEnabled(true);, i/ M- r3 t. ^4 t+ n. u3 o
  95.         ui->comBaudRate->setEnabled(true);2 v* G' D3 I% p4 J
  96.         ui->comButton->setText(u8"打开串口");/ O6 Z4 d. A4 _" G0 p% @) v( Q/ n4 H( X: S

  97. : C* e9 Z8 q0 _0 m8 c
  98.         ui->transmitBrowse->setDisabled(true);4 g& N, i0 a9 {; |' D, E
  99.         ui->transmitButton->setDisabled(true);" ^5 {# g+ k# j$ x1 u6 {
  100. 5 D( Z# L9 d% R) B1 b# C! T
  101.         ui->receiveBrowse->setDisabled(true);
    0 [  }  I1 G+ X. h$ }
  102.         ui->receiveButton->setDisabled(true);
    ' h, Y' w$ y% R- Q% G' X0 C) O
  103.     }5 }5 B; Q  ~: k1 \4 F9 i; [. k/ m# R
  104. }
    % B- x0 d# b4 D! C! ]! V9 B2 N

  105. 3 }/ ]7 u; Y! X+ h; Z& Z
  106. void Widget::on_transmitBrowse_clicked()
    6 E/ ]  R( Y6 ]  C5 b2 k8 l
  107. {
    " t7 Y0 f; X1 g" h. i
  108.     ui->transmitPath->setText(QFileDialog::getOpenFileName(this, u8"打开文件", ".", u8"任意文件 (*.*)"));5 M' s' _2 w- G+ q' k7 y! O

  109. 2 k2 e& b9 }. z% K4 Z
  110.     if(ui->transmitPath->text().isEmpty() != true)
      r, [: H* {* G+ ?) z& f% \
  111.     {
    ! L8 H! K+ J3 A# G" x# C" d( J. F
  112.         ui->transmitButton->setEnabled(true);
    , [7 H. s# ^% ?( P( D5 A
  113.     }' c. G1 L- Z. |
  114.     else% r4 k) p% M: H% Q$ Z
  115.     {' c, g6 e- G# g* A0 h4 i0 U  s
  116.         ui->transmitButton->setDisabled(true);
    1 f) X7 S$ k4 G+ O
  117.     }
    " ~8 x4 `% J) X' ?- a( [
  118. }, c. m& E3 U8 b: ^
  119. 9 A8 V# M5 B: u# Q
  120. void Widget::on_receiveBrowse_clicked()
    9 l" G0 o  h3 D' \
  121. {
    2 f9 W! U  J8 i4 T% v8 x
  122.     ui->receivePath->setText(QFileDialog::getExistingDirectory(this, u8"选择目录", ".", QFileDialog::ShowDirsOnly));1 _3 D6 H& v7 S3 f7 W7 M
  123. + t4 w) F! P/ Y6 K: g( l
  124.     if(ui->receivePath->text().isEmpty() != true)' Q9 _# y1 n$ ]% y4 b) t: ~
  125.     {' |9 @6 U2 ^$ L- L1 @1 E! H5 f
  126.         ui->receiveButton->setEnabled(true);
    ; z7 E$ \8 D9 j$ P) D9 W0 ~* s! S# ^: [
  127.     }
    5 {" ]* a. R! _7 \* h- _
  128.     else* Q9 v$ v/ {3 Q6 {  @+ r
  129.     {
    9 m1 t% U9 Y. C, M/ M8 m' r
  130.         ui->receiveButton->setDisabled(true);& h$ b- c0 \& b
  131.     }2 w6 x, _1 B, w$ i& u+ L
  132. }
    % w4 s% m# v/ \% l
  133. ! a9 O0 P3 O" c( R* V/ @; I7 v
  134. void Widget::on_transmitButton_clicked()
    - `% l2 H8 }- V$ a9 V0 k! ^9 |/ D6 C
  135. {
    # Y) P8 U+ B0 L/ C, P4 m- G
  136.     if(transmitButtonStatus == false)8 R: A0 h; U8 a! `0 Y. T; W" k  ?9 R+ w
  137.     {0 ?* o- U; B* Z% ?# w/ }
  138.         serialPort->close();
    # U0 q! {$ b  Q7 L
  139. . V- X' S% g( M9 T1 O
  140.         ymodemFileTransmit->setFileName(ui->transmitPath->text());
    5 _! X2 ?  D  |  g
  141.         ymodemFileTransmit->setPortName(ui->comPort->currentText());
    . m" Q1 p4 X& @( Z* h% P
  142.         ymodemFileTransmit->setPortBaudRate(ui->comBaudRate->currentText().toInt());! Z7 H) X$ ^' H- L
  143. 9 u7 O% p" T+ v( h2 P) ?: _& [' s
  144.         if(ymodemFileTransmit->startTransmit() == true), H% d& r8 O! [$ D- @4 C
  145.         {6 [+ Q1 Z1 |# Q5 ^
  146.             transmitButtonStatus = true;
    ' l) {4 `+ i3 f  ^7 l2 M: ~/ A4 Y

  147. - I* S, j4 x( x6 u  E. z
  148.             ui->comButton->setDisabled(true);% L5 t- }1 u1 s
  149. . q  H2 g7 w$ D+ R; C
  150.             ui->receiveBrowse->setDisabled(true);' [) C5 C4 C( S4 T
  151.             ui->receiveButton->setDisabled(true);
    - o) q5 M  _0 t; q, m# U
  152. ) g* ]( {  M7 `- h1 r9 i. N
  153.             ui->transmitBrowse->setDisabled(true);
    $ O' l) v5 O( @. n
  154.             ui->transmitButton->setText(u8"取消");
    , f# `1 w  f- x0 G! l
  155.             ui->transmitProgress->setValue(0);: [, P0 C$ |8 i6 W( C
  156.         }9 z  v) ?) m# I/ A  e
  157.         else
    : Y; U6 G0 Q. H) x/ L
  158.         {
    : X/ `: R- O. F4 [6 v4 ]
  159.             QMessageBox::warning(this, u8"失败", u8"文件发送失败!", u8"关闭");
    . x, z. n( ?1 ?
  160.         }, y7 g4 E, A9 a" ^. f
  161.     }  J3 c0 H6 O# p
  162.     else
    ! X; q$ `) w" Z/ z) |
  163.     {
    ; n: X0 ]$ K" D4 e" c& C* J
  164.         ymodemFileTransmit->stopTransmit();5 v1 \% S8 S+ D0 ^0 f
  165.     }
    6 K% O' X  S: [, F0 [
  166. }
    5 a# I7 }/ b0 a1 o

  167. * Q) C# }. i: Y" j
  168. void Widget::on_receiveButton_clicked()
    6 w. D7 `6 X* }% L! Z
  169. {
    , n; H; n# K" |. B/ \: ^
  170.     if(receiveButtonStatus == false)) i: \' i# b5 }2 z6 N0 P
  171.     {
    ! ^: K1 Y& R4 s- r! h  d
  172.         serialPort->close();8 e6 b% q5 C  V5 W6 Y2 W; j

  173. 2 V) X, e2 U4 l( n5 i3 k
  174.         ymodemFileReceive->setFilePath(ui->receivePath->text());/ O/ A5 y8 w/ ]+ i
  175.         ymodemFileReceive->setPortName(ui->comPort->currentText());' K/ g  w' p9 X5 v4 @% k, `- C
  176.         ymodemFileReceive->setPortBaudRate(ui->comBaudRate->currentText().toInt());
    * N9 R0 H- y, a9 t5 ^, I' L' B. H

  177. " N& o5 Z( s) H; I* o
  178.         if(ymodemFileReceive->startReceive() == true)
    0 }4 C- v$ R+ c8 ^6 o% L
  179.         {
    ; o+ M5 z# e7 L5 R' j
  180.             receiveButtonStatus = true;6 f0 B. ?8 {3 m

  181. 4 Q1 c  e+ @5 ^$ p6 W7 D( a3 v
  182.             ui->comButton->setDisabled(true);7 e# t! o' s4 ^4 |% m' l& y

  183. ) e* c1 J0 C; c* y. j# C$ K$ f  M
  184.             ui->transmitBrowse->setDisabled(true);
    * |3 V1 Z0 A9 `" [+ V
  185.             ui->transmitButton->setDisabled(true);
      E2 n: z3 G8 f! o* s; Y7 e$ ^% r) K

  186. 3 f* d' o6 E5 t
  187.             ui->receiveBrowse->setDisabled(true);
    7 Z5 v- l+ d8 p+ s
  188.             ui->receiveButton->setText(u8"取消");" G+ v7 ?$ D" `* |' ~
  189.             ui->receiveProgress->setValue(0);# {  W$ Q7 U6 Z2 \( Z- C  y4 L
  190.         }8 M+ e) R8 C+ V4 `2 v3 q
  191.         else& w8 x! g0 b) w$ Z
  192.         {/ m3 l  A$ f  F, c, U' O& W
  193.             QMessageBox::warning(this, u8"失败", u8"文件接收失败!", u8"关闭");8 r+ V7 f6 Y# x7 F: L0 p& Z5 g
  194.         }
    2 H4 E2 f' t7 g0 [, t
  195.     }
    + g* ?6 h% ~1 C, v( w: d; R
  196.     else
    ' f! \/ B8 O8 l: l7 w
  197.     {
    % \% l# Q" I/ d0 w2 {+ U4 \
  198.         ymodemFileReceive->stopReceive();
    0 k* O; u9 y) F. N) t. X, s9 C
  199.     }9 B1 y- T! Z4 t! T$ q" t2 z
  200. }
    1 k. e& {# j6 D2 e
  201. 4 X: Q! m. K7 a& \
  202. void Widget::transmitProgress(int progress)) D  O1 P" {2 D0 k8 j$ [
  203. {# p/ F* z1 C3 g( e* V
  204.     ui->transmitProgress->setValue(progress);
    4 b% c( O; t/ p% G$ j: v
  205. }
    : w) D2 |6 h" L$ P9 u
  206. * Z1 U' `# g$ l" j
  207. void Widget::receiveProgress(int progress)
    8 B2 D, H4 n% a3 A/ [7 C7 L
  208. {
    ( s- p- B% `7 X! m; B* ?  q
  209.     ui->receiveProgress->setValue(progress);
    1 |- y+ s7 l! J- X4 P
  210. }7 u( Q! V" q; y2 [4 o, z
  211. 7 ?% c9 i: K4 P9 X- ^3 L5 B' z6 u
  212. void Widget::transmitStatus(Ymodem::Status status)
    ) I8 y' G" S" Z! b% ~3 z
  213. {! L/ w2 |# C; N# C, d, M* g+ L
  214.     switch(status)( I' T# U7 ^8 u& Q8 \* e/ j# c/ \
  215.     {5 x+ C' j) Y( H
  216.         case YmodemFileTransmit::StatusEstablish:8 {7 n0 R4 r" q) f6 L# R
  217.         {
    ) [' n! K. w0 W. Y# W& j
  218.             break;
    " I2 K7 [' ]$ D; d! [, [
  219.         }
    " i3 Y" E( @7 N( J
  220. - J/ `/ ]/ k* q
  221.         case YmodemFileTransmit::StatusTransmit:" G$ k) u2 z2 W1 w3 `: S9 D6 Y0 G+ U
  222.         {' `& m. a4 }& R: _
  223.             break;
    + u# V7 [7 J" d9 \* P% v( u
  224.         }$ C' f5 F+ c+ V5 v6 A

  225.   ~6 y& x3 G0 r" Q( E5 p  P0 s
  226.         case YmodemFileTransmit::StatusFinish:
    8 e8 K. p0 E1 |! x9 p/ d
  227.         {2 d3 a5 T4 z: ?; }1 p. }# |! |
  228.             transmitButtonStatus = false;
    ( _2 X/ `& I, z2 E

  229. 0 [& R+ `- N( G9 T+ m8 p
  230.             ui->comButton->setEnabled(true);
      y6 K- _' R& ^7 z* Y1 l$ `

  231. & ~$ {2 j7 Y5 l' L( G2 H% g, a! R
  232.             ui->receiveBrowse->setEnabled(true);" [$ }1 ]0 F* o  Z8 Z6 N  {. l
  233. 8 X: e5 ~- N0 q, p! L* b
  234.             if(ui->receivePath->text().isEmpty() != true): y* S2 I8 E( I( a1 M
  235.             {
    * w- b0 H5 y; |" c- x+ C- u
  236.                 ui->receiveButton->setEnabled(true);
    $ l  P! W  k  }8 i7 ~
  237.             }
    % i0 q, Y7 N, s; `

  238. ( L* L& ?, u: V/ R( ]. c: d
  239.             ui->transmitBrowse->setEnabled(true);& u  b8 a1 w* c3 h
  240.             ui->transmitButton->setText(u8"发送");
    ) V! j2 H9 \" v: y1 I

  241. / X3 f$ M6 q: j
  242.             QMessageBox::warning(this, u8"成功", u8"文件发送成功!", u8"关闭");
    ! S: p/ x3 Y; g6 ?
  243. - s: H" B6 ^1 _+ S3 J
  244.             break;- I5 C) L) Z$ m, V0 Z8 D; l1 U& ]
  245.         }- W; @- {& C* g  L! e, D& ?
  246. & c3 l8 O6 a0 W: s2 W
  247.         case YmodemFileTransmit::StatusAbort:1 j+ Z5 {6 ]# P' o7 F) P
  248.         {) {6 y, y0 D4 P- }0 R# v
  249.             transmitButtonStatus = false;9 C  M, e% J5 p

  250. 4 R! E% b! u# Z$ {
  251.             ui->comButton->setEnabled(true);
    & c: L" d5 w( H  `; ~8 ]

  252. # n# h1 j3 ^/ X5 t% h
  253.             ui->receiveBrowse->setEnabled(true);/ U+ p; b6 x& L8 P! m6 c* |; M% E
  254. 8 o  u8 E5 f6 u; N& s- R
  255.             if(ui->receivePath->text().isEmpty() != true)
    0 z% L' T6 `  C7 m2 w& W
  256.             {
    . a4 h- W* K  w8 Z5 c0 C) K' X- B
  257.                 ui->receiveButton->setEnabled(true);- s- x  i/ [: u, h$ N3 Z
  258.             }
    # `& P7 s/ p3 R1 Z+ a" E" {* |

  259. " c# Z5 S: C" U* |
  260.             ui->transmitBrowse->setEnabled(true);
    - F: H7 W+ `+ z% A# D4 e$ w
  261.             ui->transmitButton->setText(u8"发送");. Y. `* H7 l" h' x: o
  262. ! _1 o4 K# F6 f0 W4 G6 w
  263.             QMessageBox::warning(this, u8"失败", u8"文件发送失败!", u8"关闭");
    ' q" G( ~0 [$ j1 z' E  C7 l

  264. & ]* ~9 h: l" r. _
  265.             break;
    8 ]( \2 T/ {7 s+ p5 t/ T) ^( r
  266.         }
    3 u0 [- p# j  b5 B$ c3 R
  267. ' g7 q" d$ U7 @0 w7 u" @
  268.         case YmodemFileTransmit::StatusTimeout:
      X; z; H1 Z3 Y# s: I6 e
  269.         {
    % f8 X' O$ C9 Y/ K
  270.             transmitButtonStatus = false;' b0 Z. ~+ s, G8 m
  271. 8 u' v3 @  O8 o* D0 l$ F) C) |/ \
  272.             ui->comButton->setEnabled(true);
    3 X; V2 T1 }+ s3 ~7 G6 s3 h

  273. 4 Q5 b* l/ }4 b5 f3 N
  274.             ui->receiveBrowse->setEnabled(true);& M. M5 o- O4 R; e; W6 Q% f& J  E

  275. 0 g6 n8 X' ?/ ^5 k# p
  276.             if(ui->receivePath->text().isEmpty() != true)( }6 j- X# d) I' v* L1 w
  277.             {
    ; V; t. d% o, U) T
  278.                 ui->receiveButton->setEnabled(true);! r$ Z# `8 o, O, w) X& Q
  279.             }
    ( f0 z3 L. C3 o  \
  280. ) }" ~& v; \' ^6 T  D, X# u7 f
  281.             ui->transmitBrowse->setEnabled(true);6 b8 z. x7 V) I4 i& q. o6 v
  282.             ui->transmitButton->setText(u8"发送");8 k" E/ j: x- ~: D

  283. 2 F7 e) A+ l1 M: W# T0 ~
  284.             QMessageBox::warning(this, u8"失败", u8"文件发送失败!", u8"关闭");
    ; e1 K  l1 D5 a+ [9 o' J
  285. " O! u( z: K5 z$ w& Y
  286.             break;& K4 ]8 K% u7 [$ t- k8 T, j3 G
  287.         }( N6 n% ^# G: h% j2 m
  288.   C' i9 z9 ]( U- [
  289.         default:
    . n5 O! H' x7 @
  290.         {8 A( w: p6 ]# {% p5 s
  291.             transmitButtonStatus = false;  w3 E- e' Y2 `- k! \! w
  292. " A7 V4 @* n# }: R& {$ k* ^5 @
  293.             ui->comButton->setEnabled(true);# b9 z  \9 m; o5 G% j* I! `3 v
  294. 0 o1 A$ d3 Y2 d" o9 P2 Z
  295.             ui->receiveBrowse->setEnabled(true);
    2 I+ G; _2 F2 ~: i! z6 X

  296. ! a9 D6 z. X! Y! E
  297.             if(ui->receivePath->text().isEmpty() != true)" U7 G6 @1 ?* L/ b: K
  298.             {
    - N8 a9 {4 q  E1 [
  299.                 ui->receiveButton->setEnabled(true);- f3 p! G9 B; f: G$ ^* H: F* @3 f3 v
  300.             }( ]5 }" `& v6 e- S6 G! V% k
  301. ; ~& ~5 x# `7 U/ t* V7 k* E; s
  302.             ui->transmitBrowse->setEnabled(true);
    - s, a4 N$ k( Q( b3 `) J
  303.             ui->transmitButton->setText(u8"发送");: u3 ]- t6 y' \: K( H
  304. ; d  d( n8 J- B+ P, Z+ f
  305.             QMessageBox::warning(this, u8"失败", u8"文件发送失败!", u8"关闭");, R5 V0 N' h3 o$ \" ~
  306.         }7 d$ v# m- R/ P% y# o
  307.     }
    / D; ]5 L5 G  \+ K+ }) _" v
  308. }9 _% A  z, ?/ y# l

  309. ) m" E% i7 C; r. Z* q" d5 z2 G& v5 k
  310. void Widget::receiveStatus(YmodemFileReceive::Status status)
    8 t! j" @: s' H: i
  311. {
    ! |. A0 y$ p# N) z4 T
  312.     switch(status)
    + n: q8 B. Z/ j* l# K6 X" M
  313.     {/ c) S% h( E9 J4 Y* s
  314.         case YmodemFileReceive::StatusEstablish:
    ( q& Y' N+ ?% t1 s1 z- \! q
  315.         {& [1 R! F" x' x. P; @: l6 j
  316.             break;
      }2 Q9 f" z8 C" F% B- Y4 A
  317.         }
    ( \& U2 B9 ~* p; p- Z

  318. 1 m, L# Y5 j3 E& @" W2 T' N& Z
  319.         case YmodemFileReceive::StatusTransmit:8 @% u6 _- Z2 n
  320.         {
    + R8 v4 y' C+ M( L
  321.             break;; [4 Z1 v, j5 K! _' w
  322.         }
    - \' q+ P# a, A( {. e$ X
  323. ! d1 M& D& [2 U( e0 {( k
  324.         case YmodemFileReceive::StatusFinish:8 j, X  c* [3 y6 w$ @( _
  325.         {
    2 `/ u5 a3 S3 Z8 Z% a8 W) M5 d* M9 j
  326.             receiveButtonStatus = false;' x) J5 z+ b  O6 y+ a' }1 d) q
  327. ! i+ J: |& u) v
  328.             ui->comButton->setEnabled(true);$ k, ^6 T* E: u$ F5 `; l
  329. 4 L  ]  Q; T' U2 n- b
  330.             ui->transmitBrowse->setEnabled(true);' b# e( t0 v0 i0 E
  331. & ]# b0 ~$ {: A9 Q. X/ J
  332.             if(ui->transmitPath->text().isEmpty() != true)2 e1 R) E, C+ X/ e9 z( C9 q( K
  333.             {% {& k6 h+ \  |3 B) \# a
  334.                 ui->transmitButton->setEnabled(true);4 Y1 c# d; O- ^2 j% w
  335.             }7 H0 G4 N- u) t% O! V
  336. ) O2 F' _5 x" c$ j1 y/ U
  337.             ui->receiveBrowse->setEnabled(true);9 @: I( ?6 q3 V9 R4 f  w7 z
  338.             ui->receiveButton->setText(u8"接收");( d0 {) D3 p0 _( o3 P5 v
  339. + ?7 s0 |6 \! X' D6 t5 Q4 w
  340.             QMessageBox::warning(this, u8"成功", u8"文件接收成功!", u8"关闭");
    : t: m7 }5 j! o2 U6 i6 q1 p- |
  341. 2 F. Q5 a6 z# @* e$ x
  342.             break;7 U* h9 p, u: X# x. J
  343.         }7 G. Q, X. a- `% K

  344. # ^0 G; i2 ]9 B) s  E2 j: O
  345.         case YmodemFileReceive::StatusAbort:
    8 b7 d* t1 x3 @3 O
  346.         {0 e0 @! T- H2 m# H" ~
  347.             receiveButtonStatus = false;: Z9 W. A0 y4 p3 Y* m6 g) S1 e' _

  348. 3 r+ w$ |# e) [1 a/ B5 P" ]
  349.             ui->comButton->setEnabled(true);+ X2 y2 f: a. [0 B

  350. % V# }1 H! @2 S
  351.             ui->transmitBrowse->setEnabled(true);
    ( Y  D$ v* u) \% i2 o, A

  352. $ u, u5 z0 F2 T# W
  353.             if(ui->transmitPath->text().isEmpty() != true)+ _! @3 |: z8 t% q. e5 u
  354.             {& Q- m$ v9 m4 }
  355.                 ui->transmitButton->setEnabled(true);+ m- V. W  x9 F$ q) }  u0 J
  356.             }- P( a8 v9 M' e5 k9 A- [* y! `

  357. 2 j+ G% F, b( o
  358.             ui->receiveBrowse->setEnabled(true);
    & ~( k, R3 S' s5 `/ D, h
  359.             ui->receiveButton->setText(u8"接收");
    8 i2 k) \4 n1 M% t. d

  360. ! N; p( v; S5 R2 G/ ]/ G
  361.             QMessageBox::warning(this, u8"失败", u8"文件接收失败!", u8"关闭");1 d3 [) F3 e) x+ O* M+ C' e2 N

  362. + ~3 n2 `! ~8 c8 Z- p& j6 u, X
  363.             break;/ ^, t0 C4 f0 Q# q7 j4 q
  364.         }  U8 }( K5 ?, x$ |

  365. ) a0 g5 N/ M! E
  366.         case YmodemFileReceive::StatusTimeout:
    / k$ ^+ E8 x0 K9 l! s4 ?+ b: \2 Q8 u
  367.         {
    % T7 }2 [" b0 \/ P7 ^6 p' U/ g
  368.             receiveButtonStatus = false;: _3 q) n" i/ j+ G) ]9 D! H
  369. ) A* J+ \3 |& J9 ~& ~/ y1 ]
  370.             ui->comButton->setEnabled(true);
    ( V1 f+ K, P; [! ^9 x! i# Y

  371. # [# a3 d9 L' d9 {
  372.             ui->transmitBrowse->setEnabled(true);
    0 Z6 E) P) j% `. }

  373. 4 ]7 y% C; b* h+ E
  374.             if(ui->transmitPath->text().isEmpty() != true)
    - e! a8 K& y2 U
  375.             {
    $ l9 b* p9 }8 S  T, Y1 ~% P5 k
  376.                 ui->transmitButton->setEnabled(true);
    + c" l( A3 X' ~5 b# [
  377.             }( j& {7 P# {, H& q
  378. & E- q$ t4 ]5 s  F4 L# @
  379.             ui->receiveBrowse->setEnabled(true);( R6 G3 I" ^, A
  380.             ui->receiveButton->setText(u8"接收");
    - c5 O, y2 T/ X( w, f

  381. & n, J' X7 r( U; Y! d0 [
  382.             QMessageBox::warning(this, u8"失败", u8"文件接收失败!", u8"关闭");
    ' _5 L" v- j5 _& F

  383. ; X9 w: e+ f! c+ ^
  384.             break;9 s1 E& y# J. x5 ^
  385.         }! H+ `4 b8 y( a1 w0 r
  386. : @2 x! o$ j6 D  c+ r9 K+ n
  387.         default:
    / w' \/ f# U! u# Z/ c& }# ?3 k8 t4 f
  388.         {) p% s8 |( r/ o% x9 y" K% s" ]$ ]/ W4 l
  389.             receiveButtonStatus = false;% @) ^8 s7 M& T

  390. ) C* @* T) k8 {0 L7 E: L6 q" }
  391.             ui->comButton->setEnabled(true);) U! F. u, K2 N0 D3 X

  392. + r/ h& W: {5 B7 @
  393.             ui->transmitBrowse->setEnabled(true);
    7 n" ]$ H5 d, P3 G

  394. : a5 d5 X  s% B1 f
  395.             if(ui->transmitPath->text().isEmpty() != true)
    & O) `, V4 P6 V8 G: t7 k5 W
  396.             {
    , a: p( f3 Z( j, M8 \4 T! C  a
  397.                 ui->transmitButton->setEnabled(true);
    ! @$ h4 N, @  H( f  w
  398.             }
    + u* I0 L& R* S7 p1 j5 o. j, f
  399. + ], l) C& E) \( W! M# s$ o- m$ E/ U
  400.             ui->receiveBrowse->setEnabled(true);
    + z3 k9 L. X0 Y( o, P0 i
  401.             ui->receiveButton->setText(u8"接收");
    + t- E" B+ l1 h" Z8 k! Q) D- \
  402. " g' i' K3 m$ l+ L! Q
  403.             QMessageBox::warning(this, u8"失败", u8"文件接收失败!", u8"关闭");
    - s4 I4 m% A* ^
  404.         }3 ?9 }6 g$ d5 J* B6 c! v
  405.     }6 e- p9 ^) }3 y$ H* t/ [
  406. }" Q' y* O- @9 j8 J5 ~% M7 ^% U
复制代码
7 V- [: Z  _1 g; @& ]: j$ c

: Q+ Y$ C5 ~2 M/ G. C  ]
+ t1 t% ]7 N. n; T9 }  g7 _: X# F3 J  S2 I
( {  ~6 X) |( C( J9 z6 v
8 Y, {7 k# S) [, N0 n& T
XinLiYF 回答时间:2018-3-6 22:32:40
      main.cpp文件
/ E3 b6 s: ~4 U5 \3 Z
  1. #include "widget.h"9 s8 x6 ^" E% K: |6 B
  2. #include <QApplication>
    9 L, P# A, s7 u- x' P  w- @

  3.   ^0 k& u; y$ a2 t2 }
  4. int main(int argc, char *argv[])5 T6 R0 o0 J4 [5 o3 A' A
  5. {9 u; t2 m, r1 F+ a
  6.     QApplication a(argc, argv);
    4 R4 k* ^; G; [, Y# I
  7.     Widget w;# N% s' x7 E# N, ]9 ?# @
  8.     w.show();/ c* D5 W  ~0 n3 N

  9. ; A3 R3 q; T7 t1 C
  10.     return a.exec();) y$ Y6 e$ c$ `# W2 w2 v: r
  11. }/ A# @7 v, z- E/ s! e% T9 m1 F3 f
复制代码

3 k) t# r' Z9 h8 X      SerialPortYmodem.pro文件
  k: o2 d7 g/ Y1 D. u: x1 {5 d
  1. #-------------------------------------------------
    ' D( u# u6 w" c2 T) S- O9 T
  2. #& J1 z/ ^2 ]8 d! m; ~% R
  3. # Project created by QtCreator 2018-01-20T23:00:467 v- @) w, n/ R- C+ m) w% S5 K" U- F
  4. #
    $ g: U5 x1 b. P' ?& X
  5. #-------------------------------------------------
    6 [) M$ o) C/ p2 D; V) u1 P) r
  6. , j# W3 K  @; _
  7. QT       += core gui4 u+ f/ a3 F4 M  i! p1 S! }+ L0 Y3 _" `
  8. QT       += serialport
    ! L  _( a2 J& G( x% p

  9. / o' R; J) W- r
  10. greaterThan(QT_MAJOR_VERSION, 4): QT += widgets! m( E7 _' M; }$ J, G' p- u

  11.   W! m/ ^; K# Y0 Q) F# P3 [
  12. TARGET = SerialPortYmodem! L0 X/ p4 Y4 p: f. g, p) e2 z+ @5 z- M
  13. TEMPLATE = app- ~* |! _; ~! L( E( j# }

  14. ! r: u/ Y9 V! T' X( B
  15. # The following define makes your compiler emit warnings if you use$ S4 \, y. I6 ~0 z) G# A! T
  16. # any feature of Qt which as been marked as deprecated (the exact warnings0 ~7 Y& k3 M$ S2 \' s7 E+ U& i
  17. # depend on your compiler). Please consult the documentation of the" U+ |6 b5 _( }, s) e% P  p1 G
  18. # deprecated API in order to know how to port your code away from it.% f6 s+ A- C& v6 A# u
  19. DEFINES += QT_DEPRECATED_WARNINGS
      q1 r6 {4 X) U* g+ `

  20. 9 _( l) v# n" i5 w/ h
  21. # You can also make your code fail to compile if you use deprecated APIs.
    5 q# V$ d/ z$ D# ]
  22. # In order to do so, uncomment the following line.
    ; x$ x$ G, {% `9 ~2 W
  23. # You can also select to disable deprecated APIs only up to a certain version of Qt.2 G( L4 j# c0 Z: Y' h1 z4 Q
  24. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
    - C; n% s; G; U* j( Y
  25. # C( Z! d, F( K: @& T. N2 j; G
  26. ' d# \5 G# ^9 p
  27. SOURCES += main.cpp\8 x+ B/ t# C  }/ w8 c( r& K
  28.         widget.cpp \0 K  n1 ^5 E8 s% V1 Y
  29.     YmodemFileReceive.cpp \
    " s2 {# x  N5 V0 Z% y$ `) G8 W' i9 X
  30.     Ymodem.cpp \" k  |$ L4 ^3 i
  31.     YmodemFileTransmit.cpp
      {+ C5 S* v1 j( j4 ]
  32. 3 f/ i9 P$ P+ J" ^
  33. HEADERS  += widget.h \
    - f. {$ P" a6 e! V- q0 ]* w; P
  34.     Ymodem.h \( l9 z  e  L/ @
  35.     YmodemFileReceive.h \6 o" ?* z- ~: G* k. J$ R4 A. L# ^
  36.     YmodemFileTransmit.h
    / W6 e- d2 {6 H

  37. # Y% _) j$ K% E
  38. FORMS    += widget.ui! |+ C; y! d9 N  W0 y8 g

  39. + d: r3 ]* ]( d0 v
  40. RC_ICONS = SerialPortYmodem.ico: ^; A3 h; ?5 O7 F8 ]6 A
复制代码

9 e5 S# _6 ^% L      SerialPortYmodem.ico文件) w9 {% g/ q. b. l$ \' p, T# A

' h: x7 s! u- C) ~- R7 R3,运行效果  h2 s/ A2 S' \# |
, s8 f5 ~- Q9 L2 w! L$ E

6 y: _$ k! g& C! r1 s! i
( ^( b& T# \) S: x) N. C! p& r
+ Y9 k! w* g+ G7 h% ?: n
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( Q# @: W1 ]/ j+ V5 K; B2 R- V
请教,单片机端如何处理呢?

4 g) Y3 |5 I8 ]/ `7 ]4 o3 m0 ^可以移植到单片机上,文件的接收和发送都支持。
Kevin_G 回答时间:2018-12-26 09:46:05
收藏
huangchao09 回答时间:2019-3-24 20:37:59
多谢楼主共享

所属标签

相似分享

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