arduino-0018-linux-x64
This commit is contained in:
		
							parent
							
								
									8e4748e499
								
							
						
					
					
						commit
						ed785c5798
					
				
					 426 changed files with 76732 additions and 0 deletions
				
			
		
							
								
								
									
										480
									
								
								arduino-0018-linux-x64/examples/ArduinoISP/ArduinoISP.pde
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										480
									
								
								arduino-0018-linux-x64/examples/ArduinoISP/ArduinoISP.pde
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,480 @@
 | 
			
		|||
// this sketch turns the Arduino into a AVRISP
 | 
			
		||||
// using the following pins:
 | 
			
		||||
// 10: slave reset
 | 
			
		||||
// 11: MOSI
 | 
			
		||||
// 12: MISO
 | 
			
		||||
// 13: SCK
 | 
			
		||||
 | 
			
		||||
// 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
 | 
			
		||||
//
 | 
			
		||||
// 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
 | 
			
		||||
 | 
			
		||||
#define SCK 13
 | 
			
		||||
#define MISO 12
 | 
			
		||||
#define MOSI 11
 | 
			
		||||
#define RESET 10
 | 
			
		||||
 | 
			
		||||
#define LED_HB 9
 | 
			
		||||
#define LED_ERR 8
 | 
			
		||||
#define LED_PMODE 7
 | 
			
		||||
 | 
			
		||||
#define HWVER 2
 | 
			
		||||
#define SWMAJ 1
 | 
			
		||||
#define SWMIN 18
 | 
			
		||||
 | 
			
		||||
// 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(int pin, int times);
 | 
			
		||||
 | 
			
		||||
void setup() {
 | 
			
		||||
  Serial.begin(19200);
 | 
			
		||||
  pinMode(7, OUTPUT);
 | 
			
		||||
  pulse(7, 2);
 | 
			
		||||
  pinMode(8, OUTPUT);
 | 
			
		||||
  pulse(8, 2);
 | 
			
		||||
  pinMode(9, OUTPUT);
 | 
			
		||||
  pulse(9, 2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int error=0;
 | 
			
		||||
int pmode=0;
 | 
			
		||||
// address for reading and writing, set by 'U' command
 | 
			
		||||
int here;
 | 
			
		||||
uint8_t buff[256]; // global block storage
 | 
			
		||||
 | 
			
		||||
#define beget16(addr) (*addr * 256 + *(addr+1) )
 | 
			
		||||
typedef 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;
 | 
			
		||||
  int flashpoll;
 | 
			
		||||
  int eeprompoll;
 | 
			
		||||
  int pagesize;
 | 
			
		||||
  int eepromsize;
 | 
			
		||||
  int flashsize;
 | 
			
		||||
} 
 | 
			
		||||
parameter;
 | 
			
		||||
 | 
			
		||||
parameter param;
 | 
			
		||||
 | 
			
		||||
// this provides a heartbeat on pin 9, so you can tell the software is running.
 | 
			
		||||
uint8_t hbval=128;
 | 
			
		||||
int8_t hbdelta=8;
 | 
			
		||||
void heartbeat() {
 | 
			
		||||
  if (hbval > 192) hbdelta = -hbdelta;
 | 
			
		||||
  if (hbval < 32) hbdelta = -hbdelta;
 | 
			
		||||
  hbval += hbdelta;
 | 
			
		||||
  analogWrite(LED_HB, hbval);
 | 
			
		||||
  delay(40);
 | 
			
		||||
}
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
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.available()) {
 | 
			
		||||
    avrisp();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t getch() {
 | 
			
		||||
  while(!Serial.available());
 | 
			
		||||
  return Serial.read();
 | 
			
		||||
}
 | 
			
		||||
void readbytes(int n) {
 | 
			
		||||
  for (int x = 0; x < n; x++) {
 | 
			
		||||
    buff[x] = Serial.read();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define PTIME 30
 | 
			
		||||
void pulse(int pin, int times) {
 | 
			
		||||
  do {
 | 
			
		||||
    digitalWrite(pin, HIGH);
 | 
			
		||||
    delay(PTIME);
 | 
			
		||||
    digitalWrite(pin, LOW);
 | 
			
		||||
    delay(PTIME);
 | 
			
		||||
  } 
 | 
			
		||||
  while (times--);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void spi_init() {
 | 
			
		||||
  uint8_t x;
 | 
			
		||||
  SPCR = 0x53;
 | 
			
		||||
  x=SPSR;
 | 
			
		||||
  x=SPDR;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void spi_wait() {
 | 
			
		||||
  do {
 | 
			
		||||
  } 
 | 
			
		||||
  while (!(SPSR & (1 << SPIF)));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t spi_send(uint8_t b) {
 | 
			
		||||
  uint8_t reply;
 | 
			
		||||
  SPDR=b;
 | 
			
		||||
  spi_wait();
 | 
			
		||||
  reply = SPDR;
 | 
			
		||||
  return reply;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t spi_transaction(uint8_t a, uint8_t b, uint8_t c, uint8_t d) {
 | 
			
		||||
  uint8_t n;
 | 
			
		||||
  spi_send(a); 
 | 
			
		||||
  n=spi_send(b);
 | 
			
		||||
  //if (n != a) error = -1;
 | 
			
		||||
  n=spi_send(c);
 | 
			
		||||
  return spi_send(d);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void empty_reply() {
 | 
			
		||||
  if (CRC_EOP == getch()) {
 | 
			
		||||
    Serial.print((char)STK_INSYNC);
 | 
			
		||||
    Serial.print((char)STK_OK);
 | 
			
		||||
  } 
 | 
			
		||||
  else {
 | 
			
		||||
    Serial.print((char)STK_NOSYNC);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void breply(uint8_t b) {
 | 
			
		||||
  if (CRC_EOP == getch()) {
 | 
			
		||||
    Serial.print((char)STK_INSYNC);
 | 
			
		||||
    Serial.print((char)b);
 | 
			
		||||
    Serial.print((char)STK_OK);
 | 
			
		||||
  } 
 | 
			
		||||
  else {
 | 
			
		||||
    Serial.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() {
 | 
			
		||||
  // 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])
 | 
			
		||||
  //getch(); // discard second value
 | 
			
		||||
  
 | 
			
		||||
  // WARNING: not sure about the byte order of the following
 | 
			
		||||
  // 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 = buff[16] * 0x01000000
 | 
			
		||||
    + buff[17] * 0x00010000
 | 
			
		||||
    + buff[18] * 0x00000100
 | 
			
		||||
    + buff[19];
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void start_pmode() {
 | 
			
		||||
  spi_init();
 | 
			
		||||
  // following delays may not work on all targets...
 | 
			
		||||
  pinMode(RESET, OUTPUT);
 | 
			
		||||
  digitalWrite(RESET, HIGH);
 | 
			
		||||
  pinMode(SCK, OUTPUT);
 | 
			
		||||
  digitalWrite(SCK, LOW);
 | 
			
		||||
  delay(50);
 | 
			
		||||
  digitalWrite(RESET, LOW);
 | 
			
		||||
  delay(50);
 | 
			
		||||
  pinMode(MISO, INPUT);
 | 
			
		||||
  pinMode(MOSI, OUTPUT);
 | 
			
		||||
  spi_transaction(0xAC, 0x53, 0x00, 0x00);
 | 
			
		||||
  pmode = 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void end_pmode() {
 | 
			
		||||
  pinMode(MISO, INPUT);
 | 
			
		||||
  pinMode(MOSI, INPUT);
 | 
			
		||||
  pinMode(SCK, INPUT);
 | 
			
		||||
  pinMode(RESET, INPUT);
 | 
			
		||||
  pmode = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void universal() {
 | 
			
		||||
  int w;
 | 
			
		||||
  uint8_t ch;
 | 
			
		||||
 | 
			
		||||
  for (w = 0; w < 4; w++) {
 | 
			
		||||
    buff[w] = getch();
 | 
			
		||||
  }
 | 
			
		||||
  ch = spi_transaction(buff[0], buff[1], buff[2], buff[3]);
 | 
			
		||||
  breply(ch);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void flash(uint8_t hilo, int addr, uint8_t data) {
 | 
			
		||||
  spi_transaction(0x40+8*hilo, 
 | 
			
		||||
  addr>>8 & 0xFF, 
 | 
			
		||||
  addr & 0xFF,
 | 
			
		||||
  data);
 | 
			
		||||
}
 | 
			
		||||
void commit(int addr) {
 | 
			
		||||
  spi_transaction(0x4C, (addr >> 8) & 0xFF, addr & 0xFF, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//#define _current_page(x) (here & 0xFFFFE0)
 | 
			
		||||
int current_page(int addr) {
 | 
			
		||||
  if (param.pagesize == 32) return here & 0xFFFFFFF0;
 | 
			
		||||
  if (param.pagesize == 64) return here & 0xFFFFFFE0;
 | 
			
		||||
  if (param.pagesize == 128) return here & 0xFFFFFFC0;
 | 
			
		||||
  if (param.pagesize == 256) return here & 0xFFFFFF80;
 | 
			
		||||
  return here;
 | 
			
		||||
}
 | 
			
		||||
uint8_t write_flash(int length) {
 | 
			
		||||
  if (param.pagesize < 1) return STK_FAILED;
 | 
			
		||||
  //if (param.pagesize != 64) return STK_FAILED;
 | 
			
		||||
  int page = current_page(here);
 | 
			
		||||
  int x = 0;
 | 
			
		||||
  while (x < length) {
 | 
			
		||||
    if (page != current_page(here)) {
 | 
			
		||||
      commit(page);
 | 
			
		||||
      page = current_page(here);
 | 
			
		||||
    }
 | 
			
		||||
    flash(LOW, here, buff[x++]);
 | 
			
		||||
    flash(HIGH, here, buff[x++]);
 | 
			
		||||
    here++;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  commit(page);
 | 
			
		||||
 | 
			
		||||
  return STK_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t write_eeprom(int length) {
 | 
			
		||||
  // here is a word address, so we use here*2
 | 
			
		||||
  // this writes byte-by-byte,
 | 
			
		||||
  // page writing may be faster (4 bytes at a time)
 | 
			
		||||
  for (int x = 0; x < length; x++) {
 | 
			
		||||
    spi_transaction(0xC0, 0x00, here*2+x, buff[x]);
 | 
			
		||||
    delay(45);
 | 
			
		||||
  } 
 | 
			
		||||
  return STK_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void program_page() {
 | 
			
		||||
  char result = (char) STK_FAILED;
 | 
			
		||||
  int length = 256 * getch() + getch();
 | 
			
		||||
  if (length > 256) {
 | 
			
		||||
      Serial.print((char) STK_FAILED);
 | 
			
		||||
      return;
 | 
			
		||||
  }
 | 
			
		||||
  char memtype = getch();
 | 
			
		||||
  for (int x = 0; x < length; x++) {
 | 
			
		||||
    buff[x] = getch();
 | 
			
		||||
  }
 | 
			
		||||
  if (CRC_EOP == getch()) {
 | 
			
		||||
    Serial.print((char) STK_INSYNC);
 | 
			
		||||
    if (memtype == 'F') result = (char)write_flash(length);
 | 
			
		||||
    if (memtype == 'E') result = (char)write_eeprom(length);
 | 
			
		||||
    Serial.print(result);
 | 
			
		||||
  } 
 | 
			
		||||
  else {
 | 
			
		||||
    Serial.print((char) STK_NOSYNC);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
uint8_t flash_read(uint8_t hilo, int addr) {
 | 
			
		||||
  return spi_transaction(0x20 + hilo * 8,
 | 
			
		||||
    (addr >> 8) & 0xFF,
 | 
			
		||||
    addr & 0xFF,
 | 
			
		||||
    0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char flash_read_page(int length) {
 | 
			
		||||
  for (int x = 0; x < length; x+=2) {
 | 
			
		||||
    uint8_t low = flash_read(LOW, here);
 | 
			
		||||
    Serial.print((char) low);
 | 
			
		||||
    uint8_t high = flash_read(HIGH, here);
 | 
			
		||||
    Serial.print((char) high);
 | 
			
		||||
    here++;
 | 
			
		||||
  }
 | 
			
		||||
  return STK_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char eeprom_read_page(int length) {
 | 
			
		||||
  // here again we have a word address
 | 
			
		||||
  for (int x = 0; x < length; x++) {
 | 
			
		||||
    uint8_t ee = spi_transaction(0xA0, 0x00, here*2+x, 0xFF);
 | 
			
		||||
    Serial.print((char) ee);
 | 
			
		||||
  }
 | 
			
		||||
  return STK_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void read_page() {
 | 
			
		||||
  char result = (char)STK_FAILED;
 | 
			
		||||
  int length = 256 * getch() + getch();
 | 
			
		||||
  char memtype = getch();
 | 
			
		||||
  if (CRC_EOP != getch()) {
 | 
			
		||||
    Serial.print((char) STK_NOSYNC);
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
  Serial.print((char) STK_INSYNC);
 | 
			
		||||
  if (memtype == 'F') result = flash_read_page(length);
 | 
			
		||||
  if (memtype == 'E') result = eeprom_read_page(length);
 | 
			
		||||
  Serial.print(result);
 | 
			
		||||
  return;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void read_signature() {
 | 
			
		||||
  if (CRC_EOP != getch()) {
 | 
			
		||||
    Serial.print((char) STK_NOSYNC);
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
  Serial.print((char) STK_INSYNC);
 | 
			
		||||
  uint8_t high = spi_transaction(0x30, 0x00, 0x00, 0x00);
 | 
			
		||||
  Serial.print((char) high);
 | 
			
		||||
  uint8_t middle = spi_transaction(0x30, 0x00, 0x01, 0x00);
 | 
			
		||||
  Serial.print((char) middle);
 | 
			
		||||
  uint8_t low = spi_transaction(0x30, 0x00, 0x02, 0x00);
 | 
			
		||||
  Serial.print((char) low);
 | 
			
		||||
  Serial.print((char) STK_OK);
 | 
			
		||||
}
 | 
			
		||||
//////////////////////////////////////////
 | 
			
		||||
//////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////
 | 
			
		||||
////////////////////////////////////
 | 
			
		||||
int avrisp() { 
 | 
			
		||||
  uint8_t data, low, high;
 | 
			
		||||
  uint8_t ch = getch();
 | 
			
		||||
  switch (ch) {
 | 
			
		||||
  case '0': // signon
 | 
			
		||||
    empty_reply();
 | 
			
		||||
    break;
 | 
			
		||||
  case '1':
 | 
			
		||||
    if (getch() == CRC_EOP) {
 | 
			
		||||
      Serial.print((char) STK_INSYNC);
 | 
			
		||||
      Serial.print("AVR ISP");
 | 
			
		||||
      Serial.print((char) STK_OK);
 | 
			
		||||
    }
 | 
			
		||||
    break;
 | 
			
		||||
  case 'A':
 | 
			
		||||
    get_version(getch());
 | 
			
		||||
    break;
 | 
			
		||||
  case 'B':
 | 
			
		||||
    readbytes(20);
 | 
			
		||||
    set_parameters();
 | 
			
		||||
    empty_reply();
 | 
			
		||||
    break;
 | 
			
		||||
  case 'E': // extended parameters - ignore for now
 | 
			
		||||
    readbytes(5);
 | 
			
		||||
    empty_reply();
 | 
			
		||||
    break;
 | 
			
		||||
 | 
			
		||||
  case 'P':
 | 
			
		||||
    start_pmode();
 | 
			
		||||
    empty_reply();
 | 
			
		||||
    break;
 | 
			
		||||
  case 'U':
 | 
			
		||||
    here = getch() + 256 * getch();
 | 
			
		||||
    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
 | 
			
		||||
    read_page();    
 | 
			
		||||
    break;
 | 
			
		||||
 | 
			
		||||
  case 'V':
 | 
			
		||||
    universal();
 | 
			
		||||
    break;
 | 
			
		||||
  case 'Q':
 | 
			
		||||
    error=0;
 | 
			
		||||
    end_pmode();
 | 
			
		||||
    empty_reply();
 | 
			
		||||
    break;
 | 
			
		||||
    
 | 
			
		||||
  case 0x75: //STK_READ_SIGN
 | 
			
		||||
    read_signature();
 | 
			
		||||
    break;
 | 
			
		||||
 | 
			
		||||
  // expecting a command, not CRC_EOP
 | 
			
		||||
  // this is how we can get back in sync
 | 
			
		||||
  case CRC_EOP:
 | 
			
		||||
    Serial.print((char) STK_NOSYNC);
 | 
			
		||||
    break;
 | 
			
		||||
    
 | 
			
		||||
  // anything else we will return STK_UNKNOWN
 | 
			
		||||
  default:
 | 
			
		||||
    if (CRC_EOP == getch()) 
 | 
			
		||||
      Serial.print((char)STK_UNKNOWN);
 | 
			
		||||
    else
 | 
			
		||||
      Serial.print((char)STK_NOSYNC);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Reference in a new issue