Offline
Newbie
Karma: 0
Posts: 22
|
 |
« on: December 15, 2012, 03:33:08 pm » |
Hi, the last release of the Wire library has added support for an extra parameter to the Wire.endTransmission and Wire.requestFrom, to specify if a STOP should be sent or not. Nevertheless, it seems it is not working for Due. I have inspected the source code for the two aforementioned methods and they ignore the boolean parameter altogether. I have also inspected the SCL and SDA lines with an oscilloscope and I could clearly see the STOP condition being sent.
Am I missing something? or is this not supported on Due yet?
Best regards, Dan.
P.S. See the attached files.
|
|
|
|
|
Logged
|
|
|
|
|
USA
Offline
Newbie
Karma: 0
Posts: 40
|
 |
« Reply #1 on: December 21, 2012, 08:57:22 am » |
Dan,
I'm about to start an I2C project that may require I2C repeated starts.
Have you learned anything about this issue?
-Chris
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 22
|
 |
« Reply #2 on: December 21, 2012, 09:15:35 am » |
Hello, what board are you going to use ? What are the specific I2C transactions that you'll need? With the Due board, I was able to read/write from/to an internal register of a I2C slave device (MLX90614), using the API in the libsam library. You can find the source in arduino-1.5.1r2\hardware\arduino\sam\system\libsam\source. Look for twi.c and twi.h The functions of interest are void TWI_StartRead and void TWI_StartWrite. They both have a parameter called uint32_t iaddress where you can put the internal address/register you want to access. If you specify it, then the controller will automatically send a REPEATED START condition after writing the address of the slave device and of the internal register on the bus and before reading/writing the data bytes. Best regards, Dan. Dan,
I'm about to start an I2C project that may require I2C repeated starts.
Have you learned anything about this issue?
-Chris
|
|
|
|
|
Logged
|
|
|
|
|
USA
Offline
Newbie
Karma: 0
Posts: 40
|
 |
« Reply #3 on: December 21, 2012, 09:43:43 am » |
Hi Dan,
On the Due.
I have some pcb's with both a PCA9539 (from NXP) and LTC2489 (Linear Tech), perhaps others.
Protocols:
LTC2489_I2C.png (12kB) PCA9539_I2C.png (22kB)
There's a bit of history with these boards (struggling to get other external uC's to issue an I2C repeated start without stop), so your post caught my attention.
I appreciate the pointers, and any other suggestions you may have.
Regards,
Chris
|
|
|
|
« Last Edit: February 04, 2013, 04:50:17 pm by chriskner »
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 22
|
 |
« Reply #4 on: December 21, 2012, 12:35:49 pm » |
Hello, I had a quick look over the LTC2489's specs and I think it would be very easy to interface it with the Due board. - You WRITE to the device's input register to select the input channels for the next selection. Input register is 8bit long.
- You READ from the device's output register the value of the last conversion. The output register is 24bit long
- The device starts a new conversion after the output register is READ and the master has generated a STOP CONDITION
- If you want to select a different channel and read the previously converted value, in a single transaction, then you use a REPEATED START condition
Check out the attachment. I'll have a look to the PCA9539, later this evening.
|
|
|
|
|
Logged
|
|
|
|
|
USA
Offline
Newbie
Karma: 0
Posts: 40
|
 |
« Reply #5 on: December 23, 2012, 06:21:36 pm » |
Thanks Dan,
I'm on the road right now. I'll check it all out in one week.
-Chris
|
|
|
|
|
Logged
|
|
|
|
|
USA
Offline
Newbie
Karma: 0
Posts: 40
|
 |
« Reply #6 on: January 24, 2013, 09:58:03 am » |
Hi Dan, (DUE, 1.5.1r2)
I also have confirmed that a 'Stop' is always sent regardless of including true/false in endTransmission().
I can supply logic traces if anyone's interested.
Now, perhaps this neophyte could have a bit more help?
How does one invoke 'TWI_Startread' in code? Specifically, what would I include for the first parameter: TWI_StartRead(???, i2c_addr, i2c_register, 8 );
Thanks,
Chris
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 22
|
 |
« Reply #7 on: January 24, 2013, 10:59:24 am » |
The first param is a pointer to a Twi structure denoting the I2C bus that you want to use. In the case of arduino due there are 2 I2C buses, therefore you can use WIRE_INTERFACE_ID or WIRE1_INTERFACE_ID. Both of them are defined in hardware\arduino\sam\variants\arduino_due_x\variant.h
|
|
|
|
« Last Edit: January 24, 2013, 11:01:26 am by cdan »
|
Logged
|
|
|
|
|
USA
Offline
Newbie
Karma: 0
Posts: 40
|
 |
« Reply #8 on: January 24, 2013, 11:42:44 am » |
Dan, Please forgive my ignorance on this matter. However: TWI_StartRead(WIRE_INTERFACE_ID, i2c_addr, i2c_register, 8 ); results in: error: invalid conversion from 'int' to 'Twi*' error: initializing argument 1 of 'void TWI_StartRead(Twi*, uint8_t, uint32_t, uint8_t)'I have this uncomfortable feeling of not knowing the right questions to ask, and where to look to figure things out... Regards, Chris
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 22
|
 |
« Reply #9 on: January 24, 2013, 01:18:34 pm » |
It's my mistake. Use WIRE_INTERFACE or WIRE1_INTERFACE You can find both defined in variant.h
|
|
|
|
|
Logged
|
|
|
|
|
USA
Offline
Newbie
Karma: 0
Posts: 40
|
 |
« Reply #10 on: January 24, 2013, 01:49:55 pm » |
Thanks Dan... Onward!
|
|
|
|
|
Logged
|
|
|
|
|
USA
Offline
Newbie
Karma: 0
Posts: 40
|
 |
« Reply #11 on: January 29, 2013, 02:16:27 pm » |
After some turmoil, I have retreated to the state where only 1 byte at a time may be read from a slave. Figure 34-20. " TWI Read Operation with Multiple Data Bytes with or without Internal Address" in the SAM3X8E datasheet seems out of reach. (Page 729, of the 28-May-12 revision) I have found that a NACK is always generated after the 1st read by some unidentified mechanism, making multiple byte reads impossible. For the desired protocol, see Figure 34-10. " Master Read with Multiple Data Bytes" (Page 721). It seems that the Arduino community has been driving in circles over this problem for years. For a sample: http://code.google.com/p/arduino/issues/detail?id=28I haven't been able to find a way to specify how the master (the Due) should respond for multiple sequential reads. I have resorted to supporting only 1 byte reads for the foreseeable future. This, of course, is a hack in my 50+ device I2C network. Any ideas/suggestions? TWI_StartRead(WIRE_INTERFACE, i2c_addr, i2c_register, 1); Embiic_WaitByteXferComplete(); for(i = 0; i < numOfBytes; i++) { //Need to set STOP condition WHILE reading the last byte... if ((i+1) == numOfBytes) { TWI_SendSTOPCondition(WIRE_INTERFACE); //DBG_PRINT("Sending last-byte STOP."); } Embiic_WaitByteReceived(); //DBG_PRINTLN("Read_I2C_Values: Byte Ready"); params[i] = TWI_ReadByte(WIRE_INTERFACE); } if (Embiic_WaitByteXferComplete()) { DBG_PRINTLN("Read_I2C_Values: Transaction completed successfully."); } else { DBG_PRINTLN("Read_I2C_Values: Transaction nottacompleted."); }
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 22
|
 |
« Reply #12 on: January 30, 2013, 02:32:36 am » |
Can you please post a screenshot of the output from running your algorithm with numOfBytes=2 ?
|
|
|
|
|
Logged
|
|
|
|
|
USA
Offline
Newbie
Karma: 0
Posts: 40
|
 |
« Reply #13 on: January 30, 2013, 08:50:05 am » |
The traces above are the same with any num Of Bytes value. That one was generated with nOB=3. However, I get the same result for nOB= 1. Of course, as you know, we expect the NACK on only the last read, and ACK's on all 1..n-1 reads. The way that it is now, all reads beyond the first byte result in a timeout. (code below) I suspect that there's a state machine somewhere (that I can't find), that I would like to look over. I did find this: /arduino-1.5.1r2/hardware/arduino/sam/system/CMSIS/Device/ATMEL/sam3xa/html/TWI0.htmlwhich lists the TW registers in a nice format. However, there isn't much to play with there. boolean Embiic_WaitByteReceived() { unsigned long start, now; start = millis(); while (!TWI_ByteReceived(WIRE_INTERFACE)) { //if (WIRE_INTERFACE->TWI_SR & TWI_SR_NACK) { // Failed ACK // DBG_PRINTLN("Embiic_WaitByteReceived: Failed ACK."); // Error_Code = 9010; // return false; //} now = millis(); if (now < start) { // cheap! handle overflow, at at the expense of a longer timeout start = now; now++; } else { now = now - start; } if (now > I2C_READ_TIMEOUTmS){ DBG_PRINTLN("Embiic_WaitByteReceived: Timeout."); Error_Code = 9011; return false; } } return true; }
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 22
|
 |
« Reply #14 on: January 30, 2013, 09:10:38 am » |
I have just order a Bus Pirate from a retailer in RO. I'll have it tomorrow and I'll give it a try too. I have to look closer to this issue.
|
|
|
|
|
Logged
|
|
|
|
|
|