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

Thread: Teensy 4.0 and single-wire serial

  1. #1
    Senior Member
    Join Date
    Jan 2014
    Posts
    110

    Teensy 4.0 and single-wire serial

    Hi,

    I'm trying to switch Teensy 4.0 serials into single-wire mode but it doesn't quite work for me. I'm trying to follow the i.MX RT1060 Processor Reference Manual and do the following:

    First I initialize Serial port 1 normally
    Code:
    Serial1.begin(57600);
    then I switch the port into single-wire operation but setting the LOOPS and RSRC flags of the Serial 1 (UART6) CTRL register
    Code:
    LPUART6_CTRL |= (LPUART_CTRL_LOOPS | LPUART_CTRL_RSRC);
    finally I switch the port into receive mode by making sure the TXDIR flag of the same CTRL register is cleared
    Code:
    LPUART6_CTRL &= ~LPUART_CTRL_TXDIR;
    Then I connect the TX pin of Serial1 to TX pin of Serial2 and send some data in the loop from Serial2. Unfortunately none of that is received by Serial1.

    Am I missing something?

    Here is the complete code I use
    Code:
    void setup() {
      Serial.begin(115200);
      Serial1.begin(57600);
      LPUART6_CTRL |= (LPUART_CTRL_LOOPS | LPUART_CTRL_RSRC);
      LPUART6_CTRL &= ~LPUART_CTRL_TXDIR;
      Serial2.begin(57600);
      Serial.println("Teensy 4.0 Single-Wire Serial Test");
    }
    
    void loop() {
      Serial2.write(0x02);
      if(Serial1.available()) Serial.println(Serial1.read(), HEX);
    }
    I'm using Arduino 1.8.10 and Teensyduino 1.48

  2. #2
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    5,701
    I keep meaning to try it, I have so far run my Dynamixel servos using a buffer like chip with a direction IO pin...

    But I keep meaning to add the code to my BioloidSerial code to allow to use a single pin.

    If/When I do it, I will probably start off similar to what you have, however some things I would check and need to address, include:

    I believe you need to configure the IOMUXC input daisy chain... In this case Page 856 in reference manual, you probably need:
    Code:
    IOMUXC_LPUART6_TX_SELECT_INPUT = 1
    And in addition I would probably update the TX pins configuration information.
    Example on T3.x I do:
    Code:
     volatile uint32_t *reg = portConfigRegister(tx_pin);
            *reg = PORT_PCR_DSE | PORT_PCR_SRE | PORT_PCR_MUX(3) | PORT_PCR_PE | PORT_PCR_PS; // pullup on output pin;
    But of course different registers for T4... but same idea of enable the PU resistor...

  3. #3
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    10,069
    AFAIK - didn't see any such testing on the Beta thread.

    What pins are in use?

    The Serial1 code will have expectations/config on Rx and Tx pins. Making above change after to the alter UART function may not be effective/complete with that standard config?

    .. funny … detailed crosspost with the master

  4. #4
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    3,133
    I don't think you can use the core Serialx library on a modified single wire bus, you'd need to implement another library to handle it.

  5. #5
    Senior Member+ manitou's Avatar
    Join Date
    Jan 2013
    Posts
    2,235
    In January, I successfully ran OneWire lib example with DS18B20 attached to T4

  6. #6
    Senior Member
    Join Date
    Jan 2014
    Posts
    110
    Thank you all for the quick reply

    Quote Originally Posted by KurtE View Post
    I believe you need to configure the IOMUXC input daisy chain... In this case Page 856 in reference manual, you probably need:
    Code:
    IOMUXC_LPUART6_TX_SELECT_INPUT = 1
    That did the trick, thanks a lot!

  7. #7
    Senior Member
    Join Date
    Jan 2014
    Posts
    110
    BTW I've noticed that in HadwareSerialX.cpp configuration of the IOMUXC for TX pins in omitted for most of the serials (except Serial5/LPUART8). Is there any particular reason for that?

    Here is an example of Serial1

    Code:
    const HardwareSerial::hardware_t UART6_Hardware = {
        0, IRQ_LPUART6, &IRQHandler_Serial1, &serial_event_check_serial1,
        CCM_CCGR3, CCM_CCGR3_LPUART6(CCM_CCGR_ON),
        {{0,2, &IOMUXC_LPUART6_RX_SELECT_INPUT, 1}, {0xff, 0xff, nullptr, 0}},
        {{1,2, nullptr, 0}, {0xff, 0xff, nullptr, 0}},
        0xff, // No CTS pin
        0, // No CTS
        IRQ_PRIORITY, 38, 24, // IRQ, rts_low_watermark, rts_high_watermark

  8. #8
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    5,701
    The simple answer was because when I ported over HardwareSerial early in T4 beta and some Serial ports were not working, I finally figured out about the IOMUXC_..._SELECT_INPUT settings, and at the time I was unsure if I needed to also set the ones on the OUTPUT pins as well. Turns out no. It is only needed IF the pin is used as INPUT... I was probably testing on Serial5 when I figured out some of this... Now it may not hurt to someday fill in that table if for no other reason it documents it.

    Also not sure if there would be any negative effect to set it anyway in normal HardwareSerial cases.

    Also at one point I wanted to add in some new non standard APIs, something like:
    Serial1.setDuplex(HardwareSerial::HALF_DUPLEX);

    And either another API, like Serial1.setPinDirection(HardwareSerial::TX_PIN_INP UT);

    Again these are off to top of the head apis. And actually preferred, would have the code to not need the second one, but to work off of the transmitterEnable code, which when you to a Serial1.write(), automatically switches to TX mode, and when the ISR detects that the queue is empty and last byte has output (transmit complete), to switch back to input mode...

    Actually alternative to new api, and something I thought about hacking in, might to have something like:
    #define HALF_DUPLEX_PIN 0xfe
    Serial1.transmtterEnable(HALF_DUPLEX_PIN);

    and/or alternatively if the pin passed in is the TX pin...

    But I am not sure what @Paul would think of these additions. If I were to do this, would probably also put it into T3.x code base as well...

  9. #9
    Senior Member
    Join Date
    Jan 2014
    Posts
    110
    Thanks for clarification.

    Another alternative to set the port into single-wire mode would be to add new defines for format that could be passed to begin function, but I think a new API for the single-wire operation would be cleaner (it could even be one function to enable/disable and set direction at the same time). And yes, that should deffinitely be done for T3.x as well.

Posting Permissions

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