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

Thread: Teensyduino 1.20 Released

  1. #26
    Senior Member xxxajk's Avatar
    Join Date
    Nov 2013
    Location
    Buffalo, NY USA
    Posts
    528
    I'm already in contact with Chris, and I'll be emailing you soon the new SIP.cpp and SPI.h files in a couple of hours. I need to do more testing first. You will have to do testing for Due, which I don't own. I need to also finish the Due fixes as well.

  2. #27
    Senior Member xxxajk's Avatar
    Join Date
    Nov 2013
    Location
    Buffalo, NY USA
    Posts
    528
    as far as digitalPinToInterrupt() thanks for the tip. The new library will require 1.0.6 or better anyway.

  3. #28
    Senior Member xxxajk's Avatar
    Join Date
    Nov 2013
    Location
    Buffalo, NY USA
    Posts
    528
    Oh by the way, the gui uploader now works properly. Thanks! I don't know if you have had reports of it working well, consider this one....

  4. #29
    Senior Member xxxajk's Avatar
    Join Date
    Nov 2013
    Location
    Buffalo, NY USA
    Posts
    528
    Looks like there is a bug with attachInterrupt(). The ISR is expecting to be ran with interrupts off (like it does on the AVR). Any chance to fix this?

  5. #30
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    20,554
    I don't understand what you mean by "The ISR is expecting to be ran with interrupts off". Maybe explain in a little more detail?

  6. #31
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    20,554
    Maybe you're looking at the PRIMASK bit, which is manipulated by cli() and __disable_irq()?

    On AVR, the GIE bit is the only global mechanism which controls whether interrupts can occur. Of course, each interrupt has to be enabled within its peripheral, but just that 1 bit enables and disables all interrupts that are enabled within their peripheral hardware.

    ARM Cortex-M4 has a much more advanced system. PRIMASK can be used to prevent all interrupts from happening, so in that respect it's similar to AVR. But when you use sei() or __enable_irq() to clear PRIMASK, that does NOT necessarily allow all configured interrupts to occur. ARM has more stuff that controls which interrupt can happen.

    The ARM core has a seldom accessed register called ICSR, which automatically get updated with the new priority level of an interrupt. Normally nobody writes code to access it, since it automatically manages itself. Suppose a pin change interrupt occurs and your function is running, because you used attachInterrupt. It will be running at the default priority level, which is 128. Even though PRIMASK is clear (allowing all interrupts), the setting in ICSR will always mask all other interrupts configured at 128 and lower priority (higher numbers are lower priority levels).

    On AVR, the processor clear the GIE bit as it starts executing your interrupt. If it didn't, then your interrupt could interrupt itself, and all others could too, which would lead to chaos.

    On ARM, the processor updates ICSR as it starts executing your interrupt. It does NOT change PRIMASK, because its interrupt system is very different from the simplistic one on AVR. So while your interrupt runs, if you look only at PRIMASK and apply experience with AVR, it might seem as if things are going horribly wrong. In fact, that's how ARM works. ICSR is the normal mechanism for managing which interrupts can happen, not PRIMASK.

    ARM also has 2 bits that control each interrupt. On AVR, there's only 1 per interrupt, inside the peripheral itself. Most of the peripherals have a bit that controls whether that will generate interrupts, but there's also a 2nd bit inside the CPU core for every interrupt. AVR has nothing like this. On ARM, there's a few bits in the CPU for every interrupt, that enable/disable it, independently of the bit inside the peripheral itself. There's also a bit that tells whether the interrupt is pending and hasn't run yet. AVR has such a bit for each interrupt, but they're not memory mapped so you can't access them. On ARM, all those bits are in registers. There's also bits to force any interrupt to become pending, and to clear the pending status. There's also a bit to track if the interrupt is actually running, which adds another layer of protections to prevent the core from every running 2 instances of the same ISR (which normally couldn't happen anyway due to the priority scheme, but could if you reconfigured the priority at runtime in wreckless ways).

    Anyway, the long-winded point is the ARM interrupt controller is much more sophisticated than AVR's. Things like PRIMASK provide similar capability to disable interrupts temporarily, but they're not perfectly equivalent to AVR.

  7. #32
    Senior Member xxxajk's Avatar
    Join Date
    Nov 2013
    Location
    Buffalo, NY USA
    Posts
    528
    Argh. Yes, I am aware it is much more complex. Yes, I am using PRIMASK. I thought that primask blocks the current level and irq.

  8. #33
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    20,554
    Yes, PRIMASK blocks everything except faults.

    PRIMASK should only be used for very brief interrupt disable, without calling other functions. The other features, like raising base priority or masking specific interrupts should be used if you need to disable an interrupt for longer times.

  9. #34
    Senior Member xxxajk's Avatar
    Join Date
    Nov 2013
    Location
    Buffalo, NY USA
    Posts
    528
    Basically the trouble is that the user sketch interferes with the isr, since they both want access to parts at the same time.
    Also, on avr arduinos, when an isr is entered from attachinterrupt, it is expecting to have irq's off...
    I do have to call a few other parts too...
    Basically the code I am using is something like this:

    void someisr(void) {

    [critical code]

    if (we are not already in something critical flags) {
    interrupts();
    [does a pile of non-critical code]

    }

    On avr it is expecting cli to have been done for you...

  10. #35
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    20,554
    Is the interference only due to both wanting to access the SPI port?

  11. #36
    Senior Member xxxajk's Avatar
    Join Date
    Nov 2013
    Location
    Buffalo, NY USA
    Posts
    528
    The case happens when I am in the bottom half, and a re-entrant irq hits and starts to use SPI too, which is the intention, and this works fine on the avr.
    I'll email you the current SPI.cpp and SPI.h so you can take a look at it. That said, attachInterrupt does need to do noInterrupts() as early as possible. It is expected behavior, which happens to be automatically done on the AVR.

  12. #37
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    20,554
    When you say "re-entrant irq", do you mean the USB chip asserts its INT pin again and the function runs again, recursively, while a previous copy is still running?

  13. #38
    Senior Member xxxajk's Avatar
    Join Date
    Nov 2013
    Location
    Buffalo, NY USA
    Posts
    528
    Yes, The top half is fully intended to be allowed to run when an irq is generated by the bottom half, which enables interrupts.

  14. #39
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    20,554
    I'm afraid this type of approach is nearly impossible on ARM. The hardware manages interrupts and it's designed to prevent the same ISR from running again until it's completed the previous run.

  15. #40
    Senior Member xxxajk's Avatar
    Join Date
    Nov 2013
    Location
    Buffalo, NY USA
    Posts
    528
    Here is the code, with parts muted....

    Code:
    void MAX3421E_HOST::ISRTask(void) //USB state machine
    {
           {
                    uint8_t HIRQ_sendback = 0x00;
                    uint8_t HIRQALL = regRd(rHIRQ); //determine interrupt source
                    uint8_t HIRQ = HIRQALL & IRQ_CHECK_MASK;
                    [ this section does what it needs to do based on the HIRQ value....]
            }
            if(!disabled) {
                    Disable(); // sets disabled to true
                    // Enable interrupts
                    interrupts();
                    switch(usb_task_state) {
                            [This section does various state machine operations, some controlled from the top half]
                    }
                    // Disable interrupts
                    noInterrupts();
                    Enable(); // sets disabled to false
            }
    }

    Note also that the code expects that irq is disabled at the end, this is how they would be on an avr...
    I tried working around this by adding noInterrupts() at the top, and interrupts() at the bottom, and while the avr could care less either way, it is either too late for the arm (unlikely) or something else is happening... I have not looked into the code in the teensy3 core yet, but are you disabling the pin or something?

  16. #41
    Senior Member xxxajk's Avatar
    Join Date
    Nov 2013
    Location
    Buffalo, NY USA
    Posts
    528
    Quote Originally Posted by PaulStoffregen View Post
    I'm afraid this type of approach is nearly impossible on ARM. The hardware manages interrupts and it's designed to prevent the same ISR from running again until it's completed the previous run.
    Argh, got an idea for this then?

  17. #42
    Senior Member xxxajk's Avatar
    Join Date
    Nov 2013
    Location
    Buffalo, NY USA
    Posts
    528
    What if you...
    cli();
    push helper_stub_address
    return

    and the stub...
    calls the isr that is attached
    sei();
    ret <-- this should return back to the place we got interrupted from

    Of course you would have to push/pop registers, and this is just the terse form.

  18. #43

  19. #44
    Senior Member xxxajk's Avatar
    Join Date
    Nov 2013
    Location
    Buffalo, NY USA
    Posts
    528
    So I'm guessing this is my problem....

  20. #45
    Senior Member xxxajk's Avatar
    Join Date
    Nov 2013
    Location
    Buffalo, NY USA
    Posts
    528
    I believe I know how I can solve this in my own code... I know exactly where it occurs :-)

  21. #46
    Senior Member xxxajk's Avatar
    Join Date
    Nov 2013
    Location
    Buffalo, NY USA
    Posts
    528
    Read passed, Read 500 sectors in 1000ms
    Test complete.

    Thanks for explaining the inability to reenter ISRs, I've fixed it so that it works now. This means that the code I sent you passes my tests as atomically correct.

  22. #47
    Senior Member xxxajk's Avatar
    Join Date
    Nov 2013
    Location
    Buffalo, NY USA
    Posts
    528
    I have a few extra bits-and-chunks I want to clean up in the code i emailed to you. I can post here a zip file containing the replacement files within a couple of hours.
    .

  23. #48
    Senior Member xxxajk's Avatar
    Join Date
    Nov 2013
    Location
    Buffalo, NY USA
    Posts
    528
    Here is what I tested, and works rock solid. I really abused things in order to make certain that corruption won't happen.

    • Teensy++ 2.0 PASS
    • Teensy 3.0 PASS
    • Teensy 3.1 PASS
    • Arduino UNO PASS
    • Arduino Duemilanove PASS
    • Arduino Diecimila PASS
    • Arduino Mega PASS
    • Arduino Mega 2560 PASS
    • Digilent Uno-32 NOT COMPATIBLE


    Boards not listed are not owned by me, thus are not tested.
    Attached Files Attached Files

  24. #49
    Senior Member pictographer's Avatar
    Join Date
    May 2013
    Location
    San Jose, CA
    Posts
    664
    Installed OS X Yosemite Version 10.10. The Arduino IDE wouldn't run until I installed a legacy Java update JavaForOSX2014-001.dmg. After that I was able to flash a T3.1 with the blink example with no problems.

  25. #50
    Senior Member
    Join Date
    Aug 2014
    Posts
    165
    Quote Originally Posted by pictographer View Post
    Installed OS X Yosemite Version 10.10. The Arduino IDE wouldn't run until I installed a legacy Java update JavaForOSX2014-001.dmg. After that I was able to flash a T3.1 with the blink example with no problems.
    Same for me - all working well.

    In fact I think the uploader works better? Or am I just imagining that? Sometimes before I'd have to click on the Teensyduino app for it to upload to the board after the Arduino IDE had tried x number of times and failed.

Posting Permissions

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