Перейти к содержанию
    

Инициализация SD карты в SPI режиме

Доброе время суток всем!!!

 

Занимаюсь сейчас девайсом на ATMEGA16, который должен следить за параметрами сетевого напряжения и создавать логи параметров на флеш-карте. Работу с картой памяти моделировал для начала в протеусе там всё работает просто замечательно и читает и пишет в неё (в протеусе правда есть модель только MMC карты, но насколько я понял она в SPI режиме совместима с SD). А вот когда начал тоже самое делать на реальном железе (купил для этого SD карту от Панасоника на 16Мбайт) начались проблеммы!

 

Сброс и переход в SPI режим идёт отлично как по маслу, карточка возвращает положенную единичку после нескольких команд CMD0. А при попытке выполнить инициализацию по CMD1 в цикле сначала выдаёт несколько единиц (как в общем то и положено), а потом вместо нуля, говорящего, что инициализация окончена, переводит линию в третье состояние и больше уже на CMD1 не реагирует. На другие команды после этого отвечает единичкой это означает, что карта не готова. На недопустимые команды выдаёт 4, что и означает - команда недопустима, т. е. ведёт себя вполне адекватно.

 

Почему карта не инициализируется для меня оказалась великой тайной. Помогите пожалуйста, может у кого есть идеи на этот счёт или сталкивался уже с этой проблеммой!!!

 

:help:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вапрос немного в всторону...ты работаешь с файловой системой? у тя есть че почитать по этому поводу...лучше если на русском...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вроде как все правильно делаете.

На CMD1 карта может достаточно долго не отзываться (~500ms).

Попробуйте добавить пустые циклы клоков после снятия CS.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вапрос немного в всторону...ты работаешь с файловой системой? у тя есть че почитать по этому поводу...лучше если на русском...

 

Нет с FAT пока не работаю, просто пишу на карту поток данных, возможно впоследствии и займусь этим.

 

http://mp3vkarmane.nm.ru/mmc.html - это единственный вразумительный документ на русском по FAT для карт памяти, остальное на инглише. В гугле полно доков на эту темму.

 

На CMD1 карта может достаточно долго не отзываться (~500ms).

Попробуйте добавить пустые циклы клоков после снятия CS.

 

Спасибо буду пробовать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо всем!!! Решил я проблему :biggrin: , дело было в питании карточки - стабилизатор на 3,3 В тухлый оказался, под нагрузкой, когда к карте обращаешься, напряжение на нём падало до 1 - 2 В. Заменил стабилизатор и всё заработало как надо.

 

С Наступающим всех. :cheers:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Тему новую как то заводить нехотелось и поиском не нашел..Объясните пожалуйста что означает "CMD1"и подобного рода команды в SD, т.е. понятно что это команда..но расшифровки найти немогу..формат..сколько байт и какая команда чему соответствует.. Подскажите ссылки или доки .Спасибо

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Тему новую как то заводить нехотелось и поиском не нашел..Объясните пожалуйста что означает "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=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);

}

 

//Читаем 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 - указатель на буфер с данными, должен быть равен размеру сектора, поскольку читать и писать можно только сектор целиком, как в жёстком диске.

 

Вот в общемто и всё что надо

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Кому интересно - FAT - http://elm-chan.org/fsw/ff/00index_e.html нормально переносится в кодевижн. Работает на ура, там есть и работа с ММС, всё готово. Там же http://elm-chan.org/docs/mmc/mmc_e.html описание работы с ММС. Лично всё переносил, работает.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...