WizziLab's serial protocol library

Dependents:   modem_ref_helper_for_v5_3_217 modem_ref_helper

Committer:
Jeej
Date:
Tue May 09 12:53:39 2017 +0000
Revision:
2:6a00ed67fe29
Parent:
1:ca1c9bfb1cf4
Child:
3:230cb1ea9702
Put callback process to Realtime priority.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Jeej 0:95b73d0b37b7 1 #include "WizziCom.h"
Jeej 0:95b73d0b37b7 2
Jeej 0:95b73d0b37b7 3 #if 1
Jeej 0:95b73d0b37b7 4 #define COM_DPRINT(...) DPRINT(__VA_ARGS__)
Jeej 0:95b73d0b37b7 5 #define COM_DPRINT_DATA(...) DPRINT_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 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 0:95b73d0b37b7 299 void WizziCom::_rx_isr()
Jeej 0:95b73d0b37b7 300 {
Jeej 0:95b73d0b37b7 301 // Loop just in case more than one character is in UART's receive FIFO buffer
Jeej 0:95b73d0b37b7 302 while (_serial->readable())
Jeej 0:95b73d0b37b7 303 {
Jeej 0:95b73d0b37b7 304 _rx_buf.push(_serial->getc());
Jeej 0:95b73d0b37b7 305 //PRINT("-");
Jeej 0:95b73d0b37b7 306 }
Jeej 0:95b73d0b37b7 307
Jeej 0:95b73d0b37b7 308 // unlock data parsing thread
Jeej 0:95b73d0b37b7 309 if (_state == SEARCH_HEADER && _rx_buf.available_data() >= KAL_COM_HEADER_LEN)
Jeej 0:95b73d0b37b7 310 {
Jeej 0:95b73d0b37b7 311 _state = PARSE_HEADER;
Jeej 0:95b73d0b37b7 312 _data_parsing.release();
Jeej 0:95b73d0b37b7 313 }
Jeej 0:95b73d0b37b7 314 else if (_state == SEARCH_BODY && _rx_buf.available_data() >= _msg.blen)
Jeej 0:95b73d0b37b7 315 {
Jeej 0:95b73d0b37b7 316 _state = PARSE_BODY;
Jeej 0:95b73d0b37b7 317 _data_parsing.release();
Jeej 0:95b73d0b37b7 318 }
Jeej 0:95b73d0b37b7 319 }
Jeej 0:95b73d0b37b7 320
Jeej 0:95b73d0b37b7 321 /**
Jeej 0:95b73d0b37b7 322 CTS pin Interrupt Service Routine.
Jeej 0:95b73d0b37b7 323 For flow control (not yet inplemented)
Jeej 0:95b73d0b37b7 324
Jeej 0:95b73d0b37b7 325 @param void
Jeej 0:95b73d0b37b7 326 @return void
Jeej 0:95b73d0b37b7 327 */
Jeej 0:95b73d0b37b7 328 void WizziCom::_irq_in_isr()
Jeej 0:95b73d0b37b7 329 {
Jeej 0:95b73d0b37b7 330 //PRINT("IRQ_IN_ISR\r\n");
Jeej 0:95b73d0b37b7 331 //_irq_in_int->release();
Jeej 0:95b73d0b37b7 332 }
Jeej 0:95b73d0b37b7 333
Jeej 0:95b73d0b37b7 334 /**
Jeej 0:95b73d0b37b7 335 Wakes-up modem and send data throught Serial.
Jeej 0:95b73d0b37b7 336
Jeej 0:95b73d0b37b7 337 @param const uint8_t* Pointer to data buffer
Jeej 0:95b73d0b37b7 338 @param int Data length
Jeej 0:95b73d0b37b7 339 @return void
Jeej 0:95b73d0b37b7 340 */
Jeej 0:95b73d0b37b7 341 void WizziCom::_send_raw(wizzi_com_tx_buf_t* tx_buf)
Jeej 0:95b73d0b37b7 342 {
Jeej 0:95b73d0b37b7 343 COM_FPRINT("\r\n");
Jeej 0:95b73d0b37b7 344
Jeej 1:ca1c9bfb1cf4 345 COM_DPRINT("<-- (%02d) %d\r\n", wizzicom_flow_to_type(tx_buf->buf[4]), (tx_buf->len - KAL_COM_HEADER_LEN));
Jeej 0:95b73d0b37b7 346
Jeej 0:95b73d0b37b7 347 if (_irq_out)
Jeej 0:95b73d0b37b7 348 {
Jeej 0:95b73d0b37b7 349 *(_irq_out) = 1;
Jeej 0:95b73d0b37b7 350 Thread::wait(3);
Jeej 0:95b73d0b37b7 351 }
Jeej 0:95b73d0b37b7 352
Jeej 0:95b73d0b37b7 353 for (uint32_t i=0 ; i<tx_buf->len ; i++)
Jeej 0:95b73d0b37b7 354 {
Jeej 0:95b73d0b37b7 355 _serial->putc(tx_buf->buf[i]);
Jeej 0:95b73d0b37b7 356 }
Jeej 0:95b73d0b37b7 357
Jeej 0:95b73d0b37b7 358 if (_irq_out)
Jeej 0:95b73d0b37b7 359 {
Jeej 0:95b73d0b37b7 360 // Important to not release the ressource too soon
Jeej 0:95b73d0b37b7 361 Thread::wait(2);
Jeej 0:95b73d0b37b7 362 *(_irq_out) = 0;
Jeej 0:95b73d0b37b7 363 }
Jeej 0:95b73d0b37b7 364 }
Jeej 0:95b73d0b37b7 365
Jeej 0:95b73d0b37b7 366 void WizziCom::_sys_xack(void)
Jeej 0:95b73d0b37b7 367 {
Jeej 0:95b73d0b37b7 368 send(WizziComPacketSysXack, 0, NULL);
Jeej 0:95b73d0b37b7 369 }
Jeej 0:95b73d0b37b7 370
Jeej 0:95b73d0b37b7 371 // Formats to send packet throught Serial.
Jeej 0:95b73d0b37b7 372 wizzi_com_tx_buf_t* WizziCom::_new_msg(wizzi_com_tx_msg_t* msg)
Jeej 0:95b73d0b37b7 373 {
Jeej 0:95b73d0b37b7 374 uint8_t len = KAL_COM_HEADER_LEN + msg->alen + msg->plen;
Jeej 0:95b73d0b37b7 375 COM_FPRINT("(len:%d)\r\n", len);
Jeej 0:95b73d0b37b7 376
Jeej 0:95b73d0b37b7 377 wizzi_com_tx_buf_t* tx_buf = (wizzi_com_tx_buf_t*)MALLOC(sizeof(wizzi_com_tx_buf_t) - 1 + len);
Jeej 0:95b73d0b37b7 378
Jeej 0:95b73d0b37b7 379 // construct serial header
Jeej 0:95b73d0b37b7 380 // concatenate and update tx_seq ID
Jeej 0:95b73d0b37b7 381 uint8_t* p = tx_buf->buf;
Jeej 0:95b73d0b37b7 382 uint8_t* t = p;
Jeej 0:95b73d0b37b7 383 *p++ = (uint8_t)KAL_COM_SYNC_BYTE_0;
Jeej 0:95b73d0b37b7 384 *p++ = (uint8_t)KAL_COM_SYNC_BYTE_1;
Jeej 0:95b73d0b37b7 385 *p++ = (uint8_t)msg->alen + msg->plen;
Jeej 0:95b73d0b37b7 386 *p++ = (uint8_t)_tx_seq++;
Jeej 0:95b73d0b37b7 387 *p++ = (uint8_t)msg->id;
Jeej 0:95b73d0b37b7 388
Jeej 0:95b73d0b37b7 389 // copy payload and parameters
Jeej 0:95b73d0b37b7 390 memcpy(p, msg->pbuf, msg->plen);
Jeej 0:95b73d0b37b7 391 p += msg->plen;
Jeej 0:95b73d0b37b7 392 memcpy(p, msg->abuf, msg->alen);
Jeej 0:95b73d0b37b7 393 p += msg->alen;
Jeej 0:95b73d0b37b7 394
Jeej 0:95b73d0b37b7 395 tx_buf->len = (uint32_t)(p - t);
Jeej 0:95b73d0b37b7 396
Jeej 0:95b73d0b37b7 397 ASSERT(tx_buf->len == len, "New msg wrong length %d expected %d\r\n", tx_buf->len, len);
Jeej 0:95b73d0b37b7 398
Jeej 0:95b73d0b37b7 399 return tx_buf;
Jeej 0:95b73d0b37b7 400 }
Jeej 0:95b73d0b37b7 401
Jeej 0:95b73d0b37b7 402 void WizziCom::_post_msg(wizzi_com_tx_msg_t* msg)
Jeej 0:95b73d0b37b7 403 {
Jeej 0:95b73d0b37b7 404 COM_FPRINT("\r\n");
Jeej 0:95b73d0b37b7 405
Jeej 0:95b73d0b37b7 406 ASSERT(_tx_queue.put(_new_msg(msg)) == osOK, "WizziCom TX queue full!\r\n");
Jeej 0:95b73d0b37b7 407 }
Jeej 0:95b73d0b37b7 408
Jeej 0:95b73d0b37b7 409 void WizziCom::_new_pkt(WizziComPacket_t* packet)
Jeej 0:95b73d0b37b7 410 {
Jeej 0:95b73d0b37b7 411 //COM_COM_FPRINT("\r\n");
Jeej 0:95b73d0b37b7 412
Jeej 0:95b73d0b37b7 413 COM_DPRINT("--> (%02d) %d\r\n", packet->type, packet->length);
Jeej 0:95b73d0b37b7 414
Jeej 0:95b73d0b37b7 415 // Distribute packet types to callbacks
Jeej 0:95b73d0b37b7 416 switch (packet->type)
Jeej 0:95b73d0b37b7 417 {
Jeej 0:95b73d0b37b7 418 case WizziComPacketSysXon:
Jeej 0:95b73d0b37b7 419 FREE(packet);
Jeej 0:95b73d0b37b7 420 COM_DPRINT("XON\r\n");
Jeej 0:95b73d0b37b7 421 _tx_thread.signal_set(XON_SIGNAL);
Jeej 0:95b73d0b37b7 422 break;
Jeej 0:95b73d0b37b7 423 case WizziComPacketSysXoff:
Jeej 0:95b73d0b37b7 424 FREE(packet);
Jeej 0:95b73d0b37b7 425 COM_DPRINT("XOFF\r\n");
Jeej 0:95b73d0b37b7 426 _sys_xack();
Jeej 0:95b73d0b37b7 427 break;
Jeej 0:95b73d0b37b7 428 default:
Jeej 0:95b73d0b37b7 429 ASSERT(_rx_queue.put(packet) == osOK, "WizziCom RX queue full!\r\n");
Jeej 0:95b73d0b37b7 430 break;
Jeej 0:95b73d0b37b7 431 }
Jeej 0:95b73d0b37b7 432 }
Jeej 0:95b73d0b37b7 433
Jeej 0:95b73d0b37b7 434
Jeej 0:95b73d0b37b7 435 /**
Jeej 0:95b73d0b37b7 436 Reads the Rx buffer, parses the packets
Jeej 0:95b73d0b37b7 437
Jeej 0:95b73d0b37b7 438 @param void
Jeej 0:95b73d0b37b7 439 @return void
Jeej 0:95b73d0b37b7 440 */
Jeej 0:95b73d0b37b7 441 void WizziCom::_parse_packet_header(void)
Jeej 0:95b73d0b37b7 442 {
Jeej 0:95b73d0b37b7 443 COM_FPRINT("\r\n");
Jeej 0:95b73d0b37b7 444
Jeej 0:95b73d0b37b7 445 uint8_t header[KAL_COM_HEADER_LEN];
Jeej 0:95b73d0b37b7 446 uint8_t seqnum;
Jeej 0:95b73d0b37b7 447
Jeej 0:95b73d0b37b7 448 ASSERT(_rx_buf.available_data() >= KAL_COM_HEADER_LEN, "Not enough data for header\r\n");
Jeej 0:95b73d0b37b7 449
Jeej 0:95b73d0b37b7 450 _skipped_bytes = 0;
Jeej 0:95b73d0b37b7 451
Jeej 0:95b73d0b37b7 452 header[0] = _rx_buf.pop();
Jeej 0:95b73d0b37b7 453
Jeej 0:95b73d0b37b7 454 while (_rx_buf.available_data() >= KAL_COM_HEADER_LEN - 1)
Jeej 0:95b73d0b37b7 455 {
Jeej 0:95b73d0b37b7 456 header[1] = _rx_buf.pop();
Jeej 0:95b73d0b37b7 457
Jeej 0:95b73d0b37b7 458 // Check sync bytes
Jeej 0:95b73d0b37b7 459 if(KAL_COM_SYNC_BYTE_0 == header[0] && KAL_COM_SYNC_BYTE_1 == header[1])
Jeej 0:95b73d0b37b7 460 {
Jeej 0:95b73d0b37b7 461 // Copy header
Jeej 0:95b73d0b37b7 462 _rx_buf.get(&header[2], KAL_COM_HEADER_LEN - 2);
Jeej 0:95b73d0b37b7 463
Jeej 0:95b73d0b37b7 464 // Fill temp header
Jeej 0:95b73d0b37b7 465 _msg.blen = header[2];
Jeej 0:95b73d0b37b7 466 seqnum = header[3];
Jeej 1:ca1c9bfb1cf4 467 _msg.id = wizzicom_flow_to_type(header[4]);
Jeej 0:95b73d0b37b7 468
Jeej 0:95b73d0b37b7 469 // Update seqnum
Jeej 0:95b73d0b37b7 470 WARNING(_rx_seq == seqnum, "COM Bad seqnum expected:%d got:%d\r\n", _rx_seq, seqnum);
Jeej 0:95b73d0b37b7 471 _rx_seq = seqnum + 1;
Jeej 0:95b73d0b37b7 472
Jeej 0:95b73d0b37b7 473 // search for body
Jeej 0:95b73d0b37b7 474 _state = SEARCH_BODY;
Jeej 0:95b73d0b37b7 475
Jeej 0:95b73d0b37b7 476 // Start parsing if data is already available
Jeej 0:95b73d0b37b7 477 if (_rx_buf.available_data() >= _msg.blen)
Jeej 0:95b73d0b37b7 478 {
Jeej 0:95b73d0b37b7 479 _state = PARSE_BODY;
Jeej 0:95b73d0b37b7 480 _data_parsing.release();
Jeej 0:95b73d0b37b7 481 }
Jeej 0:95b73d0b37b7 482
Jeej 0:95b73d0b37b7 483 //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 484 break;
Jeej 0:95b73d0b37b7 485 }
Jeej 0:95b73d0b37b7 486 else
Jeej 0:95b73d0b37b7 487 {
Jeej 0:95b73d0b37b7 488 // Shift by 1 byte
Jeej 0:95b73d0b37b7 489 //WARNING(false, "COM Skipped byte 0x%02X.\r\n", header[0]);
Jeej 0:95b73d0b37b7 490 _skipped_bytes++;
Jeej 0:95b73d0b37b7 491 header[0] = header[1];
Jeej 0:95b73d0b37b7 492 }
Jeej 0:95b73d0b37b7 493 }
Jeej 0:95b73d0b37b7 494
Jeej 0:95b73d0b37b7 495 WARNING(!_skipped_bytes, "COM Skipped %d bytes.\r\n", _skipped_bytes);
Jeej 0:95b73d0b37b7 496 }
Jeej 0:95b73d0b37b7 497
Jeej 0:95b73d0b37b7 498 /**
Jeej 0:95b73d0b37b7 499 Reads the Rx buffer, parses the packets
Jeej 0:95b73d0b37b7 500
Jeej 0:95b73d0b37b7 501 @param void
Jeej 0:95b73d0b37b7 502 @return void
Jeej 0:95b73d0b37b7 503 */
Jeej 0:95b73d0b37b7 504 void WizziCom::_parse_packet_body(void)
Jeej 0:95b73d0b37b7 505 {
Jeej 0:95b73d0b37b7 506 ASSERT(_rx_buf.available_data() >= _msg.blen, "Not enough data for body\r\n");
Jeej 0:95b73d0b37b7 507
Jeej 0:95b73d0b37b7 508 if (_callback[_msg.id] || _callback[WizziComPacketOther])
Jeej 0:95b73d0b37b7 509 {
Jeej 0:95b73d0b37b7 510 //COM_DPRINT("COM body found (%d bytes)\r\n", _msg.blen);
Jeej 0:95b73d0b37b7 511
Jeej 0:95b73d0b37b7 512 WizziComPacket_t* pkt = (WizziComPacket_t*)MALLOC(sizeof(WizziComPacket_t) - 1 + _msg.blen);
Jeej 0:95b73d0b37b7 513
Jeej 0:95b73d0b37b7 514 // copy data to buffer
Jeej 0:95b73d0b37b7 515 pkt->length = _msg.blen;
Jeej 0:95b73d0b37b7 516 pkt->type = _msg.id;
Jeej 0:95b73d0b37b7 517
Jeej 0:95b73d0b37b7 518 if (_msg.blen)
Jeej 0:95b73d0b37b7 519 {
Jeej 0:95b73d0b37b7 520 _rx_buf.get(pkt->data, _msg.blen);
Jeej 0:95b73d0b37b7 521 }
Jeej 0:95b73d0b37b7 522
Jeej 0:95b73d0b37b7 523 // add packet to queue
Jeej 0:95b73d0b37b7 524 _new_pkt(pkt);
Jeej 0:95b73d0b37b7 525 }
Jeej 0:95b73d0b37b7 526 else
Jeej 0:95b73d0b37b7 527 {
Jeej 0:95b73d0b37b7 528 // Ignore packet
Jeej 0:95b73d0b37b7 529 //COM_DPRINT("Ignore pkt id %02X\r\n", _msg.id);
Jeej 0:95b73d0b37b7 530 if (_msg.blen)
Jeej 0:95b73d0b37b7 531 {
Jeej 0:95b73d0b37b7 532 _rx_buf.get(NULL, _msg.blen);
Jeej 0:95b73d0b37b7 533 }
Jeej 0:95b73d0b37b7 534 }
Jeej 0:95b73d0b37b7 535
Jeej 0:95b73d0b37b7 536 // Seach for next header
Jeej 0:95b73d0b37b7 537 _state = SEARCH_HEADER;
Jeej 0:95b73d0b37b7 538
Jeej 0:95b73d0b37b7 539 // Start parsing if data is already available
Jeej 0:95b73d0b37b7 540 if (_rx_buf.available_data() >= KAL_COM_HEADER_LEN)
Jeej 0:95b73d0b37b7 541 {
Jeej 0:95b73d0b37b7 542 _state = PARSE_HEADER;
Jeej 0:95b73d0b37b7 543 _data_parsing.release();
Jeej 0:95b73d0b37b7 544 }
Jeej 0:95b73d0b37b7 545 }
Jeej 0:95b73d0b37b7 546
Jeej 0:95b73d0b37b7 547 // Thread for calling callbacks
Jeej 0:95b73d0b37b7 548 // Like arg, arg thread is stalled by callbacks but not the parsing thread.
Jeej 0:95b73d0b37b7 549 void WizziCom::_thread_callback(void)
Jeej 0:95b73d0b37b7 550 {
Jeej 0:95b73d0b37b7 551 osEvent evt;
Jeej 0:95b73d0b37b7 552 WizziComPacket_t* packet;
Jeej 0:95b73d0b37b7 553
Jeej 0:95b73d0b37b7 554 COM_FPRINT("(id:0x%08x)\r\n", osThreadGetId());
Jeej 0:95b73d0b37b7 555 while (true)
Jeej 0:95b73d0b37b7 556 {
Jeej 0:95b73d0b37b7 557 // wait for available packet
Jeej 0:95b73d0b37b7 558 evt = _rx_queue.get();
Jeej 0:95b73d0b37b7 559 packet = (evt.status == osEventMessage)? (WizziComPacket_t*)evt.value.p : NULL;
Jeej 0:95b73d0b37b7 560
Jeej 0:95b73d0b37b7 561 if (packet != NULL)
Jeej 0:95b73d0b37b7 562 {
Jeej 0:95b73d0b37b7 563 if (_callback[packet->type])
Jeej 0:95b73d0b37b7 564 {
Jeej 0:95b73d0b37b7 565 _callback[packet->type].call(this, packet);
Jeej 0:95b73d0b37b7 566 }
Jeej 0:95b73d0b37b7 567 else if (_callback[WizziComPacketOther])
Jeej 0:95b73d0b37b7 568 {
Jeej 0:95b73d0b37b7 569 _callback[WizziComPacketOther].call(this, packet);
Jeej 0:95b73d0b37b7 570 }
Jeej 0:95b73d0b37b7 571 else
Jeej 0:95b73d0b37b7 572 {
Jeej 0:95b73d0b37b7 573 EPRINT("Untreated pkt type %d in queue!\r\n", packet->type);
Jeej 0:95b73d0b37b7 574 FREE(packet);
Jeej 0:95b73d0b37b7 575 }
Jeej 0:95b73d0b37b7 576 }
Jeej 0:95b73d0b37b7 577 }
Jeej 0:95b73d0b37b7 578 }
Jeej 0:95b73d0b37b7 579
Jeej 0:95b73d0b37b7 580
Jeej 0:95b73d0b37b7 581 // Thread for parsing packets from RX buffer.
Jeej 0:95b73d0b37b7 582 void WizziCom::_thread_rx(void)
Jeej 0:95b73d0b37b7 583 {
Jeej 0:95b73d0b37b7 584 COM_FPRINT("(id:0x%08x)\r\n", osThreadGetId());
Jeej 0:95b73d0b37b7 585 while (true)
Jeej 0:95b73d0b37b7 586 {
Jeej 0:95b73d0b37b7 587 // wait for data available
Jeej 0:95b73d0b37b7 588 _data_parsing.wait();
Jeej 0:95b73d0b37b7 589
Jeej 0:95b73d0b37b7 590 if (_state == PARSE_HEADER)
Jeej 0:95b73d0b37b7 591 {
Jeej 0:95b73d0b37b7 592 _parse_packet_header();
Jeej 0:95b73d0b37b7 593 }
Jeej 0:95b73d0b37b7 594 else if (_state == PARSE_BODY)
Jeej 0:95b73d0b37b7 595 {
Jeej 0:95b73d0b37b7 596 _parse_packet_body();
Jeej 0:95b73d0b37b7 597 }
Jeej 0:95b73d0b37b7 598 }
Jeej 0:95b73d0b37b7 599 }
Jeej 0:95b73d0b37b7 600
Jeej 0:95b73d0b37b7 601 void WizziCom::_thread_tx(void)
Jeej 0:95b73d0b37b7 602 {
Jeej 0:95b73d0b37b7 603 COM_FPRINT("(id:0x%08x)\r\n", osThreadGetId());
Jeej 0:95b73d0b37b7 604
Jeej 0:95b73d0b37b7 605 wizzi_com_tx_buf_t* msg;
Jeej 0:95b73d0b37b7 606 osEvent evt;
Jeej 0:95b73d0b37b7 607 uint8_t flow_id;
Jeej 0:95b73d0b37b7 608
Jeej 0:95b73d0b37b7 609 while (true)
Jeej 0:95b73d0b37b7 610 {
Jeej 0:95b73d0b37b7 611 // wait for data to send
Jeej 0:95b73d0b37b7 612 evt = _tx_queue.get();
Jeej 0:95b73d0b37b7 613 msg = (evt.status == osEventMessage)? (wizzi_com_tx_buf_t*)evt.value.p : NULL;
Jeej 0:95b73d0b37b7 614
Jeej 0:95b73d0b37b7 615
Jeej 0:95b73d0b37b7 616 // send message
Jeej 0:95b73d0b37b7 617 if (msg != NULL)
Jeej 0:95b73d0b37b7 618 {
Jeej 0:95b73d0b37b7 619 flow_id = msg->buf[4];
Jeej 0:95b73d0b37b7 620
Jeej 0:95b73d0b37b7 621 _send_raw(msg);
Jeej 0:95b73d0b37b7 622 FREE(msg);
Jeej 0:95b73d0b37b7 623
Jeej 0:95b73d0b37b7 624 if (KAL_COM_FLOW_SYS_XACK == flow_id)
Jeej 0:95b73d0b37b7 625 {
Jeej 0:95b73d0b37b7 626 COM_DPRINT("XACK\r\n");
Jeej 0:95b73d0b37b7 627 _tx_thread.signal_wait(XON_SIGNAL);
Jeej 0:95b73d0b37b7 628 }
Jeej 0:95b73d0b37b7 629 }
Jeej 0:95b73d0b37b7 630 }
Jeej 0:95b73d0b37b7 631 }