Hi all, Regarding to I2C API usage, I have a few questions:
(1) My tinyos application needs to periodically keep reading sensor information through I2C interface. What is the best practice to use I2CResource.request() and call I2CResource.release()? One way is when application is booted, call I2CResource.request() to obtain I2C resource. After that, just call I2CPacket.write and I2CPacket.read to read from I2C. Another way is: in the beginning of every reading cycle, call I2CResource.request(); and after reading finishes, call I2CResource.release(). I didn't dip into the driver code, but what I guess is that request() and release() are used to turn on and off software flags, which is useful in case of multiple accesses of I2C interface. In my case, the I2C calls are in sequential. There is no competition. So my guess method one should be better in terms of fewer function callls. (2) in order to read through I2C, if I call APIs like call I2CPacket.write(I2C_START|I2C_STOP, deviceAddr, 1, registerAddr) then call I2CPacket.read(I2C_START|I2C_STOP, deviceAddr, NumberOfBytes2Read, &readData); Sometimes, the I2CPacket.readDone() is never triggered; so my app hangs; because I wait for that event to happen. Is there a bug in driver? The point is even if I used the API wrongly, it should give me callback. So according to the following post from Eric, the right call order should be call I2CPacket.write(I2C_START, deviceAddr, 1, registerAddr) then call I2CPacket.read(I2C_START|I2C_STOP, deviceAddr, NumberOfBytes2Read, &readData); Somehow, the following seems also working. call I2CPacket.write(I2C_START, deviceAddr, 1, registerAddr) then call I2CPacket.read(I2C_STOP, deviceAddr, NumberOfBytes2Read, &readData); (3) Is it safe to immediately call I2CPacket.write/read after I2CPacket.write/read, i.e., put I2CPacket.write/read in I2CPacket.writeDone or I2CPacket.readDone? Thx for your inputs. ________________________________________ From: Eric Decker [[email protected]] Sent: Saturday, 2 February, 2013 9:48:58 AM To: He Dajiang (I2R) Cc: [email protected] Subject: Re: [Tinyos-help] I2C read and write API The I2C protocol itself doesn't define the concept of a register. The addr field is the device address (7 bit, right aligned) which is defined by the i2c protocol. Many many devices however structure their interface along register lines and define their device protocol as having a register field. But that is device specific. It isn't part of I2C per sey. I've rewritten the msp430 i2c driver for the x5 family and one of the things I've added is a I2CReg interface that does know about registers. The rewrite is a superset and implements what has already been defined. This rewrite is in the tos/chips/msp430/x5xxx/usci-v2 directory on the tp-master branch of the tp-freeforall/prod repository on github. On Fri, Feb 1, 2013 at 7:39 AM, He Dajiang (I2R) <[email protected]<mailto:[email protected]>> wrote: Hi list, Sorry if this question has been asked. I am wondering why in the I2C interface functions read and write, there is no field for register address. async command error_t read(i2c_flags_t flags, uint16_t addr, uint8_t length, u int8_t* data); async command error_t write(i2c_flags_t flags, uint16_t addr, uint8_t length, uint8_t* data); I guess the addr field is for device address, isn't it? On the TI msp430, the data path is double buffered while the control path (start/stop) isn't so getting everything to work right especially with interrupts is problematic. It is one of the reasons I rewrote the driver for the x5 parts. You want to do something like: call I2CPacket.write(I2C_START, deviceAddr, 1,registerAddr) then call I2CPacket.write(I2C_START|I2C_STOP, deviceAddr, NumberOfBytes2Read, &readData); The above sequence is called a restart and doesn't let go of the bus so the master won't lose arbitration. You are probably in a single master system (the 1611 or whatever cpu you are using) so probably doesn't matter. For reading data from a register, my function calls like: call I2CPacket.write(I2C_START | I2C_STOP, deviceAddress, 1, registerAddr) if sucessful, call I2CPacket.read(I2C_START | I2C_STOP, deviceAddress, NumberOfBytes2Read + 1, &readData); Why +1? Device addr doesn't count as part of the data payload. By using the above method, seemingly I am able to read values through I2C. How about write? Anyone can shed some light on this issue. For writing you have a buffer with your data in it. And at the very front of the buffer y0]ou have space for the register address. buff[0] = registerAddr; buff[1..len-1] = data to send. call I2CPacket.write(I2C_START | I2C_STOP, deviceAddr, len, buff); Thx. Institute for Infocomm Research disclaimer: "This email is confidential and may be privileged. If you are not the intended recipient, please delete it and notify us immediately. Please do not copy or use it for any purpose, or disclose its contents to any other person. Thank you." _______________________________________________ Tinyos-help mailing list [email protected]<mailto:[email protected]> https://www.millennium.berkeley.edu/cgi-bin/mailman/listinfo/tinyos-help -- Eric B. Decker Senior (over 50 :-) Researcher Institute for Infocomm Research disclaimer: "This email is confidential and may be privileged. If you are not the intended recipient, please delete it and notify us immediately. Please do not copy or use it for any purpose, or disclose its contents to any other person. Thank you." _______________________________________________ Tinyos-help mailing list [email protected] https://www.millennium.berkeley.edu/cgi-bin/mailman/listinfo/tinyos-help
