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

Thread: Teensy4.1 MAX baud rate

  1. #1
    Junior Member MO_YA_NE's Avatar
    Join Date
    May 2021
    Location
    Japan
    Posts
    6

    Teensy4.1 MAX baud rate

    Hi!
    I have been teensydiuno for the third day.
    I want to communicate with other MPUs at high speed using RS485 communication.
    I set the teensy 4.1 hardware serial to 6Mbps, but higher values ​​didn't work.
    Is there any way to get higher speeds?

    Code:
    void setup() {
    //  Serial1.begin(3000000);     //3M OK
        Serial1.begin(6000000);     //6M OK
    //  Serial1.begin(12000000);    //equal to 6M
    
    }
    
    void loop() {
      Serial1.write(0x55);
      delay(1000);
    }

  2. #2
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    9,117
    Currently the Serial code on T4.x is using the fixed 24mhz clock and probably the min divide is which gives your 6M...

    I believe it would be possible to make it faster. I have never tried it:

    In the cores\teensy4 directory:
    startup.c - Fixes the Serial to 24mhz:
    Code:
    	// UARTs run from 24 MHz clock (works if PLL3 off or bypassed)
    	CCM_CSCDR1 = (CCM_CSCDR1 & ~CCM_CSCDR1_UART_CLK_PODF(0x3F)) | CCM_CSCDR1_UART_CLK_SEL;
    This could be adjusted to use the PLL3 clock which I think is 480mhz
    So that register you would want to remove the CCM_CSCDR1_UART_CLK_SEL bit (Page 1062)
    Then if you look at the clock tree: page 1017 you will see then The PLL3_SW_CLOCK / 6 gets passed in so : 80mhz.
    We set the LCDIF_PRED field to 0 so divide by 1...

    Then the HardwareSerial code needs to be updated to know about this. Which again would not be hard.

    There is a define at line 63 of hardwareSerial.cpp: #define UART_CLOCK 24000000

    That is used in:
    Code:
    void HardwareSerial::begin(uint32_t baud, uint16_t format)
    {
    	//printf("HardwareSerial begin\n");
    	float base = (float)UART_CLOCK / (float)baud;
    We should instead read the CCM_CSCDR1 and compute the clock which is not hard:
    Simply see if the CCM_CSCDR1_UART_CLK_SEL bit is set then 24mhz else 80mhz / by the UART_CLK_PODF

    Note the PODF if I read correctly is either 0(1) or 0x3f which is: 2^6 or 64, which I have not tried or used...

    Then the rest should take care of it self... It may of course change the actual generated baud rates and how close some are...
    Example 6mhz with a 24mhz base is 24/6=4.. but at 80mhz 80/6= 13.333

  3. #3
    Junior Member MO_YA_NE's Avatar
    Join Date
    May 2021
    Location
    Japan
    Posts
    6
    Thanks for your reply Kurt-san.
    I hope I can get a higher baud rate with the method you suggested.

    I'm still not familiar with the clock division of the IMXRT1060.
    I'll try your ideas as I peruse the hardware manual.

  4. #4
    Junior Member MO_YA_NE's Avatar
    Join Date
    May 2021
    Location
    Japan
    Posts
    6
    Thank you Mr. KurtE ! It was exactly what you said!
    I am very grateful for your advice.
    I succeeded in raising the baud rate to 20Mbps.

    I just rewrote the UART_CLK_SEL bit in the CCM_CSCDR1 register to 0.
    Look at the code and the execution result.

    Code:
    void setup() {
    //  Serial1.begin(3000000);     //3M OK
    //  Serial1.begin(6000000);     //6M OK
        Serial1.begin(20000000);    //20MHz
        CCM_CSCDR1=105450240;       //UART_CLK_SEL bit set to 0
    }
    
    void loop() {
      Serial1.write(0x55);
      delay(1000);
    }
    Click image for larger version. 

Name:	20Mhz_uart.jpg 
Views:	8 
Size:	149.4 KB 
ID:	24743

  5. #5
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    9,117
    @PaulStoffregen - Wondering if I should update HardwareSerial to check the state of the CCM_CSCDR1
    And properly configure the baud rate for the input clock of either 24 or 80mhz?

    My guess is to leave the default for 24... Or could potentially add code that if the user asks for > 6mbs and no other active Hardware Serial ports, we could update that register as well.
    Could probably check if the other hardware ports are configured and reconfigure, but run into issues like what happens if the queue is active or input coming or ...

  6. #6
    Senior Member
    Join Date
    May 2015
    Location
    USA
    Posts
    919
    > I succeeded in raising the baud rate to 20Mbps.

    Have you found that this baud rate provides reliable data transfer?

  7. #7
    Junior Member MO_YA_NE's Avatar
    Join Date
    May 2021
    Location
    Japan
    Posts
    6
    I have not tried to send and receive actual data yet.
    I just saw the output waveform of TX1.
    I'm going to connect Teensy 4.1 with Renesas RX72T and Microchip PIC32MZ with RS485 and try the actual data communication.
    Click image for larger version. 

Name:	3boad.jpg 
Views:	7 
Size:	176.9 KB 
ID:	24744

  8. #8
    Junior Member MO_YA_NE's Avatar
    Join Date
    May 2021
    Location
    Japan
    Posts
    6
    I tried a program that connects teensy 4.1 and PIC32MZ and echo back.
    Teensy 4.1 sends characters at 20Mbps and PIC32MZ just adds 1 and returns.
    It looks working fine.
    Code:
    void setup() {
      pinMode(3, OUTPUT);
      
        while (!Serial) ;
      
    //  Serial1.begin(3000000);     //3M OK
    //  Serial1.begin(6000000);     //6M OK
        Serial1.begin(20000000);    //20MHz
        CCM_CSCDR1=105450240;       //UART_CLK_SEL bit set to 0
    }
    
    void loop() {
      char c1;
      Serial.printf("Press any key>");
      while(Serial.available()<=0){}
      c1=Serial.read();
    
      digitalWrite(3, HIGH);        //R/W=H
      Serial1.write(c1);
      Serial1.flush();
      digitalWrite(3, LOW);       //R/W=L
    
      while(Serial1.available()<=0){}
      c1=Serial1.read();
    
      Serial.printf("c1=%d\n\r",c1);    //
      
    }
    Click image for larger version. 

Name:	teensy_pic32_2.jpg 
Views:	17 
Size:	118.5 KB 
ID:	24746
    Click image for larger version. 

Name:	teensy_pic32_1.jpg 
Views:	11 
Size:	60.3 KB 
ID:	24747

  9. #9
    Senior Member
    Join Date
    May 2015
    Location
    USA
    Posts
    919
    I think a reasonable test would be to send a block of data at full speed, read back an echo and compare to check for any errors.

  10. #10
    Member
    Join Date
    Aug 2013
    Location
    Ohio
    Posts
    99

    NXP UARTs fine at 9.375 Mbits/sec in T3.5/T3.6 related project

    FWIW, I have been involved in a project that drives Kinetis K60 and K66 microcontroller UARTs at their max rate (150MHz sysclock /16=9.375) across optical links through 50MHz-rated transceivers. In early prototyping we drove these speeds through 12-18 inch (30-45cm) flying leads between overclocked K64F dev boards, without detectable errors (in an electromagnetically challenging environment no less...). Our little protocol uses CRC32 to check packet integrity for packet sizes ranging from 6 to about 400 bytes, and have not ever seen any issues attributable to transmission errors. This relates to the Teensy in that the Teensy 3.5 is based on the K64F and Teensy3.6 is based on the K66.

    Our system consists of 20 networked nodes, and they are stable and consistent. I have not tried the rt106x, being way busy with my day job. I would assume your tests should be successful even though the rt106x would be set to 8x oversampling rather then the 16x oversampling in the K6x (not configurable to the best of my knowledge).

    As you run experiments with your units, I would be very interested in knowing whether you have difficulties.

  11. #11
    Junior Member MO_YA_NE's Avatar
    Join Date
    May 2021
    Location
    Japan
    Posts
    6
    I extended the harness length to 2.5m and experimented again.
    I sent and received 20Mbps by 5000byte.

    The result was all 5000 bytes OK.
    It was carried out about 10 times, and the same result was obtained.


    I am trying to apply this to a 250W-motor driver.
    I am wondering if it is possible to communicate at 20Mbps in a high noise environment.

    Code:
    char Big_Data[5000];
    
    void setup() {
      pinMode(3, OUTPUT);
      
        while (!Serial) ;
      
    //  Serial1.begin(3000000);     //3M OK
    //  Serial1.begin(6000000);     //6M OK
        Serial1.begin(20000000);    //20MHz
        CCM_CSCDR1=105450240;       //UART_CLK_SEL bit set to 0
    }
    
    void loop() {
      char c;
      int i,data_num;
      int ok_cnt=0;
        
      data_num=5000;
        
      Serial.printf("Press any key>");
      while(Serial.available()<=0){}
      c=Serial.read();
      Serial.printf("\n\r");
    
      digitalWrite(3, HIGH);        //R/W=H
      for(i=0;i<data_num;i++){
      Serial1.write(255*i/data_num);
      Serial1.flush();
      }
      digitalWrite(3, LOW);       //R/W=L
    
      for(i=0;i<data_num;i++){
      while(Serial1.available()<=0){}
      Big_Data[i]=Serial1.read();
      }
    
      for(i=0;i<data_num;i++){
      if(Big_Data[i]==255*i/data_num+1) ok_cnt++;
      Serial.printf("%d %d\n\r",Big_Data[i],ok_cnt);    //
      }
      Serial.printf("OK_Count=%d\n\r",ok_cnt);      //
    
      
    }
    Click image for larger version. 

Name:	rs_485_2.5m.jpg 
Views:	12 
Size:	147.5 KB 
ID:	24750Click image for larger version. 

Name:	rs_485_2.5m_2.jpg 
Views:	8 
Size:	44.9 KB 
ID:	24751

  12. #12
    Senior Member
    Join Date
    Jul 2020
    Posts
    1,038
    Using differential signalling is going to maximize your change of success for this, so lets hope it works first time!

Posting Permissions

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