summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorJim Mussared <jim.mussared@gmail.com>2020-11-10 12:55:24 +1100
committerDamien George <damien@micropython.org>2020-11-16 17:09:12 +1100
commit21c293fbcd1f9d5bafac300b5da265b4efd2be52 (patch)
treeee6bf53e777a634ffaff0a787e45352e44c3ef59
parent119c88ef17c390e43828b825c3df99ffc1dc39b9 (diff)
downloadmicropython-21c293fbcd1f9d5bafac300b5da265b4efd2be52.tar.gz
micropython-21c293fbcd1f9d5bafac300b5da265b4efd2be52.zip
stm32/rfcore: Don't send HCI ACL cmds while another is pending.
And, for TX, the next/prev entries ane unused so set them to NULL to indicate this. Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
-rw-r--r--ports/stm32/rfcore.c33
1 files changed, 27 insertions, 6 deletions
diff --git a/ports/stm32/rfcore.c b/ports/stm32/rfcore.c
index 6133720958..da77be6117 100644
--- a/ports/stm32/rfcore.c
+++ b/ports/stm32/rfcore.c
@@ -32,6 +32,7 @@
#include "py/mphal.h"
#include "py/runtime.h"
#include "extmod/modbluetooth.h"
+#include "nimble/nimble_npl.h"
#include "rtc.h"
#include "rfcore.h"
@@ -72,8 +73,9 @@
#define HCI_KIND_VENDOR_RESPONSE (0x11)
#define HCI_KIND_VENDOR_EVENT (0x12)
-#define HCI_EVENT_COMMAND_COMPLETE (0x0E) // <num packets><opcode 16><status><data...>
-#define HCI_EVENT_COMMAND_STATUS (0x0F) // <status><num_packets><opcode 16>
+#define HCI_EVENT_COMMAND_COMPLETE (0x0E) // <num packets><opcode 16><status><data...>
+#define HCI_EVENT_COMMAND_STATUS (0x0F) // <status><num_packets><opcode 16>
+#define HCI_EVENT_NUMBER_OF_COMPLETED_PACKETS (0x13) // <num>(<handle 16><completed 16>)*
#define SYS_ACK_TIMEOUT_MS (250)
#define BLE_ACK_TIMEOUT_MS (250)
@@ -83,6 +85,8 @@
// AN5289
#define MAGIC_IPCC_MEM_INCORRECT 0x3DE96F61
+volatile bool hci_acl_cmd_pending = false;
+
typedef struct _tl_list_node_t {
volatile struct _tl_list_node_t *next;
volatile struct _tl_list_node_t *prev;
@@ -305,6 +309,11 @@ STATIC size_t tl_parse_hci_msg(const uint8_t *buf, parse_hci_info_t *parse) {
case HCI_KIND_BT_EVENT: {
info = "HCI_EVT";
+ // Acknowledgment of a pending ACL request, allow another one to be sent.
+ if (buf[1] == HCI_EVENT_NUMBER_OF_COMPLETED_PACKETS) {
+ hci_acl_cmd_pending = false;
+ }
+
len = 3 + buf[2];
if (parse != NULL) {
@@ -424,8 +433,8 @@ STATIC void tl_check_msg(volatile tl_list_node_t *head, unsigned int ch, parse_h
STATIC void tl_hci_cmd(uint8_t *cmd, unsigned int ch, uint8_t hdr, uint16_t opcode, const uint8_t *buf, size_t len) {
tl_list_node_t *n = (tl_list_node_t *)cmd;
- n->next = n;
- n->prev = n;
+ n->next = NULL;
+ n->prev = NULL;
cmd[8] = hdr;
cmd[9] = opcode;
cmd[10] = opcode >> 8;
@@ -584,13 +593,25 @@ void rfcore_ble_hci_cmd(size_t len, const uint8_t *src) {
} else if (src[0] == HCI_KIND_BT_ACL) {
n = (tl_list_node_t *)&ipcc_membuf_ble_hci_acl_data_buf[0];
ch = IPCC_CH_HCI_ACL;
+
+ // Give the previous ACL command up to 100ms to complete.
+ mp_uint_t timeout_start_ticks_ms = mp_hal_ticks_ms();
+ while (hci_acl_cmd_pending) {
+ if (mp_hal_ticks_ms() - timeout_start_ticks_ms > 100) {
+ break;
+ }
+ mp_bluetooth_nimble_hci_uart_wfi();
+ }
+
+ // Prevent sending another command until this one returns with HCI_EVENT_COMMAND_{COMPLETE,STATUS}.
+ hci_acl_cmd_pending = true;
} else {
printf("** UNEXPECTED HCI HDR: 0x%02x **\n", src[0]);
return;
}
- n->next = n;
- n->prev = n;
+ n->next = NULL;
+ n->prev = NULL;
memcpy(n->body, src, len);
// IPCC indicate.