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 1:32ac89dcd434, committed 2018-10-03
- Comitter:
- marcel1691
- Date:
- Wed Oct 03 14:07:46 2018 +0000
- Parent:
- 0:62e55edab701
- Commit message:
- ATParser doppelt
Changed in this revision
--- a/ATParser/ATParser.cpp Wed Oct 03 14:03:01 2018 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,454 +0,0 @@
-/* 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"
-
-#ifdef LF
-#undef LF
-#define LF 10
-#else
-#define LF 10
-#endif
-
-#ifdef CR
-#undef CR
-#define CR 13
-#else
-#define CR 13
-#endif
-#define MIN(a,b) (((a)<(b))?(a):(b))
-
-// activate / de-activate debug
-#define dbg_on 0
-#define AT_DATA_PRINT 0
-#define AT_COMMAND_PRINT 0
-#define AT_HEXA_DATA 0
-
-ATParser::ATParser(BufferedSpi &serial_spi, const char *delimiter, int buffer_size, int timeout) :
- _serial_spi(&serial_spi),
- _buffer_size(buffer_size), _in_prev(0), _oobs(NULL)
-{
- _buffer = new char[buffer_size];
- setTimeout(timeout);
- setDelimiter(delimiter);
-}
-
-
-// getc/putc handling with timeouts
-int ATParser::putc(char c)
-{
- return _serial_spi->putc(c);
-}
-
-int ATParser::getc()
-{
- return _serial_spi->getc();
-}
-
-void ATParser::flush()
-{
- _bufferMutex.lock();
- while (_serial_spi->readable()) {
- _serial_spi->getc();
- }
- _bufferMutex.unlock();
-}
-
-// read/write handling with timeouts
-int ATParser::write(const char *data, int size_of_data, int size_in_buff)
-{
- int i = 0;
- _bufferMutex.lock();
- debug_if(dbg_on, "ATParser write: %d BYTES\r\n", size_of_data);
- debug_if(AT_DATA_PRINT, "ATParser write: (ASCII) ", size_of_data);
- for (; i < size_of_data; i++) {
- debug_if(AT_DATA_PRINT, "%c", data[i]);
- if (putc(data[i]) < 0) {
- debug_if(AT_DATA_PRINT, "\r\n");
- _bufferMutex.unlock();
- return -1;
- }
- }
- debug_if(AT_DATA_PRINT, "\r\n");
-
- _serial_spi->buffsend(size_of_data + size_in_buff);
- _bufferMutex.unlock();
-
- return (size_of_data + size_in_buff);
-}
-
-int ATParser::read(char *data)
-{
- int readsize;
- int i = 0;
-
- _bufferMutex.lock();
-
- //this->flush();
- if (!_serial_spi->readable()) {
- readsize = _serial_spi->read();
- } else {
- debug_if(dbg_on, "Pending data when reading from WIFI\r\n");
- return -1;
- }
-
- debug_if(dbg_on, "ATParser read: %d data avail in SPI\r\n", readsize);
-
- if (readsize < 0) {
- _bufferMutex.unlock();
- return -1;
- }
-
- for (i = 0 ; i < readsize; i++) {
- int c = getc();
- if (c < 0) {
- _bufferMutex.unlock();
- return -1;
- }
- data[i] = c;
- }
-
-#if AT_HEXA_DATA
- debug_if(AT_DATA_PRINT, "ATParser read: (HEXA) ");
- for (i = 0; i < readsize; i++) {
- debug_if(AT_DATA_PRINT, "%2X ", data[i]);
- if ((i + 1) % 20 == 0) {
- debug_if(AT_DATA_PRINT, "\r\n");
- }
- }
- debug_if(AT_DATA_PRINT, "\r\n");
-#endif
- debug_if(AT_DATA_PRINT, "ATParser read: (ASCII) ");
- for (i = 0; i < readsize; i++) {
- debug_if(AT_DATA_PRINT, "%c", data[i]);
- }
- debug_if(AT_DATA_PRINT, "\r\n");
-
- _bufferMutex.unlock();
-
- return (readsize);
-}
-
-// printf/scanf handling
-int ATParser::vprintf(const char *format, va_list args)
-{
- _bufferMutex.lock();
- if (vsprintf(_buffer, format, args) < 0) {
- _bufferMutex.unlock();
- return false;
- }
-
- int i = 0;
- for (; _buffer[i]; i++) {
- if (putc(_buffer[i]) < 0) {
- _bufferMutex.unlock();
- return -1;
- }
- }
- _bufferMutex.unlock();
-
- 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;
-
- _bufferMutex.lock();
-
- 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) {
- _bufferMutex.unlock();
- return false;
- }
- // Recieve next character
- int c = getc();
- if (c < 0) {
- _bufferMutex.unlock();
- 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);
- _bufferMutex.unlock();
- return j;
- }
- }
-}
-
-
-// Command parsing with line handling
-bool ATParser::vsend(const char *command, va_list args)
-{
- int i = 0, j = 0;
- _bufferMutex.lock();
- // Create and send command
- if (vsprintf(_buffer, command, args) < 0) {
- _bufferMutex.unlock();
- return false;
- }
- /* get buffer length */
- for (i = 0; _buffer[i]; i++) {
- }
-
- for (j = 0; _delimiter[j]; j++) {
- _buffer[i + j] = _delimiter[j];
- }
- _buffer[i + j] = 0; // only to get a clean debug log
-
- bool ret = !(_serial_spi->buffwrite(_buffer, i + j) < 0);
-
- debug_if(AT_COMMAND_PRINT, "AT> %s\n", _buffer);
- _bufferMutex.unlock();
- return ret;
-}
-
-bool ATParser::vrecv(const char *response, va_list args)
-{
- _bufferMutex.lock();
-
- if (!_serial_spi->readable()) {
- // debug_if(dbg_on, "NO DATA, read again\r\n");
- if (_serial_spi->read() < 0) {
- return false;
- }
- }
- // else {
- // debug_if(dbg_on, "Pending data\r\n");
- // }
-
-restart:
- _aborted = false;
- // 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;
- bool whole_line_wanted = false;
-
- while (response[i]) {
- if (response[i] == '%' && response[i + 1] != '%' && response[i + 1] != '*') {
- _buffer[offset++] = '%';
- _buffer[offset++] = '*';
- i++;
- } else {
- _buffer[offset++] = response[i++];
- // Find linebreaks, taking care not to be fooled if they're in a %[^\n] conversion specification
- if (response[i - 1] == '\n' && !(i >= 3 && response[i - 3] == '[' && response[i - 2] == '^')) {
- whole_line_wanted = true;
- break;
- }
- }
- }
-
- // 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;
-
- // debug_if(dbg_on, "ATParser vrecv: AT? ====%s====\n", _buffer);
- // 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) {
- debug_if(dbg_on, "AT(Timeout)\n");
- _bufferMutex.unlock();
- return false;
- }
-
- // debug_if(AT_DATA_PRINT, "%2X ", c);
-
- _buffer[offset + j++] = c;
- _buffer[offset + j] = 0;
-
- // Check for oob data
- for (struct oob *oob = _oobs; oob; oob = oob->next) {
- if ((unsigned)j == oob->len && memcmp(
- oob->prefix, _buffer + offset, oob->len) == 0) {
- debug_if(dbg_on, "AT! %s\n", oob->prefix);
- oob->cb();
-
- if (_aborted) {
- debug_if(dbg_on, "AT(Aborted)\n");
- _bufferMutex.unlock();
- return false;
- }
- // oob may have corrupted non-reentrant buffer,
- // so we need to set it up again
- goto restart;
- }
- }
-
- // Check for match
- int count = -1;
- if (whole_line_wanted && c != '\n') {
- // Don't attempt scanning until we get delimiter if they included it in format
- // This allows recv("Foo: %s\n") to work, and not match with just the first character of a string
- // (scanf does not itself match whitespace in its format string, so \n is not significant to it)
- } else {
- sscanf(_buffer + offset, _buffer, &count);
- }
-
- // We only succeed if all characters in the response are matched
- if (count == j) {
- debug_if(AT_COMMAND_PRINT, "AT= ====%s====\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 ((c == '\n')) {
- // debug_if(dbg_on, "New line AT<<< %s", _buffer+offset);
- j = 0;
- }
- if ((j + 1 >= (_buffer_size - offset))) {
-
- debug_if(dbg_on, "Out of space AT<<< %s, j=%d", _buffer + offset, j);
- j = 0;
- }
- }
- }
-
- _bufferMutex.unlock();
-
- 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 = new struct oob;
- oob->len = strlen(prefix);
- oob->prefix = prefix;
- oob->cb = cb;
- oob->next = _oobs;
- _oobs = oob;
-}
-
-void ATParser::abort()
-{
- _aborted = true;
-}
-
-
-
--- a/ATParser/ATParser.h Wed Oct 03 14:03:01 2018 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,246 +0,0 @@
-/* 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
- *
- */
-#ifndef AT_PARSER_H
-#define AT_PARSER_H
-
-#include "mbed.h"
-#include <cstdarg>
-#include <vector>
-#include "BufferedSpi.h"
-#include "Callback.h"
-
-#define DEFAULT_SPI_TIMEOUT 60000 /* 1 minute */
-
-/**
-* 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
- BufferedSpi *_serial_spi;
- int _buffer_size;
- char *_buffer;
- Mutex _bufferMutex;
-
- // Parsing information
- const char *_delimiter;
- int _delim_size;
- char _in_prev;
- volatile bool _aborted;
-
- struct oob {
- unsigned len;
- const char *prefix;
- mbed::Callback<void()> cb;
- oob *next;
- };
- oob *_oobs;
-
-public:
- /**
- * Constructor
- *
- * @param serial spi 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(BufferedSpi &serial_spi, const char *delimiter = "\r\n", int buffer_size = 1440, int timeout = DEFAULT_SPI_TIMEOUT);
-
- /**
- * Destructor
- */
- ~ATParser()
- {
- while (_oobs) {
- struct oob *oob = _oobs;
- _oobs = oob->next;
- delete oob;
- }
- delete[] _buffer;
- }
-
- /**
- * Allows timeout to be changed between commands
- *
- * @param timeout timeout of the connection
- */
- void setTimeout(int timeout)
- {
- _serial_spi->setTimeout(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);
- }
-
- /**
- * 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 a newline
- * @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);
-
- /**
- * Receive an AT response
- *
- * Receives a formatted response using scanf style formatting
- * @see scanf
- *
- * Responses are parsed line at a time.
- * Any received 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
- * assuming the header of the command is already in _txbuffer
- *
- * @param data the array of bytes to write
- * @param size_of_data number of bytes in data array
- * @param size_in_buff number of bytes already in the internal buff
- * @return number of bytes written or -1 on failure
- */
- int write(const char *data, int size_of_data, int size_in_buff);
-
- /**
- * 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);
-
- /**
- * 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);
-
- /**
- * Flushes the underlying stream
- */
- void flush();
-
- /**
- * Abort current recv
- *
- * Can be called from oob handler to interrupt the current
- * recv operation.
- */
- void abort();
-
- /**
- * Process out-of-band data
- *
- * Process out-of-band data in the receive buffer. This function
- * returns immediately if there is no data to process.
- *
- * @return true if oob data processed, false otherwise
- */
- bool process_oob(void);
- /**
- * Get buffer_size
- */
- int get_size(void)
- {
- return _buffer_size;
- }
-
-};
-#endif
--- a/ATParser/BufferedSpi/Buffer/MyBuffer.cpp Wed Oct 03 14:03:01 2018 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,86 +0,0 @@
-
-/**
- * @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>
-uint32_t MyBuffer<T>::getNbAvailable()
-{
- if (_wloc >= _rloc) {
- return (_wloc - _rloc);
- } else {
- return (_size - _rloc + _wloc);
- }
-}
-
-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>;
--- a/ATParser/BufferedSpi/Buffer/MyBuffer.h Wed Oct 03 14:03:01 2018 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,164 +0,0 @@
-
-/**
- * @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();
- uint32_t getNbAvailable();
-
- /** 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;
- //return 1;
-}
-
-#endif
-
--- a/ATParser/BufferedSpi/BufferedPrint.c Wed Oct 03 14:03:01 2018 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-/*
- * 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 BufferedSpiThunk(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 ) {
- BufferedSpiThunk(stream, buffer, r);
- }
- return r;
-}
--- a/ATParser/BufferedSpi/BufferedSpi.cpp Wed Oct 03 14:03:01 2018 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,333 +0,0 @@
-/**
- * @file BufferedSpi.cpp
- * @brief Software Buffer - Extends mbed SPI functionallity
- * @author Armelle Duboc
- * @version 1.0
- * @see
- *
- * Copyright (c) STMicroelectronics 2017
- *
- * 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 "BufferedSpi.h"
-#include <stdarg.h>
-#include "mbed_debug.h"
-#include "mbed_error.h"
-
-// change to true to add few SPI debug lines
-#define local_debug false
-
-extern "C" int BufferedPrintfC(void *stream, int size, const char *format, va_list arg);
-
-void BufferedSpi::DatareadyRising(void)
-{
- if (_cmddata_rdy_rising_event == 1) {
- _cmddata_rdy_rising_event = 0;
- }
-}
-
-int BufferedSpi::wait_cmddata_rdy_high(void)
-{
- Timer timer;
- timer.start();
-
- /* wait for dataready = 1 */
- while (dataready.read() == 0) {
- if (timer.read_ms() > _timeout) {
- debug_if(local_debug, "ERROR: SPI write timeout\r\n");
- return -1;
- }
- }
-
- _cmddata_rdy_rising_event = 1;
-
- return 0;
-}
-
-int BufferedSpi::wait_cmddata_rdy_rising_event(void)
-{
- Timer timer;
- timer.start();
-
- while (_cmddata_rdy_rising_event == 1) {
- if (timer.read_ms() > _timeout) {
- _cmddata_rdy_rising_event = 0;
- if (dataready.read() == 1) {
- debug_if(local_debug, "ERROR: We missed rising event !! (timemout=%d)\r\n", _timeout);
- }
- debug_if(local_debug, "ERROR: SPI read timeout\r\n");
- return -1;
- }
- }
-
- return 0;
-}
-
-BufferedSpi::BufferedSpi(PinName mosi, PinName miso, PinName sclk, PinName _nss, PinName _datareadypin,
- uint32_t buf_size, uint32_t tx_multiple, const char *name)
- : SPI(mosi, miso, sclk, NC), nss(_nss), _txbuf((uint32_t)(tx_multiple * buf_size)), _rxbuf(buf_size), dataready(_datareadypin)
-{
- this->_buf_size = buf_size;
- this->_tx_multiple = tx_multiple;
- this->_sigio_event = 0;
-
- _datareadyInt = new InterruptIn(_datareadypin);
- _datareadyInt->rise(callback(this, &BufferedSpi::DatareadyRising));
-
- _cmddata_rdy_rising_event = 1;
-
- return;
-}
-
-BufferedSpi::~BufferedSpi(void)
-{
-
- return;
-}
-
-void BufferedSpi::frequency(int hz)
-{
- SPI::frequency(hz);
-}
-
-void BufferedSpi::format(int bits, int mode)
-{
- SPI::format(bits, mode);
-}
-
-void BufferedSpi::disable_nss()
-{
- nss = 1;
- wait_us(15);
-}
-
-void BufferedSpi::enable_nss()
-{
- nss = 0;
- wait_us(15);
-}
-
-int BufferedSpi::readable(void)
-{
- return _rxbuf.available(); // note: look if things are in the buffer
-}
-
-int BufferedSpi::writeable(void)
-{
- return 1; // buffer allows overwriting by design, always true
-}
-
-int BufferedSpi::getc(void)
-{
- if (_rxbuf.available()) {
- return _rxbuf;
- } else {
- return -1;
- }
-}
-
-int BufferedSpi::putc(int c)
-{
- _txbuf = (char)c;
-
- return c;
-}
-
-void BufferedSpi::flush_txbuf(void)
-{
- _txbuf.clear();
-}
-
-int BufferedSpi::puts(const char *s)
-{
- if (s != NULL) {
- const char *ptr = s;
-
- while (*(ptr) != 0) {
- _txbuf = *(ptr++);
- }
- _txbuf = '\n'; // done per puts definition
- BufferedSpi::txIrq(); // only write to hardware in one place
- return (ptr - s) + 1;
- }
- return 0;
-}
-
-extern "C" size_t BufferedSpiThunk(void *buf_spi, const void *s, size_t length)
-{
- BufferedSpi *buffered_spi = (BufferedSpi *)buf_spi;
- return buffered_spi->buffwrite(s, length);
-}
-
-int BufferedSpi::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 BufferedSpi::buffwrite(const void *s, size_t length)
-{
- /* flush buffer from previous message */
- this->flush_txbuf();
-
- if (wait_cmddata_rdy_high() < 0) {
- debug_if(local_debug, "BufferedSpi::buffwrite timeout (%d)\r\n", _timeout);
- return -1;
- }
-
- this->enable_nss();
-
- if (s != NULL && length > 0) {
- /* 1st fill _txbuf */
- const char *ptr = (const char *)s;
- const char *end = ptr + length;
-
- while (ptr != end) {
- _txbuf = *(ptr++);
- }
- if (length & 1) { /* padding to send the last char */
- _txbuf = '\n';
- length++;
- }
-
- /* 2nd write in SPI */
- BufferedSpi::txIrq(); // only write to hardware in one place
-
- this->disable_nss();
- return ptr - (const char *)s;
- }
- this->disable_nss();
-
- return 0;
-}
-
-ssize_t BufferedSpi::buffsend(size_t length)
-{
- /* wait for dataready = 1 */
- if (wait_cmddata_rdy_high() < 0) {
- debug_if(local_debug, "BufferedSpi::buffsend timeout (%d)\r\n", _timeout);
- return -1;
- }
-
- this->enable_nss();
-
- /* _txbuffer is already filled with data to send */
- /* check if _txbuffer needs padding to send the last char */
- if (length & 1) {
- _txbuf = '\n';
- length++;
- }
- BufferedSpi::txIrq(); // only write to hardware in one place
-
- this->disable_nss();
-
- return length;
-}
-
-ssize_t BufferedSpi::read()
-{
- return this->read(0);
-}
-
-ssize_t BufferedSpi::read(uint32_t max)
-{
- uint32_t len = 0;
- uint8_t FirstRemoved = 1;
- int tmp;
-
- disable_nss();
-
- /* wait for data ready is up */
- if (wait_cmddata_rdy_rising_event() != 0) {
- debug_if(local_debug, "BufferedSpi::read timeout (%d)\r\n", _timeout);
- return -1;
- }
-
- enable_nss();
- while (dataready.read() == 1 && (len < (_buf_size - 2))) {
- tmp = SPI::write(0xAA); // dummy write to receive 2 bytes
-
- if (!((len == 0) && (tmp == 0x0A0D) && (FirstRemoved))) {
- /* do not take into account the 2 firts \r \n char in the buffer */
- if ((max == 0) || (len < max)) {
- _rxbuf = (char)(tmp & 0x00FF);
- _rxbuf = (char)((tmp >> 8) & 0xFF);
- len += 2;
- }
- } else {
- FirstRemoved = 0;
- }
- }
- disable_nss();
-
- if (len >= _buf_size) {
- debug_if(local_debug, "firmware ERROR ES_WIFI_ERROR_STUFFING_FOREVER\r\n");
- return -1;
- }
-
- debug_if(local_debug, "SPI READ %d BYTES\r\n", len);
-
- return len;
-}
-
-void BufferedSpi::txIrq(void)
-{
- /* write everything available in the _txbuffer */
- int value = 0;
- int dbg_cnt = 0;
- while (_txbuf.available() && (_txbuf.getNbAvailable() > 0)) {
- value = _txbuf.get();
- if (_txbuf.available() && ((_txbuf.getNbAvailable() % 2) != 0)) {
- value |= ((_txbuf.get() << 8) & 0XFF00);
- SPI::write(value);
- dbg_cnt++;
- }
- }
- debug_if(local_debug, "SPI Sent %d BYTES\r\n", 2 * dbg_cnt);
- // disable the TX interrupt when there is nothing left to send
- BufferedSpi::attach(NULL, BufferedSpi::TxIrq);
- // trigger callback if necessary
- if (_cbs[TxIrq]) {
- _cbs[TxIrq]();
- }
- return;
-}
-
-void BufferedSpi::prime(void)
-{
- BufferedSpi::txIrq(); // only write to hardware in one place
- return;
-}
-
-void BufferedSpi::attach(Callback<void()> func, IrqType type)
-{
- _cbs[type] = func;
-}
-
-void BufferedSpi::sigio(Callback<void()> func)
-{
- core_util_critical_section_enter();
- _sigio_cb = func;
- if (_sigio_cb) {
- if (_sigio_event == 1) {
- _sigio_cb();
- _sigio_event = 0;
- }
- }
- core_util_critical_section_exit();
-}
-
--- a/ATParser/BufferedSpi/BufferedSpi.h Wed Oct 03 14:03:01 2018 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,234 +0,0 @@
-
-/**
- * @file BufferedSpi.h
- * @brief Software Buffer - Extends mbed SPI functionallity
- * @author Armelle Duboc
- * @version 1.0
- * @see
- *
- * Copyright (c) STMicroelectronics 2017
- *
- * 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 BUFFEREDSPI_H
-#define BUFFEREDSPI_H
-
-#include "mbed.h"
-#include "MyBuffer.h"
-
-/** A spi port (SPI) for communication with wifi device
- *
- * 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 BufferedSpi
- * @brief Software buffers and interrupt driven tx and rx for Serial
- */
-class BufferedSpi : public SPI {
-private:
- DigitalOut nss;
- MyBuffer <char> _txbuf;
- uint32_t _buf_size;
- uint32_t _tx_multiple;
- volatile int _timeout;
- void txIrq(void);
- void prime(void);
-
- InterruptIn *_datareadyInt;
- volatile int _cmddata_rdy_rising_event;
- void DatareadyRising(void);
- int wait_cmddata_rdy_rising_event(void);
- int wait_cmddata_rdy_high(void);
-
-
- Callback<void()> _cbs[2];
-
- Callback<void()> _sigio_cb;
- uint8_t _sigio_event;
-
-public:
- MyBuffer <char> _rxbuf;
- DigitalIn dataready;
- enum IrqType {
- RxIrq = 0,
- TxIrq,
-
- IrqCnt
- };
-
- /** Create a BufferedSpi Port, connected to the specified transmit and receive pins
- * @param SPI mosi pin
- * @param SPI miso pin
- * @param SPI sclk pin
- * @param SPI nss pin
- * @param Dataready 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
- */
- BufferedSpi(PinName mosi, PinName miso, PinName sclk, PinName nss, PinName datareadypin, uint32_t buf_size = 2500, uint32_t tx_multiple = 1, const char *name = NULL);
-
- /** Destroy a BufferedSpi Port
- */
- virtual ~BufferedSpi(void);
-
- /** call to SPI frequency Function
- */
- virtual void frequency(int hz);
-
- /** clear the transmit buffer
- */
- virtual void flush_txbuf(void);
-
- /** call to SPI format function
- */
- virtual void format(int bits, int mode);
-
- virtual void enable_nss(void);
-
- virtual void disable_nss(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 BufferedSpi Port.
- * Should check readable() before calling this.
- * @return A byte that came in on the SPI Port
- */
- virtual int getc(void);
-
- /** Write a single byte to the BufferedSpi Port.
- * @param c The byte to write to the SPI Port
- * @return The byte that was written to the SPI Port Buffer
- */
- virtual int putc(int c);
-
- /** Write a string to the BufferedSpi Port. Must be NULL terminated
- * @param s The string to write to the Spi Port
- * @return The number of bytes written to the Spi Port Buffer
- */
- virtual int puts(const char *s);
-
- /** Write a formatted string to the BufferedSpi Port.
- * @param format The string + format specifiers to write to the Spi Port
- * @return The number of bytes written to the Spi Port Buffer
- */
- virtual int printf(const char *format, ...);
-
- /** Write data to the Buffered Spi 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 Spi Port Buffer
- */
- virtual ssize_t buffwrite(const void *s, std::size_t length);
-
- /** Send datas to the Spi port that are already present
- * in the internal _txbuffer
- * @param length
- * @return the number of bytes written on the SPI port
- */
- virtual ssize_t buffsend(size_t length);
-
- /** Read data from the Spi Port to the _rxbuf
- * @param max: optional. = max sieze of the input read
- * @return The number of bytes read from the SPI port and written to the _rxbuf
- */
- virtual ssize_t read();
- virtual ssize_t read(uint32_t max);
-
- /**
- * Allows timeout to be changed between commands
- *
- * @param timeout timeout of the connection in ms
- */
- void setTimeout(int timeout)
- {
- /* this is a safe guard timeout at SPI level in case module is stuck */
- _timeout = timeout;
- }
-
- /** Register a callback once any data is ready for sockets
- * @param func Function to call on state change
- */
- virtual void sigio(Callback<void()> func);
-
- /** 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