gicking / stm8gal

PC tool for uplading hexfiles to the STM8 microcontroller via UART or SPI , using the built-in ROM bootloader. Works under Windows and Posix operating systems
Apache License 2.0
80 stars 21 forks source link

confusion about the uart mode #7

Closed tenbaht closed 5 years ago

tenbaht commented 5 years ago

This is not really a bug report, but a report of an odd finding. I am posting here instead of PM in the hope that this might be useful information for others as well.

I am using stm8gal (on mint19/ubuntu 18.4) with the simple breakout boards from China for the STM8S105K4T6 but the default communication fails:

$ stm8gal -p /dev/ttyUSB0

stm8gal (v1.1.8)
  reset STM8 and press <return>
  open serial port '/dev/ttyUSB0' with 230.4kBaud ... ok
  synchronize ... ok (ACK)
  determine device ... 

error in 'bsl_memCheck()': ACK1 timeout (expect 1, received 0), exit!

It turns out, that the MCU expects data transfer without parity (8N1), despite UM0560 specifically asking for even parity (8E1). This (surprisingly) works:

$ stm8gal -u 2 -p /dev/ttyUSB0

stm8gal (v1.1.8)
  reset STM8 and press <return>
  open serial port '/dev/ttyUSB0' with 230.4kBaud ... ok
  synchronize ... ok (ACK)
  determine device ... ok (STM8S; 32kB flash; BSL v1.3)
  Uploading RAM routines ... ok (304B from 0x00a0)
  jump to address 0x8000 ... ok
done with program

Do you have any idea why? I couldn't find a detailed list about the expected data format for each CPU.

gicking commented 5 years ago

hi Michael,

actually "-u 2" does not change the parity, but the so-called "uart mode" of the bootloader, see here. And "reply mode" (-u 2) emulates the echo which occurs if a 1-line communication like LIN or K-line is used. The supported bootloader modes are described on page 12 in UM0560. Does this help?

Regards, Georg

tenbaht commented 5 years ago

The UM0560 is where my confusion started. It asks for 8E1 for UART connections and 8N1 for LIN-bus. But that does not work with my STM8S105K4 here. It ignores 8E1 data and only replies to 8N1.

I found out about the parity using a logic analyser - "-u 0" really sends 9 bits (8 data, 1 even parity) and "-u 2" sends only 8 data bits. That made me investigating the code and finding this, starting at line 505 in main.c:

  ////////
  // open port with given properties
  ////////

  // UART interface (default)
  if (physInterface == 0) {

    if (g_verbose == 2)
      printf("  open serial port '%s' with %gkBaud ... ", portname, (float) baudrate / 1000.0);
    fflush(stdout);
    if (uartMode == 0)
      ptrPort = init_port(portname, baudrate, 1000, 8, 2, 1, 0, 0);   // use even parity
    else
      ptrPort = init_port(portname, baudrate, 1000, 8, 0, 1, 0, 0);   // use no parity

UM0560, section 2.1 (page 12) specifies 8E1 for UART mode. But on the next page, section 2.1.1 specifies 8N1 for UART communication in reply mode. The table 5 (page 12) lists the replay mode (meaning 8N1) for most cases of UART communication with only STM8L/low and medium density and STM8AL medium density being the only exception.

I am not sure what that means for the 1-wire and half-duplex modes. Maybe we need something like duplex/8E1 and duplex/8N1. Or maybe it needs another parameter parity/noparity. Or, to make it a little easier for the user, a mcu type or mcu series specifier, similar to stm8flash -p partno or avrdude -p partno.

tenbaht commented 5 years ago

Or, maybe an autodetection is even easier. The sync always works because 0x7e already has even parity. Then it would be possible to try both formats for the next step: First 8N1 and if there is no answer, try 8E1 before giving up.

gicking commented 5 years ago

I actually don't see a conflict in UM0560. Page 12ff describe that "normal" UART mode requires 8E1, and reply mode requires 8N1. And your STM8S105K4 as "medium density" supports bootloader via UART2 in “reply mode" --> 8N1 (as you observed)

Part number IMHO is no solution because some parts support both normal and reply-mode via different UARTs. For these you would need to specify both part and UART used. Not nice...

But I like your auto-detection idea. There is just one other issue I need to solve: in reply mode, not only the parity is different. Specifically for reply mode and 2-wire interface the PC must reply each byte received from the STM8 to emulate the 1-wire echo. So in addition to auto-detection of parity I also need to detect the used interface. Sounds like fun...

I just checked UM0560 and I believe I have boards for all modes available (duplex, reply 1-wire, and reply 2-wire). Let me check this out.

gicking commented 5 years ago

I just created a new Git branch detectMode (thanks Michael!) which uses 1-line echo and parity to detect the physical interface (simplex or duplex) and also the correct parity (none or even). Idea is that the user doesn't need to specify the user mode anymore -> no more confusion like above...

Currently it seems to work under Posix but fails under Windows. Anyway, could you please check the branch and let me know your experience. Usage is as before, just omit the -u mode option.

gicking commented 5 years ago

Just merged branch develop back to main. The new v1.3.0 in main can detect the bootloader UART mode (=default) --> issue is closed