Author Topic: DIGISPARK as FUSE-Resetter  (Read 42173 times)

gogol

  • Sr. Member
  • ****
  • Posts: 398
DIGISPARK as FUSE-Resetter
« on: July 30, 2013, 10:13:51 am »
Hello,

as I burned now some attinys while playing with the digispark as USB-ISP thanks to littlewire, I thought, that I have to complete my tool-set.

So I did some research and figured out, that the digispark has all, what is needed to fix broken fuses.  However till now I found no way, to report somehow, if the reset worked, as all six ports are used for the reset HVSP-function.

Enclosed a short schematic diagramm showing the wiring. All it needs is six resistors and one NPN transistor. 

I fixed now three attinys, they are again visible to littlewire and other ISP-programmers, as RST is enabled!



Quote
    // HVSP-FUSE-resetter for attiny85 compatibles
// tested with attiny85 in both roles as rescuer and victim
// inspired by https://sites.google.com/site/wayneholder/attiny-fuse-reset
// as a reduced form of
// and http://www.rickety.us/wp-content/uploads/2010/03/hv_serial_prog.pde
// adapted to all informations from the data-sheet of attiny85 as
// both implementations differed.


// defining which PIN will be used for which role

#define  DATAIN   2   // Target Data Input
                      //->connect to PIN7 (SDO) via 1k resistor
#define  RST      5   // connect to 12V switch-Resistor for HVS-programming,
                      // limited current of PB5 no problem for that purpose
                      //->connect via 10k resistor to basis of transistor to PIN1 (RST)
#define  VCC      1   // Target VCC
                      // internal digispark LED indicates therefore when victim gets 5V
                      //->connect to PIN8 (Vcc) direct
#define  INSTOUT  4   // Target Instruction Input
                      // limited high of 3.6V because of zener no problem, as detected as high
                      //->connect to PIN6 (SII) via 1k resistor
#define  CLKOUT   3   // Target Clock Input
                      // limited high of 3.6V because of zener and pullup no problem, as detected as high
                      //->connect to PIN2 (SCI) via 1k resistor
#define  DATAOUT  0   // Target Data Output
                      //->connect to PIN5 (SDI) via 1k resistor

// fuses for attiny85 digispark-compatibel use, without RSTDISBL
// avrdude parameters: -U lfuse:w:0xe1:m -U hfuse:w:0xdd:m -U efuse:w:0xfe:m
#define  HFVAL  0xdd
#define  LFVAL  0xe1
#define  EFVAL  0xfe

// byte constants for HVSP-programming instructions
// see attiny85 datasheet table 20-16
#define _0_0000_0000_00 0b00000000
#define _0_0000_0100_00 0b00000100
#define _0_0000_1000_00 0b00001000
#define _0_0000_1100_00 0b00001100
#define _0_0010_1100_00 0b00101100
#define _0_0100_0000_00 0b01000000
#define _0_0100_1100_00 0b01001100
#define _0_0110_0100_00 0b01100100
#define _0_0110_0110_00 0b01100110
#define _0_0110_1000_00 0b01101000
#define _0_0110_1010_00 0b01101010
#define _0_0110_1100_00 0b01101100
#define _0_0110_1110_00 0b01101110
#define _0_0111_0100_00 0b01110100
#define _0_0111_1010_00 0b01111010
#define _0_0111_1100_00 0b01111100
#define _0_0111_1110_00 0b01111110


boolean fuse_ok = false;

void setup() {
  // all work is done in setup()
  // fuse resetting either works or fails
  // The following instructions are from the datasheet:
  // 1. Set Prog_enable pins listed in Table 20-14 to “000”, RESET pin and VCC to 0V.
  // 2. Apply 4.5 - 5.5V between VCC and GND. Ensure that VCC reaches at least 1.8V within the next 20 μs.
  // 3. Wait 20 - 60 μs, and apply 11.5 - 12.5V to RESET.
  // 4. Keep the Prog_enable pins unchanged for at least 10 μs after the High-voltage has been applied to
  //    ensure the Prog_enable Signature has been latched.
  // 5. Release the Prog_enable[2] pin to avoid drive contention on the Prog_enable[2]/SDO pin.
  // 6. Wait at least 300 μs before giving any serial instructions on SDI/SII.
  // 7. Exit Programming mode by power the device down or by bringing RESET pin to 0V.
 
  pinMode(VCC, OUTPUT);
  pinMode(RST, OUTPUT);
  pinMode(INSTOUT, OUTPUT);
  pinMode(CLKOUT, OUTPUT);
  pinMode(DATAOUT, OUTPUT);     
  pinMode(DATAIN, OUTPUT);     // temporary for fullfilling 1.)
  digitalWrite(RST, HIGH);     // transistor is inverting signal, this shuts off 12V
  digitalWrite(INSTOUT, LOW);
  digitalWrite(DATAOUT, LOW);
  digitalWrite(DATAIN, LOW);
  digitalWrite(VCC, LOW); 
  digitalWrite(VCC, HIGH);     // 2.) switch target Vcc on, internal LED burns
  delayMicroseconds(50);
  digitalWrite(RST, LOW);      // 3.) 12v powered ON
  delayMicroseconds(15);       // 4.)
  pinMode(DATAIN, INPUT);      // 5.) Set DATAIN to input
  delayMicroseconds(330);      // 6.)
  writeFuse(LFVAL, _0_0110_0100_00, _0_0110_1100_00);
  writeFuse(HFVAL, _0_0111_0100_00, _0_0111_1100_00);
  writeFuse(EFVAL, _0_0110_0110_00, _0_0110_1110_00);
  fuse_ok = checkFuses();
  digitalWrite(CLKOUT, LOW);
  digitalWrite(VCC, LOW);      // 7.)
  digitalWrite(RST, HIGH);     //     
}

void clockPulse() {
  digitalWrite(CLKOUT, HIGH);
  digitalWrite(CLKOUT, LOW);


int hvsp_bytes_out( byte val, byte val1)
{
  int inBits = 0;
  // Wait until DATAIN goes high
  while (!digitalRead(DATAIN));  // now we are ready
  // each instruction command has 11 clock pulses
  // one before each of the 8bits, one after each bit, two after each byte
  //initial clock pulse while DATAOUT and INSTOUT LOW
  digitalWrite(DATAOUT, LOW);
  digitalWrite(INSTOUT, LOW);
  clockPulse();
  int i;
  // now the 8 databits
  for (i = 0; i < 8; i++)  {
    digitalWrite(DATAOUT, !!(val & (1 << (7 - i))));
    digitalWrite(INSTOUT, !!(val1 & (1 << (7 - i))));
    // a given return byte starts one bit before output bits!
    // therefore reading it before clock-pulse for out
    inBits <<=1;
    inBits |= digitalRead(DATAIN);
    clockPulse(); 
  }
  // after each byte-group (one byte to DATAOUT and INSTOUT in parallel)
  // two clock-pulses with DATAOUT and INSTOUT LOW
  digitalWrite(DATAOUT, LOW);
  digitalWrite(INSTOUT, LOW);
  clockPulse();
  clockPulse();
  // return the 8-bits read
  // interpretation see datasheet
  return inBits;
}

void writeFuse( byte value, byte instrc3, byte instrc4) {
  hvsp_bytes_out( _0_0100_0000_00, _0_0100_1100_00);
  hvsp_bytes_out( value,           _0_0010_1100_00);
  hvsp_bytes_out( _0_0000_0000_00, instrc3);
  hvsp_bytes_out( _0_0000_0000_00, instrc4);
  // Wait after Instr. 4 until SDO goes high
  while (!digitalRead(DATAIN));


byte readFuse(byte instrc2, byte instrc3) {
  hvsp_bytes_out( _0_0000_0100_00, _0_0100_1100_00);
  hvsp_bytes_out( _0_0000_0000_00, instrc2);
  return hvsp_bytes_out( _0_0000_0000_00, instrc3);


boolean checkFuses () {
  if (LFVAL != readFuse(_0_0110_1000_00, _0_0110_1100_00)) {
    return false;
  } 
  if (HFVAL != readFuse(_0_0111_1010_00, _0_0111_1110_00)) {
    return false;
  } 
  // the only guaranteed value is the first bit
  // all other values the datasheet tells: "don't care!"
  if ((0b00000001 & EFVAL) != ( 0b00000001 &  readFuse(_0_0110_1010_00, _0_0110_1110_00))) {
    return false;
  } 
  return true;
}


void loop() {
  if (! fuse_ok) {
    // any idea, how the status of fuse_ok can be made visible
    // without breaking the function because of additional LEDs or I2C
    // Ideas are welcome!
  }



« Last Edit: July 30, 2013, 11:12:48 am by gogol »

gogol

  • Sr. Member
  • ****
  • Posts: 398
Re: DIGISPARK as FUSE-Resetter
« Reply #1 on: July 31, 2013, 12:59:04 am »
I have right now an idea, how to solve the reporting issue. Unfortunately I am now for two weeks away from my soldering station, so I can work only in theory.

When I connect an I2C display to PB0 and PB2 and put an additional PNP-transistor between 5v and those two pullups, like:


Code: [Select]
                  +5V
                    |
                   e|
                 pnp \|________ from digispark PB1
                     /|
                   c|
                    |
to LCD--+---<4k7>---+---<4k7>---+---to LCD
        |                       |
      to PB0                  to PB2 
   of digispark            of digispark
the pullups should be disabled, while the HSV-programming takes place. As soon, as 5V is shut down, the PNP would enable the pullups.
So far theory, practice will follow in about two weeks, if nobody is faster ;-)

With that solution it should be possible to give perfect feedback, reading even more data like the signature and report it in the display!
As the display stores the content while I2c is off, its possible to send first text to the display, than start HSVP for example reading signature, stop HSVP and send information to the display, and so on.
It should also be no problem, using PB3 for an pushbutton (secured with an transistor like above) for reading input, while 5V on PB1 is off.

The only problem I see, that the I2C slave is interpreting the HSV-protocol and sending some answers.  Should be a very low probability, as the protocol differs and it will start sending first, after he received his address in the first byte.

However, what other possibilities are there?  Is it possible, to switch the pullups including the I2C connection with mosfets or jfets?


The solution could look like:

Code: [Select]
                          +5V
                            |
                            |
        to LCD--+---<4k7>---+---<4k7>---+---to LCD
                |                       |
                |                       |
from PB1____?  some  ?            ?  some  ?____from PB1
            ? switch ?            ? switch ?
                |                       |
             to PB0                  to PB2 
         of digispark            of digispark
     


Someone here, who can give an answer?


Regards

  .g

Bluebie

  • Sr. Member
  • ****
  • Posts: 486
Re: DIGISPARK as FUSE-Resetter
« Reply #2 on: July 31, 2013, 07:05:33 am »
I think if you're sneaky you'll be able to use the tristate ability of the digispark pins to control the vcc and the 12v reset pulse with just one pin, but I'm too sleepy to figure out how.


Otherwise one of my favourite kinds of user feedback is sound - add a little piezo transducer and use toneOut to play a little happy melody when you're finished doing whatever it is you're doing ^_^

Mark

  • Full Member
  • ***
  • Posts: 196
Re: DIGISPARK as FUSE-Resetter
« Reply #3 on: July 31, 2013, 08:37:49 am »
One other thought is to put a led (and resistor) between DataIN and VCC.

You will need to swap DataIn back to and Output (as you do to start with) and maybe pulse it with an errorcode, or solid.
Under your writing phase the LED is reverse biased since VCC will be higher than the DATAIN pin.

Your PNP transistor to the pullups is another possibility.
You need a resistor in the base though to stop it supplying the 5v and stop it being destroyed when 'VCC' is LOW 

Nice job.

Mark

gogol

  • Sr. Member
  • ****
  • Posts: 398
Re: DIGISPARK as FUSE-Resetter
« Reply #4 on: August 13, 2013, 05:43:00 am »
Hi,

I am now back, and I tried different versions, to connect the I2C-LCD. I enhanced my PNP-solution with two transistors between each 4k7 resistor and +5V, to avoid the 9k6 bridge.
However the target controller (that one, which should be fused) is pulling the voltage down to GND via the 1k resistor, even when not powered.

there was finally one working solution, when i used two two-way-switching relays, to toggle PB0 and PB2 of the digispark either via 1k to the corresponding pins of the target controller, or to the I2C bus. Both relays were triggered by PB1 (like the PNP-transistor).

However that solution is ways to complicated, i try now a solution, where I can show success somehow with one or two LEDs.

Finally i think, that the cheap FUSE-resetter with comfortable LCD-logging (and perhaps menu driven decision if the chip should be erased as well) will wait for the (hopefully soon upcoming sibling of the digispark) http://digistump.com/board/index.php/topic,997.html

For right now, my solution is working, as fuses are set.  Making it comfortable with feedback, I prefer LCD messages over just blinking LEDs.

regards

   gogol






bobricius

  • Newbie
  • *
  • Posts: 49
Re: DIGISPARK as FUSE-Resetter
« Reply #5 on: August 13, 2013, 01:03:04 pm »

gogol

  • Sr. Member
  • ****
  • Posts: 398
Re: DIGISPARK as FUSE-Resetter
« Reply #6 on: August 14, 2013, 02:30:52 am »
Hello bobricius,

thanks for that inspiration! 
I compared this solution carefully with mine.
That solution uses the trick, bluebie mentioned earlier in this thread, combining 5V and 12V into 1 pin.
However they make no additional use of it, as they don't use PB5, the digispark can use!
So I compared the usage of the pins (as well as the restrictions) of both solutions. In the first columns are the PINs of the master, in the following columns are the pins from the target, which are connected to the corresponding master-pin:

Pinnamedigispark restrictiongogols solutionremarkbobricius inspirationremark
1PB5/RST            12V     12V-RSTnot used     not used   
2PB3    zener/pullupPB3 (1k)CLKOUT PB3 (direct) CLKOUT     
3PB4    zener       PB1 (1k)INSTOUT5/12V        Vcc and 12V
4GND                                                       
5PB0                PB0 (1k)DATAOUTPB0 (direct) DATAOUT   
6PB1    on-board LEDVcc     Vcc    PB1 (direct) INSTOUT   
7PB2                PB2 (1k)DATAIN PB2 (330/LED)DATAIN     
8Vcc                                                       

I could win one free pin for I2C, swapping the usage of PB1 and PB2 in my solution. I would however still need a solution for the second I2C-pin.
I could use the free pin for some indication via LED. However when I swap the two mentioned pins, I can do the same as in the inspiration-solution:  Give some blink messages with the digispark internal LED.  That is something I couldn't do with my pinout, as I would fire up the target controller together with the LED, which would cause several problems (depending on the program running there).
The target should only have power during HVSP-connections and otherwise not.

Furthermore the inspiration uses an 12V regulator, while I just use a cheap A23 12V-batterie.

Last are there no resistors between both attinys, where I have 1k resistors to prevent damage through shortages.

I will finish up the schematics and the code, when I have cleaned my workarounds. 

The solution for now is just swapping the two pins, and defining some morse-like result codes, I will blink at the end!

As soon, as there is the bigger sibling available (http://digistump.com/board/index.php/topic,997.html), I will continue my LCD-solution.

Regards

  gogol
« Last Edit: August 14, 2013, 02:54:12 am by gogol »

gogol

  • Sr. Member
  • ****
  • Posts: 398
Re: DIGISPARK as FUSE-Resetter
« Reply #7 on: August 14, 2013, 10:53:59 am »
Hello together,

Now i publish the current final version 3.0 of my FUSE resetter.

This version has the following enhancements:
  • the on-board-LED burns permanent, when resetting fuses was succesful
  • the on-board-LED flashes 1:1, when the lockbit is set, preventing reset of fuses
  • when PB4 is hold on high (switch) during start, the target gets erased, which will reset the lockbits
  • when resetting fuses was not successful by other errors, the LED flashes 1:2
As parts are needed: 
  • 7 resistors,
  • a simple pnp-transistor,
  • one push-button
  • one socket for the target-chip (if no breadboard is used)
  • a A23 12V batterie or another 12 Volt source
I checked it now several times with a bunch of different attinys (85/45)  and controlled the settings of the targets with an STK500

Short usage instructions:
  • prepare digispark and load the resetter-code
  • connect digispark to the circuit and connect target
  • supply 12V to Vin of digispark
  • if  the onboard-LED burns steady after 7 sec, everything is ok
  • if the onboard-LED blinks in ration 1:1, at least one lockbit is set
  • in that case remove 12V and press the pushbutton, so PB4 is high
  • supply 12V  to Vin of digispark
if the onboard LED is blinking 1:2, other errors occured, check connections, values of resistors and if the target is really an attiny85/45


Have fun!



Quote
// HVSP-FUSE-resetter for attiny85 compatibles
// tested with attiny85 in both roles as rescuer and victim
// inspired by https://sites.google.com/site/wayneholder/attiny-fuse-reset
// as a reduced form of
// and http://www.rickety.us/wp-content/uploads/2010/03/hv_serial_prog.pde
// adapted to all informations from the data-sheet of attiny85 as
// both implementations differed.

// Version 3.0
// 14. August 2013 by gogol


// defining which PIN will be used for which role

#define  DATAIN   1   // Target Data Input
                      //->connect to PIN7 (SDO) via 1k resistor
#define  RST      5   // connect to 12V switch-Resistor for HVS-programming,
                      // limited current of PB5 no problem for that purpose
                      //->connect via 10k resistor to basis of transistor to PIN1 (RST)
#define  VCC      2   // Target VCC
                      // internal digispark LED indicates therefore when victim gets 5V
                      //->connect to PIN8 (Vcc) direct
#define  INSTOUT  4   // Target Instruction Input
                      // limited high of 3.6V because of zener no problem, as detected as high
                      //->connect to PIN6 (SII) via 1k resistor
#define  CLKOUT   3   // Target Clock Input
                      // limited high of 3.6V because of zener and pullup no problem, as detected as high
                      //->connect to PIN2 (SCI) via 1k resistor
#define  DATAOUT  0   // Target Data Output
                      //->connect to PIN5 (SDI) via 1k resistor

// fuses for attiny85 digispark-compatibel use, without RSTDISBL
// avrdude parameters: -U lfuse:w:0xe1:m -U hfuse:w:0xdd:m -U efuse:w:0xfe:m
#define  HFVAL  0xdd
#define  LFVAL  0xe1
#define  EFVAL  0xfe

// byte constants for HVSP-programming instructions
// see attiny85 datasheet table 20-16
#define _0_0000_0000_00 0b00000000
#define _0_0000_0100_00 0b00000100
#define _0_0000_1000_00 0b00001000
#define _0_0000_1100_00 0b00001100
#define _0_0010_1100_00 0b00101100
#define _0_0100_0000_00 0b01000000
#define _0_0100_1100_00 0b01001100
#define _0_0110_0100_00 0b01100100
#define _0_0110_0110_00 0b01100110
#define _0_0110_1000_00 0b01101000
#define _0_0110_1010_00 0b01101010
#define _0_0110_1100_00 0b01101100
#define _0_0110_1110_00 0b01101110
#define _0_0111_0100_00 0b01110100
#define _0_0111_1000_00 0b01111000
#define _0_0111_1010_00 0b01111010
#define _0_0111_1100_00 0b01111100
#define _0_0111_1110_00 0b01111110
#define _0_1000_0000_00 0b10000000


boolean fuse_ok      = false;
boolean lock_bit_set = false;
boolean eraseChip    = false;

void setup() {
  // all work is done in setup()
  // fuse resetting either works or fails
  // The following instructions are from the datasheet:
  // 1. Set Prog_enable pins listed in Table 20-14 to “000”, RESET pin and VCC to 0V.
  // 2. Apply 4.5 - 5.5V between VCC and GND. Ensure that VCC reaches at least 1.8V within the next 20 μs.
  // 3. Wait 20 - 60 μs, and apply 11.5 - 12.5V to RESET.
  // 4. Keep the Prog_enable pins unchanged for at least 10 μs after the High-voltage has been applied to
  //    ensure the Prog_enable Signature has been latched.
  // 5. Release the Prog_enable[2] pin to avoid drive contention on the Prog_enable[2]/SDO pin.
  // 6. Wait at least 300 μs before giving any serial instructions on SDI/SII.
  // 7. Exit Programming mode by power the device down or by bringing RESET pin to 0V.

 
  pinMode(VCC, OUTPUT);
  digitalWrite(VCC, LOW);      // make sure, no +5V on target
  pinMode(RST, OUTPUT);
  digitalWrite(RST, HIGH);     // transistor is inverting signal, this shuts off 12V
  pinMode(CLKOUT, OUTPUT);
  digitalWrite(CLKOUT, LOW);   
  pinMode(DATAOUT, OUTPUT);     
  digitalWrite(DATAOUT, LOW);
  pinMode(DATAIN, OUTPUT);     // temporary for fullfilling 1.)
  digitalWrite(DATAIN, LOW);

  pinMode(INSTOUT, INPUT);
  if (digitalRead(INSTOUT)) {
     eraseChip = true;          // when INSTOUT is high at startup, the chip should be erased
  };
  while (digitalRead(INSTOUT)); // make sure, the key is not longer pressed
  delay(500);

  pinMode(INSTOUT, OUTPUT);     // now set INSTOUT as well to OUTPUT!
  digitalWrite(INSTOUT, LOW);

  digitalWrite(VCC, HIGH);     // 2.) switch target Vcc on, internal LED burns
  delayMicroseconds(50);
  digitalWrite(RST, LOW);      // 3.) 12v powered ON
  delayMicroseconds(15);       // 4.)
  pinMode(DATAIN, INPUT);      // 5.) Set DATAIN to input
  delayMicroseconds(330);      // 6.)
  if (eraseChip) {
    chipErase();
  } 
  if (( 0b00000110 & readLockBits()) != 0b00000110) {
    lock_bit_set = true;
  }  else {
    writeFuse(LFVAL, _0_0110_0100_00, _0_0110_1100_00);
    writeFuse(HFVAL, _0_0111_0100_00, _0_0111_1100_00);
    writeFuse(EFVAL, _0_0110_0110_00, _0_0110_1110_00);
    fuse_ok = checkFuses();
  } 

  digitalWrite(CLKOUT, LOW);
  digitalWrite(VCC, LOW);      // 7.)
  digitalWrite(RST, HIGH);     //     
  pinMode(DATAIN, OUTPUT);     // change to output, so loop can blink codes
  digitalWrite(DATAIN, LOW);

 
}

void clockPulse() {
  digitalWrite(CLKOUT, HIGH);
  digitalWrite(CLKOUT, LOW);


int hvsp_bytes_out( byte val, byte val1)
{
  int inBits = 0;
  // Wait until DATAIN goes high
  while (!digitalRead(DATAIN));  // now we are ready
  // each instruction command has 11 clock pulses
  // one before each of the 8bits, one after each bit, two after each byte
  //initial clock pulse while DATAOUT and INSTOUT LOW
  digitalWrite(DATAOUT, LOW);
  digitalWrite(INSTOUT, LOW);
  clockPulse();
  int i;
  // now the 8 databits
  for (i = 0; i < 8; i++)  {
    digitalWrite(DATAOUT, !!(val & (1 << (7 - i))));
    digitalWrite(INSTOUT, !!(val1 & (1 << (7 - i))));
    // a given return byte starts one bit before output bits!
    // therefore reading it before clock-pulse for out
    inBits <<=1;
    inBits |= digitalRead(DATAIN);
    clockPulse(); 
  }
  // after each byte-group (one byte to DATAOUT and INSTOUT in parallel)
  // two clock-pulses with DATAOUT and INSTOUT LOW
  digitalWrite(DATAOUT, LOW);
  digitalWrite(INSTOUT, LOW);
  clockPulse();
  clockPulse();
  // return the 8-bits read
  // interpretation see datasheet
  return inBits;
}

void writeFuse( byte value, byte instrc3, byte instrc4) {
  hvsp_bytes_out( _0_0100_0000_00, _0_0100_1100_00);
  hvsp_bytes_out( value,           _0_0010_1100_00);
  hvsp_bytes_out( _0_0000_0000_00, instrc3);
  hvsp_bytes_out( _0_0000_0000_00, instrc4);
  // Wait after Instr. 4 until SDO goes high
  while (!digitalRead(DATAIN));


byte readFuse(byte instrc2, byte instrc3) {
  hvsp_bytes_out( _0_0000_0100_00, _0_0100_1100_00);
  hvsp_bytes_out( _0_0000_0000_00, instrc2);
  return hvsp_bytes_out( _0_0000_0000_00, instrc3);


byte readLockBits( ) {
  hvsp_bytes_out( _0_0000_0100_00, _0_0100_1100_00);
  hvsp_bytes_out( _0_0000_0000_00, _0_0111_1000_00);
  return hvsp_bytes_out( _0_0000_0000_00, _0_0111_1100_00);


void chipErase( ) {
  hvsp_bytes_out( _0_1000_0000_00, _0_0100_1100_00);
  hvsp_bytes_out( _0_0000_0000_00, _0_0110_0100_00);
  hvsp_bytes_out( _0_0000_0000_00, _0_0110_1100_00);
  // Wait after Instr. 3 until SDO goes high
  while (!digitalRead(DATAIN));


boolean checkFuses () {
  if (LFVAL != readFuse(_0_0110_1000_00, _0_0110_1100_00)) {
    return false;
  } 
  if (HFVAL != readFuse(_0_0111_1010_00, _0_0111_1110_00)) {
    return false;
  } 
  // the only guaranteed value is the first bit
  // all other values the datasheet tells: "don't care!"
  if ((0b00000001 & EFVAL) != ( 0b00000001 &  readFuse(_0_0110_1010_00, _0_0110_1110_00))) {
    return false;
  } 
  return true;
}


void loop() {
  if (fuse_ok) { // LED on, when fusing was ok
      digitalWrite(DATAIN, HIGH);
  } else if (lock_bit_set) {
      digitalWrite(DATAIN, HIGH); // LED blinking 1:1, when lock-bit set
      delay(1000);
      digitalWrite(DATAIN, LOW);
      delay(1000);
  } else {
      digitalWrite(DATAIN, HIGH); // LED blinking 1:2, when error in fusing
      delay(500);
      digitalWrite(DATAIN, LOW);
      delay(1000);
  } 



« Last Edit: August 14, 2013, 11:00:52 am by gogol »

CBcracker

  • Jr. Member
  • **
  • Posts: 80
Re: DIGISPARK as FUSE-Resetter
« Reply #8 on: August 14, 2013, 03:43:26 pm »

Furthermore the inspiration uses an 12V regulator, while I just use a cheap A23 12V-batterie.

Or just use 12v from a PC power supply.  1 side of the 3.5" floppy power connector plugs easily onto a 2-pin 0.1" male header.

CBcracker

  • Jr. Member
  • **
  • Posts: 80
Re: DIGISPARK as FUSE-Resetter
« Reply #9 on: August 15, 2013, 12:55:15 am »
p.s. nice work.  I'm going to try it out once the digispark I ordered last weekend (the 15% off sale) arrives.  Given what I've seen playing with parallel port programming, I think I can simplify your design so it works without the transistor and no resistors.
As you suggested, it's perfect for a small breadboard.  When you can get a small breadboard for $1.56 shipped, I don't think there's any point in Digistump trying to sell a fuse resetter shield.
https://www.fasttech.com/products/0/10002010/1144000-mini-170-tie-points-prototype-solderless-breadboar


digistump

  • Administrator
  • Hero Member
  • *****
  • Posts: 1465
Re: DIGISPARK as FUSE-Resetter
« Reply #10 on: August 15, 2013, 01:10:54 am »
There is certainly no point in us selling anything when compared to the price of a breadboard and parts! Except that we put it together, support it, etc - but if you look at my work bench you'll see lots of proto-boards with parts (I hate breadboards) and very few "manufactured" kits and boards - except of course the ones we are testing. The main feature of the fuse resetter shield we have in the works is that it has a 5v->12v step up on it - though I don't really think it is necessary it is often requested.

gogol

  • Sr. Member
  • ****
  • Posts: 398
Re: DIGISPARK as FUSE-Resetter
« Reply #11 on: August 15, 2013, 02:01:57 am »
the 12V stepup can be taken out of bobricius inpiration link.
However i believe, that such a thing should stay as simple as possible.  An A23 batterie is cheap, and there are more 12V sources around, CBcracker posted one!

@cbcracker:  the 1k resistors could be left of for sure, in bobricius link they are not in.  But in this case, you must make 100% sure, that you don't power the target with immediatley giving 12V to reset. Otherwise the target may boot and run its own programs, generating shortages between both controllers.
As resistors are cheap and not breaking anything here, why not.  If you build it in a bread-board the resistor gives the connection between both controllers.

If you find a solution without the transistor, or any other improvement, i am more than curious.

I believe, that this is something, people will put together not in advance, but on that day, they locked down their attiny.  For that purpose simplicity is key!

So I think, that it might be a good plan, to mark certain resistors as optional.


Regards

  gogol

digistump

  • Administrator
  • Hero Member
  • *****
  • Posts: 1465
Re: DIGISPARK as FUSE-Resetter
« Reply #12 on: August 15, 2013, 03:23:57 am »
Agreed on it being put together right after locking down your attiny - I built these types of circuits over and over (and should have soldered them down!) when I was developing the Digispark - I have a version somewhere that is just a relay shield and a 12v source on the VIN pin to power the Digispark and then jumpered over to the relay screw terminal - to make the relay work (because of the switching delay) I had to remove some delays from the code I was using, but it worked!

Grezzo

  • Newbie
  • *
  • Posts: 4
Re: DIGISPARK as FUSE-Resetter
« Reply #13 on: December 15, 2015, 02:05:50 am »
Would the circuit and code from @gogol work to reset the fuses on a digispark that has had a bad firmware update, or would the other components on the "broken" digispark get in the way of resetting the fuses?