HV fuse programmer for AVR

Discussion in 'The Projects Forum' started by Tim Weri, Sep 26, 2012.

  1. Tim Weri

    Thread Starter New Member

    Sep 6, 2012
    15
    0
    Hello.
    I am working on making programmers for AVR, and I found an instruction on how to change incorrectly set fuse bits using high voltage programming: http://denki.world3.net/avr_rescue.html
    [​IMG]
    The circuit includes 2 MCUs: an atmega8, and an atmega48/88/168. The atmega8 is used to program the atmega48/88/168 family. However, I want to program a 40-pin atmega32, and the pins are pretty different. Could anyone explain what does each pin of the atmega32, and the atmega48/88/168 do, and how to convert the circuit to fit the atmega32.
    Here's the code for the atmega8:
    Code ( (Unknown Language)):
    1. #include <avr/io.h>
    2. #include <util/delay.h>
    3.  
    4. #define HFUSE   0xDF    // Default for ATmega48/88/168, for others see
    5. #define LFUSE   0x62    // http://www.engbedded.com/cgi-bin/fc.cgi
    6.  
    7. /*
    8. #define  DATA    PORTD // PORTD = Arduino Digital pins 0-7
    9. #define  DATAD   DDRD  // Data direction register for DATA port
    10. #define  VCC     8      PB0
    11. #define  RDY     12     PB4 // RDY/!BSY signal from target
    12. #define  OE      11     PB3
    13. #define  WR      10     PB2
    14. #define  BS1     9      PB1
    15. #define  XA0     13     PB5
    16. #define  XA1     18     PC4 // Analog inputs 0-5 can be addressed as
    17. #define  PAGEL   19     PC5 // digital outputs 14-19
    18. #define  RST     14     PC0 // Output to level shifter for !RESET
    19. #define  BS2     16     PC2
    20. #define  XTAL1   17     PC3
    21.  
    22. #define  BUTTON  15     PC1 // Run button
    23. #define  LED     0
    24. */
    25.  
    26. // PORTB
    27. #define _VCC    (1<<0)
    28. #define _RDY    (1<<4)
    29. #define _OE     (1<<3)
    30. #define _WR     (1<<2)
    31. #define _BS1    (1<<1)
    32. #define _XA0    (1<<5)
    33.  
    34. // PORTC
    35. #define _XA1    (1<<4)
    36. #define _PAGEL  (1<<5)
    37. #define _RST    (1<<0)
    38. #define _BS2    (1<<2)
    39. #define _XTAL1  (1<<3)
    40.  
    41. #define _BUTTON (1<<1)
    42.  
    43. void HardwareInit()
    44. {
    45.     DDRB    = ~(_RDY);          // all outputs except RDY (PB4)
    46.     PORTB   = 0x00;             // no pull-up
    47.  
    48.     DDRC    = ~(_BUTTON);       // all outputs except BUTTON (PC1)
    49.     PORTC   = (_BUTTON)|(_RST); // pull-up and 12V off (PC0 = 1)
    50.  
    51.     DDRD    = 0xff;             // all outputs
    52.     PORTD   = 0x00;
    53. }
    54.  
    55. void sendcmd(unsigned char command)
    56. {
    57.     PORTC |= _XA1;
    58.     PORTB &= ~(_XA0|_BS1);
    59.    
    60.     PORTD = command;
    61.  
    62.     PORTC |= _XTAL1;
    63.     _delay_ms(1);
    64.     PORTC &= ~(_XTAL1);
    65.     _delay_ms(1);
    66. }
    67.  
    68. void writefuse(unsigned char fuse, char highbyte)
    69. {
    70.     PORTC &= ~(_XA1);
    71.     PORTB |= _XA0;
    72.     _delay_ms(1);
    73.  
    74.     PORTD = fuse;
    75.     PORTC |= _XTAL1;
    76.     _delay_ms(1);
    77.     PORTC &= ~(_XTAL1);
    78.  
    79.     if (highbyte)
    80.         PORTB |= _BS1;
    81.     else
    82.         PORTB &= ~(_BS1);
    83.  
    84.     PORTB &= ~(_WR);
    85.     _delay_ms(1);
    86.     PORTB |= _WR;
    87.     _delay_ms(100);
    88. }
    89.  
    90. int main()
    91. {
    92.     HardwareInit();
    93.  
    94.     for (;;)
    95.     {
    96.         while (PINC & _BUTTON) {}   // wait for button
    97.  
    98.         // Initialize pins to enter programming mode
    99.         PORTC &= ~(_PAGEL|_XA1|_BS2);
    100.         PORTB &= ~(_XA0|_BS1);
    101.    
    102.         // Enter programming mode
    103.         PORTB |= _VCC|_WR|_OE;
    104.         _delay_ms(1);
    105.         PORTC &= ~(_RST);
    106.         _delay_ms(1);
    107.  
    108.         // Program HFUSE
    109.         sendcmd(0b01000000);
    110.         writefuse(HFUSE, 1);
    111.  
    112.         // Program LFUSE
    113.         sendcmd(0b01000000);
    114.         writefuse(LFUSE, 0);
    115.  
    116.         _delay_ms(1000);            // allow button to be released
    117.  
    118.         // Exit programming mode
    119.         PORTC |= _RST;
    120.  
    121.         // Turn off outputs
    122.         PORTD = 0x00;
    123.         PORTB &= ~(_VCC|_WR|_OE|_XA0|_BS1);
    124.         PORTC &= ~(_PAGEL|_XA1|_BS2);
    125.     }
    126. }
    127.  
    128.  
    Thanks a lot :D
     
    Last edited: Sep 26, 2012
  2. DickCappels

    Moderator

    Aug 21, 2008
    2,653
    632
    For the purpose of programming, the functions of the pins are the same on both the chips. However, the pins differ. You can see how the functions map between the two chips by comparing the parallel programming diagrams of the data sheets for the respective chips.

    Also, the algorithm for the ATMEGA32 is a little bit more complicated than that of the ATMEGA48; it looks as though the ATMEGA32 has to be treated a little more carefully to make sure it gets into the programming mode, so you will have to alter the programming program to achieve that.

    I think you will see that the parallel (high voltage) programming is pretty simple and straight-forward and that you will have little if any trouble understanding it and how to modify the existing fuse restorer code by reading the Memory Programming section of both datasheets.

    It's not that hard.
     
    Tim Weri likes this.
  3. Tim Weri

    Thread Starter New Member

    Sep 6, 2012
    15
    0
    I see that the atmega32, and 48 have some pins of the same name such as MOSI, MISO, SCK,... Do they do the same job when being programmed ?
     
  4. DickCappels

    Moderator

    Aug 21, 2008
    2,653
    632
    If he were to use the in-circuit (serial) programming method, he could go by those. The parallel (high voltage) method uses several more pins and the assignments of many of them differ between the two. The differences between the pin-outs and the algorithms are readily seen by comparing the relevant sections of the datasheets for the two parts.
     
    Tim Weri likes this.
  5. Tim Weri

    Thread Starter New Member

    Sep 6, 2012
    15
    0
    I have another question. Why does he use bit shifting in every define commands? Why not using hex, or decimal numbers?
     
  6. Tim Weri

    Thread Starter New Member

    Sep 6, 2012
    15
    0
    Here's my Proteus version of that circuit. I changed to Atmega128. I followed the datasheet and this is what I got. Please check it for me. Thank you :D. The switch is quite confusing, I don't know exactly what kind of switch it is...
     
    Last edited: Sep 28, 2012
  7. MrChips

    Moderator

    Oct 2, 2009
    12,440
    3,361
    Hex, decimal or binary would work too.

    #define _XA0 (1<<5)

    also makes sense because this says that he is using bit-5
     
    Tim Weri likes this.
  8. Tim Weri

    Thread Starter New Member

    Sep 6, 2012
    15
    0
    Thanks. I guess I missed that part. Well, still waiting for sb to check the schematic.
     
  9. Tim Weri

    Thread Starter New Member

    Sep 6, 2012
    15
    0
    Oh come on. I don't want to get my board screwed up.
     
Loading...