Controlando GPIO no U-Boot

O principal objetivo desse artigo é mostrar como alterar o estado do uma GPIO ao ligar o equipamento através do u-boot. Em alguns casos, o u-boot suporta essa funcionalidade por linha de comando, desde que os pinos já estejam previamente configurados no código-fonte. Sendo assim, é possível fazer isso apenas por comandos de u-boot ou também simplesmente salvar esses comandos nas suas variáveis de ambiente. A outra maneira de fazer isso é alterando diretamente o código fonte do u-boot, permitindo que pinos não configurados previamente sejam acessíveis conforme descrito anteriormente, ou mesmo permitindo o controle dos pinos diretamente pelo código-fonte, sem precisar executar comandos durante o tempo de boot.

 

Uma das principais razões para o uso dessa funcionalidade é em casos de equipamentos que implementam o desligamento ou reinicialização por hardware, usando um GPIO. Nesses casos, uma GPIO é conectada diretamente a um circuito que lê seu valor para desligar o equipamento. Por esse motivo, é preciso ter controle do estado dessa GPIO o mais rápido possível para evitar o desligamento ou reinicialização indesejada.

 

Esse artigo irá apresentar como realizar os dois métodos e também a diferença de tempo entre a energização do equipamento até a mudança de estado da GPIO.

 

 

Linha de comando

 

Para setar ou zerar um pino de GPIO por meio da linha de comando, você pode executar os comandos a seguir:

 

 

Nos quais <gpio> é o número do pino. Para descobrir qual número usar, você pode consultar o reference manual do seu processador, geralmente é ilustrado PORTX_YY, onde X é o controlador e Y o pino. No nosso caso, estamos usando o processador Vybrid Vfxx e seu controlador inicia em 0, logo a conta feita é:  (X x 32) + pin.  Para mais informações, esta tabela mostra a lista de pinos e valores,  que descreve exatamente a relação entre o número do pino e seu nome no SoC. Após descobrir o nome do pino para o SoC, você pode encontrar o número deste no conector SODIMM do módulo consultando seu datasheet, que pode ser obtido aqui.

 

Por exemplo, procurando no datasheet do CoM Colibri Vybrid, este possui uma tabela (página 21 do PDF) na qual a relação entre o nome do pino no SoC (coluna ALT0 – GPIO) e o conector SODIMM (coluna X1) pode ser obtida. Dito isto, se você quiser acessar o pino SODIMM 73 na Colibri Evaluation Board, você poderia pesquisar pelo pino no datasheet da Evaluation Board, no qual você pode notar a correspondência na qual este é o pino 31 da barra de pinos X11 (seção 3.12 - GPIO usage). A informação descrita neste parágrafo está concentrada na tabela 1:

 

Tabela 1: Correspondência de pinos para o Vybrid

Evaluation Board

SODIMM connector

SoC pin name

GPIO

Pin number

Pin 31 - X11 connector

73

PTB21

PORT1[11]

43

 

 

Um procedimento similar pode ser realizado para encontrar a correspondência para os pinos dos módulos iMX6 e Tegra. As tabelas 2 e 3 apresentam exemplos para ambos os casos:

 

Tabela 2: Correspondência de pinos para o iMX6

Evaluation Board

SODIMM connector

SoC pin name

Pin number

Pin 31 - X11 connector

73

GPIO3_IO27

91

 

 

Tabela 3: Correspondência de pinos para o Tegra T30

Evaluation Board

SODIMM connector

SoC pin name

Pin number

Pin 31 - X11 connector

73

S0

144

 

O procedimento descrito acima para chavear GPIO pela linha de comando somente funcionará por padrão se o pino em questão estiver configurado no código-fonte do U-Boot como GPIO. Caso contrário, será preciso configurá-lo e recompilar o U-Boot.

 

 

Configurando pin como GPIO no código-fonte do U-Boot

 

Há um artigo que pode ser encontrado aqui e que descreve como obter o código-fonte, configurar para o target específico, compilar e instalar. Esta seção irá omitir estes passos e somente descreverá as modificações feitas para configurar o pino como GPIO.

 

Um bom lugar para começar é o arquivo board/toradex/colibri_<current-module>/colibri_<current-module>.c. Por exemplo, dê uma olhada no arquivo board/toradex/colibri_vf/colibri_vf.c. Após os includes, são definidas algumas configurações de pads e, após isso, há várias funções que fazem setup dos pinos, como por exemplo a função setup_iomux_gpio(void) (linha 225) que configura os pads de GPIO e é apresentada abaixo:

 

 

Observe que somente alguns pinos são configurados como GPIO por padrão e, consultando a tabela 1, pode-se perceber que o pino PTB21 não é um destes, portanto é preciso adicioná-lo como VF610_PAD_PTB21__GPIO_43 no array gpio_pads. Isto ainda não é o suficiente, já que este pad específico precisa ser definido no arquivo arch/arm/include/asm/arch-vf610/iomux-vf610.h.

 

Dentro deste arquivo há somente definições e descrições da configuração dos pads. Abaixo são apresentados alguns exemplos extraídos do arquivo:

 

 

Quanto às definições (#define), elas definem como os pinos serão configurados. Por exemplo, um resistor de pull-up de 47kohm ou uma saída CMOS com um slew-rate rápido, etc. Informações quanto às opções de configuração podem ser encontradas na seção 5.2 (página 250) do VFxxx reference manual.

 

Após as definições, há a declaração de cada pad usado e sua configuração. Uma vez que estamos interessados em usar pinos como GPIO, dê uma olhada no VF610_PAD_PTA20__CPIO10. Para configurar qualquer pino como GPIO, somente é preciso mudar o offset do pad a partir do exemplo (no qual 0x0028 é o offset para o pino PTA20). Para descobri-lo para o pino desejado, a seção 3.14.1 (página 219) do VFxxx reference manual pode ser consultada.

 

Com relação ao pad da tabela 1 (PTB21), pode ser obtido a partir do reference manual que seu offset é 0x00AC. Isto significa que nós precisamos adicionar a linha abaixo ao arquivo arch/arm/include/asm/arch-vf610/iomux-vf610.h.

 

 

NOTA: O procedimento descrito é brevemente diferente para os módulos das famílias de SoC iMX e Tegra, o que significa que os arquivos nos quais a configuração é realizada ou a sintaxe empregada irá mudar dentre os módulos.

 

Se você recompilar e instalar o U-Boot no módulo Colibri VF61, o pad do SODIMM 73 poderá ser chaveado a partir da linha de comando do U-Boot, conforme descrito mais cedo na seção Linha de Comando.

 

 

Setando pinos de GPIO no código-fonte do U-Boot

 

Se você quer setar ou zerar um pino de GPIO a partir do código-fonte – o que pode ser útil se você precisa configurar um pino o mais rápido possível após energizar o módulo - você pode fazê-lo no arquivo board/toradex/colibri_<current-module>/colibri_<current-module>.c. Ele possui uma função chamada board_init que é um bom lugar para chavear um pino de GPIO o mais cedo possível, já que esta função é chamada logo após o driver de GPIO ser carregado. Abaixo é apresentada a função board_init modificada para setar o pino PTB21:

 

 

NOTA: O procedimento descrito pode variar entre os módulos.

 

Salve as mudanças, recompile e instale o U-Boot no módulo Colibri VF61. Observe que, após energizar o módulo, o pino do SODIMM 73 é setado.

 

 

Tempos de chaveamento

 

Para medir o tempo entre ligar o módulo e chavear o GPIO, a Colibri Evaluation Board e o analisador lógico LHT00SU1 foram empregados.

 

Três sinais foram capturados: o pushbutton de on/off (SW7), a alimentação de 3,3V e o pino de GPIO. O tempo medido foi o tempo entre a fonte ligar e o pino de GPIO mudar seu valor para nível alto. Foi observado que, entre apertar o botão de on/off e a fonte de 3,3V ligar, há um delay de 35ms.

 

A figura 1 apresenta os resultados para o método por linha de comando, setando uma variável do U-Boot. Demora 182ms para que o GPIO seja setado após energizar o módulo.

 

GPIO no U-Boot - Tempo para setar o GPIO pela linha de comando
Figura 1: Tempo para setar o GPIO pela linha de comando

 

A figura 2 apresenta os resultado para setar o GPIO diretamente do código-fonte do U-Boot. O tempo que leva entre energizar o módulo e o pino subir para nível alto é de 124ms.

 

GPIO no U-Boot - Tempo para setar o GPIO direto no código-fonte
Figura 2: Tempo para setar o GPIO direto no código-fonte

 

 

Conclusão

 

Este é o básico sobre como setar um pino de GPIO no U-boot. Embora os exemplos descritos neste artigo só funcionem – sem mudanças - para os módulos Colibri VFxx, o procedimento é muito similar para os outros módulos, o que significa que segui-lo será útil em qualquer situação. Espero vê-lo em breve!

NEWSLETTER

Receba os melhores conteúdos sobre sistemas eletrônicos embarcados, dicas, tutoriais e promoções.

Obrigado! Sua inscrição foi um sucesso.

Ops, algo deu errado. Por favor tente novamente.

Licença Creative Commons Esta obra está licenciada com uma Licença Creative Commons Atribuição-CompartilhaIgual 4.0 Internacional.

Deixe um comentário

avatar
 
  Notificações  
Notificar