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