Explorar o código

Merge pull request #15 from armink-rtt-pkgs/master

完善 CMUX 1.1.0 版本
xiangxistu %!s(int64=3) %!d(string=hai) anos
pai
achega
f06f5d76ee
Modificáronse 3 ficheiros con 82 adicións e 24 borrados
  1. 12 3
      inc/cmux.h
  2. 10 17
      src/cmux.c
  3. 60 4
      src/gsm/cmux_gsm.c

+ 12 - 3
inc/cmux.h

@@ -17,10 +17,17 @@
 extern "C" {
 #endif
 
-#define CMUX_BUFFER_SIZE   2048
+//#define CMUX_DEBUG
 
-#define CMUX_SW_VERSION           "1.0.0"
-#define CMUX_SW_VERSION_NUM       0x10000
+/* CMUX using long frame mode by default */
+#define CMUX_RECV_READ_MAX 2048
+
+#ifndef CMUX_BUFFER_SIZE
+#define CMUX_BUFFER_SIZE   (CMUX_RECV_READ_MAX * 2)
+#endif
+
+#define CMUX_SW_VERSION           "1.1.0"
+#define CMUX_SW_VERSION_NUM       0x10100
 
 struct cmux_buffer
 {
@@ -97,6 +104,8 @@ rt_err_t cmux_start(struct cmux *object);
 rt_err_t cmux_stop(struct cmux *object);
 rt_err_t cmux_attach(struct cmux *object, int port, const char *alias_name, rt_uint16_t flags, void *user_data);
 rt_err_t cmux_detach(struct cmux *object, const char *alias_name);
+void cmux_at_cmd_cfg(uint8_t mode, uint8_t subset, uint32_t port_speed, uint32_t N1, uint32_t T1, uint32_t N2,
+        uint32_t T2, uint32_t T3, uint32_t k);
 
 /* cmux_utils */
 rt_uint8_t cmux_frame_check(const rt_uint8_t *input, int length);

+ 10 - 17
src/cmux.c

@@ -53,13 +53,7 @@
 /* Tells, how much free space there is in the buffer */
 #define cmux_buffer_free(buff) (((buff)->read_point > (buff)->write_point) ? ((buff)->read_point - (buff)->write_point) : (CMUX_BUFFER_SIZE - ((buff)->write_point - (buff)->read_point)))
 
-#define CMUX_RECV_READ_MAX 32
-
-#ifdef CMUX_DEBUG
-#define CMUX_THREAD_STACK_SIZE 1536
-#else
-#define CMUX_THREAD_STACK_SIZE 1024
-#endif
+#define CMUX_THREAD_STACK_SIZE (CMUX_RECV_READ_MAX + 1536)
 #define CMUX_THREAD_PRIORITY 8
 
 #define CMUX_RECIEVE_RESET 0
@@ -256,11 +250,12 @@ static rt_err_t cmux_frame_push(struct cmux *cmux, int channel, struct cmux_fram
         rt_slist_append(&cmux->vcoms[channel].flist, &frame_new->frame_list);
         rt_hw_interrupt_enable(level);
 
-        LOG_D("new message for channel(%d) is append, Message total: %d.", channel, ++cmux->vcoms[channel].frame_index);
-
 #ifdef CMUX_DEBUG
         LOG_HEX("CMUX_RX", 32, frame->data, frame->data_length);
 #endif
+
+        LOG_D("new message (len:%d) for channel (%d) is append, Message total: %d.", frame_new->frame->data_length, channel, ++cmux->vcoms[channel].frame_index);
+
         return RT_EOK;
     }
     LOG_E("malloc failed, the message for channel(%d) is long than CMUX_MAX_FRAME_LIST_LEN(%d).", channel, CMUX_MAX_FRAME_LIST_LEN);
@@ -296,7 +291,7 @@ static struct cmux_frame *cmux_frame_pop(struct cmux *cmux, int channel)
         rt_slist_remove(frame_list, frame_list_find);
         rt_hw_interrupt_enable(level);
 
-        LOG_D("new message for channel(%d) has been used, Message remain: %d.", channel, --cmux->vcoms[channel].frame_index);
+        LOG_D("A message (len:%d) for channel (%d) has been used, Message remain: %d.", frame_data->data_length, channel, --cmux->vcoms[channel].frame_index);
         rt_free(frame);
     }
 
@@ -395,7 +390,7 @@ static struct cmux_frame *cmux_frame_parse(struct cmux_buffer *buffer)
             LOG_D("len_need: %d, frame_data_len: %d.", length_needed, frame->data_length);
         }
         length_needed += frame->data_length;
-        if (!(cmux_buffer_length(buffer) >= length_needed))
+        if (cmux_buffer_length(buffer) < length_needed)
         {
             cmux_frame_destroy(frame);
             return RT_NULL;
@@ -478,9 +473,7 @@ static void cmux_recv_processdata(struct cmux *cmux, rt_uint8_t *buf, rt_size_t
 
     cmux_buffer_write(cmux->buffer, buf, count);
 
-    frame = cmux_frame_parse(cmux->buffer);
-
-    if (frame != RT_NULL)
+    while ((frame = cmux_frame_parse(cmux->buffer)) != RT_NULL)
     {
         /* distribute different data */
         if ((CMUX_FRAME_IS(CMUX_FRAME_UI, frame) || CMUX_FRAME_IS(CMUX_FRAME_UIH, frame)))
@@ -564,7 +557,7 @@ static rt_size_t cmux_send_data(struct rt_device *dev, int port, rt_uint8_t type
     c = rt_device_write(dev, 0, prefix, prefix_length);
     if (c != prefix_length)
     {
-        LOG_D("Couldn't write the whole prefix to the serial port for the virtual port %d. Wrote only %d  bytes.", port, c);
+        LOG_E("Couldn't write the whole prefix to the serial port for the virtual port %d. Wrote only %d  bytes.", port, c);
         return 0;
     }
     if (length > 0)
@@ -572,14 +565,14 @@ static rt_size_t cmux_send_data(struct rt_device *dev, int port, rt_uint8_t type
         c = rt_device_write(dev, 0, data, length);
         if (length != c)
         {
-            LOG_D("Couldn't write all data to the serial port from the virtual port %d. Wrote only %d bytes.", port, c);
+            LOG_E("Couldn't write all data to the serial port from the virtual port %d. Wrote only %d bytes.", port, c);
             return 0;
         }
     }
     c = rt_device_write(dev, 0, postfix, 2);
     if (c != 2)
     {
-        LOG_D("Couldn't write the whole postfix to the serial port for the virtual port %d. Wrote only %d bytes.", port, c);
+        LOG_E("Couldn't write the whole postfix to the serial port for the virtual port %d. Wrote only %d bytes.", port, c);
         return 0;
     }
 #ifdef CMUX_DEBUG

+ 60 - 4
src/gsm/cmux_gsm.c

@@ -24,18 +24,68 @@
 #endif
 #include <rtdbg.h>
 
+/**
+ * +CMUX=<mode>[,<subset>[,<port_speed>[,<N1>[,<T1>[,<N2>[,<T2>[,<T3>[,<k>]]]]]]]]
+ * port_speed:
+ * 1 9600
+   2 19200
+   3 38400
+   4 57600
+   5 115200
+   6 230400
+   7 460800
+   8 921600
+ *
+ */
 #ifndef CMUX_CMD
 #define CMUX_CMD "AT+CMUX=0,0,5,2048,20,3,30,10,2"
 #endif
 
-struct cmux *gsm = RT_NULL;
+static struct cmux *gsm = RT_NULL;
+static char cmux_cmd[64] = { CMUX_CMD };
 
-static const struct modem_chat_data cmd[] =
+static struct modem_chat_data cmd[] =
 {
     {"AT",              MODEM_CHAT_RESP_OK,              10, 1, RT_FALSE},
-    {CMUX_CMD,          MODEM_CHAT_RESP_OK,               5, 1, RT_FALSE},
+    {cmux_cmd,          MODEM_CHAT_RESP_OK,               5, 1, RT_FALSE},
 };
 
+/**
+ * configuration the AT+CMUX command parameter
+ *
+ * default @see CMUX_CMD
+ *
+ * @param mode 0 Basic option, 1 Advanced option
+ * @param subset 0 UIH frames used only, 1 UI frames used only, 2 I frames used only
+ * @param port_speed serial port speed, like 115200
+ * @param N1 maximum frame size
+ * @param T1 acknowledgement timer in units of ten milliseconds
+ * @param N2 maximum number of re-transmissions
+ * @param T2 response timer for the multiplexer control channel in units of ten milliseconds, T2 must be longer than T1
+ * @param T3 wake up response timer in seconds
+ * @param k window size, for Advanced operation with Error Recovery options
+ */
+void cmux_at_cmd_cfg(uint8_t mode, uint8_t subset, uint32_t port_speed, uint32_t N1, uint32_t T1, uint32_t N2,
+        uint32_t T2, uint32_t T3, uint32_t k)
+{
+    RT_ASSERT(T2 > T1);
+    switch(port_speed)
+    {
+        case 9600: port_speed = 1; break;
+        case 19200: port_speed = 2; break;
+        case 38400: port_speed = 3; break;
+        case 57600: port_speed = 4; break;
+        case 115200: port_speed = 5; break;
+        case 230400: port_speed = 6; break;
+        case 460800: port_speed = 7; break;
+        case 921600: port_speed = 8; break;
+        default: RT_ASSERT("Not support port speed" && 0);
+    }
+
+    rt_snprintf(cmux_cmd, sizeof(cmux_cmd), "AT+CMUX=%d,%d,%d,%d,%d,%d,%d,%d,%d", mode, subset, port_speed, N1, T1, N2, T2,
+            T3, k);
+}
+
 static rt_err_t cmux_at_command(struct rt_device *device)
 {
     /* private control, you can add power control */
@@ -50,7 +100,13 @@ static rt_err_t cmux_gsm_start(struct cmux *obj)
     struct rt_device *device = RT_NULL;
 
     device = obj->dev;
-    result = rt_device_open(device, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_INT_RX);
+    /* using DMA mode first */
+    result = rt_device_open(device, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_DMA_RX);
+    /* result interrupt mode when DMA mode not supported */
+    if (result == -RT_EIO)
+    {
+        result = rt_device_open(device, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_INT_RX);
+    }
     if(result != RT_EOK)
     {
         LOG_E("cmux can't open %s.", device->parent.name);