Shop OBEX P1 Docs P2 Docs Learn Events
Multiple UART Interfacing Issue In P2 — Parallax Forums

Multiple UART Interfacing Issue In P2

Hello,
we are developing code in c++ for multi - uart interfacing of parallax propeller 2 with Raspberry Pi 4.
In Raspberry Pi 4 we are using three different UART port (ttyAMA0, ttyAMA1, ttyAMA2) to send the data to Propeller P2 simultaneously using threading.

In P2 side we have taken three different cog to receive respective serial port data parallely in c++ code,
For UART communication in P2, We are using jm_fullduplexserial.spin2 file and it's also using cog. So when we are creating 3 UART, at the same time 6 cog is creating.

We required more cog for data manipulation in c++ code.
So is there any way we can receive 3 UART data parallely in c++ with only 3 cogs using Jm_fullduplexserial.spin2?

Comments

  • I am not able to help you in c++ but in terms of raw power the P2 has plenty to do it. I am managing 6x UARTS at 460800 baud concurrently in Forth+assembler with just one cog.

  • @jurop said:
    I am not able to help you in c++ but in terms of raw power the P2 has plenty to do it. I am managing 6x UARTS at 460800 baud concurrently in Forth+assembler with just one cog.

    Wow!!great, have you used Jm_fullduplexserial.spin2?

  • @disha_sudra said:

    @jurop said:
    I am not able to help you in c++ but in terms of raw power the P2 has plenty to do it. I am managing 6x UARTS at 460800 baud concurrently in Forth+assembler with just one cog.

    Wow!!great, have you used Jm_fullduplexserial.spin2?

    There is also:
    https://forums.parallax.com/discussion/172733/p2-multiport-x16-serial-driver-working-based-on-jonnymacs-fullduplexserial/p1

    Craig

  • pik33pik33 Posts: 2,366

    Wow!!great, have you used Jm_fullduplexserial.spin2?

    Not available in Forth :)

    The Jm_fullduplexserial.spin2 object is good for its purpose: you need an UART, you get the object and voila, you have the UART.
    But if you want more of them, duplicating the object is not optimal way to do. You have to write your own code, or modify the object - it is simple enough to hack and modify - to service more UARTs at once.

  • I have a C serial driver that doesn't use a cog that you can wrapper with your own code that works with flexprop.

    You can find it here: P2 Custom.

    Serial on the P2 is easy enough to do.

    Mike

  • Serial on the P2 is easy enough to do.

    Indeed. And while I don't need multi-port serial (yet), the way I wrote jm_fullduplexserial.spin2 was with the intention that it should be able to expand to multi-port in one cog. Ray (Cluso) demonstrated that. Multi-port serial using one cog is not new, people were doing it back with the P1. As Mike points out, P2 serial is easy via smart pins, so multi-port should be less work.

  • Stephen MoracoStephen Moraco Posts: 316
    edited 2023-01-24 01:02

    Another project for your reference with a lot of testing against it (certifying performance) is my Octo-Serial subsystem at github. Verification Page shows that I'm achieving 3.335 mBit full duplex performance on 8 channels simultaneously with no data loss.

  • @"Stephen Moraco" thank you, always great to see more complex projects to learn from.

  • What is the overall throughput you are trying to achieve? And what do your data packets look like?
    Can you reduce any bloat in your data packets to effectively gain any throughput ?

  • jmgjmg Posts: 15,173

    @disha_sudra said:
    In Raspberry Pi 4 we are using three different UART port (ttyAMA0, ttyAMA1, ttyAMA2) to send the data to Propeller P2 simultaneously using threading.

    What peak and sustained baud rates do you need (and what can the Pi 4 support) ?
    Do you need fully duplex, or is this half duplex ?

    As above, the smart pins on P2 can ease the SW loading, so you can drop data into buffers in bursts, but note that overall your whole application needs to keep up with the sustained average data flow.
    If that is not possible, you need to add HW or SW handshakes.

  • @iseries said:
    I have a C serial driver that doesn't use a cog that you can wrapper with your own code that works with flexprop.

    You can find it here: P2 Custom.

    Serial on the P2 is easy enough to do.

    Mike

    Hello @iseries,
    We tried to use libserial library for serial communication. We are running basic serial example serial_test.cpp(Attached).

    But we are not able to get the single byte from it. Please find attached output also, every time we are getting Zero value.

    Is there any additional setup/modification require to use Libserial?

  • Ok, I never tested it at 2Meg before. Had to look around to find something that would run that fast to test with.

    Most of the time I work with 9600 or 115200.

    Anyway I used putty with the Parallax prop plug. Set it to do 115200, 921600, 100000, and then 2000000.

    They all work just fine no issues. The fact that you're getting zeros means there's data being transmitted.

    Mike
    Serial Test

  • Anyway I used putty with the Parallax prop plug. Set it to do 115200, 921600, 100000, and then 2000000.

    We are already using Parallax P2 evaluation board with prop plug. Not able to receive data at baud rate higher than 9600.

  • Don't know what to say, In my configuration I have the prop plug connected to pins 51 and 52 with baud rate of 2Meg.

    The WiFi module is connected to the programming port where the program is loaded.

    In Putty set the baud rate on COM5, Prop Plug, to 2Meg and typed A B C and D.

    On the WiFi module connected to a terminal program see 41, and 42 in Hex.

    #include <stdio.h>
    #include <propeller.h>
    #include "serial.h"
    
    #define RXPIN 51
    #define TXPIN 52
    
    char Data[256];
    FILE *s;
    
    int main(int argc, char** argv)
    {
        int i;
    
        s = serial_open(RXPIN, TXPIN, 115200);
    
    
        Data[0] = serial_rxChar(s);
        Data[1] = serial_rxChar(s);
        Data[2] = serial_rxChar(s);
        Data[3] = serial_rxChar(s);
    
        printf("Serial: %x\n", Data[0]);
        printf("Serial2: %x\n", Data[1]);
    
        printf("done\n");
    
        while (1)
        {
            _waitms(1000);
        }
    }
    

    Mike

  • Hi @iseries,

    I'm able to receive data at baud rate of 921600. Still at higher baud rate, am not able to receive data. Here is the function for receiving data.

    void uart1() {
        printf("uart1\n");
        s = serial_open(RXPIN, TXPIN, 921600);
    
        int cnt = 0;
        if (serial_rxChar(s) == 251) {                  // R-pi send 251 to initiate communication.
            serial_txChar(s,248);                       // P2 send acknowledgement.
            while(1){
                serial_read(s, Data, BUFF_SIZE);        // Receiving data in buffer.
    
                cnt++;
                //printf("cnt : %d\n", cnt);
                if (cnt==10){                           // If 10 buffers received then break while loop.
                    serial_txChar(s,249);
                    break;
                }
                serial_txChar(s,249);                   // After every buffer send acknowledgement to R-pi.
            }
            printf("Total cnt : %d\n", cnt);    
        }
    }
    
  • Beau SchwabeBeau Schwabe Posts: 6,566
    edited 2023-02-03 20:52

    Other than optimizing a double acknowledgement at the end of 10 buffers and a slight discrepancy of 248 vs. 249 this should work if you have a clean or direct connection.

    Code to optimize double acknowledgement and breakout:

        int cnt = 0;
        if (serial_rxChar(s) == 251) {                  // R-pi send 251 to initiate communication.
            serial_txChar(s,248);                       // P2 send acknowledgement.
            while(cnt < 10){                            // If 10 buffers received then break while loop.
                serial_read(s, Data, BUFF_SIZE);        // Receiving data in buffer.
                cnt++;
                serial_txChar(s,249);                   // After every buffer send acknowledgement to R-pi. 
                //printf("cnt : %d\n", cnt);
            }
            printf("Total cnt : %d\n", cnt);    
        }
    

    Aside from that I would strongly recommend using structured data packets and CRC checking.... i.e.

    [ 251 ] [ BUFF_SIZE ] [ DATA1 ] [ DATA2 ]...[ DATAN ] [ CRC High ] [ CRC Low ]

    The CRC is a word variable representing the entire data packet ... if a "packet" is received and the CRC check is valid then send an acknowledgement to the Pi and advance your buffer counter

  • Well, I dug up my Pi 3B and hooked it up to the P2.

    I set the baudrate to 2000000 and it works just fine with the serial program.

    Here is the Pi program I used to send the data:

    /*
     * serialTest.c:
     *  Very simple program to test the serial port. Expects
     *  the port to be looped back to itself
     *
     * Copyright (c) 2012-2013 Gordon Henderson.
     ***********************************************************************
     * This file is part of wiringPi:
     *      https://github.com/WiringPi/WiringPi
     *
     *    wiringPi is free software: you can redistribute it and/or modify
     *    it under the terms of the GNU Lesser General Public License as published by
     *    the Free Software Foundation, either version 3 of the License, or
     *    (at your option) any later version.
     *
     *    wiringPi is distributed in the hope that it will be useful,
     *    but WITHOUT ANY WARRANTY; without even the implied warranty of
     *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     *    GNU Lesser General Public License for more details.
     *
     *    You should have received a copy of the GNU Lesser General Public License
     *    along with wiringPi.  If not, see <http://www.gnu.org/licenses/>.
     ***********************************************************************
     */
    
    #include <stdio.h>
    #include <string.h>
    #include <errno.h>
    
    #include <wiringPi.h>
    #include <wiringSerial.h>
    
    int main ()
    {
      int fd ;
      int count ;
      unsigned int nextTime ;
    
      if ((fd = serialOpen ("/dev/ttyS0", 2000000)) < 0)
      {
        fprintf (stderr, "Unable to open serial device: %s\n", strerror (errno)) ;
        return 1 ;
      }
    
      if (wiringPiSetup () == -1)
      {
        fprintf (stdout, "Unable to start wiringPi: %s\n", strerror (errno)) ;
        return 1 ;
      }
    
      nextTime = millis () + 300 ;
    
      for (count = 0 ; count < 256 ; )
      {
        if (millis () > nextTime)
        {
          printf ("\nOut: %3d: ", count) ;
          fflush (stdout) ;
          serialPutchar (fd, count) ;
          nextTime += 300 ;
          ++count ;
        }
    
        delay (3) ;
    
        while (serialDataAvail (fd))
        {
          printf (" -> %3d", serialGetchar (fd)) ;
          fflush (stdout) ;
        }
      }
    
      printf ("\n") ;
      return 0 ;
    }
    

    This is the receiving program on the P2:

    #include <stdio.h>
    #include <propeller.h>
    #include "serial.h"
    
    #define RXPIN 36
    #define TXPIN 37
    
    char Data[256];
    FILE *s;
    
    int main(int argc, char** argv)
    {
        int i;
    
        s = serial_open(RXPIN, TXPIN, 2000000);
    
    
        Data[0] = serial_rxChar(s);
        Data[1] = serial_rxChar(s);
        Data[2] = serial_rxChar(s);
        Data[3] = serial_rxChar(s);
    
        printf("Serial: %x\n", Data[0]);
        printf("Serial2: %x\n", Data[1]);
    
        printf("done\n");
    
        while (1)
        {
            _waitms(1000);
        }
    }
    

    And finally this is a picture of the wiring:
    Pi to P2 Wiring

    On the Pi I used GPIO14(TX), and GPIO15(RX).
    On the P2 I used Pin36.

    I used an LED to check that data was being sent.

    Mike

  • I set the baudrate to 2000000 and it works just fine with the serial program.

    We tried your code and wiringPi library. Achieved maximum baud rate (2000000) to data transfer but, speed is comparatively too low. Received 19200 bytes in 7 sec. Using my previous R-pi code, able to receive 1 MB data in 12 sec at baud rate 921600.

Sign In or Register to comment.