Subversion Repositories freemyipod

Rev

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