Forum Rule: Always post complete source code & details to reproduce any issue!
Page 28 of 28 FirstFirst ... 18 26 27 28
Results 676 to 696 of 696

Thread: New I2C library for Teensy3

  1. #676
    Senior Member
    Join Date
    Mar 2013
    Location
    Austin TX
    Posts
    429
    Quote Originally Posted by LeD View Post
    I'm interested in the topic, my new Teensy 4.0 cannot access I2C buses to control devices I already tested with 3.2 and 3.6.
    Any news about development?
    Any suggestion about how to add some modification to the last library version to make it work (even modification not very efficient) for T4.0?

    Thank you anyway
    Sorry, I don't have anything running on T4 at the moment. I acquired some parts, but I haven't had time to work on it. For now you will have to utilize the Wire library.

  2. #677
    Senior Member
    Join Date
    Jun 2017
    Posts
    114
    Not working for me; the #include <wire.h> line in the main sketch still picks up the file in C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Wire\W ire.h

  3. #678
    Senior Member
    Join Date
    Mar 2013
    Location
    Austin TX
    Posts
    429
    Quote Originally Posted by paynterf View Post
    Not working for me; the #include <wire.h> line in the main sketch still picks up the file in C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Wire\W ire.h
    To use this library you need to use #include <i2c_t3.h>, not #include <wire.h>. The example files that are included demonstrate usage.

  4. #679
    Senior Member
    Join Date
    Jun 2017
    Posts
    114
    nox771,

    Hmm, This is what I tried, something from an earlier post of yours.

    Click image for larger version. 

Name:	Annotation 2020-05-22 103901.jpg 
Views:	39 
Size:	44.4 KB 
ID:	20230

    I have used your fine i2c_t3.h library in many other Teensy projects, but can't in this one because the various V53L0X libraries use Wire.h

    Regards,

    Frank

  5. #680
    Senior Member
    Join Date
    Oct 2015
    Location
    Roma (IT, EU)
    Posts
    339
    You can't include both <i2c_t3.h> and <Wire.h>. Include <i2c_t3.h> only.
    If other libraries include <Wire.h>, the only way is replacing every Wire.h with i2c_t3.h across every source of the project/library.

  6. #681
    Senior Member
    Join Date
    Apr 2020
    Location
    DFW area in Texas
    Posts
    170
    Quote Originally Posted by paynterf View Post
    I have used your fine i2c_t3.h library in many other Teensy projects, but can't in this one because the various V53L0X libraries use Wire.h
    Here's a dirty hack that might help you to test in the short-term:

    - if you're on a Windows machine, rename the offending "Wire.h" file (to something else, maybe oldWire.h")
    - in place of the previous "Wire.h", create a shortcut named "Wire.h" that points to "i2c_t3.h"
    - if you're on a linux machine, do a similar thing, creating a soft link instead

    Mark J Culross
    KD5RXT

  7. #682
    Senior Member+ MichaelMeissner's Avatar
    Join Date
    Nov 2012
    Location
    Ayer Massachussetts
    Posts
    3,931
    Quote Originally Posted by kd5rxt-mark View Post
    Here's a dirty hack that might help you to test in the short-term:

    - if you're on a Windows machine, rename the offending "Wire.h" file (to something else, maybe oldWire.h")
    - in place of the previous "Wire.h", create a shortcut named "Wire.h" that points to "i2c_t3.h"
    - if you're on a linux machine, do a similar thing, creating a soft link instead

    Mark J Culross
    KD5RXT
    At least in the past you needed to define TwoWire also:
    Code:
    typedef i2c_t3 TwoWire;

  8. #683
    Senior Member
    Join Date
    Jun 2017
    Posts
    114
    Thanks for the information - that sounds a whole lot easier than trying to track down all the library references.

    So, for my Windows 10 setup:

    rename 'C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Wire\W ire.h' to 'C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Wire\O ldWire.h'

    then, in an elevated command prompt:

    C:\Windows\system32>mklink /h "C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Wire\W ire.h" "C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\i2c_t3 \i2c_t3.h"

    Is that correct?


    What happens the next time the Arduino IDE and or TeensyDuino gets updated? Does the hard link disappear and have to be re-done?

  9. #684
    Senior Member
    Join Date
    Mar 2013
    Location
    Austin TX
    Posts
    429
    I would expect if you reinstall Arduino over the same files it will overwrite the link with the Wire.h file. There are many variations of this idea, including altering the contents of the file, or the file itself with a link as suggested, or somehow altering the build system. But they don't survive getting overwritten.

    I don't think there is an ideal solution to trivially swapping libraries. Creating some tool to do this is a reasonable project idea though, because there are always things like display libraries and such that have a dozen variants which would be nice to pick and choose what gets used.

  10. #685
    Junior Member
    Join Date
    May 2017
    Posts
    11
    Hello,

    first of all: Merry Chrismas to all Hope your fine.

    My problem: I like to use a chip which takes it's firmware via I2C I/F. This firmware is long, longer than the buffer in the lib of i2c_t3. When I increase the buffer of the lib to 1kB and send a FW package which is about 900 bytes, everything is fine. But I need also to send FW images which are longer (about 500kB). Yes it takes a while but this is not problem. The problem is, I do not have success to send larger files than the internal buffer of the lib is.
    I have no idea but I guess the chip I'm using is not handle the repeated start correctly.

    Sample code (not the code I'm using):
    Code:
    do
    {
      Wire.beginTransmission(address);
      status = Wire.write( &buf[completedLen], wrLenToSend);
      // evaluete sendStop: I2C_NOSTOP or I2C_STOP
      Wire.endTransmission(sendStop);  // sendStop is set correct, I have checked this
      status = Wire.finish(1000000L);
      if(status==0)
      {
        PRINT_ERR("i2c finish error\n");
      }
    }
    while(sendStop==I2C_NOSTOP);
    When I send a package with 900 bytes and the lib internal buffer is 1kB, everything is fine. When I decrease the lib internal buffer to the original values (259 bytes), the loop is running 4 times. On the logic analyzer I
    found the correct data, e.g.:
    Code:
    START,addr, <data bytes>, ACK
    repeated START,addr, <data bytes>, ACK
    repeated START,addr, <data bytes>, ACK
    repeated START,addr, <data bytes>, ACK, STOP
    But this is not working. Only this is working:
    Code:
    START,addr, <complete data bytes>, ACK, STOP
    Now my question: how to use the lib, sending a large amount of data (longer then the internal buffer is) without the repeted start? The lib should not use it's internal buffer, send data immediatly.
    I guess it is not possible in the moment but may be there is a solution (may be without this lib)?

    Thank you very much for helping

    Edit: The chip documentation does not describe the "protocol" in detail using I2C, only states, I may use the I2C IF to load and command.
    Edit2: The chip I'm using has no address to initiate the FW download. Only a command "Load FW" without a target address. So on the I2C bus you see:
    START, device address, n bytes of data (without target/register address), ACK, STOP.
    Last edited by _joachim; 12-26-2020 at 03:40 PM.

  11. #686
    Senior Member
    Join Date
    May 2015
    Location
    USA
    Posts
    835
    Can you do many smaller writes? What is the target chip and software running on it?

  12. #687
    Junior Member
    Join Date
    May 2017
    Posts
    11
    It is a FM/DAB receiver chip SI4688 from Silabs. After reset a firmware download must made. I can only perform a complete write to the chip, the complete FW package between START and STOP without repeated START. Smaller writes are failed, the FW is not booting after.

  13. #688
    Senior Member
    Join Date
    May 2015
    Location
    USA
    Posts
    835
    You should post your actual code. I don't know much about it, but possibly use wait_idle() between partial writes.

  14. #689
    Senior Member
    Join Date
    Mar 2013
    Location
    Austin TX
    Posts
    429
    Existing i2c_t3 doesn't support continuous spooling of data into the transmit buffer. It's probably not that difficult, but it would require some low level modifications.

    To transmit data which exceeds the buffer size would require a customized transmit and ISR routine. Transmit would need to only preload part of the data into the buffer, and would need some mechanism to know where to get more data. Also it would require maintaining a total data count separate from the buffer index (currently the index is compared against the data count loaded in the buffer to know when to end).

    It may be as simple as using a separate data count, and if the buffer index equals the buffer end, then send last byte, reset index to zero, refill buffer with new data (next ISR will then send from the beginning of the buffer). Continue for full data count.

    This may be easier done using a non-interrupt based routine, like the old Wire code. That is a straightforward polling loop. As long as you can pull data from someplace you can loop as long as you want.

  15. #690
    Junior Member
    Join Date
    May 2017
    Posts
    11
    Below is the comlete function as I use it. It is working as written, the short FW package I send has about 900 bytes. I have also increased the buffer of the lib i2c_t3.
    But when I change the define in my function to I2C_PACKET_LENGTH to 256 then the FW is not booting and I got no errors from I2C send functions. Then the data are send in 4 packets.
    wait_idle() is nt available in this function, at least I didn't found it

    Code:
    int32_t shieldTwi::writeTest(uint8_t address, uint8_t *buf, uint32_t writeLen )
    {
    #define I2C_PACKET_LENGTH (1020)
      uint8_t e=0;
      uint32_t status=0;
      uint32_t packetLen;
      uint32_t lenAlreadySend=0;
      i2c_stop sendStop;
    
      if(writeLen > 0)
      {
        do
        {
          packetLen= (writeLen - lenAlreadySend) > I2C_PACKET_LENGTH ? I2C_PACKET_LENGTH : writeLen - lenAlreadySend;
          if( lenAlreadySend + packetLen >= writeLen )
            sendStop = I2C_STOP;
          else
            sendStop = I2C_NOSTOP;
    
          Wire.beginTransmission(address);
          PRINT_MSG(1,"wrLen = %ld, complLen=%ld, sendStop=%ld, data=0x%02X\n", packetLen, lenAlreadySend, sendStop, buf[lenAlreadySend]);
          // fill up I2C buffer
          status = Wire.write( &buf[lenAlreadySend], packetLen);
          if(status != packetLen)
          {
            PRINT_ERR("i2c write error, status=%ld\n", status);
          }
    
          // transmit buffer
          Wire.endTransmission(sendStop);
    
          // update completed length
          lenAlreadySend += packetLen;
    
          // check for errors
          if( (e=Wire.getError()) )
          {
            // 0=success, 1=data too long, 2=recv addr NACK, 3=recv data NACK, 4=other error (timeout, arb lost)
            switch(e)
            {
            case 1:
              PRINT_ERR("i2c wr error: data too long\n");
              break;
            case 2:
              PRINT_ERR("i2c wr error: recv addr NACK, addr: 0x%02X\n", address);
              break;
            case 3:
              PRINT_ERR("i2c wr error: recv data NACK\n");
              break;
            case 4:
              PRINT_ERR("i2c wr error: other error (timeout, arb lost)\n");
              break;
            default:
              PRINT_ERR("i2c wr error: unknown");
              break;
            }
          }
        }
        while( sendStop == I2C_NOSTOP );
    
      }
    
      return lenAlreadySend;
    }

  16. #691
    Junior Member
    Join Date
    May 2017
    Posts
    11
    nox771, you wrote what I had assumed, it is not possible with the lib to send data longer than the internal buffer without a repeated start.
    I need to take a look in the source further to decide if I will implement one of your proposed solutions. I do not know if the original lib for I2C does habdle the data as I want. I do not need the interrupt/DMA driven solution for my case.
    Yes it's nice but....

    Does the original lib using a buffer? If yes, it doesn't help But I will see. At least I want to nknow if I'm doing something wrong or if it is not posssible what I like to do.
    Thank very much you so far

  17. #692
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    8,217
    The normal Wire library also uses a fixed size buffer.

    Not sure which Teensy you are using. Guessing not T4.x as last time I checked, T4 support had not yet been added to I2C_t3.

    I believe by default it defaults to buffer of 32... You can probably change to larger.
    However it would take more surgery to go beyond 255 as it looks like all of the counters and the like are stored in uint8_t member variables.

    I wish that some of these classes would have members like: Wire.setTXBuffer(my_buffer, my_buffer_size);
    It would be semi trivial to add. Alternatively could do like we did for Serial objects with the addMemory... Makes the code very slightly more complicated but not really too difficult as it is not a ring type buffer.

  18. #693
    Junior Member
    Join Date
    May 2017
    Posts
    11
    I have take a look into the "normal" Wire librray, yes it is using also a buffer. I'm using a Teensy 3.2 not the 4. But now I have verified that I can use a buffer of a few bytes more than 4kB in the i2c_t3 lib. This fits all needs as the biggest packet to send is 4kB. To upload a FW with 500kB this must be split into 4kB packets. The 900 byte packet is a bootloader patch. And I can live with a buffer of 4Kb in the lib.

  19. #694
    Senior Member
    Join Date
    May 2015
    Location
    USA
    Posts
    835
    Good that you found something that works. As I see it, your application could use less buffer space if it had something like this for all but the first and last portions:

    endTransmission(omitStart, omitStop);

  20. #695
    Junior Member
    Join Date
    May 2017
    Posts
    11
    endTransmission(sendStop) is existing. But for the next transmission a beginTransmission must be used and this is sending a repeated Start on the bus. And this the chip don't like as it seems.
    And the repeated START is necessary as the bus is released after the transmission for the case there is a multimaster system. So another master can request the bus.
    I'm not sure if my understanding is correct in this case

    Of course, it is possible implementing all this things but I have a solution.

  21. #696
    Senior Member
    Join Date
    May 2015
    Location
    USA
    Posts
    835
    My understanding is that if you omit the stop, then the bus isn't released and, with your slave chip/application, the following start isn't needed/tolerated.
    But the libraries don't provide a way to do this.

Posting Permissions

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