Сделал автономный программатор для AVR с блекджеком и девочками, т.е. с экраном и SD картой. Пока для затравочки закидываю часть кода. Если тема будет интересна, продолжу )
#ifndef ARDUINOISP_H
#define ARDUINOISP_H
#define ARDUINOISP_PIN_RESET A3
#define ARDUINOISP_PIN_MOSI A2
#define ARDUINOISP_PIN_MISO A1
#define ARDUINOISP_PIN_SCK A0
#define SPI_CLOCK (1000000 / 6 )
class BitBangedSPI {
public:
void begin() {
digitalWrite(ARDUINOISP_PIN_SCK, LOW);
digitalWrite(ARDUINOISP_PIN_MOSI, LOW);
pinMode(ARDUINOISP_PIN_SCK, OUTPUT);
pinMode(ARDUINOISP_PIN_MOSI, OUTPUT);
pinMode(ARDUINOISP_PIN_MISO, INPUT);
}
void beginTransaction(uint32_t clock) {
pulseWidth = (500000 + clock - 1) / clock;
if (pulseWidth == 0) {
pulseWidth = 1;
}
}
void end() {}
uint8_t transfer(uint8_t b) {
for (unsigned int i = 0; i < 8; ++i) {
digitalWrite(ARDUINOISP_PIN_MOSI, (b & 0x80) ? HIGH : LOW);
digitalWrite(ARDUINOISP_PIN_SCK, HIGH);
delayMicroseconds(pulseWidth);
b = (b << 1) | digitalRead(ARDUINOISP_PIN_MISO);
digitalWrite(ARDUINOISP_PIN_SCK, LOW); // slow pulse
delayMicroseconds(pulseWidth);
}
return b;
}
private:
unsigned long pulseWidth; // in microseconds
};
static BitBangedSPI SPI_BB;
void Serial_print_HEX(uint8_t n) {
if (n <= 0x0F) Serial.print("0");
Serial.print(n, HEX);
}
void reset_target(bool reset) {
digitalWrite(ARDUINOISP_PIN_RESET, reset ? LOW : HIGH);
}
uint8_t spi_transaction(uint8_t a, uint8_t b, uint8_t c, uint8_t d) {
SPI_BB.transfer(a);
SPI_BB.transfer(b);
SPI_BB.transfer(c);
return SPI_BB.transfer(d);
}
uint8_t spi_enable_prog_mode() {
uint8_t res;
SPI_BB.transfer(0xAC);
SPI_BB.transfer(0x53);
res = SPI_BB.transfer(0x00);
SPI_BB.transfer(0x00);
if (res == 0x53) return 0;
else return 1;
}
uint8_t start_pmode() {
Serial.println("start programm mode");
reset_target(true);
pinMode(ARDUINOISP_PIN_RESET, OUTPUT);
SPI_BB.begin();
SPI_BB.beginTransaction(SPI_CLOCK);
digitalWrite(ARDUINOISP_PIN_SCK, LOW);
delay(20);
reset_target(false);
delayMicroseconds(100);
reset_target(true);
delay(50);
return spi_enable_prog_mode();
}
void end_pmode() {
Serial.println("end programm mode");
SPI_BB.end();
pinMode(ARDUINOISP_PIN_MOSI, INPUT);
pinMode(ARDUINOISP_PIN_SCK, INPUT);
reset_target(false);
pinMode(ARDUINOISP_PIN_RESET, INPUT);
}
void spi_transaction_test(uint8_t a, uint8_t b, uint8_t c, uint8_t d) {
Serial_print_HEX(SPI_BB.transfer(a));
Serial_print_HEX(SPI_BB.transfer(b));
Serial_print_HEX(SPI_BB.transfer(c));
Serial_print_HEX(SPI_BB.transfer(d));
Serial.println();
}
uint8_t flash_read(uint8_t hilo, unsigned int addr) {
return spi_transaction(0x20 + hilo * 8, (addr >> 8) & 0xFF, addr & 0xFF, 0);
}
void flash_read_page(unsigned int start, int length) {
unsigned int here = start / 2;
for (int x = 0; x < length; x += 2) {
uint8_t low = flash_read(LOW, here);
Serial_print_HEX(low);
Serial.print(" ");
uint8_t high = flash_read(HIGH, here);
Serial_print_HEX(high);
Serial.print(" ");
here++;
}
Serial.println();
}
void flash_read_page_buffer(uint8_t *buff, unsigned int start, int length) {
unsigned int here = start / 2;
for (int x = 0; x < length; x += 2) {
buff[x] = flash_read(LOW, here);
buff[x + 1] = flash_read(HIGH, here);
here++;
}
}
void eeprom_read_page(unsigned int start, int length) {
for (int x = 0; x < length; x++) {
int addr = start + x;
uint8_t ee = spi_transaction(0xA0, (addr >> 8) & 0xFF, addr & 0xFF, 0xFF);
Serial_print_HEX(ee);
Serial.print(" ");
}
}
void write_flash(uint8_t hilo, unsigned int addr, uint8_t data) {
spi_transaction(0x40 + 8 * hilo, addr >> 8 & 0xFF, addr & 0xFF, data);
}
void commit(unsigned int addr) {
spi_transaction(0x4C, (addr >> 8) & 0xFF, addr & 0xFF, 0);
}
void write_flash_page(uint8_t *buff, unsigned int start, unsigned int length) {
unsigned int here = start / 2;
int x = 0;
unsigned int page = here & 0xFFFFFFF0;
// Serial.println(page);
while (x < length) {
if (page != here & 0xFFFFFFF0) {
commit(page);
page = here & 0xFFFFFFF0;
delay(20);
}
write_flash(LOW, here, buff[x++]);
write_flash(HIGH, here, buff[x++]);
here++;
}
commit(page);
delay(20);
}
void write_eeprom_page(uint8_t *buff, unsigned int start, unsigned int length) {
for (unsigned int x = 0; x < length; x++) {
unsigned int addr = start + x;
spi_transaction(0xC0, (addr >> 8) & 0xFF, addr & 0xFF, buff[x]);
delay(20);
}
}
void read_signature() {
Serial.print("signature: ");
uint8_t high = spi_transaction(0x30, 0x00, 0x00, 0x00);
Serial_print_HEX(high);
Serial.print(" ");
uint8_t middle = spi_transaction(0x30, 0x00, 0x01, 0x00);
Serial_print_HEX(middle);
Serial.print(" ");
uint8_t low = spi_transaction(0x30, 0x00, 0x02, 0x00);
Serial_print_HEX(low);
Serial.println(" ");
}
void read_fuse() {
Serial.print("fuse high: ");
Serial_print_HEX(spi_transaction(0x58, 0x08, 0x00, 0x00));
Serial.println();
Serial.print("fuse low: ");
Serial_print_HEX(spi_transaction(0x50, 0x00, 0x00, 0x00));
Serial.println();
Serial.print("extend: ");
Serial_print_HEX(spi_transaction(0x50, 0x08, 0x00, 0x00));
Serial.println();
Serial.print("lock: ");
Serial_print_HEX(spi_transaction(0x58, 0x00, 0x00, 0x00));
Serial.println();
}
void chip_erase() {
Serial.println("erase flash");
spi_transaction(0xAC, 0x80, 0x00, 0x00);
delay(20);
};
#endif