7E1 UART2 mode problem - bad frames

Hello!

Another big problem with UART - it seems that data sent with 7e1 frames (7 data bits, 1 stop, even parity) has wrong parity bit values.
This is my example code - I am sending some data over UART2 - when the frame is set to 8e1 data are sent correctly. But when it is set to 7e1 I get the data but with “frame error” (HTerm 0.6.5 shows frame errors). I suppose it is a parity error.

#include "adl_global.h"

#define SIGMAPACKAGE    ":013A0000C5\r\n"

const u16 wm_apmCustomStackSize = 1024;
static s8 fcmHandle;

void SendString ( ascii * StringToSend );

void SendMessage_TimerHandler ( u8 ID )
{
    TRACE (( 1, "Embedded : Send Message" ));
    //adl_fcmSendData(fcmHandle,MESSAGE, sizeof(MESSAGE)-1);
    SendString(SIGMAPACKAGE);
    //adl_atSendResponse ( ADL_AT_UNS, "\r\nHello World from Open-AT\r\n" );
}

bool fcmCtrlH ( u8 Event )
{
    bool bReturn = TRUE;
    
    TRACE (( 1, "V24 event %d", Event ));
    
    // Switch on event
    switch ( Event )
    {   
        case ADL_FCM_EVENT_FLOW_OPENNED :       
            adl_fcmSwitchV24State ( fcmHandle, ADL_FCM_V24_STATE_DATA );
            TRACE (( 1, "Switch to data" ));
              
            
        break;
        
        case ADL_FCM_EVENT_RESUME :
            
            TRACE (( 1, "Resume Data Flow"));
            
        break;
        
        case ADL_FCM_EVENT_MEM_RELEASE :
            
            TRACE (( 1, "Data are sent"));
            
        break;          
    }
    
    return bReturn; 
}

/***************************************************************************/
/*  Function   : fcmDataH                                                  */
/*-------------------------------------------------------------------------*/

bool fcmDataH ( u16 DataLen, u8 * Data )
{
    /* Scan received string */
    u8 i;
    ascii * RecString = adl_memGet ( ( u16 ) ( DataLen ) );    
    
    TRACE (( 1, "V24DataHandler begin"));
    wm_memcpy ( ( ascii * ) RecString, ( ascii * ) Data, DataLen );

    DUMP ( 2, RecString, DataLen);
    adl_memRelease ( RecString );

return TRUE;

}


bool Res_WMFM1_Handler ( adl_atResponse_t *paras ) {return TRUE;}
bool Res_IPR_Handler( adl_atResponse_t *paras ) {return TRUE;}
bool Res_IPR_Handler2( adl_atResponse_t *paras ) {return TRUE;}
bool Res_IPR_Handler1( adl_atResponse_t *paras ) {    
    TRACE (( 1, "(evh_sim) fcm handler create" ));
    fcmHandle = adl_fcmSubscribe( ADL_FCM_FLOW_V24_UART2, fcmCtrlH, fcmDataH );
    return TRUE;
    
}

void SendString ( ascii * StringToSend )
{
    adl_fcmDataBlock_t  *BlockToSend;
    s32 sReturn;
    
    TRACE (( 1, "SendString "));
    /* Build block to send */
    BlockToSend = adl_memGet ( ( u16 ) ( sizeof ( adl_fcmDataBlock_t ) + wm_strlen ( StringToSend ) ) );
    BlockToSend->DataLength = wm_strlen ( StringToSend );
    wm_memcpy ( ( ascii * ) BlockToSend->Data, StringToSend, wm_strlen ( StringToSend ) );
    
       
    /* Send Block */
    sReturn = adl_fcmSendDataExt ( fcmHandle, BlockToSend );
    TRACE (( 1, "Submit data : %d", sReturn ));
    if ( sReturn == FALSE )
    {
        TRACE (( 1, "No more credit ; wait for resume" ));
        
        /* Block sent, but flow not ready to send more data */
        return;
    }
    else
    {
        // Wait for resume
        TRACE (( 1, "String saved but not sent : wait for resume" ));
    }
}

/***************************************************************************/
/*  Function   : adl_main                                                  */
/*-------------------------------------------------------------------------*/

void adl_main ( adl_InitType_e  InitType )
{
    TRACE (( 1, "Embedded : Appli Init" ));

        adl_atCmdCreate( "AT+WMFM=0,1,2", FALSE, Res_WMFM1_Handler, "*", NULL ); //Activate UART2

        adl_atCmdCreate( "AT+IPR=19200", ADL_AT_PORT_TYPE( ADL_AT_UART2, FALSE ),
            Res_IPR_Handler, "*", NULL );
            
        adl_atCmdCreate( "AT+IFC=0,0", ADL_AT_PORT_TYPE( ADL_AT_UART2, FALSE ),
           Res_IPR_Handler2, "*", NULL );

        adl_atCmdCreate( "AT+ICF=5,1", ADL_AT_PORT_TYPE( ADL_AT_UART2, FALSE ),
            Res_IPR_Handler1, "*", NULL ); // 2,1 = 8e1, 5,1 = 7e1
            
        adl_tmrSubscribe ( TRUE, 20, ADL_TMR_TYPE_100MS, SendMessage_TimerHandler );
}


In red are bytes with error. These first weird bytes are unsolicited messages (witch 8n1 115200 I suppose) which I can’t disable (see: viewtopic.php?f=15&t=2220).
Change “AT+ICF=5,1” to “AT+ICF=2,1” in code and there is no errors, but I must have 7e1 data transmission :frowning:

Workaround: use 8n1 frame and calculate 8th (MSB) bit which will be parity bit in 7e1 - it works but if problem I mentioned above is bug in the firmware it should be fixed.

u8 addparity(u8 data) {
    u8 parity = 0x00;
    u8 tmp = data;
    tmp &= 0x7F;
    
    while (tmp) {
        parity = ~parity;
        tmp = tmp & (tmp - 1);
    }
    
parity &= 0x80;
return (data & 0x7F) | parity;

}

Still I need fix this problem due to program speed reason.