Отговори на тема  [ 17 мнения ]  Отиди на страница 1, 2  Следваща
Четене на SD (Secure Digital) Card 
Автор Съобщение
Ранг: Почетен член
Ранг: Почетен член

Регистриран на: Пет Яну 22, 2010 5:46 pm
Мнения: 680
Мнение Четене на SD (Secure Digital) Card
Пробвам се да прочета SD карта, но нещо не ми се получава. Контролера е PIC16F874.
До момента успях да инициализирам картата с команди:
CMD0
CMD8
CMD58
CMD55+ACMD41

След последната получавам отговор 0x00, а преди това когато няма грешка е 0х01 - както си пише по спецификация.

След това опитах команда CMD9 - работи и връща смислени неща съгласно спецификацията.
CMD17 обаче отказва да работи. Изобщо. При четенето опитах следните подходи:

Опитах:
1. изпращам CMD16 за да укажа големина на блока 1 байт - отговор - ОК, четене - никакво.
2. Махнах CMD16 и прочитам и показвам 4 байта, и след това с цикъл прочитам останалите

Резултати:
1. След CMD17 получавам 0xFF
2. С цикък пропускам всички0xFF -> получавам няколко 0x00 и пак 0xFF
3. С цикъл чакам токен за начало на данни - 0xFE -> отново следват 0x00 и/или 0xFF.
4. Опитах различни закъснения в цикъла (от 40us до 200ms) - никаква разлика

Кода след толкова опити е каша, но все пак ще пусна малко:


Код:
; writeSPI - write byte in WREG and read in WREG
; readSPI - write 0xFF and read in WREG
readSPI:
   movlw   0xFF
writeSPI:

   ;movf   SSPBUF, w
   movwf   SSPBUF      ;write

waitSSPIF:
   btfss   PIR1, SSPIF
   goto   waitSSPIF         ; wait
   bcf      PIR1, SSPIF

   movf   SSPBUF, w   ; read
   return


sdWriteCmd17   ; read single block

   call   readSPI

   movlw   0x40+.17
   movlw   0x51
   movwf   sdCmd      ; display on LCD
   call   writeSPI

   movf   sdAddr3, w   ; MSB first
   call   writeSPI
   movf   sdAddr2, w
   call   writeSPI
   movf   sdAddr1, w
   call   writeSPI
   movf   sdAddr0, w
   call   writeSPI

   call   readSPI      ; send 8 clock sycles after the command

   movlw   .10
   movwf   sdReadRetryCount
   movlw   0xFF
   movwf   sdResponse

retryGetResponseCmd17

   decf   sdReadRetryCount, f
   skipnz
   return
   call   readSPI
   movwf   sdResponse
   xorlw   0xFF
   skipnz
   goto   retryGetResponseCmd17


   ;call   sdWriteCmd   

   callw   delayms, .1

   movlw   .255
   movwf   sdReadRetryCount

retryReadCmd17
   callw   delayms, .1
   decf   sdReadRetryCount, f
   skipnz
   goto   cmd17Timeout

   call   readSPI
   movwf   sdCrc
   xorlw   0xFF
   skipnz
   goto   retryReadCmd17

   movf   sdReadRetryCount, f
   skipz
   return

cmd17Timeout
   ; error - timeout
   setDDAddress   0x40 + .17
   callw   writeChar, 'E'
   callw   writeChar, 'r'
   callw   writeChar, 'r'

   return



;................. в main.asm


button1pressed2
   delaymsm .10
   btfss   PORTB, button1
   goto   $-1



   ledOn
   bcf      sdCsPort, sdCsBit
   callw   delayms, .1

   call   sdWriteCmd17


   setDDAddress   0x40

   call   readSPI
   movwf   sdOCR3
   call   writeHexLcd

   call   readSPI   ; crc byte 1
   movwf   sdOCR2
   call   writeHexLcd

   call   readSPI   ; crc byte 2
   movwf   sdOCR1
   call   writeHexLcd

   call   readSPI
   movwf   sdOCR0
   call   writeHexLcd


   call   readSPI
   call   writeHexLcd
   call   readSPI
   call   writeHexLcd
   call   readSPI
   call   writeHexLcd
   call   readSPI
   call   writeHexLcd

   clrf   sdReadRetryCount
readLoop1
   call   readSPI
   decfsz   sdReadRetryCount, f
   goto   readLoop1

   clrf   sdReadRetryCount
readLoop2
   call   readSPI
   decfsz   sdReadRetryCount,f
   goto   readLoop2


   call   lcdJob2
   incf   sdAddr1, f
   incf   sdAddr1, f

   bsf      sdCsPort, sdCsBit

   callw   delayms, .50
   ledOff


   movlw   9
   movwf   stage

   call   displayStage
   goto   endStage






Прикачени файлове:
SD-connections.png
SD-connections.png [ 8.62 KiB | Прегледано 2983 пъти ]

_________________
PIC SPBRG values calculator


Последна промяна npelov на Нед Юли 17, 2011 1:40 pm, променена общо 1 път

Нед Юли 17, 2011 12:02 pm
Профил WWW
Ранг: Почетен член
Ранг: Почетен член

Регистриран на: Пет Яну 22, 2010 5:46 pm
Мнения: 680
Мнение 
Ето малко подробности (едит):

Чатенето връща:
R1 - 0х00
FE 00 00 00 00 00 - ако големината на блока е 2 байта


Първите байтове от картата всъщност са:
EB 58 90 4D 53 44 4F 53

Каквото и да правя тези байтове не излизат. Адреса който изпращам е 00 00 00 00. Да не би да има някакъв трик в адресирането?

_________________
PIC SPBRG values calculator


Нед Юли 17, 2011 12:30 pm
Профил WWW
Ранг: Почетен член
Ранг: Почетен член

Регистриран на: Пет Яну 22, 2010 5:46 pm
Мнения: 680
Мнение 
CMD9 работи - изпращам 49 00 00 00 00 FF, чакам FE и чета:

00 5Е 00 32 5F 59 83 CF
ED B6 FF 87 96 40 00 3F
C4 0F

_________________
PIC SPBRG values calculator


Нед Юли 17, 2011 1:51 pm
Профил WWW
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Сря Апр 20, 2005 12:02 pm
Мнения: 9119
Местоположение: Разград
Мнение 
Що не разгледаш някоя библиотека за SD?

Това да се мъчиш да подкарваш такива работи си е малко спортна злоба. Скоро ползвах една библиотека с FAT16 и сякаш много прилично се държи. Пък на мен ми трябват и файлове при това.


Нед Юли 17, 2011 2:51 pm
Профил ICQ
Ранг: Почетен член
Ранг: Почетен член

Регистриран на: Пет Яну 22, 2010 5:46 pm
Мнения: 680
Мнение 
щото няма за асемблер. Пък и не съм виждал библиотека за микроконтролер за някакъв хардуер да е супер универсална. Или са вързани за няколко конкретни контролера, или пък изискват да са на определени пинове... До сега съм подкарал много хардуер и нито една библиотека.

_________________
PIC SPBRG values calculator


Нед Юли 17, 2011 2:56 pm
Профил WWW
Ранг: Почетен член
Ранг: Почетен член

Регистриран на: Пет Яну 22, 2010 5:46 pm
Мнения: 680
Мнение 
Нещо с адресирането не е наред. Пиша адрес 01 00 00 00 и получавам съдържание, което иначе се намеира на офсет 0х00FF3600 според WinHex.

Четох в нета някакъв имал подобен проблем. Каза, че използвал логически адрес, а трябвало физически. Тук ме хвърли в размисъл. Никъде не намерих нищо за адресиране на SD карта включително в смотаната спецификация ... навсякъде пише (или поне така аз го тълкувам), че адрес 00 00 00 00 е първия адрес от картата.
Както и да въртиш байтовете 01 00 00 00 не може да стане на 00 FF 36 00 ...

_________________
PIC SPBRG values calculator


Последна промяна npelov на Нед Юли 17, 2011 3:39 pm, променена общо 1 път



Нед Юли 17, 2011 3:31 pm
Профил WWW
Ранг: Почетен член
Ранг: Почетен член

Регистриран на: Пет Яну 22, 2010 5:46 pm
Мнения: 680
Мнение 
... няма нищо общо с подкарването... По метода на опита и грешката открих че началния адрес на картата е: 0x0000CA00 ... въпроса е защо и същия ли е за всяка карта?

_________________
PIC SPBRG values calculator


Нед Юли 17, 2011 3:39 pm
Профил WWW
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Нед Сеп 26, 2004 4:11 pm
Мнения: 3750
Местоположение: София
Мнение 
1. Прочети сектор #0 на картата. Там се намира т.н. Master Boot Record ( по аналогия с твърдите дискове )
2. Проверка за валидност: на отместване 0x1FE трябва да има 0xAA55
3. На отместване 0x1BE с дължина 4 байта се намира адресът на първия сектор от DOS/WIN партишъна ( тип 4 или 6 )
4. Действай, пари нема!


Нед Юли 17, 2011 3:45 pm
Профил ICQ
Ранг: Почетен член
Ранг: Почетен член

Регистриран на: Пет Яну 22, 2010 5:46 pm
Мнения: 680
Мнение 
Както вече казах физическия адрес който подавам и адреса в картата се различават с 0xCA00 байта. Прочетох 2 байта от адрес 00 00 01 FE + CA00 = 00 00 CB FE и там действително има 55АА... Защо трябва да добавям това отместване 0xCA00 и защо е различно за всяка карта.

Даже успях да прочета текстов файл - с WinHex му видях адреса, добавих 0xCA00 - и всичко си е така както го написах с Notepad...

_________________
PIC SPBRG values calculator


Нед Юли 17, 2011 4:17 pm
Профил WWW
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Нед Сеп 26, 2004 4:11 pm
Мнения: 3750
Местоположение: София
Мнение 
bateAz написа:
...
3. На отместване 0x1BE с дължина 4 байта се намира адресът на първия сектор от DOS/WIN партишъна ( тип 4 или 6 )
...


Нед Юли 17, 2011 4:33 pm
Профил ICQ
Ранг: Почетен член
Ранг: Почетен член

Регистриран на: Пет Яну 22, 2010 5:46 pm
Мнения: 680
Мнение 
прочетох 4 байта - 6F 74 68 65 (CRC = 37 74) - изглежда ли достоверно? Само че нещо си объркал - като разглеждам с WinHex на адрес 0х01BE наистина има тези байтове, но това е текст "Remove disks or other media. Disk error Press any key to restart". Мисля че си се заблудил от размера на картата - тази е 256 МБ, а те нямат партишънинг. Форматирани са като флопи диск

Все пак колкото и опити да провеждам съвпадат напълно със това, което виждам в Hex редактора, с тази разлика, че на картата задавам адреса с отместване 0х0000CA00. Как е възможно да не намеря нищо по въпроса в спецификацията. Никакво отместване, никакви особености за адреса. Нищо дори в нета не намерих. На всякъде съветват "опитай с адрес 0 за да видиш буут рекърда". Аз го виждам, но на адрес 0x0000CA00.

_________________
PIC SPBRG values calculator


Нед Юли 17, 2011 5:20 pm
Профил WWW
Ранг: Почетен член
Ранг: Почетен член

Регистриран на: Пет Яну 22, 2010 5:46 pm
Мнения: 680
Мнение 
Опалааааа.... Открих че WinHex наистина не показва физическото устройство. Отворих устройството с FlexHEX и там на адрес 0х01BE има 00 03 06 00 -> това като 4 байта int трябва да е 0х00060300. Ама нещо не се връзва - нито на 0х00060300 има нещо, нито на 0х00030600.

Все пак съм четял правилно - в началото на картата си е пълно с 00

_________________
PIC SPBRG values calculator


Нед Юли 17, 2011 5:38 pm
Профил WWW
Ранг: Почетен член
Ранг: Почетен член

Регистриран на: Пет Яну 22, 2010 5:46 pm
Мнения: 680
Мнение 
С winhex разкодирах кое какво означава:
1BE - 00 (80 за активен партишън)
1BF - start head - 3
1C0 - start sector - 6
1C1 - start cylinder - 0
...
1C6 - sectors preceding partition 1 - 101

Хубаво - глави, сектори ама как са ги напъхали тия глави в СД карта. С други думи - как да знам колко байта е един сектор, колко сектора на цилиндър, колко глави има една карта. Пише ли го в спецификацията? Т.е. хардуерно ли е?

Едит - отговора се намира на 1C6 -> 101 ... не знам колко байта е това число, но 1, 2 или 4 байта в този конкретен случай все е 101. 101*512 = 51712 или 0хCA00 :) ето го моето отместване. А аз си мислех че карти < 1ГБ се форматират без партишън - като дискета.

_________________
PIC SPBRG values calculator


Последна промяна npelov на Нед Юли 17, 2011 9:02 pm, променена общо 1 път



Нед Юли 17, 2011 8:33 pm
Профил WWW
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Нед Сеп 26, 2004 4:11 pm
Мнения: 3750
Местоположение: София
Мнение 
Код:
// четене на MasterBoot Sector
   offs = read_sector(0);
   if (offs == 0xFFFF) return 0xFFFF;
   // проверка за валидност на MBR
   memcpy( &ui, &disk_buff[offs + 0x1FE], 2 );
   if (ui != 0xAA55) return 0x8001;
   // данни за партишън #0 : type = 4 или 6
   if ((disk_buff[offs + 0x1BE + 4] != 4) && (disk_buff[offs + 0x1BE + 4] != 6)) {
      drive_first_sector = 0;
   } else {
      //  чете позицията на 'start sector' на партишъна
      memcpy( &drive_first_sector, &disk_buff[offs + 0x1BE + 8], 4 );
   }
   // четене на Boot Sector на DOS партишъна
   offs = read_sector(drive_first_sector);
   if (offs == 0xFFFF) return 0xFFFF;
   // проверка за валидност на Boot Sector
   memcpy( &ui, &disk_buff[offs + 0x1FE], 2 );
   if (ui != 0xAA55) return 0x8004;
   // проверка за брой байтове в сектор = 512
   memcpy( &ui, &disk_buff[offs + 0x0B], 2 );
   if (ui != 0x0200) return 0x8005;
   // проверка за брой на FAT = 2
   if (disk_buff[offs + 0x10] != 2) return 0x8003;
   // попълва брой сектори в клъстер
   sectors_per_cluster = (unsigned int)(disk_buff[offs + 0x0D]);
   if (sectors_per_cluster == 0) return 0x8006;
   // попълва брой на елементите в основния каталог
   memcpy( &number_of_dir_entries, &disk_buff[offs + 0x11], 2 );
   // попълва размер на едно копие на FAT в брой сектори
   memcpy( &fat_size, &disk_buff[offs + 0x16], 2 );
   // размер на партишъна в сектори
   number_of_sectors = 0;
   memcpy( &number_of_sectors, &disk_buff[offs + 0x13], 2 );
   if (number_of_sectors == 0)
     memcpy( &number_of_sectors, &disk_buff[offs + 0x20], 4 );
   // размер на партишъна в брой клъстери
   number_of_clusters = number_of_sectors / sectors_per_cluster;
   if ((number_of_clusters > 65526) || (number_of_clusters < 4085)) return 0x8002;
   // маски за съвпадение да два адреса да са в един сектор или един клъстер
   in_cluster_mask = in_sector_mask * (unsigned long)(sectors_per_cluster);
   // стартов сектор на FAT_1 и FAT_2
   memcpy( &ui, &disk_buff[offs + 0x0E], 2 );
   fat_first_sector = drive_first_sector + (unsigned long)(ui);
   // стартов сектор на ROOT
   root_first_sector = fat_first_sector + (unsigned long)(fat_size) + (unsigned long)(fat_size);
   data_first_sector = root_first_sector + (number_of_dir_entries >> 4);
   // поставя текуща да е основната директория
   currdir_first_sector = root_first_sector;
   currdir_nmbr_of_entries = number_of_dir_entries;
   // търсенето на свободен клъстер да започне от началото на партишъна
   last_got_free_cluster = 0;
   // изход ОК
   mounted = 1;
   return 0;


Нед Юли 17, 2011 8:48 pm
Профил ICQ
Ранг: Почетен член
Ранг: Почетен член

Регистриран на: Пет Яну 22, 2010 5:46 pm
Мнения: 680
Мнение 
да, мерси ... малко ме обърка като каза че отместването на партишъна е на 1BE. Всъщност от кода дето си пуснал се вижда че е 1BE + 8 или както сам отгатнах - 1C6. Както виждам от твоя код отместването е 4 байта Int.

_________________
PIC SPBRG values calculator


Нед Юли 17, 2011 9:09 pm
Профил WWW
Покажи мненията от миналия:  Сортирай по  
Отговори на тема   [ 17 мнения ]  Отиди на страница 1, 2  Следваща

Кой е на линия

Потребители разглеждащи този форум: 0 регистрирани и 3 госта


Вие не можете да пускате нови теми
Вие не можете да отговаряте на теми
Вие не можете да променяте собственото си мнение
Вие не можете да изтривате собствените си мнения
Вие не можете да прикачвате файл

Търсене:
Иди на:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.
Хостинг и Домейни