Trond Enger / d7a_1x

Fork of d7a_1x by WizziLab

Committer:
Jeej
Date:
Wed Dec 21 14:11:09 2016 +0000
Revision:
78:f1c0affd99e7
Parent:
77:8c792719a1fc
Child:
79:82b01c1a62f6
Reduced stack size to fit in target NUCLEO-L432KC.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Jeej 24:a8433b091764 1 #include "mbed.h"
Jeej 24:a8433b091764 2 #include "rtos.h"
Jeej 24:a8433b091764 3 #include "dbg.h"
Jeej 49:81d5bddb02f0 4 #include "d7a.h"
Jeej 24:a8433b091764 5 #include "d7a_com.h"
Jeej 45:b85384e7d825 6 #include "d7a_alp.h"
Jeej 25:aac250164497 7 #include "d7a_common.h"
Jeej 25:aac250164497 8 #include "d7a_fs.h"
Jeej 25:aac250164497 9 #include "d7a_modem.h"
Jeej 25:aac250164497 10 #include "d7a_sys.h"
Jeej 76:fda2e34ff19d 11 #include "cbuffer.h"
Jeej 24:a8433b091764 12
Jeej 37:e04613e021f2 13 #define XON_SIGNAL (0x0001 << 0)
Jeej 37:e04613e021f2 14 #define START_SIGNAL (0x0001 << 1)
Jeej 31:ab9bfdbc6b44 15
Jeej 31:ab9bfdbc6b44 16 typedef struct {
Jeej 31:ab9bfdbc6b44 17 uint32_t len;
Jeej 45:b85384e7d825 18 uint8_t buf[1];
Jeej 31:ab9bfdbc6b44 19 } d7a_com_tx_buf_t;
Jeej 30:d775c1409849 20
Jeej 77:8c792719a1fc 21 static bool g_com_rx_started;
Jeej 77:8c792719a1fc 22 static bool g_com_tx_started;
Jeej 77:8c792719a1fc 23 static uint8_t g_com_state;
Jeej 77:8c792719a1fc 24 static DigitalOut* g_com_rts;
Jeej 77:8c792719a1fc 25 static InterruptIn* g_com_cts;
Jeej 77:8c792719a1fc 26 static CBuffer<uint8_t, 512> g_com_rx_buf;
Jeej 77:8c792719a1fc 27 static d7a_com_rx_msg_t g_com_msg;
Jeej 77:8c792719a1fc 28 static uint16_t g_com_skipped_bytes;
Jeej 77:8c792719a1fc 29 static uint8_t g_com_tx_seq;
Jeej 77:8c792719a1fc 30 static uint8_t g_com_rx_seq;
Jeej 77:8c792719a1fc 31 static Semaphore g_com_data_parsing(0);
Jeej 77:8c792719a1fc 32 static Semaphore g_com_cts_int(0);
Jeej 77:8c792719a1fc 33 static RawSerial* g_com_serial;
Jeej 78:f1c0affd99e7 34 static Thread g_com_rx_thread(osPriorityRealtime, 512, NULL);
Jeej 78:f1c0affd99e7 35 static Thread g_com_tx_thread(osPriorityHigh, 512, NULL);
Jeej 77:8c792719a1fc 36 static Queue<d7a_com_tx_buf_t, 8> g_com_tx_queue;
Jeej 77:8c792719a1fc 37 static Timer g_com_tim;
Jeej 77:8c792719a1fc 38
Jeej 77:8c792719a1fc 39
Jeej 37:e04613e021f2 40 enum {
Jeej 37:e04613e021f2 41 SEARCH_HEADER,
Jeej 37:e04613e021f2 42 PARSE_HEADER,
Jeej 37:e04613e021f2 43 SEARCH_BODY,
Jeej 37:e04613e021f2 44 PARSE_BODY,
Jeej 37:e04613e021f2 45 };
Jeej 30:d775c1409849 46
Jeej 24:a8433b091764 47
Jeej 24:a8433b091764 48 /**
Jeej 24:a8433b091764 49 Thread for parsing packets from RX buffer.
Jeej 24:a8433b091764 50
Jeej 24:a8433b091764 51 @param void
Jeej 24:a8433b091764 52 @return void
Jeej 24:a8433b091764 53 */
Jeej 76:fda2e34ff19d 54 void d7a_com_rx_thread();
Jeej 76:fda2e34ff19d 55 void d7a_com_tx_thread();
Jeej 31:ab9bfdbc6b44 56
Jeej 24:a8433b091764 57
Jeej 24:a8433b091764 58 /**
Jeej 24:a8433b091764 59 Serial Rx Interrupt Service Routine.
Jeej 24:a8433b091764 60 Add recevied bytes to the RX buffer.
Jeej 24:a8433b091764 61
Jeej 24:a8433b091764 62 @param void
Jeej 24:a8433b091764 63 @return void
Jeej 24:a8433b091764 64 */
Jeej 24:a8433b091764 65 void rx_isr()
Jeej 24:a8433b091764 66 {
Jeej 24:a8433b091764 67 // Loop just in case more than one character is in UART's receive FIFO buffer
Jeej 77:8c792719a1fc 68 while (g_com_serial->readable())
Jeej 34:1311cc53201a 69 {
Jeej 77:8c792719a1fc 70 g_com_rx_buf.push(g_com_serial->getc());
Jeej 34:1311cc53201a 71 //PRINT("-");
Jeej 78:f1c0affd99e7 72 }
Jeej 78:f1c0affd99e7 73
Jeej 78:f1c0affd99e7 74 // unlock data parsing thread
Jeej 78:f1c0affd99e7 75 if (g_com_state == SEARCH_HEADER && g_com_rx_buf.available_data() >= KAL_COM_HEADER_LEN)
Jeej 78:f1c0affd99e7 76 {
Jeej 78:f1c0affd99e7 77 g_com_state = PARSE_HEADER;
Jeej 78:f1c0affd99e7 78 g_com_data_parsing.release();
Jeej 78:f1c0affd99e7 79 }
Jeej 78:f1c0affd99e7 80 else if (g_com_state == SEARCH_BODY && g_com_rx_buf.available_data() >= g_com_msg.blen)
Jeej 78:f1c0affd99e7 81 {
Jeej 78:f1c0affd99e7 82 g_com_state = PARSE_BODY;
Jeej 78:f1c0affd99e7 83 g_com_data_parsing.release();
Jeej 24:a8433b091764 84 }
Jeej 24:a8433b091764 85 }
Jeej 24:a8433b091764 86
Jeej 24:a8433b091764 87 /**
Jeej 24:a8433b091764 88 CTS pin Interrupt Service Routine.
Jeej 24:a8433b091764 89 For flow control (not yet inplemented)
Jeej 24:a8433b091764 90
Jeej 24:a8433b091764 91 @param void
Jeej 24:a8433b091764 92 @return void
Jeej 24:a8433b091764 93 */
Jeej 24:a8433b091764 94 void cts_isr()
Jeej 24:a8433b091764 95 {
Jeej 34:1311cc53201a 96 //PRINT("CTS_INT\r\n");
Jeej 77:8c792719a1fc 97 //g_com_cts_int->release();
Jeej 24:a8433b091764 98 }
Jeej 24:a8433b091764 99
Jeej 26:9f0b9833cac6 100 // D7a_com constructor.
Jeej 26:9f0b9833cac6 101 // Opens a serial port and monitors the input for ALP packets.
Jeej 26:9f0b9833cac6 102 // Pins are those of the host, not the modem:
Jeej 26:9f0b9833cac6 103 // TX-host -> RX-modem
Jeej 26:9f0b9833cac6 104 // RX-host <- TX-modem
Jeej 26:9f0b9833cac6 105 // RTS-host -> CTS-modem
Jeej 26:9f0b9833cac6 106 // CTS-host <- RTS-modem
Jeej 49:81d5bddb02f0 107 d7a_errors_t d7a_com_open( const d7a_com_config_t* config )
Jeej 26:9f0b9833cac6 108 {
Jeej 26:9f0b9833cac6 109 FPRINT("\r\n");
Jeej 26:9f0b9833cac6 110
Jeej 77:8c792719a1fc 111 g_com_state = SEARCH_HEADER;
Jeej 77:8c792719a1fc 112 g_com_skipped_bytes = 0;
Jeej 77:8c792719a1fc 113 g_com_tx_seq = 0;
Jeej 77:8c792719a1fc 114 g_com_rx_seq = 0;
Jeej 31:ab9bfdbc6b44 115
Jeej 77:8c792719a1fc 116 g_com_serial = new RawSerial(config->tx, config->rx, 115200);
Jeej 77:8c792719a1fc 117 g_com_rts = new DigitalOut(config->rts);
Jeej 77:8c792719a1fc 118 g_com_cts = new InterruptIn(config->cts);
Jeej 69:18852c154df9 119
Jeej 77:8c792719a1fc 120 g_com_cts->rise(&cts_isr);
Jeej 30:d775c1409849 121
Jeej 77:8c792719a1fc 122 g_com_serial->format(8, SerialBase::None, 1);
Jeej 77:8c792719a1fc 123 g_com_serial->attach(&rx_isr, Serial::RxIrq);
Jeej 76:fda2e34ff19d 124
Jeej 77:8c792719a1fc 125 osStatus err = g_com_rx_thread.start(d7a_com_rx_thread);
Jeej 76:fda2e34ff19d 126 ASSERT(err == osOK, "Failed to start d7a_com_rx_thread (err: %d)\r\n", err);
Jeej 76:fda2e34ff19d 127
Jeej 77:8c792719a1fc 128 err = g_com_tx_thread.start(d7a_com_tx_thread);
Jeej 76:fda2e34ff19d 129 ASSERT(err == osOK, "Failed to start d7a_com_tx_thread (err: %d)\r\n", err);
Jeej 49:81d5bddb02f0 130
Jeej 49:81d5bddb02f0 131 return D7A_ERR_NONE;
Jeej 26:9f0b9833cac6 132 }
Jeej 26:9f0b9833cac6 133
Jeej 26:9f0b9833cac6 134 // Destructor
Jeej 56:da34fc11e760 135 d7a_errors_t d7a_com_close(void)
Jeej 26:9f0b9833cac6 136 {
Jeej 26:9f0b9833cac6 137 FPRINT("\r\n");
Jeej 77:8c792719a1fc 138 g_com_rx_thread.terminate();
Jeej 77:8c792719a1fc 139 g_com_tx_thread.terminate();
Jeej 77:8c792719a1fc 140 delete g_com_serial;
Jeej 77:8c792719a1fc 141 delete g_com_rts;
Jeej 77:8c792719a1fc 142 delete g_com_cts;
Jeej 49:81d5bddb02f0 143
Jeej 49:81d5bddb02f0 144 return D7A_ERR_NONE;
Jeej 26:9f0b9833cac6 145 }
Jeej 26:9f0b9833cac6 146
Jeej 34:1311cc53201a 147
Jeej 34:1311cc53201a 148 void d7a_com_restart(void)
Jeej 34:1311cc53201a 149 {
Jeej 34:1311cc53201a 150 FPRINT("\r\n");
Jeej 69:18852c154df9 151
Jeej 77:8c792719a1fc 152 g_com_serial->attach(NULL, Serial::RxIrq);
Jeej 42:1578f0480dcb 153
Jeej 77:8c792719a1fc 154 g_com_state = SEARCH_HEADER;
Jeej 77:8c792719a1fc 155 g_com_skipped_bytes = 0;
Jeej 77:8c792719a1fc 156 g_com_tx_seq = 0;
Jeej 77:8c792719a1fc 157 g_com_rx_seq = 0;
Jeej 34:1311cc53201a 158
Jeej 77:8c792719a1fc 159 g_com_rx_buf.reset();
Jeej 34:1311cc53201a 160
Jeej 77:8c792719a1fc 161 g_com_serial->attach(&rx_isr, Serial::RxIrq);
Jeej 34:1311cc53201a 162 }
Jeej 34:1311cc53201a 163
Jeej 42:1578f0480dcb 164
Jeej 24:a8433b091764 165 /**
Jeej 24:a8433b091764 166 Wakes-up modem and send data throught Serial.
Jeej 24:a8433b091764 167
Jeej 24:a8433b091764 168 @param const uint8_t* Pointer to data buffer
Jeej 24:a8433b091764 169 @param int Data length
Jeej 24:a8433b091764 170 @return void
Jeej 24:a8433b091764 171 */
Jeej 45:b85384e7d825 172 static void d7a_com_send(d7a_com_tx_buf_t* tx_buf)
Jeej 69:18852c154df9 173 {
Jeej 45:b85384e7d825 174 FPRINT("\r\n");
Jeej 45:b85384e7d825 175
Jeej 45:b85384e7d825 176 DPRINT("<-- (0x%02X) %d\r\n", tx_buf->buf[4], (tx_buf->len - KAL_COM_HEADER_LEN));
Jeej 34:1311cc53201a 177
Jeej 77:8c792719a1fc 178 *(g_com_rts) = 1;
Jeej 24:a8433b091764 179
Jeej 47:19f22e1a448a 180 //dbg_print_data("", "%02X ", (uint8_t*)tx_buf->buf, tx_buf->len, "\r\n");
Jeej 45:b85384e7d825 181
Jeej 70:07b378285c95 182 Thread::wait(3);
Jeej 24:a8433b091764 183
Jeej 45:b85384e7d825 184 for (uint32_t i=0 ; i<tx_buf->len ; i++)
Jeej 24:a8433b091764 185 {
Jeej 77:8c792719a1fc 186 g_com_serial->putc(tx_buf->buf[i]);
Jeej 24:a8433b091764 187 }
Jeej 24:a8433b091764 188
Jeej 66:492b1d7ba370 189 // Important to not release the ressource too soon
Jeej 70:07b378285c95 190 Thread::wait(2);
Jeej 42:1578f0480dcb 191
Jeej 77:8c792719a1fc 192 *(g_com_rts) = 0;
Jeej 24:a8433b091764 193 }
Jeej 24:a8433b091764 194
Jeej 26:9f0b9833cac6 195 // Formats and send packet throught Serial.
Jeej 45:b85384e7d825 196 d7a_com_tx_buf_t* d7a_com_new_msg(d7a_com_tx_msg_t* msg)
Jeej 34:1311cc53201a 197 {
Jeej 45:b85384e7d825 198 uint8_t len = KAL_COM_HEADER_LEN + msg->alen + msg->plen;
Jeej 34:1311cc53201a 199 FPRINT("(len:%d)\r\n", len);
Jeej 34:1311cc53201a 200
Jeej 45:b85384e7d825 201 d7a_com_tx_buf_t* tx_buf = (d7a_com_tx_buf_t*)MALLOC(sizeof(d7a_com_tx_buf_t) - 1 + len);
Jeej 34:1311cc53201a 202
Jeej 34:1311cc53201a 203 // construct serial header
Jeej 34:1311cc53201a 204 // concatenate and update tx_seq ID
Jeej 45:b85384e7d825 205 uint8_t* p = tx_buf->buf;
Jeej 45:b85384e7d825 206 uint8_t* t = p;
Jeej 45:b85384e7d825 207 *p++ = (uint8_t)KAL_COM_SYNC_BYTE_0;
Jeej 45:b85384e7d825 208 *p++ = (uint8_t)KAL_COM_SYNC_BYTE_1;
Jeej 45:b85384e7d825 209 *p++ = (uint8_t)msg->alen + msg->plen;
Jeej 77:8c792719a1fc 210 *p++ = (uint8_t)g_com_tx_seq++;
Jeej 45:b85384e7d825 211 *p++ = (uint8_t)msg->id;
Jeej 34:1311cc53201a 212
Jeej 34:1311cc53201a 213 // copy payload and parameters
Jeej 45:b85384e7d825 214 memcpy(p, msg->pbuf, msg->plen);
Jeej 45:b85384e7d825 215 p += msg->plen;
Jeej 45:b85384e7d825 216 memcpy(p, msg->abuf, msg->alen);
Jeej 45:b85384e7d825 217 p += msg->alen;
Jeej 34:1311cc53201a 218
Jeej 45:b85384e7d825 219 tx_buf->len = (uint32_t)(p - t);
Jeej 34:1311cc53201a 220
Jeej 45:b85384e7d825 221 ASSERT(tx_buf->len == len, "New msg wrong length %d expected %d\r\n", tx_buf->len, len);
Jeej 45:b85384e7d825 222
Jeej 45:b85384e7d825 223 return tx_buf;
Jeej 34:1311cc53201a 224 }
Jeej 34:1311cc53201a 225
Jeej 34:1311cc53201a 226 void d7a_com_post_msg(d7a_com_tx_msg_t* msg)
Jeej 45:b85384e7d825 227 {
Jeej 45:b85384e7d825 228 FPRINT("\r\n");
Jeej 26:9f0b9833cac6 229
Jeej 77:8c792719a1fc 230 g_com_tx_queue.put(d7a_com_new_msg(msg));
Jeej 26:9f0b9833cac6 231 }
Jeej 26:9f0b9833cac6 232
Jeej 30:d775c1409849 233 void d7a_com_dump(uint8_t* buf, uint8_t len, d7a_com_flow_t flow)
Jeej 30:d775c1409849 234 {
Jeej 30:d775c1409849 235 d7a_com_tx_msg_t msg;
Jeej 30:d775c1409849 236
Jeej 30:d775c1409849 237 msg.id = flow;
Jeej 30:d775c1409849 238 msg.pbuf = buf;
Jeej 30:d775c1409849 239 msg.plen = len;
Jeej 30:d775c1409849 240 msg.alen = 0;
Jeej 34:1311cc53201a 241 d7a_com_post_msg(&msg);
Jeej 30:d775c1409849 242 }
Jeej 30:d775c1409849 243
Jeej 25:aac250164497 244 static void d7a_com_new_pkt(d7a_com_rx_msg_t* pkt)
Jeej 25:aac250164497 245 {
Jeej 26:9f0b9833cac6 246 //FPRINT("\r\n");
Jeej 35:1fe2975c5a63 247
Jeej 35:1fe2975c5a63 248 DPRINT("--> (0x%02X) %d\r\n", pkt->id, pkt->blen);
Jeej 35:1fe2975c5a63 249
Jeej 25:aac250164497 250 // Distribute packet types to processes
Jeej 25:aac250164497 251 switch (KAL_COM_FLOWID(pkt->id))
Jeej 25:aac250164497 252 {
Jeej 25:aac250164497 253 case KAL_COM_FLOWID_FS:
Jeej 25:aac250164497 254 d7a_fs_new_pkt(pkt);
Jeej 25:aac250164497 255 break;
Jeej 25:aac250164497 256 case KAL_COM_FLOWID_CMD:
Jeej 25:aac250164497 257 d7a_modem_new_pkt(pkt);
Jeej 25:aac250164497 258 break;
Jeej 45:b85384e7d825 259 case KAL_COM_FLOWID_ALP:
Jeej 45:b85384e7d825 260 d7a_alp_new_pkt(pkt);
Jeej 45:b85384e7d825 261 break;
Jeej 25:aac250164497 262 case KAL_COM_FLOWID_SYS:
Jeej 30:d775c1409849 263 // This has to be here to avoid going to another process
Jeej 30:d775c1409849 264 if (pkt->id == KAL_COM_FLOW_SYS_XON)
Jeej 30:d775c1409849 265 {
Jeej 65:ac3844adfe49 266 FREE(pkt);
Jeej 42:1578f0480dcb 267 DPRINT("XON\r\n");
Jeej 77:8c792719a1fc 268 g_com_tx_thread.signal_set(XON_SIGNAL);
Jeej 30:d775c1409849 269 }
Jeej 30:d775c1409849 270 else if (pkt->id == KAL_COM_FLOW_SYS_XOFF)
Jeej 30:d775c1409849 271 {
Jeej 65:ac3844adfe49 272 FREE(pkt);
Jeej 42:1578f0480dcb 273 DPRINT("XOFF\r\n");
Jeej 34:1311cc53201a 274 d7a_sys_xack();
Jeej 30:d775c1409849 275 }
Jeej 30:d775c1409849 276 else
Jeej 30:d775c1409849 277 {
Jeej 30:d775c1409849 278 d7a_sys_new_pkt(pkt);
Jeej 30:d775c1409849 279 }
Jeej 30:d775c1409849 280 break;
Jeej 25:aac250164497 281 default:
Jeej 25:aac250164497 282 EPRINT("Untreated pkt type 0x%02X\r\n", pkt->id);
Jeej 25:aac250164497 283 FREE(pkt);
Jeej 25:aac250164497 284 break;
Jeej 25:aac250164497 285 }
Jeej 25:aac250164497 286 }
Jeej 24:a8433b091764 287
Jeej 33:f9a542d3efaa 288
Jeej 24:a8433b091764 289 /**
Jeej 34:1311cc53201a 290 Reads the Rx buffer, parses the packets
Jeej 24:a8433b091764 291
Jeej 24:a8433b091764 292 @param void
Jeej 24:a8433b091764 293 @return void
Jeej 24:a8433b091764 294 */
Jeej 37:e04613e021f2 295 static void parse_packet_header(void)
Jeej 24:a8433b091764 296 {
Jeej 76:fda2e34ff19d 297 FPRINT("\r\n");
Jeej 76:fda2e34ff19d 298
Jeej 37:e04613e021f2 299 uint8_t header[KAL_COM_HEADER_LEN];
Jeej 37:e04613e021f2 300 uint8_t seqnum;
Jeej 33:f9a542d3efaa 301
Jeej 77:8c792719a1fc 302 ASSERT(g_com_rx_buf.available_data() >= KAL_COM_HEADER_LEN, "Not enough data for header\r\n");
Jeej 42:1578f0480dcb 303
Jeej 77:8c792719a1fc 304 g_com_skipped_bytes = 0;
Jeej 33:f9a542d3efaa 305
Jeej 77:8c792719a1fc 306 header[0] = g_com_rx_buf.pop();
Jeej 69:18852c154df9 307
Jeej 77:8c792719a1fc 308 while (g_com_rx_buf.available_data() >= KAL_COM_HEADER_LEN - 1)
Jeej 24:a8433b091764 309 {
Jeej 77:8c792719a1fc 310 header[1] = g_com_rx_buf.pop();
Jeej 69:18852c154df9 311
Jeej 69:18852c154df9 312 // Check sync bytes
Jeej 69:18852c154df9 313 if(KAL_COM_SYNC_BYTE_0 == header[0] && KAL_COM_SYNC_BYTE_1 == header[1])
Jeej 24:a8433b091764 314 {
Jeej 69:18852c154df9 315 // Copy header
Jeej 77:8c792719a1fc 316 g_com_rx_buf.get(&header[2], KAL_COM_HEADER_LEN - 2);
Jeej 69:18852c154df9 317
Jeej 69:18852c154df9 318 // Fill temp header
Jeej 77:8c792719a1fc 319 g_com_msg.blen = header[2];
Jeej 69:18852c154df9 320 seqnum = header[3];
Jeej 77:8c792719a1fc 321 g_com_msg.id = header[4];
Jeej 69:18852c154df9 322
Jeej 69:18852c154df9 323 // Update seqnum
Jeej 77:8c792719a1fc 324 WARNING(g_com_rx_seq == seqnum, "COM Bad seqnum expected:%d got:%d\r\n", g_com_rx_seq, seqnum);
Jeej 77:8c792719a1fc 325 g_com_rx_seq = seqnum + 1;
Jeej 69:18852c154df9 326
Jeej 69:18852c154df9 327 // search for body
Jeej 77:8c792719a1fc 328 g_com_state = SEARCH_BODY;
Jeej 69:18852c154df9 329
Jeej 69:18852c154df9 330 // Start parsing if data is already available
Jeej 77:8c792719a1fc 331 if (g_com_rx_buf.available_data() >= g_com_msg.blen)
Jeej 33:f9a542d3efaa 332 {
Jeej 77:8c792719a1fc 333 g_com_state = PARSE_BODY;
Jeej 77:8c792719a1fc 334 g_com_data_parsing.release();
Jeej 33:f9a542d3efaa 335 }
Jeej 69:18852c154df9 336
Jeej 77:8c792719a1fc 337 //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);
Jeej 69:18852c154df9 338 break;
Jeej 24:a8433b091764 339 }
Jeej 69:18852c154df9 340 else
Jeej 69:18852c154df9 341 {
Jeej 69:18852c154df9 342 // Shift by 1 byte
Jeej 69:18852c154df9 343 WARNING(false, "COM Skipped byte 0x%02X.\r\n", header[0]);
Jeej 69:18852c154df9 344 header[0] = header[1];
Jeej 69:18852c154df9 345 }
Jeej 37:e04613e021f2 346 }
Jeej 37:e04613e021f2 347 }
Jeej 37:e04613e021f2 348
Jeej 37:e04613e021f2 349 /**
Jeej 37:e04613e021f2 350 Reads the Rx buffer, parses the packets
Jeej 37:e04613e021f2 351
Jeej 37:e04613e021f2 352 @param void
Jeej 37:e04613e021f2 353 @return void
Jeej 37:e04613e021f2 354 */
Jeej 37:e04613e021f2 355 static void parse_packet_body(void)
Jeej 37:e04613e021f2 356 {
Jeej 77:8c792719a1fc 357 ASSERT(g_com_rx_buf.available_data() >= g_com_msg.blen, "Not enough data for body\r\n");
Jeej 42:1578f0480dcb 358
Jeej 77:8c792719a1fc 359 if (KAL_COM_FLOWID(g_com_msg.id) != KAL_COM_FLOWID_TRC)
Jeej 37:e04613e021f2 360 {
Jeej 77:8c792719a1fc 361 //DPRINT("COM body found (%d bytes)\r\n", g_com_msg.blen);
Jeej 37:e04613e021f2 362
Jeej 77:8c792719a1fc 363 d7a_com_rx_msg_t* pkt = (d7a_com_rx_msg_t*)MALLOC(sizeof(d7a_com_rx_msg_t) - 1 + g_com_msg.blen);
Jeej 37:e04613e021f2 364
Jeej 37:e04613e021f2 365 // copy data to buffer
Jeej 77:8c792719a1fc 366 pkt->blen = g_com_msg.blen;
Jeej 77:8c792719a1fc 367 pkt->id = g_com_msg.id;
Jeej 77:8c792719a1fc 368 g_com_rx_buf.get(pkt->buffer, g_com_msg.blen);
Jeej 65:ac3844adfe49 369
Jeej 37:e04613e021f2 370 // add packet to queue
Jeej 37:e04613e021f2 371 d7a_com_new_pkt(pkt);
Jeej 37:e04613e021f2 372 }
Jeej 37:e04613e021f2 373 else
Jeej 37:e04613e021f2 374 {
Jeej 37:e04613e021f2 375 // Ignore packet
Jeej 77:8c792719a1fc 376 //DPRINT("Ignore pkt id %02X\r\n", g_com_msg.id);
Jeej 77:8c792719a1fc 377 g_com_rx_buf.get(NULL, g_com_msg.blen);
Jeej 24:a8433b091764 378 }
Jeej 33:f9a542d3efaa 379
Jeej 69:18852c154df9 380 // Seach for next header
Jeej 77:8c792719a1fc 381 g_com_state = SEARCH_HEADER;
Jeej 42:1578f0480dcb 382
Jeej 42:1578f0480dcb 383 // Start parsing if data is already available
Jeej 77:8c792719a1fc 384 if (g_com_rx_buf.available_data() >= KAL_COM_HEADER_LEN)
Jeej 42:1578f0480dcb 385 {
Jeej 77:8c792719a1fc 386 g_com_state = PARSE_HEADER;
Jeej 77:8c792719a1fc 387 g_com_data_parsing.release();
Jeej 42:1578f0480dcb 388 }
Jeej 24:a8433b091764 389 }
Jeej 24:a8433b091764 390
Jeej 24:a8433b091764 391
Jeej 24:a8433b091764 392 // Thread for parsing packets from RX buffer.
Jeej 76:fda2e34ff19d 393 void d7a_com_rx_thread()
Jeej 24:a8433b091764 394 {
Jeej 58:38a366236bda 395 FPRINT("(id:0x%08x)\r\n", osThreadGetId());
Jeej 24:a8433b091764 396 while (true)
Jeej 24:a8433b091764 397 {
Jeej 24:a8433b091764 398 // wait for data available
Jeej 77:8c792719a1fc 399 g_com_data_parsing.wait();
Jeej 37:e04613e021f2 400
Jeej 77:8c792719a1fc 401 if (g_com_state == PARSE_HEADER)
Jeej 33:f9a542d3efaa 402 {
Jeej 37:e04613e021f2 403 parse_packet_header();
Jeej 37:e04613e021f2 404 }
Jeej 77:8c792719a1fc 405 else if (g_com_state == PARSE_BODY)
Jeej 37:e04613e021f2 406 {
Jeej 37:e04613e021f2 407 parse_packet_body();
Jeej 33:f9a542d3efaa 408 }
Jeej 24:a8433b091764 409 }
Jeej 24:a8433b091764 410 }
Jeej 31:ab9bfdbc6b44 411
Jeej 76:fda2e34ff19d 412 void d7a_com_tx_thread()
Jeej 31:ab9bfdbc6b44 413 {
Jeej 58:38a366236bda 414 FPRINT("(id:0x%08x)\r\n", osThreadGetId());
Jeej 31:ab9bfdbc6b44 415
Jeej 31:ab9bfdbc6b44 416 d7a_com_tx_buf_t* msg;
Jeej 31:ab9bfdbc6b44 417 osEvent evt;
Jeej 34:1311cc53201a 418 uint8_t flow_id;
Jeej 34:1311cc53201a 419
Jeej 31:ab9bfdbc6b44 420 while (true)
Jeej 31:ab9bfdbc6b44 421 {
Jeej 31:ab9bfdbc6b44 422 // wait for data to send
Jeej 77:8c792719a1fc 423 evt = g_com_tx_queue.get();
Jeej 31:ab9bfdbc6b44 424 msg = (evt.status == osEventMessage)? (d7a_com_tx_buf_t*)evt.value.p : NULL;
Jeej 37:e04613e021f2 425
Jeej 31:ab9bfdbc6b44 426
Jeej 31:ab9bfdbc6b44 427 // send message
Jeej 31:ab9bfdbc6b44 428 if (msg != NULL)
Jeej 31:ab9bfdbc6b44 429 {
Jeej 34:1311cc53201a 430 flow_id = msg->buf[4];
Jeej 34:1311cc53201a 431
Jeej 45:b85384e7d825 432 d7a_com_send(msg);
Jeej 31:ab9bfdbc6b44 433 FREE(msg);
Jeej 34:1311cc53201a 434
Jeej 34:1311cc53201a 435 if (KAL_COM_FLOW_SYS_XACK == flow_id)
Jeej 34:1311cc53201a 436 {
Jeej 42:1578f0480dcb 437 DPRINT("XACK\r\n");
Jeej 77:8c792719a1fc 438 g_com_tx_thread.signal_wait(XON_SIGNAL);
Jeej 34:1311cc53201a 439 }
Jeej 31:ab9bfdbc6b44 440 }
Jeej 31:ab9bfdbc6b44 441 }
Jeej 31:ab9bfdbc6b44 442 }