Forum Rule: Always post complete source code & details to reproduce any issue!
Page 2 of 2 FirstFirst 1 2
Results 26 to 46 of 46

Thread: Arduino 1.8.3

  1. #26
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    21,467
    Ok, still no Arduino 1.8.3. Odds are slim they'll release over the weekend.

    I'm packing up a 1.37-beta1 now, so we can all play with the new stuff.

    Edit, here it is: https://forum.pjrc.com/threads/44546...no-1-37-Beta-1

  2. #27
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    6,325
    Thanks Paul,

    I was also wondering if it would make sense to add a new API that takes care of it for you... Something like:
    static SPIClass *mapPinsToBuss(uint8_t sck, uint8_t mosi=0xff, uint8_t miso=0xff)

    Then user classes/programs, could simply pass the values in a get a pointer to the appropriate buss... Thought maybe could be reference instead, but not sure if references work inside classes very well unless used in constructor...

    Also in my version I had functions to return back a pointer to the KINETISK_SPI or KINESTL_SPI registers... (Also in case of K how big the Queue sizes are)
    I find them useful for programs that which to work like the ILI9341_t3 library, but not sure how many might want it... Should probably take that part up later..

    Again thanks!

  3. #28
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    4,806
    Was doing some troubleshooting with the usb2.0 library and I got it working by changing buffered spi.transfers with essentially single byte transfers.(posted here https://forum.pjrc.com/threads/44413...l=1#post144890 ) When @jgeorge suggested that I download the latest SPI library and give it a try. So of course I did but on compile of the board_qc sketch I received the following error:
    Code:
    C:\Local Programs\arduino-1.8.2\hardware\teensy\avr\libraries\SPI\SPI.cpp:191:10: error: 'DMAMUX_SOURCE_SPI1' was not declared in this scope
    
      511, 0, DMAMUX_SOURCE_SPI1,
    
              ^
    
    C:\Local Programs\arduino-1.8.2\hardware\teensy\avr\libraries\SPI\SPI.cpp:210:10: error: 'DMAMUX_SOURCE_SPI2' was not declared in this scope
    
      511, 0, DMAMUX_SOURCE_SPI2,
    
              ^
    Just wanted to let you know on this thread as well just in case.

    Mike
    Last edited by mjs513; 06-03-2017 at 04:24 AM.

  4. #29
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    6,325
    Probably needed updated core file kinetis...h. I think my version had a conditional define if it was not defined. Although if my async apis were not included, then probably not used, can probably, just change to 0...

  5. #30
    Senior Member
    Join Date
    Jan 2013
    Posts
    843
    Quote Originally Posted by KurtE View Post
    Thanks Paul,

    I was also wondering if it would make sense to add a new API that takes care of it for you... Something like:
    static SPIClass *mapPinsToBuss(uint8_t sck, uint8_t mosi=0xff, uint8_t miso=0xff)
    There could be multiple SPI modules per pin. I don't think this is the case for current Teensies (except for shared hardware chip selects), but there are MCUs that can remux all pins to anything.

    Simply returning the first SPI module that supports the pin isn't a good choice. The SPI module most likely can only use a single set of pins but different SPI library users may end up wanting to use it with different pin sets.

    So for the larger Arduino picture, there needs to be a way to select both pins and a specific SPI module.

  6. #31
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    6,325
    @tni - I understand what you are saying. Which is why when we have code adapting to the ability for multiple SPI objects, I would suggest allowing them to pass in pointer or reference to desired SPI object. But it is nice to allow code to recover if they don't... For example in my Teensyview code I first try to verify if the passed in pins are valid on the SPI object that was passed in (Note I default to SPI in the header). If they are not valid, I try to then recover and see if there is an SPI buss that will work... So was wondering if we should make that easier and provide a helper function.

    @mjs513 - Again a couple of possible fixes
    a) Grab the Kinetis.h file from the beta...
    b) Edit SPI.cpp and add some defines maybe around line 168 like:
    Code:
    #if defined(__MK64FX512__)  && !defined( DMAMUX_SOURCE_SPI1)
    #define DMAMUX_SOURCE_SPI1		16
    #define DMAMUX_SOURCE_SPI2		17
    #endif
    @Paul and @mjs513 - There is part of my Hardware objects here including this one that is only needed if we are going to include my ASYNC (DMA) transfer code. I will try to do a quick Delta (PR) to this to remove some of this (hopefully for just now)...

  7. #32
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    21,467
    Please install 1.37-beta1 to resolve the missing symbols.

    Let's leave the DMA hardware description in place. It only adds a few extra bytes of flash usage. Keeping it in the released SPI lib will make experimenting with DMA easier.

    On the matter of representing hardware capability, I'd prefer to take a slow & deliberate approach. The future is likely to bring far more configurable hardware. In addition to more flexible pin assignment, some new chips are providing flexible switch matrix interconnect and even some programmable logic for internal event, interrupt & DMA signals. NXP/Freecale's new KV5 chips (which are meant for machine control and lack USB) are one example. I must admit, at this point I'm still having a hard time trying to imagine the incredible flexibility this will bring....

    On async APIs, I'm concerned about offering interrupt context callbacks.

  8. #33
    Senior Member
    Join Date
    Jan 2013
    Posts
    843
    Did you decide against C++14?

  9. #34
    Senior Member+ Theremingenieur's Avatar
    Join Date
    Feb 2014
    Location
    Colmar, France
    Posts
    2,558
    Quote Originally Posted by tni View Post
    Did you decide against C++14?
    Apparently he did. See my comment in the td 1.37 beta thread

  10. #35
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    6,325
    Thanks Paul,

    I have an updated version of the Sparkfun_teensyview code that I have modified to use this verison. Had to remove (#ifdef) out code that uses the transfer buffer function (so instead does copy to temp locations and then output with the destructive buffer transfer). Also #ifdef out the Async support.

    I now have tried it out on T3.5 on SPI/SPI1/SPI2... So that part is working! Will try out on at least one or two other boards as well...

    Only testing using one display at a time. My multi-display test relies too much on ASYNC support... But may update to round robin

    Also thinking of generating a version of the Adafruit_SSD1306 code to work with this as well. However I strongly dislike that they have you edit the the header file to define if you are using 32 line or 64 line displays. I understand why they did this, as to be able to define the right size buffer without using malloc... I may instead use two sub-classes for this....

    As for the Async API - With callback on Interrupt... I see a couple of options here:
    a) Don't support async... Obviously the easiest.
    b) Don't have callback function, the user has to query to see if it is done or not.
    c) Could do on interrupt as I have it... So far I did not run into issues, but...
    d) Maybe could setup to have the yield function be able to do the callback...

    Which reminds me - Should I try to implement a version of yield, where maybe we generate a bitmask of possible things to test. So We only test Serial1 if Serial1 has had begin called... And the default SerialEvent callback functions will unset this option... So then for those apps that have not implemented any serialEvent functions, hopefully soon the code will reduce to simply checking the bitmask and return...

  11. #36
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    21,467
    Quote Originally Posted by tni View Post
    Did you decide against C++14?
    Yes and no...

    Yes, for 1.37 I believe going from gnu++0x to gnu++14 is too big a jump. I want to have at least 2 stable releases using gnu++11. Or perhaps even 1 release will be enough, if there are no issues. If compatibility problems are found, we might need more than 2.

    And no, gnu++14 has not been ruled out, only delayed. Perhaps I'm being a little too paranoid? But *any* compile error in any of the thousands of Arduino libraries, many of which are poorly written by authors not even enabling compiler warnings, is a huge problem for novice users.

  12. #37
    Senior Member
    Join Date
    Jan 2013
    Posts
    843
    Quote Originally Posted by PaulStoffregen View Post
    Yes, for 1.37 I believe going from gnu++0x to gnu++14 is too big a jump. I want to have at least 2 stable releases using gnu++11.
    gnu++11 is exactly the same as gnu++0x (except for the flag name being deprecated).

    https://gcc.gnu.org/onlinedocs/gcc/C...t-Options.html

  13. #38
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    4,806
    I updated to 1.37 beta usind IDE 1.8.2 just now and ran it with Host Shield 2.0 without any modifications and it worked fine with no need for my crazy work around which is a good thing. Looks like the changes made to SPI cleared up the issues I was having with SPI and Host Shield 2.0.

    Also, compiled for a sketch that I am using that uses vector and received the following error message:
    Arduino: 1.8.2 (Windows 10), TD: 1.37-beta1, Board: "Teensy 3.5, Serial, 120 MHz, Faster, US English"

    Code:
    In file included from c:\local programs\arduino-1.8.2\hardware\tools\arm\arm-none-eabi\include\c++\5.4.1\vector:60:0,
    
                     from C:\Users\CyberPalin\Documents\Arduino\TeensyOpenMV\TeensyOpenMV.ino:7:
    
    c:\local programs\arduino-1.8.2\hardware\tools\arm\arm-none-eabi\include\c++\5.4.1\bits\stl_algobase.h:243:56: error: macro "min" passed 3 arguments, but takes just 2
    
         min(const _Tp& __a, const _Tp& __b, _Compare __comp)
    
                                                            ^
    
    c:\local programs\arduino-1.8.2\hardware\tools\arm\arm-none-eabi\include\c++\5.4.1\bits\stl_algobase.h:265:56: error: macro "max" passed 3 arguments, but takes just 2
    
         max(const _Tp& __a, const _Tp& __b, _Compare __comp)
    
                                                            ^
    Line 7 is just the declaration #include <vector>. Compiled no issue with 1.36.

    Also, ran the TeensyThreads test sketch and passed all tests.

    Mike

  14. #39
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    6,325
    @paul - not sure if I should move to different thread for SPI updates for this release?

    But wondering: How best to know how many SPI Interfaces are supported by the current board?

    Lots of old code probably does it by doing things like:
    Test for T3.5/6 or LC to know that SPI1 is valid
    Test for T3.5/6 for SPI2 valid...

    I have in my version of SPI #define SPI_INTERFACES_COUNT
    As that is what I believe many oof the other SPI implementations use it (Arduino SAMD, SAM) and those derived from them Adafruit...

    Could do like you did in Wire library
    #elif defined(__MK64FX512__)
    #define WIRE_IMPLEMENT_WIRE
    #define WIRE_IMPLEMENT_WIRE1
    #define WIRE_IMPLEMENT_WIRE2

    Which is sort of similar how we can also check for UARTS.

    ------------------------------------------------------------------------------------------------
    Edit: Thought I would mention, that I have a version of the Sparkfun_Teensyview which is working with new version of SPI, where I can have multiple Teensyview or other SSD1306 displays working.
    https://github.com/KurtE/SparkFun_Te...e/Multiple-SPI

    Note: I hacked the library to define the SPI_INTERFACES_COUNT...

    I have a version of my test program, that tries to define one of these displays for each SPI interface each board has. The first one is defined as 32 lines wide (Teensyview), the 2nd a 64 line version (Purchased a few from amazon), and 3rd another Teensyview...

    So far this morning I have tested on:
    T3.5 - All three busses
    T3.2 - One buss
    TLC - Both Busses.

    Test program:
    Code:
    /******************************************************************************
    TeensyView_Demo.ino
    SFE_TeensyView Library Demo
    Jim Lindblom @ SparkFun Electronics
    Original Creation Date: October 27, 2014
    Modified Febuary 2, 2017
    This sketch uses the TeensyView library to draw a 3-D projected
    cube, and rotate it along all three axes.
    Development environment specifics:
    Arduino IDE 1.6.12 w/ Teensyduino 1.31
    Arduino IDE 1.8.1 w/ Teensyduino 1.35
    TeensyView v1.0
    This code is beerware; if you see me (or any other SparkFun employee) at thewa
    local, and you've found our code helpful, please buy us a round!
    Distributed as-is; no warranty is given.
    ******************************************************************************/
    #include <SPI.h>
    #include <TeensyView.h> // Include the SFE_TeensyView library
    // /////////////////////////////////
    // TeensyView Object Declaration //
    // /////////////////////////////////
    // #define TLC_SPI1
    // #define T36_SPI1
    // #define T36_SPI2
    // #define DEFAULT_PINS
    
    #ifdef DEFAULT_PINS
    #define PIN_RESET 15
    #define PIN_DC 5
    #define PIN_CS 10
    #define PIN_SCK 13
    #define PIN_MOSI 11
    #endif
    
    #ifdef TLC_SPI1
    #define PIN_RESET 15
    #define PIN_SCK 20
    #define PIN_MOSI 21
    #define PIN_DC 4
    #define PIN_CS 3
    #endif
    
    #ifdef T36_SPI1
    #define PIN_RESET 15
    #define PIN_SCK 20
    #define PIN_MOSI 21
    #define PIN_DC 31
    #define PIN_CS 32
    #endif
    
    #ifdef T36_SPI2
    #define PIN_RESET 15
    #define PIN_SCK 53
    #define PIN_MOSI 52
    #define PIN_DC 55
    #define PIN_CS 51
    #endif
    
    // Kurt's setup
    
    #ifndef PIN_SCK
    
    #if defined(KINETISK)
    #define PIN_RESET 15
    #define PIN_SCK 13
    #define PIN_MOSI 11
    #define PIN_DC 21
    #define PIN_CS 20
    // Setup 2nd one SPI1
    #define PIN_RESET1 16
    #define PIN_SCK1 32
    #define PIN_MOSI1 0
    #define PIN_DC1 31
    #define PIN_CS1 30
    
    #elif defined(KINETISL)  // Teensy LC
    // For multiple need to change CS to not 20 as only valid sck1 on lc
    #define PIN_RESET 15
    #define PIN_SCK 13
    #define PIN_MOSI 11
    #define PIN_DC 21
    #define PIN_CS 22
    // #undef SPI_INTERFACES_COUNT
    // #define SPI_INTERFACES_COUNT 1
    #define PIN_RESET1 16
    #define PIN_SCK1 20
    #define PIN_MOSI1 0
    #define PIN_DC1 6
    #define PIN_CS1 7
    #else // AVR... T2 SS(0), SCK(1), MOSI(2), MISO(3)
    #define PIN_RESET 5
    #define PIN_SCK 13
    #define PIN_MOSI 11
    #define PIN_DC 4
    #define PIN_CS 0
    #endif
    
    // Pins on connector on Beta T3.6 board (3.3, GND)(48, 47)(57 56) (51 52) (53 55)
    #define PIN_RESET2 48
    // #define PIN_MISO2 51
    #define PIN_MOSI2 52
    #define PIN_SCK2 53
    #define PIN_DC2 55
    #define PIN_CS2 56
    #endif
    
    TeensyView32 oled(PIN_RESET, PIN_DC, PIN_CS, PIN_SCK, PIN_MOSI);
    
    #if SPI_INTERFACES_COUNT > 1
    TeensyView64 oled1(PIN_RESET1, PIN_DC1, PIN_CS1, PIN_SCK1, PIN_MOSI1);
    
        #if SPI_INTERFACES_COUNT > 2
    TeensyView32 oled2(PIN_RESET2, PIN_DC2, PIN_CS2, PIN_SCK2, PIN_MOSI2);
        #endif
    
    #endif
    
    #ifdef SPI_HAS_TRANSFER_ASYNC
    #define DO_ASYNC true
    #define DISPLAYFUNC displayAsync
    #else
    #define DO_ASYNC false
    #define DISPLAYFUNC display
    #endif
    
    
    TeensyView * oleds[] =
    {
    #if 0
        & oled,
        & oled1
    #else  
        & oled
    
    #if SPI_INTERFACES_COUNT > 1
        , & oled1
    
        #if SPI_INTERFACES_COUNT > 2
        , & oled2
        #endif
    #endif
    #endif
    
    };
    
    uint8_t oled_which_test[] =
    {
        0, 0, 0
    };
    
    uint16_t test_iterations_left[] =
    {
        0xffff, 0xffff, 0xffff
    };
    
    uint32_t last_test_start_time[] =
    {
        0, 0, 0
    };
    
    uint32_t next_test_start_time[] =
    {
        0, 0, 0
    };
    
    extern void testRects(TeensyView * _oled, bool draw_async, uint16_t & iterations_left);
    extern void testCircles(TeensyView * _oled, bool draw_async, uint16_t & iterations_left);
    extern void TestpixelsAsync(TeensyView * _oled, uint16_t & iterations_left);
    extern void TestFillRects(TeensyView * _oled, uint16_t & iterations_left);
    extern void testdrawline(TeensyView * _oled, uint16_t & iterations_left, uint32_t & next_test_start_time);
    extern void testscrolltext(TeensyView * _oled, uint16_t & iterations_left, uint32_t & next_test_start_time);
    void setup()
    {
        pinMode(2, OUTPUT);
        digitalWrite(2, LOW);
        pinMode(3, OUTPUT);
        digitalWrite(3, LOW);
        while (!Serial && millis() < 3000);
        Serial.begin(38400);
        oled.begin(); // Initialize the OLED
        oled.display(); // Display what's in the buffer (splashscreen)
    
    #if SPI_INTERFACES_COUNT > 1
        oled1.begin(); // Initialize the OLED
        oled1.display(); // Display what's in the buffer (splashscreen)''
        Serial.println("oled1 displayed");
    #endif
    
    #if SPI_INTERFACES_COUNT > 2
        oled2.begin(); // Initialize the OLED
        oled2.display(); // Display what's in the buffer (splashscreen)''
        Serial.println("oled2 displayed");
    #endif
    
        delay(1000); // Delay 1000 ms
        oled.clear(HARDWARE_MEM); // Clear the buffer.
    
    #if SPI_INTERFACES_COUNT > 1
        oled1.clear(HARDWARE_MEM); // Clear the buffer.
    #endif
    
    #if SPI_INTERFACES_COUNT > 2
        oled2.clear(HARDWARE_MEM);
    #endif
    #ifdef A1
        randomSeed(analogRead(A0) + analogRead(A1));
    #else
       randomSeed(analogRead(A0) + (analogRead(A0)<<1));
    #endif    
    }
    
    void loop()
    {
        // Lets see which of our displays is ready to display something different
        for (uint8_t i = 0; i < sizeof(oleds) /sizeof(oleds[0]); i++)
        {
    #ifdef SPI_HAS_TRANSFER_ASYNC
            if ((millis() > next_test_start_time[i]) && !oleds[i] -> displayAsyncActive())
    #else
            if ((millis() > next_test_start_time[i]))
    #endif
            {
                last_test_start_time[i] = millis();
                switch (oled_which_test[i])
                {
                    case 0:
                        testRects(oleds[i], DO_ASYNC, test_iterations_left[i]);
                        break;
                    case 1:
                        testRects(oleds[i], DO_ASYNC, test_iterations_left[i]);
                        break;
                    case 2:
                        TestpixelsAsync(oleds[i], test_iterations_left[i]);
                        break;
                    case 3:
                        TestFillRects(oleds[i], test_iterations_left[i]);
                        break;
                    case 4:
                        testdrawline(oleds[i], test_iterations_left[i], next_test_start_time[i]);
                        break;
                    case 5:
                        testscrolltext(oleds[i], test_iterations_left[i], next_test_start_time[i]);
                        break;
                }
                if (test_iterations_left[i] == 0)
                {
                    oled_which_test[i] ++;
                    if (oled_which_test[i] > 5)
                        oled_which_test[i] = 0;
                    test_iterations_left[i] = 0xffff; // mark it special for first call
                    next_test_start_time[i] = millis() + 100;
                }
            }
            else
                if ((millis() - last_test_start_time[i]) > 2500)
                {
                    Serial.printf("Oled %d hung test: %d iter: %d\n ", i, oled_which_test[i], test_iterations_left[i]);
                    printDebugInfo(oleds[i]);
                    last_test_start_time[i] = millis();
                }
        }
    }
    
    void printDebugInfo(TeensyView * _oled)
    {
    
    #ifdef KINETISK
    
      #ifdef SPI_DEBUG_ASYNC_T3X
        extern void dumpDMA_TCD(const char * psz, DMABaseClass * dmabc);
        dumpDMA_TCD("TX:", _oled -> _spi -> _dmaTX);
        dumpDMA_TCD("RX:", _oled -> _spi -> _dmaRX);
      #endif  
    #else
    
            #ifdef SPI_DEBUG_ASYNC_LC
        extern void dumpDMA_CFG(const char * sz, DMABaseClass * dmabc);
        dumpDMA_CFG("TX:", _oled -> _spi -> _dmaTX);
        dumpDMA_CFG("RX:", _oled -> _spi -> _dmaRX);
            #endif
    
    #endif
    
    }
    
    void testRects(TeensyView * _oled, bool draw_async, uint16_t & iterations_left)
    {
        int n, i, i2;
        int cx = _oled -> getLCDWidth() / 2;
        int cy = _oled -> getLCDHeight() / 2;
        _oled -> clear(PAGE);
        n = min(_oled -> getLCDWidth(), _oled -> getLCDHeight());
        for (i = 2; i < n; i += 6)
        {
            i2 = i / 2;
            _oled -> rect(cx - i2, cy - i2, i, i);
        }
        if (draw_async)
        {
            _oled -> DISPLAYFUNC();
        }
        else
        {
            _oled -> display();
        }
        iterations_left = 0;
    }
    
    void testCircles(TeensyView * _oled, bool draw_async, uint16_t & iterations_left)
    {
        uint16_t radius = 10;
        int x, y, r2 = radius * 2,
        w = _oled -> getLCDWidth() + radius,
        h = _oled -> getLCDHeight() + radius;
        _oled -> clear(PAGE);
        for (x = 0; x < w; x += r2)
        {
            for (y = 0; y < h; y += r2)
            {
                _oled -> circle(x, y, radius);
            }
        }
        if (draw_async)
        {
            _oled -> DISPLAYFUNC();
        }
        else
        {
            _oled -> display();
        }
        iterations_left = 0;
    }
    
    void TestpixelsAsync(TeensyView * _oled, uint16_t & iterations_left)
    {
        if (iterations_left == 0xffff)
        {
            _oled -> clear(PAGE);
            iterations_left = 1024;
        }
        _oled -> pixel(random(_oled -> getLCDWidth()), random(_oled -> getLCDHeight()));
        _oled -> DISPLAYFUNC();
        iterations_left--;
    }
    
    void TestFillRects(TeensyView * _oled, uint16_t & iterations_left)
    {
        if (iterations_left == 0xffff)
        {
            _oled -> clear(PAGE);
            iterations_left = 0; // Not really, but makes it simple as we will update
        }
        _oled -> rectFill(iterations_left, iterations_left,
        _oled -> getLCDWidth() - iterations_left * 2, _oled -> getLCDHeight() - iterations_left * 2,(iterations_left & 1)? 0:1, NORM);
        _oled -> DISPLAYFUNC();
        iterations_left += 3;
        if (iterations_left >= _oled -> getLCDHeight() /2)
        {
            iterations_left = 0; // we are done.
        }
    }
    
    void testdrawline(TeensyView * _oled, uint16_t & iterations_left, uint32_t & next_test_start_time)
    {
        // Serial.printf("testDrawline %x %x\n", _oled, iterations_left);
        if (iterations_left == 0xffff)
        {
            _oled -> clear(PAGE);
            iterations_left = 0; // Not really, but makes it simple as we will update
        }
        uint8_t line_test = iterations_left >> 8;
        uint8_t i = iterations_left & 0xff;
        switch (line_test)
        {
            case 0:
                _oled -> line(0, 0, i, _oled -> getLCDHeight() - 1);
                _oled -> DISPLAYFUNC();
                i += 4;
                if (i >= _oled -> getLCDWidth())
                {
                    i = 0;
                    line_test++;
                }
                break;
            case 1:
                _oled -> line(0, 0, _oled -> getLCDWidth() - 1, i);
                _oled -> DISPLAYFUNC();
                i += 4;
                if (i >= _oled -> getLCDHeight())
                {
                    i = 0;
                    line_test++;
                    next_test_start_time = millis() + 250;
                }
            case 2:
                if (i == 0)
                {
                    _oled -> clear(PAGE);
                }
                _oled -> line(0, _oled -> getLCDHeight() - 1, i, 0);
                _oled -> DISPLAYFUNC();
                i += 4;
                if (i >= _oled -> getLCDWidth())
                {
                    i = 0;
                    line_test++;
                }
                break;
            case 3:
                _oled -> line(0, _oled -> getLCDHeight() - 1, _oled -> getLCDWidth() - 1, i);
                _oled -> DISPLAYFUNC();
                i += 4;
                if (i >= _oled -> getLCDHeight())
                {
                    i = 0;
                    line_test++;
                    next_test_start_time = millis() + 250;
                }
                break;
            case 4:
                if (i == 0)
                {
                    _oled -> clear(PAGE);
                }
                _oled -> line(_oled -> getLCDWidth() - 1, _oled -> getLCDHeight() - 1, i, 0);
                _oled -> DISPLAYFUNC();
                i += 4;
                if (i >= _oled -> getLCDWidth())
                {
                    i = 0;
                    line_test++;
                }
                break;
            case 5:
                _oled -> line(_oled -> getLCDWidth() - 1, _oled -> getLCDHeight() - 1, 0, i);
                _oled -> DISPLAYFUNC();
                i += 4;
                if (i >= _oled -> getLCDHeight())
                {
                    i = 0;
                    line_test++;
                    next_test_start_time = millis() + 250;
                }
                break;
            case 6:
                if (i == 0)
                {
                    _oled -> clear(PAGE);
                }
                _oled -> line(_oled -> getLCDWidth() - 1, 0, 0, i);
                _oled -> DISPLAYFUNC();
                i += 4;
                if (i >= _oled -> getLCDHeight())
                {
                    i = 0;
                    line_test++;
                }
                break;
            case 7:
                _oled -> line(_oled -> getLCDWidth() - 1, 0, i, _oled -> getLCDHeight() - 1);
                _oled -> DISPLAYFUNC();
                i += 4;
                if (i >= _oled -> getLCDWidth())
                {
                    i = 0;
                    line_test = 0; // Say we are done
                }
        }
        iterations_left = (line_test << 8) | i;
    }
    
    void testscrolltext(TeensyView * _oled, uint16_t & iterations_left, uint32_t & next_test_start_time)
    {
        if (iterations_left == 0xffff)
        {
            int middleX = _oled -> getLCDWidth() / 2;
            int middleY = _oled -> getLCDHeight() / 2;
            _oled -> clear(PAGE);
            _oled -> setFontType(1);
            // Try to set the cursor in the middle of the screen
            _oled -> setCursor(middleX - (_oled -> getFontWidth() * (6 / 2)),
            middleY - (_oled -> getFontWidth() / 2));
            // Print the title:
            _oled -> print("Scroll");
            _oled -> DISPLAYFUNC();
            iterations_left = 1; // Not really, but makes it simple as we will update
            return;
        }
        switch (iterations_left)
        {
            case 1:
                _oled -> scrollRight(0x00, 0x0f, true);
                next_test_start_time = millis() + 2000;
                break;
            case 2:
                _oled -> scrollStop();
                next_test_start_time = millis() + 1000;
                break;
            case 3:
                _oled -> scrollLeft(0x00, 0x0f, true);
                next_test_start_time = millis() + 2000;
                break;
            case 4:
                _oled -> scrollStop();
                next_test_start_time = millis() + 1000;
                break;
            case 5:
                _oled -> scrollVertRight(0x00, 0x07, true);
                next_test_start_time = millis() + 2000;
                break;
            case 6:
                _oled -> scrollVertLeft(0x00, 0x07, true);
                next_test_start_time = millis() + 2000;
                break;
            case 7:
                _oled -> scrollStop();
                next_test_start_time = millis() + 50;
                break;
        }
        if (++iterations_left > 7)
            iterations_left = 0;
    }
    Still need to test on T3.6, but my setup was pilfered to play with ILI9341 displays
    Update: Tested on T3.6 with first two display SPI and SPI1 and SPI2
    Last edited by KurtE; 06-03-2017 at 05:40 PM. Reason: Tested on T3.6 - All three busses

  15. #40
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    6,325
    Not sure if anyone is interested, but I did hack up a version of the Adafruit_SSD1306 to also work with the new SPI code.
    Which is up on my github in a new branch: https://github.com/KurtE/Adafruit_SS...tree/Multi-SPI

    The code allows me to pass in a reference to the appropriate SPI object on the constructor...
    Note: This is off of my version that also allowed me to pass in reference to Wire object if you have one of the I2C versions.

    Then I did some semi-random changes, for my own purposes
    a) Moved the buffer into the object instead of global, as to probably allow multiple ones.
    b) Made two sub-classes for 32 line and 64 line versions (I hated the editing the header file to change especially if you might have multiple...
    c) Currently the main class defaults to the setting from before, there is an optional parameter on constructor to allow you to choose. But in this main class it uses malloc to allocate the object, but the two sub-classes have buffer defined within the actual class...
    d) The update screen function call the spi.transfer(x, cnt)... to speed up transfer... Currently has to do copy to temporary buffer... So only do 32 bytes per call...

    Again not sure if anyone wishes to also play with this, but here is test program:
    Code:
    /*********************************************************************
    This is an example for our Monochrome OLEDs based on SSD1306 drivers
    
      Pick one up today in the adafruit shop!
      ------> http://www.adafruit.com/category/63_98
    
    This example is for a 128x32 size display using SPI to communicate
    4 or 5 pins are required to interface
    
    Adafruit invests time and resources providing this open source code, 
    please support Adafruit and open-source hardware by purchasing 
    products from Adafruit!
    
    Written by Limor Fried/Ladyada  for Adafruit Industries.  
    BSD license, check license.txt for more information
    All text above, and the splash screen must be included in any redistribution
    *********************************************************************/
    
    #include <SPI.h>
    #include <Wire.h>
    #include <Adafruit_GFX.h>
    #include <Adafruit_SSD1306.h>
    
    //#define TEST_SPI
    //#define TEST_SPI1
    #define TEST_SPI2
    
    #ifdef TEST_SPI
    // If using software SPI (the default case):
    #define OLED_MOSI  11
    #define OLED_CLK   13
    #define OLED_DC    21
    #define OLED_CS    20
    #define OLED_RESET 15
    Adafruit_SSD1306 display(OLED_DC, OLED_RESET, OLED_CS);
    #endif
    
    #ifdef TEST_SPI1
    // If using software SPI (the default case):
    #define OLED_MOSI  0
    #define OLED_CLK   32
    #define OLED_DC    31
    #define OLED_CS    30
    #define OLED_RESET 16
    Adafruit_SSD1306_64 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS, SPI1);
    #endif
    
    
    #ifdef TEST_SPI2
    // If using software SPI (the default case):
    #define OLED_MOSI  52
    #define OLED_CLK   53
    #define OLED_DC    55
    #define OLED_CS    56
    #define OLED_RESET 48
    Adafruit_SSD1306_32 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS, SPI2);
    #endif
    
    #define NUMFLAKES 10
    #define XPOS 0
    #define YPOS 1
    #define DELTAY 2
    
    #define LOGO16_GLCD_HEIGHT 16 
    #define LOGO16_GLCD_WIDTH  16 
    static const unsigned char PROGMEM logo16_glcd_bmp[] =
    { B00000000, B11000000,
      B00000001, B11000000,
      B00000001, B11000000,
      B00000011, B11100000,
      B11110011, B11100000,
      B11111110, B11111000,
      B01111110, B11111111,
      B00110011, B10011111,
      B00011111, B11111100,
      B00001101, B01110000,
      B00011011, B10100000,
      B00111111, B11100000,
      B00111111, B11110000,
      B01111100, B11110000,
      B01110000, B01110000,
      B00000000, B00110000 };
    
    #if (SSD1306_LCDHEIGHT != 32)
    #error("Height incorrect, please fix Adafruit_SSD1306.h!");
    #endif
    
    void setup()   {      
      while (!Serial && (millis() < 2000)) ;          
      Serial.begin(9600);
      
      // by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
      display.begin(SSD1306_SWITCHCAPVCC);
      // init done
      
      // Show image buffer on the display hardware.
      // Since the buffer is intialized with an Adafruit splashscreen
      // internally, this will display the splashscreen.
      display.display();
      delay(2000);
    
      // Clear the buffer.
      display.clearDisplay();
    
      // draw a single pixel
      display.drawPixel(10, 10, WHITE);
      // Show the display buffer on the hardware.
      // NOTE: You _must_ call display after making any drawing commands
      // to make them visible on the display hardware!
      display.display();
      delay(2000);
      display.clearDisplay();
    
      // draw many lines
      testdrawline();
      display.display();
      delay(2000);
      display.clearDisplay();
    
      // draw rectangles
      testdrawrect();
      display.display();
      delay(2000);
      display.clearDisplay();
    
      // draw multiple rectangles
      testfillrect();
      display.display();
      delay(2000);
      display.clearDisplay();
    
      // draw mulitple circles
      testdrawcircle();
      display.display();
      delay(2000);
      display.clearDisplay();
    
      // draw a white circle, 10 pixel radius
      display.fillCircle(display.width()/2, display.height()/2, 10, WHITE);
      display.display();
      delay(2000);
      display.clearDisplay();
    
      testdrawroundrect();
      delay(2000);
      display.clearDisplay();
    
      testfillroundrect();
      delay(2000);
      display.clearDisplay();
    
      testdrawtriangle();
      delay(2000);
      display.clearDisplay();
       
      testfilltriangle();
      delay(2000);
      display.clearDisplay();
    
      // draw the first ~12 characters in the font
      testdrawchar();
      display.display();
      delay(2000);
      display.clearDisplay();
    
      // draw scrolling text
      testscrolltext();
      delay(2000);
      display.clearDisplay();
    
      // text display tests
      display.setTextSize(1);
      display.setTextColor(WHITE);
      display.setCursor(0,0);
      display.println("Hello, world!");
      display.setTextColor(BLACK, WHITE); // 'inverted' text
      display.println(3.141592);
      display.setTextSize(2);
      display.setTextColor(WHITE);
      display.print("0x"); display.println(0xDEADBEEF, HEX);
      display.display();
      delay(2000);
      display.clearDisplay();
    
      // miniature bitmap display
      display.drawBitmap(30, 16,  logo16_glcd_bmp, 16, 16, 1);
      display.display();
    
      // invert the display
      display.invertDisplay(true);
      delay(1000); 
      display.invertDisplay(false);
      delay(1000); 
      display.clearDisplay();
    
      // draw a bitmap icon and 'animate' movement
      testdrawbitmap(logo16_glcd_bmp, LOGO16_GLCD_HEIGHT, LOGO16_GLCD_WIDTH);
    }
    
    
    void loop() {
      
    }
    
    
    void testdrawbitmap(const uint8_t *bitmap, uint8_t w, uint8_t h) {
      uint8_t icons[NUMFLAKES][3];
     
      // initialize
      for (uint8_t f=0; f< NUMFLAKES; f++) {
        icons[f][XPOS] = random(display.width());
        icons[f][YPOS] = 0;
        icons[f][DELTAY] = random(5) + 1;
        
        Serial.print("x: ");
        Serial.print(icons[f][XPOS], DEC);
        Serial.print(" y: ");
        Serial.print(icons[f][YPOS], DEC);
        Serial.print(" dy: ");
        Serial.println(icons[f][DELTAY], DEC);
      }
    
      while (1) {
        // draw each icon
        for (uint8_t f=0; f< NUMFLAKES; f++) {
          display.drawBitmap(icons[f][XPOS], icons[f][YPOS], bitmap, w, h, WHITE);
        }
        display.display();
        delay(200);
        
        // then erase it + move it
        for (uint8_t f=0; f< NUMFLAKES; f++) {
          display.drawBitmap(icons[f][XPOS], icons[f][YPOS], bitmap, w, h, BLACK);
          // move it
          icons[f][YPOS] += icons[f][DELTAY];
          // if its gone, reinit
          if (icons[f][YPOS] > display.height()) {
            icons[f][XPOS] = random(display.width());
            icons[f][YPOS] = 0;
            icons[f][DELTAY] = random(5) + 1;
          }
        }
       }
    }
    
    
    void testdrawchar(void) {
      display.setTextSize(1);
      display.setTextColor(WHITE);
      display.setCursor(0,0);
    
      for (uint8_t i=0; i < 168; i++) {
        if (i == '\n') continue;
        display.write(i);
        if ((i > 0) && (i % 21 == 0))
          display.println();
      }    
      display.display();
    }
    
    void testdrawcircle(void) {
      for (int16_t i=0; i<display.height(); i+=2) {
        display.drawCircle(display.width()/2, display.height()/2, i, WHITE);
        display.display();
      }
    }
    
    void testfillrect(void) {
      uint8_t color = 1;
      for (int16_t i=0; i<display.height()/2; i+=3) {
        // alternate colors
        display.fillRect(i, i, display.width()-i*2, display.height()-i*2, color%2);
        display.display();
        color++;
      }
    }
    
    void testdrawtriangle(void) {
      for (int16_t i=0; i<min(display.width(),display.height())/2; i+=5) {
        display.drawTriangle(display.width()/2, display.height()/2-i,
                         display.width()/2-i, display.height()/2+i,
                         display.width()/2+i, display.height()/2+i, WHITE);
        display.display();
      }
    }
    
    void testfilltriangle(void) {
      uint8_t color = WHITE;
      for (int16_t i=min(display.width(),display.height())/2; i>0; i-=5) {
        display.fillTriangle(display.width()/2, display.height()/2-i,
                         display.width()/2-i, display.height()/2+i,
                         display.width()/2+i, display.height()/2+i, WHITE);
        if (color == WHITE) color = BLACK;
        else color = WHITE;
        display.display();
      }
    }
    
    void testdrawroundrect(void) {
      for (int16_t i=0; i<display.height()/2-2; i+=2) {
        display.drawRoundRect(i, i, display.width()-2*i, display.height()-2*i, display.height()/4, WHITE);
        display.display();
      }
    }
    
    void testfillroundrect(void) {
      uint8_t color = WHITE;
      for (int16_t i=0; i<display.height()/2-2; i+=2) {
        display.fillRoundRect(i, i, display.width()-2*i, display.height()-2*i, display.height()/4, color);
        if (color == WHITE) color = BLACK;
        else color = WHITE;
        display.display();
      }
    }
       
    void testdrawrect(void) {
      for (int16_t i=0; i<display.height()/2; i+=2) {
        display.drawRect(i, i, display.width()-2*i, display.height()-2*i, WHITE);
        display.display();
      }
    }
    
    void testdrawline() {  
      for (int16_t i=0; i<display.width(); i+=4) {
        display.drawLine(0, 0, i, display.height()-1, WHITE);
        display.display();
      }
      for (int16_t i=0; i<display.height(); i+=4) {
        display.drawLine(0, 0, display.width()-1, i, WHITE);
        display.display();
      }
      delay(250);
      
      display.clearDisplay();
      for (int16_t i=0; i<display.width(); i+=4) {
        display.drawLine(0, display.height()-1, i, 0, WHITE);
        display.display();
      }
      for (int16_t i=display.height()-1; i>=0; i-=4) {
        display.drawLine(0, display.height()-1, display.width()-1, i, WHITE);
        display.display();
      }
      delay(250);
      
      display.clearDisplay();
      for (int16_t i=display.width()-1; i>=0; i-=4) {
        display.drawLine(display.width()-1, display.height()-1, i, 0, WHITE);
        display.display();
      }
      for (int16_t i=display.height()-1; i>=0; i-=4) {
        display.drawLine(display.width()-1, display.height()-1, 0, i, WHITE);
        display.display();
      }
      delay(250);
    
      display.clearDisplay();
      for (int16_t i=0; i<display.height(); i+=4) {
        display.drawLine(display.width()-1, 0, 0, i, WHITE);
        display.display();
      }
      for (int16_t i=0; i<display.width(); i+=4) {
        display.drawLine(display.width()-1, 0, i, display.height()-1, WHITE); 
        display.display();
      }
      delay(250);
    }
    
    void testscrolltext(void) {
      display.setTextSize(2);
      display.setTextColor(WHITE);
      display.setCursor(10,0);
      display.clearDisplay();
      display.println("scroll");
      display.display();
     
      display.startscrollright(0x00, 0x0F);
      delay(2000);
      display.stopscroll();
      delay(1000);
      display.startscrollleft(0x00, 0x0F);
      delay(2000);
      display.stopscroll();
      delay(1000);    
      display.startscrolldiagright(0x00, 0x07);
      delay(2000);
      display.startscrolldiagleft(0x00, 0x07);
      delay(2000);
      display.stopscroll();
    }

  16. #41
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    21,467
    Arduino finally released 1.8.3. I'm updating Teensyduino now.

    Should have 1.37-beta2 available within a couple hours.

  17. #42
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    10,925
    IDE 1.8.3 release notes don't look real significant WRT to Teensy? Any surprises? I just finished downloads of 1.8.3 and TD_1.37b2 to install later.

    ARDUINO 1.8.3 2017.05.31

    (bugfix service release)

    [ide]
    * Fixed RESOURCE_NAME in install.sh script
    * Serial Monitor: added "Clear output" button. Thanks @MichaelSy
    * added options in preferences.txt for: custom title, comment/uncomment shortcut, always show file extensions. Thanks @MichaelSy
    * added options in preferences.txt to enable/disable typing assistance (auto close brace, auto indent)
    * Enabling "Use external editor" option now requires to save all sketches.

    [core]
    * AVR: added availableForWrite() method in generic Stream class. Thanks @eric-wieser
    * AVR: moved flush() method up in the class hierarchy from Stream to Print class. Thanks @matthijskooijman

    [other]
    * Update Wifi101 Firmware Updater plugin

  18. #43
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    6,325
    I have installed on Windows and have done a few compiles.

    The one thing I notice is there is a new button in the TeensyMonitor <Clear Output>
    Which currently does not look like it does anything with Teensy.

  19. #44
    Senior Member
    Join Date
    Apr 2016
    Location
    St. Petersburg, FL
    Posts
    149
    The ZIP version of V1.8.3 works OK but Teensyduino and TyTools won't install. The former won't enable the Next button after the folder is selected. The later says the folder is not valid. What seems to be the problem, perhaps something missing that's expected?

    PS
    Both programs install correctly in V1.8.2.
    Last edited by Arctic_Eddie; 06-08-2017 at 01:49 PM.

  20. #45
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    6,325
    For 1.8.3 - Teensyduino beta 2, from the thread: https://forum.pjrc.com/threads/44596...1-8-3-support) installed for me.
    And likewise I was able to install TyTools. This is on my Windows 10 64 bit machine.

  21. #46
    Senior Member
    Join Date
    Apr 2016
    Location
    St. Petersburg, FL
    Posts
    149
    Both install correctly now using beta2. Thanks for the info.

Posting Permissions

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