Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: WS6318 мультиплексорный режим
Форум разработчиков электроники ELECTRONIX.ru > Интерфейсы > Форумы по интерфейсам > Сотовая связь и ее приложения
Eirte
Всем привет,

работаю с модемом WS6318, необходим в использовании мультплексорный режим.
Но при переходе в мультиплексорный режим модем не отвечает на сообщения протокола мультиплексирования.
В даташите указан протокол 3GPP TS 27.010.
Известна ли корректная работа мультплексорного режима данного модема?
sobr
Цитата(Eirte @ Apr 9 2014, 11:30) *
Всем привет, ...
Известна ли корректная работа мультплексорного режима данного модема?

Да.
Цитата
Уважаемые знатоки,
при использовании команды CMUX модем отвечает всего две секунды, после затыкается и далее не реагирует ни на AT команды ни на мультплексорные. Хотя в первые две секунды полностью отвечает и на те и на другие.
использую модем Sierra Wireless WS6318.
В чем может быть проблема?
Дабы не трясти воздух... Вы бы лог обмена с модемом выложили бы.
Eirte
Обмен следующий для basic mode
1)отсылаю AT+CMUX=0,0,5,127
модем отвечает OK
2)отсылаю F9 03 3F 01 1С F9 (тип сообщения SABM)
если отправлено в первые две секунды
получаю
F9 03 73 00 00 A4 F9 (тип сообщения UA, странно что поле Length 00 00 вместо правильного 01 или 00 01)
после этих двух секунд затыкается и не отвечает ни на AT - команды ни на мультиплексорные



две секунды после OK принемает AT команды и мультиплексорные(После подачи мультиплексорной SABM AT-команды не принемаются)

пробовал на разных скоростях не помогло.
пробовал advansed mode результат такойже.
изменения длины пакета тоже не помогло.
кстати ответы некоторых команд тоже не соответствуют даташиту.
sobr
Цитата(Eirte @ Apr 10 2014, 14:46) *
Обмен следующий для basic mode
1)отсылаю AT+CMUX=0,0,5,127
модем отвечает OK
2)отсылаю F9 03 3F 01 1С F9 (тип сообщения SABM)
если отправлено в первые две секунды
получаю
F9 03 73 00 00 A4 F9 (тип сообщения UA, странно что поле Length 00 00 вместо правильного 01 или 00 01)
после этих двух секунд затыкается и не отвечает ни на AT - команды ни на мультиплексорные



две секунды после OK принемает AT команды и мультиплексорные(После подачи мультиплексорной SABM AT-команды не принемаются)

пробовал на разных скоростях не помогло.
пробовал advansed mode результат такойже.
изменения длины пакета тоже не помогло.
кстати ответы некоторых команд тоже не соответствуют даташиту.

У меня:
1. AT+CMUX=0,,,64\r
>OK
2. F9 03 3F 01 1C F9
> Ответ
3. F9 07 3F 01 DE F9
> Ответ
3. F9 0B 3F 01 59 F9
> Ответ
Ну и далее... Все работает.
Eirte
Цитата(sobr @ Apr 11 2014, 03:34) *
У меня:
1. AT+CMUX=0,,,64\r
>OK
2. F9 03 3F 01 1C F9
> Ответ
3. F9 07 3F 01 DE F9
> Ответ
3. F9 0B 3F 01 59 F9
> Ответ
Ну и далее... Все работает.


на модеме WS6318?
sobr
Цитата(Eirte @ Apr 11 2014, 11:00) *
на модеме WS6318?

Да, конечно. Я как бы с первого поста понял о каком модеме речь идет. И врядли стал бы приводить листинг от SL6087...
kan35
Я запускаю CMUX на 38400, после чего передаю управление на драйвер CMUX:
Код
            ATCmdWRPR(5, PHYSICAL_PORT, "AT+CMUX?\r", 500, 2, "OK\r\n", "ERROR\r\n");
            ATCmdWRPR(5, PHYSICAL_PORT, "AT+CMUX=0,0,3,127\r", 200, 2, "OK\r\n", "ERROR\r\n");
            ATCmdWRPR(5, PHYSICAL_PORT, "AT+CMUX?\r", 500, 2, "OK\r\n", "ERROR\r\n");
            vTaskDelay(100);
            if ( CMUX_Start() != 0 )

Далее 1 канал использую под управление lwIP стеком, другой - под sms и звонки, третий для постоянной вычитки данных базовых станциях.
Драйвер работает как на WS6318 так и на Quectel M72

Драйвер CMUX, работает вроде, хотя не все в нем реализовано или реализовано корректно, например перевод в энергосберегающий режим у Quectel не только по DTR линии, но надо давать спец. команду, а WS6318 и без команды и без DTR отлично засыпает.
Код плохочитаем, что называется as is:
CODE

#include <stdio.h>
//#include <system.h>

#include "FreeRtos.h"
#include "task.h"
#include "semphr.h"
#include "queue.h"

#include "structs.h"
#include "driver_modem.h"
#include "driver_uart.h"
#include "driver_cmux.h"
#include "ConfigStorage.h"

extern struct T_TrackerSetup TrackerSetup;
extern void MODEM_DMA_New_data_block_decoded( unsigned char * data, unsigned short len, enum E_SERIAL_PORT port);
extern void putchar_modem(unsigned char litera);
void (*CMUX_NewData)(unsigned char * data, unsigned short len, enum E_SERIAL_PORT) = 0;

extern xQueueHandle queue_tcp_strout;
extern xSemaphoreHandle sema_modemtx;
volatile unsigned char packet_rcvd = 0;
unsigned char cmux = 0;
unsigned char N1 = 31;



enum E_CMUX{
CMUX_STATE_WAITSTART = 0,
CMUX_STATE_WAITADRESS,
CMUX_STATE_WAITCONTROL,
CMUX_STATE_WAITLEN1,
CMUX_STATE_WAITLEN2,
CMUX_STATE_WAITDATA,
CMUX_STATE_WAITFCS,
CMUX_STATE_WAITSTOP
};

#define CONTROL_OCTET_SAMB (0x2F)
#define CONTROL_OCTET_UA (0x63)
#define CONTROL_OCTET_DM (0x0F)
#define CONTROL_OCTET_DISC (0x43)
#define CONTROL_OCTET_UIH (0xEF)
#define CONTROL_OCTET_UI (0x03)

volatile enum E_CMUX cmux_state = CMUX_STATE_WAITSTART;
void CMUX_Decode(unsigned char byte)
{
static volatile enum E_SERIAL_PORT port = PHYSICAL_PORT;
static unsigned short data_len = 0;
static unsigned short data_ptr;
static unsigned char buffer[128];
static volatile unsigned char control;
static volatile unsigned char fcs;

if (!cmux)
{
CMUX_NewData(&byte, 1, PHYSICAL_PORT);
return;
}
switch (cmux_state)
{
case CMUX_STATE_WAITSTART:
if (byte == 0xF9)
cmux_state = CMUX_STATE_WAITADRESS;
else
CMUX_NewData(&byte, 1, PHYSICAL_PORT);
break;
case CMUX_STATE_WAITADRESS:
if (byte != 0xF9)
{
cmux_state = CMUX_STATE_WAITCONTROL;
if ( (byte>>2) == 0)
port = VIRTUAL_PORT_0;
else if ( (byte>>2) == 1)
port = VIRTUAL_PORT_1;
else if ( (byte>>2) == 2)
port = VIRTUAL_PORT_2;
else if ( (byte>>2) == 3)
port = VIRTUAL_PORT_3;
else
cmux_state = CMUX_STATE_WAITSTART;
}
break;
case CMUX_STATE_WAITCONTROL:
control = byte;
cmux_state = CMUX_STATE_WAITLEN1;
if (byte == 0xF9)
cmux_state = CMUX_STATE_WAITCONTROL;
break;
case CMUX_STATE_WAITLEN1:
if (byte&0x01)
{
cmux_state = CMUX_STATE_WAITDATA;
data_len = byte>>1;
if (data_len == 0)
cmux_state = CMUX_STATE_WAITFCS;
}
else
{
cmux_state = CMUX_STATE_WAITLEN2;
data_len = byte;
}
data_ptr = 0;
break;
case CMUX_STATE_WAITLEN2:
data_len |= byte<<8;
data_len >>= 1;
cmux_state = CMUX_STATE_WAITDATA;
if (data_len == 0)
cmux_state = CMUX_STATE_WAITFCS;
break;
case CMUX_STATE_WAITDATA:
if (data_len > sizeof(buffer))
{
if (TrackerSetup.error_inform_en)
xQueueSend(queue_tcp_strout, "#M#Error 1\r\n", 0);
cmux_state = CMUX_STATE_WAITSTART;
}
else
{
buffer[data_ptr] = byte;
if (++data_ptr == data_len)
cmux_state = CMUX_STATE_WAITFCS;
}
break;
case CMUX_STATE_WAITFCS:
cmux_state = CMUX_STATE_WAITSTOP;
fcs = byte;
break;
case CMUX_STATE_WAITSTOP:
if (byte == 0xF9)
{
//&& ((control&0xEF) != CONTROL_OCTET_UA)&& ((control&0xEF) != CONTROL_OCTET_UA) )
if ( data_len )
CMUX_NewData(buffer, data_len, port);
else
packet_rcvd = 1;
}
else
{
CMUX_NewData(&byte, 1, PHYSICAL_PORT);
if (TrackerSetup.error_inform_en)
xQueueSend(queue_tcp_strout, "#M#Error 2\r\n", 0);
}
cmux_state = CMUX_STATE_WAITSTART;
break;

default:
break;
}
}

void CMUX_AssignCallback(void (* callback)(unsigned char *, unsigned short, enum E_SERIAL_PORT))
{
CMUX_NewData = callback;
}

unsigned char CMUX_Init(unsigned char n1)
{
N1 = n1;
CMUX_AssignCallback( MODEM_DMA_New_data_block_decoded );
return 0;
}

const char cmux_a_open_dlci0[] = {0x03, 0x3F, 0x01};
const char cmux_a_close_dlci0[] = {0x03, 0xEF, 0x05, 0xC3, 0x01};

const char cmux_a_open_dlci[][3] ={
{0x07, 0x3F, 0x01},
{0x0B, 0x3F, 0x01},
{0x0F, 0x3F, 0x01}
};

const char cmux_a_setup_msc[][5] = {
{0xE3, 0x07, 0x07, 0x0D, 0x01},
{0xE3, 0x07, 0x0B, 0x0D, 0x01},
{0xE3, 0x07, 0x0F, 0x0D, 0x01}
};

const char cmux_a_close_dlci [][3] = {
{0x07, 0x53, 0x01},
{0x0B, 0x53, 0x01},
{0x0F, 0x53, 0x01}
};

unsigned char CMUX_IsPacketRcvd(void)
{
vTaskDelay(50);
if (packet_rcvd == 1)
{
packet_rcvd = 0;
return 1;
}
else
{
return 0;
}
}

unsigned char CMUX_Start(void)
{
cmux = 1;
if (CMUX_OpenChannel(0))
{
cmux = 0;
return 1;
}
if (CMUX_OpenChannel(1))
return 2;
if (CMUX_OpenChannel(2))
return 3;
if (CMUX_OpenChannel(3))
return 4;
return 0;
}

unsigned char CMUX_Stop(void)
{
if (CMUX_CloseChannel(3))
return 4;
if (CMUX_CloseChannel(2))
return 3;
if (CMUX_CloseChannel(1))
return 2;
if (CMUX_CloseChannel(0))
return 1;
cmux = 0;
return 0;
}

void CMUX_SendControl(char * str, unsigned char len)
{
unsigned char fsc = CalcFCS((unsigned char *)str, len);
putchar_modem( 0xF9);
for (unsigned char i = 0; i < len; i++)
putchar_modem( str[i] );
putchar_modem( fsc);
putchar_modem( 0xF9);
}

unsigned char CMUX_CloseChannel(unsigned char channel)
{
unsigned char counter;
switch(channel)
{
case 0:
counter = 10;
do
CMUX_SendControl( (char *)cmux_a_close_dlci0, sizeof(cmux_a_close_dlci0));
while (!CMUX_IsPacketRcvd() && counter--);
if ( !counter )
{
xSemaphoreGive( sema_modemtx );
return 1;
}
break;
case 1:
case 2:
case 3:
counter = 10;
do
CMUX_SendControl((char *)cmux_a_close_dlci[channel - 1], sizeof(cmux_a_close_dlci[channel - 1]));
while (!CMUX_IsPacketRcvd() && counter--);
if ( !counter )
{
xSemaphoreGive( sema_modemtx );
return channel + 1;
}
break;
}
xSemaphoreGive( sema_modemtx );
return 0;
}

unsigned char CMUX_OpenChannel(unsigned char channel)
{
unsigned char counter;
switch(channel)
{
case 0:
counter = 10;
do
CMUX_SendControl((char *)cmux_a_open_dlci0, sizeof(cmux_a_open_dlci0));
while (!CMUX_IsPacketRcvd() && counter--);
if ( !counter ) return 1;
break;
case 1:
case 2:
case 3:
counter = 10;
do
CMUX_SendControl((char *)cmux_a_open_dlci[channel-1], sizeof(cmux_a_open_dlci[channel-1]));
while (!CMUX_IsPacketRcvd() && counter--);
if ( !counter ) return 1;

counter = 10;
do
CMUX_SendData((char *)cmux_a_setup_msc[channel - 1], sizeof(cmux_a_setup_msc[channel - 1]), VIRTUAL_PORT_0);
while (!CMUX_IsPacketRcvd() && counter--);
if ( !counter ) return 1;
break;
}
return 0;
}

void CMUX_Reset(void)
{
xSemaphoreGive( sema_modemtx );
cmux = 0;
}

unsigned char CMUX_GetStatus(void)
{
return cmux;
}
static const unsigned char crctable[256] = { //reversed, 8-bit, poly=0x07
0x00, 0x91, 0xE3, 0x72, 0x07, 0x96, 0xE4, 0x75, 0x0E, 0x9F, 0xED, 0x7C, 0x09, 0x98, 0xEA, 0x7B,
0x1C, 0x8D, 0xFF, 0x6E, 0x1B, 0x8A, 0xF8, 0x69, 0x12, 0x83, 0xF1, 0x60, 0x15, 0x84, 0xF6, 0x67,
0x38, 0xA9, 0xDB, 0x4A, 0x3F, 0xAE, 0xDC, 0x4D, 0x36, 0xA7, 0xD5, 0x44, 0x31, 0xA0, 0xD2, 0x43,
0x24, 0xB5, 0xC7, 0x56, 0x23, 0xB2, 0xC0, 0x51, 0x2A, 0xBB, 0xC9, 0x58, 0x2D, 0xBC, 0xCE, 0x5F,
0x70, 0xE1, 0x93, 0x02, 0x77, 0xE6, 0x94, 0x05, 0x7E, 0xEF, 0x9D, 0x0C, 0x79, 0xE8, 0x9A, 0x0B,
0x6C, 0xFD, 0x8F, 0x1E, 0x6B, 0xFA, 0x88, 0x19, 0x62, 0xF3, 0x81, 0x10, 0x65, 0xF4, 0x86, 0x17,
0x48, 0xD9, 0xAB, 0x3A, 0x4F, 0xDE, 0xAC, 0x3D, 0x46, 0xD7, 0xA5, 0x34, 0x41, 0xD0, 0xA2, 0x33,
0x54, 0xC5, 0xB7, 0x26, 0x53, 0xC2, 0xB0, 0x21, 0x5A, 0xCB, 0xB9, 0x28, 0x5D, 0xCC, 0xBE, 0x2F,
0xE0, 0x71, 0x03, 0x92, 0xE7, 0x76, 0x04, 0x95, 0xEE, 0x7F, 0x0D, 0x9C, 0xE9, 0x78, 0x0A, 0x9B,
0xFC, 0x6D, 0x1F, 0x8E, 0xFB, 0x6A, 0x18, 0x89, 0xF2, 0x63, 0x11, 0x80, 0xF5, 0x64, 0x16, 0x87,
0xD8, 0x49, 0x3B, 0xAA, 0xDF, 0x4E, 0x3C, 0xAD, 0xD6, 0x47, 0x35, 0xA4, 0xD1, 0x40, 0x32, 0xA3,
0xC4, 0x55, 0x27, 0xB6, 0xC3, 0x52, 0x20, 0xB1, 0xCA, 0x5B, 0x29, 0xB8, 0xCD, 0x5C, 0x2E, 0xBF,
0x90, 0x01, 0x73, 0xE2, 0x97, 0x06, 0x74, 0xE5, 0x9E, 0x0F, 0x7D, 0xEC, 0x99, 0x08, 0x7A, 0xEB,
0x8C, 0x1D, 0x6F, 0xFE, 0x8B, 0x1A, 0x68, 0xF9, 0x82, 0x13, 0x61, 0xF0, 0x85, 0x14, 0x66, 0xF7,
0xA8, 0x39, 0x4B, 0xDA, 0xAF, 0x3E, 0x4C, 0xDD, 0xA6, 0x37, 0x45, 0xD4, 0xA1, 0x30, 0x42, 0xD3,
0xB4, 0x25, 0x57, 0xC6, 0xB3, 0x22, 0x50, 0xC1, 0xBA, 0x2B, 0x59, 0xC8, 0xBD, 0x2C, 0x5E, 0xCF
};

unsigned char CalcFCS( unsigned char *buf, int len)
{
unsigned char FCS=0xFF;
while (len--) FCS=crctable[FCS^*buf++];
return (0xFF-FCS);
}

int CheckFCS( unsigned char *buf, int len)
{
unsigned char FCS=0xFF ;
while (len--)
{
FCS=crctable[FCS^*buf++];
}
// 0xCF is the reversed order of 11110011.
return (FCS==0xCF);
}

void CMUX_SetN1(unsigned char n1)
{
N1 = n1;
}

void CMUX_SendData(char * data, unsigned short len, enum E_SERIAL_PORT virtual_port)
{
xSemaphoreTake( sema_modemtx, portMAX_DELAY );
switch (virtual_port)
{
case PHYSICAL_PORT:
while (len--)
putchar_modem( *data++);
break;
case VIRTUAL_PORT_0:
case VIRTUAL_PORT_1:
case VIRTUAL_PORT_2:
case VIRTUAL_PORT_3:
while (len)
{
unsigned char local_counter = N1;
unsigned char fcalc[3];
putchar_modem( 0xF9);
if (virtual_port == VIRTUAL_PORT_0)
fcalc[0] = 0x01;
if (virtual_port == VIRTUAL_PORT_1)
fcalc[0] = 0x05;
else if (virtual_port == VIRTUAL_PORT_2)
fcalc[0] = 0x09;
else //if (virtual_port == VIRTUAL_PORT_3)
fcalc[0] = 0x0D;
putchar_modem( fcalc[0]);
fcalc[1] = 0xEF;
putchar_modem( fcalc[1]);
// len
if (len>N1)
fcalc[2] = (N1<<1)|0x01;
else
fcalc[2] = (len<<1)|0x01;
putchar_modem( fcalc[2]);
while (local_counter-- && len)
{
putchar_modem( *data++);
len--;
}
putchar_modem( CalcFCS(fcalc, 3));
putchar_modem( 0xF9);
}
break;
}
xSemaphoreGive( sema_modemtx );
}

Надеюсь поможет:-)
kan35
Я запускаю CMUX на 38400, после чего передаю управление на драйвер CMUX:
Код
            ATCmdWRPR(5, PHYSICAL_PORT, "AT+CMUX?\r", 500, 2, "OK\r\n", "ERROR\r\n");
            ATCmdWRPR(5, PHYSICAL_PORT, "AT+CMUX=0,0,3,127\r", 200, 2, "OK\r\n", "ERROR\r\n");
            ATCmdWRPR(5, PHYSICAL_PORT, "AT+CMUX?\r", 500, 2, "OK\r\n", "ERROR\r\n");
            vTaskDelay(100);
            if ( CMUX_Start() != 0 )

Далее 1 канал использую под управление lwIP стеком, другой - под sms и звонки, третий для постоянной вычитки данных базовых станциях.
Драйвер работает как на WS6318 так и на Quectel M72

Драйвер CMUX, работает вроде, хотя не все в нем реализовано или реализовано корректно, например перевод в энергосберегающий режим у Quectel не только по DTR линии, но надо давать спец. команду, а WS6318 и без команды и без DTR отлично засыпает.
Код плохочитаем, что называется as is:
CODE

#include <stdio.h>
//#include <system.h>

#include "FreeRtos.h"
#include "task.h"
#include "semphr.h"
#include "queue.h"

#include "structs.h"
#include "driver_modem.h"
#include "driver_uart.h"
#include "driver_cmux.h"
#include "ConfigStorage.h"

extern struct T_TrackerSetup TrackerSetup;
extern void MODEM_DMA_New_data_block_decoded( unsigned char * data, unsigned short len, enum E_SERIAL_PORT port);
extern void putchar_modem(unsigned char litera);
void (*CMUX_NewData)(unsigned char * data, unsigned short len, enum E_SERIAL_PORT) = 0;

extern xQueueHandle queue_tcp_strout;
extern xSemaphoreHandle sema_modemtx;
volatile unsigned char packet_rcvd = 0;
unsigned char cmux = 0;
unsigned char N1 = 31;



enum E_CMUX{
CMUX_STATE_WAITSTART = 0,
CMUX_STATE_WAITADRESS,
CMUX_STATE_WAITCONTROL,
CMUX_STATE_WAITLEN1,
CMUX_STATE_WAITLEN2,
CMUX_STATE_WAITDATA,
CMUX_STATE_WAITFCS,
CMUX_STATE_WAITSTOP
};

#define CONTROL_OCTET_SAMB (0x2F)
#define CONTROL_OCTET_UA (0x63)
#define CONTROL_OCTET_DM (0x0F)
#define CONTROL_OCTET_DISC (0x43)
#define CONTROL_OCTET_UIH (0xEF)
#define CONTROL_OCTET_UI (0x03)

volatile enum E_CMUX cmux_state = CMUX_STATE_WAITSTART;
void CMUX_Decode(unsigned char byte)
{
static volatile enum E_SERIAL_PORT port = PHYSICAL_PORT;
static unsigned short data_len = 0;
static unsigned short data_ptr;
static unsigned char buffer[128];
static volatile unsigned char control;
static volatile unsigned char fcs;

if (!cmux)
{
CMUX_NewData(&byte, 1, PHYSICAL_PORT);
return;
}
switch (cmux_state)
{
case CMUX_STATE_WAITSTART:
if (byte == 0xF9)
cmux_state = CMUX_STATE_WAITADRESS;
else
CMUX_NewData(&byte, 1, PHYSICAL_PORT);
break;
case CMUX_STATE_WAITADRESS:
if (byte != 0xF9)
{
cmux_state = CMUX_STATE_WAITCONTROL;
if ( (byte>>2) == 0)
port = VIRTUAL_PORT_0;
else if ( (byte>>2) == 1)
port = VIRTUAL_PORT_1;
else if ( (byte>>2) == 2)
port = VIRTUAL_PORT_2;
else if ( (byte>>2) == 3)
port = VIRTUAL_PORT_3;
else
cmux_state = CMUX_STATE_WAITSTART;
}
break;
case CMUX_STATE_WAITCONTROL:
control = byte;
cmux_state = CMUX_STATE_WAITLEN1;
if (byte == 0xF9)
cmux_state = CMUX_STATE_WAITCONTROL;
break;
case CMUX_STATE_WAITLEN1:
if (byte&0x01)
{
cmux_state = CMUX_STATE_WAITDATA;
data_len = byte>>1;
if (data_len == 0)
cmux_state = CMUX_STATE_WAITFCS;
}
else
{
cmux_state = CMUX_STATE_WAITLEN2;
data_len = byte;
}
data_ptr = 0;
break;
case CMUX_STATE_WAITLEN2:
data_len |= byte<<8;
data_len >>= 1;
cmux_state = CMUX_STATE_WAITDATA;
if (data_len == 0)
cmux_state = CMUX_STATE_WAITFCS;
break;
case CMUX_STATE_WAITDATA:
if (data_len > sizeof(buffer))
{
if (TrackerSetup.error_inform_en)
xQueueSend(queue_tcp_strout, "#M#Error 1\r\n", 0);
cmux_state = CMUX_STATE_WAITSTART;
}
else
{
buffer[data_ptr] = byte;
if (++data_ptr == data_len)
cmux_state = CMUX_STATE_WAITFCS;
}
break;
case CMUX_STATE_WAITFCS:
cmux_state = CMUX_STATE_WAITSTOP;
fcs = byte;
break;
case CMUX_STATE_WAITSTOP:
if (byte == 0xF9)
{
//&& ((control&0xEF) != CONTROL_OCTET_UA)&& ((control&0xEF) != CONTROL_OCTET_UA) )
if ( data_len )
CMUX_NewData(buffer, data_len, port);
else
packet_rcvd = 1;
}
else
{
CMUX_NewData(&byte, 1, PHYSICAL_PORT);
if (TrackerSetup.error_inform_en)
xQueueSend(queue_tcp_strout, "#M#Error 2\r\n", 0);
}
cmux_state = CMUX_STATE_WAITSTART;
break;

default:
break;
}
}

void CMUX_AssignCallback(void (* callback)(unsigned char *, unsigned short, enum E_SERIAL_PORT))
{
CMUX_NewData = callback;
}

unsigned char CMUX_Init(unsigned char n1)
{
N1 = n1;
CMUX_AssignCallback( MODEM_DMA_New_data_block_decoded );
return 0;
}

const char cmux_a_open_dlci0[] = {0x03, 0x3F, 0x01};
const char cmux_a_close_dlci0[] = {0x03, 0xEF, 0x05, 0xC3, 0x01};

const char cmux_a_open_dlci[][3] ={
{0x07, 0x3F, 0x01},
{0x0B, 0x3F, 0x01},
{0x0F, 0x3F, 0x01}
};

const char cmux_a_setup_msc[][5] = {
{0xE3, 0x07, 0x07, 0x0D, 0x01},
{0xE3, 0x07, 0x0B, 0x0D, 0x01},
{0xE3, 0x07, 0x0F, 0x0D, 0x01}
};

const char cmux_a_close_dlci [][3] = {
{0x07, 0x53, 0x01},
{0x0B, 0x53, 0x01},
{0x0F, 0x53, 0x01}
};

unsigned char CMUX_IsPacketRcvd(void)
{
vTaskDelay(50);
if (packet_rcvd == 1)
{
packet_rcvd = 0;
return 1;
}
else
{
return 0;
}
}

unsigned char CMUX_Start(void)
{
cmux = 1;
if (CMUX_OpenChannel(0))
{
cmux = 0;
return 1;
}
if (CMUX_OpenChannel(1))
return 2;
if (CMUX_OpenChannel(2))
return 3;
if (CMUX_OpenChannel(3))
return 4;
return 0;
}

unsigned char CMUX_Stop(void)
{
if (CMUX_CloseChannel(3))
return 4;
if (CMUX_CloseChannel(2))
return 3;
if (CMUX_CloseChannel(1))
return 2;
if (CMUX_CloseChannel(0))
return 1;
cmux = 0;
return 0;
}

void CMUX_SendControl(char * str, unsigned char len)
{
unsigned char fsc = CalcFCS((unsigned char *)str, len);
putchar_modem( 0xF9);
for (unsigned char i = 0; i < len; i++)
putchar_modem( str[i] );
putchar_modem( fsc);
putchar_modem( 0xF9);
}

unsigned char CMUX_CloseChannel(unsigned char channel)
{
unsigned char counter;
switch(channel)
{
case 0:
counter = 10;
do
CMUX_SendControl( (char *)cmux_a_close_dlci0, sizeof(cmux_a_close_dlci0));
while (!CMUX_IsPacketRcvd() && counter--);
if ( !counter )
{
xSemaphoreGive( sema_modemtx );
return 1;
}
break;
case 1:
case 2:
case 3:
counter = 10;
do
CMUX_SendControl((char *)cmux_a_close_dlci[channel - 1], sizeof(cmux_a_close_dlci[channel - 1]));
while (!CMUX_IsPacketRcvd() && counter--);
if ( !counter )
{
xSemaphoreGive( sema_modemtx );
return channel + 1;
}
break;
}
xSemaphoreGive( sema_modemtx );
return 0;
}

unsigned char CMUX_OpenChannel(unsigned char channel)
{
unsigned char counter;
switch(channel)
{
case 0:
counter = 10;
do
CMUX_SendControl((char *)cmux_a_open_dlci0, sizeof(cmux_a_open_dlci0));
while (!CMUX_IsPacketRcvd() && counter--);
if ( !counter ) return 1;
break;
case 1:
case 2:
case 3:
counter = 10;
do
CMUX_SendControl((char *)cmux_a_open_dlci[channel-1], sizeof(cmux_a_open_dlci[channel-1]));
while (!CMUX_IsPacketRcvd() && counter--);
if ( !counter ) return 1;

counter = 10;
do
CMUX_SendData((char *)cmux_a_setup_msc[channel - 1], sizeof(cmux_a_setup_msc[channel - 1]), VIRTUAL_PORT_0);
while (!CMUX_IsPacketRcvd() && counter--);
if ( !counter ) return 1;
break;
}
return 0;
}

void CMUX_Reset(void)
{
xSemaphoreGive( sema_modemtx );
cmux = 0;
}

unsigned char CMUX_GetStatus(void)
{
return cmux;
}
static const unsigned char crctable[256] = { //reversed, 8-bit, poly=0x07
0x00, 0x91, 0xE3, 0x72, 0x07, 0x96, 0xE4, 0x75, 0x0E, 0x9F, 0xED, 0x7C, 0x09, 0x98, 0xEA, 0x7B,
0x1C, 0x8D, 0xFF, 0x6E, 0x1B, 0x8A, 0xF8, 0x69, 0x12, 0x83, 0xF1, 0x60, 0x15, 0x84, 0xF6, 0x67,
0x38, 0xA9, 0xDB, 0x4A, 0x3F, 0xAE, 0xDC, 0x4D, 0x36, 0xA7, 0xD5, 0x44, 0x31, 0xA0, 0xD2, 0x43,
0x24, 0xB5, 0xC7, 0x56, 0x23, 0xB2, 0xC0, 0x51, 0x2A, 0xBB, 0xC9, 0x58, 0x2D, 0xBC, 0xCE, 0x5F,
0x70, 0xE1, 0x93, 0x02, 0x77, 0xE6, 0x94, 0x05, 0x7E, 0xEF, 0x9D, 0x0C, 0x79, 0xE8, 0x9A, 0x0B,
0x6C, 0xFD, 0x8F, 0x1E, 0x6B, 0xFA, 0x88, 0x19, 0x62, 0xF3, 0x81, 0x10, 0x65, 0xF4, 0x86, 0x17,
0x48, 0xD9, 0xAB, 0x3A, 0x4F, 0xDE, 0xAC, 0x3D, 0x46, 0xD7, 0xA5, 0x34, 0x41, 0xD0, 0xA2, 0x33,
0x54, 0xC5, 0xB7, 0x26, 0x53, 0xC2, 0xB0, 0x21, 0x5A, 0xCB, 0xB9, 0x28, 0x5D, 0xCC, 0xBE, 0x2F,
0xE0, 0x71, 0x03, 0x92, 0xE7, 0x76, 0x04, 0x95, 0xEE, 0x7F, 0x0D, 0x9C, 0xE9, 0x78, 0x0A, 0x9B,
0xFC, 0x6D, 0x1F, 0x8E, 0xFB, 0x6A, 0x18, 0x89, 0xF2, 0x63, 0x11, 0x80, 0xF5, 0x64, 0x16, 0x87,
0xD8, 0x49, 0x3B, 0xAA, 0xDF, 0x4E, 0x3C, 0xAD, 0xD6, 0x47, 0x35, 0xA4, 0xD1, 0x40, 0x32, 0xA3,
0xC4, 0x55, 0x27, 0xB6, 0xC3, 0x52, 0x20, 0xB1, 0xCA, 0x5B, 0x29, 0xB8, 0xCD, 0x5C, 0x2E, 0xBF,
0x90, 0x01, 0x73, 0xE2, 0x97, 0x06, 0x74, 0xE5, 0x9E, 0x0F, 0x7D, 0xEC, 0x99, 0x08, 0x7A, 0xEB,
0x8C, 0x1D, 0x6F, 0xFE, 0x8B, 0x1A, 0x68, 0xF9, 0x82, 0x13, 0x61, 0xF0, 0x85, 0x14, 0x66, 0xF7,
0xA8, 0x39, 0x4B, 0xDA, 0xAF, 0x3E, 0x4C, 0xDD, 0xA6, 0x37, 0x45, 0xD4, 0xA1, 0x30, 0x42, 0xD3,
0xB4, 0x25, 0x57, 0xC6, 0xB3, 0x22, 0x50, 0xC1, 0xBA, 0x2B, 0x59, 0xC8, 0xBD, 0x2C, 0x5E, 0xCF
};

unsigned char CalcFCS( unsigned char *buf, int len)
{
unsigned char FCS=0xFF;
while (len--) FCS=crctable[FCS^*buf++];
return (0xFF-FCS);
}

int CheckFCS( unsigned char *buf, int len)
{
unsigned char FCS=0xFF ;
while (len--)
{
FCS=crctable[FCS^*buf++];
}
// 0xCF is the reversed order of 11110011.
return (FCS==0xCF);
}

void CMUX_SetN1(unsigned char n1)
{
N1 = n1;
}

void CMUX_SendData(char * data, unsigned short len, enum E_SERIAL_PORT virtual_port)
{
xSemaphoreTake( sema_modemtx, portMAX_DELAY );
switch (virtual_port)
{
case PHYSICAL_PORT:
while (len--)
putchar_modem( *data++);
break;
case VIRTUAL_PORT_0:
case VIRTUAL_PORT_1:
case VIRTUAL_PORT_2:
case VIRTUAL_PORT_3:
while (len)
{
unsigned char local_counter = N1;
unsigned char fcalc[3];
putchar_modem( 0xF9);
if (virtual_port == VIRTUAL_PORT_0)
fcalc[0] = 0x01;
if (virtual_port == VIRTUAL_PORT_1)
fcalc[0] = 0x05;
else if (virtual_port == VIRTUAL_PORT_2)
fcalc[0] = 0x09;
else //if (virtual_port == VIRTUAL_PORT_3)
fcalc[0] = 0x0D;
putchar_modem( fcalc[0]);
fcalc[1] = 0xEF;
putchar_modem( fcalc[1]);
// len
if (len>N1)
fcalc[2] = (N1<<1)|0x01;
else
fcalc[2] = (len<<1)|0x01;
putchar_modem( fcalc[2]);
while (local_counter-- && len)
{
putchar_modem( *data++);
len--;
}
putchar_modem( CalcFCS(fcalc, 3));
putchar_modem( 0xF9);
}
break;
}
xSemaphoreGive( sema_modemtx );
}

Надеюсь поможет:-)
Eirte
Цитата(sobr @ Apr 11 2014, 03:34) *
У меня:
1. AT+CMUX=0,,,64\r
>OK
2. F9 03 3F 01 1C F9
> Ответ
3. F9 07 3F 01 DE F9
> Ответ
3. F9 0B 3F 01 59 F9
> Ответ
Ну и далее... Все работает.


Какие еще AT-команды подаете?
Eirte
Попробовал еще один модем, картина таже, через 2 секунды перестает отвечать
Eirte
Попробовал еще модемы, заработало
Eirte
Как в мультиплексорном режиме послать AT-команду?
Eirte
Подскажите пожалуста, как происходит разбиение на сообщения согласно параметру N1? Происходит ли разбиение для ответов на AT-команды или данный параметр определяет разбиение только для данных?
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.