1616 * Either 2.4" or 3.5" TFT FeatherWing is used to display uploaded image
1717 * - https://www.adafruit.com/product/3315
1818 * - https://www.adafruit.com/product/3651
19+ * - https://www.adafruit.com/product/4367
1920 */
2021
21- // if USE_35_TFT_FEATHERWING = 0 then the 2.4" TFT will be used instead
22- #define USE_35_TFT_FEATHERWING 1
22+ #define TFT_35_FEATHERWING 1
23+ #define TFT_24_FEATHERWING 2
24+ #define TFT_15_GIZMO 3
25+
26+ // one of above supported TFT add-on
27+ #define TFT_IN_USE TFT_35_FEATHERWING
2328
2429#include < bluefruit.h>
2530#include < SPI.h>
4045 #define TFT_CS A6
4146#endif
4247
43- #if USE_35_TFT_FEATHERWING
48+ #if TFT_IN_USE == TFT_35_FEATHERWING
4449 #include " Adafruit_HX8357.h"
4550 Adafruit_HX8357 tft = Adafruit_HX8357(TFT_CS, TFT_DC);
46- #else
51+ #elif TFT_IN_USE == TFT_24_FEATHERWING
4752 #include < Adafruit_ILI9341.h>
4853 Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);
54+ #elif TFT_IN_USE == TFT_15_GIZMO
55+ #error "Not supported yet"
56+ #else
57+ #error "TFT display is not supported"
4958#endif
5059
5160#define COLOR_WHITE 0xFFFF
@@ -62,15 +71,17 @@ BLEUart bleuart(10*1024);
6271/* The Image Transfer module sends the image of your choice to Bluefruit LE over UART.
6372 * Each image sent begins with
6473 * - A single byte char '!' (0x21) followed by 'I' helper for image
74+ * - Color depth: 24-bit for RGB 888, 16-bit for RGB 655
6575 * - Image width (uint16 little endian, 2 bytes)
6676 * - Image height (uint16 little endian, 2 bytes)
6777 * - Pixel data encoded as RGB 24-bit and suffixed by a single byte CRC.
6878 *
69- * Format: [ '!' ] [ 'I' ] [ uint16 width ] [ uint16 height ] [ r g b ] [ r g b ] [ r g b ] … [ CRC ]
79+ * Format: [ '!' ] [ 'I' ] [uint8_t color bit] [ uint16 width ] [ uint16 height ] [ r g b ] [ r g b ] [ r g b ] … [ CRC ]
7080 */
7181
7282uint16_t imageWidth = 0 ;
7383uint16_t imageHeight = 0 ;
84+ uint8_t imageColorBit = 0 ;
7485
7586uint32_t totalPixel = 0 ; // received pixel
7687
@@ -107,7 +118,21 @@ void setup()
107118
108119 // Configure and Start BLE Uart Service
109120 bleuart.begin ();
110- bleuart.setRxCallback (bleuart_rx_callback);
121+
122+ // Due to huge amount of image data
123+ // NRF52832 doesn't have enough SRAM to queue up received packets using deferred callbacks.
124+ // Therefore it must process data as soon as it comes, this can be done by
125+ // changing the default "deferred" option to false to invoke callback immediately.
126+ // However, the transfer speed will be affected since immediate callback will block BLE task
127+ // to process data especially when tft.drawRGBBitmap() is calling.
128+ #ifdef NRF52840_XXAA
129+ // 2nd argument is true to deferred callbacks i.e queue it up in seperated callback Task
130+ bleuart.setRxCallback (bleuart_rx_callback, true );
131+ #else
132+ // 2nd argument is false to invoke callbacks immediately (thus blocking other ble events)
133+ bleuart.setRxCallback (bleuart_rx_callback, false );
134+ #endif
135+
111136 bleuart.setRxOverflowCallback (bleuart_overflow_callback);
112137
113138 // Set up and start advertising
@@ -171,11 +196,13 @@ void bleuart_rx_callback(uint16_t conn_hdl)
171196
172197 if ( !bleuart.available () ) return ;
173198
199+ imageColorBit = bleuart.read8 ();
174200 imageWidth = bleuart.read16 ();
175201 imageHeight = bleuart.read16 ();
176202
177203 totalPixel = 0 ;
178204
205+ PRINT_INT (imageColorBit);
179206 PRINT_INT (imageWidth);
180207 PRINT_INT (imageHeight);
181208
@@ -186,10 +213,18 @@ void bleuart_rx_callback(uint16_t conn_hdl)
186213 // Extract pixel data to buffer and draw image line by line
187214 while ( bleuart.available () >= 3 )
188215 {
189- uint8_t rgb[3 ];
190- bleuart.read (rgb, 3 );
191-
192- pixel_buf[totalPixel % imageWidth] = ((rgb[0 ] & 0xF8 ) << 8 ) | ((rgb[1 ] & 0xFC ) << 3 ) | (rgb[2 ] >> 3 );
216+ // TFT FeatherWing use 16-bit RGB 655 color, need to convert if input is 24-bit color
217+ if ( imageColorBit == 24 )
218+ {
219+ uint8_t rgb[3 ];
220+ bleuart.read (rgb, 3 );
221+ pixel_buf[totalPixel % imageWidth] = ((rgb[0 ] & 0xF8 ) << 8 ) | ((rgb[1 ] & 0xFC ) << 3 ) | (rgb[2 ] >> 3 );
222+ }
223+ else if ( imageColorBit == 16 )
224+ {
225+ // native 16-bit 655 color
226+ pixel_buf[totalPixel % imageWidth] = bleuart.read16 ();
227+ }
193228
194229 totalPixel++;
195230
@@ -207,10 +242,12 @@ void bleuart_rx_callback(uint16_t conn_hdl)
207242 // do checksum later
208243
209244 // print speed summary
210- print_summary (totalPixel*3 + 7 , rxLastTime-rxStartTime);
245+ print_summary (totalPixel*(imageColorBit/ 8 ) + 8 , rxLastTime-rxStartTime);
211246
212247 // reset and waiting for new image
213- totalPixel = imageWidth = imageHeight = 0 ;
248+ imageColorBit = 0 ;
249+ imageWidth = imageHeight = 0 ;
250+ totalPixel = 0 ;
214251 }
215252}
216253
@@ -220,6 +257,7 @@ void connect_callback(uint16_t conn_handle)
220257
221258 tft.println (" Connected" );
222259
260+ #if 1
223261 conn->requestPHY ();
224262 tft.println (" Switching PHY" );
225263
@@ -228,6 +266,7 @@ void connect_callback(uint16_t conn_handle)
228266
229267 conn->requestMtuExchange (247 );
230268 tft.println (" Exchanging MTU" );
269+ #endif
231270
232271 tft.setTextColor (COLOR_GREEN);
233272 tft.println (" Ready to receive new image" );
@@ -251,14 +290,14 @@ void print_summary(uint32_t count, uint32_t ms)
251290
252291 tft.println (" seconds" );
253292
254- tft.print (" Speed " );
293+ tft.print (" Speed: " );
255294 tft.setTextColor (COLOR_YELLOW);
256295 tft.print ( (count / 1000 .0F ) / (ms / 1000 .0F ), 2 );
257296 tft.setTextColor (COLOR_WHITE);
258- tft.print (" KB/s with " );
297+ tft.print (" KB/s for " );
259298
260299 tft.setTextColor (COLOR_YELLOW);
261- tft.print (imageWidth); tft.print (" x " ); tft.print (imageHeight);
300+ tft.print (imageWidth); tft.print (" x " ); tft.print (imageHeight);
262301
263302 tft.setTextColor (COLOR_WHITE);
264303 tft.println (" Image" );
@@ -301,7 +340,9 @@ void disconnect_callback(uint16_t conn_handle, uint8_t reason)
301340 tft.setCursor (0 , 0 );
302341 tft.println (" Advertising ..." );
303342
304- totalPixel = imageWidth = imageHeight = 0 ;
343+ imageColorBit = 0 ;
344+ imageWidth = imageHeight = 0 ;
345+ totalPixel = 0 ;
305346 bleuart_overflowed = false ;
306347
307348 bleuart.flush ();
0 commit comments