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

Spi Флешки - Написание Программатора На C++


Рекомендуемые сообщения

Пытаюсь разобраться в программировании устройств при помощи SPI интерфейса, вроде прочитал несколько статей, и вроде как понял как работать с LPT портом в данной задачи, у меня есть флеш MX25L3205, помогите понять как ее читать и также программировать, пытался читать даташит по ней, но к сожалению ничего не понял - с английским совсем плохо. Как получить ID флеш? Какие команды правильно подать и какой такт должен быть. Подскажите как мне правильно с ней работать.

P.S. у самого имеется Willem, но хотелось бы написать программу для работы с такими флеш!

Спасибо за внимание.

Изменено пользователем gafbich
Ссылка на комментарий
Поделиться на другие сайты

Пытаюсь разобраться в автомобилестроении, вроде разобрался, как пользоваться гаечным ключом, пытался читать иностранные чертежи - но плохо с английским. Напишите ка мне здесь, как построить автомобиль своими руками

(утрирую)

Вобщем это к тому, что Вам нужно онлайн-переводчиком воспользоваться, или подучить технический английский. Не будут же Вам форумчане в "10-ти" томах (утрирую) объяснять принципы работы флеш-памяти, а следом работу SPI интерфейса, а потом ещё как одно с другим взаимодействует именно в вашей микросхеме...

Если в качестве ответа хотели русскую версию датащита получить, то эт Вам на сайт переводчиков надо обращаться.

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

Сравнительное тестирование аккумуляторов EVE Energy и Samsung типоразмера 18650

Инженеры КОМПЭЛ провели сравнительное тестирование аккумуляторов EVE и Samsung популярного для бытовых и индустриальных применений типоразмера 18650. 

Для теста были выбраны аккумуляторы литий-никельмарганцевой системы: по два образца одного наименования каждого производителя – и протестированы на двух значениях тока разряда: 0,5 А и 2,5 А. Испытания проводились в нормальных условиях на электронной нагрузке EBD-USB от ZKEtech, а зарядка осуществлялась от лабораторного источника питания в режиме CC+CV в соответствии с рекомендациями в даташите на определенную модель. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

Так никто не запрещает Вам читать даташит прямо из PDF файла с переводом.

Конечно пару технических слов переводить будет кривовато, но всё же понять можно.

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

Новый аккумулятор EVE серии PLM для GSM-трекеров, работающих в жёстких условиях (до -40°С)

Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре. 

Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств. Подробнее параметры и результаты тестов новой серии PLM по ссылке.

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

Литиевые батарейки и аккумуляторы от мирового лидера  EVE в Компэл

Компания Компэл, официальный дистрибьютор EVE Energy, бренда №1 по производству химических источников тока (ХИТ) в мире, предлагает продукцию EVE как со склада, так и под заказ. Компания EVE широко известна в странах Европы, Америки и Юго-Восточной Азии уже более 20 лет. Недавно EVE была объявлена поставщиком новых аккумуляторных элементов круглого формата для электрических моделей «нового класса» компании BMW.

Продукция EVE предназначена для самого широкого спектра применений – от бытового до промышленного. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

Написал маленькую инструкцию.

Без стороннего софта тут не обойтись. Скачиваем две программы, SumatraPDF - читалка PDF и QTranslate - переводчик, устанавливаем и настраиваем.

Открываем Ваш Datasheet, мышью отмечаем текст, два раза кликаем Ctrl, и перевод открывается в маленьком окне QTranslate, читаем, всё легко и просто.

P.S. Обе программы есть в портативной версии. Текст отмечаем по немножку, конечно может с первого раза не получится, но привыкните. И ещё, с картинок НЕ ПЕРЕВОДИТ!

Лично Adobe Reader для чтения не пользуюсь, тяжёлая и неповоротливая программа, да и много весит.

Надеюсь поможет изучению технического Английского. Удачи.

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

Вроде, как я понял для начало надо сформировать фронт импульса (1,4 мс) на SCLK. Для того чтобы определить флеш, при подачи на SI команду 9F на протяжении 8 тактов и прочитать с SO идентификатор (RDID). Подскажите правильно ли я описал процедуру получения идентификатора флеш?

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

Подскажите правильно ли я описал процедуру получения идентификатора флеш?

Правильно вроде. Но чтобы больше было понятно, снова работаем с датащитом.

The RDID instruction is for reading the manufacturer ID of 1-byte and followed by Device ID of 2-byte. The MXIC

Manufacturer ID is C2(hex), the memory type ID is 20(hex) as the first-byte device ID, and the individual device ID of

second-byte ID is as followings: 16(hex) for MX25L3205.

Приблизительный перевод: возвращает 1 байт идентификатора производителя (С2h) и два байта идентификатора устройства - первый из них тип памяти (20h) и второй индивидуальный идентификатор устройства (16h)

The sequence of issuing RDID instruction is: CS# goes low-> sending RDID instruction code -> 24-bits ID data out on SO

-> to end RDID operation can use CS# to high at any time during data out. (see Figure. 14)

Приблизительный перевод: последовательность сигналов для выполнения инструкции - CS в низкий уровень, передача кода инструкции, приём 24 бит данных, сигналом CS->высокий уровень можно прервать операцию в любой момент передачи идентификатора.

Смотреть рисунок 14.

Смотрим рисунок 14 и видим без всякого перевода, как что подавать:

post-159698-0-12570000-1362927840_thumb.jpg

Дополнение:

Вобщем суть такова - пользуйтесь переводчиком и почаще в графики заглядывайте - их там полдатащита на все случаи.

Изменено пользователем tcoder
Ссылка на комментарий
Поделиться на другие сайты

Огромное спасибо, я изначально подумал что принимается 8 бит, не предал значение полной диаграмме. Попробую сегодня написать, считать ID флешки.

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

не предал значение полной диаграмме.

Ну это не художественное произведение, а техническая информация - временная диаграма. Там нельзя упускать детали.

Попробую сегодня написать, считать ID флешки.

Вы главное её к питанию не забудьте подключить :) . (Вы про свой уровень знаний в электронике не сообщили)

Изменено пользователем tcoder
Ссылка на комментарий
Поделиться на другие сайты

Не ну к питанию то подключу, (3.3В) (HOLD, WP, Vcc), Не ну Мультивибраторы когда-то собирал)) Я не претендую на специалиста в этой области, но одолевает желание быть им!)

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

А согласование с LPT есть? LPT под 5 вольт даёт сигналы.

не претендую на специалиста в этой области, но одолевает желание быть им!)

Тогда в любом случае нужно подтягивать английский, или осваивать инструментарий перевода, т.к. большая часть полезных микросхем производится за границей, соответственно и датащиты на русском - редкость.

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

Питание флешка получит от лабораторного источника питания (3.3В). А шина данных D0(CS#), D1(DI), D2(SCLK), S6(DO) будет согласована сопротивлением на 100-150 Ом. Завтра (если сил останется после работы) макетку соберу по-возможности. Попробую. Отпишусь

Вопрос один остается, как правильно такт сформировать на выводе D2 . в виде задержки на 1мс сначала лог. 0 задержка, потом лог. 1 и т.д.?!

Изменено пользователем gafbich
Ссылка на комментарий
Поделиться на другие сайты

Чтобы такт формировать, просто нужно 0 и 1 чередовать на SCLK. При спаде в 0 одновременно меняете передаваемый бит, при переходе в 1 - снимаете принимаемый бит. Задержка не факт что нужна, т.к. SPI намного быстрее может работать, чем LPT. Хотя для надёжности можно и задержку поставить. Желательно после CS->0 поставить задержку.

И после обмена данными не забывать SCLK вернуть в то же состояние, в котором он был изначально, чтобы не возникло путаницы с уровнем сигнала при следующем "сеансе связи". В каком состоянии держать SCLK в момент простоя - Вам решать, по идее микросхема переварит любой вариант (поддержка SPI режимов "0" и "3").

С резистивными делителями от lpt к flash понятно, а в обратном направлении как согласовали?. Тут и уровень напряжений опять не совпадает, и насколько я помню, в LPT на входы резистор подтяжки к питанию установлен.

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

Собрал макет, написал небольшой код на С++, использовал библиотеку для работы LPT (inpout32)

#include "iostream.h"
#include "conio.h"
#include "stdlib.h"
#include "h.h"
#include "time.h"

void Delay(int Millisec){
int StartTime=clock();
int StopTime=StartTime+Millisec;
while(clock()<StopTime);
}

void main()
{
 int Address = 888;
 int Address2 = 889;
 short x[8]={4,0,0,4,4,4,4,4};
 short s;
 int n=0;
 int d=0;


Out32(Address,0);
 while( 1 )
 { 
  Out32(Address,0);
  Delay(1);
  //cout<<n<<" = "<<x[n]<<endl;
  //cout<<x[0]<<" 0"<<endl;
  Out32(Address,x[n++]);

  Out32(Address,2);

  if(n==8)break;
  Delay(1);
 }
 Delay(1);
 while( 1 )
 { 
  Delay(1);
  Out32(Address,0);
  s=Inp32(Address);
  cout<<s<<endl;
  //Out32(Address,2);
  d++;
  if(d==24)break;
  Delay(1);
 }
 getch();
}

результат опроса порта LPT регистра DATA - все "0". А когда принимал данные от DO регистром Status - было некое чередование 1 и 0, когда решил DO повесить на регистр DATA на вывод D3 - теперь только нули, как-будто ничего не принимается.

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

результат опроса порта LPT регистра DATA - все "0", когда решил DO повесить на регистр DATA на вывод D3 - теперь только нули, как-будто ничего не принимается.

Этот регистр не может одновременно в обе стороны работать. Он по умолчанию настроен на выход. При чтении выдаётся содержимое защёлок скорее всего. За направление отвечает какой то из битов ещё одного регистра LPT. Если он на приём настроен, тогда должны единички читаться, управляться должен замыканием контакта на ноль. При этом способность в обе стороны работать зависит ещё и от режима порта - настраивается в BIOS (там EPP, ECP и т.д.). Причём эти режимы и на управляющий регистр как то влияли. Толком ничего не помню - но в инете полно русскоязычной информации про устройство LPT - почитайте. Но на мой взгляд лучше не использовать DATA в обе стороны - мороки меньше. Также не стоит забывать, что порт с программой не связан, и остаётся в том состоянии, в каком его бросили. А потому нужна инициализация в программе.

А когда принимал данные от DO регистром Status - было некое чередование 1 и 0

А что же Вы эту последовательность не считали? Там конкретные цифры должны считываться: С0h-20h-16h (1100-0000-0010-0000-0001-0110) - на последние 24 такта, первые 8 тактов - передача команды 9F. Возможно в инверсном виде будут считываться. А некое чередование 0 и 1 - в SPI ничего кроме этого и не может быть)

Касательно программы - выложите код с комментариями, неохота и лень гадать, что Вы там где имели ввиду. В третьем куске выдачи такта не видно, закомментирован чтоле? И схему подключения к порту выложите наглядную (та, которая через status)

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

Посмотрел Вашу программу. Она по идее вообще не должна работать :unknw: . В порте картинка далёкая от figure 14 получается, как бы там ни было подключено, или я чего то не понимаю. Может быть выложу вечером свою версию кода :yes:

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

Вот такой кодик - им впринципе можно любую простую операцию реализовывать

.....
//======================================================================================================================
// КОНСТАНТЫ
//======================================================================================================================
//*с помощью данных констант устанавливается фунциональное назначение бита порта
const unsigned char SPI_DO_NUM=6; //Номер бита DO
const unsigned char SPI_DO=64; //Бит S6 (2^6) (01000000)
const unsigned char SPI_SCLK=4; //Бит D2 (2^2) (00000100)
const unsigned char SPI_DI=2; //Бит D1 (2^1) (00000010)
const unsigned char SPI_CS=1; //Бит D0 (2^0) (00000001)
//адреса LPT порта
const int lpt_data=888;
const int lpt_status=889;
//======================================================================================================================
// ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ
//======================================================================================================================
unsigned char port; //переменная-буфер для порта (на всякий случай)
//======================================================================================================================
// ПЕРЕНОС БУФЕРНОЙ ПЕРЕМЕННОЙ НА ВЫХОД
//======================================================================================================================
void UpdatePort(){
cout<<"LPT <= "<<(int)port<<endl;
//Out32(lpt_data,(short)port); //Раскомментировать
}


//======================================================================================================================
// ФУНКЦИЯ ЗАДЕРЖКИ
//======================================================================================================================
void Delay(int ms){
//Заменить на свою функцию задержки
}
//======================================================================================================================
// ФУНКЦИЯ ОТПРАВКИ БАЙТА
//======================================================================================================================
//Отправить байт
void SendByte(unsigned char dta){
cout<<"-- Sending byte "<<(int)dta<<endl<<endl;

//Цикл побитового вывода байта
for (int i=0;i<8;i++){

//Возможная задержка
Delay(1);

//Установка бита SPI_DI в соответствии с перебираемым битом
port=(((1<<(7-i))&dta)>0)?SPI_DI:0x00;
UpdatePort();

//Возможная задержка
Delay(1);
//Инвертирование бита SPI_SCLK (формирование фронта)
port^=SPI_SCLK;
UpdatePort();

cout<<"."<<endl;
}
//Возможная задержка
Delay(1);
}

//======================================================================================================================
// ФУНКЦИЯ ПОЛУЧЕНИЯ БАЙТА
//======================================================================================================================

//Принять байт
unsigned char GetByte(){
unsigned char bf,ov;

//Сброс порта
port=0;
UpdatePort();
//Установка первоначального значения
ov=0;
for (int i=0;i<8;i++){

//Возможная задержка
Delay(1);
//Формирование фронта
port^=SPI_SCLK;
UpdatePort();


//Возможная задержка
Delay(1);
//Получение бита от флеш
bf=0;
//bf=Inp32(lpt_status); //Раскомментировать
bf&=SPI_DO;
bf>>=SPI_DO_NUM;
ov|=bf<<(7-i);
//Возможная задержка
Delay(1);
//Формирование спада
port^=SPI_SCLK;
UpdatePort();
}
return ov;
}

//======================================================================================================================
// ГЛАВНАЯ ФУНКЦИЯ ПРИЛОЖЕНИЯ
//======================================================================================================================
int main(int argc, char* argv[])
{
//Инициализация LPT
//SCLK=0,D=0,CS=1
port=SPI_CS;
UpdatePort();
cout<<"PRESS ANY KEY FOR SENDING COMMAND"<<endl;
getch();

//Активация чипа (всё в ноль)
port=0;
UpdatePort();
cout<<"CHIP SELECTED"<<endl;

//Возможно необходимая задержка
Delay(1);

//Отправка команды "получить id"
SendByte(0x9f);

cout<<"RECEIVE BYTES"<<endl<<endl;

//Приём трех байт с информацией об устройстве
cout<<"FIRST BYTE ="<<(int)GetByte()<<endl;
cout<<"SECOND BYTE ="<<(int)GetByte()<<endl;
cout<<"THIRD BYTE ="<<(int)GetByte()<<endl;
//Отключение чипа (CS=1)
port=SPI_CS;
UpdatePort();
cout<<"OPERATION COMPLETE. CHIP DISABLED. PRESS ANY KEY FOR EXIT"<<endl;

getch();
return 0;
}

Это для вывода через data и ввода через status. Выводы настраиваются константами вначале. Необходимо раскомментировать обращения к порту (у меня нет библы для портов и возиться с ней лень). Функцию задержки заменить на свою. Отлажено в данной конфигурации выводов. Ввод проверял на имитации входных данных с помощью клавиатуры в побитовом режиме однако.... (LPT на моём ноуте нет....)

Вот "перехватограмма" с выхода порта:

post-159698-0-80827200-1363191524_thumb.png

Вроде похож на figure-14 :)

Изменено пользователем tcoder
Ссылка на комментарий
Поделиться на другие сайты

Спасибо, за помощь, буду разбираться с работой Вашей программы, как получиться довести все до конца (задумки) - выложу полный код. Задача будет решенной - когда смогу прочитать и записать в CHIP!

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

Да Вы сначала последовательность ID-устройства считайте. Данный вариант этим и занимается - правда ответ в десятичной системе выдается. Только в UpdatePort(); закомментируйте cout - чтобы консоль сильно не засорял (сделано просто для наглядности - что в порт выводится). Ещё в этой же функции строка вывода в порт - возможно вот так: Out32(lpt_data,(unsigned short)port); - должен быть unsigned перед short вероятно. На всякий случай.

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

Да я вчера ознакомился с Вашей программой, мне понравилось реализация при помощи битових сдвигов, я чего-то даже и неподумал в ту сторону. то что она считывает ID я это понял. Но вот что касается CS# , в главной части программы, Вы устанавливаете его в лог. 1 на чипе будет спад (так как он инвертирован), а вот когда выполняется код

//Активация чипа (всё в ноль)
port=0;
UpdatePort();
cout<<"CHIP SELECTED"<<endl;

то есть на регистре DATA будут все выводы в нуле - соответственно вывод CS# будет в лог 0 - высокий уровень, тем самым прервется операция.

может в этом случае лучше использовать регистр Control (на сколько помню он управляется только программой) - установить на нем нужный уровень или поменять

//port=(((1<<(7-i))&dta)>0)?SPI_DI:0x00
port=(((1<<(7-i))&dta)>0)?SPI_DI:0x01

тогда CS# - будет иметь низкий уровень.

Поправьте если я не прав.

Изменено пользователем gafbich
Ссылка на комментарий
Поделиться на другие сайты

Ну поэтому и просил схему выложить, чтобы небыло путаницы с тем, что как подключено. В моей реализации CS подключен к выходу D0, а насколько я знаю все выходы D0-D7 LPT-порта аппаратно не инвертируются. Соответственно изначально там ставится 1, а потом 0 - для выбора чипа. Если Вы имели ввиду, что микросхема там что то инвертирует, то это учтено - если CS=1, то микра неактивна; если CS=0, то микра активизируется - это и на figure14 описано.

Опишите подробнее, в каком месте CS у вас инвертируется. Будем разбираться однако.

Изменено пользователем tcoder
Ссылка на комментарий
Поделиться на другие сайты

Выкладываю лог, то что получилось. Код получается 192 0 40 = С0 0 28. В одном случае получился C0 0 2C. Задержка используемая в коде ни как не сказалась.

LPT <= 1
PRESS ANY KEY FOR SENDING COMMAND
LPT <= 0
CHIP SELECTED
-- Sending byte 159
LPT <= 2
LPT <= 6
.
LPT <= 0
LPT <= 4
.
LPT <= 0
LPT <= 4
.
LPT <= 2
LPT <= 6
.
LPT <= 2
LPT <= 6
.
LPT <= 2
LPT <= 6
.
LPT <= 2
LPT <= 6
.
LPT <= 2
LPT <= 6
.
RECEIVE BYTES
LPT <= 0
LPT <= 4
LPT <= 0
LPT <= 4
LPT <= 0
LPT <= 4
LPT <= 0
LPT <= 4
LPT <= 0
LPT <= 4
LPT <= 0
LPT <= 4
LPT <= 0
LPT <= 4
LPT <= 0
LPT <= 4
LPT <= 0
FIRST BYTE =192
LPT <= 0
LPT <= 4
LPT <= 0
LPT <= 4
LPT <= 0
LPT <= 4
LPT <= 0
LPT <= 4
LPT <= 0
LPT <= 4
LPT <= 0
LPT <= 4
LPT <= 0
LPT <= 4
LPT <= 0
LPT <= 4
LPT <= 0
SECOND BYTE =0
LPT <= 0
LPT <= 4
LPT <= 0
LPT <= 4
LPT <= 0
LPT <= 4
LPT <= 0
LPT <= 4
LPT <= 0
LPT <= 4
LPT <= 0
LPT <= 4
LPT <= 0
LPT <= 4
LPT <= 0
LPT <= 4
LPT <= 0
THIRD BYTE =40
LPT <= 1
OPERATION COMPLETE. CHIP DISABLED. PRESS ANY KEY FOR EXIT

Ой, проблема решена, проблема была в питание, понизил напряжение - прочитала как надо C2 20 16. Напряжение 3,3В

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

Поздравляю с успешным чтением ID.

Задержка используемая в коде ни как не сказалась.

Теоретически задержки тут вообще лишние. У микросхемы быстродействие в десятки раз выше чем у LPT. Соответственно если задержки убрать, то порт будет работать на пределе своих скоростных возможностей - и всё равно не сможет достигнуть того порога, где микросхема не будет успевать реагировать. (аж на 50МГц она может работать по SPI, а LPT чуть больше 1МГц развивает).

Для эксперимента нейтрализуйте функцию Delay(), а затем попробуйте считать ID. Наверняка всё нормально пройдет, но проверить всё равно надо :)

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

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

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

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

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

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

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

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

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...