Created
January 30, 2023 09:11
-
-
Save doug65536/15024c21e09663fe5576879aa22b6cd9 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define PIN_RESET 22 | |
#define PIN_MOSI 5 | |
#define PIN_MISO 19 | |
#define PIN_SCLK 21 | |
// Send the given byte and return the byte received (mode0) | |
byte spi_transfer(byte value = 0) | |
{ | |
// As we shift out outgoing bits out the top bits, | |
// we shift the incoming bits into the low bits | |
Serial.print("Sending 0x"); | |
Serial.println(value, HEX); | |
for (byte i = 0; i < 8; ++i) { | |
byte b = (value & 0x80U) ? HIGH : LOW; | |
value <<= 1; | |
digitalWrite(PIN_MOSI, b); | |
delayMicroseconds(1000); | |
digitalWrite(PIN_SCLK, HIGH); | |
value |= (digitalRead(PIN_MISO) != LOW); | |
delayMicroseconds(1000); | |
digitalWrite(PIN_SCLK, LOW); | |
} | |
Serial.print("Received 0x"); | |
Serial.println((unsigned)value, HEX); | |
return value; | |
} | |
#define AVRISP_CMD_CHIP_ERASE 0b10000000 | |
#define AVRISP_CMD_WRITE_FUSE 0b01000000 | |
#define AVRISP_CMD_WRITE_LOCK 0b00100000 | |
#define AVRISP_CMD_WRITE_FLASH 0b00010000 | |
#define AVRISP_CMD_WRITE_EEPROM 0b00010001 | |
#define AVRISP_CMD_READ_SIGCAL 0b00001000 | |
#define AVRISP_CMD_READ_FUSE 0b00000100 | |
#define AVRISP_CMD_READ_FLASH 0b00000010 | |
#define AVRISP_CMD_READ_EEPROM 0b00000011 | |
struct isp_cmd { | |
byte command; | |
byte addrhi; | |
byte addrlo; | |
byte value; | |
}; | |
byte send_isp_cmd(struct isp_cmd const *cmd, byte *full_reply = nullptr) | |
{ | |
if (!full_reply) { | |
spi_transfer(cmd->command); | |
spi_transfer(cmd->addrhi); | |
spi_transfer(cmd->addrlo); | |
return spi_transfer(cmd->value); | |
} | |
full_reply[0] = spi_transfer(cmd->command); | |
full_reply[1] = spi_transfer(cmd->addrhi); | |
full_reply[2] = spi_transfer(cmd->addrlo); | |
full_reply[3] = spi_transfer(cmd->value); | |
return full_reply[3]; | |
} | |
//byte avrisp_read_sigcal() | |
//{ | |
//} | |
byte avrisp_read_fuselock() | |
{ | |
isp_cmd cmd{0b01010000, 0, 0, 0}; | |
byte fuselock = send_isp_cmd(&cmd); | |
return fuselock; | |
} | |
// Should return 0b01010011 | |
byte avrisp_programming_enable() | |
{ | |
byte reply[4]; | |
isp_cmd cmd{0b10101100, 0b01010011, 0, 0}; | |
send_isp_cmd(&cmd, reply); | |
return reply[3]; | |
} | |
void setup() | |
{ | |
Serial.begin(115200); | |
// Must give at least two cycles reset high before pulling reset low, | |
// if you can't guarantee that reset is initially low | |
digitalWrite(PIN_RESET, HIGH); | |
delayMicroseconds(2); | |
// Pull reset low | |
// otherwise the device might drive those SPI pins | |
digitalWrite(PIN_RESET, LOW); | |
pinMode(PIN_RESET, OUTPUT); | |
digitalWrite(PIN_MOSI, LOW); | |
digitalWrite(PIN_MISO, LOW); | |
digitalWrite(PIN_SCLK, LOW); | |
pinMode(PIN_MOSI, OUTPUT); | |
pinMode(PIN_MISO, INPUT); | |
pinMode(PIN_SCLK, OUTPUT); | |
// After pulling Reset low, wait at least 20ms before issuing the first command | |
delayMicroseconds(20000); | |
Serial.println("Enabling programming"); | |
byte reply = avrisp_programming_enable(); | |
Serial.print("Enable programming reply: "); | |
Serial.println(reply); | |
Serial.println("Reading fuselock"); | |
byte fuselock = avrisp_read_fuselock(); | |
Serial.print("Fuse/lock byte: 0x"); | |
Serial.println(fuselock, HEX); | |
// Tristate everything | |
// pinMode(PIN_SCLK, INPUT); | |
// pinMode(PIN_MOSI, INPUT); | |
// pinMode(PIN_RESET, INPUT); | |
} | |
void loop() { | |
// put your main code here, to run repeatedly: | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment