Go Down

Topic: Problema I2C: me lee uno y dos bytes pero no tres. (Read 502 times) previous topic - next topic

Vaque

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:
Code: [Select]

#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.


fm

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

Vaque

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 ;)

Vaque

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)

Code: [Select]

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.

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy