PS
я считываю с карты и пишу на нее, но если я И считываю а затем И пишу, то все виснет:(
В чем заключается зависание мк? Что он в это время делает?Protobear писал(а):Уважаемые коты, кто работал с SD картами - у меня зависает мк при втором чтении или записи
А если попробовать прочитать 2 сектора или записать сразу два сектора - работает?Protobear писал(а):я считываю с карты и пишу на нее, но если я И считываю а затем И пишу, то все виснет:(
я считываю с карты и пишу на нее, но если я И считываю а затем И пишу, то все виснет:([/quote]А если попробовать прочитать 2 сектора или записать сразу два сектора - работает?mas123 писал(а):В чем заключается зависание мк? Что он в это время делает?Protobear писал(а):Уважаемые коты, кто работал с SD картами - у меня зависает мк при втором чтении или записи
Ога, карточка после сектора выдает 2 байта CRC, а при записи требует 2 байта CRC от тебя.Protobear писал(а):обалдеть! что вы хотите сказать что любой алгоритм записи заключает в себе передачу предварительно считанных байтов срс?
Код внимательнее посмотрю чуть позже, пока что-то мне уже там не нравится....Protobear писал(а):код прилагаю.
КАК именно виснет? в каком месте? Какая-нибудь отладочная инфа выводится хоть куда-нить?Protobear писал(а): но если я пишу другой массив то он виснет.
По карточкам погугли спецификацию - тама расписано.Protobear писал(а): опишите пожалуйста про байты CRC поподробнее - я правильно понял(выше)?
Да, нет это я понял) я в коде посылаю CRC "от балды" (во многих источниках говорят что CRC нужен только для смд 0 и 8 )я то думал что CRC строится на базе 512 байт данных, а что какие 2 байта СRC требует карточка? тех что я считал или тех что оспадают с CRC моих данных подготовленных для записи?mas123 писал(а):Ога, карточка после сектора выдает 2 байта CRC, а при записи требует 2 байта CRC от тебя.Protobear писал(а):обалдеть! что вы хотите сказать что любой алгоритм записи заключает в себе передачу предварительно считанных байтов срс?
да по SPI инициализация 0х40 ответ 0х01 ;0х41 ответ 0х00. затем то что в текст документе, да там циклы while(o==0xff); после if(o!=0x00) goto mark1; не нужны, но это не важно, главное что проблема остается.mas123 писал(а): По какой схеме включена карточка? Через SPI?
Как инициализируешь SD?
после всех функции считывания и отправки:mas123 писал(а): КАК именно виснет? в каком месте? Какая-нибудь отладочная инфа выводится хоть куда-нить?
Protobear писал(а):код прилагаю.
Код: Выделить всё
unsigned char SD_RECIVE_DATA(long int address)
{
unsigned char o;
PORTB&=~(1<<PB4);
_delay_us(100);
mark:
SD_transmit(0x51);
SD_transmit((address>>24)&0x000000ff);
SD_transmit((address>>16)&0x000000ff);
SD_transmit((address>>8)&0x000000ff);
SD_transmit(address&0x000000ff);
SD_transmit(0x95);
ReadByteSPI(0xff);
o=ReadByteSPI(0xff);
if(o!=0x00) goto mark;
while((ReadByteSPI(0xff))!=0xff);
while(o!=0xfe) {o=ReadByteSPI(0xff);}
for (int p=0;p<512;p++)
{
mass[p]=ReadByteSPI(0xff);
}
ReadByteSPI(0xff);// считываю 2 байта СРС (вникуда)
o=ReadByteSPI(0xff);// -//- -//-
while((ReadByteSPI(0xff))!=0xff);
_delay_us(100);
PORTB|=(1<<PB4);
return o;
}Ога, я передаю "правильные" CRC для этих 2 команд.Protobear писал(а):Да, нет это я понял) я в коде посылаю CRC "от балды" (во многих источниках говорят что CRC нужен только для смд 0 и 8 )
Не разбирался с этим вопросом, ибо контроль CRC отключаю. При работе по SPI контроль вроде бы сам выключается, я даже убрал передачу команды 59Protobear писал(а):я то думал что CRC строится на базе 512 байт данных, а что какие 2 байта СRC требует карточка? тех что я считал или тех что оспадают с CRC моих данных подготовленных для записи?
Не знаю по какому именно документу делаешьProtobear писал(а):да по SPI инициализация 0х40 ответ 0х01 ;0х41 ответ 0х00. затем то что в текст документе,mas123 писал(а):Как инициализируешь SD?
Код: Выделить всё
//************************************************************************
//* Активизация карты: разбудить карту
//************************************************************************
//* ВХОД
//************************************************************************
//* ВЫХОД
//* результат
//************************************************************************
bool CDataSD::WakeUp()
{
m_cTypeCard = _SDCARD_TYPE_NONE; // тип карты
// при выключеном CS выдать 10 байт 0xFF, затем ждать 1 мс
LockSPI_Init();
g_drvSPI.Transfer(&Null_Word, NULL, 10, 0, 0);
UnlockSPI();
VDK::Sleep(10);
BYTE cResult;
for(WORD i=0; i<SD_RETRY_WAKEUP; i++)
{
LockSPI_Init();
cResult = SendCommandAndWait(SD_GO_IDLE_STATE, 0,
_SD_TIMEOUT_COMMAND, true);
if( cResult == SD_R1_IDLE_STATE )
{
DummySend(1); // Send One Byte Delay
UnlockSPI();
break;
}
UnlockSPI();
VDK::Sleep(10); ///~~~
}
if( cResult != SD_R1_IDLE_STATE )
return false;
VDK::Sleep(80);
bool bVersSD2 = false;
// Проверить статус питания, обязательно для SDHC карт
for(WORD i=0; i<255; i++)
{
LockSPI_Init();
DummySend(1);
cResult = SendCommandAndWait(SD_SEND_IF_COND, 0x000001AA,
_SD_TIMEOUT_COMMAND, true);
UnlockSPI();
if( SD_R1_IDLE_STATE == cResult )
{ // возможно, это SDHC!
bVersSD2 = true;
break;
}
VDK::Sleep(20);
}
// ждем, когда карта выйдет из спящего режима.
// Проверка SD карты
for(WORD i=0; i<60; i++)
{
LockSPI_Init();
DummySend(1); // Send One Byte Delay
cResult = SendCommandAndWait(SD_APP_CMD, 0, _SD_TIMEOUT_COMMAND, true);
if( cResult != SD_R1_OK )
{
cResult = SendCommandAndWait(SD_APP_CMD, 0, _SD_TIMEOUT_COMMAND, true);
if( cResult != SD_R1_IDLE_STATE )
{
UnlockSPI();
continue;
}
}
cResult = SendCommandAndWait(SD_SEND_OP_COND_FOR_SD, 0x40000000, ///~~~ было 0
_SD_TIMEOUT_COMMAND, true); // ACMD41
UnlockSPI();
if( SD_R1_OK == cResult )
{ // нашли SD карту
m_cTypeCard = _SDCARD_TYPE_SD_VER1; // тип карты
if( bVersSD2 )
CheckSDHC(); // это SD 2-й версии или SDHC
return true;
}
VDK::Sleep(20);
}
LockSPI_Init();
cResult = SendCommandAndWait(SD_GO_IDLE_STATE, 0,
_SD_TIMEOUT_COMMAND, true);
UnlockSPI();
if( cResult != SD_R1_IDLE_STATE )
{
return false;
}
// poll card by sending CMD1 and wait for card initialization complete
for(short i=0; i<300; i++ )
{
LockSPI_Init();
DummySend(1); // Send One Byte Delay
// Send CMD1
cResult = SendCommandAndWait(SD_SEND_OP_COND_FOR_MMC, 0,
_SD_TIMEOUT_COMMAND, true);
if( SD_R1_OK == cResult )
{ // нашли MMC карту
UnlockSPI();
m_cTypeCard = _SDCARD_TYPE_MMC; // тип карты
return true;
}
UnlockSPI();
VDK::Sleep(20);
}
return false;
}подключаешь UART Rx/Tx на COM-порт и кидаешь в него ключевые буковки: дошел до такого-то места в коде - кинул в УАРТ нужную буковку.Protobear писал(а):после всех функции считывания и отправки:mas123 писал(а): КАК именно виснет? в каком месте? Какая-нибудь отладочная инфа выводится хоть куда-нить?
выводится ф-ей print(ho) ; .....
ТО до показа на дисплей не доходит дело.
Этот ответ получаешь сразу после передачи в карточку данных?Protobear писал(а):PS Более того при записи карта отвечает на пацана 0xe5 что свидетельствует о "Data accepted"
это после записи 512 байт, т.е. все как положено.mas123 писал(а): А что возвращает ожидание окончания записи?
- я тоже посылаю правильные) 0х95.mas123 писал(а):Правильные срс для 41 и 40
Т.е. мой комментарий по твоему коду проигнорирован начисто? Про постоянную передачу команды в карточку и ожидания ответа ровно на 2-й байт?Protobear писал(а):Хотите верьте - хотите нет - но происходит ЛАЖА какая то)),
Код: Выделить всё
unsigned char sd_cmd(char b0, char b1, char b2, char b3, char b4, char b5)
//Отправка команды карте SD|MMC
{ unsigned char res;
long int count;
spi_transmit (b0); //Передать индекс команды
spi_transmit (b1); //Передать аргумент
spi_transmit (b2);
spi_transmit (b3);
spi_transmit (b4);
spi_transmit (b5); //Передать CRC
count=0;
do { //Подождпть R1 ответа
res=spi_receive();
count=count+1;
} while ( ((res&0x80)!=0x00)&&(count<0xffff) );
return res;
}Нет, он был убран после чего сразу пошла запись(с мусором), однако код еще не до конца похож на сайтовский, как сделаю отпишу что вышло, спасибо большое за помощь!mas123 писал(а):Т.е. мой комментарий по твоему коду проигнорирован начисто? Про постоянную передачу команды в карточку и ожидания ответа ровно на 2-й байт?
Код: Выделить всё
Cluster_base = (Root_base + root_entry_size) - (2*Sectors_per_Cluster) ;