Страница 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.

Вот только не знаю как это сделать :cry:. Читал про ЛПТ порт, пробывал тестовую программу писать - получалось устанавливать высокий и низкий уровень на отдельных пинах лпт. Но как целый байт передавать/считать - ума не приложу. Эта проблемка является следствием 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 или ОЗУ и програмь себе небольшие МК (можно даже аппаратно).
:shock: О! Первый раз про такую штуку слышу. Интересно. Можно поподробнее пожалуйста рассказать? Почитать бы где нить про эту реализацию. * отправлюсь в гугл пока )

Добавлено: Чт апр 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). Не усмотрел это в ДШ.
Задержки вроде как не влияют вообще, импульсы доходят/читаються и без них, но для верности можно и оставить.

Через пару дней продолжу работу. Буду пробывать считать прошивку с мк. Если что не получиться - я к вам за помощью. Ещё раз всем спасибо за дельные идеи и советы.