How to send a Hexa data using adl_fcmSendData

Yes, what I described covers that scenario:

Yours is the blue case!

No, you don’t need a function to do that!
In fact, a function is almost certainly the wrong way to do it!

Remember that Open-AT is entirely Event-driven; that is, your application is only ever “woken up” when the system has an Event for it.

Look at the basic AT command example in the SDK: the application just sets-up the handlers, and then “exits” - thereafter, it is only ever woken-up when the system detects that the command has been entered, and calls the handler.

Your FCM application needs to do the same: send the data, then exit. Your application will then be woken when an event happens; eg, MEM_RELEASE…

There is no need for any specific wait within your code!

i am sorry but i still didn’t understand how to make the sending process resume from the last place when the buffer is full. because in my thought, everytime the buffer is full then the system was halted and waiting for the resume event. but the resume event will trigger another routine and not continuing the previously halted process. i attach my application below, would you mind to go through it and give me an example or direction for what am i supposed to write in my code?

int sendFcmH ( u8 input)
{
	res = adl_fcmSendData (Handle, (u8 *)&input, 1); // send 1 byte from the address of input
		switch (res)
		{
		case ADL_FCM_RET_OK_WAIT_RESUME:
			TRACE ((1,"ADL_FCM_RET_OK_WAIT_RESUME"));
			break;
		case ADL_RET_ERR_PARAM:
			TRACE ((1,"ADL_RET_ERR_PARAM"));
			break;
		case ADL_RET_ERR_UNKNOWN_HDL:
			TRACE ((1,"ADL_RET_ERR_UNKNOWN_HDL"));
			break;
		case ADL_RET_ERR_BAD_STATE:
			TRACE ((1,"ADL_RET_ERR_BAD_STATE"));
			break;
		case ADL_FCM_RET_ERR_WAIT_RESUME:
			TRACE ((1,"ADL_FCM_RET_ERR_WAIT_RESUME"));
			break;
		}
	return 0;
}


void transmitZero ( int x)
{
	int i = 1;
	for (i==1;i<=x;i++)
	{
		sendFcmH(0x00);
	}
}

void testHandler ()
{	
	adl_fcmSwitchV24State (Handle, ADL_FCM_V24_STATE_DATA);	
}

bool fcmCtrlH (u8 event)
{
	adl_atSendResponse (ADL_AT_UNS, "inside fcmCtrlH\n");
	switch (event)
	{
	case ADL_FCM_EVENT_FLOW_OPENNED:
		adl_atSendResponse (ADL_AT_UNS, "Flow Openned");                                 /* switching from AT mode to Data Mode*/
		break;
	case ADL_FCM_EVENT_V24_DATA_MODE:
		adl_atSendResponse (ADL_AT_UNS, "Flow in Data Mode");                          /* Sending data to the external app via v24 serial link*/
		a=0;
		c=0;
		sendFcmH(0x01);
		sendFcmH(0x7F);
		transmitZero(2);
//transmit movement
		for ( a=0;a<4;a++)
		{
			for ( c = 0; c<2;c++)
			{
				sendFcmH(0x90);
			}
		}
//Transmit data                                        
		a=0;
		for (a==0;a<200;a++)                                             
		{
			sendFcmH(0xFF);
		}

		break;
	case ADL_FCM_EVENT_RESUME:
		TRACE((1,"ADL_FCM_EVENT_RESUME"));
		break;
	case ADL_FCM_EVENT_MEM_RELEASE:
		TRACE((1,"MEM_RELEASE"));
		break;

	}
return TRUE;
}

bool fcmDataH (u16 DataLen, u8 * Data)
{
	adl_fcmSendData(Handle,Data,DataLen);
	
	return TRUE;
}

No, the system is not halted; the system is still running - it’s just your application “task” that is effectively suspended.

Your application “task” is rescheduled whenever there is an Event for it - such as a MEM_RELEASE event.

The event will be delivered to the appropriate Event Handler - in this case, the FCM Control Event handler.

So how exactly can i continue the supended task? since according to what you have said

You need to give your application some kind of “memory” so that it can “remember” where it was when it was last suspended.

In other words, you need to give your application some “memory” of its State - which is probably easiest done by writing your application as a Finite State Machine (FSM) - or just “State Machine” for short…

another question. why does every time i use a while function the system automatically restarted?

Probably it’s the Watchdog.

See the section “Hardware Security - Watchdog Protection” in the ADL User Guide.

You must not have long loops - eg, busy-wait loops - in your application.

but i only use this code :

int sendFcmH ( u8 input)
{
	u8 temp;
	
		temp = adl_fcmGetStatus(Handle, ADL_FCM_WAY_FROM_EMBEDDED);
		while (temp == ADL_FCM_RET_BUFFER_EMPTY)
		{
		temp = adl_fcmGetStatus(Handle, ADL_FCM_WAY_FROM_EMBEDDED);
		}
		adl_fcmSendData(Handle,(u8 *)&input,1);
}

does my code counted as an infinite loop??

If there’s something stopping the buffer from emptying (eg, flow control) - then it could be infinite.

Even if it’s not not “infinite”, it could still be longer than the watchdog timeout.

As already noted, you should never put a busy-wait loop in an Open-AT application - always find an Even to wait for instead.

In this case, there is no need to wait for the buffer to be empty - the MEM_RELEASE event will tell you when FCM is ready to accept another adl_fcmSendData call.

Hiya,

The Watchdog in the OpenAT firmware is quite unforgiving - and it has to be, as the CPU is not only running your application but also doing all the GSM radio stuff as well. There are strict time limits on some GSM radio processes and the CPU HAS to handle the GSM firmware events in time - or the GSM network may detect there is something wrong with the module and de-register it from the network.

As awneil says - OpenAT is an EVENT-DRIVEN operating system - probably completely different from any other operating system you’ve ever programmed before. Pretty much every operation in OpenAT is done using Event/Call-back handlers, and long term operations are all done using State Machines.

Don’t EVER write code such as this:

while ( boolean test )
{
    some operation;
};

As this will invariably trip the watchdog timer.

BTW, one advantage of a state machine is that you can completely define the entire task operation. That is, you know every state that the program is in, and how to transition between states.

There is a reasonable introduction to (finite) state machines here.

ciao, Dave

Hi all, I have followed your instruction about using FSM for my application. and thank god it worked. now i am continuing my application by combining the WIPSoft and the Fcm function. what i intend to make is an application which automatically request a web page containing my data from a web server. And after getting the data the app should send the preprocessed data into the UART1 using FcmSend Data. but there is a problem when i tried combining these function. the data that i saved when i accessing the web page is some kind of missing. and i cannot use the data to send it through the UART1.

I save the retrieved data into an array of string with the declaration like this : char* dataText[7]. The declaration was global. if i tried to use the data immediately after i retrieved it from the web page the data is good. but if i used it in another sub routine the data is lost and sometimes just filled with gibberish. i am still working on it now. i don’t think this is the perfect place to ask about it. so i just want to tell you that my fcm send Data is working perfectly now. If there’s any advice regarding the problem that i faced right now i will be more then happy to know it.

Best regards,
Hade

Once again, I suspect it’s your flaky foundations that are causing your building to collapse.

Go back to that textbook again and study again the difference between arrays and pointers.

char* dataText[7] is not an array of strings - it is an array of pointers, isn’t it?

The declaration of the pointers may be global, but what about the data that it points to…?

Sounds very much like your pointers are pointing to stuff that is not valid outside that function…