diff --git a/CHANGELOG.md b/CHANGELOG.md index 1935d0913..f94993e16 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ ### Added - Experimental support for USB connectivity on SPIKE Prime ([pybricks-micropython#208]). - Initial support for `pybricks.iodevices.UARTDevice` ([support#220]). +- Enabled previously hidden support for multiple code + slots ([pybricks-micropython#264], [pybricks-micropython#312]). A new + (unreleased) version of Pybricks Code is needed to use this. ### Changed - Extensive overhaul of UART and port drivers on all hubs. This affects all @@ -21,6 +24,8 @@ [support#220]: https://github.com/pybricks/support/issues/220 [support#2206]: https://github.com/pybricks/support/issues/2206 [pybricks-micropython#208]: https://github.com/pybricks/pybricks-micropython/pull/208 +[pybricks-micropython#264]: https://github.com/pybricks/pybricks-micropython/pull/264 +[pybricks-micropython#312]: https://github.com/pybricks/pybricks-micropython/pull/312 ## [3.6.1] - 2025-03-11 diff --git a/lib/pbio/drv/bluetooth/bluetooth_stm32_bluenrg.c b/lib/pbio/drv/bluetooth/bluetooth_stm32_bluenrg.c index c421b0013..068875f9b 100644 --- a/lib/pbio/drv/bluetooth/bluetooth_stm32_bluenrg.c +++ b/lib/pbio/drv/bluetooth/bluetooth_stm32_bluenrg.c @@ -1078,7 +1078,7 @@ static PT_THREAD(init_pybricks_service(struct pt *pt)) { PT_WAIT_WHILE(pt, write_xfer_size); { uint8_t buf[PBIO_PYBRICKS_HUB_CAPABILITIES_VALUE_SIZE]; - pbio_pybricks_hub_capabilities(buf, ATT_MTU - 3, PBSYS_CONFIG_APP_FEATURE_FLAGS, pbsys_storage_get_maximum_program_size()); + pbio_pybricks_hub_capabilities(buf, ATT_MTU - 3, PBSYS_CONFIG_APP_FEATURE_FLAGS, pbsys_storage_get_maximum_program_size(), 0); aci_gatt_update_char_value_begin(pybricks_service_handle, pybricks_hub_capabilities_char_handle, 0, PBIO_PYBRICKS_HUB_CAPABILITIES_VALUE_SIZE, buf); } diff --git a/lib/pbio/drv/bluetooth/bluetooth_stm32_cc2640.c b/lib/pbio/drv/bluetooth/bluetooth_stm32_cc2640.c index da702df4e..2c976c69e 100644 --- a/lib/pbio/drv/bluetooth/bluetooth_stm32_cc2640.c +++ b/lib/pbio/drv/bluetooth/bluetooth_stm32_cc2640.c @@ -1483,7 +1483,7 @@ static void handle_event(uint8_t *packet) { uint8_t buf[PBIO_PYBRICKS_HUB_CAPABILITIES_VALUE_SIZE]; // REVISIT: this assumes connection_handle == conn_handle - pbio_pybricks_hub_capabilities(buf, conn_mtu - 3, PBSYS_CONFIG_APP_FEATURE_FLAGS, pbsys_storage_get_maximum_program_size()); + pbio_pybricks_hub_capabilities(buf, conn_mtu - 3, PBSYS_CONFIG_APP_FEATURE_FLAGS, pbsys_storage_get_maximum_program_size(), 0); rsp.len = sizeof(buf); rsp.pValue = buf; ATT_ReadRsp(connection_handle, &rsp); diff --git a/lib/pbio/drv/bluetooth/pybricks_service_server.c b/lib/pbio/drv/bluetooth/pybricks_service_server.c index 57cd80ec3..c41b1fc18 100644 --- a/lib/pbio/drv/bluetooth/pybricks_service_server.c +++ b/lib/pbio/drv/bluetooth/pybricks_service_server.c @@ -89,7 +89,7 @@ static uint16_t pybricks_service_read_callback(hci_con_handle_t con_handle, uint if (attribute_handle == pybricks_hub_capabilities_value_handle) { if (buffer && buffer_size >= PBIO_PYBRICKS_HUB_CAPABILITIES_VALUE_SIZE) { pbio_pybricks_hub_capabilities(buffer, pbio_int_math_min(att_server_get_mtu(con_handle) - 3, 512), - PBSYS_CONFIG_APP_FEATURE_FLAGS, pbsys_storage_get_maximum_program_size()); + PBSYS_CONFIG_APP_FEATURE_FLAGS, pbsys_storage_get_maximum_program_size(), PBSYS_CONFIG_HMI_NUM_SLOTS); } return PBIO_PYBRICKS_HUB_CAPABILITIES_VALUE_SIZE; } diff --git a/lib/pbio/drv/usb/stm32_usbd/usbd_desc.c b/lib/pbio/drv/usb/stm32_usbd/usbd_desc.c index 8a5a3fb14..9d2d83794 100644 --- a/lib/pbio/drv/usb/stm32_usbd/usbd_desc.c +++ b/lib/pbio/drv/usb/stm32_usbd/usbd_desc.c @@ -536,7 +536,8 @@ void USBD_Pybricks_Desc_Init(void) { pbio_pybricks_hub_capabilities(ptr, USBD_PYBRICKS_MAX_PACKET_SIZE - 1, PBSYS_CONFIG_APP_FEATURE_FLAGS, - pbsys_storage_get_maximum_program_size()); + pbsys_storage_get_maximum_program_size(), + PBSYS_CONFIG_HMI_NUM_SLOTS); ptr += PBIO_PYBRICKS_HUB_CAPABILITIES_VALUE_SIZE; /* Update wTotalLength field in BOS Descriptor */ diff --git a/lib/pbio/include/pbio/protocol.h b/lib/pbio/include/pbio/protocol.h index 8610bdb54..ea2322977 100644 --- a/lib/pbio/include/pbio/protocol.h +++ b/lib/pbio/include/pbio/protocol.h @@ -24,7 +24,7 @@ #define PBIO_PROTOCOL_VERSION_MAJOR 1 /** The minor version number for the protocol. */ -#define PBIO_PROTOCOL_VERSION_MINOR 4 +#define PBIO_PROTOCOL_VERSION_MINOR 5 /** The patch version number for the protocol. */ #define PBIO_PROTOCOL_VERSION_PATCH 0 @@ -342,9 +342,9 @@ typedef enum { #define PBIO_PYBRICKS_STATUS_FLAG(status) (1 << status) /** Size of status report event message in bytes. */ -#define PBIO_PYBRICKS_EVENT_STATUS_REPORT_SIZE 6 +#define PBIO_PYBRICKS_EVENT_STATUS_REPORT_SIZE 7 -uint32_t pbio_pybricks_event_status_report(uint8_t *buf, uint32_t flags, pbio_pybricks_user_program_id_t program_id); +uint32_t pbio_pybricks_event_status_report(uint8_t *buf, uint32_t flags, pbio_pybricks_user_program_id_t program_id, uint8_t slot); /** * Application-specific feature flag supported by a hub. @@ -391,12 +391,13 @@ typedef enum { void pbio_pybricks_hub_capabilities(uint8_t *buf, uint16_t max_char_size, pbio_pybricks_feature_flags_t feature_flags, - uint32_t max_user_prog_size); + uint32_t max_user_prog_size, + uint8_t num_slots); /** * Number of bytes in the Pybricks hub capabilities characteristic value. */ -#define PBIO_PYBRICKS_HUB_CAPABILITIES_VALUE_SIZE 10 +#define PBIO_PYBRICKS_HUB_CAPABILITIES_VALUE_SIZE 11 extern const uint8_t pbio_pybricks_service_uuid[]; extern const uint8_t pbio_pybricks_command_event_char_uuid[]; diff --git a/lib/pbio/include/pbsys/status.h b/lib/pbio/include/pbsys/status.h index a3e8ddb19..e78c9443f 100644 --- a/lib/pbio/include/pbsys/status.h +++ b/lib/pbio/include/pbsys/status.h @@ -14,7 +14,7 @@ #include -#define PBSYS_STATUS_REPORT_SIZE 6 +#define PBSYS_STATUS_REPORT_SIZE 7 /** * Status flag change. diff --git a/lib/pbio/platform/prime_hub/pbsysconfig.h b/lib/pbio/platform/prime_hub/pbsysconfig.h index b5bfc7082..d05b40e25 100644 --- a/lib/pbio/platform/prime_hub/pbsysconfig.h +++ b/lib/pbio/platform/prime_hub/pbsysconfig.h @@ -10,7 +10,7 @@ #define PBSYS_CONFIG_BLUETOOTH (1) #define PBSYS_CONFIG_BLUETOOTH_TOGGLE (1) #define PBSYS_CONFIG_BLUETOOTH_TOGGLE_BUTTON (512) // PBIO_BUTTON_RIGHT_UP, but enum value cannot be used here. -#define PBSYS_CONFIG_HMI_NUM_SLOTS (0) +#define PBSYS_CONFIG_HMI_NUM_SLOTS (5) #define PBSYS_CONFIG_HUB_LIGHT_MATRIX (1) #define PBSYS_CONFIG_HOST (1) #define PBSYS_CONFIG_MAIN (1) diff --git a/lib/pbio/platform/test/pbsysconfig.h b/lib/pbio/platform/test/pbsysconfig.h index c30269868..b45d9dc86 100644 --- a/lib/pbio/platform/test/pbsysconfig.h +++ b/lib/pbio/platform/test/pbsysconfig.h @@ -8,6 +8,7 @@ #define PBSYS_CONFIG_FEATURE_PROGRAM_FORMAT_MULTI_MPY_V6_1_NATIVE (0) #define PBSYS_CONFIG_BLUETOOTH (1) #define PBSYS_CONFIG_HOST (1) +#define PBSYS_CONFIG_HMI_NUM_SLOTS (0) #define PBSYS_CONFIG_HUB_LIGHT_MATRIX (0) #define PBSYS_CONFIG_MAIN (0) #define PBSYS_CONFIG_STORAGE (0) diff --git a/lib/pbio/src/protocol/pybricks.c b/lib/pbio/src/protocol/pybricks.c index ddd3aa392..ccf201cd0 100644 --- a/lib/pbio/src/protocol/pybricks.c +++ b/lib/pbio/src/protocol/pybricks.c @@ -17,15 +17,22 @@ _Static_assert(NUM_PBIO_PYBRICKS_STATUS <= sizeof(uint32_t) * 8, * * The buffer must be at least ::PBIO_PYBRICKS_EVENT_STATUS_REPORT_SIZE bytes. * + * @since Pybricks Profile v1.0.0 + * + * Program ID parameter was added in Pybricks Profile v1.4.0. + * Slot parameter was added in Pybricks Profile v1.5.0. + * * @param [in] buf The buffer to hold the binary data. * @param [in] flags The status flags. - * @param [in] program_id Program identifier. + * @param [in] program_id Program identifier of currently running program. + * @param [in] slot The currently selected program slot. * @return The number of bytes written to @p buf. */ -uint32_t pbio_pybricks_event_status_report(uint8_t *buf, uint32_t flags, pbio_pybricks_user_program_id_t program_id) { +uint32_t pbio_pybricks_event_status_report(uint8_t *buf, uint32_t flags, pbio_pybricks_user_program_id_t program_id, uint8_t slot) { buf[0] = PBIO_PYBRICKS_EVENT_STATUS_REPORT; pbio_set_uint32_le(&buf[1], flags); buf[5] = program_id; + buf[6] = slot; return PBIO_PYBRICKS_EVENT_STATUS_REPORT_SIZE; } @@ -37,15 +44,22 @@ uint32_t pbio_pybricks_event_status_report(uint8_t *buf, uint32_t flags, pbio_py * @param [in] max_char_size The maximum characteristic value size (negotiated MTU - 3). * @param [in] feature_flags The feature flags. * @param [in] max_user_prog_size The maximum allowable size for the user program. + * @param [in] num_slots The number of program slots available on the hub. + * + * @since Pybricks Profile v1.2.0 + * + * num_slots was added in Pybricks Profile v1.5.0. */ void pbio_pybricks_hub_capabilities(uint8_t *buf, uint16_t max_char_size, pbio_pybricks_feature_flags_t feature_flags, - uint32_t max_user_prog_size) { + uint32_t max_user_prog_size, + uint8_t num_slots) { pbio_set_uint16_le(&buf[0], max_char_size); pbio_set_uint32_le(&buf[2], feature_flags); pbio_set_uint32_le(&buf[6], max_user_prog_size); + buf[10] = num_slots; } /** diff --git a/lib/pbio/sys/bluetooth.c b/lib/pbio/sys/bluetooth.c index 1848f41d9..d1599841c 100644 --- a/lib/pbio/sys/bluetooth.c +++ b/lib/pbio/sys/bluetooth.c @@ -22,6 +22,7 @@ #include #include +#include "hmi.h" #include "storage.h" // REVISIT: this can be the negotiated MTU - 3 to allow for better throughput @@ -254,6 +255,9 @@ static PT_THREAD(pbsys_bluetooth_monitor_status(struct pt *pt)) { static struct etimer timer; static uint32_t old_status_flags; static send_msg_t msg; + #if PBSYS_CONFIG_HMI_NUM_SLOTS + static uint8_t old_program_slot; + #endif PT_BEGIN(pt); @@ -267,7 +271,11 @@ static PT_THREAD(pbsys_bluetooth_monitor_status(struct pt *pt)) { for (;;) { // wait for status to change or timeout - PT_WAIT_UNTIL(pt, pbsys_status_get_flags() != old_status_flags || etimer_expired(&timer)); + PT_WAIT_UNTIL(pt, pbsys_status_get_flags() != old_status_flags || + #if PBSYS_CONFIG_HMI_NUM_SLOTS + pbsys_hmi_get_selected_program_slot() != old_program_slot || + #endif + etimer_expired(&timer)); etimer_restart(&timer); diff --git a/lib/pbio/sys/status.c b/lib/pbio/sys/status.c index 7c9ad5726..bffdb87df 100644 --- a/lib/pbio/sys/status.c +++ b/lib/pbio/sys/status.c @@ -59,9 +59,16 @@ static void pbsys_status_update_flag(pbio_pybricks_status_t status, bool set) { * @return The number of bytes written to @p buf. */ uint32_t pbsys_status_get_status_report(uint8_t *buf) { + #if PBSYS_CONFIG_HMI_NUM_SLOTS + uint8_t slot = pbsys_hmi_get_selected_program_slot(); + #else + uint8_t slot = 0; + #endif + _Static_assert(PBSYS_STATUS_REPORT_SIZE == PBIO_PYBRICKS_EVENT_STATUS_REPORT_SIZE, "size of status report does not match size of event"); - return pbio_pybricks_event_status_report(buf, pbsys_status.flags, pbsys_status.program_id); + + return pbio_pybricks_event_status_report(buf, pbsys_status.flags, pbsys_status.program_id, slot); } /**