SL6087 - Interfacing a Sensor via UART2 using OpenUART


#1

Hi Everybody

I want to use UART 2 of the SL6087 to interface a Sensor with RS485 Interface.

i 've allready connected the Sensor sucessfully via a LTC1487 to UART2. I m also able to send “some” data (code based on ADL User Guide example), problem is the sensor doesnt answer.

In order to wake the Sensor up i have to generate a break signal.
Serial Specs of the sensor:
38400 baud, 1 start bit, 2 stop bits, no parity.

Dataframe is defined as: Break, Command, AdressH, AdressM, AdressL, Data, Checksum. Checksum is the bitwise negation of the sum of all bytes exept Break, only lower 8 bits are used. The Break is defined as a continuous low of 22 bit periods (more lowbits are allowed) and 2 high bit periods.

by reading the forum i noticed a post which described a method to generate breaks by manipulating the UART settings. the idea: UART2 sucessfully opened -> change settings to 19200baud, 1 Stopbit, Dataframe 16bit -> close and reopen UART2 via adl_opendevice() to initiate new settings -> write “0” (16 bits * half transmit speed equals 32 bit periods “low”, 1 stopbit high at half transmit speed equals the required 2 high bits) -> reopen UART2 with serial specs of sensor -> send rest of the dataframe.

My Questions:

  • is there a more effective way of changing the uart settings without close / reopen?
  • can i ensure that closing /reopening the uart will be done immediatly, without stretching the timing of the dataframe?
  • is my way of casting the dataframe-array correct?
  • eUartData contains two interesting definitions named UART_DATALENGTH_AUTOFRAME and UART_DATALENGTH_LAST. Can anyone explain to me what exactly they do (may be interesting for generating brake)?
  • Are there any more documents which describe “all” open AT functions, Datatypes and structs in detail?

Many thanks in advance,

D.K

PS: I not very experienced in programming c and absolutely new to event based programming, so please forgive me those errors that are trivial to you :wink:

PSS: Yes i WANT to use Open UART, not flowcontrol.

#include "adl_global.h"
#include "adl_ctx.h"
#include "adl_OpenDevice.h"
#include "wm_uart.h"
#include "generated.h"

s32 GpioHandle;				// GPIO Handler

static psGItfCont_t uart_if;
static u32 uart_hdl;			// UART Handler
s32 result;						// Returncode, wird nicht benötigt
sUartFlowCtrl_t Fc;
sUartSsIoc_t ioCtrl;
sUartSettings_t settings;
sUartLc_t line_coding;


// Funktionsprototypen
// -------------------
void UART2_ChangeSetting( bool state);
void UART2_Subscribe(void);
void UART2_UnSubscribe(void);
void SRF_GenBrake(void);
void SRF_SendByte(u16 iByte[1]);
void SRF_SendFrame(u8 SRF_command, u8 SRF_adressH, u8 SRF_adressM, u8 SRF_adressL, u8 SRF_data);



void SRF_SendByte(u16 iByte[1])
{
	void *pByte;
	pByte = iByte;
	uart_if->write(uart_hdl, &pByte, 1);
}

void SRF_GenBrake(void)
{
	UART2_ChangeSetting(TRUE);
	SRF_SendByte (0x00); // Brake, Stopbit vervollständigt die Sequenz
	UART2_ChangeSetting(FALSE);
}


void UART2_Subscribe(void)
{
	// SUB UART2
	//TRACE ((11, "Sub Uart2"));
	uart_hdl = adl_OpenDevice(DF_UART_CLID, &settings);
	TRACE(( 1, "uarthdl: (%d)", uart_hdl));
}

void UART2_UnSubscribe(void)
{
	// UNSUB UART2
	if (uart_hdl)
	{
		result = uart_if->close(uart_hdl);
		uart_hdl=0;
	}
	else
	{
		// Kein Handle offen!
	}
}
// TRUE = Brake, FALSE = Data
void UART2_ChangeSetting (bool state)
{

	if (state == TRUE)
	{
		line_coding.rate = (UART_RATE_19200);
		line_coding.stop = UART_STOP_BIT_1;
		line_coding.data = UART_DATALENGTH_16;
	}
	else
	{
		line_coding.rate = (UART_RATE_38400);
		line_coding.stop = UART_STOP_BIT_2;
		line_coding.data = UART_DATALENGTH_8;
	}
	settings.line_coding = &line_coding;
	UART2_UnSubscribe();
	UART2_Subscribe();

}




void SRF_SendFrame(u8 SRF_command, u8 SRF_adressH, u8 SRF_adressM, u8 SRF_adressL, u8 SRF_data)
{
	//TRACE((2, "Sende Frame..."));
	//UART2_SetFlow(TRUE);		// Setze RTS

	// Berechne Checksumme, Bereite Sequenz vor
	u8 SRF_checksum=0x0C;
	u8 iFrame[]={ SRF_command, SRF_adressH, SRF_adressM, SRF_adressL, SRF_data, SRF_checksum, 0x00}; //, 0x00};
	void *pFrame;
	pFrame =iFrame;
	SRF_GenBrake();							// Sende Break
	uart_if->write(uart_hdl, &pFrame, 6);	// Sende eigendliche Sequenz



	// TODO - Dummy Iframe[7], falls letztes Byte durch RTS abgeschnibbelt wird ???
	// uart_if->write(uart_hdl, 0x00, 1);
	//UART2_SetFlow(FALSE);		// Lösche RTS
	// TRACE((2, "Done! Erwarte Antwort..."));
}




// TimerHandle, soll Sensor mit Testframe ansprechen
void Test_SRF_TimerHandler (u8 id, void* Context)
{
	SRF_SendFrame ( 0x51, 0x00, 0x00, 0x00, 0x00);
}

void main_task ( void )
{

	// UART Konfiguration
	// Set line coding parameters
	line_coding.valid_fields = UART_LC_ALL;
	line_coding.rate = (eUartRate_t)(UART_RATE_USER_DEF | 38400);
	line_coding.stop = UART_STOP_BIT_2;
	line_coding.data = UART_DATALENGTH_8;
	line_coding.parity = UART_PARITY_NONE;

	// UART2 will be opened in NULL MODEM role / with synchronous read/write
	settings.identity = "UART2";
	settings.role = UART_ROLE_NM;
	settings.capabilities = 0;
	settings.interface = &uart_if;
	settings.line_coding = &line_coding;

	TRACE((1, "---------------"));
	TRACE((1, "Enter main task"));
	TRACE((1, "---------------"));
	UART2_Subscribe();
    /* Flow control IO control setting */
	Fc.op   = G_IOC_OP_SET;
	Fc.type = UART_FC_NONE;//UART_FC_RTS_CTS;
	// Aktiviere manual Flow Control
	//uart_if->io_control( uart_hdl, IOC_UART_FC, (void*) &Fc);


	// Subscribe Timer, zyklisch, 0,5 Sekunden,
	adl_tmrSubscribe ( TRUE, 5, ADL_TMR_TYPE_100MS, Test_SRF_TimerHandler );
}

EDIT: two more questions added, code optimized


#2

Hi,

On thing…

For generating break signal on UART using open UART :following code should be used :

signal.op = G_IOC_OP_SET;
signal.sig_id = UART_SIG_BREAK;
signal.state = UART_SIG_BREAK;

if(uart_itf.io_control(UartHandle,IOC_UART_SS, (void *)&signal) )

                                            {
                                                            TRACE ( ( 1, "An error occurred in sending break") 

                                            }

                            else
                            {
                                            TRACE ( ( 1, "Break signal sent" ) );

                            }

sig_id allows the application to specify the identities of the signal to be set or retrieved.
State allows the application to specify / retrieve the state of the signals identified in the sig_id field.

UART_SIG_BREAK in the enumeration list eUartSs_t allows the user to set a “break condition” on the TX line.

After UART is successfully opened using adl_OpenDevice API, io_control allows to set configuration, or to get configuration information from the UART service provider.

Please refer to ADl user guide for more details.

Thanks.


#3

Meanwhile i contacted the support of my distributor which answered several questions which i decided to share with you.

  • is there a more effective way of changing the uart settings without close / reopen?
    –> not if you want to change the framelength, too. without changing the framelength, it should be possible via “uart_if->io_control( uart_hdl, IOC_UART_LC, &line_coding))”

  • can i ensure that closing /reopening the uart will be done immediatly, without stretching the timing of the dataframe?
    –> definitively not possible.

  • is my way of casting the dataframe-array correct?
    –> it works, even without the cast. see following code:

u8 iFrame[]={ SRF_command, SRF_adressH, SRF_adressM, SRF_adressL, SRF_data, SRF_checksum, 0x00};
//  void *pFrame;      <-- not necessary
//  pFrame =iFrame; <-- not necessary
uart_if->write(uart_hdl, &iFrame, 6);

regarding eUartData i did not get an answer.

  • Are there any more documents which describe “all” open AT functions, Datatypes and structs in detail?
    Well - No. I found the latest version of the ADL User Guide at "com.wavecom.openat.ide.spm.lib.os.model. “version and some numbers”\resources\doc, however the contained .pdf was compiled in 06.2012 and still contains errors like for example the faulty OpenUART openDevice sample.

Regarding my problem: i decided to stop looking into my crystal ball trying to guess how to "ab"use the uart implementation in order to generate a “proper timed” breaksignal and used a cheap microcontroller which translates the naked frame (including break) and sends the modified sequence via softuart.

Overall i am dissapointed about the current status of ADL Framework - especially the way the “universal” asynchron Receiver Transmitter is implemented and documented. important details like how to “reset” single signal states (break) are missing. also faulty programming samples are a No-Go in my humble oppinion. please take this as an advice how to improve your product, not as a rant.

Regards
D.K