Forum Rule: Always post complete source code & details to reproduce any issue!
Page 24 of 24 FirstFirst ... 14 22 23 24
Results 576 to 591 of 591

Thread: New I2C library for Teensy3

  1. #576
    Senior Member
    Join Date
    Mar 2013
    Location
    Austin TX
    Posts
    401
    Quote Originally Posted by tonton81 View Post
    just out of curiosity of watching the chip registers to see if their intact to make sure i2c bus is operational, does the library have it's own check built in to detect operational bus without writing a request to the device on the bus?
    Internally the library maintains its state through several variables in the i2cStruct (refer to i2c_t3.h file, and look for i2cStruct, then "Current" variables). There are functions to access some of those, but i2cStruct is public, so any setting can be read from it at any time (eg. Wire.i2c->currentRate for example).

    If it needs to determine bus state it will check C1 register (I2C_C1_MST) and S register (I2C_S_BUSY). Refer to the acquireBus_() function to see how it checks those. It does not require talking to Slaves on the bus.

  2. #577
    Senior Member
    Join Date
    Nov 2012
    Location
    Salt Lake City, UT, USA
    Posts
    246
    Quote Originally Posted by tonton81 View Post
    just out of curiosity of watching the chip registers to see if their intact to make sure i2c bus is operational, does the library have it's own check built in to detect operational bus without writing a request to the device on the bus?
    If by seeing if any of the bus lines are stuck, we have added a simple pin-wiggle high and low test to the startup code in our project which depends on I2C for a lot of the system I/O. Then we report SDA or SCL stuck low or high as errors. Not sure if that's what you are asking here.

    If a clock gets "lost" or missed by a slave, it could fail to release the bus, and the library has the ability to send extra clocks to recover from that, if you enable it. I added the ability to see if that recovery has happened, it's in a pull request which you can view if curious about what was added and want to duplicate that.

  3. #578
    Senior Member
    Join Date
    Nov 2012
    Location
    Salt Lake City, UT, USA
    Posts
    246
    Quote Originally Posted by chrisCode View Post
    Hi,
    is there any option to send data to multiple slaves in one DMA-mode session? I mean write buffer with 1st slave address and data, 2nd slave addr and data (3th and so on) and then use sendTransmission() function?
    See @nox771s answer which relates to i2c_t3. But in the bigger world if you have intelligent I2C slaves (microcontrollers) then yes, you can have a multi-master system on I2C or perhaps more correctly, it is a multi-peer system. You can send a message modeled on UDP and all slaves can receive it at the same time. Those that want to pay attention to it can. It's like a broadcast vs sending to one slave. We implemented such a system for a robotic platform and it worked well. The trick is arbitration resolves in the "UDP like" header so there is never a clash of multiple slaves responding to one message. There's nothing preventing this in the I2c spec, though a peer I2C net is unusual.

  4. #579
    Senior Member
    Join Date
    Mar 2013
    Location
    Austin TX
    Posts
    401
    Just FYI - I've uploaded a v9.3 release to the top post and GitHub. It fixes a Slave-mode bug in the ISR for LC/3.5/3.6 devices (STOP bit not properly triggering callback). Try the update if you have any problem running that configuration.

    Edit: Just re-uploaded to merge Paul's Teensy 2.0 patch. First post and GitHub are updated.
    Last edited by nox771; 09-20-2017 at 04:39 PM.

  5. #580
    Senior Member
    Join Date
    Nov 2012
    Location
    Salt Lake City, UT, USA
    Posts
    246

    Trouble compiling i2c_t3 under Linux

    So... I'm attempting to get a Linux (Ubuntu 17.04) dev system working... because I am hoping it is "better" than Windows. For one thing it is 10X faster to program a new Teensy module: no drivers to install every. single. time. But when I try to build a program under LInux I'm getting errors not present when building on Windows:

    This happens with Arduino 1.8.2/TD 1.36 and Arduino 1.8.4/TD1.39
    I'm pulling in the identical libraries from my github repo where appropriate so those are the same on Windows and Linux.

    The problem appears to be in

    Code:
    /tmp/arduino_build_440080/libraries/i2c_t3/i2c_t3.cpp.o:/home/bruce/Documents/code/Arduino/libraries/i2c_t3/i2c_t3.cpp:1405: first defined here
    /home/bruce/Documents/arduino-1.8.2/hardware/tools/arm/bin/../lib/gcc/arm-none-eabi/5.4.1/../../../../arm-none-eabi/bin/ld: Disabling relaxation: it will not work with multiple definitions
    /tmp/arduino_build_440080/libraries/Wire/WireKinetis.cpp.o: In function `Print::flush()':
    /home/bruce/Documents/code/Arduino/libraries/Wire/WireKinetis.h:132: multiple definition of `i2c1_isr'
    /tmp/arduino_build_440080/libraries/i2c_t3/i2c_t3.cpp.o:/home/bruce/Documents/code/Arduino/libraries/i2c_t3/i2c_t3.h:926: first defined here
    /tmp/arduino_build_440080/libraries/Wire/WireKinetis.cpp.o: In function `Print::flush()':
    /home/bruce/Documents/code/Arduino/libraries/Wire/WireKinetis.h:132: multiple definition of `Wire1'
    /tmp/arduino_build_440080/libraries/i2c_t3/i2c_t3.cpp.o:/home/bruce/Documents/code/Arduino/libraries/i2c_t3/i2c_t3.h:926: first defined here
    /home/bruce/Documents/arduino-1.8.2/hardware/tools/arm/bin/../lib/gcc/arm-none-eabi/5.4.1/../../../../arm-none-eabi/bin/ld: Warning: size of symbol `Wire1' changed from 20 in /tmp/arduino_build_440080/libraries/i2c_t3/i2c_t3.cpp.o to 108 in /tmp/arduino_build_440080/libraries/Wire/WireKinetis.cpp.o
    /tmp/arduino_build_440080/libraries/Wire/WireKinetis.cpp.o: In function `Print::flush()':
    /home/bruce/Documents/code/Arduino/libraries/Wire/WireKinetis.h:132: multiple definition of `Wire'
    /tmp/arduino_build_440080/libraries/i2c_t3/i2c_t3.cpp.o:/home/bruce/Documents/code/Arduino/libraries/i2c_t3/i2c_t3.h:926: first defined here
    /home/bruce/Documents/arduino-1.8.2/hardware/tools/arm/bin/../lib/gcc/arm-none-eabi/5.4.1/../../../../arm-none-eabi/bin/ld: Warning: size of symbol `Wire' changed from 20 in /tmp/arduino_build_440080/libraries/i2c_t3/i2c_t3.cpp.o to 108 in /tmp/arduino_build_440080/libraries/Wire/WireKinetis.cpp.o
    collect2: error: ld returned 1 exit status
    I'm not understanding how this error can happen just on Linux... assuming all the code and library files are the same on both platforms... and not sure how to proceed. Thanks.

  6. #581
    Senior Member
    Join Date
    Mar 2013
    Location
    Austin TX
    Posts
    401
    Quote Originally Posted by bboyes View Post
    So... I'm attempting to get a Linux (Ubuntu 17.04) dev system working... because I am hoping it is "better" than Windows. For one thing it is 10X faster to program a new Teensy module: no drivers to install every. single. time. But when I try to build a program under LInux I'm getting errors not present when building on Windows:

    This happens with Arduino 1.8.2/TD 1.36 and Arduino 1.8.4/TD1.39
    I'm pulling in the identical libraries from my github repo where appropriate so those are the same on Windows and Linux.

    The problem appears to be in

    Code:
    /tmp/arduino_build_440080/libraries/i2c_t3/i2c_t3.cpp.o:/home/bruce/Documents/code/Arduino/libraries/i2c_t3/i2c_t3.cpp:1405: first defined here
    /home/bruce/Documents/arduino-1.8.2/hardware/tools/arm/bin/../lib/gcc/arm-none-eabi/5.4.1/../../../../arm-none-eabi/bin/ld: Disabling relaxation: it will not work with multiple definitions
    /tmp/arduino_build_440080/libraries/Wire/WireKinetis.cpp.o: In function `Print::flush()':
    /home/bruce/Documents/code/Arduino/libraries/Wire/WireKinetis.h:132: multiple definition of `i2c1_isr'
    /tmp/arduino_build_440080/libraries/i2c_t3/i2c_t3.cpp.o:/home/bruce/Documents/code/Arduino/libraries/i2c_t3/i2c_t3.h:926: first defined here
    /tmp/arduino_build_440080/libraries/Wire/WireKinetis.cpp.o: In function `Print::flush()':
    /home/bruce/Documents/code/Arduino/libraries/Wire/WireKinetis.h:132: multiple definition of `Wire1'
    /tmp/arduino_build_440080/libraries/i2c_t3/i2c_t3.cpp.o:/home/bruce/Documents/code/Arduino/libraries/i2c_t3/i2c_t3.h:926: first defined here
    /home/bruce/Documents/arduino-1.8.2/hardware/tools/arm/bin/../lib/gcc/arm-none-eabi/5.4.1/../../../../arm-none-eabi/bin/ld: Warning: size of symbol `Wire1' changed from 20 in /tmp/arduino_build_440080/libraries/i2c_t3/i2c_t3.cpp.o to 108 in /tmp/arduino_build_440080/libraries/Wire/WireKinetis.cpp.o
    /tmp/arduino_build_440080/libraries/Wire/WireKinetis.cpp.o: In function `Print::flush()':
    /home/bruce/Documents/code/Arduino/libraries/Wire/WireKinetis.h:132: multiple definition of `Wire'
    /tmp/arduino_build_440080/libraries/i2c_t3/i2c_t3.cpp.o:/home/bruce/Documents/code/Arduino/libraries/i2c_t3/i2c_t3.h:926: first defined here
    /home/bruce/Documents/arduino-1.8.2/hardware/tools/arm/bin/../lib/gcc/arm-none-eabi/5.4.1/../../../../arm-none-eabi/bin/ld: Warning: size of symbol `Wire' changed from 20 in /tmp/arduino_build_440080/libraries/i2c_t3/i2c_t3.cpp.o to 108 in /tmp/arduino_build_440080/libraries/Wire/WireKinetis.cpp.o
    collect2: error: ld returned 1 exit status
    I'm not understanding how this error can happen just on Linux... assuming all the code and library files are the same on both platforms... and not sure how to proceed. Thanks.
    This looks like a problem in the build system, not in the source code. It seems to be trying to link in default Wire lib (WireKinetis.cpp.o) at the same time as i2c_t3, which won't work because they define the same things. I don't have experience trying to use Arduino build system in linux. If the source is not using Wire lib then it shouldn't be trying to link it in, so I don't know why that is happening. If you can get the attention of Paul you might get a better answer.

  7. #582
    Senior Member
    Join Date
    Mar 2013
    Location
    Austin TX
    Posts
    401
    All - I've uploaded a v9.4 release to the top post and GitHub. A couple other bugs showed up involving RepSTART into Slave ISR on LC/3.5/3.6. Changes are:

    • Fixed Slave ISR for LC/3.5/3.6 not properly recognizing RepSTART
    • Fixed nested Wire calls during Slave ISR receive (calling Wire inside Wire1 Slave ISR)
    • Added uint8_t and char array read functions - Wire.read(databuf, count);
    • Updated examples to demonstrate read/write array functions
    • Added basic_echo example

  8. #583
    Senior Member
    Join Date
    Sep 2013
    Location
    Hamburg, Germany
    Posts
    884
    I'd like to read data from a slave asynchronously. Your API explanation seems to indicate that this is possible using sendRequest(address, length, i2c_stop), but I can't find an example. There seems to be no callback when a request has been handled, so I'd have to use done() to determine if data has been read, or finish() to wait until it has been read.

    What happens when a second independent part of an application calls sendRequest() while another request is already being handled?

    Regards

    Christoph

  9. #584
    Senior Member
    Join Date
    Mar 2013
    Location
    Austin TX
    Posts
    401
    Quote Originally Posted by christoph View Post
    I'd like to read data from a slave asynchronously. Your API explanation seems to indicate that this is possible using sendRequest(address, length, i2c_stop), but I can't find an example. There seems to be no callback when a request has been handled, so I'd have to use done() to determine if data has been read, or finish() to wait until it has been read.
    sendRequest() will background a transfer, but it is correct you will need to poll or periodically check done() or finish() to know when the transfer is complete. The expectation was this is something that would be done at the end of a main loop iteration or similar. I suppose in the future I could set it up with a callback similar to Slave operation, but at the moment it does not do this. The advanced_master example has a tiny test for sendRequest() where it just runs a counter while the transfer is backgrounded, but there is no complex example of this.

    Quote Originally Posted by christoph View Post
    What happens when a second independent part of an application calls sendRequest() while another request is already being handled?
    That would not be supported. Starting a new Master operation while one is ongoing will negate the ongoing operation. The way to deal with this is to have the code block or poll for done() or finish() until the bus is clear, then start the new operation (or perhaps utilize a second dedicated bus). The basic_echo example does something like this in the receiveEvent() callback where the Slave will echo data incoming on Wire1 out on Wire (as a backgrounded transmit), but it blocks at Wire.finish() until the bus is clear to send.

  10. #585
    Senior Member
    Join Date
    Mar 2013
    Location
    Austin TX
    Posts
    401
    All, I've uploaded a new v10.0 library to the top post and GitHub. Documentation has been updated.

    This has passed all my testing but it is a pretty involved change in some parts, so post here if you have any problems with it. There are three major changes (first three below), and some extra cleanup and fixes. The changes are:

    1. Unbound SCL, SDA pin assignment. The library now supports setSCL() and setSDA() functions, and in general any place that used to take a pins enum value will now accept a SCL,SDA pin pair (in that order). This includes the begin() function. The enum values will remain supported so there is no risk of breaking existing code. This is primarily to add compatibility to any code written against standard Teensy Wire. Refer to the top-post or GitHub for the full array of valid pin settings.

    New functions are (where '^' indicates optional parameters):
    • begin(mode, address, ^pinSCL, ^pinSDA, ^i2c_pullup, ^rate, ^i2c_op_mode);
    • begin(mode, address1, address2, ^pinSCL, ^pinSDA, ^i2c_pullup, ^rate, ^i2c_op_mode);
    • pinConfigure(pinSCL, pinSDA, ^pullup);
    • setSCL(pin);
    • setSDA(pin);
    • getSCL();
    • getSDA();

    Examples:
    Code:
    Wire.begin(I2C_MASTER, 0x00, I2C_PINS_18_19, I2C_PULLUP_EXT, 400000); // Wire bus, SCL pin 19, SDA pin 18, ext pullup, 400kHz 
    Wire.begin(I2C_MASTER, 0x00, 19, 18);                                 // equivalent to above, will default to ext pullup at 400kHz
    Wire.begin(I2C_MASTER, 0x00, 16, 18);                                 // similar to above, but using SCL pin 16 and SDA pin 18
    Note that this change impacted the Wire.i2c->currentPins internal variable, which is now replaced by Wire.i2c->currentSCL and Wire.i2c->currentSDA. This is not normally something someone would use, but be aware if you run into a 'currentPins not defined' error (possibly on old example code).


    2. Added Master callback functions. These callbacks were initially added to trigger when background transfers complete (sendTransmission() and sendRequest()), however they will also trigger on foreground transfers. There is also a error function callback which will trigger on any error that terminates a Master transfer. These can be used to do exit status and error checking in common functions instead of explicitly coding everywhere. Additions are:
    • onTransmitDone(function) - where function() is called when Master Transmit is complete
    • onReqFromDone(function) - where function() is called when Master Receive is complete
    • onError(function) - where function() is called upon any I2C error which terminates the Master bus operation (eg. NAK, timeout, acquire fail, etc)
    • basic_master_callback - an added example which demonstrates the above functions


    3. Error counters. An error counting system was added which can track bus errors over long durations. It tracks seven different types of errors. This functionality is gated by a define I2C_ERROR_COUNTERS, which by default is enabled, but it can be disabled if there is any performance concern (refer to top of i2c_t3.h file). There are two supporting functions, one to return error count, and the other to zero the count. The functions are:
    • getErrorCount(counter)
    • zeroErrorCount(counter)
    • where counter is an enum value with one of the following settings:
      • I2C_ERRCNT_RESET_BUS
      • I2C_ERRCNT_TIMEOUT
      • I2C_ERRCNT_ADDR_NAK
      • I2C_ERRCNT_DATA_NAK
      • I2C_ERRCNT_ARBL
      • I2C_ERRCNT_NOT_ACQ
      • I2C_ERRCNT_DMA_ERR


    4. Misc cleanup and fixes.
    • Added default settings on many function arguments and did some cleanup. With the exception of old style Arduino calls (Wire.begin() and Wire.begin(addr) which are 100kHz), more complex calls will use default pins, external pullups, 400kHz, and ISR mode if those settings are not explicitly set.
    • Also fixed some blocking conditions that could occur in immediate mode
    • Updated all docs



  11. #586
    Hi nox771

    thanks for all the improvements. Will try them. I had serious problems with a data-collecting master and a slave writing data to an SD-card, communicating over i2c. This was last spring and I could not spot where the problem was. Happened sometimes after 5 minutes, sometimes it took 1 hour. Well - end of last spring I had not the time to investigate further and I let it be as it was.

    best regards

  12. #587
    Senior Member brtaylor's Avatar
    Join Date
    Mar 2016
    Location
    Portland, OR
    Posts
    178

    General Call

    Hi Brian,

    Great library, I use it with all of my Teensy specific code. Is there a plan to implement the ability for slaves to respond to a general call (i.e. respond to a master transmitting to address 0)?

    Thanks!
    Brian

  13. #588
    Senior Member
    Join Date
    Mar 2013
    Location
    Austin TX
    Posts
    401
    Quote Originally Posted by brtaylor View Post
    Great library, I use it with all of my Teensy specific code. Is there a plan to implement the ability for slaves to respond to a general call (i.e. respond to a master transmitting to address 0)?
    GC is one of several things that are lacking, but unfortunately at the moment I'm out of time, and it might be a while before I can look into it. I can add this as a future to-do.

  14. #589
    Forgive me if I'm missing something obvious, but wire.readByte and wire.peekByte seem like they'll have a problem if the data byte to be returned is a zero. How do you tell the difference between a zero data byte and the buffer being empty?

  15. #590
    Senior Member
    Join Date
    Mar 2013
    Location
    Austin TX
    Posts
    401
    Quote Originally Posted by Mrchadwickusa View Post
    Forgive me if I'm missing something obvious, but wire.readByte and wire.peekByte seem like they'll have a problem if the data byte to be returned is a zero. How do you tell the difference between a zero data byte and the buffer being empty?
    You don't use those functions to determine if the buffer is empty, instead use Wire.available(). Those functions exist because at a hardware level the I2C moves data in bytes, so it is natural to manipulate data in bytes.

    The original Wire lib tried to mash two functions together by returning a signed int, with -1 being buffer empty. This almost certainly requires casting to use the data (it is actually cast twice, once to convert to signed int, and again to convert to something else).

    Both sets of functions exist in the lib so you can use either, eg. Wire.read()/Wire.peek() for signed int, or Wire.readByte()/Wire.peekByte() with Wire.available() for working with uint8_t. It's up to the end user to decide which they like.

  16. #591
    Thanks for the cogent, quick and kind reply!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •