1

Hope you are all well. I am experiencing a weird trouble while trying to make a serial communication with RPi-Pico -> PC. From Pico I am sending 9 Bytes packet (8 Byte Data from ADC + \n) once a second through Serial communication using USB BUS. While reading it from windows, my program at the first hand reading nothing, only staying at the if (!WaitCommEvent(hComm, &dwEventMask, NULL)) stage. But if I run putty with any configuration, then data is shown in putty. After closing putty if I run my program, surprisingly it's also reading data without any fail!!!! Again after restarting the Pico, same situation comes back. That's so far very much unknown feature for me. Could any of you help me to solve that situation? I am sending the code snippet for analysis. Thank you so much in advance. Have a great day / evening!

hComm = CreateFileA(commPortName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
        if (hComm == INVALID_HANDLE_VALUE)
            cout << "\nError Port " << commPortName << " can't be opened!!!\n";
        else
            cout << "\nPort " << commPortName << " is opened!!\n";
        dcbParams.DCBlength = sizeof(dcbParams);
        if (!GetCommState(hComm, &dcbParams))
            cout << "\nError in GetCommState()\n";
        dcbParams.BaudRate = CBR_115200; dcbParams.ByteSize = 8; 
        dcbParams.StopBits = ONESTOPBIT; dcbParams.Parity = NOPARITY;
        if (!SetCommState(hComm, &dcbParams))
            cout << "\nError in setting Device-Control Block(DCB)\n";
        else
        {
            cout << "\n\n    Setting DCB Structure Successfull" 
                << "\n       Baudrate --> " << dcbParams.BaudRate 
                << "\n       ByteSize --> " << (unsigned int)dcbParams.ByteSize 
                << "\n       StopBits --> " << (unsigned int)dcbParams.StopBits 
                << "\n       Parity   --> " << (unsigned int)dcbParams.Parity;
        }
        timeouts.ReadIntervalTimeout = 50;
        timeouts.ReadTotalTimeoutConstant = 50;
        timeouts.ReadTotalTimeoutMultiplier = 10;
        if (!SetCommTimeouts(hComm, &timeouts))
            cout << "\n\n    Error! in Setting Time Outs\n";
        else
            cout << "\n\n    Setting Serial Port Timeouts Successfull\n";
        if (!SetCommMask(hComm, EV_RXCHAR))
            cout << "\n\n    Error! in Setting Communication Mask\n";
        else
            cout << "\n\n    Setting Communication Mask successfull\n";
        cout << "\n\n    Waiting for Data Reception....\n";
        for (int i = 0; i <= 99; i+=1)
        {
            if (!WaitCommEvent(hComm, &dwEventMask, NULL))
                cout << "\n    Error! in Setting Wait for Communication Event...!\n";
            else
            {
                ReadFile(hComm, &readBuffer, sizeof(readBuffer), &noBytesRead, NULL);
                cout << "           " << readBuffer;
            }
        }
        CloseHandle(hComm);
Luzian
  • 13
  • 3
  • It could be a configuration issue as you said. Try to compare the MASK and the [COMMCONFIG](https://learn.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-commconfig) before and after. – YangXiaoPo-MSFT Mar 08 '23 at 06:50
  • Thank you @YangXiaoPo-MSFT for your reply. I tried the methods. The result I am writing below. Everything is zero except `wcProviderData`. Is there any other mask rather than EV_RXCHAR to receive data? Baudrate --> 115200 ByteSize --> 8 StopBits --> 0 Parity --> 0 Returned Mask Value : 0 dwSize --> 0 wVersion --> 0 dwProviderSubType --> 0 dwProviderOffset --> 0 dwProviderSize --> 0 wcProviderData --> 0x7ff7091588d0 – Luzian Mar 08 '23 at 22:46
  • I mean comparing the configuration before putty and after putty. After checking the [putty](https://github.com/github/putty/blob/7003b43963aef6cdf2841c2a882a684025f1d806/windows/winser.c#L94) source, in which only [SetCommState](https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-setcommstate) and *SetCommMask* are involved, [The DTR (data-terminal-ready) flow control](https://learn.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-dcb) could be the issue. – YangXiaoPo-MSFT Mar 09 '23 at 01:51
  • 1
    Thank you so much @YangXiaoPo-MSFT for the help! The issue is resolved. I had to add `dcbParams.fDtrControl = DTR_CONTROL_ENABLE` to the dcb. RPi-Pico is strictly DTR controlled. Thanks a lot once again!!! – Luzian Mar 09 '23 at 15:46
  • Some should post the working snippet of code below as an answer so that this question will be useful to future readers. – David Grayson Mar 09 '23 at 19:15
  • Hello @DavidGrayson the code snippet I sent previously, is all ok, except one thing. That is : `dcbParams.fDtrControl = DTR_CONTROL_ENABLE` must be added at the stage of DCB Initialization. And for standard non overlapping serial communication in DIY, that's enough. But if someone wants to make a terminal software like "putty", then they will have to follow the whole DCB structure modification as mentioned by @YangXiaoPo-MSFT. – Luzian Mar 10 '23 at 17:38

1 Answers1

0

As @Luzian said in the question, it is a device configuration issue(SetCommState). After checking the putty source, The DTR (data-terminal-ready) flow control is not enabled in @Luzian 's code. And RPi-Pico proved to be strictly DTR controlled.

The following code is excerpted from putty.

    /*
     * Set up the serial port parameters. If we can't even
     * GetCommState, we ignore the problem on the grounds that the
     * user might have pointed us at some other type of two-way
     * device instead of a serial port.
     */
    if (GetCommState(serport, &dcb)) {
        const char *str;

        /*
         * Boilerplate.
         */
        dcb.fBinary = true;
        dcb.fDtrControl = DTR_CONTROL_ENABLE;
        dcb.fDsrSensitivity = false;
        dcb.fTXContinueOnXoff = false;
        dcb.fOutX = false;
        dcb.fInX = false;
        dcb.fErrorChar = false;
        dcb.fNull = false;
        dcb.fRtsControl = RTS_CONTROL_ENABLE;
        dcb.fAbortOnError = false;
        dcb.fOutxCtsFlow = false;
        dcb.fOutxDsrFlow = false;
        ...
    }
YangXiaoPo-MSFT
  • 1,589
  • 1
  • 4
  • 22