LINUX.ORG.RU

Не получаю правильного ответа на команду Programming Enable ATmega8A

 ,


0

1

Пару месяцев назад собрал AVR программатор на ft232rl по схеме http://we.easyelectronics.ru/AVR/usb-programmator-dlya-mikrokontrollerov-avr-... В Windows на старой версии avrdude из статьи все работало, но мне очень хочется чтобы тоже самое работало и на Linux/MacOS. Для этого я решил для начала написать простую программу на libftdi 1.1, которая включала бы микросхему и пыталась послать команду Program Enable на ATmega8A https://gist.github.com/goganchic/b88c85b0ea652e66a320.

Какие проблемы наблюдаются:

  • перед отправкой команд я полностью очищаю буфер микросхемы. Потом в режиме SYNCBB я записываю и считываю одно и то же количество байт, но при этом чаще всего после выполнения всех команд остается 1 байт в буфере на чтение. Может быть я неправильно понимаю принцип работы синхронного bitbang режима у микросхем ft232rl?
  • ATmega8A неверно отвечает на команду Programming Enable, то есть такое ощущение что я то ли неправильно записываю эту команду, то ли неправильно вычитываю.

Железный сетап 100% безпроблемный, сужу об этом по следующим фактам:

  • если воткнуть этот же программатор в windows машину - то avr-ка прошивается как положено
  • на linux и mac os включал последовательно каждый вывод и проверял тестером
    • при записи 1 на выход (MOSI, SCK, RESET) - напряжение 5в, при записи 0 - напряжение 0в
    • при записи 0 в буфер - все выходы активны, при записи 1 в буфер - все выходы отключены
    • при подключении 0 к MISO - считывается 0, при подключении 5В - считывается 1

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

Заранее спасибо за ответы!

Ответ на: комментарий от yax123

Первым делом попробовал avrdude 6.1, начнем с того, что конфиг виндовой патченой версии отличается от конфига который надо подсунуть в avrdude 6.1 чтобы работала связка ft232rl + буферная микросхема. Методом проб, ошибок и изучения исходников я подобрал что нужно выставить, но вот в чем дело: при попытке получить fuse-биты все работает, а при попытке прошить avr-ку - сначала проводится проверка подписи (чтобы удостовериться что микросхема именно ATmega8A), а потом - непосредственно сам процесс прошивки. Так вот, при проверке подписи ответ на Programming Enable - корректный, а при последующей записи прошивки - нет, поэтому прошивка не начинается. Если использовать опцию отключения проверки подписи - то заливка прошивки происходит, но видимо не так как надо, поэтому avr-ка потом не работает.

В исходных кодах avrdude 6.1 непонятно зачем создается доп. поток (thread) который параллельно с записью данных в ft232rl производит чтение, что конечно же затрудняет понимание исходников и процесс отладки. Как я понял, это сделано из-за особенностей работы sync bitbang режима микросехмы ft232rl, который описан на сайте производителя. К сожалению, то ли из-за моей непомерной тупости, то ли из-за ужасной кривизны документации, я так до конца и не понял как работает этот самый sync bitbang режим, поэтому и пытаюсь разобраться с ним путем проб и ошибок.

Как я понял, чтобы прочитать текущее состояние входов в режиме sync bitbang необходимо записать 1 байт данных. Если же ничего не записывать в микросхему - то прочитать ничего невозможно. Из этого я сделал вполне логичный вывод: если преварительно очистить буфер чтения и последовательно производить операции чтения и записи - то прочитать можно ровно столько байт данных, сколько было записано. На практике я получаю ситуацию, когда записывается 64 байта, а прочитать можно 64 + 1, а в некоторых случаях - просто 64 байта.

Отсюда и возникает глобальный вопрос: где в моем коде баг из-за которого Programming Enable не получает правильного отклика от avr-ки и более конкретный взаимосвязанный вопрос: откуда этот дополнительный байт?

Goganchic ★★ ()
Ответ на: комментарий от Goganchic

Xм. Может стоит в сети поискать у кого взлетела связка avrdude+ft232rl прежде чем нырять в исходники?

Насчет синхробитбанга: в целом это единственное, что там работает (из битбангов). Точней это то, что у всех завелось. Примеров работы остального в сети не встречал. Работает это примерно так:

// записываем в порт массив  data_out, размером index
ftStatus = FT_Write(ftHandle, data_out, index, &dwBytesInQueue);
// потом в цикле ждем пока в очереди на прием (RxQ) не появится нужное количество данных.
<loop> {
  ftStatus = FT_GetStatus(ftHandle, &RxQ, &TxQ, &Event);
  if(RxQ>= index) break;
}
// потом читаем все что там в очереди лежит
ftStatus = FT_Read(ftHandle, data_in0, RxQ, &dwBytesInQueue); 
соответственно при каждой выдаче байта в параллельный порт ft232rl, она перед этим читает состояние этого порта и складывает в свой буфер. Состояние этого буфера читаем через FT_GetStatus. Тонкий момент - буфер нужно всегда вычитывать после каждой записи (иногда это не очевидно).

yax123 ★★★★ ()

теперь собери USBASP, прошей контроллер на нем тем, что у тебя есть из под оффтопика и наслаждайся.

WRG ★★★★ ()
Ответ на: комментарий от yax123

Xм. Может стоит в сети поискать у кого взлетела связка avrdude+ft232rl прежде чем нырять в исходники?

так в винде же работает на старой версии, поэтому я и захотел поднять так же, но не в винде :)

Тонкий момент - буфер нужно всегда вычитывать после каждой записи (иногда это не очевидно)

вычитывать насколько? Я читаю ровно столько же, сколько пишу.

Алгоритм такой: включил SYNCBB, потом вычитал все что есть, потом записал 4 байта и вычитал 4 байта, а после этого каким-то макаром смог вычитать еще 1 байт, причем не всегда, скажем в 9 случаях из 10 я могу вычитать еще 1 байт, а 1 раз из 10 - не могу.

теперь собери USBASP, прошей контроллер на нем тем, что у тебя есть из под оффтопика и наслаждайся

собрать USBASP - это легкий путь, хочется именно с ft232rl, чтобы в случае чего припаять ее к какой-нибудь поделке своей и получить возможность прошивать обновления через usb, без программатора

Goganchic ★★ ()
Ответ на: комментарий от Goganchic

так в винде же работает на старой версии

неверно считать, что кто угодно может написать кросс платформенную прогу в которой все будет одинаково для всех платформ. Искать «успех» именно для варианта в линуксе.

вычитывать насколько?

Смотря как считать, я сначала жду прихода всех данных, а потом уже читаю, столько сколько лежит в буфере.

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

Лично я бы поступил так (проверенный вариант). Взял бы логический анализатор (мне нравится u-logic от 6-lab). Записал обмен для успешного случая (например через винду), потом то же самое для неуспешного. И сравнил бы дампы.
Можно еще написать парсер, который бы выдавал уже осмысленные коды команд и данных.
Гарантированный вариант успеха.

yax123 ★★★★ ()
Ответ на: комментарий от Goganchic

Смотрю ты и на forum.easyelectronics уже нафлудил.

Глянул твой код. Я использовал оригинальную библиотеку от ftdi: libftd2xx1.1.12.tar.gz

Возможно поделка от intra2net не так хороша в сравнении с тем, что сделал автор железки.

yax123 ★★★★ ()
Ответ на: комментарий от Goganchic

Итак, на новую либу переходить не стал, но разобрался с багами в текущем коде, теперь ответ приходит правильный. Если кому-то интересно, описываю какие были баги (достаточно глупые, на самом деле)

  • Почему иногда был фантомный байт - в некоторых командах я записываю и вычитываю 1 байт, при этом не было проверки того, что вычитался именно 1 байт. В результате: вычитывалось 0 байт и повторного чтения не происходило, а потом в следующем вызове я получал этот недочитанный байт.
  • Почему ATmega8A неверно отвечала на команду Programming Enable: во-первых см. предыдущий пункт, во-вторых - я неверно записывал данные в буфер отправки (байты шли по неправильному смещению и перекрывали друг друга) и в-третьих я записывал неправильные байты, т.е. был кривой макрос SET_BITS_0 (плохо адаптировал макрос из avrdude)

правильный макрос такой:

#define SET_BITS_0(x,pinbit,level) (((x) & ~(1 << (pinbit))) | ((level && 1) << (pinbit)))

в общем, как оказалось - всему виной кривые руки, библиотека непричем

теперь буду дальше разбираться почему неправильно работает avrdude 6.1, может даже зачиню его :)

Goganchic ★★ ()
Последнее исправление: Goganchic (всего исправлений: 1)
Ответ на: комментарий от Goganchic

в некоторых командах я записываю и вычитываю 1 байт, при этом не было проверки того, что вычитался именно 1 байт. В результате: вычитывалось 0 байт и повторного чтения не происходило

:)
именно поэтому сначала, ждем появления данных (а они появляются крайне нерегулярно) и только потом вычитываем столько сколько появилось.

yax123 ★★★★ ()
Ответ на: комментарий от yax123

в libftdi нет аналога FT_GetStatus, можно только попытаться прочитать и в ответ получить число реально прочитанных байт, поэтому чуть-чуть другой алгоритм

Goganchic ★★ ()
Ответ на: комментарий от Goganchic

в libftdi нет аналога FT_GetStatus

как я удачно-то библу выбрал, а то бы побегал по граблям (хотя конечно побегал).

yax123 ★★★★ ()
Ответ на: комментарий от yax123

если честно - я не вижу особой разницы между: «проверять есть ли 10 байт для чтения а потом прочттать все разом» и «пытаться прочитать много раз подряд пока не наберется в сумме 10 байт»

баг был скорее в том что я считал что с первого раза смогу прочитать 10 байт и не проверял ошибки

Goganchic ★★ ()

Я собирал avrdude сам для программатора на ft232. Могу скинуть бинарники, если актуально.

CYB3R ★★★★★ ()
Ответ на: комментарий от Goganchic

не вижу особой разницы

Я на шоколадку не поспорю, но вроде как иногда приходит чуть больше байт. Чем надо, а вычитать тем не менее надо все.
Но в целом не настаиваю.

yax123 ★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.