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.
main.cpp@0:39b7f3158ebe, 2018-04-05 (annotated)
- Committer:
- wninghj
- Date:
- Thu Apr 05 21:26:10 2018 +0000
- Revision:
- 0:39b7f3158ebe
TEAM12 DJ;
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| wninghj | 0:39b7f3158ebe | 1 | #include "mbed.h" |
| wninghj | 0:39b7f3158ebe | 2 | #include "rtos.h" |
| wninghj | 0:39b7f3158ebe | 3 | #include "sdep.h" |
| wninghj | 0:39b7f3158ebe | 4 | #include "Adafruit_FIFO.h" |
| wninghj | 0:39b7f3158ebe | 5 | #include <stdio.h> |
| wninghj | 0:39b7f3158ebe | 6 | |
| wninghj | 0:39b7f3158ebe | 7 | #define BLUEFRUIT_MODE_COMMAND HIGH |
| wninghj | 0:39b7f3158ebe | 8 | #define BLUEFRUIT_MODE_DATA LOW |
| wninghj | 0:39b7f3158ebe | 9 | #define BLE_BUFSIZE 4*SDEP_MAX_PACKETSIZE |
| wninghj | 0:39b7f3158ebe | 10 | |
| wninghj | 0:39b7f3158ebe | 11 | |
| wninghj | 0:39b7f3158ebe | 12 | #define SPI_IGNORED_BYTE 0xFEu /**< SPI default character. Character clocked out in case of an ignored transaction. */ |
| wninghj | 0:39b7f3158ebe | 13 | #define SPI_OVERREAD_BYTE 0xFFu /**< SPI over-read character. Character clocked out after an over-read of the transmit buffer. */ |
| wninghj | 0:39b7f3158ebe | 14 | #define SPI_DEFAULT_DELAY_US 50 |
| wninghj | 0:39b7f3158ebe | 15 | |
| wninghj | 0:39b7f3158ebe | 16 | DigitalOut myled(LED1); |
| wninghj | 0:39b7f3158ebe | 17 | |
| wninghj | 0:39b7f3158ebe | 18 | Serial pc(USBTX,USBRX); |
| wninghj | 0:39b7f3158ebe | 19 | |
| wninghj | 0:39b7f3158ebe | 20 | SPI spi(p5, p6, p7); // mosi, miso, sclk |
| wninghj | 0:39b7f3158ebe | 21 | |
| wninghj | 0:39b7f3158ebe | 22 | DigitalOut cs(p21); |
| wninghj | 0:39b7f3158ebe | 23 | DigitalIn m_irq_pin(p22); |
| wninghj | 0:39b7f3158ebe | 24 | DigitalOut ble_reset(p23); |
| wninghj | 0:39b7f3158ebe | 25 | |
| wninghj | 0:39b7f3158ebe | 26 | void enable_spi() { |
| wninghj | 0:39b7f3158ebe | 27 | cs = 0; |
| wninghj | 0:39b7f3158ebe | 28 | } |
| wninghj | 0:39b7f3158ebe | 29 | |
| wninghj | 0:39b7f3158ebe | 30 | void disable_spi() { |
| wninghj | 0:39b7f3158ebe | 31 | cs = 1; |
| wninghj | 0:39b7f3158ebe | 32 | } |
| wninghj | 0:39b7f3158ebe | 33 | |
| wninghj | 0:39b7f3158ebe | 34 | // TX |
| wninghj | 0:39b7f3158ebe | 35 | uint8_t m_tx_buffer[SDEP_MAX_PACKETSIZE] = {0}; |
| wninghj | 0:39b7f3158ebe | 36 | uint8_t m_tx_count = 0; |
| wninghj | 0:39b7f3158ebe | 37 | |
| wninghj | 0:39b7f3158ebe | 38 | // RX |
| wninghj | 0:39b7f3158ebe | 39 | uint8_t m_rx_buffer[BLE_BUFSIZE * 2] = {0}; |
| wninghj | 0:39b7f3158ebe | 40 | Adafruit_FIFO m_rx_fifo(m_rx_buffer, sizeof(m_rx_buffer), 1, true); |
| wninghj | 0:39b7f3158ebe | 41 | |
| wninghj | 0:39b7f3158ebe | 42 | enum BLE_MODE { |
| wninghj | 0:39b7f3158ebe | 43 | COMMAND = 0, |
| wninghj | 0:39b7f3158ebe | 44 | DATA |
| wninghj | 0:39b7f3158ebe | 45 | }; |
| wninghj | 0:39b7f3158ebe | 46 | |
| wninghj | 0:39b7f3158ebe | 47 | BLE_MODE bleMode = COMMAND; |
| wninghj | 0:39b7f3158ebe | 48 | |
| wninghj | 0:39b7f3158ebe | 49 | |
| wninghj | 0:39b7f3158ebe | 50 | // prototypes |
| wninghj | 0:39b7f3158ebe | 51 | void spixfer(void *buff, size_t len); |
| wninghj | 0:39b7f3158ebe | 52 | uint8_t spixfer(uint8_t x); |
| wninghj | 0:39b7f3158ebe | 53 | bool bleGetResponse(void); |
| wninghj | 0:39b7f3158ebe | 54 | bool sendPacket(uint16_t command, const uint8_t* buf, uint8_t count, uint8_t more_data); |
| wninghj | 0:39b7f3158ebe | 55 | size_t bleWriteChar(uint8_t c); |
| wninghj | 0:39b7f3158ebe | 56 | void bleWrite(char *cmd); |
| wninghj | 0:39b7f3158ebe | 57 | |
| wninghj | 0:39b7f3158ebe | 58 | |
| wninghj | 0:39b7f3158ebe | 59 | volatile unsigned long _millis = 0; |
| wninghj | 0:39b7f3158ebe | 60 | unsigned long millis(void) { |
| wninghj | 0:39b7f3158ebe | 61 | return _millis; |
| wninghj | 0:39b7f3158ebe | 62 | } |
| wninghj | 0:39b7f3158ebe | 63 | |
| wninghj | 0:39b7f3158ebe | 64 | |
| wninghj | 0:39b7f3158ebe | 65 | class TimeoutTimer |
| wninghj | 0:39b7f3158ebe | 66 | { |
| wninghj | 0:39b7f3158ebe | 67 | private: |
| wninghj | 0:39b7f3158ebe | 68 | uint32_t start; |
| wninghj | 0:39b7f3158ebe | 69 | uint32_t interval; |
| wninghj | 0:39b7f3158ebe | 70 | |
| wninghj | 0:39b7f3158ebe | 71 | public: |
| wninghj | 0:39b7f3158ebe | 72 | TimeoutTimer() { start = millis(); interval = 0; } |
| wninghj | 0:39b7f3158ebe | 73 | TimeoutTimer(uint32_t msec) { set(msec); } |
| wninghj | 0:39b7f3158ebe | 74 | |
| wninghj | 0:39b7f3158ebe | 75 | void set(uint32_t msec) { start = millis(); interval = msec; } |
| wninghj | 0:39b7f3158ebe | 76 | bool expired(void) const { return (millis() - start) >= interval; } |
| wninghj | 0:39b7f3158ebe | 77 | void restart(void) { start = millis(); } |
| wninghj | 0:39b7f3158ebe | 78 | void reset(void) { start += interval; } // used for periodic invoke to prevent drift |
| wninghj | 0:39b7f3158ebe | 79 | }; |
| wninghj | 0:39b7f3158ebe | 80 | |
| wninghj | 0:39b7f3158ebe | 81 | |
| wninghj | 0:39b7f3158ebe | 82 | uint16_t word(uint8_t h, uint8_t l) { |
| wninghj | 0:39b7f3158ebe | 83 | uint16_t res = h; |
| wninghj | 0:39b7f3158ebe | 84 | res <<= 8; |
| wninghj | 0:39b7f3158ebe | 85 | res |= l; |
| wninghj | 0:39b7f3158ebe | 86 | return res; |
| wninghj | 0:39b7f3158ebe | 87 | } |
| wninghj | 0:39b7f3158ebe | 88 | |
| wninghj | 0:39b7f3158ebe | 89 | |
| wninghj | 0:39b7f3158ebe | 90 | uint32_t _timeout = 250; |
| wninghj | 0:39b7f3158ebe | 91 | |
| wninghj | 0:39b7f3158ebe | 92 | |
| wninghj | 0:39b7f3158ebe | 93 | bool bleGetPacket(sdepMsgResponse_t* p_response) |
| wninghj | 0:39b7f3158ebe | 94 | { |
| wninghj | 0:39b7f3158ebe | 95 | // Wait until IRQ is asserted, double timeout since some commands take long time to start responding |
| wninghj | 0:39b7f3158ebe | 96 | TimeoutTimer tt(2*_timeout); |
| wninghj | 0:39b7f3158ebe | 97 | |
| wninghj | 0:39b7f3158ebe | 98 | while ( !m_irq_pin ) { |
| wninghj | 0:39b7f3158ebe | 99 | if (tt.expired()) return false; |
| wninghj | 0:39b7f3158ebe | 100 | } |
| wninghj | 0:39b7f3158ebe | 101 | |
| wninghj | 0:39b7f3158ebe | 102 | sdepMsgHeader_t* p_header = &p_response->header; |
| wninghj | 0:39b7f3158ebe | 103 | |
| wninghj | 0:39b7f3158ebe | 104 | enable_spi(); |
| wninghj | 0:39b7f3158ebe | 105 | |
| wninghj | 0:39b7f3158ebe | 106 | tt.set(_timeout); |
| wninghj | 0:39b7f3158ebe | 107 | |
| wninghj | 0:39b7f3158ebe | 108 | do { |
| wninghj | 0:39b7f3158ebe | 109 | if ( tt.expired() ) break; |
| wninghj | 0:39b7f3158ebe | 110 | |
| wninghj | 0:39b7f3158ebe | 111 | p_header->msg_type = spixfer(0xff); |
| wninghj | 0:39b7f3158ebe | 112 | |
| wninghj | 0:39b7f3158ebe | 113 | if (p_header->msg_type == SPI_IGNORED_BYTE) |
| wninghj | 0:39b7f3158ebe | 114 | { |
| wninghj | 0:39b7f3158ebe | 115 | // Bluefruit may not be ready |
| wninghj | 0:39b7f3158ebe | 116 | // Disable & Re-enable CS with a bit of delay for Bluefruit to ready itself |
| wninghj | 0:39b7f3158ebe | 117 | disable_spi(); |
| wninghj | 0:39b7f3158ebe | 118 | wait_us(50); |
| wninghj | 0:39b7f3158ebe | 119 | enable_spi(); |
| wninghj | 0:39b7f3158ebe | 120 | } |
| wninghj | 0:39b7f3158ebe | 121 | else if (p_header->msg_type == SPI_OVERREAD_BYTE) |
| wninghj | 0:39b7f3158ebe | 122 | { |
| wninghj | 0:39b7f3158ebe | 123 | // IRQ may not be pulled down by Bluefruit when returning all data in previous transfer. |
| wninghj | 0:39b7f3158ebe | 124 | // This could happen when Arduino MCU is running at fast rate comparing to Bluefruit's MCU, |
| wninghj | 0:39b7f3158ebe | 125 | // causing an SPI_OVERREAD_BYTE to be returned at stage. |
| wninghj | 0:39b7f3158ebe | 126 | // |
| wninghj | 0:39b7f3158ebe | 127 | // Walkaround: Disable & Re-enable CS with a bit of delay and keep waiting |
| wninghj | 0:39b7f3158ebe | 128 | // TODO IRQ is supposed to be OFF then ON, it is better to use GPIO trigger interrupt. |
| wninghj | 0:39b7f3158ebe | 129 | |
| wninghj | 0:39b7f3158ebe | 130 | disable_spi(); |
| wninghj | 0:39b7f3158ebe | 131 | // wait for the clock to be enabled.. |
| wninghj | 0:39b7f3158ebe | 132 | // while (!digitalRead(m_irq_pin)) { |
| wninghj | 0:39b7f3158ebe | 133 | // if ( tt.expired() ) break; |
| wninghj | 0:39b7f3158ebe | 134 | // } |
| wninghj | 0:39b7f3158ebe | 135 | // if (!digitalRead(m_irq_pin)) break; |
| wninghj | 0:39b7f3158ebe | 136 | wait_us(50); |
| wninghj | 0:39b7f3158ebe | 137 | enable_spi(); |
| wninghj | 0:39b7f3158ebe | 138 | } |
| wninghj | 0:39b7f3158ebe | 139 | } while (p_header->msg_type == SPI_IGNORED_BYTE || p_header->msg_type == SPI_OVERREAD_BYTE); |
| wninghj | 0:39b7f3158ebe | 140 | |
| wninghj | 0:39b7f3158ebe | 141 | bool result=false; |
| wninghj | 0:39b7f3158ebe | 142 | |
| wninghj | 0:39b7f3158ebe | 143 | // Not a loop, just a way to avoid goto with error handling |
| wninghj | 0:39b7f3158ebe | 144 | do |
| wninghj | 0:39b7f3158ebe | 145 | { |
| wninghj | 0:39b7f3158ebe | 146 | // Look for the header |
| wninghj | 0:39b7f3158ebe | 147 | // note that we should always get the right header at this point, and not doing so will really mess up things. |
| wninghj | 0:39b7f3158ebe | 148 | while ( p_header->msg_type != SDEP_MSGTYPE_RESPONSE && p_header->msg_type != SDEP_MSGTYPE_ERROR && !tt.expired() ) |
| wninghj | 0:39b7f3158ebe | 149 | { |
| wninghj | 0:39b7f3158ebe | 150 | p_header->msg_type = spixfer(0xff); |
| wninghj | 0:39b7f3158ebe | 151 | } |
| wninghj | 0:39b7f3158ebe | 152 | |
| wninghj | 0:39b7f3158ebe | 153 | if ( tt.expired() ) break; |
| wninghj | 0:39b7f3158ebe | 154 | |
| wninghj | 0:39b7f3158ebe | 155 | memset( (&p_header->msg_type)+1, 0xff, sizeof(sdepMsgHeader_t) - 1); |
| wninghj | 0:39b7f3158ebe | 156 | spixfer((&p_header->msg_type)+1, sizeof(sdepMsgHeader_t) - 1); |
| wninghj | 0:39b7f3158ebe | 157 | |
| wninghj | 0:39b7f3158ebe | 158 | // Command is 16-bit at odd address, may have alignment issue with 32-bit chip |
| wninghj | 0:39b7f3158ebe | 159 | uint16_t cmd_id = word(p_header->cmd_id_high, p_header->cmd_id_low); |
| wninghj | 0:39b7f3158ebe | 160 | |
| wninghj | 0:39b7f3158ebe | 161 | // Error Message Response |
| wninghj | 0:39b7f3158ebe | 162 | if ( p_header->msg_type == SDEP_MSGTYPE_ERROR ) break; |
| wninghj | 0:39b7f3158ebe | 163 | |
| wninghj | 0:39b7f3158ebe | 164 | // Invalid command |
| wninghj | 0:39b7f3158ebe | 165 | if (!(cmd_id == SDEP_CMDTYPE_AT_WRAPPER || |
| wninghj | 0:39b7f3158ebe | 166 | cmd_id == SDEP_CMDTYPE_BLE_UARTTX || |
| wninghj | 0:39b7f3158ebe | 167 | cmd_id == SDEP_CMDTYPE_BLE_UARTRX) ) |
| wninghj | 0:39b7f3158ebe | 168 | { |
| wninghj | 0:39b7f3158ebe | 169 | break; |
| wninghj | 0:39b7f3158ebe | 170 | } |
| wninghj | 0:39b7f3158ebe | 171 | |
| wninghj | 0:39b7f3158ebe | 172 | // Invalid length |
| wninghj | 0:39b7f3158ebe | 173 | if(p_header->length > SDEP_MAX_PACKETSIZE) break; |
| wninghj | 0:39b7f3158ebe | 174 | |
| wninghj | 0:39b7f3158ebe | 175 | // read payload |
| wninghj | 0:39b7f3158ebe | 176 | memset(p_response->payload, 0xff, p_header->length); |
| wninghj | 0:39b7f3158ebe | 177 | spixfer(p_response->payload, p_header->length); |
| wninghj | 0:39b7f3158ebe | 178 | |
| wninghj | 0:39b7f3158ebe | 179 | result = true; |
| wninghj | 0:39b7f3158ebe | 180 | }while(0); |
| wninghj | 0:39b7f3158ebe | 181 | |
| wninghj | 0:39b7f3158ebe | 182 | disable_spi(); |
| wninghj | 0:39b7f3158ebe | 183 | |
| wninghj | 0:39b7f3158ebe | 184 | return result; |
| wninghj | 0:39b7f3158ebe | 185 | } |
| wninghj | 0:39b7f3158ebe | 186 | |
| wninghj | 0:39b7f3158ebe | 187 | |
| wninghj | 0:39b7f3158ebe | 188 | /******************************************************************************/ |
| wninghj | 0:39b7f3158ebe | 189 | /*! |
| wninghj | 0:39b7f3158ebe | 190 | |
| wninghj | 0:39b7f3158ebe | 191 | */ |
| wninghj | 0:39b7f3158ebe | 192 | /******************************************************************************/ |
| wninghj | 0:39b7f3158ebe | 193 | void spixfer(void *buff, size_t len) { |
| wninghj | 0:39b7f3158ebe | 194 | uint8_t *p = (uint8_t *)buff; |
| wninghj | 0:39b7f3158ebe | 195 | while (len--) { |
| wninghj | 0:39b7f3158ebe | 196 | p[0] = spixfer(p[0]); |
| wninghj | 0:39b7f3158ebe | 197 | p++; |
| wninghj | 0:39b7f3158ebe | 198 | } |
| wninghj | 0:39b7f3158ebe | 199 | } |
| wninghj | 0:39b7f3158ebe | 200 | |
| wninghj | 0:39b7f3158ebe | 201 | /******************************************************************************/ |
| wninghj | 0:39b7f3158ebe | 202 | /*! |
| wninghj | 0:39b7f3158ebe | 203 | |
| wninghj | 0:39b7f3158ebe | 204 | */ |
| wninghj | 0:39b7f3158ebe | 205 | /******************************************************************************/ |
| wninghj | 0:39b7f3158ebe | 206 | uint8_t spixfer(uint8_t x) { |
| wninghj | 0:39b7f3158ebe | 207 | return spi.write(x); |
| wninghj | 0:39b7f3158ebe | 208 | } |
| wninghj | 0:39b7f3158ebe | 209 | |
| wninghj | 0:39b7f3158ebe | 210 | |
| wninghj | 0:39b7f3158ebe | 211 | /******************************************************************************/ |
| wninghj | 0:39b7f3158ebe | 212 | /*! |
| wninghj | 0:39b7f3158ebe | 213 | @brief Try to perform an full AT response transfer from Bluefruit, or execute |
| wninghj | 0:39b7f3158ebe | 214 | as many SPI transaction as internal FIFO can hold up. |
| wninghj | 0:39b7f3158ebe | 215 | |
| wninghj | 0:39b7f3158ebe | 216 | @note If verbose is enabled, all the received data will be print to Serial |
| wninghj | 0:39b7f3158ebe | 217 | |
| wninghj | 0:39b7f3158ebe | 218 | @return |
| wninghj | 0:39b7f3158ebe | 219 | - true : if succeeded |
| wninghj | 0:39b7f3158ebe | 220 | - false : if failed |
| wninghj | 0:39b7f3158ebe | 221 | */ |
| wninghj | 0:39b7f3158ebe | 222 | /******************************************************************************/ |
| wninghj | 0:39b7f3158ebe | 223 | bool bleGetResponse(void) |
| wninghj | 0:39b7f3158ebe | 224 | { |
| wninghj | 0:39b7f3158ebe | 225 | // Try to read data from Bluefruit if there is enough room in the fifo |
| wninghj | 0:39b7f3158ebe | 226 | while ( m_rx_fifo.remaining() >= SDEP_MAX_PACKETSIZE ) |
| wninghj | 0:39b7f3158ebe | 227 | { |
| wninghj | 0:39b7f3158ebe | 228 | // Get a SDEP packet |
| wninghj | 0:39b7f3158ebe | 229 | sdepMsgResponse_t msg_response; |
| wninghj | 0:39b7f3158ebe | 230 | memset(&msg_response, 0, sizeof(sdepMsgResponse_t)); |
| wninghj | 0:39b7f3158ebe | 231 | |
| wninghj | 0:39b7f3158ebe | 232 | if ( !bleGetPacket(&msg_response) ) return false; |
| wninghj | 0:39b7f3158ebe | 233 | |
| wninghj | 0:39b7f3158ebe | 234 | // Write to fifo |
| wninghj | 0:39b7f3158ebe | 235 | if ( msg_response.header.length > 0) |
| wninghj | 0:39b7f3158ebe | 236 | { |
| wninghj | 0:39b7f3158ebe | 237 | m_rx_fifo.write_n(msg_response.payload, msg_response.header.length); |
| wninghj | 0:39b7f3158ebe | 238 | } |
| wninghj | 0:39b7f3158ebe | 239 | |
| wninghj | 0:39b7f3158ebe | 240 | // No more packet data |
| wninghj | 0:39b7f3158ebe | 241 | if ( !msg_response.header.more_data ) break; |
| wninghj | 0:39b7f3158ebe | 242 | |
| wninghj | 0:39b7f3158ebe | 243 | // It takes a bit since all Data received to IRQ to get LOW |
| wninghj | 0:39b7f3158ebe | 244 | // May need to delay a bit for it to be stable before the next try |
| wninghj | 0:39b7f3158ebe | 245 | wait_us(50); |
| wninghj | 0:39b7f3158ebe | 246 | } |
| wninghj | 0:39b7f3158ebe | 247 | |
| wninghj | 0:39b7f3158ebe | 248 | return true; |
| wninghj | 0:39b7f3158ebe | 249 | } |
| wninghj | 0:39b7f3158ebe | 250 | |
| wninghj | 0:39b7f3158ebe | 251 | |
| wninghj | 0:39b7f3158ebe | 252 | void bleWrite(char *cmd) { |
| wninghj | 0:39b7f3158ebe | 253 | while (*cmd != '\0') { |
| wninghj | 0:39b7f3158ebe | 254 | bleWriteChar((uint8_t) *cmd); |
| wninghj | 0:39b7f3158ebe | 255 | cmd += 1; |
| wninghj | 0:39b7f3158ebe | 256 | } |
| wninghj | 0:39b7f3158ebe | 257 | } |
| wninghj | 0:39b7f3158ebe | 258 | |
| wninghj | 0:39b7f3158ebe | 259 | |
| wninghj | 0:39b7f3158ebe | 260 | /******************************************************************************/ |
| wninghj | 0:39b7f3158ebe | 261 | /*! |
| wninghj | 0:39b7f3158ebe | 262 | @brief Check if the response from the previous command is ready |
| wninghj | 0:39b7f3158ebe | 263 | |
| wninghj | 0:39b7f3158ebe | 264 | @return 'true' if a response is ready, otherwise 'false' |
| wninghj | 0:39b7f3158ebe | 265 | */ |
| wninghj | 0:39b7f3158ebe | 266 | /******************************************************************************/ |
| wninghj | 0:39b7f3158ebe | 267 | int bleAvailable(void) |
| wninghj | 0:39b7f3158ebe | 268 | { |
| wninghj | 0:39b7f3158ebe | 269 | if (! m_rx_fifo.empty() ) { |
| wninghj | 0:39b7f3158ebe | 270 | return m_rx_fifo.count(); |
| wninghj | 0:39b7f3158ebe | 271 | } |
| wninghj | 0:39b7f3158ebe | 272 | |
| wninghj | 0:39b7f3158ebe | 273 | if ( bleMode == DATA ) |
| wninghj | 0:39b7f3158ebe | 274 | { |
| wninghj | 0:39b7f3158ebe | 275 | // DATA Mode: query for BLE UART data |
| wninghj | 0:39b7f3158ebe | 276 | sendPacket(SDEP_CMDTYPE_BLE_UARTRX, NULL, 0, 0); |
| wninghj | 0:39b7f3158ebe | 277 | |
| wninghj | 0:39b7f3158ebe | 278 | // Waiting to get response from Bluefruit |
| wninghj | 0:39b7f3158ebe | 279 | bleGetResponse(); |
| wninghj | 0:39b7f3158ebe | 280 | |
| wninghj | 0:39b7f3158ebe | 281 | return m_rx_fifo.count(); |
| wninghj | 0:39b7f3158ebe | 282 | }else{ |
| wninghj | 0:39b7f3158ebe | 283 | return m_irq_pin; |
| wninghj | 0:39b7f3158ebe | 284 | } |
| wninghj | 0:39b7f3158ebe | 285 | } |
| wninghj | 0:39b7f3158ebe | 286 | |
| wninghj | 0:39b7f3158ebe | 287 | /******************************************************************************/ |
| wninghj | 0:39b7f3158ebe | 288 | /*! |
| wninghj | 0:39b7f3158ebe | 289 | @brief Get a byte from response data, perform SPI transaction if needed |
| wninghj | 0:39b7f3158ebe | 290 | |
| wninghj | 0:39b7f3158ebe | 291 | @return -1 if no data is available |
| wninghj | 0:39b7f3158ebe | 292 | */ |
| wninghj | 0:39b7f3158ebe | 293 | /******************************************************************************/ |
| wninghj | 0:39b7f3158ebe | 294 | int bleRead(void) |
| wninghj | 0:39b7f3158ebe | 295 | { |
| wninghj | 0:39b7f3158ebe | 296 | uint8_t ch; |
| wninghj | 0:39b7f3158ebe | 297 | |
| wninghj | 0:39b7f3158ebe | 298 | // try to grab from buffer first... |
| wninghj | 0:39b7f3158ebe | 299 | if (!m_rx_fifo.empty()) { |
| wninghj | 0:39b7f3158ebe | 300 | m_rx_fifo.read(&ch); |
| wninghj | 0:39b7f3158ebe | 301 | return (int)ch; |
| wninghj | 0:39b7f3158ebe | 302 | } |
| wninghj | 0:39b7f3158ebe | 303 | |
| wninghj | 0:39b7f3158ebe | 304 | if ( bleMode == DATA ) |
| wninghj | 0:39b7f3158ebe | 305 | { |
| wninghj | 0:39b7f3158ebe | 306 | // DATA Mode: query for BLE UART data |
| wninghj | 0:39b7f3158ebe | 307 | sendPacket(SDEP_CMDTYPE_BLE_UARTRX, NULL, 0, 0); |
| wninghj | 0:39b7f3158ebe | 308 | |
| wninghj | 0:39b7f3158ebe | 309 | // Waiting to get response from Bluefruit |
| wninghj | 0:39b7f3158ebe | 310 | bleGetResponse(); |
| wninghj | 0:39b7f3158ebe | 311 | }else |
| wninghj | 0:39b7f3158ebe | 312 | { |
| wninghj | 0:39b7f3158ebe | 313 | // COMMAND Mode: Only read data from Bluefruit if IRQ is raised |
| wninghj | 0:39b7f3158ebe | 314 | if ( m_irq_pin ) bleGetResponse(); |
| wninghj | 0:39b7f3158ebe | 315 | } |
| wninghj | 0:39b7f3158ebe | 316 | |
| wninghj | 0:39b7f3158ebe | 317 | return m_rx_fifo.read(&ch) ? ((int) ch) : EOF; |
| wninghj | 0:39b7f3158ebe | 318 | |
| wninghj | 0:39b7f3158ebe | 319 | } |
| wninghj | 0:39b7f3158ebe | 320 | |
| wninghj | 0:39b7f3158ebe | 321 | |
| wninghj | 0:39b7f3158ebe | 322 | uint16_t bleReadLine(char * buf, uint16_t bufsize) |
| wninghj | 0:39b7f3158ebe | 323 | { |
| wninghj | 0:39b7f3158ebe | 324 | uint16_t timeout = 1000 * 10; |
| wninghj | 0:39b7f3158ebe | 325 | bool multiline = false; |
| wninghj | 0:39b7f3158ebe | 326 | uint16_t replyidx = 0; |
| wninghj | 0:39b7f3158ebe | 327 | |
| wninghj | 0:39b7f3158ebe | 328 | while (timeout--) { |
| wninghj | 0:39b7f3158ebe | 329 | while(bleAvailable()) { |
| wninghj | 0:39b7f3158ebe | 330 | //pc.printf("SPI: Available\n"); |
| wninghj | 0:39b7f3158ebe | 331 | char c = bleRead(); |
| wninghj | 0:39b7f3158ebe | 332 | //pc.printf("SPI: %d\n", (int) c); |
| wninghj | 0:39b7f3158ebe | 333 | //SerialDebug.println(c); |
| wninghj | 0:39b7f3158ebe | 334 | |
| wninghj | 0:39b7f3158ebe | 335 | if (c == '\r') continue; |
| wninghj | 0:39b7f3158ebe | 336 | |
| wninghj | 0:39b7f3158ebe | 337 | if (c == '\n') { |
| wninghj | 0:39b7f3158ebe | 338 | // the first '\n' is ignored |
| wninghj | 0:39b7f3158ebe | 339 | if (replyidx == 0) continue; |
| wninghj | 0:39b7f3158ebe | 340 | |
| wninghj | 0:39b7f3158ebe | 341 | if (!multiline) { |
| wninghj | 0:39b7f3158ebe | 342 | timeout = 0; |
| wninghj | 0:39b7f3158ebe | 343 | break; |
| wninghj | 0:39b7f3158ebe | 344 | } |
| wninghj | 0:39b7f3158ebe | 345 | } |
| wninghj | 0:39b7f3158ebe | 346 | buf[replyidx] = c; |
| wninghj | 0:39b7f3158ebe | 347 | replyidx++; |
| wninghj | 0:39b7f3158ebe | 348 | |
| wninghj | 0:39b7f3158ebe | 349 | // Buffer is full |
| wninghj | 0:39b7f3158ebe | 350 | if (replyidx >= bufsize) { |
| wninghj | 0:39b7f3158ebe | 351 | //if (_verbose) { SerialDebug.println("*overflow*"); } // for my debuggin' only! |
| wninghj | 0:39b7f3158ebe | 352 | timeout = 0; |
| wninghj | 0:39b7f3158ebe | 353 | break; |
| wninghj | 0:39b7f3158ebe | 354 | } |
| wninghj | 0:39b7f3158ebe | 355 | } |
| wninghj | 0:39b7f3158ebe | 356 | |
| wninghj | 0:39b7f3158ebe | 357 | // delay if needed |
| wninghj | 0:39b7f3158ebe | 358 | if (timeout) { |
| wninghj | 0:39b7f3158ebe | 359 | Thread::wait(1); |
| wninghj | 0:39b7f3158ebe | 360 | } |
| wninghj | 0:39b7f3158ebe | 361 | } |
| wninghj | 0:39b7f3158ebe | 362 | |
| wninghj | 0:39b7f3158ebe | 363 | buf[replyidx] = 0; // null term |
| wninghj | 0:39b7f3158ebe | 364 | |
| wninghj | 0:39b7f3158ebe | 365 | return replyidx; |
| wninghj | 0:39b7f3158ebe | 366 | } |
| wninghj | 0:39b7f3158ebe | 367 | |
| wninghj | 0:39b7f3158ebe | 368 | bool waitForOK(void) |
| wninghj | 0:39b7f3158ebe | 369 | { |
| wninghj | 0:39b7f3158ebe | 370 | // Use temp buffer to avoid overwrite returned result if any |
| wninghj | 0:39b7f3158ebe | 371 | char tempbuf[BLE_BUFSIZE + 1]; |
| wninghj | 0:39b7f3158ebe | 372 | |
| wninghj | 0:39b7f3158ebe | 373 | while (bleReadLine(tempbuf, BLE_BUFSIZE)) { |
| wninghj | 0:39b7f3158ebe | 374 | // pc.printf("SPI: %s\n", tempbuf); |
| wninghj | 0:39b7f3158ebe | 375 | if (strcmp(tempbuf, "OK") == 0) return true; |
| wninghj | 0:39b7f3158ebe | 376 | if (strcmp(tempbuf, "ERROR") == 0) return false; |
| wninghj | 0:39b7f3158ebe | 377 | } |
| wninghj | 0:39b7f3158ebe | 378 | return false; |
| wninghj | 0:39b7f3158ebe | 379 | } |
| wninghj | 0:39b7f3158ebe | 380 | |
| wninghj | 0:39b7f3158ebe | 381 | bool sendATCommand(char *cmd) { |
| wninghj | 0:39b7f3158ebe | 382 | bleMode = COMMAND; |
| wninghj | 0:39b7f3158ebe | 383 | bleWrite(cmd); |
| wninghj | 0:39b7f3158ebe | 384 | bleWrite("\r\n"); |
| wninghj | 0:39b7f3158ebe | 385 | bool result = waitForOK(); |
| wninghj | 0:39b7f3158ebe | 386 | bleMode = DATA; |
| wninghj | 0:39b7f3158ebe | 387 | return result; |
| wninghj | 0:39b7f3158ebe | 388 | } |
| wninghj | 0:39b7f3158ebe | 389 | |
| wninghj | 0:39b7f3158ebe | 390 | bool sendCommandCheckOK(char *cmd) { |
| wninghj | 0:39b7f3158ebe | 391 | return sendATCommand(cmd); |
| wninghj | 0:39b7f3158ebe | 392 | } |
| wninghj | 0:39b7f3158ebe | 393 | |
| wninghj | 0:39b7f3158ebe | 394 | // ============================================================================= |
| wninghj | 0:39b7f3158ebe | 395 | |
| wninghj | 0:39b7f3158ebe | 396 | void flush(void) |
| wninghj | 0:39b7f3158ebe | 397 | { |
| wninghj | 0:39b7f3158ebe | 398 | m_rx_fifo.clear(); |
| wninghj | 0:39b7f3158ebe | 399 | } |
| wninghj | 0:39b7f3158ebe | 400 | |
| wninghj | 0:39b7f3158ebe | 401 | uint8_t highByte(uint16_t x) { |
| wninghj | 0:39b7f3158ebe | 402 | return (uint8_t) (x >> 8); |
| wninghj | 0:39b7f3158ebe | 403 | } |
| wninghj | 0:39b7f3158ebe | 404 | |
| wninghj | 0:39b7f3158ebe | 405 | uint8_t lowByte(uint16_t x) { |
| wninghj | 0:39b7f3158ebe | 406 | return (uint8_t) (x & 0xff); |
| wninghj | 0:39b7f3158ebe | 407 | } |
| wninghj | 0:39b7f3158ebe | 408 | |
| wninghj | 0:39b7f3158ebe | 409 | bool sendPacket(uint16_t command, const uint8_t* buf, uint8_t count, uint8_t more_data) { |
| wninghj | 0:39b7f3158ebe | 410 | // flush old response before sending the new command |
| wninghj | 0:39b7f3158ebe | 411 | if (more_data == 0) flush(); |
| wninghj | 0:39b7f3158ebe | 412 | |
| wninghj | 0:39b7f3158ebe | 413 | sdepMsgCommand_t msgCmd; |
| wninghj | 0:39b7f3158ebe | 414 | |
| wninghj | 0:39b7f3158ebe | 415 | msgCmd.header.msg_type = SDEP_MSGTYPE_COMMAND; |
| wninghj | 0:39b7f3158ebe | 416 | msgCmd.header.cmd_id_high = highByte(command); |
| wninghj | 0:39b7f3158ebe | 417 | msgCmd.header.cmd_id_low = lowByte(command); |
| wninghj | 0:39b7f3158ebe | 418 | msgCmd.header.length = count; |
| wninghj | 0:39b7f3158ebe | 419 | msgCmd.header.more_data = (count == SDEP_MAX_PACKETSIZE) ? more_data : 0; |
| wninghj | 0:39b7f3158ebe | 420 | |
| wninghj | 0:39b7f3158ebe | 421 | // Copy payload |
| wninghj | 0:39b7f3158ebe | 422 | if ( buf != NULL && count > 0) memcpy(msgCmd.payload, buf, count); |
| wninghj | 0:39b7f3158ebe | 423 | |
| wninghj | 0:39b7f3158ebe | 424 | enable_spi(); |
| wninghj | 0:39b7f3158ebe | 425 | |
| wninghj | 0:39b7f3158ebe | 426 | TimeoutTimer tt(_timeout); |
| wninghj | 0:39b7f3158ebe | 427 | |
| wninghj | 0:39b7f3158ebe | 428 | // Bluefruit may not be ready |
| wninghj | 0:39b7f3158ebe | 429 | while ( ( spixfer(msgCmd.header.msg_type) == SPI_IGNORED_BYTE ) && !tt.expired() ) |
| wninghj | 0:39b7f3158ebe | 430 | { |
| wninghj | 0:39b7f3158ebe | 431 | // Disable & Re-enable CS with a bit of delay for Bluefruit to ready itself |
| wninghj | 0:39b7f3158ebe | 432 | disable_spi(); |
| wninghj | 0:39b7f3158ebe | 433 | wait_us(SPI_DEFAULT_DELAY_US); |
| wninghj | 0:39b7f3158ebe | 434 | enable_spi(); |
| wninghj | 0:39b7f3158ebe | 435 | } |
| wninghj | 0:39b7f3158ebe | 436 | |
| wninghj | 0:39b7f3158ebe | 437 | bool result = !tt.expired(); |
| wninghj | 0:39b7f3158ebe | 438 | if ( result ) |
| wninghj | 0:39b7f3158ebe | 439 | { |
| wninghj | 0:39b7f3158ebe | 440 | // transfer the rest of the data |
| wninghj | 0:39b7f3158ebe | 441 | spixfer((void*) (((uint8_t*)&msgCmd) +1), sizeof(sdepMsgHeader_t)+count-1); |
| wninghj | 0:39b7f3158ebe | 442 | } |
| wninghj | 0:39b7f3158ebe | 443 | |
| wninghj | 0:39b7f3158ebe | 444 | disable_spi(); |
| wninghj | 0:39b7f3158ebe | 445 | |
| wninghj | 0:39b7f3158ebe | 446 | return result; |
| wninghj | 0:39b7f3158ebe | 447 | } |
| wninghj | 0:39b7f3158ebe | 448 | |
| wninghj | 0:39b7f3158ebe | 449 | size_t bleWriteChar(uint8_t c) { |
| wninghj | 0:39b7f3158ebe | 450 | if (bleMode == DATA) |
| wninghj | 0:39b7f3158ebe | 451 | { |
| wninghj | 0:39b7f3158ebe | 452 | sendPacket(SDEP_CMDTYPE_BLE_UARTTX, &c, 1, 0); |
| wninghj | 0:39b7f3158ebe | 453 | bleGetResponse(); |
| wninghj | 0:39b7f3158ebe | 454 | return 1; |
| wninghj | 0:39b7f3158ebe | 455 | } |
| wninghj | 0:39b7f3158ebe | 456 | |
| wninghj | 0:39b7f3158ebe | 457 | // Following code handle BLUEFRUIT_MODE_COMMAND |
| wninghj | 0:39b7f3158ebe | 458 | |
| wninghj | 0:39b7f3158ebe | 459 | // Final packet due to \r or \n terminator |
| wninghj | 0:39b7f3158ebe | 460 | if (c == '\r' || c == '\n') |
| wninghj | 0:39b7f3158ebe | 461 | { |
| wninghj | 0:39b7f3158ebe | 462 | if (m_tx_count > 0) |
| wninghj | 0:39b7f3158ebe | 463 | { |
| wninghj | 0:39b7f3158ebe | 464 | bool result = sendPacket(SDEP_CMDTYPE_AT_WRAPPER, m_tx_buffer, m_tx_count, 0); |
| wninghj | 0:39b7f3158ebe | 465 | m_tx_count = 0; |
| wninghj | 0:39b7f3158ebe | 466 | if (!result) { |
| wninghj | 0:39b7f3158ebe | 467 | return 0; |
| wninghj | 0:39b7f3158ebe | 468 | } |
| wninghj | 0:39b7f3158ebe | 469 | } |
| wninghj | 0:39b7f3158ebe | 470 | } |
| wninghj | 0:39b7f3158ebe | 471 | // More than max packet buffered --> send with more_data = 1 |
| wninghj | 0:39b7f3158ebe | 472 | else if (m_tx_count == SDEP_MAX_PACKETSIZE) |
| wninghj | 0:39b7f3158ebe | 473 | { |
| wninghj | 0:39b7f3158ebe | 474 | bool result = sendPacket(SDEP_CMDTYPE_AT_WRAPPER, m_tx_buffer, m_tx_count, 1); |
| wninghj | 0:39b7f3158ebe | 475 | |
| wninghj | 0:39b7f3158ebe | 476 | m_tx_buffer[0] = c; |
| wninghj | 0:39b7f3158ebe | 477 | m_tx_count = 1; |
| wninghj | 0:39b7f3158ebe | 478 | if (!result) { |
| wninghj | 0:39b7f3158ebe | 479 | return 0; |
| wninghj | 0:39b7f3158ebe | 480 | } |
| wninghj | 0:39b7f3158ebe | 481 | } |
| wninghj | 0:39b7f3158ebe | 482 | // Not enough data, continue to buffer |
| wninghj | 0:39b7f3158ebe | 483 | else |
| wninghj | 0:39b7f3158ebe | 484 | { |
| wninghj | 0:39b7f3158ebe | 485 | m_tx_buffer[m_tx_count++] = c; |
| wninghj | 0:39b7f3158ebe | 486 | } |
| wninghj | 0:39b7f3158ebe | 487 | return 1; |
| wninghj | 0:39b7f3158ebe | 488 | } |
| wninghj | 0:39b7f3158ebe | 489 | |
| wninghj | 0:39b7f3158ebe | 490 | int32_t readline_parseInt(void) |
| wninghj | 0:39b7f3158ebe | 491 | { |
| wninghj | 0:39b7f3158ebe | 492 | char buffer[101] = { 0 }; |
| wninghj | 0:39b7f3158ebe | 493 | uint16_t len = bleReadLine(buffer, 100); |
| wninghj | 0:39b7f3158ebe | 494 | if (len == 0) return 0; |
| wninghj | 0:39b7f3158ebe | 495 | |
| wninghj | 0:39b7f3158ebe | 496 | // also parsed hex number e.g 0xADAF |
| wninghj | 0:39b7f3158ebe | 497 | int32_t val = strtol(buffer, NULL, 0); |
| wninghj | 0:39b7f3158ebe | 498 | |
| wninghj | 0:39b7f3158ebe | 499 | return val; |
| wninghj | 0:39b7f3158ebe | 500 | } |
| wninghj | 0:39b7f3158ebe | 501 | |
| wninghj | 0:39b7f3158ebe | 502 | bool send_arg_get_resp(int32_t *reply) { |
| wninghj | 0:39b7f3158ebe | 503 | bleWrite("\r\n"); // execute command |
| wninghj | 0:39b7f3158ebe | 504 | |
| wninghj | 0:39b7f3158ebe | 505 | // parse integer response if required |
| wninghj | 0:39b7f3158ebe | 506 | if (reply) |
| wninghj | 0:39b7f3158ebe | 507 | { |
| wninghj | 0:39b7f3158ebe | 508 | (*reply) = readline_parseInt(); |
| wninghj | 0:39b7f3158ebe | 509 | } |
| wninghj | 0:39b7f3158ebe | 510 | |
| wninghj | 0:39b7f3158ebe | 511 | // check OK or ERROR status |
| wninghj | 0:39b7f3158ebe | 512 | return waitForOK(); |
| wninghj | 0:39b7f3158ebe | 513 | } |
| wninghj | 0:39b7f3158ebe | 514 | |
| wninghj | 0:39b7f3158ebe | 515 | int32_t sendATCommandIntReply(char *cmd) { |
| wninghj | 0:39b7f3158ebe | 516 | int32_t reply = 0; |
| wninghj | 0:39b7f3158ebe | 517 | BLE_MODE current_mode = bleMode; |
| wninghj | 0:39b7f3158ebe | 518 | |
| wninghj | 0:39b7f3158ebe | 519 | // switch mode if necessary to execute command |
| wninghj | 0:39b7f3158ebe | 520 | bleMode = COMMAND; |
| wninghj | 0:39b7f3158ebe | 521 | |
| wninghj | 0:39b7f3158ebe | 522 | // Execute command with parameter and get response |
| wninghj | 0:39b7f3158ebe | 523 | bleWrite(cmd); |
| wninghj | 0:39b7f3158ebe | 524 | send_arg_get_resp(&reply); |
| wninghj | 0:39b7f3158ebe | 525 | |
| wninghj | 0:39b7f3158ebe | 526 | // switch back if necessary |
| wninghj | 0:39b7f3158ebe | 527 | if ( current_mode == DATA ) bleMode = DATA; |
| wninghj | 0:39b7f3158ebe | 528 | return reply; |
| wninghj | 0:39b7f3158ebe | 529 | } |
| wninghj | 0:39b7f3158ebe | 530 | |
| wninghj | 0:39b7f3158ebe | 531 | bool sendInitializePattern() { |
| wninghj | 0:39b7f3158ebe | 532 | return sendPacket(SDEP_CMDTYPE_INITIALIZE, NULL, 0, 0); |
| wninghj | 0:39b7f3158ebe | 533 | } |
| wninghj | 0:39b7f3158ebe | 534 | |
| wninghj | 0:39b7f3158ebe | 535 | bool isBLEConnected() { |
| wninghj | 0:39b7f3158ebe | 536 | int32_t connected = 0; |
| wninghj | 0:39b7f3158ebe | 537 | connected = sendATCommandIntReply("AT+GAPGETCONN"); |
| wninghj | 0:39b7f3158ebe | 538 | return connected; |
| wninghj | 0:39b7f3158ebe | 539 | } |
| wninghj | 0:39b7f3158ebe | 540 | |
| wninghj | 0:39b7f3158ebe | 541 | |
| wninghj | 0:39b7f3158ebe | 542 | void timer_function_millis(void const *n) { |
| wninghj | 0:39b7f3158ebe | 543 | _millis += 1; |
| wninghj | 0:39b7f3158ebe | 544 | } |
| wninghj | 0:39b7f3158ebe | 545 | |
| wninghj | 0:39b7f3158ebe | 546 | int main() { |
| wninghj | 0:39b7f3158ebe | 547 | // timer to bump _millis |
| wninghj | 0:39b7f3158ebe | 548 | RtosTimer millis_timer(timer_function_millis, osTimerPeriodic, (void *)0); |
| wninghj | 0:39b7f3158ebe | 549 | millis_timer.start(1); |
| wninghj | 0:39b7f3158ebe | 550 | |
| wninghj | 0:39b7f3158ebe | 551 | pc.baud(115200); |
| wninghj | 0:39b7f3158ebe | 552 | spi.format(8, 0); |
| wninghj | 0:39b7f3158ebe | 553 | spi.frequency(4000000); |
| wninghj | 0:39b7f3158ebe | 554 | |
| wninghj | 0:39b7f3158ebe | 555 | pc.printf("Prepare to initiaize BLE\n"); |
| wninghj | 0:39b7f3158ebe | 556 | |
| wninghj | 0:39b7f3158ebe | 557 | // initialize BLE |
| wninghj | 0:39b7f3158ebe | 558 | cs = 1; |
| wninghj | 0:39b7f3158ebe | 559 | if (!sendInitializePattern()) pc.printf("BLE Init Failed\n"); |
| wninghj | 0:39b7f3158ebe | 560 | ble_reset = 1; |
| wninghj | 0:39b7f3158ebe | 561 | ble_reset = 0; |
| wninghj | 0:39b7f3158ebe | 562 | Thread::wait(10); |
| wninghj | 0:39b7f3158ebe | 563 | ble_reset = 1; |
| wninghj | 0:39b7f3158ebe | 564 | Thread::wait(500); |
| wninghj | 0:39b7f3158ebe | 565 | cs = 1; |
| wninghj | 0:39b7f3158ebe | 566 | |
| wninghj | 0:39b7f3158ebe | 567 | pc.printf("Set BLE Name\n"); |
| wninghj | 0:39b7f3158ebe | 568 | |
| wninghj | 0:39b7f3158ebe | 569 | // change name |
| wninghj | 0:39b7f3158ebe | 570 | if (!sendCommandCheckOK("AT+GAPDEVNAME=AdafruitDJ")) { |
| wninghj | 0:39b7f3158ebe | 571 | pc.printf("Could not set device name.\n"); |
| wninghj | 0:39b7f3158ebe | 572 | } |
| wninghj | 0:39b7f3158ebe | 573 | |
| wninghj | 0:39b7f3158ebe | 574 | // wait until connected |
| wninghj | 0:39b7f3158ebe | 575 | while (!isBLEConnected()) { |
| wninghj | 0:39b7f3158ebe | 576 | Thread::wait(100); |
| wninghj | 0:39b7f3158ebe | 577 | } |
| wninghj | 0:39b7f3158ebe | 578 | |
| wninghj | 0:39b7f3158ebe | 579 | pc.printf("Ready\n"); |
| wninghj | 0:39b7f3158ebe | 580 | |
| wninghj | 0:39b7f3158ebe | 581 | Thread::wait(1000); |
| wninghj | 0:39b7f3158ebe | 582 | |
| wninghj | 0:39b7f3158ebe | 583 | int i = 0; |
| wninghj | 0:39b7f3158ebe | 584 | while (true) { |
| wninghj | 0:39b7f3158ebe | 585 | bleMode = DATA; |
| wninghj | 0:39b7f3158ebe | 586 | // send character |
| wninghj | 0:39b7f3158ebe | 587 | char str[40] = { 0 }; |
| wninghj | 0:39b7f3158ebe | 588 | sprintf(str, "Hello DJ %d\r\n", i); |
| wninghj | 0:39b7f3158ebe | 589 | bleWrite(str); |
| wninghj | 0:39b7f3158ebe | 590 | Thread::wait(1000); |
| wninghj | 0:39b7f3158ebe | 591 | pc.printf("Send\n"); |
| wninghj | 0:39b7f3158ebe | 592 | i += 1; |
| wninghj | 0:39b7f3158ebe | 593 | } |
| wninghj | 0:39b7f3158ebe | 594 | |
| wninghj | 0:39b7f3158ebe | 595 | Thread::wait(osWaitForever); |
| wninghj | 0:39b7f3158ebe | 596 | } |