WizziLab's serial protocol library

Dependents:   modem_ref_helper_for_v5_3_217 modem_ref_helper

Committer:
Jeej
Date:
Fri Feb 19 10:59:27 2021 +0000
Revision:
12:9edd3fd978d2
Parent:
11:9b623641fd85
Child:
13:a3997e6aea6e
Removed debug

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Jeej 0:95b73d0b37b7 1 #include "WizziCom.h"
Jeej 0:95b73d0b37b7 2
Jeej 3:230cb1ea9702 3 #if 0
Jeej 3:230cb1ea9702 4 #define COM_DPRINT(...) PRINT(__VA_ARGS__)
Jeej 3:230cb1ea9702 5 #define COM_DPRINT_DATA(...) PRINT_DATA(__VA_ARGS__)
Jeej 0:95b73d0b37b7 6 #define COM_FPRINT(...) FPRINT(__VA_ARGS__)
Jeej 0:95b73d0b37b7 7 #else
Jeej 0:95b73d0b37b7 8 #define COM_DPRINT(...);
Jeej 0:95b73d0b37b7 9 #define COM_DPRINT_DATA(...);
Jeej 0:95b73d0b37b7 10 #define COM_FPRINT(...);
Jeej 0:95b73d0b37b7 11 #endif
Jeej 0:95b73d0b37b7 12
Jeej 0:95b73d0b37b7 13 #define XON_SIGNAL (0x0001 << 0)
Jeej 0:95b73d0b37b7 14 #define START_SIGNAL (0x0001 << 1)
Jeej 0:95b73d0b37b7 15
Jeej 0:95b73d0b37b7 16 // +--------------+--------+--------+--------+---- - - - - - - - - - - --------+
Jeej 0:95b73d0b37b7 17 // | SYNC | LEN | SEQ | ID | PAYLOAD |
Jeej 0:95b73d0b37b7 18 // +--------------+--------+--------+--------+---- - - - - - - - - - - --------+
Jeej 0:95b73d0b37b7 19 //
Jeej 0:95b73d0b37b7 20 // 2 bytes 1 byte 1 byte 1 byte LEN bytes
Jeej 0:95b73d0b37b7 21 // |<------------>|<------>|<------>|<------>|<--- - - - - - - - - - - ------->|
Jeej 0:95b73d0b37b7 22
Jeej 0:95b73d0b37b7 23
Jeej 0:95b73d0b37b7 24 // first byte of the sync word
Jeej 0:95b73d0b37b7 25 // (ASCII start of heading)
Jeej 0:95b73d0b37b7 26 #define KAL_COM_SYNC_BYTE_0 0x01
Jeej 0:95b73d0b37b7 27
Jeej 0:95b73d0b37b7 28 // second byte of the sync word
Jeej 0:95b73d0b37b7 29 // (ASCII group separator)
Jeej 0:95b73d0b37b7 30 #define KAL_COM_SYNC_BYTE_1 0x1F
Jeej 0:95b73d0b37b7 31
Jeej 0:95b73d0b37b7 32
Jeej 0:95b73d0b37b7 33 //======================================================================
Jeej 0:95b73d0b37b7 34 // wizzi_com_fid_t
Jeej 0:95b73d0b37b7 35 //----------------------------------------------------------------------
Jeej 0:95b73d0b37b7 36 // Enumerator of serial Flow-ids
Jeej 0:95b73d0b37b7 37 //======================================================================
Jeej 0:95b73d0b37b7 38 typedef enum
Jeej 0:95b73d0b37b7 39 {
Jeej 0:95b73d0b37b7 40 // Trace channel
Jeej 0:95b73d0b37b7 41 KAL_COM_FLOWID_TRC = 0,
Jeej 0:95b73d0b37b7 42 // General purpose Command channel
Jeej 0:95b73d0b37b7 43 KAL_COM_FLOWID_CMD,
Jeej 0:95b73d0b37b7 44 // ALP channel
Jeej 0:95b73d0b37b7 45 KAL_COM_FLOWID_ALP,
Jeej 0:95b73d0b37b7 46 // System notifications
Jeej 0:95b73d0b37b7 47 KAL_COM_FLOWID_SYS,
Jeej 0:95b73d0b37b7 48 // File System channel
Jeej 0:95b73d0b37b7 49 KAL_COM_FLOWID_FS,
Jeej 0:95b73d0b37b7 50
Jeej 0:95b73d0b37b7 51 KAL_COM_FLOWID_QTY
Jeej 0:95b73d0b37b7 52
Jeej 0:95b73d0b37b7 53 } wizzi_com_fid_t;
Jeej 0:95b73d0b37b7 54
Jeej 0:95b73d0b37b7 55 #define KAL_COM_FLOW(fid,type) ((((fid)&0x7)<<4) | ((type)&0xF))
Jeej 0:95b73d0b37b7 56 #define KAL_COM_FLOWID(id) (((id)>>4)&0x7)
Jeej 0:95b73d0b37b7 57 #define KAL_COM_FLOWID_REDIRECT 0x80
Jeej 0:95b73d0b37b7 58
Jeej 0:95b73d0b37b7 59 //======================================================================
Jeej 0:95b73d0b37b7 60 // wizzi_com_flow_t
Jeej 0:95b73d0b37b7 61 //----------------------------------------------------------------------
Jeej 0:95b73d0b37b7 62 // Enumerator of serial flows
Jeej 0:95b73d0b37b7 63 //======================================================================
Jeej 0:95b73d0b37b7 64 typedef enum
Jeej 0:95b73d0b37b7 65 {
Jeej 0:95b73d0b37b7 66 // Default printf type
Jeej 0:95b73d0b37b7 67 KAL_COM_FLOW_PRINTF = KAL_COM_FLOW(KAL_COM_FLOWID_TRC,0),
Jeej 0:95b73d0b37b7 68 // Substitute the string by a codeword
Jeej 0:95b73d0b37b7 69 // interpreted by the PC com tool
Jeej 0:95b73d0b37b7 70 KAL_COM_FLOW_PRINTF_COMPRESSED = KAL_COM_FLOW(KAL_COM_FLOWID_TRC,1),
Jeej 0:95b73d0b37b7 71 // Display the payload as hex data
Jeej 0:95b73d0b37b7 72 KAL_COM_FLOW_PRINT_HEX = KAL_COM_FLOW(KAL_COM_FLOWID_TRC,2),
Jeej 0:95b73d0b37b7 73
Jeej 0:95b73d0b37b7 74 // AT command
Jeej 0:95b73d0b37b7 75 KAL_COM_FLOW_AT_CMD = KAL_COM_FLOW(KAL_COM_FLOWID_ALP,0),
Jeej 0:95b73d0b37b7 76 // AT command response
Jeej 0:95b73d0b37b7 77 KAL_COM_FLOW_AT_RESP = KAL_COM_FLOW(KAL_COM_FLOWID_ALP,1),
Jeej 0:95b73d0b37b7 78 // AT unsolicited message
Jeej 0:95b73d0b37b7 79 KAL_COM_FLOW_AT_UNS = KAL_COM_FLOW(KAL_COM_FLOWID_ALP,2),
Jeej 0:95b73d0b37b7 80 // AT unsolicited error
Jeej 0:95b73d0b37b7 81 KAL_COM_FLOW_AT_ERR = KAL_COM_FLOW(KAL_COM_FLOWID_ALP,3),
Jeej 0:95b73d0b37b7 82
Jeej 0:95b73d0b37b7 83 // Remote Commands
Jeej 0:95b73d0b37b7 84 KAL_COM_FLOW_CMD = KAL_COM_FLOW(KAL_COM_FLOWID_CMD,0),
Jeej 0:95b73d0b37b7 85
Jeej 0:95b73d0b37b7 86 // Remote System reset
Jeej 0:95b73d0b37b7 87 KAL_COM_FLOW_SYS_RST = KAL_COM_FLOW(KAL_COM_FLOWID_SYS,0),
Jeej 0:95b73d0b37b7 88 // Button Emulator
Jeej 0:95b73d0b37b7 89 KAL_COM_FLOW_SYS_BUTTON = KAL_COM_FLOW(KAL_COM_FLOWID_SYS,1),
Jeej 0:95b73d0b37b7 90 // Dump Debug parameters
Jeej 0:95b73d0b37b7 91 KAL_COM_FLOW_SYS_INFO = KAL_COM_FLOW(KAL_COM_FLOWID_SYS,2),
Jeej 0:95b73d0b37b7 92 // CUP signalisation
Jeej 0:95b73d0b37b7 93 KAL_COM_FLOW_SYS_CUP = KAL_COM_FLOW(KAL_COM_FLOWID_SYS,3),
Jeej 0:95b73d0b37b7 94 // Ping distant COM
Jeej 0:95b73d0b37b7 95 KAL_COM_FLOW_SYS_PING = KAL_COM_FLOW(KAL_COM_FLOWID_SYS,4),
Jeej 0:95b73d0b37b7 96 // Pong from distant COM
Jeej 0:95b73d0b37b7 97 KAL_COM_FLOW_SYS_PONG = KAL_COM_FLOW(KAL_COM_FLOWID_SYS,5),
Jeej 0:95b73d0b37b7 98 // Enable system config from distant COM
Jeej 0:95b73d0b37b7 99 KAL_COM_FLOW_SYS_CFG = KAL_COM_FLOW(KAL_COM_FLOWID_SYS,6),
Jeej 0:95b73d0b37b7 100 // Configure Output Trace level from distant COM
Jeej 0:95b73d0b37b7 101 KAL_COM_FLOW_SYS_TLEV = KAL_COM_FLOW(KAL_COM_FLOWID_SYS,7),
Jeej 0:95b73d0b37b7 102 // Configure COM port redirection
Jeej 0:95b73d0b37b7 103 KAL_COM_FLOW_SYS_REDIR = KAL_COM_FLOW(KAL_COM_FLOWID_SYS,8),
Jeej 0:95b73d0b37b7 104 // Flow control signalling
Jeej 0:95b73d0b37b7 105 KAL_COM_FLOW_SYS_XON = KAL_COM_FLOW(KAL_COM_FLOWID_SYS,9),
Jeej 0:95b73d0b37b7 106 KAL_COM_FLOW_SYS_XOFF = KAL_COM_FLOW(KAL_COM_FLOWID_SYS,10),
Jeej 0:95b73d0b37b7 107 KAL_COM_FLOW_SYS_XACK = KAL_COM_FLOW(KAL_COM_FLOWID_SYS,11),
Jeej 0:95b73d0b37b7 108
Jeej 0:95b73d0b37b7 109 // File System Command/Response
Jeej 0:95b73d0b37b7 110 KAL_COM_FLOW_FS_CMD = KAL_COM_FLOW(KAL_COM_FLOWID_FS,0),
Jeej 0:95b73d0b37b7 111 KAL_COM_FLOW_FS_RESP = KAL_COM_FLOW(KAL_COM_FLOWID_FS,1),
Jeej 0:95b73d0b37b7 112
Jeej 0:95b73d0b37b7 113 } wizzi_com_flow_t;
Jeej 0:95b73d0b37b7 114
Jeej 0:95b73d0b37b7 115
Jeej 0:95b73d0b37b7 116
Jeej 0:95b73d0b37b7 117
Jeej 0:95b73d0b37b7 118 enum {
Jeej 0:95b73d0b37b7 119 SEARCH_HEADER,
Jeej 0:95b73d0b37b7 120 SEARCH_BODY,
Jeej 0:95b73d0b37b7 121 };
Jeej 0:95b73d0b37b7 122
Jeej 0:95b73d0b37b7 123 void wizzi_com_rx_thread();
Jeej 0:95b73d0b37b7 124 void wizzi_com_tx_thread();
Jeej 0:95b73d0b37b7 125
Jeej 0:95b73d0b37b7 126 const uint8_t g_type_to_flow[WIZZICOM_PKT_QTY] = {
Jeej 0:95b73d0b37b7 127 // Default printf type
Jeej 0:95b73d0b37b7 128 KAL_COM_FLOW_PRINTF,
Jeej 0:95b73d0b37b7 129 // Substitute the string by a codeword
Jeej 0:95b73d0b37b7 130 // interpreted by the PC com tool
Jeej 0:95b73d0b37b7 131 KAL_COM_FLOW_PRINTF_COMPRESSED,
Jeej 0:95b73d0b37b7 132 // Display the payload as hex data
Jeej 0:95b73d0b37b7 133 KAL_COM_FLOW_PRINT_HEX,
Jeej 0:95b73d0b37b7 134
Jeej 0:95b73d0b37b7 135 // AT command
Jeej 0:95b73d0b37b7 136 KAL_COM_FLOW_AT_CMD,
Jeej 0:95b73d0b37b7 137 // AT command response
Jeej 0:95b73d0b37b7 138 KAL_COM_FLOW_AT_RESP,
Jeej 0:95b73d0b37b7 139 // AT unsolicited message
Jeej 0:95b73d0b37b7 140 KAL_COM_FLOW_AT_UNS,
Jeej 0:95b73d0b37b7 141 // AT unsolicited error
Jeej 0:95b73d0b37b7 142 KAL_COM_FLOW_AT_ERR,
Jeej 0:95b73d0b37b7 143
Jeej 0:95b73d0b37b7 144 // Remote Commands
Jeej 0:95b73d0b37b7 145 KAL_COM_FLOW_CMD,
Jeej 0:95b73d0b37b7 146
Jeej 0:95b73d0b37b7 147 // Remote System reset
Jeej 0:95b73d0b37b7 148 KAL_COM_FLOW_SYS_RST,
Jeej 0:95b73d0b37b7 149 // Button Emulator
Jeej 0:95b73d0b37b7 150 KAL_COM_FLOW_SYS_BUTTON,
Jeej 0:95b73d0b37b7 151 // Dump Debug parameters
Jeej 0:95b73d0b37b7 152 KAL_COM_FLOW_SYS_INFO,
Jeej 0:95b73d0b37b7 153 // CUP signalisation
Jeej 0:95b73d0b37b7 154 KAL_COM_FLOW_SYS_CUP,
Jeej 0:95b73d0b37b7 155 // Ping distant COM
Jeej 0:95b73d0b37b7 156 KAL_COM_FLOW_SYS_PING,
Jeej 0:95b73d0b37b7 157 // Pong from distant COM
Jeej 0:95b73d0b37b7 158 KAL_COM_FLOW_SYS_PONG,
Jeej 0:95b73d0b37b7 159 // Enable system config from distant COM
Jeej 0:95b73d0b37b7 160 KAL_COM_FLOW_SYS_CFG,
Jeej 0:95b73d0b37b7 161 // Configure Output Trace level from distant COM
Jeej 0:95b73d0b37b7 162 KAL_COM_FLOW_SYS_TLEV,
Jeej 0:95b73d0b37b7 163 // Configure COM port redirection
Jeej 0:95b73d0b37b7 164 KAL_COM_FLOW_SYS_REDIR,
Jeej 0:95b73d0b37b7 165 // Flow control signalling
Jeej 0:95b73d0b37b7 166 KAL_COM_FLOW_SYS_XON,
Jeej 0:95b73d0b37b7 167 KAL_COM_FLOW_SYS_XOFF,
Jeej 0:95b73d0b37b7 168 KAL_COM_FLOW_SYS_XACK,
Jeej 0:95b73d0b37b7 169
Jeej 0:95b73d0b37b7 170 // File System Command/Response
Jeej 0:95b73d0b37b7 171 KAL_COM_FLOW_FS_CMD,
Jeej 0:95b73d0b37b7 172 KAL_COM_FLOW_FS_RESP
Jeej 0:95b73d0b37b7 173 };
Jeej 0:95b73d0b37b7 174
Jeej 1:ca1c9bfb1cf4 175 uint8_t wizzicom_type_to_flow(uint8_t packet_type)
Jeej 1:ca1c9bfb1cf4 176 {
Jeej 1:ca1c9bfb1cf4 177 return g_type_to_flow[packet_type];
Jeej 1:ca1c9bfb1cf4 178 }
Jeej 1:ca1c9bfb1cf4 179
Jeej 1:ca1c9bfb1cf4 180 uint8_t wizzicom_flow_to_type(uint8_t flow_id)
Jeej 1:ca1c9bfb1cf4 181 {
Jeej 1:ca1c9bfb1cf4 182 // Get packet type from flow_id
Jeej 1:ca1c9bfb1cf4 183 uint8_t packet_type = 0;
Jeej 1:ca1c9bfb1cf4 184 while ((g_type_to_flow[packet_type] != flow_id) && (packet_type < WIZZICOM_PKT_QTY))
Jeej 1:ca1c9bfb1cf4 185 {
Jeej 1:ca1c9bfb1cf4 186 packet_type++;
Jeej 1:ca1c9bfb1cf4 187 }
Jeej 1:ca1c9bfb1cf4 188 return packet_type;
Jeej 1:ca1c9bfb1cf4 189 }
Jeej 1:ca1c9bfb1cf4 190
Jeej 0:95b73d0b37b7 191 WizziCom::WizziCom(PinName tx, PinName rx, PinName irq_out, PinName irq_in) :
Jeej 8:42e00820df36 192 _tx_done(0),
Jeej 8:42e00820df36 193 _rx_done(0),
Jeej 0:95b73d0b37b7 194 _irq_in_int(0),
Jeej 2:6a00ed67fe29 195 _rx_thread(osPriorityHigh, 512, NULL),
Jeej 0:95b73d0b37b7 196 _tx_thread(osPriorityHigh, 512, NULL),
Jeej 2:6a00ed67fe29 197 _callback_thread(osPriorityRealtime, 1024, NULL)
Jeej 0:95b73d0b37b7 198 {
Jeej 0:95b73d0b37b7 199 _tx_seq = 0;
Jeej 0:95b73d0b37b7 200 _rx_seq = 0;
Jeej 0:95b73d0b37b7 201
Jeej 0:95b73d0b37b7 202 memset(_callback, 0, sizeof(_callback));
Jeej 0:95b73d0b37b7 203
Jeej 9:0140247bab90 204 _cbuf = &_cbuf_h;
Jeej 9:0140247bab90 205 kal_buf_circ_create_static(&_cbuf_h, _cbuf_b, RX_BUF_SIZE, sizeof(uint8_t));
Jeej 9:0140247bab90 206
Jeej 0:95b73d0b37b7 207 _serial = new RawSerial(tx, rx, 115200);
Jeej 0:95b73d0b37b7 208 _serial->format(8, SerialBase::None, 1);
Jeej 9:0140247bab90 209 //_serial->attach(callback(this, &WizziCom::_rx_isr), Serial::RxIrq);
Jeej 9:0140247bab90 210 _serial->read(&_rx_byte, sizeof(uint8_t), callback(this, &WizziCom::_rx_done_isr));
Jeej 8:42e00820df36 211 _serial->set_flow_control(SerialBase::Disabled);
Jeej 0:95b73d0b37b7 212
Jeej 0:95b73d0b37b7 213 _irq_out = (irq_out != NC)? new DigitalOut(irq_out) : NULL;
Jeej 0:95b73d0b37b7 214
Jeej 0:95b73d0b37b7 215 if (irq_in != NC)
Jeej 0:95b73d0b37b7 216 {
Jeej 0:95b73d0b37b7 217 _irq_in = new InterruptIn(irq_in);
Jeej 0:95b73d0b37b7 218 _irq_in->rise(callback(this, &WizziCom::_irq_in_isr));
Jeej 0:95b73d0b37b7 219 }
Jeej 0:95b73d0b37b7 220 else
Jeej 0:95b73d0b37b7 221 {
Jeej 0:95b73d0b37b7 222 _irq_in = NULL;
Jeej 0:95b73d0b37b7 223 }
Jeej 9:0140247bab90 224
Jeej 0:95b73d0b37b7 225 osStatus err = _rx_thread.start(callback(this, &WizziCom::_thread_rx));
Jeej 0:95b73d0b37b7 226 ASSERT(err == osOK, "Failed to start WizziCom _thread_rx (err: %d)\r\n", err);
Jeej 0:95b73d0b37b7 227
Jeej 0:95b73d0b37b7 228 err = _tx_thread.start(callback(this, &WizziCom::_thread_tx));
Jeej 0:95b73d0b37b7 229 ASSERT(err == osOK, "Failed to start WizziCom _thread_tx (err: %d)\r\n", err);
Jeej 0:95b73d0b37b7 230
Jeej 0:95b73d0b37b7 231 err = _callback_thread.start(callback(this, &WizziCom::_thread_callback));
Jeej 0:95b73d0b37b7 232 ASSERT(err == osOK, "Failed to start WizziCom _thread_callback (err: %d)\r\n", err);
Jeej 0:95b73d0b37b7 233 }
Jeej 0:95b73d0b37b7 234
Jeej 0:95b73d0b37b7 235 WizziCom::~WizziCom()
Jeej 0:95b73d0b37b7 236 {
Jeej 0:95b73d0b37b7 237 _rx_thread.terminate();
Jeej 0:95b73d0b37b7 238 _tx_thread.terminate();
Jeej 0:95b73d0b37b7 239 _callback_thread.terminate();
Jeej 0:95b73d0b37b7 240 delete _serial;
Jeej 0:95b73d0b37b7 241 delete _irq_out;
Jeej 0:95b73d0b37b7 242 delete _irq_in;
Jeej 0:95b73d0b37b7 243 }
Jeej 0:95b73d0b37b7 244
Jeej 0:95b73d0b37b7 245 void WizziCom::attach(WizziComCallback function, WizziComPacketType packet_type)
Jeej 0:95b73d0b37b7 246 {
Jeej 0:95b73d0b37b7 247 _callback[packet_type] = callback(function);
Jeej 0:95b73d0b37b7 248 }
Jeej 0:95b73d0b37b7 249
Jeej 0:95b73d0b37b7 250 void WizziCom::reset(void)
Jeej 0:95b73d0b37b7 251 {
Jeej 0:95b73d0b37b7 252 COM_FPRINT("\r\n");
Jeej 0:95b73d0b37b7 253
Jeej 0:95b73d0b37b7 254 _tx_seq = 0;
Jeej 0:95b73d0b37b7 255 _rx_seq = 0;
Jeej 0:95b73d0b37b7 256 }
Jeej 0:95b73d0b37b7 257
Jeej 0:95b73d0b37b7 258 void WizziCom::send(WizziComPacketType type, uint8_t length, uint8_t* data)
Jeej 0:95b73d0b37b7 259 {
Jeej 0:95b73d0b37b7 260 wizzi_com_tx_msg_t msg;
Jeej 0:95b73d0b37b7 261
Jeej 0:95b73d0b37b7 262 msg.id = g_type_to_flow[type];
Jeej 0:95b73d0b37b7 263 msg.pbuf = data;
Jeej 0:95b73d0b37b7 264 msg.plen = length;
Jeej 0:95b73d0b37b7 265 msg.alen = 0;
Jeej 0:95b73d0b37b7 266
Jeej 0:95b73d0b37b7 267 _post_msg(&msg);
Jeej 0:95b73d0b37b7 268 }
Jeej 0:95b73d0b37b7 269
Jeej 0:95b73d0b37b7 270 void WizziCom::send(WizziComPacket_t* packet)
Jeej 0:95b73d0b37b7 271 {
Jeej 0:95b73d0b37b7 272 wizzi_com_tx_msg_t msg;
Jeej 0:95b73d0b37b7 273
Jeej 0:95b73d0b37b7 274 msg.id = g_type_to_flow[packet->type];
Jeej 0:95b73d0b37b7 275 msg.pbuf = packet->data;
Jeej 0:95b73d0b37b7 276 msg.plen = packet->length;
Jeej 0:95b73d0b37b7 277 msg.alen = 0;
Jeej 1:ca1c9bfb1cf4 278
Jeej 0:95b73d0b37b7 279 _post_msg(&msg);
Jeej 0:95b73d0b37b7 280 }
Jeej 0:95b73d0b37b7 281
Jeej 5:a06d239f3b3e 282 void WizziCom::print_raw(char* str)
Jeej 5:a06d239f3b3e 283 {
Jeej 5:a06d239f3b3e 284 _send_raw((uint8_t*)str, (uint32_t)strlen(str));
Jeej 5:a06d239f3b3e 285 }
Jeej 5:a06d239f3b3e 286
Jeej 5:a06d239f3b3e 287 void WizziCom::send_raw(uint8_t* data, uint32_t len)
Jeej 5:a06d239f3b3e 288 {
Jeej 5:a06d239f3b3e 289 _send_raw(data, len);
Jeej 5:a06d239f3b3e 290 }
Jeej 0:95b73d0b37b7 291
Jeej 0:95b73d0b37b7 292 /**
Jeej 0:95b73d0b37b7 293 Serial Rx Interrupt Service Routine.
Jeej 0:95b73d0b37b7 294 Add recevied bytes to the RX buffer.
Jeej 0:95b73d0b37b7 295
Jeej 0:95b73d0b37b7 296 @param void
Jeej 0:95b73d0b37b7 297 @return void
Jeej 0:95b73d0b37b7 298 */
Jeej 8:42e00820df36 299
Jeej 8:42e00820df36 300 void WizziCom::_tx_done_isr(int event)
Jeej 8:42e00820df36 301 {
Jeej 8:42e00820df36 302 _tx_done.release();
Jeej 8:42e00820df36 303 }
Jeej 8:42e00820df36 304
Jeej 9:0140247bab90 305 void WizziCom::_rx_isr(void)
Jeej 9:0140247bab90 306 {
Jeej 9:0140247bab90 307 uint8_t byte;
Jeej 9:0140247bab90 308
Jeej 9:0140247bab90 309 while (_serial->readable())
Jeej 9:0140247bab90 310 {
Jeej 9:0140247bab90 311 byte = _serial->getc();
Jeej 9:0140247bab90 312 kal_buf_circ_push(_cbuf, &byte);
Jeej 9:0140247bab90 313 }
Jeej 9:0140247bab90 314
Jeej 9:0140247bab90 315 _rx_done.release();
Jeej 9:0140247bab90 316 }
Jeej 9:0140247bab90 317
Jeej 8:42e00820df36 318 void WizziCom::_rx_done_isr(int event)
Jeej 0:95b73d0b37b7 319 {
Jeej 9:0140247bab90 320 uint8_t byte = _rx_byte;
Jeej 9:0140247bab90 321
Jeej 9:0140247bab90 322 _serial->read(&_rx_byte, sizeof(uint8_t), callback(this, &WizziCom::_rx_done_isr));
Jeej 9:0140247bab90 323
Jeej 9:0140247bab90 324 kal_buf_circ_push(_cbuf, &byte);
Jeej 9:0140247bab90 325
Jeej 9:0140247bab90 326 _rx_done.release();
Jeej 0:95b73d0b37b7 327 }
Jeej 0:95b73d0b37b7 328 /**
Jeej 0:95b73d0b37b7 329 CTS pin Interrupt Service Routine.
Jeej 0:95b73d0b37b7 330 For flow control (not yet inplemented)
Jeej 0:95b73d0b37b7 331
Jeej 0:95b73d0b37b7 332 @param void
Jeej 0:95b73d0b37b7 333 @return void
Jeej 0:95b73d0b37b7 334 */
Jeej 0:95b73d0b37b7 335 void WizziCom::_irq_in_isr()
Jeej 0:95b73d0b37b7 336 {
Jeej 0:95b73d0b37b7 337 //PRINT("IRQ_IN_ISR\r\n");
Jeej 0:95b73d0b37b7 338 //_irq_in_int->release();
Jeej 0:95b73d0b37b7 339 }
Jeej 0:95b73d0b37b7 340
Jeej 0:95b73d0b37b7 341 /**
Jeej 0:95b73d0b37b7 342 Wakes-up modem and send data throught Serial.
Jeej 0:95b73d0b37b7 343
Jeej 0:95b73d0b37b7 344 @param const uint8_t* Pointer to data buffer
Jeej 5:a06d239f3b3e 345 @param uint32_t Data length
Jeej 0:95b73d0b37b7 346 @return void
Jeej 0:95b73d0b37b7 347 */
Jeej 5:a06d239f3b3e 348 void WizziCom::_send_raw(uint8_t* data, uint32_t len)
Jeej 0:95b73d0b37b7 349 {
Jeej 0:95b73d0b37b7 350 if (_irq_out)
Jeej 0:95b73d0b37b7 351 {
Jeej 5:a06d239f3b3e 352 *(_irq_out) = 1;
Jeej 11:9b623641fd85 353 ThisThread::sleep_for(10);
Jeej 0:95b73d0b37b7 354 }
Jeej 0:95b73d0b37b7 355
Jeej 8:42e00820df36 356 _serial->write(data, len, callback(this, &WizziCom::_tx_done_isr));
Jeej 8:42e00820df36 357 _tx_done.acquire();
Jeej 0:95b73d0b37b7 358
Jeej 0:95b73d0b37b7 359 if (_irq_out)
Jeej 0:95b73d0b37b7 360 {
Jeej 0:95b73d0b37b7 361 // Important to not release the ressource too soon
Jeej 8:42e00820df36 362 ThisThread::sleep_for(2);
Jeej 0:95b73d0b37b7 363 *(_irq_out) = 0;
Jeej 0:95b73d0b37b7 364 }
Jeej 0:95b73d0b37b7 365 }
Jeej 0:95b73d0b37b7 366
Jeej 0:95b73d0b37b7 367 void WizziCom::_sys_xack(void)
Jeej 0:95b73d0b37b7 368 {
Jeej 0:95b73d0b37b7 369 send(WizziComPacketSysXack, 0, NULL);
Jeej 0:95b73d0b37b7 370 }
Jeej 0:95b73d0b37b7 371
Jeej 0:95b73d0b37b7 372 // Formats to send packet throught Serial.
Jeej 0:95b73d0b37b7 373 wizzi_com_tx_buf_t* WizziCom::_new_msg(wizzi_com_tx_msg_t* msg)
Jeej 0:95b73d0b37b7 374 {
Jeej 0:95b73d0b37b7 375 uint8_t len = KAL_COM_HEADER_LEN + msg->alen + msg->plen;
Jeej 0:95b73d0b37b7 376 COM_FPRINT("(len:%d)\r\n", len);
Jeej 0:95b73d0b37b7 377
Jeej 0:95b73d0b37b7 378 wizzi_com_tx_buf_t* tx_buf = (wizzi_com_tx_buf_t*)MALLOC(sizeof(wizzi_com_tx_buf_t) - 1 + len);
Jeej 0:95b73d0b37b7 379
Jeej 0:95b73d0b37b7 380 // construct serial header
Jeej 0:95b73d0b37b7 381 // concatenate and update tx_seq ID
Jeej 0:95b73d0b37b7 382 uint8_t* p = tx_buf->buf;
Jeej 0:95b73d0b37b7 383 uint8_t* t = p;
Jeej 0:95b73d0b37b7 384 *p++ = (uint8_t)KAL_COM_SYNC_BYTE_0;
Jeej 0:95b73d0b37b7 385 *p++ = (uint8_t)KAL_COM_SYNC_BYTE_1;
Jeej 0:95b73d0b37b7 386 *p++ = (uint8_t)msg->alen + msg->plen;
Jeej 0:95b73d0b37b7 387 *p++ = (uint8_t)_tx_seq++;
Jeej 0:95b73d0b37b7 388 *p++ = (uint8_t)msg->id;
Jeej 0:95b73d0b37b7 389
Jeej 0:95b73d0b37b7 390 // copy payload and parameters
Jeej 0:95b73d0b37b7 391 memcpy(p, msg->pbuf, msg->plen);
Jeej 0:95b73d0b37b7 392 p += msg->plen;
Jeej 0:95b73d0b37b7 393 memcpy(p, msg->abuf, msg->alen);
Jeej 0:95b73d0b37b7 394 p += msg->alen;
Jeej 0:95b73d0b37b7 395
Jeej 0:95b73d0b37b7 396 tx_buf->len = (uint32_t)(p - t);
Jeej 0:95b73d0b37b7 397
Jeej 0:95b73d0b37b7 398 ASSERT(tx_buf->len == len, "New msg wrong length %d expected %d\r\n", tx_buf->len, len);
Jeej 0:95b73d0b37b7 399
Jeej 0:95b73d0b37b7 400 return tx_buf;
Jeej 0:95b73d0b37b7 401 }
Jeej 0:95b73d0b37b7 402
Jeej 0:95b73d0b37b7 403 void WizziCom::_post_msg(wizzi_com_tx_msg_t* msg)
Jeej 0:95b73d0b37b7 404 {
Jeej 0:95b73d0b37b7 405 COM_FPRINT("\r\n");
Jeej 0:95b73d0b37b7 406
Jeej 0:95b73d0b37b7 407 ASSERT(_tx_queue.put(_new_msg(msg)) == osOK, "WizziCom TX queue full!\r\n");
Jeej 0:95b73d0b37b7 408 }
Jeej 0:95b73d0b37b7 409
Jeej 0:95b73d0b37b7 410 void WizziCom::_new_pkt(WizziComPacket_t* packet)
Jeej 0:95b73d0b37b7 411 {
Jeej 0:95b73d0b37b7 412 //COM_COM_FPRINT("\r\n");
Jeej 0:95b73d0b37b7 413
Jeej 0:95b73d0b37b7 414 COM_DPRINT("--> (%02d) %d\r\n", packet->type, packet->length);
Jeej 0:95b73d0b37b7 415
Jeej 0:95b73d0b37b7 416 // Distribute packet types to callbacks
Jeej 0:95b73d0b37b7 417 switch (packet->type)
Jeej 0:95b73d0b37b7 418 {
Jeej 0:95b73d0b37b7 419 case WizziComPacketSysXon:
Jeej 0:95b73d0b37b7 420 FREE(packet);
Jeej 0:95b73d0b37b7 421 COM_DPRINT("XON\r\n");
Jeej 6:ed1ba668b6ef 422 _tx_thread.flags_set(XON_SIGNAL);
Jeej 0:95b73d0b37b7 423 break;
Jeej 0:95b73d0b37b7 424 case WizziComPacketSysXoff:
Jeej 0:95b73d0b37b7 425 FREE(packet);
Jeej 0:95b73d0b37b7 426 COM_DPRINT("XOFF\r\n");
Jeej 0:95b73d0b37b7 427 _sys_xack();
Jeej 0:95b73d0b37b7 428 break;
Jeej 0:95b73d0b37b7 429 default:
Jeej 0:95b73d0b37b7 430 ASSERT(_rx_queue.put(packet) == osOK, "WizziCom RX queue full!\r\n");
Jeej 0:95b73d0b37b7 431 break;
Jeej 0:95b73d0b37b7 432 }
Jeej 0:95b73d0b37b7 433 }
Jeej 0:95b73d0b37b7 434
Jeej 0:95b73d0b37b7 435 // Thread for calling callbacks
Jeej 0:95b73d0b37b7 436 // Like arg, arg thread is stalled by callbacks but not the parsing thread.
Jeej 0:95b73d0b37b7 437 void WizziCom::_thread_callback(void)
Jeej 0:95b73d0b37b7 438 {
Jeej 0:95b73d0b37b7 439 osEvent evt;
Jeej 0:95b73d0b37b7 440 WizziComPacket_t* packet;
Jeej 0:95b73d0b37b7 441
Jeej 0:95b73d0b37b7 442 COM_FPRINT("(id:0x%08x)\r\n", osThreadGetId());
Jeej 0:95b73d0b37b7 443 while (true)
Jeej 0:95b73d0b37b7 444 {
Jeej 0:95b73d0b37b7 445 // wait for available packet
Jeej 0:95b73d0b37b7 446 evt = _rx_queue.get();
Jeej 0:95b73d0b37b7 447 packet = (evt.status == osEventMessage)? (WizziComPacket_t*)evt.value.p : NULL;
Jeej 0:95b73d0b37b7 448
Jeej 0:95b73d0b37b7 449 if (packet != NULL)
Jeej 0:95b73d0b37b7 450 {
Jeej 0:95b73d0b37b7 451 if (_callback[packet->type])
Jeej 0:95b73d0b37b7 452 {
Jeej 0:95b73d0b37b7 453 _callback[packet->type].call(this, packet);
Jeej 0:95b73d0b37b7 454 }
Jeej 4:a37e42de1ba7 455 else if (_callback[WizziComPacketUntreated])
Jeej 0:95b73d0b37b7 456 {
Jeej 4:a37e42de1ba7 457 _callback[WizziComPacketUntreated].call(this, packet);
Jeej 0:95b73d0b37b7 458 }
Jeej 0:95b73d0b37b7 459 else
Jeej 0:95b73d0b37b7 460 {
Jeej 0:95b73d0b37b7 461 EPRINT("Untreated pkt type %d in queue!\r\n", packet->type);
Jeej 0:95b73d0b37b7 462 }
Jeej 8:42e00820df36 463 FREE(packet);
Jeej 0:95b73d0b37b7 464 }
Jeej 0:95b73d0b37b7 465 }
Jeej 0:95b73d0b37b7 466 }
Jeej 0:95b73d0b37b7 467
Jeej 0:95b73d0b37b7 468
Jeej 0:95b73d0b37b7 469 // Thread for parsing packets from RX buffer.
Jeej 0:95b73d0b37b7 470 void WizziCom::_thread_rx(void)
Jeej 0:95b73d0b37b7 471 {
Jeej 9:0140247bab90 472 uint8_t seqnum;
Jeej 9:0140247bab90 473 uint8_t header[KAL_COM_HEADER_LEN];
Jeej 9:0140247bab90 474
Jeej 0:95b73d0b37b7 475 COM_FPRINT("(id:0x%08x)\r\n", osThreadGetId());
Jeej 0:95b73d0b37b7 476 while (true)
Jeej 0:95b73d0b37b7 477 {
Jeej 12:9edd3fd978d2 478 // Wait for header data
Jeej 12:9edd3fd978d2 479 while (kal_buf_circ_size(_cbuf) < KAL_COM_HEADER_LEN)
Jeej 9:0140247bab90 480 {
Jeej 12:9edd3fd978d2 481 _rx_done.acquire();
Jeej 9:0140247bab90 482 }
Jeej 9:0140247bab90 483
Jeej 9:0140247bab90 484 // Copy header from buffer (data stays in buffer)
Jeej 9:0140247bab90 485 kal_buf_circ_fetch(_cbuf, header, KAL_COM_HEADER_LEN);
Jeej 9:0140247bab90 486
Jeej 9:0140247bab90 487 // Check sync bytes
Jeej 9:0140247bab90 488 if(KAL_COM_SYNC_BYTE_0 == header[0] && KAL_COM_SYNC_BYTE_1 == header[1])
Jeej 9:0140247bab90 489 {
Jeej 12:9edd3fd978d2 490 // Packet valid, drop header from buffer
Jeej 12:9edd3fd978d2 491 kal_buf_circ_get(_cbuf, NULL, KAL_COM_HEADER_LEN);
Jeej 12:9edd3fd978d2 492
Jeej 9:0140247bab90 493 // Fill temp header
Jeej 9:0140247bab90 494 _msg.blen = header[2];
Jeej 9:0140247bab90 495 seqnum = header[3];
Jeej 9:0140247bab90 496 _msg.id = wizzicom_flow_to_type(header[4]);
Jeej 9:0140247bab90 497
Jeej 12:9edd3fd978d2 498 // Wait for body data
Jeej 12:9edd3fd978d2 499 while (kal_buf_circ_size(_cbuf) < _msg.blen)
Jeej 9:0140247bab90 500 {
Jeej 12:9edd3fd978d2 501 _rx_done.acquire();
Jeej 9:0140247bab90 502 }
Jeej 9:0140247bab90 503
Jeej 9:0140247bab90 504 // Update seqnum
Jeej 9:0140247bab90 505 WARNING(_rx_seq == seqnum, "COM Bad seqnum expected:%d got:%d\r\n", _rx_seq, seqnum);
Jeej 9:0140247bab90 506 _rx_seq = seqnum + 1;
Jeej 9:0140247bab90 507
Jeej 12:9edd3fd978d2 508 COM_DPRINT("COM packet (id: %02X seq: %d body: %d bytes)\r\n", _msg.id, seqnum, _msg.blen);
Jeej 9:0140247bab90 509
Jeej 9:0140247bab90 510 if (_callback[_msg.id] || _callback[WizziComPacketUntreated])
Jeej 9:0140247bab90 511 {
Jeej 9:0140247bab90 512 WizziComPacket_t* pkt = (WizziComPacket_t*)MALLOC(sizeof(WizziComPacket_t) - 1 + _msg.blen);
Jeej 9:0140247bab90 513
Jeej 9:0140247bab90 514 // copy data to buffer
Jeej 9:0140247bab90 515 pkt->length = _msg.blen;
Jeej 9:0140247bab90 516 pkt->type = _msg.id;
Jeej 9:0140247bab90 517
Jeej 9:0140247bab90 518 if (_msg.blen)
Jeej 9:0140247bab90 519 {
Jeej 9:0140247bab90 520 // Get payload from buffer
Jeej 9:0140247bab90 521 kal_buf_circ_get(_cbuf, pkt->data, _msg.blen);
Jeej 9:0140247bab90 522 }
Jeej 9:0140247bab90 523
Jeej 9:0140247bab90 524 // add packet to queue
Jeej 9:0140247bab90 525 _new_pkt(pkt);
Jeej 9:0140247bab90 526 }
Jeej 9:0140247bab90 527 else
Jeej 9:0140247bab90 528 {
Jeej 9:0140247bab90 529 // Ignore packet
Jeej 9:0140247bab90 530 COM_DPRINT("Ignore pkt id %02X\r\n", _msg.id);
Jeej 9:0140247bab90 531
Jeej 9:0140247bab90 532 // Drop payload from buffer
Jeej 9:0140247bab90 533 kal_buf_circ_get(_cbuf, NULL, _msg.blen);
Jeej 9:0140247bab90 534 }
Jeej 9:0140247bab90 535 }
Jeej 9:0140247bab90 536 else
Jeej 9:0140247bab90 537 {
Jeej 9:0140247bab90 538 // Resync
Jeej 9:0140247bab90 539 PRINT("COM: Resync\n");
Jeej 9:0140247bab90 540
Jeej 9:0140247bab90 541 // Drop a byte
Jeej 9:0140247bab90 542 kal_buf_circ_pop(_cbuf, NULL);
Jeej 9:0140247bab90 543 }
Jeej 0:95b73d0b37b7 544 }
Jeej 0:95b73d0b37b7 545 }
Jeej 0:95b73d0b37b7 546
Jeej 0:95b73d0b37b7 547 void WizziCom::_thread_tx(void)
Jeej 0:95b73d0b37b7 548 {
Jeej 0:95b73d0b37b7 549 COM_FPRINT("(id:0x%08x)\r\n", osThreadGetId());
Jeej 0:95b73d0b37b7 550
Jeej 0:95b73d0b37b7 551 wizzi_com_tx_buf_t* msg;
Jeej 0:95b73d0b37b7 552 osEvent evt;
Jeej 0:95b73d0b37b7 553 uint8_t flow_id;
Jeej 0:95b73d0b37b7 554
Jeej 0:95b73d0b37b7 555 while (true)
Jeej 0:95b73d0b37b7 556 {
Jeej 0:95b73d0b37b7 557 // wait for data to send
Jeej 0:95b73d0b37b7 558 evt = _tx_queue.get();
Jeej 0:95b73d0b37b7 559 msg = (evt.status == osEventMessage)? (wizzi_com_tx_buf_t*)evt.value.p : NULL;
Jeej 0:95b73d0b37b7 560
Jeej 0:95b73d0b37b7 561
Jeej 0:95b73d0b37b7 562 // send message
Jeej 0:95b73d0b37b7 563 if (msg != NULL)
Jeej 0:95b73d0b37b7 564 {
Jeej 0:95b73d0b37b7 565 flow_id = msg->buf[4];
Jeej 5:a06d239f3b3e 566
Jeej 5:a06d239f3b3e 567 COM_DPRINT("<-- (%02d) %d\r\n", wizzicom_flow_to_type(flow_id), (msg->len - KAL_COM_HEADER_LEN));
Jeej 0:95b73d0b37b7 568
Jeej 5:a06d239f3b3e 569 _send_raw(msg->buf, msg->len);
Jeej 0:95b73d0b37b7 570 FREE(msg);
Jeej 0:95b73d0b37b7 571
Jeej 0:95b73d0b37b7 572 if (KAL_COM_FLOW_SYS_XACK == flow_id)
Jeej 0:95b73d0b37b7 573 {
Jeej 0:95b73d0b37b7 574 COM_DPRINT("XACK\r\n");
Jeej 7:45fe755f52bc 575 ThisThread::flags_wait_all(XON_SIGNAL);
Jeej 0:95b73d0b37b7 576 }
Jeej 0:95b73d0b37b7 577 }
Jeej 0:95b73d0b37b7 578 }
Jeej 0:95b73d0b37b7 579 }