Trond Enger / d7a_1x

Fork of d7a_1x by WizziLab

Committer:
Jeej
Date:
Thu Jun 02 09:24:52 2016 +0000
Revision:
31:ab9bfdbc6b44
Parent:
30:d775c1409849
Child:
33:f9a542d3efaa
New process for TX commands in d7a_com.

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