blob: d86deceb81bb54478ff2e237422ffeade3f64159 [file] [log] [blame]
Marcin Bukat8f4202d2011-05-30 21:10:43 +00001#include <stdio.h>
2#include <stdint.h>
3#include <stdlib.h>
4#include <string.h>
5#include <libusb.h>
6
7#include "rk27load.h"
8#include "common.h"
9#include "scramble.h"
10#include "checksum.h"
11#include "stage3_upload.h"
12
13int upload_stage3_code(libusb_device_handle *hdev, char *fn_stage3)
14{
15 FILE *f;
16 uint32_t codesize;
17 uint32_t remain;
18 uint8_t *code;
19 uint16_t send_size = 0x200;
20 uint32_t i = 0;
21 int ret, transfered;
22
23 if ((f = fopen(fn_stage3, "rb")) == NULL)
24 {
25 fprintf(stderr, "[error]: Could not open file \"%s\"\n", fn_stage3);
26 return -31;
27 }
28
29 codesize = filesize(f);
30
31 fprintf(stderr, "[stage3]: Loading user code (%d bytes)... ", codesize);
32
33 /* allocate buffer */
34 code = (uint8_t *) malloc(codesize + 0x204);
35 if (code == NULL)
36 {
37 fprintf(stderr, "\n[error]: Out of memory\n");
38 fclose(f);
39 return -32;
40 }
41
42 memset(code, 0, codesize + 0x204);
43 /* read usercode into buffer */
44 if (fread(&code[4], 1, codesize, f) != codesize)
45 {
46 fprintf(stderr, "\n[error]: I/O error\n");
47 fclose(f);
Thomas Jarosche0024c92011-08-25 20:40:28 +000048 free(code);
Marcin Bukat8f4202d2011-05-30 21:10:43 +000049 return -33;
50 }
51 fprintf(stderr, "done\n");
52
53 fclose(f);
54
55 /* put code size at the first 4 bytes */
56 codesize += 4;
57 code[0] = codesize & 0xff;
58 code[1] = (codesize >> 8) & 0xff;
59 code[2] = (codesize >> 16) & 0xff;
60 code[3] = (codesize >> 24) & 0xff;
61
62 fprintf(stderr, "[stage3]: Uploading user code (%d bytes)... ", codesize);
63
64 remain = codesize;
65
66 while (remain > 0)
67 {
68 if (remain < 0x200)
69 send_size = remain;
70
71 ret = libusb_bulk_transfer(hdev, /* handle */
72 1, /* EP */
73 &code[i * 0x200], /* data */
74 send_size, /* length */
75 &transfered, /* xfered */
76 USB_TIMEOUT /* timeout */
77 );
78
79 if (ret != LIBUSB_SUCCESS)
80 {
81 fprintf(stderr, "\n[error]: Bulk transfer error (%d, %d)\n", ret, i);
82 free(code);
83 return -34;
84 }
85
86 remain -= send_size;
87 i++;
88 }
89
90 fprintf(stderr,"done (sent %d blocks)\n", i);
91 return 0;
92}
93