Skip to content

Commit c31deb3

Browse files
committed
update image upload to support color depth 16 or 24 bit.
1 parent 460222b commit c31deb3

File tree

1 file changed

+57
-16
lines changed

1 file changed

+57
-16
lines changed

libraries/Bluefruit52Lib/examples/Peripheral/image_upload/image_upload.ino

Lines changed: 57 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,15 @@
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>
@@ -40,12 +45,16 @@
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

7282
uint16_t imageWidth = 0;
7383
uint16_t imageHeight = 0;
84+
uint8_t imageColorBit = 0;
7485

7586
uint32_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

Comments
 (0)