/*
* HV_Reset_ATmega2560.c
*
* Created: 04-Dec-2022 10:40:22 PM
* Author : D. Porlidas
*/
#include <avr/io.h>
#include <util/delay.h>
void clk (void)
{
PORTA |= (1<<2); // XTAL -> 1
_delay_ms(10); // Delay (150ns min)
PORTA &= ~(1<<2); // XTAL -> 0
_delay_ms(10); // Delay (200ns min)
}
void wrnp (void)
{
PORTD &= ~(1<<3); // WR -> 0
_delay_ms(10); // Delay (150ns min)
PORTD |= (1<<3); // WR -> 1
_delay_ms(20);
}
void blink (void)
{
PORTA &= ~(1<<0); // LED ON
_delay_ms(500); // Delay
PORTA |= (1<<0); // LED OFF
_delay_ms(500); // Delay
}
int main(void)
{
PORTA |= (1<<1); // RESET=0 (RESET Relay -> 1 - Relay arms with 0)
PORTA &= ~(1<<0); // LED ON
PORTA &= ~(1<<2); // XTAL 0
DDRA = 0b00000111; // PA3:0 Output (LED A0, Reset Relay A1, XTAL A2)
PORTA |= (1<<1); // RESET=0 (RESET Relay -> 1 - Relay arms with 0)
PORTA &= ~(1<<0); // LED ON
PORTA &= ~(1<<2); // XTAL 0
DDRC = 0b11111111; // PORTC Output
PORTC = 0;
DDRD = 0b11111101; // PORTD PD1 Input, all others Output
PORTD = 0b11111111;
_delay_ms(500); // Delay
PORTA |= (1<<0); // LED OFF
_delay_ms(200); // Delay
blink();
// START PROGRAMMING SEQUENCE
for (uint8_t i=0; i<8; i++) // Toggle XTAL at least 6 times
{
clk();
}
PORTD = 0b00001110; // Prog_enable bits 0000 (PD7:4 & BS2)
_delay_ms(10); // Delay (Wait at least 100ns)
PORTA &= ~(1<<1); // RESET -> 12V (RESET Relay -> 0 - Relay arms with 0)
_delay_ms(10); // Delay (Wait at least 100ns + 50ns)
blink();
// CHIP ERASE
PORTD |= (1<<6); // XA1 -> 1
PORTC = 0b10000000; // DATA Chip erase command
_delay_ms(10); // Delay (67ns min)
clk(); // Load command
wrnp(); // Write command
while (!(PIND & (1<<1))); // Wait while RDY/BSY=0
_delay_ms(10); // Delay (67ns min)
PORTD &= ~(1<<6); // XA1 -> 0
_delay_ms(10); // Delay
// PROGRAMMING FUSE LOW BITS
PORTD |= (1<<6); // XA1 -> 1
PORTC = 0b01000000; // DATA Programming Fuses command
_delay_ms(10); // Delay (67ns min)
clk(); // Load command
PORTD &= ~(1<<6); // XA1 -> 0
_delay_ms(1);
PORTC = 0xFF; // Fuse Low Bits data
_delay_ms(10); // Delay (67ns min)
clk(); // Load Low Bits data
wrnp(); // Write Low Bits data
while (!(PIND & (1<<1))); // wait while RDY/BSY=0
_delay_ms(10); // Delay
// PROGRAMMING FUSE HIGH BITS
PORTD |= (1<<6); // XA1 -> 1
PORTC = 0b01000000; // DATA Programming Fuses command
_delay_ms(10); // Delay (67ns min)
clk(); // Load command
PORTD &= ~(1<<6); // XA1 -> 0
_delay_ms(1);
PORTC = 0xDF; // Fuse High Bits data
_delay_ms(10); // Delay (67ns min)
clk(); // Load High Bits data
PORTD |= (1<<4); // BS1 -> 1
_delay_ms(10); // Delay
wrnp(); // Write High Bits data
while (!(PIND & (1<<1))); // Wait while RDY/BSY=0
_delay_ms(10); // Delay
PORTD &= ~(1<<4); // BS1 -> 0
_delay_ms(10);
// PROGRAMMING EXTENDED FUSE BITS
PORTD |= (1<<6); // XA1 -> 1
PORTC = 0b01000000; // DATA Programming Fuses command
_delay_ms(10); // Delay (67ns min)
clk(); // Load command
PORTD &= ~(1<<6); // XA1 -> 0
_delay_ms(1);
PORTC = 0xFD; // Extended Fuse Bits data
_delay_ms(10); // Delay (67ns min)
clk(); // Load Extended Bits data
PORTD |= (1<<0); // BS2 -> 1
_delay_ms(10); // Delay
wrnp(); // Write Extended Bits data
while (!(PIND & (1<<1))); // Wait while RDY/BSY=0
_delay_ms(10); // Delay
PORTD &= ~(1<<0); // BS2 -> 0
PORTA |= (1<<1); // RESET=0 (RESET Relay -> 1 - Relay arms with 0)
PORTA &= ~(1<<0); // LED ON
// END OF PROGRAMMING SEQUENCE
}