Tengo un comportamiento extraño con la biblioteca Wire de Energia, así que pensé que intentaría hacer i2c yo mismo.
Estoy escribiendo mi propia implementación (bit-bang) si i2c y lo mantengo bastante simple. Por ahora, solo quiero detectar un dispositivo i2c en particular. Aquí está mi algoritmo básico.
Sé que lo anterior puede ser un poco simplificado, pero solo quería poner las cosas en contexto. Tengo problemas con el paso 4 y conozco el momento particular en el que liberar y volver a adquirir el control de la línea SDA durante un Ack.
Entonces, después de que el último bit de lectura/escritura se haya establecido en SDA y el SCL establecido en ALTO, necesito saber cuál es el orden de las operaciones para obtener un Ack del esclavo.
He probado todas las combinaciones que se me ocurren, pero parece que no funciona correctamente. Parece que debería hacer lo siguiente:
setMode(SDA, INPUT); //Release the SDA line to the slave device
digitalWrite(SCL,LOW); //Pulse the SCL line
digitalWrite(SCL,HIGH);
int ack = digitalRead(SDA) == LOW; //Read from the SDA line
setMode(SDA, OUTPUT); //Seize control of the SDA line
La secuencia anterior no parece estar funcionando. Mi analizador digital no reconoce mis comunicaciones como debería.
Cualquier corrección en mis suposiciones o ajustes al código anterior sería de gran ayuda.
Para mayor aclaración:
Estoy usando un entorno de desarrollo llamado 'Energia'. Es una bifurcación de Arduino y se utiliza para 'simplificar' el proceso de programación de los procesadores TI MSP430x. De todos modos, no parece tener ningún concepto de modo 'OpenCollector'.
Es Entrada, Salida o Input_Pullup. Me pregunto si Input_Pullup no es su versión del modo OpenCollector. Lo intentaré... Hay una discusión interesante sobre Input, Output, Input_Pullup aquí:
La mayor parte de su problema probablemente se deba al hecho de que está configurando estas líneas altas en lugar de dejarlas flotar. SDA y SCL aumentan porque hay una resistencia que los sube a +V, no porque estén altos. Mucha gente no se da cuenta de que la línea del reloj también está diseñada para funcionar de esta manera.
Hay algo más en la forma en que describe su lógica que me hace pensar que mientras ve la transición de SCL a bajo como el evento que bloquea los datos, parece pensar que luego regresa a SCL a alto. Te animo a pensar en el evento del reloj más así:
De la forma en que lo estás haciendo, puedes meterte en problemas de la siguiente manera:
¡Sorpresa! Acabas de crear una condición de STOP sin darte cuenta.
Cada vez que se transmite un bit, el escritor activa SDA (o no) inmediatamente después de que SCL baja, y el lector lee el estado de SDA cuando SCL aumenta. (El nivel alto de SCL puede ser retrasado por el esclavo con el alargamiento del reloj; debe esperar a que SCL realmente suba).
Su código debe pulsar SCL durante el tiempo suficiente para que el esclavo tenga suficiente tiempo para establecer el valor (al menos 4,7 µs).
Cambiar SDA al modo de salida podría bajarlo si ese fuera el último valor anterior. Esto no está permitido mientras el SCL está alto (a menos que realmente quiera hacer un inicio repetido).
DoxyLover
DoxyLover
CL.
Curtis