Richard-Gemmell / teensy4_i2c

An I2C library for the Teensy 4. Provides slave and master mode.
MIT License
92 stars 19 forks source link

Multiple addresses for a single slave #10

Open lbuchman opened 3 years ago

lbuchman commented 3 years ago

It would be really great if Teensy 4.x supports I2C Multiple addresses for a single slave as Teensy 3.x

Richard-Gemmell commented 3 years ago

Please can you tell me what you're trying to achieve. I'd like to understand why your slave needs to respond on multiple addresses.

Do you have some code that shows how you would use this feature? Pseudo code would be fine.

cheers, Richard

lbuchman commented 3 years ago

Thank you for your quick respond. I am RC modeler and I am using Spektrum (https://www.spektrumrc.com/) telemetry. I am working on the telemetry project which will be open source when I am done HW and FW. So, when I fly the plane my transmitter (Spektrum DX6) speaks out loud the plane speed, altitude, the battery used etc. The Spektrum receiver which is installed inside the RC plane and controls all plane's servos and the motor has I2C master port @100Khz which Spektrum calls X-BUS. The telemetry sensors can be connected to that port. Each sensor is I2C slave. I am using GPS, current, battery capacity, altitude, RPM and Airspeed sensors. (https://www.spektrumrc.com/ProdInfo/Files/SPM_Telemetry_Developers_Specs.pdf). I designed a custom board I plug the Teensy 3.x in. The board has required peripheral to all raw sensors above. When I say raw sensors I mean sensors are not X-BUS compatible, like GPS Neo-M8N, or BMP280 etc. So, Teensy talks to the raw sensors and needs to emulate to the Spektrum receiver each sensor as a separate slave device.
On power Up, the Spektrum X-BUS master will scan the X-BUS port for I2C address 0x3 - 0x7C. If there is a reply from the sensor the X-BUS master will query (I2C read) the sensor about every 200 msec and Teensy reply 16 bytes telemetry data. Regards, Leo

Richard-Gemmell commented 3 years ago

Thanks for the explanation. That makes sense to me.

I'll have a look at this next week. I'll add the feature if it's not too complicated.

cheers, Richard

lbuchman commented 3 years ago

Thank you, looking forward for and I can test the feature.

Richard-Gemmell commented 3 years ago

Hi Leo, I've just pushed a new version (1.1.0) that supports address ranges in slave mode. (It also allows a slave to listen to 2 completely separate addresses such as 0x01 and 0x2D.)

There's an example here: https://github.com/Richard-Gemmell/teensy4_i2c/blob/master/examples/raw/raw_multiple_slave_addresses/raw_multiple_slave_addresses.ino

If you prefer to use the Wire API there's an example here: https://github.com/Richard-Gemmell/teensy4_i2c/blob/master/examples/wire/multiple_slave_addresses/multiple_slave_addresses.ino

Please let me know if it does what you want.

cheers, Richard

lbuchman commented 3 years ago

It is perfect, thank you very much Richard. I will test it over the weekend and post the result. Thank you again

lbuchman commented 3 years ago

Hello Richard, the changes to the library work great. I am using Spektrum TM1000 telemetry transmitter a I2C master and everything works as expected. Except one thing, if I activate on Tennsy SPI to BMP280 and/or to NeoM8N GPS I2C stops working. Spektrum TM1000 will stop pooling sensors if there are I2c protocol errors and since I do not have a protocol analyzer I do not know for sure what is going on on the wire. My old TDS 210 shows idle BUS. So, at start TM1000 pulls sensors and T4 replies to every request (single or multiple addresses), until I activate SPI. After that Spektrum TM1000 master stop transmitting. I do not know why SPI communication makes TM1000 so unhappy. Any ideas?

Richard-Gemmell commented 3 years ago

I'm glad to hear the multiple slave addresses is working well.

I haven't tested my library with SPI. There may be a bug in it. Please tell me which I2C and SPI pins you're using and I'll try it out.

I don't know why you're having problems with SPI. Here are some things I'd investigate.

I'll do a bit of testing to find out if I2C and SPI work together at all.

cheers, Richard

lbuchman commented 3 years ago

Thank you Richard for the reply:

  1. I am using standard SPI lib and I do not deal with ISR directly
  2. For I2C I am using Slave (18,19) and for SPI 11,12,13. with with 2 CSs 3 Everything works fine on 3.2 & and 3.6, it is not a wiring issue, I develop PCB for. The PCB was built for teensy 3.2 but it is good enough for 4.x
  3. can can send you the schematic if you want to see it no problem, just provide the link
  4. I got from the office DPO 7254 and I am planning to implement I2C master simulator to mock spektrum 1000, this will help to find what is the problem. But it will take some time.

regards

Leo

Richard-Gemmell commented 3 years ago

Hi Leo,

I'm testing the same sort of setup that you're using. The raw API seems to work Ok with SPI. I've run into a problem with the Wire wrapper though. If I call SPI.begin() before Wire.begin(8) then the Teensy hangs. Initialising them the other way round seems to be Ok though.

Are you using the Wire wrapper? Does the order of initialisation matter in your case?

cheers, Richard

Richard-Gemmell commented 3 years ago

The problem I found isn't a bug. My test harness was blinking the Teensy's LED. That's controlled by pin 13 which is one of the SPI pins. So what I actually demonstrated was that calling pinMode(LED_BUILTIN, OUTPUT); will break the SPI interface.

In short, I'm not seeing the same problem that you are.

If you've still got problems, please send me the simplest possible example that shows the bug.

cheers, Richard

lbuchman commented 3 years ago

Hello Richard, I cannot send you anything yet. Also, I never said there is bug, what I am saying is that something does not work quite right and I am trying to find what is it. My setup would be difficult to replicate since it will require hardware but I think that with the right tooling it would be easy for me to find the smoking gun and help community. I do not have right tooling yet, but I will, soon. So, what I know today: I have

  1. Teensy (3.x, 4.x)
  2. slave Spektrum telemetry enabled RC radio TM1000, TM1000 has pull-ups <Slave i.e. I2C 0>
  3. BMP280 on SPI0-BUS, CS - D14
  4. Neo-M8N GPS on SPI0, CS - d22 I know that Spektrum TM1000 is very touchy, if it detects protocol errors it will stop pulling slaves until rebooted. So, Teensy 3.x works, maybe there are issue, but communication does not fail and I2CBus recovers, I did not investigate because there is no issue. Teensy 4.x beautifully works too, single salve or multi slave setup, works nice. When I enable SPI slaves, Neo-M8N is the works case because it sends more data, everything works fine until I2C interrupts SPI transfer at the special time and place which is difficult to pinpoint. After that I2C bus goes south. I captured few traces from the scope I will share and then continue few thoughts. The trace below is TM1000 is reading from T4 address 0x16, 16 bytes of telemetry data. Everything is normal. The Red trace is Neo GPS CS line and Green trace Neo Ext ISR line. It is low because T4 does not read Neo just ye.
lbuchman commented 3 years ago

image Normal Trace

lbuchman commented 3 years ago

image

I enabled reading Neo GPS over SPY. After some time T4 replies NACK on I2C. Note that SPI CS is LOWwhich means SPI transfer and I2C were in about the same time. Neo Neo ISR line is low indication that it has more data to send. After this Spektrum TM1000 will stop puling the I2C BUS

lbuchman commented 3 years ago

the next trace is like the prev. one, but for some reason SDA line is low. It was not T4 pulling the line down. image

lbuchman commented 3 years ago

T 3.2 and T3.6 work fine and T4 does not. Looks like a HW issue, but I cannot see the issue on the scope except SDA line down.