none
WEC2013 SerialPort receive RRS feed

  • Question

  • Hi everybody,

    i have a strange behaviour on my serial ports on WEC2013.

    In the registry i see COM1-COM3 with COM16550.dll driver.

    Sending data with WriteFile works fine.

    But no chance to receive any data.

    I have tried both methods, ReadFile and WaitCommEvent.

    On Windows7 the code works great, and thereby the cable connection must be also correct.

    Here is the code:   

    DWORD dwError;
    
        // Open the serial port.
        HANDLE hPort = CreateFile(L"COM2:", // Pointer to the name of the port
          GENERIC_READ | GENERIC_WRITE,
          // Access (read-write) mode
          0,            // Share mode
          NULL,         // Pointer to the security attribute
          OPEN_EXISTING,// How to open the serial port
          0,            // Port attributes
          NULL);        // Handle to port with attribute
                        // to copy
    
        DCB PortDCB;
    
        // Initialize the DCBlength member.
        PortDCB.DCBlength = sizeof(DCB);
    
        // Get the default port setting information.
        GetCommState(hPort, &PortDCB);
    
        // Change the DCB structure settings.
        PortDCB.BaudRate = 9600;              // Current baud
        PortDCB.fBinary = TRUE;               // Binary mode; no EOF check
        PortDCB.fParity = TRUE;               // Enable parity checking
        PortDCB.fOutxCtsFlow = FALSE;         // No CTS output flow control
        PortDCB.fOutxDsrFlow = FALSE;         // No DSR output flow control
        PortDCB.fDtrControl = DTR_CONTROL_ENABLE;
        // DTR flow control type
        PortDCB.fDsrSensitivity = FALSE;      // DSR sensitivity
        PortDCB.fTXContinueOnXoff = TRUE;     // XOFF continues Tx
        PortDCB.fOutX = FALSE;                // No XON/XOFF out flow control
        PortDCB.fInX = FALSE;                 // No XON/XOFF in flow control
        PortDCB.fErrorChar = FALSE;           // Disable error replacement
        PortDCB.fNull = FALSE;                // Disable null stripping
        PortDCB.fRtsControl = RTS_CONTROL_ENABLE;
        // RTS flow control
        PortDCB.fAbortOnError = FALSE;        // Do not abort reads/writes on
                                              // error
        PortDCB.ByteSize = 8;                 // Number of bits/byte, 4-8
        PortDCB.Parity = NOPARITY;            // 0-4=no,odd,even,mark,space
        PortDCB.StopBits = ONESTOPBIT;        // 0,1,2 = 1, 1.5, 2
    
                                              // Configure the port according to the specifications of the DCB
                                              // structure.
        if (!SetCommState(hPort, &PortDCB))
        {
          // Could not configure the serial port.
          dwError = GetLastError();
          printf("Unable to configure the serial port");
          return FALSE;
        }
    
        // Retrieve the timeout parameters for all read and write operations
        // on the port.
        COMMTIMEOUTS CommTimeouts;
        GetCommTimeouts(hPort, &CommTimeouts);
    
        // Change the COMMTIMEOUTS structure settings.
        CommTimeouts.ReadIntervalTimeout = MAXDWORD;
        CommTimeouts.ReadTotalTimeoutMultiplier = 0;
        CommTimeouts.ReadTotalTimeoutConstant = 0;
        CommTimeouts.WriteTotalTimeoutMultiplier = 10;
        CommTimeouts.WriteTotalTimeoutConstant = 1000;
    
        // Set the timeout parameters for all read and write operations
        // on the port.
        if (!SetCommTimeouts(hPort, &CommTimeouts))
        {
          // Could not set the timeout parameters.
          printf("Unable to set the timeout parameters");
          dwError = GetLastError();
          return FALSE;
        }
    
        dwBytesTransferred = 0;
        while (dwBytesTransferred == 0)
        {
            ReadFile(hPort,            // Port handle
            &Byte,                          // Pointer to data to read
            1,                                 // Number of bytes to read
            &dwBytesTransferred, // Pointer to number of bytes read
            NULL                            // Must be NULL for Windows CE
            );
        }
    
        CloseHandle(hPort);

    Can anybody give me some tips or had the same behaviour?

    Thanks in advance.

    Wednesday, November 22, 2017 9:24 AM

All replies

  • Can you send a long message, like 100 bytes?  Or does it only send a part of that message?  If the message is truncated, then I suspect an interrupt problem.

    I assume that you are using the same x86 board for both the WEC2013 and Windows 7 tests, is that correct?  If so, then you have verified the board - if not, can you?  And by same board, I don't mean a different board of the same type.  Assuming that you verified the board, then you have also verified the cables and your application.  Then the problem is in the serial driver, which may simply mean registry settings - so time to do some debugging.


    Bruce Eitman
    Senior Engineer
    Bruce.Eitman AT Synopsys DOT com
    My BLOG http://geekswithblogs.net/bruceeitman
    I work for Synopsys

    Wednesday, November 22, 2017 2:52 PM
    Moderator
  • Also try disabling DTR and RTS control.

    Good luck,

    Michel Verhagen, eMVP
    Check out my blog: https://guruce.com/blog

    GuruCE
    Microsoft Embedded Partner
    NXP Proven Partner
    https://guruce.com
    Consultancy, training and development services.

    Interested in WEC on i.MX6?
    Get the only 100% stable and best performing i.MX6 BSP for WEC7 and WEC2013 here: https://guruce.com/imx6

    Thursday, November 23, 2017 7:59 AM
    Moderator
  • Hi and thanks for your answer.

    Yes i used the same x86 board for both the WEC2013 and Windows 7 tests.

    In the meantime i send some messages with 100 bytes and its reproducible that just 16 chars arrive.

    I don't really know how to go on.

    My registry settings in platform.reg are the original from Intel BSP.

    IF BSP_SERIAL1
    [HKEY_LOCAL_MACHINE\Drivers\BuiltIn\Serial1]
        "Flags"=dword:0010            ; User Mode: DEVFLAGS_LOAD_AS_USERPROC
        "Dll"="Com16550.Dll"
        "Prefix"="COM"
        "Order"=dword:0
        "Index"=dword:1
        "SysIntr"=dword:14
        ;COM debug port IOBase=0x3F8 (per BIOS settings)
        "IoBase"=dword:03F8
        "IoLen"=dword:8
        "DeviceArrayIndex"=dword:1
        "IClass"="{CC5195AC-BA49-48a0-BE17-DF6D1B0173DD}"
        "UserProcGroup"=dword:$(PROCGROUP_DRIVER_MSFT_DEFAULT)
    IF IMGENFORA
        ; Turn on installable ISR (isr16550 supporting SOFTWARE FIFO)
        "Flags"=dword:0                 ; Kernel Mode
        "Irq"=dword:3
        "IsrDll"="isr16550.dll"
        "IsrHandler"="ISRHandler"
    ENDIF IMGENFORA

    [HKEY_LOCAL_MACHINE\Drivers\BuiltIn\Serial1\Unimodem]
        "Tsp"="Unimodem.dll"
        "DeviceType"=dword:0
        "DevConfig"=hex: 10,00, 00,00, 05,00,00,00, 10,01,00,00, 00,4B,00,00, 00,00, 08, 00, 00, 00,00,00,00

    [HKEY_LOCAL_MACHINE\Drivers\BuiltIn\Serial1\HayesCompat]
        "Tsp"="Unimodem.dll"
        "DeviceType"=dword:1
    ENDIF BSP_SERIAL1

    Thursday, November 23, 2017 4:02 PM
  • Already tried this without success, but thanks for the tip.
    Thursday, November 23, 2017 4:05 PM
  • Hi _SR_,

     there is a few reasons to get such results: 

    1. incorrect BIOS settings (IRQ) for appropriate port.
    Because of interrupt-driven model of the driver, driver may miss recieve intr if it mismatch BIOS settings.
    You should check your registry settings for serial port and BIOS' one. 
    Please note, if you have set driver to work under user-mode ( "Flags"=dword:0010 ), you should specify serial SysIntr (not IRQ value, it's easy calculated as 0x10 + IRQ). Don't worry, required translation has been made at WINCE700\platform\common\src\x86\common\intr\init.c already.

    2. Com16550 can't work with shared interrupts! IMGENFORA option (soft fifo implementation) doesn't work properly too.
    It is common to share the same IRQ for couple of UARTs, e.g. IRQ4 may be used for COM1/COM3.
    So, you have to adjust BIOS and driver settings to use different IRQs, e.g. com1 - IRQ4/3F8, com2 - IRQ3/2F8, com3 - IRQ5/3E8.

    Also, make sure if appropriate port hasn't used as debug output (I can't check right now, if Intel's BSP disable debug port in proper way).

    Finally, please share your reginit.ini with serial port settings (BuiltIn\SerialXX blocks)

    BR, Igor

    Monday, November 27, 2017 8:22 AM
  • Are you sure that the sender is sending the bytes?

    Bruce Eitman
    Senior Engineer
    Bruce.Eitman AT Synopsys DOT com
    My BLOG http://geekswithblogs.net/bruceeitman
    I work for Synopsys

    Monday, November 27, 2017 2:45 PM
    Moderator
  • Hi _SR_,

     there is a few reasons to get such results: 

    1. incorrect BIOS settings (IRQ) for appropriate port.
    Because of interrupt-driven model of the driver, driver may miss recieve intr if it mismatch BIOS settings.
    You should check your registry settings for serial port and BIOS' one. 
    Please note, if you have set driver to work under user-mode ( "Flags"=dword:0010 ), you should specify serial SysIntr (not IRQ value, it's easy calculated as 0x10 + IRQ). Don't worry, required translation has been made at WINCE700\platform\common\src\x86\common\intr\init.c already.

    2. Com16550 can't work with shared interrupts! IMGENFORA option (soft fifo implementation) doesn't work properly too.
    It is common to share the same IRQ for couple of UARTs, e.g. IRQ4 may be used for COM1/COM3.
    So, you have to adjust BIOS and driver settings to use different IRQs, e.g. com1 - IRQ4/3F8, com2 - IRQ3/2F8, com3 - IRQ5/3E8.

    Also, make sure if appropriate port hasn't used as debug output (I can't check right now, if Intel's BSP disable debug port in proper way).

    Finally, please share your reginit.ini with serial port settings (BuiltIn\SerialXX blocks)

    BR, Igor


    Hi Igor,

    my board has four COM Ports, two of them i need for my application.

    Settings read with Windows 7:

    1. COM1 - IRQ 0x4 - IO 03F8
    2. COM2 - IRQ 0x3 - IO 02F8
    3. COM3 - IRQ 0x7 - IO 03E8
    4. COM4 - IRQ 0x7 - IO 02E8

    In the registry the SysIntr seems to be correct with

    • COM1 = SysIntr14
    • COM2 = SysIntr13

    I have COM 3 & COM4 disabled in the meantime.

    I see absolutely see no change in the behaviour when i set the IMGENFORA flag

    (No receive at all and send is always truncated to 16 Bytes).

    I have uploaded the reginit.ini at https://1drv.ms/u/s!AiRPxMHR9lTOcmKJRd-HVmi1dYs.

    BR, _SR_



    Tuesday, November 28, 2017 8:39 AM
  • Are you sure that the sender is sending the bytes?

    Bruce Eitman
    Senior Engineer
    Bruce.Eitman AT Synopsys DOT com
    My BLOG http://geekswithblogs.net/bruceeitman
    I work for Synopsys

    Yes im sure, but always limited to 16 chars.
    Tuesday, November 28, 2017 8:41 AM
  • Well, if the send is failing, why do you characterize this as a receive problem?

    Bruce Eitman
    Senior Engineer
    Bruce.Eitman AT Synopsys DOT com
    My BLOG http://geekswithblogs.net/bruceeitman
    I work for Synopsys

    Tuesday, November 28, 2017 2:02 PM
    Moderator
  • Well, if the send is failing, why do you characterize this as a receive problem?

    Bruce Eitman
    Senior Engineer
    Bruce.Eitman AT Synopsys DOT com
    My BLOG http://geekswithblogs.net/bruceeitman
    I work for Synopsys

    Sry i think i missunderstood the question.

    I'm testing this way:

    - Sending from WEC2013 with one WriteFile call 100 byte to my notebook and seeing in Terminal that just 16 bytes arriving.

    - Sending from notebook Terminal to WEC2013 100 byte and doing a while loop with ReadFile call where the readBytes always 0.

    Tuesday, November 28, 2017 3:30 PM
  • In the meantime i found out that changes in the "SysIntr" regValue doesnt change the behaviour.

    How could that be? Is this plausible, because after all, 16 bytes have been successfully written using the WriteFile () method. Doesn't it need a functioning SysIntr? If so, it would mean that a interrupt is not necessarily for sending and necessary for receiving. Did you mean that in your first answer?


    • Edited by __SR__ Tuesday, November 28, 2017 7:08 PM enlargement
    Tuesday, November 28, 2017 3:42 PM
  • I am still very confused.  Why are you discussing sending bytes with WriteFile()?  You say that this is a receive problem - which is it?

    Are you using a loopback?  That is sending and receiving bytes on the same device?  If so, try sending from a different device, like your dev PC.  Also, make sure that you have the handshaking set up correctly, and that your cables support that method - it could be different settings from your baseline test.  When using handshaking, the sender will stop if not signaled to continue sending.

    Interrupts are necessary for sending - very necessary - but only after the FIFO is emptied the first time.  So, the first N bytes will go out just fine - where N is the depth of the FIFO.  In your case, N is probably 16.


    Bruce Eitman
    Senior Engineer
    Bruce.Eitman AT Synopsys DOT com
    My BLOG http://geekswithblogs.net/bruceeitman
    I work for Synopsys

    Wednesday, November 29, 2017 1:39 PM
    Moderator
  • The main goal is to receive serial data on my x86 WEC2013 device, which is actually not working.

    Therefore thisthread is called serial receive. 

    But i'm testing both directions and the send data from x86 WEC2013 device to my dev pc is truncated to the 16 bytes.

    I'm using no loopback and Handshake off. 

    Wednesday, November 29, 2017 2:32 PM
  • Do an independent test of the send and receive to figure out where the problem is.

    Bruce Eitman
    Senior Engineer
    Bruce.Eitman AT Synopsys DOT com
    My BLOG http://geekswithblogs.net/bruceeitman
    I work for Synopsys

    Wednesday, November 29, 2017 2:57 PM
    Moderator
  • Hi _SR_,

      what is your hardware/motherboard?
    I've faced with some embedded hw, where was non-generic UART.

    BR.

    Thursday, November 30, 2017 9:49 AM
  • Hi iShust,

    it's an ASrock SBC-220  with an Intel N3150 Celeron processor.

    On the board is a Nuvoton NCT6106D chip.

    Did you found a solution for non-generic UARTs?

    BR _SR_

    Thursday, November 30, 2017 10:40 AM
  • That is a 16550 compatible UART, so it should be good - but you need to be sure that you are setting it up correctly (i.e. read the datasheet)

    Also, on further review of your code, you are using handshaking.  Disable it and try.


    Bruce Eitman
    Senior Engineer
    Bruce.Eitman AT Synopsys DOT com
    My BLOG http://geekswithblogs.net/bruceeitman
    I work for Synopsys


    • Edited by Bruce EitmanModerator Thursday, November 30, 2017 1:58 PM Double checked the OPs datasheet, it is a 16550 compatible UART
    Thursday, November 30, 2017 1:47 PM
    Moderator
  • Did you found a solution for non-generic UARTs?

    BR _SR_

    Sure! Original com16550 driver is buggy and winbond SIO is buggy too, so I have a lot of debugging it ;)

    Actually, NCT6106 is not quite 16550-compatible because of large FIFO.
    A few years ago, I have improved com16550 driver for similar Nuvoton.

    Try to add the following lines to the end of CPdd16550::Init() (@ pdd16550.cpp) and rebuild the driver:

            if (!MapHardware() || !CreateHardwareAccess()) {
                return FALSE;
            }

    +        // Toggle FIFO en
    +       m_pReg16550->Write_FCR (0);
    +        Sleep (1);
    +        m_pReg16550->Write_FCR (SERIAL_FCR_ENABLE);

    +        // Enable IRQ
    +        m_pReg16550->Write_MCR(SERIAL_MCR_IRQ_ENABLE);
            
            return TRUE;        
        }
        return FALSE;
    }

    Good luck!


    • Edited by iShust Thursday, November 30, 2017 2:55 PM
    Thursday, November 30, 2017 2:55 PM
  • Thanks for your research Bruce.

    I've tried this without success.

    Another approach could be the included HSUART driver in the IntelBSP.

    It consists of two dlls included in the platform.bib:

    IF BSP_IOH_HSUART
    hsuart.dll      $(_FLATRELEASEDIR)\hsuart.dll             NK SHK
    hsuartisr.dll      $(_FLATRELEASEDIR)\hsuartisr.dll       NK SHK
    ENDIF BSP_IOH_HSUART

    And this registry entry:

    IF BSP_IOH_HSUART

    [HKEY_LOCAL_MACHINE\Drivers\BuiltIn\PCI\Template\HSUART]
        "Dll"="hsuart.dll"
        "Prefix"="COM"
        "VendorID"=multi_sz:"8086","8086","8086","8086"
        "DeviceID"=multi_sz:"0F0A","0F0C","228A","228C"
        "DeviceArrayIndex"=dword:1
        "IsrDll"="hsuartisr.dll"
        "IsrHandler"="ISRHandler"
        "RegStride"=dword:4
        "WaterMarker"=dword:62
        "RxBufferSize"=dword:80
        "ForcePIO"=dword:0
        "IClass"="{A32942B7-920C-486b-B0E6-92A702A99B35}"
    ENDIF BSP_IOH_HSUART

    But i have no idea why it isn't loading.

    The BSP_IOH_HSUART flag i've set to 1 in the BSP's .bat file

    and the files as well as the registry entries are included in the image file.

    If the driver is loaded correctly he should be registered in [HKEY_LOCAL_MACHINE\Drivers\BuiltIn\PCI\Instance \HSUART] to my knowledge.

    The big problem is that i have no working Kernel debugger to see some output messages.


    • Edited by __SR__ Thursday, November 30, 2017 3:49 PM
    Thursday, November 30, 2017 2:58 PM
  • Did you found a solution for non-generic UARTs?

    BR _SR_

    Sure! Original com16550 driver is buggy and winbond SIO is buggy too, so I have a lot of debugging it ;)

    Actually, NCT6106 is not quite 16550-compatible because of large FIFO.
    A few years ago, I have improved com16550 driver for similar Nuvoton.

    Try to add the following lines to the end of CPdd16550::Init() (@ pdd16550.cpp) and rebuild the driver:

            if (!MapHardware() || !CreateHardwareAccess()) {
                return FALSE;
            }

    +        // Toggle FIFO en
    +       m_pReg16550->Write_FCR (0);
    +        Sleep (1);
    +        m_pReg16550->Write_FCR (SERIAL_FCR_ENABLE);

    +        // Enable IRQ
    +        m_pReg16550->Write_MCR(SERIAL_MCR_IRQ_ENABLE);
            
            return TRUE;        
        }
        return FALSE;
    }

    Good luck!


    Hi iShust,

    unfortunately, the change remained without visible effect.

    Thanks anyway

    Friday, December 1, 2017 7:56 AM
  • Could you please post me your registry settings iShust?
    Thursday, December 28, 2017 2:07 PM