Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of d7a_1x by
Diff: src/d7a_com.cpp
- Revision:
- 77:8c792719a1fc
- Parent:
- 76:fda2e34ff19d
- Child:
- 78:f1c0affd99e7
--- a/src/d7a_com.cpp Tue Dec 20 09:30:14 2016 +0000
+++ b/src/d7a_com.cpp Wed Dec 21 10:47:29 2016 +0000
@@ -10,8 +10,6 @@
#include "d7a_sys.h"
#include "cbuffer.h"
-#define LocalCBuffer CBuffer<uint8_t, 1024>
-
#define XON_SIGNAL (0x0001 << 0)
#define START_SIGNAL (0x0001 << 1)
@@ -20,6 +18,26 @@
uint8_t buf[1];
} d7a_com_tx_buf_t;
+static bool g_com_rx_started;
+static bool g_com_tx_started;
+static uint8_t g_com_state;
+static DigitalOut* g_com_rts;
+static InterruptIn* g_com_cts;
+static CBuffer<uint8_t, 512> g_com_rx_buf;
+static d7a_com_rx_msg_t g_com_msg;
+static uint16_t g_com_skipped_bytes;
+static uint8_t g_com_tx_seq;
+static uint8_t g_com_rx_seq;
+static uint32_t g_com_timeout;
+static Semaphore g_com_data_parsing(0);
+static Semaphore g_com_cts_int(0);
+static RawSerial* g_com_serial;
+static Thread g_com_rx_thread(osPriorityRealtime, DEFAULT_STACK_SIZE, NULL);
+static Thread g_com_tx_thread(osPriorityHigh, DEFAULT_STACK_SIZE, NULL);
+static Queue<d7a_com_tx_buf_t, 8> g_com_tx_queue;
+static Timer g_com_tim;
+
+
enum {
SEARCH_HEADER,
PARSE_HEADER,
@@ -27,48 +45,6 @@
PARSE_BODY,
};
-typedef struct {
- bool rx_started;
- bool tx_started;
-
- uint8_t state;
-
- DigitalOut* rts;
- InterruptIn* cts;
-
- LocalCBuffer* rx_buf;
-
- // min data in buffer before parsing body
- d7a_com_rx_msg_t msg;
- // Number of skipped bytes while parsing
- uint16_t skipped_bytes;
-
- // Port TX sequence number
- uint8_t tx_seq;
- // Port RX sequence number
- uint8_t rx_seq;
- // Response to command maximum time
- uint32_t timeout;
-
- // Waiting for data available in RX buffer
- Semaphore* data_parsing;
- // CTS management
- Semaphore* cts_int;
-
- // Data treatment threads
- Thread* rx_thread;
- RawSerial* serial;
-
- // Tx Thread
- Thread* tx_thread;
- Queue<d7a_com_tx_buf_t, 32> tx_queue;
-
- Timer tim;
-
-} d7a_com_ctx_t;
-
-
-static d7a_com_ctx_t g_com_ctx;
/**
Thread for parsing packets from RX buffer.
@@ -91,24 +67,24 @@
{
// Loop just in case more than one character is in UART's receive FIFO buffer
// Stop if buffer full
- while (g_com_ctx.serial->readable())
+ while (g_com_serial->readable())
{
- g_com_ctx.rx_buf->push(g_com_ctx.serial->getc());
+ g_com_rx_buf.push(g_com_serial->getc());
//PRINT("-");
- //if (g_com_ctx.rx_started)
+ //if (g_com_rx_started)
{
// unlock data parsing thread
- if (g_com_ctx.state == SEARCH_HEADER && g_com_ctx.rx_buf->available_data() >= KAL_COM_HEADER_LEN)
+ if (g_com_state == SEARCH_HEADER && g_com_rx_buf.available_data() >= KAL_COM_HEADER_LEN)
{
- g_com_ctx.state = PARSE_HEADER;
- g_com_ctx.data_parsing->release();
+ g_com_state = PARSE_HEADER;
+ g_com_data_parsing.release();
}
- else if (g_com_ctx.state == SEARCH_BODY && g_com_ctx.rx_buf->available_data() >= g_com_ctx.msg.blen)
+ else if (g_com_state == SEARCH_BODY && g_com_rx_buf.available_data() >= g_com_msg.blen)
{
- g_com_ctx.state = PARSE_BODY;
- g_com_ctx.data_parsing->release();
+ g_com_state = PARSE_BODY;
+ g_com_data_parsing.release();
}
}
}
@@ -124,7 +100,7 @@
void cts_isr()
{
//PRINT("CTS_INT\r\n");
- //g_com_ctx.cts_int->release();
+ //g_com_cts_int->release();
}
// D7a_com constructor.
@@ -138,32 +114,24 @@
{
FPRINT("\r\n");
- g_com_ctx.state = SEARCH_HEADER;
- g_com_ctx.skipped_bytes = 0;
- g_com_ctx.tx_seq = 0;
- g_com_ctx.rx_seq = 0;
-
- g_com_ctx.serial = new RawSerial(config->tx, config->rx);
- g_com_ctx.rts = new DigitalOut(config->rts);
- g_com_ctx.cts = new InterruptIn(config->cts);
- g_com_ctx.data_parsing = new Semaphore(0);
- g_com_ctx.cts_int = new Semaphore(0);
+ g_com_state = SEARCH_HEADER;
+ g_com_skipped_bytes = 0;
+ g_com_tx_seq = 0;
+ g_com_rx_seq = 0;
- g_com_ctx.cts->rise(&cts_isr);
+ g_com_serial = new RawSerial(config->tx, config->rx, 115200);
+ g_com_rts = new DigitalOut(config->rts);
+ g_com_cts = new InterruptIn(config->cts);
- g_com_ctx.rx_buf = new LocalCBuffer;
-
- g_com_ctx.serial->baud(115200);
- g_com_ctx.serial->format(8, SerialBase::None, 1);
- g_com_ctx.serial->attach(&rx_isr, Serial::RxIrq);
+ g_com_cts->rise(&cts_isr);
- g_com_ctx.tx_thread = new Thread(osPriorityHigh, DEFAULT_STACK_SIZE*2, NULL);
- g_com_ctx.rx_thread = new Thread(osPriorityHigh, DEFAULT_STACK_SIZE*2, NULL);
+ g_com_serial->format(8, SerialBase::None, 1);
+ g_com_serial->attach(&rx_isr, Serial::RxIrq);
- osStatus err = g_com_ctx.rx_thread->start(d7a_com_rx_thread);
+ osStatus err = g_com_rx_thread.start(d7a_com_rx_thread);
ASSERT(err == osOK, "Failed to start d7a_com_rx_thread (err: %d)\r\n", err);
- err = g_com_ctx.tx_thread->start(d7a_com_tx_thread);
+ err = g_com_tx_thread.start(d7a_com_tx_thread);
ASSERT(err == osOK, "Failed to start d7a_com_tx_thread (err: %d)\r\n", err);
return D7A_ERR_NONE;
@@ -173,14 +141,11 @@
d7a_errors_t d7a_com_close(void)
{
FPRINT("\r\n");
- g_com_ctx.rx_thread->terminate();
- g_com_ctx.tx_thread->terminate();
- delete g_com_ctx.data_parsing;
- delete g_com_ctx.cts_int;
- delete g_com_ctx.serial;
- delete g_com_ctx.rts;
- delete g_com_ctx.cts;
- delete g_com_ctx.rx_buf;
+ g_com_rx_thread.terminate();
+ g_com_tx_thread.terminate();
+ delete g_com_serial;
+ delete g_com_rts;
+ delete g_com_cts;
return D7A_ERR_NONE;
}
@@ -188,43 +153,43 @@
void d7a_com_start_rx(void)
{
FPRINT("\r\n");
- g_com_ctx.rx_started = true;
- g_com_ctx.rx_thread->signal_set(START_SIGNAL);
+ g_com_rx_started = true;
+ g_com_rx_thread.signal_set(START_SIGNAL);
}
void d7a_com_stop_rx(void)
{
FPRINT("\r\n");
- g_com_ctx.rx_started = false;
+ g_com_rx_started = false;
}
void d7a_com_start_tx(void)
{
FPRINT("\r\n");
- g_com_ctx.tx_started = true;
- g_com_ctx.tx_thread->signal_set(START_SIGNAL);
+ g_com_tx_started = true;
+ g_com_tx_thread.signal_set(START_SIGNAL);
}
void d7a_com_stop_tx(void)
{
FPRINT("\r\n");
- g_com_ctx.tx_started = false;
+ g_com_tx_started = false;
}
void d7a_com_restart(void)
{
FPRINT("\r\n");
- g_com_ctx.serial->attach(NULL, Serial::RxIrq);
+ g_com_serial->attach(NULL, Serial::RxIrq);
- g_com_ctx.state = SEARCH_HEADER;
- g_com_ctx.skipped_bytes = 0;
- g_com_ctx.tx_seq = 0;
- g_com_ctx.rx_seq = 0;
+ g_com_state = SEARCH_HEADER;
+ g_com_skipped_bytes = 0;
+ g_com_tx_seq = 0;
+ g_com_rx_seq = 0;
- g_com_ctx.rx_buf->reset();
+ g_com_rx_buf.reset();
- g_com_ctx.serial->attach(&rx_isr, Serial::RxIrq);
+ g_com_serial->attach(&rx_isr, Serial::RxIrq);
}
@@ -241,7 +206,7 @@
DPRINT("<-- (0x%02X) %d\r\n", tx_buf->buf[4], (tx_buf->len - KAL_COM_HEADER_LEN));
- *(g_com_ctx.rts) = 1;
+ *(g_com_rts) = 1;
//dbg_print_data("", "%02X ", (uint8_t*)tx_buf->buf, tx_buf->len, "\r\n");
@@ -249,13 +214,13 @@
for (uint32_t i=0 ; i<tx_buf->len ; i++)
{
- g_com_ctx.serial->putc(tx_buf->buf[i]);
+ g_com_serial->putc(tx_buf->buf[i]);
}
// Important to not release the ressource too soon
Thread::wait(2);
- *(g_com_ctx.rts) = 0;
+ *(g_com_rts) = 0;
}
// Formats and send packet throught Serial.
@@ -273,7 +238,7 @@
*p++ = (uint8_t)KAL_COM_SYNC_BYTE_0;
*p++ = (uint8_t)KAL_COM_SYNC_BYTE_1;
*p++ = (uint8_t)msg->alen + msg->plen;
- *p++ = (uint8_t)g_com_ctx.tx_seq++;
+ *p++ = (uint8_t)g_com_tx_seq++;
*p++ = (uint8_t)msg->id;
// copy payload and parameters
@@ -293,7 +258,7 @@
{
FPRINT("\r\n");
- g_com_ctx.tx_queue.put(d7a_com_new_msg(msg));
+ g_com_tx_queue.put(d7a_com_new_msg(msg));
}
void d7a_com_dump(uint8_t* buf, uint8_t len, d7a_com_flow_t flow)
@@ -331,7 +296,7 @@
{
FREE(pkt);
DPRINT("XON\r\n");
- g_com_ctx.tx_thread->signal_set(XON_SIGNAL);
+ g_com_tx_thread.signal_set(XON_SIGNAL);
}
else if (pkt->id == KAL_COM_FLOW_SYS_XOFF)
{
@@ -365,42 +330,42 @@
uint8_t header[KAL_COM_HEADER_LEN];
uint8_t seqnum;
- ASSERT(g_com_ctx.rx_buf->available_data() >= KAL_COM_HEADER_LEN, "Not enough data for header\r\n");
+ ASSERT(g_com_rx_buf.available_data() >= KAL_COM_HEADER_LEN, "Not enough data for header\r\n");
- g_com_ctx.skipped_bytes = 0;
+ g_com_skipped_bytes = 0;
- header[0] = g_com_ctx.rx_buf->pop();
+ header[0] = g_com_rx_buf.pop();
- while (g_com_ctx.rx_buf->available_data() >= KAL_COM_HEADER_LEN - 1)
+ while (g_com_rx_buf.available_data() >= KAL_COM_HEADER_LEN - 1)
{
- header[1] = g_com_ctx.rx_buf->pop();
+ header[1] = g_com_rx_buf.pop();
// Check sync bytes
if(KAL_COM_SYNC_BYTE_0 == header[0] && KAL_COM_SYNC_BYTE_1 == header[1])
{
// Copy header
- g_com_ctx.rx_buf->get(&header[2], KAL_COM_HEADER_LEN - 2);
+ g_com_rx_buf.get(&header[2], KAL_COM_HEADER_LEN - 2);
// Fill temp header
- g_com_ctx.msg.blen = header[2];
+ g_com_msg.blen = header[2];
seqnum = header[3];
- g_com_ctx.msg.id = header[4];
+ g_com_msg.id = header[4];
// Update seqnum
- WARNING(g_com_ctx.rx_seq == seqnum, "COM Bad seqnum expected:%d got:%d\r\n", g_com_ctx.rx_seq, seqnum);
- g_com_ctx.rx_seq = seqnum + 1;
+ WARNING(g_com_rx_seq == seqnum, "COM Bad seqnum expected:%d got:%d\r\n", g_com_rx_seq, seqnum);
+ g_com_rx_seq = seqnum + 1;
// search for body
- g_com_ctx.state = SEARCH_BODY;
+ g_com_state = SEARCH_BODY;
// Start parsing if data is already available
- if (g_com_ctx.rx_buf->available_data() >= g_com_ctx.msg.blen)
+ if (g_com_rx_buf.available_data() >= g_com_msg.blen)
{
- g_com_ctx.state = PARSE_BODY;
- g_com_ctx.data_parsing->release();
+ g_com_state = PARSE_BODY;
+ g_com_data_parsing.release();
}
- //DPRINT("COM header found (id: %02X seq: %d body: %d/%d bytes)\r\n", g_com_ctx.msg.id, seqnum, g_com_ctx.rx_buf->available_data(), g_com_ctx.msg.blen);
+ //DPRINT("COM header found (id: %02X seq: %d body: %d/%d bytes)\r\n", g_com_msg.id, seqnum, g_com_rx_buf.available_data(), g_com_msg.blen);
break;
}
else
@@ -420,18 +385,18 @@
*/
static void parse_packet_body(void)
{
- ASSERT(g_com_ctx.rx_buf->available_data() >= g_com_ctx.msg.blen, "Not enough data for body\r\n");
+ ASSERT(g_com_rx_buf.available_data() >= g_com_msg.blen, "Not enough data for body\r\n");
- if (KAL_COM_FLOWID(g_com_ctx.msg.id) != KAL_COM_FLOWID_TRC)
+ if (KAL_COM_FLOWID(g_com_msg.id) != KAL_COM_FLOWID_TRC)
{
- //DPRINT("COM body found (%d bytes)\r\n", g_com_ctx.msg.blen);
+ //DPRINT("COM body found (%d bytes)\r\n", g_com_msg.blen);
- d7a_com_rx_msg_t* pkt = (d7a_com_rx_msg_t*)MALLOC(sizeof(d7a_com_rx_msg_t) - 1 + g_com_ctx.msg.blen);
+ d7a_com_rx_msg_t* pkt = (d7a_com_rx_msg_t*)MALLOC(sizeof(d7a_com_rx_msg_t) - 1 + g_com_msg.blen);
// copy data to buffer
- pkt->blen = g_com_ctx.msg.blen;
- pkt->id = g_com_ctx.msg.id;
- g_com_ctx.rx_buf->get(pkt->buffer, g_com_ctx.msg.blen);
+ pkt->blen = g_com_msg.blen;
+ pkt->id = g_com_msg.id;
+ g_com_rx_buf.get(pkt->buffer, g_com_msg.blen);
// add packet to queue
d7a_com_new_pkt(pkt);
@@ -439,18 +404,18 @@
else
{
// Ignore packet
- //DPRINT("Ignore pkt id %02X\r\n", g_com_ctx.msg.id);
- g_com_ctx.rx_buf->get(NULL, g_com_ctx.msg.blen);
+ //DPRINT("Ignore pkt id %02X\r\n", g_com_msg.id);
+ g_com_rx_buf.get(NULL, g_com_msg.blen);
}
// Seach for next header
- g_com_ctx.state = SEARCH_HEADER;
+ g_com_state = SEARCH_HEADER;
// Start parsing if data is already available
- if (g_com_ctx.rx_buf->available_data() >= KAL_COM_HEADER_LEN)
+ if (g_com_rx_buf.available_data() >= KAL_COM_HEADER_LEN)
{
- g_com_ctx.state = PARSE_HEADER;
- g_com_ctx.data_parsing->release();
+ g_com_state = PARSE_HEADER;
+ g_com_data_parsing.release();
}
}
@@ -462,13 +427,13 @@
while (true)
{
// wait for data available
- g_com_ctx.data_parsing->wait();
+ g_com_data_parsing.wait();
- if (g_com_ctx.state == PARSE_HEADER)
+ if (g_com_state == PARSE_HEADER)
{
parse_packet_header();
}
- else if (g_com_ctx.state == PARSE_BODY)
+ else if (g_com_state == PARSE_BODY)
{
parse_packet_body();
}
@@ -486,7 +451,7 @@
while (true)
{
// wait for data to send
- evt = g_com_ctx.tx_queue.get();
+ evt = g_com_tx_queue.get();
msg = (evt.status == osEventMessage)? (d7a_com_tx_buf_t*)evt.value.p : NULL;
@@ -501,7 +466,7 @@
if (KAL_COM_FLOW_SYS_XACK == flow_id)
{
DPRINT("XACK\r\n");
- g_com_ctx.tx_thread->signal_wait(XON_SIGNAL);
+ g_com_tx_thread.signal_wait(XON_SIGNAL);
}
}
}
