ATMEGA TWI / I2C Slave - ¿Cómo implementar el estiramiento del reloj?

1

Estoy programando un esclavo TWI basado en un ATMEGA644PV.

Está funcionando en general, el maestro puede enviar y leer datos del esclavo. Hasta ahora todo bien.
Pero en algunas solicitudes de lectura, el esclavo requiere "más tiempo" para preparar los datos. Me gustaría utilizar el estiramiento de reloj para que el maestro espere hasta que los datos estén listos.

La hoja de datos de ATMEGA señala:

  

El esclavo puede extender el período bajo de SCL tirando de la línea SCL hacia abajo. Esto es útil si la velocidad de reloj configurada por el Maestro es demasiado rápida para el Esclavo, o el Esclavo necesita tiempo extra para procesar entre las transmisiones de datos.

Esto es exactamente lo que quiero, pero no entiendo cómo implementar esto en el nivel del controlador. No veo ninguna manera de indicar al hardware esclavo I2C que no debería ACK inmediatamente, sino que, en cambio, retire el SCL por un período de mi elección.

De lo que obtengo, solo puedo decirle al esclavo a ACK o, bueno, no a ACK en absoluto después de ser direccionado o la transferencia de un byte de datos.

¿Me estoy perdiendo algo obvio aquí? Esta es la primera vez que veo I2C desde la vista de un esclavo.

    
pregunta Rev1.0

2 respuestas

2

Los procesadores Atmel Atmega (incluido el Atmega644) ejecutan automáticamente el estiramiento del reloj cada vez que la interfaz I2C necesita una acción realizada por el software.

Esta acción podría ser cuando un esclavo ha recibido un byte de datos y los datos deben eliminarse del registro de datos antes de que se pueda recibir el siguiente byte o cuando se necesiten datos para transmitir. Sucede siempre que se establece el indicador TWINT.

La hoja de datos no resalta mucho el hecho, pero se menciona en algunos lugares (como en la sección 19.5.5 en la página 207 en la hoja de datos de 02/12).

    
respondido por el Kevin White
0

Consulte el siguiente esquema para ver la interfaz más utilizada entre los dispositivos I2C maestro y esclavo. Esta interfaz no utiliza el estiramiento de reloj. El maestro genera todas las señales de reloj en SCL con SW2 (y el esclavo solo recibe estas señales de reloj).
Los datos pueden transferirse en ambos sentidos : de maestro a esclavo con SW1, o de esclavo -a-master con SW3. Por supuesto, ambos extremos deben acordar quién puede controlar la línea de datos de SDA para evitar colisiones. Por "control", quiero decir que el interruptor está cerrado, cortocircuitando la línea de datos a tierra. Un interruptor abierto permite que la línea SDA se eleve para suministrar voltaje a través de la resistencia de pull-up. Un interruptor cerrado tiene "control" de la línea SDA, tirando de él a tierra (bajo). Un bus inactivo tiene todos los interruptores abiertos.

simular este circuito : esquema creado usando CircuitLab En el esquema anterior, el maestro registra SW2 a una velocidad de 100k ciclos por segundo (o 400k para alta velocidad), esperando que el esclavo continúe. En un sistema de reloj alargado, el inicio maestro inicia un ciclo de reloj cerrando SW2, y abre SW2 poco tiempo después (eso normalmente terminaría ese ciclo de reloj). Pero supervisa la línea del reloj con BUF4 para ver si el R2 se ha vuelto realmente al estado alto inactivo. Si el interruptor esclavo SW4 mantiene la línea del reloj baja, eso es un alargamiento del reloj, aguantando más transferencias de datos:

simular este circuito Un dispositivo esclavo muy a menudo no tiene manera de realizar un estiramiento de reloj, porque SW4 no existe, o si existe, no hay manera de cerrarlo. Pero cualquier microcontrolador tiene pines GPIO que pueden hacer la función SW4, bajando a tierra. El tiempo de SW4 es crítico: se debe bajar solo mientras SW2 también se está agotando, para realizar la función de estiramiento de reloj esclavo. Así que el pseudocódigo para controlar el pin GPIO (SW4) en el esclavo es así:
Initialize GPIO pin to be an input (read). When Slave must clock-stretch, continually monitor GPIO pin, looking for "low". While SCL is low, change GPIO to be output pin, set to logic "0". Keep low until Slave is ready to continue. Once Slave is ready, change GPIO to be input, clearing the clock-stretch.

La transferencia de bits de datos ACK o NACK se utiliza principalmente para garantizar master & Los esclavos están vivos y sincronizados.

    
respondido por el glen_geek

Lea otras preguntas en las etiquetas