1 votos

¿cuánto tiempo debe esperar un esclavo I2C por un bit de STOP (si es que lo hace)?

I2C enmarca cada grupo de bytes de mensaje en condiciones de START y STOP, definidas como SDA cambiando el estado 1>0 o 0>1 (respectivamente) mientras SCL está alto, como se describe ici .

Estoy escribiendo manejadores controlados por interrupciones para el PIC32MX170, y llegué bastante lejos usando el bit de STOP como señal al software de que el mensaje ha terminado. Esto permite cosas como la comprobación de la cuenta de bytes rx/tx y así sucesivamente. Encontré que la comprobación de la bandera de STOP en el software era bastante fiable, con la combinación de hardware y reloj que utilicé.

Sin embargo, ahora descubro que no es fiable en absoluto: el uso de un reloj más rápido o un controlador más lento significa que el ISR puede salir y perder el bit de STOP por completo. Peor aún, como el siguiente byte será el START de un nuevo mensaje, no hay manera de saber si alguna vez llegó (a menos que te sientes a sondear el bus, que no es realmente el tipo de cosa que quiero en un ISR, incluso con el tiempo de espera).

Sin embargo, el código que depende de combinaciones defectuosas de hardware y relojes también es bastante malo, así que me estoy enfrentando a un rediseño que asume que los bits de STOP no son fiables (por suerte no intento hacer cuentas de bytes variables).

(Algunos uC's siempre levantan una interrupción en STOP, pero desafortunadamente no este, por lo que puedo decir).

Pero esto plantea la pregunta: ¿debe un ISR esperar en el bit de STOP? Si es así, ¿por cuánto tiempo? ¿Hay algo en las especificaciones sobre esto?

EDITAR: Añado alguna información, ya que quizás no me expresé con total claridad en mi original. Mi pregunta se refería realmente a los medios para detectar el inicio y la parada del mensaje, lo que por supuesto es esencial. (Más adelante se discute sobre asuntos relacionados, como en qué parte del código se realiza la decodificación, lo cual también es muy valioso, pero no es lo que yo preguntaba).

El problema es básicamente que, aunque las condiciones de START y STOP (S y P) (en realidad los bits de estado que las señalan en el dispositivo) no siempre se establecen cuando el ISR se ejecuta, aunque sea la última vez para el mensaje. (También está la cuestión de si el ISR necesita mirar esos bits, lo que creo que tiene que ver más con el diseño del sistema, pero también es interesante y relevante).

Además de las banderas S/P, también hay banderas que le indican el tipo de byte que acaba de recibir: Dirección R/W y Datos R/W. Address Write siempre señala el inicio de un mensaje. Después de este punto se debe observar una cierta estructura, que puede implicar condiciones S repetidas y así sucesivamente. Dependiendo de cómo diseñes tu protocolo de mensajes (especialmente si soportas longitudes variables o no) estos también pueden ser usados para entender la estructura del mensaje. De esto trata la pregunta.

2voto

Nick Alexeev Puntos 20994

I 2 C tiene un reconocer el bit y un condición de parada . Estoy haciendo una suposición operativa que usted está preguntando acerca de esos. Por favor, corrígeme si me equivoco.
(I 2 C no tiene parada bit .)

Pero esto plantea la pregunta: ¿debe un ISR esperar en el bit de STOP? Si es así, ¿durante cuánto tiempo? ¿Hay algo en las especificaciones sobre esto?

El I 2 La especificación C no contempla ningún tiempo de espera. En teoría, el esclavo debe esperar indefinidamente. Del mismo modo, el maestro esperará indefinidamente cuando el esclavo haga un estiramiento del reloj.

Podrías introducir un tiempo de espera en el dispositivo esclavo. Sin embargo, tendrías que abordar la siguiente capa de preguntas sobre el manejo general del tiempo de espera. Si el esclavo ha agotado el tiempo de espera, significa que la comunicación se ha corrompido. ¿Cómo señalas ese tipo de excepción al controlador maestro? ¿Intentas recuperarte? ¿Intentas apagar todo el sistema de forma elegante?

... combinaciones defectuosas de hardware y relojes... ...así que me estoy enfrentando a un rediseño que asume que los bits de STOP no son fiables (por suerte no intento hacer cuentas de bytes variables).

He estado en una situación similar . Arreglen los herrajes. Hay que tener condición de parada en el I 2 C.

2voto

RelaXNow Puntos 1164

Realmente necesitas una arquitectura de firmware adecuada para algo como esto, donde reaccionas a eventos externos asíncronos que no están bajo tu control.

Las rutinas de interrupción deben atender el evento de hardware inmediato, y luego salir del camino. Aquí NO se debe tratar el tiempo arbitrario entre eventos. Tampoco es donde deberías tratar de entender los eventos individuales a un nivel superior, como un mensaje IIC completo.

La última vez que tuve que implementar un esclavo IIC en un dsPIC, utilicé el hardware para recibir eventos en una rutina de interrupción. Sin embargo, esa rutina de interrupción en su mayoría empujó los eventos en un FIFO. Ese FIFO se vaciaba entonces en una tarea separada dedicada a interpretar los eventos como secuencias IIC y actuar sobre ellos. Esto funcionó bastante bien.

Respuesta a los comentarios

"En primer plano" significa ejecutar una tarea de su bucle principal, ¿verdad?

Significa que se ejecuta desde un código que no interrumpe. Si eso es desde el bucle de eventos principal o una tarea diferente depende de su diseño de firmware.

¿el ISR I2c tiene mayor o menor prioridad?

Más alto, obviamente. Ese es parte del objetivo de las interrupciones. Si no tuvieran una prioridad más alta, no podrían interrumpir nada.

si está estirando el reloj mientras espera el mensaje - ¿no hace que en realidad se alargue la marcha, no que se acorte?

No. La rutina de interrupción no se ejecuta en absoluto durante el tiempo de estiramiento del reloj. La rutina de interrupción obtiene el byte de dirección. Lo pone en un FIFO y sale. El código en primer plano interpreta el inicio del mensaje IIC, se da cuenta de que debe responder, rellena un buffer de bytes de respuesta, y activa la interrupción de envío de bytes IIC. Esa interrupción se produce inmediatamente. La rutina de interrupción obtiene el primer byte del buffer y lo escribe en el hardware IIC. Esto finaliza el estiramiento del reloj y comienza a enviar el primer byte de datos. La rutina de interrupción sale y se ejecuta de nuevo cuando el hardware IIC está listo para aceptar el siguiente byte de datos.

1voto

Surendra Patil Puntos 11

El ISR debería pas esperar. Siempre.

De hecho, no debería hacer ningún tipo de procesamiento de mensajes. Debería rellenar los datos recibidos en el búfer, ACKing cuando sea necesario, activando la bandera de "listo" cuando encuentre una condición de parada y restableciendo el contador del búfer al principio en la condición de inicio.

El programa principal puede entonces empezar a procesar los mensajes en paralelo. Puede controlar el ISR mediante banderas como "estirar el reloj, no estoy listo para responder todavía", etc.

O, si quieres ser extravagante, haz varios buffers para que uno se pueda ir llenando mientras el otro(s) se procesa en main (asumiendo que los mensajes entrantes no requieren respuesta inmediata).

0voto

silverbolt Puntos 18

No confíes en que el bit de parada esté presente en absoluto. No es necesario que una transferencia termine con un bit de parada. En muchos casos, las transferencias terminarán con un inicio repetido al comienzo de la siguiente transferencia.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X