Forum Rule: Always post complete source code & details to reproduce any issue!
Page 18 of 27 FirstFirst ... 8 16 17 18 19 20 ... LastLast
Results 426 to 450 of 674

Thread: New I2C library for Teensy3

  1. #426
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    9,693
    Quote Originally Posted by nox771 View Post
    That's a good summary. You should post this on the Tips and Tricks thread.
    Done :: Calling this "CPUspecs();" from setup will show you compile time details on your Teensy

    opps >> ORIGINAL post had T_LC and T_3.0 swapped. :: CORRECTED above and T&T

    This line is also useful to record compile TIME and DATE:
    Code:
      Serial.print(__DATE__);   Serial.print(" -- ");  Serial.println(__TIME__);
    Last edited by defragster; 09-22-2016 at 06:32 AM.

  2. #427
    Senior Member brtaylor's Avatar
    Join Date
    Mar 2016
    Location
    Portland, OR
    Posts
    536
    Great library and use it all the time! One question, is it possible to setup a teensy as a slave responding to an address range that is not continuous? For example, have the teensy respond to 0x21 and 0x30 through 0x40?

    Thanks!
    Brian

  3. #428
    Senior Member
    Join Date
    Mar 2013
    Location
    Austin TX
    Posts
    425
    Quote Originally Posted by onehorse View Post
    36 MHz with 300 kHz is also a 120 divide...
    Yes I know, this sort of confirms that it is something with that 120 divide setting. I haven't had a chance to study it yet, I'll try and take a look at it tonight.

  4. #429
    Senior Member
    Join Date
    Mar 2013
    Location
    Austin TX
    Posts
    425
    Quote Originally Posted by brtaylor View Post
    Great library and use it all the time! One question, is it possible to setup a teensy as a slave responding to an address range that is not continuous? For example, have the teensy respond to 0x21 and 0x30 through 0x40?
    No, well not directly. The address range feature is a HW function, and it only allows contiguous range. However, on a dual bus part you could setup one bus (Wire) to respond to 0x21 and the other bus (Wire1) to respond to 0x30 to 0x40, then wire them on the same bus.

    I've never tried parallel slaves on one device, but I have done master/slave on one device and it did work.

    Edit: Actually I did do multiple slaves before and it did work. On T3.6 devel I ran one master and 3 slaves IIRC and it did work, so running dual slave on T3.2 should work also.
    Last edited by nox771; 09-23-2016 at 08:27 PM.

  5. #430
    Junior Member
    Join Date
    Feb 2016
    Posts
    2
    I am attempting to run this library as I require access to the secondary I2C pins and am having trouble sourcing the set of defines that populates the i2c_div_ratio array. Right now only I2C_F_DIV52, 60, 136, 176, and 352 are defined. Everything else errors out. I'll probably just delete everything not defined and keep the ones that are, but if I am missing those defines I may be missing something else as well...

    Thank you.

    -chlore
    uc: teensy3.2 @144mhz IDE: visual micro.


    Edit: Deleting everything not defined removed the errors and now the class works as expected. One more question: if I only need the Wire1 on the 29/30 pins am I required to include the Wire bus as well? Can I set Wire to use the 29/30 pins and then set I2C_BUS_ENABLE 1 to save memory?
    Last edited by chlore; 09-24-2016 at 01:20 AM.

  6. #431
    Senior Member
    Join Date
    Feb 2016
    Location
    Australia
    Posts
    219
    Quote Originally Posted by nox771 View Post
    That doesn't make sense. Make sure you are running the latest library version and it is not linking in an older version from Teensyduino. If you are using a latest library which is in your sketchbook/libraries folder, then it should dump out something like this when it compiles:
    Code:
    Multiple libraries were found for "i2c_t3.h"
     Used: C:\your_sketchbook_folder\libraries\i2c_t3
     Not used: C:\teensyduino_install_folder\arduino-1.6.9\hardware\teensy\avr\libraries\i2c_t3
    If you follow the "used" path, make sure it points to the latest version - near the top of the .cpp or .h file it should say v9:
    Code:
    - (v9) Modified 01Jul16 by Brian (nox771 at gmail.com)
    Or if you have the latest development teensyduino it should be upgraded already. You can find it here:
    https://forum.pjrc.com/threads/36756...ta-4-Available
    Running V8 at 400k i2c speed:
    CPU is T_3.1/3.2
    F_CPU =96000000
    ARDUINO =10609
    F_PLL =96000000
    F_BUS =48000000
    F_MEM =24000000
    time it takes to update 1 layer (5 io expanders):687uS

    V8 at 800k:
    CPU is T_3.1/3.2
    F_CPU =96000000
    ARDUINO =10609
    F_PLL =96000000
    F_BUS =48000000
    F_MEM =24000000
    time it takes to update 1 layer (5 io expanders):401

    v8 at 1.2M:

    CPU is T_3.1/3.2
    F_CPU =96000000
    ARDUINO =10609
    F_PLL =96000000
    F_BUS =48000000
    F_MEM =24000000
    time it takes to update 1 layer (5 io expanders):332

    v9 at 400k:
    CPU is T_3.1/3.2
    F_CPU =96000000
    ARDUINO =10609
    F_PLL =96000000
    F_BUS =48000000
    F_MEM =24000000
    i2c speed(getClock()): 400000
    time it takes to update 1 layer (5 io expanders):692

    v9 at 800k:
    CPU is T_3.1/3.2
    F_CPU =96000000
    ARDUINO =10609
    F_PLL =96000000
    F_BUS =48000000
    F_MEM =24000000
    i2c speed(getClock()): 800000
    time it takes to update 1 layer (5 io expanders):445

    v9 at 1.2M:
    PU is T_3.1/3.2
    F_CPU =96000000
    ARDUINO =10609
    F_PLL =96000000
    F_BUS =48000000
    F_MEM =24000000
    i2c speed(getClock()): 1200000
    time it takes to update 1 layer (5 io expanders):373

    I believe v9 working a bit slower for me.
    41uS slower for sending a couple of bytes to 5 mcp23017 io expanders

    edit: v8 1.5M I'm getting 305uS and v9 1.5M i'm getting 340uS.
    Last edited by Gibbedy; 09-24-2016 at 05:11 PM.

  7. #432
    Senior Member
    Join Date
    Mar 2013
    Location
    Austin TX
    Posts
    425
    Quote Originally Posted by chlore View Post
    I am attempting to run this library as I require access to the secondary I2C pins and am having trouble sourcing the set of defines that populates the i2c_div_ratio array. Right now only I2C_F_DIV52, 60, 136, 176, and 352 are defined. Everything else errors out. I'll probably just delete everything not defined and keep the ones that are, but if I am missing those defines I may be missing something else as well...

    Thank you.

    -chlore
    uc: teensy3.2 @144mhz IDE: visual micro.


    Edit: Deleting everything not defined removed the errors and now the class works as expected. One more question: if I only need the Wire1 on the 29/30 pins am I required to include the Wire bus as well? Can I set Wire to use the 29/30 pins and then set I2C_BUS_ENABLE 1 to save memory?
    You need to make sure you have the latest Teensyduino installed. The new header file defines in the core Teensyduino files are what defines the majority of the I2C_F_DIVxxx values. Get the latest devel version here and install it:
    https://forum.pjrc.com/threads/37204...ta-1-Available

    The v9 library will perform VERY poorly if you don't do that because it uses the table of dividers to setup the I2C rate, and if those are missing the rate you get will potentially be very wrong.

    If you install latest Teensyduino and also v9 library and you still have I2C_F_DIVxxx problems then let me know.

    No you cannot use Wire1 on Wire pins. This is a hardware limitation. Wire maps to I2C0 interface and Wire1 maps to I2C1 interface and there are limited pin mux options in the hardware (eg. I2C0 only routes to certain pins, and same for I2C1).

  8. #433
    Senior Member
    Join Date
    Mar 2013
    Location
    Austin TX
    Posts
    425
    Quote Originally Posted by Gibbedy View Post
    Running V8 at 400k i2c speed:
    CPU is T_3.1/3.2
    F_CPU =96000000
    ARDUINO =10609
    F_PLL =96000000
    F_BUS =48000000
    F_MEM =24000000
    time it takes to update 1 layer (5 io expanders):687uS

    V8 at 800k:
    CPU is T_3.1/3.2
    F_CPU =96000000
    ARDUINO =10609
    F_PLL =96000000
    F_BUS =48000000
    F_MEM =24000000
    time it takes to update 1 layer (5 io expanders):401

    v8 at 1.2M:

    CPU is T_3.1/3.2
    F_CPU =96000000
    ARDUINO =10609
    F_PLL =96000000
    F_BUS =48000000
    F_MEM =24000000
    time it takes to update 1 layer (5 io expanders):332

    v9 at 400k:
    CPU is T_3.1/3.2
    F_CPU =96000000
    ARDUINO =10609
    F_PLL =96000000
    F_BUS =48000000
    F_MEM =24000000
    i2c speed(getClock()): 400000
    time it takes to update 1 layer (5 io expanders):692

    v9 at 800k:
    CPU is T_3.1/3.2
    F_CPU =96000000
    ARDUINO =10609
    F_PLL =96000000
    F_BUS =48000000
    F_MEM =24000000
    i2c speed(getClock()): 800000
    time it takes to update 1 layer (5 io expanders):445

    v9 at 1.2M:
    PU is T_3.1/3.2
    F_CPU =96000000
    ARDUINO =10609
    F_PLL =96000000
    F_BUS =48000000
    F_MEM =24000000
    i2c speed(getClock()): 1200000
    time it takes to update 1 layer (5 io expanders):373

    I believe v9 working a bit slower for me.
    41uS slower for sending a couple of bytes to 5 mcp23017 io expanders

    edit: v8 1.5M I'm getting 305uS and v9 1.5M i'm getting 340uS.
    Thanks for the benchmarks. This is possibly due to some simplifications that had to be removed. On the v8 code the supported multibus devices (T3.1, T3.2, LC) only had two interfaces, but on the upcoming T3.5 and T3.6 there can be up to four. The v8 code had a bunch of code written like "if bus0 else bus1", wherein anything that was not bus0 was assumed to be bus1. That didn't work anymore on these newer parts so I had to replace it with more conditional checks.

    However a ~10%+ hit seems kind of large to me. I'm not sure exactly what the cause is. I probably can't investigate this in detail just yet, but I'll keep it in mind as something that needs to be checked out.

  9. #434
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    9,693
    Nox771 - posted over here : How-to-minimize-CPU-overhead-of-I2C-128x64-display-Interrupts?

    I was noting the SSD1306 runs I2c at 2.4 MHz - but seems to fail with some bus speeds - is this just a bad gap in the math?

  10. #435
    Senior Member
    Join Date
    Mar 2013
    Location
    Austin TX
    Posts
    425
    Quote Originally Posted by defragster View Post
    Nox771 - posted over here : How-to-minimize-CPU-overhead-of-I2C-128x64-display-Interrupts?
    I was noting the SSD1306 runs I2c at 2.4 MHz - but seems to fail with some bus speeds - is this just a bad gap in the math?
    You'll have to elaborate more on which speeds fail. Specifically if it is any one of the below I would want to know.

    The 120 rate that is giving onehorse trouble is setup as a divide by 30 with a 4x multiplier. Unfortunately there is no direct divide by 120, and the multipliers only have choices of 1x, 2x, or 4x. There is no divide by 60 or 120 settings, so for an exact divide by 120 that's all I'm seeing.

    There are a number of divide ratios that are set like this (using divide ratio multiplier settings), specifically these:
    Code:
        #define I2C_F_DIV52  ((uint8_t)0x43)
        #define I2C_F_DIV60  ((uint8_t)0x45)
        #define I2C_F_DIV120 ((uint8_t)0x85)
        #define I2C_F_DIV136 ((uint8_t)0x4F)
        #define I2C_F_DIV176 ((uint8_t)0x55)
        #define I2C_F_DIV352 ((uint8_t)0x95)
    Now there is a divide by 112 and divide by 128, which are close enough to 120 to be usable. I'm wondering if I should nix the 120 setting and let it choose one of those.

    onehorse - can you run the following test?

    Two edits to i2c_t3.h:
    1) Change the define block at the very top of the i2c_t3.h file to comment out the I2C_F_DIV120 setting:
    Code:
    #ifndef I2C_F_DIV52
        #define I2C_F_DIV52  ((uint8_t)0x43)
        #define I2C_F_DIV60  ((uint8_t)0x45)
    //    #define I2C_F_DIV120 ((uint8_t)0x85)
        #define I2C_F_DIV136 ((uint8_t)0x4F)
        #define I2C_F_DIV176 ((uint8_t)0x55)
        #define I2C_F_DIV352 ((uint8_t)0x95)
        #define I2C_FLT_SSIE    ((uint8_t)0x20)         // Start/Stop Interrupt Enable
        #define I2C_FLT_STARTF  ((uint8_t)0x10)         // Start Detect Flag
    #endif
    2) Farther down in the i2c_t3.h file (about 40% down), there are two array tables defined. Change them as follows to comment out this setting:
    Code:
    // ------------------------------------------------------------------------------------------------------
    // Divide ratio tables
    //
    const int32_t i2c_div_num[] =
        {20,22,24,26,28,30,32,34,36,40,44,48,52,56,60,64,68,72,
         80,88,96,104,112, // 120,
         128,136,144,160,176,192,224,240,256,288,
         320,352,384,448,480,512,576,640,768,896,960,1024,1152,
         1280,1536,1920,1792,2048,2304,2560,3072,3840};
    
    const uint8_t i2c_div_ratio[] =
        {I2C_F_DIV20,I2C_F_DIV22,I2C_F_DIV24,I2C_F_DIV26,
         I2C_F_DIV28,I2C_F_DIV30,I2C_F_DIV32,I2C_F_DIV34,
         I2C_F_DIV36,I2C_F_DIV40,I2C_F_DIV44,I2C_F_DIV48,
         I2C_F_DIV52,I2C_F_DIV56,I2C_F_DIV60,I2C_F_DIV64,
         I2C_F_DIV68,I2C_F_DIV72,I2C_F_DIV80,I2C_F_DIV88,
         I2C_F_DIV96,I2C_F_DIV104,I2C_F_DIV112, // I2C_F_DIV120,
         I2C_F_DIV128,I2C_F_DIV136,I2C_F_DIV144,I2C_F_DIV160,
         I2C_F_DIV176,I2C_F_DIV192,I2C_F_DIV224,I2C_F_DIV240,
         I2C_F_DIV256,I2C_F_DIV288,I2C_F_DIV320,I2C_F_DIV352,
         I2C_F_DIV384,I2C_F_DIV448,I2C_F_DIV480,I2C_F_DIV512,
         I2C_F_DIV576,I2C_F_DIV640,I2C_F_DIV768,I2C_F_DIV896,
         I2C_F_DIV960,I2C_F_DIV1024,I2C_F_DIV1152,I2C_F_DIV1280,
         I2C_F_DIV1536,I2C_F_DIV1920,I2C_F_DIV1792,I2C_F_DIV2048,
         I2C_F_DIV2304,I2C_F_DIV2560,I2C_F_DIV3072,I2C_F_DIV3840};
    Let me know if this works for your 96MHz, 400kHz setup. It's really too bad, this is a very common config and not being able to get an exact 400kHz is unfortunate.

  11. #436
    Senior Member onehorse's Avatar
    Join Date
    Apr 2014
    Location
    Danville, California
    Posts
    921
    Hi Brian,

    This works now with an I2C frequency of ~428 kHz:

    I2C clock rate = 428571 Hz
    F_CPU =96000000
    ARDUINO =10608
    F_PLL =96000000
    F_BUS =48000000
    F_MEM =24000000
    NVIC_NUM_INTERRUPTS =95
    DMA_NUM_CHANNELS =16
    CORE_NUM_TOTAL_PINS =34
    CORE_NUM_DIGITAL =34
    CORE_NUM_INTERRUPT =34
    CORE_NUM_ANALOG =21
    CORE_NUM_PWM =12


    But is this specific to this particular board or is this a generic problem with the Teensy or what? I mean if it is just this one sensor board I think I would rather just choose the clock frequencies that work for it and leave the library alone...

  12. #437
    Senior Member
    Join Date
    Mar 2013
    Location
    Austin TX
    Posts
    425
    I can't say. This frequency divide ratio goes back to v1 of the library, so it's been around a while. That said maybe something changed on more recent T3.2 parts (maybe they did something on the die), so perhaps it just doesn't work right anymore. Or maybe it never worked right and nobody complained about it. I've used the setting plenty of times myself and didn't have a problem, but I have a very limited set of slaves.

    The standard Wire library does not use this ratio, it uses a divider of 112 for this setting, so the same setting as you are getting now. So in that sense for consistency it makes sense to get rid of it, and then it will match what Wire is doing. I'll probably upload a patch for it soon.

    I'd be interested to know if defragster had trouble with this same setting or something else.

  13. #438
    Senior Member
    Join Date
    Mar 2013
    Location
    Austin TX
    Posts
    425
    Quote Originally Posted by defragster View Post
    Nox771 - posted over here : How-to-minimize-CPU-overhead-of-I2C-128x64-display-Interrupts?

    I was noting the SSD1306 runs I2c at 2.4 MHz - but seems to fail with some bus speeds - is this just a bad gap in the math?
    Using the info from the other thread, as I understand it this is the situation:
    Code:
    F_CPU  F_BUS  I2C_Target  Works  Divider  I2C_Rate
    ==================================================
     180M    60M    2.4M        N      24?      2.5M
     120M    60M    2.4M        N      24?      2.5M
      96M    48M    2.4M        N      20       2.4M
     180M    90M    2.4M        Y      36?      2.5M
     240M   120M    2.4M        Y      48?      2.5M
     240M    80M    2.4M        Y      34?     ~2.35M
    
    Is that right?

    If so, the common factor I see is when the divide ratios are low it fails, and when they are high it works. The HW Start/Stop timings and delays are dependent on these same settings, so it may be the case that the slave devices are sensitive to these timings, and at these low ratios they just don't work well. I don't necessarily see a fix being needed here, other than find settings that work well with the particular slaves in question (which may involve running the bus high to get a high divide ratio).

    The 96M/48M/2.4M one is odd though, I've personally run that setting a lot and never had trouble with it. I do have a number of SSD1306, and IIRC I was able to get them to sometimes work at top rate, but for reliable operation I had to drop the rate to a lower setting.

  14. #439
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    9,693
    @nox771 your summary above looks right . . . now using the i2c_t3 from TD_1.31b1 - my sketchbook version didn't have getClock - I see the same effect - default compile of 180M with F_BUS==60M fails at 2.4M I2c speed.

    Here is my HACKED sketch { opps missed delay(1000)'s in testscrolltext()}:: ssd1306_128x64_i2c_925.ino
    This edit to adafruit_SSD1306.cpp:
    //#include <Wire.h>
    #include <i2c_t3.h>
    Printing with getClock here are results - the 2.5 math is the same getClock at 180 with 60 and 90 F_BUS - but something else is wrong see the elapsed micros:

    This FAILS:: { Note the failure is a still screen - but the indicated "2,400 elapsed Micros=2704" is also TOO LOW! }
    --- Hello World ---
    F_CPU =180000000 F_PLL =180000000 F_BUS =60000000 F_MEM =25714286
    DEFAULT Wire1306.getClock() =104166

    400 elapsed Micros=31327
    Wire1306.getClock() =416666
    2,400 elapsed Micros=2704
    Wire1306.getClock() =2500000
    This Works::
    --- Hello World ---
    F_CPU =180000000 F_PLL =180000000 F_BUS =90000000 F_MEM =25714286
    DEFAULT Wire1306.getClock() =100446

    400 elapsed Micros=30983
    Wire1306.getClock() =401785
    2,400 elapsed Micros=9759
    Wire1306.getClock() =2500000
    This Works::
    --- Hello World ---
    F_CPU =240000000 F_PLL =240000000 F_BUS =80000000 F_MEM =30000000
    DEFAULT Wire1306.getClock() =104166

    400 elapsed Micros=29927
    Wire1306.getClock() =416666
    2,400 elapsed Micros=9376
    Wire1306.getClock() =2352941
    Last edited by defragster; 09-26-2016 at 12:07 AM.

  15. #440
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    9,693
    @onehorse: In your sample that fails I wonder if you might see any time dilation like I do when the clock speed combo goes to not working?

    Can you set up a timer around a series of calls that takes measurable time when it works say : "with an I2C frequency of ~428 kHz". Then get back to using the near 400 kHz version where it fails and see how long the same loop takes?

    In my post #439 on the same F_CPU the slower bus @60 completes the test 3.6 times faster when it fails than with the faster bus @90 when it runs properly.

    If you can see the same issue with a clock reference then it would show a common issue where the I2c is jamming the data out too fast for the device to be responding to. Then nox771 might be able to see and correct the behavior with one of his SSD1306 units.

    BTW: glancing at the i2c_t3 sources I saw that 2.8 and 3.0 MHz were defined - and when it fails the same 'completes too fast' behavior follows.

    I see that the SSD1306 can run at both these speeds with the right bus speeds:
    --- Hello World ---
    F_CPU =240000000 F_PLL =240000000 F_BUS =80000000 F_MEM =30000000
    DEFAULT Wire1306.getClock() =104166
    2,400 elapsed Micros=9344
    Wire1306.getClock() =2352941
    2,800 elapsed Micros=2155 // FAIL
    Wire1306.getClock() =2857142

    --- Hello World ---
    F_CPU =240000000 F_PLL =240000000 F_BUS =120000000 F_MEM =30000000
    DEFAULT Wire1306.getClock() =104166
    2,400 elapsed Micros=8450
    Wire1306.getClock() =2500000
    2,800 elapsed Micros=8133
    Wire1306.getClock() =2727272
    3,000 elapsed Micros=7690
    Wire1306.getClock() =3000000
    Last edited by defragster; 09-26-2016 at 04:35 AM.

  16. #441
    Senior Member
    Join Date
    Mar 2013
    Location
    Austin TX
    Posts
    425
    Quote Originally Posted by defragster View Post
    but something else is wrong see the elapsed micros:
    This FAILS:: { Note the failure is a still screen - but the indicated "2,400 elapsed Micros=2704" is also TOO LOW! }
    Not sure what is causing this, but to isolate the timing better you should capture the elapsedMicros before printing it, eg. uint32_t delay = i2cTime; Serial.print("..."); Serial.println(delay); Otherwise you're capturing the Serial.print latency also.

    This method is also subject to interrupt priority delays. Maybe run the library in immediate mode instead of interrupt, eg. Wire.setOpMode(I2C_OP_MODE_IMM); Actually I'm not sure if that does it either, may need to force priority zero on the I2C0 ISR.

    btw - your also zeroing i2cTime in testdrawbitmap() function.

  17. #442
    Senior Member
    Join Date
    Mar 2013
    Location
    Austin TX
    Posts
    425
    Quote Originally Posted by defragster View Post
    In my post #439 on the same F_CPU the slower bus @60 completes the test 3.6 times faster when it fails than with the faster bus @90 when it runs properly.
    The reason it's finishing fast is that the I2C bus will terminate the transfer if the slave fails to ACK the transmission. If error checks were added in it would probably be responding with ADDR NAK errors. It's the result of one-way communication and no error checks...

  18. #443
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    9,693
    I said it was HACKED . . . I assumed the USB delay would be minimal and consistent - corrected here:: ssd1306_128x64_i2c_925.ino

    BTW:: I am resetting speed multiple times in my test - but I have confirmed that with only a single adjustment to a failing speed - it still fails.
    Also noted that below the getClock values are different in the fail case versus success - but above combination Post_439 has them identical at 2500000 and one fails the other not.

    I also removed the bogus zero of the timer in mid test of cut and pasted code . . .

    This SSD1306 is really BLAZING at 3 MHz!!!!

    --- Hello World ---
    F_CPU =240000000 F_PLL =240000000 F_BUS =80000000 F_MEM =30000000
    DEFAULT Wire1306.getClock() =104166
    2,400 elapsed Micros=3006211
    Wire1306.getClock() =2352941
    2,800 elapsed Micros=651214 // FAIL
    Wire1306.getClock() =2857142
    3,000 elapsed Micros=643681 // FAIL
    Wire1306.getClock() =3076923


    --- Hello World ---
    F_CPU =240000000 F_PLL =240000000 F_BUS =120000000 F_MEM =30000000
    DEFAULT Wire1306.getClock() =104166
    2,400 elapsed Micros=2714994
    Wire1306.getClock() =2500000
    2,800 elapsed Micros=2600331
    Wire1306.getClock() =2727272
    3,000 elapsed Micros=2483040
    Wire1306.getClock() =3000000
    Last edited by defragster; 09-26-2016 at 04:55 AM.

  19. #444
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    9,693
    Quote Originally Posted by nox771 View Post
    The reason it's finishing fast is that the I2C bus will terminate the transfer if the slave fails to ACK the transmission. If error checks were added in it would probably be responding with ADDR NAK errors. It's the result of one-way communication and no error checks...
    You know this way better than I do - the failure to ACK is seen that fast?

    In any case for a well formed transaction this shows the device is not incapable of maintaining that 3 MHz speed. My T_3.6 [F_CPU =240000000 F_BUS =120000000 ] is running my SSD1306 at Wire1306.getClock() =3000000 for 10-20 minutes with no problem as posted in #443

  20. #445
    Senior Member
    Join Date
    Mar 2013
    Location
    Austin TX
    Posts
    425
    When the master sends an initial request to a slave the first byte is the address. If the slave doesn't ACK the address there is either no slave or it is unresponsive. This gives a ADDR NAK error (since this is the first byte it can happen very quickly). As the communication is going, each byte ends with an ACK bit, if the slave fails to ACK then it results in a DATA NAK error (sometimes slaves do this intentionally because their input buffer is full).

    Either error will stop the transmission, which in the case of a display, wherein maybe you are sending a bitmap or some other long transmission, it will get cut much shorter than the normal length.

    So I can't say definitively this is what's happening, but it is a very likely explanation (with respect to transfer speed appearing "fast"). A logic analyzer would easily show the situation if that was occurring.

    If you look at the divider and hold table, the SCL start/stop and SDA hold delays vary with divider setting. It is possible that these settings are the problem with respect to whether the chosen rate works or not. If so, there isn't much to be done about it besides picking a value that works and moving on (which may or may not yield the exact freq one wants, as with the 120 divider).

    Click image for larger version. 

Name:	screenshot.676.jpg 
Views:	68 
Size:	176.7 KB 
ID:	8276

  21. #446
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    9,693
    I don't have history with or access to an LA or Scope. No doubt something is breaking the timing that otherwise works well - even at the 'same getClock()' value like in p#439.

    Very cool to see SSD1306 can work so fast - just not at the default rates as tested in p#439:: F_CPU =180000000 F_BUS =60000000.

    The device is not going offline - just re-ordered this test case where after failing - it then picks up normal behavior at a working speed combination - which happens to be slower:

    --- Hello World ---
    F_CPU =240000000 F_PLL =240000000 F_BUS =80000000 F_MEM =30000000
    DEFAULT Wire1306.getClock() =104166
    2,800 elapsed Micros=651922
    Wire1306.getClock() =2857142
    2,400 elapsed Micros=3005574
    Wire1306.getClock() =2352941
    T_3.1 running the same sketch - 2.4 MHz runs great - maxes out at Wire1306.getClock() =2400000
    --- Hello World ---
    F_CPU =96000000 F_PLL =96000000 F_BUS =48000000 F_MEM =24000000
    DEFAULT Wire1306.getClock() =100000
    2,400 elapsed Micros=3575018
    Wire1306.getClock() =2400000
    Last edited by defragster; 09-26-2016 at 08:04 AM.

  22. #447
    Senior Member
    Join Date
    Jan 2015
    Location
    SF Bay Area
    Posts
    255
    I2C_AUTO_RETRY

    I used this library because I need to use the alternate i2c pins for teensy 3.2, and noticed I am getting an error (or the slave device is returning an error message).

    I hooked up a logic analyzer and can see a send from teensy getting resent after a read from a second slave device. I checked my code to make sure I am only sending the command once and I could not figure out why the resend till I found the option I2C_AUTO_RETRY, which is enabled by default. I don't see any I2C protocol issue. The error the slave is returning is because it received the command twice.

    I don't get any more error after commenting out the I2C_AUTO_RETRY define. I think this should be disabled by default.

  23. #448
    Senior Member
    Join Date
    Mar 2013
    Location
    Austin TX
    Posts
    425
    Quote Originally Posted by doughboy View Post
    I2C_AUTO_RETRY

    I used this library because I need to use the alternate i2c pins for teensy 3.2, and noticed I am getting an error (or the slave device is returning an error message).

    I hooked up a logic analyzer and can see a send from teensy getting resent after a read from a second slave device. I checked my code to make sure I am only sending the command once and I could not figure out why the resend till I found the option I2C_AUTO_RETRY, which is enabled by default. I don't see any I2C protocol issue. The error the slave is returning is because it received the command twice.

    I don't get any more error after commenting out the I2C_AUTO_RETRY define. I think this should be disabled by default.
    That's quite odd. Retry should not be doing anything unless it has trouble acquiring the bus. I have a pending update to remove the 120 divide ratio, so I'll disable the default when that update happens. I don't have time to investigate further at the moment, but I'll make a note of it.

  24. #449
    Senior Member
    Join Date
    Mar 2013
    Location
    Austin TX
    Posts
    425
    Quote Originally Posted by doughboy View Post
    I don't get any more error after commenting out the I2C_AUTO_RETRY define. I think this should be disabled by default.
    I have uploaded a new version with aforementioned fixes to GitHub and the 1st post.

    Looking at the code though, it seems to me for I2C_AUTO_RETRY to be causing a problem you must be running with timeouts enabled, and the timeout must be too short for your rate setting. Is that the case?

  25. #450
    Senior Member
    Join Date
    Jan 2015
    Location
    SF Bay Area
    Posts
    255
    I did not specify timeout. Is timeout the only way auto retry can be triggered?
    the send then receive signals looked fine, and the resend went out immediately after the receive. Come to think of it, I think that means the "reset" sequence, which should take up some time, did not occur right? The MK20 I2C does not auto resend right?
    Last edited by doughboy; 10-17-2016 at 03:56 AM.

Posting Permissions

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