/*Arduino RST GPIO attiny85
22/11/2021
pour valider ou non PB5 en Reset ou en I/O
Sélection faite par un chiffre envoyé à partir du moniteur série
1 = configuration d'origine (1 MHz + reset)
2 = 1 MHz + GPIO
lien:
https://www.youtube.com/watch?v=yAT_TdD6nL0 AVR High-voltage Serial Programmer
Originally created by Paul Willoughby 03/20/2010
www.rickety.us/2010/03/arduino-avr-high-voltage-serial-programmer/ Inspired by Jeff Keyzer mightyohm.com
Serial Programming routines from ATtiny25/45/85 datasheet
test: ok
Brochage ATtiny85
pin13 --- RST =|1 U 8|= VCC --- pin8
pin12 --- SCI =|2 7|= SDO --- pin11
=|3 6|= SII --- pin10
GND =|4 5|= SDI --- pin9
Raccordement module - alim 12V & arduino
_____
|= GND noir GND arduino & alim
|= +12V rouge alim
module |= RST violet 13
CIBLE |= SCI bleu 12
|= SDO vert 11
|= SII jaune 10
|= SDI orange 9
|= VCC rouge 8
_____|
*/
#include "Arduino.h"
// Configuration de fusible souhaitée
// #define LFUSE 0xE2 // 8MHz
#define LFUSE 0x62 // Valeurs par défaut pour ATtiny25/45/85 RC 8 MHz interne avec division par 8, donc 1 MHz.
#define HFUSE 0xDF // Reset actif
#define RST 13 // Sortie vers le décaleur de niveau pour !RESET du transistor à la Pin 1
#define CLKOUT 12 // Connexion à la Pin 2 de l'entrée d'horloge série (SCI)
#define DATAIN 11 // Connexion à la sortie de données série (SDO) Pin 7
#define INSTOUT 10 // Connexion à la Pin 6 de l'entrée d'instruction série (SII)
#define DATAOUT 9 // Connexion à la pin 5 de l'entrée de données série (SDI)
#define VCC 8 // Connexion à VCC Pin 8
int inData = 0; // octet série entrant AVR
int targetValue = HFUSE;
void setup() {
// Configurer les lignes de contrôle pour la programmation parallèle HT
pinMode(VCC, OUTPUT);
pinMode(RST, OUTPUT);
pinMode(DATAOUT, OUTPUT);
pinMode(INSTOUT, OUTPUT);
pinMode(CLKOUT, OUTPUT);
pinMode(DATAIN, OUTPUT); // configuré comme entrée en mode programmation
// Initialiser les broches de sortie selon les besoins
digitalWrite(RST, HIGH); // Le levier de niveau s'inverse, cela coupe le 12V
// démarre le port série à 9600 bps:
Serial.begin(19200);
} // fin setup
void loop() {
switch (establishContact()) {
case
49:// 1 envoyé à partir du moniteur série
targetValue = HFUSE; // reset actif
break;
case
50:// 2 envoyé à partir du moniteur série
targetValue = 0x5F; // Reset inactif
break;
default:
targetValue = HFUSE;
}
Serial.println("Entrée en mode de programmation\n");
// Initialiser les broches pour entrer en mode programmation
pinMode(DATAIN, OUTPUT); //Temporaire
digitalWrite(DATAOUT, LOW);
digitalWrite(INSTOUT, LOW);
digitalWrite(DATAIN, LOW);
digitalWrite(RST, HIGH); // Le levier de niveau s'inverse, cela coupe le 12V
// Entrer en mode de programmation série haute tension
digitalWrite(VCC, HIGH); // Appliquer VCC pour démarrer le processus de programmation
delayMicroseconds(20);
digitalWrite(RST, LOW); // Activer le 12v
delayMicroseconds(10);
pinMode(DATAIN, INPUT); // Libérer DATAIN
delayMicroseconds(300);
//Mode programmation
int hFuse = readFuses();
//Écrivez hfuse si ce n'est pas déjà la valeur que nous voulons 0xDF (pour autoriser RST sur la broche 1)
if (hFuse != targetValue) {
delay(1000);
Serial.print("Ecriture H fuse comme "); Serial.println(targetValue, HEX);
shiftOut2(DATAOUT, INSTOUT, CLKOUT, MSBFIRST, 0x40, 0x4C);
// La fonctionnalité RESET par défaut
//shiftOut2(DATAOUT, INSTOUT, CLKOUT, MSBFIRST, HFUSE, 0x2C);
// cela transforme la broche RST 1 en un port IO (faible)
//shiftOut2(DATAOUT, INSTOUT, CLKOUT, MSBFIRST, 0x5F, 0x2C);
// option sélectionnée par l'utilisateur
shiftOut2(DATAOUT, INSTOUT, CLKOUT, MSBFIRST, targetValue, 0x2C);
shiftOut2(DATAOUT, INSTOUT, CLKOUT, MSBFIRST, 0x00, 0x74);
shiftOut2(DATAOUT, INSTOUT, CLKOUT, MSBFIRST, 0x00, 0x7C);
}
//Ecrire L fuse
delay(1000);
Serial.println("Ecriture L fuse\n");
shiftOut2(DATAOUT, INSTOUT, CLKOUT, MSBFIRST, 0x40, 0x4C);
shiftOut2(DATAOUT, INSTOUT, CLKOUT, MSBFIRST, LFUSE, 0x2C);
shiftOut2(DATAOUT, INSTOUT, CLKOUT, MSBFIRST, 0x00, 0x64);
shiftOut2(DATAOUT, INSTOUT, CLKOUT, MSBFIRST, 0x00, 0x6C);
// Confirmation du nouvel état
hFuse = readFuses();
digitalWrite(CLKOUT, LOW);
digitalWrite(VCC, LOW);
digitalWrite(RST, HIGH); // désactiver le 12v
Serial.println("\nProgrammation terminée. Appuyez sur RESET pour recommencer.");
while (1 == 1) {};
} // fin loop
int establishContact() {
Serial.println("Allumez l'alimentation 12 volts/ \n\n Vous pouvez ACTIVER la broche RST (comme RST) "
" pour autoriser la programmation \n ou DÉSACTIVER pour la transformer en une broche GPIO (faible). \n " );
// Nous devons obtenir un 1 ou 2 pour continuer
int reply;
do {
Serial.println("Entrer 1 pour ACTIVER la broche RST (retour à la normale)");
Serial.println("Entrer 2 pour DESACTIVER la broche RST (en faire une broche GPIO)");
while (!Serial.available()) {
// Attendre l'entrée de la valeur par l'utilisateur
}
reply = Serial.read();
}
while (!(reply == 49 || reply == 50));
return reply;
} // fin etablisContact
int shiftOut2(uint8_t dataPin, uint8_t dataPin1, uint8_t clockPin, uint8_t bitOrder, byte val, byte val1) {
int i;
int inBits = 0;
// Attendre que DATAIN passe au niveau haut
while (!digitalRead(DATAIN)) {
// Rien à faire ici
}
// Bit de départ
digitalWrite(DATAOUT, LOW);
digitalWrite(INSTOUT, LOW);
digitalWrite(clockPin, HIGH);
digitalWrite(clockPin, LOW);
for (i = 0; i < 8; i++) {
if (bitOrder == LSBFIRST) {
digitalWrite(dataPin, !!(val & (1 << i)));
digitalWrite(dataPin1, !!(val1 & (1 << i)));
}
else {
digitalWrite(dataPin, !!(val & (1 << (7 - i))));
digitalWrite(dataPin1, !!(val1 & (1 << (7 - i))));
}
inBits <<= 1;
inBits |= digitalRead(DATAIN);
digitalWrite(clockPin, HIGH);
digitalWrite(clockPin, LOW);
}
// Bits de fin
digitalWrite(DATAOUT, LOW);
digitalWrite(INSTOUT, LOW);
digitalWrite(clockPin, HIGH);
digitalWrite(clockPin, LOW);
digitalWrite(clockPin, HIGH);
digitalWrite(clockPin, LOW);
return inBits;
}
// Retourne la valeur de HFUSE
int readFuses() {
Serial.println("Lectures des fusibles");
//Lire la valeur de Lfuse
shiftOut2(DATAOUT, INSTOUT, CLKOUT, MSBFIRST, 0x04, 0x4C);
shiftOut2(DATAOUT, INSTOUT, CLKOUT, MSBFIRST, 0x00, 0x68);
inData = shiftOut2(DATAOUT, INSTOUT, CLKOUT, MSBFIRST, 0x00, 0x6C);
Serial.print("L fuse se lit comme ");
Serial.println(inData, HEX);
//Lire la valeur de Hfuse
shiftOut2(DATAOUT, INSTOUT, CLKOUT, MSBFIRST, 0x04, 0x4C);
shiftOut2(DATAOUT, INSTOUT, CLKOUT, MSBFIRST, 0x00, 0x7A);
inData = shiftOut2(DATAOUT, INSTOUT, CLKOUT, MSBFIRST, 0x00, 0x7E);
Serial.print("H fuse se lit comme ");
Serial.println(inData, HEX);
int hFuse = inData;
//Lire la valeur Efuse
shiftOut2(DATAOUT, INSTOUT, CLKOUT, MSBFIRST, 0x04, 0x4C);
shiftOut2(DATAOUT, INSTOUT, CLKOUT, MSBFIRST, 0x00, 0x6A);
inData = shiftOut2(DATAOUT, INSTOUT, CLKOUT, MSBFIRST, 0x00, 0x6E);
Serial.print("E fuse se lit comme ");
Serial.println(inData, HEX);
Serial.println();
return hFuse;
}