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
src/d7a_com.cpp@28:0376b97b4b55, 2016-04-04 (annotated)
- Committer:
- Jeej
- Date:
- Mon Apr 04 14:00:28 2016 +0000
- Revision:
- 28:0376b97b4b55
- Parent:
- 27:934ab7455115
- Child:
- 30:d775c1409849
wait after notif to avoid fs conflicts;
Who changed what in which revision?
User | Revision | Line number | New 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 | 25:aac250164497 | 10 | typedef struct { |
Jeej | 25:aac250164497 | 11 | DigitalOut* rts; |
Jeej | 25:aac250164497 | 12 | InterruptIn* cts; |
Jeej | 25:aac250164497 | 13 | |
Jeej | 25:aac250164497 | 14 | // RX buffer address |
Jeej | 25:aac250164497 | 15 | uint8_t* rx_buffer; |
Jeej | 25:aac250164497 | 16 | // RX buffer size |
Jeej | 25:aac250164497 | 17 | uint16_t rx_buffer_size; |
Jeej | 25:aac250164497 | 18 | // Write index in RX buffer |
Jeej | 25:aac250164497 | 19 | volatile uint16_t write_idx; |
Jeej | 25:aac250164497 | 20 | // Read index in RX buffer |
Jeej | 25:aac250164497 | 21 | uint16_t read_idx; |
Jeej | 25:aac250164497 | 22 | // Number of bytes available in RX buffer |
Jeej | 25:aac250164497 | 23 | volatile uint16_t data_available; |
Jeej | 25:aac250164497 | 24 | // Port TX sequence number |
Jeej | 25:aac250164497 | 25 | uint8_t tx_seq; |
Jeej | 25:aac250164497 | 26 | // Port RX sequence number |
Jeej | 25:aac250164497 | 27 | uint8_t rx_seq; |
Jeej | 25:aac250164497 | 28 | // Response to command maximum time |
Jeej | 25:aac250164497 | 29 | uint32_t timeout; |
Jeej | 25:aac250164497 | 30 | |
Jeej | 25:aac250164497 | 31 | // Packet reception queue |
Jeej | 25:aac250164497 | 32 | Queue<d7a_com_rx_msg_t, 32> pkt_queue; |
Jeej | 25:aac250164497 | 33 | |
Jeej | 25:aac250164497 | 34 | // Waiting for data available in RX buffer |
Jeej | 25:aac250164497 | 35 | Semaphore* data_parsing; |
Jeej | 25:aac250164497 | 36 | // CTS management |
Jeej | 25:aac250164497 | 37 | Semaphore* cts_int; |
Jeej | 25:aac250164497 | 38 | |
Jeej | 25:aac250164497 | 39 | // Data treatment threads |
Jeej | 25:aac250164497 | 40 | Thread* thread; |
Jeej | 25:aac250164497 | 41 | Serial* serial; |
Jeej | 25:aac250164497 | 42 | |
Jeej | 25:aac250164497 | 43 | uint32_t rx_pkt_count; |
Jeej | 25:aac250164497 | 44 | uint32_t rx_byte_count; |
Jeej | 25:aac250164497 | 45 | uint32_t tx_pkt_count; |
Jeej | 25:aac250164497 | 46 | uint32_t tx_byte_count; |
Jeej | 25:aac250164497 | 47 | } d7a_com_ctx_t; |
Jeej | 24:a8433b091764 | 48 | |
Jeej | 24:a8433b091764 | 49 | static d7a_com_ctx_t g_com_ctx; |
Jeej | 24:a8433b091764 | 50 | |
Jeej | 24:a8433b091764 | 51 | /** |
Jeej | 24:a8433b091764 | 52 | Thread for parsing packets from RX buffer. |
Jeej | 24:a8433b091764 | 53 | |
Jeej | 24:a8433b091764 | 54 | @param void |
Jeej | 24:a8433b091764 | 55 | @return void |
Jeej | 24:a8433b091764 | 56 | */ |
Jeej | 25:aac250164497 | 57 | void d7a_com_thread( void const *p ); |
Jeej | 24:a8433b091764 | 58 | |
Jeej | 24:a8433b091764 | 59 | |
Jeej | 24:a8433b091764 | 60 | /** |
Jeej | 24:a8433b091764 | 61 | Serial Rx Interrupt Service Routine. |
Jeej | 24:a8433b091764 | 62 | Add recevied bytes to the RX buffer. |
Jeej | 24:a8433b091764 | 63 | |
Jeej | 24:a8433b091764 | 64 | @param void |
Jeej | 24:a8433b091764 | 65 | @return void |
Jeej | 24:a8433b091764 | 66 | */ |
Jeej | 24:a8433b091764 | 67 | void rx_isr() |
Jeej | 24:a8433b091764 | 68 | { |
Jeej | 24:a8433b091764 | 69 | // Loop just in case more than one character is in UART's receive FIFO buffer |
Jeej | 24:a8433b091764 | 70 | // Stop if buffer full |
Jeej | 24:a8433b091764 | 71 | 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 | 72 | g_com_ctx.rx_buffer[g_com_ctx.write_idx] = g_com_ctx.serial->getc(); |
Jeej | 24:a8433b091764 | 73 | g_com_ctx.data_available++; |
Jeej | 24:a8433b091764 | 74 | //DPRINT("."); |
Jeej | 24:a8433b091764 | 75 | |
Jeej | 24:a8433b091764 | 76 | g_com_ctx.write_idx = (g_com_ctx.write_idx + 1) % g_com_ctx.rx_buffer_size; |
Jeej | 24:a8433b091764 | 77 | } |
Jeej | 24:a8433b091764 | 78 | |
Jeej | 24:a8433b091764 | 79 | // unlock data parsing thread |
Jeej | 25:aac250164497 | 80 | // do not parse if minimum packet size is not available |
Jeej | 25:aac250164497 | 81 | if (g_com_ctx.data_available > KAL_COM_HEADER_LEN) |
Jeej | 25:aac250164497 | 82 | { |
Jeej | 25:aac250164497 | 83 | g_com_ctx.data_parsing->release(); |
Jeej | 25:aac250164497 | 84 | } |
Jeej | 24:a8433b091764 | 85 | |
Jeej | 24:a8433b091764 | 86 | return; |
Jeej | 24:a8433b091764 | 87 | } |
Jeej | 24:a8433b091764 | 88 | |
Jeej | 24:a8433b091764 | 89 | /** |
Jeej | 24:a8433b091764 | 90 | CTS pin Interrupt Service Routine. |
Jeej | 24:a8433b091764 | 91 | For flow control (not yet inplemented) |
Jeej | 24:a8433b091764 | 92 | |
Jeej | 24:a8433b091764 | 93 | @param void |
Jeej | 24:a8433b091764 | 94 | @return void |
Jeej | 24:a8433b091764 | 95 | */ |
Jeej | 24:a8433b091764 | 96 | void cts_isr() |
Jeej | 24:a8433b091764 | 97 | { |
Jeej | 24:a8433b091764 | 98 | g_com_ctx.cts_int->release(); |
Jeej | 24:a8433b091764 | 99 | return; |
Jeej | 24:a8433b091764 | 100 | } |
Jeej | 24:a8433b091764 | 101 | |
Jeej | 26:9f0b9833cac6 | 102 | // D7a_com constructor. |
Jeej | 26:9f0b9833cac6 | 103 | // Opens a serial port and monitors the input for ALP packets. |
Jeej | 26:9f0b9833cac6 | 104 | // Pins are those of the host, not the modem: |
Jeej | 26:9f0b9833cac6 | 105 | // TX-host -> RX-modem |
Jeej | 26:9f0b9833cac6 | 106 | // RX-host <- TX-modem |
Jeej | 26:9f0b9833cac6 | 107 | // RTS-host -> CTS-modem |
Jeej | 26:9f0b9833cac6 | 108 | // CTS-host <- RTS-modem |
Jeej | 26:9f0b9833cac6 | 109 | void d7a_com_open( const d7a_com_config_t* config ) |
Jeej | 26:9f0b9833cac6 | 110 | { |
Jeej | 26:9f0b9833cac6 | 111 | FPRINT("\r\n"); |
Jeej | 26:9f0b9833cac6 | 112 | |
Jeej | 26:9f0b9833cac6 | 113 | g_com_ctx.rx_buffer_size = config->rx_buffer_size; |
Jeej | 26:9f0b9833cac6 | 114 | g_com_ctx.rx_buffer = (uint8_t*)MALLOC(g_com_ctx.rx_buffer_size); |
Jeej | 26:9f0b9833cac6 | 115 | g_com_ctx.cts->rise(&cts_isr); |
Jeej | 26:9f0b9833cac6 | 116 | g_com_ctx.data_available = 0; |
Jeej | 26:9f0b9833cac6 | 117 | g_com_ctx.write_idx = 0; |
Jeej | 26:9f0b9833cac6 | 118 | g_com_ctx.read_idx = 0; |
Jeej | 26:9f0b9833cac6 | 119 | g_com_ctx.tx_seq = 0; |
Jeej | 26:9f0b9833cac6 | 120 | g_com_ctx.rx_seq = 0; |
Jeej | 26:9f0b9833cac6 | 121 | |
Jeej | 26:9f0b9833cac6 | 122 | g_com_ctx.serial = new Serial(config->tx, config->rx); |
Jeej | 26:9f0b9833cac6 | 123 | g_com_ctx.rts = new DigitalOut(config->rts); |
Jeej | 26:9f0b9833cac6 | 124 | g_com_ctx.cts = new InterruptIn(config->cts); |
Jeej | 26:9f0b9833cac6 | 125 | g_com_ctx.data_parsing = new Semaphore(1); |
Jeej | 26:9f0b9833cac6 | 126 | g_com_ctx.cts_int = new Semaphore(1); |
Jeej | 26:9f0b9833cac6 | 127 | g_com_ctx.thread = new Thread(d7a_com_thread, NULL, osPriorityBelowNormal, DEFAULT_STACK_SIZE*2); |
Jeej | 26:9f0b9833cac6 | 128 | |
Jeej | 26:9f0b9833cac6 | 129 | /* XXX: Unknown bug: |
Jeej | 26:9f0b9833cac6 | 130 | Baud rate can be found with high error rate (> 4%). |
Jeej | 26:9f0b9833cac6 | 131 | It is here manualy corrected after an oscilloscope measure. |
Jeej | 26:9f0b9833cac6 | 132 | Normal Baudrate should be 115200. |
Jeej | 26:9f0b9833cac6 | 133 | */ |
Jeej | 26:9f0b9833cac6 | 134 | g_com_ctx.serial->baud(117000); // XXX |
Jeej | 26:9f0b9833cac6 | 135 | g_com_ctx.serial->format(8, SerialBase::None, 1); |
Jeej | 26:9f0b9833cac6 | 136 | g_com_ctx.serial->attach(&rx_isr, Serial::RxIrq); |
Jeej | 26:9f0b9833cac6 | 137 | } |
Jeej | 26:9f0b9833cac6 | 138 | |
Jeej | 26:9f0b9833cac6 | 139 | // Destructor |
Jeej | 26:9f0b9833cac6 | 140 | void d7a_com_close() |
Jeej | 26:9f0b9833cac6 | 141 | { |
Jeej | 26:9f0b9833cac6 | 142 | FPRINT("\r\n"); |
Jeej | 26:9f0b9833cac6 | 143 | g_com_ctx.thread->terminate(); |
Jeej | 26:9f0b9833cac6 | 144 | delete g_com_ctx.data_parsing; |
Jeej | 26:9f0b9833cac6 | 145 | delete g_com_ctx.cts_int; |
Jeej | 26:9f0b9833cac6 | 146 | delete g_com_ctx.serial; |
Jeej | 26:9f0b9833cac6 | 147 | delete g_com_ctx.rts; |
Jeej | 26:9f0b9833cac6 | 148 | delete g_com_ctx.cts; |
Jeej | 26:9f0b9833cac6 | 149 | FREE(g_com_ctx.rx_buffer); |
Jeej | 26:9f0b9833cac6 | 150 | } |
Jeej | 26:9f0b9833cac6 | 151 | |
Jeej | 24:a8433b091764 | 152 | |
Jeej | 24:a8433b091764 | 153 | /** |
Jeej | 24:a8433b091764 | 154 | Wakes-up modem and send data throught Serial. |
Jeej | 24:a8433b091764 | 155 | |
Jeej | 24:a8433b091764 | 156 | @param const uint8_t* Pointer to data buffer |
Jeej | 24:a8433b091764 | 157 | @param int Data length |
Jeej | 24:a8433b091764 | 158 | @return void |
Jeej | 24:a8433b091764 | 159 | */ |
Jeej | 26:9f0b9833cac6 | 160 | static void d7a_com_send(const uint8_t* buffer, int length) |
Jeej | 24:a8433b091764 | 161 | { |
Jeej | 24:a8433b091764 | 162 | int i; |
Jeej | 24:a8433b091764 | 163 | |
Jeej | 24:a8433b091764 | 164 | *(g_com_ctx.rts) = 1; |
Jeej | 24:a8433b091764 | 165 | |
Jeej | 24:a8433b091764 | 166 | Thread::wait(5); |
Jeej | 24:a8433b091764 | 167 | |
Jeej | 24:a8433b091764 | 168 | for (i=0 ; i<length ; i++) |
Jeej | 24:a8433b091764 | 169 | { |
Jeej | 24:a8433b091764 | 170 | g_com_ctx.serial->putc(buffer[i]); |
Jeej | 24:a8433b091764 | 171 | } |
Jeej | 24:a8433b091764 | 172 | |
Jeej | 24:a8433b091764 | 173 | *(g_com_ctx.rts) = 0; |
Jeej | 24:a8433b091764 | 174 | } |
Jeej | 24:a8433b091764 | 175 | |
Jeej | 26:9f0b9833cac6 | 176 | // Formats and send packet throught Serial. |
Jeej | 26:9f0b9833cac6 | 177 | void d7a_com_send_msg(d7a_com_tx_msg_t* msg) |
Jeej | 26:9f0b9833cac6 | 178 | { |
Jeej | 26:9f0b9833cac6 | 179 | FPRINT("\r\n"); |
Jeej | 26:9f0b9833cac6 | 180 | uint8_t* buf; |
Jeej | 26:9f0b9833cac6 | 181 | uint16_t len = msg->alen + msg->plen; |
Jeej | 26:9f0b9833cac6 | 182 | |
Jeej | 26:9f0b9833cac6 | 183 | buf = (uint8_t*)MALLOC(KAL_COM_HEADER_LEN + len); |
Jeej | 26:9f0b9833cac6 | 184 | |
Jeej | 26:9f0b9833cac6 | 185 | // construct serial header |
Jeej | 26:9f0b9833cac6 | 186 | // concatenate and update tx_seq ID |
Jeej | 26:9f0b9833cac6 | 187 | buf[0] = (uint8_t)KAL_COM_SYNC_BYTE_0; |
Jeej | 26:9f0b9833cac6 | 188 | buf[1] = (uint8_t)KAL_COM_SYNC_BYTE_1; |
Jeej | 26:9f0b9833cac6 | 189 | buf[2] = (uint8_t)len; |
Jeej | 26:9f0b9833cac6 | 190 | buf[3] = (uint8_t)g_com_ctx.tx_seq++; |
Jeej | 26:9f0b9833cac6 | 191 | buf[4] = (uint8_t)msg->id; |
Jeej | 26:9f0b9833cac6 | 192 | len += KAL_COM_HEADER_LEN; |
Jeej | 26:9f0b9833cac6 | 193 | |
Jeej | 26:9f0b9833cac6 | 194 | // copy payload and parameters |
Jeej | 26:9f0b9833cac6 | 195 | memcpy(buf + KAL_COM_HEADER_LEN, msg->pbuf, msg->plen); |
Jeej | 26:9f0b9833cac6 | 196 | memcpy(buf + KAL_COM_HEADER_LEN + msg->plen, msg->abuf, msg->alen); |
Jeej | 26:9f0b9833cac6 | 197 | |
Jeej | 26:9f0b9833cac6 | 198 | d7a_com_send(buf, len); |
Jeej | 26:9f0b9833cac6 | 199 | |
Jeej | 26:9f0b9833cac6 | 200 | // Stats |
Jeej | 26:9f0b9833cac6 | 201 | g_com_ctx.tx_pkt_count++; |
Jeej | 26:9f0b9833cac6 | 202 | g_com_ctx.tx_byte_count += len; |
Jeej | 26:9f0b9833cac6 | 203 | |
Jeej | 26:9f0b9833cac6 | 204 | FREE(buf); |
Jeej | 28:0376b97b4b55 | 205 | |
Jeej | 28:0376b97b4b55 | 206 | DPRINT("<-- %d (0x%02X)\r\n", (len - KAL_COM_HEADER_LEN), msg->id); |
Jeej | 26:9f0b9833cac6 | 207 | } |
Jeej | 26:9f0b9833cac6 | 208 | |
Jeej | 26:9f0b9833cac6 | 209 | |
Jeej | 25:aac250164497 | 210 | static void d7a_com_new_pkt(d7a_com_rx_msg_t* pkt) |
Jeej | 25:aac250164497 | 211 | { |
Jeej | 26:9f0b9833cac6 | 212 | //FPRINT("\r\n"); |
Jeej | 25:aac250164497 | 213 | // Distribute packet types to processes |
Jeej | 25:aac250164497 | 214 | switch (KAL_COM_FLOWID(pkt->id)) |
Jeej | 25:aac250164497 | 215 | { |
Jeej | 25:aac250164497 | 216 | case KAL_COM_FLOWID_FS: |
Jeej | 25:aac250164497 | 217 | d7a_fs_new_pkt(pkt); |
Jeej | 25:aac250164497 | 218 | break; |
Jeej | 25:aac250164497 | 219 | case KAL_COM_FLOWID_CMD: |
Jeej | 25:aac250164497 | 220 | d7a_modem_new_pkt(pkt); |
Jeej | 25:aac250164497 | 221 | break; |
Jeej | 25:aac250164497 | 222 | case KAL_COM_FLOWID_SYS: |
Jeej | 25:aac250164497 | 223 | d7a_sys_new_pkt(pkt); |
Jeej | 25:aac250164497 | 224 | break; |
Jeej | 25:aac250164497 | 225 | default: |
Jeej | 25:aac250164497 | 226 | EPRINT("Untreated pkt type 0x%02X\r\n", pkt->id); |
Jeej | 25:aac250164497 | 227 | FREE(pkt); |
Jeej | 25:aac250164497 | 228 | break; |
Jeej | 25:aac250164497 | 229 | } |
Jeej | 25:aac250164497 | 230 | } |
Jeej | 24:a8433b091764 | 231 | |
Jeej | 24:a8433b091764 | 232 | /** |
Jeej | 24:a8433b091764 | 233 | Reads the Rx buffer, parses the packets and adds them to _pkt_queue |
Jeej | 24:a8433b091764 | 234 | |
Jeej | 24:a8433b091764 | 235 | @param void |
Jeej | 24:a8433b091764 | 236 | @return void |
Jeej | 24:a8433b091764 | 237 | */ |
Jeej | 24:a8433b091764 | 238 | static bool parse_packet(const uint16_t start_idx, const uint16_t data_available) |
Jeej | 24:a8433b091764 | 239 | { |
Jeej | 24:a8433b091764 | 240 | uint16_t data_read = 0; |
Jeej | 24:a8433b091764 | 241 | uint8_t data = 0; |
Jeej | 24:a8433b091764 | 242 | uint8_t state = 0; |
Jeej | 24:a8433b091764 | 243 | uint8_t seqnum = 0; |
Jeej | 24:a8433b091764 | 244 | uint8_t len = 0; |
Jeej | 24:a8433b091764 | 245 | uint8_t id = 0; |
Jeej | 24:a8433b091764 | 246 | uint8_t i = 0; |
Jeej | 24:a8433b091764 | 247 | bool pkt_found = false; |
Jeej | 24:a8433b091764 | 248 | |
Jeej | 24:a8433b091764 | 249 | while (data_read < data_available) |
Jeej | 24:a8433b091764 | 250 | { |
Jeej | 24:a8433b091764 | 251 | // do not parse if minimum packet size is not available |
Jeej | 24:a8433b091764 | 252 | if (0 == state && (data_available - data_read) <= KAL_COM_HEADER_LEN) |
Jeej | 24:a8433b091764 | 253 | { |
Jeej | 24:a8433b091764 | 254 | break; |
Jeej | 24:a8433b091764 | 255 | } |
Jeej | 24:a8433b091764 | 256 | |
Jeej | 24:a8433b091764 | 257 | // Pop data |
Jeej | 24:a8433b091764 | 258 | data = g_com_ctx.rx_buffer[(g_com_ctx.read_idx + data_read) % g_com_ctx.rx_buffer_size]; |
Jeej | 24:a8433b091764 | 259 | data_read++; |
Jeej | 24:a8433b091764 | 260 | //DPRINT("Read %d of %d bytes: 0x%02X\r\n", data_read, data_available, data); |
Jeej | 24:a8433b091764 | 261 | |
Jeej | 24:a8433b091764 | 262 | // search first sync byte |
Jeej | 24:a8433b091764 | 263 | if (0 == state && KAL_COM_SYNC_BYTE_0 == data) |
Jeej | 24:a8433b091764 | 264 | { |
Jeej | 24:a8433b091764 | 265 | state++; |
Jeej | 24:a8433b091764 | 266 | } |
Jeej | 24:a8433b091764 | 267 | // look up second sync byte |
Jeej | 24:a8433b091764 | 268 | else if (1 == state && KAL_COM_SYNC_BYTE_1 == data) |
Jeej | 24:a8433b091764 | 269 | { |
Jeej | 24:a8433b091764 | 270 | state++; |
Jeej | 24:a8433b091764 | 271 | } |
Jeej | 24:a8433b091764 | 272 | // look up packet size |
Jeej | 24:a8433b091764 | 273 | else if (2 == state && 0 != data) |
Jeej | 24:a8433b091764 | 274 | { |
Jeej | 24:a8433b091764 | 275 | len = data; |
Jeej | 24:a8433b091764 | 276 | // if not enough data is available |
Jeej | 24:a8433b091764 | 277 | if (data_available < data_read + 1 + 1 + len) // data read + seqnum + id + data length |
Jeej | 24:a8433b091764 | 278 | { |
Jeej | 24:a8433b091764 | 279 | // go back to begining of packet |
Jeej | 24:a8433b091764 | 280 | data_read -= 3; |
Jeej | 24:a8433b091764 | 281 | break; |
Jeej | 24:a8433b091764 | 282 | } |
Jeej | 24:a8433b091764 | 283 | else |
Jeej | 24:a8433b091764 | 284 | { |
Jeej | 24:a8433b091764 | 285 | state++; |
Jeej | 24:a8433b091764 | 286 | } |
Jeej | 24:a8433b091764 | 287 | } |
Jeej | 24:a8433b091764 | 288 | // get seqnum |
Jeej | 24:a8433b091764 | 289 | else if (3 == state) |
Jeej | 24:a8433b091764 | 290 | { |
Jeej | 24:a8433b091764 | 291 | seqnum = data; |
Jeej | 24:a8433b091764 | 292 | if (g_com_ctx.rx_seq != seqnum) |
Jeej | 24:a8433b091764 | 293 | { |
Jeej | 27:934ab7455115 | 294 | WARNING(false, "COM Missing %d seqnum\r\n", g_com_ctx.rx_seq - seqnum); |
Jeej | 24:a8433b091764 | 295 | g_com_ctx.rx_seq = seqnum; |
Jeej | 24:a8433b091764 | 296 | } |
Jeej | 24:a8433b091764 | 297 | |
Jeej | 24:a8433b091764 | 298 | g_com_ctx.rx_seq++; |
Jeej | 24:a8433b091764 | 299 | state++; |
Jeej | 24:a8433b091764 | 300 | } |
Jeej | 24:a8433b091764 | 301 | // get id |
Jeej | 24:a8433b091764 | 302 | else if (4 == state) |
Jeej | 24:a8433b091764 | 303 | { |
Jeej | 24:a8433b091764 | 304 | id = data; |
Jeej | 24:a8433b091764 | 305 | state++; |
Jeej | 24:a8433b091764 | 306 | } |
Jeej | 24:a8433b091764 | 307 | // we got a full packet |
Jeej | 24:a8433b091764 | 308 | else if (5 == state) |
Jeej | 24:a8433b091764 | 309 | { |
Jeej | 25:aac250164497 | 310 | d7a_com_rx_msg_t* pkt = NULL; |
Jeej | 25:aac250164497 | 311 | pkt = (d7a_com_rx_msg_t*)MALLOC(sizeof(d7a_com_rx_msg_t) - 1 + len); |
Jeej | 24:a8433b091764 | 312 | |
Jeej | 24:a8433b091764 | 313 | //DPRINT("Got packet fid %d len %d\r\n", fid, len); |
Jeej | 24:a8433b091764 | 314 | |
Jeej | 24:a8433b091764 | 315 | // copy data to buffer |
Jeej | 25:aac250164497 | 316 | pkt->blen = len; |
Jeej | 24:a8433b091764 | 317 | pkt->id = id; |
Jeej | 24:a8433b091764 | 318 | for (i=0 ; i<len ; i++) |
Jeej | 24:a8433b091764 | 319 | { |
Jeej | 25:aac250164497 | 320 | pkt->buffer[i] = g_com_ctx.rx_buffer[(g_com_ctx.read_idx + data_read + i - 1) % g_com_ctx.rx_buffer_size]; |
Jeej | 24:a8433b091764 | 321 | } |
Jeej | 24:a8433b091764 | 322 | data_read += i - 1; |
Jeej | 24:a8433b091764 | 323 | |
Jeej | 24:a8433b091764 | 324 | // add packet to queue |
Jeej | 26:9f0b9833cac6 | 325 | DPRINT("--> %d (0x%02X)\r\n", pkt->blen, pkt->id); |
Jeej | 25:aac250164497 | 326 | d7a_com_new_pkt(pkt); |
Jeej | 24:a8433b091764 | 327 | |
Jeej | 24:a8433b091764 | 328 | pkt_found = true; |
Jeej | 24:a8433b091764 | 329 | |
Jeej | 24:a8433b091764 | 330 | // Stats |
Jeej | 24:a8433b091764 | 331 | g_com_ctx.rx_pkt_count++; |
Jeej | 24:a8433b091764 | 332 | g_com_ctx.rx_byte_count += (len + KAL_COM_HEADER_LEN); |
Jeej | 24:a8433b091764 | 333 | |
Jeej | 24:a8433b091764 | 334 | break; |
Jeej | 24:a8433b091764 | 335 | } |
Jeej | 24:a8433b091764 | 336 | else |
Jeej | 24:a8433b091764 | 337 | { |
Jeej | 24:a8433b091764 | 338 | // Restart search |
Jeej | 24:a8433b091764 | 339 | state = 0; |
Jeej | 24:a8433b091764 | 340 | } |
Jeej | 24:a8433b091764 | 341 | } |
Jeej | 24:a8433b091764 | 342 | |
Jeej | 24:a8433b091764 | 343 | if (data_read) |
Jeej | 24:a8433b091764 | 344 | { |
Jeej | 24:a8433b091764 | 345 | uint16_t discarded_bytes; |
Jeej | 24:a8433b091764 | 346 | if (pkt_found) |
Jeej | 24:a8433b091764 | 347 | { |
Jeej | 24:a8433b091764 | 348 | // If packet is found, bytes before the packet are discarded |
Jeej | 24:a8433b091764 | 349 | discarded_bytes = data_read - len - KAL_COM_HEADER_LEN; |
Jeej | 24:a8433b091764 | 350 | } |
Jeej | 24:a8433b091764 | 351 | else |
Jeej | 24:a8433b091764 | 352 | { |
Jeej | 24:a8433b091764 | 353 | // Discard all bytes |
Jeej | 24:a8433b091764 | 354 | discarded_bytes = data_read; |
Jeej | 24:a8433b091764 | 355 | } |
Jeej | 24:a8433b091764 | 356 | |
Jeej | 24:a8433b091764 | 357 | if (discarded_bytes) |
Jeej | 24:a8433b091764 | 358 | { |
Jeej | 24:a8433b091764 | 359 | EPRINT("Discarding %d bytes\r\n", discarded_bytes); |
Jeej | 24:a8433b091764 | 360 | for (i=0 ; i<discarded_bytes ; i++) |
Jeej | 24:a8433b091764 | 361 | { |
Jeej | 24:a8433b091764 | 362 | DPRINT("%02X ", g_com_ctx.rx_buffer[(g_com_ctx.read_idx + i) % g_com_ctx.rx_buffer_size]); |
Jeej | 24:a8433b091764 | 363 | } |
Jeej | 24:a8433b091764 | 364 | DPRINT("\r\n"); |
Jeej | 24:a8433b091764 | 365 | } |
Jeej | 24:a8433b091764 | 366 | |
Jeej | 24:a8433b091764 | 367 | // update buffer indexes |
Jeej | 24:a8433b091764 | 368 | g_com_ctx.read_idx = (g_com_ctx.read_idx + data_read) % g_com_ctx.rx_buffer_size; |
Jeej | 24:a8433b091764 | 369 | g_com_ctx.data_available -= data_read; |
Jeej | 24:a8433b091764 | 370 | } |
Jeej | 24:a8433b091764 | 371 | |
Jeej | 24:a8433b091764 | 372 | return pkt_found; |
Jeej | 24:a8433b091764 | 373 | } |
Jeej | 24:a8433b091764 | 374 | |
Jeej | 24:a8433b091764 | 375 | |
Jeej | 24:a8433b091764 | 376 | |
Jeej | 24:a8433b091764 | 377 | |
Jeej | 24:a8433b091764 | 378 | |
Jeej | 24:a8433b091764 | 379 | // Thread for parsing packets from RX buffer. |
Jeej | 25:aac250164497 | 380 | void d7a_com_thread( void const *p ) |
Jeej | 24:a8433b091764 | 381 | { |
Jeej | 25:aac250164497 | 382 | FPRINT("\r\n"); |
Jeej | 24:a8433b091764 | 383 | while (true) |
Jeej | 24:a8433b091764 | 384 | { |
Jeej | 24:a8433b091764 | 385 | // wait for data available |
Jeej | 24:a8433b091764 | 386 | g_com_ctx.data_parsing->wait(); |
Jeej | 24:a8433b091764 | 387 | // search for packets |
Jeej | 24:a8433b091764 | 388 | parse_packet(g_com_ctx.read_idx, g_com_ctx.data_available); |
Jeej | 24:a8433b091764 | 389 | } |
Jeej | 24:a8433b091764 | 390 | } |