Skip to content

UART Core com suporte a RTS/CTS para comunicação serial em FPGA. Projeto de Iniciação Científica (CNPq) do Telecore 64, um console portátil em FPGA que integra jogos 2D e controle de robôs, unindo sistemas embarcados, teleoperação e redes.

Notifications You must be signed in to change notification settings

TAlmeida003/uart-core

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 

Repository files navigation

UART Core

Desenvolvimento de um Módulo de Comunicação em Rede entre FPGA e ESP8266 12E utilizando UART

-----------------------------------------------------

Descrição do Projeto

A comunicação serial UART (Universal Asynchronous Receiver and Transmitter) é amplamente utilizada em sistemas digitais pela sua simplicidade e eficiência na troca de dados ponto a ponto. Este projeto tem como objetivo desenvolver um núcleo UART configurável para FPGA, com suporte a transmissão e recepção assíncrona de dados, além de controle de fluxo por hardware (RTS/CTS).

O módulo UART é projetado para comunicação com periféricos externos, como o ESP8266 12E, permitindo a troca de informações por meio de comandos seriais. Ele atua como intermediário entre a lógica digital da FPGA e dispositivos que utilizam interfaces seriais, sendo essencial para aplicações que envolvem controle, monitoramento ou comunicação em rede.

-----------------------------------------------------

Autor

-----------------------------------------------------

Orientador

  • Dr. Anfranserai Morais Dias
  • Departamento de Tecnologia (DTEC) — UEFS

-----------------------------------------------------

Sumário

-----------------------------------------------------

UART

Um receptor e transmissor assíncrono universal (em inglês, Universal Asynchronous Receiver and Transmitter), com a sigla UART, é um circuito utilizado para enviar dados paralelos por meio de uma linha serial, onde os bits são transmitidos sequencialmente, um de cada vez, formando uma fila [PEDRONI, 2008]. Essa comunicação é considerada assíncrona, pois não exige o sincronismo entre os relógios do receptor e do transmissor. Cada caractere transmitido carrega seus próprios sinais de sincronismo [EPUSP, 2015].

A comunicação UART é full-duplex, ou seja, permite a transmissão e recepção de dados simultaneamente. Os dados são enviados do bit LSB (Least Significant Bit) para o MSB (Most Significant Bit). A linha serial é 1 quando está ociosa. A transmissão começa com um bit de início, que é 0, seguido pelos bits de dados e, opcionalmente, um bit de paridade. A transmissão termina com bits de parada, que são sempre 1 [PEDRONI, 2008].

As configurações comuns incluem:

  • Número de bits de dados: 6, 7 ou 8 bits.
  • Número de bits de parada: 1, 1,5 ou 2 bits.
  • Paridade: Opcional.

A configuração padrão utilizada é de 8 bits de dados, sem paridade, e 1 bit de parada.

Abaixo, é apresentada uma figura que ilustra a estrutura de um quadro de dados UART.

Figura X: Estrutura de um quadro de dados UART

Baud Rate

Para a comunicação entre a FPGA e o ESP8266 12e, ambos os dispositivos precisam usar a mesma taxa de transmissão de dados, chamada Baud Rate. Essa taxa, medida em bits por segundo (bps), pode ter valores como 9.600 bps, 115.200 bps, 921.600 bps, entre outros.

No projeto, foi utilizada a taxa de 115.200 bps, que é o padrão do ESP8266. Para garantir a correta amostragem dos dados, foi aplicado um procedimento de sobreamostragem, que consiste em amostrar o sinal de entrada a uma frequência 16 vezes maior que a taxa de transmissão. Isso assegura que o sinal seja capturado no momento correto, reduzindo erros.

Para configurar a taxa na FPGA, calcula-se o divisor de frequência do clock do módulo UART com a fórmula:

Fórmula do divisor de clock

Onde:

Descrição dos parâmetros

Essa configuração gera uma margem de erro de apenas 0,47%, que é aceitável para a comunicação serial.

Controle de Fluxo

O controle de fluxo é usado para garantir que os dados sejam transmitidos sem perda de informações. Ele permite que o receptor avise o transmissor quando está pronto para receber dados. Existem dois métodos principais: XON/XOFF e RTS/CTS. Este projeto utiliza o método RTS/CTS devido à sua eficiência e para evitar sobrecarga de dados (overhead).

No método RTS/CTS, o transmissor ativa (nível lógico LOW) o sinal RTS quando está pronto para enviar dados, indicando que seu buffer de transmissão está vazio. O receptor ativa (nível lógico LOW) o sinal CTS quando está pronto para receber dados, indicando que seu buffer de recepção está vazio.

Para garantir que nada seja perdido por overflow, o sinal é assionado quando o buffer está 75% cheio. Isso permite que mesmo que o transmissor envie dados a maior que a taxa de recepção, o receptor ainda possa receber os dados sem perda de informações.

Figura X: Diagrama de controle de fluxo RTS/CTS

O sinal RTS do transmissor é conectado ao pino CTS do receptor, e o sinal CTS do receptor é conectado ao pino RTS do transmissor. Isso permite que o transmissor e o receptor se comuniquem entre si, garantindo que os dados sejam transmitidos corretamente.

Abaixo, são apresentados os diagramas temporais dos sinais RTS e CTS:

Figura X: Diagrama temporal dos sinais CTS

Figura X: Diagrama de temporal dos sinais RTS

Figura X: Diagrama rts automatico

Sinais de Conexão

Na comunicação UART, é utilizada a norma EIA-RS-232C como referência para a conexão entre dispositivos, garantindo que fabricantes diferentes possam seguir uma interface comum [EPUSP, 2015]. Os sinais utilizados no projeto são descritos a seguir:

  • Transmissão de Dados (TXD - Transmit Data): Transmite dados da FPGA para o ESP8266 12e.
  • Recepção de Dados (RXD - Receive Data): Recebe dados do ESP8266 12e para a FPGA.
  • Pronto para Enviar (RTS - Ready to Send): Indica que a FPGA está pronta para enviar dados.
  • Pronto para Receber (CTS - Clear to Send): Indica que o ESP8266 12e está pronto para receber dados.
  • Terra (GND - Ground): Referência de tensão.

A norma EIA-RS-232C também define outros sinais, como DTR, DSR, DCD e RI, que não são utilizados neste projeto. Além disso, embora a norma especifique níveis de tensão próprios para RS-232, o projeto utiliza sinais em níveis lógicos de 0V para o nível lógico 0 e 3,3V para o nível lógico 1, adequados aos dispositivos conectados.

A figura a seguir ilustra a conexão entre a FPGA e o ESP8266 12e usando o padrão UART, mostrando os sinais de conexão utilizados.

Figura X: Conecção entre FPGA e ESP8266 12e usando UART

Receptor UART

O receptor UART é responsável por receber os dados transmitidos pelo transmissor e enviá-los para a FPGA. É usado uma máquina de estados para controlar a recepção dos dados. A máquina de estados é composta por quatro estados: IDLE, START, DATA, STOP e ERROR.

Estado IDLE: O receptor aguarda a detecção do bit de início, que é o bit 0. Quando o bit de início é detectado, o receptor muda para o estado START e então inicie o contador de tiques de amostragem.

Estado START: O receptor aguarda o meio do bit de início para sincronizar a amostragem dos dados. Quando o meio do bit de início é detectado, o receptor muda para o estado DATA e inicia a amostragem dos bits de dados. Em caso de uma falha na detecção do bit de início, o receptor vai para o estado de ERROR.

Estado DATA: Quando o contador atinge 15, o sinal de entrada progride por um bit e atinge o meio do primeiro bit de dados. Recupere seu valor, desloque-o para um registrador e reinicie o contador. O receptor permanece neste estado até que todos os bits de dados sejam recebidos. Quando o último bit de dados é recebido, o receptor muda para o estado STOP.

Estado STOP: O receptor aguarda o meio do bit de parada. Quando o meio do bit de parada é detectado, o receptor muda para o estado IDLE e envia os dados recebidos para a FPGA junto com o sinal confirmado o recebimento dos dados. Em caso de uma falha na detecção do bit de parada, o receptor vai para o estado de ERROR.

Estado ERROR: O receptor fica nesse até que o que o sinal de entrada volte a ser 1, indicando que o sinal estabilizou. Quando o sinal estabiliza, o receptor volta para o estado IDLE.

Figura X: Máquina de estados do receptor UART

Transmissor UART

O transmissor UART é responsável por enviar os dados recebidos pela FPGA para o ESP8266 12e. A organização de um subsistema de transmissão UART é semelhante à do subsistema de recepção, com a principal diferença sendo os sinais de controle e a lógica de transmissão.

A taxa de transmissão é controlada por tiques gerados a partir de um ciclo de clock, que são produzidos por um gerador de taxa de transmissão. Como não há sobreamostragem no transmissor, a frequência dos tiques é 16 vezes mais lenta do que a do receptor UART. Para controlar o número de tiques, o transmissor geralmente compartilha o gerador de taxa do receptor e utiliza um contador interno. A cada 16 tiques de habilitação, um bit é deslocado e enviado.

O transmissor UART é composto por uma máquina de estados que controla a transmissão dos dados. A máquina de estados é composta por quatro estados: IDLE, START, DATA e STOP.

Estado IDLE: O transmissor aguarda a solicitação de transmissão de dados. Quando a solicitação é recebida, o transmissor muda para o estado START e inicia o contador de tiques de transmissão.

Estado START: O transmissor aguarda os 16 tiques de transmissão para sincronizar a transmissão dos dados. Quando os 16 tiques são contados, o transmissor muda para o estado DATA e inicia a transmissão dos bits de dados.

Estado DATA: Quando o contador atinge 15, o sinal de saída progride por um bit deslando o valor de entrada até que todos os bits de dados sejam transmitidos. Quando o último bit de dados é transmitido, o transmissor muda para o estado STOP.

Estado STOP: O transmissor aguarda os 16 tiques de transmissão para sincronizar a transmissão do bit de parada. Quando os 16 tiques são contados, o transmissor muda para o estado IDLE.

A figura a seguir ilustra a máquina de estados do transmissor UART.

Figura X: Máquina de estados do transmissor UART

Comunicação orientada a interrupções

A comunicação UART orientada a interrupções é uma abordagem eficiente para maximizar o desempenho do sistema. Nesse modelo, a FPGA pode executar outras tarefas enquanto monitora eventos UART, como o recebimento ou envio de dados. Quando ocorre um evento, o módulo UART gera uma interrupção, alertando a FPGA para suspender temporariamente sua tarefa atual e processar a comunicação UART. Esse mecanismo otimiza o uso do tempo de processamento da FPGA, garantindo maior eficiência no sistema.

Para implementar esse modelo, são utilizados registradores de controle e status que registram o estado da comunicação UART. Ao detectar um evento, o módulo UART atualiza esses registradores e aciona uma interrupção, que é tratada pela FPGA. Durante o tratamento, a FPGA gerencia a leitura e escrita de dados nos registradores e retoma a troca de informações com o ESP8266 12e, garantindo uma comunicação confiável e eficiente.

No software, a configuração da FPGA para lidar com interrupções envolve a definição de rotinas específicas. Essas rotinas tratam os eventos de interrupção, gerenciam os registradores de controle e status, e asseguram o fluxo correto de dados. Essa abordagem é fundamental para manter a integridade da comunicação entre a FPGA e o ESP8266 12e, maximizando a eficiência do sistema.

-----------------------------------------------------

FIFO

Para armazenar dados recebidos e transmitidos em sistemas digitais, é amplamente utilizado um buffer FIFO (First In, First Out). Essa estrutura de dados segue o princípio "o primeiro que entra é o primeiro que sai", garantindo que os dados sejam lidos na mesma ordem em que foram escritos, o que é essencial para manter a integridade e a sequência de informações em diversas aplicações.

Figura X: Estrutura de um buffer FIFO

O funcionamento do FIFO é baseado em dois ponteiros: o ponteiro de escrita e o ponteiro de leitura. O ponteiro de escrita aponta para a posição onde o próximo dado será armazenado, enquanto o ponteiro de leitura aponta para a posição do próximo dado a ser lido. Quando o buffer está vazio, ambos os ponteiros apontam para a mesma posição, indicando que não há dados disponíveis para leitura. Quando o buffer está cheio, o ponteiro de escrita atinge a posição imediatamente anterior ao ponteiro de leitura, impedindo novas operações de escrita até que algum dado seja lido.

Essa estrutura é projetada para operar de forma eficiente em sistemas com múltiplos processos ou dispositivos que compartilham dados. Além disso, o FIFO pode incorporar sinalizadores auxiliares, como "quase cheio" (almost full) e "quase vazio" (almost empty), que ajudam no gerenciamento do buffer, prevenindo sobrecargas e melhorando o desempenho do sistema. A figura a seguir ilustra a estrutura de um buffer FIFO:

Figura X: Exemplo das fases de um buffer FIFO

Os buffers FIFOs foram utilizados no projeto para armazenar os dados recebidos e transmitidos pela FPGA, garantindo a integridade e a ordem dos dados durante a comunicação com o ESP8266 12e.

-----------------------------------------------------

ESP8266 12e

Comandos de Controle

O ESP8266 12e se comunica com a FPGA através de comandos AT, que são comandos de controle que permitem a configuração do módulo. Os comandos AT são enviados pela FPGA para o ESP através da comunicação UART. Por default, o ESP opera a uma taxa de 115200 bps.

Comandos basicos:

comando descrição resposta
AT Teste de comunicação OK
ATE0 Desabilita o eco de caracteres. OK
AT+RST Reinicia o módulo. OK
AT+GSLP=<time> Coloca o módulo em modo de baixo consumo de energia por um tempo especificado. <time> OK
AT+RESTORE Restaura as configurações de fábrica. OK
AT+UART_CUR=<baud>,<databits>,<stopbits>,<parity>,<flow control> Configura a UART. OK
AT+UART_DEF=<baud>,<databits>,<stopbits>,<parity>,<flow control> Configura a UART de forma permanente. OK

Tabela X: Comandos básicos do ESP8266 12e

O comando AT+UART_CUR=115200,8,1,0,3 configura a UART para 115200 bps, 8 bits de dados, 1 bit de parada, sem paridade e com controle de fluxo RTS/CTS.

Comandos wifi:

comando descrição resposta
AT+CWMODE=<mode> Configura o modo de operação do módulo. OK
AT+CWJAP=<ssid>,<password> Conecta o módulo a uma rede Wi-Fi. OK ou ERRO
AT+CWLAP Lista as redes Wi-Fi disponíveis. OK
AT+CWQAP Desconecta o módulo da rede Wi-Fi. OK
AT+CWAUTOCONN=<enable> Habilita/desabilita a conexão automática à rede Wi-Fi. OK

Tabela X: Comandos de configuração Wi-Fi do ESP8266 12e

O comando AT+CWMODE=3 configura o módulo para operar em modo AP e STA.

O comando AT+CWJAP="ssid","password" conecta o módulo a uma rede Wi-Fi com SSID e senha especificados.

Comandos TCP/IP:

comando descrição resposta
AT+CIPSTATUS Retorna o status da conexão TCP/IP. STATUS:<status>
AT+CIPSTART=<type>,<addr>,<port> Estabelece uma conexão TCP/IP. CONNECT ou ERRO
AT+CIPSSLSIZE=<size> Configura o tamanho do buffer SSL. OK
AT+CIPSEND=<length> Envia dados pela conexão TCP/IP. OK ou ERRO
AT+CIPCLOSE Fecha a conexão TCP/IP. CLOSED
+IPD Recebe dados pela conexão TCP/IP. +IPD,<length>:<data>
AT+CIPRECVMODE=<mode> Configura o modo de recepção de dados. OK
AT+CIPRECVDATA=<length> Recebe dados no modo manual. OK

Tabela X: Comandos de configuração TCP/IP do ESP8266 12e

Ao usar AT+CIPSEND espera-se que o módulo responda com o caractere >, indicando que o módulo está pronto para receber os dados a serem enviados.

O comando AT+CIPRECVMODE=0 configura o módulo para receber dados de forma automática e AT+CIPRECVMODE = 1 configura o módulo para receber dados manualmente.

-----------------------------------------------------

Arquitetura do Projeto

Modulo UART

Versão simplificada da arquitetura do módulo UART:

Figura X: Versão simplificada da arquitetura do módulo UART

Comunicação entre o processador e o ESP8266 12e

Segue a versão simplificada da comunicação entre o processador e o ESP8266 12e utilizando a UART:

Figura X: Versão simplificada da comunicação entre o processador e o ESP8266 12e

Para facilitar a visualização, segue um diagrama de sequência que ilustra a comunicação entre o processador e o ESP8266 12e com os comandos AT para realizar a conexão Wi-Fi e a comunicação TCP/IP:

Organização dos Registradores

Tabela dos os endereços dos registradores:

Endereço Registrador
0x00 Dados de transmissão e recepção
0x01 Controle do Modulo UART
0x02 Mascara de interrupção
0x03 status de interrupção

Tabela X: Endereços dos registradores

Tabela de dados de transmissão e recepção:

Bit Index Descrição Sigla tipo
7 - 0 Dados de transmissão RBR W
7 - 0 Dados de recepção TBR R
31 - 8 Não utilizado

Tabela X: Organização dos dados do registrador de transmissão e recepção

Tabela de controle do módulo UART:

Bit Index Descrição Sigla tipo
0 Reset do Módulo UART RST W/R
1 Habilitar Controle de Fluxo ENFC W/R
2 Reiniciar FIFO de Transmissão TXRST W/R
3 Reiniciar FIFO de Recebimento RXRST W/R
4 Habilitar Módulos de Transmissão e Recebimento EN W/R
5 Buffer de Recebimento Cheio RXFULL R
6 Buffer de Recebimento Vazio RXEMPTY R
7 Buffer de Transmissão Cheio TXFULL R
8 Buffer de Transmissão Vazio TXEMPTY R
9 Erro no Frame EFRM R
10 RTS Ativo RTS R
31 - 11 Não utilizado

Tabela X: Organização dos dados do registrador de controle do módulo UART

Tabela de máscara de interrupção:

Bit Index Descrição Sigla tipo
0 Habilita interrupções na transmissão TX_INT_EN W/R
1 Habilita Byte Recebido (RX Ready) RX_READY_INT W/R
2 Habilitar Interrupção do Buffer de Recebimento Cheio RX_FULL_INT_EN W/R
3 Habilitar Interrupção quando o Buffer de Recebimento não está vazio RX_NOT_EMPTY_INT_EN W/R
4 Habilitar Interrupção do Buffer de Transmissão Cheio TX_FULL_INT_EN W/R
5 Habilitar Interrupção do Buffer de Transmissão Vazio TX_EMPTY_INT_EN W/R
6 Habilitar Mudança no Estado do RTS (Delta RTS) DRTS W/R
7 Habilitar Interrupção Buffer de Transmissão não está cheio TX_NOT_FULL_INT_EN W/R
31 - 8 Não utilizado

Tabela X: Organização dos dados do registrador de máscara de interrupção

Tabela de status de interrupção:

Bit Index Descrição Sigla tipo
0 Status de Interrupção ao Transmitir um Byte TX_INT_STATUS W/R
1 Status de Interrupção ao Receber um Byte (RX Ready) RX_READY_INT_STATUS W/R
2 Status de Interrupção do Buffer de Recebimento Cheio RX_FULL_INT_STATUS W/R
3 Status de Interrupção quando o Buffer de Recebimento não está vazio RX_NOT_EMPTY_INT_STATUS W/R
4 Status de Interrupção do Buffer de Transmissão Cheio TX_FULL_INT_STATUS W/R
5 Status de Interrupção do Buffer de Transmissão Vazio TX_EMPTY_INT_STATUS W/R
6 Status de Mudança no Estado do RTS (Delta RTS) DRTS_INT_STATUS W/R
7 Status de Interrupção Buffer de Transmissão não está cheio TX_NOT_FULL_INT_STATUS W/R
31 - 8 Não utilizado

Tabela X: Organização dos dados do registrador de status de interrupção

Lógica de Envio de dados

Figura X: Fluxograma de envio de dados

Figura X: Fluxograma de interrupção

-----------------------------------------------------

Referências

PEDRONI, Volnei A. FPGA Prototyping by Verilog Examples: Xilinx Spartan-3 Version. 1st ed. Hoboken: Wiley-Interscience, 2008.

EPUSP — PCS 2021 — Laboratório Digital. UART. Versão 2015. Disponível em: https://www2.pcs.usp.br/~labdig/pdffiles_2015/uart.pdf. Acesso em 19 de Dezembro de 2024.

Espressif. ESP8266 AT Instruction Set. Disponível em: https://www.espressif.com/sites/default/files/documentation/4a-esp8266_at_instruction_set_en.pdf. Acesso em: 16 de Dezembro de 2024.

About

UART Core com suporte a RTS/CTS para comunicação serial em FPGA. Projeto de Iniciação Científica (CNPq) do Telecore 64, um console portátil em FPGA que integra jogos 2D e controle de robôs, unindo sistemas embarcados, teleoperação e redes.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published