Use of both I2C interfaces on R-Pi
Kim Faulkner (84) 30 posts |
Does anyone have any knowledge of whether the OS_IICOp system calls can access both available I2C interfaces on the Raspberry Pi. Is anyone else experimenting with this currently. |
WPB (1391) 352 posts |
The plan was to use the top bits of R1 to specify the bus number, and that appears to be in the documentation now, so I suspect it’s been implemented. Not sure if the RPi HAL does the necessary, though. Hopefully someone with more knowledge will answer you soon. I’m not sure if Tank’s GPIOModule provides additional calls to make things easier or not, either, but it might be worth taking a look. |
Tank (53) 375 posts |
The GPIO module only accesses the I2C bus to check for GPIO extenders. |
Jeffrey Lee (213) 6048 posts |
I’ve just checked the sources, and it looks like the current version of the Pi HAL does only support one I2C bus. |
Kim Faulkner (84) 30 posts |
Thank you Jeffrey, |
Dave Higton (1515) 3526 posts |
The driver chooses the interface that controls the same pins, whether it’s a revision 1 or 2 board. |
Dave Higton (1515) 3526 posts |
That’s true. I did start work on a driver that would permit more than one IIC interface to be used simultaneously, but then USB audio came up and I’ve not touched the IIC driver since. |
Joe (3904) 3 posts |
I am still pretty new to RISC OS. On my RPi 3B, I see that GPIO2 and GPIO3 are labeled for I2C interfacing. I would like to have a BBC Basic program talk to a device that interfaces via I2C. This discussion topic from more than 4 years ago seems to hint that there was no I2C support available for such uses at that time. Have things changed in regard to this? Is there still no way for me to do that? Would I get into trouble if I try to write my own software to manipulate these two pins? Is that even possible? Could it be done from Basic? Are there SWI facilities that I could call on to use this I2C interface? Thanks in advance for any advice you can provide. |
Andrew Conroy (370) 740 posts |
Yes, you can use the I2C bus on GPIOs 2 & 3. I have a number of devices connected including an RTC, temerature sensor and LCD 16×2 display. The SWI you need is OS_IICOp |
Chris Hall (132) 3554 posts |
Could it be done from Basic? Yes. SatNav does use the IIC bus to talk to the RTC chip, example below:
Just an example – it writes 00 to the IIC address (&D0 >> 1) and then reads 16 bytes from the same address. Can’t remember what the ‘&20’ is for. Edit: I think it was an attempt to set the retry bit and thus should be &200000D0/&200000D1 but haven’t tried it. The top 8 bits of the number of transfers to make (at iic%!8 and iic%!20) is the IIC bus number, zero. |
Andrew Conroy (370) 740 posts |
That sets bit 13 of R0 doesn’t it? The docs say that bits 8-28 are reserved, though! |
Joe (3904) 3 posts |
This looks most encouraging although I see that I have a few things to learn about BBC Basic. Your response will light the way. Thank you so much. You have both been a great help indeed. |
Joe (3904) 3 posts |
Things have been going pretty well here. I wanted to operate a camera using BBC BASIC under RISC OS. Since the standard RPI camera has no RISC OS support, I bought an OV7670 (with AL422 FIFO). Conveniently, the OV7670 camera with FIFO operates from 3.3V power so there are no logic level conversion issues. This camera is set up and controlled generally through I2C. When a photo is taken, it is stored into the on-board AL422 FIFO. Then it can be leisurely transferred to the computer from the FIFO for processing. So far, I am just trying to operate the I2C part of the interface so I connected the camera’s SIOD and SIOC signals to pins 3 and 5, respectively, of the RPi 3 B module’s GPIO connector and provided 3.3V power and ground. Starting from the example above provided by Chris Hall, I learned about BBC BASIC’s pointers and indirection operators as well as the OS_IICOp SWI. Then I started trying to write some routines to perform simple reading and writing operations with the registers in the camera via I2C. By the way, the camera’s write and read I2C addresses are &42 and &43. There are many registers in the camera which are numbered from &00 up to &C9. (Some in that range are reserved but most have valid functions.) Writing a data byte into a register consists of sending a Start bit, the camera’s I2C write address, a register number, the data byte to be written into the register, and a Stop bit. (I suspect that sending multiple data bytes would result in them being stored in successive registers after the selected one but I am starting simple with sending just a single data byte for now.) Reading a data byte from a register consists of sending a Start bit, the camera’s I2C write address, a register number, a Stop bit, a Start bit (perhaps some question about this), the camera’s I2C read address, and then reading a data byte from the selected register in the camera, followed by sending a Stop bit. (As before, reading multiple data bytes results in them coming from successive registers and I have actually done that, but again I am staying simple for now and reading only one data byte.) I have managed to get the following two routines operating well and I could continue with just using them: REM Routine to write a data byte to a specified register in the camera. REM Routine to read and return a data byte from a specified register in the camera. However, you will note above that I am invoking the OS_IICOp SWI twice in the camera reading function, once to write the selected register number to the camera and a second time to read the data byte back from the camera. My understanding is that these two operations (a write followed by a read) should be possible using a single call to the OS_IICOp SWI as in the following version of the camera read routine: REM Routine to read and return a data byte from a specified register in the camera. However, this causes the camera to not send an acknowledgement in the statement that invokes the SWI. If I add the NoStart bit by updating the appropriate statement thusly: iic%!12 = CamReadAddr% OR &80000000Then it does not elicit the error message but the function always returns &80 from any register that I try to read in the camera. As a further experiment, I tried to use the deprecated IIC_Control SWI with the following version of the FNReadCam() function: DEF FNReadCam(reg%) This routine seems to work correctly. Of course, I know that we are directed to replace the use of IIC_Control with OS_IICOp. I still feel that I must be missing something related to using OS_IICOp that should allow it to work with a single call that both writes the register selection to the camera and then reads back the current contents of that register. I would appreciate any advice that you have. P.S. – I reviewed the example posted by Chris Hall one more time and noted that mysterious &20 that was present but left people wondering about its purpose. It occurred to me that this might be an important clue as to what should be done. So I tried testing the version of the camera read routine that uses a single OS_IICOp operation with that &20 mixed in at the same positions as in the example. I also tried it both with and without the &80000000 NoStart bit. The presence or absence of the &20 made no difference in the outcome of any of these tests. |