I'm not sure if I can find reference somewhere of exact timing of reset signal and programming enable for atmega mcus:
All of the following numbers are in ms. Code is in ESP-IDF but I wanted to highlight delay values so I didn't put them in Code tag.
This worked. Fuse changed to programmed values:
gpio_set_level(rst,0); // mcu now enters reset
// Make sure SCK is stable. Should be, once SPI driver is initialized on bus.
vTaskDelay(pdMS_TO_TICKS(2)); // Wait 2 MCU cycles but this delay isn't that accurate.
gpio_set_level(rst,1); // mcu now exits reset
vTaskDelay(pdMS_TO_TICKS(2)); // Wait 2 MCU cycles but this delay isn't that accurate. This makes sure that a blank mcu running at 1MHz has enough time to respond to change of fuse to run at 8MHz.
gpio_set_level(rst,0); // mcu now enters reset
vTaskDelay(pdMS_TO_TICKS(20)); // Wait 20 ms before sending programming enable.
// Programming enable
send_cmd(spi,avr_isp_prg_enable,2,&readByte);
This didn't work. Fuse didn't change. (delays too long?):
gpio_set_level(rst,0); // mcu now enters reset
// Make sure SCK is stable. Should be, once SPI driver is initialized on bus.
vTaskDelay(pdMS_TO_TICKS(20)); // Wait 2 MCU cycles but this delay isn't that accurate.
gpio_set_level(rst,1); // mcu now exits reset
vTaskDelay(pdMS_TO_TICKS(200)); // Wait 2 MCU cycles but this delay isn't that accurate. This makes sure that a blank mcu running at 1MHz has enough time to respond to change of fuse to run at 8MHz.
gpio_set_level(rst,0); // mcu now enters reset
vTaskDelay(pdMS_TO_TICKS(20)); // Wait 20 ms before sending programming enable.
// Programming enable
send_cmd(spi,avr_isp_prg_enable,2,&readByte);
The reason I wanted longer delay is that these blank chips are programmed to run at 1MHz. I need them at 8MHz with external crystals. So I thought, if I program the fuses, reset, and then I can program them at 8MHz. Not working! So I thought I should add longer delay for crystal oscillator to stabilize but that caused failure to programming fuse values.