Teensyduino 1.20 Release Candidate #1 Available

Status
Not open for further replies.
Dear Paul,
1.20 Release Candidate #1

Code:
#define FTM_CONF_BDMMODE  (((n) & 3) << 6)   // Behavior when in debug mode
#define FTM_CONF_NUMTOF     (((n) & 31) << 0) // ratio of counter overflows

must be
Code:
#define FTM_CONF_BDMMODE(n) (((n) & 3) << 6)   // Behavior when in debug mode
#define FTM_CONF_NUMTOF(n)    (((n) & 31) << 0) // ratio of counter overflows

why do you don't use _MASK extension
like -> FTM_MODE_FTMEN_MASK;
i must rewritten some example Code!

Barney
 
I've at home a Teensy3.0 and I use it with OctoWS2811 and 256leds/strip.
With that number of leds a free byte of ram is a free byte !

I don't care to have USB serial, I just need to be able to flash the teensy.
I'll be nice to have an option to disable it.

With this small (ugly?) patch which add an option : USB_NONE, I save ~1.2kB of ram.

Code:
index 248cb1e..8508e85 100644
--- a/hardware/teensy/boards.txt
+++ b/hardware/teensy/boards.txt
@@ -146,6 +146,7 @@ teensy3.build.option3=-D__MK20DX128__
 teensy3.build.option4=-DTEENSYDUINO=120
 teensy3.build.cppoption1=-fno-rtti
 teensy3.build.linkoption1=-mthumb
+teensy3.build.linkoption2=-Wl,-Map,map.out
 teensy3.build.additionalobject1=-larm_cortexM4l_math
 teensy3.build.linkscript=mk20dx128.ld
 teensy3.build.architecture=arm-none-eabi
@@ -162,6 +163,8 @@ teensy3.build.dependency=true
 teensy3.build.time_t=true
 #teensy3.build.linker_relaxation=true
 teensy3.build.post_compile_script=teensy_post_compile
+teensy3.menu.usb.none.name=None
+teensy3.menu.usb.none.build.define0=-DUSB_NONE
 teensy3.menu.usb.serial.name=Serial
 teensy3.menu.usb.serial.build.define0=-DUSB_SERIAL
 teensy3.menu.usb.hid.name=Keyboard + Mouse + Joystick
diff --git a/hardware/teensy/cores/teensy3/usb_desc.h b/hardware/teensy/cores/teensy3/usb_desc.h
index c3cf15c..f1240e6 100644
--- a/hardware/teensy/cores/teensy3/usb_desc.h
+++ b/hardware/teensy/cores/teensy3/usb_desc.h
@@ -83,7 +83,27 @@ let me know?  http://forum.pjrc.com/forums/4-Suggestions-amp-Bug-Reports
 
 
 
-#if defined(USB_SERIAL)
+#if defined(USB_NONE)
+  #define VENDOR_ID            0x16C0
+  #define PRODUCT_ID           0x0483
+  #define MANUFACTURER_NAME    {'T','e','e','n','s','y','d','u','i','n','o'}
+  #define MANUFACTURER_NAME_LEN        11
+  #define PRODUCT_NAME         {'U','S','B',' ','F','l','a','s','h'}
+  #define PRODUCT_NAME_LEN     9
+  #define EP0_SIZE             8
+  #define NUM_ENDPOINTS                0
+  #define NUM_USB_BUFFERS      0
+  #define NUM_INTERFACE                2
+  #define CDC_STATUS_INTERFACE 0
+  #define CDC_DATA_INTERFACE   1
+  #define CDC_ACM_ENDPOINT     2
+  #define CDC_RX_ENDPOINT       3
+  #define CDC_TX_ENDPOINT       4
+  #define CDC_ACM_SIZE          16
+  #define CDC_RX_SIZE           64
+  #define CDC_TX_SIZE           64
+  #define CONFIG_DESC_SIZE     (9+9+5+5+4+5+7+9+7+7)
+#elif defined(USB_SERIAL)
   #define VENDOR_ID            0x16C0
   #define PRODUCT_ID           0x0483
   #define DEVICE_CLASS         2       // 2 = Communication Class
diff --git a/hardware/teensy/cores/teensy3/yield.cpp b/hardware/teensy/cores/teensy3/yield.cpp
index 55e7d29..16ae996 100644
--- a/hardware/teensy/cores/teensy3/yield.cpp
+++ b/hardware/teensy/cores/teensy3/yield.cpp
@@ -40,7 +40,9 @@ void yield(void)
 
        if (running) return; // TODO: does this need to be atomic?
        running = 1;
+#ifdef USB_SERIAL
        if (Serial.available()) serialEvent();
+#endif
        if (Serial1.available()) serialEvent1();
        if (Serial2.available()) serialEvent2();
        if (Serial3.available()) serialEvent3();

This patch should be improvable. I just tried to reduce the USB buffers to save RAM.

Same thing for VectorsRam, if we don't need to change the vector table, it's 256 bytes of ram wasted :/
Code:
diff --git a/hardware/teensy/cores/teensy3/mk20dx128.c b/hardware/teensy/cores/teensy3/mk20dx128.c
index d9a751f..04abe32 100644
--- a/hardware/teensy/cores/teensy3/mk20dx128.c
+++ b/hardware/teensy/cores/teensy3/mk20dx128.c
@@ -407,9 +407,13 @@ void ResetHandler(void)
        while (dest < &_ebss) *dest++ = 0;
 
        // default all interrupts to medium priority level
+#if defined(STATIC_VECTOR_TABLE)
+       SCB_VTOR = (uint32_t)_VectorsFlash;     // use vector table in FLASH
+#else
        for (i=0; i < NVIC_NUM_INTERRUPTS + 16; i++) _VectorsRam[i] = _VectorsFlash[i];
-       for (i=0; i < NVIC_NUM_INTERRUPTS; i++) NVIC_SET_PRIORITY(i, 128);
        SCB_VTOR = (uint32_t)_VectorsRam;       // use vector table in RAM
+#endif
+       for (i=0; i < NVIC_NUM_INTERRUPTS; i++) NVIC_SET_PRIORITY(i, 128);
 
        // hardware always starts in FEI mode
        //  C1[CLKS] bits are written to 00
 
Anyway, FASTRUN is a great idea !

It gives a serious boost on my plasma-like effect on ILI9341 : 134.7ms / frame => 62.3 ms / frame (-53% ... more than x2 !)

I now run my plasma effect @16fps, tx !
 
This is actually in-the-works :) If you run at < 20MHz, it will screw up too. I need to see if Paul has fixed this issue yet. With NO USB you can even do your own USB stuff, which is what I need.
 
I have two bugs reported on github.
The first bug is actually a set of bugs.
port[abcde]_isr should be prefixed with __attribute__((weak)) to allow them to be overridden. https://github.com/PaulStoffregen/cores/issues/34

Second bug is that micros() can't be called from within an ISR because it will enable interrupts. https://github.com/PaulStoffregen/cores/issues/35
There are a lot of other timing functions that also depend on it. Any of them used within an ISR will enable IRQs, which is bad.
 
Tested with current 64-bit Ubuntu 14.04 against current 64-bit Arduino code. Solves a problem I was having with Teensy 3.1 where the USB serial ports weren't appearing. Well done!
 
I am trying to get serial event() to work - this code works on AVR but not on teensy - any suggestions (or corrections :) )

Code:
char tempBuffer[100] = {0};
const int MaxInput  = 10;
elapsedMillis hBeat;     // "waiting" starts at zero

// ---------------------------------------------------------------------------
void setup()
// ---------------------------------------------------------------------------
{
  Serial.begin(115200);
  while (!Serial); // wait for connection to terminal emulator
  Serial.println("Enter something");
}

// ---------------------------------------------------------------------------
void loop()
// ---------------------------------------------------------------------------
{
  if (hBeat >= 1000)
  {
    Serial.println(".");
    hBeat = 0; // reset count
  }
}

// ---------------------------------------------------------------------------
void serialEvent()
// ---------------------------------------------------------------------------
{
  static unsigned int input_pos = 0;
  //Serial.println("+"); // debug so we know this has been called
  while (Serial.available()) 
  {
    char inByte = (char)Serial.read();
    switch (inByte)
    {
    case '\n':   // end of text
      tempBuffer [input_pos] = 0;  // terminating null byte
      Serial.println(tempBuffer);
      input_pos = 0;
      break;

    default:
      // only allow alphabet and punctuation chrs
      if (inByte >= 32 && inByte <= 126)
      {
        // keep adding if not full ... allow for terminating null byte
        if (input_pos < (MaxInput - 1)) tempBuffer[input_pos++] = inByte;
      } // end if((inByte ....
      break;
    }
  }
}
 
What version of the Teensyduino are you running? I believe this has been added for the current beta 1.20rc2 (maybe rc1 as well).
 
Sometimesyou need to fix nested interrupt locking

I have two bugs reported on github.
Second bug is that micros() can't be called from within an ISR because it will enable interrupts. https://github.com/PaulStoffregen/cores/issues/35
There are a lot of other timing functions that also depend on it. Any of them used within an ISR will enable IRQs, which is bad.

Hi, I saw this post looking through the release notes. I also saw Paul closed your issue seeming to say it wasn't broken.
This notion of nested interrupt locking has come up before in this forum. And there seems to be this notion that because
you can use interrupt priority with our ARM MCU you don't have to worry about the interrupt locking issue. But that's
just sort of wrong I think. As you point out, the problem comes up with nested critical sections. Much current Teensy/Arduino code uses __disable_interrupt and __enable_interrupt to protect a critical section. However, if a call
is made inside a critical section to code that tries to also implement a critical section the same way then the code
breaks because the nested __enable_interrupts call unconditionally enables the interrupts breaking the critical section.
So, for any critical sections that can potentially be nested I use the inline routines I wrote below instead. It's a bit
more overhead but than the unconditional routines but they work. And they have to be used as you also note.

Code:
static inline uint32_t sl_hw_lock(void) __attribute__((always_inline, unused));
static inline void sl_hw_unlock(uint32_t primask) __attribute__((always_inline,
                                                                 unused));

/**
 * Lock interrupts to start a critical section.
 *
 * When used with sl_hw_unlock() this function starts a critical section that
 * works properly even if nested in another critical section because it reads
 * the PRIMASK value so it can be restored.
 *
 * @return the priority mask (PRIMASK) register value upon entry
 */
static inline uint32_t
sl_hw_lock(void)
{
    uint32_t  primask;

    asm volatile("mrs %0, primask\n" : "=r" (primask)::);
    __disable_irq();
    return primask;
}

/**
 * Unlock interrupts to end a critical section.
 *
 * When used with sl_hw_lock() this function ends a critical section that works
 * properly even if nested in another critical section because it uses the
 * previous interrupt locking state (defined by PRIMASK) to selectively unlock
 * interrupts.
 *
 * @param primask   The previous priority mask (PRIMASK) register value as
 *                  returned by sl_hw_lock().
 */
static inline void
sl_hw_unlock(uint32_t primask)
{
    if (primask == 0) {
        __enable_irq();
    }
}

When this came up a while ago on the forum there was an argument that it wasn't a problem. The well composed thread is:
http://forum.pjrc.com/threads/24098-I-don-t-think-critical-sections-work-(interrupt-locking)
Well, I just wrote my code the way I knew I needed it.
 
Another question, when you say it works on an Arduino? Which one? If normal Atmega328 or the like, than you are using IO pins 0,1 for the serial device and not USB input?

If so pins 0, 1 on the Teensy 3/3.1 as well as Arduino like Leonardo that are atmega 32u4 based is not the Serial object, but instead Serial1 object... So in that case you need to change your code to use serialEvent1() and Serial1 ...
 
Tested with an UNO (code below) using default USB connection as serial port inn both cases (teensy 3.1 and UNO) - UNO it works - teensy does not - moving this to Bug reports as suggested by Paul below.

Code:
char tempBuffer[100] = {0};
const int MaxInput  = 10;
long prevMillis = 0;
int loopDelay = 1000; 

// ---------------------------------------------------------------------------
void setup()
// ---------------------------------------------------------------------------
{
  Serial.begin(115200);
  while (!Serial); // wait for connection to terminal emulator
  Serial.println("Enter something");
}

// ---------------------------------------------------------------------------
void loop()
// ---------------------------------------------------------------------------
{
  if (millis() > prevMillis + loopDelay)
  {
    prevMillis = millis(); // reset count
    Serial.println(".");
  }
}

// ---------------------------------------------------------------------------
void serialEvent()
// ---------------------------------------------------------------------------
{
  static unsigned int input_pos = 0;
  //Serial.println("+"); // debug so we know this has been called
  while (Serial.available()) 
  {
    char inByte = (char)Serial.read();
    switch (inByte)
    {
    case '\n':   // end of text
      tempBuffer [input_pos] = 0;  // terminating null byte
      Serial.println(tempBuffer);
      input_pos = 0;
      break;

    default:
      // only allow alphabet and punctuation chrs
      if (inByte >= 32 && inByte <= 126)
      {
        // keep adding if not full ... allow for terminating null byte
        if (input_pos < (MaxInput - 1)) tempBuffer[input_pos++] = inByte;
      } // end if((inByte ....
      break;
    }
  }
}
 
Status
Not open for further replies.
Back
Top