Skip to content

Commit 8e24f8c

Browse files
committed
ble: Wait with setting the product string to after orientation
usb_processing wasn't being setup until AFTER usb was enabled. This was a problem beacuse the app is so fast that it manages to send the first requests over ble before usb is setup. Since "usb_processing" is unrelated to the usb driver, we initialize it before we initialize the usb driver.
1 parent bff902e commit 8e24f8c

14 files changed

+118
-40
lines changed

Makefile

+4
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ bootloader-btc: | build
7979
$(MAKE) -C build bb02-bl-btconly.elf
8080
bootloader-btc-development: | build
8181
$(MAKE) -C build bb02-bl-btconly-development.elf
82+
bootloader-btc-plus-development: | build
83+
$(MAKE) -C build bb02p-bl-btconly-development.elf
8284
bootloader-btc-production: | build
8385
$(MAKE) -C build bb02-bl-btconly-production.elf
8486
factory-setup: | build
@@ -113,6 +115,8 @@ jlink-flash-bootloader-development: | build
113115
JLinkExe -NoGui 1 -if SWD -device ATSAMD51J20 -speed 4000 -autoconnect 1 -CommanderScript ./build/scripts/bb02-bl-multi-development.jlink
114116
jlink-flash-bootloader-plus-development: | build
115117
JLinkExe -NoGui 1 -if SWD -device ATSAMD51J20 -speed 4000 -autoconnect 1 -CommanderScript ./build/scripts/bb02p-bl-multi-development.jlink
118+
jlink-flash-bootloader-btc-plus-development: | build
119+
JLinkExe -NoGui 1 -if SWD -device ATSAMD51J20 -speed 4000 -autoconnect 1 -CommanderScript ./build/scripts/bb02p-bl-btconly-development.jlink
116120
jlink-flash-bootloader-development-locked: | build
117121
JLinkExe -NoGui 1 -if SWD -device ATSAMD51J20 -speed 4000 -autoconnect 1 -CommanderScript ./build/scripts/bb02-bl-multi-development-locked.jlink
118122
jlink-flash-bootloader: | build

src/bootloader/bootloader.c

+4-5
Original file line numberDiff line numberDiff line change
@@ -849,14 +849,12 @@ static size_t _api_command(const uint8_t* input, uint8_t* output, const size_t m
849849

850850
case OP_REBOOT: {
851851
#if PLATFORM_BITBOX02PLUS == 1
852-
// da14531_set_product("", 0, &uart_write_queue);
853-
da14531_reset(&uart_write_queue);
854-
// Send it now, because we are about to reset ourselves
852+
da14531_set_product(NULL, 0, &uart_write_queue);
853+
// Send it now, because we are about to reset ourselves
855854
while (ringbuffer_num(&uart_write_queue)) {
856855
uart_poll(NULL, 0, NULL, &uart_write_queue);
857856
}
858857
#endif
859-
860858
_api_reboot();
861859
} break;
862860

@@ -1046,7 +1044,8 @@ void bootloader_jump(void)
10461044
util_log("Not jumping to firmware");
10471045
_compute_is_app_flash_empty();
10481046
bootloader_render_default_screen();
1049-
if (usb_start(_api_setup) != ERR_NONE) {
1047+
_api_setup();
1048+
if (usb_start() != ERR_NONE) {
10501049
_render_message("Failed to initialize USB", 0);
10511050
}
10521051
}

src/bootloader/startup.c

+16-2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <string.h>
2424
#include <usb/class/hid/hww/hid_hww.h>
2525
#include <usb/usb_processing.h>
26+
#include <bootloader/bootloader_version.h>
2627

2728
#if defined(BOOTLOADER_DEVDEVICE) || PLATFORM_BITBOX02PLUS == 1
2829
#include <qtouch.h>
@@ -34,7 +35,15 @@
3435
#include <da14531/da14531_protocol.h>
3536
#include <uart.h>
3637
#include <utils_ringbuffer.h>
38+
39+
#if PRODUCT_BITBOX_PLUS_MULTI == 1
40+
#define DEVICE_MODE "{\"p\":\"bb02p-bl-multi\",\"v\":\"" BOOTLOADER_VERSION "\"}"
41+
#elif PRODUCT_BITBOX_PLUS_BTCONLY == 1
42+
#define DEVICE_MODE "{\"p\":\"bb02p-bl-btconly\",\"v\":\"" BOOTLOADER_VERSION "\"}"
43+
#else
44+
#error "unknown product"
3745
#endif
46+
#endif // PLATFORM_BITBOX02PLUS == 1
3847

3948
extern void __attribute__((noreturn)) __stack_chk_fail(void);
4049
void __attribute__((noreturn)) __stack_chk_fail(void)
@@ -85,10 +94,15 @@ int main(void)
8594
uint16_t uart_read_buf_len = 0;
8695

8796
ringbuffer_init(&uart_write_queue, &uart_write_buf, UART_OUT_BUF_LEN);
88-
#define DEVICE_MODE "{\"p\":\"bb02p-bl-multi\",\"v\":\"1.1.0\"}"
89-
da14531_set_product(DEVICE_MODE, sizeof(DEVICE_MODE) - 1, &uart_write_queue);
9097
bool usb_hww_request_seen = false;
9198

99+
// Set product to bootloader string, this is necessary if we have rebooted from firmware. Must
100+
// be done after usb_processing is initalized to avoid getting request from the app to early.
101+
da14531_handler_current_product = (const uint8_t*)DEVICE_MODE;
102+
da14531_handler_current_product_len = sizeof(DEVICE_MODE) - 1;
103+
da14531_set_product(
104+
da14531_handler_current_product, da14531_handler_current_product_len, &uart_write_queue);
105+
92106
da14531_protocol_init();
93107
#endif
94108
usb_processing_init();

src/da14531/da14531.c

+7-2
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,16 @@ void da14531_power_down(struct ringbuffer* uart_out)
4545
}
4646
}
4747

48-
void da14531_set_product(const char* product, uint16_t product_len, struct ringbuffer* uart_out)
48+
void da14531_set_product(
49+
volatile const uint8_t* product,
50+
volatile uint16_t product_len,
51+
struct ringbuffer* uart_out)
4952
{
5053
uint8_t payload[64] = {0};
5154
payload[0] = CTRL_CMD_PRODUCT_STRING;
52-
memcpy(&payload[1], product, product_len);
55+
for (int i = 0; i < product_len; i++) {
56+
payload[1 + i] = product[i];
57+
}
5358
uint8_t tmp[128];
5459
uint16_t tmp_len = da14531_protocol_format(
5560
&tmp[0], sizeof(tmp), DA14531_PROTOCOL_PACKET_TYPE_CTRL_DATA, &payload[0], 1 + product_len);

src/da14531/da14531.h

+5-2
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,12 @@ void da14531_power_down(struct ringbuffer* uart_out);
3636

3737
void da14531_reset(struct ringbuffer* uart_out);
3838

39-
// product is an array of characters to be set as product characteristic
39+
// product is an array of characters to be set as product characteristic (not null terminated)
4040
// procuct_len is the number of characters in the product array
4141
// uart_out is the queue where to put the outgoing serially encoded bytes
42-
void da14531_set_product(const char* product, uint16_t product_len, struct ringbuffer* uart_out);
42+
void da14531_set_product(
43+
volatile const uint8_t* product,
44+
volatile uint16_t product_len,
45+
struct ringbuffer* uart_out);
4346

4447
#endif

src/da14531/da14531_handler.c

+7-6
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@
2525
#include <ui/components/ui_images.h>
2626
#include <ui/fonts/monogram_5X9.h>
2727

28+
// These are set from interrupt context in the orientation workflow :/ therefore they need to be
29+
// volatile
30+
volatile const uint8_t* da14531_handler_current_product = NULL;
31+
volatile uint16_t da14531_handler_current_product_len = 0;
32+
2833
struct da14531_ctrl_frame {
2934
enum da14531_protocol_packet_type type;
3035
uint16_t payload_length; // includes length of cmd
@@ -205,12 +210,8 @@ static void _ctrl_handler(struct da14531_ctrl_frame* frame, struct ringbuffer* q
205210
} break;
206211
case CTRL_CMD_PRODUCT_STRING: {
207212
// util_log("da14531: get device mode");
208-
#if defined(BOOTLOADER)
209-
#define DEVICE_MODE "{\"p\":\"bb02p-bl-multi\",\"v\":\"1.1.0\"}"
210-
#else
211-
#define DEVICE_MODE "{\"p\":\"bb02p-multi\",\"v\":\"9.22.0\"}"
212-
#endif
213-
da14531_set_product(DEVICE_MODE, sizeof(DEVICE_MODE) - 1, queue);
213+
da14531_set_product(
214+
da14531_handler_current_product, da14531_handler_current_product_len, queue);
214215
} break;
215216
case CTRL_CMD_IDENTITY_ADDRESS: {
216217
// util_log("da14531: get addr");

src/da14531/da14531_handler.h

+3
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818
#include "da14531_protocol.h"
1919
#include <utils_ringbuffer.h>
2020

21+
extern volatile const uint8_t* da14531_handler_current_product;
22+
extern volatile uint16_t da14531_handler_current_product_len;
23+
2124
void da14531_handler(struct da14531_protocol_frame* frame, struct ringbuffer* queue);
2225

2326
#endif

src/da14531/da14531_protocol.c

+6-1
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,12 @@ static struct da14531_protocol_frame* _serial_link_in_poll(
242242
case SERIAL_LINK_STATE_READING: {
243243
int len = self->buf_in_len;
244244
for (int i = 0; i < len; i++) {
245-
// util_log("i:%d,b:%02x,l:%u", i, self->buf_in[i], self->buf_in_len);
245+
// util_log(
246+
// "i:%d,b:%02x,l:%u,h:%s",
247+
// i,
248+
// self->buf_in[i],
249+
// self->buf_in_len,
250+
// util_dbg_hex(&self->frame[0], 10));
246251
self->buf_in_len--;
247252
// Reset firmware loader on STX
248253
if (self->buf_in[i] == STX) {

src/firmware_main_loop.c

+4-8
Original file line numberDiff line numberDiff line change
@@ -47,21 +47,17 @@
4747

4848
void firmware_main_loop(void)
4949
{
50-
// This starts the async orientation screen workflow, which is processed by the loop below.
51-
orientation_screen();
52-
53-
// TODO: Send out new BLE product string, so app sees that we are booted
54-
// Set it to the size of the ringbuffer in the UART driver so we can read out all bytes
50+
// Set the size of uart_read_buf to the size of the ringbuffer in the UART driver so we can read
51+
// out all bytes
5552
uint8_t uart_read_buf[USART_0_BUFFER_SIZE] = {0};
5653
uint16_t uart_read_buf_len = 0;
5754

5855
struct ringbuffer uart_write_queue;
5956
uint8_t uart_write_buf[UART_OUT_BUF_LEN];
6057
ringbuffer_init(&uart_write_queue, &uart_write_buf, UART_OUT_BUF_LEN);
6158

62-
// Immediately enqueue the new firmware product string
63-
#define DEVICE_MODE "{\"p\":\"bb02p-multi\",\"v\":\"9.22.0\"}"
64-
da14531_set_product(DEVICE_MODE, sizeof(DEVICE_MODE) - 1, &uart_write_queue);
59+
// This starts the async orientation screen workflow, which is processed by the loop below.
60+
orientation_screen(&uart_write_queue);
6561

6662
const uint8_t* hww_data = NULL;
6763
uint8_t hww_frame[USB_REPORT_SIZE] = {0};

src/system.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ static void _ble_clear_product(void)
2828
struct ringbuffer uart_queue;
2929
uint8_t uart_queue_buf[64];
3030
ringbuffer_init(&uart_queue, &uart_queue_buf[0], sizeof(uart_queue_buf));
31-
da14531_set_product("", 0, &uart_queue);
31+
da14531_set_product(NULL, 0, &uart_queue);
3232
while (ringbuffer_num(&uart_queue)) {
3333
#ifndef TESTING
3434
uart_poll(NULL, 0, NULL, &uart_queue);

src/usb/usb.c

+3-9
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
#include "usb_desc_bitbox02plus.h"
2020
#include "usb_size.h"
2121
#include "usbdc.h"
22+
#include <da14531/da14531.h>
23+
#include <da14531/da14531_handler.h>
2224
#include <memory/memory_shared.h>
2325
#if APP_U2F == 1
2426
#include "u2f.h"
@@ -46,7 +48,6 @@ static uint8_t _descriptor_bytes_bitbox02plus[] = {
4648
static struct usbd_descriptors _descriptor_bitbox02plus[] = {
4749
{_descriptor_bytes_bitbox02plus,
4850
_descriptor_bytes_bitbox02plus + sizeof(_descriptor_bytes_bitbox02plus)}};
49-
static void (*_on_hww_init)(void) = NULL;
5051
static void _hww_endpoint_available(void);
5152
#if APP_U2F == 1
5253
static void _u2f_endpoint_available(void);
@@ -58,9 +59,6 @@ static void _hww_endpoint_available(void)
5859
if (!hid_hww_is_enabled()) {
5960
return;
6061
}
61-
if (_on_hww_init != NULL) {
62-
_on_hww_init();
63-
}
6462
hid_hww_setup();
6563
}
6664

@@ -71,7 +69,6 @@ static void _u2f_endpoint_available(void)
7169
if (!hid_u2f_is_enabled()) {
7270
return;
7371
};
74-
u2f_device_setup();
7572
hid_u2f_setup();
7673
}
7774
#endif
@@ -87,7 +84,7 @@ static void _timeout_cb(const struct timer_task* const timer_task)
8784

8885
static bool _usb_enabled = false;
8986

90-
int32_t usb_start(void (*on_hww_init)(void))
87+
int32_t usb_start(void)
9188
{
9289
#if !defined(TESTING) && APP_U2F == 1
9390
static struct timer_task Timer_task;
@@ -105,7 +102,6 @@ int32_t usb_start(void (*on_hww_init)(void))
105102
if (ret != 0) {
106103
return ret;
107104
}
108-
_on_hww_init = on_hww_init;
109105
ret = hid_hww_init(_hww_endpoint_available);
110106
if (ret != 0) {
111107
return ret;
@@ -125,8 +121,6 @@ int32_t usb_start(void (*on_hww_init)(void))
125121
break;
126122
}
127123
usbdc_attach();
128-
#else
129-
(void)on_hww_init;
130124
#endif
131125
_usb_enabled = true;
132126
return 0;

src/usb/usb.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
/**
2222
* Start the USB HID interfaces.
2323
*/
24-
int32_t usb_start(void (*on_hww_init)(void));
24+
int32_t usb_start(void);
2525

2626
/**
2727
* Stop the USB interfaces.

src/workflow/orientation_screen.c

+54-2
Original file line numberDiff line numberDiff line change
@@ -19,22 +19,71 @@
1919
#include <hal_timer.h>
2020
#include <platform/driver_init.h>
2121
#endif
22+
#include <da14531/da14531.h>
23+
#include <da14531/da14531_handler.h>
2224
#include <hww.h>
25+
#include <memory/memory_shared.h>
2326
#include <screen.h>
2427
#include <ui/components/lockscreen.h>
2528
#include <ui/components/orientation_arrows.h>
2629
#include <ui/screen_stack.h>
2730
#include <usb/usb.h>
31+
#include <utils_ringbuffer.h>
32+
#include <version.h>
33+
34+
#if APP_U2F
35+
#include <u2f.h>
36+
#endif
2837

2938
#ifndef TESTING
3039
#define IDLE_PERIOD_MS 1300
3140

41+
// Currently we have one firmware for both BB02 and BB02_PLUS, and only the
42+
// PRODUCT_BITBOX_MULTI/BTCONLY definitions apply. The PRODUCT_BITBOX_PLUS_MULTI/BTCONLY defs
43+
// currently only apply in the bootloader, which we don't need here.
44+
#if PRODUCT_BITBOX_MULTI == 1
45+
#define PRODUCT_STRING_SUFFIX "multi"
46+
#elif PRODUCT_BITBOX_BTCONLY == 1
47+
#define PRODUCT_STRING_SUFFIX "btconly"
48+
#elif PRODUCT_BITBOX02_FACTORYSETUP == 1
49+
// Dummy, not actually needed, but this file is currently needlessly compiled for factorysetup.
50+
#define PRODUCT_STRING_SUFFIX "factory"
51+
#else
52+
#error "unknown edition"
53+
#endif
54+
55+
#define DEVICE_MODE \
56+
"{\"p\":\"bb02p-" PRODUCT_STRING_SUFFIX "\",\"v\":\"" DIGITAL_BITBOX_VERSION "\"}"
57+
3258
static struct timer_task _idle_timer_task = {0};
3359

60+
struct select_orientation_data {
61+
struct ringbuffer* uart_out_queue;
62+
};
63+
64+
static struct select_orientation_data _data = {0};
65+
3466
static void _idle_timer_cb(const struct timer_task* const timer_task)
3567
{
3668
(void)timer_task;
37-
usb_start(hww_setup);
69+
70+
// Setup usb_processing handlers
71+
hww_setup();
72+
#if APP_U2F
73+
u2f_device_setup();
74+
#endif
75+
76+
// hww handler in usb_process must be setup before we can allow ble connections
77+
if (memory_get_platform() == MEMORY_PLATFORM_BITBOX02_PLUS) {
78+
da14531_handler_current_product = (const uint8_t*)DEVICE_MODE;
79+
da14531_handler_current_product_len = sizeof(DEVICE_MODE) - 1;
80+
da14531_set_product(
81+
da14531_handler_current_product,
82+
da14531_handler_current_product_len,
83+
_data.uart_out_queue);
84+
}
85+
86+
usb_start();
3887
ui_screen_stack_push(lockscreen_create());
3988
}
4089
#endif
@@ -57,7 +106,10 @@ static void _select_orientation_done(bool upside_down, void* cb_param)
57106
#endif
58107
}
59108

60-
void orientation_screen(void)
109+
void orientation_screen(struct ringbuffer* uart_out_queue)
61110
{
111+
#ifndef TESTING
112+
_data.uart_out_queue = uart_out_queue;
113+
#endif
62114
ui_screen_stack_push(orientation_arrows_create(_select_orientation_done, NULL));
63115
}

src/workflow/orientation_screen.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
#ifndef __ORIENTATION_SCREEN_H
1616
#define __ORIENTATION_SCREEN_H
1717

18-
void orientation_screen(void);
18+
#include <utils_ringbuffer.h>
19+
20+
void orientation_screen(struct ringbuffer* uart_out_queue);
1921

2022
#endif // __ORIENTATION_SCREEN_H

0 commit comments

Comments
 (0)