WizziLab's serial protocol library

Dependents:   modem_ref_helper_for_v5_3_217 modem_ref_helper

Committer:
Jeej
Date:
Wed Sep 20 14:40:41 2017 +0000
Revision:
5:a06d239f3b3e
Parent:
4:a37e42de1ba7
Child:
6:ed1ba668b6ef
Added RAW print functions.

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