wifi test

Dependencies:   X_NUCLEO_IKS01A2 mbed-http

Committer:
JMF
Date:
Wed Sep 05 14:28:24 2018 +0000
Revision:
0:24d3eb812fd4
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
JMF 0:24d3eb812fd4 1 /**
JMF 0:24d3eb812fd4 2 * @file BufferedSpi.cpp
JMF 0:24d3eb812fd4 3 * @brief Software Buffer - Extends mbed SPI functionallity
JMF 0:24d3eb812fd4 4 * @author Armelle Duboc
JMF 0:24d3eb812fd4 5 * @version 1.0
JMF 0:24d3eb812fd4 6 * @see
JMF 0:24d3eb812fd4 7 *
JMF 0:24d3eb812fd4 8 * Copyright (c) STMicroelectronics 2017
JMF 0:24d3eb812fd4 9 *
JMF 0:24d3eb812fd4 10 * Licensed under the Apache License, Version 2.0 (the "License");
JMF 0:24d3eb812fd4 11 * you may not use this file except in compliance with the License.
JMF 0:24d3eb812fd4 12 * You may obtain a copy of the License at
JMF 0:24d3eb812fd4 13 *
JMF 0:24d3eb812fd4 14 * http://www.apache.org/licenses/LICENSE-2.0
JMF 0:24d3eb812fd4 15 *
JMF 0:24d3eb812fd4 16 * Unless required by applicable law or agreed to in writing, software
JMF 0:24d3eb812fd4 17 * distributed under the License is distributed on an "AS IS" BASIS,
JMF 0:24d3eb812fd4 18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
JMF 0:24d3eb812fd4 19 * See the License for the specific language governing permissions and
JMF 0:24d3eb812fd4 20 * limitations under the License.
JMF 0:24d3eb812fd4 21 */
JMF 0:24d3eb812fd4 22
JMF 0:24d3eb812fd4 23 #include "BufferedSpi.h"
JMF 0:24d3eb812fd4 24 #include <stdarg.h>
JMF 0:24d3eb812fd4 25 #include "mbed_debug.h"
JMF 0:24d3eb812fd4 26 #include "mbed_error.h"
JMF 0:24d3eb812fd4 27
JMF 0:24d3eb812fd4 28 // change to true to add few SPI debug lines
JMF 0:24d3eb812fd4 29 #define local_debug false
JMF 0:24d3eb812fd4 30
JMF 0:24d3eb812fd4 31 extern "C" int BufferedPrintfC(void *stream, int size, const char *format, va_list arg);
JMF 0:24d3eb812fd4 32
JMF 0:24d3eb812fd4 33 void BufferedSpi::DatareadyRising(void)
JMF 0:24d3eb812fd4 34 {
JMF 0:24d3eb812fd4 35 if (_cmddata_rdy_rising_event == 1) {
JMF 0:24d3eb812fd4 36 _cmddata_rdy_rising_event = 0;
JMF 0:24d3eb812fd4 37 }
JMF 0:24d3eb812fd4 38 }
JMF 0:24d3eb812fd4 39
JMF 0:24d3eb812fd4 40 int BufferedSpi::wait_cmddata_rdy_high(void)
JMF 0:24d3eb812fd4 41 {
JMF 0:24d3eb812fd4 42 Timer timer;
JMF 0:24d3eb812fd4 43 timer.start();
JMF 0:24d3eb812fd4 44
JMF 0:24d3eb812fd4 45 /* wait for dataready = 1 */
JMF 0:24d3eb812fd4 46 while (dataready.read() == 0) {
JMF 0:24d3eb812fd4 47 if (timer.read_ms() > _timeout) {
JMF 0:24d3eb812fd4 48 debug_if(local_debug, "ERROR: SPI write timeout\r\n");
JMF 0:24d3eb812fd4 49 return -1;
JMF 0:24d3eb812fd4 50 }
JMF 0:24d3eb812fd4 51 }
JMF 0:24d3eb812fd4 52
JMF 0:24d3eb812fd4 53 _cmddata_rdy_rising_event = 1;
JMF 0:24d3eb812fd4 54
JMF 0:24d3eb812fd4 55 return 0;
JMF 0:24d3eb812fd4 56 }
JMF 0:24d3eb812fd4 57
JMF 0:24d3eb812fd4 58 int BufferedSpi::wait_cmddata_rdy_rising_event(void)
JMF 0:24d3eb812fd4 59 {
JMF 0:24d3eb812fd4 60 Timer timer;
JMF 0:24d3eb812fd4 61 timer.start();
JMF 0:24d3eb812fd4 62
JMF 0:24d3eb812fd4 63 while (_cmddata_rdy_rising_event == 1) {
JMF 0:24d3eb812fd4 64 if (timer.read_ms() > _timeout) {
JMF 0:24d3eb812fd4 65 _cmddata_rdy_rising_event = 0;
JMF 0:24d3eb812fd4 66 if (dataready.read() == 1) {
JMF 0:24d3eb812fd4 67 debug_if(local_debug, "ERROR: We missed rising event !! (timemout=%d)\r\n", _timeout);
JMF 0:24d3eb812fd4 68 }
JMF 0:24d3eb812fd4 69 debug_if(local_debug, "ERROR: SPI read timeout\r\n");
JMF 0:24d3eb812fd4 70 return -1;
JMF 0:24d3eb812fd4 71 }
JMF 0:24d3eb812fd4 72 }
JMF 0:24d3eb812fd4 73
JMF 0:24d3eb812fd4 74 return 0;
JMF 0:24d3eb812fd4 75 }
JMF 0:24d3eb812fd4 76
JMF 0:24d3eb812fd4 77 BufferedSpi::BufferedSpi(PinName mosi, PinName miso, PinName sclk, PinName _nss, PinName _datareadypin,
JMF 0:24d3eb812fd4 78 uint32_t buf_size, uint32_t tx_multiple, const char *name)
JMF 0:24d3eb812fd4 79 : SPI(mosi, miso, sclk, NC), nss(_nss), _txbuf((uint32_t)(tx_multiple * buf_size)), _rxbuf(buf_size), dataready(_datareadypin)
JMF 0:24d3eb812fd4 80 {
JMF 0:24d3eb812fd4 81 this->_buf_size = buf_size;
JMF 0:24d3eb812fd4 82 this->_tx_multiple = tx_multiple;
JMF 0:24d3eb812fd4 83 this->_sigio_event = 0;
JMF 0:24d3eb812fd4 84
JMF 0:24d3eb812fd4 85 _datareadyInt = new InterruptIn(_datareadypin);
JMF 0:24d3eb812fd4 86 _datareadyInt->rise(callback(this, &BufferedSpi::DatareadyRising));
JMF 0:24d3eb812fd4 87
JMF 0:24d3eb812fd4 88 _cmddata_rdy_rising_event = 1;
JMF 0:24d3eb812fd4 89
JMF 0:24d3eb812fd4 90 return;
JMF 0:24d3eb812fd4 91 }
JMF 0:24d3eb812fd4 92
JMF 0:24d3eb812fd4 93 BufferedSpi::~BufferedSpi(void)
JMF 0:24d3eb812fd4 94 {
JMF 0:24d3eb812fd4 95
JMF 0:24d3eb812fd4 96 return;
JMF 0:24d3eb812fd4 97 }
JMF 0:24d3eb812fd4 98
JMF 0:24d3eb812fd4 99 void BufferedSpi::frequency(int hz)
JMF 0:24d3eb812fd4 100 {
JMF 0:24d3eb812fd4 101 SPI::frequency(hz);
JMF 0:24d3eb812fd4 102 }
JMF 0:24d3eb812fd4 103
JMF 0:24d3eb812fd4 104 void BufferedSpi::format(int bits, int mode)
JMF 0:24d3eb812fd4 105 {
JMF 0:24d3eb812fd4 106 SPI::format(bits, mode);
JMF 0:24d3eb812fd4 107 }
JMF 0:24d3eb812fd4 108
JMF 0:24d3eb812fd4 109 void BufferedSpi::disable_nss()
JMF 0:24d3eb812fd4 110 {
JMF 0:24d3eb812fd4 111 nss = 1;
JMF 0:24d3eb812fd4 112 wait_us(15);
JMF 0:24d3eb812fd4 113 }
JMF 0:24d3eb812fd4 114
JMF 0:24d3eb812fd4 115 void BufferedSpi::enable_nss()
JMF 0:24d3eb812fd4 116 {
JMF 0:24d3eb812fd4 117 nss = 0;
JMF 0:24d3eb812fd4 118 wait_us(15);
JMF 0:24d3eb812fd4 119 }
JMF 0:24d3eb812fd4 120
JMF 0:24d3eb812fd4 121 int BufferedSpi::readable(void)
JMF 0:24d3eb812fd4 122 {
JMF 0:24d3eb812fd4 123 return _rxbuf.available(); // note: look if things are in the buffer
JMF 0:24d3eb812fd4 124 }
JMF 0:24d3eb812fd4 125
JMF 0:24d3eb812fd4 126 int BufferedSpi::writeable(void)
JMF 0:24d3eb812fd4 127 {
JMF 0:24d3eb812fd4 128 return 1; // buffer allows overwriting by design, always true
JMF 0:24d3eb812fd4 129 }
JMF 0:24d3eb812fd4 130
JMF 0:24d3eb812fd4 131 int BufferedSpi::getc(void)
JMF 0:24d3eb812fd4 132 {
JMF 0:24d3eb812fd4 133 if (_rxbuf.available()) {
JMF 0:24d3eb812fd4 134 return _rxbuf;
JMF 0:24d3eb812fd4 135 } else {
JMF 0:24d3eb812fd4 136 return -1;
JMF 0:24d3eb812fd4 137 }
JMF 0:24d3eb812fd4 138 }
JMF 0:24d3eb812fd4 139
JMF 0:24d3eb812fd4 140 int BufferedSpi::putc(int c)
JMF 0:24d3eb812fd4 141 {
JMF 0:24d3eb812fd4 142 _txbuf = (char)c;
JMF 0:24d3eb812fd4 143
JMF 0:24d3eb812fd4 144 return c;
JMF 0:24d3eb812fd4 145 }
JMF 0:24d3eb812fd4 146
JMF 0:24d3eb812fd4 147 void BufferedSpi::flush_txbuf(void)
JMF 0:24d3eb812fd4 148 {
JMF 0:24d3eb812fd4 149 _txbuf.clear();
JMF 0:24d3eb812fd4 150 }
JMF 0:24d3eb812fd4 151
JMF 0:24d3eb812fd4 152 int BufferedSpi::puts(const char *s)
JMF 0:24d3eb812fd4 153 {
JMF 0:24d3eb812fd4 154 if (s != NULL) {
JMF 0:24d3eb812fd4 155 const char *ptr = s;
JMF 0:24d3eb812fd4 156
JMF 0:24d3eb812fd4 157 while (*(ptr) != 0) {
JMF 0:24d3eb812fd4 158 _txbuf = *(ptr++);
JMF 0:24d3eb812fd4 159 }
JMF 0:24d3eb812fd4 160 _txbuf = '\n'; // done per puts definition
JMF 0:24d3eb812fd4 161 BufferedSpi::txIrq(); // only write to hardware in one place
JMF 0:24d3eb812fd4 162 return (ptr - s) + 1;
JMF 0:24d3eb812fd4 163 }
JMF 0:24d3eb812fd4 164 return 0;
JMF 0:24d3eb812fd4 165 }
JMF 0:24d3eb812fd4 166
JMF 0:24d3eb812fd4 167 extern "C" size_t BufferedSpiThunk(void *buf_spi, const void *s, size_t length)
JMF 0:24d3eb812fd4 168 {
JMF 0:24d3eb812fd4 169 BufferedSpi *buffered_spi = (BufferedSpi *)buf_spi;
JMF 0:24d3eb812fd4 170 return buffered_spi->buffwrite(s, length);
JMF 0:24d3eb812fd4 171 }
JMF 0:24d3eb812fd4 172
JMF 0:24d3eb812fd4 173 int BufferedSpi::printf(const char *format, ...)
JMF 0:24d3eb812fd4 174 {
JMF 0:24d3eb812fd4 175 va_list arg;
JMF 0:24d3eb812fd4 176 va_start(arg, format);
JMF 0:24d3eb812fd4 177 int r = BufferedPrintfC((void *)this, this->_buf_size, format, arg);
JMF 0:24d3eb812fd4 178 va_end(arg);
JMF 0:24d3eb812fd4 179 return r;
JMF 0:24d3eb812fd4 180 }
JMF 0:24d3eb812fd4 181
JMF 0:24d3eb812fd4 182 ssize_t BufferedSpi::buffwrite(const void *s, size_t length)
JMF 0:24d3eb812fd4 183 {
JMF 0:24d3eb812fd4 184 /* flush buffer from previous message */
JMF 0:24d3eb812fd4 185 this->flush_txbuf();
JMF 0:24d3eb812fd4 186
JMF 0:24d3eb812fd4 187 if (wait_cmddata_rdy_high() < 0) {
JMF 0:24d3eb812fd4 188 debug_if(local_debug, "BufferedSpi::buffwrite timeout (%d)\r\n", _timeout);
JMF 0:24d3eb812fd4 189 return -1;
JMF 0:24d3eb812fd4 190 }
JMF 0:24d3eb812fd4 191
JMF 0:24d3eb812fd4 192 this->enable_nss();
JMF 0:24d3eb812fd4 193
JMF 0:24d3eb812fd4 194 if (s != NULL && length > 0) {
JMF 0:24d3eb812fd4 195 /* 1st fill _txbuf */
JMF 0:24d3eb812fd4 196 const char *ptr = (const char *)s;
JMF 0:24d3eb812fd4 197 const char *end = ptr + length;
JMF 0:24d3eb812fd4 198
JMF 0:24d3eb812fd4 199 while (ptr != end) {
JMF 0:24d3eb812fd4 200 _txbuf = *(ptr++);
JMF 0:24d3eb812fd4 201 }
JMF 0:24d3eb812fd4 202 if (length & 1) { /* padding to send the last char */
JMF 0:24d3eb812fd4 203 _txbuf = '\n';
JMF 0:24d3eb812fd4 204 length++;
JMF 0:24d3eb812fd4 205 }
JMF 0:24d3eb812fd4 206
JMF 0:24d3eb812fd4 207 /* 2nd write in SPI */
JMF 0:24d3eb812fd4 208 BufferedSpi::txIrq(); // only write to hardware in one place
JMF 0:24d3eb812fd4 209
JMF 0:24d3eb812fd4 210 this->disable_nss();
JMF 0:24d3eb812fd4 211 return ptr - (const char *)s;
JMF 0:24d3eb812fd4 212 }
JMF 0:24d3eb812fd4 213 this->disable_nss();
JMF 0:24d3eb812fd4 214
JMF 0:24d3eb812fd4 215 return 0;
JMF 0:24d3eb812fd4 216 }
JMF 0:24d3eb812fd4 217
JMF 0:24d3eb812fd4 218 ssize_t BufferedSpi::buffsend(size_t length)
JMF 0:24d3eb812fd4 219 {
JMF 0:24d3eb812fd4 220 /* wait for dataready = 1 */
JMF 0:24d3eb812fd4 221 if (wait_cmddata_rdy_high() < 0) {
JMF 0:24d3eb812fd4 222 debug_if(local_debug, "BufferedSpi::buffsend timeout (%d)\r\n", _timeout);
JMF 0:24d3eb812fd4 223 return -1;
JMF 0:24d3eb812fd4 224 }
JMF 0:24d3eb812fd4 225
JMF 0:24d3eb812fd4 226 this->enable_nss();
JMF 0:24d3eb812fd4 227
JMF 0:24d3eb812fd4 228 /* _txbuffer is already filled with data to send */
JMF 0:24d3eb812fd4 229 /* check if _txbuffer needs padding to send the last char */
JMF 0:24d3eb812fd4 230 if (length & 1) {
JMF 0:24d3eb812fd4 231 _txbuf = '\n';
JMF 0:24d3eb812fd4 232 length++;
JMF 0:24d3eb812fd4 233 }
JMF 0:24d3eb812fd4 234 BufferedSpi::txIrq(); // only write to hardware in one place
JMF 0:24d3eb812fd4 235
JMF 0:24d3eb812fd4 236 this->disable_nss();
JMF 0:24d3eb812fd4 237
JMF 0:24d3eb812fd4 238 return length;
JMF 0:24d3eb812fd4 239 }
JMF 0:24d3eb812fd4 240
JMF 0:24d3eb812fd4 241 ssize_t BufferedSpi::read()
JMF 0:24d3eb812fd4 242 {
JMF 0:24d3eb812fd4 243 return this->read(0);
JMF 0:24d3eb812fd4 244 }
JMF 0:24d3eb812fd4 245
JMF 0:24d3eb812fd4 246 ssize_t BufferedSpi::read(uint32_t max)
JMF 0:24d3eb812fd4 247 {
JMF 0:24d3eb812fd4 248 uint32_t len = 0;
JMF 0:24d3eb812fd4 249 uint8_t FirstRemoved = 1;
JMF 0:24d3eb812fd4 250 int tmp;
JMF 0:24d3eb812fd4 251
JMF 0:24d3eb812fd4 252 disable_nss();
JMF 0:24d3eb812fd4 253
JMF 0:24d3eb812fd4 254 /* wait for data ready is up */
JMF 0:24d3eb812fd4 255 if (wait_cmddata_rdy_rising_event() != 0) {
JMF 0:24d3eb812fd4 256 debug_if(local_debug, "BufferedSpi::read timeout (%d)\r\n", _timeout);
JMF 0:24d3eb812fd4 257 return -1;
JMF 0:24d3eb812fd4 258 }
JMF 0:24d3eb812fd4 259
JMF 0:24d3eb812fd4 260 enable_nss();
JMF 0:24d3eb812fd4 261 while (dataready.read() == 1 && (len < (_buf_size - 2))) {
JMF 0:24d3eb812fd4 262 tmp = SPI::write(0xAA); // dummy write to receive 2 bytes
JMF 0:24d3eb812fd4 263
JMF 0:24d3eb812fd4 264 if (!((len == 0) && (tmp == 0x0A0D) && (FirstRemoved))) {
JMF 0:24d3eb812fd4 265 /* do not take into account the 2 firts \r \n char in the buffer */
JMF 0:24d3eb812fd4 266 if ((max == 0) || (len < max)) {
JMF 0:24d3eb812fd4 267 _rxbuf = (char)(tmp & 0x00FF);
JMF 0:24d3eb812fd4 268 _rxbuf = (char)((tmp >> 8) & 0xFF);
JMF 0:24d3eb812fd4 269 len += 2;
JMF 0:24d3eb812fd4 270 }
JMF 0:24d3eb812fd4 271 } else {
JMF 0:24d3eb812fd4 272 FirstRemoved = 0;
JMF 0:24d3eb812fd4 273 }
JMF 0:24d3eb812fd4 274 }
JMF 0:24d3eb812fd4 275 disable_nss();
JMF 0:24d3eb812fd4 276
JMF 0:24d3eb812fd4 277 if (len >= _buf_size) {
JMF 0:24d3eb812fd4 278 debug_if(local_debug, "firmware ERROR ES_WIFI_ERROR_STUFFING_FOREVER\r\n");
JMF 0:24d3eb812fd4 279 return -1;
JMF 0:24d3eb812fd4 280 }
JMF 0:24d3eb812fd4 281
JMF 0:24d3eb812fd4 282 debug_if(local_debug, "SPI READ %d BYTES\r\n", len);
JMF 0:24d3eb812fd4 283
JMF 0:24d3eb812fd4 284 return len;
JMF 0:24d3eb812fd4 285 }
JMF 0:24d3eb812fd4 286
JMF 0:24d3eb812fd4 287 void BufferedSpi::txIrq(void)
JMF 0:24d3eb812fd4 288 {
JMF 0:24d3eb812fd4 289 /* write everything available in the _txbuffer */
JMF 0:24d3eb812fd4 290 int value = 0;
JMF 0:24d3eb812fd4 291 int dbg_cnt = 0;
JMF 0:24d3eb812fd4 292 while (_txbuf.available() && (_txbuf.getNbAvailable() > 0)) {
JMF 0:24d3eb812fd4 293 value = _txbuf.get();
JMF 0:24d3eb812fd4 294 if (_txbuf.available() && ((_txbuf.getNbAvailable() % 2) != 0)) {
JMF 0:24d3eb812fd4 295 value |= ((_txbuf.get() << 8) & 0XFF00);
JMF 0:24d3eb812fd4 296 SPI::write(value);
JMF 0:24d3eb812fd4 297 dbg_cnt++;
JMF 0:24d3eb812fd4 298 }
JMF 0:24d3eb812fd4 299 }
JMF 0:24d3eb812fd4 300 debug_if(local_debug, "SPI Sent %d BYTES\r\n", 2 * dbg_cnt);
JMF 0:24d3eb812fd4 301 // disable the TX interrupt when there is nothing left to send
JMF 0:24d3eb812fd4 302 BufferedSpi::attach(NULL, BufferedSpi::TxIrq);
JMF 0:24d3eb812fd4 303 // trigger callback if necessary
JMF 0:24d3eb812fd4 304 if (_cbs[TxIrq]) {
JMF 0:24d3eb812fd4 305 _cbs[TxIrq]();
JMF 0:24d3eb812fd4 306 }
JMF 0:24d3eb812fd4 307 return;
JMF 0:24d3eb812fd4 308 }
JMF 0:24d3eb812fd4 309
JMF 0:24d3eb812fd4 310 void BufferedSpi::prime(void)
JMF 0:24d3eb812fd4 311 {
JMF 0:24d3eb812fd4 312 BufferedSpi::txIrq(); // only write to hardware in one place
JMF 0:24d3eb812fd4 313 return;
JMF 0:24d3eb812fd4 314 }
JMF 0:24d3eb812fd4 315
JMF 0:24d3eb812fd4 316 void BufferedSpi::attach(Callback<void()> func, IrqType type)
JMF 0:24d3eb812fd4 317 {
JMF 0:24d3eb812fd4 318 _cbs[type] = func;
JMF 0:24d3eb812fd4 319 }
JMF 0:24d3eb812fd4 320
JMF 0:24d3eb812fd4 321 void BufferedSpi::sigio(Callback<void()> func)
JMF 0:24d3eb812fd4 322 {
JMF 0:24d3eb812fd4 323 core_util_critical_section_enter();
JMF 0:24d3eb812fd4 324 _sigio_cb = func;
JMF 0:24d3eb812fd4 325 if (_sigio_cb) {
JMF 0:24d3eb812fd4 326 if (_sigio_event == 1) {
JMF 0:24d3eb812fd4 327 _sigio_cb();
JMF 0:24d3eb812fd4 328 _sigio_event = 0;
JMF 0:24d3eb812fd4 329 }
JMF 0:24d3eb812fd4 330 }
JMF 0:24d3eb812fd4 331 core_util_critical_section_exit();
JMF 0:24d3eb812fd4 332 }
JMF 0:24d3eb812fd4 333