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@34:1311cc53201a, 2016-08-22 (annotated)
- Committer:
- Jeej
- Date:
- Mon Aug 22 13:47:39 2016 +0000
- Revision:
- 34:1311cc53201a
- Parent:
- 33:f9a542d3efaa
- Child:
- 35:1fe2975c5a63
Working version with mbed rev 120
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 | 34:1311cc53201a | 10 | |
Jeej | 34:1311cc53201a | 11 | #define XON_SIGNAL 0x0001 |
Jeej | 31:ab9bfdbc6b44 | 12 | |
Jeej | 31:ab9bfdbc6b44 | 13 | typedef struct { |
Jeej | 31:ab9bfdbc6b44 | 14 | uint32_t len; |
Jeej | 31:ab9bfdbc6b44 | 15 | uint8_t* buf; |
Jeej | 31:ab9bfdbc6b44 | 16 | } d7a_com_tx_buf_t; |
Jeej | 30:d775c1409849 | 17 | |
Jeej | 30:d775c1409849 | 18 | |
Jeej | 25:aac250164497 | 19 | typedef struct { |
Jeej | 34:1311cc53201a | 20 | bool started; |
Jeej | 34:1311cc53201a | 21 | |
Jeej | 25:aac250164497 | 22 | DigitalOut* rts; |
Jeej | 25:aac250164497 | 23 | InterruptIn* cts; |
Jeej | 25:aac250164497 | 24 | |
Jeej | 25:aac250164497 | 25 | // RX buffer address |
Jeej | 25:aac250164497 | 26 | uint8_t* rx_buffer; |
Jeej | 25:aac250164497 | 27 | // RX buffer size |
Jeej | 25:aac250164497 | 28 | uint16_t rx_buffer_size; |
Jeej | 25:aac250164497 | 29 | // Write index in RX buffer |
Jeej | 25:aac250164497 | 30 | volatile uint16_t write_idx; |
Jeej | 25:aac250164497 | 31 | // Read index in RX buffer |
Jeej | 25:aac250164497 | 32 | uint16_t read_idx; |
Jeej | 25:aac250164497 | 33 | // Number of bytes available in RX buffer |
Jeej | 25:aac250164497 | 34 | volatile uint16_t data_available; |
Jeej | 33:f9a542d3efaa | 35 | // Last Number of available data |
Jeej | 33:f9a542d3efaa | 36 | volatile uint16_t last_available; |
Jeej | 33:f9a542d3efaa | 37 | // Number of skipped bytes while parsing |
Jeej | 33:f9a542d3efaa | 38 | uint16_t skipped_bytes; |
Jeej | 33:f9a542d3efaa | 39 | |
Jeej | 25:aac250164497 | 40 | // Port TX sequence number |
Jeej | 25:aac250164497 | 41 | uint8_t tx_seq; |
Jeej | 25:aac250164497 | 42 | // Port RX sequence number |
Jeej | 25:aac250164497 | 43 | uint8_t rx_seq; |
Jeej | 25:aac250164497 | 44 | // Response to command maximum time |
Jeej | 25:aac250164497 | 45 | uint32_t timeout; |
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 | 25:aac250164497 | 51 | |
Jeej | 25:aac250164497 | 52 | // Data treatment threads |
Jeej | 31:ab9bfdbc6b44 | 53 | Thread* rx_thread; |
Jeej | 25:aac250164497 | 54 | Serial* serial; |
Jeej | 25:aac250164497 | 55 | |
Jeej | 31:ab9bfdbc6b44 | 56 | // Tx Thread |
Jeej | 31:ab9bfdbc6b44 | 57 | Thread* tx_thread; |
Jeej | 31:ab9bfdbc6b44 | 58 | Queue<d7a_com_tx_buf_t, 32> tx_queue; |
Jeej | 31:ab9bfdbc6b44 | 59 | |
Jeej | 34:1311cc53201a | 60 | Timer tim; |
Jeej | 34:1311cc53201a | 61 | |
Jeej | 25:aac250164497 | 62 | } d7a_com_ctx_t; |
Jeej | 24:a8433b091764 | 63 | |
Jeej | 31:ab9bfdbc6b44 | 64 | |
Jeej | 24:a8433b091764 | 65 | static d7a_com_ctx_t g_com_ctx; |
Jeej | 24:a8433b091764 | 66 | |
Jeej | 24:a8433b091764 | 67 | /** |
Jeej | 24:a8433b091764 | 68 | Thread for parsing packets from RX buffer. |
Jeej | 24:a8433b091764 | 69 | |
Jeej | 24:a8433b091764 | 70 | @param void |
Jeej | 24:a8433b091764 | 71 | @return void |
Jeej | 24:a8433b091764 | 72 | */ |
Jeej | 31:ab9bfdbc6b44 | 73 | void d7a_com_rx_thread( void const *p ); |
Jeej | 31:ab9bfdbc6b44 | 74 | void d7a_com_tx_thread( void const *p ); |
Jeej | 31:ab9bfdbc6b44 | 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 | 34:1311cc53201a | 88 | while (g_com_ctx.serial->readable()) |
Jeej | 34:1311cc53201a | 89 | { |
Jeej | 34:1311cc53201a | 90 | |
Jeej | 24:a8433b091764 | 91 | g_com_ctx.rx_buffer[g_com_ctx.write_idx] = g_com_ctx.serial->getc(); |
Jeej | 34:1311cc53201a | 92 | //PRINT("-"); |
Jeej | 34:1311cc53201a | 93 | |
Jeej | 34:1311cc53201a | 94 | if (g_com_ctx.started) |
Jeej | 34:1311cc53201a | 95 | { |
Jeej | 34:1311cc53201a | 96 | g_com_ctx.data_available++; |
Jeej | 34:1311cc53201a | 97 | |
Jeej | 34:1311cc53201a | 98 | g_com_ctx.write_idx = (g_com_ctx.write_idx >= (g_com_ctx.rx_buffer_size-1))? 0 : g_com_ctx.write_idx+1; |
Jeej | 34:1311cc53201a | 99 | //g_com_ctx.write_idx = (g_com_ctx.write_idx + 1) % g_com_ctx.rx_buffer_size; |
Jeej | 34:1311cc53201a | 100 | } |
Jeej | 24:a8433b091764 | 101 | } |
Jeej | 33:f9a542d3efaa | 102 | |
Jeej | 34:1311cc53201a | 103 | ASSERT(g_com_ctx.data_available <= g_com_ctx.rx_buffer_size, "RX Buffer overflow! (%d/%d)\r\n", g_com_ctx.data_available, g_com_ctx.rx_buffer_size); |
Jeej | 34:1311cc53201a | 104 | |
Jeej | 24:a8433b091764 | 105 | // unlock data parsing thread |
Jeej | 33:f9a542d3efaa | 106 | g_com_ctx.data_parsing->release(); |
Jeej | 24:a8433b091764 | 107 | } |
Jeej | 24:a8433b091764 | 108 | |
Jeej | 24:a8433b091764 | 109 | /** |
Jeej | 24:a8433b091764 | 110 | CTS pin Interrupt Service Routine. |
Jeej | 24:a8433b091764 | 111 | For flow control (not yet inplemented) |
Jeej | 24:a8433b091764 | 112 | |
Jeej | 24:a8433b091764 | 113 | @param void |
Jeej | 24:a8433b091764 | 114 | @return void |
Jeej | 24:a8433b091764 | 115 | */ |
Jeej | 24:a8433b091764 | 116 | void cts_isr() |
Jeej | 24:a8433b091764 | 117 | { |
Jeej | 34:1311cc53201a | 118 | //PRINT("CTS_INT\r\n"); |
Jeej | 34:1311cc53201a | 119 | //g_com_ctx.cts_int->release(); |
Jeej | 24:a8433b091764 | 120 | } |
Jeej | 24:a8433b091764 | 121 | |
Jeej | 26:9f0b9833cac6 | 122 | // D7a_com constructor. |
Jeej | 26:9f0b9833cac6 | 123 | // Opens a serial port and monitors the input for ALP packets. |
Jeej | 26:9f0b9833cac6 | 124 | // Pins are those of the host, not the modem: |
Jeej | 26:9f0b9833cac6 | 125 | // TX-host -> RX-modem |
Jeej | 26:9f0b9833cac6 | 126 | // RX-host <- TX-modem |
Jeej | 26:9f0b9833cac6 | 127 | // RTS-host -> CTS-modem |
Jeej | 26:9f0b9833cac6 | 128 | // CTS-host <- RTS-modem |
Jeej | 26:9f0b9833cac6 | 129 | void d7a_com_open( const d7a_com_config_t* config ) |
Jeej | 26:9f0b9833cac6 | 130 | { |
Jeej | 26:9f0b9833cac6 | 131 | FPRINT("\r\n"); |
Jeej | 26:9f0b9833cac6 | 132 | |
Jeej | 34:1311cc53201a | 133 | g_com_ctx.started = false; |
Jeej | 26:9f0b9833cac6 | 134 | g_com_ctx.rx_buffer_size = config->rx_buffer_size; |
Jeej | 26:9f0b9833cac6 | 135 | g_com_ctx.rx_buffer = (uint8_t*)MALLOC(g_com_ctx.rx_buffer_size); |
Jeej | 26:9f0b9833cac6 | 136 | g_com_ctx.data_available = 0; |
Jeej | 33:f9a542d3efaa | 137 | g_com_ctx.last_available = 0; |
Jeej | 33:f9a542d3efaa | 138 | g_com_ctx.skipped_bytes = 0; |
Jeej | 26:9f0b9833cac6 | 139 | g_com_ctx.write_idx = 0; |
Jeej | 26:9f0b9833cac6 | 140 | g_com_ctx.read_idx = 0; |
Jeej | 26:9f0b9833cac6 | 141 | g_com_ctx.tx_seq = 0; |
Jeej | 26:9f0b9833cac6 | 142 | g_com_ctx.rx_seq = 0; |
Jeej | 26:9f0b9833cac6 | 143 | |
Jeej | 26:9f0b9833cac6 | 144 | g_com_ctx.serial = new Serial(config->tx, config->rx); |
Jeej | 26:9f0b9833cac6 | 145 | g_com_ctx.rts = new DigitalOut(config->rts); |
Jeej | 26:9f0b9833cac6 | 146 | g_com_ctx.cts = new InterruptIn(config->cts); |
Jeej | 34:1311cc53201a | 147 | g_com_ctx.data_parsing = new Semaphore(0); |
Jeej | 34:1311cc53201a | 148 | g_com_ctx.cts_int = new Semaphore(0); |
Jeej | 31:ab9bfdbc6b44 | 149 | |
Jeej | 34:1311cc53201a | 150 | g_com_ctx.cts->rise(&cts_isr); |
Jeej | 34:1311cc53201a | 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 | 34:1311cc53201a | 159 | //g_com_ctx.serial->baud(57600); // 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 | 34:1311cc53201a | 181 | void d7a_com_start(void) |
Jeej | 34:1311cc53201a | 182 | { |
Jeej | 34:1311cc53201a | 183 | FPRINT("\r\n"); |
Jeej | 34:1311cc53201a | 184 | g_com_ctx.started = true; |
Jeej | 34:1311cc53201a | 185 | } |
Jeej | 34:1311cc53201a | 186 | |
Jeej | 34:1311cc53201a | 187 | void d7a_com_restart(void) |
Jeej | 34:1311cc53201a | 188 | { |
Jeej | 34:1311cc53201a | 189 | FPRINT("\r\n"); |
Jeej | 34:1311cc53201a | 190 | g_com_ctx.started = false; |
Jeej | 34:1311cc53201a | 191 | g_com_ctx.data_available = 0; |
Jeej | 34:1311cc53201a | 192 | g_com_ctx.last_available = 0; |
Jeej | 34:1311cc53201a | 193 | g_com_ctx.skipped_bytes = 0; |
Jeej | 34:1311cc53201a | 194 | g_com_ctx.write_idx = 0; |
Jeej | 34:1311cc53201a | 195 | g_com_ctx.read_idx = 0; |
Jeej | 34:1311cc53201a | 196 | g_com_ctx.tx_seq = 0; |
Jeej | 34:1311cc53201a | 197 | g_com_ctx.rx_seq = 0; |
Jeej | 34:1311cc53201a | 198 | |
Jeej | 34:1311cc53201a | 199 | d7a_com_tx_buf_t* msg; |
Jeej | 34:1311cc53201a | 200 | d7a_com_rx_msg_t* pkt; |
Jeej | 34:1311cc53201a | 201 | osEvent evt; |
Jeej | 34:1311cc53201a | 202 | |
Jeej | 34:1311cc53201a | 203 | // Flush TX queue |
Jeej | 34:1311cc53201a | 204 | do |
Jeej | 34:1311cc53201a | 205 | { |
Jeej | 34:1311cc53201a | 206 | // wait for data |
Jeej | 34:1311cc53201a | 207 | evt = g_com_ctx.tx_queue.get(1); |
Jeej | 34:1311cc53201a | 208 | msg = (evt.status == osEventMessage)? (d7a_com_tx_buf_t*)evt.value.p : NULL; |
Jeej | 34:1311cc53201a | 209 | |
Jeej | 34:1311cc53201a | 210 | // free message |
Jeej | 34:1311cc53201a | 211 | if (msg != NULL) |
Jeej | 34:1311cc53201a | 212 | { |
Jeej | 34:1311cc53201a | 213 | FREE(msg->buf); |
Jeej | 34:1311cc53201a | 214 | FREE(msg); |
Jeej | 34:1311cc53201a | 215 | } |
Jeej | 34:1311cc53201a | 216 | } while (msg != NULL); |
Jeej | 34:1311cc53201a | 217 | |
Jeej | 34:1311cc53201a | 218 | // Flush RX |
Jeej | 34:1311cc53201a | 219 | for (int i = 0 ; i < 3 ; i++) |
Jeej | 34:1311cc53201a | 220 | { |
Jeej | 34:1311cc53201a | 221 | do |
Jeej | 34:1311cc53201a | 222 | { |
Jeej | 34:1311cc53201a | 223 | // wait for data |
Jeej | 34:1311cc53201a | 224 | if (i == 0) |
Jeej | 34:1311cc53201a | 225 | { |
Jeej | 34:1311cc53201a | 226 | pkt = d7a_modem_wait_pkt(1); |
Jeej | 34:1311cc53201a | 227 | } |
Jeej | 34:1311cc53201a | 228 | else if (i == 1) |
Jeej | 34:1311cc53201a | 229 | { |
Jeej | 34:1311cc53201a | 230 | pkt = d7a_fs_wait_pkt(1); |
Jeej | 34:1311cc53201a | 231 | } |
Jeej | 34:1311cc53201a | 232 | else |
Jeej | 34:1311cc53201a | 233 | { |
Jeej | 34:1311cc53201a | 234 | pkt = d7a_sys_wait_pkt(1); |
Jeej | 34:1311cc53201a | 235 | } |
Jeej | 34:1311cc53201a | 236 | |
Jeej | 34:1311cc53201a | 237 | // free message |
Jeej | 34:1311cc53201a | 238 | if (pkt != NULL) |
Jeej | 34:1311cc53201a | 239 | { |
Jeej | 34:1311cc53201a | 240 | FREE(pkt); |
Jeej | 34:1311cc53201a | 241 | } |
Jeej | 34:1311cc53201a | 242 | } while (pkt != NULL); |
Jeej | 34:1311cc53201a | 243 | } |
Jeej | 34:1311cc53201a | 244 | |
Jeej | 34:1311cc53201a | 245 | g_com_ctx.started = true; |
Jeej | 34:1311cc53201a | 246 | } |
Jeej | 34:1311cc53201a | 247 | |
Jeej | 34:1311cc53201a | 248 | static void d7a_com_copy_to_linear(uint8_t* linear_buffer, uint16_t read_start, uint16_t length) |
Jeej | 34:1311cc53201a | 249 | { |
Jeej | 34:1311cc53201a | 250 | uint16_t first_part_size; |
Jeej | 34:1311cc53201a | 251 | uint16_t second_part_size; |
Jeej | 34:1311cc53201a | 252 | |
Jeej | 34:1311cc53201a | 253 | ASSERT(length <= g_com_ctx.rx_buffer_size, "Length too long (%d) for buffer size (%d)\r\n", length, g_com_ctx.rx_buffer_size); |
Jeej | 34:1311cc53201a | 254 | |
Jeej | 34:1311cc53201a | 255 | read_start %= g_com_ctx.rx_buffer_size; |
Jeej | 34:1311cc53201a | 256 | first_part_size = (length > (g_com_ctx.rx_buffer_size - read_start))? g_com_ctx.rx_buffer_size - read_start : length; |
Jeej | 34:1311cc53201a | 257 | |
Jeej | 34:1311cc53201a | 258 | memcpy((void*)&linear_buffer[0], (const void*)&g_com_ctx.rx_buffer[read_start], first_part_size); |
Jeej | 34:1311cc53201a | 259 | |
Jeej | 34:1311cc53201a | 260 | // The circular buffer is wrapping |
Jeej | 34:1311cc53201a | 261 | if (length > first_part_size) |
Jeej | 34:1311cc53201a | 262 | { |
Jeej | 34:1311cc53201a | 263 | second_part_size = length - first_part_size; |
Jeej | 34:1311cc53201a | 264 | memcpy((void*)&linear_buffer[first_part_size], (const void*)&g_com_ctx.rx_buffer[0], second_part_size); |
Jeej | 34:1311cc53201a | 265 | } |
Jeej | 34:1311cc53201a | 266 | } |
Jeej | 24:a8433b091764 | 267 | |
Jeej | 24:a8433b091764 | 268 | /** |
Jeej | 24:a8433b091764 | 269 | Wakes-up modem and send data throught Serial. |
Jeej | 24:a8433b091764 | 270 | |
Jeej | 24:a8433b091764 | 271 | @param const uint8_t* Pointer to data buffer |
Jeej | 24:a8433b091764 | 272 | @param int Data length |
Jeej | 24:a8433b091764 | 273 | @return void |
Jeej | 24:a8433b091764 | 274 | */ |
Jeej | 26:9f0b9833cac6 | 275 | static void d7a_com_send(const uint8_t* buffer, int length) |
Jeej | 24:a8433b091764 | 276 | { |
Jeej | 31:ab9bfdbc6b44 | 277 | FPRINT("(len:%d)\r\n", length); |
Jeej | 34:1311cc53201a | 278 | ASSERT(g_com_ctx.started, "COM not started!\r\n"); |
Jeej | 34:1311cc53201a | 279 | |
Jeej | 24:a8433b091764 | 280 | *(g_com_ctx.rts) = 1; |
Jeej | 24:a8433b091764 | 281 | |
Jeej | 31:ab9bfdbc6b44 | 282 | //dbg_print_data("%02X ", (uint8_t*)buffer, length); |
Jeej | 31:ab9bfdbc6b44 | 283 | //DPRINT("\r\n"); |
Jeej | 24:a8433b091764 | 284 | Thread::wait(5); |
Jeej | 24:a8433b091764 | 285 | |
Jeej | 34:1311cc53201a | 286 | for (uint32_t i=0 ; i<length ; i++) |
Jeej | 24:a8433b091764 | 287 | { |
Jeej | 24:a8433b091764 | 288 | g_com_ctx.serial->putc(buffer[i]); |
Jeej | 24:a8433b091764 | 289 | } |
Jeej | 24:a8433b091764 | 290 | |
Jeej | 24:a8433b091764 | 291 | *(g_com_ctx.rts) = 0; |
Jeej | 24:a8433b091764 | 292 | } |
Jeej | 24:a8433b091764 | 293 | |
Jeej | 31:ab9bfdbc6b44 | 294 | |
Jeej | 31:ab9bfdbc6b44 | 295 | static void d7a_com_post_tx(uint8_t* buffer, uint32_t length) |
Jeej | 31:ab9bfdbc6b44 | 296 | { |
Jeej | 31:ab9bfdbc6b44 | 297 | FPRINT("(len:%d)\r\n", length); |
Jeej | 34:1311cc53201a | 298 | ASSERT(g_com_ctx.started, "COM not started!\r\n"); |
Jeej | 34:1311cc53201a | 299 | |
Jeej | 31:ab9bfdbc6b44 | 300 | d7a_com_tx_buf_t* tx_buf = (d7a_com_tx_buf_t*)MALLOC(sizeof(d7a_com_tx_buf_t)); |
Jeej | 31:ab9bfdbc6b44 | 301 | |
Jeej | 31:ab9bfdbc6b44 | 302 | tx_buf->len = length; |
Jeej | 31:ab9bfdbc6b44 | 303 | tx_buf->buf = buffer; |
Jeej | 31:ab9bfdbc6b44 | 304 | |
Jeej | 31:ab9bfdbc6b44 | 305 | g_com_ctx.tx_queue.put(tx_buf); |
Jeej | 31:ab9bfdbc6b44 | 306 | } |
Jeej | 31:ab9bfdbc6b44 | 307 | |
Jeej | 26:9f0b9833cac6 | 308 | // Formats and send packet throught Serial. |
Jeej | 26:9f0b9833cac6 | 309 | void d7a_com_send_msg(d7a_com_tx_msg_t* msg) |
Jeej | 34:1311cc53201a | 310 | { |
Jeej | 34:1311cc53201a | 311 | uint8_t* buf; |
Jeej | 34:1311cc53201a | 312 | uint16_t len = msg->alen + msg->plen; |
Jeej | 34:1311cc53201a | 313 | FPRINT("(len:%d)\r\n", len); |
Jeej | 34:1311cc53201a | 314 | |
Jeej | 34:1311cc53201a | 315 | buf = (uint8_t*)MALLOC(KAL_COM_HEADER_LEN + len); |
Jeej | 34:1311cc53201a | 316 | |
Jeej | 34:1311cc53201a | 317 | // construct serial header |
Jeej | 34:1311cc53201a | 318 | // concatenate and update tx_seq ID |
Jeej | 34:1311cc53201a | 319 | buf[0] = (uint8_t)KAL_COM_SYNC_BYTE_0; |
Jeej | 34:1311cc53201a | 320 | buf[1] = (uint8_t)KAL_COM_SYNC_BYTE_1; |
Jeej | 34:1311cc53201a | 321 | buf[2] = (uint8_t)len; |
Jeej | 34:1311cc53201a | 322 | buf[3] = (uint8_t)g_com_ctx.tx_seq++; |
Jeej | 34:1311cc53201a | 323 | buf[4] = (uint8_t)msg->id; |
Jeej | 34:1311cc53201a | 324 | len += KAL_COM_HEADER_LEN; |
Jeej | 34:1311cc53201a | 325 | |
Jeej | 34:1311cc53201a | 326 | // copy payload and parameters |
Jeej | 34:1311cc53201a | 327 | memcpy(buf + KAL_COM_HEADER_LEN, msg->pbuf, msg->plen); |
Jeej | 34:1311cc53201a | 328 | memcpy(buf + KAL_COM_HEADER_LEN + msg->plen, msg->abuf, msg->alen); |
Jeej | 34:1311cc53201a | 329 | |
Jeej | 34:1311cc53201a | 330 | DPRINT("<-- (0x%02X) %d\r\n", buf[4], (len - KAL_COM_HEADER_LEN)); |
Jeej | 34:1311cc53201a | 331 | |
Jeej | 34:1311cc53201a | 332 | d7a_com_send(buf, len); |
Jeej | 34:1311cc53201a | 333 | } |
Jeej | 34:1311cc53201a | 334 | |
Jeej | 34:1311cc53201a | 335 | void d7a_com_post_msg(d7a_com_tx_msg_t* msg) |
Jeej | 34:1311cc53201a | 336 | { |
Jeej | 26:9f0b9833cac6 | 337 | uint8_t* buf; |
Jeej | 26:9f0b9833cac6 | 338 | uint16_t len = msg->alen + msg->plen; |
Jeej | 30:d775c1409849 | 339 | FPRINT("(len:%d)\r\n", len); |
Jeej | 26:9f0b9833cac6 | 340 | |
Jeej | 26:9f0b9833cac6 | 341 | buf = (uint8_t*)MALLOC(KAL_COM_HEADER_LEN + len); |
Jeej | 26:9f0b9833cac6 | 342 | |
Jeej | 26:9f0b9833cac6 | 343 | // construct serial header |
Jeej | 26:9f0b9833cac6 | 344 | // concatenate and update tx_seq ID |
Jeej | 26:9f0b9833cac6 | 345 | buf[0] = (uint8_t)KAL_COM_SYNC_BYTE_0; |
Jeej | 26:9f0b9833cac6 | 346 | buf[1] = (uint8_t)KAL_COM_SYNC_BYTE_1; |
Jeej | 26:9f0b9833cac6 | 347 | buf[2] = (uint8_t)len; |
Jeej | 26:9f0b9833cac6 | 348 | buf[3] = (uint8_t)g_com_ctx.tx_seq++; |
Jeej | 26:9f0b9833cac6 | 349 | buf[4] = (uint8_t)msg->id; |
Jeej | 26:9f0b9833cac6 | 350 | len += KAL_COM_HEADER_LEN; |
Jeej | 26:9f0b9833cac6 | 351 | |
Jeej | 26:9f0b9833cac6 | 352 | // copy payload and parameters |
Jeej | 26:9f0b9833cac6 | 353 | memcpy(buf + KAL_COM_HEADER_LEN, msg->pbuf, msg->plen); |
Jeej | 26:9f0b9833cac6 | 354 | memcpy(buf + KAL_COM_HEADER_LEN + msg->plen, msg->abuf, msg->alen); |
Jeej | 26:9f0b9833cac6 | 355 | |
Jeej | 31:ab9bfdbc6b44 | 356 | d7a_com_post_tx(buf, len); |
Jeej | 26:9f0b9833cac6 | 357 | } |
Jeej | 26:9f0b9833cac6 | 358 | |
Jeej | 31:ab9bfdbc6b44 | 359 | |
Jeej | 30:d775c1409849 | 360 | void d7a_com_dump(uint8_t* buf, uint8_t len, d7a_com_flow_t flow) |
Jeej | 30:d775c1409849 | 361 | { |
Jeej | 30:d775c1409849 | 362 | d7a_com_tx_msg_t msg; |
Jeej | 30:d775c1409849 | 363 | |
Jeej | 30:d775c1409849 | 364 | msg.id = flow; |
Jeej | 30:d775c1409849 | 365 | msg.pbuf = buf; |
Jeej | 30:d775c1409849 | 366 | msg.plen = len; |
Jeej | 30:d775c1409849 | 367 | msg.alen = 0; |
Jeej | 34:1311cc53201a | 368 | d7a_com_post_msg(&msg); |
Jeej | 30:d775c1409849 | 369 | } |
Jeej | 30:d775c1409849 | 370 | |
Jeej | 34:1311cc53201a | 371 | void d7a_com_force_dump(uint8_t* buf, uint8_t len, d7a_com_flow_t flow) |
Jeej | 33:f9a542d3efaa | 372 | { |
Jeej | 34:1311cc53201a | 373 | d7a_com_tx_msg_t msg; |
Jeej | 34:1311cc53201a | 374 | |
Jeej | 34:1311cc53201a | 375 | msg.id = flow; |
Jeej | 34:1311cc53201a | 376 | msg.pbuf = buf; |
Jeej | 34:1311cc53201a | 377 | msg.plen = len; |
Jeej | 34:1311cc53201a | 378 | msg.alen = 0; |
Jeej | 34:1311cc53201a | 379 | d7a_com_send_msg(&msg); |
Jeej | 33:f9a542d3efaa | 380 | } |
Jeej | 26:9f0b9833cac6 | 381 | |
Jeej | 25:aac250164497 | 382 | static void d7a_com_new_pkt(d7a_com_rx_msg_t* pkt) |
Jeej | 25:aac250164497 | 383 | { |
Jeej | 26:9f0b9833cac6 | 384 | //FPRINT("\r\n"); |
Jeej | 30:d775c1409849 | 385 | if (KAL_COM_FLOWID(pkt->id) != KAL_COM_FLOWID_TRC) |
Jeej | 30:d775c1409849 | 386 | { |
Jeej | 33:f9a542d3efaa | 387 | DPRINT("--> (0x%02X) %d\r\n", pkt->id, pkt->blen); |
Jeej | 30:d775c1409849 | 388 | } |
Jeej | 30:d775c1409849 | 389 | |
Jeej | 25:aac250164497 | 390 | // Distribute packet types to processes |
Jeej | 25:aac250164497 | 391 | switch (KAL_COM_FLOWID(pkt->id)) |
Jeej | 25:aac250164497 | 392 | { |
Jeej | 25:aac250164497 | 393 | case KAL_COM_FLOWID_FS: |
Jeej | 25:aac250164497 | 394 | d7a_fs_new_pkt(pkt); |
Jeej | 25:aac250164497 | 395 | break; |
Jeej | 25:aac250164497 | 396 | case KAL_COM_FLOWID_CMD: |
Jeej | 25:aac250164497 | 397 | d7a_modem_new_pkt(pkt); |
Jeej | 25:aac250164497 | 398 | break; |
Jeej | 25:aac250164497 | 399 | case KAL_COM_FLOWID_SYS: |
Jeej | 30:d775c1409849 | 400 | // This has to be here to avoid going to another process |
Jeej | 30:d775c1409849 | 401 | if (pkt->id == KAL_COM_FLOW_SYS_XON) |
Jeej | 30:d775c1409849 | 402 | { |
Jeej | 34:1311cc53201a | 403 | g_com_ctx.tx_thread->signal_set(XON_SIGNAL); |
Jeej | 30:d775c1409849 | 404 | FREE(pkt); |
Jeej | 30:d775c1409849 | 405 | } |
Jeej | 30:d775c1409849 | 406 | else if (pkt->id == KAL_COM_FLOW_SYS_XOFF) |
Jeej | 30:d775c1409849 | 407 | { |
Jeej | 34:1311cc53201a | 408 | d7a_sys_xack(); |
Jeej | 30:d775c1409849 | 409 | FREE(pkt); |
Jeej | 30:d775c1409849 | 410 | } |
Jeej | 30:d775c1409849 | 411 | else |
Jeej | 30:d775c1409849 | 412 | { |
Jeej | 34:1311cc53201a | 413 | if (KAL_COM_FLOW_SYS_PONG == pkt->id) |
Jeej | 34:1311cc53201a | 414 | { |
Jeej | 34:1311cc53201a | 415 | g_com_ctx.tim.stop(); |
Jeej | 34:1311cc53201a | 416 | uint32_t time_us = g_com_ctx.tim.read_us(); |
Jeej | 34:1311cc53201a | 417 | IPRINT("Ping in %d.%03dms\r\n", time_us/1000, time_us%1000); |
Jeej | 34:1311cc53201a | 418 | } |
Jeej | 30:d775c1409849 | 419 | d7a_sys_new_pkt(pkt); |
Jeej | 30:d775c1409849 | 420 | } |
Jeej | 30:d775c1409849 | 421 | break; |
Jeej | 30:d775c1409849 | 422 | case KAL_COM_FLOWID_TRC: |
Jeej | 31:ab9bfdbc6b44 | 423 | FREE(pkt); |
Jeej | 25:aac250164497 | 424 | break; |
Jeej | 25:aac250164497 | 425 | default: |
Jeej | 25:aac250164497 | 426 | EPRINT("Untreated pkt type 0x%02X\r\n", pkt->id); |
Jeej | 25:aac250164497 | 427 | FREE(pkt); |
Jeej | 25:aac250164497 | 428 | break; |
Jeej | 25:aac250164497 | 429 | } |
Jeej | 25:aac250164497 | 430 | } |
Jeej | 24:a8433b091764 | 431 | |
Jeej | 33:f9a542d3efaa | 432 | |
Jeej | 24:a8433b091764 | 433 | /** |
Jeej | 34:1311cc53201a | 434 | Reads the Rx buffer, parses the packets |
Jeej | 24:a8433b091764 | 435 | |
Jeej | 24:a8433b091764 | 436 | @param void |
Jeej | 24:a8433b091764 | 437 | @return void |
Jeej | 24:a8433b091764 | 438 | */ |
Jeej | 33:f9a542d3efaa | 439 | static void parse_packet(void) |
Jeej | 24:a8433b091764 | 440 | { |
Jeej | 33:f9a542d3efaa | 441 | uint16_t base = 0; |
Jeej | 33:f9a542d3efaa | 442 | uint16_t current = 0; |
Jeej | 33:f9a542d3efaa | 443 | uint8_t byte; |
Jeej | 33:f9a542d3efaa | 444 | |
Jeej | 33:f9a542d3efaa | 445 | // Packet fields |
Jeej | 24:a8433b091764 | 446 | uint8_t seqnum = 0; |
Jeej | 24:a8433b091764 | 447 | uint8_t len = 0; |
Jeej | 24:a8433b091764 | 448 | uint8_t id = 0; |
Jeej | 33:f9a542d3efaa | 449 | |
Jeej | 33:f9a542d3efaa | 450 | // Stats |
Jeej | 33:f9a542d3efaa | 451 | uint16_t nb_pkt = 0; |
Jeej | 33:f9a542d3efaa | 452 | |
Jeej | 33:f9a542d3efaa | 453 | while (g_com_ctx.data_available >= (base + KAL_COM_HEADER_LEN + 1)) |
Jeej | 24:a8433b091764 | 454 | { |
Jeej | 33:f9a542d3efaa | 455 | // Pop data |
Jeej | 33:f9a542d3efaa | 456 | byte = g_com_ctx.rx_buffer[(g_com_ctx.read_idx + (base + current)) % g_com_ctx.rx_buffer_size]; |
Jeej | 34:1311cc53201a | 457 | DPRINT("Treating base %d byte %d of %d: 0x%02X\r\n", base, current, g_com_ctx.data_available, byte); |
Jeej | 33:f9a542d3efaa | 458 | |
Jeej | 33:f9a542d3efaa | 459 | // search first sync byte |
Jeej | 33:f9a542d3efaa | 460 | if (0 == current) |
Jeej | 24:a8433b091764 | 461 | { |
Jeej | 33:f9a542d3efaa | 462 | WARNING(g_com_ctx.skipped_bytes != 1, "COM not sync. Searching for header.\r\n"); |
Jeej | 24:a8433b091764 | 463 | |
Jeej | 33:f9a542d3efaa | 464 | if(KAL_COM_SYNC_BYTE_0 == byte) |
Jeej | 33:f9a542d3efaa | 465 | { |
Jeej | 33:f9a542d3efaa | 466 | current++; |
Jeej | 33:f9a542d3efaa | 467 | } |
Jeej | 33:f9a542d3efaa | 468 | else |
Jeej | 33:f9a542d3efaa | 469 | { |
Jeej | 33:f9a542d3efaa | 470 | // Not a packet. Restart at base + 1 |
Jeej | 33:f9a542d3efaa | 471 | g_com_ctx.skipped_bytes++; |
Jeej | 33:f9a542d3efaa | 472 | base++; |
Jeej | 33:f9a542d3efaa | 473 | } |
Jeej | 24:a8433b091764 | 474 | } |
Jeej | 24:a8433b091764 | 475 | // look up second sync byte |
Jeej | 33:f9a542d3efaa | 476 | else if (1 == current) |
Jeej | 24:a8433b091764 | 477 | { |
Jeej | 33:f9a542d3efaa | 478 | if(KAL_COM_SYNC_BYTE_1 == byte) |
Jeej | 24:a8433b091764 | 479 | { |
Jeej | 33:f9a542d3efaa | 480 | current++; |
Jeej | 24:a8433b091764 | 481 | } |
Jeej | 24:a8433b091764 | 482 | else |
Jeej | 24:a8433b091764 | 483 | { |
Jeej | 33:f9a542d3efaa | 484 | // Not a packet. Restart at base + 1 |
Jeej | 33:f9a542d3efaa | 485 | g_com_ctx.skipped_bytes++; |
Jeej | 33:f9a542d3efaa | 486 | base++; |
Jeej | 33:f9a542d3efaa | 487 | current = 0; |
Jeej | 24:a8433b091764 | 488 | } |
Jeej | 33:f9a542d3efaa | 489 | } |
Jeej | 33:f9a542d3efaa | 490 | // look up packet size |
Jeej | 33:f9a542d3efaa | 491 | else if (2 == current) |
Jeej | 33:f9a542d3efaa | 492 | { |
Jeej | 33:f9a542d3efaa | 493 | len = byte; |
Jeej | 33:f9a542d3efaa | 494 | // if not enough data is available |
Jeej | 34:1311cc53201a | 495 | if (g_com_ctx.data_available < (KAL_COM_HEADER_LEN + len + base)) |
Jeej | 33:f9a542d3efaa | 496 | { |
Jeej | 33:f9a542d3efaa | 497 | // exit parser |
Jeej | 34:1311cc53201a | 498 | DPRINT("len exit\r\n"); |
Jeej | 33:f9a542d3efaa | 499 | break; |
Jeej | 33:f9a542d3efaa | 500 | } |
Jeej | 33:f9a542d3efaa | 501 | |
Jeej | 33:f9a542d3efaa | 502 | current++; |
Jeej | 24:a8433b091764 | 503 | } |
Jeej | 24:a8433b091764 | 504 | // get seqnum |
Jeej | 33:f9a542d3efaa | 505 | else if (3 == current) |
Jeej | 33:f9a542d3efaa | 506 | { |
Jeej | 33:f9a542d3efaa | 507 | seqnum = byte; |
Jeej | 33:f9a542d3efaa | 508 | current++; |
Jeej | 33:f9a542d3efaa | 509 | } |
Jeej | 33:f9a542d3efaa | 510 | // get id |
Jeej | 33:f9a542d3efaa | 511 | else if (4 == current) |
Jeej | 24:a8433b091764 | 512 | { |
Jeej | 33:f9a542d3efaa | 513 | id = byte; |
Jeej | 33:f9a542d3efaa | 514 | current++; |
Jeej | 33:f9a542d3efaa | 515 | } |
Jeej | 33:f9a542d3efaa | 516 | // we got a full packet |
Jeej | 33:f9a542d3efaa | 517 | else if (5 == current) |
Jeej | 33:f9a542d3efaa | 518 | { |
Jeej | 33:f9a542d3efaa | 519 | if (g_com_ctx.skipped_bytes) |
Jeej | 33:f9a542d3efaa | 520 | { |
Jeej | 33:f9a542d3efaa | 521 | WARNING(false, "COM header found, skipped %d bytes.\r\n", g_com_ctx.skipped_bytes); |
Jeej | 34:1311cc53201a | 522 | #if 1 |
Jeej | 34:1311cc53201a | 523 | uint8_t* temp = (uint8_t*)MALLOC(g_com_ctx.skipped_bytes); |
Jeej | 34:1311cc53201a | 524 | d7a_com_copy_to_linear(temp, g_com_ctx.read_idx + (base - g_com_ctx.skipped_bytes), g_com_ctx.skipped_bytes); |
Jeej | 34:1311cc53201a | 525 | PRINT_DATA("", "%02X ", temp, g_com_ctx.skipped_bytes, "\r\n"); |
Jeej | 34:1311cc53201a | 526 | FREE(temp); |
Jeej | 34:1311cc53201a | 527 | #endif |
Jeej | 33:f9a542d3efaa | 528 | g_com_ctx.skipped_bytes = 0; |
Jeej | 33:f9a542d3efaa | 529 | } |
Jeej | 33:f9a542d3efaa | 530 | |
Jeej | 33:f9a542d3efaa | 531 | // Update seqnum |
Jeej | 34:1311cc53201a | 532 | WARNING(g_com_ctx.rx_seq == seqnum, "COM Bad seqnum expected:%d got:%d (base:%d curr:%d avail:%d read:%d)\r\n", |
Jeej | 34:1311cc53201a | 533 | g_com_ctx.rx_seq, seqnum, base, current, g_com_ctx.data_available, g_com_ctx.read_idx); |
Jeej | 34:1311cc53201a | 534 | |
Jeej | 34:1311cc53201a | 535 | g_com_ctx.rx_seq = seqnum + 1; |
Jeej | 33:f9a542d3efaa | 536 | |
Jeej | 33:f9a542d3efaa | 537 | nb_pkt++; |
Jeej | 33:f9a542d3efaa | 538 | |
Jeej | 34:1311cc53201a | 539 | //DPRINT("Got packet id 0x%02X len %d\r\n", id, len); |
Jeej | 34:1311cc53201a | 540 | |
Jeej | 31:ab9bfdbc6b44 | 541 | if (KAL_COM_FLOWID(id) != KAL_COM_FLOWID_TRC) |
Jeej | 24:a8433b091764 | 542 | { |
Jeej | 31:ab9bfdbc6b44 | 543 | d7a_com_rx_msg_t* pkt = NULL; |
Jeej | 31:ab9bfdbc6b44 | 544 | pkt = (d7a_com_rx_msg_t*)MALLOC(sizeof(d7a_com_rx_msg_t) - 1 + len); |
Jeej | 31:ab9bfdbc6b44 | 545 | |
Jeej | 31:ab9bfdbc6b44 | 546 | // copy data to buffer |
Jeej | 31:ab9bfdbc6b44 | 547 | pkt->blen = len; |
Jeej | 31:ab9bfdbc6b44 | 548 | pkt->id = id; |
Jeej | 34:1311cc53201a | 549 | d7a_com_copy_to_linear(pkt->buffer, g_com_ctx.read_idx + (base + current), len); |
Jeej | 31:ab9bfdbc6b44 | 550 | |
Jeej | 31:ab9bfdbc6b44 | 551 | // add packet to queue |
Jeej | 31:ab9bfdbc6b44 | 552 | d7a_com_new_pkt(pkt); |
Jeej | 24:a8433b091764 | 553 | } |
Jeej | 31:ab9bfdbc6b44 | 554 | else |
Jeej | 31:ab9bfdbc6b44 | 555 | { |
Jeej | 33:f9a542d3efaa | 556 | // Ignore packet |
Jeej | 31:ab9bfdbc6b44 | 557 | } |
Jeej | 33:f9a542d3efaa | 558 | |
Jeej | 33:f9a542d3efaa | 559 | // Search next packet |
Jeej | 34:1311cc53201a | 560 | base += current + len; |
Jeej | 33:f9a542d3efaa | 561 | current = 0; |
Jeej | 24:a8433b091764 | 562 | } |
Jeej | 24:a8433b091764 | 563 | else |
Jeej | 24:a8433b091764 | 564 | { |
Jeej | 33:f9a542d3efaa | 565 | ASSERT(false, "D7A COM parser!\r\n"); |
Jeej | 24:a8433b091764 | 566 | } |
Jeej | 24:a8433b091764 | 567 | } |
Jeej | 33:f9a542d3efaa | 568 | |
Jeej | 33:f9a542d3efaa | 569 | // update buffer indexes |
Jeej | 33:f9a542d3efaa | 570 | g_com_ctx.read_idx = (g_com_ctx.read_idx + base) % g_com_ctx.rx_buffer_size; |
Jeej | 33:f9a542d3efaa | 571 | g_com_ctx.data_available -= base; |
Jeej | 33:f9a542d3efaa | 572 | |
Jeej | 33:f9a542d3efaa | 573 | if (base) { |
Jeej | 33:f9a542d3efaa | 574 | DPRINT("Parsed %d bytes of %d (%d packets)\r\n", base, g_com_ctx.data_available + base, nb_pkt); |
Jeej | 24:a8433b091764 | 575 | } |
Jeej | 24:a8433b091764 | 576 | } |
Jeej | 24:a8433b091764 | 577 | |
Jeej | 24:a8433b091764 | 578 | |
Jeej | 24:a8433b091764 | 579 | // Thread for parsing packets from RX buffer. |
Jeej | 31:ab9bfdbc6b44 | 580 | void d7a_com_rx_thread( void const *p ) |
Jeej | 24:a8433b091764 | 581 | { |
Jeej | 25:aac250164497 | 582 | FPRINT("\r\n"); |
Jeej | 24:a8433b091764 | 583 | while (true) |
Jeej | 24:a8433b091764 | 584 | { |
Jeej | 24:a8433b091764 | 585 | // wait for data available |
Jeej | 24:a8433b091764 | 586 | g_com_ctx.data_parsing->wait(); |
Jeej | 24:a8433b091764 | 587 | // search for packets |
Jeej | 33:f9a542d3efaa | 588 | if ((g_com_ctx.last_available != g_com_ctx.data_available) && (g_com_ctx.data_available >= (KAL_COM_HEADER_LEN + 1))) |
Jeej | 33:f9a542d3efaa | 589 | { |
Jeej | 33:f9a542d3efaa | 590 | g_com_ctx.last_available = g_com_ctx.data_available; |
Jeej | 33:f9a542d3efaa | 591 | parse_packet(); |
Jeej | 33:f9a542d3efaa | 592 | } |
Jeej | 24:a8433b091764 | 593 | } |
Jeej | 24:a8433b091764 | 594 | } |
Jeej | 31:ab9bfdbc6b44 | 595 | |
Jeej | 31:ab9bfdbc6b44 | 596 | void d7a_com_tx_thread( void const *p ) |
Jeej | 31:ab9bfdbc6b44 | 597 | { |
Jeej | 31:ab9bfdbc6b44 | 598 | FPRINT("\r\n"); |
Jeej | 31:ab9bfdbc6b44 | 599 | |
Jeej | 31:ab9bfdbc6b44 | 600 | d7a_com_tx_buf_t* msg; |
Jeej | 31:ab9bfdbc6b44 | 601 | osEvent evt; |
Jeej | 34:1311cc53201a | 602 | uint8_t flow_id; |
Jeej | 34:1311cc53201a | 603 | |
Jeej | 31:ab9bfdbc6b44 | 604 | while (true) |
Jeej | 31:ab9bfdbc6b44 | 605 | { |
Jeej | 31:ab9bfdbc6b44 | 606 | // wait for data to send |
Jeej | 31:ab9bfdbc6b44 | 607 | evt = g_com_ctx.tx_queue.get(); |
Jeej | 31:ab9bfdbc6b44 | 608 | msg = (evt.status == osEventMessage)? (d7a_com_tx_buf_t*)evt.value.p : NULL; |
Jeej | 31:ab9bfdbc6b44 | 609 | |
Jeej | 31:ab9bfdbc6b44 | 610 | // send message |
Jeej | 31:ab9bfdbc6b44 | 611 | if (msg != NULL) |
Jeej | 31:ab9bfdbc6b44 | 612 | { |
Jeej | 34:1311cc53201a | 613 | flow_id = msg->buf[4]; |
Jeej | 34:1311cc53201a | 614 | DPRINT("<-- (0x%02X) %d\r\n", flow_id, (msg->len - KAL_COM_HEADER_LEN)); |
Jeej | 34:1311cc53201a | 615 | |
Jeej | 31:ab9bfdbc6b44 | 616 | d7a_com_send(msg->buf, msg->len); |
Jeej | 31:ab9bfdbc6b44 | 617 | FREE(msg->buf); |
Jeej | 31:ab9bfdbc6b44 | 618 | FREE(msg); |
Jeej | 34:1311cc53201a | 619 | |
Jeej | 34:1311cc53201a | 620 | if (KAL_COM_FLOW_SYS_PING == flow_id) |
Jeej | 34:1311cc53201a | 621 | { |
Jeej | 34:1311cc53201a | 622 | g_com_ctx.tim.reset(); |
Jeej | 34:1311cc53201a | 623 | g_com_ctx.tim.start(); |
Jeej | 34:1311cc53201a | 624 | } |
Jeej | 34:1311cc53201a | 625 | |
Jeej | 34:1311cc53201a | 626 | if (KAL_COM_FLOW_SYS_XACK == flow_id) |
Jeej | 34:1311cc53201a | 627 | { |
Jeej | 34:1311cc53201a | 628 | DPRINT("XOFF\r\n"); |
Jeej | 34:1311cc53201a | 629 | g_com_ctx.tx_thread->signal_wait(XON_SIGNAL); |
Jeej | 34:1311cc53201a | 630 | DPRINT("XON\r\n"); |
Jeej | 34:1311cc53201a | 631 | } |
Jeej | 31:ab9bfdbc6b44 | 632 | } |
Jeej | 31:ab9bfdbc6b44 | 633 | } |
Jeej | 31:ab9bfdbc6b44 | 634 | } |