Hay un buen truco que puedes hacer si la comunicación es en una dirección solo a la vez (es decir, comunicación semidúplex). No funcionará si ambas partes hablan entre sí al mismo tiempo (dúplex completo), pero si es el típico "haz esto" "ok, aquí está la respuesta" "ahora haz esto" "ok, aquí está la nueva respuesta" tipo de comunicaciones funciona bastante bien.
Dado que el enlace UART usa una condición inactiva del transmisor en un nivel lógico alto (1), usaría una puerta AND de 2 entradas y conectaría el TX de cada lado a una entrada AND. La salida de la compuerta AND es su entrada a la UART de su sniffer (es el pin RX). Ahora tome la línea TX del dispositivo B y llévela a un puerto de E / S en el detector. Configurará el sniffer para generar una interrupción cuando este pin pase de alto a bajo.
Para recapitular: dispositivo A UART TX - > Y entrada de puerta. Dispositivo B UART TX - > otra entrada de compuerta AND Y pin GPIO sniffer. Salida de la puerta AND - > sniffer línea UART RX.
Las comunicaciones UART consisten en un bit de inicio, un cierto número de bits de datos, un bit de paridad opcional y uno o más bits de parada. Dado que el estado inactivo es un nivel lógico alto (1), el inicio de CADA byte será un nivel lógico bajo (0) y se disparará la interrupción en el rastreador. Mientras su sniffer está ejecutando la interrupción de E / S, el hardware de UART recolectará bits de la puerta AND. En el momento en que UART haya recibido el bit de parada, la interrupción de E / S se completará por mucho tiempo y la interrupción de RX de UART se disparará.
La rutina de interrupción de IO-cambio establecerá una variable de "dirección" para indicar que las comunicaciones están en la dirección "B- > A". La interrupción de recepción de UART del sniffer observaría esta variable de "dirección" y escribiría el byte que se acaba de recibir en el búfer apropiado. La interrupción de RX de UART restablecería la variable de "dirección" al estado predeterminado "A- > B":
volatile int direction = 0; /* 0 = A -> B */
void io_interrupt(void)
{
direction = 1; /* switch direction, now B -> A */
}
void uart_interrupt(void)
{
unsigned char b;
b = UART_RX_REG;
if(direction) {
store_byte_to_device_b_sniff_buffer(b);
} else {
store_byte_to_device_a_sniff_buffer(b);
}
direction = 0; /* reset direction to default A -> B */
}
Este código está escrito para mayor claridad y no necesariamente lo que escribirías en una situación del mundo real. Personalmente, convertiría la "dirección" en un indicador de la estructura FIFO apropiada, pero ese es otro ejercicio completamente. :-)
Cuando el dispositivo A está hablando, la línea de E / S no se mueve (permanece en un '1' lógico ya que el transmisor UART del dispositivo B está inactivo), y la interrupción de RX de UART recibirá un byte, verifique que la dirección es A - > B, y almacena los datos en ese búfer. Cuando el dispositivo B está hablando, la línea de E / S bajará tan pronto como el dispositivo B comience a desplazar los datos, y la rutina de interrupción de E / S establecerá la dirección para indicar que el dispositivo B está hablando. La interrupción de RX de UART finalmente se activará después de que se hayan recopilado todos los bits y, dado que la interrupción de E / S se ha ocupado de configurar el registro de dirección de manera adecuada, el byte recibido se almacenará en el búfer correcto.
Presto: comunicaciones half-duplex entre dos dispositivos capturados con una sola UART y una línea de E / S en el sniffer, sin comunicaciones UART de bit banged.