Hey,
I’m having trouble with the UART interface on the SL6087. Prototype code created from the UART demo code that streams data over UART2 on the Q2687 causes an exception reset on the SL6087 after a few seconds of streaming data. I know that wise folks on the forum suggest using FCM over UART access, but I need CTS flow control to manage data to the walnut sized buffer on a slave device and data transfer rate is an issue.
I’m using an SL6087 with version 7.45 firmware. Data is sent over UART2, in mode, at 115200 baud. Have I missed something? Any ideas?
Thanks,
David
Code in question:
#include <string.h>
#include "adl_global.h"
#include "wm_uart.h"
#include "adl_AppliInit.h"
#include "adl_event.h"
#include "adl_traces.h"
#include "adl_OpenDevice.h"
#include "wm_list.h"
#include "adl_port.h"
#include "adl_str.h"
#include "adl_at.h"
#include "adl_CmdHandler.h"
#include "adl_RspHandler.h"
/***************************************************************************/
/* Local functions */
/***************************************************************************/
/* callbacks declaration */
static void uart_OnError( void* user_data, void* ev_param);
static void uart_OnSigStateChange( void* user_data, psUartCbOssc_t psSigState );
static void uart_OnRxDataAvailable( void* user_data, void* ev_param);
static void uart_OnTxComplete( void* user_data, psUartCbOtxC_t psOnTxParam );
/***************************************************************************/
/* Mandatory variables */
/*-------------------------------------------------------------------------*/
/* wm_apmCustomStackSize */
/*-------------------------------------------------------------------------*/
/***************************************************************************/
const u16 wm_apmCustomStackSize = 1024*3;
/***************************************************************************/
/* Local constants */
/***************************************************************************/
#define RX_EVENT_WAIT_MASK 1 //corresponding to RX DATA AVAILABLE
#define TX_EVENT_WAIT_MASK 2 //corresponding to TX COMPLETE
#define INIT_TX_RX_MASK TX_EVENT_WAIT_MASK
#define DATA_MAX 512
/* callback table */
static const sGCbDesc_t uartCbTab[] =
{
/* user data */ /* callbacks */
{ (void*)UART_CB_ON_TX_COMPLETE, (pGEvtNotif_t)&uart_OnTxComplete },
{ (void*)-1L , NULL },
{ (void*)UART_CB_ON_RX_DATA_AVAILABLE, &uart_OnRxDataAvailable },
{ (void*)UART_CB_ON_SIG_STATE_CHANGE, (pGEvtNotif_t)&uart_OnSigStateChange},
{ (void*)UART_CB_ON_ERROR, &uart_OnError },
{ (void*)-1L, NULL }
};
sUartFlowCtrl_t Fc;
/***************************************************************************/
/* Local variables */
/***************************************************************************/
static sGItfCont_t uart_itf;
static s32 uart_handle;
int dataTextPos = 0;
// data buffer prototype
char dataText[] =
"1B2A606c00000030aaaaaa924aaaaaaaaaaaaaaaaaaaaaaaeb6aaab76f7b5000";
/***************************************************************************/
/* Uart Callbacks */
/***************************************************************************/
void uart_OnTxComplete( void* user_data, psUartCbOtxC_t psOnTxParam )
{
/* reset all : no more data to be send here */
psOnTxParam->buf = NULL;
psOnTxParam->len = 0;
/* set Tx event */
adl_atSendResponse ( ADL_AT_UNS, "TxComplete");
}
void uart_OnRxDataAvailable (void* user_data, void* ev_param)
{
adl_atSendResponse ( ADL_AT_UNS, "RxDataAvailable");
}
void uart_OnSigStateChange (void* user_data, psUartCbOssc_t psSigState)
{
char temptext[100];
memset(temptext, 0x00, sizeof(temptext));
sprintf(temptext, "EVENT : SIG CHANGE delta %x state %x",psSigState->delta,psSigState->state);
adl_atSendResponse ( ADL_AT_UNS, temptext);
}
void uart_OnError (void* user_data, void* ev_param)
{
char temptext[100];
memset(temptext, 0x00, sizeof(temptext));
sprintf(temptext, "EVENT : ERROR %x",(u32)ev_param);
adl_atSendResponse ( ADL_AT_UNS, temptext);
}
void printer_TimerHandler(u8 ID, void * Context )
{
char temptext[100];
u8 tempChars[100];
u32 serialDataLength = 16;
memset(temptext, 0x00, sizeof(temptext));
memset(tempChars, 0x00, sizeof(tempChars));
memcpy(temptext, &dataText[dataTextPos], (serialDataLength * 2));
wm_hexatoibuf (tempChars, temptext );
sprintf(temptext, "\r\nPrinting line: %d\r\n",dataTextPos);
adl_atSendResponse ( ADL_AT_UNS, temptext);
memset(temptext, 0x00, sizeof(temptext));
memcpy(temptext, &dataText[dataTextPos], (serialDataLength * 2));
adl_atSendResponse ( ADL_AT_UNS, temptext);
if ( -1 != uart_itf.write(uart_handle, tempChars, serialDataLength) )
{
dataTextPos =dataTextPos + (serialDataLength * 2);
} else {
adl_atSendResponse ( ADL_AT_UNS, "ERROR write !");
}
if (dataTextPos < 64) adl_tmrSubscribe ( FALSE, 2, ADL_TMR_TYPE_TICK, printer_TimerHandler );
}
void adl_main( adl_InitType_e InitType )
{
sUartSettings_t Settings;
psGItfCont_t pinterface;
sUartEvent_t events;
sUartLc_t lc;
adl_atSendResponse ( ADL_AT_UNS, "Program start\r\n" );
adl_atSendResponsePort(ADL_AT_RSP,ADL_PORT_UART2,"UART 2\r\n");
/* Device */
Settings.capabilities = NULL;
Settings.identity = "UART2";
Settings.role = UART_ROLE_NM;
/* Events */
events.user_data = (void*)0;
events.valid_cb = UART_CB_ON_ALL;
memcpy((u8*)events.cb_list, (u8*)uartCbTab, 6*sizeof(sGCbDesc_t));
Settings.event_handlers = &events;
//Settings.event_handlers = NULL;
/* To retrieve the UART SP Interface */
Settings.interface = &pinterface;
/* Line Coding */
lc.valid_fields = UART_LC_ALL;
lc.rate = (eUartRate_t)(UART_RATE_USER_DEF | 115200 );
lc.stop = UART_STOP_BIT_1;
lc.parity = UART_PARITY_NONE;
lc.data = UART_DATALENGTH_8;
Settings.line_coding = &lc;
/*------------------*/
/* open UART device */
/*------------------*/
uart_handle = adl_OpenDevice( DF_UART_CLID, &Settings);
if(0 < uart_handle)
{
adl_atSendResponse ( ADL_AT_UNS, "UART successfully opened" );
/* Locally store the uart interface */
uart_itf = *pinterface;
/* Flow control IO control setting */
Fc.op = G_IOC_OP_SET;
Fc.type = UART_FC_RTS_CTS;
if( uart_itf.io_control( uart_handle, IOC_UART_FC, (void*) &Fc) )
{
uart_itf.close( uart_handle );
adl_atSendResponse ( ADL_AT_UNS, "ERROR : IOCTL FC Set");
uart_handle = 0;
}
/*
switch( uart_itf.io_control( uart_handle, IOC_UART_EH, (void*) &events) )
{
case CH_STATUS_ERROR:
uart_itf.close( uart_handle );
adl_atSendResponse ( ADL_AT_UNS, "ERROR : CH_STATUS_ERROR");
uart_handle = 0;
break;
case CH_STATUS_NORMAL:
adl_atSendResponse ( ADL_AT_UNS, "Flow control events subscribed");
break;
default:
adl_atSendResponse ( ADL_AT_UNS, "default");
break;
}
*/
}
else
{
adl_atSendResponse ( ADL_AT_UNS, "Uart_Open : ERROR UART is not opened" );
}
adl_tmrSubscribe ( FALSE, 50, ADL_TMR_TYPE_100MS, printer_TimerHandler );
}