Цитата(add @ Dec 25 2006, 14:13)

Тему новую как то заводить нехотелось и поиском не нашел..Объясните пожалуйста что означает "CMD1"и подобного рода команды в SD, т.е. понятно что это команда..но расшифровки найти немогу..формат..сколько байт и какая команда чему соответствует.. Подскажите ссылки или доки .Спасибо
CMD1 - команда сброса и инициализации карточки. Полный список команд можно посмотреть на сайте СанДиска
http://www.sandisk.com/Oem/Manuals/По мануалам довольно сложно понять как реализован протокол обмена карты, поэтому выкладываю исходники библиотеки работы с SD картой для КодеВизиона. Может кому поможет съэкономить несколько дней работы.
Итак карта подключается к SPI проца. В исходниках к порту PORTB.4 подключена линия CS SD карты.
Заголовочный файл для работы с картой содержит коды комманд:
................................................................................
.............................................................................
//Файл mmccommand.h
//Комманды и ответы
#define MMC_GO_IDLE_STATE 0 ///< initialize card to SPI-type access
#define MMC_SEND_OP_COND 1 ///< set card operational mode
#define MMC_SEND_CSD 9 ///< get card's CSD
#define MMC_SEND_CID 10 ///< get card's CID
#define MMC_SEND_STATUS 13
#define MMC_SET_BLOCKLEN 16 ///< Set number of bytes to transfer per block
#define MMC_READ_SINGLE_BLOCK 17 ///< read a block
#define MMC_WRITE_BLOCK 24 ///< write a block
#define MMC_PROGRAM_CSD 27
#define MMC_SET_WRITE_PROT 28
#define MMC_CLR_WRITE_PROT 29
#define MMC_SEND_WRITE_PROT 30
#define MMC_TAG_SECTOR_START 32
#define MMC_TAG_SECTOR_END 33
#define MMC_UNTAG_SECTOR 34
#define MMC_TAG_ERASE_GROUP_START 35 ///< Sets beginning of erase group (mass erase)
#define MMC_TAG_ERARE_GROUP_END 36 ///< Sets end of erase group (mass erase)
#define MMC_UNTAG_ERASE_GROUP 37 ///< Untag (unset) erase group (mass erase)
#define MMC_ERASE 38 ///< Perform block/mass erase
#define MMC_CRC_ON_OFF 59 ///< Turns CRC check on/off
// R1 Response bit-defines
#define MMC_R1_BUSY 0x80 ///< R1 response: bit indicates card is busy
#define MMC_R1_PARAMETER 0x40
#define MMC_R1_ADDRESS 0x20
#define MMC_R1_ERASE_SEQ 0x10
#define MMC_R1_COM_CRC 0x08
#define MMC_R1_ILLEGAL_COM 0x04
#define MMC_R1_ERASE_RESET 0x02
#define MMC_R1_IDLE_STATE 0x01
// Data Start tokens
#define MMC_STARTBLOCK_READ 0xFE ///< when received from card, indicates that a block of data will follow
#define MMC_STARTBLOCK_WRITE 0xFE ///< when sent to card, indicates that a block of data will follow
#define MMC_STARTBLOCK_MWRITE 0xFC
// Data Stop tokens
#define MMC_STOPTRAN_WRITE 0xFD
// Data Error Token values
#define MMC_DE_MASK 0x1F
#define MMC_DE_ERROR 0x01
#define MMC_DE_CC_ERROR 0x02
#define MMC_DE_ECC_FAIL 0x04
#define MMC_DE_OUT_OF_RANGE 0x04
#define MMC_DE_CARD_LOCKED 0x04
// Data Response Token values
#define MMC_DR_MASK 0x1F
#define MMC_DR_ACCEPT 0x05
#define MMC_DR_REJECT_CRC 0x0B
#define MMC_DR_REJECT_WRITE_ERROR 0x0D
................................................................................
.............................................................................
CMDx соответствует коду команды только в десятичном виде.
Далее представлен сам файл с функциями
................................................................................
.............................................................................
//Файл mmclib.c 2006 Michael Fisher Vet inc.
#include "mmcCommand.h"
#include <spi.h>
#include <stdio.h>
#include <delay.h>
char i,b;
char MMC_Reset(void)
{
unsigned char retry,r1;
r1=retry=0;
//Устанавливаем карту в режим SPI
do
{
spi(0xFF);
spi(0xFF);
spi(0xFF);
spi(0xFF);
r1=MMC_SendCommand(MMC_GO_IDLE_STATE,0);
retry++;
if(retry>10)return 10;
}while(r1!=0x01);
//Инициализировать карту
retry=0;
do
{
r1=MMC_SendCommand(MMC_SEND_OP_COND,0);
retry++;
if(retry>250)return r1;
}while(r1);
//Отключить CRC проверку
r1=MMC_SendCommand(MMC_CRC_ON_OFF, 0);
//Установить длину блока
r1=MMC_SendCommand(MMC_SET_BLOCKLEN,512);//Сдесь задаётся размер сектора
return r1;
}
unsigned char MMC_SendCommand(char cmd,unsigned long int arg)
{
char r1;
PORTB.4=0;
r1=MMC_Command(cmd,arg);
PORTB.4=1;
spi(0xFF);
return r1;
}
unsigned char MMC_Command(char cmd,unsigned long int arg)
{
char r1,retry;
retry=0;
//Передать комманду
spi(cmd|0x40);//Комманда
spi(arg>>24);//Аргумент
spi(arg>>16);
spi(arg>>8);
spi(arg);
spi(0x95);//Имеет значение только при передачи режима обмена
//Ждём ответа, если ответа нет более 64 циклa, то ошибка карты и возвращаем 0хFF
while((r1=spi(0xff))==0xFF)if(retry++>252)break;
//Вернуть ответ
return r1;
}
unsigned char MMC_ReadSector(unsigned long int sector,unsigned char *buffer)
{
char r1;
int i;
PORTB.4=0;//Активировать карту
r1=MMC_Command(MMC_READ_SINGLE_BLOCK, sector<<9);//Установить номер сектора
if(r1!=0)return r1;//Если комманда не выполнена сообщить код ошибки
while(spi(0xFF)!=MMC_STARTBLOCK_READ);//Ждём готовности данных
for(i=0;i<512;i++)//Читаем данные в буфер
{
buffer[i]=spi(0xFF);
}
//Читаем 2 бита CRC
spi(0xFF);
spi(0xFF);
PORTB.4=1;//Освобождаем карту
spi(0xFF);
return 0;
}
unsigned char MMC_WriteSector(unsigned long int sector,unsigned char *buffer)
{
char r1;
int i;
PORTB.4=0;//Активировать карту
r1=MMC_Command(MMC_WRITE_BLOCK, sector<<9);//Установить номер сектора
if(r1!=0)//Если комманда не выполнена сообщить код ошибки
{
PORTB.4=1;//Освобождаем карту
return r1;
}
// пЕРЕДАТЬ ПУСТОЙ БАЙТ
spi(0xFF);
spi(0xFF);
//Передать стартовый байт
spi(MMC_STARTBLOCK_WRITE);
//Записываем в карту данные
for(i=0; i<512; i++)
{
spi(buffer[i]);
}
//Читаем 2 бита CRC
spi(0xFF);
spi(0xFF);
//Читаем ответ карты
r1 = spi(0xFF);
if( (r1&MMC_DR_MASK)!= MMC_DR_ACCEPT)
{
PORTB.4=1;//Освобождаем карту
return r1;
}
// wait until card not busy
while(!spi(0xFF));
PORTB.4=1;//Освобождаем карту
spi(0xFF);
return 0;
}
................................................................................
.............................................................................
В основном коде перед работой с картой вызываем функцию MMC_Reset(); Если она вернула 0, то всё впорядке и работаем далее, если нет то ошибка расшифрована хорошо в доке -
http://mp3vkarmane.nm.ru/mmc.html.
После инициализации можно:
-записать сектор - unsigned char MMC_WriteSector(unsigned long int sector,unsigned char *buffer), в случае успеха вернёт 0
-прочитать сектор - unsigned char MMC_ReadSector(unsigned long int sector,unsigned char *buffer)
Где sector - номер сектора от 0 до n (n=объём карты/размер сектора), *buffer - указатель на буфер с данными, должен быть равен размеру сектора, поскольку читать и писать можно только сектор целиком, как в жёстком диске.
Вот в общемто и всё что надо
[/i]Восприятие верёвки как змеи так же ложно, как и восприятие верёвки как верёвки