Bug in OpenAT?Problem with UART2-GSM flow interfered byUART1

Hello,

To better present my problem, please have a look at the picture:

[attachment=0]wavecom_uart1+uart2+gsm.PNG[/attachment]

I power up wavecom demo board with application running on Q2686. Application enables communication between sensor connected to UART2 and PC over GSM network:

void adl_main ( adl_InitType_e  InitType ) {

      returned_value = adl_atCmdCreate ("AT+WMFM=0,1,2\r", FALSE,(adl_atRspHandler_t) HandleWmfmUART2,"*",NULL);
    }

    bool HandleWmfmUART2(adl_atResponse_t *response)
    { 
    HelloWorld_TimerHandler2(0); return(FALSE); 
    }

    void HelloWorld_TimerHandler2 ( u8 ID )
    {

        adl_atCmdCreate ("AT+IPR=9600\r", ADL_AT_PORT_TYPE(ADL_PORT_UART2,FALSE), (adl_atRspHandler_t) NULL,NULL);
       adl_atSendResponse ( ADL_AT_UNS, "UART2 set to 9600\32\r\n" );
       adl_callSubscribe (Call_Handler);
    }

In call event handler (ADL_CALL_EVENT_ANSWER_OK) I subscribe for GSM flow & UART2 flow
My GSM & UART2 handlers are following:

bool GSM_DATA_DataHandler (u16 DataLen, u8 * Data) {
      adl_fcmSendData(FCMHandler,Data, DataLen);

    return TRUE;
    }

    bool FcmDataHandler (u16 DataLen, u8 * Data) {

        adl_fcmSendData (GSM_DATA_Handle,Data,DataLen);

    return TRUE;
    }

I am making data call from Hypertrm, PC A to Wavecom demo board. Once the connection has been established, on Hypertrm UART2 pop up:

And at the same time I receive on Hypertrm UART1:

Which shouldn’t appear. I subscribe only to UART2. Can someone explain why I got data on UART1?

What’s more, when I type in Hypertrm UART2, characters doesn’t show up in Hypertrm, PC A terminal. But when typed on PC A, they show up on Hypertrm UART2. When I type in Hypertrm UART1, then chatracters appear in HyperTrm on PC A. Why GSM is linked to UART1? I am not using UART1! I don’t understand this. Is there any bug in OpenAT or am I missing somthing?

Best regards,
Tom

Shouldn’t it?

That’s not data - that’s AT responses.

Thank you for answer, but it didn’t help me to figure out this problem.

OK, you are right,maybe UART1 can send commands to PC A, without any subscription to GSM and UART1 data flow. But this is not stated in any documentation.

I did only subscription to UART2 and GSM flow! Not UART1.

So why I don’t get any data sent from UART2 to PC A? Data from PC A to UART2 can be send.

Thanks in advance for explanation.
Tom

If the UART is not subscribed by an application, it behaves in the normal manner for a modem serial port; ie, it accepts AT Commands, and gives responses - including unsolicited responses like RING when the modem is called, and CONNECT when the call is established!

You haven’t shown your UART2 subscription.

You are also making a lot of ADL calls without checking return codes…

The picture seems to have gone missing from your original post…

I made a bunch of experiments with Call part of wavecom modules but still cannot understand how does it work. :slight_smile: You can try to use UART2 as GSM data channel. It can be made with adl_callAnswerExt. And I think it is not necessary to setup speed of your UART - it should switch speed automagically after CONNECT.

Thanks for reply,

I have attached again picture which presents my problem. (Someone has deleted it…).

Here is my UART2 subscription, and everything seems all right here:

case ADL_CALL_EVENT_ANSWER_OK:  //MT!!!
    adl_atSendResponse ( ADL_AT_UNS, "ADL_CALL_EVENT_ANSWER_OK\n\r");

    // this is for UART2 flow:
    FCMHandler = adl_fcmSubscribe( ADL_PORT_UART2, FcmCtrlHandler , FcmDataHandler);
   //this is for GSM flow:
   GSM_DATA_Handle = adl_fcmSubscribe ( ADL_FCM_FLOW_GSM_DATA, GSM_DATA_Control_Handler, GSM_DATA_DataHandler );
      
      break;
case ADL_CALL_EVENT_HANGUP_OK:
           adl_fcmSwitchV24State(FCMHandler,ADL_FCM_V24_STATE_AT);
           adl_atSendResponse ( ADL_AT_UNS, "ADL_CALL_EVENT_HANGUP_OK\n\r");
           adl_fcmUnsubscribe(GSM_DATA_Handle);
      break;

Blackyblack has advice me to use adl_callAnswerExt , Well I am going to test this function and will give feedback.

I am using only: adl_callAnswer

case ADL_CALL_EVENT_RING_DATA: // if data phone call MT
           adl_atSendResponse ( ADL_AT_UNS, "ADL_CALL_EVENT_RING_DATA;data phone call\n\r");
         nb_rang++;
         if (nb_rang>2) //if 2 rings -> answer
         adl_callAnswer();
      break;

Cheers,
Tom

Where do you switch the UART2 flow to Data mode?

In definition of FcmCtrlHandler for UART2, that is also correct, (according to many examples on this forum)

bool FcmCtrlHandler (adl_fcmEvent_e Event)
{    
    switch (Event)
    {

case ADL_FCM_EVENT_FLOW_OPENNED :
      {
         TRACE((1, "ADL_FCM_EVENT_FLOW_OPENNED"));
         adl_atSendResponse(ADL_AT_UNS,"fcmSubscribe openned UART2\r\n");
         adl_fcmSwitchV24State(FCMHandler,ADL_FCM_V24_STATE_DATA);
         break ;
      }
    } //switch
}//handler

Thanks blackyblack for advice. I’ve replaced adl_callAnswer for adl_callAnswerExt (ADL_PORT_UART2 );
But it didn’t help, After changing this I can only see that data from UART1 are not send to HyperTerminal on PC A. This is the only advantage of using adl_callAnswerExt (ADL_PORT_UART2 ). Still I cannot send data from UART2 to PC A over GSM.

and do you get the Event to confirm that it has actually switched to Data mode?

Well, in FcmCtrlHandler for UART2 I have also:

case ADL_FCM_EVENT_V24_DATA_MODE:
      {
         TRACE((1, "ADL_FCM_EVENT_V24_DATA_MODE"));
         adl_atSendResponse(ADL_AT_UNS,"now UART2 is in data_mode\r\n");
         //s8r=adl_fcmSendData(FCMHandler,"abc",3);
         break ;
      }

On HyperTrm connected to UART2 I have:

when I type +++ in HyperTrm, then I got:

The same will show up on HyperTrm in UART1 without string “test1”, because “test1” has been send form HyperTrm in PC A over GSM to UART2 in data mode… (I guess)…

In your adl_atSendResponse calls, you aren’t specifying to which port you want the responses sent…

Ok, now I have replaced all adl_atSendResponse calls by adding ADL_AT_PORT_TYPE(ADL_AT_UART2,ADL_AT_RSP) macro in first argument:

adl_atSendResponse( ADL_AT_PORT_TYPE(ADL_AT_UART2,ADL_AT_RSP),"ADL_PORT_GPRS_BASE READY TO HANDLE\32\r\n" );

But this didn’t help a lot, still I cannot received data on HyperTrm on PC A over data call. but I can send data from HyperTrm on PCa to UART2 over GSM.

How can I debug this problem? It seems that data are somewhere lost or not delivered to GSM flow… (only one way UART2->GSM).

Sorry,
Maybe I have lost some information in the way. Here you have made a gateway between the GSM and the physical port:

bool GSM_DATA_DataHandler (u16 DataLen, u8 * Data) {
      adl_fcmSendData(FCMHandler,Data, DataLen);

    return TRUE;
    }

    bool FcmDataHandler (u16 DataLen, u8 * Data) {

        adl_fcmSendData (GSM_DATA_Handle,Data,DataLen);

    return TRUE;
    }

Your subscriptions of FCM handlers ar the following:

// this is for UART2 flow:
    FCMHandler = adl_fcmSubscribe( ADL_PORT_UART2, FcmCtrlHandler , FcmDataHandler);
   //this is for GSM flow:
   GSM_DATA_Handle = adl_fcmSubscribe ( ADL_FCM_FLOW_GSM_DATA, GSM_DATA_Control_Handler, GSM_DATA_DataHandler );

So you have implemented a gateway between UART2 and GSM flow.

How many wires does the cables you are using between PC A and evaluation board have?
Anyway I recomend you to check the respones of adl_fcmSendData, and the incoming data to the data handlers using traces. Is this posible?

Are you sure that’s a good idea?

Before you do that, you need to double check that you only ever call adl_atSendResponse for UART2 when UART2 is in AT Command mode…

Use the Debug facilities - TRACE and DUMP.

At a minimum, you should trace every return value from every ADL call…

If you use callAnswerExt on some port it is supposed that GSM flow will use provided port (UART2) in data mode. So during adl_callAnswerExt it is supposed that you do not have other flows subscribed to the same port. So try to remove all FCM subscriptions except adl_callAnswerExt for UART2. Also remove every adl_atSendResponse on UART2 (or UNS) that could possibly show up during connect or data exchange on this port - put all debug data on some other port (UART1).
And still I don’t know anybody who knows how does CSD calls are proceeded by wavecom modules. It is supposed that GSM calls are proceeded on OPENAT_BASE port and not interferred with UART1 (but block every GPRS data exchange). But in reality we have both working GSM and GPRS data exchange but with UART1 used for GSM and OPENAT_BASE for GPRS. It is weird behaviour and you problem is a part of this behaviour - your GSM call uses UART1 while it has to use OPENAT_BASE (virtual uart).

I think it’s better not to use AT responses at all for debug; use TRACE and DUMP instead - that’s what they’re there for!

This also means that you are not tied to any particular port - you can get the TRACE and DUMP on any port that seems convenient at the time - UART1, UART2, or USB. :smiley:

Thanks to all for discussion on this problem.

fer.caballero, yes I did kind of gateway between the GSM and the physical port.

Between evaluation board and PC A is a GSM link, where I use another modem and cable from this modem to PC A. (Have a look at picture I put in first post). The cable is standard RS232 cable. I wouldn’t worry about this link, because I have tested this modem with cables in other scenarios… Problem has to be in Q2686, how this CPU is linking UART2 to GSM…

Well, I not familiar with TRACE and DUMP() macros. But I see those are inevitable, so I am going to familiar with those macros and use them.

Right now I did this:

case ADL_FCM_EVENT_FLOW_OPENNED :
      {
         TRACE((1, "ADL_FCM_EVENT_FLOW_OPENNED"));
      adl_atSendResponse(ADL_AT_PORT_TYPE(ADL_AT_UART1,ADL_AT_RSP),"fcmSubscribe openned UART2\r\n");
        s8r=adl_fcmSendData(FCMHandler, (u8 *)"flow_ope",8);
         if (s8r == OK) adl_atSendResponse(ADL_AT_PORT_TYPE(ADL_AT_UART1,ADL_AT_RSP),"flow openned, code: OK \r\n");
         else if (s8r == ADL_FCM_RET_OK_WAIT_RESUME) adl_atSendResponse(ADL_AT_PORT_TYPE(ADL_AT_UART1,ADL_AT_RSP),"flow openned, code: ADL_FCM_RET_OK_WAIT_RESUME \r\n");
         else if (s8r == ADL_RET_ERR_PARAM) adl_atSendResponse(ADL_AT_PORT_TYPE(ADL_AT_UART1,ADL_AT_RSP),"flow openned, code: ADL_RET_ERR_PARAM \r\n");
         else if (s8r == ADL_RET_ERR_UNKNOWN_HDL) adl_atSendResponse(ADL_AT_PORT_TYPE(ADL_AT_UART1,ADL_AT_RSP),"flow openned, code: ADL_RET_ERR_UNKNOWN_HDL \r\n");
         else if (s8r == ADL_RET_ERR_BAD_STATE) adl_atSendResponse(ADL_AT_PORT_TYPE(ADL_AT_UART1,ADL_AT_RSP),"flow openned, code: ADL_RET_ERR_BAD_STATE \r\n");
         else if (s8r == ADL_FCM_RET_ERR_WAIT_RESUME) adl_atSendResponse(ADL_AT_PORT_TYPE(ADL_AT_UART1,ADL_AT_RSP),"flow openned, code: ADL_FCM_RET_ERR_WAIT_RESUME \r\n");
         else if (s8r == ADL_RET_ERR_SERVICE_LOCKED) adl_atSendResponse(ADL_AT_PORT_TYPE(ADL_AT_UART1,ADL_AT_RSP),"flow openned, code: ADL_RET_ERR_SERVICE_LOCKED \r\n");
         //else if (s8r == ADL_FCM_RET_XXX_WAIT_RESUME) adl_atSendResponse(ADL_AT_PORT_TYPE(ADL_AT_UART1,ADL_AT_RSP),"flow openned, code: ADL_FCM_RET_XXX_WAIT_RESUME \r\n");
         else adl_atSendResponse(ADL_AT_PORT_TYPE(ADL_AT_UART1,ADL_AT_RSP),"flow openned, code: error not in range \r\n"); 
         
       
         adl_fcmSwitchV24State(FCMHandler,ADL_FCM_V24_STATE_DATA);
         TRACE(( 1, "adl_fcmSwitchV24State Ret= %d", s8r)); 
         break ;
      }

And on HyperTrm on UART2 I got:

so the error is: ADL_RET_ERR_BAD_STATE which means that “the flow is not ready to send data”

Why?

blackyblack I only subscribe to UART2 & GSM flow, so I think I fulfill requirements for callAnswerExt() I have also remove not necessary adl_atSendResponse() calls.

I am going to replace them with TRACE and DUMP macros, so I will keep you informed about status of this gatway.

ohh, Yes, Can someone explain why it is using UART1 even if not subscribed to UART1?

It seems that you are trying to send data before your flow goes to DATA mode. Fix it.

I think there is no need to subscribe to UART2 flow if you bind GSM flow to UART2.

Agreed.

This must be always before:

adl_fcmSwitchV24State(FCMHandler,ADL_FCM_V24_STATE_DATA);

this:

s8r=adl_fcmSendData(FCMHandler, (u8 *)"flow_ope",8);