Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Revision 0:cd7c54f07d25, committed 2017-03-21
- Comitter:
- lizhibo32
- Date:
- Tue Mar 21 03:56:12 2017 +0000
- Commit message:
- build system
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.gitignore Tue Mar 21 03:56:12 2017 +0000 @@ -0,0 +1,4 @@ +.build +.mbed +projectfiles +*.py*
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/MXCHIP_WIFI_Driver/MXCHIP/ATParser/ATParser.cpp Tue Mar 21 03:56:12 2017 +0000
@@ -0,0 +1,333 @@
+/* Copyright (c) 2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @section DESCRIPTION
+ *
+ * Parser for the AT command syntax
+ *
+ */
+
+#include "ATParser.h"
+#include "mbed_debug.h"
+
+
+// getc/putc handling with timeouts
+int ATParser::putc(char c)
+{
+ Timer timer;
+ timer.start();
+
+ while (true) {
+ if (_serial->writeable()) {
+ return _serial->putc(c);
+ }
+ if (timer.read_ms() > _timeout) {
+ return -1;
+ }
+ }
+}
+
+int ATParser::getc()
+{
+ Timer timer;
+ timer.start();
+
+ while (true) {
+ if (_serial->readable()) {
+ return _serial->getc();
+ }
+ if (timer.read_ms() > _timeout) {
+ return -1;
+ }
+ }
+}
+
+void ATParser::flush()
+{
+ while (_serial->readable()) {
+ _serial->getc();
+ }
+}
+
+
+// read/write handling with timeouts
+int ATParser::write(const char *data, int size)
+{
+ int i = 0;
+ for ( ; i < size; i++) {
+ if (putc(data[i]) < 0) {
+ return -1;
+ }
+ }
+ return i;
+}
+
+int ATParser::read(char *data, int size)
+{
+ int i = 0;
+ for ( ; i < size; i++) {
+ int c = getc();
+ if (c < 0) {
+ return -1;
+ }
+ data[i] = c;
+ }
+ return i;
+}
+
+
+// printf/scanf handling
+int ATParser::vprintf(const char *format, va_list args)
+{
+ if (vsprintf(_buffer, format, args) < 0) {
+ return false;
+ }
+ int i = 0;
+ for ( ; _buffer[i]; i++) {
+ if (putc(_buffer[i]) < 0) {
+ return -1;
+ }
+ }
+ return i;
+}
+
+int ATParser::vscanf(const char *format, va_list args)
+{
+ // Since format is const, we need to copy it into our buffer to
+ // add the line's null terminator and clobber value-matches with asterisks.
+ //
+ // We just use the beginning of the buffer to avoid unnecessary allocations.
+ int i = 0;
+ int offset = 0;
+
+ while (format[i]) {
+ if (format[i] == '%' && format[i+1] != '%' && format[i+1] != '*') {
+ _buffer[offset++] = '%';
+ _buffer[offset++] = '*';
+ i++;
+ } else {
+ _buffer[offset++] = format[i++];
+ }
+ }
+
+ // Scanf has very poor support for catching errors
+ // fortunately, we can abuse the %n specifier to determine
+ // if the entire string was matched.
+ _buffer[offset++] = '%';
+ _buffer[offset++] = 'n';
+ _buffer[offset++] = 0;
+
+ // To workaround scanf's lack of error reporting, we actually
+ // make two passes. One checks the validity with the modified
+ // format string that only stores the matched characters (%n).
+ // The other reads in the actual matched values.
+ //
+ // We keep trying the match until we succeed or some other error
+ // derails us.
+ int j = 0;
+
+ while (true) {
+ // Ran out of space
+ if (j+1 >= _buffer_size - offset) {
+ return false;
+ }
+ // Recieve next character
+ int c = getc();
+ if (c < 0) {
+ return -1;
+ }
+ _buffer[offset + j++] = c;
+ _buffer[offset + j] = 0;
+
+ // Check for match
+ int count = -1;
+ sscanf(_buffer+offset, _buffer, &count);
+
+ // We only succeed if all characters in the response are matched
+ if (count == j) {
+ // Store the found results
+ vsscanf(_buffer+offset, format, args);
+ return j;
+ }
+ }
+}
+
+
+// Command parsing with line handling
+bool ATParser::vsend(const char *command, va_list args)
+{
+ // Create and send command
+ if (vsprintf(_buffer, command, args) < 0) {
+ return false;
+ }
+ for (int i = 0; _buffer[i]; i++) {
+ if (putc(_buffer[i]) < 0) {
+ return false;
+ }
+ }
+
+ // Finish with newline
+ for (int i = 0; _delimiter[i]; i++) {
+ if (putc(_delimiter[i]) < 0) {
+ return false;
+ }
+ }
+
+ debug_if(dbg_on, "AT> %s\r\n", _buffer);
+ return true;
+}
+
+bool ATParser::vrecv(const char *response, va_list args)
+{
+ // Iterate through each line in the expected response
+ while (response[0]) {
+ // Since response is const, we need to copy it into our buffer to
+ // add the line's null terminator and clobber value-matches with asterisks.
+ //
+ // We just use the beginning of the buffer to avoid unnecessary allocations.
+ int i = 0;
+ int offset = 0;
+
+ while (response[i]) {
+ if (memcmp(&response[i+1-_delim_size], _delimiter, _delim_size) == 0) {
+ i++;
+ break;
+ } else if (response[i] == '%' && response[i+1] != '%' && response[i+1] != '*') {
+ _buffer[offset++] = '%';
+ _buffer[offset++] = '*';
+ i++;
+ } else {
+ _buffer[offset++] = response[i++];
+ }
+ }
+
+ // Scanf has very poor support for catching errors
+ // fortunately, we can abuse the %n specifier to determine
+ // if the entire string was matched.
+ _buffer[offset++] = '%';
+ _buffer[offset++] = 'n';
+ _buffer[offset++] = 0;
+
+ // To workaround scanf's lack of error reporting, we actually
+ // make two passes. One checks the validity with the modified
+ // format string that only stores the matched characters (%n).
+ // The other reads in the actual matched values.
+ //
+ // We keep trying the match until we succeed or some other error
+ // derails us.
+ int j = 0;
+
+ while (true) {
+ // Recieve next character
+ int c = getc();
+ if (c < 0) {
+ return false;
+ }
+ _buffer[offset + j++] = c;
+ _buffer[offset + j] = 0;
+
+ // Check for oob data
+ for (int k = 0; k < _oobs.size(); k++) {
+ if (j == _oobs[k].len && memcmp(
+ _oobs[k].prefix, _buffer+offset, _oobs[k].len) == 0) {
+ debug_if(dbg_on, "AT! %s\r\n", _oobs[k].prefix);
+ _oobs[k].cb();
+
+ // oob may have corrupted non-reentrant buffer,
+ // so we need to set it up again
+ return vrecv(response, args);
+ }
+ }
+
+ // Check for match
+ int count = -1;
+ sscanf(_buffer+offset, _buffer, &count);
+
+ // We only succeed if all characters in the response are matched
+ if (count == j) {
+ debug_if(dbg_on, "AT= %s\r\n", _buffer+offset);
+ // Reuse the front end of the buffer
+ memcpy(_buffer, response, i);
+ _buffer[i] = 0;
+
+ // Store the found results
+ vsscanf(_buffer+offset, _buffer, args);
+
+ // Jump to next line and continue parsing
+ response += i;
+ break;
+ }
+
+ // Clear the buffer when we hit a newline or ran out of space
+ // running out of space usually means we ran into binary data
+ if (j+1 >= _buffer_size - offset ||
+ strcmp(&_buffer[offset + j-_delim_size], _delimiter) == 0) {
+
+ debug_if(dbg_on, "AT< %s", _buffer+offset);
+ j = 0;
+ }
+ }
+ }
+
+ return true;
+}
+
+
+// Mapping to vararg functions
+int ATParser::printf(const char *format, ...)
+{
+ va_list args;
+ va_start(args, format);
+ int res = vprintf(format, args);
+ va_end(args);
+ return res;
+}
+
+int ATParser::scanf(const char *format, ...)
+{
+ va_list args;
+ va_start(args, format);
+ int res = vscanf(format, args);
+ va_end(args);
+ return res;
+}
+
+bool ATParser::send(const char *command, ...)
+{
+ va_list args;
+ va_start(args, command);
+ bool res = vsend(command, args);
+ va_end(args);
+ return res;
+}
+
+bool ATParser::recv(const char *response, ...)
+{
+ va_list args;
+ va_start(args, response);
+ bool res = vrecv(response, args);
+ va_end(args);
+ return res;
+}
+
+
+// oob registration
+void ATParser::oob(const char *prefix, Callback<void()> cb)
+{
+ struct oob oob;
+ oob.len = strlen(prefix);
+ oob.prefix = prefix;
+ oob.cb = cb;
+ _oobs.push_back(oob);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/MXCHIP_WIFI_Driver/MXCHIP/ATParser/ATParser.h Tue Mar 21 03:56:12 2017 +0000
@@ -0,0 +1,232 @@
+/* Copyright (c) 2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @section DESCRIPTION
+ *
+ * Parser for the AT command syntax
+ *
+ */
+
+#include "mbed.h"
+#include <cstdarg>
+#include <vector>
+#include "BufferedSerial.h"
+#include "Callback.h"
+
+
+/**
+* Parser class for parsing AT commands
+*
+* Here are some examples:
+* @code
+* ATParser at = ATParser(serial, "\r\n");
+* int value;
+* char buffer[100];
+*
+* at.send("AT") && at.recv("OK");
+* at.send("AT+CWMODE=%d", 3) && at.recv("OK");
+* at.send("AT+CWMODE?") && at.recv("+CWMODE:%d\r\nOK", &value);
+* at.recv("+IPD,%d:", &value);
+* at.read(buffer, value);
+* at.recv("OK");
+* @endcode
+*/
+class ATParser
+{
+private:
+ // Serial information
+ BufferedSerial *_serial;
+ int _buffer_size;
+ char *_buffer;
+ int _timeout;
+
+ // Parsing information
+ const char *_delimiter;
+ int _delim_size;
+ bool dbg_on;
+
+ struct oob {
+ unsigned len;
+ const char *prefix;
+ mbed::Callback<void()> cb;
+ };
+ std::vector<oob> _oobs;
+
+public:
+ /**
+ * Constructor
+ *
+ * @param serial serial interface to use for AT commands
+ * @param buffer_size size of internal buffer for transaction
+ * @param timeout timeout of the connection
+ * @param delimiter string of characters to use as line delimiters
+ */
+ ATParser(BufferedSerial &serial, const char *delimiter = "\r\n", int buffer_size = 256, int timeout = 8000, bool debug = false) :
+ _serial(&serial),
+ _buffer_size(buffer_size) {
+ _buffer = new char[buffer_size];
+ setTimeout(timeout);
+ setDelimiter(delimiter);
+ debugOn(debug);
+ }
+
+ /**
+ * Destructor
+ */
+ ~ATParser() {
+ delete [] _buffer;
+ }
+
+ /**
+ * Allows timeout to be changed between commands
+ *
+ * @param timeout timeout of the connection
+ */
+ void setTimeout(int timeout) {
+ _timeout = timeout;
+ }
+
+ /**
+ * Sets string of characters to use as line delimiters
+ *
+ * @param delimiter string of characters to use as line delimiters
+ */
+ void setDelimiter(const char *delimiter) {
+ _delimiter = delimiter;
+ _delim_size = strlen(delimiter);
+ }
+
+ /**
+ * Allows echo to be on or off
+ *
+ * @param echo 1 for echo and 0 turns it off
+ */
+ void debugOn(uint8_t on) {
+ dbg_on = (on) ? 1 : 0;
+ }
+
+ /**
+ * Sends an AT command
+ *
+ * Sends a formatted command using printf style formatting
+ * @see ::printf
+ *
+ * @param command printf-like format string of command to send which
+ * is appended with the specified delimiter
+ * @param ... all printf-like arguments to insert into command
+ * @return true only if command is successfully sent
+ */
+ bool send(const char *command, ...);
+ bool vsend(const char *command, va_list args);
+
+ /**
+ * Recieve an AT response
+ *
+ * Recieves a formatted response using scanf style formatting
+ * @see ::scanf
+ *
+ * Responses are parsed line at a time using the specified delimiter.
+ * Any recieved data that does not match the response is ignored until
+ * a timeout occurs.
+ *
+ * @param response scanf-like format string of response to expect
+ * @param ... all scanf-like arguments to extract from response
+ * @return true only if response is successfully matched
+ */
+ bool recv(const char *response, ...);
+ bool vrecv(const char *response, va_list args);
+
+ /**
+ * Write a single byte to the underlying stream
+ *
+ * @param c The byte to write
+ * @return The byte that was written or -1 during a timeout
+ */
+ int putc(char c);
+
+ /**
+ * Get a single byte from the underlying stream
+ *
+ * @return The byte that was read or -1 during a timeout
+ */
+ int getc();
+
+ /**
+ * Write an array of bytes to the underlying stream
+ *
+ * @param data the array of bytes to write
+ * @param size number of bytes to write
+ * @return number of bytes written or -1 on failure
+ */
+ int write(const char *data, int size);
+
+ /**
+ * Read an array of bytes from the underlying stream
+ *
+ * @param data the destination for the read bytes
+ * @param size number of bytes to read
+ * @return number of bytes read or -1 on failure
+ */
+ int read(char *data, int size);
+
+ /**
+ * Direct printf to underlying stream
+ * @see ::printf
+ *
+ * @param format format string to pass to printf
+ * @param ... arguments to printf
+ * @return number of bytes written or -1 on failure
+ */
+ int printf(const char *format, ...);
+ int vprintf(const char *format, va_list args);
+
+ /**
+ * Direct scanf on underlying stream
+ * @see ::scanf
+ *
+ * @param format format string to pass to scanf
+ * @param ... arguments to scanf
+ * @return number of bytes read or -1 on failure
+ */
+ int scanf(const char *format, ...);
+ int vscanf(const char *format, va_list args);
+
+ /**
+ * Attach a callback for out-of-band data
+ *
+ * @param prefix string on when to initiate callback
+ * @param func callback to call when string is read
+ * @note out-of-band data is only processed during a scanf call
+ */
+ void oob(const char *prefix, mbed::Callback<void()> func);
+
+ /**
+ * Attach a callback for out-of-band data
+ *
+ * @param prefix string on when to initiate callback
+ * @param obj pointer to object to call member function on
+ * @param method callback to call when string is read
+ * @note out-of-band data is only processed during a scanf call
+ */
+ template <typename T, typename M>
+ void oob(const char *prefix, T *obj, M method) {
+ return oob(prefix, mbed::Callback<void()>(obj, method));
+ }
+
+ /**
+ * Flushes the underlying stream
+ */
+ void flush();
+};
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/MXCHIP_WIFI_Driver/MXCHIP/ATParser/BufferedSerial/Buffer/MyBuffer.cpp Tue Mar 21 03:56:12 2017 +0000
@@ -0,0 +1,76 @@
+
+/**
+ * @file Buffer.cpp
+ * @brief Software Buffer - Templated Ring Buffer for most data types
+ * @author sam grove
+ * @version 1.0
+ * @see
+ *
+ * Copyright (c) 2013
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "MyBuffer.h"
+
+template <class T>
+MyBuffer<T>::MyBuffer(uint32_t size)
+{
+ _buf = new T [size];
+ _size = size;
+ clear();
+
+ return;
+}
+
+template <class T>
+MyBuffer<T>::~MyBuffer()
+{
+ delete [] _buf;
+
+ return;
+}
+
+template <class T>
+uint32_t MyBuffer<T>::getSize()
+{
+ return this->_size;
+}
+
+template <class T>
+void MyBuffer<T>::clear(void)
+{
+ _wloc = 0;
+ _rloc = 0;
+ memset(_buf, 0, _size);
+
+ return;
+}
+
+template <class T>
+uint32_t MyBuffer<T>::peek(char c)
+{
+ return 1;
+}
+
+// make the linker aware of some possible types
+template class MyBuffer<uint8_t>;
+template class MyBuffer<int8_t>;
+template class MyBuffer<uint16_t>;
+template class MyBuffer<int16_t>;
+template class MyBuffer<uint32_t>;
+template class MyBuffer<int32_t>;
+template class MyBuffer<uint64_t>;
+template class MyBuffer<int64_t>;
+template class MyBuffer<char>;
+template class MyBuffer<wchar_t>;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/MXCHIP_WIFI_Driver/MXCHIP/ATParser/BufferedSerial/Buffer/MyBuffer.h Tue Mar 21 03:56:12 2017 +0000
@@ -0,0 +1,163 @@
+
+/**
+ * @file Buffer.h
+ * @brief Software Buffer - Templated Ring Buffer for most data types
+ * @author sam grove
+ * @version 1.0
+ * @see
+ *
+ * Copyright (c) 2013
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MYBUFFER_H
+#define MYBUFFER_H
+
+#include <stdint.h>
+#include <string.h>
+
+/** A templated software ring buffer
+ *
+ * Example:
+ * @code
+ * #include "mbed.h"
+ * #include "MyBuffer.h"
+ *
+ * MyBuffer <char> buf;
+ *
+ * int main()
+ * {
+ * buf = 'a';
+ * buf.put('b');
+ * char *head = buf.head();
+ * puts(head);
+ *
+ * char whats_in_there[2] = {0};
+ * int pos = 0;
+ *
+ * while(buf.available())
+ * {
+ * whats_in_there[pos++] = buf;
+ * }
+ * printf("%c %c\n", whats_in_there[0], whats_in_there[1]);
+ * buf.clear();
+ * error("done\n\n\n");
+ * }
+ * @endcode
+ */
+
+template <typename T>
+class MyBuffer
+{
+private:
+ T *_buf;
+ volatile uint32_t _wloc;
+ volatile uint32_t _rloc;
+ uint32_t _size;
+
+public:
+ /** Create a Buffer and allocate memory for it
+ * @param size The size of the buffer
+ */
+ MyBuffer(uint32_t size = 0x100);
+
+ /** Get the size of the ring buffer
+ * @return the size of the ring buffer
+ */
+ uint32_t getSize();
+
+ /** Destry a Buffer and release it's allocated memory
+ */
+ ~MyBuffer();
+
+ /** Add a data element into the buffer
+ * @param data Something to add to the buffer
+ */
+ void put(T data);
+
+ /** Remove a data element from the buffer
+ * @return Pull the oldest element from the buffer
+ */
+ T get(void);
+
+ /** Get the address to the head of the buffer
+ * @return The address of element 0 in the buffer
+ */
+ T *head(void);
+
+ /** Reset the buffer to 0. Useful if using head() to parse packeted data
+ */
+ void clear(void);
+
+ /** Determine if anything is readable in the buffer
+ * @return 1 if something can be read, 0 otherwise
+ */
+ uint32_t available(void);
+
+ /** Overloaded operator for writing to the buffer
+ * @param data Something to put in the buffer
+ * @return
+ */
+ MyBuffer &operator= (T data)
+ {
+ put(data);
+ return *this;
+ }
+
+ /** Overloaded operator for reading from the buffer
+ * @return Pull the oldest element from the buffer
+ */
+ operator int(void)
+ {
+ return get();
+ }
+
+ uint32_t peek(char c);
+
+};
+
+template <class T>
+inline void MyBuffer<T>::put(T data)
+{
+ _buf[_wloc++] = data;
+ _wloc %= (_size-1);
+
+ return;
+}
+
+template <class T>
+inline T MyBuffer<T>::get(void)
+{
+ T data_pos = _buf[_rloc++];
+ _rloc %= (_size-1);
+
+ return data_pos;
+}
+
+template <class T>
+inline T *MyBuffer<T>::head(void)
+{
+ T *data_pos = &_buf[0];
+
+ return data_pos;
+}
+
+template <class T>
+inline uint32_t MyBuffer<T>::available(void)
+{
+ return (_wloc == _rloc) ? 0 : 1;
+}
+
+#endif
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/MXCHIP_WIFI_Driver/MXCHIP/ATParser/BufferedSerial/BufferedPrint.c Tue Mar 21 03:56:12 2017 +0000
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2014-2015 ARM Limited. All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0
+ * Licensed under the Apache License, Version 2.0 (the License); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdarg.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "mbed_error.h"
+
+size_t BufferedSerialThunk(void *buf_serial, const void *s, size_t length);
+
+int BufferedPrintfC(void *stream, int size, const char* format, va_list arg)
+{
+ int r;
+ char buffer[512];
+ if (size >= 512) {
+ return -1;
+ }
+ memset(buffer, 0, size);
+ r = vsprintf(buffer, format, arg);
+ // this may not hit the heap but should alert the user anyways
+ if(r > (int32_t) size) {
+ error("%s %d buffer overwrite (max_buf_size: %d exceeded: %d)!\r\n", __FILE__, __LINE__, size, r);
+ return 0;
+ }
+ if ( r > 0 ) {
+ BufferedSerialThunk(stream, buffer, r);
+ }
+ return r;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/MXCHIP_WIFI_Driver/MXCHIP/ATParser/BufferedSerial/BufferedSerial.cpp Tue Mar 21 03:56:12 2017 +0000
@@ -0,0 +1,166 @@
+/**
+ * @file BufferedSerial.cpp
+ * @brief Software Buffer - Extends mbed Serial functionallity adding irq driven TX and RX
+ * @author sam grove
+ * @version 1.0
+ * @see
+ *
+ * Copyright (c) 2013
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "BufferedSerial.h"
+#include <stdarg.h>
+
+extern "C" int BufferedPrintfC(void *stream, int size, const char* format, va_list arg);
+
+BufferedSerial::BufferedSerial(PinName tx, PinName rx, uint32_t buf_size, uint32_t tx_multiple, const char* name)
+ : RawSerial(tx, rx) , _rxbuf(buf_size), _txbuf((uint32_t)(tx_multiple*buf_size))
+{
+ RawSerial::attach(this, &BufferedSerial::rxIrq, Serial::RxIrq);
+ this->_buf_size = buf_size;
+ this->_tx_multiple = tx_multiple;
+ return;
+}
+
+BufferedSerial::~BufferedSerial(void)
+{
+ RawSerial::attach(NULL, RawSerial::RxIrq);
+ RawSerial::attach(NULL, RawSerial::TxIrq);
+
+ return;
+}
+
+int BufferedSerial::readable(void)
+{
+ return _rxbuf.available(); // note: look if things are in the buffer
+}
+
+int BufferedSerial::writeable(void)
+{
+ return 1; // buffer allows overwriting by design, always true
+}
+
+int BufferedSerial::getc(void)
+{
+ return _rxbuf;
+}
+
+int BufferedSerial::putc(int c)
+{
+ _txbuf = (char)c;
+ BufferedSerial::prime();
+
+ return c;
+}
+
+int BufferedSerial::puts(const char *s)
+{
+ if (s != NULL) {
+ const char* ptr = s;
+
+ while(*(ptr) != 0) {
+ _txbuf = *(ptr++);
+ }
+ _txbuf = '\n'; // done per puts definition
+ BufferedSerial::prime();
+
+ return (ptr - s) + 1;
+ }
+ return 0;
+}
+
+extern "C" size_t BufferedSerialThunk(void *buf_serial, const void *s, size_t length)
+{
+ BufferedSerial *buffered_serial = (BufferedSerial *)buf_serial;
+ return buffered_serial->write(s, length);
+}
+
+int BufferedSerial::printf(const char* format, ...)
+{
+ va_list arg;
+ va_start(arg, format);
+ int r = BufferedPrintfC((void*)this, this->_buf_size, format, arg);
+ va_end(arg);
+ return r;
+}
+
+ssize_t BufferedSerial::write(const void *s, size_t length)
+{
+ if (s != NULL && length > 0) {
+ const char* ptr = (const char*)s;
+ const char* end = ptr + length;
+
+ while (ptr != end) {
+ _txbuf = *(ptr++);
+ }
+ BufferedSerial::prime();
+
+ return ptr - (const char*)s;
+ }
+ return 0;
+}
+
+
+void BufferedSerial::rxIrq(void)
+{
+ // read from the peripheral and make sure something is available
+ if(serial_readable(&_serial)) {
+ _rxbuf = serial_getc(&_serial); // if so load them into a buffer
+ // trigger callback if necessary
+ if (_cbs[RxIrq]) {
+ _cbs[RxIrq]();
+ }
+ }
+
+ return;
+}
+
+void BufferedSerial::txIrq(void)
+{
+ // see if there is room in the hardware fifo and if something is in the software fifo
+ while(serial_writable(&_serial)) {
+ if(_txbuf.available()) {
+ serial_putc(&_serial, (int)_txbuf.get());
+ } else {
+ // disable the TX interrupt when there is nothing left to send
+ RawSerial::attach(NULL, RawSerial::TxIrq);
+ // trigger callback if necessary
+ if (_cbs[TxIrq]) {
+ _cbs[TxIrq]();
+ }
+ break;
+ }
+ }
+
+ return;
+}
+
+void BufferedSerial::prime(void)
+{
+ // if already busy then the irq will pick this up
+ if(serial_writable(&_serial)) {
+ RawSerial::attach(NULL, RawSerial::TxIrq); // make sure not to cause contention in the irq
+ BufferedSerial::txIrq(); // only write to hardware in one place
+ RawSerial::attach(this, &BufferedSerial::txIrq, RawSerial::TxIrq);
+ }
+
+ return;
+}
+
+void BufferedSerial::attach(Callback<void()> func, IrqType type)
+{
+ _cbs[type] = func;
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/MXCHIP_WIFI_Driver/MXCHIP/ATParser/BufferedSerial/BufferedSerial.h Tue Mar 21 03:56:12 2017 +0000
@@ -0,0 +1,168 @@
+
+/**
+ * @file BufferedSerial.h
+ * @brief Software Buffer - Extends mbed Serial functionallity adding irq driven TX and RX
+ * @author sam grove
+ * @version 1.0
+ * @see
+ *
+ * Copyright (c) 2013
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef BUFFEREDSERIAL_H
+#define BUFFEREDSERIAL_H
+
+#include "mbed.h"
+#include "MyBuffer.h"
+
+/** A serial port (UART) for communication with other serial devices
+ *
+ * Can be used for Full Duplex communication, or Simplex by specifying
+ * one pin as NC (Not Connected)
+ *
+ * Example:
+ * @code
+ * #include "mbed.h"
+ * #include "BufferedSerial.h"
+ *
+ * BufferedSerial pc(USBTX, USBRX);
+ *
+ * int main()
+ * {
+ * while(1)
+ * {
+ * Timer s;
+ *
+ * s.start();
+ * pc.printf("Hello World - buffered\n");
+ * int buffered_time = s.read_us();
+ * wait(0.1f); // give time for the buffer to empty
+ *
+ * s.reset();
+ * printf("Hello World - blocking\n");
+ * int polled_time = s.read_us();
+ * s.stop();
+ * wait(0.1f); // give time for the buffer to empty
+ *
+ * pc.printf("printf buffered took %d us\n", buffered_time);
+ * pc.printf("printf blocking took %d us\n", polled_time);
+ * wait(0.5f);
+ * }
+ * }
+ * @endcode
+ */
+
+/**
+ * @class BufferedSerial
+ * @brief Software buffers and interrupt driven tx and rx for Serial
+ */
+class BufferedSerial : public RawSerial
+{
+private:
+ MyBuffer <char> _rxbuf;
+ MyBuffer <char> _txbuf;
+ uint32_t _buf_size;
+ uint32_t _tx_multiple;
+
+ void rxIrq(void);
+ void txIrq(void);
+ void prime(void);
+
+ Callback<void()> _cbs[2];
+
+public:
+ /** Create a BufferedSerial port, connected to the specified transmit and receive pins
+ * @param tx Transmit pin
+ * @param rx Receive pin
+ * @param buf_size printf() buffer size
+ * @param tx_multiple amount of max printf() present in the internal ring buffer at one time
+ * @param name optional name
+ * @note Either tx or rx may be specified as NC if unused
+ */
+ BufferedSerial(PinName tx, PinName rx, uint32_t buf_size = 256, uint32_t tx_multiple = 4,const char* name=NULL);
+
+ /** Destroy a BufferedSerial port
+ */
+ virtual ~BufferedSerial(void);
+
+ /** Check on how many bytes are in the rx buffer
+ * @return 1 if something exists, 0 otherwise
+ */
+ virtual int readable(void);
+
+ /** Check to see if the tx buffer has room
+ * @return 1 always has room and can overwrite previous content if too small / slow
+ */
+ virtual int writeable(void);
+
+ /** Get a single byte from the BufferedSerial Port.
+ * Should check readable() before calling this.
+ * @return A byte that came in on the Serial Port
+ */
+ virtual int getc(void);
+
+ /** Write a single byte to the BufferedSerial Port.
+ * @param c The byte to write to the Serial Port
+ * @return The byte that was written to the Serial Port Buffer
+ */
+ virtual int putc(int c);
+
+ /** Write a string to the BufferedSerial Port. Must be NULL terminated
+ * @param s The string to write to the Serial Port
+ * @return The number of bytes written to the Serial Port Buffer
+ */
+ virtual int puts(const char *s);
+
+ /** Write a formatted string to the BufferedSerial Port.
+ * @param format The string + format specifiers to write to the Serial Port
+ * @return The number of bytes written to the Serial Port Buffer
+ */
+ virtual int printf(const char* format, ...);
+
+ /** Write data to the Buffered Serial Port
+ * @param s A pointer to data to send
+ * @param length The amount of data being pointed to
+ * @return The number of bytes written to the Serial Port Buffer
+ */
+ virtual ssize_t write(const void *s, std::size_t length);
+
+ /** Attach a function to call whenever a serial interrupt is generated
+ * @param func A pointer to a void function, or 0 to set as none
+ * @param type Which serial interrupt to attach the member function to (Serial::RxIrq for receive, TxIrq for transmit buffer empty)
+ */
+ virtual void attach(Callback<void()> func, IrqType type=RxIrq);
+
+ /** Attach a member function to call whenever a serial interrupt is generated
+ * @param obj pointer to the object to call the member function on
+ * @param method pointer to the member function to call
+ * @param type Which serial interrupt to attach the member function to (Serial::RxIrq for receive, TxIrq for transmit buffer empty)
+ */
+ template <typename T>
+ void attach(T *obj, void (T::*method)(), IrqType type=RxIrq) {
+ attach(Callback<void()>(obj, method), type);
+ }
+
+ /** Attach a member function to call whenever a serial interrupt is generated
+ * @param obj pointer to the object to call the member function on
+ * @param method pointer to the member function to call
+ * @param type Which serial interrupt to attach the member function to (Serial::RxIrq for receive, TxIrq for transmit buffer empty)
+ */
+ template <typename T>
+ void attach(T *obj, void (*method)(T*), IrqType type=RxIrq) {
+ attach(Callback<void()>(obj, method), type);
+ }
+};
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/MXCHIP_WIFI_Driver/MXCHIP/MXCHIP.cpp Tue Mar 21 03:56:12 2017 +0000
@@ -0,0 +1,110 @@
+
+#include "MXCHIP.h"
+
+
+MXCHIP::MXCHIP(PinName tx, PinName rx, bool debug): _serial(tx, rx, 1024), _parser(_serial), _packets(0), _packets_end(&_packets)
+{
+ _serial.baud(115200);
+ _parser.debugOn(debug);
+}
+
+bool MXCHIP::startup(int mode)
+{
+ //only 3 valid modes
+ if(mode < 1 || mode > 3)
+ {
+ return false;
+ }
+
+ bool success = reset()
+ && _parser.send("AT+CWMODE=%d", mode)
+ && _parser.recv("OK")
+ && _parser.send("AT+CIPMUX=1")
+ && _parser.recv("OK");
+
+ _parser.oob("+IPD", this, &MXCHIP::_packet_handler);
+
+ return success;
+}
+
+bool MXCHIP::reset(void)
+{
+ for (int i = 0; i < 2; i++)
+ {
+ if (_parser.send("AT+RST")
+ && _parser.recv("OK\r\nready"))
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool MXCHIP::dhcp(bool enabled, int mode)
+{
+ //only 3 valid modes
+ if(mode < 0 || mode > 2)
+ {
+ return false;
+ }
+
+ return _parser.send("AT+CWDHCP=%d,%d", enabled?1:0, mode)
+ && _parser.recv("OK");
+}
+
+bool MXCHIP::connect(const char *ap, const char *passPhrase)
+{
+ return _parser.send("AT+CWJAP=\"%s\",\"%s\"", ap, passPhrase)
+ && _parser.recv("OK");
+}
+
+bool MXCHIP::disconnect(void)
+{
+ return _parser.send("AT+CWQAP") && _parser.recv("OK");
+}
+
+const char *MXCHIP::getIPAddress(void)
+{
+ if (!(_parser.send("AT+CIFSR")
+ && _parser.recv("+CIFSR:STAIP,\"%15[^\"]\"", _ip_buffer)
+ && _parser.recv("OK"))) {
+ return 0;
+ }
+
+ return _ip_buffer;
+}
+
+const char *MXCHIP::getMACAddress(void)
+{
+ if (!(_parser.send("AT+CIFSR")
+ && _parser.recv("+CIFSR:STAMAC,\"%17[^\"]\"", _mac_buffer)
+ && _parser.recv("OK"))) {
+ return 0;
+ }
+
+ return _mac_buffer;
+}
+
+const char *MXCHIP::getGateway()
+{
+ if (!(_parser.send("AT+CIPSTA?")
+ && _parser.recv("+CIPSTA:gateway:\"%15[^\"]\"", _gateway_buffer)
+ && _parser.recv("OK"))) {
+ return 0;
+ }
+
+ return _gateway_buffer;
+}
+
+const char *MXCHIP::getNetmask()
+{
+ if (!(_parser.send("AT+CIPSTA?")
+ && _parser.recv("+CIPSTA:netmask:\"%15[^\"]\"", _netmask_buffer)
+ && _parser.recv("OK")))
+ {
+ return 0;
+ }
+
+ return _netmask_buffer;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/MXCHIP_WIFI_Driver/MXCHIP/MXCHIP.h Tue Mar 21 03:56:12 2017 +0000
@@ -0,0 +1,99 @@
+
+#ifndef __MBED_MXCHIP_H
+#define __MBED_MXCHIP_H
+
+#include "ATParser.h"
+
+class MXCHIP
+{
+public:
+ MXCHIP(PinName tx, PinName rx, bool debug=false);
+ /**
+ * Startup the ESP8266
+ *
+ * @param mode mode of WIFI 1-client, 2-host, 3-both
+ * @return true only if ESP8266 was setup correctly
+ */
+ bool startup(int mode);
+ /**
+ * Reset ESP8266
+ *
+ * @return true only if ESP8266 resets successfully
+ */
+ bool reset(void);
+
+ /**
+ * Enable/Disable DHCP
+ *
+ * @param enabled DHCP enabled when true
+ * @param mode mode of DHCP 0-softAP, 1-station, 2-both
+ * @return true only if ESP8266 enables/disables DHCP successfully
+ */
+ bool dhcp(bool enabled, int mode);
+
+ /**
+ * Connect ESP8266 to AP
+ *
+ * @param ap the name of the AP
+ * @param passPhrase the password of AP
+ * @return true only if ESP8266 is connected successfully
+ */
+ bool connect(const char *ap, const char *passPhrase);
+
+ /**
+ * Disconnect ESP8266 from AP
+ *
+ * @return true only if ESP8266 is disconnected successfully
+ */
+ bool disconnect(void);
+
+ /**
+ * Get the IP address of ESP8266
+ *
+ * @return null-teriminated IP address or null if no IP address is assigned
+ */
+ const char *getIPAddress(void);
+
+ /**
+ * Get the MAC address of ESP8266
+ *
+ * @return null-terminated MAC address or null if no MAC address is assigned
+ */
+ const char *getMACAddress(void);
+
+ /** Get the local gateway
+ *
+ * @return Null-terminated representation of the local gateway
+ * or null if no network mask has been recieved
+ */
+ const char *getGateway();
+
+ /** Get the local network mask
+ *
+ * @return Null-terminated representation of the local network mask
+ * or null if no network mask has been recieved
+ */
+ const char *getNetmask();
+
+
+private:
+ BufferedSerial _serial;
+ ATParser _parser;
+
+ struct packet
+ {
+ struct packet *next;
+ int id;
+ uint32_t len;
+ // data follows
+ } *_packets, **_packets_end;
+
+ //buffer
+ char _ip_buffer[16];
+ char _gateway_buffer[16];
+ char _netmask_buffer[16];
+ char _mac_buffer[18];
+
+}
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/MXCHIP_WIFI_Driver/MXCHIP_WIFI_Interface.cpp Tue Mar 21 03:56:12 2017 +0000
@@ -0,0 +1,38 @@
+#include "MXCHIP_WIFI_Interface.h"
+
+MXCHIP_WIFI_Interface::MXCHIP_WIFI_Interface(PinName tx, PinName rx, bool debug): _mxchip(tx, rx, debug)
+{
+
+}
+
+int MXCHIP_WIFI_Interface::connect(const char *ssid, const char *pass, nsapi_security_t security = NSAPI_SECURITY_NONE,
+ uint8_t channel = 0);
+{
+
+}
+
+int MXCHIP_WIFI_Interface::disconnect()
+{
+ return _mxchip.disconnect();
+}
+
+const char *MXCHIP_WIFI_Interface::get_ip_address()
+{
+ return _mxchip.getIPAddress();
+}
+
+const char *MXCHIP_WIFI_Interface::get_mac_address()
+{
+ return _mxchip.getMACAddress();
+}
+
+const char *MXCHIP_WIFI_Interface::get_gateway()
+{
+ return _mxchip.getGateway();
+}
+
+const char *MXCHIP_WIFI_Interface::get_netmask()
+{
+ return _mxchip.getNetmask();
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/MXCHIP_WIFI_Driver/MXCHIP_WIFI_Interface.h Tue Mar 21 03:56:12 2017 +0000
@@ -0,0 +1,65 @@
+#ifndef __MBED_MXCHIP_WIFI_Interface_H
+#define __MBED_MXCHIP_WIFI_Interface_H
+
+#include "mbed.h"
+#include "MXCHIP.h"
+
+class MXCHIP_WIFI_Interface
+{
+public:
+ /** MXCHIP_WIFI_Interface lifetime
+ * @param tx TX pin
+ * @param rx RX pin
+ * @param debug Enable debugging
+ */
+ MXCHIP_WIFI_Interface(PinName tx, PinName rx);
+
+ /** Start the interface
+ *
+ * Attempts to connect to a WiFi network.
+ *
+ * @param ssid Name of the network to connect to
+ * @param pass Security passphrase to connect to the network
+ * @param security Type of encryption for connection (Default: NSAPI_SECURITY_NONE)
+ * @param channel This parameter is not supported, setting it to anything else than 0 will result in NSAPI_ERROR_UNSUPPORTED
+ * @return 0 on success, or error code on failure
+ */
+ int connect(const char *ssid, const char *pass, nsapi_security_t security = NSAPI_SECURITY_NONE,
+ uint8_t channel = 0);
+
+ /** Stop the interface
+ * @return 0 on success, negative on failure
+ */
+ int disconnect();
+
+ /** Get the internally stored IP address
+ * @return IP address of the interface or null if not yet connected
+ */
+ const char *get_ip_address();
+
+ /** Get the internally stored MAC address
+ * @return MAC address of the interface
+ */
+ const char *get_mac_address();
+
+
+
+
+ const char *get_gateway();
+
+ /** Get the local network mask
+ *
+ * @return Null-terminated representation of the local network mask
+ * or null if no network mask has been recieved
+ */
+ const char *get_netmask();
+
+private:
+ MXCHIP _mxchip;
+
+
+
+};
+
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/README.md Tue Mar 21 03:56:12 2017 +0000 @@ -0,0 +1,87 @@ +# Getting started with Blinky on mbed OS + +This guide reviews the steps required to get Blinky working on an mbed OS platform. + +Please install [mbed CLI](https://github.com/ARMmbed/mbed-cli#installing-mbed-cli). + +## Import the example application + +From the command-line, import the example: + +``` +mbed import mbed-os-example-blinky +cd mbed-os-example-blinky +``` + +### Now compile + +Invoke `mbed compile`, and specify the name of your platform and your favorite toolchain (`GCC_ARM`, `ARM`, `IAR`). For example, for the ARM Compiler 5: + +``` +mbed compile -m K64F -t ARM +``` + +Your PC may take a few minutes to compile your code. At the end, you see the following result: + +``` +[snip] ++----------------------------+-------+-------+------+ +| Module | .text | .data | .bss | ++----------------------------+-------+-------+------+ +| Misc | 13939 | 24 | 1372 | +| core/hal | 16993 | 96 | 296 | +| core/rtos | 7384 | 92 | 4204 | +| features/FEATURE_IPV4 | 80 | 0 | 176 | +| frameworks/greentea-client | 1830 | 60 | 44 | +| frameworks/utest | 2392 | 512 | 292 | +| Subtotals | 42618 | 784 | 6384 | ++----------------------------+-------+-------+------+ +Allocated Heap: unknown +Allocated Stack: unknown +Total Static RAM memory (data + bss): 7168 bytes +Total RAM memory (data + bss + heap + stack): 7168 bytes +Total Flash memory (text + data + misc): 43402 bytes +Image: .\.build\K64F\ARM\mbed-os-example-blinky.bin +``` + +### Program your board + +1. Connect your mbed device to the computer over USB. +1. Copy the binary file to the mbed device. +1. Press the reset button to start the program. + +The LED on your platform turns on and off. + +## Export the project to Keil MDK, and debug your application + +From the command-line, run the following command: + +``` +mbed export -m K64F -i uvision +``` + +To debug the application: + +1. Start uVision. +1. Import the uVision project generated earlier. +1. Compile your application, and generate an `.axf` file. +1. Make sure uVision is configured to debug over CMSIS-DAP (From the Project menu > Options for Target '...' > Debug tab > Use CMSIS-DAP Debugger). +1. Set breakpoints, and start a debug session. + + + +## Troubleshooting + +1. Make sure `mbed-cli` is working correctly and its version is `>1.0.0` + + ``` + mbed --version + ``` + + If not, you can update it: + + ``` + pip install mbed-cli --upgrade + ``` + +2. If using Keil MDK, make sure you have a license installed. [MDK-Lite](http://www.keil.com/arm/mdk.asp) has a 32 KB restriction on code size. \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp Tue Mar 21 03:56:12 2017 +0000
@@ -0,0 +1,22 @@
+#include "mbed.h"
+#include "MXCHIP_WIFI_Interface.h"
+
+
+DigitalOut led1(LED1);
+
+Serial pc(SERIAL_TX, SERIAL_RX);
+
+
+// main() runs in its own thread in the OS
+int main()
+{
+
+ while (true)
+ {
+ led1 = !led1;
+ wait(0.5);
+
+
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os.lib Tue Mar 21 03:56:12 2017 +0000 @@ -0,0 +1,1 @@ +https://github.com/ARMmbed/mbed-os/#f4864dc6429e1ff5474111d4e0f6bee36a759b1c