Страница 1 из 1
Пишу софт для программатора. Есть вопросы. Нужен совет
Добавлено: Ср апр 16, 2008 21:55:27
zi4rox
Всем привет,
Вобщем стоит передо мной следющая задача, которую и пробую решить:
Написать управляющую программу для программатора (аля PonyProg, avreal, etc ) для прошивки atmega16 под WinXP посредством LPT.
Тестовая плата и программатор (stk200) готовы, теперь дело за главным - написать пресловутый софт.
В процессе появляются разные вопросы и запарки, поэтому прошу вас помочь добрым советом али просто направить в нужное русло.
Почитав даташит на 16ую мегу понял, что существует специальный алгоритм для начала и непосредственного программирования.
Вольный перевод, то как понял.
Алгоритм последовательного программирования на atmega16:
1. Подать питание, при этом RESЕT и SCK должны быть 0.
2. Подождать как минимум 20 мс затем включить режим SPI Serial Programming [послать 4 байта инструкции на MOSI]
3. Проверить вошел ли контроллер в режим программирования.(Проверить синхронизацию). Когда режим синхронизации установлен, то 2ой байт ответит назад $53 запрашивая при этом 3ий байт. Не зависимо от того был ли правильно получен ответ или нет - нужно обязательно передать все 4 байта. Если этого не произошло, то задать 1 на RESET и повторить заново.
4. FLASH программируется по-странично.
5. EEPROM программируется по-байтно, путем сообщения адреса и информации вместе с подходяшей инструкцией записи.
6. Успешную запись можно проверить считав любой адерс в памяти использую read инструкцию, которая вернет данные по адресу на выход MISO.
7. На RESET подать 1 для начала функционирования.
Вобщем хотел бы все это уже попробывать, да посмотреть что и как, да вот запарки, которые мешают двигаться дальше, надеюсь добрые коты помогут:
Текущие вопросы-непонятки:
1. Я понял, что общение программатор-мк происходит через SPI интерфейс, т.е через MOSI MISO и SCK. И допустим чтобы войти в режим программирования нужно послать инструкцию (4 байта из даташита) на MOSI.
Вот только не знаю как это сделать

. Читал про ЛПТ порт, пробывал тестовую программу писать - получалось устанавливать высокий и низкий уровень на отдельных пинах лпт. Но как целый байт передавать/считать - ума не приложу. Эта проблемка является следствием 2ой )
2. Ни как не могу разобраться каким пинам на лпт соответсвуют пресловутые MOSI MISO SCK RESET. С GND тут просто 18-25 выводы. а остальные ни как не могу разобраться. Пожалуйста гляньте схематик в аттаче. [Схемкой поделился старший товарищ, но сам он ответить на мой вопрос не смог к сожалению. Сделал скриншот схематика, дабы меньше заморочек было с разными версиями пикадов, да и те у кого его нет могли бы быстренько глянуть]
Вобщем пока эти 2 проблемы-непонятки мешают двигаться дальше. Прошу помощи.
*
Надеюсь также эта темка будет полезна всем кто когда нибудь решит занятся подобным, потому что упорный поиск ничего схожего с данной ситуацией не выдал.
**
Так же буду премного благодарен любой информации по сабжу, любым докам, линкам и инфе.
Добавлено: Чт апр 17, 2008 08:20:10
__Alexander
У ЛПТ, да и соссно и у кома, нет аппаратного SPI. Так что, все делается программно - выставлением 1 или 0 на пинах, и чтением входящего сигнала - эмулируй SPI и все. Протокол обмена ты привел из даташита. Вот и дерзай. Для упрощения могу посоветовать пока буффер не ставить, т.к. в ЛПТ уровень 5В как и в МК, только окуратно соедени 5 проводков. Желательно подтяжку по питанию делать не для MISO, а для RESET.
А вообще должно быть куча схем в инете. Эта же не единственная.
Вот к примеру
http://avr.nikolaew.org, там есть программатор uniprof с софтом где можно устанавливать пины для ЛПТ.
Добавлено: Чт апр 17, 2008 08:47:26
ARV
zi4rox, а не желаешь сделать плагин для ChipBoom? необходиму инфу предоставлю, если требуется, и по программному SPI помогу в этом случае.
Добавлено: Чт апр 17, 2008 15:12:20
zi4rox
2__Alexander:
спс за линк - гляну что за uniprof такой.
2 ARV
ChipBoom видел - очень сносный ) С удовольствием попробывал написать плагин, но после того как эту задачу решу. Мне нужна именно своя отдельная софтина, и сроки уже почти поджимают. Так что как разберусь с этим обязательно отпишу.
** Было бы супер если бы ктонить хотя бы схематично набросал как в коде должно выглядеть например чтение прошивки мк. Сам вот этот процесс эмуляции и т.п Я как понял, ведь например понипрогу неважно какие у меня проводки от лпт до мк идут - он работает полюбому. значит там какое то либо стандартное расположение пар пинов, либо как то по особому просто идет это самое общение комп-мк посредством лпт. Хотя бы кусочек кода с чтением мк например чтобы разобраться. АРВ - может покажешь плиз как в чип буме например происходит?
Добавлено: Чт апр 17, 2008 17:03:12
__Alexander
Пофигу как проходит. Я так понял, тебе нужно именно формат SPI. Так вот, практически похож на I2C. Поставил бит DATA, подал 1 на CLK, прочел входной бит, подал 0 на CLK, поменял DATA и т.д. Если по нижнему фронту, то читаешь после подачи нуля.
Вопрос в чем, зачем оно тебе надо, профессиональные (фирменные) программаторы работают быстрее всех осталльных (проверено), у тебя же выйдет тоже, что уже существует на рынке около 10 лет. Зачем? Если для прикола или сдачи курсового, то рекомендую перейти резко с МК на МК. Я пробывал с помощью меги128 прошить 2313 - получилось (код я записал во флэш 128, протокол программный). А ты читай код с MMC или ОЗУ и програмь себе небольшие МК (можно даже аппаратно). А если все же ты для профи - тогда интерфейс ЛПТ ты не по сегодняшним нормам выбрал.
Добавлено: Чт апр 17, 2008 17:08:18
Tohey
В сети куча программаторов, зачем же повторять? Да и LPT щас редко встретишь, а на новых и COM.
Кстати если я не ошибаюсь на PonyProg были какие то исходники на оффсайте.
Добавлено: Чт апр 17, 2008 17:45:43
zi4rox
Сам не люблю изобретать велосипед, понимаю почем ругаете - софтина делается исключительно для сдачи курсовика, ну и + самому есть интерес разобраться как оно и что там.
__Alexander писал(а):Зачем? Если для прикола или сдачи курсового, то рекомендую перейти резко с МК на МК. Я пробывал с помощью меги128 прошить 2313 - получилось (код я записал во флэш 128, протокол программный). А ты читай код с MMC или ОЗУ и програмь себе небольшие МК (можно даже аппаратно).

О! Первый раз про такую штуку слышу. Интересно. Можно поподробнее пожалуйста рассказать? Почитать бы где нить про эту реализацию. * отправлюсь в гугл пока )
Добавлено: Чт апр 17, 2008 18:45:28
__Alexander
О! Штука ни на что есть обычная, только вместо компа - МК. Что ты на ЛПТ бушь сигналы формировать, что на МК, пофигу. За исключением того, что в МК есть аппаратный SPI, что соссно занчится на скорости. Так что для курсовика, покатит программный, цепляй МК <-> МК по SPI далее разберемся.
Добавлено: Чт апр 17, 2008 18:49:56
__Alexander
Ты бы тему курсовика привел или че соссно надо тебе там накалякать, если тебе программатор надо на десяток микрух это одно, а если одну заштить так это совсем другое.
Добавлено: Чт апр 17, 2008 19:00:51
zi4rox
__Alexander писал(а):Ты бы тему курсовика привел или че соссно надо тебе там накалякать, если тебе программатор надо на десяток микрух это одно, а если одну заштить так это совсем другое.
"Софтовая" часть курсовика вот:
Программа, написанная на одном из языков высокого уровня для ПК, которая осуществляет запись скомпилированной программы в микроконтроллер(atmega16) с использованием одного из стандартных портов (LPT). Записанная программа должна быть представлена в HEX коде.
Т.е мне чтобы 16ую мегу прошивало и все. Остальное побарабану.
Собственно вот как оно есть. Может я сам чего нагоняю и все проще чем кажется ?)
Добавлено: Пт апр 18, 2008 00:35:46
abc
Я в Атмелах не очень, но, по-моему, вам надо просто поискать гуглем. Кодовая фраза "ATmega programmer source".
Вот нашел с кодом на С, поможет? -
http://www.captain.at/electronics/atmel-programmer/
и там же -
http://www.nongnu.org/uisp/index.html
Добавлено: Сб апр 19, 2008 09:25:06
zi4rox
Ситуация на данный момент следующая:
1. Задача по прежнему - написать софтину, которая прошивает амегу16
2. Научился управлять ЛПТ, т.е 1-0 подавать могу на какой либо из ног
Локальная задача, которую необходимо решить:
Пытаяюсь эмулировать SPI интерфейс - но никак не получается, помогите разобраться плиз.
Алогритм входа в режим программирования (из даташита):
1. Подать питание, при этом RESЕT и SCK должны быть 0.
2. Подождать как минимум 20 мс затем включить режим SPI Serial Programming
[послать 4 байта на MOSI]:
Byte1: 1010 1100
Byte2: 0101 0011
Byte3: xxxx xxxx // не важно что посылается
Byte4: xxxx xxxx // не важно что посылается
3. Проверить вошел ли контроллер в режим программирования.(Проверить синхронизацию). Когда режим синхронизации установлен, то 2ой байт ответит назад $53 запрашивая при этом 3ий байт. Не зависимо от того был ли правильно получен ответ или нет - нужно обязательно передать все 4 байта. Если этого не произошло, то задать 1 на RESET и повторить заново.
Вот, т.е хорошей проверкой того правильно я сделал или нет - будет то что при посылке 3его байта я получу в ответ $53. Но увы, пока этого не происходит, с чем и прошу помочь разобраться.
Прошу посмотрите как делаю в коде, возможно логика не та у меня и делаю не правильно:
{
Решился писать в Дельфях, потому что удобную либо под лпт нашел, если у кого то неприязнь к паскалю - заранее сорри. Комментарии к коду справа, после //
Значение функций MOSI; SCK; RESET; VCC; - при вызове они инвертируют то что было на этой ноге перед вызовом. Т.е Если на ноге MOSI было 0 после вызова станет 1. и наоборот.
MISO - читает 1 или 0 с ноги.
}
Да и ещё, - по даташиту: Запись в контроллер происходит по фронту, а чтение из мк по спаду. Т.е если я правильно понял, чтобы мк считал 1 например - я сначала её выставляю, а потом подаю положительный импульс на SCK.
Код: Выделить всё
Lpt.WritePort(GetCurrentPort,LPT_DATA_REG,0); // SCK = 0 MOSI = 0 RESET = 0 VCC = 0. Везде нули
VCC; // VCC = 1
Delay(40); // ждем 40мс с запасом
SCK; // SCK = 1 MOSI = 0
SCK; // SCK = 0
SCK; // SCK = 1 MOSI = 0
SCK; // SCK = 0
MOSI;
SCK; // SCK = 1 MOSI = 1
SCK; // SCK = 0
SCK; // SCK = 1 MOSI = 1
SCK; // SCK = 0
MOSI;
SCK; // SCK = 1 MOSI = 0
SCK; // SCK = 0
MOSI;
SCK; // SCK = 1 MOSI = 1
SCK; // SCK = 0
MOSI;
SCK; // SCK = 1 MOSI = 0
SCK; // SCK = 0
MOSI;
SCK; // SCK = 1 MOSI = 1
SCK; // SCK = 0
SCK; // SCK = 1 MOSI = 1
SCK; // SCK = 0
SCK; // SCK = 1 MOSI = 1
SCK; // SCK = 0
MOSI;
SCK; // SCK = 1 MOSI = 0
SCK; // SCK = 0
SCK; // SCK = 1 MOSI = 0
SCK; // SCK = 0
MOSI;
SCK; // SCK = 1 MOSI = 1
SCK; // SCK = 0
MOSI;
SCK; // SCK = 1 MOSI = 0
SCK; // SCK = 0
MOSI;
SCK; // SCK = 1 MOSI = 1
SCK; // SCK = 0
MOSI;
SCK; // SCK = 1 MOSI = 0
SCK; // SCK = 0
SCK; // SCK = 1 MOSI = 0
SCK; // SCK = 0
Memo1.Lines.Add(MISO); // читаю что на ноге MISO
SCK; // SCK = 1 MOSI = 0
SCK; // SCK = 0
Memo1.Lines.Add(MISO); // читаю что на ноге MISO
SCK; // SCK = 1 MOSI = 0
SCK; // SCK = 0
Memo1.Lines.Add(MISO); // читаю что на ноге MISO
SCK; // SCK = 1 MOSI = 0
SCK; // SCK = 0
Memo1.Lines.Add(MISO); // читаю что на ноге MISO
SCK; // SCK = 1 MOSI = 0
SCK; // SCK = 0
Memo1.Lines.Add(MISO); // читаю что на ноге MISO
SCK; // SCK = 1 MOSI = 0
SCK; // SCK = 0
Memo1.Lines.Add(MISO); // читаю что на ноге MISO
SCK; // SCK = 1 MOSI = 0
SCK; // SCK = 0
Memo1.Lines.Add(MISO); // читаю что на ноге MISO
SCK; // SCK = 1 MOSI = 0
SCK; // SCK = 0
Memo1.Lines.Add(MISO); // читаю что на ноге MISO
SCK; // SCK = 1 MOSI = 0
SCK; // SCK = 0
SCK; // SCK = 1 MOSI = 0
SCK; // SCK = 0
SCK; // SCK = 1 MOSI = 0
SCK; // SCK = 0
SCK; // SCK = 1 MOSI = 0
SCK; // SCK = 0
SCK; // SCK = 1 MOSI = 0
SCK; // SCK = 0
SCK; // SCK = 1 MOSI = 0
SCK; // SCK = 0
SCK; // SCK = 1 MOSI = 0
SCK; // SCK = 0
SCK; // SCK = 1 MOSI = 0
SCK; // SCK = 0
В результате байт синхронизации не приходит, значение на MISO - постоянно 1.
Прошу проглядеть плиз, и пнуть меня в нужном направлении плиз.
Добавлено: Сб апр 19, 2008 10:41:27
ARV
прочти описание протокола SPI: данные с MISO надо считывать в то время, когда SCK высокий уровень, а ты выдал импульс SCK и читаешь... надо во время импульса SCK:
SCK; // SCK=1
MISO; // считаем MISO
SCK; // SCK=0
И вообще, о том, что существуют циклы - не в курсе? Что за миллион строк для вывода 1 байта?! УЖОС!!!
Добавлено: Сб апр 19, 2008 22:46:58
zi4rox
Переписал все в процедуру. Стало заменто легче. Поигрался с задержками импульсов, временем чтения выхода (MISO) - резульатат по прежнему один: в контроллер байты передаются от контроллера отклика не получаю. (Проверял это дело этой софтиной -
xlpt - в мк байты идут, отклика нет)
Привожу ниже листинг того, что в коде творится теперь:
В глобальных переменных имеем 2 массива на входные и выходные 4 байта инструкций
Код: Выделить всё
var
spi_cmd: array [1..4] of byte;
spi_out: array [1..4] of byte;
Процедура SPISend(spi_cmd); - которой в качестве параметра дается массив с 4мя байтами инструкции.
Посылает побитно на MOSI начиная с младшего бита. Также на каждый тактовый импульс считывает выход с мк (MISO) обрабатывает и в spi_out[] получаем 4 байта ответа (хотя поидее нужен только 1 - сделал на все)
Код: Выделить всё
procedure TForm1.SPISend (spi_cmd : array of byte);
var
cnt_byte, cnt_bit, pin: byte;
temp_in, temp_out: string;
begin
for cnt_byte:=1 to 4 do begin
temp_in:= IntToBin(spi_cmd[cnt_byte],8);
temp_out:= '';
for cnt_bit:=8 downto 1 do begin
if SCK_HIGH then SCK;
if MOSI_HIGH then
pin:= 1 else
pin:= 0;
if StrToInt(temp_in[cnt_bit]) <> pin then
MOSI;
SCK; // 1, фронт импульса
{Delay(10); // Длительность импульса}
If MISO_HIGH then
temp_out:= temp_out+'1' else
temp_out:= temp_out+'0';
SCK; // 0, спад импульса
end;
spi_out[cnt_byte]:= BinToInt(temp_out);
end;
end;
Небольшое пояснение:
Код: Выделить всё
MISO_HIGH : boolean; // Возвращает true если на входе 1
MOSI_HIGH : boolean; // Возвращает true если на входе 1
SCK_HIGH : boolean; // Возвращает true если на входе 1
MISO,MOSI,SCK,VCC,RESET // Инвертирует значение на ножке. Если было 1 сделает 0 и наоборот.
Теперь инструкция на Programming Enable [1010 1100 | 0101 0011 | xxxx xxxx | xxxx xxxx] выглядит так:
Код: Выделить всё
Lpt.WritePort(GetCurrentPort,LPT_DATA_REG,0); // SCK = 0 MOSI = 0 RESET = 0 VCC = 0
VCC; // VCC = 1
Delay(100);
spi_cmd[1]:= $ac;
spi_cmd[2]:= $53;
spi_cmd[3]:= 0;
spi_cmd[4]:= 0;
SPISend(spi_cmd);
if spi_out[3] <> $53 then
Application.MessageBox('Синхронизация не прошла. Эхо не получено!','ERROR',MB_OK);
Значение на выходе MISO не меняется вообще. Как стоит 1 так до конца и не меняется. В результате чего значение spi_out:
spi_out[1] = 255 ($ff)
spi_out[2] = 255 ($ff)
spi_out[3] = 255 ($ff)
spi_out[4] = 255 ($ff)
Пытался читать и вовремя прихода импульса и до и после - нужного результата не дало.
Прошу помощи и свежего взгляда со стороны.
Добавлено: Вс апр 20, 2008 10:51:29
__Alexander
unsigned char WRITE_BYTE_PROG(unsigned char byte)
{
unsigned char x, ret=0;
SCK_0;
for(x=8; x>0; x--)
{
if (CHECKBIT(byte, x-1))
MOSI_1
else
MOSI_0;
__delay_cycles(10000);
SCK_0;
__delay_cycles(10000);
SCK_1;
__delay_cycles(10000);
ret = ret << 1;
if (CHECKBIT(PING, 0))
SETBIT(ret, 0);
else
CLEARBIT(ret, 0);
SCK_0;
__delay_cycles(100000);
}
return ret;
}
Объяснять думаю здесь нечего. 100% работает. Напомню, что зашил Мегой128 классику 2313. Задержки стоят для уверенности, можно убрать.
Добавлено: Вс апр 20, 2008 18:36:01
zi4rox
Получилось войти в режим программирования! Отклик получил.
Дело было в том что надо было сначала MSB посылать (а у меня было наоборот - первым шел LSB). Не усмотрел это в ДШ.
Задержки вроде как не влияют вообще, импульсы доходят/читаються и без них, но для верности можно и оставить.
Через пару дней продолжу работу. Буду пробывать считать прошивку с мк. Если что не получиться - я к вам за помощью. Ещё раз всем спасибо за дельные идеи и советы.