I2C on BeagleBoard
Andrew Conroy (370) 740 posts |
I’m considering getting a BeagleBoard xM when they’re available. Is it possible to access the I2C interface on the BeagleBoard expansion header from RISC OS? I was considering adding something like the TinCan Trainer board which exposes the I2C and does level translation for you. I’ve currently got a few sensors running off I2C on my RPC and it would be fun to move them onto the BB if possible. If it’s not currently possible, is there a chance it may become possible later on if I smiled nicely enough at someone? :-) |
Jeffrey Lee (213) 6048 posts |
Yes and no :) The driver in the HAL supports all of the I2C interfaces, but RISC OS is blissfully unaware of anything other than the first bus. In my mind the main problem with adding support for multiple IIC buses is working out how to expand the current API - I don’t think the OS_IICOp SWI leaves much room for us to specify the bus number. So if you’ve got any ideas on how to expand the API (in a backwards-compatible manner!) then I’m open to suggestion :) Either adding new flags to the SWI (e.g. I think it may be possible to add the bus number to the register that contains the target IIC address), or maybe add an entirely new SWI interface (maybe with support for background transfers instead of it being a blocking call?), etc. |
Jan Rinze (235) 368 posts |
yet again a problem about expanding current APIs. We really need some overall strategy for new features and backward compatibility. Until that has been resolved many things will remain on the drawing board and will never see the light of day. |
Jeffrey Lee (213) 6048 posts |
Yes, it would be useful to have some kind of procedure to go through when we find that an API needs extending. Unfortunately, I think any such procedure would largely depend on whether ROOL have enough time to provide their input. |
Jan Rinze (235) 368 posts |
May it is just me but i expect ROOL to have thought that over before they even started with enabling others to contribute. If not then what is their input in regard to the future of RO5? (i might sound a bit harsh here though) Vision, roadmap and room for future expansion of functionality are pillars for a healthy future of RO5 and on i.m.h.o. |
Dave Higton (281) 668 posts |
On the topic of IIC, I have been aware for some years that the IIC module doesn’t provide a full enough set of features. For example, different devices require different sizes of address field (a 64 kiB memory with programmable reset polarity requires a 17 bit address, which is padded out to 24 bits). Perhaps the simple solution is to add extra SWIs to address different IIC busses and specify different address field lengths. I see no reason why they shouldn’t coexist. Programmes that are aware of the new SWIS can (and should) use them; programmes that are only aware of the original SWIs can continue to use them, to communicate only with the devices that ever used to be in RISC OS machines. |
Jeffrey Lee (213) 6048 posts |
Are you sure you’re not confusing the IIC device address with the data which is being sent to the device? IIRC the maximum device address length supported by the protocol is only around 11 bits, with most devices/busses only supporting/using 7 bit addresses. EPROMs and other memories typically only occupy one address on the IIC bus; in order to address the individual bytes of memory in the EPROM you actually send a packet of data to the device containing the address you want to access. |
Dave Higton (281) 668 posts |
It has a 7 bit device address, and then a 17 (padded to 24) bit address within the device. |
Jeffrey Lee (213) 6048 posts |
Yes, and there’s nothing stopping you from talking to such a device using the current API. To read data you’d perform two IIC ops – a write of 3 bytes to set the address, then a read of N bytes to read N sequential bytes of data from memory. To write data you perform one IIC op – a write of 3 bytes + N bytes, where the data pointer you pass to the IIC SWI would have to point to a buffer containing both the 3 byte address and the N bytes of data. The HAL API is a bit nicer than this, since it allows you to specify a list of transfers to perform. It could be good to expose that API, as it would allow you to write data without having to stick the addres + data in the same buffer. AFAIK this isn’t much different to the IIC API offered by any other OS - it’s still down to the user to know how to correctly communicate with each attached device (i.e. how to tell an EPROM what address you want to access). But if people want a new API designed to simplify communication with generic EPROM-like devices then I don’t see any reason why we can’t add one. |
Andrew Conroy (370) 740 posts |
The SWI currently has:
would it be possible to add: R3=I2C bus with bus 0 being the ‘default’ one which RISC OS can currently access. That way existing code which doesn’t supply anything in R3 would still work on the default bus, but subsequent code could specify buses 1 or 2 (or whatever) for additional I2C buses. |
Tank (53) 375 posts |
As Jeffrey mentions, the I2C spec is only 7 bit or 10 bit plus R/W, so the R0 register could be split. If the bottom 24 bits are kept for address+R/W pointer (still allowing for further expansion) and the top 8 bits can then be used for specifying a bus number (up-to 256 or less if a non blocking flag is needed). All current calls would work addressing bus 0 as they do now. The Paradise joystick module uses a similar technique to access the second PSX joystick on their interface/module. Andrew, how do you determine the contents of R3 are a valid address and not some random data. |
Dave Higton (281) 668 posts |
If you do that, you have an IIC Stop condition between the addressing and the data transfer. Have a look at a device data sheet. There isn’t a Stop condition – just another Start condition. If it works, it’s luck; it’s different from the IIC specification. |
Andrew Conroy (370) 740 posts |
Oops, sorry, showing my BASIC programming heritage where missing registers are passed in as zero. Obviously this wouldn’t work outside BASIC. Splitting R0 to have some high bits showing which I2C bus is in use would seem to make more sense, yes. |
Jeffrey Lee (213) 6048 posts |
There is a way around that, but I’m not sure if it’s been officially documented! Under RISC OS 5, all the IIC_Control SWI does is call a new SWI, OS_IICOp. And OS_IICOp provides a more powerful interface that’s much closer to the one the HAL supports (although it still doesn’t allow specification of the bus number): ; in: R0 -> array of transfer descriptors ; R1 = number of transfers ; ; out: transfer descriptors may be updated (beware) ; ; Transfer descriptor is 3 words: ; word 0 = device address (+direction) ; (bit 29 signifies retry for response) ; (bit 30 signifies checksum read only - ie fill in word 1 with ; sum of bytes read) ; (bit 31 signifies continued transfer - ie no start or address) ; word 1 -> data block ; word 2 = length of data block So you can use bit 31 to send back-to-back transfers without sending a start bit/address. It also leaves bits 28-8 free for expansion (although we’d probably want to keep bits 15-8 free to cope with longer IIC addresses) And also I should clarify that IIC_Control does still use the old API - it just pushes R0-R2 onto the stack to create a transfer descriptor and passes that to OS_IICOp. It also doesn’t do any parameter checking, so it will support whatever changes we make to the format of word 0. |
Jan Rinze (235) 368 posts |
Jeffrey, I like the idea of using bitfields for expansion. To allow developers to think about such ideas it would be interesting to ‘reserve’ the ‘unused bitfields’ in documentation regarding parameters passed to SWIs. Next to that we need ROOL to support this idea and decide on the specific usage of those fields so that there can be made room for future expansion of current SWIs without risking backward compatibility issues. Bitfields can be easily used to signify the use of extra registers too. For example if there would be a bit in R0 passed that is 0 per default then setting it to 1 would signify the use of extra registers passed to the SWI. I have always wondered why SWIs aren’t abiding the ABI for calls. It would be quite easy to see them as calls to a function without the need to know the function address. (can’t change the way it works now i know.. just some thoughts.) |
Steve Revill (20) 1361 posts |
I think the thing to do once you’ve kicked an idea around in the forums is to email code@riscosopen.org if you have an API change suggestion – that’s more likely to get our attention than discussions on the forum. We’ll try to give it due consideration and give you a meaningful response in good time. |