grigorig / stcgal

Open Source STC MCU ISP flash tool
642 stars 135 forks source link

STCGAL doesn't work with FAKE chip FT232RL #57

Closed PSLLSP closed 1 year ago

PSLLSP commented 3 years ago

There are adapters on the China market that looks like they have genuine FT232RL chip but that is just a FAKE copy of FTDI chip from China. That is not perfect copy and it doesn't work with STCGAL under Linux.

I have adapter with genuine FTDI FT232RL chip and that works great. And I order new one last month from China and it doesn't work with stcgal; It just prints message Waiting for MCU, please cycle power: but it doesn't detect that MCU power was "recycled".

How to find FAKE FT232RL? My chips has serial number A50285BI, that is well know serial number of fake chips; serial number can be check under Linux with lsusb -v command.

It is interesting that FAKE chips work under Windows with STC-ISP, no issue there. I see problem only under Linux. It is possible that there is a problem in Linux kernel and the issue cannot be fixed in stcgal. Maybe that issue is with stcgal and when some timeout will be tuned or some programming sequence slowed down that it will fix compatibility issue with FAKE FT232RL chips...

I have one more adapter that cannot be used with stcgal under Linux, it is based on "cp210x". Maybe that timing in stcgal is just not right... Adpater with cp210x has different problem, it could be a problem with driver in Linux kernel. This is how it looks: Waiting for MCU, please cycle power: I/O error: [Errno 5] Input/output error Adapter based on "cp210x" has no problem under Win7 with STC-ISP, it just works...

grigorig commented 3 years ago

With fake chips, of course, all bets are off. It could be anything. As far as I know, there are several FTDI fakes. I don't know of any specific compatibility issues under Linux, but this is quite possible, of course.

CP2102 works fine for me, though. Do you have some issue with your power cycling maybe? The error points to something like a USB disconnect. Do you see any message about in dmesg?

grigorig commented 3 years ago

Note that it could be phantom power issue with the fake FTDI, too. Maybe the fake chip is able to inject more power through I/O pins. As a first experiment, I'd introduce series resistors to RX/TX lines in the range of 1-10K.

STC unfortunately uses the worst possible way to switch on the bootloader, causing all kinds of issues.

PSLLSP commented 3 years ago

CP2102 chip disconnects, it is visible with dmesg. I just cannot use them with stcgal in Linux. I just connect CP2102 adapter to PC, no STC51 is connected and I start "stcgal", message about power is printed. stcgal prints the error in just few seconds, it was re-connected. I do not understand this, it looks like a problem in Linux kernel. Maybe I have "fake" CP2102" chip; I will try to find some older adapter.

I spent some time experimenting with FAKE FT232RL. I think the "problem" is in Linux kernel. If you want to touch these fake chips, just order cheap FT232RL from Aliexpress. I ordered two different adapters a month ago and both have the same "fake" chip.

Both adapters work in Windows with STC-ISP, that is interesting observation and I think it indicate that this is not problem of "phantom power"; I see (RX LED blinks) that chip is rebooted and it sends response but stcgal doesn't receive it or it is "demaged" in some way.

STC-ISP for Windows has many advanced options, one of them is to trigger boot-loader with a custom packet. I do not use this option but it is interesting one from my point of view. I understand it that customer program flashed to the chip monitors serial communication and when it receives "trigger" packet, it reboots the chip and that starts boot-loader.

PSLLSP commented 3 years ago

I have found older Arduino ISP programmer, it is from "Deek-Robot" and it is based on FT232RL. It is fake chip with famous serial number A50285BI and I didn't know that until today because that ISP works in Linux without issues, like this:

[1923312.032360] usb 4-1: new full-speed USB device number 49 using ohci-pci
[1923312.238390] usb 4-1: New USB device found, idVendor=0403, idProduct=6001, bcdDevice= 6.00
[1923312.238395] usb 4-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[1923312.238398] usb 4-1: Product: FT232R USB UART
[1923312.238400] usb 4-1: Manufacturer: FTDI
[1923312.238403] usb 4-1: SerialNumber: A50285BI
[1923312.244476] ftdi_sio 4-1:1.0: FTDI USB Serial Device converter detected
[1923312.244551] usb 4-1: Detected FT232RL
[1923312.250624] usb 4-1: FTDI USB Serial Device converter now attached to ttyUSB0
$ avrdude -c arduino-ft232r -p m328p
avrdude: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.10s
avrdude: Device signature = 0x1e950f (probably m328p)
avrdude: safemode: Fuses OK (E:FD, H:DE, L:FF)
avrdude done.  Thank you.

I cannot use this adapter with stcgal in Linux, it doesn't work. Maybe that difference is that stcgal uses UART to communicate with the MCU but Arduino ISP uses just bit banging on status lines. I am not sure about this.

PSLLSP commented 3 years ago

I solved mystery with CP2102. There was other program running in the background that tried to control CP2102 chip. I stopped that daemon and stcgal now works with CP2102 without problem. This was tricky issue... ;-)

PSLLSP commented 3 years ago

ISP programmer from "deek-robot" uses status lines (CTS, DSR, DCD, RI) to program Ardiuino. https://arduino.stackexchange.com/questions/30564/ftdi-breakout-with-additional-isp-connector I can use this adapter with fake FT232RL to program Arduino but it fails when I try to program STC51.

nekromant commented 3 years ago

: I/O error: [Errno 5] Input/output error

My lucky guess (and experience with fake nRF24L01) would be that the fake chips may need bigger capacitors on the power rails and making sure that the the voltage drop on the cable isn't that big.

Another option to try would be that changing the baudrate to an unsupported/high value may trigger some kind of bug in the IC.

Try using -l and -b options, so that your handshake and upload baudrates match. If these chips work fine with arduino, I would assume the baudrate change is the only really different thing.

PSLLSP commented 3 years ago

I do not think that this issue has to do anything with parasitic power, filtering capacitors or USB cable. The same configuration works in Windows with STC-ISP SW...

I tried to set the same baud rate but I cannot see any improvement, it just doesn't work...

I have found that when I "cycle" power again and again, some data are received but stcgal doesn't like them. Example, this was produced after about 20 "power cycles":

$ stcgal -D -l 2400 -b 2400
Waiting for MCU, please cycle power: <- Packet data: 46 B9 68 00 34 50 31 D2 75 C3 BA BB 7D 01 84 C7 C1 F5 26 BA 00 00 C9 A2 0D 50 AF AC 20 20 DC 3C 02 19 1F 22 91 42 04 10 33 C8 82 DD B1 60 FD FF FD 65 16 AC 20 46
<- Packet data: 09
<- Packet data: E3
<- Packet data: 16
<- Packet data: 46 B9 68 00 28 50 31 D2 75 C3 BA BB 7D 01 42 C7 C1 F5 26 A6 01 02 24 A2 0D 50 AF AC 80 20 DC 3C 02 19 1F 22 24 A1 02 88 06 8D
<- Packet data: B0
<- Packet data: 8B
<- Packet data: 1F
<- Packet data: 4C
<- Packet data: F7
<- Packet data: FD
<- Packet data: 65
<- Packet data: 0A
<- Packet data: AC
<- Packet data: 10
<- Packet data: 46 42
<- Packet data: 96
<- Packet data: F1
<- Packet data: 46 B9 68 00 34 50 31 D2 5D 78 ED BB 3F 01 44 C7 C1 F5 26 A1 00 00 E4 51 03 A8 7D 2B C8 10 6E 9E 02 19 1F 22 24 A1 02 44 06 46 58 8B 1F 4C F7 FD 65 0B AC 10 46 42
<- Packet data: 65
<- Packet data: 16
<- Packet data: 46 B9 68 00 34 50 31 D2 75 C3 BA BB 7D 01 84 C7 C1 F5 26 AB 00 00 C9 A2 0D 50 AF AC 90 20 DC 3C 02 19 1F 22 91 42 04 88 33 64 82 DD EC 60 FD FF FD 65 16 AC 10 46
<- Packet data: 42
<- Packet data: 6A
<- Packet data: 16

BTW, I do not like that stcgal doesn't print what (USB) port it is using, even in debug mode. And timestamp are missing too, those could be helpful as the list covers more than 30 seconds of experiments but it is not visible in the list...

This is genuine FT232RL from FTDI, the same STC chip and the same cable:

$ stcgal -D -l 2400 -b 2400
Waiting for MCU, please cycle power: <- Packet data: 46 B9 68 00 34 50 8C D2 5D 78 F7 BB 9F 00 A8 FC F0 FD 26 B5 00 00 72 54 00 F5 1F 05 06 70 78 02 19 1F 22 24 28 00 34 20 04 DD EC 60 BF FF FF 19 01 05 30 12 DE 16
done
Protocol detected: stc15
Target model:
  Name: STC15W408AS
  Magic: F51F
  Code flash: 8.0 KB
  EEPROM flash: 5.0 KB
Target frequency: 11.075 MHz
Target BSL version: 7.2.5T
Target wakeup frequency: 36.050 KHz
Target options:
  reset_pin_enabled=False
  clock_source=internal
  clock_gain=high
  watchdog_por_enabled=False
  watchdog_stop_idle=True
  watchdog_prescale=256
  low_voltage_reset=True
  low_voltage_threshold=3
  eeprom_lvd_inhibit=True
  eeprom_erase_enabled=False
  bsl_pindetect_enabled=False
  por_reset_delay=long
  rstout_por_state=high
  uart2_passthrough=False
  uart2_pin_mode=normal
  cpu_core_voltage=unknown
-> Packet data: 46 B9 6A 00 07 82 00 F3 16
Disconnected!

To eliminate problems with power cycle to trigger firmware loader, this is a simple C program demo that triggers firmware upload with a software button (BTN). It is for SDCC compiler. I test it on STC15F104W, a mini module with LED, button and STC15F104W from AliExpress. STCGAL has to be patched to support STC15F104W!, see #17:

$ sdcc --iram-size 128 --xram-size 0 blinky3.c
$ cat blinky3.c

#include <stc12.h>

#define LED P3_3
#define BTN P3_2
//#define TXD P3_1
//#define RXD P3_0

/* ------------------------------------------------------------------------- */

void _delay_ms(unsigned int ms)
{
    unsigned int i;
    while (ms--) {
        i = 552;
        while (--i);
    };
}

//void reset (void)
//{
//   ((void (__code *) (void)) 0x0000) ();
//}

void isp_firmware()
{
    //IAP_CONTR |= 1 << 6; // SWBS, activate ISP monitor
    //IAP_CONTR |= 1 << 5; // SWRST, trigger reset
    //IAP_CONTR = (1<<5) | (1<<6);
    IAP_CONTR = 0x60;  // IAP_CONTR is at address 0xC7
}

int main()
{
    LED = 0;
    _delay_ms(1000);

    while(1) {                
        LED = 1;
        if (BTN==0) isp_firmware(); // !! RESET & ACTIVATE firmware loader
        _delay_ms(200);
        LED = 0;
        _delay_ms(200);
    }
}
/* ------------------------------------------------------------------------- */
PSLLSP commented 3 years ago

I see other compatibility problem at Linux. I tried to use an USB hub and one of them doesn't work under Linux. When serial adapter is connected directly to PC, stcgal works without issues. When I insert between PC and serial adapter an USB hub then stcgal fails to program chip. I tried with the same USB hub to flash the same chip under Windows (STC-ISP) and there was no such problem.

I tried other USB hub and it worked with stcgal without problem. This is strange and it looks like some problem with timing. I am not sure...

The USB hub that doesn't work with stcgal is small 3-port USB hub with memory card reader. Output from dmesg:

[909864.266632] usb 2-2: new high-speed USB device number 121 using ehci-pci
[909864.423028] usb 2-2: New USB device found, idVendor=058f, idProduct=6254, bcdDevice= 1.00
[909864.423032] usb 2-2: New USB device strings: Mfr=0, Product=0, SerialNumber=0
[909864.423340] hub 2-2:1.0: USB hub found
[909864.423398] hub 2-2:1.0: 4 ports detected
[909864.714610] usb 2-2.1: new high-speed USB device number 122 using ehci-pci
[909864.827956] usb 2-2.1: New USB device found, idVendor=058f, idProduct=6366, bcdDevice= 1.00
[909864.827959] usb 2-2.1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[909864.827961] usb 2-2.1: Product: Mass Storage Device
[909864.827963] usb 2-2.1: Manufacturer: Generic
[909864.827964] usb 2-2.1: SerialNumber: 058F63666433
[909864.828386] usb-storage 2-2.1:1.0: USB Mass Storage device detected
[909864.835357] scsi host7: usb-storage 2-2.1:1.0
[909865.867175] scsi 7:0:0:0: Direct-Access     Multiple Card  Reader     1.00 PQ: 0 ANSI: 0
[909865.867458] sd 7:0:0:0: Attached scsi generic sg2 type 0
[909865.892290] sd 7:0:0:0: [sdc] Attached SCSI removable disk

This is USB hub that works (dmesg):

[910185.257536] usb 2-2: new high-speed USB device number 7 using ehci-pci
[910185.418112] usb 2-2: New USB device found, idVendor=1a40, idProduct=0101, bcdDevice= 1.11
[910185.418115] usb 2-2: New USB device strings: Mfr=0, Product=1, SerialNumber=0
[910185.418117] usb 2-2: Product: USB 2.0 Hub
[910185.418401] hub 2-2:1.0: USB hub found
[910185.418490] hub 2-2:1.0: 4 ports detected
nekromant commented 3 years ago

The USB hub that doesn't work with stcgal is small 3-port USB hub with memory card reader. Output from dmesg:

Now this definetely looks like power issues. Do you have any leads where I can get some of those fake FT232RL cheaply?

PSLLSP commented 3 years ago

The USB hub that doesn't work with stcgal is small 3-port USB hub with memory card reader. Output from dmesg:

Now this definetely looks like power issues. Do you have any leads where I can get some of those fake FT232RL cheaply?

No, it is not power issue. Two different USB hubs with the same PC and the same serial adapter but different result. It doesn't look like power issue. Where to get FAKE FT232RL? Any adapter with FT232RL at Aliexpress has FAKE chip... Like this one, https://www.aliexpress.com/item/4000539821134.html

BTW, this time I was using serial adapter with CH340E chip (ch341 or HL-340? 1a86:7523 is USB ID), I start to use these adapters because those are cheaper, smaller and they just work OK...

nekromant commented 3 years ago

Just ordered one. Now I really wonder what those guys could've screwed up in the schematics or silicon so it acts THAT weird. But I'm still pretty sure the symptoms look like power. Why? Because usb hubs have different wiring (cheap thin wires vs more expensive and thicker). If the hub has a cardreader - that also eats some power. If your device works with one hub and doesn't work with the other - in my experience that's pretty much the power issue.

Give a spin with USB HDD through those hubs, or anything that consumes more power. If the disc won't spin up from the same hub the fake chip didn't work - you got the idea ;)

PSLLSP commented 3 years ago

I ordered "genuine" (not cheap) FT232RL chips to fix my serial adapters with cheap "fake" chips. Unfortunately, new FT232RL chips don't work with stcgal. It is possible that those are fake chips too but I am not sure because new chips have unique serial numbers. It is possible that these are just "improved fake" chips. :-( FTDI support was not able to confirm if chips are genuine or "fake" chips just on serial number. I ordered my FT232RL chips from distributor that is not on the list of authorized FTDI distributors...

PSLLSP commented 3 years ago

I tried stcgal under Windows. It doesn't work with FAKE chip FT232RL under Windows too! When I try STC-ISP, it works, no problem. So far I assumed that there is some problem in Linux but I can replicate the same under Windows.

I used Win7 box, I installed Python 3 there (https://www.python.org/ftp/python/3.8.5/python-3.8.5-amd64.exe) and than I installed stcgal from command line (pip install stcgal).

This is genuine FT232RL under Windows:

C:\Users\simpanse>stcgal -V
stcgal 1.6

C:\Users\simpanse>stcgal -p COM23
Waiting for MCU, please cycle power: done
Protocol detected: stc15
Target model:
  Name: STC15F104W
  Magic: F294
  Code flash: 4.0 KB
  EEPROM flash: 1.0 KB
Target frequency: 11.063 MHz
Target BSL version: 7.2.5Q
Target wakeup frequency: 36.776 KHz
Target options:
  reset_pin_enabled=False
  clock_source=internal
  clock_gain=high
  watchdog_por_enabled=False
  watchdog_stop_idle=True
  watchdog_prescale=64
  low_voltage_reset=False
  low_voltage_threshold=3
  eeprom_lvd_inhibit=False
  eeprom_erase_enabled=True
  bsl_pindetect_enabled=False
  por_reset_delay=long
  rstout_por_state=high
  uart2_passthrough=False
  uart2_pin_mode=normal
  cpu_core_voltage=unknown
Disconnected!

And this is FT232RL from Aliexpress, stcgal doesn't accept data sent from MCU to PC (I see that STC MCU reboots and hello sequence is sent again and again, RX LED is blinking):

C:\Users\simpanse>stcgal -p COM29
Waiting for MCU, please cycle power:
PSLLSP commented 3 years ago

My genuine FT232RL chip that works great is "revision B" and it was manufactured in year 2010. All other FT232RL adapters I have are with chips in revision C, and those do not work. The key question is what is the difference between revision B and C of FT232RL and who is troublemaker, is it stcgal or python library?

Document that describes difference between revision B and C doesn't highlight any important change and it seems that difference between B and C are just cosmetic and should have no visible impact. So I assume that all FTDI chips in rev C I have are "fake" chips... :-(

https://www.ftdichip.com/Support/Documents/ProductChangeNotifications/PCN_FT_008.pdf

PSLLSP commented 3 years ago

I have found another FT232RL adapter in a box with my old projects.It is revision C from year 2014 and it works! So far I have only two adapters those work with stcgal:

Live is not easy. I have found my first Arduino board (clone from China) and it has FT232RL UART. I used this board for years without any problem. FT232RL is revision B from 2010 (1013-B, SN A100eE3W). This is FAKE chip, it doesn't work with stcgal.

PSLLSP commented 3 years ago

I modified stcgal to print more details about data it sends and receives. I see difference between genuine and fake chips. When fake chip is used, stcgal receives more bytes and it seems that some bytes are shifted by one bit (0x05 is sometimes received as 0x0A) or by 2 bits (0x8F is received as 0x3D), etc. My explanation is that STC chips uses baud rate detection and maybe that fake chip doesn't generate perfect baudrate, so STC baudrate is calibrated with serious error.

This is "hello" packet received by real FT232RL:

<- Packet data: 46 B9 68 00 34 50 8F A8 83 A3 F5 7B 9F 00 A8 CE 10 FF 27 19 00 00 72 51 03 F2 94 05 06 70 A3 02 19 1E 21 24 21 80 14 10 04 CC FF 84 BF FF FF 17 07 29 01 12 22 16

These packets are received with fake FT232RL, all the same STC chip, the same condition. My STC chip is programmed to auto enter firmware upload (cycle), so I don't need to do any action, I just connect serial adapter and start stcgal and I see result.

<- Packet data: 46 B9 68 00 68 50 3D A8 83 A3 D5 ED FA 0A 10 75 1E 62 9D F4 08 20 40 39 51 03 C9 94 05 19 82 1B 25 58 CC 28 22 A2 88 C0 14 41 23 8C D6 11 F5 F7 FD 5D 74 2C 59 60 42 0C 16
<- Packet data: 46 B9 68 00 68 50 3D A8 83 A3 D5 ED FA 0A 10 75 1E 62 9D E4 08 20 40 39 51 03 C9 94 05 19 82 1B 25 58 CC 28 22 A2 88 C0 14 41 23 8C D6 11 F5 F7 FD 5D 74 2C 59 60 42 22 F1
<- Packet data: 46 B9 68 00 38 50 3D A8 83 A3 D5 ED FA 05 10 9D 1E B1 9D 02 08 10 40 4E D4 40 F9 94 05 06 C1 1B 25 58 CC 28 22 A2 44 C0 14 41 23 C6 D6 11 FA F7 FD 5D 3A 2C 59 60 42 82 16

My theory has one weak point. It doesn't explain why STC-ISP works with fake chips...

PSLLSP commented 3 years ago

I have found simple 8 channel logical analyzer from "Salease" and checked data on serial line. I understand the issue now, it is crystal clear!

Serial communication of STC15F104W is 8E1 (EVEN PARITY) but stcgal configures communication to 8N1 (NONE PARITY). There is a BUG in stcgal!

It seem that "fake chips" have serious problem when receiving and handling data with framing error, and framing errors are there when serial data is configured for 8N1 (8-bits) but data are in 8E1 format (9-bits). Fake FT232RL chips synchronize to data stream in different way than genuine FT232RL when UART is configured to 8N1 but data on serial line are in format 8E1. Crystal clear... It is interesting that other UART chips (PL2303, CP2102, CH340G, genuine FT232RL, etc) were working with this BUG in stcgal without problem, so this bug was undetected for years...

PSLLSP commented 3 years ago

DEMO program for STC MCU for SDCC compiler. It sends data to serial port in format 9600 8E1, just a text strings. It uses software UART and I test it on STC15F104W.

$ cat uart-test.c

#include <stc12.h>

//define baudrate const
//BAUD = 256 - FOSC/3/BAUDRATE/M (1T:M=1; 12T:M=12)
//NOTE: (FOSC/3/BAUDRATE) must be greater than 98, (RECOMMEND GREATER THAN 110)
//#define BAUD 0xF400 // 1200bps @ 11.0592MHz
//#define BAUD 0xFA00 // 2400bps @ 11.0592MHz
//#define BAUD 0xFD00 // 4800bps @ 11.0592MHz
#define BAUD 0xFE80 // 9600bps @ 11.0592MHz
//#define BAUD 0xFF40 //19200bps @ 11.0592MHz
//#define BAUD 0xFFA0 //38400bps @ 11.0592MHz
//#define BAUD 0xEC00 // 1200bps @ 18.432MHz
//#define BAUD 0xF600 // 2400bps @ 18.432MHz
//#define BAUD 0xFB00 // 4800bps @ 18.432MHz
//#define BAUD 0xFD80 // 9600bps @ 18.432MHz
//#define BAUD 0xFEC0 //19200bps @ 18.432MHz
//#define BAUD 0xFF60 //38400bps @ 18.432MHz
//#define BAUD 0xE800 // 1200bps @ 22.1184MHz
//#define BAUD 0xF400 // 2400bps @ 22.1184MHz
//#define BAUD 0xFA00 // 4800bps @ 22.1184MHz
//#define BAUD 0xFD00 // 9600bps @ 22.1184MHz
//#define BAUD 0xFE80 //19200bps @ 22.1184MHz
//#define BAUD 0xFF40 //38400bps @ 22.1184MHz
//#define BAUD 0xFF80 //57600bps @ 22.1184MHz

//sfr AUXR = 0x8E;
//sbit RXB = P3^0; //define UART TX/RX port
//sbit TXB = P3^1;

#define RXB P3_0
#define TXB P3_1
#define BTN P3_2     
#define LED P3_3     

//typedef bit BOOL;
typedef __bit BOOL;
typedef unsigned char BYTE;
typedef unsigned int WORD;
BYTE TBUF,RBUF;
BYTE TDAT,RDAT;
BYTE TCNT,RCNT;
BYTE TBIT,RBIT;
BOOL TING,RING;
BOOL TEND,REND;
BOOL TPAR,RPAR;
void UART_INIT();
BYTE t, r;
BYTE buf[16];

//-----------------------------------------
//Timer interrupt routine for UART
//void tm0() interrupt 1 using 1
void tm0() __interrupt 1 __using 1
{
  if (RING) {
    if (--RCNT == 0) {
      RCNT = 3; //reset send baudrate counter
      if (--RBIT == 0) {
        RBUF = RDAT; //save the data to RBUF
        RING = 0; //stop receive
        REND = 1; //set receive completed flag
      }
      else if (RBIT == 1) {
        RPAR = RXB;  // parity bit
      }
      else {
        RDAT >>= 1;
        if (RXB) RDAT |= 0x80; //shift RX data to RX buffer
      }
    }
  }
  else if (!RXB) {
    RING = 1; //set start receive flag
    RCNT = 4; //initial receive baudrate counter
    RBIT = 10; //initial receive bit number (8 data bits + parity + 1 stop bit)
  }

  if (--TCNT == 0) {
    TCNT = 3;    //reset send baudrate counter
    if (TING) {  //judge whether sending
      if (TBIT == 0) {
        TXB = 0; //send start bit
        TDAT = TBUF; //load data from TBUF to TDAT
        TBIT = TDAT ^ (TDAT >> 1);
        TBIT = TBIT ^ (TBIT >> 2);
        TBIT = TBIT ^ (TBIT >> 4);
        TPAR = (TBIT & 1);  // EVEN PARITY

        TBIT = 10; //initial send bit number (8 data bits + parity + 1 stop bit)
      }
    else {
      if (--TBIT == 0) {
        TXB = 1;   //stop bit
        TING = 0; //stop send
        TEND = 1; //set send completed flag
      }
      else if (TBIT == 1) {
        TXB = TPAR;  // PARITY
      }
      else {
        TDAT >>= 1; //shift data to CY
        TXB = CY; //write CY to TX port
      }
    }
  }
}
}

//-----------------------------------------
//initial UART module variable
void UART_INIT()
{
  TING = 0;
  RING = 0;
  TEND = 1;
  REND = 0;
  TCNT = 0;
  RCNT = 0;
}

//-----------------------------------------

void isp_firmware()
{
    //IAP_CONTR |= 1 << 6; // SWBS, activate ISP monitor
    //IAP_CONTR |= 1 << 5; // SWRST, trigger reset
    //IAP_CONTR = (1<<5) | (1<<6);
    IAP_CONTR = 0x60;  // IAP_CONTR is at address 0xC7
}

void putc(const char c)
{
  while (TEND==0);
  TBUF = c;
  TEND = 0;
  TING = 1;
}

void puts(const char *s)
{
   while (*s) putc(*s++);
}

void main()
{

  WORD delay;
  TMOD = 0x00; //timer0 in 16-bit auto reload mode
  AUXR = 0x80; //timer0 working at 1T mode
  TL0 = BAUD & 0xff;
  TH0 = BAUD>>8; //initial timer0 and set reload value
  TR0 = 1;     //tiemr0 start running
  ET0 = 1;     //enable timer0 interrupt
  PT0 = 1;     //improve timer0 interrupt priority
  EA = 1;      //open global interrupt switch

  if (BTN==0) isp_firmware();

  UART_INIT();

  while (1) { //user's function
    puts("FT232RL TEST\n");
    puts("ABCDEFGHIJKLMNOPQRSTUVWXYZ\n");
    puts("0123456789\n\n");
    delay = 30000;
    while (--delay);
    LED ^= 1;
    if (BTN==0) isp_firmware();  // trigger firmware upload with a button
  }

/*
  while (1) { //user's function

    if (BTN==0) isp_firmware();

    if (REND) {
      buf[r++ & 0x0f] = RBUF;
      REND = 0;
    }
    if (TEND) {
      if (t != r) {
        TEND = 0;
        TBUF = buf[t++ & 0x0f];
        TING = 1;
      }
    }
  }
  */
}
$ sdcc --iram-size 128 uart-test.c

The program is just source of serial data in 9600 8E1 format. It is interesting to see how different UARTs see data when configured in wrong way. Try to receive data as 9600 8E1 and then as 9600 8N1.

The FT232RL, that I believe is genuine, has the same output for "9600 8E1 and 9600 8N1", I cannot see that serial terminal was configured in the wrong way. When I try to receive data with "fake" FT232RL, I see garbage when serial terminal is configured for 9600 8N1.

FAKE FT232RL, 9600 8E1:

$ picocom -b 9600 --parity e --imap lfcrlf /dev/ttyUSB2
FT232RL TEST
ABCDEFGHIJKLMNOPQRSTUVWXYZ
0123456789

FAKE FT232RL, 9600 8N1:

$ picocom -b 9600 --parity n --imap lfcrlf /dev/ttyUSB2
�ҪKLMN=��Mm�%�5k�-
0œ6DVdt�����FT232RL TES�S��h�EFGH�S[bk���ԩSTUV]���I�̙3`�dt���H�FT23h�cF��J�
-II�̙345ٺ�����FT23ɓc��J��S��h"EFGH%S[�Z���ԩSQ��e�h�EFGH%S[�Z���ԩSQ���
#U��$R��K�kr��ԩS�����-II�̙345ٺ���H�FT232RL TEST
#*f�$IҥK1kr��ԩSTUY��-II�̙3p�dt���H�FT23

genuine FT232RL, 9600 8N1:

$ picocom -b 9600 --parity n --imap lfcrlf /dev/ttyUSB2
FT232RL TEST
ABCDEFGHIJKLMNOPQRSTUVWXYZ
0123456789
PSLLSP commented 3 years ago

Test in Python to identify FAKE FT232RL. Similar test like in the previous update, this time is generator written in Python and it switches between "9600 8E1" and "9600 8N1":

$ cat uart-test.py

#!/usr/bin/env python3

import serial
import time
import sys

BAUDRATE = 9600

if len(sys.argv) < 2:
    print('ERROR, one parameter is required, specify serial port')
    sys.exit(1)

PORT = sys.argv[1]
print('Transmiting serial data to port ' + PORT)

while True:
    with serial.Serial(port=PORT, baudrate=BAUDRATE, parity=serial.PARITY_NONE, bytesize=serial.EIGHTBITS) as s:
        print('9600 8N1')
        for i in range(3):
            s.write('UART TEST - 9600 8N1: 0123456789 - ABCDEFGHIJKLMNOPQRSTUVWXYZ\n'.encode('utf-8'))
            s.flush()
            time.sleep(1)
    with serial.Serial(port=PORT, baudrate=BAUDRATE, parity=serial.PARITY_EVEN, bytesize=serial.EIGHTBITS) as s:
        print('9600 8E1')
        for i in range(3):
            s.write('UART TEST - 9600 8E1: 0123456789 - ABCDEFGHIJKLMNOPQRSTUVWXYZ\n'.encode('utf-8'))
            s.flush()
            time.sleep(1)

Some UART is connected to /dev/ttyUSB3:

$ python3 uart-test.py /dev/ttyUSB3
Transmiting serial data to port /dev/ttyUSB3
9600 8N1
9600 8E1
9600 8N1
9600 8E1
...

Serial adaptor with FT232RL is connected to UART at /dev/ttyUSB2, just three wires (GND-GND, TX-RX, RX-TX), this serial adaptor receives data and it is at /dev/ttyUSB2. This is FAKE FT232RL:

$ picocom -b 9600 --parity n --imap lfcrlf /dev/ttyUSB2

UART TEST - 9600 8N1: 0123456789 - ABCDEFGHIJKLMNOPQRSTUVWXYZ
UART TEST - 9600 8N1: 0123456789 - ABCDEFGHIJKLMNOPQRSTUVWXYZ
UART TEST - 9600 8N1: 0123456789 - ABCDEFGHIJKLMNOPQRSTUVWXYZ
2��J� -��dVZ3G�0œ6DVdt��Yd�BCD3�I�JK�kr�J�RSQ���5k�Z
-II�UART TEST - 9600 8N1: 0123456789 - ABCDEFGHIJKLMNOPQRSTUVWXYZ
UART TEST - 9600 8N1: 0123456789 - ABCDEFGHIJKLMNOPQRSTUVWXYZ
UART TEST - 9600 8N1: 0123456789 - ABCDEFGHIJKLMNOPQRSTUVWXYZ
2��J� -��dVZ3G�0123ѫdt�����!CD3�I�JK1k��J�RSQ���5k�Z
-II�� -��dVZ3G�0œ6DVdt��Y��!CDEFG!JM�Z��J�RSQ���
...

This is genuine FT232RL or almoust any other serial UART (PL2303, CP2102, etc):

$ picocom -b 9600 --parity n --imap lfcrlf /dev/ttyUSB2

UART TEST - 9600 8N1: 0123456789 - ABCDEFGHIJKLMNOPQRSTUVWXYZ
UART TEST - 9600 8N1: 0123456789 - ABCDEFGHIJKLMNOPQRSTUVWXYZ
UART TEST - 9600 8N1: 0123456789 - ABCDEFGHIJKLMNOPQRSTUVWXYZ
UART TEST - 9600 8E1: 0123456789 - ABCDEFGHIJKLMNOPQRSTUVWXYZ
UART TEST - 9600 8E1: 0123456789 - ABCDEFGHIJKLMNOPQRSTUVWXYZ
UART TEST - 9600 8E1: 0123456789 - ABCDEFGHIJKLMNOPQRSTUVWXYZ
UART TEST - 9600 8N1: 0123456789 - ABCDEFGHIJKLMNOPQRSTUVWXYZ
UART TEST - 9600 8N1: 0123456789 - ABCDEFGHIJKLMNOPQRSTUVWXYZ
UART TEST - 9600 8N1: 0123456789 - ABCDEFGHIJKLMNOPQRSTUVWXYZ
UART TEST - 9600 8E1: 0123456789 - ABCDEFGHIJKLMNOPQRSTUVWXYZ
...

NOTE: It is nice that you can use even two adapters with FAKE FT232RL and this test will detect them... ;-) Just connect two adapters with FT232RL to your PC and first try one as a transmitter and other as receiver and then swap them. If any of them is FAKE FT232RL, it will be detected. It is possible that this could be automated in Python...

Automated test in Python:

$ cat uart-test2.py

#!/usr/bin/env python3

import serial
import time
import sys

def testTxRx(port1, port2, baudrate, testData):

    print('== {} {} 8E1 -> {} {} 8N1'.format(port1, baudrate, port2, baudrate))

    with serial.Serial(port=port1, baudrate=baudrate, parity=serial.PARITY_EVEN, bytesize=serial.EIGHTBITS) as s1:
        with serial.Serial(port=port2, baudrate=baudrate, parity=serial.PARITY_NONE, bytesize=serial.EIGHTBITS) as s2:
           for i in range(3):
              txData = testData.encode('utf8')
              s1.write(txData)
              s1.flush()
              time.sleep(0.5)
              rxData = s2.read(len(txData))
              if txData != rxData:
                 print('ERROR: wrong data received from port ' + port2)
                 print('TX: ', txData)
                 print('RX: ', rxData)
              else:
                 print('received the same data, OK')

# MAIN

if len(sys.argv) < 3:
    print('ERROR, two parameters are required, specify serial ports')
    sys.exit(1)

BAUDRATE = 9600

PORT1 = sys.argv[1]
PORT2 = sys.argv[2]

for i in range(3):
   print('\nThis test should pass, these data have the same pattern in 8N1 as in 8E1')
   test = 'LIFO1248CJQRT7WX'   # these characters have 1 at position of parity bit, so this test should pass without any problem
   testTxRx(PORT1, PORT2, BAUDRATE, test)
   testTxRx(PORT2, PORT1, BAUDRATE, test)

   print('\nReal test, if ERROR is reported, it is likely that you have "fake" FT232RL or other problem')
   test = 'UART TEST - 9600 8E1: 0123456789 - ABCDEFGHIJKLMNOPQRSTUVWXYZ'  # real test
   testTxRx(PORT1, PORT2, BAUDRATE, test)
   testTxRx(PORT2, PORT1, BAUDRATE, test)
$ python3 uart-test2.py /dev/ttyUSB2 /dev/ttyUSB3

This test should pass, these data have the same pattern in 8N1 as in 8E1
== /dev/ttyUSB2 9600 8E1 -> /dev/ttyUSB3 9600 8N1
received the same data, OK
received the same data, OK
received the same data, OK
== /dev/ttyUSB3 9600 8E1 -> /dev/ttyUSB2 9600 8N1
received the same data, OK
received the same data, OK
received the same data, OK

Real test, if ERROR is reported, it is likely that you have "fake" FT232RL or other problem
== /dev/ttyUSB2 9600 8E1 -> /dev/ttyUSB3 9600 8N1
received the same data, OK
received the same data, OK
received the same data, OK
== /dev/ttyUSB3 9600 8E1 -> /dev/ttyUSB2 9600 8N1
ERROR: wrong data received from port /dev/ttyUSB2
TX:  b'UART TEST - 9600 8E1: 0123456789 - ABCDEFGHIJKLMNOPQRSTUVWXYZ'
RX:  b'U\x05\x92\x8d\r2\xb5\xd1J\xaa -\x81\xcbd\x04\x04\x04\x19VZ3G\x900\xc5\x936DVdt\x86\x96\x04Y\x11d\x90BCD\x153\xed\x12I\xd2\xa5K1k\xc9\xd2\x1aJ\xd4RSQ\xab'
ERROR: wrong data received from port /dev/ttyUSB2
TX:  b'UART TEST - 9600 8E1: 0123456789 - ABCDEFGHIJKLMNOPQRSTUVWXYZ'
RX:  b'd\xe95k\x96-U\x05\x92\x8d\r2\xb5\xd1J\xaa -\x81\xcbd\x04\x04\x04\x19VZ3G\x900\xc5\x936DVdt\x86\x96\x04Y\x11d\x90BCD\x153\xed\x12I\xd2JK1k\xc9\xd2\x1a'
ERROR: wrong data received from port /dev/ttyUSB2
TX:  b'UART TEST - 9600 8E1: 0123456789 - ABCDEFGHIJKLMNOPQRSTUVWXYZ'
RX:  b'J\xd4RSQ\xab\xc9\xe95k\x96ZU\x05\x92\x8d\r\x12\xb5\xd1J\xaa -\x81\xcbd\x04\x04\x04\x19V-3G\x900\xc5\x936DVdt\x86\x96\x04Y\x11d\x90BCD\x153\xed\x12\xa9\xd2\xa5'

This test should pass, these data have the same pattern in 8N1 as in 8E1
== /dev/ttyUSB2 9600 8E1 -> /dev/ttyUSB3 9600 8N1
received the same data, OK
...

Test for Arduino.

/*
  TEST UART for handling frame errors. Send data in 9600 8E1.

  When these data are received by UART in mode 9600 8N1, it has to handle frame errors.
  How it recovers from frame errors? Does it synchronize to the next character correctly??

  Old Arduino boards used FT232RL chip to communicate with PC over USB.
  Some of those boards from China used FAKE FT232RL, clone chip that was not manufactured by FTDI.
  Such bad chips are in many devices. The FAKE chip looks like genuine FTDI FT232RL
  but it is not 100% compatible with the original.
  Early FAKE chips were manufactured with the same serial number so it was easy to identify them.
  Advanced FAKE chips are produced with unique serial numbers but they still have the same bugs in their design.
  This test checks one bug in the FT232RL clone,
  it cannot handle frame error well and when frame error occurs, synchronization to data stream is lost.

  This test can be used to test external UART too:
    - connect RX pin from external UART to PIN DIGITAL1 (TX) on Arduino
    - connect GND pin from external UART to GND pin on Arduino board
    - check what data are received by external UART when serial terminal is configured to 9600 8N1
*/

void setup() {
  //Initialize serial and wait for port to open:
  Serial.begin(9600, SERIAL_8E1);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
}

void loop() {
  // these characters have parity bit 1 and are in the same format in 8E1 and 8N1
  // it test that your terminal is configured to 9600 8N1
  Serial.println("LLL");
  delay(500);
  Serial.println("LIFO1248CJQRT7WX");
  delay(500);
  // mix of characters, this string test framing error synchronisation
  // in the case that it is not received correctly when your serial terminal is configured to  9600 8N1,
  // then it is likely that your UART is FAKE chip FT232R
  Serial.println("UART TEST - 9600 8E1: 0123456789 - ABCDEFGHIJKLMNOPQRSTUVWXYZ");
  delay(500);
}

Genuine FT232RL:

$ picocom -b 9600 --parity n --imap lfcrlf /dev/ttyUSB2

LLL
LIFO1248CJQRT7WX
UART TEST - 9600 8E1: 0123456789 - ABCDEFGHIJKLMNOPQRSTUVWXYZ
LLL
LIFO1248CJQRT7WX
UART TEST - 9600 8E1: 0123456789 - ABCDEFGHIJKLMNOPQRSTUVWXYZ
LLL
...

FAKE FT232RL:

$ picocom -b 9600 --parity n --imap lfcrlf /dev/ttyUSB2

�LLL
�LIFO1248CJQRT7WX
��J� -��d   VZ3G�0123ѫdt�����!CD3;   R)iI�MN=�)Mm%�I+WXYZ5S�LLL
�LIFO1248CJQRT7WX
-I���LLL�dV-3G�0123h�dt��Y��!CDEFG�JSmZ���ԩS����
�LIFO1248CJQRT7WX
��J� -��d�VZ3G�0œ6DVdt��Yd�!CD�3; R�iI�MN=�M�J�UV]��I���LLL
�LIFO1248CJQRT7WX
��J� -��dVZ3G�012345ٺ����!CD3; R�iI�MN=�M�J�UV]��I���LLL
�LIFO1248CJQRT7WX
��J� -��d�VZ3G�0e�6DVdt��Y��!CDEFG�JSmZ���ԩSTUY��-I���LLL
...
PSLLSP commented 3 years ago

I received new serial adapter, from Aliexpress. It is with chip FT232BM. And it is FAKE chip! This is how it identifies in Linux (dmesg). This chip has no serial number and it doesn't work with stcgal...

[515837.081681] usb 2-2.2: new full-speed USB device number 102 using ehci-pci
[515837.199058] usb 2-2.2: New USB device found, idVendor=0403, idProduct=6001, bcdDevice= 4.00
[515837.199062] usb 2-2.2: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[515837.199063] usb 2-2.2: Product: USB <-> Serial
[515837.199065] usb 2-2.2: Manufacturer: FTDI
[515837.199598] ftdi_sio 2-2.2:1.0: FTDI USB Serial Device converter detected
[515837.199633] usb 2-2.2: Detected FT232BM
[515837.200960] usb 2-2.2: FTDI USB Serial Device converter now attached to ttyUSB2

FTDI replaced FT232BM with FT232BL. This FAKE chip from Aliexpress has FT232BL printed on the package. It was advertised as FT232BM and Linux identifies it as FT232BM...

NOTE: I think it is OK that serial number is 0. FT232BM/FT232BL stores serial number in external serial EEPROM and when no such EEPROM is attached, serial number is 0. My serial adapters with FT232BL have no external EEPROM. FT232BL chip with older design and newer design, like FT232RL, has embedded EEPROM in the chip.

Nable80 commented 3 years ago

I was following this thread for a long time in read-only mode but I can't stop myself anymore, sorry.

Is there any reason to buy FT232 chips nowadays? Especially from Ali, where no one have any reason to provide anything genuine (when cheaper fakes are available).

I'm personally using CH340 USB-UART chips and they're so extremely cheap, that no one makes fake clones of them. At the same time they're good enough for most uses. I agree that you've found real bugs and your research is impressive but is there any reason to insist on using FT232?

PSLLSP commented 3 years ago

Is there any reason to buy FT232 chips nowadays? Especially from Ali, where no one have any reason to provide anything genuine (when cheaper fakes are available).

FT232RL has some extra features that are not required for most of projects. When I started to play with STC51 chips I took a "random" adapter from my box with serial adapters. And that was adapter with FT232RL, genuine one, I liked it because connector was well described. Few days later I started other project with STC51 and this time I selected other serial adapter with FT232RL, that one was with fake chip and it was not working. I had two similar adapters, one of them was not working with stcgal but both were working in Windows with STCISP. That was a mystery that took my attention...

Results so far:

I'm personally using CH340 USB-UART chips and they're so extremely cheap, that no one makes fake clones of them. At the same time they're good enough for most uses. I agree that you've found real bugs and your research is impressive but is there any reason to insist on using FT232?

I agree, use any serial chip you like, I switched to CH340 chips too, I like mini adapters with micro USB connector (CH340E).

It is interested that FTDI manufactures even cheaper and simpler UARTs in package with less pins, like FT230XS, but adapters with these chips are rare and really expensive. FT232RL was a standard established in the past, it is well known part and it was so popular that fake copies are produced in huge numbers. I had no idea that I have several fake chips in my lab, that was two months ago. I know now that I have only two genuine FT232RL and the rest are adapters with FAKE chips.

It is normal that manufactures copies popular parts, like timer NE555, but they sell them under their brand. In the case of chips from FTDI, these are produced by pirate manufactures "as real FTDI" but are even not 100% compatible, that is bad...

There is one more reason why I am interested in FT232RL. Some new chips require UART serial signals at 1.8V. It is easy to buy serial adapter that is designed for 5V or 3.3V but once you need 1.8V adapter then you have a problem. ODROID single board computer with ARM chip is a device that comunicates at 1.8V. ODROID manufactures UART adapator for their computers but those are expensive. And they are unique, they use VCC pin to control IO voltage (that VCC pin is input pin serial adapter), so they can be used with 3.3V and 1.8V boards and they switch automatically. I failed to find any similar adapter on the market. I think I can use serial adapter with FT232RL and modify it to have similar function. I checked other UART chips and I think that it is not possible with UARTs like CH340 or PL2303. I have not tried to modify FT232RL adapter to autodect voltage of target system yet but that is on my TODO list...

grigorig commented 3 years ago

Serial communication of STC15F104W is 8E1 (EVEN PARITY) but stcgal configures communication to 8N1 (NONE PARITY). There is a BUG in stcgal!

Hm... stcgal should use the correct parity configuration. The protocol autodetection might break this, though. Have you tried to manually specify the protocol?

PSLLSP commented 3 years ago

I have not tried to manually force some protocol, I used auto-detection only.

I have an update to "fake" chips. I bought "genuine" FT232RL and FT232BL from official components distributor (FARNELL) and all these chips have the "frame error" bug. My conclusion is that there are no fake chips because the bug is in genuine chips from FTDI. This bug is not documented. The last question that remains is what are the two FT232RL chips I have from the past that doesn't have the framing error bug. These could be older design from FTDI or fake chips, bad clones of FT232RL... I tried to communicate with FTDI support but I haven't received full explanation of the situation or any plans how to address this issue. They just state that I bought chips from their official distributor and that implies that my chips are genuine FTDI chips. FTDI refused to send me samples of FT232RL.

PSLLSP commented 3 years ago

I just try FT232RL with framing bug with STC15W201S. When I try autdetect mode, it doesn't work, STC MCU is not detected:

$ stcgal -p /dev/ttyUSB0
Waiting for MCU, please cycle power: 

When I force protocol stc15, it works, STC MCU is detected:

$ stcgal -P stc15 -p /dev/ttyUSB0
Waiting for MCU, please cycle power: done
Target model:
  Name: STC15W201S
  Magic: F511
  Code flash: 1.0 KB
  EEPROM flash: 4.0 KB
Target frequency: 11.051 MHz
Target BSL version: 7.2.5T
Target wakeup frequency: 37.715 KHz
Target options:
  reset_pin_enabled=False
  clock_source=internal
  clock_gain=high
  watchdog_por_enabled=False
  watchdog_stop_idle=True
  watchdog_prescale=256
  low_voltage_reset=True
  low_voltage_threshold=2
  eeprom_lvd_inhibit=True
  eeprom_erase_enabled=False
  bsl_pindetect_enabled=False
  por_reset_delay=long
  rstout_por_state=high
  uart2_passthrough=False
  uart2_pin_mode=normal
  cpu_core_voltage=unknown
Disconnected!
grigorig commented 3 years ago

Thanks, that's good to know. Autodetection mode starts off with 8N1 mode and after detecting the MCU, it switches to the correct parity for the protocol. That usually works... but apparently not always. I think I'll just add a note to the FAQ, providing the protocol explicitly is probably an acceptable workaround for the time being.

PSLLSP commented 3 years ago

I just want to highlight that STC-ISP for Windows works, it autodetects chip even when I use FT232RL that has frame error bug...

Just an idea, start communication in 9N1 and autodetect parity in the software... In theory, all communication can be in 9N1 and parity can be handled in SW...

Other idea is to start autodetect mode in 8E1, it can receive 8N1 too (few parity errors will be detected but these can be ignored). Parity is not critical in this protocol because each block has known structure and checksum.

grigorig commented 3 years ago

Yeah, 8E1 sounds like a good idea, I'm just wary of changing anything as it might affect compatibility with other MCUs or other UART chips and the like. 9N1 is probably not a good idea since support for > 8 bit transfers is spotty (and pyserial doesn't support it at all).

PSLLSP commented 3 years ago

I see, stcgal is written in Python and Serial library has serious limits what can be configured. STC-ISP for Windows can probably do more tricks... There are reports on internet forums, that it could be possible to trick Serial library to transmit 9N1 data (switch between 8M1 and 8S1) and even possible to receive 9N1 data (set receiver to 8M1 and detect parity errors) but this seems like a dark magic. I have not tried these tricks.

From my point of view, issue #17 is high priority; to support newer chips. I can test it...

grigorig commented 3 years ago

I did a little bit of testing yesterday, protocol autodetection fails to work with 8E1 on older STC MCUs with protocols that do not natively use parity, such as STC12C2052. So I don't think we should change to that.

Maybe the reception issues on some FT232 can be fixed by setting the number of stop bits to 1.5 or 2. Can you try that? It's a wild guess, but might work. Not sure if that possibly causes new issues, I think the MCUs leave enough space between individual bytes though.

PSLLSP commented 3 years ago

More stop bits cannot fix bug in FT232RL. I just tried with two stop bits and it doesn't work. Problem is that parity bit zero is used as start bit and triggers reception of new byte, so one or two stop bits doesn't change anything (well, different byte is received). UARTs from other manufactures first wait for stop bit (line in state 1) and only after stop bit is detected, they start to search for start bit (line is state 0), so they synchronize to the next character correctly.

Other problem is that we have problem when stcgal receives bytes, so changing number of stops bits is useless. Stopbits are used by transmitter to delay communication, to grant receiver more time to process received byte. And transmitter in our case is STC MCU and we cannot modify how it sends serial data...

grigorig commented 3 years ago

The protocol autodetection seems to work fine with MARK parity on allegedly fake FT232 chips. Needs more testing with those older MCUs.

PSLLSP commented 3 years ago

It is interesting discovery and I can confirm that it works. I try it with a python script. Transmitter is configured to 8E1. When receiver is 8N1, it receives corrupted data (frame error bug). When receiver is configured to 8M1, 8S1, 8E1 or even 8O1, it receives data that are synchronized to start bit. That is really surprise that even 8O1 (odd parity) works...

I tried this with several different UARTS (PL2303, CP2303, CHG340E, CH340G, FT232RL, FT232BL) and it is the same, when transmitter is 8E1 and receiver is 8M1 or 8O1, it works, no errors are reported. It looks like Python serial library ignores parity errors. When receiver is 8N1, then only FT232RL and FT232BL receive corrupted data...

grigorig commented 3 years ago

Unfortunately that still doesn't work with old STC MCUs. MARK parity only works reliably if an 8N1 sender (i.e. the older STC MCU in our case) inserts some extra idle time after sending each byte, but at least STC89C52RC doesn't, so the received data is erroneous.

Whatever, it's an acceptable workaround to specify the protocol if you have one of the problematic FT232 UARTs.