I2C EEPROM bit-banging: escribe bien, pero solo si el primer bit no está configurado

9

Actualmente estoy trabajando en un proyecto I2C EEPROM usando bit-banging para manejar las líneas SDA y SCL.

Mi función de lectura funciona bien, pero cada vez que escribo cualquier byte con un "1" inicial, siempre leo FF; incluso si el byte ha sido programado con algo más antes. Liderando "0" es perfecto. No es mi rutina de lectura; Como puedo ver en el alcance, devuelve FF.

Estoy buscando sugerencias sobre por qué esto podría ser. ¿Hay alguna obvia que pueda pasar por alto que pueda causar el problema? [No puedo publicar el código - empresa confidencial ... :(]

Cada forma de onda que miro cumple exactamente con las especificaciones. Estoy desacoplando la EEPROM. Mis pull ups son 2.2k, así que dentro de las especificaciones. Estoy registrando a unos 500 Hz en este prototipo. El chip está enviando ACK a cada uno de mis bytes, por lo que los reconoce. Pero simplemente no funciona ...

Estoy usando un Microchip 24LC256 .

Algoritmo de escritura simplificado para un byte:

wait
SDA low
SCL low
wait
for each bit
    if bit is set:   SDA high
    if bit is unset: SDA low
    wait
    SCL high
    wait
    wait
    SCL low
    wait
wait
SDA high 
SCL high
wait
wait
check ACK status
SDA low
SCL low
wait
return ACK status

Algoritmo de lectura simplificado para un byte:

wait
SCL low
SDA high
for each bit (8 bits)
    SCL high
    wait
    wait
    SCL low
    wait
    check and store received bit
    wait
do a NACK or ACK depending on if it is the last byte
Thomas O
fuente
1
@Justin - Creo que dice que escribir el valor 0x7F en cualquier dirección funciona, pero escribir 0x80 en cualquier dirección no funciona.
Rocketmagnet
1
Cosas como esta me hacen odiar a I2C.
Rocketmagnet
1
Tengo una corazonada loca. En su código para cada bit, ¿está inadvertidamente extendiendo la señal con una operación de cambio a la derecha? Si es así, su líder finalmente lo dejará con un 0xFF después de 7 operaciones de turno.
vicatcu
3
La ironía, aquí, es el código "confidencial de la compañía". Es valioso para ellos. Todos los demás aquí comparten código que funciona. Lo que diferencia al código de esta compañía de los demás es que no funciona.
gbarry
2
Es difícil imaginar por qué una empresa necesita con tanta urgencia mantener confidencial el código de golpes de un bit I2C. Hay mucho en Internet.
Rocketmagnet

Respuestas:

4

Estás leyendo los datos después de que el reloj vuelva a estar bajo. Tendrás que hacer eso entre hacer que el reloj sea alto y hacerlo bajo. Una vez que el reloj está bajo, el esclavo puede cambiar la línea de datos, no mientras esté alto.

ingrese la descripción de la imagen aquí

Entonces leer debería ser así:

wait
SCL low
SDA high
for each bit (8 bits)
    SCL high                      <--------
    wait
    check and store received bit  <--------
    wait
    SCL low                       <--------
    wait
    wait
do a NACK or ACK depending on if it is the last byte
stevenvh
fuente
Ese es un buen punto; Lo arreglaré Sin embargo, mis datos todavía se muestran como todos (FF) en mi alcance, por lo que mi lectura no puede ser el problema ... :(
Thomas O
3

El problema al final resultó ser que estaba enviando inadvertidamente una condición de DETENCIÓN en algunas condiciones debido a la sincronización. Dejé de usar el alcance y saqué el analizador lógico, y pude solucionar el problema en 15 minutos, ya que resaltaba la PARADA que no debería haber estado allí. Elegiré a quién dar la recompensa en función de la respuesta más útil. Gracias por todas las soluciones.

Thomas O
fuente
Me alegra que lo haya resuelto "verifique el tiempo de escritura"
3
Te dije que esto se resolvería mirando la forma de onda.
Rocketmagnet
@Rocketmagnet Siempre he estado mirando la forma de onda, pero nunca antes me había dado cuenta.
Thomas O
Sí, pero no nos mostró la forma de onda, a pesar de que se la pedimos repetidamente. Podrías haber resuelto este problema hace días.
Rocketmagnet
@Rocket - Estoy de acuerdo. Desearía tener una cámara disponible en ese momento. El DPO de Tek que estaba usando tenía una unidad de disquete pero no un disquete. Hubiera publicado una foto si hubiera podido.
Thomas O
2

OK, su alcance demuestra que el primer byte que ingresa al PIC es malo, por lo que no es la función de lectura del PIC.

¿Verificó que el tiempo de escritura es correcto en el extremo receptor?

¿Esto falla en los dos modos a continuación?

- Byte mode sequential
- Page mode Sequential

La especificación muestra "El bit más significativo (MSB) 'b7' se envía primero" Esto también es coincidente cuando b7 = 1 que el byte completo se vuelve a leer como FF. Por lo tanto, no se escribe y solo se borra (condición de falla) cuando b7 = 1, o se lee incorrectamente como FF independientemente del contenido anterior. Dado que cada escritura es un borrado amplio de bytes antes de la escritura, ¿podría ser una mala escritura o una mala lectura o la sincronización del primer byte es diferente?

Sugerencia: Verifique la señal PTC durante una escritura / lectura para garantizar el funcionamiento normal. ingrese la descripción de la imagen aquí

Existe la opción de usar un reloj externo para cronometrar la duración de un ciclo E / W usando PTC. ¿Has intentado usar esto?

Tiempo de ciclo tE / W

  • oscilador interno 7ms típ
  • reloj externo 4 ~ 10 ms min ~ max

¿Pasa este criterio?


fuente
1

Parece que podría ser un par de cosas:

  1. ¿Qué más hay en el autobús? ¿Podría haber una disputa de bus con otro dispositivo que se está reteniendo o sin inicializar?
  2. ¿Estás cambiando correctamente la dirección del pin de E / S? Si está funcionando bien en el caso de salida, podría haberse olvidado accidentalmente de cambiar la dirección del pin a la entrada y siempre leerá 0xFF. El pin podría dejarse como una salida que conduce el autobús mientras lee.
  3. ¿Tiene pull-ups internos en el pin en sí y / o en las líneas de E / S? Los microcontroladores generalmente ofrecen un rango de resistencia y no un valor fijo. Es posible que desee deshabilitar los pull-ups en el micro y simplemente usar los discretos en el bus, ya que puede obtener una resistencia de pull-up más precisa de los componentes discretos.
  4. Polaridad del reloj: ¿está seguro de que está midiendo en el borde / fase correcta entre el reloj / datos? Podría estar registrando lo que le parece excelente en el alcance, pero si la fase está fuera de línea, todo su EEPROM verá es 0xFFs (y lo más probable es que devuelva lo mismo, ya que probablemente sea un comando / condición no válida).
Joel B
fuente
1. Solo la EEPROM y MCU. 2. Sí, creo que sí, ya que la EEPROM puede mantener bajo el SDA / SCL. 3. Hay 2.2k 5% pull ups en el tablero adyacente a la EEPROM.
Thomas O
para el n. ° 2, ¿está seguro de que la EEPROM es la que mantiene el bus bajo? ¿La EEPROM tiene alguna condición en la hoja de datos donde devolverá todos los 0xFFs? Vea mis ediciones arriba también.
Joel B
# 4. La EEPROM está "ACEPTANDO" mis solicitudes y funciona con algunas palabras, pero no con todas.
Thomas O
0

Envié esto como un comentario arriba, pero mi confianza en la respuesta ha crecido silenciosamente en los profundos recovecos de mi mente, así que lo estoy promoviendo para una respuesta.

Tengo el presentimiento de que esto es casi seguro que es un error de software de bajo nivel relacionado con la firma de algunas variables. En su código para cada bit, ¿está inadvertidamente extendiendo la señal con una operación de cambio a la derecha? Si es así, su líder finalmente lo dejará con un 0xFF después de 7 operaciones de turno.

Steven aludió a esto en un comentario, pero ¿ha sido testigo de la santidad de sus operaciones de escritura en un osciloscopio, o solo presume que funcionan en función de que la mitad de las lecturas se vean bien? Si no ha intentado mirar la operación de escritura del valor 0xAA, puede ser una buena idea intentarlo.

Si puede proporcionar el código real de su bucle interno y las declaraciones de variables asociadas, podríamos detectar un error.

vicatcu
fuente
Mis escritos son buenos; Puedo ver esto en el alcance. Otra rareza: las direcciones con los principales MSB están bien. ¡Solo los datos causan problemas! Pienso en publicar el código pronto.
Thomas O
1
En apoyo de esta respuesta: si este es el código C, cambie todas las declaraciones 'char' a 'unsigned char' e intente nuevamente.
Wouter van Ooijen