Trond Enger / d7a_1x

Fork of d7a_1x by WizziLab

Committer:
Jeej
Date:
Fri Jun 24 10:11:19 2016 +0000
Revision:
33:f9a542d3efaa
Parent:
31:ab9bfdbc6b44
Child:
34:1311cc53201a
Rewritten parser.

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 24:a8433b091764 4 #include "d7a_com.h"
Jeej 25:aac250164497 5 #include "d7a_common.h"
Jeej 25:aac250164497 6 #include "d7a_fs.h"
Jeej 25:aac250164497 7 #include "d7a_modem.h"
Jeej 25:aac250164497 8 #include "d7a_sys.h"
Jeej 24:a8433b091764 9
Jeej 30:d775c1409849 10 static volatile bool g_xon;
Jeej 31:ab9bfdbc6b44 11
Jeej 31:ab9bfdbc6b44 12 typedef struct {
Jeej 31:ab9bfdbc6b44 13 uint32_t len;
Jeej 31:ab9bfdbc6b44 14 uint8_t* buf;
Jeej 31:ab9bfdbc6b44 15 } d7a_com_tx_buf_t;
Jeej 30:d775c1409849 16
Jeej 30:d775c1409849 17
Jeej 25:aac250164497 18 typedef struct {
Jeej 25:aac250164497 19 DigitalOut* rts;
Jeej 25:aac250164497 20 InterruptIn* cts;
Jeej 25:aac250164497 21
Jeej 25:aac250164497 22 // RX buffer address
Jeej 25:aac250164497 23 uint8_t* rx_buffer;
Jeej 25:aac250164497 24 // RX buffer size
Jeej 25:aac250164497 25 uint16_t rx_buffer_size;
Jeej 25:aac250164497 26 // Write index in RX buffer
Jeej 25:aac250164497 27 volatile uint16_t write_idx;
Jeej 25:aac250164497 28 // Read index in RX buffer
Jeej 25:aac250164497 29 uint16_t read_idx;
Jeej 25:aac250164497 30 // Number of bytes available in RX buffer
Jeej 25:aac250164497 31 volatile uint16_t data_available;
Jeej 33:f9a542d3efaa 32 // Last Number of available data
Jeej 33:f9a542d3efaa 33 volatile uint16_t last_available;
Jeej 33:f9a542d3efaa 34 // Number of skipped bytes while parsing
Jeej 33:f9a542d3efaa 35 uint16_t skipped_bytes;
Jeej 33:f9a542d3efaa 36
Jeej 25:aac250164497 37 // Port TX sequence number
Jeej 25:aac250164497 38 uint8_t tx_seq;
Jeej 25:aac250164497 39 // Port RX sequence number
Jeej 25:aac250164497 40 uint8_t rx_seq;
Jeej 25:aac250164497 41 // Response to command maximum time
Jeej 25:aac250164497 42 uint32_t timeout;
Jeej 25:aac250164497 43
Jeej 25:aac250164497 44 // Packet reception queue
Jeej 25:aac250164497 45 Queue<d7a_com_rx_msg_t, 32> pkt_queue;
Jeej 25:aac250164497 46
Jeej 25:aac250164497 47 // Waiting for data available in RX buffer
Jeej 25:aac250164497 48 Semaphore* data_parsing;
Jeej 25:aac250164497 49 // CTS management
Jeej 25:aac250164497 50 Semaphore* cts_int;
Jeej 30:d775c1409849 51 // XON/XOFF management
Jeej 30:d775c1409849 52 Semaphore* xonoff;
Jeej 25:aac250164497 53
Jeej 25:aac250164497 54 // Data treatment threads
Jeej 31:ab9bfdbc6b44 55 Thread* rx_thread;
Jeej 25:aac250164497 56 Serial* serial;
Jeej 25:aac250164497 57
Jeej 31:ab9bfdbc6b44 58 // Tx Thread
Jeej 31:ab9bfdbc6b44 59 Thread* tx_thread;
Jeej 31:ab9bfdbc6b44 60 Queue<d7a_com_tx_buf_t, 32> tx_queue;
Jeej 31:ab9bfdbc6b44 61
Jeej 25:aac250164497 62 uint32_t rx_pkt_count;
Jeej 25:aac250164497 63 uint32_t rx_byte_count;
Jeej 25:aac250164497 64 uint32_t tx_pkt_count;
Jeej 25:aac250164497 65 uint32_t tx_byte_count;
Jeej 25:aac250164497 66 } d7a_com_ctx_t;
Jeej 24:a8433b091764 67
Jeej 31:ab9bfdbc6b44 68
Jeej 24:a8433b091764 69 static d7a_com_ctx_t g_com_ctx;
Jeej 24:a8433b091764 70
Jeej 24:a8433b091764 71 /**
Jeej 24:a8433b091764 72 Thread for parsing packets from RX buffer.
Jeej 24:a8433b091764 73
Jeej 24:a8433b091764 74 @param void
Jeej 24:a8433b091764 75 @return void
Jeej 24:a8433b091764 76 */
Jeej 31:ab9bfdbc6b44 77 void d7a_com_rx_thread( void const *p );
Jeej 31:ab9bfdbc6b44 78 void d7a_com_tx_thread( void const *p );
Jeej 31:ab9bfdbc6b44 79
Jeej 24:a8433b091764 80
Jeej 24:a8433b091764 81
Jeej 24:a8433b091764 82 /**
Jeej 24:a8433b091764 83 Serial Rx Interrupt Service Routine.
Jeej 24:a8433b091764 84 Add recevied bytes to the RX buffer.
Jeej 24:a8433b091764 85
Jeej 24:a8433b091764 86 @param void
Jeej 24:a8433b091764 87 @return void
Jeej 24:a8433b091764 88 */
Jeej 24:a8433b091764 89 void rx_isr()
Jeej 24:a8433b091764 90 {
Jeej 24:a8433b091764 91 // Loop just in case more than one character is in UART's receive FIFO buffer
Jeej 24:a8433b091764 92 // Stop if buffer full
Jeej 33:f9a542d3efaa 93 while (g_com_ctx.serial->readable()) {
Jeej 24:a8433b091764 94 g_com_ctx.rx_buffer[g_com_ctx.write_idx] = g_com_ctx.serial->getc();
Jeej 24:a8433b091764 95 g_com_ctx.data_available++;
Jeej 33:f9a542d3efaa 96 //dbg_print(".");
Jeej 24:a8433b091764 97
Jeej 24:a8433b091764 98 g_com_ctx.write_idx = (g_com_ctx.write_idx + 1) % g_com_ctx.rx_buffer_size;
Jeej 24:a8433b091764 99 }
Jeej 33:f9a542d3efaa 100
Jeej 24:a8433b091764 101 // unlock data parsing thread
Jeej 33:f9a542d3efaa 102 g_com_ctx.data_parsing->release();
Jeej 24:a8433b091764 103
Jeej 24:a8433b091764 104 return;
Jeej 24:a8433b091764 105 }
Jeej 24:a8433b091764 106
Jeej 24:a8433b091764 107 /**
Jeej 24:a8433b091764 108 CTS pin Interrupt Service Routine.
Jeej 24:a8433b091764 109 For flow control (not yet inplemented)
Jeej 24:a8433b091764 110
Jeej 24:a8433b091764 111 @param void
Jeej 24:a8433b091764 112 @return void
Jeej 24:a8433b091764 113 */
Jeej 24:a8433b091764 114 void cts_isr()
Jeej 24:a8433b091764 115 {
Jeej 24:a8433b091764 116 g_com_ctx.cts_int->release();
Jeej 24:a8433b091764 117 return;
Jeej 24:a8433b091764 118 }
Jeej 24:a8433b091764 119
Jeej 26:9f0b9833cac6 120 // D7a_com constructor.
Jeej 26:9f0b9833cac6 121 // Opens a serial port and monitors the input for ALP packets.
Jeej 26:9f0b9833cac6 122 // Pins are those of the host, not the modem:
Jeej 26:9f0b9833cac6 123 // TX-host -> RX-modem
Jeej 26:9f0b9833cac6 124 // RX-host <- TX-modem
Jeej 26:9f0b9833cac6 125 // RTS-host -> CTS-modem
Jeej 26:9f0b9833cac6 126 // CTS-host <- RTS-modem
Jeej 26:9f0b9833cac6 127 void d7a_com_open( const d7a_com_config_t* config )
Jeej 26:9f0b9833cac6 128 {
Jeej 26:9f0b9833cac6 129 FPRINT("\r\n");
Jeej 26:9f0b9833cac6 130
Jeej 26:9f0b9833cac6 131 g_com_ctx.rx_buffer_size = config->rx_buffer_size;
Jeej 26:9f0b9833cac6 132 g_com_ctx.rx_buffer = (uint8_t*)MALLOC(g_com_ctx.rx_buffer_size);
Jeej 26:9f0b9833cac6 133 g_com_ctx.cts->rise(&cts_isr);
Jeej 26:9f0b9833cac6 134 g_com_ctx.data_available = 0;
Jeej 33:f9a542d3efaa 135 g_com_ctx.last_available = 0;
Jeej 33:f9a542d3efaa 136 g_com_ctx.skipped_bytes = 0;
Jeej 26:9f0b9833cac6 137 g_com_ctx.write_idx = 0;
Jeej 26:9f0b9833cac6 138 g_com_ctx.read_idx = 0;
Jeej 26:9f0b9833cac6 139 g_com_ctx.tx_seq = 0;
Jeej 26:9f0b9833cac6 140 g_com_ctx.rx_seq = 0;
Jeej 26:9f0b9833cac6 141
Jeej 26:9f0b9833cac6 142 g_com_ctx.serial = new Serial(config->tx, config->rx);
Jeej 26:9f0b9833cac6 143 g_com_ctx.rts = new DigitalOut(config->rts);
Jeej 26:9f0b9833cac6 144 g_com_ctx.cts = new InterruptIn(config->cts);
Jeej 26:9f0b9833cac6 145 g_com_ctx.data_parsing = new Semaphore(1);
Jeej 26:9f0b9833cac6 146 g_com_ctx.cts_int = new Semaphore(1);
Jeej 31:ab9bfdbc6b44 147 g_com_ctx.xonoff = new Semaphore(1);
Jeej 26:9f0b9833cac6 148
Jeej 31:ab9bfdbc6b44 149 g_xon = true;
Jeej 31:ab9bfdbc6b44 150 g_com_ctx.xonoff->wait();
Jeej 31:ab9bfdbc6b44 151
Jeej 26:9f0b9833cac6 152 /* XXX: Unknown bug:
Jeej 26:9f0b9833cac6 153 Baud rate can be found with high error rate (> 4%).
Jeej 26:9f0b9833cac6 154 It is here manualy corrected after an oscilloscope measure.
Jeej 26:9f0b9833cac6 155 Normal Baudrate should be 115200.
Jeej 26:9f0b9833cac6 156 */
Jeej 33:f9a542d3efaa 157 //g_com_ctx.serial->baud(117000); // XXX
Jeej 33:f9a542d3efaa 158 g_com_ctx.serial->baud(115200); // XXX
Jeej 30:d775c1409849 159 //g_com_ctx.serial->baud(58500); // XXX
Jeej 26:9f0b9833cac6 160 g_com_ctx.serial->format(8, SerialBase::None, 1);
Jeej 26:9f0b9833cac6 161 g_com_ctx.serial->attach(&rx_isr, Serial::RxIrq);
Jeej 30:d775c1409849 162
Jeej 31:ab9bfdbc6b44 163 g_com_ctx.tx_thread = new Thread(d7a_com_tx_thread, NULL, osPriorityHigh, DEFAULT_STACK_SIZE);
Jeej 31:ab9bfdbc6b44 164 g_com_ctx.rx_thread = new Thread(d7a_com_rx_thread, NULL, osPriorityHigh, DEFAULT_STACK_SIZE);
Jeej 26:9f0b9833cac6 165 }
Jeej 26:9f0b9833cac6 166
Jeej 26:9f0b9833cac6 167 // Destructor
Jeej 26:9f0b9833cac6 168 void d7a_com_close()
Jeej 26:9f0b9833cac6 169 {
Jeej 26:9f0b9833cac6 170 FPRINT("\r\n");
Jeej 31:ab9bfdbc6b44 171 g_com_ctx.rx_thread->terminate();
Jeej 31:ab9bfdbc6b44 172 g_com_ctx.tx_thread->terminate();
Jeej 26:9f0b9833cac6 173 delete g_com_ctx.data_parsing;
Jeej 26:9f0b9833cac6 174 delete g_com_ctx.cts_int;
Jeej 26:9f0b9833cac6 175 delete g_com_ctx.serial;
Jeej 26:9f0b9833cac6 176 delete g_com_ctx.rts;
Jeej 26:9f0b9833cac6 177 delete g_com_ctx.cts;
Jeej 26:9f0b9833cac6 178 FREE(g_com_ctx.rx_buffer);
Jeej 26:9f0b9833cac6 179 }
Jeej 26:9f0b9833cac6 180
Jeej 24:a8433b091764 181
Jeej 24:a8433b091764 182 /**
Jeej 24:a8433b091764 183 Wakes-up modem and send data throught Serial.
Jeej 24:a8433b091764 184
Jeej 24:a8433b091764 185 @param const uint8_t* Pointer to data buffer
Jeej 24:a8433b091764 186 @param int Data length
Jeej 24:a8433b091764 187 @return void
Jeej 24:a8433b091764 188 */
Jeej 26:9f0b9833cac6 189 static void d7a_com_send(const uint8_t* buffer, int length)
Jeej 24:a8433b091764 190 {
Jeej 24:a8433b091764 191 int i;
Jeej 31:ab9bfdbc6b44 192 FPRINT("(len:%d)\r\n", length);
Jeej 24:a8433b091764 193 *(g_com_ctx.rts) = 1;
Jeej 24:a8433b091764 194
Jeej 31:ab9bfdbc6b44 195 //dbg_print_data("%02X ", (uint8_t*)buffer, length);
Jeej 31:ab9bfdbc6b44 196 //DPRINT("\r\n");
Jeej 24:a8433b091764 197 Thread::wait(5);
Jeej 24:a8433b091764 198
Jeej 24:a8433b091764 199 for (i=0 ; i<length ; i++)
Jeej 24:a8433b091764 200 {
Jeej 24:a8433b091764 201 g_com_ctx.serial->putc(buffer[i]);
Jeej 24:a8433b091764 202 }
Jeej 24:a8433b091764 203
Jeej 24:a8433b091764 204 *(g_com_ctx.rts) = 0;
Jeej 24:a8433b091764 205 }
Jeej 24:a8433b091764 206
Jeej 31:ab9bfdbc6b44 207
Jeej 31:ab9bfdbc6b44 208 static void d7a_com_post_tx(uint8_t* buffer, uint32_t length)
Jeej 31:ab9bfdbc6b44 209 {
Jeej 31:ab9bfdbc6b44 210 FPRINT("(len:%d)\r\n", length);
Jeej 31:ab9bfdbc6b44 211 d7a_com_tx_buf_t* tx_buf = (d7a_com_tx_buf_t*)MALLOC(sizeof(d7a_com_tx_buf_t));
Jeej 31:ab9bfdbc6b44 212
Jeej 31:ab9bfdbc6b44 213 tx_buf->len = length;
Jeej 31:ab9bfdbc6b44 214 tx_buf->buf = buffer;
Jeej 31:ab9bfdbc6b44 215
Jeej 31:ab9bfdbc6b44 216 g_com_ctx.tx_queue.put(tx_buf);
Jeej 31:ab9bfdbc6b44 217 }
Jeej 31:ab9bfdbc6b44 218
Jeej 26:9f0b9833cac6 219 // Formats and send packet throught Serial.
Jeej 26:9f0b9833cac6 220 void d7a_com_send_msg(d7a_com_tx_msg_t* msg)
Jeej 26:9f0b9833cac6 221 {
Jeej 26:9f0b9833cac6 222 uint8_t* buf;
Jeej 26:9f0b9833cac6 223 uint16_t len = msg->alen + msg->plen;
Jeej 30:d775c1409849 224 FPRINT("(len:%d)\r\n", len);
Jeej 26:9f0b9833cac6 225
Jeej 26:9f0b9833cac6 226 buf = (uint8_t*)MALLOC(KAL_COM_HEADER_LEN + len);
Jeej 26:9f0b9833cac6 227
Jeej 26:9f0b9833cac6 228 // construct serial header
Jeej 26:9f0b9833cac6 229 // concatenate and update tx_seq ID
Jeej 26:9f0b9833cac6 230 buf[0] = (uint8_t)KAL_COM_SYNC_BYTE_0;
Jeej 26:9f0b9833cac6 231 buf[1] = (uint8_t)KAL_COM_SYNC_BYTE_1;
Jeej 26:9f0b9833cac6 232 buf[2] = (uint8_t)len;
Jeej 26:9f0b9833cac6 233 buf[3] = (uint8_t)g_com_ctx.tx_seq++;
Jeej 26:9f0b9833cac6 234 buf[4] = (uint8_t)msg->id;
Jeej 26:9f0b9833cac6 235 len += KAL_COM_HEADER_LEN;
Jeej 26:9f0b9833cac6 236
Jeej 26:9f0b9833cac6 237 // copy payload and parameters
Jeej 26:9f0b9833cac6 238 memcpy(buf + KAL_COM_HEADER_LEN, msg->pbuf, msg->plen);
Jeej 26:9f0b9833cac6 239 memcpy(buf + KAL_COM_HEADER_LEN + msg->plen, msg->abuf, msg->alen);
Jeej 26:9f0b9833cac6 240
Jeej 31:ab9bfdbc6b44 241 d7a_com_post_tx(buf, len);
Jeej 26:9f0b9833cac6 242 }
Jeej 26:9f0b9833cac6 243
Jeej 31:ab9bfdbc6b44 244
Jeej 30:d775c1409849 245 void d7a_com_dump(uint8_t* buf, uint8_t len, d7a_com_flow_t flow)
Jeej 30:d775c1409849 246 {
Jeej 30:d775c1409849 247 d7a_com_tx_msg_t msg;
Jeej 30:d775c1409849 248
Jeej 30:d775c1409849 249 msg.id = flow;
Jeej 30:d775c1409849 250 msg.pbuf = buf;
Jeej 30:d775c1409849 251 msg.plen = len;
Jeej 30:d775c1409849 252 msg.alen = 0;
Jeej 30:d775c1409849 253 d7a_com_send_msg(&msg);
Jeej 30:d775c1409849 254 }
Jeej 30:d775c1409849 255
Jeej 33:f9a542d3efaa 256 void d7a_com_flush_rx(void)
Jeej 33:f9a542d3efaa 257 {
Jeej 33:f9a542d3efaa 258 g_com_ctx.data_available = 0;
Jeej 33:f9a542d3efaa 259 g_com_ctx.last_available = 0;
Jeej 33:f9a542d3efaa 260 g_com_ctx.skipped_bytes = 0;
Jeej 33:f9a542d3efaa 261 g_com_ctx.write_idx = 0;
Jeej 33:f9a542d3efaa 262 g_com_ctx.read_idx = 0;
Jeej 33:f9a542d3efaa 263 g_com_ctx.tx_seq = 0;
Jeej 33:f9a542d3efaa 264 g_com_ctx.rx_seq = 0;
Jeej 33:f9a542d3efaa 265 }
Jeej 26:9f0b9833cac6 266
Jeej 25:aac250164497 267 static void d7a_com_new_pkt(d7a_com_rx_msg_t* pkt)
Jeej 25:aac250164497 268 {
Jeej 26:9f0b9833cac6 269 //FPRINT("\r\n");
Jeej 30:d775c1409849 270 if (KAL_COM_FLOWID(pkt->id) != KAL_COM_FLOWID_TRC)
Jeej 30:d775c1409849 271 {
Jeej 33:f9a542d3efaa 272 DPRINT("--> (0x%02X) %d\r\n", pkt->id, pkt->blen);
Jeej 30:d775c1409849 273 }
Jeej 30:d775c1409849 274
Jeej 25:aac250164497 275 // Distribute packet types to processes
Jeej 25:aac250164497 276 switch (KAL_COM_FLOWID(pkt->id))
Jeej 25:aac250164497 277 {
Jeej 25:aac250164497 278 case KAL_COM_FLOWID_FS:
Jeej 25:aac250164497 279 d7a_fs_new_pkt(pkt);
Jeej 25:aac250164497 280 break;
Jeej 25:aac250164497 281 case KAL_COM_FLOWID_CMD:
Jeej 25:aac250164497 282 d7a_modem_new_pkt(pkt);
Jeej 25:aac250164497 283 break;
Jeej 25:aac250164497 284 case KAL_COM_FLOWID_SYS:
Jeej 30:d775c1409849 285 // This has to be here to avoid going to another process
Jeej 30:d775c1409849 286 if (pkt->id == KAL_COM_FLOW_SYS_XON)
Jeej 30:d775c1409849 287 {
Jeej 31:ab9bfdbc6b44 288 DPRINT("XON\r\n");
Jeej 30:d775c1409849 289 g_xon = true;
Jeej 30:d775c1409849 290 // Free all threads
Jeej 31:ab9bfdbc6b44 291 g_com_ctx.xonoff->release();
Jeej 30:d775c1409849 292 FREE(pkt);
Jeej 30:d775c1409849 293 }
Jeej 30:d775c1409849 294 else if (pkt->id == KAL_COM_FLOW_SYS_XOFF)
Jeej 30:d775c1409849 295 {
Jeej 30:d775c1409849 296 uint8_t buf[] = "X";
Jeej 30:d775c1409849 297 d7a_com_dump(buf, 1, KAL_COM_FLOW_SYS_XACK);
Jeej 30:d775c1409849 298 g_xon = false;
Jeej 30:d775c1409849 299 FREE(pkt);
Jeej 30:d775c1409849 300 DPRINT("XOFF\r\n");
Jeej 30:d775c1409849 301 }
Jeej 30:d775c1409849 302 else
Jeej 30:d775c1409849 303 {
Jeej 30:d775c1409849 304 d7a_sys_new_pkt(pkt);
Jeej 30:d775c1409849 305 }
Jeej 30:d775c1409849 306 break;
Jeej 30:d775c1409849 307 case KAL_COM_FLOWID_TRC:
Jeej 31:ab9bfdbc6b44 308 FREE(pkt);
Jeej 25:aac250164497 309 break;
Jeej 25:aac250164497 310 default:
Jeej 25:aac250164497 311 EPRINT("Untreated pkt type 0x%02X\r\n", pkt->id);
Jeej 25:aac250164497 312 FREE(pkt);
Jeej 25:aac250164497 313 break;
Jeej 25:aac250164497 314 }
Jeej 25:aac250164497 315 }
Jeej 24:a8433b091764 316
Jeej 33:f9a542d3efaa 317
Jeej 24:a8433b091764 318 /**
Jeej 24:a8433b091764 319 Reads the Rx buffer, parses the packets and adds them to _pkt_queue
Jeej 24:a8433b091764 320
Jeej 24:a8433b091764 321 @param void
Jeej 24:a8433b091764 322 @return void
Jeej 24:a8433b091764 323 */
Jeej 33:f9a542d3efaa 324 static void parse_packet(void)
Jeej 24:a8433b091764 325 {
Jeej 33:f9a542d3efaa 326 uint16_t base = 0;
Jeej 33:f9a542d3efaa 327 uint16_t current = 0;
Jeej 33:f9a542d3efaa 328 uint8_t byte;
Jeej 33:f9a542d3efaa 329
Jeej 33:f9a542d3efaa 330 // Packet fields
Jeej 24:a8433b091764 331 uint8_t seqnum = 0;
Jeej 24:a8433b091764 332 uint8_t len = 0;
Jeej 24:a8433b091764 333 uint8_t id = 0;
Jeej 33:f9a542d3efaa 334
Jeej 24:a8433b091764 335 uint8_t i = 0;
Jeej 33:f9a542d3efaa 336
Jeej 33:f9a542d3efaa 337 // Stats
Jeej 33:f9a542d3efaa 338 uint16_t nb_pkt = 0;
Jeej 33:f9a542d3efaa 339
Jeej 33:f9a542d3efaa 340 //dbg_print("Parsing %d bytes\r\n", g_com_ctx.data_available);
Jeej 24:a8433b091764 341
Jeej 33:f9a542d3efaa 342 while (g_com_ctx.data_available >= (base + KAL_COM_HEADER_LEN + 1))
Jeej 24:a8433b091764 343 {
Jeej 33:f9a542d3efaa 344 // Pop data
Jeej 33:f9a542d3efaa 345 byte = g_com_ctx.rx_buffer[(g_com_ctx.read_idx + (base + current)) % g_com_ctx.rx_buffer_size];
Jeej 33:f9a542d3efaa 346 //DPRINT("Treating base %d byte %d of %d: 0x%02X\r\n", base, current, g_com_ctx.data_available, byte);
Jeej 33:f9a542d3efaa 347
Jeej 33:f9a542d3efaa 348 // search first sync byte
Jeej 33:f9a542d3efaa 349 if (0 == current)
Jeej 24:a8433b091764 350 {
Jeej 33:f9a542d3efaa 351 WARNING(g_com_ctx.skipped_bytes != 1, "COM not sync. Searching for header.\r\n");
Jeej 24:a8433b091764 352
Jeej 33:f9a542d3efaa 353 if(KAL_COM_SYNC_BYTE_0 == byte)
Jeej 33:f9a542d3efaa 354 {
Jeej 33:f9a542d3efaa 355 current++;
Jeej 33:f9a542d3efaa 356 }
Jeej 33:f9a542d3efaa 357 else
Jeej 33:f9a542d3efaa 358 {
Jeej 33:f9a542d3efaa 359 // Not a packet. Restart at base + 1
Jeej 33:f9a542d3efaa 360 g_com_ctx.skipped_bytes++;
Jeej 33:f9a542d3efaa 361 base++;
Jeej 33:f9a542d3efaa 362 }
Jeej 33:f9a542d3efaa 363 continue;
Jeej 24:a8433b091764 364 }
Jeej 24:a8433b091764 365 // look up second sync byte
Jeej 33:f9a542d3efaa 366 else if (1 == current)
Jeej 24:a8433b091764 367 {
Jeej 33:f9a542d3efaa 368 if(KAL_COM_SYNC_BYTE_1 == byte)
Jeej 24:a8433b091764 369 {
Jeej 33:f9a542d3efaa 370 current++;
Jeej 24:a8433b091764 371 }
Jeej 24:a8433b091764 372 else
Jeej 24:a8433b091764 373 {
Jeej 33:f9a542d3efaa 374 // Not a packet. Restart at base + 1
Jeej 33:f9a542d3efaa 375 g_com_ctx.skipped_bytes++;
Jeej 33:f9a542d3efaa 376 base++;
Jeej 33:f9a542d3efaa 377 current = 0;
Jeej 24:a8433b091764 378 }
Jeej 33:f9a542d3efaa 379 continue;
Jeej 33:f9a542d3efaa 380 }
Jeej 33:f9a542d3efaa 381 // look up packet size
Jeej 33:f9a542d3efaa 382 else if (2 == current)
Jeej 33:f9a542d3efaa 383 {
Jeej 33:f9a542d3efaa 384 len = byte;
Jeej 33:f9a542d3efaa 385 // if not enough data is available
Jeej 33:f9a542d3efaa 386 if ((g_com_ctx.data_available - base) < (KAL_COM_HEADER_LEN + len))
Jeej 33:f9a542d3efaa 387 {
Jeej 33:f9a542d3efaa 388 // exit parser
Jeej 33:f9a542d3efaa 389 break;
Jeej 33:f9a542d3efaa 390 }
Jeej 33:f9a542d3efaa 391
Jeej 33:f9a542d3efaa 392 current++;
Jeej 33:f9a542d3efaa 393 continue;
Jeej 24:a8433b091764 394 }
Jeej 24:a8433b091764 395 // get seqnum
Jeej 33:f9a542d3efaa 396 else if (3 == current)
Jeej 33:f9a542d3efaa 397 {
Jeej 33:f9a542d3efaa 398 seqnum = byte;
Jeej 33:f9a542d3efaa 399 current++;
Jeej 33:f9a542d3efaa 400 continue;
Jeej 33:f9a542d3efaa 401 }
Jeej 33:f9a542d3efaa 402 // get id
Jeej 33:f9a542d3efaa 403 else if (4 == current)
Jeej 24:a8433b091764 404 {
Jeej 33:f9a542d3efaa 405 id = byte;
Jeej 33:f9a542d3efaa 406 current++;
Jeej 33:f9a542d3efaa 407 continue;
Jeej 33:f9a542d3efaa 408 }
Jeej 33:f9a542d3efaa 409 // we got a full packet
Jeej 33:f9a542d3efaa 410 else if (5 == current)
Jeej 33:f9a542d3efaa 411 {
Jeej 33:f9a542d3efaa 412 if (g_com_ctx.skipped_bytes)
Jeej 33:f9a542d3efaa 413 {
Jeej 33:f9a542d3efaa 414 WARNING(false, "COM header found, skipped %d bytes.\r\n", g_com_ctx.skipped_bytes);
Jeej 33:f9a542d3efaa 415 g_com_ctx.skipped_bytes = 0;
Jeej 33:f9a542d3efaa 416 }
Jeej 33:f9a542d3efaa 417
Jeej 33:f9a542d3efaa 418 // Update seqnum
Jeej 24:a8433b091764 419 if (g_com_ctx.rx_seq != seqnum)
Jeej 24:a8433b091764 420 {
Jeej 33:f9a542d3efaa 421 ASSERT(false, "COM Bad seqnum expected:%d got:%d\r\n", seqnum, g_com_ctx.rx_seq);
Jeej 24:a8433b091764 422 g_com_ctx.rx_seq = seqnum;
Jeej 24:a8433b091764 423 }
Jeej 24:a8433b091764 424 g_com_ctx.rx_seq++;
Jeej 33:f9a542d3efaa 425
Jeej 33:f9a542d3efaa 426 nb_pkt++;
Jeej 33:f9a542d3efaa 427
Jeej 31:ab9bfdbc6b44 428 if (KAL_COM_FLOWID(id) != KAL_COM_FLOWID_TRC)
Jeej 24:a8433b091764 429 {
Jeej 31:ab9bfdbc6b44 430 d7a_com_rx_msg_t* pkt = NULL;
Jeej 31:ab9bfdbc6b44 431 pkt = (d7a_com_rx_msg_t*)MALLOC(sizeof(d7a_com_rx_msg_t) - 1 + len);
Jeej 31:ab9bfdbc6b44 432
Jeej 31:ab9bfdbc6b44 433 //DPRINT("Got packet id 0x%02X len %d\r\n", id, len);
Jeej 31:ab9bfdbc6b44 434
Jeej 31:ab9bfdbc6b44 435 // copy data to buffer
Jeej 31:ab9bfdbc6b44 436 pkt->blen = len;
Jeej 31:ab9bfdbc6b44 437 pkt->id = id;
Jeej 31:ab9bfdbc6b44 438 for (i=0 ; i<len ; i++)
Jeej 31:ab9bfdbc6b44 439 {
Jeej 33:f9a542d3efaa 440 pkt->buffer[i] = g_com_ctx.rx_buffer[(g_com_ctx.read_idx + (base + current + i)) % g_com_ctx.rx_buffer_size];
Jeej 31:ab9bfdbc6b44 441 }
Jeej 31:ab9bfdbc6b44 442
Jeej 31:ab9bfdbc6b44 443 // add packet to queue
Jeej 31:ab9bfdbc6b44 444 d7a_com_new_pkt(pkt);
Jeej 24:a8433b091764 445 }
Jeej 31:ab9bfdbc6b44 446 else
Jeej 31:ab9bfdbc6b44 447 {
Jeej 33:f9a542d3efaa 448 // Ignore packet
Jeej 31:ab9bfdbc6b44 449 }
Jeej 33:f9a542d3efaa 450
Jeej 33:f9a542d3efaa 451 // Go to EOP
Jeej 33:f9a542d3efaa 452 current += len - 1;
Jeej 24:a8433b091764 453
Jeej 33:f9a542d3efaa 454 // Search next packet
Jeej 33:f9a542d3efaa 455 base += current + 1;
Jeej 33:f9a542d3efaa 456 current = 0;
Jeej 33:f9a542d3efaa 457 continue;
Jeej 24:a8433b091764 458 }
Jeej 24:a8433b091764 459 else
Jeej 24:a8433b091764 460 {
Jeej 33:f9a542d3efaa 461 ASSERT(false, "D7A COM parser!\r\n");
Jeej 24:a8433b091764 462 }
Jeej 24:a8433b091764 463 }
Jeej 33:f9a542d3efaa 464
Jeej 33:f9a542d3efaa 465 // update buffer indexes
Jeej 33:f9a542d3efaa 466 g_com_ctx.read_idx = (g_com_ctx.read_idx + base) % g_com_ctx.rx_buffer_size;
Jeej 33:f9a542d3efaa 467 g_com_ctx.data_available -= base;
Jeej 33:f9a542d3efaa 468
Jeej 33:f9a542d3efaa 469 if (base) {
Jeej 33:f9a542d3efaa 470 DPRINT("Parsed %d bytes of %d (%d packets)\r\n", base, g_com_ctx.data_available + base, nb_pkt);
Jeej 24:a8433b091764 471 }
Jeej 24:a8433b091764 472 }
Jeej 24:a8433b091764 473
Jeej 24:a8433b091764 474
Jeej 24:a8433b091764 475 // Thread for parsing packets from RX buffer.
Jeej 31:ab9bfdbc6b44 476 void d7a_com_rx_thread( void const *p )
Jeej 24:a8433b091764 477 {
Jeej 25:aac250164497 478 FPRINT("\r\n");
Jeej 24:a8433b091764 479 while (true)
Jeej 24:a8433b091764 480 {
Jeej 24:a8433b091764 481 // wait for data available
Jeej 24:a8433b091764 482 g_com_ctx.data_parsing->wait();
Jeej 33:f9a542d3efaa 483 ASSERT(g_com_ctx.data_available <= g_com_ctx.rx_buffer_size, "COM buffer overflow\r\n");
Jeej 24:a8433b091764 484 // search for packets
Jeej 33:f9a542d3efaa 485 if ((g_com_ctx.last_available != g_com_ctx.data_available) && (g_com_ctx.data_available >= (KAL_COM_HEADER_LEN + 1)))
Jeej 33:f9a542d3efaa 486 {
Jeej 33:f9a542d3efaa 487 g_com_ctx.last_available = g_com_ctx.data_available;
Jeej 33:f9a542d3efaa 488 parse_packet();
Jeej 33:f9a542d3efaa 489 }
Jeej 24:a8433b091764 490 }
Jeej 24:a8433b091764 491 }
Jeej 31:ab9bfdbc6b44 492
Jeej 31:ab9bfdbc6b44 493 void d7a_com_tx_thread( void const *p )
Jeej 31:ab9bfdbc6b44 494 {
Jeej 31:ab9bfdbc6b44 495 FPRINT("\r\n");
Jeej 31:ab9bfdbc6b44 496
Jeej 31:ab9bfdbc6b44 497 d7a_com_tx_buf_t* msg;
Jeej 31:ab9bfdbc6b44 498 osEvent evt;
Jeej 31:ab9bfdbc6b44 499 while (true)
Jeej 31:ab9bfdbc6b44 500 {
Jeej 31:ab9bfdbc6b44 501 if (g_xon == false)
Jeej 31:ab9bfdbc6b44 502 {
Jeej 31:ab9bfdbc6b44 503 g_com_ctx.xonoff->wait();
Jeej 31:ab9bfdbc6b44 504 }
Jeej 31:ab9bfdbc6b44 505
Jeej 31:ab9bfdbc6b44 506 // wait for data to send
Jeej 31:ab9bfdbc6b44 507 evt = g_com_ctx.tx_queue.get();
Jeej 31:ab9bfdbc6b44 508 msg = (evt.status == osEventMessage)? (d7a_com_tx_buf_t*)evt.value.p : NULL;
Jeej 31:ab9bfdbc6b44 509
Jeej 31:ab9bfdbc6b44 510 // send message
Jeej 31:ab9bfdbc6b44 511 if (msg != NULL)
Jeej 31:ab9bfdbc6b44 512 {
Jeej 33:f9a542d3efaa 513 DPRINT("<-- (0x%02X) %d\r\n", msg->buf[4], (msg->len - KAL_COM_HEADER_LEN));
Jeej 31:ab9bfdbc6b44 514 d7a_com_send(msg->buf, msg->len);
Jeej 31:ab9bfdbc6b44 515 FREE(msg->buf);
Jeej 31:ab9bfdbc6b44 516 FREE(msg);
Jeej 31:ab9bfdbc6b44 517 }
Jeej 31:ab9bfdbc6b44 518 }
Jeej 31:ab9bfdbc6b44 519 }