EMW3162 driver for NSAPI

Dependents:   HelloEMW3162

Fork of emw3162-driver by Maggie Mei

Committer:
Maggie17
Date:
Mon Nov 14 02:30:49 2016 +0000
Revision:
2:fb6251306b21
Parent:
0:2d5090e1ceb4
Change the API name from ESP8266 to EMW3162

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Maggie17 2:fb6251306b21 1 /* EMW3162 Example
Maggie17 0:2d5090e1ceb4 2 * Copyright (c) 2015 ARM Limited
Maggie17 0:2d5090e1ceb4 3 *
Maggie17 0:2d5090e1ceb4 4 * Licensed under the Apache License, Version 2.0 (the "License");
Maggie17 0:2d5090e1ceb4 5 * you may not use this file except in compliance with the License.
Maggie17 0:2d5090e1ceb4 6 * You may obtain a copy of the License at
Maggie17 0:2d5090e1ceb4 7 *
Maggie17 0:2d5090e1ceb4 8 * http://www.apache.org/licenses/LICENSE-2.0
Maggie17 0:2d5090e1ceb4 9 *
Maggie17 0:2d5090e1ceb4 10 * Unless required by applicable law or agreed to in writing, software
Maggie17 0:2d5090e1ceb4 11 * distributed under the License is distributed on an "AS IS" BASIS,
Maggie17 0:2d5090e1ceb4 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Maggie17 0:2d5090e1ceb4 13 * See the License for the specific language governing permissions and
Maggie17 0:2d5090e1ceb4 14 * limitations under the License.
Maggie17 0:2d5090e1ceb4 15 */
Maggie17 0:2d5090e1ceb4 16
Maggie17 0:2d5090e1ceb4 17 #include "EMW3162.h"
Maggie17 0:2d5090e1ceb4 18
Maggie17 2:fb6251306b21 19 EMW3162::EMW3162(PinName tx, PinName rx, bool debug)
Maggie17 0:2d5090e1ceb4 20 : _serial(tx, rx, 1024), _parser(_serial)
Maggie17 0:2d5090e1ceb4 21 , _packets(0), _packets_end(&_packets)
Maggie17 0:2d5090e1ceb4 22 {
Maggie17 0:2d5090e1ceb4 23 _serial.baud(115200);
Maggie17 0:2d5090e1ceb4 24 _parser.debugOn(debug);
Maggie17 0:2d5090e1ceb4 25 }
Maggie17 0:2d5090e1ceb4 26
Maggie17 2:fb6251306b21 27 bool EMW3162::startup(void)
Maggie17 0:2d5090e1ceb4 28 {
Maggie17 0:2d5090e1ceb4 29 bool success = reset("FACTORY");
Maggie17 0:2d5090e1ceb4 30
Maggie17 2:fb6251306b21 31 _parser.oob("+EVENT=SOCKET", this, &EMW3162::_packet_handler);
Maggie17 0:2d5090e1ceb4 32
Maggie17 0:2d5090e1ceb4 33 return success;
Maggie17 0:2d5090e1ceb4 34 }
Maggie17 0:2d5090e1ceb4 35
Maggie17 2:fb6251306b21 36 bool EMW3162::reset(const char *reset)
Maggie17 0:2d5090e1ceb4 37 {
Maggie17 0:2d5090e1ceb4 38 for (int i = 0; i < 2; i++) {
Maggie17 0:2d5090e1ceb4 39 if (_parser.send("AT+%s", reset)
Maggie17 0:2d5090e1ceb4 40 && _parser.recv("+OK")) {
Maggie17 0:2d5090e1ceb4 41 return true;
Maggie17 0:2d5090e1ceb4 42 }
Maggie17 0:2d5090e1ceb4 43 }
Maggie17 0:2d5090e1ceb4 44
Maggie17 0:2d5090e1ceb4 45 return false;
Maggie17 0:2d5090e1ceb4 46 }
Maggie17 0:2d5090e1ceb4 47
Maggie17 2:fb6251306b21 48 bool EMW3162::dhcp(bool enabled)
Maggie17 0:2d5090e1ceb4 49 {
Maggie17 0:2d5090e1ceb4 50 return _parser.send("AT+DHCP=%s", enabled ? "ON":"OFF")
Maggie17 0:2d5090e1ceb4 51 && _parser.recv("+OK");
Maggie17 0:2d5090e1ceb4 52 }
Maggie17 0:2d5090e1ceb4 53
Maggie17 2:fb6251306b21 54 bool EMW3162::connect(const char *ap, const char *passPhrase)
Maggie17 0:2d5090e1ceb4 55 {
Maggie17 0:2d5090e1ceb4 56 return _parser.send("AT+WSTA=%s,%s", ap, passPhrase)
Maggie17 0:2d5090e1ceb4 57 && _parser.recv("+OK")
Maggie17 0:2d5090e1ceb4 58 && _parser.send("AT+EVENT=ON")
Maggie17 0:2d5090e1ceb4 59 && _parser.recv("+OK")
Maggie17 0:2d5090e1ceb4 60 && _parser.recv("+EVENT=WIFI_LINK,STATION_UP");
Maggie17 0:2d5090e1ceb4 61 }
Maggie17 0:2d5090e1ceb4 62
Maggie17 2:fb6251306b21 63 bool EMW3162::disconnect(void)
Maggie17 0:2d5090e1ceb4 64 {
Maggie17 0:2d5090e1ceb4 65
Maggie17 0:2d5090e1ceb4 66 return _parser.send("AT+WLANF=STA,OFF")
Maggie17 0:2d5090e1ceb4 67 && _parser.recv("+OK")
Maggie17 0:2d5090e1ceb4 68 && _parser.recv("+EVENT=WIFI_LINK,STATION_DOWN")
Maggie17 0:2d5090e1ceb4 69 && _parser.send("AT+EVENT=OFF")
Maggie17 0:2d5090e1ceb4 70 && _parser.recv("+OK");
Maggie17 0:2d5090e1ceb4 71 }
Maggie17 0:2d5090e1ceb4 72
Maggie17 2:fb6251306b21 73 const char *EMW3162::getIPAddress(void)
Maggie17 0:2d5090e1ceb4 74 {
Maggie17 0:2d5090e1ceb4 75 if (!(_parser.send("AT+IPCONFIG")
Maggie17 0:2d5090e1ceb4 76 && _parser.recv("%*[^,],%*[^,],%*[^,],%[^,]%*[^#]#", _ip_buffer))) {
Maggie17 0:2d5090e1ceb4 77 return 0;
Maggie17 0:2d5090e1ceb4 78 }
Maggie17 0:2d5090e1ceb4 79
Maggie17 0:2d5090e1ceb4 80 return _ip_buffer;
Maggie17 0:2d5090e1ceb4 81 }
Maggie17 0:2d5090e1ceb4 82
Maggie17 2:fb6251306b21 83 const char *EMW3162::getMACAddress(void)
Maggie17 0:2d5090e1ceb4 84 {
Maggie17 0:2d5090e1ceb4 85 if (!(_parser.send("AT+WMAC")
Maggie17 0:2d5090e1ceb4 86 && _parser.recv("%*[^=]=%[^#]#", _mac_buffer))) {
Maggie17 0:2d5090e1ceb4 87 return 0;
Maggie17 0:2d5090e1ceb4 88 }
Maggie17 0:2d5090e1ceb4 89
Maggie17 0:2d5090e1ceb4 90 return _mac_buffer;
Maggie17 0:2d5090e1ceb4 91 }
Maggie17 0:2d5090e1ceb4 92
Maggie17 2:fb6251306b21 93 bool EMW3162::isConnected(void)
Maggie17 0:2d5090e1ceb4 94 {
Maggie17 0:2d5090e1ceb4 95 return getIPAddress() != 0;
Maggie17 0:2d5090e1ceb4 96 }
Maggie17 0:2d5090e1ceb4 97
Maggie17 2:fb6251306b21 98 int EMW3162::open(const char *type, int id, const char* addr, int port)
Maggie17 0:2d5090e1ceb4 99 {
Maggie17 0:2d5090e1ceb4 100 int state1 = 0, state2 = 0;
Maggie17 0:2d5090e1ceb4 101 state1 = _parser.send("AT+CON1=%s,%d,%d,%s", type, id, port, addr)
Maggie17 0:2d5090e1ceb4 102 && _parser.recv("+OK")
Maggie17 0:2d5090e1ceb4 103 && _parser.send("AT+SAVE")
Maggie17 0:2d5090e1ceb4 104 && _parser.recv("+OK")
Maggie17 0:2d5090e1ceb4 105 && reset("REBOOT")
Maggie17 0:2d5090e1ceb4 106 && _parser.recv("+EVENT=REBOOT");
Maggie17 0:2d5090e1ceb4 107
Maggie17 0:2d5090e1ceb4 108 wait(3);
Maggie17 0:2d5090e1ceb4 109 char conType[10]; // UDP/TCP connection type: SERVER, CLIENT, BROADCAST, UNICAST
Maggie17 0:2d5090e1ceb4 110 int socketId; // UDP/TCP socket id
Maggie17 0:2d5090e1ceb4 111
Maggie17 0:2d5090e1ceb4 112 // Receive wifi connect event
Maggie17 0:2d5090e1ceb4 113 state2 = _parser.recv("+EVENT=WIFI_LINK,STATION_UP")
Maggie17 0:2d5090e1ceb4 114 && _parser.recv("+EVENT=%[^,],CONNECT,%d", conType, &socketId);
Maggie17 0:2d5090e1ceb4 115
Maggie17 0:2d5090e1ceb4 116 if (state1 && state2)
Maggie17 0:2d5090e1ceb4 117 return socketId;
Maggie17 0:2d5090e1ceb4 118 else
Maggie17 0:2d5090e1ceb4 119 return -1;
Maggie17 0:2d5090e1ceb4 120 }
Maggie17 0:2d5090e1ceb4 121
Maggie17 2:fb6251306b21 122 bool EMW3162::send(int id, const void *data, uint32_t amount)
Maggie17 0:2d5090e1ceb4 123 {
Maggie17 0:2d5090e1ceb4 124 //May take a second try if device is busy
Maggie17 0:2d5090e1ceb4 125 for (unsigned i = 0; i < 2; i++) {
Maggie17 0:2d5090e1ceb4 126 if (_parser.send("AT+SSEND=%d,%d", id, amount)
Maggie17 0:2d5090e1ceb4 127 && _parser.recv(">")
Maggie17 0:2d5090e1ceb4 128 && _parser.write((char*)data, (int)amount) >= 0
Maggie17 0:2d5090e1ceb4 129 && _parser.recv("+OK")) {
Maggie17 0:2d5090e1ceb4 130 //wait(3);
Maggie17 0:2d5090e1ceb4 131 return true;
Maggie17 0:2d5090e1ceb4 132 }
Maggie17 0:2d5090e1ceb4 133 }
Maggie17 0:2d5090e1ceb4 134
Maggie17 0:2d5090e1ceb4 135 return false;
Maggie17 0:2d5090e1ceb4 136 }
Maggie17 0:2d5090e1ceb4 137
Maggie17 2:fb6251306b21 138 void EMW3162::_packet_handler()
Maggie17 0:2d5090e1ceb4 139 {
Maggie17 0:2d5090e1ceb4 140 int id;
Maggie17 0:2d5090e1ceb4 141 uint32_t amount;
Maggie17 0:2d5090e1ceb4 142
Maggie17 0:2d5090e1ceb4 143 // parse out the packet
Maggie17 0:2d5090e1ceb4 144 if (!_parser.recv(",%d,%d,", &id, &amount)) {
Maggie17 0:2d5090e1ceb4 145 return;
Maggie17 0:2d5090e1ceb4 146 }
Maggie17 0:2d5090e1ceb4 147
Maggie17 0:2d5090e1ceb4 148 struct packet *packet = (struct packet*)malloc(
Maggie17 0:2d5090e1ceb4 149 sizeof(struct packet) + amount);
Maggie17 0:2d5090e1ceb4 150 if (!packet) {
Maggie17 0:2d5090e1ceb4 151 return;
Maggie17 0:2d5090e1ceb4 152 }
Maggie17 0:2d5090e1ceb4 153
Maggie17 0:2d5090e1ceb4 154 packet->id = id;
Maggie17 0:2d5090e1ceb4 155 packet->len = amount;
Maggie17 0:2d5090e1ceb4 156 packet->next = 0;
Maggie17 0:2d5090e1ceb4 157
Maggie17 0:2d5090e1ceb4 158 if (!(_parser.read((char*)(packet + 1), amount))) {
Maggie17 0:2d5090e1ceb4 159 free(packet);
Maggie17 0:2d5090e1ceb4 160 return;
Maggie17 0:2d5090e1ceb4 161 }
Maggie17 0:2d5090e1ceb4 162
Maggie17 0:2d5090e1ceb4 163 // append to packet list
Maggie17 0:2d5090e1ceb4 164 *_packets_end = packet;
Maggie17 0:2d5090e1ceb4 165 _packets_end = &packet->next;
Maggie17 0:2d5090e1ceb4 166 }
Maggie17 0:2d5090e1ceb4 167
Maggie17 2:fb6251306b21 168 int32_t EMW3162::recv(int id, void *data, uint32_t amount)
Maggie17 0:2d5090e1ceb4 169 {
Maggie17 0:2d5090e1ceb4 170 while (true) {
Maggie17 0:2d5090e1ceb4 171 // check if any packets are ready for us
Maggie17 0:2d5090e1ceb4 172 for (struct packet **p = &_packets; *p; p = &(*p)->next) {
Maggie17 0:2d5090e1ceb4 173 if ((*p)->id == id) {
Maggie17 0:2d5090e1ceb4 174 struct packet *q = *p;
Maggie17 0:2d5090e1ceb4 175
Maggie17 0:2d5090e1ceb4 176 if (q->len <= amount) { // Return and remove full packet
Maggie17 0:2d5090e1ceb4 177 memcpy(data, q+1, q->len);
Maggie17 0:2d5090e1ceb4 178
Maggie17 0:2d5090e1ceb4 179 if (_packets_end == &(*p)->next) {
Maggie17 0:2d5090e1ceb4 180 _packets_end = p;
Maggie17 0:2d5090e1ceb4 181 }
Maggie17 0:2d5090e1ceb4 182 *p = (*p)->next;
Maggie17 0:2d5090e1ceb4 183
Maggie17 0:2d5090e1ceb4 184 uint32_t len = q->len;
Maggie17 0:2d5090e1ceb4 185 free(q);
Maggie17 0:2d5090e1ceb4 186 return len;
Maggie17 0:2d5090e1ceb4 187 } else { // return only partial packet
Maggie17 0:2d5090e1ceb4 188 memcpy(data, q+1, amount);
Maggie17 0:2d5090e1ceb4 189
Maggie17 0:2d5090e1ceb4 190 q->len -= amount;
Maggie17 0:2d5090e1ceb4 191 memmove(q+1, (uint8_t*)(q+1) + amount, q->len);
Maggie17 0:2d5090e1ceb4 192
Maggie17 0:2d5090e1ceb4 193 return amount;
Maggie17 0:2d5090e1ceb4 194 }
Maggie17 0:2d5090e1ceb4 195 }
Maggie17 0:2d5090e1ceb4 196 }
Maggie17 0:2d5090e1ceb4 197
Maggie17 0:2d5090e1ceb4 198 // Wait for inbound packet
Maggie17 0:2d5090e1ceb4 199 if (!_parser.recv("#")) {
Maggie17 0:2d5090e1ceb4 200 return -1;
Maggie17 0:2d5090e1ceb4 201 }
Maggie17 0:2d5090e1ceb4 202 }
Maggie17 0:2d5090e1ceb4 203 }
Maggie17 0:2d5090e1ceb4 204
Maggie17 2:fb6251306b21 205 bool EMW3162::close(int id)
Maggie17 0:2d5090e1ceb4 206 {
Maggie17 0:2d5090e1ceb4 207 //May take a second try if device is busy
Maggie17 0:2d5090e1ceb4 208 for (unsigned i = 0; i < 2; i++) {
Maggie17 0:2d5090e1ceb4 209 if (_parser.send("AT+CONF=1,OFF")
Maggie17 0:2d5090e1ceb4 210 && _parser.recv("+OK")) {
Maggie17 0:2d5090e1ceb4 211 char conType[10]; // Used for UDP/TCP connection type: SERVER, CLIENT, BROADCAST, UNICAST
Maggie17 0:2d5090e1ceb4 212 int socketId; // Used for UDP/TCP socket id
Maggie17 0:2d5090e1ceb4 213
Maggie17 0:2d5090e1ceb4 214 _parser.recv("+EVENT=%[^,],DISCONNECT,%d", conType, &socketId);
Maggie17 0:2d5090e1ceb4 215 return true;
Maggie17 0:2d5090e1ceb4 216 }
Maggie17 0:2d5090e1ceb4 217 }
Maggie17 0:2d5090e1ceb4 218
Maggie17 0:2d5090e1ceb4 219 return false;
Maggie17 0:2d5090e1ceb4 220 }
Maggie17 0:2d5090e1ceb4 221
Maggie17 2:fb6251306b21 222 void EMW3162::setTimeout(uint32_t timeout_ms)
Maggie17 0:2d5090e1ceb4 223 {
Maggie17 0:2d5090e1ceb4 224 _parser.setTimeout(timeout_ms);
Maggie17 0:2d5090e1ceb4 225 }
Maggie17 0:2d5090e1ceb4 226
Maggie17 2:fb6251306b21 227 bool EMW3162::readable()
Maggie17 0:2d5090e1ceb4 228 {
Maggie17 0:2d5090e1ceb4 229 return _serial.readable();
Maggie17 0:2d5090e1ceb4 230 }
Maggie17 0:2d5090e1ceb4 231
Maggie17 2:fb6251306b21 232 bool EMW3162::writeable()
Maggie17 0:2d5090e1ceb4 233 {
Maggie17 0:2d5090e1ceb4 234 return _serial.writeable();
Maggie17 0:2d5090e1ceb4 235 }
Maggie17 0:2d5090e1ceb4 236
Maggie17 2:fb6251306b21 237 void EMW3162::attach(Callback<void()> func)
Maggie17 0:2d5090e1ceb4 238 {
Maggie17 0:2d5090e1ceb4 239 _serial.attach(func);
Maggie17 0:2d5090e1ceb4 240 }