Obsolete unused backup project such as OK6410
guowenxue
2018-02-04 00cb813bffdc9876ae03ff0b967be3b1912f2454
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/********************************************************************************************
 *        File:  xmodem.c
 *     Version:  1.0.0
 *   Copyright:  2011 (c) Guo Wenxue <guowenxue@gmail.com>
 * Description:  Xmodem protocal used to download the second stage bootloader(launcher)
 *   ChangeLog:  1, Release initial version on "Tue Jul 12 16:43:18 CST 2011"
 *
 *******************************************************************************************/
 
#include "common.h"
 
#define XMODEM_SOH 0x01         /*Start Of Header, standard Xmodem */
#define XMODEM_STX 0x02         /*1K-Modem start Xmodem */
#define XMODEM_EOT 0x04         /*End Of Transmission */
#define XMODEM_ACK 0x06
#define XMODEM_NAK 0x15
#define XMODEM_CAN 0x18         /*Stop transmission */
#define XMODEM_EOF 0x1a         /*CTRL+Z EOF */
 
#define XMODEM_BLOCK_SIZE 128
 
static int xmodem_wait(void)
{
    long cnt = 0;
 
    while (!serial_tstc())
    {
        if (++cnt >= 20000000)
        {
            cnt = 0;
            serial_putc(XMODEM_NAK);
        }
    }
 
    return 0;
}
 
static int xmodem_read_block(unsigned char block_number, char *buf)
{
    unsigned char c, block_num, check_sum;
    int i;
 
    block_num = serial_getc();
    if (block_num != block_number)
        return -1;
 
    block_num ^= serial_getc();
    if (block_num != 0xff)
        return -1;
 
    check_sum = 0;
    for (i = 0; i < XMODEM_BLOCK_SIZE; i++)
    {
        c = serial_getc();
        *(buf++) = c;
        check_sum += c;
    }
 
    check_sum ^= serial_getc();
    if (check_sum)
        return -1;
 
    return i;
}
 
long xmodem_recv(char *buf)
{
    int r, receiving = 0;
    long size = 0;
    unsigned char c, block_number = 1;
 
    while (1)
    {
        if (!receiving)
            xmodem_wait();
 
        c = serial_getc();
 
        switch (c)
        {
          case XMODEM_EOT:
              serial_putc(XMODEM_ACK);
 
              /*Remove the CMPEOF */
              long cnt = 0;
              if ((buf[-1] == XMODEM_EOF) && (buf[-2] == XMODEM_EOF) && (buf[-3] == XMODEM_EOF))
              {
                  while (size && buf[-cnt - 1] == XMODEM_EOF)
                      cnt++;
              }
 
              size -= cnt;
              goto RECV_OK;
 
          case XMODEM_CAN:
              return -1;
 
          case XMODEM_SOH:
              receiving++;
              r = xmodem_read_block(block_number, buf);
              if (r < 0)
              {
                  serial_putc(XMODEM_NAK);
              }
              else
              {
                  block_number++;
                  size += r;
                  buf += r;
                  serial_putc(XMODEM_ACK);
              }
              break;
 
          default:
              if (receiving)
                  return -1;
        }
    }
 
  RECV_OK:
    return size;
}