No obtener el reconocimiento adecuado y la condición de parada en el bus I2C

Estoy tratando de comunicar la placa de torre Kinetis K60 con una placa de desarrollo Cypress IC CY8CMBR3116 cy8320 como IC esclavo. Solo hay dos dispositivos en el bus I2C. Adjunto una instantánea de la comunicación que tiene lugar en el bus I2C.ingrese la descripción de la imagen aquí

El problema es que el reconocimiento no es lo suficientemente bajo para que el maestro lo detecte e incluso la condición de parada no es correcta. Esto sucede después de enviar la dirección predeterminada de 0X37 al Cypress IC.

Por favor, dígame el motivo de esta salida.

¿Estás haciendo tu propio I2C en el K60? Parece que el maestro está impulsando la línea SDA push-pull en lugar de colector abierto. Esos niveles intermedios parecen una pelea de autobuses en la que el amo conduce alto mientras que el esclavo conduce bajo.
No, estamos usando el periférico I2C integrado en el microcontrolador Kinetis K60DN512VMD10 en la placa de la torre.
La primera transacción (dirección 37) del bus maestro parece una transacción ACK corrupta al final. Su maestro de bus continúa independientemente con una segunda transacción (que no obtiene un ACK corrupto, pero no recibe ACK . ¿Su código verifica si hay ACK válidos?
¿Ha probado una secuencia de borrado de bus I2C recomendada mucho después de que ambos sistemas se hayan encendido?
No estoy familiarizado con los Kinetis. En la configuración, ¿necesita configurar manualmente el modo pin en colector abierto?
Veo que has hecho la misma pregunta en el foro de NXP . No hay respuestas en el momento en que escribo esto. Sin embargo, para cualquiera que lea esta pregunta aquí, es posible que cualquier respuesta futura allí pueda contener información útil, razón por la cual proporcioné ese enlace a su hilo en el foro de NXP.

Respuestas (1)

TL; DR: algunos o todos los problemas están en su código.

No proporcionó el código relevante, pero los dos problemas que veo en ese seguimiento del alcance están relacionados con el código:

  • Como señaló DoxyLover , el rastro muestra claramente un voltaje intermedio, causado por un conflicto entre dos dispositivos que conducen esa señal SDA en direcciones opuestas para el ciclo I²C ACK . Dado que el esclavo I²C está conduciendo esa señal a un nivel bajo (como un ACK ), entonces su MCU Kinetis K60 debe estar llevándola a un nivel alto al mismo tiempo.

    Al igual que con muchas MCU, cuando el módulo I²C interno está conectado a los pines externos reales (por ejemplo, a través del multiplexor de pin interno), esos dos pines también deben configurarse en modo de "drenaje abierto" como un paso separado en la configuración .

    En el Manual de referencia de NXP que creo que incluye su MCU K60 específico ( archivo pdf de 20 MB ), página 282 (sección 11.6.1 Control de pines) dice:

    Por ejemplo, si una función I²C está habilitada en un pin, eso no anula la configuración de extracción o drenaje abierto para ese pin.

    En otras palabras, habilitar I²C en un pin no establece automáticamente el pin en drenaje abierto (ni cambia la configuración actual para el pull-up interno).

    En este documento "I2C para Kinetis MCU" , la página 23 tiene esta pregunta y respuesta:

    P: ¿Por qué la señal de bajo nivel en SDA o SCL no se reduce completamente a 0 voltios?
    R: Para los MCU Kinetis, es posible que deba configurar los pines I2C para el modo de drenaje abierto configurando el bit PORTx_PCR[ODE]. Otra causa de esto puede ser una mala conexión a tierra entre su dispositivo maestro y el dispositivo esclavo.
    [mi énfasis arriba]

    (Según el seguimiento del alcance, dudo que la conexión a tierra sea la causa de su problema).

    Como ejemplos de configuración del modo de drenaje abierto en algún código I²C, encontré dos ejemplos aleatorios en el código de muestra de Kinetis aquí :

    #define I2C_0_PORT_CFG (PORT_PCR_MUX(I2C_0_PIN_AF) | PORT_PCR_ODE_MASK)

    y aquí :

    PORTB->PCR[0] = PORT_PCR_MUX(2) | PORT_PCR_ODE_MASK; PORTB->PCR[1] = PORT_PCR_MUX(2) | PORT_PCR_ODE_MASK;

  • Como ha destacado glen_geek en comentarios anteriores, parece que su código continúa con la comunicación I²C incluso después de que el ciclo ACK tiene el problema descrito anteriormente. Por lo tanto, es posible que tenga otro error de código en esta área.

¿Está cableado O hay conflicto alto o alto/bajo? Uno podría probar con 10k pullup o pull down para determinar Z de ese voltaje de nivel medio (ignorar si el código lo soluciona)
@Tony: no sé exactamente a qué te refieres con "cableado O alto". Supongo que está sugiriendo que la resistencia pull-up podría ser demasiado fuerte (es decir, un valor demasiado bajo), lo que podría provocar que los controladores I2C típicos de 3 mA no puedan llevar la señal a ~ 0 V. ¿Es eso lo que está preguntando? Si es así, al observar el seguimiento del osciloscopio, noto que el maestro puede bajar con éxito la señal SDA a ~ 0 V cuando está impulsando esa señal sola, por lo que el valor de la resistencia pull-up I2C no parece demasiado fuerte (valor bajo ) . Mi voto, basado en la experiencia de depuración de problemas similares, sigue siendo un "conflicto alto/bajo", como expliqué.
pero si el nivel bajo es de 100 ohmios y el nivel alto es pasivo de 10k, debo entender mal por qué ~ 3V
Lo siento @Tony, no entiendo tu hipótesis. Sin embargo, si tiene una explicación alternativa que se ajuste a todas las partes del seguimiento del alcance (y la falta de confirmación del OP de que establezcan el modo de drenaje abierto), entonces tal vez escribirlo en una respuesta ayudaría al OP, en caso de que mi hipótesis sea equivocado.
Vol = 0,6 V @ 6 mA disipador para buenos chips I2C o Ron = 0,6 V/6 mA = 100 ohmios e I2C es algo de R a Vdd entonces ¿cuál es R para obtener V de estado medio de 2 V? mientras que "1" parece 3,3 V y "0" parece 0,3 V, es por eso que sugerí agregar otro pull-up para probar la corriente de carga. Si tiene 10k internos activos habilitados a tierra, eso explicaría la falla en el controlador.
¿Es su i2C 1k o 10k pull-up? Me pregunto.
Leí K60 pull-up/dn interno son 35k +\- 50% SI está habilitado.
"¿Es su i2C 1k o 10k pull-up?" De acuerdo con el esquema de la placa citado por el OP (ver R54 y R55 en la página 7), son pull-ups de 4.7k a 3.3 V. Incluso si fueran pull-ups de 1k, como sugiere, un controlador débil de 3mA todavía poder dejar caer 3V (3mA * 1k) a través de la resistencia y lograr un Vol de 0.3V, que no es lo que vemos en la traza del osciloscopio. Así que todavía no entiendo cómo encaja tu hipótesis con los datos presentados por el OP :-( ¿Quizás alguien más entiende tu hipótesis mejor que yo?
Gracias Sam por el enlace. entonces Iol=3.3/4k7=0.7mA max y si Vol=0.3 entonces Ron=0.3/0.7m=~4xx Ohms para "0" que todavía está bien así que si el estado medio está justo por encima del disparador de 1.72V o ~2V entonces abra fantasma la carga a tierra parece ser de 8K a tierra durante esa ventana, lo que crea un umbral ilegal con histéresis en un mínimo de 3,3 V o 2,2 V para Voh. Así que ubique la R desplegable fantasma durante ese período o intente agregar 5 ~ 10k pullup
Creo que tiene razón, que el modo de drenaje abierto no está habilitado y el problema activo alto/bajo también se puede verificar con un pull-up de 1k y verifique el cambio en los controladores V. ARM generalmente son de 25 ohmios.