Микроконтроллеры, АЦП, память и т.д Темы касающиеся микроконтроллеров разных производителей, памяти, АЦП/ЦАП, периферийных модулей... |
27.08.2012, 16:02
|
|
Гуру портала
Регистрация: 20.11.2004
Сообщений: 10,015
Сказал спасибо: 936
Сказали Спасибо 2,269 раз(а) в 1,563 сообщении(ях)
|
Re: Mega32+SD
Сообщение от Easyrider83
|
Есть готовый код низкоуровневых операций, но я его под stm32 писал.
|
А что там может так зверски отличаться ?
Окромя инита SPI и дерганья вручную CS ???
__________________
Осторожно , злой кот
|
|
|
|
27.08.2012, 16:23
|
|
Гуру портала
Регистрация: 27.10.2008
Адрес: ЕС
Сообщений: 10,835
Сказал спасибо: 919
Сказали Спасибо 4,308 раз(а) в 2,573 сообщении(ях)
|
Re: Mega32+SD
|
|
|
|
27.08.2012, 16:30
|
|
Гуру портала
Регистрация: 20.11.2004
Сообщений: 10,015
Сказал спасибо: 936
Сказали Спасибо 2,269 раз(а) в 1,563 сообщении(ях)
|
Re: Mega32+SD
Сообщение от Easyrider83
|
Ну хотя бы тем, что работает
|
Собственно мысль верная . Выкинуть на avr и сделать все на STM.
Для ТС, у меня подобная схема глючила страшно . Пока не выкинул преобразователи , не запитал все от 3.3 v и не поставил pullup на все выводы у SD карты ...
__________________
Осторожно , злой кот
|
|
|
|
27.08.2012, 16:44
|
|
Гуру портала
Регистрация: 27.10.2008
Адрес: ЕС
Сообщений: 10,835
Сказал спасибо: 919
Сказали Спасибо 4,308 раз(а) в 2,573 сообщении(ях)
|
Re: Mega32+SD
Код старый, но рабочий. Привязки к железу нет. Почти нет. Допилить легко.
Код:
|
#include "SDMMC.h"
#include "LCDv1.h"
char inbuff[Data_Size];
char outbuff[Data_Size];
/************************************************** *****************************
* Function Name : SDMMC_Init
* Description : Initialize SDMMC card
* Input : - SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
* Output : None
* Return : 0 if no ERROR appears, ERROR CODE in case of ERROR
************************************************** *****************************/
u8 SDMMC_Init(SPI_TypeDef* SPIx)
{
u8 cnt,tmp;
init_all(SPIx);
PIN_ON(CS_GPIO, CS);
for(cnt=0;cnt!=10;cnt++)SPI_SendByte(0xFF,SPIx);
PIN_OFF(CS_GPIO, CS);
SDMMC_Send_Cmd(SPIx,CMD0,0,0x95);
tmp=0xFF;
cnt=0;
while((tmp!=0)&(cnt!=Max_Init_Repeats))
{
tmp=SDMMC_Send_Cmd(SPIx,CMD1,0,1);
cnt++;
}
if (cnt==Max_Init_Repeats) return SDMMC_ERROR_INIT;
if (tmp!=0) return tmp;
return 0;
}
/************************************************** *****************************
* Function Name : SDMMC_Send_Cmd
* Description : Send command to SDMMC card
* Input : - SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
* : - index - command number
* : - argument [optional] - parameters for command
* : - crc [optional] - control summ
* Output : None
* Return : 0 if no ERROR appears, ERROR CODE in case of ERROR
************************************************** *****************************/
u8 SDMMC_Send_Cmd(SPI_TypeDef* SPIx, u8 index, u32 argument, u8 crc)
{
u8 cnt,tmp;
SPI_SendByte(((index&0x1F)|(1‹‹6)),SPIx); //index send
SPI_SendByte(((argument&0xFF000000)››24),SPIx);
SPI_SendByte(((argument&0x00FF0000)››16),SPIx);
SPI_SendByte(((argument&0x0000FF00)›› 8),SPIx);
SPI_SendByte(((argument&0x000000FF)›› 0),SPIx);
SPI_SendByte(crc,SPIx); //crc send
cnt=0;
do
{
tmp=SPI_ReadByte(0xFF,SPIx);
cnt++;
}
while ( ((tmp&0x80)!=0x00)&&(cnt‹Max_Response_Times) );
if(cnt==Max_Response_Times) {return SDMMC_ERROR_RESPONSE;} else {return tmp;}
}
/************************************************** *****************************
* Function Name : SDMMC_Read_Data
* Description : Receives data from SDMMC card
* Input : - SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
* : - adrs: adress of reading block (0x200 equal)
* Output : 512 bytes to inbuff[512] array
* Return : 0 if no ERROR appears, ERROR CODE in case of ERROR
************************************************** *****************************/
u8 SDMMC_Read_Data(SPI_TypeDef* SPIx, long adrs)
{
u8 tmp;
u16 cnt=0;
if (SDMMC_Send_Cmd(SPIx,CMD17,adrs,1)!=0) return SDMMC_ERROR_READ;
cnt=0;
tmp=0xFF;
while((cnt!=Max_Response_Times)&(tmp==0xFF)) //wait token
{
tmp=SPI_ReadByte(0xFF,SPIx);
cnt++;
}
if(cnt==Max_Response_Times) {return SDMMC_ERROR_RESPONSE;}
if (tmp!=0xFE) return SDMMC_ERROR_TOKEN;
for(cnt=0;cnt!=512;cnt++) inbuff[cnt]=SPI_ReadByte(0xFF,SPIx);
tmp=SPI_ReadByte(0xFF,SPIx);
tmp=SPI_ReadByte(0xFF,SPIx);
return 0;
}
/************************************************** *****************************
* Function Name : SDMMC_Read_Block_Num
* Description : Receives data from SDMMC card
* Input : - SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
* : - block_num: number of reading block
* Output : 512 bytes to inbuff[512] array
* Return : 0 if no ERROR appears, ERROR CODE in case of ERROR
************************************************** *****************************/
u8 SDMMC_Read_Block_Num(SPI_TypeDef* SPIx, long block_num)
{return SDMMC_Read_Data(SPIx, (block_num*0x200));}
/************************************************** *****************************
* Function Name : SDMMC_Write_Block_Num
* Description : Stores data to SDMMC card
* Input : - SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
* : - block_num: number of writing block
* Output : None
* Return : 0 if no ERROR appears, ERROR CODE in case of ERROR
************************************************** *****************************/
u8 SDMMC_Write_Block_Num(SPI_TypeDef* SPIx, long block_num)
{return SDMMC_Write_Data(SPIx, (block_num*0x200));}
/************************************************** *****************************
* Function Name : SDMMC_Write_Data
* Description : Stores data to SDMMC card
* Input : - SPIx: where x can be 1, 2 or 3 to select the SPI peripheral.
* : - adrs: adress of writing block (0x200 equal)
* Output : None
* Return : 0 if no ERROR appears, ERROR CODE in case of ERROR
************************************************** *****************************/
u8 SDMMC_Write_Data(SPI_TypeDef* SPIx, long adrs)
{
u8 tmp;
u16 cnt=0;
tmp=SDMMC_Send_Cmd(SPIx,CMD24,adrs,0x95);
if (tmp!=0) return SDMMC_ERROR_READ;
SPI_SendByte(0xFF,SPIx);
SPI_SendByte(0xFE,SPIx); //TOKEN SEND
for(cnt=0;cnt‹Data_Size;cnt++) SPI_SendByte(outbuff[cnt],SPIx); //send 512 bytes data
SPI_SendByte(0xFF,SPIx);SPI_SendByte(0xFF,SPIx); //CRC
tmp=(SPI_ReadByte(0xFF,SPIx)&0x05);
if(tmp!=0x05) return SDMMC_ERROR_WRITE; //check answer
cnt=0;
do
{
tmp=SPI_ReadByte(0xFF,SPIx);
cnt++;
}
while((cnt!=Max_Response_Times)&(tmp!=0xff));
if(cnt›=Max_Response_Times) {return SDMMC_ERROR_RESPONSE;}
return 0;
} |
|
|
|
|
27.08.2012, 16:49
|
|
Прописка
Регистрация: 14.06.2012
Сообщений: 263
Сказал спасибо: 2
Сказали Спасибо 129 раз(а) в 103 сообщении(ях)
|
Re: Mega32+SD
Сообщение от Easyrider83
|
Тайминги там не так важны - карта все равно быстрее. Там важно дожидаться флага готовности.
|
Я писал не о таймингах сигнала, а именно о времени внутренних операций, которые могут занимать несколько миллисекунт. В доках это тоже зовется таймингом.
Цитата:
|
10 байт х 8 бит = 80 тактовых импульсов на вывод CLK.
|
Да там автор программно эмулирует работу SPI. Спрашивается - с жуя ли? Отмазка о плохой переносимости кода слабо канает.
Я же сразу топикстартеру советовал применить аппаратный SPI в режиме 0 и не париться ваапсче. Вообще, для практического изучения работы с SD (или MMC) топикстартеру настоятельно рекомендую написат свой собственный код. Писать на первых порах можно предельно примитивно, не заморачиваясь красивостью кода.
Прямо так по порядку и писать:
-- Ждать обнаружения карты в разъеме (там есть контакты присутствия карты).
-- Запустить отсчет 250 мс от включения питания (или от вставки SD карты в разъем.
-- Передать по SPI 10 байт 0xFF на небольшой скорости, за время 1 мс
-- CS=0
-- передать по SPI 0х40, 0х00, 0х00, 0х00, 0х00, 0х95
-- передавать еще байты 0xFF и смотреть, что принимается при этом, ожидая байт 0х01
-- передать по SPI байты 0х48, 0х00, 0х00, 0х00, 0х00, 0х95. (Команда CMD8 для версии 2.0 и старше). Байтом 0х95 я обозначаю просто последний передаваемый байт в команде, поскольку в SPI режиме по умолчанию выключена проверка CRC. Главное, чтобы младший бит был равет 1. Если хочется использовать CMD1, то используйте ее на свой риск - я предупреждал о последствиях.
-- передать еще несколько 0xFF до получения ответа R7, описанного в мануале и передать еще 5 раз 0хFF, принимая 5 байт ответа R7.
Если вместо ответа R7 возвращается ответ R1 с ошибкой Illegal Command (0х04), то используемая карта имеет версию 1.х и тогда нужно попробовать передать команду ACDM41 (0х69, 0х00, 0х00, 0х00, 0х00, 0х95). и проверить ответ на нее - должен вернуться ответ R1 без ошибок (0x00). Если возвращается 0х01 - повторить еще раз эту команду.
CS поднимать в "1" нельзя до завершения передачи и получения ответа.
...
ну и так далее.. Так и пиши, по порядку.
В мануале же написано. Да, читать долго, но на форуме описывать это тоже не быстро. Вона я скока букав уже исписал. А толку то?
Не забываем про врмя выполнения некоторых команд.
Если инициализация у тебя получится, значит, получится и остальное. Делай все по тому же принципу - просто передавай байты команд и "пустые" 0xFF, читай принятые и анализируй их и всё получится.
Easyrider83, на новых SD-шках не проканает из-за пресловутой CMD1. Ну не понимают они такой команды и все тут. Вон, даже топикстартер об этом писал. Спасает только CMD0 - CMD8 - ACMD41. И вот после нее, если хочешь, можешь CMD1 для рестарта.
Цитата:
|
Не нашёл у автора установку размера блока CMD16(SET_BLOCKLEN), он определённо уверен, что бывает только 512 байт.
|
Ну если тому автору не нужно было менять размер блока, то он и не менял его. Один фик, CMD16 влияет только на рабзмер блока чтения. А писать то все равно по 512 байт. Это же SPI режим, а не SD. Более того, изменить размер блока можно только для карт SDSC, для остальных - он фиксированный в 512 байт
Последний раз редактировалось Алекс Василич; 27.08.2012 в 17:08.
|
|
|
|
27.08.2012, 16:59
|
|
Гуру портала
Регистрация: 27.10.2008
Адрес: ЕС
Сообщений: 10,835
Сказал спасибо: 919
Сказали Спасибо 4,308 раз(а) в 2,573 сообщении(ях)
|
Re: Mega32+SD
Сообщение от Алекс Василич
|
Я писал не о таймингах сигнала, а именно о времени внутренних операций, которые могут занимать несколько миллисекунт. В доках это тоже зовется таймингом.
|
Так это по биту занятости проверяется.
|
|
|
|
27.08.2012, 17:08
|
|
Почётный гражданин KAZUS.RU
Регистрация: 19.08.2006
Адрес: Львов
Сообщений: 1,616
Сказал спасибо: 65
Сказали Спасибо 315 раз(а) в 264 сообщении(ях)
|
Re: Mega32+SD
__________________
С уважением,
Vic / ut1wpr
Последний раз редактировалось ut1wpr; 27.08.2012 в 17:13.
|
|
|
|
27.08.2012, 17:11
|
|
Частый гость
Регистрация: 25.08.2012
Сообщений: 11
Сказал спасибо: 0
Сказали Спасибо 5 раз(а) в 5 сообщении(ях)
|
Re: Mega32+SD
Благодарю за потраченное на меня время, буду дальше пробовать.
|
|
|
|
27.08.2012, 17:27
|
|
Прописка
Регистрация: 14.06.2012
Сообщений: 263
Сказал спасибо: 2
Сказали Спасибо 129 раз(а) в 103 сообщении(ях)
|
Re: Mega32+SD
Цитата:
|
Так это по биту занятости проверяется.
|
Разумеется. Но прикинь, обмен идет на околомегабитных скоростях и тебе придется постоянно дергать проверку вместо выполнения какой-либо другой операции.
А зная время выполнения, ты уже будешь лучше организовывать работу кода.
|
|
|
|
27.08.2012, 18:10
|
|
Почётный гражданин KAZUS.RU
Регистрация: 19.08.2006
Адрес: Львов
Сообщений: 1,616
Сказал спасибо: 65
Сказали Спасибо 315 раз(а) в 264 сообщении(ях)
|
Re: Mega32+SD
Сообщение от Алекс Василич
|
Разумеется. Но прикинь, обмен идет на околомегабитных скоростях и тебе придется постоянно дергать проверку вместо выполнения какой-либо другой операции.
А зная время выполнения, ты уже будешь лучше организовывать работу кода.
|
Дергать ведь придется не побитно. И даже не побайтно. Пишем ведь блоками. Побайтно мы заполняем буфер МК. Потом этот буфер "сливаем" во внутренний буфер карты и инициируем запись блока. Вот перед этой процедурой и есть смыл притормозить на проверку бита занятости. Никуда не денешься. Механизма выдачи интеррапта по окончанию записи в карте не предусмотрено, какой-то поллинг все равно будет иметь место. А вот заранее задавть какие-то гарантированные задержки - это нонсенс. Время записи у разных производителей разное. Да оно разное даже внутри серии...
__________________
С уважением,
Vic / ut1wpr
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 08:34.
|
|