Problem in receiving data on UART2

Hello,

I am trying to receive data from a microcontroller. I am having problem. There are some characters like ‘Z’ are inserted into received data. I have attached the code below and I would appreciate if someone could point out what is the mistake I have made. I am using Q24Plus

/***************************************************************************/
/* Section to Handle Data from MCU */
/***************************************************************************/
// Control handler for UART 2
bool FCM_UART2_CtrlHandler(adl_fcmEvent_e Event)
{
	s8 resultat;
	adl_atSendResponse ( ADL_AT_UNS,"FCM_UART2_CtrlHandler\r\n" );

	switch(Event)
	{
		case ADL_FCM_EVENT_FLOW_OPENNED:
			adl_atSendResponse ( ADL_AT_UNS,"ADL_FCM_EVENT_FLOW_OPENNED\r\n");
			resultat = adl_fcmSwitchV24State(FCM_UART2_handle, ADL_FCM_V24_STATE_DATA);
			break;

		case ADL_FCM_EVENT_FLOW_CLOSED:
			adl_atSendResponse ( ADL_AT_UNS,"ADL_FCM_EVENT_FLOW_CLOSED\r\n" );
			break;

		case ADL_FCM_EVENT_V24_DATA_MODE:
			adl_atSendResponse ( ADL_AT_UNS,"ADL_FCM_EVENT_V24_DATA_MODE\r\n");
			uart2Mode = UART_MODE_DATA;
			uart2Status = UART2_READY; // UART2 is now completely initialised
			break;

		case ADL_FCM_EVENT_V24_DATA_MODE_EXT:
			adl_atSendResponse ( ADL_AT_UNS,"ADL_FCM_EVENT_V24_DATA_MODE_EXT\r\n");
			break;

		case ADL_FCM_EVENT_V24_AT_MODE:
			adl_atSendResponse ( ADL_AT_UNS,"ADL_FCM_EVENT_V24_AT_MODE\r\n");
			uart2Mode = UART_MODE_AT;
			break;

		case ADL_FCM_EVENT_V24_AT_MODE_EXT:
			adl_atSendResponse ( ADL_AT_UNS,"ADL_FCM_EVENT_V24_AT_MODE_EXT\r\n");
			break;

		case ADL_FCM_EVENT_RESUME:
			adl_atSendResponse ( ADL_AT_UNS,"ADL_FCM_EVENT_RESUME\r\n");
			b_canSendDataToUart2 = TRUE;
			// sendBufToUart2();
			break;

		case ADL_FCM_EVENT_MEM_RELEASE:
			adl_atSendResponse ( ADL_AT_UNS,"ADL_FCM_EVENT_MEM_RELEASE\r\n");
			break;

		case ADL_FCM_EVENT_V24_DATA_MODE_FROM_CALL:
			adl_atSendResponse ( ADL_AT_UNS,"ADL_FCM_EVENT_V24_DATA_MODE_FROM_CALL\r\n");
			break;

		case ADL_FCM_EVENT_V24_AT_MODE_FROM_CALL:
			adl_atSendResponse ( ADL_AT_UNS,"ADL_FCM_EVENT_V24_AT_MODE_FROM_CALL\r\n");
			break;

		default:
			adl_atSendResponse ( ADL_AT_UNS,"DEFAULT\r\n");
			break;
	}
return(FALSE);
}

// Data handler for UART 2
bool FCM_UART2_DataHandler(u16 DataSize, u8 * Data)
{
	adl_atSendResponse ( ADL_AT_UNS,Data);
	return(TRUE);
}

// Subscribe to the UART2 FCM after a short delay
void tmrHandler_startFcmUart2( u8 ID )
{
	// Subscribe to the FCM for UART2
	FCM_UART2_handle = adl_fcmSubscribe ( ADL_FCM_FLOW_V24_UART2, FCM_UART2_CtrlHandler, FCM_UART2_DataHandler );

	adl_atSendResponse ( ADL_AT_UNS, "adl_fcmSubscribe UART2 return value: ");
	adl_atSendResponse ( ADL_AT_UNS, FCM_UART2_handle );
	adl_atSendResponse ( ADL_AT_UNS, "\r\n");

	if(FCM_UART2_handle < 0)
		adl_atSendResponse ( ADL_AT_UNS,"adl_fcmSubscribe UART2 failed\r\n" );
}

//----------------------------------------------------------------------------------------
// Check that OK is received after setting UART2 default speed
// If OK, wait, then subscribe to the FCM for UART2
//----------------------------------------------------------------------------------------
bool cmd_RspHandler_IPR(adl_atResponse_t * params)
{
	ascii buf[30];

	adl_atSendResponse ( ADL_AT_UNS, "cmd_RspHandler_IPR\r\n");

	wm_strRemoveCRLF(buf, params->StrData, params->StrLength);

	if ((!wm_strcmp(buf, "OK")) && (uart2Status == UART2_CHANGING_SPEED))
	{
		uart2Status = UART2_OPENING_FCM;
		// Must wait before subscribing to the FCM for UART 2,
		// otherwise the UART2 parameters are not set correctly
		// and the UART2 is not synchronised to the incomming data.
		adl_tmrSubscribe ( FALSE, 1, ADL_TMR_TYPE_100MS, tmrHandler_startFcmUart2 );
	}
	return FALSE;
}


//----------------------------------------------------------------------------------------
// Response handler after requesting/modifying UART2 status.
// If UART2 is closed then open it. Once open, then change speed.
// If it is already open, then leave it open and change speed.
//----------------------------------------------------------------------------------------
bool cmd_RspHandler_WMFM(adl_atResponse_t * params)
{
	ascii buf[30];

	wm_strRemoveCRLF(buf, params->StrData, params->StrLength);

	switch(uart2Status)
	{
		case UART2_GETTING_STATUS:
			if(buf[13] == '0') // "+WMFM: 0,2,x,0" ==> Closed
			{
				uart2Status = UART2_CLOSED_WAITING_OK;
			}
			else if(buf[13] == '1') // "+WMFM: 0,2,x,1" ==> Open
			{
				uart2Status = UART2_OPEN_WAITING_OK;
			}
			break;

		case UART2_CLOSED_WAITING_OK:
			if(!wm_strcmp(buf, "OK"))
			{
				uart2Status = UART2_OPENING_WAITING_OK;
				// By default, only UART 1 is open. UART 2 must be explicitly opened
				adl_atCmdCreate( "AT+WMFM=0,1,2", FALSE, ( adl_atRspHandler_t ) cmd_RspHandler_WMFM, "*", NULL );
			}
			break;

		case UART2_OPEN_WAITING_OK:
			if(!wm_strcmp(buf, "OK"))
			{
				uart2Status = UART2_CHANGING_SPEED;
				// Set default speed for UART 2
				adl_atCmdCreate("AT+IPR=4800", ADL_AT_PORT_TYPE( ADL_AT_UART2, FALSE ), (adl_atRspHandler_t) cmd_RspHandler_IPR, "*", NULL);
			}
			break;

		case UART2_OPENING_WAITING_OK:
			if(!wm_strcmp(buf, "OK"))
			{
				uart2Status = UART2_GETTING_STATUS;
				// startUart2(); // get status of UART2 again. Should be open now
			}
			break;
	}

	return FALSE;
}

void startUart2(void)
{
	// Get UART2 status first.
	// If we try to open it when all ready open, then an error is returned.
	// Similarly, if we try to close it when all ready closed, then an error is returned.
	// So check status first and then act accordingly.
	adl_atSendResponse ( ADL_AT_UNS, "startUart2: get status UART2\r\n" );
	uart2Status = UART2_GETTING_STATUS;
	adl_atCmdCreate( "AT+WMFM=0,2,2", FALSE, ( adl_atRspHandler_t ) cmd_RspHandler_WMFM, "*", NULL );
}

Thanks
Green

I don’t think the data handler returns zero-terminated strings (check the doc to be sure). So if the memory at address Data+Datasize happens to contain a non-zero byte (and its content is random in theory), you’ll append random garbage at the end of your adl_sendResponse().

Data is definitely not zero-terminated, since it can hold the byte value 0 as a databyte and not as string-terminator.

Good point :smiley:

Thank you all for the reply.

Would it be enough if I make sure that I just grab the exact datasize using substring

or should I do anything else ?

I think you have a fundamental misunderstanding about strings in ‘C’?

The NUL character marks the end of the string;
The NUL character is, therefore, not possible anywhere within a string.

strncpy will not add the NUL if it wasn’t there to start with, and will stop at any NUL found before the specified size…

The doc doesn’t specifically mention this.

However, as already noted, it has to support NUL bytes in the data, so it can’t be a string;

Also, the fact that separate pointer and size are given is a huge clue that it’s not a string… 8)

Having said that, the ADL User Guide does mis-use the term “string” in some places; eg, viewtopic.php?f=47&t=1682

Thank you all for the help. String termination was the problem indeed.