Laut dem i2c programm mit dem man auf embedded linux den am2321
ausliest, braucht der sensor beim lesen 8 slots:
st_am2321 am2321() {
int fd;
int ret;
int retry_cnt;
unsigned char data[8];
/* open I2C device */
fd = open( I2C_DEVICE, O_RDWR );
if ( fd < 0 ) {
perror( "am2321(1)" );
exit( 1 );
}
/* set address of I2C device in 7 bits */
ret = ioctl( fd, I2C_SLAVE, AM2321_ADDR );
if ( ret < 0 ) {
perror( "am2321(2)" );
exit( 2 );
}
retry_cnt = 0;
retry:
/* wake I2C device up */
write( fd, NULL, 0);
/* write measurement request */
data[0] = 0x03; data[1] = 0x00; data[2] = 0x04;
ret = write( fd, data, 3 );
if ( ret < 0 && retry_cnt++ < 5 ) {
fprintf( stderr, "am2321: retry\n" );
udelay( 1000 );
goto retry;
}
if ( ret < 0 ) {
perror( "am2321(3)" );
exit( 3 );
}
/* wait for having measured */
udelay( 1500 );
/* read measured result */
memset( data, 0x00, 8 );
ret = read( fd, data, 8 );
if ( ret < 0 ) {
perror( "am2321(4)" );
exit( 4 );
}
/* close I2C device */
close( fd );
return __st_am2321( data );
}
Eventuell ist im Am2321 nicht die vollständige i2c state machine
implementiert, und wenn du zyklich zu wenige daten abfragst, kommst du
aus dem tritt mit dem was der sensor an CLK erwartet, und du ihm
mitteilen will?
Auch würde ich keine blinden while schleifen nutzen - ein I2c slave kann
CLK low halten, bzw wenn ein slave ein SCLK verpasst, kann sich der I2c
bus aufhängen (bekanntes problem), daher würde ich wohl immer einen
counter mitlaufen lassen (von oben nach null, geht schneller auf AVR)
und nach jedem byte auf eventuelle timeouts achten...
Wie dem auch sei, im Osci trace fehlt aber von den 2 read bytes jede
Spur - nachdem ich keine hardware i2c im avr genutzt habe (und zu faul
bin, die doku zu lesen), sicher dass man da nicht in den registern
irgendwas von schreibend (und ACK bit lesen) auf lesen (und ACK / NACK
schreiben) umstellen muß?
In meinem Falle hab ich den AM2321 einfach an den AT91SAM9G25 auf einen
I2C Port gehängt, und er lief sofort ohne probleme... Allerdings mit
vorgefertigter Software, da ich faul bin - wozu das Rad neu erfinden :)