-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSDSPI.html
1332 lines (1219 loc) · 241 KB
/
SDSPI.html
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<pre>
<font color="#5e6d03">#include</font> <font color="#434f54"><</font><font color="#000000">stdbool</font><font color="#434f54">.</font><font color="#000000">h</font><font color="#434f54">></font>
<font color="#5e6d03">#include</font> <font color="#434f54"><</font><font color="#000000">stdint</font><font color="#434f54">.</font><font color="#000000">h</font><font color="#434f54">></font>
<font color="#5e6d03">#include</font> <font color="#434f54"><</font><font color="#000000">string</font><font color="#434f54">.</font><font color="#000000">h</font><font color="#434f54">></font>
<font color="#5e6d03">#include</font> <font color="#005c5f">"../pin_manager.h"</font>
<font color="#5e6d03">#include</font> <font color="#005c5f">"../drivers/spi_master.h"</font>
<font color="#95a5a6">/******************************************************************************/</font>
<font color="#95a5a6">/* SD Configuration */</font>
<font color="#95a5a6">/******************************************************************************/</font>
<font color="#434f54">// Description: Media Response Delay Timeout Values</font>
<font color="#5e6d03">#define</font> <font color="#000000">SD_SPI_STARTUP_DELAY_MS</font> <font color="#000000">30u</font>
<font color="#5e6d03">#define</font> <font color="#000000">SD_SPI_COMMAND_WAIT_MS</font> <font color="#000000">1u</font>
<font color="#5e6d03">#define</font> <font color="#000000">SD_NCR_TIMEOUT</font> <font color="#000000">(</font><font color="#00979c">uint16_t</font><font color="#000000">)</font><font color="#000000">20</font> <font color="#434f54">//byte times before command response is expected (must be at least 8)</font>
<font color="#5e6d03">#define</font> <font color="#000000">SD_NAC_TIMEOUT</font> <font color="#000000">(</font><font color="#00979c">uint32_t</font><font color="#000000">)</font><font color="#000000">0x40000</font> <font color="#434f54">//SPI byte times we should wait when performing read operations (should be at least 100ms for SD cards)</font>
<font color="#5e6d03">#define</font> <font color="#000000">SD_WRITE_TIMEOUT</font> <font color="#000000">(</font><font color="#00979c">uint32_t</font><font color="#000000">)</font><font color="#000000">0xA0000</font> <font color="#434f54">//SPI byte times to wait before timing out when the media is performing a write operation (should be at least 250ms for SD cards).</font>
<font color="#5e6d03">#define</font> <font color="#000000">SD_SPI_ChipSelect</font><font color="#000000">(</font><font color="#000000">)</font> <font color="#000000">SDCard_CS_SetLow</font><font color="#000000">(</font><font color="#000000">)</font>
<font color="#5e6d03">#define</font> <font color="#000000">SD_SPI_ChipDeselect</font><font color="#000000">(</font><font color="#000000">)</font> <font color="#000000">SDCard_CS_SetHigh</font><font color="#000000">(</font><font color="#000000">)</font>
<font color="#5e6d03">#define</font> <font color="#000000">SD_SPI_exchangeByte</font><font color="#000000">(</font><font color="#d35400">data</font><font color="#000000">)</font> <font color="#000000">spiMaster</font><font color="#000000">[</font><font color="#000000">SDFAST</font><font color="#000000">]</font><font color="#434f54">.</font><font color="#000000">exchangeByte</font><font color="#000000">(</font><font color="#d35400">data</font><font color="#000000">)</font>
<font color="#5e6d03">#define</font> <font color="#000000">SD_SPI_exchangeBlock</font><font color="#000000">(</font><font color="#d35400">data</font><font color="#434f54">,</font> <font color="#d35400">length</font><font color="#000000">)</font> <font color="#000000">spiMaster</font><font color="#000000">[</font><font color="#000000">SDFAST</font><font color="#000000">]</font><font color="#434f54">.</font><font color="#000000">exchangeBlock</font><font color="#000000">(</font><font color="#d35400">data</font><font color="#434f54">,</font> <font color="#d35400">length</font><font color="#000000">)</font>
<font color="#5e6d03">#define</font> <font color="#000000">SD_SPI_master_open</font><font color="#000000">(</font><font color="#d35400">config</font><font color="#000000">)</font> <font color="#000000">spiMaster</font><font color="#000000">[</font><font color="#d35400">config</font><font color="#000000">]</font><font color="#434f54">.</font><font color="#000000">spiOpen</font><font color="#000000">(</font><font color="#000000">)</font>
<font color="#5e6d03">#define</font> <font color="#000000">SD_SPI_close</font><font color="#000000">(</font><font color="#000000">)</font> <font color="#000000">spiMaster</font><font color="#000000">[</font><font color="#000000">SDFAST</font><font color="#000000">]</font><font color="#434f54">.</font><font color="#000000">spiClose</font><font color="#000000">(</font><font color="#000000">)</font>
<font color="#5e6d03">#define</font> <font color="#000000">SD_SPI_GetCardDetect</font><font color="#000000">(</font><font color="#000000">)</font> <font color="#000000">1</font>
<font color="#5e6d03">#define</font> <font color="#000000">SD_SPI_GetWriteProtect</font><font color="#000000">(</font><font color="#000000">)</font> <font color="#000000">0</font>
<font color="#95a5a6">/*****************************************************************************/</font>
<font color="#95a5a6">/* Custom structures and definitions */</font>
<font color="#95a5a6">/*****************************************************************************/</font>
<font color="#95a5a6">/* in SPI SLOW mode (<400kHz) 400kHz = 400 clocks for 1ms.</font>
<font color="#95a5a6"> * 8 clocks per byte = 50 bytes of dummy data results in at least 1ms</font>
<font color="#95a5a6"> * of delay. */</font>
<font color="#5e6d03">#define</font> <font color="#000000">SD_SLOW_CLOCK_DELAY_1MS_MIN</font> <font color="#000000">50u</font>
<font color="#434f54">//Definition for a structure used when calling either SD_AsyncReadTasks()</font>
<font color="#434f54">//function, or the SD_AsyncWriteTasks() function.</font>
<font color="#00979c">struct</font> <font color="#000000">SD_ASYNC_IO</font>
<font color="#000000">{</font>
<font color="#00979c">uint16_t</font> <font color="#000000">wNumBytes</font><font color="#000000">;</font> <font color="#434f54">//Number of bytes to attempt to read or write in the next call to MDD_SDSPI_AsyncReadTasks() or MDD_SDSPI_AsyncWriteTasks. May be updated between calls to the handler.</font>
<font color="#00979c">uint32_t</font> <font color="#000000">dwBytesRemaining</font><font color="#000000">;</font> <font color="#434f54">//Should be initialized to the total number of uint8_ts that you wish to read or write. This value is allowed to be greater than a single block size of the media.</font>
<font color="#00979c">uint8_t</font><font color="#434f54">*</font> <font color="#000000">pBuffer</font><font color="#000000">;</font> <font color="#434f54">//Pointer to where the read/written uint8_ts should be copied to/from. May be updated between calls to the handler function.</font>
<font color="#00979c">uint32_t</font> <font color="#000000">dwAddress</font><font color="#000000">;</font> <font color="#434f54">//Starting block address to read or to write to on the media. Should only get initialized, do not modify after that.</font>
<font color="#00979c">uint8_t</font> <font color="#000000">bStateVariable</font><font color="#000000">;</font> <font color="#434f54">//State machine variable. Should get initialized to ASYNC_READ_QUEUED or ASYNC_WRITE_QUEUED to start an operation. After that, do not modify until the read or write is complete.</font>
<font color="#000000">}</font><font color="#000000">;</font>
<font color="#434f54">//Response codes for the SD_AsyncReadTasks() function.</font>
<font color="#5e6d03">#define</font> <font color="#000000">SD_ASYNC_READ_COMPLETE</font> <font color="#000000">0x00</font>
<font color="#5e6d03">#define</font> <font color="#000000">SD_ASYNC_READ_BUSY</font> <font color="#000000">0x01</font>
<font color="#5e6d03">#define</font> <font color="#000000">SD_ASYNC_READ_NEW_PACKET_READY</font> <font color="#000000">0x02</font>
<font color="#5e6d03">#define</font> <font color="#000000">SD_ASYNC_READ_ERROR</font> <font color="#000000">0xFF</font>
<font color="#434f54">//SD_AsyncReadTasks() state machine variable values. These are used internally to sd_spi.c.</font>
<font color="#5e6d03">#define</font> <font color="#000000">SD_ASYNC_READ_COMPLETE</font> <font color="#000000">0x00</font>
<font color="#5e6d03">#define</font> <font color="#000000">SD_ASYNC_READ_QUEUED</font> <font color="#000000">0x01</font> <font color="#434f54">//Initialize to this to start a read sequence</font>
<font color="#5e6d03">#define</font> <font color="#000000">SD_ASYNC_READ_WAIT_START_TOKEN</font> <font color="#000000">0x03</font>
<font color="#5e6d03">#define</font> <font color="#000000">SD_ASYNC_READ_NEW_PACKET_READY</font> <font color="#000000">0x02</font>
<font color="#5e6d03">#define</font> <font color="#000000">SD_ASYNC_READ_ABORT</font> <font color="#000000">0xFE</font>
<font color="#5e6d03">#define</font> <font color="#000000">SD_ASYNC_READ_ERROR</font> <font color="#000000">0xFF</font>
<font color="#434f54">//Possible return values when calling SD_AsyncWriteTasks()</font>
<font color="#5e6d03">#define</font> <font color="#000000">SD_ASYNC_WRITE_COMPLETE</font> <font color="#000000">0x00</font>
<font color="#5e6d03">#define</font> <font color="#000000">SD_ASYNC_WRITE_SEND_PACKET</font> <font color="#000000">0x02</font>
<font color="#5e6d03">#define</font> <font color="#000000">SD_ASYNC_WRITE_BUSY</font> <font color="#000000">0x03</font>
<font color="#5e6d03">#define</font> <font color="#000000">SD_ASYNC_WRITE_ERROR</font> <font color="#000000">0xFF</font>
<font color="#434f54">//SD_AsyncWriteTasks() state machine variable values. These are used internally to sd_spi.c.</font>
<font color="#5e6d03">#define</font> <font color="#000000">SD_ASYNC_WRITE_COMPLETE</font> <font color="#000000">0x00</font>
<font color="#5e6d03">#define</font> <font color="#000000">SD_ASYNC_WRITE_QUEUED</font> <font color="#000000">0x01</font> <font color="#434f54">//Initialize to this to start a write sequence</font>
<font color="#5e6d03">#define</font> <font color="#000000">SD_ASYNC_WRITE_TRANSMIT_PACKET</font> <font color="#000000">0x02</font>
<font color="#5e6d03">#define</font> <font color="#000000">SD_ASYNC_WRITE_MEDIA_BUSY</font> <font color="#000000">0x03</font>
<font color="#5e6d03">#define</font> <font color="#000000">SD_ASYNC_STOP_TOKEN_SENT_WAIT_BUSY</font> <font color="#000000">0x04</font>
<font color="#5e6d03">#define</font> <font color="#000000">SD_ASYNC_WRITE_ABORT</font> <font color="#000000">0xFE</font>
<font color="#5e6d03">#define</font> <font color="#000000">SD_ASYNC_WRITE_ERROR</font> <font color="#000000">0xFF</font>
<font color="#5e6d03">#define</font> <font color="#000000">SD_MEDIA_BLOCK_SIZE</font> <font color="#000000">512u</font> <font color="#434f54">//Should always be 512 for v1 and v2 devices.</font>
<font color="#00979c">enum</font> <font color="#000000">SD_STATE</font>
<font color="#000000">{</font>
<font color="#000000">SD_STATE_NOT_INITIALIZED</font><font color="#434f54">,</font>
<font color="#000000">SD_STATE_READY_FOR_COMMAND</font><font color="#434f54">,</font>
<font color="#000000">SD_STATE_BUSY</font>
<font color="#000000">}</font><font color="#000000">;</font>
<font color="#00979c">enum</font> <font color="#000000">MEDIA_ERRORS</font>
<font color="#000000">{</font>
<font color="#000000">MEDIA_NO_ERROR</font><font color="#434f54">,</font> <font color="#434f54">// No errors</font>
<font color="#000000">MEDIA_DEVICE_NOT_PRESENT</font><font color="#434f54">,</font> <font color="#434f54">// The requested device is not present</font>
<font color="#000000">MEDIA_CANNOT_INITIALIZE</font> <font color="#434f54">// Cannot initialize media</font>
<font color="#000000">}</font> <font color="#000000">;</font>
<font color="#434f54">// Media information flags. The driver's MediaInitialize function will return a pointer to one of these structures.</font>
<font color="#00979c">struct</font> <font color="#000000">MEDIA_INFORMATION</font>
<font color="#000000">{</font>
<font color="#00979c">enum</font> <font color="#000000">MEDIA_ERRORS</font> <font color="#000000">errorCode</font><font color="#000000">;</font> <font color="#434f54">// The status of the initialization MEDIA_ERRORS</font>
<font color="#00979c">uint16_t</font> <font color="#000000">sectorSize</font><font color="#000000">;</font> <font color="#434f54">// The sector size of the target device.</font>
<font color="#00979c">enum</font> <font color="#000000">SD_STATE</font> <font color="#d35400">state</font><font color="#000000">;</font>
<font color="#00979c">uint32_t</font> <font color="#000000">finalLBA</font><font color="#000000">;</font>
<font color="#00979c">uint8_t</font> <font color="#000000">gSDMode</font><font color="#000000">;</font>
<font color="#000000">}</font><font color="#000000">;</font>
<font color="#95a5a6">/******************************************************************************</font>
<font color="#95a5a6"> * Global Variables</font>
<font color="#95a5a6"> *****************************************************************************/</font>
<font color="#00979c">enum</font> <font color="#000000">SD_TOKEN</font>
<font color="#000000">{</font>
<font color="#000000">SD_TOKEN_START</font> <font color="#434f54">=</font> <font color="#000000">0xFE</font><font color="#434f54">,</font>
<font color="#000000">SD_TOKEN_START_MULTI_BLOCK</font> <font color="#434f54">=</font> <font color="#000000">0xFC</font><font color="#434f54">,</font>
<font color="#000000">SD_TOKEN_STOP_TRANSMISSION</font> <font color="#434f54">=</font> <font color="#000000">0xFD</font><font color="#434f54">,</font>
<font color="#000000">SD_TOKEN_DATA_ACCEPTED</font> <font color="#434f54">=</font> <font color="#000000">0x05</font><font color="#434f54">,</font>
<font color="#000000">SD_TOKEN_FLOATING_BUS</font> <font color="#434f54">=</font> <font color="#000000">0xFF</font>
<font color="#000000">}</font><font color="#000000">;</font>
<font color="#00979c">enum</font> <font color="#000000">SD_COMMAND</font>
<font color="#000000">{</font>
<font color="#434f54">// Description: This macro defines the command code to reset the SD card</font>
<font color="#000000">SD_COMMAND_GO_IDLE_STATE</font> <font color="#434f54">=</font> <font color="#000000">0</font><font color="#434f54">,</font>
<font color="#434f54">// Description: This macro defines the command code to initialize the SD card</font>
<font color="#000000">SD_COMMAND_SEND_OP_COND</font> <font color="#434f54">=</font> <font color="#000000">1</font><font color="#434f54">,</font>
<font color="#434f54">// Description: This macro defined the command code to check for sector addressing</font>
<font color="#000000">SD_COMMAND_SEND_IF_COND</font> <font color="#434f54">=</font> <font color="#000000">8</font><font color="#434f54">,</font>
<font color="#434f54">// Description: This macro defines the command code to get the Card Specific Data</font>
<font color="#000000">SD_COMMAND_SEND_CSD</font> <font color="#434f54">=</font> <font color="#000000">9</font><font color="#434f54">,</font>
<font color="#434f54">// Description: This macro defines the command code to get the Card Information</font>
<font color="#000000">SD_COMMAND_SEND_CID</font> <font color="#434f54">=</font> <font color="#000000">10</font><font color="#434f54">,</font>
<font color="#434f54">// Description: This macro defines the command code to stop transmission during a multi-block read</font>
<font color="#000000">SD_COMMAND_STOP_TRANSMISSION</font> <font color="#434f54">=</font> <font color="#000000">12</font><font color="#434f54">,</font>
<font color="#434f54">// Description: This macro defines the command code to get the card status information</font>
<font color="#000000">SD_COMMAND_SEND_STATUS</font> <font color="#434f54">=</font> <font color="#000000">13</font><font color="#434f54">,</font>
<font color="#434f54">// Description: This macro defines the command code to set the block length of the card</font>
<font color="#000000">SD_COMMAND_SET_BLOCK_LENGTH</font> <font color="#434f54">=</font> <font color="#000000">16</font><font color="#434f54">,</font>
<font color="#434f54">// Description: This macro defines the command code to read one block from the card</font>
<font color="#000000">SD_COMMAND_READ_SINGLE_BLOCK</font> <font color="#434f54">=</font> <font color="#000000">17</font><font color="#434f54">,</font>
<font color="#434f54">// Description: This macro defines the command code to read multiple blocks from the card</font>
<font color="#000000">SD_COMMAND_READ_MULTI_BLOCK</font> <font color="#434f54">=</font> <font color="#000000">18</font><font color="#434f54">,</font>
<font color="#434f54">// Description: This macro defines the command code to tell the media how many blocks to pre-erase (for faster multi-block writes to follow)</font>
<font color="#434f54">//Note: This is an "application specific" command. This tells the media how many blocks to pre-erase for the subsequent WRITE_MULTI_BLOCK</font>
<font color="#000000">SD_COMMAND_SET_WRITE_BLOCK_ERASE_COUNT</font> <font color="#434f54">=</font> <font color="#000000">23</font><font color="#434f54">,</font>
<font color="#434f54">// Description: This macro defines the command code to write one block to the card</font>
<font color="#000000">SD_COMMAND_WRITE_SINGLE_BLOCK</font> <font color="#434f54">=</font> <font color="#000000">24</font><font color="#434f54">,</font>
<font color="#434f54">// Description: This macro defines the command code to write multiple blocks to the card</font>
<font color="#000000">SD_COMMAND_WRITE_MULTI_BLOCK</font> <font color="#434f54">=</font> <font color="#000000">25</font><font color="#434f54">,</font>
<font color="#434f54">// Description: This macro defines the command code to set the address of the start of an erase operation</font>
<font color="#000000">SD_COMMAND_TAG_SECTOR_START</font> <font color="#434f54">=</font> <font color="#000000">32</font><font color="#434f54">,</font>
<font color="#434f54">// Description: This macro defines the command code to set the address of the end of an erase operation</font>
<font color="#000000">SD_COMMAND_TAG_SECTOR_END</font> <font color="#434f54">=</font> <font color="#000000">33</font><font color="#434f54">,</font>
<font color="#434f54">// Description: This macro defines the command code to erase all previously selected blocks</font>
<font color="#000000">SD_COMMAND_ERASE</font> <font color="#434f54">=</font> <font color="#000000">38</font><font color="#434f54">,</font>
<font color="#434f54">//Description: This macro defines the command code to initialize an SD card and provide the CSD register value.</font>
<font color="#434f54">//Note: this is an "application specific" command (specific to SD cards) and must be preceded by cmdAPP_CMD.</font>
<font color="#000000">SD_COMMAND_SD_SEND_OP_COND</font> <font color="#434f54">=</font> <font color="#000000">41</font><font color="#434f54">,</font>
<font color="#434f54">// Description: This macro defines the command code to begin application specific command inputs</font>
<font color="#000000">SD_COMMAND_APP_CMD</font> <font color="#434f54">=</font> <font color="#000000">55</font><font color="#434f54">,</font>
<font color="#434f54">// Description: This macro defines the command code to get the OCR register information from the card</font>
<font color="#000000">SD_COMMAND_READ_OCR</font> <font color="#434f54">=</font> <font color="#000000">58</font><font color="#434f54">,</font>
<font color="#434f54">// Description: This macro defines the command code to disable CRC checking</font>
<font color="#000000">SD_COMMAND_CRC_ON_OFF</font> <font color="#434f54">=</font> <font color="#000000">59</font>
<font color="#000000">}</font><font color="#000000">;</font>
<font color="#5e6d03">#define</font> <font color="#000000">SD_MODE_NORMAL</font> <font color="#000000">0</font>
<font color="#5e6d03">#define</font> <font color="#000000">SD_MODE_HC</font> <font color="#000000">1</font>
<font color="#434f54">//Constants</font>
<font color="#5e6d03">#define</font> <font color="#000000">SD_WRITE_RESPONSE_TOKEN_MASK</font> <font color="#000000">0x1F</font> <font color="#434f54">//Bit mask to AND with the write token response uint8_t from the media, to clear the don't care bits.</font>
<font color="#434f54">// Description: Enumeration of different SD response types</font>
<font color="#00979c">typedef</font> <font color="#00979c">enum</font>
<font color="#000000">{</font>
<font color="#000000">SD_RESPONSE_R1</font><font color="#434f54">,</font> <font color="#434f54">// R1 type response</font>
<font color="#000000">SD_RESPONSE_R1b</font><font color="#434f54">,</font> <font color="#434f54">// R1b type response</font>
<font color="#000000">SD_RESPONSE_R2</font><font color="#434f54">,</font> <font color="#434f54">// R2 type response</font>
<font color="#000000">SD_RESPONSE_R3</font><font color="#434f54">,</font> <font color="#434f54">// R3 type response</font>
<font color="#000000">SD_RESPONSE_R7</font> <font color="#434f54">// R7 type response</font>
<font color="#000000">}</font><font color="#000000">SD_RESPONSE_TYPE</font><font color="#000000">;</font>
<font color="#5e6d03">#define</font> <font color="#000000">SD_COMMAND_CODE_BIT_MASK</font> <font color="#000000">(</font><font color="#000000">0b00111111</font><font color="#000000">)</font>
<font color="#5e6d03">#define</font> <font color="#000000">SD_COMMAND_TRANSMIT_BIT_MASK</font> <font color="#000000">(</font><font color="#000000">1</font><font color="#434f54"><<</font><font color="#000000">6</font><font color="#000000">)</font>
<font color="#5e6d03">#define</font> <font color="#000000">SD_COMMAND_START_BIT_MASK</font> <font color="#000000">(</font><font color="#000000">1</font><font color="#434f54"><<</font><font color="#000000">6</font><font color="#000000">)</font>
<font color="#434f54">// Summary: The format of an R1 type response</font>
<font color="#434f54">// Description: This union represents different ways to access an SD card R1 type response packet.</font>
<font color="#00979c">typedef</font> <font color="#00979c">union</font>
<font color="#000000">{</font>
<font color="#00979c">uint8_t</font> <font color="#000000">_byte</font><font color="#000000">;</font> <font color="#434f54">// byte-wise access</font>
<font color="#434f54">// This structure allows bitwise access of the response</font>
<font color="#00979c">struct</font>
<font color="#000000">{</font>
<font color="#00979c">unsigned</font> <font color="#000000">IN_IDLE_STATE</font><font color="#434f54">:</font><font color="#000000">1</font><font color="#000000">;</font> <font color="#434f54">// Card is in idle state</font>
<font color="#00979c">unsigned</font> <font color="#000000">ERASE_RESET</font><font color="#434f54">:</font><font color="#000000">1</font><font color="#000000">;</font> <font color="#434f54">// Erase reset flag</font>
<font color="#00979c">unsigned</font> <font color="#000000">ILLEGAL_CMD</font><font color="#434f54">:</font><font color="#000000">1</font><font color="#000000">;</font> <font color="#434f54">// Illegal command flag</font>
<font color="#00979c">unsigned</font> <font color="#000000">CRC_ERR</font><font color="#434f54">:</font><font color="#000000">1</font><font color="#000000">;</font> <font color="#434f54">// CRC error flag</font>
<font color="#00979c">unsigned</font> <font color="#000000">ERASE_SEQ_ERR</font><font color="#434f54">:</font><font color="#000000">1</font><font color="#000000">;</font> <font color="#434f54">// Erase sequence error flag</font>
<font color="#00979c">unsigned</font> <font color="#000000">ADDRESS_ERR</font><font color="#434f54">:</font><font color="#000000">1</font><font color="#000000">;</font> <font color="#434f54">// Address error flag</font>
<font color="#00979c">unsigned</font> <font color="#000000">PARAM_ERR</font><font color="#434f54">:</font><font color="#000000">1</font><font color="#000000">;</font> <font color="#434f54">// Parameter flag </font>
<font color="#00979c">unsigned</font> <font color="#000000">B7</font><font color="#434f54">:</font><font color="#000000">1</font><font color="#000000">;</font> <font color="#434f54">// Unused bit 7</font>
<font color="#000000">}</font><font color="#000000">;</font>
<font color="#000000">}</font> <font color="#000000">SD_RESPONSE_1</font><font color="#000000">;</font>
<font color="#434f54">// Summary: The format of an R2 type response</font>
<font color="#434f54">// Description: This union represents different ways to access an SD card R2 type response packet</font>
<font color="#00979c">typedef</font> <font color="#00979c">union</font>
<font color="#000000">{</font>
<font color="#00979c">uint16_t</font> <font color="#000000">_uint16_t</font><font color="#000000">;</font>
<font color="#00979c">struct</font>
<font color="#000000">{</font>
<font color="#00979c">uint8_t</font> <font color="#000000">_byte0</font><font color="#000000">;</font>
<font color="#00979c">uint8_t</font> <font color="#000000">_byte1</font><font color="#000000">;</font>
<font color="#000000">}</font><font color="#000000">;</font>
<font color="#00979c">struct</font>
<font color="#000000">{</font>
<font color="#00979c">unsigned</font> <font color="#000000">IN_IDLE_STATE</font><font color="#434f54">:</font><font color="#000000">1</font><font color="#000000">;</font>
<font color="#00979c">unsigned</font> <font color="#000000">ERASE_RESET</font><font color="#434f54">:</font><font color="#000000">1</font><font color="#000000">;</font>
<font color="#00979c">unsigned</font> <font color="#000000">ILLEGAL_CMD</font><font color="#434f54">:</font><font color="#000000">1</font><font color="#000000">;</font>
<font color="#00979c">unsigned</font> <font color="#000000">CRC_ERR</font><font color="#434f54">:</font><font color="#000000">1</font><font color="#000000">;</font>
<font color="#00979c">unsigned</font> <font color="#000000">ERASE_SEQ_ERR</font><font color="#434f54">:</font><font color="#000000">1</font><font color="#000000">;</font>
<font color="#00979c">unsigned</font> <font color="#000000">ADDRESS_ERR</font><font color="#434f54">:</font><font color="#000000">1</font><font color="#000000">;</font>
<font color="#00979c">unsigned</font> <font color="#000000">PARAM_ERR</font><font color="#434f54">:</font><font color="#000000">1</font><font color="#000000">;</font>
<font color="#00979c">unsigned</font> <font color="#000000">B7</font><font color="#434f54">:</font><font color="#000000">1</font><font color="#000000">;</font>
<font color="#00979c">unsigned</font> <font color="#000000">CARD_IS_LOCKED</font><font color="#434f54">:</font><font color="#000000">1</font><font color="#000000">;</font>
<font color="#00979c">unsigned</font> <font color="#000000">WP_ERASE_SKIP_LK_FAIL</font><font color="#434f54">:</font><font color="#000000">1</font><font color="#000000">;</font>
<font color="#00979c">unsigned</font> <font color="#00979c">ERROR</font><font color="#434f54">:</font><font color="#000000">1</font><font color="#000000">;</font>
<font color="#00979c">unsigned</font> <font color="#000000">CC_ERROR</font><font color="#434f54">:</font><font color="#000000">1</font><font color="#000000">;</font>
<font color="#00979c">unsigned</font> <font color="#000000">CARD_ECC_FAIL</font><font color="#434f54">:</font><font color="#000000">1</font><font color="#000000">;</font>
<font color="#00979c">unsigned</font> <font color="#000000">WP_VIOLATION</font><font color="#434f54">:</font><font color="#000000">1</font><font color="#000000">;</font>
<font color="#00979c">unsigned</font> <font color="#000000">ERASE_PARAM</font><font color="#434f54">:</font><font color="#000000">1</font><font color="#000000">;</font>
<font color="#00979c">unsigned</font> <font color="#000000">OUTRANGE_CSD_OVERWRITE</font><font color="#434f54">:</font><font color="#000000">1</font><font color="#000000">;</font>
<font color="#000000">}</font><font color="#000000">;</font>
<font color="#000000">}</font> <font color="#000000">SD_RESPONSE_2</font><font color="#000000">;</font>
<font color="#434f54">// Summary: The format of an R7 or R3 type response</font>
<font color="#434f54">// Description: This union represents different ways to access an SD card R7 type response packet.</font>
<font color="#00979c">typedef</font> <font color="#00979c">union</font>
<font color="#000000">{</font>
<font color="#00979c">struct</font>
<font color="#000000">{</font>
<font color="#00979c">uint8_t</font> <font color="#000000">_byte</font><font color="#000000">;</font> <font color="#434f54">// byte-wise access</font>
<font color="#00979c">union</font>
<font color="#000000">{</font>
<font color="#434f54">//Note: The SD card argument response field is 32-bit, big endian format.</font>
<font color="#434f54">//However, the C compiler stores 32-bit values in little endian in RAM.</font>
<font color="#434f54">//When writing to the _returnVal/argument bytes, make sure to byte</font>
<font color="#434f54">//swap the order from which it arrived over the SPI from the SD card.</font>
<font color="#00979c">uint32_t</font> <font color="#000000">_returnVal</font><font color="#000000">;</font>
<font color="#00979c">struct</font>
<font color="#000000">{</font>
<font color="#00979c">uint8_t</font> <font color="#000000">_byte0</font><font color="#000000">;</font>
<font color="#00979c">uint8_t</font> <font color="#000000">_byte1</font><font color="#000000">;</font>
<font color="#00979c">uint8_t</font> <font color="#000000">_byte2</font><font color="#000000">;</font>
<font color="#00979c">uint8_t</font> <font color="#000000">_byte3</font><font color="#000000">;</font>
<font color="#000000">}</font><font color="#000000">;</font>
<font color="#000000">}</font><font color="#000000">argument</font><font color="#000000">;</font>
<font color="#000000">}</font> <font color="#000000">bytewise</font><font color="#000000">;</font>
<font color="#434f54">// This structure allows bitwise access of the response</font>
<font color="#00979c">struct</font>
<font color="#000000">{</font>
<font color="#00979c">struct</font>
<font color="#000000">{</font>
<font color="#00979c">unsigned</font> <font color="#000000">IN_IDLE_STATE</font><font color="#434f54">:</font><font color="#000000">1</font><font color="#000000">;</font> <font color="#434f54">// Card is in idle state</font>
<font color="#00979c">unsigned</font> <font color="#000000">ERASE_RESET</font><font color="#434f54">:</font><font color="#000000">1</font><font color="#000000">;</font> <font color="#434f54">// Erase reset flag</font>
<font color="#00979c">unsigned</font> <font color="#000000">ILLEGAL_CMD</font><font color="#434f54">:</font><font color="#000000">1</font><font color="#000000">;</font> <font color="#434f54">// Illegal command flag</font>
<font color="#00979c">unsigned</font> <font color="#000000">CRC_ERR</font><font color="#434f54">:</font><font color="#000000">1</font><font color="#000000">;</font> <font color="#434f54">// CRC error flag</font>
<font color="#00979c">unsigned</font> <font color="#000000">ERASE_SEQ_ERR</font><font color="#434f54">:</font><font color="#000000">1</font><font color="#000000">;</font> <font color="#434f54">// Erase sequence error flag</font>
<font color="#00979c">unsigned</font> <font color="#000000">ADDRESS_ERR</font><font color="#434f54">:</font><font color="#000000">1</font><font color="#000000">;</font> <font color="#434f54">// Address error flag</font>
<font color="#00979c">unsigned</font> <font color="#000000">PARAM_ERR</font><font color="#434f54">:</font><font color="#000000">1</font><font color="#000000">;</font> <font color="#434f54">// Parameter flag </font>
<font color="#00979c">unsigned</font> <font color="#000000">B7</font><font color="#434f54">:</font><font color="#000000">1</font><font color="#000000">;</font> <font color="#434f54">// Unused bit 7</font>
<font color="#000000">}</font><font color="#d35400">bits</font><font color="#000000">;</font>
<font color="#00979c">uint32_t</font> <font color="#000000">_returnVal</font><font color="#000000">;</font>
<font color="#000000">}</font> <font color="#000000">bitwise</font><font color="#000000">;</font>
<font color="#000000">}</font> <font color="#000000">SD_RESPONSE_7</font><font color="#000000">;</font>
<font color="#434f54">// Summary: A union of responses from an SD card</font>
<font color="#434f54">// Description: The SD_RESPONSE union represents any of the possible responses that an SD card can return after</font>
<font color="#434f54">// being issued a command.</font>
<font color="#00979c">typedef</font> <font color="#00979c">union</font>
<font color="#000000">{</font>
<font color="#000000">SD_RESPONSE_1</font> <font color="#000000">r1</font><font color="#000000">;</font>
<font color="#000000">SD_RESPONSE_2</font> <font color="#000000">r2</font><font color="#000000">;</font>
<font color="#000000">SD_RESPONSE_7</font> <font color="#000000">r7</font><font color="#000000">;</font>
<font color="#000000">}</font><font color="#000000">SD_RESPONSE</font><font color="#000000">;</font>
<font color="#434f54">// Description: Used for the mass-storage library to determine capacity</font>
<font color="#00979c">static</font> <font color="#00979c">struct</font> <font color="#000000">MEDIA_INFORMATION</font> <font color="#000000">mediaInformation</font> <font color="#434f54">=</font> <font color="#000000">{</font><font color="#000000">MEDIA_NO_ERROR</font><font color="#434f54">,</font> <font color="#000000">SD_MEDIA_BLOCK_SIZE</font><font color="#434f54">,</font> <font color="#000000">SD_STATE_NOT_INITIALIZED</font><font color="#434f54">,</font> <font color="#000000">0ul</font><font color="#434f54">,</font> <font color="#000000">SD_MODE_NORMAL</font><font color="#000000">}</font><font color="#000000">;</font>
<font color="#00979c">static</font> <font color="#00979c">struct</font> <font color="#000000">SD_ASYNC_IO</font> <font color="#000000">ioInfo</font><font color="#000000">;</font> <font color="#434f54">//Declared global context, for fast/code efficient access</font>
<font color="#434f54">// Summary: An enumeration of SD commands</font>
<font color="#434f54">// Description: This enumeration corresponds to the position of each command in the sdmmc_cmdtable array</font>
<font color="#434f54">// These macros indicate to the SD_SendCmd function which element of the sdmmc_cmdtable array</font>
<font color="#434f54">// to retrieve command code information from.</font>
<font color="#00979c">enum</font> <font color="#000000">SD_COMMAND_INDEX</font>
<font color="#000000">{</font>
<font color="#000000">SD_GO_IDLE_STATE</font> <font color="#434f54">=</font> <font color="#000000">0</font><font color="#434f54">,</font>
<font color="#000000">SD_SEND_OP_COND</font><font color="#434f54">,</font>
<font color="#000000">SD_SEND_IF_COND</font><font color="#434f54">,</font>
<font color="#000000">SD_SEND_CSD</font><font color="#434f54">,</font>
<font color="#000000">SD_SEND_CID</font><font color="#434f54">,</font>
<font color="#000000">SD_STOP_TRANSMISSION</font><font color="#434f54">,</font>
<font color="#000000">SD_SEND_STATUS</font><font color="#434f54">,</font>
<font color="#000000">SD_SET_BLOCK_LENGTH</font><font color="#434f54">,</font>
<font color="#000000">SD_READ_SINGLE_BLOCK</font><font color="#434f54">,</font>
<font color="#000000">SD_READ_MULTI_BLOCK</font><font color="#434f54">,</font>
<font color="#000000">SD_WRITE_SINGLE_BLOCK</font><font color="#434f54">,</font>
<font color="#000000">SD_WRITE_MULTI_BLOCK</font><font color="#434f54">,</font>
<font color="#000000">SD_TAG_SECTOR_START</font><font color="#434f54">,</font>
<font color="#000000">SD_TAG_SECTOR_END</font><font color="#434f54">,</font>
<font color="#000000">SD_ERASE</font><font color="#434f54">,</font>
<font color="#000000">SD_APP_CMD</font><font color="#434f54">,</font>
<font color="#000000">SD_READ_OCR</font><font color="#434f54">,</font>
<font color="#000000">SD_CRC_ON_OFF</font><font color="#434f54">,</font>
<font color="#000000">SD_SD_SEND_OP_COND</font><font color="#434f54">,</font>
<font color="#000000">SD_SET_WRITE_BLOCK_ERASE_COUNT</font>
<font color="#000000">}</font> <font color="#000000">;</font>
<font color="#434f54">// Summary: SD card command data structure</font>
<font color="#434f54">// Description: The SD_COMMAND structure is used to create a command table of information needed for each relevant SD command</font>
<font color="#00979c">struct</font> <font color="#000000">SD_COMMAND_TABLE_ENTRY</font>
<font color="#000000">{</font>
<font color="#00979c">enum</font> <font color="#000000">SD_COMMAND</font> <font color="#000000">CmdCode</font><font color="#000000">;</font> <font color="#434f54">// The command code</font>
<font color="#00979c">uint8_t</font> <font color="#000000">CRC</font><font color="#000000">;</font> <font color="#434f54">// The CRC value for that command</font>
<font color="#000000">SD_RESPONSE_TYPE</font> <font color="#000000">responsetype</font><font color="#000000">;</font> <font color="#434f54">// The response type</font>
<font color="#00979c">bool</font> <font color="#000000">moreDataExpected</font><font color="#000000">;</font>
<font color="#000000">}</font><font color="#000000">;</font>
<font color="#434f54">// Summary: Table of SD card commands and parameters</font>
<font color="#434f54">// Description: The sdmmc_cmdtable contains an array of SD card commands, the corresponding CRC code, the</font>
<font color="#434f54">// response type that the card will return, and a parameter indicating whether to expect</font>
<font color="#434f54">// additional data from the card.</font>
<font color="#00979c">static</font> <font color="#00979c">const</font> <font color="#00979c">struct</font> <font color="#000000">SD_COMMAND_TABLE_ENTRY</font> <font color="#000000">sdmmc_cmdtable</font><font color="#000000">[</font><font color="#000000">]</font> <font color="#434f54">=</font>
<font color="#000000">{</font>
<font color="#434f54">// cmd crc response more data expected</font>
<font color="#000000">{</font><font color="#000000">SD_COMMAND_GO_IDLE_STATE</font><font color="#434f54">,</font> <font color="#000000">0x95</font><font color="#434f54">,</font> <font color="#000000">SD_RESPONSE_R1</font><font color="#434f54">,</font> <font color="#00979c">false</font><font color="#000000">}</font><font color="#434f54">,</font>
<font color="#000000">{</font><font color="#000000">SD_COMMAND_SEND_OP_COND</font><font color="#434f54">,</font> <font color="#000000">0xF9</font><font color="#434f54">,</font> <font color="#000000">SD_RESPONSE_R1</font><font color="#434f54">,</font> <font color="#00979c">false</font><font color="#000000">}</font><font color="#434f54">,</font>
<font color="#000000">{</font><font color="#000000">SD_COMMAND_SEND_IF_COND</font><font color="#434f54">,</font> <font color="#000000">0x87</font><font color="#434f54">,</font> <font color="#000000">SD_RESPONSE_R7</font><font color="#434f54">,</font> <font color="#00979c">false</font><font color="#000000">}</font><font color="#434f54">,</font>
<font color="#000000">{</font><font color="#000000">SD_COMMAND_SEND_CSD</font><font color="#434f54">,</font> <font color="#000000">0xAF</font><font color="#434f54">,</font> <font color="#000000">SD_RESPONSE_R1</font><font color="#434f54">,</font> <font color="#00979c">true</font><font color="#000000">}</font><font color="#434f54">,</font>
<font color="#000000">{</font><font color="#000000">SD_COMMAND_SEND_CID</font><font color="#434f54">,</font> <font color="#000000">0x1B</font><font color="#434f54">,</font> <font color="#000000">SD_RESPONSE_R1</font><font color="#434f54">,</font> <font color="#00979c">true</font><font color="#000000">}</font><font color="#434f54">,</font>
<font color="#000000">{</font><font color="#000000">SD_COMMAND_STOP_TRANSMISSION</font><font color="#434f54">,</font> <font color="#000000">0xC3</font><font color="#434f54">,</font> <font color="#000000">SD_RESPONSE_R1b</font><font color="#434f54">,</font> <font color="#00979c">false</font><font color="#000000">}</font><font color="#434f54">,</font>
<font color="#000000">{</font><font color="#000000">SD_COMMAND_SEND_STATUS</font><font color="#434f54">,</font> <font color="#000000">0xAF</font><font color="#434f54">,</font> <font color="#000000">SD_RESPONSE_R2</font><font color="#434f54">,</font> <font color="#00979c">false</font><font color="#000000">}</font><font color="#434f54">,</font>
<font color="#000000">{</font><font color="#000000">SD_COMMAND_SET_BLOCK_LENGTH</font><font color="#434f54">,</font> <font color="#000000">0xFF</font><font color="#434f54">,</font> <font color="#000000">SD_RESPONSE_R1</font><font color="#434f54">,</font> <font color="#00979c">false</font><font color="#000000">}</font><font color="#434f54">,</font>
<font color="#000000">{</font><font color="#000000">SD_COMMAND_READ_SINGLE_BLOCK</font><font color="#434f54">,</font> <font color="#000000">0xFF</font><font color="#434f54">,</font> <font color="#000000">SD_RESPONSE_R1</font><font color="#434f54">,</font> <font color="#00979c">true</font><font color="#000000">}</font><font color="#434f54">,</font>
<font color="#000000">{</font><font color="#000000">SD_COMMAND_READ_MULTI_BLOCK</font><font color="#434f54">,</font> <font color="#000000">0xFF</font><font color="#434f54">,</font> <font color="#000000">SD_RESPONSE_R1</font><font color="#434f54">,</font> <font color="#00979c">true</font><font color="#000000">}</font><font color="#434f54">,</font>
<font color="#000000">{</font><font color="#000000">SD_COMMAND_WRITE_SINGLE_BLOCK</font><font color="#434f54">,</font> <font color="#000000">0xFF</font><font color="#434f54">,</font> <font color="#000000">SD_RESPONSE_R1</font><font color="#434f54">,</font> <font color="#00979c">true</font><font color="#000000">}</font><font color="#434f54">,</font>
<font color="#000000">{</font><font color="#000000">SD_COMMAND_WRITE_MULTI_BLOCK</font><font color="#434f54">,</font> <font color="#000000">0xFF</font><font color="#434f54">,</font> <font color="#000000">SD_RESPONSE_R1</font><font color="#434f54">,</font> <font color="#00979c">true</font><font color="#000000">}</font><font color="#434f54">,</font>
<font color="#000000">{</font><font color="#000000">SD_COMMAND_TAG_SECTOR_START</font><font color="#434f54">,</font> <font color="#000000">0xFF</font><font color="#434f54">,</font> <font color="#000000">SD_RESPONSE_R1</font><font color="#434f54">,</font> <font color="#00979c">false</font><font color="#000000">}</font><font color="#434f54">,</font>
<font color="#000000">{</font><font color="#000000">SD_COMMAND_TAG_SECTOR_END</font><font color="#434f54">,</font> <font color="#000000">0xFF</font><font color="#434f54">,</font> <font color="#000000">SD_RESPONSE_R1</font><font color="#434f54">,</font> <font color="#00979c">false</font><font color="#000000">}</font><font color="#434f54">,</font>
<font color="#000000">{</font><font color="#000000">SD_COMMAND_ERASE</font><font color="#434f54">,</font> <font color="#000000">0xDF</font><font color="#434f54">,</font> <font color="#000000">SD_RESPONSE_R1b</font><font color="#434f54">,</font> <font color="#00979c">false</font><font color="#000000">}</font><font color="#434f54">,</font>
<font color="#000000">{</font><font color="#000000">SD_COMMAND_APP_CMD</font><font color="#434f54">,</font> <font color="#000000">0x73</font><font color="#434f54">,</font> <font color="#000000">SD_RESPONSE_R1</font><font color="#434f54">,</font> <font color="#00979c">false</font><font color="#000000">}</font><font color="#434f54">,</font>
<font color="#000000">{</font><font color="#000000">SD_COMMAND_READ_OCR</font><font color="#434f54">,</font> <font color="#000000">0x25</font><font color="#434f54">,</font> <font color="#000000">SD_RESPONSE_R7</font><font color="#434f54">,</font> <font color="#00979c">false</font><font color="#000000">}</font><font color="#434f54">,</font>
<font color="#000000">{</font><font color="#000000">SD_COMMAND_CRC_ON_OFF</font><font color="#434f54">,</font> <font color="#000000">0x25</font><font color="#434f54">,</font> <font color="#000000">SD_RESPONSE_R1</font><font color="#434f54">,</font> <font color="#00979c">false</font><font color="#000000">}</font><font color="#434f54">,</font>
<font color="#000000">{</font><font color="#000000">SD_COMMAND_SD_SEND_OP_COND</font><font color="#434f54">,</font> <font color="#000000">0xFF</font><font color="#434f54">,</font> <font color="#000000">SD_RESPONSE_R7</font><font color="#434f54">,</font> <font color="#00979c">false</font><font color="#000000">}</font><font color="#434f54">,</font> <font color="#434f54">//Actual response is R3, but has same number of bytes as R7.</font>
<font color="#000000">{</font><font color="#000000">SD_COMMAND_SET_WRITE_BLOCK_ERASE_COUNT</font><font color="#434f54">,</font> <font color="#000000">0xFF</font><font color="#434f54">,</font> <font color="#000000">SD_RESPONSE_R1</font><font color="#434f54">,</font> <font color="#00979c">false</font><font color="#000000">}</font>
<font color="#000000">}</font><font color="#000000">;</font>
<font color="#95a5a6">/******************************************************************************</font>
<font color="#95a5a6"> * Private Prototypes</font>
<font color="#95a5a6"> *****************************************************************************/</font>
<font color="#00979c">static</font> <font color="#000000">SD_RESPONSE</font> <font color="#000000">SD_SendCmd</font><font color="#000000">(</font><font color="#00979c">uint8_t</font> <font color="#000000">cmd</font><font color="#434f54">,</font> <font color="#00979c">uint32_t</font> <font color="#000000">address</font><font color="#000000">)</font><font color="#000000">;</font>
<font color="#00979c">static</font> <font color="#00979c">uint8_t</font> <font color="#000000">SD_SPI_AsyncWriteTasks</font><font color="#000000">(</font><font color="#00979c">struct</font> <font color="#000000">SD_ASYNC_IO</font><font color="#434f54">*</font> <font color="#000000">info</font><font color="#000000">)</font><font color="#000000">;</font>
<font color="#00979c">static</font> <font color="#00979c">uint8_t</font> <font color="#000000">SD_SPI_AsyncReadTasks</font><font color="#000000">(</font><font color="#00979c">struct</font> <font color="#000000">SD_ASYNC_IO</font><font color="#434f54">*</font> <font color="#000000">info</font><font color="#000000">)</font><font color="#000000">;</font>
<font color="#00979c">static</font> <font color="#00979c">void</font> <font color="#000000">SDSPI_DelayMilliseconds</font><font color="#000000">(</font><font color="#00979c">uint8_t</font> <font color="#d35400">milliseconds</font><font color="#000000">)</font>
<font color="#000000">{</font>
<font color="#00979c">uint16_t</font> <font color="#000000">timeout</font> <font color="#434f54">=</font> <font color="#000000">SD_SLOW_CLOCK_DELAY_1MS_MIN</font> <font color="#434f54">*</font> <font color="#d35400">milliseconds</font><font color="#000000">;</font>
<font color="#000000">SD_SPI_ChipDeselect</font><font color="#000000">(</font><font color="#000000">)</font><font color="#000000">;</font>
<font color="#5e6d03">while</font><font color="#000000">(</font><font color="#000000">timeout</font><font color="#434f54">--</font><font color="#000000">)</font>
<font color="#000000">{</font>
<font color="#000000">(</font><font color="#00979c">void</font><font color="#000000">)</font><font color="#000000">SD_SPI_exchangeByte</font><font color="#000000">(</font><font color="#000000">0xFF</font><font color="#000000">)</font><font color="#000000">;</font>
<font color="#000000">}</font>
<font color="#000000">}</font>
<font color="#00979c">bool</font> <font color="#000000">SDSPI_IsMediaPresent</font><font color="#000000">(</font><font color="#00979c">void</font><font color="#000000">)</font>
<font color="#000000">{</font>
<font color="#5e6d03">return</font> <font color="#000000">SD_SPI_GetCardDetect</font><font color="#000000">(</font><font color="#000000">)</font> <font color="#434f54">?</font> <font color="#00979c">true</font><font color="#434f54">:</font> <font color="#00979c">false</font><font color="#000000">;</font>
<font color="#000000">}</font>
<font color="#00979c">bool</font> <font color="#000000">SDSPI_MediaInitialize</font><font color="#000000">(</font><font color="#00979c">void</font><font color="#000000">)</font>
<font color="#000000">{</font>
<font color="#00979c">uint16_t</font> <font color="#000000">timeout</font><font color="#000000">;</font>
<font color="#000000">SD_RESPONSE</font> <font color="#d35400">response</font><font color="#000000">;</font>
<font color="#00979c">uint8_t</font> <font color="#000000">CSDResponse</font><font color="#000000">[</font><font color="#000000">20</font><font color="#000000">]</font><font color="#000000">;</font>
<font color="#00979c">uint8_t</font> <font color="#000000">count</font><font color="#434f54">,</font> <font color="#000000">index</font><font color="#000000">;</font>
<font color="#00979c">uint32_t</font> <font color="#000000">c_size</font><font color="#000000">;</font>
<font color="#00979c">uint8_t</font> <font color="#000000">c_size_mult</font><font color="#000000">;</font>
<font color="#00979c">uint8_t</font> <font color="#000000">block_len</font><font color="#000000">;</font>
<font color="#000000">mediaInformation</font><font color="#434f54">.</font><font color="#d35400">state</font> <font color="#434f54">=</font> <font color="#000000">SD_STATE_NOT_INITIALIZED</font><font color="#000000">;</font>
<font color="#000000">mediaInformation</font><font color="#434f54">.</font><font color="#000000">errorCode</font> <font color="#434f54">=</font> <font color="#000000">MEDIA_NO_ERROR</font><font color="#000000">;</font>
<font color="#000000">mediaInformation</font><font color="#434f54">.</font><font color="#000000">finalLBA</font> <font color="#434f54">=</font> <font color="#000000">0x00000000</font><font color="#000000">;</font>
<font color="#000000">mediaInformation</font><font color="#434f54">.</font><font color="#000000">gSDMode</font> <font color="#434f54">=</font> <font color="#000000">SD_MODE_NORMAL</font><font color="#000000">;</font>
<font color="#000000">SD_SPI_ChipDeselect</font><font color="#000000">(</font><font color="#000000">)</font><font color="#000000">;</font>
<font color="#434f54">//MMC media powers up in the open-drain mode and cannot handle a clock faster</font>
<font color="#434f54">//than 400kHz. Initialize SPI port to <= 400kHz</font>
<font color="#5e6d03">if</font><font color="#000000">(</font> <font color="#000000">SD_SPI_master_open</font><font color="#000000">(</font><font color="#000000">SDSLOW</font><font color="#000000">)</font> <font color="#434f54">==</font> <font color="#00979c">false</font> <font color="#000000">)</font>
<font color="#000000">{</font>
<font color="#5e6d03">return</font> <font color="#00979c">false</font><font color="#000000">;</font>
<font color="#000000">}</font>
<font color="#434f54">//Media wants the longer of: Vdd ramp time, 1 ms fixed delay, or 74+ clock pulses.</font>
<font color="#434f54">//According to spec, CS should be high during the 74+ clock pulses.</font>
<font color="#434f54">//In practice it is preferable to wait much longer than 1ms, in case of</font>
<font color="#434f54">//contact bounce, or incomplete mechanical insertion (by the time we start</font>
<font color="#434f54">//accessing the media). </font>
<font color="#000000">SDSPI_DelayMilliseconds</font><font color="#000000">(</font><font color="#000000">SD_SPI_STARTUP_DELAY_MS</font><font color="#000000">)</font><font color="#000000">;</font>
<font color="#434f54">// Send CMD0 (with CS = 0) to reset the media and put SD cards into SPI mode.</font>
<font color="#000000">timeout</font> <font color="#434f54">=</font> <font color="#000000">100</font><font color="#000000">;</font>
<font color="#5e6d03">do</font>
<font color="#000000">{</font>
<font color="#434f54">//Toggle chip select, to make media abandon whatever it may have been doing</font>
<font color="#434f54">//before. This ensures the CMD0 is sent freshly after CS is asserted low,</font>
<font color="#434f54">//minimizing risk of SPI clock pulse master/slave synchronization problems, </font>
<font color="#434f54">//due to possible application noise on the SCK line.</font>
<font color="#000000">SD_SPI_ChipDeselect</font><font color="#000000">(</font><font color="#000000">)</font><font color="#000000">;</font>
<font color="#000000">(</font><font color="#00979c">void</font><font color="#000000">)</font><font color="#000000">SD_SPI_exchangeByte</font><font color="#000000">(</font><font color="#000000">0xFF</font><font color="#000000">)</font><font color="#000000">;</font> <font color="#434f54">//Send some "extraneous" clock pulses. If a previous</font>
<font color="#434f54">//command was terminated before it completed normally,</font>
<font color="#434f54">//the card might not have received the required clocking</font>
<font color="#434f54">//following the transfer.</font>
<font color="#000000">SD_SPI_ChipSelect</font><font color="#000000">(</font><font color="#000000">)</font><font color="#000000">;</font>
<font color="#000000">timeout</font><font color="#434f54">--</font><font color="#000000">;</font>
<font color="#434f54">//Send CMD0 to software reset the device</font>
<font color="#d35400">response</font> <font color="#434f54">=</font> <font color="#000000">SD_SendCmd</font><font color="#000000">(</font><font color="#000000">SD_GO_IDLE_STATE</font><font color="#434f54">,</font> <font color="#000000">0x0</font><font color="#000000">)</font><font color="#000000">;</font>
<font color="#000000">}</font><font color="#5e6d03">while</font><font color="#000000">(</font><font color="#000000">(</font><font color="#d35400">response</font><font color="#434f54">.</font><font color="#000000">r1</font><font color="#434f54">.</font><font color="#000000">_byte</font> <font color="#434f54">!=</font> <font color="#000000">0x01</font><font color="#000000">)</font> <font color="#434f54">&&</font> <font color="#000000">(</font><font color="#000000">timeout</font> <font color="#434f54">!=</font> <font color="#000000">0</font><font color="#000000">)</font><font color="#000000">)</font><font color="#000000">;</font>
<font color="#434f54">//Check if all attempts failed and we timed out. Normally, this won't happen,</font>
<font color="#434f54">//unless maybe the SD card was busy, because it was previously performing a</font>
<font color="#434f54">//read or write operation, when it was interrupted by the microcontroller getting</font>
<font color="#434f54">//reset or power cycled, without also resetting or power cycling the SD card.</font>
<font color="#434f54">//In this case, the SD card may still be busy (ex: trying to respond with the </font>
<font color="#434f54">//read request data), and may not be ready to process CMD0. In this case,</font>
<font color="#434f54">//we can try to recover by issuing CMD12 (STOP_TRANSMISSION).</font>
<font color="#5e6d03">if</font><font color="#000000">(</font><font color="#000000">timeout</font> <font color="#434f54">==</font> <font color="#000000">0</font><font color="#000000">)</font>
<font color="#000000">{</font>
<font color="#000000">SD_SPI_ChipDeselect</font><font color="#000000">(</font><font color="#000000">)</font><font color="#000000">;</font>
<font color="#000000">(</font><font color="#00979c">void</font><font color="#000000">)</font><font color="#000000">SD_SPI_exchangeByte</font><font color="#000000">(</font><font color="#000000">0xFF</font><font color="#000000">)</font><font color="#000000">;</font> <font color="#434f54">//Send some "extraneous" clock pulses. If a previous</font>
<font color="#434f54">//command was terminated before it completed normally,</font>
<font color="#434f54">//the card might not have received the required clocking</font>
<font color="#434f54">//following the transfer.</font>
<font color="#000000">SD_SPI_ChipSelect</font><font color="#000000">(</font><font color="#000000">)</font><font color="#000000">;</font>
<font color="#434f54">//Send CMD12, to stop any read/write transaction that may have been in progress</font>
<font color="#000000">(</font><font color="#00979c">void</font><font color="#000000">)</font><font color="#000000">SD_SendCmd</font><font color="#000000">(</font><font color="#000000">SD_STOP_TRANSMISSION</font><font color="#434f54">,</font> <font color="#000000">0x0</font><font color="#000000">)</font><font color="#000000">;</font> <font color="#434f54">//Blocks until SD card signals non-busy</font>
<font color="#434f54">//Now retry to send send CMD0 to perform software reset on the media</font>
<font color="#d35400">response</font> <font color="#434f54">=</font> <font color="#000000">SD_SendCmd</font><font color="#000000">(</font><font color="#000000">SD_GO_IDLE_STATE</font><font color="#434f54">,</font> <font color="#000000">0x0</font><font color="#000000">)</font><font color="#000000">;</font>
<font color="#5e6d03">if</font><font color="#000000">(</font><font color="#d35400">response</font><font color="#434f54">.</font><font color="#000000">r1</font><font color="#434f54">.</font><font color="#000000">_byte</font> <font color="#434f54">!=</font> <font color="#000000">0x01</font><font color="#000000">)</font> <font color="#434f54">//Check if card in idle state now.</font>
<font color="#000000">{</font>
<font color="#434f54">//Card failed to process CMD0 yet again. At this point, the proper thing</font>
<font color="#434f54">//to do would be to power cycle the card and retry, if the host </font>
<font color="#434f54">//circuitry supports disconnecting the SD card power. Since the</font>
<font color="#434f54">//SD/MMC PICtail+ doesn't support software controlled power removal</font>
<font color="#434f54">//of the SD card, there is nothing that can be done with this hardware.</font>
<font color="#434f54">//Therefore, we just give up now. The user needs to physically </font>
<font color="#434f54">//power cycle the media and/or the whole board.</font>
<font color="#000000">mediaInformation</font><font color="#434f54">.</font><font color="#000000">errorCode</font> <font color="#434f54">=</font> <font color="#000000">MEDIA_CANNOT_INITIALIZE</font><font color="#000000">;</font>
<font color="#000000">SD_SPI_ChipDeselect</font><font color="#000000">(</font><font color="#000000">)</font><font color="#000000">;</font>
<font color="#000000">SD_SPI_close</font><font color="#000000">(</font><font color="#000000">)</font><font color="#000000">;</font>
<font color="#5e6d03">return</font> <font color="#00979c">false</font><font color="#000000">;</font>
<font color="#000000">}</font>
<font color="#5e6d03">else</font>
<font color="#000000">{</font>
<font color="#434f54">//Card successfully processed CMD0 and is now in the idle state.</font>
<font color="#000000">}</font>
<font color="#000000">}</font><font color="#434f54">//if(timeout == 0) [for the CMD0 transmit loop]</font>
<font color="#5e6d03">else</font>
<font color="#000000">{</font>
<font color="#000000">}</font>
<font color="#434f54">//Send CMD8 (SEND_IF_COND) to specify/request the SD card interface condition (ex: indicate what voltage the host runs at).</font>
<font color="#434f54">//0x000001AA --> VHS = 0001b = 2.7V to 3.6V. The 0xAA LSB is the check pattern, and is arbitrary, but 0xAA is recommended (good blend of 0's and '1's).</font>
<font color="#434f54">//The SD card has to echo back the check pattern correctly however, in the R7 response.</font>
<font color="#434f54">//If the SD card doesn't support the operating voltage range of the host, then it may not respond.</font>
<font color="#434f54">//If it does support the range, it will respond with a type R7 response packet (6 bytes/48 bits). </font>
<font color="#434f54">//Additionally, if the SD card is MMC or SD card v1.x spec device, then it may respond with</font>
<font color="#434f54">//invalid command. If it is a v2.0 spec SD card, then it is mandatory that the card respond</font>
<font color="#434f54">//to CMD8.</font>
<font color="#d35400">response</font> <font color="#434f54">=</font> <font color="#000000">SD_SendCmd</font><font color="#000000">(</font><font color="#000000">SD_SEND_IF_COND</font><font color="#434f54">,</font> <font color="#000000">0x1AA</font><font color="#000000">)</font><font color="#000000">;</font> <font color="#434f54">//Note: If changing "0x1AA", CRC value in table must also change.</font>
<font color="#5e6d03">if</font><font color="#000000">(</font><font color="#000000">(</font><font color="#000000">(</font><font color="#d35400">response</font><font color="#434f54">.</font><font color="#000000">r7</font><font color="#434f54">.</font><font color="#000000">bytewise</font><font color="#434f54">.</font><font color="#000000">argument</font><font color="#434f54">.</font><font color="#000000">_returnVal</font> <font color="#434f54">&</font> <font color="#000000">0xFFF</font><font color="#000000">)</font> <font color="#434f54">==</font> <font color="#000000">0x1AA</font><font color="#000000">)</font> <font color="#434f54">&&</font> <font color="#000000">(</font><font color="#434f54">!</font><font color="#d35400">response</font><font color="#434f54">.</font><font color="#000000">r7</font><font color="#434f54">.</font><font color="#000000">bitwise</font><font color="#434f54">.</font><font color="#d35400">bits</font><font color="#434f54">.</font><font color="#000000">ILLEGAL_CMD</font><font color="#000000">)</font><font color="#000000">)</font>
<font color="#000000">{</font>
<font color="#434f54">//If we get to here, the device supported the CMD8 command and didn't complain about our host</font>
<font color="#434f54">//voltage range.</font>
<font color="#434f54">//Most likely this means it is either a v2.0 spec standard or high capacity SD card (SDHC)</font>
<font color="#434f54">//Send CMD58 (Read OCR [operating conditions register]). Response type is R3, which has 5 bytes.</font>
<font color="#434f54">//uint8_t 4 = normal R1 response uint8_t, bytes 3-0 are = OCR register value.</font>
<font color="#d35400">response</font> <font color="#434f54">=</font> <font color="#000000">SD_SendCmd</font><font color="#000000">(</font><font color="#000000">SD_READ_OCR</font><font color="#434f54">,</font> <font color="#000000">0x0</font><font color="#000000">)</font><font color="#000000">;</font>
<font color="#434f54">//Now that we have the OCR register value in the response packet, we could parse</font>
<font color="#434f54">//the register contents and learn what voltage the SD card wants to run at.</font>
<font color="#434f54">//If our host circuitry has variable power supply capability, it could </font>
<font color="#434f54">//theoretically adjust the SD card Vdd to the minimum of the OCR to save power.</font>
<font color="#434f54">//Now send CMD55/ACMD41 in a loop, until the card is finished with its internal initialization.</font>
<font color="#434f54">//Note: SD card specs recommend >= 1 second timeout while waiting for ACMD41 to signal non-busy.</font>
<font color="#5e6d03">for</font><font color="#000000">(</font><font color="#000000">timeout</font> <font color="#434f54">=</font> <font color="#000000">0</font><font color="#000000">;</font> <font color="#000000">timeout</font> <font color="#434f54"><</font> <font color="#000000">0xFFFF</font><font color="#000000">;</font> <font color="#000000">timeout</font><font color="#434f54">++</font><font color="#000000">)</font>
<font color="#000000">{</font>
<font color="#434f54">//Send CMD55 (lets SD card know that the next command is application specific (going to be ACMD41)).</font>
<font color="#000000">(</font><font color="#00979c">void</font><font color="#000000">)</font><font color="#000000">SD_SendCmd</font><font color="#000000">(</font><font color="#000000">SD_APP_CMD</font><font color="#434f54">,</font> <font color="#000000">0x00000000</font><font color="#000000">)</font><font color="#000000">;</font>
<font color="#434f54">//Send ACMD41. This is to check if the SD card is finished booting up/ready for full frequency and all</font>
<font color="#434f54">//further commands. Response is R3 type (6 bytes/48 bits, middle four bytes contain potentially useful data).</font>
<font color="#434f54">//Note: When sending ACMD41, the HCS bit is bit 30, and must be = 1 to tell SD card the host supports SDHC</font>
<font color="#d35400">response</font> <font color="#434f54">=</font> <font color="#000000">SD_SendCmd</font><font color="#000000">(</font><font color="#000000">SD_SD_SEND_OP_COND</font><font color="#434f54">,</font><font color="#000000">0x40000000</font><font color="#000000">)</font><font color="#000000">;</font> <font color="#434f54">//bit 30 set</font>
<font color="#434f54">//The R1 response should be = 0x00, meaning the card is now in the "standby" state, instead of</font>
<font color="#434f54">//the "idle" state (which is the default initialization state after CMD0 reset is issued). Once</font>
<font color="#434f54">//in the "standby" state, the SD card is finished with basic initialization and is ready </font>
<font color="#434f54">//for read/write and other commands.</font>
<font color="#5e6d03">if</font><font color="#000000">(</font><font color="#d35400">response</font><font color="#434f54">.</font><font color="#000000">r1</font><font color="#434f54">.</font><font color="#000000">_byte</font> <font color="#434f54">==</font> <font color="#000000">0</font><font color="#000000">)</font>
<font color="#000000">{</font>
<font color="#5e6d03">break</font><font color="#000000">;</font> <font color="#434f54">//Break out of for() loop. Card is finished initializing.</font>
<font color="#000000">}</font>
<font color="#000000">}</font>
<font color="#5e6d03">if</font><font color="#000000">(</font><font color="#000000">timeout</font> <font color="#434f54">>=</font> <font color="#000000">0xFFFF</font><font color="#000000">)</font>
<font color="#000000">{</font>
<font color="#000000">mediaInformation</font><font color="#434f54">.</font><font color="#000000">errorCode</font> <font color="#434f54">=</font> <font color="#000000">MEDIA_CANNOT_INITIALIZE</font><font color="#000000">;</font>
<font color="#000000">}</font>
<font color="#434f54">//Now send CMD58 (Read OCR register). The OCR register contains important</font>
<font color="#434f54">//info we will want to know about the card (ex: standard capacity vs. SDHC).</font>
<font color="#d35400">response</font> <font color="#434f54">=</font> <font color="#000000">SD_SendCmd</font><font color="#000000">(</font><font color="#000000">SD_READ_OCR</font><font color="#434f54">,</font> <font color="#000000">0x0</font><font color="#000000">)</font><font color="#000000">;</font>
<font color="#434f54">//Now check the CCS bit (OCR bit 30) in the OCR register, which is in our response packet.</font>
<font color="#434f54">//This will tell us if it is a SD high capacity (SDHC) or standard capacity device.</font>
<font color="#5e6d03">if</font><font color="#000000">(</font><font color="#d35400">response</font><font color="#434f54">.</font><font color="#000000">r7</font><font color="#434f54">.</font><font color="#000000">bytewise</font><font color="#434f54">.</font><font color="#000000">argument</font><font color="#434f54">.</font><font color="#000000">_returnVal</font> <font color="#434f54">&</font> <font color="#000000">0x40000000</font><font color="#000000">)</font> <font color="#434f54">//Note the HCS bit is only valid when the busy bit is also set (indicating device ready).</font>
<font color="#000000">{</font>
<font color="#000000">mediaInformation</font><font color="#434f54">.</font><font color="#000000">gSDMode</font> <font color="#434f54">=</font> <font color="#000000">SD_MODE_HC</font><font color="#000000">;</font>
<font color="#000000">}</font>
<font color="#5e6d03">else</font>
<font color="#000000">{</font>
<font color="#000000">mediaInformation</font><font color="#434f54">.</font><font color="#000000">gSDMode</font> <font color="#434f54">=</font> <font color="#000000">SD_MODE_NORMAL</font><font color="#000000">;</font>
<font color="#000000">}</font>
<font color="#434f54">//SD Card should now be finished with initialization sequence. Device should be ready</font>
<font color="#434f54">//for read/write commands.</font>
<font color="#000000">}</font><font color="#434f54">//if(((response.r7.bytewise._returnVal & 0xFFF) == 0x1AA) && (!response.r7.bitwise.bits.ILLEGAL_CMD))</font>
<font color="#5e6d03">else</font>
<font color="#000000">{</font>
<font color="#434f54">//The CMD8 wasn't supported. This means the card is not a v2.0 card.</font>
<font color="#434f54">//Presumably the card is v1.x device, standard capacity (not SDHC).</font>
<font color="#95a5a6">/* Need to delay a bit between last command and this command. */</font>
<font color="#000000">SDSPI_DelayMilliseconds</font><font color="#000000">(</font><font color="#000000">SD_SPI_COMMAND_WAIT_MS</font><font color="#000000">)</font><font color="#000000">;</font>
<font color="#000000">SD_SPI_ChipSelect</font><font color="#000000">(</font><font color="#000000">)</font><font color="#000000">;</font> <font color="#434f54">// select the device</font>
<font color="#434f54">//The CMD8 wasn't supported. This means the card is definitely not a v2.0 SDHC card.</font>
<font color="#000000">mediaInformation</font><font color="#434f54">.</font><font color="#000000">gSDMode</font> <font color="#434f54">=</font> <font color="#000000">SD_MODE_NORMAL</font><font color="#000000">;</font>
<font color="#434f54">// According to the spec CMD1 must be repeated until the card is fully initialized</font>
<font color="#000000">timeout</font> <font color="#434f54">=</font> <font color="#000000">0x1FFF</font><font color="#000000">;</font>
<font color="#5e6d03">do</font>
<font color="#000000">{</font>
<font color="#434f54">//Send CMD1 to initialize the media.</font>
<font color="#d35400">response</font> <font color="#434f54">=</font> <font color="#000000">SD_SendCmd</font><font color="#000000">(</font><font color="#000000">SD_SEND_OP_COND</font><font color="#434f54">,</font> <font color="#000000">0x00000000</font><font color="#000000">)</font><font color="#000000">;</font> <font color="#434f54">//When argument is 0x00000000, this queries MMC cards for operating voltage range</font>
<font color="#000000">timeout</font><font color="#434f54">--</font><font color="#000000">;</font>
<font color="#000000">}</font><font color="#5e6d03">while</font><font color="#000000">(</font><font color="#000000">(</font><font color="#d35400">response</font><font color="#434f54">.</font><font color="#000000">r1</font><font color="#434f54">.</font><font color="#000000">_byte</font> <font color="#434f54">!=</font> <font color="#000000">0x00</font><font color="#000000">)</font> <font color="#434f54">&&</font> <font color="#000000">(</font><font color="#000000">timeout</font> <font color="#434f54">!=</font> <font color="#000000">0</font><font color="#000000">)</font><font color="#000000">)</font><font color="#000000">;</font>
<font color="#434f54">// see if it failed</font>
<font color="#5e6d03">if</font><font color="#000000">(</font><font color="#000000">timeout</font> <font color="#434f54">==</font> <font color="#000000">0</font><font color="#000000">)</font>
<font color="#000000">{</font>
<font color="#000000">mediaInformation</font><font color="#434f54">.</font><font color="#000000">errorCode</font> <font color="#434f54">=</font> <font color="#000000">MEDIA_CANNOT_INITIALIZE</font><font color="#000000">;</font>
<font color="#000000">SD_SPI_ChipDeselect</font><font color="#000000">(</font><font color="#000000">)</font><font color="#000000">;</font> <font color="#434f54">// deselect the devices</font>
<font color="#000000">}</font>
<font color="#5e6d03">else</font>
<font color="#000000">{</font>
<font color="#434f54">//Set read/write block length to 512 bytes. Note: commented out since</font>
<font color="#434f54">//this theoretically isn't necessary, since all cards v1 and v2 are </font>
<font color="#434f54">//required to support 512 byte block size, and this is supposed to be</font>
<font color="#434f54">//the default size selected on cards that support other sizes as well.</font>
<font color="#434f54">//response = SD_SendCmd(SET_BLOCKLEN, 0x00000200); //Set read/write block length to 512 bytes</font>
<font color="#000000">}</font>
<font color="#000000">}</font>
<font color="#434f54">//Temporarily deselect device</font>
<font color="#000000">SD_SPI_ChipDeselect</font><font color="#000000">(</font><font color="#000000">)</font><font color="#000000">;</font>
<font color="#000000">SD_SPI_close</font><font color="#000000">(</font><font color="#000000">)</font><font color="#000000">;</font>
<font color="#5e6d03">if</font><font color="#000000">(</font><font color="#000000">SD_SPI_master_open</font><font color="#000000">(</font><font color="#000000">SDFAST</font><font color="#000000">)</font> <font color="#434f54">==</font> <font color="#00979c">false</font><font color="#000000">)</font>
<font color="#000000">{</font>
<font color="#5e6d03">return</font> <font color="#00979c">false</font><font color="#000000">;</font>
<font color="#000000">}</font>
<font color="#000000">SD_SPI_ChipSelect</font><font color="#000000">(</font><font color="#000000">)</font><font color="#000000">;</font>
<font color="#95a5a6">/* Send the CMD9 to read the CSD register */</font>
<font color="#000000">timeout</font> <font color="#434f54">=</font> <font color="#000000">SD_NCR_TIMEOUT</font><font color="#000000">;</font>
<font color="#5e6d03">do</font>
<font color="#000000">{</font>
<font color="#434f54">//Send CMD9: Read CSD data structure.</font>
<font color="#d35400">response</font> <font color="#434f54">=</font> <font color="#000000">SD_SendCmd</font><font color="#000000">(</font><font color="#000000">SD_SEND_CSD</font><font color="#434f54">,</font> <font color="#000000">0x00</font><font color="#000000">)</font><font color="#000000">;</font>
<font color="#000000">timeout</font><font color="#434f54">--</font><font color="#000000">;</font>
<font color="#000000">}</font><font color="#5e6d03">while</font><font color="#000000">(</font><font color="#000000">(</font><font color="#d35400">response</font><font color="#434f54">.</font><font color="#000000">r1</font><font color="#434f54">.</font><font color="#000000">_byte</font> <font color="#434f54">!=</font> <font color="#000000">0x00</font><font color="#000000">)</font> <font color="#434f54">&&</font> <font color="#000000">(</font><font color="#000000">timeout</font> <font color="#434f54">!=</font> <font color="#000000">0</font><font color="#000000">)</font><font color="#000000">)</font><font color="#000000">;</font>
<font color="#5e6d03">if</font><font color="#000000">(</font><font color="#000000">timeout</font> <font color="#434f54">==</font> <font color="#000000">0x00</font><font color="#000000">)</font>
<font color="#000000">{</font>
<font color="#434f54">//Media failed to respond to the read CSD register operation. </font>
<font color="#000000">mediaInformation</font><font color="#434f54">.</font><font color="#000000">errorCode</font> <font color="#434f54">=</font> <font color="#000000">MEDIA_CANNOT_INITIALIZE</font><font color="#000000">;</font>
<font color="#000000">SD_SPI_ChipDeselect</font><font color="#000000">(</font><font color="#000000">)</font><font color="#000000">;</font>
<font color="#000000">SD_SPI_close</font><font color="#000000">(</font><font color="#000000">)</font><font color="#000000">;</font>
<font color="#5e6d03">return</font> <font color="#00979c">false</font><font color="#000000">;</font>
<font color="#000000">}</font>
<font color="#95a5a6">/* According to the simplified spec, section 7.2.6, the card will respond</font>
<font color="#95a5a6"> with a standard response token, followed by a data block of 16 bytes</font>
<font color="#95a5a6"> suffixed with a 16-bit CRC.*/</font>
<font color="#000000">index</font> <font color="#434f54">=</font> <font color="#000000">0</font><font color="#000000">;</font>
<font color="#5e6d03">for</font> <font color="#000000">(</font><font color="#000000">count</font> <font color="#434f54">=</font> <font color="#000000">0</font><font color="#000000">;</font> <font color="#000000">count</font> <font color="#434f54"><</font> <font color="#000000">20u</font><font color="#000000">;</font> <font color="#000000">count</font> <font color="#434f54">++</font><font color="#000000">)</font>
<font color="#000000">{</font>
<font color="#000000">CSDResponse</font><font color="#000000">[</font><font color="#000000">index</font><font color="#000000">]</font> <font color="#434f54">=</font> <font color="#000000">SD_SPI_exchangeByte</font><font color="#000000">(</font><font color="#000000">0xFF</font><font color="#000000">)</font><font color="#000000">;</font>
<font color="#000000">index</font><font color="#434f54">++</font><font color="#000000">;</font>
<font color="#95a5a6">/* Hopefully the first byte is the datatoken, however, some cards do</font>
<font color="#95a5a6"> not send the response token before the CSD register.*/</font>
<font color="#5e6d03">if</font><font color="#000000">(</font><font color="#000000">(</font><font color="#000000">count</font> <font color="#434f54">==</font> <font color="#000000">0</font><font color="#000000">)</font> <font color="#434f54">&&</font> <font color="#000000">(</font><font color="#000000">CSDResponse</font><font color="#000000">[</font><font color="#000000">0</font><font color="#000000">]</font> <font color="#434f54">==</font> <font color="#000000">SD_TOKEN_START</font><font color="#000000">)</font><font color="#000000">)</font>
<font color="#000000">{</font>
<font color="#95a5a6">/* As the first byte was the datatoken, we can drop it. */</font>
<font color="#000000">index</font> <font color="#434f54">=</font> <font color="#000000">0</font><font color="#000000">;</font>
<font color="#000000">}</font>
<font color="#000000">}</font>
<font color="#434f54">//Extract some fields from the response for computing the card capacity.</font>
<font color="#434f54">//Note: The structure format depends on if it is a CSD V1 or V2 device.</font>
<font color="#434f54">//Therefore, need to first determine version of the specs that the card </font>
<font color="#434f54">//is designed for, before interpreting the individual fields.</font>
<font color="#434f54">//-------------------------------------------------------------</font>
<font color="#434f54">//READ_BL_LEN: CSD Structure v1 cards always support 512 uint8_t</font>
<font color="#434f54">//read and write block lengths. Some v1 cards may optionally report</font>
<font color="#434f54">//READ_BL_LEN = 1024 or 2048 bytes (and therefore WRITE_BL_LEN also</font>
<font color="#434f54">//1024 or 2048). However, even on these cards, 512 uint8_t partial reads</font>
<font color="#434f54">//and 512 uint8_t write are required to be supported.</font>
<font color="#434f54">//On CSD structure v2 cards, it is always required that READ_BL_LEN </font>
<font color="#434f54">//(and therefore WRITE_BL_LEN) be 512 bytes, and partial reads and</font>
<font color="#434f54">//writes are not allowed.</font>
<font color="#434f54">//Therefore, all cards support 512 byte reads/writes, but only a subset</font>
<font color="#434f54">//of cards support other sizes. For best compatibility with all cards,</font>
<font color="#434f54">//and the simplest firmware design, it is therefore preferable to </font>
<font color="#434f54">//simply ignore the READ_BL_LEN and WRITE_BL_LEN values altogether,</font>
<font color="#434f54">//and simply hardcode the read/write block size as 512 bytes.</font>
<font color="#434f54">//-------------------------------------------------------------</font>
<font color="#000000">mediaInformation</font><font color="#434f54">.</font><font color="#000000">sectorSize</font> <font color="#434f54">=</font> <font color="#000000">SD_MEDIA_BLOCK_SIZE</font><font color="#000000">;</font>
<font color="#434f54">//Calculate the finalLBA (see SD card physical layer simplified spec 2.0, section 5.3.2).</font>
<font color="#434f54">//In USB mass storage applications, we will need this information to </font>
<font color="#434f54">//correctly respond to SCSI get capacity requests. Note: method of computing </font>
<font color="#434f54">//finalLBA depends on CSD structure spec version (either v1 or v2).</font>
<font color="#5e6d03">if</font><font color="#000000">(</font><font color="#000000">CSDResponse</font><font color="#000000">[</font><font color="#000000">0</font><font color="#000000">]</font> <font color="#434f54">&</font> <font color="#000000">0xC0</font><font color="#000000">)</font> <font color="#434f54">//Check CSD_STRUCTURE field for v2+ struct device</font>
<font color="#000000">{</font>
<font color="#434f54">//Must be a v2 device (or a reserved higher version, that doesn't currently exist)</font>
<font color="#434f54">//Extract the C_SIZE field from the response. It is a 22-bit number in bit position 69:48. This is different from v1. </font>
<font color="#434f54">//It spans bytes 7, 8, and 9 of the response.</font>
<font color="#000000">c_size</font> <font color="#434f54">=</font> <font color="#000000">(</font><font color="#000000">(</font><font color="#000000">(</font><font color="#00979c">uint32_t</font><font color="#000000">)</font><font color="#000000">CSDResponse</font><font color="#000000">[</font><font color="#000000">7</font><font color="#000000">]</font> <font color="#434f54">&</font> <font color="#000000">0x3F</font><font color="#000000">)</font> <font color="#434f54"><<</font> <font color="#000000">16</font><font color="#000000">)</font> <font color="#434f54">|</font> <font color="#000000">(</font><font color="#000000">(</font><font color="#00979c">uint16_t</font><font color="#000000">)</font><font color="#000000">CSDResponse</font><font color="#000000">[</font><font color="#000000">8</font><font color="#000000">]</font> <font color="#434f54"><<</font> <font color="#000000">8</font><font color="#000000">)</font> <font color="#434f54">|</font> <font color="#000000">CSDResponse</font><font color="#000000">[</font><font color="#000000">9</font><font color="#000000">]</font><font color="#000000">;</font>
<font color="#000000">mediaInformation</font><font color="#434f54">.</font><font color="#000000">finalLBA</font> <font color="#434f54">=</font> <font color="#000000">(</font><font color="#000000">(</font><font color="#00979c">uint32_t</font><font color="#000000">)</font><font color="#000000">(</font><font color="#000000">c_size</font> <font color="#434f54">+</font> <font color="#000000">1</font><font color="#000000">)</font> <font color="#434f54">*</font> <font color="#000000">(</font><font color="#00979c">uint16_t</font><font color="#000000">)</font><font color="#000000">(</font><font color="#000000">1024u</font><font color="#000000">)</font><font color="#000000">)</font> <font color="#434f54">-</font> <font color="#000000">1</font><font color="#000000">;</font> <font color="#434f54">//-1 on end is correction factor, since LBA = 0 is valid.</font>
<font color="#000000">}</font>
<font color="#5e6d03">else</font> <font color="#434f54">//if(CSDResponse[0] & 0xC0) //Check CSD_STRUCTURE field for v1 struct device</font>
<font color="#000000">{</font>
<font color="#434f54">//Must be a v1 device.</font>
<font color="#434f54">//Extract the C_SIZE field from the response. It is a 12-bit number in bit position 73:62. </font>
<font color="#434f54">//Although it is only a 12-bit number, it spans bytes 6, 7, and 8, since it isn't byte aligned.</font>
<font color="#000000">c_size</font> <font color="#434f54">=</font> <font color="#000000">(</font><font color="#000000">(</font><font color="#00979c">uint32_t</font><font color="#000000">)</font><font color="#000000">CSDResponse</font><font color="#000000">[</font><font color="#000000">6</font><font color="#000000">]</font> <font color="#434f54"><<</font> <font color="#000000">16</font><font color="#000000">)</font> <font color="#434f54">|</font> <font color="#000000">(</font><font color="#000000">(</font><font color="#00979c">uint16_t</font><font color="#000000">)</font><font color="#000000">CSDResponse</font><font color="#000000">[</font><font color="#000000">7</font><font color="#000000">]</font> <font color="#434f54"><<</font> <font color="#000000">8</font><font color="#000000">)</font> <font color="#434f54">|</font> <font color="#000000">CSDResponse</font><font color="#000000">[</font><font color="#000000">8</font><font color="#000000">]</font><font color="#000000">;</font> <font color="#434f54">//Get the bytes in the correct positions</font>
<font color="#000000">c_size</font> <font color="#434f54">&=</font> <font color="#000000">0x0003FFC0</font><font color="#000000">;</font> <font color="#434f54">//Clear all bits that aren't part of the C_SIZE</font>
<font color="#000000">c_size</font> <font color="#434f54">=</font> <font color="#000000">c_size</font> <font color="#434f54">>></font> <font color="#000000">6</font><font color="#000000">;</font> <font color="#434f54">//Shift value down, so the 12-bit C_SIZE is properly right justified in the uint32_t.</font>
<font color="#434f54">//Extract the C_SIZE_MULT field from the response. It is a 3-bit number in bit position 49:47.</font>
<font color="#000000">c_size_mult</font> <font color="#434f54">=</font> <font color="#000000">(</font><font color="#000000">(</font><font color="#00979c">uint16_t</font><font color="#000000">)</font><font color="#000000">(</font><font color="#000000">(</font><font color="#000000">CSDResponse</font><font color="#000000">[</font><font color="#000000">9</font><font color="#000000">]</font> <font color="#434f54">&</font> <font color="#000000">0x03</font><font color="#000000">)</font> <font color="#434f54"><<</font> <font color="#000000">1</font><font color="#000000">)</font><font color="#000000">)</font> <font color="#434f54">|</font> <font color="#000000">(</font><font color="#000000">(</font><font color="#00979c">uint16_t</font><font color="#000000">)</font><font color="#000000">(</font><font color="#000000">(</font><font color="#000000">CSDResponse</font><font color="#000000">[</font><font color="#000000">10</font><font color="#000000">]</font> <font color="#434f54">&</font> <font color="#000000">0x80</font><font color="#000000">)</font> <font color="#434f54">>></font> <font color="#000000">7</font><font color="#000000">)</font><font color="#000000">)</font><font color="#000000">;</font>
<font color="#434f54">//Extract the BLOCK_LEN field from the response. It is a 4-bit number in bit position 83:80.</font>
<font color="#000000">block_len</font> <font color="#434f54">=</font> <font color="#000000">CSDResponse</font><font color="#000000">[</font><font color="#000000">5</font><font color="#000000">]</font> <font color="#434f54">&</font> <font color="#000000">0x0F</font><font color="#000000">;</font>
<font color="#000000">block_len</font> <font color="#434f54">=</font> <font color="#000000">1</font> <font color="#434f54"><<</font> <font color="#000000">(</font><font color="#000000">block_len</font> <font color="#434f54">-</font> <font color="#000000">9</font><font color="#000000">)</font><font color="#000000">;</font> <font color="#434f54">//-9 because we report the size in sectors of 512 bytes each</font>
<font color="#434f54">//Calculate the finalLBA (see SD card physical layer simplified spec 2.0, section 5.3.2).</font>
<font color="#434f54">//In USB mass storage applications, we will need this information to </font>
<font color="#434f54">//correctly respond to SCSI get capacity requests (which will cause SD_CapacityRead() to get called).</font>
<font color="#000000">mediaInformation</font><font color="#434f54">.</font><font color="#000000">finalLBA</font> <font color="#434f54">=</font> <font color="#000000">(</font><font color="#000000">(</font><font color="#00979c">uint32_t</font><font color="#000000">)</font><font color="#000000">(</font><font color="#000000">c_size</font> <font color="#434f54">+</font> <font color="#000000">1</font><font color="#000000">)</font> <font color="#434f54">*</font> <font color="#000000">(</font><font color="#00979c">uint16_t</font><font color="#000000">)</font><font color="#000000">(</font><font color="#000000">(</font><font color="#00979c">uint16_t</font><font color="#000000">)</font><font color="#000000">1</font> <font color="#434f54"><<</font> <font color="#000000">(</font><font color="#000000">c_size_mult</font> <font color="#434f54">+</font> <font color="#000000">2</font><font color="#000000">)</font><font color="#000000">)</font> <font color="#434f54">*</font> <font color="#000000">block_len</font><font color="#000000">)</font> <font color="#434f54">-</font> <font color="#000000">1</font><font color="#000000">;</font> <font color="#434f54">//-1 on end is correction factor, since LBA = 0 is valid. </font>
<font color="#000000">}</font>
<font color="#434f54">//Turn off CRC7 if we can, might be an invalid cmd on some cards (CMD59)</font>
<font color="#434f54">//Note: POR default for the media is normally with CRC checking off in SPI </font>
<font color="#434f54">//mode anyway, so this is typically redundant.</font>
<font color="#000000">(</font><font color="#00979c">void</font><font color="#000000">)</font><font color="#000000">SD_SendCmd</font><font color="#000000">(</font><font color="#000000">SD_CRC_ON_OFF</font><font color="#434f54">,</font> <font color="#000000">0x0</font><font color="#000000">)</font><font color="#000000">;</font>
<font color="#434f54">//Now set the block length to media sector size. It should be already set to this.</font>
<font color="#000000">(</font><font color="#00979c">void</font><font color="#000000">)</font><font color="#000000">SD_SendCmd</font><font color="#000000">(</font><font color="#000000">SD_SET_BLOCK_LENGTH</font> <font color="#434f54">,</font> <font color="#000000">mediaInformation</font><font color="#434f54">.</font><font color="#000000">sectorSize</font><font color="#000000">)</font><font color="#000000">;</font>
<font color="#434f54">//Deselect media while not actively accessing the card.</font>
<font color="#000000">SD_SPI_ChipDeselect</font><font color="#000000">(</font><font color="#000000">)</font><font color="#000000">;</font>
<font color="#434f54">//Finished with the SD card initialization sequence.</font>
<font color="#5e6d03">if</font><font color="#000000">(</font><font color="#000000">mediaInformation</font><font color="#434f54">.</font><font color="#000000">errorCode</font> <font color="#434f54">==</font> <font color="#000000">MEDIA_NO_ERROR</font><font color="#000000">)</font>
<font color="#000000">{</font>
<font color="#000000">mediaInformation</font><font color="#434f54">.</font><font color="#d35400">state</font> <font color="#434f54">=</font> <font color="#000000">SD_STATE_READY_FOR_COMMAND</font><font color="#000000">;</font>
<font color="#000000">SD_SPI_close</font><font color="#000000">(</font><font color="#000000">)</font><font color="#000000">;</font>
<font color="#5e6d03">return</font> <font color="#00979c">true</font><font color="#000000">;</font>
<font color="#000000">}</font>
<font color="#000000">SD_SPI_close</font><font color="#000000">(</font><font color="#000000">)</font><font color="#000000">;</font>
<font color="#5e6d03">return</font> <font color="#00979c">false</font><font color="#000000">;</font>
<font color="#000000">}</font>
<font color="#00979c">bool</font> <font color="#000000">SDSPI_IsMediaInitialized</font><font color="#000000">(</font><font color="#00979c">void</font><font color="#000000">)</font>
<font color="#000000">{</font>
<font color="#5e6d03">return</font> <font color="#000000">(</font><font color="#000000">mediaInformation</font><font color="#434f54">.</font><font color="#d35400">state</font> <font color="#434f54">!=</font> <font color="#000000">SD_STATE_NOT_INITIALIZED</font><font color="#000000">)</font><font color="#000000">;</font>
<font color="#000000">}</font>
<font color="#00979c">bool</font> <font color="#000000">SDSPI_IsWriteProtected</font><font color="#000000">(</font><font color="#00979c">void</font><font color="#000000">)</font>
<font color="#000000">{</font>
<font color="#5e6d03">return</font> <font color="#000000">SD_SPI_GetWriteProtect</font><font color="#000000">(</font><font color="#000000">)</font> <font color="#434f54">?</font> <font color="#00979c">true</font> <font color="#434f54">:</font> <font color="#00979c">false</font><font color="#000000">;</font>
<font color="#000000">}</font>
<font color="#00979c">uint16_t</font> <font color="#000000">SDSPI_GetSectorSize</font><font color="#000000">(</font><font color="#00979c">void</font><font color="#000000">)</font>
<font color="#000000">{</font>
<font color="#5e6d03">return</font> <font color="#000000">mediaInformation</font><font color="#434f54">.</font><font color="#000000">sectorSize</font><font color="#000000">;</font>
<font color="#000000">}</font>
<font color="#00979c">uint32_t</font> <font color="#000000">SDSPI_GetSectorCount</font><font color="#000000">(</font><font color="#00979c">void</font><font color="#000000">)</font>
<font color="#000000">{</font>
<font color="#5e6d03">return</font> <font color="#000000">(</font><font color="#000000">mediaInformation</font><font color="#434f54">.</font><font color="#000000">finalLBA</font><font color="#000000">)</font><font color="#000000">;</font>
<font color="#000000">}</font>
<font color="#00979c">bool</font> <font color="#000000">SDSPI_SectorRead</font><font color="#000000">(</font><font color="#00979c">uint32_t</font> <font color="#000000">sector_address</font><font color="#434f54">,</font> <font color="#00979c">uint8_t</font><font color="#434f54">*</font> <font color="#d35400">buffer</font><font color="#434f54">,</font> <font color="#00979c">uint16_t</font> <font color="#000000">sector_count</font><font color="#000000">)</font>
<font color="#000000">{</font>
<font color="#00979c">struct</font> <font color="#000000">SD_ASYNC_IO</font> <font color="#000000">info</font><font color="#000000">;</font>
<font color="#00979c">uint8_t</font> <font color="#d35400">status</font><font color="#000000">;</font>
<font color="#00979c">bool</font> <font color="#000000">result</font> <font color="#434f54">=</font> <font color="#00979c">false</font><font color="#000000">;</font>
<font color="#00979c">uint16_t</font> <font color="#000000">i</font><font color="#000000">;</font>
<font color="#5e6d03">for</font><font color="#000000">(</font><font color="#000000">i</font><font color="#434f54">=</font><font color="#000000">0</font><font color="#000000">;</font> <font color="#000000">i</font><font color="#434f54"><</font><font color="#000000">sector_count</font><font color="#000000">;</font> <font color="#000000">i</font><font color="#434f54">++</font><font color="#000000">)</font>
<font color="#000000">{</font>
<font color="#434f54">//Initialize info structure for using the SD_SPI_AsyncReadTasks() function.</font>
<font color="#000000">info</font><font color="#434f54">.</font><font color="#000000">wNumBytes</font> <font color="#434f54">=</font> <font color="#000000">1</font> <font color="#434f54"><<</font> <font color="#000000">9</font><font color="#000000">;</font> <font color="#434f54">//Equivalent to multiply by 512</font>
<font color="#000000">info</font><font color="#434f54">.</font><font color="#000000">dwBytesRemaining</font> <font color="#434f54">=</font> <font color="#000000">1</font> <font color="#434f54"><<</font> <font color="#000000">9</font><font color="#000000">;</font> <font color="#434f54">//Equivalent to multiply by 512</font>
<font color="#000000">info</font><font color="#434f54">.</font><font color="#000000">pBuffer</font> <font color="#434f54">=</font> <font color="#d35400">buffer</font> <font color="#434f54">+</font> <font color="#000000">(</font><font color="#000000">i</font> <font color="#434f54"><<</font> <font color="#000000">9</font><font color="#000000">)</font><font color="#000000">;</font> <font color="#434f54">//Equivalent to multiply by 512</font>
<font color="#000000">info</font><font color="#434f54">.</font><font color="#000000">dwAddress</font> <font color="#434f54">=</font> <font color="#000000">sector_address</font> <font color="#434f54">+</font> <font color="#000000">i</font><font color="#000000">;</font>
<font color="#000000">info</font><font color="#434f54">.</font><font color="#000000">bStateVariable</font> <font color="#434f54">=</font> <font color="#000000">SD_ASYNC_READ_QUEUED</font><font color="#000000">;</font>
<font color="#5e6d03">if</font><font color="#000000">(</font> <font color="#000000">SD_SPI_master_open</font><font color="#000000">(</font><font color="#000000">SDFAST</font><font color="#000000">)</font> <font color="#434f54">==</font> <font color="#00979c">false</font> <font color="#000000">)</font>
<font color="#000000">{</font>
<font color="#5e6d03">return</font> <font color="#00979c">false</font><font color="#000000">;</font>
<font color="#000000">}</font>
<font color="#000000">SD_SPI_ChipSelect</font><font color="#000000">(</font><font color="#000000">)</font><font color="#000000">;</font>
<font color="#5e6d03">while</font><font color="#000000">(</font><font color="#000000">1</font><font color="#000000">)</font>
<font color="#000000">{</font>
<font color="#d35400">status</font> <font color="#434f54">=</font> <font color="#000000">SD_SPI_AsyncReadTasks</font><font color="#000000">(</font><font color="#434f54">&</font><font color="#000000">info</font><font color="#000000">)</font><font color="#000000">;</font>
<font color="#5e6d03">if</font><font color="#000000">(</font><font color="#d35400">status</font> <font color="#434f54">==</font> <font color="#000000">SD_ASYNC_READ_COMPLETE</font><font color="#000000">)</font>
<font color="#000000">{</font>
<font color="#000000">result</font> <font color="#434f54">=</font> <font color="#00979c">true</font><font color="#000000">;</font>
<font color="#5e6d03">break</font><font color="#000000">;</font>
<font color="#000000">}</font>
<font color="#5e6d03">else</font> <font color="#5e6d03">if</font><font color="#000000">(</font><font color="#d35400">status</font> <font color="#434f54">==</font> <font color="#000000">SD_ASYNC_READ_ERROR</font><font color="#000000">)</font>
<font color="#000000">{</font>
<font color="#000000">result</font> <font color="#434f54">=</font> <font color="#00979c">false</font><font color="#000000">;</font>
<font color="#5e6d03">break</font><font color="#000000">;</font>
<font color="#000000">}</font>
<font color="#000000">}</font>
<font color="#000000">SD_SPI_ChipDeselect</font><font color="#000000">(</font><font color="#000000">)</font><font color="#000000">;</font>
<font color="#000000">SD_SPI_close</font><font color="#000000">(</font><font color="#000000">)</font><font color="#000000">;</font>
<font color="#000000">}</font>
<font color="#5e6d03">return</font> <font color="#000000">result</font><font color="#000000">;</font>
<font color="#000000">}</font>
<font color="#00979c">bool</font> <font color="#000000">SDSPI_SectorWrite</font><font color="#000000">(</font><font color="#00979c">uint32_t</font> <font color="#000000">sector_address</font><font color="#434f54">,</font> <font color="#00979c">const</font> <font color="#00979c">uint8_t</font><font color="#434f54">*</font> <font color="#d35400">buffer</font><font color="#434f54">,</font> <font color="#00979c">uint16_t</font> <font color="#000000">sector_count</font><font color="#000000">)</font>
<font color="#000000">{</font>
<font color="#00979c">struct</font> <font color="#000000">SD_ASYNC_IO</font> <font color="#000000">info</font><font color="#000000">;</font>
<font color="#00979c">uint8_t</font> <font color="#d35400">status</font><font color="#000000">;</font>
<font color="#00979c">bool</font> <font color="#000000">result</font> <font color="#434f54">=</font> <font color="#00979c">false</font><font color="#000000">;</font>
<font color="#00979c">uint16_t</font> <font color="#000000">i</font><font color="#000000">;</font>
<font color="#5e6d03">for</font><font color="#000000">(</font><font color="#000000">i</font><font color="#434f54">=</font><font color="#000000">0</font><font color="#000000">;</font> <font color="#000000">i</font><font color="#434f54"><</font><font color="#000000">sector_count</font><font color="#000000">;</font> <font color="#000000">i</font><font color="#434f54">++</font><font color="#000000">)</font>
<font color="#000000">{</font>
<font color="#434f54">//Initialize structure so we write a single sector worth of data.</font>
<font color="#000000">info</font><font color="#434f54">.</font><font color="#000000">wNumBytes</font> <font color="#434f54">=</font> <font color="#000000">1</font> <font color="#434f54"><<</font> <font color="#000000">9</font><font color="#000000">;</font> <font color="#434f54">//Equivalent to multiply by 512;</font>
<font color="#000000">info</font><font color="#434f54">.</font><font color="#000000">dwBytesRemaining</font> <font color="#434f54">=</font> <font color="#000000">1</font> <font color="#434f54"><<</font> <font color="#000000">9</font><font color="#000000">;</font> <font color="#434f54">//Equivalent to multiply by 512</font>
<font color="#000000">info</font><font color="#434f54">.</font><font color="#000000">pBuffer</font> <font color="#434f54">=</font> <font color="#000000">(</font><font color="#00979c">uint8_t</font><font color="#434f54">*</font><font color="#000000">)</font><font color="#d35400">buffer</font> <font color="#434f54">+</font> <font color="#000000">(</font><font color="#000000">i</font> <font color="#434f54"><<</font> <font color="#000000">9</font><font color="#000000">)</font><font color="#000000">;</font> <font color="#434f54">//Equivalent to multiply by 512</font>
<font color="#000000">info</font><font color="#434f54">.</font><font color="#000000">dwAddress</font> <font color="#434f54">=</font> <font color="#000000">sector_address</font> <font color="#434f54">+</font> <font color="#000000">i</font><font color="#000000">;</font>
<font color="#000000">info</font><font color="#434f54">.</font><font color="#000000">bStateVariable</font> <font color="#434f54">=</font> <font color="#000000">SD_ASYNC_WRITE_QUEUED</font><font color="#000000">;</font>
<font color="#5e6d03">if</font><font color="#000000">(</font> <font color="#000000">SD_SPI_master_open</font><font color="#000000">(</font><font color="#000000">SDFAST</font><font color="#000000">)</font> <font color="#434f54">==</font> <font color="#00979c">false</font> <font color="#000000">)</font>
<font color="#000000">{</font>
<font color="#5e6d03">return</font> <font color="#00979c">false</font><font color="#000000">;</font>
<font color="#000000">}</font>
<font color="#000000">SD_SPI_ChipSelect</font><font color="#000000">(</font><font color="#000000">)</font><font color="#000000">;</font>
<font color="#5e6d03">while</font><font color="#000000">(</font><font color="#000000">1</font><font color="#000000">)</font>
<font color="#000000">{</font>
<font color="#d35400">status</font> <font color="#434f54">=</font> <font color="#000000">SD_SPI_AsyncWriteTasks</font><font color="#000000">(</font><font color="#434f54">&</font><font color="#000000">info</font><font color="#000000">)</font><font color="#000000">;</font>
<font color="#5e6d03">if</font><font color="#000000">(</font><font color="#d35400">status</font> <font color="#434f54">==</font> <font color="#000000">SD_ASYNC_WRITE_COMPLETE</font><font color="#000000">)</font>
<font color="#000000">{</font>
<font color="#000000">result</font> <font color="#434f54">=</font> <font color="#00979c">true</font><font color="#000000">;</font>
<font color="#5e6d03">break</font><font color="#000000">;</font>
<font color="#000000">}</font>
<font color="#5e6d03">else</font> <font color="#5e6d03">if</font><font color="#000000">(</font><font color="#d35400">status</font> <font color="#434f54">==</font> <font color="#000000">SD_ASYNC_WRITE_ERROR</font><font color="#000000">)</font>
<font color="#000000">{</font>
<font color="#000000">result</font> <font color="#434f54">=</font> <font color="#00979c">false</font><font color="#000000">;</font>
<font color="#5e6d03">break</font><font color="#000000">;</font>
<font color="#000000">}</font>
<font color="#000000">}</font>
<font color="#000000">SD_SPI_ChipDeselect</font><font color="#000000">(</font><font color="#000000">)</font><font color="#000000">;</font>
<font color="#000000">SD_SPI_close</font><font color="#000000">(</font><font color="#000000">)</font><font color="#000000">;</font>
<font color="#000000">}</font>
<font color="#5e6d03">return</font> <font color="#000000">result</font><font color="#000000">;</font>
<font color="#000000">}</font>
<font color="#00979c">static</font> <font color="#00979c">uint8_t</font> <font color="#000000">SD_SPI_AsyncReadTasks</font><font color="#000000">(</font><font color="#00979c">struct</font> <font color="#000000">SD_ASYNC_IO</font><font color="#434f54">*</font> <font color="#000000">info</font><font color="#000000">)</font>
<font color="#000000">{</font>
<font color="#00979c">uint8_t</font> <font color="#000000">bData</font><font color="#000000">;</font>
<font color="#000000">SD_RESPONSE</font> <font color="#d35400">response</font><font color="#000000">;</font>
<font color="#00979c">static</font> <font color="#00979c">uint16_t</font> <font color="#000000">blockCounter</font><font color="#000000">;</font>
<font color="#00979c">static</font> <font color="#00979c">uint32_t</font> <font color="#000000">longTimeoutCounter</font><font color="#000000">;</font>
<font color="#00979c">static</font> <font color="#00979c">bool</font> <font color="#000000">SingleBlockRead</font><font color="#000000">;</font>
<font color="#434f54">//Check what state we are in, to decide what to do.</font>
<font color="#5e6d03">switch</font><font color="#000000">(</font><font color="#000000">info</font><font color="#434f54">-</font><font color="#434f54">></font><font color="#000000">bStateVariable</font><font color="#000000">)</font>
<font color="#000000">{</font>
<font color="#5e6d03">case</font> <font color="#000000">SD_ASYNC_READ_COMPLETE</font><font color="#434f54">:</font>
<font color="#5e6d03">return</font> <font color="#000000">SD_ASYNC_READ_COMPLETE</font><font color="#000000">;</font>
<font color="#5e6d03">case</font> <font color="#000000">SD_ASYNC_READ_QUEUED</font><font color="#434f54">:</font>
<font color="#434f54">//Start the read request.</font>
<font color="#434f54">//Initialize some variables we will use later.</font>
<font color="#000000">mediaInformation</font><font color="#434f54">.</font><font color="#d35400">state</font> <font color="#434f54">=</font> <font color="#000000">SD_STATE_BUSY</font><font color="#000000">;</font> <font color="#434f54">//Set global media status to busy, so no other code tries to send commands to the SD card</font>
<font color="#000000">blockCounter</font> <font color="#434f54">=</font> <font color="#000000">SD_MEDIA_BLOCK_SIZE</font><font color="#000000">;</font> <font color="#434f54">//Counter will be used later for block boundary tracking</font>
<font color="#000000">ioInfo</font> <font color="#434f54">=</font> <font color="#434f54">*</font><font color="#000000">info</font><font color="#000000">;</font> <font color="#434f54">//Get local copy of structure, for quicker access with less code size</font>
<font color="#434f54">//SDHC cards are addressed on a 512 byte block basis. This is 1:1 equivalent</font>
<font color="#434f54">//to LBA addressing. For standard capacity media, the media is expecting</font>
<font color="#434f54">//a complete byte address. Therefore, to convert from the LBA address to the</font>
<font color="#434f54">//byte address, we need to multiply by 512.</font>
<font color="#5e6d03">if</font> <font color="#000000">(</font><font color="#000000">mediaInformation</font><font color="#434f54">.</font><font color="#000000">gSDMode</font> <font color="#434f54">==</font> <font color="#000000">SD_MODE_NORMAL</font><font color="#000000">)</font>
<font color="#000000">{</font>
<font color="#000000">ioInfo</font><font color="#434f54">.</font><font color="#000000">dwAddress</font> <font color="#434f54"><<=</font> <font color="#000000">9</font><font color="#000000">;</font> <font color="#434f54">//Equivalent to multiply by 512</font>
<font color="#000000">}</font>
<font color="#5e6d03">if</font><font color="#000000">(</font><font color="#000000">ioInfo</font><font color="#434f54">.</font><font color="#000000">dwBytesRemaining</font> <font color="#434f54"><=</font> <font color="#000000">SD_MEDIA_BLOCK_SIZE</font><font color="#000000">)</font>
<font color="#000000">{</font>
<font color="#000000">SingleBlockRead</font> <font color="#434f54">=</font> <font color="#00979c">true</font><font color="#000000">;</font>
<font color="#d35400">response</font> <font color="#434f54">=</font> <font color="#000000">SD_SendCmd</font><font color="#000000">(</font><font color="#000000">SD_READ_SINGLE_BLOCK</font><font color="#434f54">,</font> <font color="#000000">ioInfo</font><font color="#434f54">.</font><font color="#000000">dwAddress</font><font color="#000000">)</font><font color="#000000">;</font>
<font color="#000000">}</font>
<font color="#5e6d03">else</font>
<font color="#000000">{</font>
<font color="#000000">SingleBlockRead</font> <font color="#434f54">=</font> <font color="#00979c">false</font><font color="#000000">;</font>
<font color="#d35400">response</font> <font color="#434f54">=</font> <font color="#000000">SD_SendCmd</font><font color="#000000">(</font><font color="#000000">SD_READ_MULTI_BLOCK</font><font color="#434f54">,</font> <font color="#000000">ioInfo</font><font color="#434f54">.</font><font color="#000000">dwAddress</font><font color="#000000">)</font><font color="#000000">;</font>
<font color="#000000">}</font>
<font color="#434f54">//Note: SendMMCmd() sends 8 SPI clock cycles after getting the</font>
<font color="#434f54">//response. This meets the NAC min timing parameter, so we don't</font>
<font color="#434f54">//need additional clocking here.</font>
<font color="#434f54">// Make sure the command was accepted successfully</font>
<font color="#5e6d03">if</font><font color="#000000">(</font><font color="#d35400">response</font><font color="#434f54">.</font><font color="#000000">r1</font><font color="#434f54">.</font><font color="#000000">_byte</font> <font color="#434f54">!=</font> <font color="#000000">0x00</font><font color="#000000">)</font>
<font color="#000000">{</font>
<font color="#434f54">//Perhaps the card isn't initialized or present.</font>
<font color="#000000">info</font><font color="#434f54">-</font><font color="#434f54">></font><font color="#000000">bStateVariable</font> <font color="#434f54">=</font> <font color="#000000">SD_ASYNC_READ_ABORT</font><font color="#000000">;</font>
<font color="#5e6d03">return</font> <font color="#000000">SD_ASYNC_READ_BUSY</font><font color="#000000">;</font>
<font color="#000000">}</font>
<font color="#434f54">//We successfully sent the READ_MULTI_BLOCK command to the media.</font>
<font color="#434f54">//We now need to keep polling the media until it sends us the data</font>
<font color="#434f54">//start token byte.</font>
<font color="#000000">longTimeoutCounter</font> <font color="#434f54">=</font> <font color="#000000">SD_NAC_TIMEOUT</font><font color="#000000">;</font> <font color="#434f54">//prepare timeout counter for next state</font>
<font color="#000000">info</font><font color="#434f54">-</font><font color="#434f54">></font><font color="#000000">bStateVariable</font> <font color="#434f54">=</font> <font color="#000000">SD_ASYNC_READ_WAIT_START_TOKEN</font><font color="#000000">;</font>
<font color="#5e6d03">return</font> <font color="#000000">SD_ASYNC_READ_BUSY</font><font color="#000000">;</font>
<font color="#5e6d03">case</font> <font color="#000000">SD_ASYNC_READ_WAIT_START_TOKEN</font><font color="#434f54">:</font>
<font color="#434f54">//In this case, we have already issued the READ_MULTI_BLOCK command</font>
<font color="#434f54">//to the media, and we need to keep polling the media until it sends</font>
<font color="#434f54">//us the data start token byte. This could typically take a</font>
<font color="#434f54">//couple/few milliseconds, up to a maximum of 100ms.</font>
<font color="#5e6d03">if</font><font color="#000000">(</font><font color="#000000">longTimeoutCounter</font> <font color="#434f54">!=</font> <font color="#000000">0x00000000</font><font color="#000000">)</font>
<font color="#000000">{</font>
<font color="#000000">longTimeoutCounter</font><font color="#434f54">--</font><font color="#000000">;</font>
<font color="#000000">bData</font> <font color="#434f54">=</font> <font color="#000000">SD_SPI_exchangeByte</font><font color="#000000">(</font><font color="#000000">0xFF</font><font color="#000000">)</font><font color="#000000">;</font>
<font color="#5e6d03">if</font><font color="#000000">(</font><font color="#000000">bData</font> <font color="#434f54">!=</font> <font color="#000000">SD_TOKEN_FLOATING_BUS</font><font color="#000000">)</font>
<font color="#000000">{</font>
<font color="#5e6d03">if</font><font color="#000000">(</font><font color="#000000">bData</font> <font color="#434f54">==</font> <font color="#000000">SD_TOKEN_START</font><font color="#000000">)</font>
<font color="#000000">{</font>
<font color="#434f54">//We got the start token. Ready to receive the data</font>
<font color="#434f54">//block now.</font>
<font color="#000000">info</font><font color="#434f54">-</font><font color="#434f54">></font><font color="#000000">bStateVariable</font> <font color="#434f54">=</font> <font color="#000000">SD_ASYNC_READ_NEW_PACKET_READY</font><font color="#000000">;</font>
<font color="#5e6d03">return</font> <font color="#000000">SD_ASYNC_READ_NEW_PACKET_READY</font><font color="#000000">;</font>
<font color="#000000">}</font>
<font color="#5e6d03">else</font>
<font color="#000000">{</font>
<font color="#434f54">//We got an unexpected non-0xFF, non-start token byte back?</font>
<font color="#434f54">//Some kind of error must have occurred. </font>
<font color="#000000">info</font><font color="#434f54">-</font><font color="#434f54">></font><font color="#000000">bStateVariable</font> <font color="#434f54">=</font> <font color="#000000">SD_ASYNC_READ_ABORT</font><font color="#000000">;</font>
<font color="#5e6d03">return</font> <font color="#000000">SD_ASYNC_READ_BUSY</font><font color="#000000">;</font>
<font color="#000000">}</font>
<font color="#000000">}</font>
<font color="#5e6d03">else</font>
<font color="#000000">{</font>
<font color="#434f54">//Media is still busy. Start token not received yet.</font>
<font color="#5e6d03">return</font> <font color="#000000">SD_ASYNC_READ_BUSY</font><font color="#000000">;</font>
<font color="#000000">}</font>
<font color="#000000">}</font>
<font color="#5e6d03">else</font>
<font color="#000000">{</font>
<font color="#434f54">//The media didn't respond with the start data token in the timeout</font>
<font color="#434f54">//interval allowed. Operation failed. Abort the operation.</font>
<font color="#000000">info</font><font color="#434f54">-</font><font color="#434f54">></font><font color="#000000">bStateVariable</font> <font color="#434f54">=</font> <font color="#000000">SD_ASYNC_READ_ABORT</font><font color="#000000">;</font>
<font color="#5e6d03">return</font> <font color="#000000">SD_ASYNC_READ_BUSY</font><font color="#000000">;</font>
<font color="#000000">}</font>
<font color="#5e6d03">break</font><font color="#000000">;</font>
<font color="#5e6d03">case</font> <font color="#000000">SD_ASYNC_READ_NEW_PACKET_READY</font><font color="#434f54">:</font>
<font color="#434f54">//We have sent the READ_MULTI_BLOCK command and have successfully</font>
<font color="#434f54">//received the data start token byte. Therefore, we are ready</font>
<font color="#434f54">//to receive raw data bytes from the media.</font>
<font color="#5e6d03">if</font><font color="#000000">(</font><font color="#000000">ioInfo</font><font color="#434f54">.</font><font color="#000000">dwBytesRemaining</font> <font color="#434f54">!=</font> <font color="#000000">0x00000000</font><font color="#000000">)</font>
<font color="#000000">{</font>
<font color="#434f54">//Re-update local copy of pointer and number of bytes to read in this</font>
<font color="#434f54">//call. These parameters are allowed to change between packets.</font>
<font color="#000000">ioInfo</font><font color="#434f54">.</font><font color="#000000">wNumBytes</font> <font color="#434f54">=</font> <font color="#000000">info</font><font color="#434f54">-</font><font color="#434f54">></font><font color="#000000">wNumBytes</font><font color="#000000">;</font>
<font color="#000000">ioInfo</font><font color="#434f54">.</font><font color="#000000">pBuffer</font> <font color="#434f54">=</font> <font color="#000000">info</font><font color="#434f54">-</font><font color="#434f54">></font><font color="#000000">pBuffer</font><font color="#000000">;</font>
<font color="#434f54">//Update counters for state tracking and loop exit condition tracking.</font>
<font color="#000000">ioInfo</font><font color="#434f54">.</font><font color="#000000">dwBytesRemaining</font> <font color="#434f54">-=</font> <font color="#000000">ioInfo</font><font color="#434f54">.</font><font color="#000000">wNumBytes</font><font color="#000000">;</font>
<font color="#000000">blockCounter</font> <font color="#434f54">-=</font> <font color="#000000">ioInfo</font><font color="#434f54">.</font><font color="#000000">wNumBytes</font><font color="#000000">;</font>
<font color="#434f54">//Now read a ioInfo.wNumbytes packet worth of SPI bytes, </font>
<font color="#434f54">//and place the received bytes in the user specified pBuffer.</font>
<font color="#000000">(</font><font color="#00979c">void</font><font color="#000000">)</font><font color="#d35400">memset</font><font color="#000000">(</font><font color="#000000">ioInfo</font><font color="#434f54">.</font><font color="#000000">pBuffer</font><font color="#434f54">,</font> <font color="#000000">0xFF</font><font color="#434f54">,</font> <font color="#000000">ioInfo</font><font color="#434f54">.</font><font color="#000000">wNumBytes</font><font color="#000000">)</font><font color="#000000">;</font>
<font color="#000000">SD_SPI_exchangeBlock</font><font color="#000000">(</font><font color="#000000">ioInfo</font><font color="#434f54">.</font><font color="#000000">pBuffer</font><font color="#434f54">,</font> <font color="#000000">ioInfo</font><font color="#434f54">.</font><font color="#000000">wNumBytes</font><font color="#000000">)</font><font color="#000000">;</font>
<font color="#434f54">//Check if we have received a multiple of the media block </font>
<font color="#434f54">//size (ex: 512 bytes). If so, the next two bytes are going to </font>
<font color="#434f54">//be CRC values, rather than data bytes. </font>
<font color="#5e6d03">if</font><font color="#000000">(</font><font color="#000000">blockCounter</font> <font color="#434f54">==</font> <font color="#000000">0</font><font color="#000000">)</font>
<font color="#000000">{</font>
<font color="#434f54">//Read two bytes to receive the CRC-16 value on the data block.</font>
<font color="#000000">(</font><font color="#00979c">void</font><font color="#000000">)</font><font color="#000000">SD_SPI_exchangeByte</font><font color="#000000">(</font><font color="#000000">0xFF</font><font color="#000000">)</font><font color="#000000">;</font>
<font color="#000000">(</font><font color="#00979c">void</font><font color="#000000">)</font><font color="#000000">SD_SPI_exchangeByte</font><font color="#000000">(</font><font color="#000000">0xFF</font><font color="#000000">)</font><font color="#000000">;</font>
<font color="#434f54">//Following sending of the CRC-16 value, the media may still</font>
<font color="#434f54">//need more access time to internally fetch the next block.</font>
<font color="#434f54">//Therefore, it will send back 0xFF idle value, until it is</font>
<font color="#434f54">//ready. Then it will send a new data start token, followed</font>
<font color="#434f54">//by the next block of useful data.</font>
<font color="#5e6d03">if</font><font color="#000000">(</font><font color="#000000">ioInfo</font><font color="#434f54">.</font><font color="#000000">dwBytesRemaining</font> <font color="#434f54">!=</font> <font color="#000000">0x00000000</font><font color="#000000">)</font>
<font color="#000000">{</font>
<font color="#000000">info</font><font color="#434f54">-</font><font color="#434f54">></font><font color="#000000">bStateVariable</font> <font color="#434f54">=</font> <font color="#000000">SD_ASYNC_READ_WAIT_START_TOKEN</font><font color="#000000">;</font>
<font color="#000000">}</font>
<font color="#000000">blockCounter</font> <font color="#434f54">=</font> <font color="#000000">SD_MEDIA_BLOCK_SIZE</font><font color="#000000">;</font>
<font color="#5e6d03">return</font> <font color="#000000">SD_ASYNC_READ_BUSY</font><font color="#000000">;</font>
<font color="#000000">}</font>
<font color="#5e6d03">return</font> <font color="#000000">SD_ASYNC_READ_NEW_PACKET_READY</font><font color="#000000">;</font>
<font color="#000000">}</font><font color="#434f54">//if(ioInfo.dwbytesRemaining != 0x00000000)</font>
<font color="#5e6d03">else</font>
<font color="#000000">{</font>
<font color="#434f54">//We completed the read operation successfully and have returned</font>
<font color="#434f54">//all data bytes requested.</font>
<font color="#434f54">//Send CMD12 to let the media know we are finished reading</font>
<font color="#434f54">//blocks from it, if we sent a multi-block read request earlier.</font>
<font color="#5e6d03">if</font><font color="#000000">(</font><font color="#000000">SingleBlockRead</font> <font color="#434f54">==</font> <font color="#00979c">false</font><font color="#000000">)</font>
<font color="#000000">{</font>
<font color="#000000">(</font><font color="#00979c">void</font><font color="#000000">)</font><font color="#000000">SD_SendCmd</font><font color="#000000">(</font><font color="#000000">SD_STOP_TRANSMISSION</font><font color="#434f54">,</font> <font color="#000000">0x00000000</font><font color="#000000">)</font><font color="#000000">;</font>
<font color="#000000">}</font>
<font color="#000000">SD_SPI_ChipDeselect</font><font color="#000000">(</font><font color="#000000">)</font><font color="#000000">;</font> <font color="#434f54">// De-select media</font>
<font color="#000000">(</font><font color="#00979c">void</font><font color="#000000">)</font><font color="#000000">SD_SPI_exchangeByte</font><font color="#000000">(</font><font color="#000000">0xFF</font><font color="#000000">)</font><font color="#000000">;</font>
<font color="#000000">info</font><font color="#434f54">-</font><font color="#434f54">></font><font color="#000000">bStateVariable</font> <font color="#434f54">=</font> <font color="#000000">SD_ASYNC_READ_COMPLETE</font><font color="#000000">;</font>
<font color="#000000">mediaInformation</font><font color="#434f54">.</font><font color="#d35400">state</font> <font color="#434f54">=</font> <font color="#000000">SD_STATE_READY_FOR_COMMAND</font><font color="#000000">;</font> <font color="#434f54">//Free the media for new commands, since we are now done with it</font>
<font color="#5e6d03">return</font> <font color="#000000">SD_ASYNC_READ_COMPLETE</font><font color="#000000">;</font>
<font color="#000000">}</font>
<font color="#5e6d03">case</font> <font color="#000000">SD_ASYNC_READ_ABORT</font><font color="#434f54">:</font>
<font color="#434f54">//If the application firmware wants to cancel a read request.</font>
<font color="#000000">info</font><font color="#434f54">-</font><font color="#434f54">></font><font color="#000000">bStateVariable</font> <font color="#434f54">=</font> <font color="#000000">SD_ASYNC_READ_ERROR</font><font color="#000000">;</font>
<font color="#434f54">//Send CMD12 to terminate the multi-block read request.</font>
<font color="#d35400">response</font> <font color="#434f54">=</font> <font color="#000000">SD_SendCmd</font><font color="#000000">(</font><font color="#000000">SD_STOP_TRANSMISSION</font><font color="#434f54">,</font> <font color="#000000">0x00000000</font><font color="#000000">)</font><font color="#000000">;</font>
<font color="#434f54">//Fall through to SD_ASYNC_READ_ERROR/default case.</font>
<font color="#5e6d03">case</font> <font color="#000000">SD_ASYNC_READ_ERROR</font><font color="#434f54">:</font>
<font color="#5e6d03">default</font><font color="#434f54">:</font>
<font color="#434f54">//Some error must have happened.</font>
<font color="#000000">SD_SPI_ChipDeselect</font><font color="#000000">(</font><font color="#000000">)</font><font color="#000000">;</font> <font color="#434f54">// De-select media</font>
<font color="#000000">(</font><font color="#00979c">void</font><font color="#000000">)</font><font color="#000000">SD_SPI_exchangeByte</font><font color="#000000">(</font><font color="#000000">0xFF</font><font color="#000000">)</font><font color="#000000">;</font>
<font color="#000000">mediaInformation</font><font color="#434f54">.</font><font color="#d35400">state</font> <font color="#434f54">=</font> <font color="#000000">SD_STATE_READY_FOR_COMMAND</font><font color="#000000">;</font>
<font color="#5e6d03">return</font> <font color="#000000">SD_ASYNC_READ_ERROR</font><font color="#000000">;</font>
<font color="#000000">}</font><font color="#434f54">//switch(info->stateVariable) </font>
<font color="#000000">}</font>
<font color="#00979c">static</font> <font color="#00979c">uint8_t</font> <font color="#000000">SD_SPI_AsyncWriteTasks</font><font color="#000000">(</font><font color="#00979c">struct</font> <font color="#000000">SD_ASYNC_IO</font><font color="#434f54">*</font> <font color="#000000">info</font><font color="#000000">)</font>
<font color="#000000">{</font>
<font color="#00979c">static</font> <font color="#00979c">uint8_t</font> <font color="#000000">data_byte</font><font color="#000000">;</font>
<font color="#00979c">static</font> <font color="#00979c">uint16_t</font> <font color="#000000">blockCounter</font><font color="#000000">;</font>
<font color="#00979c">static</font> <font color="#00979c">uint32_t</font> <font color="#000000">WriteTimeout</font><font color="#000000">;</font>