Hi!
I have a problem in my project. I use FCM to communicate with external devices. Everything works well. But at the end of the program I can not close the port!!! After switching to AT MODE I get event ADL_FCM_EVENT_V24_AT_MODE. Then I call the function adl_fcmUnsubscribe (rs232_state.handle) and get event ADL_FCM_EVENT_FLOW_CLOSED. Next I close the port using the command “AT + WMFM = 0,0,1” and get error answer: “+ CME ERROR: 3.” Port stoped only when the application is stopped (AT+WOPEN=0). Module SL6087, FW: 7.46. How i can close port??? Help please!
Main:
#include "adl_global.h"
#include "generated.h"
#include "dr_rs232.h"
typedef struct{
bool start;
adl_tmr_t *rs232_poll_handle;
}Poll_str;
Poll_str poll_str;
s8 poll_start(void);
void poll_stop(void);
bool poll_answer_uart1_on(adl_atResponse_t *response);
bool poll_answer_uart2_on(adl_atResponse_t *response);
bool poll_answer_uart1_off(adl_atResponse_t *response);
bool poll_answer_uart2_off(adl_atResponse_t *response);
void rs232_poll_control(Trs232_event event){
switch(event){
case RS232_EVENT_START_OK:{
adl_atSendResponse(ADL_AT_UNS,"\r\nPOLL: EVENT_START_OK");
break;
}
case RS232_EVENT_START_ERR:{
adl_atSendResponse(ADL_AT_UNS,"\r\nPOLL: EVENT_START_ERR");
break;
}
case RS232_EVENT_STOP_OK:{
adl_atSendResponse(ADL_AT_UNS,"\r\nPOLL: EVENT_STOP_OK");
adl_atSendResponse(ADL_AT_UNS,"\r\nPOLL: START OFF UARTS");
adl_atCmdCreate("at+wmfm=0,0,1",ADL_PORT_OPEN_AT_VIRTUAL_BASE,poll_answer_uart1_off,"OK",NULL);
break;
}
case RS232_EVENT_STOP_ERR:{
adl_atSendResponse(ADL_AT_UNS,"\r\nPOLL: EVENT_STOP_ERR");
break;
}
case RS232_EVENT_DATA_TRANSMIT:{
adl_atSendResponse(ADL_AT_UNS,"\r\nPOLL: EVENT_DATA_TRANSMIT");
break;
}
default:{
adl_atSendResponse(ADL_AT_UNS,"\r\nPOLL: EVENT_ERROR!!!");
break;
}
}
}
void rs232_poll_data_come(u8 *buff, u16 length){
ascii buffer[50];
memset(buffer,'\0',sizeof(buffer));
memcpy(buffer,buff,length);
adl_atSendResponse(ADL_AT_UNS,"\r\nPOLL DATA COME: ");
adl_atSendResponse(ADL_AT_UNS,buffer);
if(length==9){
if(strncmp(buffer,"POOL_STOP",9)==0){
adl_atSendResponse(ADL_AT_UNS,"\r\nPOLL: STOP COMMAND COME!!!");
poll_stop();
}
}
else{
rs232_send_data((u8*)buffer,strlen(buffer));
}
}
s8 poll_start(void){
if(poll_str.start) return ERROR;
s32 err=dr_rs232_subscribe(rs232_poll_control,rs232_poll_data_come,ADL_PORT_UART1,19200,RS232_RTS_CTS_OFF,RS232_FORMAT_8D_1S,RS232_PARITY_NONE);
if(err==ERROR){
adl_atSendResponse(ADL_AT_UNS,"\r\nPOLL: dr_rs232_subscribe ERROR!!!");
return ERROR;
}
else{
adl_atSendResponse(ADL_AT_UNS,"\r\nPOLL: dr_rs232_subscribe OK");
poll_str.start=TRUE;
return OK;
}
}
void poll_stop(void){
if(!poll_str.start) return;
dr_rs232_unsubscribe();
poll_str.start=FALSE;
}
void rs232_pool_timer(u8 ID,void *vv){
adl_atSendResponse(ADL_AT_UNS,"\r\nPOLL: TIMER TICK");
}
bool poll_answer_uart1_on(adl_atResponse_t *response){
adl_atSendResponse(ADL_AT_UNS,"\r\nPOLL: UART1 ON");
return FALSE;
}
bool poll_answer_uart2_on(adl_atResponse_t *response){
adl_atSendResponse(ADL_AT_UNS,"\r\nPOLL: UART2 ON");
return FALSE;
}
bool poll_answer_uart1_off(adl_atResponse_t *response){
adl_atSendResponse(ADL_AT_UNS,"\r\nPOLL:UART1 OFF OK");
adl_atCmdCreate("at+wmfm=0,0,2",ADL_PORT_OPEN_AT_VIRTUAL_BASE,poll_answer_uart1_off,"OK",NULL);
return TRUE;
}
bool poll_answer_uart2_off(adl_atResponse_t *response){
adl_atSendResponse(ADL_AT_UNS,"\r\nPOLL:UART2 OFF OK");
return TRUE;
}
void main_task ( void )
{
adl_atCmdCreate("at+wmfm=0,1,1",ADL_PORT_OPEN_AT_VIRTUAL_BASE,poll_answer_uart1_on,"*",NULL);
adl_atCmdCreate("at+wmfm=0,1,2",ADL_PORT_OPEN_AT_VIRTUAL_BASE,poll_answer_uart2_on,"*",NULL);
if(poll_start()==ERROR){
adl_atSendResponse(ADL_AT_UNS,"\r\nPOLL: poll_start ERROR");
}
if(!poll_str.rs232_poll_handle){
poll_str.rs232_poll_handle=adl_tmrSubscribe(TRUE,50,ADL_TMR_TYPE_100MS,rs232_pool_timer);
}
}
rs232_driver:
#include "adl_global.h"
#include "dr_rs232.h"
#include "wm_uart.h"
#define RS232_EVENT_TIME 20
s32 rs232_power_handle=0;
void rs232_event_start(Trs232_event event);
void rs232_event_stop(void);
void rs232_event(u8 ID,void *vv);
adl_tmr_t *rs232_handle_event=NULL;
adl_tmr_t *rs232_handle_packet=NULL;
bool rs232_answer_uart1_ipr(adl_atResponse_t *response);
bool rs232_answer_uart1_ifc(adl_atResponse_t *response);
bool rs232_answer_uart1_icf(adl_atResponse_t *response);
Trs232_ctrl_hdlr rs232_ctrl_hdlr;
Trs232_data_hdlr rs232_data_hdlr;
bool rs232_control_uart1(adl_fcmEvent_e Event);
bool rs232_data_uart1(u16 DataLen, u8 * Data);
typedef struct TRS232_STATE
{
bool start;
u32 rate;
s8 handle;
Trs232_mode mode;
Trs232_format format;
Trs232_parity parity;
Trs232_event event;
}Trs232_state;
Trs232_state rs232_state;
int32_t dr_rs232_subscribe(Trs232_ctrl_hdlr ctrl_handler,Trs232_data_hdlr data_handler,adl_port_e port,u32 rate,Trs232_mode mode,Trs232_format format,Trs232_parity parity)
{
if(rs232_state.start) return ERROR;
adl_ioDefs_t gpio_rs232_power[1]={(ADL_IO_GPIO|RS232_GPIO_POWER|ADL_IO_DIR_OUT)};
rs232_state.start=TRUE;;
if(RS232_DEBUG_FLAG) adl_atSendResponse(ADL_AT_UNS,"\r\nRS232:START");
rs232_power_handle=adl_ioSubscribe(1,gpio_rs232_power,0,0,0);
if(adl_ioWriteSingle ( rs232_power_handle,gpio_rs232_power, TRUE )<0) return ERROR; //on rs232 chip
rs232_state.rate=rate;
rs232_state.mode=mode;
rs232_state.format=format;
rs232_state.parity=parity;
rs232_state.handle=adl_fcmSubscribe(port,rs232_control_uart1,rs232_data_uart1);
if(rs232_state.handle<0) adl_atSendResponse(ADL_AT_UNS,"\r\nUART adl_fcmSubscribe error!");
else adl_atSendResponse(ADL_AT_UNS,"\r\nUART adl_fcmSubscribe OK!");
rs232_ctrl_hdlr=ctrl_handler;
rs232_data_hdlr=data_handler;
if((rs232_power_handle<0)||(rs232_state.handle<0))return ERROR;
return OK;
}
void dr_rs232_unsubscribe(void)
{
if(!rs232_state.start) return;
adl_ioDefs_t gpio_write[1]={(ADL_IO_GPIO|RS232_GPIO_POWER)};
rs232_state.start=FALSE;
if(RS232_DEBUG_FLAG) adl_atSendResponse(ADL_AT_UNS,"\r\nRS232:STOP");
adl_ioWriteSingle ( rs232_power_handle,gpio_write, FALSE );// off rs232 chip
adl_ioUnsubscribe(rs232_power_handle);
adl_fcmSwitchV24State(rs232_state.handle,ADL_FCM_V24_STATE_AT);// switch to at mode
}
bool rs232_control_uart1(adl_fcmEvent_e Event)
{
switch(Event)
{
case ADL_FCM_EVENT_FLOW_OPENNED:{
if(RS232_DEBUG_FLAG) adl_atSendResponse(ADL_AT_UNS,"\r\nRS232:ADL_FCM_EVENT_FLOW_OPENNED");
ascii command_buff[15]="\0";
wm_sprintf(command_buff,"at+ipr=%ld",rs232_state.rate);
adl_atCmdCreate(command_buff,ADL_AT_PORT_TYPE(ADL_PORT_UART1, FALSE),rs232_answer_uart1_ipr,NULL);
if(rs232_state.mode==RS232_RTS_CTS_OFF)adl_atCmdCreate("at+ifc=0,0",ADL_AT_PORT_TYPE(ADL_PORT_UART1, FALSE),rs232_answer_uart1_ifc,NULL);
else adl_atCmdCreate("at+ifc=2,2",ADL_AT_PORT_TYPE(ADL_PORT_UART1, FALSE),rs232_answer_uart1_ifc,NULL);
wm_sprintf(command_buff,"at+icf=%d,%d",rs232_state.format,rs232_state.parity);
adl_atCmdCreate(command_buff,ADL_AT_PORT_TYPE(ADL_PORT_UART1, FALSE),rs232_answer_uart1_icf,NULL);
adl_fcmSwitchV24State(rs232_state.handle,ADL_FCM_V24_STATE_DATA);
break;
}
case ADL_FCM_EVENT_V24_DATA_MODE:{
if(RS232_DEBUG_FLAG) adl_atSendResponse(ADL_AT_UNS,"\r\nRS232:ADL_FCM_EVENT_V24_DATA_MODE");
rs232_event_start(RS232_EVENT_START_OK);
break;
}
case ADL_FCM_EVENT_V24_AT_MODE:{
if(RS232_DEBUG_FLAG) adl_atSendResponse(ADL_AT_UNS,"\r\nRS232:ADL_FCM_EVENT_V24_AT_MODE");
adl_fcmUnsubscribe(rs232_state.handle);
rs232_event_start(RS232_EVENT_STOP_OK);
break;
}
case ADL_FCM_EVENT_V24_AT_MODE_EXT:{
if(RS232_DEBUG_FLAG) adl_atSendResponse(ADL_AT_UNS,"\r\nRS232:ADL_FCM_EVENT_V24_AT_MODE_EXT");
break;
}
case ADL_FCM_EVENT_V24_DATA_MODE_EXT:{
if(RS232_DEBUG_FLAG) adl_atSendResponse(ADL_AT_UNS,"\r\nRS232:ADL_FCM_EVENT_V24_DATA_MODE_EXT");
break;
}
case ADL_FCM_EVENT_FLOW_CLOSED:{
if(RS232_DEBUG_FLAG) adl_atSendResponse(ADL_AT_UNS,"\r\nRS232:ADL_FCM_EVENT_FLOW_CLOSED!!!");
break;
}
case ADL_FCM_EVENT_MEM_RELEASE:{
if(RS232_DEBUG_FLAG) adl_atSendResponse(ADL_AT_UNS,"\r\nRS232:ADL_FCM_EVENT_MEM_RELEASE");
rs232_ctrl_hdlr(RS232_EVENT_DATA_TRANSMIT);
break;
}
default:return TRUE;
}
return TRUE;
}
bool rs232_data_uart1(u16 DataLen, u8 * Data)
{
ascii rs232_temp_buff[50]="\0";
u16 rs232_i;
wm_sprintf(rs232_temp_buff,"\r\nRS232 DATA COME: ");
adl_atSendResponse(ADL_AT_UNS,rs232_temp_buff);
for(rs232_i=0;rs232_i<DataLen;rs232_i++)
{
wm_sprintf(rs232_temp_buff,"%02X ",Data[rs232_i]);
adl_atSendResponse(ADL_AT_UNS,rs232_temp_buff);
}
rs232_data_hdlr(Data,DataLen);
adl_fcmReleaseCredits(rs232_state.handle,0xFF);
return TRUE;
}
int32_t rs232_send_data(u8 *buff, u16 length)
{
ascii rs232_temp_buff[50]="\0";
u16 rs232_i=0;
if(!rs232_state.start)return ERROR;
wm_sprintf(rs232_temp_buff,"\r\nRS232 DATA SEND: ");
adl_atSendResponse(ADL_AT_UNS,rs232_temp_buff);
for(rs232_i=0;rs232_i<length;rs232_i++)
{
wm_sprintf(rs232_temp_buff,"%02X ",buff[rs232_i]);
adl_atSendResponse(ADL_AT_UNS,rs232_temp_buff);
}
return adl_fcmSendData(rs232_state.handle,buff,length);
}
bool rs232_answer_uart1_ipr(adl_atResponse_t *response){
return FALSE;
}
bool rs232_answer_uart1_ifc(adl_atResponse_t *response){
return FALSE;
}
bool rs232_answer_uart1_icf(adl_atResponse_t *response){
return FALSE;
}
void rs232_event_start(Trs232_event event)
{
if(!rs232_handle_event)
{
if(RS232_DEBUG_FLAG) adl_atSendResponse(ADL_AT_UNS,"\r\nRS232:TIMER EVENT START");
rs232_state.event=event;
rs232_handle_event=adl_tmrSubscribe(FALSE,RS232_EVENT_TIME,ADL_TMR_TYPE_TICK,rs232_event);
}
}
void rs232_event_stop(void)
{
if(rs232_handle_event)
{
if(RS232_DEBUG_FLAG) adl_atSendResponse(ADL_AT_UNS,"\r\nRS232:TIMER EVENT STOP");
adl_tmrUnSubscribe(rs232_handle_event,rs232_event,ADL_TMR_TYPE_TICK);
rs232_handle_event=0;
}
}
void rs232_event(u8 ID,void *vv)
{
rs232_handle_event=0;
if(RS232_DEBUG_FLAG) adl_atSendResponse(ADL_AT_UNS,"\r\nRS232:TIMER EVENT OK");
rs232_ctrl_hdlr(rs232_state.event);
}