Escrevemos o carregador OTA para ATmega128RFA1 (como parte do dispositivo Smart Response XE)



Tudo começou com a aquisição pelo autor no mercado secundário de um dispositivo interessante - Smart Response XE ( breve descrição ). Destina-se às escolas: cada aluno da classe recebe um dispositivo semelhante a um caderno ou tradutor eletrônico dos anos 90, o professor faz uma pergunta e os alunos digitam nos teclados dos dispositivos as respostas recebidas pelo canal de rádio (802.15.4) ao receptor conectado ao PC do professor.

O suporte para esses dispositivos foi descontinuado há vários anos e o fato de as escolas comprarem entre US $ 100 e 200 a cada uma agora aparece no eBay por 10 ou menos. Ferro lá é muito adequado para experimentos geek:

  • Teclado de 60 teclas
  • tela com uma resolução de 384x136, 2 bits por pixel - semelhante a BK, CGA, mas 4 não são cores, mas gradações de brilho
  • Microcontrolador ATmega128RFA1 (memória flash de 128 kB, ROM de 4 kB, RAM de 16 kB, transceptor padrão 802.15.4)
  • memória flash externa (em relação ao microcontrolador e não ao dispositivo inteiro) por 1 megabit (128 kilobytes) com SPI
  • compartimento para 4 elementos AAA.

Pelo nome do microcontrolador, fica claro que pertence à família AVR, o que significa que fabricar um dispositivo compatível com Arduino é uma tarefa mais que trivial ...

A partir das notícias sobre Hackaday, o autor descobriu que eles já fizeram isso (o mesmo link diz com o que conectar), tendo a oportunidade de executar jogos para Arduboy:


Mas o autor está mais interessado na oportunidade de não jogar no dispositivo, mas estudar:

  • SPI de flash serial
  • downloaders para AVR
  • padrão 802.15.4

O autor começou escrevendo uma biblioteca (GPL v3) que permite inicializar a exibição, exibir texto e retângulos e também acessar a memória flash com a interface SPI. Então, ele começou a ter idéias para o uso prático do dispositivo: um terminal de bolso compatível com VT-100, jogos para vários jogadores. Depois de refazer os três dispositivos, ele decidiu “ensiná-los” a obter esboços “pelo ar”. O que seria não apenas interessante, mas também muito conveniente: é difícil abrir a caixa do dispositivo a cada vez e, sob a tampa da bateria, existem apenas orifícios que permitem conectar um programador JTAG à placa.



Isso é suficiente para preencher o gerenciador de inicialização do Arduino, mas não é um esboço - a porta serial não é exibida lá, você ainda não pode abrir a caixa. Além disso, as linhas TX0 e RX0 da primeira porta serial estão alinhadas com as linhas de polling da matriz do teclado, ou seja, aquelas ao longo das quais as teclas de função são pesquisadas nas laterais da tela. Mas o que fazer - o autor construiu isso:



Lá ele trouxe as linhas JTAG, e agora não é necessário abrir o compartimento da bateria. E, para poder preencher os esboços, trouxe as duas portas seriais para o mesmo conector, adicionando também um comutador, porque quando as baterias são instaladas, o dispositivo não pode ser fisicamente desligado de uma maneira diferente.

Demorou um pouco para trabalhar com um ferro de solda, uma faca de escritório e uma pistola de cola. Em geral, esboços de derramamento “over the air” são muito mais convenientes, é urgente inventar algo para isso.

O Arduino IDE usa o avrdude para preencher esboços. Ele interage com o microcontrolador através do protocolo STK500 , que permite transferir arquivos nas duas direções. É pouco compatível com canais onde são possíveis atrasos variáveis, distorção e perda de dados. Se algo sair ou farfalhar no canal serial, você pode enlouquecer em busca de uma causa. Uma vez o autor atormentou por meio dia até perceber que o problema estava no cabo defeituoso, bem como no conversor caprichoso da interface do CP2102. Mesmo um microcontrolador com um conversor de interface embutido, por exemplo, ATmega32u4, às vezes pode ser tão desobediente. Cada usuário do Arduino notou que erros ao fazer upload de esboços não são tão raros. Às vezes, a gravação é boa e um erro é detectado durante a leitura da verificação. Isso não significa que houve um erro durante a gravação - a falha ocorreu durante a leitura. Agora imagine que, ao trabalhar "no ar", a mesma coisa acontecerá, mas com muito mais frequência.

Tendo tentado diferentes maneiras de superar esse problema, o autor apresentou o seguinte. O dispositivo possui uma memória flash de 128 kilobytes com interface SPI - recebemos dados por meio de cabos (lembre-se de que o autor já possui um dispositivo com um conector ao lado), usamos essa memória como um buffer e enviamos dados para outro dispositivo por um canal de rádio. Um olá de Cybiko.

Depois de escrever o código para trabalhar com o canal de rádio e a fonte, o carregador de inicialização passou a ter mais de 4 kilobytes. Portanto, o valor HFUSE teve que ser alterado de 0xDA para 0xD8. Agora, o carregador de inicialização pode ter até 8 kilobytes e o endereço inicial tornou-se 0x1E000. Isso é refletido no Makefile, mas deve ser levado em consideração ao preencher o gerenciador de inicialização com avrdude.

O transceptor padrão 802.15.4 no ATmega128RFA1 foi originalmente projetado para operar no protocolo ZigBee , que é bastante complicado, então o autor decidiu, em vez disso, simplesmente transmitir pacotes. Como o hardware é implementado no ATmega128RFA1, é necessário um pouco de código. Além disso, por simplicidade, o autor decidiu usar um canal fixo, impedindo-o de escolhê-lo mesmo manualmente. O padrão 802.15.4 suporta 16 canais com números de 11 a 26. Eles estão bastante obstruídos, alguns também se sobrepõem aos canais Wi-Fi (vermelho indica canais ZigBee, azul, verde e amarelo - Wi-Fi).



Verificou-se que os canais 15 e 26 são os menos suscetíveis à interferência do WiFi. O autor escolheu o segundo deles. Isenção de responsabilidade: o tradutor não sabe se o ZigBee é tão simplificado. Talvez valha a pena um pouco mais de programação e sua implementação completa?

No primeiro dos dispositivos, é necessário implementar uma máquina de estado que transmita dados usando o protocolo STK500. Na maioria das vezes, as mensagens enviadas e recebidas são auto-suficientes, mas algumas estão vinculadas àquelas que passaram pelo canal anteriormente. Uma descrição do diálogo é dada aqui .

Um componente importante desse diálogo é a transferência de pacotes destinados à gravação na memória flash do dispositivo de destino. Os microcontroladores simples da família AVR têm um tamanho de página de 128 bytes, mas o ATmega128RFA1 tem um tamanho de 256. E a memória flash conectada através do protocolo SPI tem o mesmo tamanho. O programa no primeiro dispositivo ao derramar o esboço não o transfere imediatamente para o segundo, mas o grava nessa memória. Quando o IDE do Arduino verifica a exatidão da gravação, eles enviam o que foi escrito lá. Agora você precisa transferir os dados recebidos pelo ar para o segundo dispositivo. Ao mesmo tempo, a mudança da recepção para a transmissão e vice-versa ocorre com bastante frequência. O protocolo STK500 é indiferente a atrasos, mas não tolera a perda de dados (estranho, mas é dito acima que atrasos na transmissão de dados também afetam). E as perdas de transmissão sem fio são inevitáveis. ATmega128RFA1 possui uma implementação de hardware embutida de solicitações repetidas com dúvidas sobre a transmissão correta, mas o autor decidiu implementar o mesmo programaticamente por conta própria. Ele desenvolveu um protocolo no qual muito mais dados passam em uma direção do que na outra.

É imperfeito, mas tudo funciona. Uma página de 256 bytes é dividida em quatro segmentos, cada um transmitido pelo ar como um pacote. Um pacote comporta até 125 bytes de dados, mais um byte - length e dois - CRC. Portanto, fragmentos de 64 bytes de comprimento, juntamente com os números de página e segmento (de 0 a 3), são colocados lá. No dispositivo de recebimento, é fornecida uma variável que permite rastrear quantos segmentos são recebidos e, quando todos os quatro são recebidos, a confirmação é enviada ao dispositivo de envio de que toda a página foi recebida. Sem confirmação (o CRC não correspondeu) - envie a página inteira novamente. A velocidade ao mesmo tempo é ainda maior do que na transmissão via cabo. Veja:


Mas, na verdade, seria necessário fornecer uma maneira conveniente de conectar o cabo aos dispositivos para carregar esboços e nele. Por exemplo, coloque um conversor de interface no CP2102, como na foto, e cole-o na placa para que ele possa suportar a força ao conectar e desconectar o cabo Micro USB.



Ele também possui um estabilizador de 3,3 volts (e como usá-lo em um dispositivo com fonte de alimentação de 6 volts - se houver apenas o mesmo estabilizador, e você pode adicionar dois diodos para escolher automaticamente de qual dispositivo o dispositivo será alimentado). Todos os três LEDs devem ser removidos da placa conversora de interface, caso contrário, eles carregarão adicionalmente as baterias ao trabalhar com elas e também interferirão na pesquisa do teclado e funcionarão com memória flash com a interface SPI.

A busca pelo objetivo acabou sendo ainda mais interessante do que a conquista (e você não precisa dessa piada sobre o ônibus). O autor aprendeu muito sobre os gerenciadores de inicialização do AVR, memória flash com SPI, protocolo STK500 e padrão 802.15.4.

Todo o outro código, além da biblioteca descrita acima, está aqui e também está na GPL v3. O twitter do autor está aqui .

Source: https://habr.com/ru/post/pt447026/


All Articles