Skip to content

FTDI Driver doesn't report state change on any modem signals from FTDI chip (IEC-461) #361

@Rotario

Description

@Rotario

Answers checklist.

  • I have read the component documentation ESP-IDF Components and the issue is not addressed there.
  • I am using target and esp-idf version as defined in component's idf_component.yml
  • I have searched the issue tracker for a similar issue and not found any related issue.

Which component are you using? If you choose Other, provide details in More Information.

device/esp_tinyusb

ESP-IDF version.

v5.0

Development Kit.

Custom board

Used Component version.

2.0.0

More Information.

Behavior depends on compiler implementation and may vary between GCC versions or optimization levels.

Current Code

managed_components/espressif__usb_host_ftdi_vcp/usb_host_ftdi_vcp.cpp - `FT23x::ftdi_rx()

new_state.bRxCarrier =   data[0] & 0x80; // Extract bit 7                                     
new_state.bTxCarrier =   data[0] & 0x20; // Extract bit 5                                     
new_state.bBreak =       data[1] & 0x10; // Extract bit 4                                     
new_state.bRingSignal =  data[0] & 0x40; // Extract bit 6                                     
new_state.bFraming =     data[1] & 0x08; // Extract bit 3                                     
new_state.bParity =      data[1] & 0x04; // Extract bit 2                                     
new_state.bOverRun =     data[1] & 0x02; // Extract bit 1                                     

Where cdc_acm_uart_state_t is:

typedef union {                               
    struct {                                  
        uint16_t bRxCarrier : 1;              
        uint16_t bTxCarrier : 1;              
        uint16_t bBreak : 1;                  
        uint16_t bRingSignal : 1;             
        uint16_t bFraming : 1;                
        uint16_t bParity : 1;                 
        uint16_t bOverRun : 1;                
        // ... more fields                    
    };                                        
    uint16_t val;                             
} cdc_acm_uart_state_t;                       

Expected Behavior

Bitwise AND correctly extracts the bit, and the 1-bit field is set to:

  • 1 if the extracted bit is set
  • 0 if the extracted bit is clear

Example: If data[0] = 0x80 (bit 7 set):

  • data[0] & 0x800x80 (non-zero)
  • Assign to bRxCarrierbRxCarrier = 1

Actual Behavior

The bit value is lost during assignment:

  • data[0] & 0x800x80
  • Compiler truncates to fit 1-bit field → takes LSB of 0x800
  • Assign to bRxCarrierbRxCarrier = 0

Result: The extracted bit value is inverted or lost depending on bit position.

I've tested this with a null modem cable and another FTDI chip connected to my PC. Running a short python script asserting DTR does not trigger the event_changed callback because of this bug

If I update the assignments to this
managed_components/espressif__usb_host_ftdi_vcp/usb_host_ftdi_vcp.cpp - `FT23x::ftdi_rx()

 new_state.bRxCarrier =   !!(data[0] & 0x80);                                                                                                                                                 
 new_state.bTxCarrier =   !!(data[0] & 0x20);                                                                                                                                                 
 new_state.bBreak =       !!(data[1] & 0x10);                                                                                                                                                 
 new_state.bRingSignal =  !!(data[0] & 0x40);  
 new_state.bFraming =     !!(data[1] & 0x08);  
 new_state.bParity =      !!(data[1] & 0x04);  
 new_state.bOverRun =     !!(data[1] & 0x02);  

Then the state change handling works

Here's the python script I run it with
./rs232_slow_receiver.py --dsrdtr --rtscts --no-xonxoff --port /dev/ttyUSB0
rs232_slow_receiver.py

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions