2019-02-01 06:24 PM
Hi there,
I'm trying to implement a multi-master I2C network, where there are several nodes (around 6), any of which can send a message to any other. In other words, all nodes usually acting as slaves, waiting for incoming I2C messages. When any node decides it wants to send a message, it momentarily becomes a master and sends its message to the slave it wants to. (Sort of like Ethernet: any node can initiate a transmission to any other node.) The sender is always the master, and the receiver is always the slave.
The I2C standard supports such multi-master configurations, and I wrote software for the ATmega several years ago that does this. I've decided to port it to the STM32, and though there are 20+ I2C examples in the HAL driver library, none of them demonstrate what I'm trying to do. All the examples require you to compile the code in either master mode or slave mode; none show both modes in use on the same CPU.
Are there any (simple) examples of how to do this with STM32's HAL library?
Regards,
-Jeremy
2019-02-01 07:14 PM
Most examples are based on existing board such as Nucleo, Discovery and Eval boards. Multimaster would require multiple boards, so I2C Multimaster mayve quite uncommon, so there might not be Cube examples. Last time of such multistandard was in 1999 with so called "Access Bus" which was quickly crushed by emerging USB Standard. In automotive, CAN interface is one physical layer to connect multiple chips, or Daisy Chain SPI and variations.
2019-02-01 08:14 PM
Thanks for the response!
I don't think it's a hardware issue - it seems that the Nucleo examples are already assuming you have two boards, since they tell you to compile once as master and once as slave. I was just hoping they had an example of doing both at (roughly) the same time.
It's true that what I'm doing isn't particularly common, but it's worked really well for the systems I've built. I2C is a lot more attractive than USB because it runs on much lower-end hardware, e.g. 8-bit micros, which is where I started. I've never played with CAN, but maybe it's time!
Looking at the STM32F0 libraries more carefully, I see the I2C HAL driver has functions called HAL_I2C_EnableListen_IT and HAL_I2C_DisableListen_IT - I think these probably are what I was looking for. I am hopeful that what I want to do can be achieved by setting up the STM32 as a slave; then, when the software decides it wants to send a packet, calling DisableListen, then MasterTransmit, then EnableListen. I'll give it a try and report back in case someone else is searching for the same answer!
2020-09-09 06:29 AM
Hi, sounds interesting - even after two years... Did you succeed porting your Atmel-code?
2020-09-09 09:59 AM
Ha ha, I forgot completely about this thread. Yes, I was able to get it to work, and we have a very happy 14-node network in our rocket ship treehouse (http://rocket.jonh.net) based on a multimaster I2C bus using the PCA9600 to run the bus at higher voltage and across long wires with higher capacitance. The final system is a mix of newer boards based on the STM32 and some older boards based on the atmega328.
It turned out that the STM32 HAL library does not support multimaster mode, but using the LL library it was not too hard. Here is the code, if you're interested:
https://github.com/jelson/rulos/blob/master/src/lib/chip/arm/stm32/periph/twi/twi.c
It has ifdefs for "I2C V1" (which is the V1 TWI peripheral found on the older chips like the STM32F1) and "I2C V2" which is for the V2 peripheral found in the STM32F0 and F3.
In the 2 years since this thread I have become quite a fan of the STM32 chips and use them in all my projects now.