-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSDHC_doc.txt
773 lines (729 loc) · 42.9 KB
/
SDHC_doc.txt
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
;;
;; Пояснение по формату передачи параметров и использованию регистров:
;; В данном драйвере регистры eax и esi используются для неявной передачи
;; указателей на карту регистрой контроллера(слота) и указателя на структуру
;; контроллера, использование этих регистров в других целях возможно в раде
;; случаев связанных с: API импортируемых функций, с необходимостью использо-
;; вать именно эти регистры и до получения этих указателей.
;; Параметры в основном должны передаваться через регистры, в основном через
;; ebx, edx и ecx, но в ряде случаев возможно использование стека для передачи
;; большого количества параметров или если использование регистров не подходит
;; для работы функции или не обеспечивают сохранение параметров.
;;
; Регистры контроллера
; base SD registers
; 0x00-0x0f - SD Command Generation
; если версия контроллера меньше 3 или host_version_4_enable=0, то это адрес SDMA
;Этот регистр содержит адрес системной памяти для передачи SDMA в 32битном режиме адресациию.
;Когда хост контроллер останавливает передачу SDMA, этот регистр должен указывать на адрес
;слудующую непрерывную позицию данных.
;Доступ к этому регистру возможен только в том случае, если транзакция не выполняется(т.е. после
;остановки транзакции).Чтение этого регистра во время SDMA передачи вернёт недопустимое значеие.
;Драйвер хоста должен инициализировать этот регистр перед запуском SDMA передачи.
;После остановки SDMA следующий системный адрес следующей непрерывной позиции может быть считан
;из этого регистра.
;
;Хост контроллер генерирует прерывание DMA, чтобы запросить драйвер хоста для обновления этого
;регистра. Драйвер хоста устанавливает слудующий системный адрес следующей позиции данных в этот
;регистр.Когда записывается самый верхний байт этого регистра(03h), хост контроллер перезапускает
;передачу SDMA.
;
;ADMA не использует этот регистр
; если версия больше и host_version_4_enable=1 то это 32bit block count(более подробно смотреть в
;разделе 1.15) в версии 4.0 используется только для счётчика блоков для auto CMD23, длшя установки
;аргумента CMD23 при выполнении auto CMD23. Хост контроллер будет уменьшать значение этого регистра
;при каждой передаче и при достижении нуля передача данных прекращается.Доступ к этому регистру стоит
;осуществлять только когда транзакция не выполняется. при чтении при транзакции контроллер
;может вернуть недопустимое значение
;=====
; Как я понимаю значение этого регистра: адрес на область физ памяти на некое кол-во байт
; его должен устанавливать драйвер перед каждой операцией sdma
; 0x04-0x08 -Block Size Reg
; В этом регистре содержится 3 значения.
;0-11 Transfer Block Size
; Этот регистр определяет размер блока передачи данных для CMD17, CMD18, CMD24, CMD25, CMD35.
; можно задать значение от 1 до 2048 байт. не изменять и не читать во время транзакции
; In case of memory it shall be set up to 512 bytes( Reffer to Implementation Note in Section 1.7.2)
;12-14 SDMA Buffer Boundary
; Размер выделяемой нами физической памяти для SDMA команд.(4кб 8 кб 16 кб и тд. до 512к)
; когда контроллер дошёл до конца выделенной нами памяти, вызывается прерывание DMA interrupt
; если сгенерилось событие Transfer Complete interrupt то DMA interrupt не генерится
; ADMA не использует этот регистр
; эти регистры должны поддерживаться если в регистре capabilities register
; SDMA support = 1 и если в регистре Transfer Mode register DMA Enable = 1
;16-31 16 bit block count Register
; Версия хост контроллера 4.10 расширяет количество блоков до 32бит(см Раздел 1.15)
; выбор либо 16 либо 32 битного регистра подсчёта блоков определяется следующим образом:
; если Host version 4 enable = 0 или если для регистра 0х06 установленно ненулевое значение
; то выбирается регистр 0х06
; если Host version 4 enable = 1 и регистр 0x06 установлен в ноль, то выбирает 32битный регистр
; использование 16/32 битного регистра подсчёта блоков включено, если Block Count Enable в регистре
; Trancfer Mode установлен в 1, и оно допустимо только для передачи нескольких блоков.
; Драйвер должен установить в этот регистр значение от 1 до максимального количества блоков.
; контроллер уменьшает это значение после каждой передачи блоков и останавливается, кодга количество
; достигает нуля. установка регистра в нольприводит к тому, что блоки не передаются.
; Доступ к регистру возможен только когда нет транзакции. если она есть запись игнорится а чтение
; возвращает неверное значение.
; Transfer Mode Register 0x0C-0x0D ;word (using 0-5 bits)
; Этот регистр используется для контроля операций передачи данных.Драйвер должен установить этот регистр
; перед выполнением команды с передачей данных(смотрет Data Pressent Select в Command регистре), или перед
; выполнением Resume команды. Драйвер должен сохранить этот регистр когда передача данных преостановлена
; (в результате выполнения команды приостановки) и восстановить его перед выполнением команды восстановления
; Чтобы избежать потерю данных, контроллер должен реализовать защиту от записи для этого регистра во время
; транзакции данных.Запись в этот регистр должна игнорироваться когда Command Inhibit (DAT) равен 1.
; 0 - DMA Enable
; Этот бит обеспечивает функциональность DMA как описано в разделе 1.4 .DMA может быть
; включено только в том случае, если оно поддерживается в регистре возможностей.
; Один из режимов работы DMA может быть выбран с помощью DMA Select в Host Control регистре.
; Если DMA не поддерживается этот бит всегда должен быть выставлен в 0. Если этот бит
; установлен в 1, то операция DMA должна начинаться когда драйвер хоста записывает в
; верхний байт Command регистра(0x0f).
; 1 - Block Counter Enable
; Этот бит используется для включения регистра подсчёта блоков, которые имеет значение
; только для передачи нескольких блоко. Когда этот бит нравен 0, регистр подсчёта блоков
; отключается, что полезно при выполнении бесконечной передачи(см таблицу 2-8)
; Если передача данных ADMA2 составляет более 65535 блоков, этот бит должен быть
; установлен в 0. В этом случае длина передачи данных определяется таблицей дискрипторов.
; 2 - Auto CMD12 Enable
; Для многократной передачи блоков требуется остановка транзакции через CMD12
; При установке этого бита контроллер сам отправляет эту команду при завершении транзакции
; Драйвер хоста не должен устанавливать этот бит, если команды не требуют cmd12 для
; остановки передачи данных.
; 4 - Data Transfer Direction Select
; Этот бит определяет направлене передачи данных по DAT линии. 1-Передача данных с карты
; в хост контроллер, 0 для всех остальных случаев.(1-чтение, 0-запись)
; 5 - Multi/ Single Block Select
; Этот бит устанавливается при выдаче команд многоблочной передачи с использованием
; DAT линии.Для любых других команд этот бит должен быть установлен в 0. Если этот бит
; установлен в 0 нет необходимости устанавливать Block Count регистр.
; Command Register 0x0E-0x0F ;word (using 0-13)
; Этот регистр нужно записывать только после того как проверили Command Inhibit(DAT) и (CMD),
;Запись в верхний байт этого регистра начинает генерацию команды. Драйвер несёт ответственность
;за запись этого регистра, поскольку контроллер не защищает запись, когда установлена Command Inhibit
;(CMD)
; 0-1 - Response Type Select
; 00 - No Response
; 01 - Response Length 136
; 10 - Response Length 48
; 11 - Response Length 48 check Busy after response
; 3 - Command CRC Check Enable
; 4 - Command index Check Enable
; 5 - Data Present Select
; 6-7 - Command Type
; 8-13 - Command index
;0x10-0x1f - Response
; Response Bit Definition and Each Response type
; R1,R1b (normal response) - Card Status - REP[0:31]
; R1b (Auto CMD12 response) - Card Status for Auto CMD12 - REP[96:127]
; R1 (Auto CMD23 response) - Card Status for Auto CMD23 - REP[96:127]
; R2 (CID, CSD register) - CID or CSD reg. incl. - REP[0:119]
; R3 (OCR register) - OCR register for memory - REP[0:31]
; R4 (OCR register) - OCR register for I/O etc - REP[0:31]
; R5, R5b - SDIO response - REP[0:31]
; R6 (Published RCA response) - New published RCA[16:31] etc - REP[0:31]
; R7 (return CMD8) - Voltage flags + mask protect - REP[0:31]
;0x20-0x23 - Buffer Data Port как я понимаю это указатель на буфер
; Доступ к буферу контроллера можно получить через 32bit Data Port регистр(смю Раздел 1.7)
;0x24-0x2f - Host Control 1 and Others
; Present Satte Register (offset 0x24)
; Драйвер может получить состояние контроллера через этот 32 битный регистр.
; 0 - Command inhibit (CMD)
; 1 - Command inhibit (DAT)
; 2 - DAT Line Active
; 3-7 - Resevred
; 8 - Write Transfer Active
; 9 - Read Transfer Active
; Этот статус используется для не DMA записи транзакций.
; 10 - Buffer Write Enable
; Этот статус используется для не DMA чтения транзакций.
; 11 - Buffer Read Enable
; 12-15 - Reserved
; Этот бит показывает вставлена карта или нет в слот. В нормальных условиях контроллер генерит
; прерывание Card Inesrtion и Card Removed. Ресет всего не должен влиять на это.
; 16 - Card Inserted
; 17 - Card State Stable
; 18 - Card Detect Pin Level
; Этот бит отображает пин SDWP#. Переключатель защиты от записи поддерживается для карт памяти
; и комбинированных карт.
; 19 - Write Protect Switch Pin Level (1 - Write enable SDWP#=1, 0 - Write protected SDWP#=0)
;
; 20-23 - DAT[0:3] Line Signal Level
; Этот статус используется для проверки уровня CMD линии для восстановления после ошибки и отладки.
; 24 - CMD Line Signal Level
; 25-31 - Reserved
; Host control Register (offset 0x28)
; 0 - LED Control (0 - LED off; 1 - LED on)
; Этот бит используется для предупреждения полдьзователя о том чтобы он не извлекал карту во
; время доступа к SD карте. Если ПО собирается выдавать несколько команд SD, этот бит может быть
; установлен во время всех этих транзакций. Нет необходимости вносить изменения для каждой
; транзакции.
; 1 - Data Transfer Width (0 - 1 bit mode; 1 - 4 bit mode)
; Этот бит выбирает ширину данных хост контроллера. Драйвер должен настроить его так чтобы он
; соответствовал шарене данных SD карты.
; 2 - High Speed Enable ( 0 - Normal Speed mode; 1 - High Speed mode)
; Это необязательный бит. Перед установкой проверить регистр Capabilities.
; Если этот бит равен 0 - частота до 25 МГц, если 1 - до 50 МГц.
; 3-4 - DMA Select
; Выбор одного из поддерживаемых режимов DMA. Перед этим проверить регистр Capabilities.
; Использование выбранного DMA оперделяется DMA Enable в регистре Transfer Mode.
; 00 - SDMA
; 01 - Reserved(ADMA1)
; 10 - 32-bit Address ADMA2
; 11 - 64-bit Address ADMA2
; 6 - Card Detect Test Level (1 - Card Inserted; 0 - Not Card)
; Этот бит включён когда Card Detect Signal Selection равен 1 и он указывает вставлена
; карта или нет.
; 7 - Card Detect Signal Selection (0 - SDCD# (for normal use); 1 - The Card Detect Test Level (for test purpose))
; Этот бит выбирает источник обнаружения карт.
; Power Control Regstre (offset 29h)
; 0 - SD Bus Power for VDD1
; Если хост контроллер детектит No Card состояние, то надо этот флаг очистить
; 1-3 - SD Bus Voltage Select for VDD1
; Этот бит может быть установлен если в регистре capabilities параметр 1.8V VDD2 Support
; установлен в 1.
; 101 - 1.8V
; 110 - 3.0V
; 111 - 3.3V
; block gap control = 0x2a ;byte (using 0-3 bits)
; Wekeup control (offset 2Bh) ;byte (using 0-2 bits)
; Драйвер должен поддерживать вольтаж на SD шине устанавливая SD Bus Power в Power Control, when wake
; up event via Card Interrupt is desired.
; Как это понимаю я, я должен активировать эти флаги для того чтобы ловить прерывания подкл/откл карты.
; и FN_WUS в регистре CIS установить для 00 бита данного регистра.
; 00 - Wakeup Event Enable On Card Intwrrupt.
; 01 - Wakeup Event Enable On SD Card Insertion
; 02 - Wakeup Event Enable On SD Card Removal
; 0x2c - SDHC_CTRL2
; При инициализации необходимо заполнить поле SDCLK/RCLK Frequency Select в соответствии с регистром
; Capabilities. Этот регистр управляет SDCLK в SD Mode и RCLK в UHS-II Mode.
; 0 - Internal Clock Enable
; Этот бит устанавливается в ноль когда драйвер не использует контроллер или контроллер
; ожидает прерывание пробуждения.Контроллер переходит в режим низкого потреблеиния,
; останавливает внутренние часы(internal clock), регистры доступны и на чтените и на запись.
; Часы начинают колебаться, когда бит установлен в 1, Когда тактовая частота стабилизируется
; контроллер устанавливает бит Internal Clock Stable в состояние 1. Этот бит не влияет на
; обноружение карт(но это не точно).
; 1 - Internal Clock Stable
; Начиная с версии 4.0 драйвер проверяет этот статус дважды, после установки внутренних
; часов(см выше) и после установки PLL Enable.(Refer to Figure 3-3)
; 1) Internal Clock Stable(Когда PLL Enable = 0 или если не поддерживается)
; Контроллер устанавливает этот регистр в 1, когда частота стабилизируется (см выше)
; (Doczom: как то всё запутанно, я так понял надо очередной цикл по проверке тут делать)
; 2) PLL Clock Stable (PLL Enable = 1)
; Контроллер поддерживающий PLL Enable, устанавливает это значение в 0, при изменении
; PLL Enable с 0 на 1 и устанавливает 1, когда PLL заблокирован(PLL использует встроенный
; часы в качестве эталонных часов, которые включаются в Internal Clock Enable). После
; того, как этот бит установлен в 1, драйвер может менять SD clock Enable.
; 2 - SD Clcok Enable
; Хост контроллер должен остановить SDCLK при записи этого бита в 0. Выбор частоты SDCLK
; может быть изменён кагда этот бит равен 0. Затем хост контроллер должен поддерживать
; ту же частоту до тех пор, пока SDCLK не будет остановлен(Остановка при SDCLK=0). Если
; Card insert в регистре Present State очищен, этот бит должен быть очищен.
;
;; 3 - PLL Enable
;; Этот регистр появился в версии 4.10 контроллера, использующего PLL. Это позволяет
;; инициализировать clock генератор в 2 этапа: a)стабилизация входных тактовых импульсов
;; PLL с Internal Clock Enable и b) стабилизация PLL с PLL Enable.
;; Контроллер может настроить минимальные задержки с помощью SD Clock Enable.
;;
;; 4 - Reaerved
;
; 6 - 7 - Upper Bits of SDCLK/RCLK Frequency Select
; 8 - 15 - SDCLK/RCLK Frequency Select
; Этот регистр используется для выбора частоты SDCLK пина.Определение этого поля
; зависит от версии контроллера
; 1) 8 битный Разделитель Тактов
; этот режим поддерживается в версии 1 и 2. Частота не программируется напрямую, а
; содержит делитель для Base Clock Frequency For SD Clock в регистре Capabilities
; 0x08 - base clock / 256
; 0x40 - base clock / 128
; 0x20 - base clock / 64
; 0x10 - base clock / 32
; 0x08 - base clock / 16
; 0x04 - base clock / 8
; 0x02 - base clock / 4
; 0x01 - base clock / 2
; 0x00 - base clock (10MHz-63MHz)
; При указании частоты используется самый старший бит, согласно спецификации физического
; уровня максимальная частота SD Clock = 25 MHz в нормальной скорости и 50 MHz, при высокой
; скорости и никогда не должна превышать этот лимит. Всегда надо выбирать ближайшую к нужной
; равную или меньше например base Clock = 33MHz а целевая частота равна 25MHz, то выбираем
; значение делителя 0x01 = 16,5MHz, ближайщее меньшее или равное. Аналогисно для целевой
; частоты 400KHz значение делителя ставим в 0x40 оптимальное тактовое значенике 258kHz.
; 2) 10 битный Разделитель тактов
; Хост контроллер версии 3.0 или более новые, значение просто расширяется до 10 бит
; и делитель меняется
; 0x3ff - 1/2046 base clock
; n - 1/2n base clock
; 0x002 - 1/4 base clock
; 0x001 - 1/2 base clock
; 0x000 - Base Clock (10MHz - 155MHz)
; 3) Программируемый Разделитель Тактов
; Контроллер версии 3.0 и выше если Clock Multiplier в регистре Capabilities не нулевой
; и что-то. Множитель позволяет хост-системе более чётко выбирать частоту нет необходимости
; поддерживать генерацию всех частот, указанных в этом поле, поскольку программируемый
; генератор импульсов зависит от конкретного поставщика и зависит от реализации. Поэтому
; этот режим используется с регистром Preset Value.
; Поставщик контроллера предоставляет возможные настройки, а поставщики хост-систем
; соответствующее значения в регистры Preset Value.
; 0x3FF - Base clock * M/1024
; N-1 - base clock * M/N
; 0x002 - base clock * M/3
; 0x001 - base clock * M/2
; 0x000 - base clock * M
; Это поле зависит от установленного значение в Preset Value Enable в регистре
; Host control 2. Если Preset Value Enable = 0, то этот регистр устанавливает драйвер,
; если = 1 , то это значение автоматически устанавливается установленное в одном из
; Preset value регистров.
; timeout_control = 0x2e ;byte (using 0-3 bits)
; Драйвер должен установить это значение согласно регистру capabilities
; применяется при передачи по DAT линиям.
; 0000b - TMCLK*2^13
; 0001b - TMCLK*2^14
; 1110b - TMCLK*2^27
; 1111b - Reserved
; software_reset = 0x2f ;byte (using 0-2 bits)
; Импульс генерится при изменении битов этого регистра
;для подтверждения завершения сброса смотрим чтобы все биты были равны нулю(скорее всего цикл)
; 0x02 - software reset для DAT линии (только SD Mode)
; очищаются:
; Buffer Data Port register
; буфер очищается и инициализируется
; Present State register
; Buffer Read Enable
; Buffer Write Enable
; Read Transfer Active
; Write Transfer Active
; DAT Line Active
; Command Lnhibit(DAT)
; Block Gap Control register
; Continue Request
; Stop At Block Gap Request
; Normal Interrupt Status register
; Buffer Read Ready
; Buffer Write Ready
; DMA interrupt
; Block Gap Event
; Transfer Complete
; 0x01 - software reset for CMD линии
; Для версии 4.10 используется для инициализации командной системы UHS-II
; Этот сброс действует только на схемы выдачи команд(включая состояние ошибки ответа в
; Command Inhibit(CMD) control) и не влияет на схему передачи данных.
; Контроллер может продолжать передачу данных, даже если этот сброс выполняется во время
; обработки ошибки ответа субкоманды.
; очищаются:
; Present State register
; Command Inhibit (cmd)
;` Normal Interrupt Status register
; Command Complete
; Error Interrupt Status (from Version 4.10)
; Response error statuses related to Command Inhibit (CMD)
; 0x00 - software reset for All
; Этот сброс влияет на весь контроллерЮ за исключением схемы обнаружения карты.
; Биты регистров с типом: ROC RW RW1C RWAC очищаются в 0
; Во время инициализации драйвер должен вызвать этот сброс (контроллер очистит capabilities регистр)
;Повторное выцзывание этого сброса может не повлиять на capabilities register.
;Если этот бит установлен в 1,драйвер вызвает команду сброса и заново инициализирует SD-карту
; normal_int_status_enable = 0x34 ;word
; .command_complete_status_enable = 0x01 ; 1=enabled 0=masked
; .transfer_complete_status_enable = 0x02 ; 1=enabled 0=masked
; .block_gap_event_status_enable = 0x04 ; 1=enabled 0=masked
; .dma_interrupt_status_enable = 0x08 ; 1=enabled 0=masked
; .buffer_write_readly_status_enable = 0x10 ; 1=enabled 0=masked
; .buffer_read_readly_status_enable = 0x20 ; 1=enabled 0=masked
; .card_insertion_status_enable = 0x40 ; 1=enabled 0=masked
; .card_removal_status_enable = 0x80 ; 1=enabled 0=masked
; .card_interrupt_status_enable = 0x0100 ; 1=enabled 0=masked
; .INT_A_status_enable = 0x0200 ; 1=enabled 0=masked (embedded)
; .INT_B_status_enable = 0x0400 ; 1=enabled 0=masked (embedded)
; .INT_C_status_enable = 0x0800 ; 1=enabled 0=masked (embedded)
; .Re_tuning_event_status_enable = 0x1000 ; 1=enabled 0=masked (UHS-I only)
; .FX_event_status_enable = 0x2000 ; 1=enabled 0=masked
; ;reserved 14 bit
; .Fixed_to_0 = 0x8000 ;есть во всех версиях спеки
; error_int_status = 0x36
; .command_timeout_error_status_enable = 0x01 ; 1=enabled 0=masked (SD mode only)
; .command_crc_error_status_enable = 0x02 ; 1=enabled 0=masked (SD mode only)
; .command_end_bit_error_status_enable = 0x04 ; 1=enabled 0=masked (SD mode only)
; .command_index_error_status_enable = 0x08 ; 1=enabled 0=masked (SD mode only)
; .data_timeout_error_status_enable = 0x10 ; 1=enabled 0=masked (SD mode only)
; .data_crc_error_status_enable = 0x20 ; 1=enabled 0=masked (SD mode only)
; .data_end_bit_error_enable = 0x40 ; 1=enabled 0=masked (SD mode only)
; .current_limit_error_status_enable = 0x80 ; 1=enabled 0=masked
; .auto_cmd_error_status_enable = 0x0100 ; 1=enabled 0=masked (SD mode only)
; .adma_error_status_enable = 0x0200 ; 1=enabled 0=masked
; .tuning_error_status_enable = 0x0400 ; 1=enabled 0=masked (UHS-I only)
; .response_error_status_enable = 0x0800 ; 1=enabled 0=masked (SD mode only)
; .vendor_specific_error_status_enable = 0xf000 ; 1=enabled 0=masked (НЕ ИСПОЛЬЗОВАТЬ!!!)
; normal_int_signal_enable = 0x38
; .command_complete_signal_enable = 0x01 ; 1=enabled 0=masked
; .transfer_complete_signal_enable = 0x02 ; 1=enabled 0=masked
; .block_gap_event_signal_enable = 0x04 ; 1=enabled 0=masked
; .dma_interrupt_signal_enable = 0x08 ; 1=enabled 0=masked
; .buffer_write_ready_signal_enable = 0x10 ; 1=enabled 0=masked
; .buffer_read_ready_signal_enable = 0x20 ; 1=enabled 0=masked
; .card_insertion_signal_enable = 0x40 ; 1=enabled 0=masked
; .card_removal_signal_enable = 0x80 ; 1=enabled 0=masked
; .card_interrupt_signal_enable = 0x0100 ; 1=enabled 0=masked
; .INT_A_Signal_enable = 0x0200 ; 1=enabled 0=masked (embedded)
; .INT_B_Signal_enable = 0x0400 ; 1=enabled 0=masked (embedded)
; .INT_C_Signal_enable = 0x0800 ; 1=enabled 0=masked (embedded)
; .Re_tunning_event_signal_enable = 0x1000 ; 1=enabled 0=masked (UHS_I only)
; .FX_event_signal_enable = 0x2000 ; 1=enabled 0=masked
; ;reserved 14 bit
; .Fixed_to_0 = 0x8000 ; The Host Driver shall control
; ; error interrupts using the Error Interrupt Signal Enable register.
; error_int_signal_enable = 0x3a
; .command_timeout_error_signal_enable = 0x01 ; 1=enabled 0=masked (SD mode only)
; .command_crc_error_signal_enable = 0x02 ; 1=enabled 0=masked (sd mode only)
; .command_end_bit_error_signal_enable = 0x04 ; 1=enabled 0=masked (sd mode only)
; .command_index_error_signal_enable = 0x08 ; 1=enabled 0=masked (sd mode only)
; .data_timeout_error_signal_enable = 0x10 ; 1=enabled 0=masked (sd mode only)
; .data_crc_error_signal_enable = 0x20 ; 1=enabled 0=masked (sd mode only)
; .data_end_bit_sagnal_enable = 0x40 ; 1=enabled 0=masked (sd mode only)
; .current_limit_error_signal_enable = 0x80 ; 1=enabled 0=masked
; .auto_cmd_error_signal_enable = 0x0100 ; 1=enabled 0=masked (sd mode only)
; .adma_error_signal_enable = 0x0200 ; 1=enabled 0=masked
; .tuning_error_signal_enable = 0x0400 ; 1=enabled 0=masked (UHS-I only)
; .response_error_signal_enable = 0x0800 ; 1=enabled 0=masked (sd mode only)
; .vendor_specific_error_signal_enable = 0xf000 ; 1=enabled 0=masked (НЕ ИСПОЛЬЗОВАТЬ!!!)
; Auto_cmd_error_status = 0x3C ;word(using 0-7 bits)
; .auto_cmd12_not_excuted = 0x01 ; check 0 bit - 1=not_executed 0=executed
; .auto_cmd_timeout_error = 0x02 ; check 1 bit 1=time out 0=no_error
; .auto_cmd_crc_error = 0x04 ; check 2 bit 1=crc error generation 0=no_error
; .auto_cmd_end_bit_error = 0x08 ; check 3 bit 1=end_bit_error_generated 0=no_error
; .auto_cmd_index_error = 0x10 ; check 4 bit 1=error 0=no_error
; .auto_cmd_response_error = 0x20 ; check 5 bit 1=error 0=no_error
; ; 6 bit is reserved
; .command_not_issued_by_auto_cmd12_error = 0x80 ; check 7 bit 1=Not_issued 0=no_error
; 0x40-0x4f - Capabilities
;Этот регистр предоставляет драйверу инфу, специфичную для реализации данного контроллера.
; Смотреть после полного сброса. Для разных версий спеки разная конфигурация регистров с
;сохранением обратной совместимости
; SDHC_CURR_CAPABILITY = 0x48 ; qword (using 0-23 32-39)
;этот регистр указывает на максимальную токовую способность для каждого вида напряжения,
;если контроллер поддерживает это напряжение(регистр 0x40). Если контроллер передаёт
;эти значения другим методом, то этот регистр должен быть выставлен в ноль.
; 0 - 7 - 3.3V VDD1
; 8 - 15 - 3.0V VDD1
; 16 - 23 - 1.8V VDD1
; 24 - 31 - reserved
; 32 - 39 - 1.8V VDD2
; 40 - 63 - resevred
; Данный регистр измеряет ток с шагом 4мА
; 0 - Получение информации другим способом
; 1 - 4 мА
; 2 - 8 мА
; 3 - 12 мА
; ...
; 255 - 1020 мА
; Драйвер контроллера поддерживающего SDXC карты должен проверить этот регистр для установления
;значения XPC в аргументе ACMD41. Если контроллер может позволить себе больше 150 мА то XPC = 1,
;иначе XPC = 0. Подробнее о XPC в спеке физического уровня 3.0x.
;0x50-0x53 - Force Event ; spec version 2
;0x54-0x5f - ADMA2 ; spec version 2
;0x60-0x6f - Preset Value ;spec version 3
;0x70-0x77 - ADMA3 ;spec version 4
;0x80-0xD7 - UNS-II
;0xe0-0xef - Pointers
;0xf0-0xff - common area
; SLOT_INTRPT = 0xfc ;Slot interapt status register 1 byte; 0xfd - reserved
;как я понял, это глобальный флаг который показывает, где произошло прерывание
; всего есть 8 слотов, каждому из которых соответструет 1 бит
; Регистры SD/SDIO/MMC карт и прочее
; OCR register
; bit | data
;---------|----------------------------;
; 0-6 | reserved ;
; 7 | Low Voltage Range (1.8V) ;
; 8-14 | reserved ;
; 15 | 2.7 - 2.8V ;
; 16 | 2.8 - 2.9V ;
; 17 | 2.9 - 3.0V ;
; 18 | 3.0 - 3.1V ;
; 19 | 3.1 - 3.2V ;
; 20 | 3.2 - 3.3V ;
; 21 | 3.3 - 3.4V ;
; 22 | 3.4 - 3.5V ;
; 23 | 3.5 - 3.6V ;
; 24 | reserved ; <- only to UHS-I "switching to 1.8 Accepted (S18A)"
; 25-26 | reserved ;
; 27 | reserved ; <- only to SDUC "Over to 2TB support Status (CO2T)"
; 28 | reserved ;
; 29 | reserved ; <- UHS-II Card Status
; 30 | Card Capacity Status(CCS) ;
; 31 | Card power up status bit ; (busy)
;--------------------------------------;
; I/O OCR register
; bit | data
;---------|----------------------------;
; 0-7 | reserved ;
; 8 | 2.0 - 2.1V ;
; 9 | 2.1 - 2.2V ;
; 10 | 2.2 - 2.3V ;
; 11 | 2.3 - 2.4V ;
; 12 | 2.4 - 2.5V ;
; 13 | 2.5 - 2.6V ;
; 11 | 2.6 - 2.7V ;
; 15 | 2.7 - 2.8V ;
; 16 | 2.8 - 2.9V ;
; 17 | 2.9 - 3.0V ;
; 18 | 3.0 - 3.1V ;
; 19 | 3.1 - 3.2V ;
; 20 | 3.2 - 3.3V ;
; 21 | 3.3 - 3.4V ;
; 22 | 3.4 - 3.5V ;
; 23 | 3.5 - 3.6V ;
; 24 | switching to 1.8 Accepted ; <- "switching to 1.8 Accepted (S18A)"
; 25-26 | reserved ;
; 27 | Memory Present ; <- 1 усли карта содержит SD память, 0 если только I/O
; 28-30 | Number of I/O Functions ; <- не включаем общую область функции 0 (подробнее в SDIO спеке)
; 31 | Card power up status bit ; (busy)
;--------------------------------------;
; CID register
; bit | width | data ;
;---------|-------|----------------------------;
; 0-11 | 12 | Manufacturing date(MDT) ; <- [0-3] month code(1=january) [4-11] year-2000
; 12-15 | 4 | reserved ;
; 16-47 | 32 | Product Serial Number(PSN) ;
; 48-55 | 8 | Product Revision(PRV) ; <- BCD number
; 56-95 | 40 | Product name(PRN) ;
; 96-111 | 16 | OEM/Aplication ID (OID) ;
; 112-119 | 8 | Manufacturer ID (MID) ;
;----------------------------------------------;
; CSD register ver 1.0
; bit | width | value | data ;
;---------|-------|--------------------|-----------------------------------------------------;
; 0-1 | 2 | 00b | reserved ;
; 2-3 | 2 | xxb | File Format(FILE_FORMAT) ;
; 4 | 1 | xb | temporary write protection TMP_WRITE_PROTECT ;
; 5 | 1 | xb | permanent write protection PERM_WRITE_PROTECT ;
; 6 | 1 | xb | copy flag COPY ;
; 7 | 1 | xb | file format group (FILE_FORMAT_GRP) ;
; 8-12 | 5 | 00000b | reserved ;
; 13 | 1 | xb | partial blocks for write allowed (WRITE_BL_PARTIAL) ;
; 14-17 | 4 | xxxxb | max. write data block length (WRITE_BL_LEN) ; размер сектора на чтение и запись
; 18-20 | 3 | xxxb | write speed factor (R2W_FACTOR) ;
; 21-22 | 2 | 00b | reserved ;
; 23 | 1 | xb | write protect group enable (WP_GRP_ENABLE) ;
; 24-30 | 7 | xxxxxxxb | write protect group size (WP_GRP_SIZE) ;
; 31-37 | 7 | xxxxxxxb | erase sector size (SECTOR_SIZE) ;
; 38 | 1 | xb | erase single block enable (ERASW_BLK_EN) ;
; 39-41 | 3 | xxxb | device size multiplier C_SIZE_MULT ;
; 42-44 | 3 | xxxb | VDD_W_CURR_MAX ;
; 45-47 | 3 | xxxb | VDD_W_CURR_MIN ;
; 48-50 | 3 | xxxb | VDD_R_CURR_MAX ;
; 51-53 | 3 | xxxb | VDD_R_CURR_MIN ;
; 54-65 | 12 | xxxh | device size C_SIZE ;
; 66-67 | 2 | 00b | reserved ;
; 68 | 1 | xb | DSR implemented DSR_IMP ; если или нету DSR регистр
; 69 | 1 | xb | read block misalignment (READ_BLK_MISALIGN) ; возможно ли пересечение блока данных с другими на физ уровне
; 70 | 1 | xb | write block misalignment (WRITE_BLK_MISALIGN) ; 0 - нет 1 - да
; 71 | 1 | 1b | partial blocks for read allowed (READ_BL_PARTIAL) ; всегда 1. можно читать меньше чем блок
; 72-75 | 4 | xh | max. read data block length (READ_BL_LEN) ; размер сектора на чтение и запись
; 76-87 | 12 | 01x110110101b | card command classes CCC ;
; 88-95 | 8 | 32h,5Ah | max. data transfer rate (TRAN_SPEED) ;
; 96-103 | 8 | xxh | data read access-time in CLK cycles(MSAC*100) NSAC);
; 104-111 | 8 | xxh | data read access-time (TAAC) ;
; 112-117 | 6 | 00 0000b | reserved ;
; 118-119 | 2 | 00b | CSD structure CSD_STRUCTURE ;
;--------------------------------------------------------------------------------------------;
; CSD register ver 2.0
; bit | width | value | data ;
;---------|-------|--------------------|-----------------------------------------------------;
; 0-1 | 2 | 00b | reserved ;
; 2-3 | 2 | 00b | File Format(FILE_FORMAT) ;
; 4 | 1 | x | temporary write protection TMP_WRITE_PROTECT ;
; 5 | 1 | x | permanent write protection PERM_WRITE_PROTECT ;
; 6 | 1 | x | copy flag COPY ;
; 7 | 1 | 0 | file format group (FILE_FORMAT_GRP) ;
; 8-12 | 5 | 00000b | reserved ;
; 13 | 1 | 0 | partial blocks for write allowed (WRITE_BL_PARTIAL) ;
; 14-17 | 4 | 9 | max. write data block length (WRITE_BL_LEN) ; размер сектора на чтение и запись
; 18-20 | 3 | 010b | write speed factor (R2W_FACTOR) ;
; 21-22 | 2 | 00b | reserved ;
; 23 | 1 | 0 | write protect group enable (WP_GRP_ENABLE) ;
; 24-30 | 7 | 0000000b | write protect group size (WP_GRP_SIZE) ;
; 31-37 | 7 | 7Fh | erase sector size (SECTOR_SIZE) ;
; 38 | 1 | 1 | erase single block enable (ERASW_BLK_EN) ;
; 39 | 1 | 0 | reserved ;
; 40-61 | 22 | xxxxxxh | device size C_SIZE ;
; 62-67 | 6 | 00 0000b | reserved ;
; 68 | 1 | x | DSR implemented DSR_IMP ; если или нету DSR регистр
; 69 | 1 | 0 | read block misalignment (READ_BLK_MISALIGN) ; возможно ли пересечение блока данных с другими на физ уровне
; 70 | 1 | 0 | write block misalignment (WRITE_BLK_MISALIGN) ; 0 - нет 1 - да
; 71 | 1 | 0 | partial blocks for read allowed (READ_BL_PARTIAL) ; всегда 1. можно читать меньше чем блок
; 72-75 | 4 | 9 | max. read data block length (READ_BL_LEN) ; размер сектора на чтение и запись
; 76-87 | 12 | 01x110110101b | card command classes CCC ;
; 88-95 | 8 | 32h,5Ah,0Bh or 2Bh | max. data transfer rate (TRAN_SPEED) ;
; 96-103 | 8 | 00h | data read access-time in CLK cycles(MSAC*100) NSAC);
; 104-111 | 8 | 0Eh | data read access-time (TAAC) ;
; 112-117 | 6 | 00 0000b | reserved ;
; 118-119 | 2 | 01b | CSD structure CSD_STRUCTURE ;
;--------------------------------------------------------------------------------------------;
;
; for version struct 1.0
; memory capacity = BLOCKNR * BLOCK_LEN
; BLOCKNR = (C_SIZE + 1) * MULT
; MULT = 2^(C_SIZE_MULT + 2)
; for version struct 2.0
; memory capacity = (C_SIZE + 1) * 512 KByte
; Алгоритмы
; это драйвер для работы с файлами на sd картах и возможно для ещё чего-то
; при инициализации драйвер находит контроллер проверяет его состояние
; назначает ему обработчик прерываний, активация которого сигнализирует вроде как
; подключение или отключение карты
;SD Clock Control
;
;1) SD Clock Supply Sequence
;
; получаем делитель частоты и останавливаем SD clock
; (если базовая частота равна нулю то контроллер должен другим методом передать частоту)
; устанавливаем делитель и активируем бит Internal Clcok Enable
; цикл пока internal Clcok stable не равен 1
; устанавливаем бит SD clock
;
;Это действие нужно выполнить перед:
;
;а) выдача SD команды
;б) получение прерывания с карты в 4-бит режиме
;
;2) SD clock Stop
; Устанавливаем SD clock в ноль
;
;Драйвер не должен останавливать SD Clock когда SD транзакция проходит по SD Bus -
;а именно когда Command Inhibit(DAT) или Command Inhibit(CMD) в регистре Pressent State равну 1
;
;3) Изменение тактовой частоты
;
;сначало останавливаем SD clock потом утсанавливаем
;
;SD Bus Power Control
;
; Устанавливаем максимальное напряжение из возможных(устанавливаем значение вольтажа и бит активаии)
; Получаем OCR значение SD карты
; Если подходит то всё, если нет то ставим новое значение
;
;
;
;Timeout Setting on DAT Line
;
; в соответствии с частатой в 0x40 регистре установить значение счётчика в timeout control
;
;Для обнаружения ошибка таймаута на DAT линии. Установку этого значения делать при любой sd
;транзакцией.
;; CODE FOR TEST WORKING
;DEBUGF 1,"SDHCI: TEST1 SDMA - read first sector\n"
;call TEST_SDMA_R
;DEBUGF 1,"SDHCI: TEST2 SDMA - read first sector\n"
;call TEST_SDMA_R_MUL
;proc TEST_SDMA_R
; or dword[eax + SDHC_INT_MASK], 0xFFFFFFFF
; or dword[eax + SDHC_SOG_MASK], 0xFFFFFFFF
; and dword[eax + SDHC_CTRL1], not 11000b ; set SDMA mode
; mov byte[eax + 0x2E], 1110b ; set max
; mov ebp, eax
; invoke KernelAlloc, 4096
; push eax
; invoke GetPhysAddr ; arg = eax
; xchg eax, ebp
; mov dword[eax], ebp;phys addr
; mov dword[eax + 4], SD_BLOCK_SIZE
; ;(block_count shl) 16 + (sdma_buffer_boundary shl 12) + block_size
; mov dword[eax + 8], 0 ; arg - num sector
; mov dword[eax + 0xC], (((17 shl 8) + DATA_PRSNT + RESP_TYPE.R1 ) shl 16) + 010001b
;@@:
; cmp dword[esi + SDHCI_CONTROLLER.int_status], 0
; hlt
; jz @b
; ;DEBUGF 1,"SDHCI: resp1=%x resp2=%x \n", [eax + SDHC_RESP1_0], [eax + SDHC_RESP3_2]
;.wait_int:
; mov dword[esi + SDHCI_CONTROLLER.int_status], 0
; hlt
; cmp dword[esi + SDHCI_CONTROLLER.int_status], 0
; jz .wait_int
; ;DEBUGF 1,"SDHCI: resp1=%x resp2=%x \n", [eax + SDHC_RESP1_0], [eax + SDHC_RESP3_2]
; pop ebp
; test dword[eax + SDHC_RESP1_0], 0x8000
; jnz @f
; push eax
; mov dword[.ptr], ebp
; mov ebx, .file_struct
; invoke FS_Service
; pop eax
;@@:
; ret
;.file_struct:
; dd 2
; dd 0
; dd 0
; dd 512
;.ptr: dd 0
; db '/tmp0/1/dump_first_sector',0
;
;endp
; Заметка к SDMA: Прерывание DMA возникает только при пересечении границы блока данных
; у меня это граница в 4кб
;proc TEST_SDMA_R_MUL
; or dword[eax + SDHC_INT_MASK], 0xFFFFFFFF
; or dword[eax + SDHC_SOG_MASK], 0xFFFFFFFF
; and dword[eax + SDHC_CTRL1], not 11000b ; set SDMA mode
; mov byte[eax + 0x2E], 1110b ; set max
; mov ebp, eax
; invoke KernelAlloc, 4096*0x800;128;4096*512
; push eax
; push eax
; invoke GetPhysAddr ; arg = eax
; xchg eax, ebp
; mov dword[eax], ebp;phys addr
; mov dword[eax + 4], ((8*0x800) shl 16) + SD_BLOCK_SIZE
; ;(block_count shl) 16 + (sdma_buffer_boundary shl 12) + block_size
; mov dword[eax + 8], 0;0x2000 ; arg - num sector
; mov dword[eax + 0xC], (((18 shl 8) + DATA_PRSNT + RESP_TYPE.R1 ) shl 16) + CMD_TYPE.Multiple + 10101b
;@@:
; cmp dword[esi + SDHCI_CONTROLLER.int_status], 0
; hlt
; jz @b
; ;DEBUGF 1,"SDHCI: resp1=%x resp2=%x \n", [eax + SDHC_RESP1_0], [eax + SDHC_RESP3_2]
;.wait_int:
; mov dword[esi + SDHCI_CONTROLLER.int_status], 0
; hlt
; cmp dword[esi + SDHCI_CONTROLLER.int_status], 0
; jz .wait_int
; test dword[esi + SDHCI_CONTROLLER.int_status], 10b
; jnz @f
; test dword[esi + SDHCI_CONTROLLER.int_status], 1000b
; jz @f
;
; xchg eax, ebp
; mov eax, dword[esp]
; add eax, 4096
; mov dword[esp], eax
; invoke GetPhysAddr
; xchg eax, ebp
; mov dword[eax], ebp;phys addr
;
; jmp .wait_int
;
; ;DEBUGF 1,"SDHCI: resp1=%x resp2=%x \n", [eax + SDHC_RESP1_0], [eax + SDHC_RESP3_2]
;@@:
; pop ebp
; pop ebp
; test dword[eax + SDHC_RESP1_0], 0x8000
; jnz @f
; push eax
; mov dword[.ptr], ebp
; mov ebx, .file_struct
; invoke FS_Service
; pop eax
;@@:
; ret
;.file_struct:
; dd 2
; dd 0
; dd 0
; dd 4096*0x800;128
;.ptr: dd 0
; db '/tmp0/1/dump_first_sector_mul',0
;
;endp