Pregunta

Estoy tratando de leer/escribir en un FM24CL64-GTR FRAM el chip que se conecta a través de un bus I2C en dirección 0b 1010 011.

Cuando estoy tratando de escribir 3 bytes (direcciones de datos de 2 bytes, + los datos de un byte), me sale un mensaje de kernel ([12406.360000] i2c-adapter i2c-0: sendbytes: NAK bailout.), así como la escritura vuelve != 3.Véase el código de abajo:

#include <linux/i2c-dev.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdint.h>

int file;
char filename[20];
int addr = 0x53; // 0b1010011; /* The I2C address */
uint16_t dataAddr = 0x1234;
uint8_t val = 0x5c;
uint8_t buf[3];

sprintf(filename,"/dev/i2c-%d",0);
if ((file = open(filename,O_RDWR)) < 0)
    exit(1);

if (ioctl(file,I2C_SLAVE,addr) < 0)
    exit(2);

buf[0] = dataAddr >> 8;
buf[1] = dataAddr & 0xff;
buf[2] = val;

if (write(file, buf, 3) != 3)
    exit(3);

...

Sin embargo, cuando escribo de 2 bytes, a continuación, escriba otro byte, no tengo el kernel de error, pero cuando se trata de leer desde el FRAM, siempre vuelvo 0.Aquí está el código para leer el FRAM:

uint8_t val;

if ((file = open(filename,O_RDWR)) < 0)
    exit(1);

if (ioctl(file,I2C_SLAVE,addr) < 0)
    exit(2);

if (write(file, &dataAddr, 2) != 2) {
    exit(3);

if (read(file, &val, 1) != 1) {
    exit(3);

Ninguna de las funciones devuelven un valor de error, y también he probado con:

#include <linux/i2c.h>

struct i2c_rdwr_ioctl_data work_queue;
struct i2c_msg msg[2];
uint8_t ret;

work_queue.nmsgs = 2;
work_queue.msgs = msg;

work_queue.msgs[0].addr = addr;
work_queue.msgs[0].len = 2;
work_queue.msgs[0].flags = 0;
work_queue.msgs[0].buf = &dataAddr;

work_queue.msgs[1].addr = addr;
work_queue.msgs[1].len = 1;
work_queue.msgs[1].flags = I2C_M_RD;
work_queue.msgs[1].buf = &ret;

if (ioctl(file,I2C_RDWR,&work_queue) < 0)
    exit(3);

Que también se realiza correctamente, pero siempre devuelve 0.¿Esto indicaría un problema de hardware, o estoy haciendo algo mal?

Hay FRAM controladores para FM24CL64-GTR más de I2C en Linux, y cuál sería la API de ser?Cualquier enlace que pueda ser útil.

¿Fue útil?

Solución

El NAK fue una gran pista: el pasador WriteProtect fue tirado externamente, y tuvo que ser llevado al suelo, después de que una sola escritura de la dirección seguida por datos en bytes es exitosa (primer segmento de código)

Para la lectura de la dirección puede ser escrita en primer lugar (mediante escritura ()), y luego los datos secuenciales pueden ser leídos a partir de esa dirección.

Otros consejos

No tengo experiencia con ese dispositivo en particular, pero en nuestra experiencia dispositivos I2C muchos tienen "peculiaridades" que requieren un trabajo en torno, por lo general por encima del nivel de controlador.

Nosotros usamos Linux (CELinux) y un controlador de dispositivo I2C con Linux. Sin embargo, nuestro código de la aplicación también tiene un módulo I2C no trivial que contiene todo el trabajo en torno a la inteligencia para hacer frente a todos los diferentes dispositivos que tenemos experiencia.

Además, cuando se trata de cuestiones I2C, a menudo encuentro que necesito para mí volver a familiarizarse con la especificación de fuente:

http://www.nxp.com/acrobat_download/literature/9398 /39340011.pdf

, así como el uso de un osciloscopio decente.

Buena suerte,

Por encima de enlace está muerto, he aquí algunos otros enlaces:

http://www.nxp.com/documents/user_manual/UM10204.pdf y de Wikipedia curso: http://en.wikipedia.org/wiki/I%C2%B2C

Tenga en cuenta que el método que utiliza la struct i2c_rdwr_ioctl_data y el struct i2c_msg (es decir, la última parte de código que has dado) es más eficiente que los demás, ya que con ese método se ejecuta el arranque repetido característica de I2c.

Esto significa evitar un STA-WRITE-STO -> STA-READ-<data>...-STO de transición, debido a que su comunicación se convertirá en STA-WRITE-RS-READ-<data>...STO (RS = arranque repetido).Así, se ahorra redundante STO-STA transitorio.

No es que difiera mucho en el tiempo, pero si no es necesario, ¿por qué perder en ella...

Solo mis 2 ct.

Mejor rgds,

Usted tuvo algunos errores!

La dirección de ic es Ax en hexadecimal, x puede ser cualquier cosa, pero los 4 bits superiores debe ser A=1010 !!!

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top