Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 16 of 16

Thread: Teensyduino 1.17 Release Candidate #2 Available

  1. #1
    Administrator Paul's Avatar
    Join Date
    Oct 2012
    Posts
    448

    Teensyduino 1.17 Release Candidate #2 Available

    Here is a second release candidate for Teensyduino 1.17:


    Old beta download links removed. Please use the latest version:
    https://www.pjrc.com/teensy/td_download.html



    Please give this a try and report any bugs. Try to include a sample program that reproduces the problem!


    Here's a list of the changes since Teensyduino 1.17-rc1:


    • Stream printf, eg: Serial.printf()
    • add missing new/delete
    • add digitalPinToInterrupt
    • added SPIFIFO for Teensy3
    • Ethernet library speedup (using SPIFIFO)
    • add missing string _P stuff for Teensy3
    • hardware serial support for other data formats
    • 9 bit serial format (not enabled by default)
    • Czech keyboard layout (not enabled by default)
    • fix Keyboard.releaseAll() on Teensy3
    • fix USB MIDI setHandlePitchChange on Teensy2
    • fix arm math lib warnings
    • fix digital signatures for Windows exe files
    • removed ancient Arduino 0023 support

  2. #2
    Junior Member
    Join Date
    Dec 2013
    Posts
    3
    I'm especially interested in the SPIFIFO support. Paul, could you elaborate on what it does and how it is used? I'm using SPI quite heavily so any neat tricks are welcome

  3. #3
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    28,479
    First, I should mention SPIFIFO is very new and might change. If you use it now, be prepared for possibly incompatible changes over the next few months.

    SPIFIFO has a begin() function that takes the SS pin number and the desired bitrate. The main thing you need to know is SPIFIFO automatically handles the SS pin, so you do not use digitalWrite on any pin like you would with the normal SPI library.

    SPIFIFO is faster if you use any of the natively supported SS pins (shown in green on the Teensy 3.0 pinout card). SPIFIFO will automatically work with any pin for SS, but the non-native pins are slower.

    There are 2 functions to transmit, write() and write16(). Both take one input, either 8 or 16 bits, and an optional SPI_CONTINUE input. The first write causes SS to assert. Every write within a single transaction, except the last one, must have SPI_CONTINUE. That's how it knows to keep the SS pin asserted (low). This SPI_CONTINUE mimics the special SPI extensions for Arduino Due, except Due doesn't have a FIFO.

    You use the read() function to receive data from previous writes. You MUST call read() for every write() or write16(). It will return either 8 or 16 bits, depending on whether you previously called write() or write16(). Never call read() without previously doing a write().

    Never get more than 4 writes ahead, because the FIFO is only 4 words deep. Usually you'll start with 2 or 3 writes, then do interleaved read & write, until your last write without SPI_CONTINUE. Then after that last write, you'll do 2 or 3 reads to finish up.

    The key difference between SPIFIFO.write() and normal SPI.transfer() is when it returns to your code. With SPI.transfer(), the entire byte is transmitted and whatever came in is returned, so anything you do is while the SPI is idle. With SPIFIFO.write(), control returns quickly to your code while the actual bits are probably still being pumped out. You must later call read() to get whatever came in. Both use inline functions for low overhead, but if you keep 2 or 3 writes ahead of reading, SPIFIFO really reduces the dead times between actual bits clocking in and out.

    Even if you only need to transmit and you don't care what voltage was on the MISO pin while you were transmitting, you really do need to have a read() that corresponds to every write().

    The write16() function lets you send 2 bytes at once, and the read() that corresponds will return the 2 bytes that came in during that 2 byte write. At slower than 12 Mbit/sec, this make very little difference, but at 24 Mbit/sec, it saves some overhead both in software and the SPI peripheral that really can speed things up.

    When using write16() to transmit 2 bytes at once, the format is MSB first. If you combine two bytes, shift up by 8 bits the one you want transmitted first. If your data is already stored in a 16 bit variable, but the byte to transmit first is in the lower half, you can use __builtin_bswap16() to efficiently swap the 2 bytes within the 16 bit variable. Likewise, when read() returns the 2 bytes that were on the DIN pin during that write16, the MSB will have the byte that arrived first.

    SPIFIFO also has a clear() function that will wipe any previous stuff from the FIFOs. In theory, you shouldn't need it. But in practice, if you've ever forgotten to do a read() on an previous transaction (or some other code using SPIFIFO did that), the clear() function starts you out with a clean slate. Only call it when you're pretty sure nothing is still happening on the SPI port, like right before you begin communicating. Don't use clear() as a lazy way to avoid read(), especially immediately after doing several write() calls. If the data is still being pumped out, clear() might truncate it. Always try to exactly balance every write() or write16() with a read(), even if you ignore the incoming data.

    So far, the only example is in w5100.cpp in the Ethenet library. Of course, looking at SPIFIFO.h might help too?

    If you use it, please let me know how it works for you?
    Last edited by PaulStoffregen; 12-01-2013 at 11:27 PM.

  4. #4
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    28,479
    I should mention SPIFIFO is designed with some trade-offs for useability (like automatically handling the non-native CS pins). If you keep 2 or 3 writes ahead of reading, it should usually give you the maximum or nearly maximum possible speed.

    Separate write and read is not always the most efficient way, especially when you only write while ignoring all incoming data, or only read while writing fixed output. Here's a very fast library with different design trade-offs for those scenarios.

    https://github.com/xxxajk/spi4teensy3

  5. #5
    About Serial.printf.I get the following error:

    /home/user123/arduino-1.0.5/hardware/tools/arm-none-eabi/bin/../lib/gcc/arm-none-eabi/4.7.2/../../../../arm-none-eabi/bin/ld: section .progmem.data loaded at [000000000000a15c,000000000000a16d] overlaps section .data loaded at [000000000000a15c,000000000000a78b]
    collect2: error: ld returned 1 exit status

  6. #6
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    28,479
    Can you please post the code that reproduces this error? I can't do anything if I can't reproduce the problem.

  7. #7
    Sorry. I thought it was a known issue or something like that:

    Serial.printf("%d %d %d %d %u\r\n",header.from_node,payload.id,payload.comman d,payload.pin,payload.data);

    payload and header are structs like:
    struct payload_t
    {
    byte id;
    byte command; //read, write, set digital, set analog
    byte pin; //pin number
    unsigned int data;
    };


    removing that line makes the rest of the code work. It's long, and closed source.

  8. #8
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    28,479
    If you want me to investigate, you must post a complete program that I can copy into Arduino to reproduce the problem. I don't need to see your entire proprietary application, but I do need you to copy just the part that crashes into a small but complete program that reproduces the problem.

  9. #9
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    28,479
    Here is a perfect example of why I insist people post a complete program that is reproduces a problem!

    I copied the struct definition and printf line into a small test program. I filled in the missing parts, substituting zero for the first variable since I have no idea what "header.from_node" is. Since it's referenced by "%d", I assumed at integer. (if this isn't actually an integer, it very well may be the cause of the problems you're seeing)

    Here is the code I tested:

    Code:
    struct payload_t
    {
      byte id;
      byte command; //read, write, set digital, set analog
      byte pin; //pin number
      unsigned int data;
    };
    
    payload_t test;
    
    void setup() {
      test.id = 12;
      test.command = 34;
      test.pin = 56;
      test.data = 78910;
    }
    
    void loop() {
      Serial.printf("%d %d %d %d %u\r\n",
        0, test.id, test.command, test.pin, test.data);
      delay(500);
    }
    As you can see in this screenshot, I was not able to reproduce the problem.



    Normally when people post these bug reports without a complete program, I don't do this work to turn them into a complete program for testing. It pretty much always ends up this way.


    I'm not denying there may indeed be a bug. I really do want to investigate and fix any bugs. But until you post a complete program that reproduces the problem, what am I supposed to do?
    Last edited by PaulStoffregen; 12-04-2013 at 11:05 AM.

  10. #10
    Paul, you are right. I work for a QA company, and I know the pain. I'm sorry I can't share the code. I'll try to reproduce it at home as soon as I get some spare time. I'll let you know if I find a way to reproduce the issue.

  11. #11
    Senior Member
    Join Date
    Jan 2013
    Location
    Dallas, TX USA
    Posts
    111
    Paul,
    I noticed that printf() support is not part of the Print class unless the Arduino IDE is post 1.x
    I understand the testing and support aspect of backporting stuff, but
    I'm curious for the reasoning for this. I know that pre 1.x stuff is a bit stale these days but
    this is a case where the additional features can still be supported.
    While I think that requiring 1.x is probably ok for the ARM stuff, there are still quite a few stragglers using
    the older AVR tools.

    From looking at your WStrings.h header file it looks like you are creating the F()
    macro if it doesn't exist. It was also created in WString.h in a REALLY REALLY old version of Teensyduino
    that I'm still using for testing on 022 IDE. - I'm not even sure which version it is as
    it is so old that there isn't a way to get the Teensyduino version information
    from the TeensyLoader GUI.


    In GLCDv3 & openGLCD I also created the F() macro for users in pre 1.x so that they
    get a "just works environment for pre 1.x as well when using openGLCD functions.

    I use this:

    Code:
    /*
     * On pre Arduino 1.0, define the F() flash string stuff if not already defined
     * (Teensy defines this in pre 1.0)
     */
    #if ARDUINO < 100
    #ifndef F
    class __FlashStringHelper;
    #define F(string_literal) (reinterpret_cast<__FlashStringHelper *>(PSTR(string_literal)))
    #endif
    #endif

    In your case since you also ship the Print class you can make everything, including the Print class
    printf() "just work" even for pre 1.x
    You already have the F() macro which is actually the harder part, so I'm curious why
    leave out the printf() support?



    --- bill

  12. #12
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    28,479
    Quote Originally Posted by bperrybap View Post
    Paul,
    I noticed that printf() support is not part of the Print class unless the Arduino IDE is post 1.x
    ....
    I'm curious for the reasoning for this.
    I dropped support for Arduino 0023.

    Eventually I'll purge that old, unused code. But since it doesn't cause any harm, other than making the code slightly harder to read, code cleanup is a very low priority. So in other words, "eventually" could be a very long time.

    there are still quite a few stragglers using the older AVR tools.
    I've always tried to balance supporting old versions people still actually use vs maximizing my productivity by limiting the scope of versions to support. I felt it was finally time to drop 0023 support. That's entirely an arbitrary judgement call on my part.

    Nothing any 1 person can write will change my mind. Of course, if suddenly large numbers of customers complain about lack of 0023 support, I'll take notice.

    From looking at your WStrings.h header file it looks like you are creating the F()
    macro if it doesn't exist. It was also created in WString.h in a REALLY REALLY old version of Teensyduino
    that I'm still using for testing on 022 IDE. - I'm not even sure which version it is as
    it is so old that there isn't a way to get the Teensyduino version information
    from the TeensyLoader GUI.
    There's a lot of very old history lurking in all this code.

    For a couple years, Arduino shipped an extremely buggy WString.cpp. I contributed my version. The Arduino Team was very slow to embrace it. Eventually they used it all, except the compiler flags that optimze constructors. Maybe someday they'll implement that too? During those years, my String stuff was designed to be able to drop into Arduino, for people who were hitting the known bugs.

    Again, ancient code cleanup is a very low priority for me. Many programmers prize "clean" code and dedicate lots of time to achieving pristine code, sometimes even when that conflicts with other goals. Not me. My style is very pragmatic. I also run a tiny 3-person business. Features and bug fixes that benefit customers get my attention. Cleaning up old cruft that doesn't impact anyone (other than people reading the source) ends up at the very bottom of my priority list.
    Last edited by PaulStoffregen; 12-14-2013 at 08:34 PM.

  13. #13
    Senior Member
    Join Date
    Jan 2013
    Location
    Dallas, TX USA
    Posts
    111
    I'm ok with your decision but I'm not entirely sure what it means.
    Does it mean that Teensyduino will no longer install on arduino pre 1.0 ?
    If so then perhaps the teensyduino page: http://www.pjrc.com/teensy/td_download.html#arduino1p0
    could be updated a bit to more clearly reflect which versions of the IDE are supported.

    I don't yet have the luxury of dropping pre 1.x support in openGLCD as the chipkit guys have not updated
    things to 1.x yet.

    BTW, for some reason the email notifications are no longer working.
    Has this been disabled or is there something mis-configured on my end?
    --- bill

  14. #14
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    28,479
    Quote Originally Posted by bperrybap View Post
    Does it mean that Teensyduino will no longer install on arduino pre 1.0 ?
    Yes. In fact, it currently only installs to 1.0.5. Not even 1.0.4 is supported anymore.

    If so then perhaps the teensyduino page: http://www.pjrc.com/teensy/td_download.html#arduino1p0
    could be updated a bit to more clearly reflect which versions of the IDE are supported.
    Done.

    I don't yet have the luxury of dropping pre 1.x support in openGLCD as the chipkit guys have not updated
    things to 1.x yet.
    They're not alone. Energia and Maple also lag pretty far behind.

  15. #15
    Junior Member
    Join Date
    Jan 2014
    Posts
    1

    DMA support for SPI

    Hi Paul,

    The new Teensy 3.* modules look very cool! On the new SPI library, did you shy away from using DMA for any particular reason (other than required dev effort)? I've been a little surprised to see the stock Arduino SPI libraries only let you send a byte-at-a-time. I've been working on some libs for my own project that let you send entire buffers automatically (https://github.com/loganb/teensy-uti...ster/spi.h#L41), leveraging interrupts to transmit at max speed & asynchronously. Just curious if this route is folly in some way I'll discover later.

  16. #16
    Senior Member
    Join Date
    Jun 2013
    Location
    So. Calif
    Posts
    2,825
    Novices, please note: Though the posting above caused this thread to reemerge, there is a newer thread on a later (younger) release.
    This can confuse the casual reader.

    (IMO, the announcement topics should be read-only for the non-admins here.)

Posting Permissions

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