Quando você redefine um Uno executando o carregador Optiboot, o carregador de inicialização primeiro pisca o pino 13 três vezes.
A linha superior (cinza) é enviada ao Arduino, a linha do meio (laranja) é enviada a partir do Arduino.
Enquanto isso está acontecendo, o programa avrdude
em execução no seu computador está enviando uma consulta ao dispositivo:
STK_GET_SYNC / CRC_EOP (0x30/0x20)
O Arduino não percebe o primeiro "get sync" porque está ocupado piscando o pino 13. Depois de concluído, ele percebe o "get sync" (seria armazenado em buffer pelo hardware serial) e responde:
STK_INSYNC / STK_OK (0x14/0x10)
Parece que o avrdude ficou um pouco impaciente e atingiu o tempo limite, porque tenta novamente com a consulta "obter sincronização". Desta vez, a Optiboot responde imediatamente.
O restante do upload é descrito na próxima imagem. Exemplo produzido ao fazer o upload do programa "Blink".
(Clique na imagem acima para uma versão maior)
Os passos são:
- Consulta: Obter sincronização? Resposta: em sincronização.
- Consulta: Obter parâmetro? (versão principal) Resposta: versão 4.
- Consulta: Obter parâmetro? (versão secundária) Resposta: versão 4.
Defina os parâmetros do dispositivo. Os seguintes parâmetros do dispositivo são enviados para o chip:
0x42 // STK_SET_DEVICE
0x86 // device code
0x00 // revision
0x00 // progtype: “0” – Both Parallel/High-voltage and Serial mode
0x01 // parmode: “1” – Full parallel interface
0x01 // polling: “1” – Polling may be used
0x01 // selftimed: “1” – Self timed
0x01 // lockbytes: Number of Lock bytes.
0x03 // fusebytes: Number of Fuse bytes
0xFF // flashpollval1
0xFF // flashpollval2
0xFF // eeprompollval1
0xFF // eeprompollval2
0x00 // pagesizehigh
0x80 // pagesizelow
0x04 // eepromsizehigh
0x00 // eepromsizelow
0x00 // flashsize4
0x00 // flashsize3
0x80 // flashsize2
0x00 // flashsize1
0x20 // Sync_CRC_EOP
O Optiboot ignora todos esses e responde com In Sync / OK. :)
Defina os parâmetros estendidos do dispositivo:
0x45 // STK_SET_DEVICE_EXT
0x05 // commandsize: how many bytes follow
0x04 // eeprompagesize: EEPROM page size in bytes.
0xD7 // signalpagel:
0xC2 // signalbs2:
0x00 // ResetDisable: Defines whether a part has RSTDSBL Fuse
0x20 // Sync_CRC_EOP
O Optiboot ignora todos eles e responde com In Sync / OK.
Entre no modo de programa. Resposta: Em Sincronização / OK.
Leia a assinatura. Optiboot responde 0x1E 0x95 0x0F
sem realmente ler a assinatura .
Escreva fusíveis (quatro vezes). Optiboot não escreve o fusível, mas apenas responde em Sincronização / OK.
Endereço de carga (inicialmente 0x0000). O endereço está em palavras (ou seja, uma palavra tem dois bytes). Isso define o endereço para onde a próxima página de dados será gravada.
Página do programa (até 128 bytes são enviados). O Optiboot responde "In Sync" imediatamente. Depois, há uma pausa de cerca de 4 ms enquanto ele programa a página. Em seguida, ele responde "OK".
Endereço de carga (agora 0x0040). Este é o endereço 64 em decimal, ou seja. 128 bytes desde o início da memória do programa.
Outra página está escrita. Essa sequência continua até que todas as páginas sejam gravadas.
Carregar endereço (voltar para 0x0000). Isto é para verificar a gravação.
Página de leitura (até 128 bytes são lidos). Isto é para verificar. Observe que, mesmo que a verificação falhe, os dados incorretos já foram gravados no chip.
Saia do modo de programação.
O que significa "não sincronizado"?
Como você pode ver acima, a cada passo da sequência de programação o Arduino deve responder com "In Sync" (0x14), possivelmente seguido por alguns dados, seguido de "OK" (0x10).
Se "não estiver sincronizado", significa que o avrdude não obteve a resposta "sincronizada". Os possíveis motivos podem ser:
- Taxa de transmissão incorreta usada
- Porta serial incorreta selecionada no IDE
- Tipo de placa incorreto selecionado no IDE
- Nenhum carregador de inicialização instalado
- Carregador de inicialização errado instalado
- Placa não configurada para usar o carregador de inicialização (nos fusíveis)
- Algum dispositivo conectado aos pinos D0 e D1 no Arduino, interferindo nas comunicações seriais
- O chip de interface USB (ATmega16U2) não está funcionando corretamente
- Relógio errado para o tabuleiro
- Configurações incorretas de fusível no Atmega328P (por exemplo, "divida o relógio por 8")
- Placa / chip danificado
- Cabo USB com defeito (alguns cabos USB fornecem apenas energia e não são para dados, por exemplo, cabos baratos para ventiladores USB)
O que está "sincronizado"?
Como mencionado acima, a resposta "Em sincronização" significa que o Arduino (carregador de inicialização) está sincronizado com o programa de upload.
Qual protocolo está sendo usado?
O protocolo é o protocolo STK500, conforme documentado pela Atmel. Veja as referências abaixo.
Referências
Nota : O STK500 Versão 2 não é usado no Optiboot, mas é incluído para obter informações, caso você esteja usando placas como o Mega2560.
Constantes do STK500
/* STK500 constants list, from AVRDUDE */
#define STK_OK 0x10
#define STK_FAILED 0x11 // Not used
#define STK_UNKNOWN 0x12 // Not used
#define STK_NODEVICE 0x13 // Not used
#define STK_INSYNC 0x14 // ' '
#define STK_NOSYNC 0x15 // Not used
#define ADC_CHANNEL_ERROR 0x16 // Not used
#define ADC_MEASURE_OK 0x17 // Not used
#define PWM_CHANNEL_ERROR 0x18 // Not used
#define PWM_ADJUST_OK 0x19 // Not used
#define CRC_EOP 0x20 // 'SPACE'
#define STK_GET_SYNC 0x30 // '0'
#define STK_GET_SIGN_ON 0x31 // '1'
#define STK_SET_PARAMETER 0x40 // '@'
#define STK_GET_PARAMETER 0x41 // 'A'
#define STK_SET_DEVICE 0x42 // 'B'
#define STK_SET_DEVICE_EXT 0x45 // 'E'
#define STK_ENTER_PROGMODE 0x50 // 'P'
#define STK_LEAVE_PROGMODE 0x51 // 'Q'
#define STK_CHIP_ERASE 0x52 // 'R'
#define STK_CHECK_AUTOINC 0x53 // 'S'
#define STK_LOAD_ADDRESS 0x55 // 'U'
#define STK_UNIVERSAL 0x56 // 'V'
#define STK_PROG_FLASH 0x60 // '`'
#define STK_PROG_DATA 0x61 // 'a'
#define STK_PROG_FUSE 0x62 // 'b'
#define STK_PROG_LOCK 0x63 // 'c'
#define STK_PROG_PAGE 0x64 // 'd'
#define STK_PROG_FUSE_EXT 0x65 // 'e'
#define STK_READ_FLASH 0x70 // 'p'
#define STK_READ_DATA 0x71 // 'q'
#define STK_READ_FUSE 0x72 // 'r'
#define STK_READ_LOCK 0x73 // 's'
#define STK_READ_PAGE 0x74 // 't'
#define STK_READ_SIGN 0x75 // 'u'
#define STK_READ_OSCCAL 0x76 // 'v'
#define STK_READ_FUSE_EXT 0x77 // 'w'
#define STK_READ_OSCCAL_EXT 0x78 // 'x'