ArduinoISP Versión 04m3

Descargar como docx, pdf o txt
Descargar como docx, pdf o txt
Está en la página 1de 15

//

ArduinoIS
P versión
04m3
// Copyright (c) 2008-2011 Randall Bohn
// Si necesita una licencia, vea
// http://www.opensource.org/licenses/bsd-license.php
//
// Este boceto convierte al Arduino en un AVRISP
// usando los siguientes pines arduino:
//
// nombre del pin: not-mega: mega (1280 y 2560)
// reinicio esclavo: 10: 53
// MOSI: 11: 51
// MISO: 12: 50
// SCK: 13: 52
//
// Coloque un LED (con resistencia) en los siguientes pines:
// 9: Heartbeat: muestra que el programador se está ejecutando
// 8: Error: se ilumina si algo sale mal (use rojo si eso tiene sentido)
// 7: Programación - En comunicación con el esclavo
//
// 23 de julio de 2011 Randall Bohn
// -Dirección Arduino número 509 :: Portabilidad de ArduinoISP
// http://code.google.com/p/arduino/issues/detail?id=509
//
// octubre de 2010 por Randall Bohn
// - Escribir en EEPROM> 256 bytes
// - Mejor uso de LED:
// - Flash LED_PMODE en cada confirmación flash
// - Flash LED_PMODE al escribir EEPROM (ambos dan retroalimentación
visual del progreso de la escritura)
// - Enciende LED_ERR cada vez que golpeamos un STK_NOSYNC. Apáguelo
cuando vuelva a sincronizarse.
// - Usa pins_arduino.h (también debería funcionar en Arduino Mega)
//
// octubre de 2009 por David A. Mellis
// - Se agregó soporte para el comando de lectura de firma
//
// febrero de 2009 por Randall Bohn
// - Se agregó soporte para escribir en EEPROM (¿qué tomó tanto tiempo?)
// Los usuarios de Windows deberían considerar la posibilidad de WinAVR
en lugar de
// avrdude incluido con el software Arduino.
//
// enero de 2008 por Randall Bohn
// - Gracias a Amplificar por ayudarme con el protocolo STK500
// - El protocolo AVRISP / STK500 (mk I) se usa en el cargador de
arranque arduino
// - Las funciones de SPI aquí desarrolladas para el programador
AVR910_ARD
// - Más información en http://code.google.com/p/mega-isp

#include "pins_arduino.h"
#definir RESET SS

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

#define HWVER 2
#define SWMAJ 1
#definir SWMIN 18

// Definiciones STK
#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 es un espacio ...

pulso vacío (pin int, int veces);

configuración nula () {
Serial.begin (19200);
pinMode (LED_PMODE, SALIDA);
pulso (LED_PMODE, 2);
pinMode (LED_ERR, OUTPUT);
pulso (LED_ERR, 2);
pinMode (LED_HB, SALIDA);
pulso (LED_HB, 2);
}

int error = 0;
int pmode = 0;
// dirección para leer y escribir, establecida por el comando 'U'
ahí;
uint8_t buff [256]; // almacenamiento global en bloque

#define beget16 (addr) (* addr * 256 + * (addr + 1))


typedef struct param {
uint8_t devicecode;
uint8_t revision;
uint8_t progtype;
uint8_t parmode;
uint8_t sondeo;
uint8_t selftimed;
uint8_t lockbytes;
uint8_t fusebytes;
int flashpoll;
int eeprompoll;
int tamaño de página;
int eepromsize;
int flashsize;
}
parámetro;

parámetro param;

// esto proporciona un latido en el pin 9, por lo que puede decir que el


software se está ejecutando.
uint8_t hbval = 128;
int8_t hbdelta = 8;
latido vacío () {
if (hbval> 192) hbdelta = -hbdelta;
if (hbval <32) hbdelta = -hbdelta;
hbval + = hbdelta;
analogWrite (LED_HB, hbval);
retraso (20);
}

bucle vacío (vacío) {


// ¿está activo pmode?
if (pmode) digitalWrite (LED_PMODE, HIGH);
más digitalWrite (LED_PMODE, BAJO);
// ¿hay algún error?
if (error) digitalWrite (LED_ERR, HIGH);
de lo contrario digitalWrite (LED_ERR, LOW);

// enciende el LED del latido del corazón


latido del corazón();
if (Serial.available ()) {
avrisp ();
}
}

uint8_t getch () {
while (! Serial.available ());
volver Serial.read ();
}
relleno vacío (int n) {
para (int x = 0; x <n; x ++) {
buff [x] = getch ();
}
}

#define PTIME 30
pulso vacío (int pin, int veces) {
hacer {
digitalWrite (pin, ALTO);
retraso (PTIME);
digitalWrite (pin, BAJO);
retraso (PTIME);
}
while (veces--);
}

vog prog_lamp (int estado) {


si (PROG_FLICKER)
digitalWrite (LED_PMODE, estado);
}

nulo spi_init () {
uint8_t x;
SPCR = 0x53;
x = SPSR;
x = SPDR;
}

nulo spi_wait () {
hacer {
}
while (! (SPSR & (1 << SPIF)));
}

uint8_t spi_send (uint8_t b) {


uint8_t respuesta;
SPDR = b;
spi_wait ();
respuesta = SPDR;
respuesta de respuesta;
}

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);
devuelve spi_send (d);
}
void empty_reply () {
if (CRC_EOP == getch ()) {
Serial.print ((char) STK_INSYNC);
Serial.print ((char) STK_OK);
}
más {
error ++;
Serial.print ((char) STK_NOSYNC);
}
}

vacío breply (uint8_t b) {


if (CRC_EOP == getch ()) {
Serial.print ((char) STK_INSYNC);
Serial.print ((char) b);
Serial.print ((char) STK_OK);
}
más {
error ++;
Serial.print ((char) STK_NOSYNC);
}
}

void get_version (uint8_t c) {


interruptor (c) {
caso 0x80:
brevemente (HWVER);
descanso;
caso 0x81:
breply (SWMAJ);
descanso;
caso 0x82:
brevemente (SWMIN);
descanso;
caso 0x93:
brevemente ('S'); // programador en serie
descanso;
defecto:
brevemente (0);
}
}

void set_parameters () {
// llama a esto después de leer el paquete de parámetros en 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];
// ignorar buff [9] (= buff [8])
// los siguientes son 16 bits (big endian)
param.eeprompoll = beget16 (& buff [10]);
param.pagesize = beget16 (& buff [12]);
param.eepromsize = beget16 (& buff [14]);

// Tamaño de flash de 32 bits (big endian)


param.flashsize = buff [16] * 0x01000000
+ beneficio [17] * 0x00010000
+ beneficio [18] * 0x00000100
+ buff [19];

void start_pmode () {
spi_init ();
// los siguientes retrasos pueden no funcionar en todos los
objetivos ...
pinMode (RESET, OUTPUT);
digitalWrite (RESET, ALTO);
pinMode (SCK, SALIDA);
digitalWrite (SCK, LOW);
retraso (50);
digitalWrite (RESET, BAJO);
retraso (50);
pinMode (MISO, INPUT);
pinMode (MOSI, SALIDA);
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;
}

nulo universal () {
int w;
uint8_t ch;

relleno (4);
ch = spi_transaction (beneficio [0], beneficio [1], beneficio [2],
beneficio [3]);
brevemente (ch);
}

void flash (uint8_t hilo, int addr, uint8_t data) {


spi_transaction (0x40 + 8 * hilo,
addr >> 8 y 0xFF,
addr y 0xFF,
datos);
}
void commit (int addr) {
if (PROG_FLICKER) prog_lamp (BAJO);
spi_transaction (0x4C, (addr >> 8) & 0xFF, addr & 0xFF, 0);
si (PROG_FLICKER) {
retraso (PTIME);
prog_lamp (ALTO);
}
}
// # define _current_page (x) (aquí y 0xFFFFE0)
int current_page (int addr) {
if (param.pagesize == 32) regresa aquí & 0xFFFFFFF0;
if (param.pagesize == 64) regresa aquí & 0xFFFFFFE0;
if (param.pagesize == 128) regresa aquí & 0xFFFFFFC0;
if (param.pagesize == 256) regresa aquí & 0xFFFFFF80;
regrese aquí;
}

void write_flash (int longitud) {


relleno (longitud);
if (CRC_EOP == getch ()) {
Serial.print ((char) STK_INSYNC);
Serial.print ((char) write_flash_pages (length));
}
más {
error ++;
Serial.print ((char) STK_NOSYNC);
}
}

uint8_t write_flash_pages (int longitud) {


int x = 0;
int page = current_page (aquí);
mientras que (x <longitud) {
if (page! = current_page (aquí)) {
commit (página);
página = página_actual (aquí);
}
flash (BAJO, aquí, buff [x ++]);
flash (HIGH, aquí, buff [x ++]);
aquí ++;
}

commit (página);

volver STK_OK;
}

#definir EECHUNK (32)


uint8_t write_eeprom (int longitud) {
// aquí hay una dirección de palabra, obtenga la dirección de byte
int inicio = aquí * 2;
int restante = longitud;
if (longitud> param.eepromsize) {
error ++;
volver STK_FAILED;
}
while (restante> EECHUNK) {
write_eeprom_chunk (inicio, EECHUNK);
inicio + = EECHUNK;
restante - = EECHUNK;
}
write_eeprom_chunk (inicio, restante);
volver STK_OK;
}
// escribir bytes (longitud), (inicio) es una dirección de byte
uint8_t write_eeprom_chunk (int inicio, int longitud) {
// esto escribe byte-by-byte,
// la escritura de la página puede ser más rápida (4 bytes a la vez)
relleno (longitud);
prog_lamp (BAJA);
para (int x = 0; x <longitud; x ++) {
int addr = inicio + x;
spi_transaction (0xC0, (addr >> 8) & 0xFF, addr & 0xFF, buff [x]);
retraso (45);
}
prog_lamp (ALTO);
volver STK_OK;
}

void program_page () {
resultado de char = (char) STK_FAILED;
int longitud = 256 * getch ();
longitud + = getch ();
char memtype = getch ();
// memoria flash @ aquí, (longitud) bytes
if (memtype == 'F') {
escribir_flash (longitud);
regreso;
}
if (memtype == 'E') {
resultado = (char) write_eeprom (longitud);
if (CRC_EOP == getch ()) {
Serial.print ((char) STK_INSYNC);
Serial.print (resultado);
}
más {
error ++;
Serial.print ((char) STK_NOSYNC);
}
regreso;
}
Serial.print ((char) STK_FAILED);
regreso;
}

uint8_t flash_read (uint8_t hilo, int addr) {


return spi_transaction (0x20 + hilo * 8,
(addr >> 8) y 0xFF,
addr y 0xFF,
0);
}

char flash_read_page (longitud int) {


para (int x = 0; x <longitud; x + = 2) {
uint8_t low = flash_read (BAJO, aquí);
Serial.print ((char) bajo);
uint8_t high = flash_read (HIGH, aquí);
Serial.print ((char) alto);
aquí ++;
}
volver STK_OK;
}

char eeprom_read_page (int longitud) {


// aquí nuevamente tenemos una dirección de palabra
int inicio = aquí * 2;
para (int x = 0; x <longitud; x ++) {
int addr = inicio + x;
uint8_t ee = spi_transaction (0xA0, (addr >> 8) & 0xFF, addr & 0xFF,
0xFF);
Serial.print ((char) ee);
}
volver STK_OK;
}

void read_page () {
resultado de char = (char) STK_FAILED;
int longitud = 256 * getch ();
longitud + = getch ();
char memtype = getch ();
if (CRC_EOP! = getch ()) {
error ++;
Serial.print ((char) STK_NOSYNC);
regreso;
}
Serial.print ((char) STK_INSYNC);
if (memtype == 'F') result = flash_read_page (length);
if (memtype == 'E') result = eeprom_read_page (length);
Serial.print (resultado);
regreso;
}

void read_signature () {
if (CRC_EOP! = getch ()) {
error ++;
Serial.print ((char) STK_NOSYNC);
regreso;
}
Serial.print ((char) STK_INSYNC);
uint8_t high = spi_transaction (0x30, 0x00, 0x00, 0x00);
Serial.print ((char) alto);
uint8_t middle = spi_transaction (0x30, 0x00, 0x01, 0x00);
Serial.print ((char) medio);
uint8_t low = spi_transaction (0x30, 0x00, 0x02, 0x00);
Serial.print ((char) bajo);
Serial.print ((char) STK_OK);
}
//////////////////////////////////////////
//////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////
/
/////////////////////////////////////////////////////////////////////////
/
int avrisp () {
uint8_t datos, bajo, alto;
uint8_t ch = getch ();
interruptor (ch) {
caso '0': // inicio de sesión
error = 0;
empty_reply ();
descanso;
caso 1':
if (getch () == CRC_EOP) {
Serial.print ((char) STK_INSYNC);
Serial.print ("AVR ISP");
Serial.print ((char) STK_OK);
}
descanso;
caso 'A':
get_version (getch ());
descanso;
caso 'B':
relleno (20);
set_parameters ();
empty_reply ();
descanso;
caso 'E': // parámetros extendidos - ignorar por ahora
relleno (5);
empty_reply ();
descanso;

caso 'P':
start_pmode ();
empty_reply ();
descanso;
caso 'U': // establecer dirección (palabra)
aquí = getch ();
aquí + = 256 * getch ();
empty_reply ();
descanso;

caso 0x60: // STK_PROG_FLASH


bajo = getch ();
alto = getch ();
empty_reply ();
descanso;
caso 0x61: // STK_PROG_DATA
datos = getch ();
empty_reply ();
descanso;

caso 0x64: // STK_PROG_PAGE


program_page ();
descanso;

caso 0x74: // STK_READ_PAGE 't'


read_page ();
descanso;

caso 'V': // 0x56


universal();
descanso;
caso 'Q': // 0x51
error = 0;
end_pmode ();
empty_reply ();
descanso;

caso 0x75: // STK_READ_SIGN 'u'


read_signature ();
descanso;
// esperando un comando, no CRC_EOP
// así es como podemos volver a sincronizarnos
caso CRC_EOP:
error ++;
Serial.print ((char) STK_NOSYNC);
descanso;

// cualquier otra cosa devolveremos STK_UNKNOWN


defecto:
error ++;
if (CRC_EOP == getch ())
Serial.print ((char) STK_UNKNOWN);
más
Serial.print ((char) STK_NOSYNC);
}
}

También podría gustarte