OpenCores
URL https://opencores.org/ocsvn/amber/amber/trunk

Subversion Repositories amber

[/] [amber/] [trunk/] [sw/] [boot-loader-serial/] [xmodem.c] - Blame information for rev 67

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 csantifort
/*
2
 * Copyright 2001-2010 Georges Menie (www.menie.org)
3
 * All rights reserved.
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions are met:
6
 *
7
 *     * Redistributions of source code must retain the above copyright
8
 *       notice, this list of conditions and the following disclaimer.
9
 *     * Redistributions in binary form must reproduce the above copyright
10
 *       notice, this list of conditions and the following disclaimer in the
11
 *       documentation and/or other materials provided with the distribution.
12
 *     * Neither the name of the University of California, Berkeley nor the
13
 *       names of its contributors may be used to endorse or promote products
14
 *       derived from this software without specific prior written permission.
15
 *
16
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
17
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19
 * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
20
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
 */
27
 
28
/* this code needs standard functions memcpy() and memset()
29
   and input/output functions _inbyte() and _outbyte().
30
 
31
   the prototypes of the input/output functions are:
32
     int _inbyte(unsigned short timeout); // msec timeout
33
     void _outbyte(int c);
34
 
35
 */
36
 
37
#include "crc16.h"
38
#include "boot-loader.h"
39
 
40
/*
41
#define DEBUG_XMODEM
42
*/
43
 
44
#define SOH  0x01
45
#define STX  0x02
46
#define EOT  0x04
47
#define ACK  0x06
48
#define NAK  0x15
49
#define CAN  0x18
50
#define CTRLZ 0x1A
51
 
52
 
53
#define MAXRETRANS 25
54
 
55
#ifdef DEBUG_XMODEM        
56
char* dbuf;
57
#endif
58
 
59
 
60
static int check(int crc, const unsigned char *buf, int sz)
61
{
62
        if (crc) {
63
                unsigned short crc = crc16_ccitt(buf, sz);
64
                unsigned short tcrc = (buf[sz]<<8)+buf[sz+1];
65
                if (crc == tcrc) {
66
                        #ifdef DEBUG_XMODEM        
67
                        dbuf += sprintf(dbuf, "cok1\n");
68
                        #endif
69
                        return 1;
70
                        }
71
        }
72
        else {
73
                int i;
74
                unsigned char cks = 0;
75
                for (i = 0; i < sz; ++i) {
76
                        cks += buf[i];
77
                }
78
                if (cks == buf[sz]) {
79
                    #ifdef DEBUG_XMODEM        
80
                    dbuf += sprintf(dbuf, "cok2\n");
81
                    #endif
82
                    return 1;
83
                    }
84
        }
85
 
86
        #ifdef DEBUG_XMODEM        
87
        dbuf += sprintf(dbuf, "cer\n");
88
        #endif
89
        return 0;
90
}
91
 
92
 
93
static void flushinput(void)
94
{
95
        while (_inbyte(DLY_300MS) >= 0) ;
96
}
97
 
98
 
99
int xmodemReceive(unsigned char *dest, int destsz)
100
{
101
        unsigned char xbuff[1030]; /* 1024 for XModem 1k + 3 head chars + 2 crc + nul */
102
        unsigned char *p;
103
        int bufsz, crc = 0;
104
        unsigned char trychar = 'C';
105
        unsigned char packetno = 1;
106
        int i, c, len = 0;
107
        int retry, retrans = MAXRETRANS;
108
        unsigned int wait;
109
 
110
        #ifdef DEBUG_XMODEM        
111
        dbuf = (char *) DEBUG_BUF;
112
        dbuf += sprintf(dbuf, "XR\n");
113
        #endif
114
 
115
        for(;;) {
116
                for( retry = 0; retry < 80; ++retry) {
117
                        if (trychar) _outbyte(trychar);
118
                        if ((c = _inbyte(DLY_1S)) >= 0) {
119
                                switch (c) {
120
                                case SOH:
121
                                        bufsz = 128;
122
                                        #ifdef DEBUG_XMODEM
123
                                        dbuf += sprintf(dbuf, "128\n");
124
                                        #endif
125
                                        goto start_recv;
126
                                case STX:
127
                                        bufsz = 1024;
128
                                        #ifdef DEBUG_XMODEM
129
                                        dbuf += sprintf(dbuf, "1k\n");
130
                                        #endif
131
                                        goto start_recv;
132
                                case EOT:
133
                                        _outbyte(ACK);
134
                                        flushinput();
135
                                        #ifdef DEBUG_XMODEM
136
                                        dbuf += sprintf(dbuf, "EOT\n");
137
                                        #endif
138
                                        return len; /* normal end */
139
                                case CAN:
140
                                        #ifdef DEBUG_XMODEM
141
                                        dbuf += sprintf(dbuf, "CAN\n");
142
                                        #endif
143
                                        if ((c = _inbyte(DLY_1S)) == CAN) {
144
                                                flushinput();
145
                                                _outbyte(ACK);
146
                                                return -1; /* canceled by remote */
147
                                        }
148
                                        break;
149
                                default:
150
                                        break;
151
                                }
152
                        }
153
                }
154
                if (trychar == 'C') { trychar = NAK; continue; }
155
                flushinput();
156
                _outbyte(CAN);
157
                _outbyte(CAN);
158
                _outbyte(CAN);
159
                return -2; /* sync error */
160
 
161
        start_recv:
162
                #ifdef DEBUG_XMODEM
163
                dbuf += sprintf(dbuf, "sr\n");
164
                #endif
165
                if (trychar == 'C') crc = 1;
166
                trychar = 0;
167
                p = xbuff;
168
                *p++ = c;
169
                for (i = 0;  i < (bufsz+(crc?1:0)+3); ++i) {
170
                        if ((c = _inbyte(DLY_1S)) < 0) goto reject;
171
                        *p++ = c;
172
                }
173
 
174
 
175
                if (xbuff[1] == (unsigned char)(~xbuff[2]) &&
176
                        (xbuff[1] == packetno || xbuff[1] == (unsigned char)packetno-1) &&
177
                        check(crc, &xbuff[3], bufsz)) {
178
                        if (xbuff[1] == packetno)       {
179
                                register int count = destsz - len;
180
                                if (count > bufsz) count = bufsz;
181
                                if (count > 0) {
182
                                        memcpy (&dest[len], &xbuff[3], count);
183
                                        len += count;
184
                                }
185
                                ++packetno;
186
                                retrans = MAXRETRANS+1;
187
                        }
188
                        if (--retrans <= 0) {
189
                                flushinput();
190
                                _outbyte(CAN);
191
                                _outbyte(CAN);
192
                                _outbyte(CAN);
193
                                #ifdef DEBUG_XMODEM
194
                                dbuf += sprintf(dbuf, "mx e\n");
195
                                #endif
196
                                return -3; /* too many retry error */
197
                        }
198
                        _outbyte(ACK);
199
                        continue;
200
 
201
 
202
                }
203
                else {
204
                        #ifdef DEBUG_XMODEM
205
                        dbuf += sprintf(dbuf, "bad\n");
206
                        #endif
207
                        }
208
 
209
        reject:
210
                #ifdef DEBUG_XMODEM
211
                dbuf += sprintf(dbuf, "rj %d\n", c);
212
                #endif
213
 
214
                flushinput();
215
                _outbyte(NAK);
216
        }
217
}
218
 
219
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.