Raspberry Pi RP2040: mãos
O lançamento da placa Raspberry Pi Pico da Raspberry Pi Foundation com microcontrolador RP2040 causou grande repercussão nos últimos meses na comunidade de fabricantes. Muitos demonstraram como especialmente os dois periféricos da máquina de estado de E/S programável (PIO) podem ser usados para criar geradores de vídeo DVI e outros periféricos digitais.
Juntamente com esse entusiasmo, levanta-se a questão de saber se isso causará alguma grande reviravolta para aqueles de nós que usam STM32, SAM e outros MCUs baseados em Cortex-M. O RP2040 seria talvez uma opção válida para alguns dos nossos projetos? Com o RP2040 sendo um MCU com processador Cortex-M0 + duplo, parece justo enfrentá-lo com as ofertas de um dos pesos pesados atuais no espaço ARM MCU de 32 bits: ST Microelectronics.
O pipsqueak da Raspberry Pi Foundation conseguiu mostrar aos engenheiros da ST como isso é feito ou os primeiros deveriam rever algumas de suas suposições? E quão difícil será portar código de baixo nível de STM32 para RP2040?
Para encurtar a história, depois que o RP2040 chamou minha atenção, achei que seria interessante tentar portar minha estrutura STM32 baseada em C++ para este novo MCU. Porém, não tanto para os núcleos Cortex-M0 + duplos, já que tenho MCUs STM32H7 dual-core (M4 e M7) disponíveis, que irão facilmente superar o recheio de um RP2040 com muito mais E/S de sobra. O que mais me intrigou foi esse periférico de máquina de estado (PIO) no RP2040 que parecia digno de uma olhada mais de perto.
Com base na minha experiência com STM32, imaginei que poderia transferir rapidamente alguns arquivos, criar uma nova ramificação de arquitetura 'RP' no projeto e partir para as corridas. Cortex-M é Cortex-M, certo? O procedimento usual com um novo MCU baseado em ARM é obter as folhas de dados, o manual de referência e os arquivos do dispositivo CMSIS. Depois disso, é possível adaptar facilmente o código de baixo nível para usar o novo layout de nomenclatura e registro de periféricos, enquanto os dispositivos de nível central (SysTick, NVIC, etc.) permanecem os mesmos.
Talvez ingenuamente, eu fiz um pedido de uma placa Raspberry Pi Pico antes mesmo de verificar o suporte do CMSIS ou de consultar o manual de referência. Para minha surpresa, descobri que o suporte do CMSIS ou mesmo a interoperabilidade com o resto do ecossistema Cortex-M ainda não estava no radar. Ainda assim, o arquivo SVD para RP2040 MCU é fornecido no 'Pico SDK', que pode ser usado para gerar o cabeçalho do dispositivo. Cortesia dos esforços de Chris Hockuba em inicializar o CMSIS com o RP2040, finalmente consegui uma solução funcional em conjunto.
Com um projeto STM32, existem alguns itens necessários para fazer um projeto bare-metal funcionar em um MCU alvo. Isso inclui o código de inicialização que executa algumas configurações básicas do ambiente, bem como a tabela de vetores para manipuladores de interrupção. Há também o script do vinculador para garantir que todos os bits terminem no deslocamento de memória correto. Tudo isso é mínimo, com o MCU na inicialização carregando a imagem do firmware do Flash ROM no endereço padrão.
O primeiro obstáculo do RP2040 é entender seu processo de bootloader encadeado. Assim como os disquetes inicializáveis de antigamente ou um HDD/SSD em um PC, o QSPI Flash ROM externo é tratado essencialmente como um dispositivo de inicialização potencial pelo MCU. O bootloader de primeiro estágio é integrado ao MCU na ROM de inicialização, endereço 0x0000 0000, que na inicialização verifica a interface QSPI para tentar carregar 256 bytes dela. Isso será verificado para uma correspondência de hash CRC32 válida e assumido como o bootloader de segundo estágio, se corresponder.
Há muitas coisas que este bootloader de segundo estágio pode fazer e algumas que são necessárias. Basta dizer por enquanto que, em comparação com alguns clones STM32 famosos - como os clones GigaDevices que não posso acreditar que não seja um STM32 genuíno - que também usam ROMs SPI, todo esse processo com o RP2040 é não é tão intuitivo, bem documentado ou transparente quanto poderia ser, com muitos obstáculos.
Levei bastante pesquisa na folha de dados do RP2040 e perguntei para descobrir como o gerenciador de relógio periférico no STM32 mapeia para a arquitetura do sistema RP2040. Acontece que a versão do RP2040 se chama RESETS e funciona basicamente ao contrário: você precisa desabilitar a condição de reset em um bloco para habilitar o relógio para ele. Para habilitar o clock GPIO, você deve alternar o bit 8 em RESETS_RESET (PADS_BANK0).