[FX100] RS232 communicate with external device

Hello everyone,

I’m have connected an external device on my FX100 via RS232.
Now I want to send e.g every 10 seconds an ASCII command to this device (like #00) to receive a response from it in ASCII.

I know that it should be possible with FCM, but I’m having troubles how to start.
If I’m not wrong it should be possible with the UART1 port and sending the command via data mode.

The standard settings of the external Device are:
Baudrate: 9600
Parity:None
Databits:8
Stopbits:1
Flow Control: None

I’d be really grateful if someone could help me.

Thank you very much.

Best regard

A.Sevay

Hello,

You can have a look to this sample code, it was very useful for me.

https://forum.sierrawireless.com/t/simple-uart-echo-program/4739/1

Thank you. This link was helpful.

Receiving Messages ist not a problem.
However, I have problems sending them.

I try to send every 10 seconds a message with pbuf=#001(CR) (a CarriageReturn is needed for this command)
ret = adl_fcmSendData(handle_uart1, ( u8 * )pbuf, ( u16 )(5) );
in the function FCM_Command_handler(see code below).

It sends the ASCII order via the RS232.
ret:0 handle:0 pbuf:#001 len:4

However, it won’t send a response.
I’ve made also these settings
/* Databit= 8, Stopbit=1, Parity= none => AT Command Interface page 1003 : 3,4 */
adl_atCmdCreate(“AT+ICF=3,4”, UART_1,NULL,NULL);

/* no hardware flow control */
adl_atCmdCreate(“AT+IFC=0,0”,UART_1,NULL,NULL);

Then shortly this:
ret:1 handle:0 pbuf:#001 len:4
and finally this with the error -21
ret:-21 handle:0 pbuf:#001 len:4

#include "wm_types.h"
#include "wm_stdio.h"
#include "wm_list.h"
#include "adl_str.h"
#include "adl_port.h"
#include "adl_at.h"
#include "adl_traces.h"
#include "adl_memory.h"
#include "adl_error.h"
#include "adl_fcm.h"
#include "adl_TimerHandler.h"

#include "adl_AppliInit.h"
#include "adl_UnSoHandler.h"
#include "adl_RspHandler.h"
#include "adl_CmdStackHandler.h"

#include "adl_global.h" /* Application development layer */


#include "adl_adc.h"

/*-------------------------------- defines -------------------------------*/
    #define UART_1 ADL_AT_PORT_TYPE(ADL_PORT_UART1,ADL_AT_RSP) /* refer to ADL User Guide pag 67, rspflag */

// Application tasks prototypes
extern void main_task ( void );
void FCM_Command_handler( u8 ID, void * Context );
bool FcmCtrlHandler(adl_fcmEvent_e evnt);
static bool FcmDataHandler(u16 DataSize, u8 * Data);

#ifndef __GNU_GCC__
#define DECLARE_CALL_STACK(X)   (X)
#else
#define DECLARE_CALL_STACK(X)   (X*3)
#endif /* #ifndef __GNU_GCC__ */

// Application tasks declaration table
const adl_InitTasks_t adl_InitTasks [] =
{
    { main_task,  DECLARE_CALL_STACK ( 1024 ), "main", 1 },
    { 0, 0, 0, 0 }
};

/* UART mode type */
enum UART_TYPE{
   DATAMODE,
   ATMODE
};

/*------------------------------ variables ---------------------------*/
const u16 wm_apmCustomStackSize = 1024*3;    /* application stack size (trial&error to determine size)*/

s8 handle_uart1;                     /* UART1 handler */
u8 mode_uart1;                        /* UART1 mode type */

ascii *saveFCMdata; //saves last message received from FCM

/***************************************************************************
 * FCM control handler
 */
bool FcmCtrlHandler(adl_fcmEvent_e evnt)
{
	switch (evnt)
	        {
	        /* when com is open, operation mode is defined */
	        case ADL_FCM_EVENT_FLOW_OPENNED:
	           /*  DATA MODE */
	           if(mode_uart1 == DATAMODE){
	              adl_atSendResponse(ADL_AT_RSP, "\r\nUART1: Data Mode");
	              adl_fcmSwitchV24State(handle_uart1,ADL_FCM_V24_STATE_DATA);
	           }
	           /* AT MODE */
	           else if(mode_uart1 == ATMODE){
	              adl_atSendResponse(ADL_AT_RSP, "\r\nUART1: AT Mode");
	              adl_fcmSwitchV24State(handle_uart1,ADL_FCM_V24_STATE_AT);
	           }
	           break;

	        case ADL_FCM_EVENT_V24_DATA_MODE:
	           /* DATA MODE OK */
	           break;

	        case ADL_FCM_EVENT_V24_AT_MODE:
	           /* AT MODE OK */
	           break;

	        case ADL_FCM_EVENT_RESUME:
	           break;

	        case ADL_FCM_EVENT_MEM_RELEASE:
	           break;

	        default:
	           return FALSE;
	           break;
	        }
	        return TRUE;

}

/***************************************************************************
 * FCM data handler
 */
static bool FcmDataHandler(u16 DataSize, u8 * Data)
{
	ascii buf[100] = { 0 }; 

	u16 i = 0;

	wm_sprintf(buf,"\r\nDataSize:%d|\r\n",DataSize);
	adl_atSendResponse ( ADL_AT_UNS, buf );

	wm_sprintf(buf,"\r\nData:\r\n%s[%d]|\r\n",Data,(int)Data);
	adl_atSendResponse ( ADL_AT_UNS, buf );


	saveFCMdata = malloc(DataSize * sizeof(char) );
	adl_atSendResponse ( ADL_AT_UNS,"\r\n-----------------\r\n");
	for(i=0 ; i < DataSize ;i++)
	{
		wm_sprintf(buf,"%c",Data[i]);
		adl_atSendResponse ( ADL_AT_UNS, buf );

		saveFCMdata[i] = Data[i];
	}
	adl_atSendResponse ( ADL_AT_UNS,"\r\n-----------------\r\n");


	return true;
}



/**/
//Send command every 10 seconds
void FCM_Command_handler( u8 ID, void * Context )
{
	ascii buf[100];

	s8 ret;

	ascii * pbuf;
	u16 len;


	pbuf = "#001";
	pbuf[4]=13;//CR
	pbuf[5]='\0';
	len = (u16)wm_strlen(pbuf) +1; //+1 for CR

	ret = adl_fcmSendData(handle_uart1, ( u8 * )pbuf,  ( u16 ) ( wm_strlen(pbuf)+1) ); //ret = adl_fcmSendData(handle_uart1, pbuf, &len);
	if( ret != 0)
	{
		wm_sprintf(buf, "adl_fcmSendData err = %d\r\n", ret);
		adl_atSendResponse ( ADL_AT_UNS, buf);
	}
	wm_sprintf(buf, "ret:%d handle:%d pbuf:%s len:%d \r\n", ret, handle_uart1, pbuf, len);
	adl_atSendResponse ( ADL_AT_UNS, buf);

	switch(ret){
	          case ADL_RET_ERR_PARAM:
	             adl_atSendResponse(ADL_AT_RSP,"FCM send data: parameter incorrect value");
	             break;
	          case ADL_RET_ERR_UNKNOWN_HDL:
	             adl_atSendResponse(ADL_AT_RSP,"FCM send data: unknown handle");
	             break;
	          case ADL_RET_ERR_BAD_STATE:
	             adl_atSendResponse(ADL_AT_RSP,"FCM send data: not ready to send data");
	             break;
	          case ADL_FCM_RET_ERR_WAIT_RESUME:
	             adl_atSendResponse(ADL_AT_RSP,"FCM send data: flow has no more credit");
	             break;
	          case ADL_RET_ERR_SERVICE_LOCKED:
	             adl_atSendResponse(ADL_AT_RSP,"FCM send data: from a low level");
	             break;
	          }

}


/*****************************************************************************/
/*  Function   : main_task                                                   */
/*---------------------------------------------------------------------------*/
/*  Object     : Customer application initialization                         */
/*                                                                           */
/*---------------------------------------------------------------------------*/
/*****************************************************************************/
void main_task ( void )
{
	adl_InitType_e InitType = adl_InitGetType ();

	ascii buf[100];

	
    mode_uart1 = DATAMODE;

    /* speed  with AT Command*/
     adl_atCmdCreate("AT+IPR=9600", UART_1,NULL ,NULL);


    /* Databit= 8, Stopbit=1, Parity= none => AT Command Interface page 1003 : 3,4 */
    // adl_atCmdCreate("AT+ICF=3,4", UART_1,NULL,NULL);

     /* no hardware flow control */
    //adl_atCmdCreate("AT+IFC=0,0",UART_1,NULL,NULL);


    handle_uart1=adl_fcmSubscribe(ADL_PORT_UART1, FcmCtrlHandler, FcmDataHandler);
    wm_sprintf(buf, "\r\nhandle_uart1:%d  \r\n", handle_uart1);
    adl_atSendResponse(ADL_AT_RSP,buf);

    if(adl_fcmIsAvailable(ADL_FCM_FLOW_V24_UART1))
    {
    	adl_atSendResponse ( ADL_AT_UNS, "\r\nUART1 is available.\r\n" );
    }

    //set Timer FCM_Command to send command every 10 seconds
     adl_tmrSubscribe (TRUE, 100, ADL_TMR_TYPE_100MS, FCM_Command_handler );

}

Can anyone tell what went possibly wrong here?
Thank you.

I’m not confused.

My FX100 doesn’t react on AT-commands like AT+IPR=9600, although I get a successful OK response.
In the Development mode AT+IPR? remains 0 and in the Production mode AT+IPR? remains 115200.
But even with a Baudrate set in the Production mode, it won’t send any messages (ret = adl_fcmSendData(handle_uart1, ( u8 * )pbuf, ( u16 ) ( wm_strlen(pbuf)) );),
although the return value is 0.

Interesting is that after a while I receive the return value -21.
Any idea what this error number means?

Can anyone help me why the modem behaves this weird?

Error codes are listed in the ADL User Guide - aren’t they :question:

They are, at chapter 5.1, but the smallest error number there is -20 (= Beginning of specific errors range).
So I wonder what -21 means?

Hello,

In Developer Studio, select adl_fcmSendData, right click, open declaration, then select the corresponding firmware you use.
With this action, the file adl_fcm.h is opened.
See the error code value for the method adl_fcmSendData:

/**
  @brief  Specific FCM Service Error Code
  
  @par Description:
  the flow has no more credit to use
 */
#define ADL_FCM_RET_ERR_WAIT_RESUME                 ADL_RET_ERR_SPECIFIC_BASE - 1

ADL_RET_ERR_SPECIFIC_BASE - 1 => -21

Marc

ISTR that this can occur if you have (hardware) flow control enabled, and the flow control is blocking the transmission…?