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

Thread: Usart interrupt technique on teensy4.1

  1. #1
    Junior Member
    Join Date
    May 2021
    Posts
    6

    Usart interrupt technique on teensy4.1

    Hi everybody,
    i would like an example of code where is used a uart interrupt
    technique for receive data for teensy 4.1.
    I would like that every time I receive a data the interrupt is triggered and that data is acquired and processed(buffered).

    I do so normally with the micro that I currently use, I would like to do it also with the teensy 4.1.

    thanks

  2. #2
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    9,206
    Simply look at the sources for the Hardware Serial ports. In this case: in <arduino install>\hardware\teensy\avr\cores\teensy4\hardwar eSerial.cpp (.h for class definition).
    Look at the method HardwareSerial::IRQHandler()

  3. #3
    Junior Member
    Join Date
    May 2021
    Posts
    6
    Thx
    i have see the file HardwareSerial.cpp
    but there is a simply program example that demostrate the use of that library in a sketch?

  4. #4
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    14,421
    Any use of Serial1 ( or other UART port ) will use the included library code - See :: <arduino install>\examples\04.Communication\SerialPassthrou gh\SerialPassthrough.ino

    Using that for Serial1 - just jumper pin 0 to pin 1 and anything sent on USB Serial will cross over Serial1 and echo out Serial USB.
    Code:
    void setup() {
      Serial.begin(9600);
      Serial1.begin(9600);
    }
    
    void loop() {
      if (Serial.available()) {      // If anything comes in Serial (USB),
        Serial1.write(Serial.read());   // read it and send it out Serial1 (pins 0 & 1)
      }
    
      if (Serial1.available()) {     // If anything comes in Serial1 (pins 0 & 1)
        Serial.write(Serial1.read());   // read it and send it out Serial (USB)
      }
    }

  5. #5
    Junior Member
    Join Date
    May 2021
    Posts
    6
    Thx but i dont want check in Main always if a data is available in serial port,i want that if a data is received an interrupt handler start thx

  6. #6
    Senior Member
    Join Date
    Apr 2014
    Location
    Cheltenham, UK
    Posts
    298
    Serial data from is captured under interrupts and stored in the serial input buffer.
    When you get data from the serial port you are actually taking it from the serial buffer.

  7. #7
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    9,206
    Sorry, it is really unclear to me what you are actually asking for. So it is hard to know how best to try to answer.

    You say you did something like this with another micro. But it is unclear from this if your other micro was some form of Arduino setup? And what it is you are trying to do with a Teensy 4.1.

    Have you installed a recent copy of Arduino and then installed a recent copy of Teensyduino? Personally would suggest the latest beta...

    With Arduino like boards, hardware Serial ports are typically handled by the HardwareSerial class (some other boards call the class something different)
    Details on the basics of it are up at: https://www.arduino.cc/reference/en/...cation/serial/

    On a Teensy 4.1 there are something like 8 hardware Serial ports. You will see which pins are connected to them on the Teensy 4.1 card which is also on the product page: https://www.pjrc.com/store/teensy41.html#pins

    So for example if you are using the Hardware Serial port connected to pins 0 and 1 this is Serial1.

    If you do something like: Serial1.println("Hello world");
    The HardwareSerial class will put these bytes out into a software queue, and try to return immediately. Only if the queue fills up will the code have to wait until enough characters are transferred out to make room for the rest of the data.

    If data is received on the hardware Serial port. The ISR associated with this port, will retrieve the data and put it into a software buffer, which your code can retrieve when it desires to.
    You read the data using something like: int mychar = Serial1.read();
    You can at any time see if there data in the queue by calling Serial.available();

    Arduino has also defined a sort of different way to know that you have data available in the Serial RX queue, which you can see up at: https://www.arduino.cc/reference/en/...l/serialevent/

    But basically for Serial1 you can write a function named: serialEvent1
    like: void serialEvent1() {....};

    Which in some Arduino implementations, gets called every time you return from loop() and there is something in the Serial1's RX queue. On Teensy this is somewhat extended and it is called every time your code
    does some form of yield (either direct calls, or calls to delay ....) Note: I typically don't use these.

    As I mentioned in the first reply, if you are wanting to know how this all works, all of this code is in the source files: in this case HardwareSerial.cpp and HardwareSerial.h

    To understand this code, you will probably need to refer to several chapters in the IMXRT reference manual, which if you have not already done so, there is links to it on the Teensy 4.1 product page.
    The main chapter is the LPUART which is chapter 49.

  8. #8
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    8,558
    Would be interesting to know *WHY* you need that.
    As use of interrupts is not that easy (The forum is full of questions re: "not working" interrupt-code) and the given link to the code clearly show how you could do it (simply insert a call?) I don't think interrupts are the right way for you. As all received (and to send) data is buffered, there must be a very interesting reason why you need it

  9. #9
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    14,421
    Quote Originally Posted by Emanuele View Post
    Thx
    i have see the file HardwareSerial.cpp
    but there is a simply program example that demostrate the use of that library in a sketch?
    Quote Originally Posted by Frank B View Post
    Would be interesting to know *WHY* you need that.
    As use of interrupts is not that easy (The forum is full of questions re: "not working" interrupt-code) and the given link to the code clearly show how you could do it (simply insert a call?) I don't think interrupts are the right way for you. As all received (and to send) data is buffered, there must be a very interesting reason why you need it
    Yes very unclear - as noted a demonstration asked for - simple as example in p#4. Given that the underlying code and interrupt usage can be observed ... it could be hooked or edited as desired - perhaps the interrupt could be chained - allowed to work and acted on when it returns ...

    That sketch is all it takes to activate and demonstrate the underlying library code. it is already tested and works.

  10. #10
    Junior Member
    Join Date
    May 2021
    Posts
    6
    Sorry I try to clarify usually i am working with pic in C or Assembler i do not know in depth teensy 4.1 arduino and its libraries.
    I am trying to learn now.

    I try to explain myself better:
    usually i programming the serial device by enabling the interrupt on reception.
    In main I can do what I want (even do nothing) when
    a serial data arrives, an interrupt is triggered in reception and I acquire in that interrupt the serial data.
    I would like to do this also with teensy 4.1 and I would like a sketch that shows me this.
    Code:
    void setup() {
      Serial.begin(9600);
      Serial1.begin(9600);
    }
    
    void loop() {
      if (Serial.available()) {      // If anything comes in Serial (USB),
        Serial1.write(Serial.read());   // read it and send it out Serial1 (pins 0 & 1)
      }
    
      if (Serial1.available()) {     // If anything comes in Serial1 (pins 0 & 1)
        Serial.write(Serial1.read());   // read it and send it out Serial (USB)
      }
    }
    this code is not correct because in the main it has to constantly check if a data is present.
    I simply want to program the serial device so that as soon as data arrives in the reception buffer, an interrupt is triggered.
    Thx

  11. #11
    Junior Member
    Join Date
    May 2021
    Posts
    6
    simply i want to be able to write some code inside the receiving interrupt...
    i have to be able to do it otherwise I don't have control of the microcontroller....
    Thx

  12. #12
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    14,421
    This code does have full control over the MCU - just a different idea or purpose.

    Not sure if the PIC in normal use has one tenth or 1/100th the speed/power of the T_4.1

    PJRC has encapsulated the devices and resources under the banner of Arduino - all through normal C/cpp interfaces from gcc compiler toolset where the 3000++ pages of the manual details have wrapper code in place to use all the covered devices.

    The above code would allow polling of the hardware buffered Serial1 data some 5 millions times a second.

    As indicated in post #2 the source code is present with the installed TeensyDuino. That source can be edited or modified or repurposed as desired.

    Also as noted the interrupt responding to the Serial1 could perhaps be chained through for desired purposes.

    No limit to desired edits in accordance with the Ref Man and MCU capabilities.

  13. #13
    Quote Originally Posted by Emanuele View Post
    simply i want to be able to write some code inside the receiving interrupt...
    i have to be able to do it otherwise I don't have control of the microcontroller....
    Thx
    The Teensy core is already handling the reception of serial via interrupt and loading into a buffer for you.

    If you wish to do something more than that in the interrupt, you should be able to modify the HardwareSerial files in the core. I don't think there are any examples of that, so please share if you get it working.

  14. #14
    Senior Member brtaylor's Avatar
    Join Date
    Mar 2016
    Location
    Portland, OR
    Posts
    682
    Frank B had an interrupt chain for Teensy 3.x - I'm assuming that this would still work on Teensy 4.x.

    Code:
    class interruptChain {
      public:
        void chainInterrupt(int intNumber, void (*interruptPtr)(void)) {
    			prevInterruptPtr = _VectorsRam[intNumber];
    			_VectorsRam[intNumber] = interruptPtr;
        }
        inline void callNext(void) {
          prevInterruptPtr();
        }
      protected:
        void (*prevInterruptPtr)(void);
    };
    So, using this for Serial1, I could create an instance, like:

    Code:
    interruptChain _serial1Interrupt;
    And then I would initialize it by passing the IRQ and an interrupt handler:

    Code:
    _serial1Interrupt.chainInterrupt(IRQ_UART0_STATUS + 16, serial1_int_handler);
    Where serial1_int_handler is the interrupt handler. This would get called every time a byte is received by Serial1. Inside of the interrupt handler, you need to call next right away to not break the interrupt chain:

    Code:
    void serial1_int_handler(void)
    {
      _serial1Interrupt.callNext();
      // do stuff
    }

  15. #15
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    14,421
    Quote Originally Posted by brtaylor View Post
    Frank B had an interrupt chain for Teensy 3.x - I'm assuming that this would still work on Teensy 4.x.

    ...
    Yes, just that ... so much for leaving a little mystery ...

  16. #16
    Senior Member brtaylor's Avatar
    Join Date
    Mar 2016
    Location
    Portland, OR
    Posts
    682
    Quote Originally Posted by defragster View Post
    Yes, just that ... so much for leaving a little mystery ...
    Well, if someone is searching for this in the future and stumbles across the thread, they’ll have some solutions to use.

  17. #17
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    14,421
    Quote Originally Posted by brtaylor View Post
    Well, if someone is searching for this in the future and stumbles across the thread, they’ll have some solutions to use.
    Indeed! Good job looking it up ... hopefully the OP will appreciate not having to find it.

    Of course doing anything with that can be risky - except setting a flag to poll and exiting to use the existing interface ... stalling the interrupt can break the processing.

  18. #18
    Junior Member
    Join Date
    May 2021
    Posts
    6
    Yessss soon i will try that code....if work i will share thx brtaylor and thx to all that help me

  19. #19
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    9,206
    Personally I think this is a wrong approach, unless there is a real strong reason on why one needs to setup their code this way. It is sort of like the old days on limited processors I used to write self modifying code.
    But these days would not even think of doing so.

    That is you are hard coding you sketch to some specific hardware and some specific configuration... And understanding of what the underlying ISR does.

    For example what interrupt are you actually trying to hook? For example on Serial1 of a T4.x currently all of them use LPUART6 and Serial2 uses LPUART4, but maybe that might change with the
    Teensy MicroMod as maybe we could decide to reorder the Serial objects on that board to better match their naming of Pins/signals... Maybe it will be a different LPUART under it.

    Also this ISR is not just called to receive data, it is also setup to send data as well and to know when the TX has fully completed... And as your code will be called on an ISR, you run into all of the
    normal issues of ISRs, timing...

    But if it gets your job done....

  20. #20
    Senior Member
    Join Date
    May 2015
    Location
    USA
    Posts
    990
    +1 on using serialEvent() if you don't want to poll.

Posting Permissions

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