Fcm data handler

Could some one give me a clue to how the in parameters to the fcm data handler work?

(u16 DataLen, U8 *Data);

How does DataLen(data length i assume) relate to the U8 *Data value? Does it tell me how many 8 bit data values have been recived on the flow?

I’m using UART1 to recive some data values: " 412 514 1024 1024", they are sent like this.

I have seen som examples on the forum were Data is used like an array: Data[pos].
This looks a bit strange to me… since it’s not declared as an array.

Thanks for any help!

Magne

I would suggest that you do some reading about the C basics.

u8* Data

is infact a pointer to a byte buffer, or an array of bytes, depending on how you want to look at it.
It contains exactly DataLen elements, which can be accessed like this:

u8 myByte = Data[index]; // where 0 <= index < DataLen

Best regards,

wismo_coder

In particular, the very close relationship between arrays and pointers in ‘C’…

Thanks, this was very helpful!

Magne

I have one more question regarding this subject, this is also a more general C question…

I want to send the U8 values recived by UART1 as ASCII in a SMS. Is there any easy way to convert the U8 values to ASCII??

I found some code examples that i’ve tried…but they didn’t do the trick.

bool fcmDataHdlr ( u16 DataLen, u8 *data )
				 {
					
					str_iBuftoHex(reply_txt2,data,DataLen);


					s8r=adl_fcmSwitchV24State(fcm_handle,ADL_FCM_V24_STATE_AT);
					adl_fcmUnsubscribe(fcm_handle);
                                 }


/***************************************************************************/
/*  Function   : str_iBuftoHex                                             */
/*-------------------------------------------------------------------------*/
/*  Objet      : Convert a u8* buffer to hexadecimal string                */
/*                                                                         */
/*  Return     : pointer on dst string                                     */
/*                                                                         */
/*-------------------------------------------------------------------------*/
/*  Variable Name     |IN |OUT|GLB|  Utilisation                           */
/*--------------------+---+---+---+----------------------------------------*/
/*  dst               |   | X |   |  destination string                    */
/*--------------------+---+---+---+----------------------------------------*/
/*  src               | x |   |   |  buffer to convert                     */
/*--------------------+---+---+---+----------------------------------------*/
/*  len               | x |   |   |  len of src buffer                     */
/*--------------------+---+---+---+----------------------------------------*/
/***************************************************************************/
ascii * str_iBuftoHex( ascii * dst, u8 * src, u16 len )
{
    u16 i;

    for ( i = 0 ; i < len ; i++ )
    {
        str_itoHex ( dst + ( i * 2 ), src [ i ], 2 );
    }

    dst[ i * 2 ] = 0;

    return dst;
}


/***************************************************************************/
/*  Function   : str_itoHex                                                */
/*-------------------------------------------------------------------------*/
/*  Objet      : Convert u32 to hexadecimal string                         */
/*                                                                         */
/*  Return     : pointer on dst string                                     */
/*                                                                         */
/*-------------------------------------------------------------------------*/
/*  Variable Name     |IN |OUT|GLB|  Utilisation                           */
/*--------------------+---+---+---+----------------------------------------*/
/*  dst               |   | X |   |  destination string                    */
/*--------------------+---+---+---+----------------------------------------*/
/*  Nb                | x |   |   |  u32 to convert                        */
/*--------------------+---+---+---+----------------------------------------*/
/*  Precision         | x |   |   |  field precision                       */
/*--------------------+---+---+---+----------------------------------------*/
/***************************************************************************/
ascii * str_itoHex( ascii * dst, u32 Nb, u8 Precision )
{
    u8  iDigitCtr = 9,
        i = 0;

    if ( Nb )
    {
        while ( ! ( Nb & ( 0xF0000000 >> ( ( 8 - ( --iDigitCtr ) ) * 4 ) ) ) );
    }
    else
    {
        iDigitCtr = 1;
    }

    if ( Precision > iDigitCtr )
    {
        iDigitCtr = Precision > 8 ? 8 : Precision;
    }

    while ( i < iDigitCtr )
    {
        dst [ i ] =   ( ( Nb >> ( ( iDigitCtr - i - 1 ) * 4 ) ) & 0x0000000F )
                  + ( ( ( Nb >> ( ( iDigitCtr - i - 1 ) * 4 ) ) & 0x0000000F ) >= 0x0A ? 'A' - 0x0A : '0' );
        i++;
    }
    dst[ i ] = 0;

    return dst;
}

Thanks for any help!!

Magne

sprintf ?

From my point of view u8 = ascii, what you seem to be looking for ist HEX output. Here you go:

void Bin2Hex(char* input, u32 length, char* output) {
    u32 i = 0;
    ascii tmp[3];
    bzero(tmp, 3);
    bzero(output, length * 2 + 1);

    for (i = 0; i < length; i++) {
        sprintf(tmp, "%02X", input[i]);
        wm_memcpy((char*) & output[i * 2], tmp, 2);
    }
    return;
}

But as far as I know there is also an OpenAT function that does something of the sort…

Best regards,

wismo_coder

Strictly speaking, ASCII is only 7 bits - so it’s a subrange (in Pascal-speak) of u8. 8)

Also, the ASCII codes below 0x20 are control codes.

Therefore, it isn’t generally safe to assume that any arbitrary u8 value is a “printable” character that can be safely sent through any arbitrary channel…

Great thanks, I just found the OPEN AT function for this purpose in wm_stdio.h

/***************************************************************************/
/*  Function   : wm_ibuftohexa                                             */
/*-------------------------------------------------------------------------*/
/*  Objet      : Convert a u8* buffer to hexadecimal string                */
/*                                                                         */
/*  Return     : pointer on dst string                                     */
/*                                                                         */
/*-------------------------------------------------------------------------*/
/*  Variable Name     |IN |OUT|GLB|  Utilisation                           */
/*--------------------+---+---+---+----------------------------------------*/
/*  dst               |   | X |   |  destination string                    */
/*--------------------+---+---+---+----------------------------------------*/
/*  src               | x |   |   |  buffer to convert                     */
/*--------------------+---+---+---+----------------------------------------*/
/*  len               | x |   |   |  len of src buffer                     */
/*--------------------+---+---+---+----------------------------------------*/
/***************************************************************************/
ascii * wm_ibuftohexa ( ascii * dst, u8 * src, u16 len );

Haven’t tested it yet, but it looks promising…

mag_knu

Anybody see a obvious reason for why this don’t work:

static ascii reply_txt2[30];	// Reply SMS text

bool fcmDataHdlr ( u16 DataLen, u8 *data )
				 {

					ascii my_string[DataLen+1];

					wm_ibuftohexa(my_string,data,DataLen);

					wm_strcpy( reply_txt2, my_string);


				 return TRUE;
				 }

reply_txt2 is empty after handler has been run.

Yes - you didn’t pay attention to wismo_coder’s earlier advice:

bool fcmDataHdlr ( u16 DataLen, u8 *data )
{
	ascii my_string[DataLen+1];

You can’t define an array like that!

The length has to be a compile-time constant.

Ok thanks, I changed the handler…it now filled the string reply_txt2= “00000000000000000000000000”(28 zeros). The data I am sending is like this
" 512 512 1023 1023".

static ascii reply_txt2[30];	// Reply SMS text

bool fcmDataHdlr ( u16 DataLen, u8 *data )
				 {

					ascii my_string[30];

					wm_ibuftohexa(my_string,data,DataLen);

					wm_strcpy( reply_txt2, my_string);


				 return TRUE;
				 }

When programming for a device that has only 256KB of RAM you should always try to avoid temporary variables when possible, as well as statically initialized arrays:

ascii* reply_txt2;	// Reply SMS text

bool fcmDataHdlr (u16 DataLen, u8 *data)
{
    reply_txt2 = adl_memGet(DataLen * 2 + 1); // if you want it to be really robust, check that the return value is not equal to NULL
    wm_memset(reply_txt2, 0, DataLen * 2 + 1); // check the syntax here, maybe the last two parameters should be swapped
    wm_ibuftohexa(reply_txt2, data, DataLen);
    return TRUE;
}   // don't forget to free reply_txt2 when you don't need it anymore

Best regards,

wismo_coder

Hi,

I was reading the problems about communication throw UART2.
Can somebody tell me how to initialise uart2 so I can receive messages from it.
I did already try adl_fcmSubscribe but the controlhandler and data handler don’t work.

Maybe some sample code could help.

Thanks,

Tom

Have you enabled the UART wit AT+WMFM :question:

The uart is enabled. at+wmfm? -> 0,2,2,1
I can send at commands to uart2 and the q2686 responds.
But I want to send other data over uart2. On page 102 of the adl user guide they draw a switch (1).
How can I set the switch in the software to the other position?

Regards,

Tom

Read the description that accompanies that diagram!

Hint: look for a mention of “adl_fcmSwitchV24State”…

I did wrote this function in the software.
The cntrlhandler (fcmsubscribe) is retuning ADL_FCM_EVENT_FLOW_OPENNED.
The switch function is returning 0 (so OK). But still uart2 is responding on at commands while software said that the switch is set.
If I send ascii code to that uart (using hyperterminal) DataHandler should be called and that doesn’t happened.

Have you studied the entire FCM section in the ADL User Guide?

In particular, after requesting the switch to data mode, you have to wait for the event that tells you that the switch has completed successfully…

Hi,

I did find the problem. After receiving ADL_FCM_EVENT_FLOW_OPENED I have to call adl_fcmSwitchV24State and not before.
Otherwise the switch won’t work.
Thanks a lot for the help.