Merge pull request #2799 from dhalbert/ringbuf-fixes

Ringbuf: fix PacketBuffer; clean up ringbuf implementation and use
This commit is contained in:
Scott Shawcroft 2020-05-05 08:50:22 -07:00 committed by GitHub
commit f40db45009
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
41 changed files with 604 additions and 404 deletions

View File

@ -98,7 +98,7 @@ def build_module_map():
for module in modules:
full_name = module
search_name = module.lstrip("_")
re_pattern = "CIRCUITPY_{}\s=\s(.+)".format(search_name.upper())
re_pattern = "CIRCUITPY_{}\s*\??=\s*(.+)".format(search_name.upper())
find_config = re.findall(re_pattern, configs)
if not find_config:
continue

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-04-27 18:34-0700\n"
"POT-Creation-Date: 2020-05-04 19:52-0400\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -1096,6 +1096,10 @@ msgstr "Tidak ada pin TX"
msgid "No available clocks"
msgstr ""
#: shared-bindings/_bleio/PacketBuffer.c
msgid "No connection: length cannot be determined"
msgstr ""
#: shared-bindings/board/__init__.c
msgid "No default %q bus"
msgstr "Tidak ada standar bus %q"
@ -1445,6 +1449,10 @@ msgstr ""
msgid "Too many displays"
msgstr ""
#: ports/nrf/common-hal/_bleio/PacketBuffer.c
msgid "Total data to write is larger than outgoing_packet_length"
msgstr ""
#: py/obj.c
msgid "Traceback (most recent call last):\n"
msgstr ""

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-04-27 18:34-0700\n"
"POT-Creation-Date: 2020-05-04 20:38-0400\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -1085,6 +1085,10 @@ msgstr ""
msgid "No available clocks"
msgstr ""
#: shared-bindings/_bleio/PacketBuffer.c
msgid "No connection: length cannot be determined"
msgstr ""
#: shared-bindings/board/__init__.c
msgid "No default %q bus"
msgstr ""
@ -1429,6 +1433,10 @@ msgstr ""
msgid "Too many displays"
msgstr ""
#: ports/nrf/common-hal/_bleio/PacketBuffer.c
msgid "Total data to write is larger than outgoing_packet_length"
msgstr ""
#: py/obj.c
msgid "Traceback (most recent call last):\n"
msgstr ""

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-04-27 18:34-0700\n"
"POT-Creation-Date: 2020-05-04 19:52-0400\n"
"PO-Revision-Date: 2018-07-27 11:55-0700\n"
"Last-Translator: Pascal Deneaux\n"
"Language-Team: Sebastian Plamauer, Pascal Deneaux\n"
@ -1094,6 +1094,10 @@ msgstr "Kein TX Pin"
msgid "No available clocks"
msgstr "Keine Taktgeber verfügbar"
#: shared-bindings/_bleio/PacketBuffer.c
msgid "No connection: length cannot be determined"
msgstr ""
#: shared-bindings/board/__init__.c
msgid "No default %q bus"
msgstr "Kein Standard %q Bus"
@ -1448,6 +1452,10 @@ msgstr ""
msgid "Too many displays"
msgstr "Zu viele displays"
#: ports/nrf/common-hal/_bleio/PacketBuffer.c
msgid "Total data to write is larger than outgoing_packet_length"
msgstr ""
#: py/obj.c
msgid "Traceback (most recent call last):\n"
msgstr "Zurückverfolgung (jüngste Aufforderung zuletzt):\n"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-04-27 18:34-0700\n"
"POT-Creation-Date: 2020-05-04 19:52-0400\n"
"PO-Revision-Date: 2018-07-27 11:55-0700\n"
"Last-Translator: \n"
"Language-Team: \n"
@ -1085,6 +1085,10 @@ msgstr ""
msgid "No available clocks"
msgstr ""
#: shared-bindings/_bleio/PacketBuffer.c
msgid "No connection: length cannot be determined"
msgstr ""
#: shared-bindings/board/__init__.c
msgid "No default %q bus"
msgstr ""
@ -1429,6 +1433,10 @@ msgstr ""
msgid "Too many displays"
msgstr ""
#: ports/nrf/common-hal/_bleio/PacketBuffer.c
msgid "Total data to write is larger than outgoing_packet_length"
msgstr ""
#: py/obj.c
msgid "Traceback (most recent call last):\n"
msgstr ""

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-04-27 18:34-0700\n"
"POT-Creation-Date: 2020-05-04 19:52-0400\n"
"PO-Revision-Date: 2018-07-27 11:55-0700\n"
"Last-Translator: \n"
"Language-Team: @sommersoft, @MrCertainly\n"
@ -1089,6 +1089,10 @@ msgstr ""
msgid "No available clocks"
msgstr ""
#: shared-bindings/_bleio/PacketBuffer.c
msgid "No connection: length cannot be determined"
msgstr ""
#: shared-bindings/board/__init__.c
msgid "No default %q bus"
msgstr ""
@ -1433,6 +1437,10 @@ msgstr ""
msgid "Too many displays"
msgstr ""
#: ports/nrf/common-hal/_bleio/PacketBuffer.c
msgid "Total data to write is larger than outgoing_packet_length"
msgstr ""
#: py/obj.c
msgid "Traceback (most recent call last):\n"
msgstr ""

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-04-27 18:34-0700\n"
"POT-Creation-Date: 2020-05-04 19:52-0400\n"
"PO-Revision-Date: 2018-08-24 22:56-0500\n"
"Last-Translator: \n"
"Language-Team: \n"
@ -1093,6 +1093,10 @@ msgstr "Sin pin TX"
msgid "No available clocks"
msgstr "Relojes no disponibles"
#: shared-bindings/_bleio/PacketBuffer.c
msgid "No connection: length cannot be determined"
msgstr ""
#: shared-bindings/board/__init__.c
msgid "No default %q bus"
msgstr "Sin bus %q por defecto"
@ -1446,6 +1450,10 @@ msgstr "Demasiados buses de pantalla"
msgid "Too many displays"
msgstr "Muchos displays"
#: ports/nrf/common-hal/_bleio/PacketBuffer.c
msgid "Total data to write is larger than outgoing_packet_length"
msgstr ""
#: py/obj.c
msgid "Traceback (most recent call last):\n"
msgstr "Traceback (ultima llamada reciente):\n"

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-04-27 18:34-0700\n"
"POT-Creation-Date: 2020-05-04 19:52-0400\n"
"PO-Revision-Date: 2018-12-20 22:15-0800\n"
"Last-Translator: Timothy <me@timothygarcia.ca>\n"
"Language-Team: fil\n"
@ -1101,6 +1101,10 @@ msgstr "Walang TX pin"
msgid "No available clocks"
msgstr ""
#: shared-bindings/_bleio/PacketBuffer.c
msgid "No connection: length cannot be determined"
msgstr ""
#: shared-bindings/board/__init__.c
msgid "No default %q bus"
msgstr "Walang default na %q bus"
@ -1452,6 +1456,10 @@ msgstr ""
msgid "Too many displays"
msgstr ""
#: ports/nrf/common-hal/_bleio/PacketBuffer.c
msgid "Total data to write is larger than outgoing_packet_length"
msgstr ""
#: py/obj.c
msgid "Traceback (most recent call last):\n"
msgstr "Traceback (pinakahuling huling tawag): \n"

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: 0.1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-04-27 18:34-0700\n"
"POT-Creation-Date: 2020-05-04 19:52-0400\n"
"PO-Revision-Date: 2019-04-14 20:05+0100\n"
"Last-Translator: Pierrick Couturier <arofarn@arofarn.info>\n"
"Language-Team: fr\n"
@ -1108,6 +1108,10 @@ msgstr "Pas de broche TX"
msgid "No available clocks"
msgstr "Pas d'horloge disponible"
#: shared-bindings/_bleio/PacketBuffer.c
msgid "No connection: length cannot be determined"
msgstr ""
#: shared-bindings/board/__init__.c
msgid "No default %q bus"
msgstr "Pas de bus %q par défaut"
@ -1467,6 +1471,10 @@ msgstr "Trop de bus d'affichage"
msgid "Too many displays"
msgstr "Trop d'affichages"
#: ports/nrf/common-hal/_bleio/PacketBuffer.c
msgid "Total data to write is larger than outgoing_packet_length"
msgstr ""
#: py/obj.c
msgid "Traceback (most recent call last):\n"
msgstr "Trace (appels les plus récents en dernier):\n"

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-04-27 18:34-0700\n"
"POT-Creation-Date: 2020-05-04 19:52-0400\n"
"PO-Revision-Date: 2018-10-02 16:27+0200\n"
"Last-Translator: Enrico Paganin <enrico.paganin@mail.com>\n"
"Language-Team: \n"
@ -1105,6 +1105,10 @@ msgstr "Nessun pin TX"
msgid "No available clocks"
msgstr "Nessun orologio a disposizione"
#: shared-bindings/_bleio/PacketBuffer.c
msgid "No connection: length cannot be determined"
msgstr ""
#: shared-bindings/board/__init__.c
msgid "No default %q bus"
msgstr "Nessun bus %q predefinito"
@ -1463,6 +1467,10 @@ msgstr ""
msgid "Too many displays"
msgstr "Troppi schermi"
#: ports/nrf/common-hal/_bleio/PacketBuffer.c
msgid "Total data to write is larger than outgoing_packet_length"
msgstr ""
#: py/obj.c
msgid "Traceback (most recent call last):\n"
msgstr "Traceback (chiamata più recente per ultima):\n"

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-04-27 18:34-0700\n"
"POT-Creation-Date: 2020-05-04 19:52-0400\n"
"PO-Revision-Date: 2019-05-06 14:22-0700\n"
"Last-Translator: \n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -1089,6 +1089,10 @@ msgstr ""
msgid "No available clocks"
msgstr ""
#: shared-bindings/_bleio/PacketBuffer.c
msgid "No connection: length cannot be determined"
msgstr ""
#: shared-bindings/board/__init__.c
msgid "No default %q bus"
msgstr ""
@ -1433,6 +1437,10 @@ msgstr ""
msgid "Too many displays"
msgstr ""
#: ports/nrf/common-hal/_bleio/PacketBuffer.c
msgid "Total data to write is larger than outgoing_packet_length"
msgstr ""
#: py/obj.c
msgid "Traceback (most recent call last):\n"
msgstr ""

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-04-27 18:34-0700\n"
"POT-Creation-Date: 2020-05-04 19:52-0400\n"
"PO-Revision-Date: 2019-03-19 18:37-0700\n"
"Last-Translator: Radomir Dopieralski <circuitpython@sheep.art.pl>\n"
"Language-Team: pl\n"
@ -1090,6 +1090,10 @@ msgstr "Brak nóżki TX"
msgid "No available clocks"
msgstr "Brak wolnych zegarów"
#: shared-bindings/_bleio/PacketBuffer.c
msgid "No connection: length cannot be determined"
msgstr ""
#: shared-bindings/board/__init__.c
msgid "No default %q bus"
msgstr "Nie ma domyślnej magistrali %q"
@ -1434,6 +1438,10 @@ msgstr "Zbyt wiele magistrali"
msgid "Too many displays"
msgstr "Zbyt wiele wyświetlaczy"
#: ports/nrf/common-hal/_bleio/PacketBuffer.c
msgid "Total data to write is larger than outgoing_packet_length"
msgstr ""
#: py/obj.c
msgid "Traceback (most recent call last):\n"
msgstr "Ślad wyjątku (najnowsze wywołanie na końcu):\n"

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-04-27 18:34-0700\n"
"POT-Creation-Date: 2020-05-04 19:52-0400\n"
"PO-Revision-Date: 2018-10-02 21:14-0000\n"
"Last-Translator: \n"
"Language-Team: \n"
@ -1097,6 +1097,10 @@ msgstr "Nenhum pino TX"
msgid "No available clocks"
msgstr ""
#: shared-bindings/_bleio/PacketBuffer.c
msgid "No connection: length cannot be determined"
msgstr ""
#: shared-bindings/board/__init__.c
msgid "No default %q bus"
msgstr "Nenhum barramento %q padrão"
@ -1446,6 +1450,10 @@ msgstr ""
msgid "Too many displays"
msgstr ""
#: ports/nrf/common-hal/_bleio/PacketBuffer.c
msgid "Total data to write is larger than outgoing_packet_length"
msgstr ""
#: py/obj.c
msgid "Traceback (most recent call last):\n"
msgstr ""

View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-04-27 18:34-0700\n"
"POT-Creation-Date: 2020-05-04 20:38-0400\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -1085,6 +1085,10 @@ msgstr ""
msgid "No available clocks"
msgstr ""
#: shared-bindings/_bleio/PacketBuffer.c
msgid "No connection: length cannot be determined"
msgstr ""
#: shared-bindings/board/__init__.c
msgid "No default %q bus"
msgstr ""
@ -1429,6 +1433,10 @@ msgstr ""
msgid "Too many displays"
msgstr ""
#: ports/nrf/common-hal/_bleio/PacketBuffer.c
msgid "Total data to write is larger than outgoing_packet_length"
msgstr ""
#: py/obj.c
msgid "Traceback (most recent call last):\n"
msgstr ""

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: circuitpython-cn\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-04-27 18:34-0700\n"
"POT-Creation-Date: 2020-05-04 19:52-0400\n"
"PO-Revision-Date: 2019-04-13 10:10-0700\n"
"Last-Translator: hexthat\n"
"Language-Team: Chinese Hanyu Pinyin\n"
@ -1098,6 +1098,10 @@ msgstr "Wèi zhǎodào TX yǐn jiǎo"
msgid "No available clocks"
msgstr "Méiyǒu kěyòng de shízhōng"
#: shared-bindings/_bleio/PacketBuffer.c
msgid "No connection: length cannot be determined"
msgstr ""
#: shared-bindings/board/__init__.c
msgid "No default %q bus"
msgstr "wú mòrèn %q zǒngxiàn"
@ -1455,6 +1459,10 @@ msgstr "Xiǎnshì zǒngxiàn tài duōle"
msgid "Too many displays"
msgstr "Xiǎnshì tài duō"
#: ports/nrf/common-hal/_bleio/PacketBuffer.c
msgid "Total data to write is larger than outgoing_packet_length"
msgstr ""
#: py/obj.c
msgid "Traceback (most recent call last):\n"
msgstr "Traceback (Zuìjìn yīcì dǎ diànhuà):\n"

View File

@ -198,15 +198,18 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
claim_pin(self->tx_pin->pin);
if (self->rx_pin != NULL) {
ringbuf_alloc(&self->rbuf, receiver_buffer_size, true);
// The LPUART ring buffer wastes one byte to distinguish between full and empty.
self->ringbuf = gc_alloc(receiver_buffer_size + 1, false, true /*long-lived*/);
if (!self->rbuf.buf) {
if (!self->ringbuf) {
LPUART_Deinit(self->uart);
mp_raise_msg(&mp_type_MemoryError, translate("Failed to allocate RX buffer"));
}
LPUART_TransferCreateHandle(self->uart, &self->handle, LPUART_UserCallback, self);
LPUART_TransferStartRingBuffer(self->uart, &self->handle, self->rbuf.buf, self->rbuf.size);
// Pass actual allocated size; the LPUART routines are cognizant that
// the capacity is one less than the size.
LPUART_TransferStartRingBuffer(self->uart, &self->handle, self->ringbuf, receiver_buffer_size + 1);
claim_pin(self->rx_pin->pin);
}
@ -223,9 +226,7 @@ void common_hal_busio_uart_deinit(busio_uart_obj_t *self) {
LPUART_Deinit(self->uart);
gc_free(self->rbuf.buf);
self->rbuf.size = 0;
self->rbuf.iput = self->rbuf.iget = 0;
gc_free(self->ringbuf);
// reset_pin_number(self->rx_pin);
// reset_pin_number(self->tx_pin);

View File

@ -40,7 +40,7 @@ typedef struct {
mp_obj_base_t base;
LPUART_Type *uart;
lpuart_handle_t handle;
ringbuf_t rbuf;
uint8_t* ringbuf;
bool rx_ongoing;
uint32_t baudrate;
uint8_t character_bits;

View File

@ -11,7 +11,6 @@ EXTERNAL_FLASH_DEVICES = "GD25Q16C"
# Allocate two, not just one I2C peripheral for CPB, so that we have both
# on-board and off-board I2C available.
# When SPIM3 becomes available we'll be able to have two I2C and two SPI peripherals.
# We use a CFLAGS define here because there are include order issues
# if we try to include "mpconfigport.h" into nrfx_config.h .
CFLAGS += -DCIRCUITPY_NRF_NUM_I2C=2

View File

@ -127,6 +127,7 @@ size_t common_hal_bleio_characteristic_get_value(bleio_characteristic_obj_t *sel
// self->value is set by evt handler.
return common_hal_bleio_gattc_read(self->handle, conn_handle, buf, len);
} else {
// conn_handle is ignored for non-system attributes.
return common_hal_bleio_gatts_read(self->handle, conn_handle, buf, len);
}
}
@ -152,6 +153,7 @@ void common_hal_bleio_characteristic_set_value(bleio_characteristic_obj_t *self,
(self->props & CHAR_PROP_WRITE_NO_RESPONSE));
} else {
// Always write the value locally even if no connections are active.
// conn_handle is ignored for non-system attributes, so we use BLE_CONN_HANDLE_INVALID.
common_hal_bleio_gatts_write(self->handle, BLE_CONN_HANDLE_INVALID, bufinfo);
// Check to see if we need to notify or indicate any active connections.
for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {

View File

@ -40,13 +40,11 @@
#include "supervisor/shared/tick.h"
#include "common-hal/_bleio/CharacteristicBuffer.h"
// Push all the data onto the ring buffer. When the buffer is full, new bytes will be dropped.
STATIC void write_to_ringbuf(bleio_characteristic_buffer_obj_t *self, uint8_t *data, uint16_t len) {
// Push all the data onto the ring buffer.
uint8_t is_nested_critical_region;
sd_nvic_critical_region_enter(&is_nested_critical_region);
for (size_t i = 0; i < len; i++) {
ringbuf_put(&self->ringbuf, data[i]);
}
ringbuf_put_n(&self->ringbuf, data, len);
sd_nvic_critical_region_exit(is_nested_critical_region);
}
@ -98,11 +96,11 @@ void common_hal_bleio_characteristic_buffer_construct(bleio_characteristic_buffe
}
int common_hal_bleio_characteristic_buffer_read(bleio_characteristic_buffer_obj_t *self, uint8_t *data, size_t len, int *errcode) {
uint32_t common_hal_bleio_characteristic_buffer_read(bleio_characteristic_buffer_obj_t *self, uint8_t *data, size_t len, int *errcode) {
uint64_t start_ticks = supervisor_ticks_ms64();
// Wait for all bytes received or timeout
while ( (ringbuf_count(&self->ringbuf) < len) && (supervisor_ticks_ms64() - start_ticks < self->timeout_ms) ) {
while ( (ringbuf_num_filled(&self->ringbuf) < len) && (supervisor_ticks_ms64() - start_ticks < self->timeout_ms) ) {
RUN_BACKGROUND_TASKS;
// Allow user to break out of a timeout with a KeyboardInterrupt.
if ( mp_hal_is_interrupted() ) {
@ -114,21 +112,18 @@ int common_hal_bleio_characteristic_buffer_read(bleio_characteristic_buffer_obj_
uint8_t is_nested_critical_region;
sd_nvic_critical_region_enter(&is_nested_critical_region);
size_t rx_bytes = MIN(ringbuf_count(&self->ringbuf), len);
for ( size_t i = 0; i < rx_bytes; i++ ) {
data[i] = ringbuf_get(&self->ringbuf);
}
uint32_t num_bytes_read = ringbuf_get_n(&self->ringbuf, data, len);
// Writes now OK.
sd_nvic_critical_region_exit(is_nested_critical_region);
return rx_bytes;
return num_bytes_read;
}
uint32_t common_hal_bleio_characteristic_buffer_rx_characters_available(bleio_characteristic_buffer_obj_t *self) {
uint8_t is_nested_critical_region;
sd_nvic_critical_region_enter(&is_nested_critical_region);
uint16_t count = ringbuf_count(&self->ringbuf);
uint16_t count = ringbuf_num_filled(&self->ringbuf);
sd_nvic_critical_region_exit(is_nested_critical_region);
return count;
}

View File

@ -371,6 +371,11 @@ mp_float_t common_hal_bleio_connection_get_connection_interval(bleio_connection_
return 1.25f * self->conn_params.min_conn_interval;
}
// Return the current negotiated MTU length, minus overhead.
mp_int_t common_hal_bleio_connection_get_max_packet_length(bleio_connection_internal_t *self) {
return (self->mtu == 0 ? BLE_GATT_ATT_MTU_DEFAULT : self->mtu) - 3;
}
void common_hal_bleio_connection_set_connection_interval(bleio_connection_internal_t *self, mp_float_t new_interval) {
self->conn_params_updating = true;
uint16_t interval = new_interval / 1.25f;
@ -752,3 +757,16 @@ mp_obj_t bleio_connection_new_from_internal(bleio_connection_internal_t* interna
return MP_OBJ_FROM_PTR(connection);
}
// Find the connection that uses the given conn_handle. Return NULL if not found.
bleio_connection_internal_t *bleio_conn_handle_to_connection(uint16_t conn_handle) {
bleio_connection_internal_t *connection;
for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
connection = &bleio_connections[i];
if (connection->conn_handle == conn_handle) {
return connection;
}
}
return NULL;
}

View File

@ -87,5 +87,6 @@ bool connection_on_ble_evt(ble_evt_t *ble_evt, void *self_in);
uint16_t bleio_connection_get_conn_handle(bleio_connection_obj_t *self);
mp_obj_t bleio_connection_new_from_internal(bleio_connection_internal_t* connection);
bleio_connection_internal_t *bleio_conn_handle_to_connection(uint16_t conn_handle);
#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_CONNECTION_H

View File

@ -41,7 +41,7 @@
#include "supervisor/shared/tick.h"
STATIC void write_to_ringbuf(bleio_packet_buffer_obj_t *self, uint8_t *data, uint16_t len) {
if (len + sizeof(uint16_t) > self->ringbuf.size) {
if (len + sizeof(uint16_t) > ringbuf_capacity(&self->ringbuf)) {
// This shouldn't happen.
return;
}
@ -49,7 +49,7 @@ STATIC void write_to_ringbuf(bleio_packet_buffer_obj_t *self, uint8_t *data, uin
uint8_t is_nested_critical_region;
sd_nvic_critical_region_enter(&is_nested_critical_region);
// Make room for the new value by dropping the oldest packets first.
while (self->ringbuf.size - ringbuf_count(&self->ringbuf) < (int) (len + sizeof(uint16_t))) {
while (ringbuf_capacity(&self->ringbuf) - ringbuf_num_filled(&self->ringbuf) < len + sizeof(uint16_t)) {
uint16_t packet_length;
ringbuf_get_n(&self->ringbuf, (uint8_t*) &packet_length, sizeof(uint16_t));
for (uint16_t i = 0; i < packet_length; i++) {
@ -105,12 +105,18 @@ STATIC uint32_t queue_next_write(bleio_packet_buffer_obj_t *self) {
}
STATIC bool packet_buffer_on_ble_client_evt(ble_evt_t *ble_evt, void *param) {
bleio_packet_buffer_obj_t *self = (bleio_packet_buffer_obj_t *) param;
const uint16_t evt_id = ble_evt->header.evt_id;
// Check if this is a GATTC event so we can make sure the conn_handle is valid.
if (evt_id < BLE_GATTC_EVT_BASE || evt_id > BLE_GATTC_EVT_LAST) {
return false;
}
uint16_t conn_handle = ble_evt->evt.gattc_evt.conn_handle;
bleio_packet_buffer_obj_t *self = (bleio_packet_buffer_obj_t *) param;
if (conn_handle != self->conn_handle) {
return false;
}
switch (ble_evt->header.evt_id) {
switch (evt_id) {
case BLE_GATTC_EVT_HVX: {
// A remote service wrote to this characteristic.
ble_gattc_evt_hvx_t* evt_hvx = &ble_evt->evt.gattc_evt.params.hvx;
@ -140,9 +146,9 @@ STATIC bool packet_buffer_on_ble_client_evt(ble_evt_t *ble_evt, void *param) {
STATIC bool packet_buffer_on_ble_server_evt(ble_evt_t *ble_evt, void *param) {
bleio_packet_buffer_obj_t *self = (bleio_packet_buffer_obj_t *) param;
uint16_t conn_handle = ble_evt->evt.gatts_evt.conn_handle;
switch (ble_evt->header.evt_id) {
case BLE_GATTS_EVT_WRITE: {
uint16_t conn_handle = ble_evt->evt.gatts_evt.conn_handle;
// A client wrote to this server characteristic.
ble_gatts_evt_write_t *evt_write = &ble_evt->evt.gatts_evt.params.write;
@ -166,7 +172,7 @@ STATIC bool packet_buffer_on_ble_server_evt(ble_evt_t *ble_evt, void *param) {
break;
}
case BLE_GAP_EVT_DISCONNECTED: {
if (self->conn_handle == conn_handle) {
if (self->conn_handle == ble_evt->evt.gap_evt.conn_handle) {
self->conn_handle = BLE_CONN_HANDLE_INVALID;
}
}
@ -200,10 +206,7 @@ void common_hal_bleio_packet_buffer_construct(
}
if (incoming) {
// This is a macro.
ringbuf_alloc(&self->ringbuf, buffer_size * (sizeof(uint16_t) + characteristic->max_length), false);
if (self->ringbuf.buf == NULL) {
if (!ringbuf_alloc(&self->ringbuf, buffer_size * (sizeof(uint16_t) + characteristic->max_length), false)) {
mp_raise_ValueError(translate("Buffer too large and unable to allocate"));
}
}
@ -247,45 +250,66 @@ void common_hal_bleio_packet_buffer_construct(
}
}
int common_hal_bleio_packet_buffer_readinto(bleio_packet_buffer_obj_t *self, uint8_t *data, size_t len) {
if (ringbuf_count(&self->ringbuf) < 2) {
mp_int_t common_hal_bleio_packet_buffer_readinto(bleio_packet_buffer_obj_t *self, uint8_t *data, size_t len) {
if (ringbuf_num_filled(&self->ringbuf) < 2) {
return 0;
}
uint16_t packet_length;
ringbuf_get_n(&self->ringbuf, (uint8_t*) &packet_length, sizeof(uint16_t));
// Copy received data. Lock out write interrupt handler while copying.
uint8_t is_nested_critical_region;
sd_nvic_critical_region_enter(&is_nested_critical_region);
if (packet_length > len) {
return len - packet_length;
}
// Get packet length, which is in first two bytes of packet.
uint16_t packet_length;
ringbuf_get_n(&self->ringbuf, (uint8_t*) &packet_length, sizeof(uint16_t));
ringbuf_get_n(&self->ringbuf, data, packet_length);
mp_int_t ret;
if (packet_length > len) {
// Packet is longer than requested. Return negative of overrun value.
ret = len - packet_length;
// Discard the packet if it's too large. Don't fill data.
while (packet_length--) {
(void) ringbuf_get(&self->ringbuf);
}
} else {
// Read as much as possible, but might be shorter than len.
ringbuf_get_n(&self->ringbuf, data, packet_length);
ret = packet_length;
}
// Writes now OK.
sd_nvic_critical_region_exit(is_nested_critical_region);
return packet_length;
return ret;
}
void common_hal_bleio_packet_buffer_write(bleio_packet_buffer_obj_t *self, uint8_t *data, size_t len, uint8_t* header, size_t header_len) {
mp_int_t common_hal_bleio_packet_buffer_write(bleio_packet_buffer_obj_t *self, uint8_t *data, size_t len, uint8_t* header, size_t header_len) {
if (self->outgoing[0] == NULL) {
mp_raise_bleio_BluetoothError(translate("Writes not supported on Characteristic"));
}
if (self->conn_handle == BLE_CONN_HANDLE_INVALID) {
return;
return -1;
}
uint16_t packet_size = common_hal_bleio_packet_buffer_get_packet_size(self);
uint16_t max_size = packet_size - len;
while (max_size < self->pending_size && self->conn_handle != BLE_CONN_HANDLE_INVALID) {
RUN_BACKGROUND_TASKS;
uint16_t outgoing_packet_length = common_hal_bleio_packet_buffer_get_outgoing_packet_length(self);
if (len + header_len > outgoing_packet_length) {
// Supplied data will not fit in a single BLE packet.
mp_raise_ValueError(translate("Total data to write is larger than outgoing_packet_length"));
}
if (len + self->pending_size > outgoing_packet_length) {
// No room to append len bytes to packet. Wait until we get a free buffer,
// and keep checking that we haven't been disconnected.
while (self->pending_size != 0 && self->conn_handle != BLE_CONN_HANDLE_INVALID) {
RUN_BACKGROUND_TASKS;
}
}
if (self->conn_handle == BLE_CONN_HANDLE_INVALID) {
return;
return -1;
}
size_t num_bytes_written = 0;
uint8_t is_nested_critical_region;
sd_nvic_critical_region_enter(&is_nested_critical_region);
@ -294,9 +318,11 @@ void common_hal_bleio_packet_buffer_write(bleio_packet_buffer_obj_t *self, uint8
if (self->pending_size == 0) {
memcpy(pending, header, header_len);
self->pending_size += header_len;
num_bytes_written += header_len;
}
memcpy(pending + self->pending_size, data, len);
self->pending_size += len;
num_bytes_written += len;
sd_nvic_critical_region_exit(is_nested_critical_region);
@ -304,28 +330,69 @@ void common_hal_bleio_packet_buffer_write(bleio_packet_buffer_obj_t *self, uint8
if (!self->packet_queued) {
queue_next_write(self);
}
return num_bytes_written;
}
uint16_t common_hal_bleio_packet_buffer_get_packet_size(bleio_packet_buffer_obj_t *self) {
uint16_t mtu;
if (self->conn_handle == BLE_CONN_HANDLE_INVALID) {
return 0;
mp_int_t common_hal_bleio_packet_buffer_get_incoming_packet_length(bleio_packet_buffer_obj_t *self) {
// If this PacketBuffer is coming from a remote service via NOTIFY or INDICATE
// the maximum size is what can be sent in one
// BLE packet. But we must be connected to know that value.
//
// Otherwise it can be as long as the characteristic
// will permit, whether or not we're connected.
if (self->characteristic == NULL) {
return -1;
}
bleio_connection_internal_t *connection;
for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
connection = &bleio_connections[i];
if (connection->conn_handle == self->conn_handle) {
break;
if (self->characteristic->service != NULL &&
self->characteristic->service->is_remote &&
(common_hal_bleio_characteristic_get_properties(self->characteristic) &
(CHAR_PROP_INDICATE | CHAR_PROP_NOTIFY))) {
// We are talking to a remote service, and data is arriving via NOTIFY or INDICATE.
if (self->conn_handle != BLE_CONN_HANDLE_INVALID) {
bleio_connection_internal_t *connection = bleio_conn_handle_to_connection(self->conn_handle);
if (connection) {
return MIN(common_hal_bleio_connection_get_max_packet_length(connection),
self->characteristic->max_length);
}
}
// There's no current connection, so we don't know the MTU, and
// we can't tell what the largest incoming packet length would be.
return -1;
}
if (connection->mtu == 0) {
mtu = BLE_GATT_ATT_MTU_DEFAULT;
return self->characteristic->max_length;
}
mp_int_t common_hal_bleio_packet_buffer_get_outgoing_packet_length(bleio_packet_buffer_obj_t *self) {
// If we are sending data via NOTIFY or INDICATE, the maximum size
// is what can be sent in one BLE packet. But we must be connected
// to know that value.
//
// Otherwise it can be as long as the characteristic
// will permit, whether or not we're connected.
if (self->characteristic == NULL) {
return -1;
}
if (self->characteristic->max_length > mtu) {
mtu = self->characteristic->max_length;
if (self->characteristic->service != NULL &&
!self->characteristic->service->is_remote &&
(common_hal_bleio_characteristic_get_properties(self->characteristic) &
(CHAR_PROP_INDICATE | CHAR_PROP_NOTIFY))) {
// We are sending to a client, via NOTIFY or INDICATE.
if (self->conn_handle != BLE_CONN_HANDLE_INVALID) {
bleio_connection_internal_t *connection = bleio_conn_handle_to_connection(self->conn_handle);
if (connection) {
return MIN(common_hal_bleio_connection_get_max_packet_length(connection),
self->characteristic->max_length);
}
}
// There's no current connection, so we don't know the MTU, and
// we can't tell what the largest outgoing packet length would be.
return -1;
}
uint16_t att_overhead = 3;
return mtu - att_overhead;
return self->characteristic->max_length;
}
bool common_hal_bleio_packet_buffer_deinited(bleio_packet_buffer_obj_t *self) {

View File

@ -40,8 +40,10 @@ typedef struct {
// Two outgoing buffers to alternate between. One will be queued for transmission by the SD and
// the other is waiting to be queued and can be extended.
uint8_t* outgoing[2];
uint16_t pending_size;
uint16_t conn_handle;
volatile uint16_t pending_size;
// We remember the conn_handle so we can do a NOTIFY/INDICATE to a client.
// We can find out the conn_handle on a Characteristic write or a CCCD write (but not a read).
volatile uint16_t conn_handle;
uint8_t pending_index;
uint8_t write_type;
bool client;

View File

@ -39,6 +39,8 @@ typedef struct bleio_service_obj {
bool is_remote;
bool is_secondary;
bleio_uuid_obj_t *uuid;
// The connection object is set only when this is a remote service.
// A local service doesn't know the connection.
mp_obj_t connection;
mp_obj_list_t *characteristic_list;
// Range of attribute handles of this remote service.

View File

@ -118,8 +118,8 @@ void common_hal_bleio_check_connected(uint16_t conn_handle) {
// GATTS read of a Characteristic or Descriptor.
size_t common_hal_bleio_gatts_read(uint16_t handle, uint16_t conn_handle, uint8_t* buf, size_t len) {
// conn_handle might be BLE_CONN_HANDLE_INVALID if we're not connected, but that's OK, because
// we can still read and write the local value.
// conn_handle is ignored unless this is a system attribute.
// If we're not connected, that's OK, because we can still read and write the local value.
ble_gatts_value_t gatts_value = {
.p_value = buf,
@ -132,8 +132,8 @@ size_t common_hal_bleio_gatts_read(uint16_t handle, uint16_t conn_handle, uint8_
}
void common_hal_bleio_gatts_write(uint16_t handle, uint16_t conn_handle, mp_buffer_info_t *bufinfo) {
// conn_handle might be BLE_CONN_HANDLE_INVALID if we're not connected, but that's OK, because
// we can still read and write the local value.
// conn_handle is ignored unless this is a system attribute.
// If we're not connected, that's OK, because we can still read and write the local value.
ble_gatts_value_t gatts_value = {
.p_value = bufinfo->buf,

View File

@ -98,7 +98,7 @@ static void uart_callback_irq (const nrfx_uarte_event_t * event, void * context)
switch ( event->type ) {
case NRFX_UARTE_EVT_RX_DONE:
ringbuf_put_n(&self->rbuf, event->data.rxtx.p_data, event->data.rxtx.bytes);
ringbuf_put_n(&self->ringbuf, event->data.rxtx.p_data, event->data.rxtx.bytes);
// keep receiving
(void) nrfx_uarte_rx(self->uarte, &self->rx_char, 1);
@ -112,7 +112,7 @@ static void uart_callback_irq (const nrfx_uarte_event_t * event, void * context)
// Possible Error source is Overrun, Parity, Framing, Break
// uint32_t errsrc = event->data.error.error_mask;
ringbuf_put_n(&self->rbuf, event->data.error.rxtx.p_data, event->data.error.rxtx.bytes);
ringbuf_put_n(&self->ringbuf, event->data.error.rxtx.p_data, event->data.error.rxtx.bytes);
// Keep receiving
(void) nrfx_uarte_rx(self->uarte, &self->rx_char, 1);
@ -190,9 +190,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
// pointers like this are NOT moved, allocating the buffer
// in the long-lived pool is not strictly necessary)
// (This is a macro.)
ringbuf_alloc(&self->rbuf, receiver_buffer_size, true);
if ( !self->rbuf.buf ) {
if (!ringbuf_alloc(&self->ringbuf, receiver_buffer_size, true)) {
nrfx_uarte_uninit(self->uarte);
mp_raise_msg(&mp_type_MemoryError, translate("Failed to allocate RX buffer"));
}
@ -226,10 +224,7 @@ void common_hal_busio_uart_deinit(busio_uart_obj_t *self) {
reset_pin_number(self->rx_pin_number);
self->tx_pin_number = NO_PIN;
self->rx_pin_number = NO_PIN;
gc_free(self->rbuf.buf);
self->rbuf.size = 0;
self->rbuf.iput = self->rbuf.iget = 0;
ringbuf_free(&self->ringbuf);
}
}
@ -239,11 +234,10 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t
mp_raise_ValueError(translate("No RX pin"));
}
size_t rx_bytes = 0;
uint64_t start_ticks = supervisor_ticks_ms64();
// Wait for all bytes received or timeout
while ( (ringbuf_count(&self->rbuf) < len) && (supervisor_ticks_ms64() - start_ticks < self->timeout_ms) ) {
while ( (ringbuf_num_filled(&self->ringbuf) < len) && (supervisor_ticks_ms64() - start_ticks < self->timeout_ms) ) {
RUN_BACKGROUND_TASKS;
// Allow user to break out of a timeout with a KeyboardInterrupt.
if ( mp_hal_is_interrupted() ) {
@ -254,12 +248,8 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t
// prevent conflict with uart irq
NVIC_DisableIRQ(nrfx_get_irq_number(self->uarte->p_reg));
// copy received data
rx_bytes = ringbuf_count(&self->rbuf);
rx_bytes = MIN(rx_bytes, len);
for ( uint16_t i = 0; i < rx_bytes; i++ ) {
data[i] = ringbuf_get(&self->rbuf);
}
// Copy as much received data as available, up to len bytes.
size_t rx_bytes = ringbuf_get_n(&self->ringbuf, data, len);
NVIC_EnableIRQ(nrfx_get_irq_number(self->uarte->p_reg));
@ -316,13 +306,13 @@ void common_hal_busio_uart_set_timeout(busio_uart_obj_t *self, mp_float_t timeou
}
uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self) {
return ringbuf_count(&self->rbuf);
return ringbuf_num_filled(&self->ringbuf);
}
void common_hal_busio_uart_clear_rx_buffer(busio_uart_obj_t *self) {
// prevent conflict with uart irq
NVIC_DisableIRQ(nrfx_get_irq_number(self->uarte->p_reg));
ringbuf_clear(&self->rbuf);
ringbuf_clear(&self->ringbuf);
NVIC_EnableIRQ(nrfx_get_irq_number(self->uarte->p_reg));
}

View File

@ -41,7 +41,7 @@ typedef struct {
uint32_t baudrate;
uint32_t timeout_ms;
ringbuf_t rbuf;
ringbuf_t ringbuf;
uint8_t rx_char; // EasyDMA buf
uint8_t tx_pin_number;

View File

@ -14,39 +14,21 @@ USB_SERIAL_NUMBER_LENGTH = 16
# All nRF ports have longints.
LONGINT_IMPL = MPZ
# The ?='s allow overriding in mpconfigboard.mk.
# Audio via PWM
ifndef CIRCUITPY_AUDIOCORE
CIRCUITPY_AUDIOCORE = 1
endif
CIRCUITPY_AUDIOIO = 0
CIRCUITPY_AUDIOBUSIO ?= 1
CIRCUITPY_AUDIOCORE ?= 1
CIRCUITPY_AUDIOMIXER ?= 1
CIRCUITPY_AUDIOPWMIO ?= 1
# The ifndef's allow overriding in mpconfigboard.mk.
ifndef
CIRCUITPY_BLEIO = 1
endif
ifndef CIRCUITPY_AUDIOMIXER
CIRCUITPY_AUDIOMIXER = 1
endif
ifndef CIRCUITPY_AUDIOPWMIO
CIRCUITPY_AUDIOPWMIO = 1
endif
ifndef CIRCUITPY_AUDIOBUSIO
CIRCUITPY_AUDIOBUSIO = 1
endif
CIRCUITPY_BLEIO ?= 1
# No I2CSlave implementation
CIRCUITPY_I2CSLAVE = 0
# enable RTC
ifndef CIRCUITPY_RTC
CIRCUITPY_RTC = 1
endif
CIRCUITPY_RTC ?= 1
# frequencyio not yet implemented
CIRCUITPY_FREQUENCYIO = 0
@ -72,8 +54,6 @@ NRF_DEFINES += -DNRF52840_XXAA -DNRF52840
# Defined here because system_nrf52840.c doesn't #include any of our own include files.
CFLAGS += -DCONFIG_NFCT_PINS_AS_GPIOS
CIRCUITPY_ULAB = 1
else
ifeq ($(MCU_CHIP),nrf52833)
MCU_SERIES = m4

View File

@ -209,8 +209,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
// Init buffer for rx and claim pins
if (self->rx != NULL) {
ringbuf_alloc(&self->rbuf, receiver_buffer_size, true);
if (!self->rbuf.buf) {
if (!ringbuf_alloc(&self->ringbuf, receiver_buffer_size, true)) {
mp_raise_ValueError(translate("UART Buffer allocation error"));
}
claim_pin(rx);
@ -246,9 +245,7 @@ void common_hal_busio_uart_deinit(busio_uart_obj_t *self) {
reset_pin_number(self->rx->pin->port,self->rx->pin->number);
self->tx = NULL;
self->rx = NULL;
gc_free(self->rbuf.buf);
self->rbuf.size = 0;
self->rbuf.iput = self->rbuf.iget = 0;
ringbuf_free(&self->ringbuf);
}
size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t len, int *errcode) {
@ -256,11 +253,10 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t
mp_raise_ValueError(translate("No RX pin"));
}
size_t rx_bytes = 0;
uint64_t start_ticks = supervisor_ticks_ms64();
// Wait for all bytes received or timeout, same as nrf
while ( (ringbuf_count(&self->rbuf) < len) && (supervisor_ticks_ms64() - start_ticks < self->timeout_ms) ) {
while ( (ringbuf_num_filled(&self->ringbuf) < len) && (supervisor_ticks_ms64() - start_ticks < self->timeout_ms) ) {
RUN_BACKGROUND_TASKS;
//restart if it failed in the callback
if (errflag != HAL_OK) {
@ -274,12 +270,8 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t
// Halt reception
HAL_NVIC_DisableIRQ(self->irq);
// copy received data
rx_bytes = ringbuf_count(&self->rbuf);
rx_bytes = MIN(rx_bytes, len);
for (uint16_t i = 0; i < rx_bytes; i++) {
data[i] = ringbuf_get(&self->rbuf);
}
// Copy as much received data as available, up to len bytes.
size_t rx_bytes = ringbuf_get_n(&self->ringbuf, data, len);
HAL_NVIC_EnableIRQ(self->irq);
if (rx_bytes == 0) {
@ -319,7 +311,7 @@ void HAL_UART_RxCpltCallback(UART_HandleTypeDef *handle)
if ((HAL_UART_GetState(handle) & HAL_UART_STATE_BUSY_RX) == HAL_UART_STATE_BUSY_RX) {
return;
}
ringbuf_put_n(&context->rbuf, &context->rx_char, 1);
ringbuf_put_n(&context->ringbuf, &context->rx_char, 1);
errflag = HAL_UART_Receive_IT(handle, &context->rx_char, 1);
return;
@ -378,13 +370,13 @@ void common_hal_busio_uart_set_timeout(busio_uart_obj_t *self, mp_float_t timeou
}
uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self) {
return ringbuf_count(&self->rbuf);
return ringbuf_num_filled(&self->ringbuf);
}
void common_hal_busio_uart_clear_rx_buffer(busio_uart_obj_t *self) {
// Halt reception
HAL_NVIC_DisableIRQ(self->irq);
ringbuf_clear(&self->rbuf);
ringbuf_clear(&self->ringbuf);
HAL_NVIC_EnableIRQ(self->irq);
}

View File

@ -47,7 +47,7 @@ typedef struct {
const mcu_periph_obj_t *tx;
const mcu_periph_obj_t *rx;
ringbuf_t rbuf;
ringbuf_t ringbuf;
uint8_t rx_char;
uint32_t baudrate;

View File

@ -27,37 +27,25 @@
# Manually disable by overriding in #mpconfigboard.mk
# Smaller builds can be forced for resource constrained chips (typically SAMD21s
# without external flash) by setting CIRCUITPY_FULL_BUILD=0. Avoid using this
# without external flash) by setting CIRCUITPY_FULL_BUILD=0. Avoid using this
# for merely incomplete ports, as it changes settings in other files.
ifndef CIRCUITPY_FULL_BUILD
CIRCUITPY_FULL_BUILD = 1
endif
CIRCUITPY_FULL_BUILD ?= 1
CFLAGS += -DCIRCUITPY_FULL_BUILD=$(CIRCUITPY_FULL_BUILD)
ifndef CIRCUITPY_ANALOGIO
CIRCUITPY_ANALOGIO = 1
endif
CIRCUITPY_ANALOGIO ?= 1
CFLAGS += -DCIRCUITPY_ANALOGIO=$(CIRCUITPY_ANALOGIO)
ifndef CIRCUITPY_AUDIOBUSIO
CIRCUITPY_AUDIOBUSIO = $(CIRCUITPY_FULL_BUILD)
endif
CIRCUITPY_AUDIOBUSIO ?= $(CIRCUITPY_FULL_BUILD)
CFLAGS += -DCIRCUITPY_AUDIOBUSIO=$(CIRCUITPY_AUDIOBUSIO)
ifndef CIRCUITPY_AUDIOIO
CIRCUITPY_AUDIOIO = $(CIRCUITPY_FULL_BUILD)
endif
CIRCUITPY_AUDIOIO ?= $(CIRCUITPY_FULL_BUILD)
CFLAGS += -DCIRCUITPY_AUDIOIO=$(CIRCUITPY_AUDIOIO)
ifndef CIRCUITPY_AUDIOIO_COMPAT
CIRCUITPY_AUDIOIO_COMPAT = $(CIRCUITPY_AUDIOIO)
endif
CIRCUITPY_AUDIOIO_COMPAT ?= $(CIRCUITPY_AUDIOIO)
CFLAGS += -DCIRCUITPY_AUDIOIO_COMPAT=$(CIRCUITPY_AUDIOIO_COMPAT)
ifndef CIRCUITPY_AUDIOPWMIO
CIRCUITPY_AUDIOPWMIO = 0
endif
CIRCUITPY_AUDIOPWMIO ?= 0
CFLAGS += -DCIRCUITPY_AUDIOPWMIO=$(CIRCUITPY_AUDIOPWMIO)
ifndef CIRCUITPY_AUDIOCORE
@ -69,9 +57,7 @@ endif
endif
CFLAGS += -DCIRCUITPY_AUDIOCORE=$(CIRCUITPY_AUDIOCORE)
ifndef CIRCUITPY_AUDIOMIXER
CIRCUITPY_AUDIOMIXER = $(CIRCUITPY_AUDIOIO)
endif
CIRCUITPY_AUDIOMIXER ?= $(CIRCUITPY_AUDIOIO)
CFLAGS += -DCIRCUITPY_AUDIOMIXER=$(CIRCUITPY_AUDIOMIXER)
ifndef CIRCUITPY_AUDIOMP3
@ -83,246 +69,156 @@ endif
endif
CFLAGS += -DCIRCUITPY_AUDIOMP3=$(CIRCUITPY_AUDIOMP3)
ifndef CIRCUITPY_BITBANGIO
CIRCUITPY_BITBANGIO = $(CIRCUITPY_FULL_BUILD)
endif
CIRCUITPY_BITBANGIO ?= $(CIRCUITPY_FULL_BUILD)
CFLAGS += -DCIRCUITPY_BITBANGIO=$(CIRCUITPY_BITBANGIO)
# Explicitly enabled for boards that support _bleio.
ifndef CIRCUITPY_BLEIO
CIRCUITPY_BLEIO = 0
endif
CIRCUITPY_BLEIO ?= 0
CFLAGS += -DCIRCUITPY_BLEIO=$(CIRCUITPY_BLEIO)
ifndef CIRCUITPY_BOARD
CIRCUITPY_BOARD = 1
endif
CIRCUITPY_BOARD ?= 1
CFLAGS += -DCIRCUITPY_BOARD=$(CIRCUITPY_BOARD)
ifndef CIRCUITPY_BUSIO
CIRCUITPY_BUSIO = 1
endif
CIRCUITPY_BUSIO ?= 1
CFLAGS += -DCIRCUITPY_BUSIO=$(CIRCUITPY_BUSIO)
ifndef CIRCUITPY_DIGITALIO
CIRCUITPY_DIGITALIO = 1
endif
CIRCUITPY_DIGITALIO ?= 1
CFLAGS += -DCIRCUITPY_DIGITALIO=$(CIRCUITPY_DIGITALIO)
ifndef CIRCUITPY_DISPLAYIO
CIRCUITPY_DISPLAYIO = $(CIRCUITPY_FULL_BUILD)
endif
CIRCUITPY_DISPLAYIO ?= $(CIRCUITPY_FULL_BUILD)
CFLAGS += -DCIRCUITPY_DISPLAYIO=$(CIRCUITPY_DISPLAYIO)
ifndef CIRCUITPY_FRAMEBUFFERIO
CIRCUITPY_FRAMEBUFFERIO = 0
endif
CIRCUITPY_FRAMEBUFFERIO ?= 0
CFLAGS += -DCIRCUITPY_FRAMEBUFFERIO=$(CIRCUITPY_FRAMEBUFFERIO)
ifndef CIRCUITPY_FREQUENCYIO
CIRCUITPY_FREQUENCYIO = $(CIRCUITPY_FULL_BUILD)
endif
CIRCUITPY_FREQUENCYIO ?= $(CIRCUITPY_FULL_BUILD)
CFLAGS += -DCIRCUITPY_FREQUENCYIO=$(CIRCUITPY_FREQUENCYIO)
ifndef CIRCUITPY_GAMEPAD
CIRCUITPY_GAMEPAD = $(CIRCUITPY_FULL_BUILD)
endif
CIRCUITPY_GAMEPAD ?= $(CIRCUITPY_FULL_BUILD)
CFLAGS += -DCIRCUITPY_GAMEPAD=$(CIRCUITPY_GAMEPAD)
ifndef CIRCUITPY_GAMEPADSHIFT
CIRCUITPY_GAMEPADSHIFT = 0
endif
CIRCUITPY_GAMEPADSHIFT ?= 0
CFLAGS += -DCIRCUITPY_GAMEPADSHIFT=$(CIRCUITPY_GAMEPADSHIFT)
ifndef CIRCUITPY_I2CSLAVE
CIRCUITPY_I2CSLAVE = $(CIRCUITPY_FULL_BUILD)
endif
CIRCUITPY_I2CSLAVE ?= $(CIRCUITPY_FULL_BUILD)
CFLAGS += -DCIRCUITPY_I2CSLAVE=$(CIRCUITPY_I2CSLAVE)
ifndef CIRCUITPY_MATH
CIRCUITPY_MATH = 1
endif
CIRCUITPY_MATH ?= 1
CFLAGS += -DCIRCUITPY_MATH=$(CIRCUITPY_MATH)
ifndef CIRCUITPY__EVE
CIRCUITPY__EVE = 0
endif
CIRCUITPY__EVE ?= 0
CFLAGS += -DCIRCUITPY__EVE=$(CIRCUITPY__EVE)
ifndef CIRCUITPY_MICROCONTROLLER
CIRCUITPY_MICROCONTROLLER = 1
endif
CIRCUITPY_MICROCONTROLLER ?= 1
CFLAGS += -DCIRCUITPY_MICROCONTROLLER=$(CIRCUITPY_MICROCONTROLLER)
ifndef CIRCUITPY_NEOPIXEL_WRITE
CIRCUITPY_NEOPIXEL_WRITE = 1
endif
CIRCUITPY_NEOPIXEL_WRITE ?= 1
CFLAGS += -DCIRCUITPY_NEOPIXEL_WRITE=$(CIRCUITPY_NEOPIXEL_WRITE)
# Enabled on SAMD51. Won't fit on SAMD21 builds. Not tested on nRF or STM32F4 builds.
ifndef CIRCUITPY_NETWORK
CIRCUITPY_NETWORK = 0
endif
CIRCUITPY_NETWORK ?= 0
CFLAGS += -DCIRCUITPY_NETWORK=$(CIRCUITPY_NETWORK)
ifndef CIRCUITPY_NVM
CIRCUITPY_NVM = 1
endif
CIRCUITPY_NVM ?= 1
CFLAGS += -DCIRCUITPY_NVM=$(CIRCUITPY_NVM)
ifndef CIRCUITPY_OS
CIRCUITPY_OS = 1
endif
CIRCUITPY_OS ?= 1
CFLAGS += -DCIRCUITPY_OS=$(CIRCUITPY_OS)
ifndef CIRCUITPY_PIXELBUF
CIRCUITPY_PIXELBUF = $(CIRCUITPY_FULL_BUILD)
endif
CIRCUITPY_PIXELBUF ?= $(CIRCUITPY_FULL_BUILD)
CFLAGS += -DCIRCUITPY_PIXELBUF=$(CIRCUITPY_PIXELBUF)
# Only for SAMD boards for the moment
ifndef CIRCUITPY_RGBMATRIX
CIRCUITPY_RGBMATRIX = 0
endif
CIRCUITPY_RGBMATRIX ?= 0
CFLAGS += -DCIRCUITPY_RGBMATRIX=$(CIRCUITPY_RGBMATRIX)
ifndef CIRCUITPY_PULSEIO
CIRCUITPY_PULSEIO = 1
endif
CIRCUITPY_PULSEIO ?= 1
CFLAGS += -DCIRCUITPY_PULSEIO=$(CIRCUITPY_PULSEIO)
# Only for SAMD boards for the moment
ifndef CIRCUITPY_PS2IO
CIRCUITPY_PS2IO = 0
endif
CIRCUITPY_PS2IO ?= 0
CFLAGS += -DCIRCUITPY_PS2IO=$(CIRCUITPY_PS2IO)
ifndef CIRCUITPY_RANDOM
CIRCUITPY_RANDOM = 1
endif
CIRCUITPY_RANDOM ?= 1
CFLAGS += -DCIRCUITPY_RANDOM=$(CIRCUITPY_RANDOM)
ifndef CIRCUITPY_ROTARYIO
CIRCUITPY_ROTARYIO = 1
endif
CIRCUITPY_ROTARYIO ?= 1
CFLAGS += -DCIRCUITPY_ROTARYIO=$(CIRCUITPY_ROTARYIO)
ifndef CIRCUITPY_RTC
CIRCUITPY_RTC = 1
endif
CIRCUITPY_RTC ?= 1
CFLAGS += -DCIRCUITPY_RTC=$(CIRCUITPY_RTC)
# CIRCUITPY_SAMD is handled in the atmel-samd tree.
# Only for SAMD chips.
# Assume not a SAMD build.
ifndef CIRCUITPY_SAMD
CIRCUITPY_SAMD = 0
endif
CIRCUITPY_SAMD ?= 0
CFLAGS += -DCIRCUITPY_SAMD=$(CIRCUITPY_SAMD)
# Currently always off.
ifndef CIRCUITPY_STAGE
CIRCUITPY_STAGE = 0
endif
CIRCUITPY_STAGE ?= 0
CFLAGS += -DCIRCUITPY_STAGE=$(CIRCUITPY_STAGE)
ifndef CIRCUITPY_STORAGE
CIRCUITPY_STORAGE = 1
endif
CIRCUITPY_STORAGE ?= 1
CFLAGS += -DCIRCUITPY_STORAGE=$(CIRCUITPY_STORAGE)
ifndef CIRCUITPY_STRUCT
CIRCUITPY_STRUCT = 1
endif
CIRCUITPY_STRUCT ?= 1
CFLAGS += -DCIRCUITPY_STRUCT=$(CIRCUITPY_STRUCT)
ifndef CIRCUITPY_SUPERVISOR
CIRCUITPY_SUPERVISOR = 1
endif
CIRCUITPY_SUPERVISOR ?= 1
CFLAGS += -DCIRCUITPY_SUPERVISOR=$(CIRCUITPY_SUPERVISOR)
ifndef CIRCUITPY_TIME
CIRCUITPY_TIME = 1
endif
CIRCUITPY_TIME ?= 1
CFLAGS += -DCIRCUITPY_TIME=$(CIRCUITPY_TIME)
# touchio might be native or generic. See circuitpy_defns.mk.
ifndef CIRCUITPY_TOUCHIO_USE_NATIVE
CIRCUITPY_TOUCHIO_USE_NATIVE = 0
endif
CIRCUITPY_TOUCHIO_USE_NATIVE ?= 0
CFLAGS += -DCIRCUITPY_TOUCHIO_USE_NATIVE=$(CIRCUITPY_TOUCHIO_USE_NATIVE)
ifndef CIRCUITPY_TOUCHIO
CIRCUITPY_TOUCHIO = 1
endif
CIRCUITPY_TOUCHIO ?= 1
CFLAGS += -DCIRCUITPY_TOUCHIO=$(CIRCUITPY_TOUCHIO)
# For debugging.
ifndef CIRCUITPY_UHEAP
CIRCUITPY_UHEAP = 0
endif
CIRCUITPY_UHEAP ?= 0
CFLAGS += -DCIRCUITPY_UHEAP=$(CIRCUITPY_UHEAP)
ifndef CIRCUITPY_USB_HID
CIRCUITPY_USB_HID = 1
endif
CIRCUITPY_USB_HID ?= 1
CFLAGS += -DCIRCUITPY_USB_HID=$(CIRCUITPY_USB_HID)
ifndef CIRCUITPY_USB_MIDI
CIRCUITPY_USB_MIDI = 1
endif
CIRCUITPY_USB_MIDI ?= 1
CFLAGS += -DCIRCUITPY_USB_MIDI=$(CIRCUITPY_USB_MIDI)
ifndef CIRCUITPY_PEW
CIRCUITPY_PEW = 0
endif
CIRCUITPY_PEW ?= 0
CFLAGS += -DCIRCUITPY_PEW=$(CIRCUITPY_PEW)
# For debugging.
ifndef CIRCUITPY_USTACK
CIRCUITPY_USTACK = 0
endif
CIRCUITPY_USTACK ?= 0
CFLAGS += -DCIRCUITPY_USTACK=$(CIRCUITPY_USTACK)
# Non-module conditionals
ifndef CIRCUITPY_BITBANG_APA102
CIRCUITPY_BITBANG_APA102 = 0
endif
CIRCUITPY_BITBANG_APA102 ?= 0
CFLAGS += -DCIRCUITPY_BITBANG_APA102=$(CIRCUITPY_BITBANG_APA102)
# Should busio.I2C() check for pullups?
# Some boards in combination with certain peripherals may not want this.
ifndef CIRCUITPY_REQUIRE_I2C_PULLUPS
CIRCUITPY_REQUIRE_I2C_PULLUPS = 1
endif
CIRCUITPY_REQUIRE_I2C_PULLUPS ?= 1
CFLAGS += -DCIRCUITPY_REQUIRE_I2C_PULLUPS=$(CIRCUITPY_REQUIRE_I2C_PULLUPS)
# REPL over BLE
ifndef CIRCUITPY_SERIAL_BLE
CIRCUITPY_SERIAL_BLE = 0
endif
CIRCUITPY_SERIAL_BLE ?= 0
CFLAGS += -DCIRCUITPY_SERIAL_BLE=$(CIRCUITPY_SERIAL_BLE)
ifndef CIRCUITPY_BLE_FILE_SERVICE
CIRCUITPY_BLE_FILE_SERVICE = 0
endif
CIRCUITPY_BLE_FILE_SERVICE ?= 0
CFLAGS += -DCIRCUITPY_BLE_FILE_SERVICE=$(CIRCUITPY_BLE_FILE_SERVICE)
# REPL over UART
ifndef CIRCUITPY_SERIAL_UART
CIRCUITPY_SERIAL_UART = 0
endif
CIRCUITPY_SERIAL_UART ?= 0
CFLAGS += -DCIRCUITPY_SERIAL_UART=$(CIRCUITPY_SERIAL_UART)
# ulab numerics library
ifndef CIRCUITPY_ULAB
CIRCUITPY_ULAB = $(CIRCUITPY_FULL_BUILD)
endif
CIRCUITPY_ULAB ?= $(CIRCUITPY_FULL_BUILD)
CFLAGS += -DCIRCUITPY_ULAB=$(CIRCUITPY_ULAB)
# Enabled micropython.native decorator (experimental)
ifndef CIRCUITPY_ENABLE_MPY_NATIVE
CIRCUITPY_ENABLE_MPY_NATIVE = 0
endif
CIRCUITPY_ENABLE_MPY_NATIVE ?= 0
CFLAGS += -DCIRCUITPY_ENABLE_MPY_NATIVE=$(CIRCUITPY_ENABLE_MPY_NATIVE)

View File

@ -258,6 +258,7 @@ PY_CORE_O_BASENAME = $(addprefix py/,\
repl.o \
smallint.o \
frozenmod.o \
ringbuf.o \
)
PY_EXTMOD_O_BASENAME = \

115
py/ringbuf.c Normal file
View File

@ -0,0 +1,115 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2016 Paul Sokolovsky
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "ringbuf.h"
// Dynamic initialization. This should be accessible from a root pointer.
// capacity is the number of bytes the ring buffer can hold. The actual
// size of the buffer is one greater than that, due to how the buffer
// handles empty and full statuses.
bool ringbuf_alloc(ringbuf_t *r, size_t capacity, bool long_lived) {
r->buf = gc_alloc(capacity + 1, false, long_lived);
r->size = capacity + 1;
r->iget = r->iput = 0;
return r->buf != NULL;
}
void ringbuf_free(ringbuf_t *r) {
gc_free(r->buf);
r->size = 0;
ringbuf_clear(r);
}
size_t ringbuf_capacity(ringbuf_t *r) {
return r->size - 1;
}
// Returns -1 if buffer is empty, else returns byte fetched.
int ringbuf_get(ringbuf_t *r) {
if (r->iget == r->iput) {
return -1;
}
uint8_t v = r->buf[r->iget++];
if (r->iget >= r->size) {
r->iget = 0;
}
return v;
}
// Returns -1 if no room in buffer, else returns 0.
int ringbuf_put(ringbuf_t *r, uint8_t v) {
uint32_t iput_new = r->iput + 1;
if (iput_new >= r->size) {
iput_new = 0;
}
if (iput_new == r->iget) {
return -1;
}
r->buf[r->iput] = v;
r->iput = iput_new;
return 0;
}
void ringbuf_clear(ringbuf_t *r) {
r->iput = r->iget = 0;
}
// Number of free slots that can be written.
size_t ringbuf_num_empty(ringbuf_t *r) {
return (r->size + r->iget - r->iput - 1) % r->size;
}
// Number of bytes available to read.
size_t ringbuf_num_filled(ringbuf_t *r) {
return (r->size + r->iput - r->iget) % r->size;
}
// If the ring buffer fills up, not all bytes will be written.
// Returns how many bytes were successfully written.
size_t ringbuf_put_n(ringbuf_t* r, uint8_t* buf, size_t bufsize)
{
for(size_t i=0; i < bufsize; i++) {
if ( ringbuf_put(r, buf[i]) < 0 ) {
// If ringbuf is full, give up and return how many bytes
// we wrote so far.
return i;
}
}
return bufsize;
}
// Returns how many bytes were fetched.
size_t ringbuf_get_n(ringbuf_t* r, uint8_t* buf, size_t bufsize)
{
for(size_t i=0; i < bufsize; i++) {
int b = ringbuf_get(r);
if (b < 0) {
return i;
}
buf[i] = b;
}
return bufsize;
}

View File

@ -32,78 +32,27 @@
typedef struct _ringbuf_t {
uint8_t *buf;
uint16_t size;
uint16_t iget;
uint16_t iput;
// Allocated size; capacity is one less. Don't reference this directly.
uint32_t size;
uint32_t iget;
uint32_t iput;
} ringbuf_t;
// Note that the capacity of the buffer is N-1!
// Static initialization:
// byte buf_array[N];
// ringbuf_t buf = {buf_array, sizeof(buf_array)};
// Dynamic initialization. This creates root pointer!
#define ringbuf_alloc(r, sz, long_lived) \
{ \
(r)->buf = gc_alloc(sz, false, long_lived); \
(r)->size = sz; \
(r)->iget = (r)->iput = 0; \
}
bool ringbuf_alloc(ringbuf_t *r, size_t capacity, bool long_lived);
void ringbuf_free(ringbuf_t *r);
size_t ringbuf_capacity(ringbuf_t *r);
int ringbuf_get(ringbuf_t *r);
int ringbuf_put(ringbuf_t *r, uint8_t v);
void ringbuf_clear(ringbuf_t *r);
size_t ringbuf_num_empty(ringbuf_t *r);
size_t ringbuf_num_filled(ringbuf_t *r);
size_t ringbuf_put_n(ringbuf_t* r, uint8_t* buf, size_t bufsize);
size_t ringbuf_get_n(ringbuf_t* r, uint8_t* buf, size_t bufsize);
static inline int ringbuf_get(ringbuf_t *r) {
if (r->iget == r->iput) {
return -1;
}
uint8_t v = r->buf[r->iget++];
if (r->iget >= r->size) {
r->iget = 0;
}
return v;
}
static inline int ringbuf_put(ringbuf_t *r, uint8_t v) {
uint32_t iput_new = r->iput + 1;
if (iput_new >= r->size) {
iput_new = 0;
}
if (iput_new == r->iget) {
return -1;
}
r->buf[r->iput] = v;
r->iput = iput_new;
return 0;
}
static inline uint16_t ringbuf_count(ringbuf_t *r)
{
volatile int count = r->iput - r->iget;
if ( count < 0 ) {
count += r->size;
}
return (uint16_t) count;
}
static inline void ringbuf_clear(ringbuf_t *r)
{
r->iput = r->iget = 0;
}
// will overwrite old data
static inline void ringbuf_put_n(ringbuf_t* r, uint8_t* buf, uint8_t bufsize)
{
for(uint8_t i=0; i < bufsize; i++) {
if ( ringbuf_put(r, buf[i]) < 0 ) {
// if full overwrite old data
(void) ringbuf_get(r);
ringbuf_put(r, buf[i]);
}
}
}
static inline void ringbuf_get_n(ringbuf_t* r, uint8_t* buf, uint8_t bufsize)
{
for(uint8_t i=0; i < bufsize; i++) {
buf[i] = ringbuf_get(r);
}
}
#endif // MICROPY_INCLUDED_PY_RINGBUF_H

View File

@ -32,7 +32,7 @@
extern const mp_obj_type_t bleio_characteristic_buffer_type;
extern void common_hal_bleio_characteristic_buffer_construct(bleio_characteristic_buffer_obj_t *self, bleio_characteristic_obj_t *characteristic, mp_float_t timeout, size_t buffer_size);
int common_hal_bleio_characteristic_buffer_read(bleio_characteristic_buffer_obj_t *self, uint8_t *data, size_t len, int *errcode);
uint32_t common_hal_bleio_characteristic_buffer_read(bleio_characteristic_buffer_obj_t *self, uint8_t *data, size_t len, int *errcode);
uint32_t common_hal_bleio_characteristic_buffer_rx_characters_available(bleio_characteristic_buffer_obj_t *self);
void common_hal_bleio_characteristic_buffer_clear_rx_buffer(bleio_characteristic_buffer_obj_t *self);
bool common_hal_bleio_characteristic_buffer_deinited(bleio_characteristic_buffer_obj_t *self);

View File

@ -214,6 +214,25 @@ STATIC mp_obj_t bleio_connection_get_connection_interval(mp_obj_t self_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_connection_get_connection_interval_obj, bleio_connection_get_connection_interval);
//| .. attribute:: max_packet_length
//|
//| The maximum number of data bytes that can be sent in a single transmission,
//| not including overhead bytes.
//|
//| This is the maximum number of bytes that can be sent in a notification,
//| which must be sent in a single packet.
//| But for a regular characteristic read or write, may be sent in multiple packets,
//| so this limit does not apply.
//|
STATIC mp_obj_t bleio_connection_get_max_packet_length(mp_obj_t self_in) {
bleio_connection_obj_t *self = MP_OBJ_TO_PTR(self_in);
bleio_connection_ensure_connected(self);
return mp_obj_new_int(common_hal_bleio_connection_get_max_packet_length(self->connection));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_connection_get_max_packet_length_obj, bleio_connection_get_max_packet_length);
STATIC mp_obj_t bleio_connection_set_connection_interval(mp_obj_t self_in, mp_obj_t interval_in) {
bleio_connection_obj_t *self = MP_OBJ_TO_PTR(self_in);
@ -233,6 +252,13 @@ const mp_obj_property_t bleio_connection_connection_interval_obj = {
(mp_obj_t)&mp_const_none_obj },
};
const mp_obj_property_t bleio_connection_max_packet_length_obj = {
.base.type = &mp_type_property,
.proxy = { (mp_obj_t)&bleio_connection_get_max_packet_length_obj,
(mp_obj_t)&mp_const_none_obj,
(mp_obj_t)&mp_const_none_obj },
};
STATIC const mp_rom_map_elem_t bleio_connection_locals_dict_table[] = {
// Methods
{ MP_ROM_QSTR(MP_QSTR_pair), MP_ROM_PTR(&bleio_connection_pair_obj) },
@ -243,7 +269,7 @@ STATIC const mp_rom_map_elem_t bleio_connection_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_connected), MP_ROM_PTR(&bleio_connection_connected_obj) },
{ MP_ROM_QSTR(MP_QSTR_paired), MP_ROM_PTR(&bleio_connection_paired_obj) },
{ MP_ROM_QSTR(MP_QSTR_connection_interval), MP_ROM_PTR(&bleio_connection_connection_interval_obj) },
{ MP_ROM_QSTR(MP_QSTR_max_packet_length), MP_ROM_PTR(&bleio_connection_max_packet_length_obj) },
};
STATIC MP_DEFINE_CONST_DICT(bleio_connection_locals_dict, bleio_connection_locals_dict_table);

View File

@ -34,11 +34,12 @@
extern const mp_obj_type_t bleio_connection_type;
extern void common_hal_bleio_connection_pair(bleio_connection_internal_t *self, bool bond);
extern void common_hal_bleio_connection_disconnect(bleio_connection_internal_t *self);
extern bool common_hal_bleio_connection_get_connected(bleio_connection_obj_t *self);
extern bool common_hal_bleio_connection_get_paired(bleio_connection_obj_t *self);
extern mp_obj_tuple_t *common_hal_bleio_connection_discover_remote_services(bleio_connection_obj_t *self, mp_obj_t service_uuids_whitelist);
void common_hal_bleio_connection_pair(bleio_connection_internal_t *self, bool bond);
void common_hal_bleio_connection_disconnect(bleio_connection_internal_t *self);
bool common_hal_bleio_connection_get_connected(bleio_connection_obj_t *self);
mp_int_t common_hal_bleio_connection_get_max_packet_length(bleio_connection_internal_t *self);
bool common_hal_bleio_connection_get_paired(bleio_connection_obj_t *self);
mp_obj_tuple_t *common_hal_bleio_connection_discover_remote_services(bleio_connection_obj_t *self, mp_obj_t service_uuids_whitelist);
mp_float_t common_hal_bleio_connection_get_connection_interval(bleio_connection_internal_t *self);
void common_hal_bleio_connection_set_connection_interval(bleio_connection_internal_t *self, mp_float_t new_interval);

View File

@ -42,8 +42,8 @@
//|
//| Accumulates a Characteristic's incoming packets in a FIFO buffer and facilitates packet aware
//| outgoing writes. A packet's size is either the characteristic length or the maximum transmission
//| unit (MTU), whichever is smaller. The MTU can change so check `packet_size` before creating a
//| buffer to store data.
//| unit (MTU) minus overhead, whichever is smaller. The MTU can change so check `incoming_packet_length`
//| and `outgoing_packet_length` before creating a buffer to store data.
//|
//| When we're the server, we ignore all connections besides the first to subscribe to
//| notifications.
@ -51,7 +51,7 @@
//| .. class:: PacketBuffer(characteristic, *, buffer_size)
//|
//| Monitor the given Characteristic. Each time a new value is written to the Characteristic
//| add the newly-written bytes to a FIFO buffer.
//| add the newly-written packet of bytes to a FIFO buffer.
//|
//| :param Characteristic characteristic: The Characteristic to monitor.
//| It may be a local Characteristic provided by a Peripheral Service, or a remote Characteristic
@ -71,7 +71,7 @@ STATIC mp_obj_t bleio_packet_buffer_make_new(const mp_obj_type_t *type, size_t n
const mp_obj_t characteristic = args[ARG_characteristic].u_obj;
const int buffer_size = args[ARG_buffer_size].u_int;
const mp_int_t buffer_size = args[ARG_buffer_size].u_int;
if (buffer_size < 1) {
mp_raise_ValueError_varg(translate("%q must be >= 1"), MP_QSTR_buffer_size);
}
@ -109,7 +109,7 @@ STATIC mp_obj_t bleio_packet_buffer_readinto(mp_obj_t self_in, mp_obj_t buffer_o
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(buffer_obj, &bufinfo, MP_BUFFER_WRITE);
int size = common_hal_bleio_packet_buffer_readinto(self, bufinfo.buf, bufinfo.len);
mp_int_t size = common_hal_bleio_packet_buffer_readinto(self, bufinfo.buf, bufinfo.len);
if (size < 0) {
mp_raise_ValueError_varg(translate("Buffer too short by %d bytes"), size * -1);
}
@ -125,6 +125,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_packet_buffer_readinto_obj, bleio_packet_
//|
//| This does not block until the data is sent. It only blocks until the data is pending.
//|
//| :return: number of bytes written. May include header bytes when packet is empty.
//| :rtype: int
//|
// TODO: Add a kwarg `merge=False` to dictate whether subsequent writes are merged into a pending
// one.
STATIC mp_obj_t bleio_packet_buffer_write(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
@ -149,9 +152,21 @@ STATIC mp_obj_t bleio_packet_buffer_write(mp_uint_t n_args, const mp_obj_t *pos_
mp_get_buffer_raise(args[ARG_header].u_obj, &header_bufinfo, MP_BUFFER_READ);
}
common_hal_bleio_packet_buffer_write(self, data_bufinfo.buf, data_bufinfo.len,
header_bufinfo.buf, header_bufinfo.len);
return mp_const_none;
mp_int_t num_bytes_written = common_hal_bleio_packet_buffer_write(
self, data_bufinfo.buf, data_bufinfo.len, header_bufinfo.buf, header_bufinfo.len);
if (num_bytes_written < 0) {
// TODO: Raise an error if not connected. Right now the not-connected error
// is unreliable, because common_hal_bleio_packet_buffer_write()
// checks for conn_handle being set, but setting that
// can be delayed because conn_handle is discovered by spying on
// gatts write events, which may not have been sent yet.
//
// IDEAL:
// mp_raise_bleio_ConnectionError(translate("Not connected"));
// TEMPORARY:
num_bytes_written = 0;
}
return MP_OBJ_NEW_SMALL_INT(num_bytes_written);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_packet_buffer_write_obj, 1, bleio_packet_buffer_write);
@ -168,31 +183,66 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_packet_buffer_deinit_obj, bleio_packet_bu
//| .. attribute:: packet_size
//|
//| Maximum size of each packet in bytes. This is the minimum of the Characteristic length and
//| the negotiated Maximum Transfer Unit (MTU).
//| `packet_size` is the same as `incoming_packet_length`.
//| The name `packet_size` is deprecated and
//| will be removed in CircuitPython 6.0.0.
//|
STATIC mp_obj_t bleio_packet_buffer_get_packet_size(mp_obj_t self_in) {
//| .. attribute:: incoming_packet_length
//|
//| Maximum length in bytes of a packet we are reading.
//|
STATIC mp_obj_t bleio_packet_buffer_get_incoming_packet_length(mp_obj_t self_in) {
bleio_packet_buffer_obj_t *self = MP_OBJ_TO_PTR(self_in);
return MP_OBJ_NEW_SMALL_INT(common_hal_bleio_packet_buffer_get_packet_size(self));
mp_int_t size = common_hal_bleio_packet_buffer_get_incoming_packet_length(self);
if (size < 0) {
mp_raise_ValueError(translate("No connection: length cannot be determined"));
}
return MP_OBJ_NEW_SMALL_INT(size);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_packet_buffer_get_packet_size_obj, bleio_packet_buffer_get_packet_size);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_packet_buffer_get_incoming_packet_length_obj, bleio_packet_buffer_get_incoming_packet_length);
const mp_obj_property_t bleio_packet_buffer_packet_size_obj = {
const mp_obj_property_t bleio_packet_buffer_incoming_packet_length_obj = {
.base.type = &mp_type_property,
.proxy = { (mp_obj_t)&bleio_packet_buffer_get_packet_size_obj,
.proxy = { (mp_obj_t)&bleio_packet_buffer_get_incoming_packet_length_obj,
(mp_obj_t)&mp_const_none_obj,
(mp_obj_t)&mp_const_none_obj },
};
//| .. attribute:: outgoing_packet_length
//|
//| Maximum length in bytes of a packet we are writing.
//|
STATIC mp_obj_t bleio_packet_buffer_get_outgoing_packet_length(mp_obj_t self_in) {
bleio_packet_buffer_obj_t *self = MP_OBJ_TO_PTR(self_in);
mp_int_t size = common_hal_bleio_packet_buffer_get_outgoing_packet_length(self);
if (size < 0) {
mp_raise_ValueError(translate("No connection: length cannot be determined"));
}
return MP_OBJ_NEW_SMALL_INT(size);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_packet_buffer_get_outgoing_packet_length_obj, bleio_packet_buffer_get_outgoing_packet_length);
const mp_obj_property_t bleio_packet_buffer_outgoing_packet_length_obj = {
.base.type = &mp_type_property,
.proxy = { (mp_obj_t)&bleio_packet_buffer_get_outgoing_packet_length_obj,
(mp_obj_t)&mp_const_none_obj,
(mp_obj_t)&mp_const_none_obj },
};
STATIC const mp_rom_map_elem_t bleio_packet_buffer_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&bleio_packet_buffer_deinit_obj) },
{ MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&bleio_packet_buffer_deinit_obj) },
// Standard stream methods.
{ MP_OBJ_NEW_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&bleio_packet_buffer_readinto_obj) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_write), MP_ROM_PTR(&bleio_packet_buffer_write_obj) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&bleio_packet_buffer_readinto_obj) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_write), MP_ROM_PTR(&bleio_packet_buffer_write_obj) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_packet_size), MP_ROM_PTR(&bleio_packet_buffer_packet_size_obj) },
// .packet_size is now an alias for .incoming_packet_length
// TODO: Remove in 6.0.0.
{ MP_OBJ_NEW_QSTR(MP_QSTR_packet_size), MP_ROM_PTR(&bleio_packet_buffer_incoming_packet_length_obj) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_incoming_packet_length), MP_ROM_PTR(&bleio_packet_buffer_incoming_packet_length_obj) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_outgoing_packet_length), MP_ROM_PTR(&bleio_packet_buffer_outgoing_packet_length_obj) },
};
STATIC MP_DEFINE_CONST_DICT(bleio_packet_buffer_locals_dict, bleio_packet_buffer_locals_dict_table);

View File

@ -34,9 +34,10 @@ extern const mp_obj_type_t bleio_packet_buffer_type;
extern void common_hal_bleio_packet_buffer_construct(
bleio_packet_buffer_obj_t *self, bleio_characteristic_obj_t *characteristic,
size_t buffer_size);
void common_hal_bleio_packet_buffer_write(bleio_packet_buffer_obj_t *self, uint8_t *data, size_t len, uint8_t* header, size_t header_len);
int common_hal_bleio_packet_buffer_readinto(bleio_packet_buffer_obj_t *self, uint8_t *data, size_t len);
uint16_t common_hal_bleio_packet_buffer_get_packet_size(bleio_packet_buffer_obj_t *self);
mp_int_t common_hal_bleio_packet_buffer_write(bleio_packet_buffer_obj_t *self, uint8_t *data, size_t len, uint8_t* header, size_t header_len);
mp_int_t common_hal_bleio_packet_buffer_readinto(bleio_packet_buffer_obj_t *self, uint8_t *data, size_t len);
mp_int_t common_hal_bleio_packet_buffer_get_incoming_packet_length(bleio_packet_buffer_obj_t *self);
mp_int_t common_hal_bleio_packet_buffer_get_outgoing_packet_length(bleio_packet_buffer_obj_t *self);
bool common_hal_bleio_packet_buffer_deinited(bleio_packet_buffer_obj_t *self);
void common_hal_bleio_packet_buffer_deinit(bleio_packet_buffer_obj_t *self);

View File

@ -45,10 +45,10 @@ bleio_scanresults_obj_t* shared_module_bleio_new_scanresults(size_t buffer_size,
}
mp_obj_t common_hal_bleio_scanresults_next(bleio_scanresults_obj_t *self) {
while (ringbuf_count(&self->buf) == 0 && !self->done && !mp_hal_is_interrupted()) {
while (ringbuf_num_filled(&self->buf) == 0 && !self->done && !mp_hal_is_interrupted()) {
RUN_BACKGROUND_TASKS;
}
if (ringbuf_count(&self->buf) == 0 || mp_hal_is_interrupted()) {
if (ringbuf_num_filled(&self->buf) == 0 || mp_hal_is_interrupted()) {
return mp_const_none;
}
@ -97,7 +97,7 @@ void shared_module_bleio_scanresults_append(bleio_scanresults_obj_t* self,
uint16_t len) {
int32_t packet_size = sizeof(uint8_t) + sizeof(ticks_ms) + sizeof(rssi) + NUM_BLEIO_ADDRESS_BYTES +
sizeof(addr_type) + sizeof(len) + len;
int32_t empty_space = self->buf.size - ringbuf_count(&self->buf);
int32_t empty_space = self->buf.size - ringbuf_num_filled(&self->buf);
if (packet_size >= empty_space) {
// We can't fit the packet so skip it.
return;