Problema I2C: me lee uno y dos bytes pero no tres.

Hola;
Soy nuevo por aquí. Estoy trabajando con un arduino UNO como sensor y un TS7500 como maestro en un protocolo I2C.

Tengo el siguiente código para el arduino:

#include <Wire.h>

uint8_t SensorVersion[2]  =    "V";
uint8_t SensorName[4]     =    {0x40, 0x3A, 0x09, 0x12};
uint8_t SensorType[4]     =    {0x32, 0x26, 0x11, 0x33};


byte x[4]={0,0,0,0};//contiene el valor llegado


void setup() {
    Serial.begin(9600);
    Serial.println("Inicio");
    Wire.begin(1);
    Wire.onReceive(receiveEvent); //rutinas para cuando llegue algo
    Wire.onRequest(requestEvent);
}

void loop() {
     
}

void receiveEvent(int len) {
     for (int i=0; i<len; i++)
     {
          if (i<5)
          {
               x[i] = Wire.read();
          }
          else
          {
               Wire.read();
          }
     }
}

void requestEvent() {
    
    Wire.write(SensorName,3);
  
}

El TS7500 lleva un debian empotrado; quiero saber si veis algún fallo al código... me da la sensación de que Wire.write tiene un buffer de solo 2 bytes por cada vez.

Un saludo.

Le estas transmitiendo 3 bytes en vez de 4 SensorName, tiene 4 bytes no 3 como envias con el write. Tal vez sea eso?

Con 4 tampoco funciona. Solo funciona con 2 y con 1.
A ver si mañana limpio un poco el código del TS y lo cuelgo aquí.

Gracias :wink:

Lo prometido es deuda; éste es el código que utilizo como maestro con el debian (lleva un procesador arm9-> registros utilizados desde la página 145 de éste link, donde pone TWI: https://www.embeddedarm.com/documentation/third-party/ECONA-CNS21XX-HRM-v.1.8.pdf)

void *map_phys(off_t addr,int *fd) { 
  off_t page; 
  unsigned char *start; 

  if (*fd == -1) 			     //si fd no es -1, ya estaba abierto 
    *fd = open("/dev/mem", O_RDWR|O_SYNC);   //apertura en modo escritura y lectura syncrono para que sea efectivo cualquier cambio 
  if (*fd == -1) { 
    perror("open(/dev/mem):"); 	             //no se abrio correctamente 
    return 0; 
  } 
  page = addr & 0xfffff000; 		     //las paginas son multiplos de 0x1000 primera pagina= 0x0000; segunda= 0x1000; tercera=0x3000... 
					     //ubica dispositivo en memoria de tamaño una pagina, lectura y escritura, compartido.	 
  start = mmap(0, getpagesize(), PROT_READ|PROT_WRITE, MAP_SHARED, *fd, page); 
  				             //start empieza en direccion inicial de la pagina 
  if (start == MAP_FAILED) { 
    perror("mmap:");			     //no ubico correctamente 
    return 0; 
  } 
  start = start + (addr & 0xfff);            //star ahora en direccion de la pagina + offset = direccion del registro proyectado 
  return start; 
} 

inline void cavium_enable_TWI() { 
  setbit(&reg[0],31); 		  //activa TWI 
  clrbit(&reg[0],24);             //desactiva TWI data swap: TWI_WR_DAT = PWDATA[31:0] y PRDATA = TWI_RD_DAT[31:0] 
  
} 

inline void cavium_disable_TWI(){ 
  clrbit(&reg[0],31);		 //desactiva TWI 
} 

void init_TWI() { 
  reg = map_phys(0x71000020,&fd); //reg[registrotwi/sizeof(unsigned)] ya puede ser utilizado 
  cavium_enable_TWI(); 
  TWI_clock_frequency(42724);//280448 default 
  reg[0x14/sizeof(unsigned)] = 3; //TWI_ACTDONE_FG y TWI_BUSERR_FG puestos a '0' 
} 
/* void write_TWI_data(unsigned adrs,int len,unsigned data):	   */ 
/* Escribe valor de data de len bytes en esclavo adrs mediante I2C */ 
void write_TWI_data(unsigned adrs,int len,unsigned data) { 
  int limit=10000; //limitamos tiempo espera transmision 

  clrbit(&reg[0],5); 				         // 
  setbit(&reg[0],4); 				         //TWI_TRANSFER_CMD=1='01'=Only-Write Operation 
  reg[0] = (reg[0] & 0xFFFFFFF3) | (((len - 1) & 3)<<2); //TWI_WRDAT_LEN=len 
  reg[0xC/sizeof(unsigned)] = data;			 //TWI_WR_DATA=data 
  reg[0x8/sizeof(unsigned)] = adrs;			 //TWI_SLAVE_ADDR=adrs 
  setbit(&reg[0],6);					 //comienza escritura TWI_RUN_STAR='1' 
 
  printf("Se enviara:%x\n", reg[0xC/sizeof(unsigned)]); 
  while(!getbit(&reg[0x14/sizeof(unsigned)],1) && --limit>0); // espera mientras dure la transferencia fin si TWI_ACTDONE_FG='1' 
  if (limit <=0) { 					      // o si timeout 
	printf("timeout\n"); 
  }      
  if (getbit(&reg[0x14/sizeof(unsigned)],0)) {           //si TWI_BUSERR_FG='1' ha ocurrido un error 
    print_TWI_error(); 
    exit(1); 
  } 
} 


/* void read_TWI_data(unsigned adrs,int len):	      */ 
/* Lee len bytes de adrs mediante I2C y los devuelve. */ 
unsigned read_TWI_data(unsigned adrs,int len) { 
  int limit=10000; //limitamos tiempo espera transmision 
  
  clrbit(&reg[0],5); 					      //				 
  clrbit(&reg[0],4);					      //TWI_TRANSFER_CMD=0='00'=Only-Read Operation 
  reg[0] = (reg[0] & 0xFFFFFFFC) | ((len - 1) & 3);           //TWI_RDDAT_LEN=len 
  setbit(&reg[0],6); 					      //comienza lectura TWI_RUN_STAR='1' 
  while(!getbit(&reg[0x14/sizeof(unsigned)],1) && --limit>0); // espera mientras dure la transferencia fin si TWI_ACTDONE_FG='1' 
  if (limit <=0) {					      // o si timeout	 
	 printf("timeout\n"); 
  } 
  if (getbit(&reg[0x14/sizeof(unsigned)],0)) {		      //si TWI_BUSERR_FG='1' ha ocurrido un error 
    print_TWI_error(); 
    exit(1); 
  } 
  return reg[0x10/sizeof(unsigned)];			      //devuelve TWI_RD_DATA 
}



int main(int argc,char *argv[]) { 
  unsigned lectura; 


  	init_TWI(); 
        write_TWI_data(2,1,9); //debe mandar 0x09 a la direccion esclavo 0x1
	//usleep(100000); 
	lectura=read_TWI_data(2,3); //debe leer 3 bytes del arduino solo consigo que lea uno o dos pero no 3
	printf("lectura despues=0x%X\n",lectura);
	cavium_disable_TWI(); 
  }

Si a alguien se le ocurre algo que lo diga pleaseeeeee. No da error de nada, simplemente lectura se queda con valores indebidos si intento leer más de 2 bytes del arduino (Wire.write(SensorName,>2));

Un saludo.