source: rtos_arduino/trunk/arduino_lib/libraries/Firmata/utility/BLEStream.h@ 224

Last change on this file since 224 was 224, checked in by ertl-honda, 8 years ago

1.7.10のファイルに更新

File size: 6.6 KB
Line 
1/*
2 BLEStream.h
3
4 Based on BLESerial.cpp by Voita Molda
5 https://github.com/sandeepmistry/arduino-BLEPeripheral/blob/master/examples/serial/BLESerial.h
6
7 Last updated April 04th, 2016
8 */
9
10#ifndef _BLE_STREAM_H_
11#define _BLE_STREAM_H_
12
13#include <Arduino.h>
14#if defined(_VARIANT_ARDUINO_101_X_)
15#include <CurieBLE.h>
16#define _MAX_ATTR_DATA_LEN_ BLE_MAX_ATTR_DATA_LEN
17#else
18#include <BLEPeripheral.h>
19#define _MAX_ATTR_DATA_LEN_ BLE_ATTRIBUTE_MAX_VALUE_LENGTH
20#endif
21
22#define BLESTREAM_TXBUFFER_FLUSH_INTERVAL 80
23#define BLESTREAM_MIN_FLUSH_INTERVAL 8 // minimum interval for flushing the TX buffer
24
25// #define BLE_SERIAL_DEBUG
26
27class BLEStream : public BLEPeripheral, public Stream
28{
29 public:
30 BLEStream(unsigned char req = 0, unsigned char rdy = 0, unsigned char rst = 0);
31
32 void begin(...);
33 bool poll();
34 void end();
35 void setFlushInterval(int);
36
37 virtual int available(void);
38 virtual int peek(void);
39 virtual int read(void);
40 virtual void flush(void);
41 virtual size_t write(uint8_t byte);
42 using Print::write;
43 virtual operator bool();
44
45 private:
46 bool _connected;
47 unsigned long _flushed;
48 int _flushInterval;
49 static BLEStream* _instance;
50
51 size_t _rxHead;
52 size_t _rxTail;
53 size_t _rxCount() const;
54 unsigned char _rxBuffer[256];
55 size_t _txCount;
56 unsigned char _txBuffer[_MAX_ATTR_DATA_LEN_];
57
58 BLEService _uartService = BLEService("6E400001-B5A3-F393-E0A9-E50E24DCCA9E");
59 BLEDescriptor _uartNameDescriptor = BLEDescriptor("2901", "UART");
60 BLECharacteristic _rxCharacteristic = BLECharacteristic("6E400002-B5A3-F393-E0A9-E50E24DCCA9E", BLEWriteWithoutResponse, _MAX_ATTR_DATA_LEN_);
61 BLEDescriptor _rxNameDescriptor = BLEDescriptor("2901", "RX - Receive Data (Write)");
62 BLECharacteristic _txCharacteristic = BLECharacteristic("6E400003-B5A3-F393-E0A9-E50E24DCCA9E", BLENotify, _MAX_ATTR_DATA_LEN_);
63 BLEDescriptor _txNameDescriptor = BLEDescriptor("2901", "TX - Transfer Data (Notify)");
64
65 void _received(const unsigned char* data, size_t size);
66 static void _received(BLECentral& /*central*/, BLECharacteristic& rxCharacteristic);
67};
68
69
70/*
71 * BLEStream.cpp
72 * Copied here as a hack to avoid having to install the BLEPeripheral libarary even if it's
73 * not needed.
74 */
75
76BLEStream* BLEStream::_instance = NULL;
77
78BLEStream::BLEStream(unsigned char req, unsigned char rdy, unsigned char rst) :
79#if defined(_VARIANT_ARDUINO_101_X_)
80 BLEPeripheral()
81#else
82 BLEPeripheral(req, rdy, rst)
83#endif
84{
85 this->_txCount = 0;
86 this->_rxHead = this->_rxTail = 0;
87 this->_flushed = 0;
88 this->_flushInterval = BLESTREAM_TXBUFFER_FLUSH_INTERVAL;
89 BLEStream::_instance = this;
90
91 addAttribute(this->_uartService);
92 addAttribute(this->_uartNameDescriptor);
93 setAdvertisedServiceUuid(this->_uartService.uuid());
94 addAttribute(this->_rxCharacteristic);
95 addAttribute(this->_rxNameDescriptor);
96 this->_rxCharacteristic.setEventHandler(BLEWritten, BLEStream::_received);
97 addAttribute(this->_txCharacteristic);
98 addAttribute(this->_txNameDescriptor);
99}
100
101void BLEStream::begin(...)
102{
103 BLEPeripheral::begin();
104#ifdef BLE_SERIAL_DEBUG
105 Serial.println(F("BLEStream::begin()"));
106#endif
107}
108
109bool BLEStream::poll()
110{
111 // BLEPeripheral::poll is called each time connected() is called
112 this->_connected = BLEPeripheral::connected();
113 if (millis() > this->_flushed + this->_flushInterval) {
114 flush();
115 }
116 return this->_connected;
117}
118
119void BLEStream::end()
120{
121 this->_rxCharacteristic.setEventHandler(BLEWritten, NULL);
122 this->_rxHead = this->_rxTail = 0;
123 flush();
124 BLEPeripheral::disconnect();
125}
126
127int BLEStream::available(void)
128{
129// BLEPeripheral::poll only calls delay(1) in CurieBLE so skipping it here to avoid the delay
130#ifndef _VARIANT_ARDUINO_101_X_
131 // TODO Need to do more testing to determine if all of these calls to BLEPeripheral::poll are
132 // actually necessary. Seems to run fine without them, but only minimal testing so far.
133 BLEPeripheral::poll();
134#endif
135 int retval = (this->_rxHead - this->_rxTail + sizeof(this->_rxBuffer)) % sizeof(this->_rxBuffer);
136#ifdef BLE_SERIAL_DEBUG
137 if (retval > 0) {
138 Serial.print(F("BLEStream::available() = "));
139 Serial.println(retval);
140 }
141#endif
142 return retval;
143}
144
145int BLEStream::peek(void)
146{
147#ifndef _VARIANT_ARDUINO_101_X_
148 BLEPeripheral::poll();
149#endif
150 if (this->_rxTail == this->_rxHead) return -1;
151 uint8_t byte = this->_rxBuffer[this->_rxTail];
152#ifdef BLE_SERIAL_DEBUG
153 Serial.print(F("BLEStream::peek() = 0x"));
154 Serial.println(byte, HEX);
155#endif
156 return byte;
157}
158
159int BLEStream::read(void)
160{
161#ifndef _VARIANT_ARDUINO_101_X_
162 BLEPeripheral::poll();
163#endif
164 if (this->_rxTail == this->_rxHead) return -1;
165 this->_rxTail = (this->_rxTail + 1) % sizeof(this->_rxBuffer);
166 uint8_t byte = this->_rxBuffer[this->_rxTail];
167#ifdef BLE_SERIAL_DEBUG
168 Serial.print(F("BLEStream::read() = 0x"));
169 Serial.println(byte, HEX);
170#endif
171 return byte;
172}
173
174void BLEStream::flush(void)
175{
176 if (this->_txCount == 0) return;
177#ifndef _VARIANT_ARDUINO_101_X_
178 // ensure there are available packets before sending
179 while(!this->_txCharacteristic.canNotify()) {
180 BLEPeripheral::poll();
181 }
182#endif
183 this->_txCharacteristic.setValue(this->_txBuffer, this->_txCount);
184 this->_flushed = millis();
185 this->_txCount = 0;
186#ifdef BLE_SERIAL_DEBUG
187 Serial.println(F("BLEStream::flush()"));
188#endif
189}
190
191size_t BLEStream::write(uint8_t byte)
192{
193#ifndef _VARIANT_ARDUINO_101_X_
194 BLEPeripheral::poll();
195#endif
196 if (this->_txCharacteristic.subscribed() == false) return 0;
197 this->_txBuffer[this->_txCount++] = byte;
198 if (this->_txCount == sizeof(this->_txBuffer)) flush();
199#ifdef BLE_SERIAL_DEBUG
200 Serial.print(F("BLEStream::write( 0x"));
201 Serial.print(byte, HEX);
202 Serial.println(F(") = 1"));
203#endif
204 return 1;
205}
206
207BLEStream::operator bool()
208{
209 bool retval = this->_connected = BLEPeripheral::connected();
210#ifdef BLE_SERIAL_DEBUG
211 Serial.print(F("BLEStream::operator bool() = "));
212 Serial.println(retval);
213#endif
214 return retval;
215}
216
217void BLEStream::setFlushInterval(int interval)
218{
219 if (interval > BLESTREAM_MIN_FLUSH_INTERVAL) {
220 this->_flushInterval = interval;
221 }
222}
223
224void BLEStream::_received(const unsigned char* data, size_t size)
225{
226 for (size_t i = 0; i < size; i++) {
227 this->_rxHead = (this->_rxHead + 1) % sizeof(this->_rxBuffer);
228 this->_rxBuffer[this->_rxHead] = data[i];
229 }
230#ifdef BLE_SERIAL_DEBUG
231 Serial.print(F("BLEStream::received("));
232 for (int i = 0; i < size; i++) Serial.print(data[i], HEX);
233 Serial.println(F(")"));
234#endif
235}
236
237void BLEStream::_received(BLECentral& /*central*/, BLECharacteristic& rxCharacteristic)
238{
239 BLEStream::_instance->_received(rxCharacteristic.value(), rxCharacteristic.valueLength());
240}
241
242
243#endif // _BLE_STREAM_H_
Note: See TracBrowser for help on using the repository browser.