| View previous topic :: View next topic |
| Author |
Message |
andylippitt Site Admin
Joined: 02 Jan 2006 Posts: 155 Location: Denver, CO
|
Posted: Tue May 16, 2006 11:48 pm Post subject: ACK/NAK accessibility |
|
|
I was working with the linux i2c-dev interface to try to implement the checked read/writes and found I couldn't access ACK/NAK bits for anything other than the I2C address byte. It's quite possible that it is accessible someplace and I just haven't been able to find it, but I wonder if ignoring intermediary NAKs might be common in I2C implementations?
If that's the case, perhaps we should change the way the checked write indicates failure. A master could simply perform a checked read on the same register to verify that the data arrived, but I'm sure a less verbose means of verification could be devised if this is a common problem. |
|
| Back to top |
|
 |
mpthompson
Joined: 02 Jan 2006 Posts: 650 Location: San Carlos, CA
|
Posted: Wed May 17, 2006 1:21 am Post subject: |
|
|
Andy, I don't have a lot of knowledge of I2C implementations within operating system environments, but that seems kind of strange that a NAK of a data byte isn't passed back to the calling application. Oh well. That's software for you. Are the other flags passed back?
-Mike |
|
| Back to top |
|
 |
andylippitt Site Admin
Joined: 02 Jan 2006 Posts: 155 Location: Denver, CO
|
Posted: Wed May 17, 2006 2:17 am Post subject: |
|
|
| I guess I'm not worried so much about my particular situation (I've found at least one very platform specific way of doing it), more I'm concerned that if accessibility of these flags isn't universal, perhaps we should change the protocol now rather than later. |
|
| Back to top |
|
 |
ginge Site Admin
Joined: 14 Jan 2006 Posts: 1029 Location: Manchester, UK
|
Posted: Wed May 17, 2006 9:02 am Post subject: |
|
|
I was also looking at this. It seems it might be a problem, as the linux driver hides all of the implementation behind an IOCTL call.
Whilst looking around at the ""I2C style"" implementations, I saw the SMBUS protocol. This would seem to have provisions for a CRC-8 checksum. This would be easy to implement, and make it slightly more universal.
http://www.smbus.org has some useful info.
Barry |
|
| Back to top |
|
 |
andylippitt Site Admin
Joined: 02 Jan 2006 Posts: 155 Location: Denver, CO
|
Posted: Wed May 17, 2006 1:51 pm Post subject: |
|
|
| As far as I can tell it's not even accessible through an ioctl(). My super platform specific way is mmap()ing through /dev/mem to the register ISR indicated in pxa-regs.h. |
|
| Back to top |
|
 |
ginge Site Admin
Joined: 14 Jan 2006 Posts: 1029 Location: Manchester, UK
|
Posted: Wed May 17, 2006 1:58 pm Post subject: |
|
|
yeah, it's definately not possible to get to the lower level implementation, as you say it's behind the i2c-dev driver. I like the mmaping idea though, very hacky
The SMBUS protocol looks easy enough to implement, I found some sample code in the Gumstix Robostix bootloader code.
Barry |
|
| Back to top |
|
 |
mpthompson
Joined: 02 Jan 2006 Posts: 650 Location: San Carlos, CA
|
Posted: Wed May 17, 2006 9:14 pm Post subject: |
|
|
The SMBus looks like a good source for ideas even if the full specification were not implemented by the OpenServo or just some ideas were adapted from SMBus. An application note on implementing an SMBus slave using the AVR TWI hardware can be found below:
http://www.atmel.com/dyn/resources/prod_documents/doc2583.pdf
Some things to note:
The SMBus and I2C have different electrical specifications, but not a difference that I think would matter to the OpenServo.
The SMBus specifies a clock frequency between 10 KHz and 100 KHz and we may want to drive the OpenServo faster. There are some timing requirements that I2C ignores.
The SMBus supports a Packet Error Code (PEC) that is CRC based rather than a simple checksum. The table to support the CRC would be 256 Flash bytes or a non-table version would be a non-trivial amount of code.
The ARP aspects of SMBus may be interresting for OpenServo. It allows devices to be dynamically assigned their address.
As an aside, after reading the following paragraph from the application note I suspect that the checked code won't function on the ATmega with I2C hardware as it did on the ATtiny45 with the USI-based I2C implementation:
| Quote: | When the AVR acts as a slave receiver, one must decide before receiving data whether to ACK or NACK that data. If data is recieved when e.g. a stop or repeated start condition is expected, the ACK has already been sent when the slave has detected the error. Similarly, this makes it impossible for AVR to use ACKs and NACKs to signal PEC errors. The SMBus specification does not require the slave to do this and suggests that verification of PECs can be done in a higher network protocol layer.
|
This should mean that check read/writes won't work on the ATmega OpenServo. Andy, you probably want to verify this as it means we will need to modify the protocol regardless.
-Mike |
|
| Back to top |
|
 |
andylippitt Site Admin
Joined: 02 Jan 2006 Posts: 155 Location: Denver, CO
|
Posted: Wed May 17, 2006 9:20 pm Post subject: |
|
|
| I'll have to double check it with my other bridge but I did seem to be getting ACK regardless of what I was sending in the chksum byte. |
|
| Back to top |
|
 |
andylippitt Site Admin
Joined: 02 Jan 2006 Posts: 155 Location: Denver, CO
|
Posted: Wed May 17, 2006 9:39 pm Post subject: |
|
|
| Confirmed with the PIC bridge. The current servo while correctly checking the checksum and not applying mismatches, fails to NAK a mismatch. |
|
| Back to top |
|
 |
andylippitt Site Admin
Joined: 02 Jan 2006 Posts: 155 Location: Denver, CO
|
Posted: Wed May 17, 2006 10:16 pm Post subject: |
|
|
proposed solution:
We create a REG_CHECKED_TXN_STATUS which will be updated with the results of the comparison. Immediately after a checked write is completed, twi_address (the current register pointer) is updated to point at this status register. In this way a master can immedidately switch to a read operation and read a singly byte which is this register to determine whether or not the write transaction completed.
We need to consider the possibility that the TWI_CMD_CHECKED_TXN byte was missed and that the twi_address pointer is pointed at something random. So what goes in this register? At very least I think there should be two defined values for success/fail that are not the oh so common 0/1.
Thoughts? |
|
| Back to top |
|
 |
andylippitt Site Admin
Joined: 02 Jan 2006 Posts: 155 Location: Denver, CO
|
Posted: Thu May 18, 2006 9:56 pm Post subject: |
|
|
Here's the details of the proposed Checked Write transaction
Start, SlaveAddress+Write, CMD_CHECKED_TXN
Byte Count, Starting Register Address
Data Byte 0
Data Byte n
Checksum Byte
RepeatedStart, Slave Address+Read, Checksum Status, Nak, Stop
*edit: stop/start between last checksum byte and reading checksum status back changed to a repeated start
Last edited by andylippitt on Thu May 18, 2006 11:19 pm; edited 2 times in total |
|
| Back to top |
|
 |
mpthompson
Joined: 02 Jan 2006 Posts: 650 Location: San Carlos, CA
|
Posted: Thu May 18, 2006 10:27 pm Post subject: |
|
|
Andy,
This looks good.
Do you have a proposal for the values of the checksum status? I presume 0x00 for failure and 0x01 for success would be reasonable.
Also, I would suggest eliminating the stop condition after the checksum byte is transferred from the master to the slave. There should just be a start/restart condition with the read taking place to get the checksum status. I think this will make the state machine easier to implement. A stop condition will signal the end of the trasaction and allow a completely new transaction to occur.
-Mike |
|
| Back to top |
|
 |
andylippitt Site Admin
Joined: 02 Jan 2006 Posts: 155 Location: Denver, CO
|
Posted: Thu May 18, 2006 10:45 pm Post subject: |
|
|
| Then we're making another assumption that all the masters can do a repeated start. I don't think the /dev/i2c-x interface Barry and I are using can do it. |
|
| Back to top |
|
 |
andylippitt Site Admin
Joined: 02 Jan 2006 Posts: 155 Location: Denver, CO
|
Posted: Thu May 18, 2006 11:17 pm Post subject: |
|
|
I was wrong, we can do a repstart through it  |
|
| Back to top |
|
 |
andylippitt Site Admin
Joined: 02 Jan 2006 Posts: 155 Location: Denver, CO
|
Posted: Thu May 18, 2006 11:53 pm Post subject: |
|
|
I was looking through the code a bit and think as it is, a repeated start or a stop/start are handled in the same manner. The only state we're trying to maintain across a repstart or a stop/start is the twi_address (register pointer), not any of the other state vars. So setting twi_address to the status register at the end of a checked write should be sufficient and not dependant upon any other state vars.
i think  |
|
| Back to top |
|
 |
|