Arduino Due как ISP программатор

sdml
Offline
Зарегистрирован: 25.10.2014

Не было у меня хлопот,так решил я удариться в ардуиностроение...

И первая задача которую пытаюсь решить это прошить usbasploader в usbasp с помощью имеющейся ардуино due.

дуина+usbasp с перемычкой JP2 через NativePort определяются в системе как Bossa Programming Port, но тулза BOSSA 1.2.1 говорит что не может соединиться с девайсом на этом порту.

Какую-то ArduinoISP.ino совместимую с due нашел и залил.

Через само ArduinoIDE вообще не понятно что куда писать для due.

- Неправильными установками Плата и Программатор и нажатием BurnBootloader можно убить саму ардуину?

Выбор Arduino as ISP гарантирует что сама дуина не помрет?

- Описание "atmega8usb.name=ATmega8 USB 12 MHz" и т.д. добавлять в \hardware\arduino\sam\boards.txt или \hardware\arduino\avr\boards.txt?

art100
Offline
Зарегистрирован: 09.03.2014

sdml пишет:
.. usbasp .. ардуино due...\hardware\arduino\avr\boards.txt?

Arduino Due только обкатывается

Arduino UNO R3 обкатанную возьмите и нам расскажите в чем разница.

Слово ISP забыл где-то пару лет назад.

sdml
Offline
Зарегистрирован: 25.10.2014

Берем

https://github.com/PeterVH/ArduinoISP/blob/due/ArduinoISP/ArduinoISP.ino

ArduinoISP скетч подходящий для дуо, прошиваем его.

Соединяем miso, mosi, sck, gnd прошиваемого девайса с такими же выводами на разъеме "spi".

vpp для девайса берем с 3.3v пина, reset соединяем на пин 10 ардуины.

Подключаемся через Native порт.

В командах для avrdude пишем "-c arduino".

И... все работает! С ArduinoIDE не разобрался, да и не надо пока.

Pingui
Pingui аватар
Offline
Зарегистрирован: 30.05.2017

у меня Arduino Mega 2560 r3 отдельного программатора нет, но есть горсть avr разных. я пробовал шить их, почему то мега их не видет.

Ее можно использовать как программатор ?

Buzzer2010
Buzzer2010 аватар
Offline
Зарегистрирован: 10.03.2016

sdml пишет:

Берем

https://github.com/PeterVH/ArduinoISP/blob/due/ArduinoISP/ArduinoISP.ino

ArduinoISP скетч подходящий для дуо, прошиваем его.

Соединяем miso, mosi, sck, gnd прошиваемого девайса с такими же выводами на разъеме "spi".

vpp для девайса берем с 3.3v пина, reset соединяем на пин 10 ардуины.

Подключаемся через Native порт.

В командах для avrdude пишем "-c arduino".

И... все работает! С ArduinoIDE не разобрался, да и не надо пока.

Тема опять актуальна. 

Не знаю как в 14-м году, а в 19-м "avrdude" такой команнды: "-c arduino" не понимает.

Другие флешеры можно подружить с ардуиной? Кто что скажет на этот счёт?

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

Buzzer2010 пишет:

Не знаю как в 14-м году, а в 19-м "avrdude" такой команнды: "-c arduino" не понимает.

А Вы что, пишите только эту "команду" и всё? Там как бы длинная строка должна быть, несколько параметров нужно указывать. Где Вы вообще это вводите?

Конкретно через параметр -c указывается программатор. arduino точно должно поддерживаться. Что отвечает avrdude?

Buzzer2010
Buzzer2010 аватар
Offline
Зарегистрирован: 10.03.2016

Jeka_M пишет:

Buzzer2010 пишет:

Не знаю как в 14-м году, а в 19-м "avrdude" такой команнды: "-c arduino" не понимает.

А Вы что, пишите только эту "команду" и всё? Там как бы длинная строка должна быть, несколько параметров нужно указывать. Где Вы вообще это вводите?

Конкретно через параметр -c указывается программатор. arduino точно должно поддерживаться. Что отвечает avrdude?

Добрый вечер.

Начну с того, что с коммандами консольного "avrdude" незнаком конечно. Думал что достаточно написать "-c arduino", а дальше - видно будет. Но он там что-то написал насчет флажка "-с", что его вообще не бывает. Сейчас попробую его "ответы" показать:

100% я что-то делаю неправильно... А может какой-нибудь другой GUI-флешер работать с arduino? "AsProgrammer" например. 

Может "avrdude" промолчал насчет "-c arduino", а теперь просит указать тип прошиваемого чипа? А что я ему там укажу? У меня-то не контроллер, а флешка :(

А "avrdudess" - не тоже самое что и "avrdude"? А то у него есть графический интерфейс:

 

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

Цитата:

Думал что достаточно написать "-c arduino", а дальше - видно будет

Ну конечно этого недостаточно.

Цитата:

Но он там что-то написал насчет флажка "-с", что его вообще не бывает. Сейчас попробую его "ответы" показать:

Про флажок "-с" он Вам вобще ничего не пишет. Он пишет, что отсутвует флажок "-p".

Buzzer2010
Buzzer2010 аватар
Offline
Зарегистрирован: 10.03.2016

Jeka_M пишет:
Про флажок "-с" он Вам вобще ничего не пишет. Он пишет, что отсутвует флажок "-p".

А вот я в предидущем сообщении нашёл, вроде, что-то похожее, но без флажков )))) Не подойдёт?

И там есть в списке программаторов "Ардуино" вроде:

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

Цитата:

100% я что-то делаю неправильно... А может какой-нибудь другой GUI-флешер работать с arduino? "AsProgrammer" например.

Да, вы делаете неправильно. Консольная команда для avrdude состоит из нескольких параметров, а Вы их не указали. Выглядит примерно так: -p atmega328p -c arduino -P COM3 -b 57600 -D -Uflash:w:Blink.ino.hex (это только пример, Вам нужно указать микроконтроллер, программатор, com-порт, скорость прошивки, hex файл). Документация на avrdude - https://www.nongnu.org/avrdude/user-manual/avrdude.html

Если для Вас сложно вручную составлять консольные команды, воспользуйтесь графическими (GUI) оболочками для avrdude, например SinaProg или AVRDUDE_PROG.

Или вон Вы нашли какую-то AVRDUDESS, тоже наверное подойдёт.

Buzzer2010
Buzzer2010 аватар
Offline
Зарегистрирован: 10.03.2016

Jeka_M пишет:

...Вам нужно указать микроконтроллер, программатор, com-порт, скорость прошивки, hex файл...

Тут - проблема. У меня дампы в .bin, а не в .hex (((( Может когда программа определит тип флешки, на переключится на понимание .bin файлов?

Спасибо за ссылку и "AVRDUDE_PROG" ! SinaProg слишком детальный, боюсь - неосилю. 

Buzzer2010
Buzzer2010 аватар
Offline
Зарегистрирован: 10.03.2016

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

2. С подключениями - тоже не всё понятно. Читал несколько статей на счёт DUE и там все подсоединяют как раз на ICSP разъём, а не на SPI. 

Скетч - непонятный + не туда подключу = флешер на настрою (((((Piccy.info - Free Image Hosting

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

Конкретно по DUE и прошивке бинарников не подскажу, т.к. сам не знаю, не приходилось использовать.
Обычно ICSP это тот же SPI, только выведен на отдельную колодку.

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Для, кого в гугле забанили, это

man avrdude

его малюсенький кусочек. только про ключ -U. Смотрим на тип файла, я жирненьким выделили. ;)))

Перед осовоением Ардуино следуует освоить основы поиска в Гугле, хотя некоторые начинают с Яндекса... мы не приветствует такой ложный патриотизм! ;)))

Цитата:

-U memtype:op:filename[:format]
                   Perform a memory operation as indicated.  The memtype field speci‐
                   fies the memory type to operate on.  The available memory types are
                   device-dependent, the actual configuration can be viewed with the
                   part command in terminal mode.  Typically, a device's memory con‐
                   figuration at least contains the memory types flash and eeprom.
                   All memory types currently known are:
                   calibration  One or more bytes of RC oscillator calibration data.
                   eeprom       The EEPROM of the device.
                   efuse        The extended fuse byte.
                   flash        The flash ROM of the device.
                   fuse         The fuse byte in devices that have only a single fuse
                                byte.
                   hfuse        The high fuse byte.
                   lfuse        The low fuse byte.
                   lock         The lock byte.
                   signature    The three device signature bytes (device ID).
                   fuseN        The fuse bytes of ATxmega devices, N is an integer
                                number for each fuse supported by the device.
                   application  The application flash area of ATxmega devices.
                   apptable     The application table flash area of ATxmega devices.
                   boot         The boot flash area of ATxmega devices.
                   prodsig      The production signature (calibration) area of ATxmega
                                devices.
                   usersig      The user signature area of ATxmega devices.

                   The op field specifies what operation to perform:

                   r        read device memory and write to the specified file

                   w        read data from the specified file and write to the device
                            memory

                   v        read data from both the device and the specified file and
                            perform a verify

                   The filename field indicates the name of the file to read or write.
                   The format field is optional and contains the format of the file to
                   read or write.  Format can be one of:

                   i    Intel Hex

                   s    Motorola S-record

                   r    raw binary; little-endian byte order, in the case of the flash
                        ROM data

                   m    immediate; actual byte values specified on the command line,
                        separated by commas or spaces.  This is good for programming
                        fuse bytes without having to create a single-byte file or
                        enter terminal mode.

                   a    auto detect; valid for input only, and only if the input is
                        not provided at stdin.

                   d    decimal; this and the following formats are only valid on out‐
                        put.  They generate one line of output for the respective mem‐
                        ory section, forming a comma-separated list of the values.
                        This can be particularly useful for subsequent processing,
                        like for fuse bit settings.

                   h    hexadecimal; each value will get the string 0x prepended.

                   o    octal; each value will get a 0 prepended unless it is less
                        than 8 in which case it gets no prefix.

                   b    binary; each value will get the string 0b prepended.

                   The default is to use auto detection for input files, and raw
                   binary format for output files.  Note that if filename contains a
                   colon, the format field is no longer optional since the filename
                   part following the colon would otherwise be misinterpreted as
                   format.

                   As an abbreviation, the form -U filename is equivalent to specify‐
                   ing -U flash:w:filename:a.  This will only work if filename does
                   not have a colon in it.

Buzzer2010
Buzzer2010 аватар
Offline
Зарегистрирован: 10.03.2016

Jeka_M пишет:
Конкретно по DUE и прошивке бинарников не подскажу, т.к. сам не знаю, не приходилось использовать.
А мне не приходилось ардуину в качестве программатора мучать, а вот - пришлось. HEX-ы, кстати, тоже шить не приходилось. А чего, именно - .HEX? Почему не .BIN?  Странно.

Jeka_M пишет:
Обычно ICSP это тот же SPI, только выведен на отдельную колодку.

Так а у DUE и ISP на отдельной колодке. Просто, мне кажется, что один из них вход, а второй  - выход. Только кто есть кто - не знаю я )))))

Buzzer2010
Buzzer2010 аватар
Offline
Зарегистрирован: 10.03.2016

wdrakula пишет:

Для, кого в гугле забанили, это

man avrdude

его малюсенький кусочек. только про ключ -U. Смотрим на тип файла, я жирненьким выделили. ;)))

Перед осовоением Ардуино следуует освоить основы поиска в Гугле, хотя некоторые начинают с Яндекса... мы не приветствует такой ложный патриотизм! ;)))

И ничего нас не забанели. Просто мы не знали что avrdude - man, думали - girl.

Про яндексы мы ни про какие не знаем. Просто одна голова - плохо ))))))

Спасибо, сяйчас покурим этот кусочек, с жирненьким ))))

-----------------------

Так, судя из того что я не понял, набор комманд будет выглядеть как-то так:

avrdude -c arduino -P usb -b 19200 -U flash:r:"dump.bin":b  

Это если не напутал с минусами и двоеточиями. 

-----------------

Немного не так. Если следовать инструкции подключения arduino и диспетчеру устройств, подключать надо к "Native Usb Port", который в диспетчере светится как: "Bossa Program Port" и висит, в данный момент на COM4. Так что теперь эта строчка выглядит вот так:

-c arduino -P COM4 -b 19200 -U flash:r:"dump.bin":b 

-----------------

"Native Usb Port" не подходит: его не видит avrdude. А если подключать к "Programming Port", когда avrdude пытается обратиться к ардуине, запускается "Serial" и ардуина начинает мигать лампочкой на 9-м пине.

// ArduinoISP version 04m3
// Copyright (c) 2008-2011 Randall Bohn
// If you require a license, see
//     http://www.opensource.org/licenses/bsd-license.php
//
// This sketch turns the Arduino into a AVRISP
// using the following arduino pins:
//
// pin name:    not-mega:         mega(1280 and 2560)
// slave reset: 10:               53
// MOSI:        11:               51
// MISO:        12:               50
// SCK:         13: (std LED)     52
//
// Put an LED (with resistor) on the following pins:
// 9: Heartbeat   - shows the programmer is running
// 8: Error       - Lights up if something goes wrong (use red if that makes sense)
// 7: Programming - In communication with the slave
//
// 23 July 2011 Randall Bohn
// -Address Arduino issue 509 :: Portability of ArduinoISP
// http://code.google.com/p/arduino/issues/detail?id=509
//
// October 2010 by Randall Bohn
// - Write to EEPROM > 256 bytes
// - Better use of LEDs:
// -- Flash LED_PMODE on each flash commit
// -- Flash LED_PMODE while writing EEPROM (both give visual feedback of writing progress)
// -- Light LED_ERR whenever we hit a STK_NOSYNC. Turn it off when back in sync.
// - Use pins_arduino.h (should also work on Arduino Mega)
//
// October 2009 by David A. Mellis
// - Added support for the read signature command
//
// February 2009 by Randall Bohn
// - Added support for writing to EEPROM (what took so long?)
// Windows users should consider WinAVR's avrdude instead of the
// avrdude included with Arduino software.
//
// January 2008 by Randall Bohn
// - Thanks to Amplificar for helping me with the STK500 protocol
// - The AVRISP/STK500 (mk I) protocol is used in the arduino bootloader
// - The SPI functions herein were developed for the AVR910_ARD programmer
// - More information at http://code.google.com/p/mega-isp

// Пины для подключения:

// PIN          DUE       FLASH   COLOR

// MISO:        74        2       Brown
// MOSI:        75        5       Yellow
// SCK:         76        6       Green
// RESET(CS):   10        1    
// VCC          3.3V      3,7,8   
// VSS          GND       4   
// 
// Индикаторы работы:

// LED_HB:     9       Green      HeartBeat:         Режим ожидания
// LED_ERR:    8       Red        Error:             Ошибка
// LED_PMODE:  7       Yellow     Programming Mode:  Режим записи


// versions need to be above Atmel programmer to avoid fw update attempts
#define HWVER 2
#define SWMAJ 1
#define SWMIN 18


#define BAUDRATE 19200
//#define BAUDRATE 38400
//#define BAUDRATE 115200

// create clock on digital 9 using pwm (timer1), LED_HB must move
//#define LADYADA_CLOCK

#define RESETDELAY 0

// uncomment if you want to have debug traces
// (needs a separate uart so works only on Sanguino, Leonardo, Due...)
//#define TRACES

// following settings have different defaults on SAM vs. AVR

#ifdef __SAM3X8E__

// Select uart to use for programming and debugging:
#define SERIAL_PRG SerialUSB
#define SERIAL_DBG Serial

// comment USE_HARDWARE_SPI to use bitbang spi
// use bitbang to make it work with very slow attiny2313
// #define USE_HARDWARE_SPI

#else

// Select uart to use for programming and debugging:
#define SERIAL_PRG Serial
#define SERIAL_DBG Serial1

// comment USE_HARDWARE_SPI to use bitbang spi
// use bitbang to make it work with very slow attiny2313
#define USE_HARDWARE_SPI

#endif

///////////////////////////////////////////////
//   ideally won't need to edit below here   //
///////////////////////////////////////////////



#ifdef USE_HARDWARE_SPI
#include "SPI.h"

#ifdef __AVR__  // this would better go into SPI lib
#define SPI_CLOCK_DIV_MAX  SPI_CLOCK_DIV128
#else
#define SPI_CLOCK_DIV_MAX  255
#endif

#endif

#include "pins_arduino.h"
#define PIN_RESET     SS
#define PIN_SCK       SCK
#define PIN_MOSI      MOSI
#define PIN_MISO      MISO

#define LED_HB    9
#define LED_ERR   8
#define LED_PMODE 7
#define PROG_FLICKER true



#ifdef LADYADA_CLOCK
#ifndef __AVR__
#error "Not yet implemented for non AVR's."
#endif
// needs timer1 PWM
#define CLOCK_PIN 9
#undef  LED_HB
#define LED_HB    6
#endif

#ifdef TRACES
#define TRACE_BEGIN(baud) SERIAL_DBG.begin(baud)
#define TRACE(x) SERIAL_DBG.print(x)
#define TRACELN(x) SERIAL_DBG.println(x)
#define TRACE2(x, format) SERIAL_DBG.print(x, format)
#define TRACE2LN(x, format) SERIAL_DBG.println(x, format)
#else
#define TRACE_BEGIN(baud)
#define TRACE(x)
#define TRACELN(x)
#define TRACE2(x, format)
#define TRACE2LN(x, format)
#endif


// STK Definitions
#define STK_OK      0x10
#define STK_FAILED  0x11
#define STK_UNKNOWN 0x12
#define STK_INSYNC  0x14
#define STK_NOSYNC  0x15
#define CRC_EOP     0x20 //ok it is a space...

void pulse(uint8_t pin, uint8_t times);

#ifndef USE_HARDWARE_SPI

class BitBangedSPI {
  public:

    void begin() {
      pinMode(PIN_MISO, INPUT);
      pinMode(PIN_RESET, OUTPUT);
      pinMode(PIN_SCK, OUTPUT);
      pinMode(PIN_MOSI, OUTPUT);
    }

    void end() {}

    uint8_t transfer (uint8_t b) {
      for (unsigned int i = 0; i < 8; ++i) {
        digitalWrite(PIN_MOSI, b & 0x80);
        digitalWrite(PIN_SCK, HIGH);
        b = (b << 1) | digitalRead(PIN_MISO);
        digitalWrite(PIN_SCK, LOW); // slow pulse
      }
      return b;
    }
};

static BitBangedSPI SPI;

#endif

void setup(void) {
  SERIAL_PRG.begin(BAUDRATE);
  /*
  Serial.begin (9600);
  Serial.print("MISO:  "); Serial.println(MISO);
  Serial.print("RESET: "); Serial.println(PIN_RESET);
  Serial.print("SCK:   "); Serial.println(SCK);
  Serial.print("MOSI:  "); Serial.println(MOSI);
  Serial.print("SS:    "); Serial.println(SS);
  */
  


#ifdef USE_HARDWARE_SPI
  SPI.setDataMode(0);
  SPI.setBitOrder(MSBFIRST);
  // Clock Div can be 2,4,8,16,32,64, or 128
  SPI.setClockDivider(SPI_CLOCK_DIV_MAX);
#endif

  pinMode(LED_PMODE, OUTPUT);
  pulse(LED_PMODE, 2);
  pinMode(LED_ERR, OUTPUT);
  pulse(LED_ERR, 2);
  pinMode(LED_HB, OUTPUT);
  pulse(LED_HB, 2);

#ifdef LADYADA_CLOCK
  // setup high freq PWM (timer 1)
  pinMode(CLOCK_PIN, OUTPUT);
  uint8_t sreg = SREG;
  cli(); // disable interrupts to access TCNT1, OCR1A,B
  // 50% duty cycle -> 8 MHz
  OCR1A = 0;
  ICR1 = 1;
  // OC1A output, fast PWM
  TCCR1A = _BV(WGM11) | _BV(COM1A1);
  TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10); // no clock prescale
  SREG = sreg; // restore interrupts
#endif

  TRACE_BEGIN(115200);
  TRACELN("*** setup ***");
}

uint8_t error = 0;
uint8_t pmode = 0;
uint8_t buff[256]; // global block storage
// address for reading and writing, set by 'U' command
uint16_t here;

// get multi-byte Big Endian values
#define beget16(addr) ((uint16_t)*(addr) <<  8 | (uint16_t)*((addr)+1) )
#define beget32(a) ((uint32_t)beget16(a) << 16 | (uint32_t)beget16((a)+2) )

struct param {
  uint8_t devicecode;
  uint8_t revision;
  uint8_t progtype;
  uint8_t parmode;
  uint8_t polling;
  uint8_t selftimed;
  uint8_t lockbytes;
  uint8_t fusebytes;
  uint8_t flashpoll;
  //uint8_t ignored;
  uint16_t eeprompoll;
  uint16_t pagesize;
  uint16_t eepromsize;
  uint32_t flashsize;
} param;


// this provides a heartbeat, so you can tell the software is running.
uint8_t hbval = 128;
int8_t hbdelta = 8;
unsigned long hbprev = 0;
void heartbeat(void) {
  if (hbval > 192 || hbval < 32) hbdelta = -hbdelta;
  hbval += hbdelta;
  while (millis() - hbprev < 40); // wait a bit if came back too soon
  analogWrite(LED_HB, hbval);
  hbprev = millis();
}


void loop(void) {
  // is pmode active?
  if (pmode) digitalWrite(LED_PMODE, HIGH);
  else digitalWrite(LED_PMODE, LOW);

  // is there an error?
  if (error) digitalWrite(LED_ERR, HIGH);
  else digitalWrite(LED_ERR, LOW);

  // light the heartbeat LED
  heartbeat();

  if (SERIAL_PRG.available()) {
    avrisp();
  }
}


uint8_t getch(void) {
  while (!SERIAL_PRG.available());
  return SERIAL_PRG.read();
}
void fill(unsigned n) {
  for (unsigned x = 0; x < n; x++) {
    buff[x] = getch();
  }
}

#define PTIME 30
void pulse(uint8_t pin, uint8_t times) {
  do {
    digitalWrite(pin, HIGH);
    delay(PTIME);
    digitalWrite(pin, LOW);
    delay(PTIME);
  }
  while (times--);
}

void prog_lamp(uint8_t state) {
  if (PROG_FLICKER)
    digitalWrite(LED_PMODE, state);
}

uint8_t spi_transaction(uint8_t a, uint8_t b, uint8_t c, uint8_t d) {
  SPI.transfer(a);
  SPI.transfer(b);
  SPI.transfer(c);
  return SPI.transfer(d);
}


void empty_reply(void) {
  if (CRC_EOP == getch()) {
    SERIAL_PRG.print((char)STK_INSYNC);
    SERIAL_PRG.print((char)STK_OK);
  }
  else {
    error++;
    SERIAL_PRG.print((char)STK_NOSYNC);
  }
}

void breply(uint8_t b) {
  if (CRC_EOP == getch()) {
    SERIAL_PRG.print((char)STK_INSYNC);
    SERIAL_PRG.print((char)b);
    SERIAL_PRG.print((char)STK_OK);
  }
  else {
    error++;
    SERIAL_PRG.print((char)STK_NOSYNC);
  }
}

void get_version(uint8_t c) {
  switch (c) {
    case 0x80:
      breply(HWVER);
      break;
    case 0x81:
      breply(SWMAJ);
      break;
    case 0x82:
      breply(SWMIN);
      break;
    case 0x93:
      breply('S'); // serial programmer
      break;
    default:
      breply(0);
  }
}

void set_parameters(void) {
  // call this after reading paramter packet into buff[]
  param.devicecode = buff[0];
  param.revision   = buff[1];
  param.progtype   = buff[2];
  param.parmode    = buff[3];
  param.polling    = buff[4];
  param.selftimed  = buff[5];
  param.lockbytes  = buff[6];
  param.fusebytes  = buff[7];
  param.flashpoll  = buff[8];
  // ignore buff[9] (= buff[8])
  // following are 16 bits (big endian)
  param.eeprompoll = beget16(&buff[10]);
  param.pagesize   = beget16(&buff[12]);
  param.eepromsize = beget16(&buff[14]);
  // 32 bits flashsize (big endian)
  param.flashsize = beget32(&buff[16]);
}

void start_pmode(void) {
  pmode = 1;

  // reset target before driving SCK or MOSI
  digitalWrite(PIN_RESET, LOW);
  digitalWrite(PIN_SCK, LOW);
  digitalWrite(PIN_MOSI, HIGH);

  pinMode(PIN_MISO, INPUT);
  pinMode(PIN_RESET, OUTPUT); // PIN_RESET not always SS: Leonardo, Due...
  SPI.begin(); // now SS, MOSI and SCK are output

  // See datasheets: "SERIAL_PRG Programming Algorithm":
  delay(5); // choosen arbitrarilly
  // pulse RESET high after SCK is low
  digitalWrite(PIN_RESET, HIGH);
  delay(1); // must be minimum 2 CPU clock cycles
  digitalWrite(PIN_RESET, LOW);
  delay(50); // minimum 20 ms
  if (RESETDELAY) delay(RESETDELAY);
  spi_transaction(0xAC, 0x53, 0x00, 0x00);
}

void end_pmode(void) {
  SPI.end();
  pinMode(PIN_MOSI, INPUT);
  pinMode(PIN_SCK, INPUT);
  pinMode(PIN_RESET, INPUT);
  pmode = 0;
}

void universal(void) {
  uint8_t ch;
  fill(4);
  ch = spi_transaction(buff[0], buff[1], buff[2], buff[3]);
  breply(ch);
}

#define flash_write_cmd(hilo, addr, data) \
  spi_transaction(0x40|((hilo)<<3), (addr)>>8 & 0xFF, (addr) & 0xFF, (data))

#define flash_read_cmd(hilo, addr) \
  spi_transaction(0x20|((hilo)<<3), (addr)>>8 & 0xFF, (addr) & 0xFF, 0)


void commit(uint16_t addr) {
  if (PROG_FLICKER) prog_lamp(LOW);
  spi_transaction(0x4C, (addr >> 8) & 0xFF, addr & 0xFF, 0);
  if (PROG_FLICKER) {
    delay(PTIME);
    prog_lamp(HIGH);
  }
}

uint16_t current_page(uint16_t addr) {
  if (param.pagesize == 32)  return here & 0xFFF0;
  if (param.pagesize == 64)  return here & 0xFFE0;
  if (param.pagesize == 128) return here & 0xFFC0;
  if (param.pagesize == 256) return here & 0xFF80;
  return here;
}


void write_flash(unsigned length) {
  fill(length);
  if (CRC_EOP == getch()) {
    SERIAL_PRG.print((char) STK_INSYNC);
    SERIAL_PRG.print((char) write_flash_pages(length));
  }
  else {
    error++;
    SERIAL_PRG.print((char) STK_NOSYNC);
  }
}

uint8_t write_flash_pages(unsigned length) {
  unsigned x = 0;
  uint16_t page = current_page(here);
  while (x < length) {
    if (page != current_page(here)) {
      commit(page);
      page = current_page(here);
    }
    flash_write_cmd(LOW,  here, buff[x++]);
    flash_write_cmd(HIGH, here, buff[x++]);
    here++;
  }

  commit(page);

  return STK_OK;
}

#define EECHUNK (32)
uint8_t write_eeprom(unsigned length) {
  // here is a word address, get the byte address
  uint16_t start = here << 1;
  if (length > param.eepromsize) {
    error++;
    return STK_FAILED;
  }
  while (length > EECHUNK) {
    write_eeprom_chunk(start, EECHUNK);
    start += EECHUNK;
    length -= EECHUNK;
  }
  write_eeprom_chunk(start, length);
  return STK_OK;
}
// write (length) bytes, (start) is a byte address
uint8_t write_eeprom_chunk(uint16_t addr, unsigned length) {
  // this writes byte-by-byte,
  // page writing may be faster (4 bytes at a time)
  fill(length);
  prog_lamp(LOW);
  for (unsigned x = 0; x < length; x++, addr++) {
    spi_transaction(0xC0, (addr >> 8) & 0xFF, addr & 0xFF, buff[x]);
    delay(45);
  }
  prog_lamp(HIGH);
  return STK_OK;
}

void program_page(void) {
  char result = (char) STK_FAILED;
  unsigned length = getch() << 8;
  length |= getch();
  char memtype = getch();
  // flash memory @here, (length) bytes
  if (memtype == 'F') {
    write_flash(length);
    return;
  }
  if (memtype == 'E') {
    result = (char)write_eeprom(length);
    if (CRC_EOP == getch()) {
      SERIAL_PRG.print((char) STK_INSYNC);
      SERIAL_PRG.print(result);
    }
    else {
      error++;
      SERIAL_PRG.print((char) STK_NOSYNC);
    }
    return;
  }
  SERIAL_PRG.print((char)STK_FAILED);
}

char flash_read_page(unsigned length) {
  for (unsigned x = 0; x < length; x += 2) {
    char ch;
    ch = flash_read_cmd(LOW,  here);
    SERIAL_PRG.print(ch);
    ch = flash_read_cmd(HIGH, here);
    SERIAL_PRG.print(ch);
    here++;
  }
  return STK_OK;
}

char eeprom_read_page(unsigned length) {
  // here again we have a word address
  uint16_t addr = here << 1;
  for (unsigned x = 0; x < length; x++, addr++) {
    uint8_t ee = spi_transaction(0xA0, (addr >> 8) & 0xFF, addr & 0xFF, 0xFF);
    SERIAL_PRG.print((char) ee);
  }
  return STK_OK;
}

void read_page(void) {
  char result = (char)STK_FAILED;
  unsigned length = getch() << 8;
  length |= getch();
  char memtype = getch();
  if (CRC_EOP != getch()) {
    error++;
    SERIAL_PRG.print((char) STK_NOSYNC);
    return;
  }
  SERIAL_PRG.print((char) STK_INSYNC);
  if (memtype == 'F') result = flash_read_page(length);
  if (memtype == 'E') result = eeprom_read_page(length);
  SERIAL_PRG.print(result);
}

void read_signature(void) {
  if (CRC_EOP != getch()) {
    error++;
    SERIAL_PRG.print((char) STK_NOSYNC);
    return;
  }
  SERIAL_PRG.print((char) STK_INSYNC);
  char ch;
  ch = spi_transaction(0x30, 0x00, 0x00, 0x00);
  SERIAL_PRG.print(ch);
  ch = spi_transaction(0x30, 0x00, 0x01, 0x00);
  SERIAL_PRG.print(ch);
  ch = spi_transaction(0x30, 0x00, 0x02, 0x00);
  SERIAL_PRG.print(ch);
  SERIAL_PRG.print((char) STK_OK);
}
//////////////////////////////////////////
//////////////////////////////////////////



////////////////////////////////////
////////////////////////////////////
void avrisp(void) {
  uint8_t data, low, high;
  uint8_t ch = getch();
  TRACE("> ");
  TRACELN((char) ch);
  switch (ch) {
    case '0': // signon
      error = 0;
      empty_reply();
      break;
    case '1':
      if (getch() == CRC_EOP) {
        SERIAL_PRG.print((char) STK_INSYNC);
        SERIAL_PRG.print("AVR ISP");
        SERIAL_PRG.print((char) STK_OK);
      } else {
        error++;
        SERIAL_PRG.print((char) STK_NOSYNC);
      }
      break;
    case 'A':
      get_version(getch());
      break;
    case 'B':
      fill(20);
      set_parameters();
      empty_reply();
      break;
    case 'E': // extended parameters - ignore for now
      fill(5);
      empty_reply();
      break;

    case 'P':
      if (pmode) {
        pulse(LED_ERR, 3);
      } else {
        start_pmode();
      }
      empty_reply();
      break;
    case 'U': // set address (word)
      here = getch();
      here |= getch() << 8;
      empty_reply();
      break;

    case 0x60: //STK_PROG_FLASH
      low = getch();
      high = getch();
      empty_reply();
      break;
    case 0x61: //STK_PROG_DATA
      data = getch();
      empty_reply();
      break;

    case 0x64: //STK_PROG_PAGE
      program_page();
      break;

    case 0x74: //STK_READ_PAGE 't'
      read_page();
      break;

    case 'V': //0x56
      universal();
      break;
    case 'Q': //0x51
      error = 0;
      end_pmode();
      empty_reply();
      break;

    case 0x75: //STK_READ_SIGN 'u'
      read_signature();
      break;

    // expecting a command, not CRC_EOP
    // this is how we can get back in sync
    case CRC_EOP:
      error++;
      SERIAL_PRG.print((char) STK_NOSYNC);
      break;

    // anything else we will return STK_UNKNOWN
    default:
      error++;
      if (CRC_EOP == getch())
        SERIAL_PRG.print((char)STK_UNKNOWN);
      else
        SERIAL_PRG.print((char)STK_NOSYNC);
  }
}

 

Buzzer2010
Buzzer2010 аватар
Offline
Зарегистрирован: 10.03.2016

Так, минуту. А как быть с тем что "avrdude" это: "AVR Downloader-Uploader" а DUE это ARM ? Или это просто так программу назвали, а ей, по большому счету - по барабану кого (и через что) шить?