Subversion Repositories freemyipod

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
770 user890104 1
//
2
//
3
//    Copyright 2011 user890104
4
//
5
//
6
//    This file is part of emCORE.
7
//
8
//    emCORE is free software: you can redistribute it and/or
9
//    modify it under the terms of the GNU General Public License as
10
//    published by the Free Software Foundation, either version 2 of the
11
//    License, or (at your option) any later version.
12
//
13
//    emCORE is distributed in the hope that it will be useful,
14
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
15
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16
//    See the GNU General Public License for more details.
17
//
18
//    You should have received a copy of the GNU General Public License along
19
//    with emCORE.  If not, see <http://www.gnu.org/licenses/>.
20
//
21
//
22
 
23
 
24
#include "global.h"
25
 
26
#include "emcore.h"
27
#include "util.h"
28
#include "usb.h"
29
 
30
 
31
struct emcore_usb_endpoints_addr emcore_usb_eps_addr;
32
struct emcore_usb_endpoints_max_packet_size emcore_usb_eps_mps;
33
 
34
int emcore_cout(const void* data, const uint32_t length)
35
{
36
    return usb_bulk_transfer(emcore_usb_eps_addr.cout, (void*)data, length);
37
}
38
 
39
int emcore_cin(void* data, const uint32_t length)
40
{
41
    return usb_bulk_transfer(emcore_usb_eps_addr.cin, data, length);
42
}
43
 
44
int emcore_dout(const void* data, const uint32_t length)
45
{
46
    return usb_bulk_transfer(emcore_usb_eps_addr.dout, (void*)data, length);
47
}
48
 
49
int emcore_din(void* data, const uint32_t length)
50
{
51
    return usb_bulk_transfer(emcore_usb_eps_addr.din, data, length);
52
}
53
 
54
int emcore_monitor_command(const void* out, void* in,
55
    const uint32_t send_length, const uint32_t receive_length)
56
{
57
    int res;
58
    uint32_t status;
59
 
60
#ifdef DEBUG_USB_PACKETS
61
    fprintf(stderr, "--------------------------------------------\n");
62
    fprintf(stderr, "Sending %d bytes...\n", send_length);
63
 
64
    dump_packet(out, send_length);
65
 
66
#endif
67
    res = emcore_cout(out, send_length);
68
 
69
    if (LIBUSB_SUCCESS != res)
70
    {
71
        return res;
72
    }
73
 
74
    if (in && receive_length)
75
    {
76
#ifdef DEBUG_USB_PACKETS
77
        fprintf(stderr, "Receiving %d bytes...\n", receive_length);
78
 
79
#endif
80
        res = emcore_cin(in, receive_length);
81
 
82
        if (LIBUSB_SUCCESS != res)
83
        {
84
            return res;
85
        }
86
 
87
#ifdef DEBUG_USB_PACKETS
88
        dump_packet(in, receive_length);
89
 
90
#endif
91
        status = *((int *)(in));
92
    }
93
    else
94
    {
95
        status = EMCORE_SUCCESS;
96
    }
97
 
98
#ifdef DEBUG_USB_PACKETS
99
    fprintf(stderr, "--------------------------------------------\n");
100
 
101
#endif
102
    switch (status)
103
    {
104
        case 0:
105
            return EMCORE_ERROR_INVALID;
106
        break;
107
        case 1:
108
            return EMCORE_SUCCESS;
109
        break;
110
        case 2:
111
            return EMCORE_ERROR_NOT_SUPPORTED;
112
        break;
113
        case 3:
114
            return EMCORE_ERROR_BUSY;
115
        break;
116
        default:
117
            return EMCORE_ERROR_INVALID;
118
        break;
119
    }
120
}
121
 
122
int emcore_get_version(struct emcore_dev_info* dev_info)
123
{
124
    int res;
125
    uint32_t out[4] = { 1, 0, 0, 0 }, in[4];
126
 
127
    res = emcore_monitor_command(out, in, 16, 16);
128
 
129
    if (EMCORE_SUCCESS != res)
130
    {
131
        return res;
132
    }
133
 
134
    memcpy(dev_info, &in[1], sizeof(*dev_info));
135
 
136
    return EMCORE_SUCCESS;
137
}
138
 
139
int emcore_get_packet_info(struct emcore_usb_endpoints_max_packet_size* max_packet_size)
140
{
141
    int res;
142
    uint32_t out[4] = { 1, 1, 0, 0 }, in[4];
143
 
144
    res = emcore_monitor_command(out, in, 16, 16);
145
 
146
    if (EMCORE_SUCCESS != res)
147
    {
148
        return res;
149
    }
150
 
151
    memcpy(max_packet_size, &in[1], sizeof(*max_packet_size));
152
 
153
    return EMCORE_SUCCESS;
154
}
155
 
156
int emcore_get_user_mem_range(struct emcore_user_mem_range* mem_range)
157
{
158
    int res;
159
    uint32_t out[4] = { 1, 2, 0, 0 }, in[4];
160
 
161
    res = emcore_monitor_command(out, in, 16, 16);
162
 
163
    if (EMCORE_SUCCESS != res)
164
    {
165
        return res;
166
    }
167
 
168
    memcpy(mem_range, &in[1], sizeof(*mem_range));
169
 
170
    return EMCORE_SUCCESS;
171
}
172
 
173
int emcore_reset(const uint8_t graceful)
174
{
175
    int res;
176
    uint32_t out[4] = { 2, 0xdeadbeef, 0, 0 }, in[4];
177
 
178
    out[1] = graceful;
179
 
180
    res = emcore_monitor_command(out, in, 16, graceful ? 16 : 0);
181
 
182
    if (EMCORE_SUCCESS != res)
183
    {
184
        return res;
185
    }
186
 
187
    return EMCORE_SUCCESS;
188
}
189
 
190
int emcore_poweroff(const uint8_t graceful)
191
{
192
    int res;
193
    uint32_t out[4] = { 3, 0xdeadbeef, 0, 0 }, in[4];
194
 
195
    out[1] = graceful;
196
 
197
    res = emcore_monitor_command(out, in, 16, graceful ? 16 : 0);
198
 
199
    if (EMCORE_SUCCESS != res)
200
    {
201
        return res;
202
    }
203
 
204
    return EMCORE_SUCCESS;
205
}
206
 
207
int emcore_readmem(void* data, const uint32_t addr, const uint32_t size)
208
{
209
    int res;
210
    uint32_t data_length, out[4] = { 4, 0xdeadbeef, 0xdeadbeef, 0 };
211
    void* in;
212
 
213
    out[1] = addr;
214
    out[2] = size;
215
 
216
    if (size + EMCORE_HEADER_SIZE > emcore_usb_eps_mps.cin)
217
    {
218
        return EMCORE_ERROR_OVERFLOW;
219
    }
220
 
221
    data_length = size + EMCORE_HEADER_SIZE;
222
    in = malloc(data_length);
223
 
224
    res = emcore_monitor_command(out, in, 16, data_length);
225
 
226
    if (EMCORE_SUCCESS != res)
227
    {
228
        return res;
229
    }
230
 
231
    memcpy(data, in + EMCORE_HEADER_SIZE, size);
232
 
233
    return EMCORE_SUCCESS;
234
}
235
 
236
int emcore_writemem(const void* data, const uint32_t addr, const uint32_t size)
237
{
238
    int res;
239
    uint32_t data_length, in[4], *out;
240
 
241
    if (size + EMCORE_HEADER_SIZE > emcore_usb_eps_mps.cout)
242
    {
243
        return EMCORE_ERROR_OVERFLOW;
244
    }
245
 
246
    data_length = size + EMCORE_HEADER_SIZE;
247
    out = malloc(data_length);
248
 
249
    *(out) = 5;
250
    *(out + 1) = addr;
251
    *(out + 2) = size;
252
    *(out + 3) = 0;
253
    memcpy(out + 4, data, size);
254
 
255
    res = emcore_monitor_command(out, in, data_length, 16);
256
 
257
    if (EMCORE_SUCCESS != res)
258
    {
259
        return res;
260
    }
261
 
262
    return EMCORE_SUCCESS;
263
}
264
 
265
int emcore_readdma(void* data, const uint32_t addr, const uint32_t size)
266
{
267
    int res;
268
    uint32_t out[4] = { 6, 0xdeadbeef, 0xdeadbeef, 0 }, in[4];
269
 
270
    out[1] = addr;
271
    out[2] = size;
272
 
273
    if (size > emcore_usb_eps_mps.din)
274
    {
275
        return EMCORE_ERROR_OVERFLOW;
276
    }
277
 
278
    res = emcore_monitor_command(out, in, 16, 16);
279
 
280
    if (EMCORE_SUCCESS != res)
281
    {
282
        return res;
283
    }
284
 
285
    res = emcore_din(data, size);
286
 
287
    return EMCORE_SUCCESS;
288
}
289
 
290
int emcore_writedma(const void* data, const uint32_t addr, const uint32_t size)
291
{
292
    int res;
293
    uint32_t out[4] = { 7, 0xdeadbeef, 0xdeadbeef, 0 }, in[4];
294
 
295
    out[1] = addr;
296
    out[2] = size;
297
 
298
    if (size > emcore_usb_eps_mps.dout)
299
    {
300
        return EMCORE_ERROR_OVERFLOW;
301
    }
302
 
303
    res = emcore_monitor_command(out, in, 16, 16);
304
 
305
    if (EMCORE_SUCCESS != res)
306
    {
307
        return res;
308
    }
309
 
310
    res = emcore_dout(data, size);
311
 
312
    return EMCORE_SUCCESS;
313
}
314
 
315
int emcore_readi2c(void* data, const uint8_t bus, const uint8_t slave, const uint8_t addr, const uint8_t size)
316
{
317
    int res;
318
    uint32_t data_length, out[4] = { 8, 0xdeadbeef, 0, 0 };
319
    void* in;
320
 
321
    out[1] = bus | (slave << 8) | (addr << 16) | (size << 24);
322
 
323
    if (size + EMCORE_HEADER_SIZE > emcore_usb_eps_mps.cin)
324
    {
325
        return EMCORE_ERROR_OVERFLOW;
326
    }
327
 
328
    data_length = 16 + size;
329
    in = malloc(data_length);
330
 
331
    res = emcore_monitor_command(out, in, 16, data_length);
332
 
333
    if (EMCORE_SUCCESS != res)
334
    {
335
        return res;
336
    }
337
 
338
    memcpy(data, in + 16, size);
339
 
340
    return EMCORE_SUCCESS;
341
}
342
 
343
int emcore_writei2c(const void* data, const uint8_t bus, const uint8_t slave, const uint8_t addr, const uint8_t size)
344
{
345
    int res;
346
    uint32_t data_length, in[4], *out;
347
 
348
    if (size + EMCORE_HEADER_SIZE > emcore_usb_eps_mps.cout)
349
    {
350
        return EMCORE_ERROR_OVERFLOW;
351
    }
352
 
353
    data_length = 16 + size;
354
    out = calloc(data_length, 1);
355
 
356
    *(out) = 9; // bytes 0-3
357
    *(out + 4) = bus;
358
    *(out + 5) = slave;
359
    *(out + 6) = addr;
360
    *(out + 7) = size;
361
 
362
    memcpy(out + 16, data, size); // bytes 16+
363
 
364
    res = emcore_monitor_command(out, in, data_length, 16);
365
 
366
    if (EMCORE_SUCCESS != res)
367
    {
368
        return res;
369
    }
370
 
371
    return EMCORE_SUCCESS;
372
}
373
 
374
int emcore_file_open(uint32_t* handle, const char* path, const int flags)
375
{
376
    int res;
377
    uint32_t str_length, data_length, in[4], *out;
782 user890104 378
    int flags_emcore = 0;
770 user890104 379
 
380
    *handle = 0;
381
 
382
    str_length = strlen(path);
383
    data_length = str_length + 1 + EMCORE_HEADER_SIZE;
384
 
385
    if (data_length > emcore_usb_eps_mps.cout)
386
    {
387
        return EMCORE_ERROR_OVERFLOW;
388
    }
389
 
390
    out = calloc(sizeof(char), data_length);
391
 
392
    *(out) = 30;
393
 
782 user890104 394
    /*
395
    #define O_RDONLY 0
396
    #define O_WRONLY 1
397
    #define O_RDWR   2
398
    #define O_CREAT  4
399
    #define O_APPEND 8
400
    #define O_TRUNC  0x10
401
    */
402
 
403
    if (flags & O_WRONLY) {
404
        flags_emcore |= 0x01;
405
    }
406
 
407
    if (flags & O_RDWR) {
408
        flags_emcore |= 0x02;
409
    }
410
 
411
    if (flags & O_CREAT) {
412
        flags_emcore |= 0x04;
413
    }
414
 
415
    if (flags & O_APPEND) {
416
        flags_emcore |= 0x08;
417
    }
418
 
419
    if (flags & O_TRUNC) {
420
        flags_emcore |= 0x10;
421
    }
422
 
423
    *(out + 1) = flags_emcore;
424
 
770 user890104 425
    strncpy(((char*)(out + 4)), path, str_length);
426
 
427
    res = emcore_monitor_command(out, in, data_length, 16);
428
 
429
    if (EMCORE_SUCCESS != res)
430
    {
431
        return res;
432
    }
433
 
434
    if (in[1] > 0x80000000)
435
    {
436
        return EMCORE_ERROR_IO;
437
    }
438
 
439
    *handle = in[1];
440
 
441
    return EMCORE_SUCCESS;
442
}
443
 
444
int emcore_file_size(uint32_t* size, const uint32_t handle)
445
{
446
    int res;
447
    uint32_t out[4] = { 31, 0xdeadbeef, 0, 0 }, in[4];
448
 
449
    out[1] = handle;
450
 
451
    res = emcore_monitor_command(out, in, 16, 16);
452
 
453
    if (EMCORE_SUCCESS != res)
454
    {
455
        return res;
456
    }
457
 
458
    if (in[1] > 0x80000000)
459
    {
460
        return EMCORE_ERROR_IO;
461
    }
462
 
463
    *size = in[1];
464
 
465
    return EMCORE_SUCCESS;
466
}
467
 
468
int emcore_file_read(uint32_t* nread, const uint32_t handle, const uint32_t addr, const uint32_t size)
469
{
470
    int res;
471
    uint32_t out[4] = { 32, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef }, in[4];
472
 
473
    out[1] = handle;
474
    out[2] = addr;
475
    out[3] = size;
476
 
477
    res = emcore_monitor_command(out, in, 16, 16);
478
 
479
    if (EMCORE_SUCCESS != res)
480
    {
481
        return res;
482
    }
483
 
484
    if (in[1] > 0x80000000)
485
    {
486
        return EMCORE_ERROR_IO;
487
    }
488
 
489
    *nread = in[1];
490
 
491
    return EMCORE_SUCCESS;
492
}
493
 
784 user890104 494
int emcore_file_write(uint32_t* nwrite, const uint32_t handle, const uint32_t addr, const uint32_t size)
770 user890104 495
{
496
    int res;
497
    uint32_t out[4] = { 33, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef }, in[4];
498
 
499
    out[1] = handle;
500
    out[2] = addr;
501
    out[3] = size;
502
 
503
    res = emcore_monitor_command(out, in, 16, 16);
504
 
505
    if (EMCORE_SUCCESS != res)
506
    {
507
        return res;
508
    }
509
 
510
    if (in[1] > 0x80000000)
511
    {
512
        return EMCORE_ERROR_IO;
513
    }
514
 
784 user890104 515
    *nwrite = in[1];
516
 
770 user890104 517
    return EMCORE_SUCCESS;
518
}
519
 
520
int emcore_file_seek(const uint32_t handle, const uint32_t offset, const uint32_t whence)
521
{
522
    int res;
523
    uint32_t out[4] = { 34, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef }, in[4];
524
 
525
    out[1] = handle;
526
    out[2] = offset;
527
    out[3] = whence;
528
 
529
    res = emcore_monitor_command(out, in, 16, 16);
530
 
531
    if (EMCORE_SUCCESS != res)
532
    {
533
        return res;
534
    }
535
 
536
    if (in[1] > 0x80000000)
537
    {
538
        return EMCORE_ERROR_IO;
539
    }
540
 
541
    return EMCORE_SUCCESS;
542
}
543
 
544
int emcore_file_truncate(const uint32_t handle, const uint32_t length)
545
{
546
    int res;
547
    uint32_t out[4] = { 35, 0xdeadbeef, 0xdeadbeef, 0 }, in[4];
548
 
549
    out[1] = handle;
550
    out[2] = length;
551
 
552
    res = emcore_monitor_command(out, in, 16, 16);
553
 
554
    if (EMCORE_SUCCESS != res)
555
    {
556
        return res;
557
    }
558
 
559
    if (in[1] > 0x80000000)
560
    {
561
        return EMCORE_ERROR_IO;
562
    }
563
 
564
    return EMCORE_SUCCESS;
565
}
566
 
567
int emcore_file_sync(const uint32_t handle)
568
{
569
    int res;
570
    uint32_t out[4] = { 36, 0xdeadbeef, 0, 0 }, in[4];
571
 
572
    out[1] = handle;
573
 
574
    res = emcore_monitor_command(out, in, 16, 16);
575
 
576
    if (EMCORE_SUCCESS != res)
577
    {
578
        return res;
579
    }
580
 
581
    if (in[1] > 0x80000000)
582
    {
583
        return EMCORE_ERROR_IO;
584
    }
585
 
586
    return EMCORE_SUCCESS;
587
}
588
 
589
int emcore_file_close(const uint32_t handle)
590
{
591
    int res;
592
    uint32_t out[4] = { 37, 0xdeadbeef, 0, 0 }, in[4];
593
 
594
    out[1] = handle;
595
 
596
    res = emcore_monitor_command(out, in, 16, 16);
597
 
598
    if (EMCORE_SUCCESS != res)
599
    {
600
        return res;
601
    }
602
 
603
    if (in[1] > 0x80000000)
604
    {
605
        return EMCORE_ERROR_IO;
606
    }
607
 
608
    return EMCORE_SUCCESS;
609
}
610
 
611
int emcore_file_close_all(uint32_t* count)
612
{
613
    int res;
614
    uint32_t out[4] = { 38, 0, 0, 0 }, in[4];
615
 
616
    res = emcore_monitor_command(out, in, 16, 16);
617
 
618
    if (EMCORE_SUCCESS != res)
619
    {
620
        return res;
621
    }
622
 
623
    if (in[1] > 0x80000000)
624
    {
625
        return EMCORE_ERROR_IO;
626
    }
627
 
628
    *count = in[1];
629
 
630
    return EMCORE_SUCCESS;
631
}
632
 
633
int emcore_file_kill_all(const uint32_t volume)
634
{
635
    int res;
636
    uint32_t out[4] = { 39, 0xdeadbeef, 0, 0 }, in[4];
637
 
638
    out[1] = volume;
639
 
640
    res = emcore_monitor_command(out, in, 16, 16);
641
 
642
    if (EMCORE_SUCCESS != res)
643
    {
644
        return res;
645
    }
646
 
647
    if (in[1] > 0x80000000)
648
    {
649
        return EMCORE_ERROR_IO;
650
    }
651
 
652
    return EMCORE_SUCCESS;
653
}
654
 
655
int emcore_file_unlink(const char* name)
656
{
657
    int res;
658
    uint32_t str_length, data_length, in[4], *out;
659
 
660
    str_length = strlen(name);
661
    data_length = str_length + 1 + EMCORE_HEADER_SIZE;
662
 
663
    if (data_length > emcore_usb_eps_mps.cout)
664
    {
665
        return EMCORE_ERROR_OVERFLOW;
666
    }
667
 
668
    out = calloc(sizeof(char), data_length);
669
 
670
    *(out) = 40;
671
 
672
    strncpy(((char*)(out + 4)), name, str_length);
673
 
674
    res = emcore_monitor_command(out, in, data_length, 16);
675
 
676
    if (EMCORE_SUCCESS != res)
677
    {
678
        return res;
679
    }
680
 
681
    if (in[1] > 0x80000000)
682
    {
683
        return EMCORE_ERROR_IO;
684
    }
685
 
686
    return EMCORE_SUCCESS;
687
}
688
 
689
int emcore_file_rename(const char* path, const char* newpath)
690
{
691
    int res;
692
    uint32_t str_length, data_length, in[4], *out;
693
 
694
    if (strlen(path) > 247)
695
    {
696
        return EMCORE_ERROR_OVERFLOW;
697
    }
698
 
699
    str_length = MIN(247, strlen(newpath));
700
    data_length = str_length + 1 + 248 + EMCORE_HEADER_SIZE;
701
 
702
    if (data_length > emcore_usb_eps_mps.cout)
703
    {
704
        return EMCORE_ERROR_OVERFLOW;
705
    }
706
 
707
    out = calloc(sizeof(char), data_length);
708
 
709
    *(out) = 41;
710
 
711
    strncpy(((char*)(out + 4)), path, strlen(path));
712
    strncpy(((char*)(out) + 248), newpath, str_length);
713
 
714
    res = emcore_monitor_command(out, in, data_length, 16);
715
 
716
    if (EMCORE_SUCCESS != res)
717
    {
718
        return res;
719
    }
720
 
721
    if (in[1] > 0x80000000)
722
    {
723
        return EMCORE_ERROR_IO;
724
    }
725
 
726
    return EMCORE_SUCCESS;
727
}
728
 
729
int emcore_dir_open(uint32_t* handle, const char* name)
730
{
731
    int res;
732
    size_t name_length;
733
    uint32_t data_length, in[4], *out;
734
 
735
    name_length = strlen(name);
736
    data_length = name_length + 1 + EMCORE_HEADER_SIZE;
737
    out = calloc(data_length, 1);
738
 
739
    *out = 42;
740
    strncpy(((char*)(out + 4)), name, name_length + 1);
741
 
742
    res = emcore_monitor_command(out, in, data_length, 16);
743
 
744
    if (EMCORE_SUCCESS != res)
745
    {
746
        return res;
747
    }
748
 
749
    *handle = in[1];
750
 
751
    return EMCORE_SUCCESS;
752
}
753
 
754
int emcore_dir_read(struct emcore_dir_entry* entry, const uint32_t handle)
755
{
756
    int res;
757
    uint32_t maxpath, ptr, dirent_size, emcore_errno_value, filename_buf_len,
758
        out[4] = { 43, 0xdeadbeef, 0, 0 }, in[4];
759
    void *buf;
760
 
761
    memset(entry, 0, sizeof(*entry));
762
 
763
    out[1] = handle;
764
 
765
    res = emcore_monitor_command(out, in, 16, 16);
766
 
767
    if (EMCORE_SUCCESS != res)
768
    {
769
        return res;
770
    }
771
 
772
    ptr = in[3];
773
 
774
    if (0 == ptr)
775
    {
776
        res = emcore_errno(&emcore_errno_value);
777
 
778
        if (EMCORE_SUCCESS != res)
779
        {
780
            return res;
781
        }
782 user890104 782
 
783
        if (EMCORE_SUCCESS != emcore_errno_value && 2 != emcore_errno_value)
770 user890104 784
        {
785
            return EMCORE_ERROR_IO;
786
        }
787
 
788
        return EMCORE_ERROR_NO_MORE_ENTRIES;
789
    }
790
 
791
    if (1 != in[1]) // version
792
    {
793
        return EMCORE_ERROR_NOT_IMPLEMENTED;
794
    }
795
 
796
    maxpath = in[2];
797
 
798
    dirent_size = maxpath + 16;
799
 
800
    buf = malloc(dirent_size);
801
 
802
    res = emcore_read(buf, ptr, dirent_size);
803
 
804
    if (EMCORE_SUCCESS != res)
805
    {
806
        return res;
807
    }
808
 
809
    filename_buf_len = strlen((char*)buf) + 1;
810
 
811
    entry->name = malloc(filename_buf_len);
812
    strncpy(entry->name, buf, filename_buf_len);
813
    memcpy(&entry->attributes, buf + maxpath, 16);
814
 
815
#ifdef DEBUG_DIR_ENTRIES
816
    fprintf(stderr, "Read directory entry: %s\n", entry->name);
817
    fprintf(stderr, "Attributes: 0x%08x\n", entry->attributes);
818
    fprintf(stderr, "Size: %d\n", entry->size);
819
    fprintf(stderr, "Start cluster: %d\n", entry->startcluster);
820
    fprintf(stderr, "Last written date: 0x%04x\n", entry->wrtdate);
821
    fprintf(stderr, "Last written time: 0x%04x\n", entry->wrttime);
822
    fprintf(stderr, "Last written TS: %lu\n",
823
        (unsigned long) fat_time_to_unix_ts(entry->wrttime, entry->wrtdate));
824
#endif
825
    return EMCORE_SUCCESS;
826
}
827
 
828
int emcore_dir_close(const uint32_t handle)
829
{
830
    int res;
831
    uint32_t out[4] = { 44, 0xdeadbeef, 0, 0 }, in[4];
832
 
833
    out[1] = handle;
834
 
835
    res = emcore_monitor_command(out, in, 16, 16);
836
 
837
    if (EMCORE_SUCCESS != res)
838
    {
839
        return res;
840
    }
841
 
842
    if (in[1] > 0x80000000)
843
    {
844
        return EMCORE_ERROR_IO;
845
    }
846
 
847
    return EMCORE_SUCCESS;
848
}
849
 
850
int emcore_dir_close_all(uint32_t* count)
851
{
852
    int res;
853
    uint32_t out[4] = { 45, 0, 0, 0 }, in[4];
854
 
855
    res = emcore_monitor_command(out, in, 16, 16);
856
 
857
    if (EMCORE_SUCCESS != res)
858
    {
859
        return res;
860
    }
861
 
862
    if (in[1] > 0x80000000)
863
    {
864
        return EMCORE_ERROR_IO;
865
    }
866
 
867
    *count = in[1];
868
 
869
    return EMCORE_SUCCESS;
870
}
871
 
782 user890104 872
int emcore_dir_create(const char* name)
873
{
874
    int res;
875
    uint32_t str_length, data_length, in[4], *out;
876
 
877
    str_length = strlen(name);
878
    data_length = str_length + 1 + EMCORE_HEADER_SIZE;
879
 
880
    if (data_length > emcore_usb_eps_mps.cout)
881
    {
882
        return EMCORE_ERROR_OVERFLOW;
883
    }
884
 
885
    out = calloc(sizeof(char), data_length);
886
 
887
    *(out) = 47;
888
 
889
    strncpy(((char*)(out + 4)), name, str_length);
890
 
891
    res = emcore_monitor_command(out, in, data_length, 16);
892
 
893
    if (EMCORE_SUCCESS != res)
894
    {
895
        return res;
896
    }
897
 
898
    if (in[1] > 0x80000000)
899
    {
900
        return EMCORE_ERROR_IO;
901
    }
902
 
903
    return EMCORE_SUCCESS;
904
}
905
 
906
int emcore_dir_remove(const char* name)
907
{
908
    int res;
909
    uint32_t str_length, data_length, in[4], *out;
910
 
911
    str_length = strlen(name);
912
    data_length = str_length + 1 + EMCORE_HEADER_SIZE;
913
 
914
    if (data_length > emcore_usb_eps_mps.cout)
915
    {
916
        return EMCORE_ERROR_OVERFLOW;
917
    }
918
 
919
    out = calloc(sizeof(char), data_length);
920
 
921
    *(out) = 48;
922
 
923
    strncpy(((char*)(out + 4)), name, str_length);
924
 
925
    res = emcore_monitor_command(out, in, data_length, 16);
926
 
927
    if (EMCORE_SUCCESS != res)
928
    {
929
        return res;
930
    }
931
 
932
    if (in[1] > 0x80000000)
933
    {
934
        return EMCORE_ERROR_IO;
935
    }
936
 
937
    return EMCORE_SUCCESS;
938
}
939
 
770 user890104 940
int emcore_errno(uint32_t* emcore_errno_value)
941
{
942
    int res;
943
    uint32_t out[4] = { 49, 0, 0, 0 }, in[4];
944
 
945
    res = emcore_monitor_command(out, in, 16, 16);
946
 
947
    if (EMCORE_SUCCESS != res)
948
    {
949
        return res;
950
    }
951
 
952
    *emcore_errno_value = in[1];
953
 
954
    return EMCORE_SUCCESS;
955
}
956
 
957
int emcore_malloc(uint32_t* ptr, const uint32_t size)
958
{
959
    int res;
960
    uint32_t out[4] = { 52, 0xdeadbeef, 0, 0 }, in[4];
961
 
962
    out[1] = size;
963
 
964
    res = emcore_monitor_command(out, in, 16, 16);
965
 
966
    if (EMCORE_SUCCESS != res)
967
    {
968
        return res;
969
    }
970
 
971
    *ptr = in[1];
972
 
973
    return EMCORE_SUCCESS;
974
}
975
 
976
int emcore_memalign(uint32_t* ptr, const uint32_t align, const uint32_t size)
977
{
978
    int res;
979
    uint32_t out[4] = { 53, 0xdeadbeef, 0xdeadbeef, 0 }, in[4];
980
 
981
    out[1] = align;
982
    out[2] = size;
983
 
984
    res = emcore_monitor_command(out, in, 16, 16);
985
 
986
    if (EMCORE_SUCCESS != res)
987
    {
988
        return res;
989
    }
990
 
991
    *ptr = in[1];
992
 
993
    return EMCORE_SUCCESS;
994
}
995
 
996
int emcore_realloc(uint32_t* new_ptr, const uint32_t ptr, const uint32_t size)
997
{
998
    int res;
999
    uint32_t out[4] = { 54, 0xdeadbeef, 0xdeadbeef, 0 }, in[4];
1000
 
1001
    out[1] = ptr;
1002
    out[2] = size;
1003
 
1004
    res = emcore_monitor_command(out, in, 16, 16);
1005
 
1006
    if (EMCORE_SUCCESS != res)
1007
    {
1008
        return res;
1009
    }
1010
 
1011
    *new_ptr = in[1];
1012
 
1013
    return EMCORE_SUCCESS;
1014
}
1015
 
1016
int emcore_reownalloc(const uint32_t ptr, const uint32_t owner)
1017
{
1018
    uint32_t out[4] = { 55, 0xdeadbeef, 0xdeadbeef, 0 }, in[4];
1019
 
1020
    out[1] = ptr;
1021
    out[2] = owner;
1022
 
1023
    return emcore_monitor_command(out, in, 16, 16);
1024
}
1025
 
1026
int emcore_free(const uint32_t ptr)
1027
{
1028
    uint32_t out[4] = { 56, 0xdeadbeef, 0, 0 }, in[4];
1029
 
1030
    out[1] = ptr;
1031
 
1032
    return emcore_monitor_command(out, in, 16, 16);
1033
}
1034
 
1035
int emcore_free_all(void)
1036
{
1037
    uint32_t out[4] = { 57, 0, 0, 0 }, in[4];
1038
 
1039
    return emcore_monitor_command(out, in, 16, 16);
1040
}
1041
 
1042
int emcore_read(void* data, const uint32_t addr, const uint32_t size)
1043
{
1044
    int res;
1045
    struct alignsizes* sizes;
1046
    uint32_t cin_maxsize, readsize, curraddr;
1047
 
1048
    cin_maxsize = emcore_usb_eps_mps.cin - EMCORE_HEADER_SIZE;
1049
    sizes = malloc(sizeof(*sizes));
1050
 
1051
    alignsplit(sizes, addr, size, cin_maxsize, 16);
1052
#ifdef DEBUG_ALIGN_SPLIT
1053
    fprintf(stderr, "Downloading %d bytes from 0x%08x, split as (%d/%d/%d)\n",
1054
        size, addr, sizes->head, sizes->body, sizes->tail);
1055
 
1056
#endif
1057
    curraddr = addr;
1058
 
1059
    if (sizes->head > 0)
1060
    {
1061
        res = emcore_readmem(data, curraddr, sizes->head);
1062
 
1063
        if (EMCORE_SUCCESS != res)
1064
        {
1065
            return res;
1066
        }
1067
 
1068
        data += sizes->head;
1069
        curraddr += sizes->head;
1070
    }
1071
 
1072
    while (sizes->body > 0)
1073
    {
1074
        if (sizes->body >= cin_maxsize * 2)
1075
        {
1076
            readsize = MIN(sizes->body, emcore_usb_eps_mps.din);
1077
            res = emcore_readdma(data, curraddr, readsize);
1078
        }
1079
        else
1080
        {
1081
            readsize = MIN(sizes->body, cin_maxsize);
1082
            res = emcore_readmem(data, curraddr, readsize);
1083
        }
1084
 
1085
        if (EMCORE_SUCCESS != res)
1086
        {
1087
            return res;
1088
        }
1089
 
1090
        data += readsize;
1091
        curraddr += readsize;
1092
        sizes->body -= readsize;
1093
    }
1094
 
1095
    if (sizes->tail > 0)
1096
    {
1097
        res = emcore_readmem(data, curraddr, sizes->tail);
1098
 
1099
        if (EMCORE_SUCCESS != res)
1100
        {
1101
            return res;
1102
        }
1103
 
1104
        data += sizes->tail;
1105
    }
1106
 
1107
    return EMCORE_SUCCESS;
1108
}
1109
 
1110
int emcore_write(const void* data, const uint32_t addr, const uint32_t size)
1111
{
1112
    int res;
1113
    struct alignsizes* sizes;
1114
    uint32_t cout_maxsize, writesize, curraddr;
1115
 
1116
    cout_maxsize = emcore_usb_eps_mps.cout - 16;
1117
    sizes = malloc(sizeof(*sizes));
1118
 
1119
    alignsplit(sizes, addr, size, cout_maxsize, 16);
1120
#ifdef DEBUG_ALIGN_SPLIT
1121
    fprintf(stderr, "Uploading %d bytes from 0x%08x, split as (%d/%d/%d)\n",
1122
        size, addr, sizes->head, sizes->body, sizes->tail);
1123
 
1124
#endif
1125
    curraddr = addr;
1126
 
1127
    if (sizes->head > 0)
1128
    {
1129
        res = emcore_writemem(data, curraddr, sizes->head);
1130
 
1131
        if (EMCORE_SUCCESS != res)
1132
        {
1133
            return res;
1134
        }
1135
 
1136
        data += sizes->head;
1137
        curraddr += sizes->head;
1138
    }
1139
 
1140
    while (sizes->body > 0)
1141
    {
1142
        if (sizes->body >= 2 * cout_maxsize)
1143
        {
1144
            writesize = MIN(sizes->body, emcore_usb_eps_mps.dout);
1145
            res = emcore_writedma(data, curraddr, writesize);
1146
        }
1147
        else
1148
        {
1149
            writesize = MIN(sizes->body, cout_maxsize);
1150
            res = emcore_writemem(data, curraddr, writesize);
1151
        }
1152
 
1153
        if (EMCORE_SUCCESS != res)
1154
        {
1155
            return res;
1156
        }
1157
 
1158
        data += writesize;
1159
        curraddr += writesize;
1160
        sizes->body -= writesize;
1161
    }
1162
 
1163
    if (sizes->tail > 0)
1164
    {
1165
        res = emcore_writemem(data, curraddr, sizes->tail);
1166
 
1167
        if (EMCORE_SUCCESS != res)
1168
        {
1169
            return res;
1170
        }
1171
 
1172
        data += sizes->tail;
1173
    }
1174
 
1175
    return EMCORE_SUCCESS;
1176
}
1177
 
1178
int emcore_ls(const uint32_t handle)
1179
{
1180
    int res = 0;
1181
    struct emcore_dir_entry entry;
1182
 
1183
    while (1)
1184
    {
1185
        res = emcore_dir_read(&entry, handle);
1186
 
1187
        if (EMCORE_ERROR_NO_MORE_ENTRIES == res)
1188
        {
1189
            res = EMCORE_SUCCESS;
1190
            break;
1191
        }
1192
 
1193
        if (EMCORE_SUCCESS != res)
1194
        {
1195
            return res;
1196
        }
1197
 
1198
#ifdef DEBUG_DIR_ENTRIES
1199
        fprintf(stderr, "Read directory entry:\n");
1200
        fprintf(stderr, "Name: %s\n", entry.name);
1201
        fprintf(stderr, "Attributes: 0x%08x\n", entry.attributes);
1202
        fprintf(stderr, "Size: %d\n", entry.size);
1203
        fprintf(stderr, "Start cluster: %d\n", entry.startcluster);
1204
        fprintf(stderr, "Last written date: 0x%04x\n", entry.wrtdate);
1205
        fprintf(stderr, "Last written time: 0x%04x\n", entry.wrttime);
1206
        fprintf(stderr, "Last written TS: %lu\n",
1207
            (unsigned long) fat_time_to_unix_ts(entry.wrttime, entry.wrtdate));
1208
#endif
1209
        if (entry.attributes & 0x10)
1210
        {
1211
            printf("     [DIR]");
1212
        }
1213
        else
1214
        {
1215
            printf("%10d", entry.size);
1216
        }
1217
 
1218
        printf(" %s\n", entry.name);
1219
    }
1220
 
1221
    return res;
1222
}
1223
 
1224
int emcore_test(void)
1225
{
1226
    int res;
1227
 
1228
    /* emcore_get_version */
1229
    struct emcore_dev_info dev_info;
1230
    char *hw_type;
1231
 
1232
    /* emcore_get_packet_info */
1233
    struct emcore_usb_endpoints_max_packet_size max_packet_size;
1234
 
1235
    /* emcore_get_user_mem_range */
1236
    struct emcore_user_mem_range mem_range;
1237
 
1238
    /* emcore_readmem */
1239
    void* buf;
1240
    uint16_t buf_size;
1241
    uint32_t read_addr;
1242
 
1243
    /* emcore_readi2c */
1244
    /* uint8_t i2cdata; */
1245
 
1246
    /* emcore_dir_open */
1247
    uint32_t dir_handle;
1248
 
1249
    /* emcore_dir_close_all */
1250
    uint32_t count;
1251
 
1252
    res = emcore_get_version(&dev_info);
1253
 
1254
    if (EMCORE_SUCCESS != res)
1255
    {
1256
        return res;
1257
    }
1258
 
1259
    hw_type = malloc(5);
1260
 
1261
    strncpy(hw_type, ((char*)&dev_info.hw_type), 4);
1262
 
1263
    printf("Connected to %4s running %s v%d.%d.%d r%d\n",
1264
        hw_type, (1 == dev_info.sw_type ? "emBIOS" : (2 == dev_info.sw_type ? "emCORE" : "UNKNOWN")),
1265
        dev_info.major, dev_info.minor, dev_info.patch, dev_info.svn_revision
1266
    );
1267
 
1268
    free(hw_type);
1269
 
1270
    res = emcore_get_packet_info(&max_packet_size);
1271
 
1272
    if (EMCORE_SUCCESS != res)
1273
    {
1274
        return res;
1275
    }
1276
 
1277
    printf("COUT max pckt: %d, CIN max pckt: %d, DOUT max pckt: %d, DIN max pckt: %d\n",
1278
        max_packet_size.cout, max_packet_size.cin, max_packet_size.dout, max_packet_size.din
1279
    );
1280
 
1281
    res = emcore_get_user_mem_range(&mem_range);
1282
 
1283
    if (EMCORE_SUCCESS != res)
1284
    {
1285
        return res;
1286
    }
1287
 
1288
    printf("User mem range: 0x%08x - 0x%08x\n", mem_range.lower, mem_range.upper);
1289
 
1290
    read_addr = 0x09000000;
1291
    buf_size = 0x1000;
1292
    buf = malloc(buf_size);
1293
 
1294
    printf("Reading 0x%08x bytes from 0x%08x\n", buf_size, read_addr);
1295
 
1296
    res = emcore_read(buf, read_addr, buf_size);
1297
 
1298
    if (EMCORE_SUCCESS != res)
1299
    {
1300
        return res;
1301
    }
1302
 
1303
#ifdef DEBUG
1304
    dump_packet(buf, buf_size);
1305
 
1306
#endif
1307
    printf("Writing 0x%08x bytes to 0x%08x\n", buf_size, read_addr);
1308
 
1309
    res = emcore_write(buf, read_addr, buf_size);
1310
 
1311
    if (EMCORE_SUCCESS != res)
1312
    {
1313
        return res;
1314
    }
1315
 
1316
    free(buf);
1317
 
1318
    /*
1319
    printf("Reading 1 byte from I2C\n");
1320
 
1321
    res = emcore_readi2c(&i2cdata, 0, 0xe6, 0x29, 1);
1322
 
1323
    if (EMCORE_SUCCESS != res)
1324
    {
1325
        return res;
1326
    }
1327
 
1328
#ifdef DEBUG
1329
    dump_packet(&i2cdata, 1);
1330
 
1331
#endif
1332
    */
1333
    /* nano2g - turns on/off the backlight */
1334
    /*
1335
    i2cdata = 1;
1336
 
1337
    printf("Writing 1 byte to I2C\n");
1338
 
1339
    res = emcore_writei2c(&i2cdata, 0, 0xe6, 0x29, 1);
1340
 
1341
    if (EMCORE_SUCCESS != res)
1342
    {
1343
        return res;
1344
    }
1345
 
1346
    sleep(1);
1347
 
1348
    i2cdata = 0;
1349
 
1350
    printf("Writing 1 byte to I2C\n");
1351
 
1352
    res = emcore_writei2c(&i2cdata, 0, 0xe6, 0x29, 1);
1353
 
1354
    if (EMCORE_SUCCESS != res)
1355
    {
1356
        return res;
1357
    }
1358
    */
1359
    res = emcore_dir_open(&dir_handle, "/");
1360
 
1361
    if (EMCORE_SUCCESS != res)
1362
    {
1363
        return res;
1364
    }
1365
 
1366
    printf("Opened dir handle: 0x%08x\n", dir_handle);
1367
 
1368
    res = emcore_ls(dir_handle);
1369
 
1370
    if (EMCORE_SUCCESS != res)
1371
    {
1372
        return res;
1373
    }
1374
 
1375
    printf("Listed dir handle: 0x%08x\n", dir_handle);
1376
 
1377
    res = emcore_dir_close(dir_handle);
1378
 
1379
    if (EMCORE_SUCCESS != res)
1380
    {
1381
        return res;
1382
    }
1383
 
1384
    printf("Closed dir handle 0x%08x\n", dir_handle);
1385
 
1386
    res = emcore_dir_close_all(&count);
1387
 
1388
    if (EMCORE_SUCCESS != res)
1389
    {
1390
        return res;
1391
    }
1392
 
1393
    printf("Closed %d dir handles\n", count);
1394
    /* powers off the device - graceful
1395
    res = emcore_poweroff(1);
1396
 
1397
    if (EMCORE_SUCCESS != res)
1398
    {
1399
        return res;
1400
    }
1401
 
1402
    printf("Device powered off successfully!\n");
1403
    */
1404
    return EMCORE_SUCCESS;
1405
}