toggle quoted messageShow quoted text
Yes, that is what I though, the layout of the board is a bit strange.
Thank you very much for your input! The idea of having a dedicated sensor thread has also occurred to me. We are using the Thunderboards for teaching a university course in embedded systems programming. I think this might actually be a nice example
to introduce the idea of threads and mutual exclusion.
Thank you again for your help!
I just looked at the wiring for the Thunderboard Sense 2. It is crazy….
Normally all of the I2C devices on a board are wired to a single I2C Bus. But the designers of the Thunderboard decided to connect to three different I2C busses, even though the chip only has two controllers. Hence you have ended up in the strange situation
where you need to multiplex a single controller across at least 2 sets of pins. To be honest I have never seen this before, but it is what it is…
I would start out by ignoring the hall sensor, then routing I2C_1 to PC4-5, and I2C_2 to PB6-7 and get all of your software running. Then go back and think about hacking the driver so you can flip I2C_2 between PB6-7 and PB8-9. Of course if you also have external
I2C sensors on other pins life is even more difficult.
A better solution than hacking the driver I would be starting a sensor task that processes a work que. The work queue would contain requests for I2C read/write from the multiplexed sensors. The sensor task would get a request, reconfigure the mux (if necessary),
complete the request and return the result, then work on the next request. Effectively the serial processing nature of the sensor task becomes your mutex, without the bother of trying to modify the Zephyr kernel. Since the hall and gas sensors are pretty slow,
the overhead of the sensor task will be negligible.
Thank you for your reply! Indeed, after rereading the data sheet I also realised my confusion. The problem with the rerouting however persists. The chip allows to reroute the SDA and SLC signal from either I2C peripheral dynamically during runtime by changing
the location bitfields in the respective I2Cn_ROUTELOC0 registers.
This means, that for example on the Thunderboard 2 Sense development board, different sensors are connected to the same I2C peripheral, but through different pins. So I need to change the ROUTELOC0 register every time before issuing a call to Zephyr’s i2c driver.
I was just curious if that is something common, that I’m unaware of, and if there would be a general (i.e. Zephyr idiomatic) way of doing that. I have read through the i2c driver implementation for the Gecko chip family now, and it seems, that that is not
really taken care of. So I guess one could do this either within the application code, or do it in the respective sensor driver. Ultimately, I guess it would be nice to change the i2c driver implementation to take care of this, since there probably needs to
be some form of mutex between rerouting the i2c peripheral, issuing the call, and routing it back to where it was before, and that mutex is per peripheral.
Thank you all very much for your replies! They really helped.
I have yet to see a SOC that allows connecting one internal I2C controller to two sets of external pins at one time. Although theoretically possible it would be an unusual feature, and of very limited use. The usual solution is to have multiple I2C controllers
in the SOC, and allow routing of each controller to various pins on the SOC package.
I just had a quick read through the Mighty Gecko datasheet. The processor has two I2C controllers, which in Zephyr parlance will be I2C_1 and I2C_2. You need to define both controllers and their physical pins in your device tree overlay. Then your software
must open both controllers, and you must communicate with your peripherals through the correct I2C controller.
I assume that your MCU allows alternative SDA/SCL configurations but not simultaneous, i.e. you can decide on which SDA/SCL pair of pins you can have I2C bus, but not on all pairs at the same time.
Thanks for your reply! The specific chip on that board has two I2C peripherals. However, all the sensors I’m interested in are on one (i2c_1). The chip allows routing the same I2C peripheral to multiple pins, i.e. the same SDA and SCL line is available on different
pins. Every set of (SDA, SCL) pins still needs to be configured though. For the two pins that are listed in the device tree (the one in the board.dts file just uses those that are connected to one specific sensor), this happens in the init function of the
i2c driver. The other pins (which are theoretically also connected to that I2C peripheral) are thus never configured, therefore any sensors connected to them won’t work. I could probably configure those pins manually, but then that solution doesn’t seem very
nice (i.e. I would need to adjust the device tree according to which set of sensors I want to reach for each application). So what I’m trying to achieve is, that whenever I do something like i2c_write(i2c_1_dev, …) this actually happens on all pins, that are
connected to the i2c_1 peripheral.
I’m asking if anyone maybe had a similar situation (it is the first time for me that a microcontroller allows routing the same signal to multiple pins), and how to do this so that it plays nicely with the zephyr API.
Thank’s for your input again!
It´s a bit unclear what you´re asking.
Most MCUs require you to define what pins to use for a specific peripheral, in your case i2c_1.
If you have several I2C peripherals(in the MCU) you may connect sensors/other-chips to whatever pins are configurable to that peripheral.
Please elaborate what the problem is.
Innoware Development AB