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
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