Disco-L475VG-IOT / wifi-ism43362
Committer:
marcel1691
Date:
Wed Oct 03 14:03:01 2018 +0000
Revision:
0:62e55edab701
WiFi ISM43363

Who changed what in which revision?

UserRevisionLine numberNew contents of line
marcel1691 0:62e55edab701 1
marcel1691 0:62e55edab701 2 /**
marcel1691 0:62e55edab701 3 * @file BufferedSpi.h
marcel1691 0:62e55edab701 4 * @brief Software Buffer - Extends mbed SPI functionallity
marcel1691 0:62e55edab701 5 * @author Armelle Duboc
marcel1691 0:62e55edab701 6 * @version 1.0
marcel1691 0:62e55edab701 7 * @see
marcel1691 0:62e55edab701 8 *
marcel1691 0:62e55edab701 9 * Copyright (c) STMicroelectronics 2017
marcel1691 0:62e55edab701 10 *
marcel1691 0:62e55edab701 11 * Licensed under the Apache License, Version 2.0 (the "License");
marcel1691 0:62e55edab701 12 * you may not use this file except in compliance with the License.
marcel1691 0:62e55edab701 13 * You may obtain a copy of the License at
marcel1691 0:62e55edab701 14 *
marcel1691 0:62e55edab701 15 * http://www.apache.org/licenses/LICENSE-2.0
marcel1691 0:62e55edab701 16 *
marcel1691 0:62e55edab701 17 * Unless required by applicable law or agreed to in writing, software
marcel1691 0:62e55edab701 18 * distributed under the License is distributed on an "AS IS" BASIS,
marcel1691 0:62e55edab701 19 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
marcel1691 0:62e55edab701 20 * See the License for the specific language governing permissions and
marcel1691 0:62e55edab701 21 * limitations under the License.
marcel1691 0:62e55edab701 22 */
marcel1691 0:62e55edab701 23
marcel1691 0:62e55edab701 24 #ifndef BUFFEREDSPI_H
marcel1691 0:62e55edab701 25 #define BUFFEREDSPI_H
marcel1691 0:62e55edab701 26
marcel1691 0:62e55edab701 27 #include "mbed.h"
marcel1691 0:62e55edab701 28 #include "MyBuffer.h"
marcel1691 0:62e55edab701 29
marcel1691 0:62e55edab701 30 /** A spi port (SPI) for communication with wifi device
marcel1691 0:62e55edab701 31 *
marcel1691 0:62e55edab701 32 * Can be used for Full Duplex communication, or Simplex by specifying
marcel1691 0:62e55edab701 33 * one pin as NC (Not Connected)
marcel1691 0:62e55edab701 34 *
marcel1691 0:62e55edab701 35 * Example:
marcel1691 0:62e55edab701 36 * @code
marcel1691 0:62e55edab701 37 * #include "mbed.h"
marcel1691 0:62e55edab701 38 * #include "BufferedSerial.h"
marcel1691 0:62e55edab701 39 *
marcel1691 0:62e55edab701 40 * BufferedSerial pc(USBTX, USBRX);
marcel1691 0:62e55edab701 41 *
marcel1691 0:62e55edab701 42 * int main()
marcel1691 0:62e55edab701 43 * {
marcel1691 0:62e55edab701 44 * while(1)
marcel1691 0:62e55edab701 45 * {
marcel1691 0:62e55edab701 46 * Timer s;
marcel1691 0:62e55edab701 47 *
marcel1691 0:62e55edab701 48 * s.start();
marcel1691 0:62e55edab701 49 * pc.printf("Hello World - buffered\n");
marcel1691 0:62e55edab701 50 * int buffered_time = s.read_us();
marcel1691 0:62e55edab701 51 * wait(0.1f); // give time for the buffer to empty
marcel1691 0:62e55edab701 52 *
marcel1691 0:62e55edab701 53 * s.reset();
marcel1691 0:62e55edab701 54 * printf("Hello World - blocking\n");
marcel1691 0:62e55edab701 55 * int polled_time = s.read_us();
marcel1691 0:62e55edab701 56 * s.stop();
marcel1691 0:62e55edab701 57 * wait(0.1f); // give time for the buffer to empty
marcel1691 0:62e55edab701 58 *
marcel1691 0:62e55edab701 59 * pc.printf("printf buffered took %d us\n", buffered_time);
marcel1691 0:62e55edab701 60 * pc.printf("printf blocking took %d us\n", polled_time);
marcel1691 0:62e55edab701 61 * wait(0.5f);
marcel1691 0:62e55edab701 62 * }
marcel1691 0:62e55edab701 63 * }
marcel1691 0:62e55edab701 64 * @endcode
marcel1691 0:62e55edab701 65 */
marcel1691 0:62e55edab701 66
marcel1691 0:62e55edab701 67 /**
marcel1691 0:62e55edab701 68 * @class BufferedSpi
marcel1691 0:62e55edab701 69 * @brief Software buffers and interrupt driven tx and rx for Serial
marcel1691 0:62e55edab701 70 */
marcel1691 0:62e55edab701 71 class BufferedSpi : public SPI {
marcel1691 0:62e55edab701 72 private:
marcel1691 0:62e55edab701 73 DigitalOut nss;
marcel1691 0:62e55edab701 74 MyBuffer <char> _txbuf;
marcel1691 0:62e55edab701 75 uint32_t _buf_size;
marcel1691 0:62e55edab701 76 uint32_t _tx_multiple;
marcel1691 0:62e55edab701 77 volatile int _timeout;
marcel1691 0:62e55edab701 78 void txIrq(void);
marcel1691 0:62e55edab701 79 void prime(void);
marcel1691 0:62e55edab701 80
marcel1691 0:62e55edab701 81 InterruptIn *_datareadyInt;
marcel1691 0:62e55edab701 82 volatile int _cmddata_rdy_rising_event;
marcel1691 0:62e55edab701 83 void DatareadyRising(void);
marcel1691 0:62e55edab701 84 int wait_cmddata_rdy_rising_event(void);
marcel1691 0:62e55edab701 85 int wait_cmddata_rdy_high(void);
marcel1691 0:62e55edab701 86
marcel1691 0:62e55edab701 87
marcel1691 0:62e55edab701 88 Callback<void()> _cbs[2];
marcel1691 0:62e55edab701 89
marcel1691 0:62e55edab701 90 Callback<void()> _sigio_cb;
marcel1691 0:62e55edab701 91 uint8_t _sigio_event;
marcel1691 0:62e55edab701 92
marcel1691 0:62e55edab701 93 public:
marcel1691 0:62e55edab701 94 MyBuffer <char> _rxbuf;
marcel1691 0:62e55edab701 95 DigitalIn dataready;
marcel1691 0:62e55edab701 96 enum IrqType {
marcel1691 0:62e55edab701 97 RxIrq = 0,
marcel1691 0:62e55edab701 98 TxIrq,
marcel1691 0:62e55edab701 99
marcel1691 0:62e55edab701 100 IrqCnt
marcel1691 0:62e55edab701 101 };
marcel1691 0:62e55edab701 102
marcel1691 0:62e55edab701 103 /** Create a BufferedSpi Port, connected to the specified transmit and receive pins
marcel1691 0:62e55edab701 104 * @param SPI mosi pin
marcel1691 0:62e55edab701 105 * @param SPI miso pin
marcel1691 0:62e55edab701 106 * @param SPI sclk pin
marcel1691 0:62e55edab701 107 * @param SPI nss pin
marcel1691 0:62e55edab701 108 * @param Dataready pin
marcel1691 0:62e55edab701 109 * @param buf_size printf() buffer size
marcel1691 0:62e55edab701 110 * @param tx_multiple amount of max printf() present in the internal ring buffer at one time
marcel1691 0:62e55edab701 111 * @param name optional name
marcel1691 0:62e55edab701 112 */
marcel1691 0:62e55edab701 113 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);
marcel1691 0:62e55edab701 114
marcel1691 0:62e55edab701 115 /** Destroy a BufferedSpi Port
marcel1691 0:62e55edab701 116 */
marcel1691 0:62e55edab701 117 virtual ~BufferedSpi(void);
marcel1691 0:62e55edab701 118
marcel1691 0:62e55edab701 119 /** call to SPI frequency Function
marcel1691 0:62e55edab701 120 */
marcel1691 0:62e55edab701 121 virtual void frequency(int hz);
marcel1691 0:62e55edab701 122
marcel1691 0:62e55edab701 123 /** clear the transmit buffer
marcel1691 0:62e55edab701 124 */
marcel1691 0:62e55edab701 125 virtual void flush_txbuf(void);
marcel1691 0:62e55edab701 126
marcel1691 0:62e55edab701 127 /** call to SPI format function
marcel1691 0:62e55edab701 128 */
marcel1691 0:62e55edab701 129 virtual void format(int bits, int mode);
marcel1691 0:62e55edab701 130
marcel1691 0:62e55edab701 131 virtual void enable_nss(void);
marcel1691 0:62e55edab701 132
marcel1691 0:62e55edab701 133 virtual void disable_nss(void);
marcel1691 0:62e55edab701 134
marcel1691 0:62e55edab701 135 /** Check on how many bytes are in the rx buffer
marcel1691 0:62e55edab701 136 * @return 1 if something exists, 0 otherwise
marcel1691 0:62e55edab701 137 */
marcel1691 0:62e55edab701 138 virtual int readable(void);
marcel1691 0:62e55edab701 139
marcel1691 0:62e55edab701 140 /** Check to see if the tx buffer has room
marcel1691 0:62e55edab701 141 * @return 1 always has room and can overwrite previous content if too small / slow
marcel1691 0:62e55edab701 142 */
marcel1691 0:62e55edab701 143 virtual int writeable(void);
marcel1691 0:62e55edab701 144
marcel1691 0:62e55edab701 145 /** Get a single byte from the BufferedSpi Port.
marcel1691 0:62e55edab701 146 * Should check readable() before calling this.
marcel1691 0:62e55edab701 147 * @return A byte that came in on the SPI Port
marcel1691 0:62e55edab701 148 */
marcel1691 0:62e55edab701 149 virtual int getc(void);
marcel1691 0:62e55edab701 150
marcel1691 0:62e55edab701 151 /** Write a single byte to the BufferedSpi Port.
marcel1691 0:62e55edab701 152 * @param c The byte to write to the SPI Port
marcel1691 0:62e55edab701 153 * @return The byte that was written to the SPI Port Buffer
marcel1691 0:62e55edab701 154 */
marcel1691 0:62e55edab701 155 virtual int putc(int c);
marcel1691 0:62e55edab701 156
marcel1691 0:62e55edab701 157 /** Write a string to the BufferedSpi Port. Must be NULL terminated
marcel1691 0:62e55edab701 158 * @param s The string to write to the Spi Port
marcel1691 0:62e55edab701 159 * @return The number of bytes written to the Spi Port Buffer
marcel1691 0:62e55edab701 160 */
marcel1691 0:62e55edab701 161 virtual int puts(const char *s);
marcel1691 0:62e55edab701 162
marcel1691 0:62e55edab701 163 /** Write a formatted string to the BufferedSpi Port.
marcel1691 0:62e55edab701 164 * @param format The string + format specifiers to write to the Spi Port
marcel1691 0:62e55edab701 165 * @return The number of bytes written to the Spi Port Buffer
marcel1691 0:62e55edab701 166 */
marcel1691 0:62e55edab701 167 virtual int printf(const char *format, ...);
marcel1691 0:62e55edab701 168
marcel1691 0:62e55edab701 169 /** Write data to the Buffered Spi Port
marcel1691 0:62e55edab701 170 * @param s A pointer to data to send
marcel1691 0:62e55edab701 171 * @param length The amount of data being pointed to
marcel1691 0:62e55edab701 172 * @return The number of bytes written to the Spi Port Buffer
marcel1691 0:62e55edab701 173 */
marcel1691 0:62e55edab701 174 virtual ssize_t buffwrite(const void *s, std::size_t length);
marcel1691 0:62e55edab701 175
marcel1691 0:62e55edab701 176 /** Send datas to the Spi port that are already present
marcel1691 0:62e55edab701 177 * in the internal _txbuffer
marcel1691 0:62e55edab701 178 * @param length
marcel1691 0:62e55edab701 179 * @return the number of bytes written on the SPI port
marcel1691 0:62e55edab701 180 */
marcel1691 0:62e55edab701 181 virtual ssize_t buffsend(size_t length);
marcel1691 0:62e55edab701 182
marcel1691 0:62e55edab701 183 /** Read data from the Spi Port to the _rxbuf
marcel1691 0:62e55edab701 184 * @param max: optional. = max sieze of the input read
marcel1691 0:62e55edab701 185 * @return The number of bytes read from the SPI port and written to the _rxbuf
marcel1691 0:62e55edab701 186 */
marcel1691 0:62e55edab701 187 virtual ssize_t read();
marcel1691 0:62e55edab701 188 virtual ssize_t read(uint32_t max);
marcel1691 0:62e55edab701 189
marcel1691 0:62e55edab701 190 /**
marcel1691 0:62e55edab701 191 * Allows timeout to be changed between commands
marcel1691 0:62e55edab701 192 *
marcel1691 0:62e55edab701 193 * @param timeout timeout of the connection in ms
marcel1691 0:62e55edab701 194 */
marcel1691 0:62e55edab701 195 void setTimeout(int timeout)
marcel1691 0:62e55edab701 196 {
marcel1691 0:62e55edab701 197 /* this is a safe guard timeout at SPI level in case module is stuck */
marcel1691 0:62e55edab701 198 _timeout = timeout;
marcel1691 0:62e55edab701 199 }
marcel1691 0:62e55edab701 200
marcel1691 0:62e55edab701 201 /** Register a callback once any data is ready for sockets
marcel1691 0:62e55edab701 202 * @param func Function to call on state change
marcel1691 0:62e55edab701 203 */
marcel1691 0:62e55edab701 204 virtual void sigio(Callback<void()> func);
marcel1691 0:62e55edab701 205
marcel1691 0:62e55edab701 206 /** Attach a function to call whenever a serial interrupt is generated
marcel1691 0:62e55edab701 207 * @param func A pointer to a void function, or 0 to set as none
marcel1691 0:62e55edab701 208 * @param type Which serial interrupt to attach the member function to (Serial::RxIrq for receive, TxIrq for transmit buffer empty)
marcel1691 0:62e55edab701 209 */
marcel1691 0:62e55edab701 210 virtual void attach(Callback<void()> func, IrqType type = RxIrq);
marcel1691 0:62e55edab701 211
marcel1691 0:62e55edab701 212 /** Attach a member function to call whenever a serial interrupt is generated
marcel1691 0:62e55edab701 213 * @param obj pointer to the object to call the member function on
marcel1691 0:62e55edab701 214 * @param method pointer to the member function to call
marcel1691 0:62e55edab701 215 * @param type Which serial interrupt to attach the member function to (Serial::RxIrq for receive, TxIrq for transmit buffer empty)
marcel1691 0:62e55edab701 216 */
marcel1691 0:62e55edab701 217 template <typename T>
marcel1691 0:62e55edab701 218 void attach(T *obj, void (T::*method)(), IrqType type = RxIrq)
marcel1691 0:62e55edab701 219 {
marcel1691 0:62e55edab701 220 attach(Callback<void()>(obj, method), type);
marcel1691 0:62e55edab701 221 }
marcel1691 0:62e55edab701 222
marcel1691 0:62e55edab701 223 /** Attach a member function to call whenever a serial interrupt is generated
marcel1691 0:62e55edab701 224 * @param obj pointer to the object to call the member function on
marcel1691 0:62e55edab701 225 * @param method pointer to the member function to call
marcel1691 0:62e55edab701 226 * @param type Which serial interrupt to attach the member function to (Serial::RxIrq for receive, TxIrq for transmit buffer empty)
marcel1691 0:62e55edab701 227 */
marcel1691 0:62e55edab701 228 template <typename T>
marcel1691 0:62e55edab701 229 void attach(T *obj, void (*method)(T *), IrqType type = RxIrq)
marcel1691 0:62e55edab701 230 {
marcel1691 0:62e55edab701 231 attach(Callback<void()>(obj, method), type);
marcel1691 0:62e55edab701 232 }
marcel1691 0:62e55edab701 233 };
marcel1691 0:62e55edab701 234 #endif