Хм, странно, у меня без "больше синхроимпулсов, чем количество бит в прошивке" не заливается, вернее, не проходит фаза startup (то есть не сбрасывается в 0 INIT_B и не устанавливается в 1 DONE). Причем не проходит, даже если импульсы слать, но с DIN, установленным в 0.
Насчет .bit - мой заливается, но, похоже, он действительно сгенерирован так, что не требует CRC. Как проверю - напишу. В теории CRC проверяется только для данных начиная со слова синхронизации, то есть минуя заголовок битника.
UPD Сгенерировал .bit из проекта, поставляемого с платой, проверил, чтобы была включена CRC, - битник залился.
Доброго времени суток, уважаемые efreet и erma. Не могли бы вы мне объяснить исходник конфигурации ПЛИС. На сколько я понял, то для компиляции вполне хватает хедеров board.h (arm\src\flashloader\Atmel\at91lib\boards\at91sam9260-ek) и pio.h (arm\src\flashloader\Atmel\at91lib\peripherals\pio),в IAR никаких проблем с этим не возникло).
Перенес код на плату и мой arm-linux-gnu-gcc при компиляции выдает всякую непотребщину. Подскажите какие хедеры нужно использовать с GCC?(Я сним только начинаю работать).
Насколько я понимаю, для того чтобы сделать из этого драйвер нужно:
1.Создать модуль - Makefile типа такого:
EXTRA_CFLAGS = -Wall -O2
ifneq ($(KERNELRELEASE),)
obj-m := XXXXX.o
else
PWD := $(shell pwd)
ifneq ($(MAKECMDGOALS),clean)
feq ($(ARCH),)
$(error Run using make ARCH=arm CROSS_COMPILE=Путь к компилятору
KERN_DIR=путь к исходникм ядра
Missing ARCH)
endif
ifeq ($(CROSS_COMPILE),)
$(error Run using make ARCH=arm CROSS_COMPILE=Путь к компилятору
KERN_DIR=путь к исходникм ядра.
Missing CROSS_COMPILE)
endif
ifeq ($(KERN_DIR),)
$(error Run using make ARCH=arm CROSS_COMPILE=Путь к компилятору
KERN_DIR=путь к исходникм ядра.
Missing KERN_DIR)
endif
endif
default:
$(MAKE) -C $(KERN_DIR) M=$(PWD) modules
clean:
rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c *.symvers .tmp_versions
endif
2.Написать скрипт загрузки драйвера.
Поправте,если что не так
Здравствуйте, все.
Помогите найти ошибку в процедуре конфигурации ПЛИС.
Имеется плата SK-AT91SAM9XE512-S3E с контроллером AT91SAM9260. При конфигурации в режиме slave serial вывод DONE ПЛИС не поднимается. В опциях генератора файла прошивки указано: drive DONE pin HIGH, disable internal pipe (хотя разрешена или запрещена последняя опция - не влияет). При заливке по JTAG с зажатым ресетом контроллера ПЛИС исправно запускается.
На контроллере запущен линукс с корневой ФС на microSD карте. Соединил дополнительно вывод INIT_B ПЛИС и PC11 контроллера (чтобы из дравера следить за правильностью CRC и различать когда можно дить конфигурацию).
Написал драйвер, заливающий в ПЛИС прошивку по такому алгоритму:
в инициализации драйвера (после команды insmod) выводы DIN, CCLK - выходы с записанной в них 1, PROG_B, DONE и INIT_B - выводы с открытым стоком и записанной в них 1, т.е. уровни на этих линиях задает ПЛИС.
Затем PROG_B опускается в 0 на 1 мкс (по осциллографу).
Ждем, пока INIT_B у ПЛИСС не перейдет в 1 (около 150 - 200 мкс).
Выход из инициализации драйвера.
Затем происходит запись из bin файла в ПЛИС. Производится это программой cat, копирующей побайтно из файла прошивки в драйвер.
В функции записи драйвера запись принятых данных происходит MSB first. Если файл некорректен (скажем, я дописал в него пару символов), то по окончании заливки файла вывод INIT_B ПЛИС опускается в 0. Если же файл корректный, INIT_B после окончания файла прошивки остается в 1.
При выгрузке драйвера в ПЛИС записываю еще 8 единичных бит, выполняя требование мануала UG332. Но вывод DONE не поднимается. Что я делаю не так?
Судя по всему дело в том, что Startup sequence занимает больше синхроимпульсов, чем 8. Сейчас платы под рукой нет, но глянув свой код, обнаружил, что посылаю импульсы с DIN=1 до тех пор, пока DONE не выставится в 1. А уже после этого дополнительно посылаются 8 импульсов, кажется.
так я тоже пробовал, DONE не выставляется даже если пару секунд посылать клюки (до 8М). При этом данные не имеют значение - 0, 1 или вперемешку.
Т.е. после окончания прошивки послать 8 или 8000000 клоков - разницы не увидел. В конце стоял цикл:
прочитать DONE и INIT,
если INIT == 1 и DONE == 0,
записать (от 8 до 1024 в разных билдах) бит (разных данных),
если записано уже много (до 8Мбит), прервать цикл,
и по новой.
а после него еще 8 бит писал.
Просто, не увидев результата и разницы, я заремил этот цикл.
Частоту менял от 200 кГц до 2 МГц. Без изменений.
Спасибо за ответы.
Если вкратце - то же самое, завтра с работы выложу.
различие в том, что я не 3 мс жду, а поллю флаг INIT, допаянный с ПЛИС к контроллеру. Также все выводы разворачиваю на выход (кстати, здесь может и вылезти ошибка), но INIT, PROG и DONE - ставлю открытый сток и пишу 1.
Ну и совершенно неважные вещи типа с 0 до 8 или с 8 до 0 вести цикл:
Вот мой исходник (незначимые части и инициализацию драйвера вырезал, т.к. пользовался работоспособной заготовкой):
Запись в ПЛИС происходит в функции записи, как уже писал - если передавать сознательно испорченный файл, INIT падает в 0 после получения CRC, если файл правильный, то пишется еще 16М бит в ожидании единицы на DONE или нуля на INIT.
При этом записывать 0, 1 или их попеременно - раззницы не увидел.
Кстати, ситуация похожа на прошивку ПЛИС JTАGом без удерживания АРМа в ресете. INIT точно так же не опускается, а DONE точно так же не поднимается.
UPD: проверил, не запирает ли кто-то вывод DONE в ноль - в драйвере переориетнировал его на вход. Не запирает.
Наконец получилось загрузить ПЛИС из АРМа. Причем почему тот же код не работает из уровня ядра, не понял. Может, просмотрел ошибку. В общем, выкладываю программу под линукс, грузящую ПЛИС через GPIO. Собирается кроссплатформенно. Файл прошивки - первый аргумент командной строки. Время загрузки около 0,5 с. Просьба - потестируйте, уважаемые.
Да, еще - R45 был перемычкой, я вместо нее впаял 470 Ом (100 под рукой не было). Вряд ли это важно, тем не менее.