Estoy usando un ATmega328P para enviar datos a otro dispositivo a una alta velocidad de transmisión (230400). El dispositivo al que estoy enviando datos admite el control de flujo y aumenta la señal RTS cuando necesita mantener la transmisión. El problema es que el dispositivo espera que detenga la transmisión inmediatamente después de que se afirma RTS.
El ATmega328P tiene un búfer de transmisión (UDR) y un registro de desplazamiento desde el cual se envían datos a la línea TX. Dado que el ATmega328P no es compatible con el control de flujo en el hardware, lo estoy implementando en el software. Antes de enviar (antes de escribir en UDR) estoy revisando RTS y esperando hasta que baje, pero aparentemente esto no es suficiente porque los datos en el búfer de transmisión y el registro de desplazamiento todavía se envían y aún se puede enviar un byte completo después de que RTS es afirmó cuando el ATmega328P vacía sus búferes.
Aparentemente, deshabilitar el transmisor cuando se afirma RTS (configurar el TXEN en cero) no ayuda, ya que no se hará efectivo hasta que se completen las transmisiones en curso y pendientes, según la sección de documentación 19.6.5 .
Una solución alternativa podría ser esperar hasta que se complete la transmisión (TXC) antes de enviar cada byte, pero esto afectaría la tasa de datos ya que no estoy enviando el flujo de bytes de forma consecutiva incluso cuando RTS no está afirmado (estoy empezando a enviar un nuevo byte solo después de que el anterior haya sido enviado por completo).
Con el ATmega328P, ¿hay alguna forma de admitir el control de flujo RTS en el transmisor mientras se sigue disfrutando de la canalización proporcionada por el búfer de transmisión y el registro de desplazamiento?
Parece que tiene dos problemas básicos, un dispositivo externo mal diseñado y que está tratando de hacer que un hardware inapropiado haga un trabajo para el que no está diseñado.
Primero, ¿realmente este otro dispositivo no requiere absolutamente más bytes después de que se afirma RTS? Eso sería muy inusual. Es muy común que los transmisores vacíen un pequeño búfer antes de obedecer a RTS, por lo que, a menos que el otro ingeniero no supiera lo que estaba haciendo, el dispositivo debería poder tolerar unos pocos bytes más. Tal vez no pueda manejar el caso "con todas las funciones" de 16 bytes más, pero no permitir 2-4 bytes más es simplemente un mal diseño.
En segundo lugar, dado que debe dejar de transmitir más rápido que el tamaño del búfer de salida, eligió el hardware incorrecto. No estoy familiarizado con esa línea de micros, pero seguramente esto está en la hoja de datos. Veo tres opciones:
Ninguna de estas compensaciones puede ser lo que desea, pero ese es el costo de una mala arquitectura. Arréglalo en la siguiente revolución o vuelve a girar ahora si es realmente importante. El mundo no siempre tiene una respuesta mágica solo porque tu jefe la quiere ahora o porque te arrinconaste.
UDRn
más un registro de desplazamiento de transmisión. El SW puede escribir en UDRn
el siguiente valor a enviar mientras el anterior se envía desde el registro de desplazamiento al mismo tiempo. El problema aquí es el hecho de que la transmisión no se puede detener hasta que ambos UDRn
y el registro de desplazamiento de transmisión estén vacíos.UDRE
esté vacío, pero lo que debería suceder es que el siguiente byte no debería ponerse en cola hasta que se complete la transmisión. Esto permitirá el control byte por byte.
Ignacio Vázquez-Abrams
Rdo
Amir Gonnen
Ignacio Vázquez-Abrams
Amir Gonnen
Amir Gonnen
Rdo
Ignacio Vázquez-Abrams
Amir Gonnen
Amir Gonnen
UDREn
y noTXCn
.