do HCI pin init in Python, not here

This commit is contained in:
Dan Halbert 2020-06-26 19:27:05 -04:00
parent 1bc2e979eb
commit f879114c43
4 changed files with 58 additions and 129 deletions

View File

@ -177,17 +177,13 @@ char default_ble_name[] = { 'C', 'I', 'R', 'C', 'U', 'I', 'T', 'P', 'Y', 0, 0, 0
// common_hal_bleio_adapter_set_name(self, (char*) default_ble_name);
// }
void common_hal_bleio_adapter_construct(bleio_adapter_obj_t *self, const mcu_pin_obj_t *tx, const mcu_pin_obj_t *rx, const mcu_pin_obj_t *rts, const mcu_pin_obj_t *cts, uint32_t baudrate, uint32_t buffer_size, const mcu_pin_obj_t* spi_cs, const mcu_pin_obj_t* gpio0, const mcu_pin_obj_t *reset, bool reset_high) {
void common_hal_bleio_adapter_hci_init(bleio_adapter_obj_t *self, const mcu_pin_obj_t *tx, const mcu_pin_obj_t *rx, const mcu_pin_obj_t *rts, const mcu_pin_obj_t *cts, uint32_t baudrate, uint32_t buffer_size) {
self->tx = tx;
self->rx = rx;
self->rts = rts;
self->cts = cts;
self->baudrate = baudrate;
self->buffer_size = buffer_size;
self->spi_cs = spi_cs;
self->gpio0 = gpio0;
self->reset = reset;
self->reset_high = reset_high;
self->enabled = false;
}
@ -199,60 +195,8 @@ void common_hal_bleio_adapter_set_enabled(bleio_adapter_obj_t *self, bool enable
return;
}
if (enabled) {
// Enable adapter.
// common_hal UART takes rts and cts, but is currently not implemented for many ports.
// In addition, rts and cts may be pins that are not part of the serial peripheral
// used for tx and rx, so use GPIO for them.
common_hal_busio_uart_construct(&self->hci_uart, self->tx, self->rx, NULL, NULL, NULL, false,
self->baudrate, 8, PARITY_NONE, 1, 0.0f,
self->buffer_size, NULL, false);
// RTS is output, active high
common_hal_digitalio_digitalinout_construct(&self->rts_digitalio, self->rts);
common_hal_digitalio_digitalinout_switch_to_output(&self->rts_digitalio, false, DRIVE_MODE_PUSH_PULL);
// CTS is input.
common_hal_digitalio_digitalinout_construct(&self->cts_digitalio, self->cts);
// SPI_CS and GPI0 are used to signal entering BLE mode.
// SPI_CS should be low, and GPI0 should be high
common_hal_digitalio_digitalinout_construct(&self->spi_cs_digitalio, self->spi_cs);
common_hal_digitalio_digitalinout_construct(&self->gpio0_digitalio, self->gpio0);
common_hal_digitalio_digitalinout_switch_to_output(&self->spi_cs_digitalio, false, DRIVE_MODE_PUSH_PULL);
common_hal_digitalio_digitalinout_switch_to_output(&self->gpio0_digitalio, true, DRIVE_MODE_PUSH_PULL);
// RESET is output, start in non-reset state.
common_hal_digitalio_digitalinout_construct(&self->reset_digitalio, self->reset);
common_hal_digitalio_digitalinout_switch_to_output(&self->reset_digitalio,
!self->reset_high, DRIVE_MODE_PUSH_PULL);
// Adapter will enter BLE mode on reset, based on SPI_CS and GPIO0 settings.
// Reset HCI processor. Assert reset for 100ms, then wait 750ms for reset to complete.
common_hal_digitalio_digitalinout_set_value(&self->reset_digitalio, self->reset_high);
mp_hal_delay_ms(100);
common_hal_digitalio_digitalinout_set_value(&self->reset_digitalio, !self->reset_high);
mp_hal_delay_ms(750);
// After reset, set SPI_CS high.
common_hal_digitalio_digitalinout_set_value(&self->spi_cs_digitalio, true);
return;
}
// Disable.
common_hal_digitalio_digitalinout_set_value(&self->reset_digitalio, self->reset_high);
mp_hal_delay_ms(100);
common_hal_digitalio_digitalinout_set_value(&self->reset_digitalio, !self->reset_high);
// Free all pins.
common_hal_busio_uart_deinit(&self->hci_uart);
common_hal_digitalio_digitalinout_deinit(&self->rts_digitalio);
common_hal_digitalio_digitalinout_deinit(&self->cts_digitalio);
common_hal_digitalio_digitalinout_deinit(&self->spi_cs_digitalio);
common_hal_digitalio_digitalinout_deinit(&self->gpio0_digitalio);
common_hal_digitalio_digitalinout_deinit(&self->reset_digitalio);
//FIX enable/disable HCI adapter, but don't reset it, since we don't know how.
self->enabled = enabled;
}
bool common_hal_bleio_adapter_get_enabled(bleio_adapter_obj_t *self) {

View File

@ -58,16 +58,9 @@ typedef struct {
const mcu_pin_obj_t* cts;
uint32_t baudrate;
uint16_t buffer_size;
const mcu_pin_obj_t* spi_cs;
const mcu_pin_obj_t* gpio0;
const mcu_pin_obj_t* reset;
bool reset_high;
busio_uart_obj_t hci_uart;
digitalio_digitalinout_obj_t rts_digitalio;
digitalio_digitalinout_obj_t cts_digitalio;
digitalio_digitalinout_obj_t spi_cs_digitalio;
digitalio_digitalinout_obj_t gpio0_digitalio;
digitalio_digitalinout_obj_t reset_digitalio;
bool enabled;
} bleio_adapter_obj_t;

View File

@ -65,24 +65,26 @@
//| connections and also initiate connections."""
//|
//| def __init__(self, *, tx: Pin, rx: Pin, rts: Pin, cts: Pin, baudrate: int = 115200, buffer_size: int = 256, spi_cs: Pin, gpio0: Pin, reset: Pin, reset_high: bool):
//| """On boards with native BLE, such as the nRf52840,
//| you cannot create an instance of `_bleio.Adapter`.
//| def __init__(self, *, tx: Pin, rx: Pin, rts: Pin, cts: Pin, baudrate: int = 115200, buffer_size: int = 256):
//| You cannot create an instance of `_bleio.Adapter`.
//| Use `_bleio.adapter` to access the sole instance available."""
//|
//| On boards that do not have native BLE,
//| call `_bleio.Adapter()` once, passing it the pins used to communicate
//| with an HCI co-processor, such as an Adafruit AirLift, on or off the board.
//| The `Adapter` object will be initialized, enabled, and will be available as `_bleio.adapter`.
//| On boards that do not have native BLE. You can use HCI co-processor.
//| Call `_bleio.adapter.hci_init()` passing it the pins used to communicate
//| with the co-processor, such as an Adafruit AirLift.
//| The co-processor must have been reset and put into BLE mode beforehand
//| by the appropriate pin manipulation.
//| The `tx`, `rx`, `rts`, and `cs` pins are used to communicate with the HCI co-processor in HCI mode.
//| The `spi_cs` and `gpio0` pins are used to enable BLE mode
//| (usually `spi_cs` is low and `gpio0` is high to enter BLE mode).
//| The `reset` pin is used to reset the co-processor.
//| `reset_high` describes whether the reset pin is active high or active low.
//|
#if CIRCUITPY_BLEIO_HCI
STATIC mp_obj_t bleio_adapter_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_tx, ARG_rx, ARG_rts, ARG_cts, ARG_baudrate, ARG_buffer_size, ARG_spi_cs, ARG_gpio0, ARG_reset, ARG_reset_high };
mp_obj_t bleio_adapter_hci_init(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
bleio_adapter_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
if (self->enabled) {
mp_raise_ValueError(translate("HCI Adapter is already enabled"));
}
enum { ARG_tx, ARG_rx, ARG_rts, ARG_cts, ARG_baudrate, ARG_buffer_size };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_tx, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_rx, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_OBJ },
@ -90,43 +92,33 @@ STATIC mp_obj_t bleio_adapter_make_new(const mp_obj_type_t *type, size_t n_args,
{ MP_QSTR_cts, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_baudrate, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 115200 } },
{ MP_QSTR_buffer_size, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 256 } },
{ MP_QSTR_spi_cs, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_gpio0, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_reset, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_reset_high, MP_ARG_KW_ONLY | MP_ARG_BOOL },
};
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
const mcu_pin_obj_t *tx = validate_obj_is_free_pin(args[ARG_tx].u_obj);
const mcu_pin_obj_t *rx = validate_obj_is_free_pin(args[ARG_rx].u_obj);
const mcu_pin_obj_t *rts = validate_obj_is_free_pin(args[ARG_rts].u_obj);
const mcu_pin_obj_t *cts = validate_obj_is_free_pin(args[ARG_cts].u_obj);
const mcu_pin_obj_t *spi_cs = validate_obj_is_free_pin(args[ARG_spi_cs].u_obj);
const mcu_pin_obj_t *gpio0 = validate_obj_is_free_pin(args[ARG_gpio0].u_obj);
const mcu_pin_obj_t *reset = validate_obj_is_free_pin(args[ARG_reset].u_obj);
const bool reset_high = args[ARG_reset_high].u_bool;
const mcu_pin_obj_t *tx = validate_obj_is_free_pin(args[ARG_tx].u_obj);
const mcu_pin_obj_t *rx = validate_obj_is_free_pin(args[ARG_rx].u_obj);
const mcu_pin_obj_t *rts = validate_obj_is_free_pin(args[ARG_rts].u_obj);
const mcu_pin_obj_t *cts = validate_obj_is_free_pin(args[ARG_cts].u_obj);
if (args[ARG_baudrate].u_int <= 0) {
mp_raise_ValueError(translate("baudrate must be > 0"));
}
const uint32_t baudrate = args[ARG_baudrate].u_int;
if (args[ARG_baudrate].u_int <= 0) {
mp_raise_ValueError(translate("baudrate must be > 0"));
}
const uint32_t baudrate = args[ARG_baudrate].u_int;
if (args[ARG_buffer_size].u_int <= 1) {
mp_raise_ValueError(translate("buffer_size must be >= 1"));
}
const uint32_t buffer_size = args[ARG_buffer_size].u_int;
if (args[ARG_buffer_size].u_int <= 1) {
mp_raise_ValueError(translate("buffer_size must be >= 1"));
}
const uint32_t buffer_size = args[ARG_buffer_size].u_int;
common_hal_bleio_adapter_construct(&common_hal_bleio_adapter_obj, tx, rx, rts, cts,
baudrate, buffer_size,
spi_cs, gpio0,
reset, reset_high);
common_hal_bleio_adapter_set_enabled(&common_hal_bleio_adapter_obj, true);
return MP_OBJ_FROM_PTR(&common_hal_bleio_adapter_obj);
common_hal_bleio_adapter_hci_init(&common_hal_bleio_adapter_obj, tx, rx, rts, cts,
baudrate, buffer_size);
return mp_const_none;
}
#endif
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_adapter_hci_init_obj, 1, bleio_adapter_hci_init);
#endif // CIRCUITPY_BLEIO_HCI
//|
//| enabled: Any = ...
//| """State of the BLE adapter."""
@ -451,6 +443,9 @@ STATIC mp_obj_t bleio_adapter_erase_bonding(mp_obj_t self_in) {
STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_adapter_erase_bonding_obj, bleio_adapter_erase_bonding);
STATIC const mp_rom_map_elem_t bleio_adapter_locals_dict_table[] = {
#if CIRCUITPY_BLEIO_HCI
{ MP_ROM_QSTR(MP_QSTR_hci_init), MP_ROM_PTR(&bleio_adapter_hci_init_obj) },
#endif
{ MP_ROM_QSTR(MP_QSTR_enabled), MP_ROM_PTR(&bleio_adapter_enabled_obj) },
{ MP_ROM_QSTR(MP_QSTR_address), MP_ROM_PTR(&bleio_adapter_address_obj) },
{ MP_ROM_QSTR(MP_QSTR_name), MP_ROM_PTR(&bleio_adapter_name_obj) },
@ -475,8 +470,5 @@ STATIC MP_DEFINE_CONST_DICT(bleio_adapter_locals_dict, bleio_adapter_locals_dict
const mp_obj_type_t bleio_adapter_type = {
.base = { &mp_type_type },
.name = MP_QSTR_Adapter,
#if CIRCUITPY_BLEIO_HCI
.make_new = bleio_adapter_make_new,
#endif
.locals_dict = (mp_obj_t)&bleio_adapter_locals_dict,
};

View File

@ -38,30 +38,30 @@
const mp_obj_type_t bleio_adapter_type;
#if CIRCUITPY_BLEIO_HCI
void common_hal_bleio_adapter_construct(bleio_adapter_obj_t *self, const mcu_pin_obj_t *tx, const mcu_pin_obj_t *rx, const mcu_pin_obj_t *rts, const mcu_pin_obj_t *cts, uint32_t baudrate, uint32_t buffer_size, const mcu_pin_obj_t* spi_cs, const mcu_pin_obj_t* gpio0, const mcu_pin_obj_t *reset, bool reset_high);
#endif
void common_hal_bleio_adapter_hci_init(bleio_adapter_obj_t *self, const mcu_pin_obj_t *tx, const mcu_pin_obj_t *rx, const mcu_pin_obj_t *rts, const mcu_pin_obj_t *cts, uint32_t baudrate, uint32_t buffer_size);
#endif // CIRCUITPY_BLEIO_HCI
extern bool common_hal_bleio_adapter_get_advertising(bleio_adapter_obj_t *self);
extern bool common_hal_bleio_adapter_get_enabled(bleio_adapter_obj_t *self);
extern void common_hal_bleio_adapter_set_enabled(bleio_adapter_obj_t *self, bool enabled);
extern bool common_hal_bleio_adapter_get_connected(bleio_adapter_obj_t *self);
extern bleio_address_obj_t *common_hal_bleio_adapter_get_address(bleio_adapter_obj_t *self);
bool common_hal_bleio_adapter_get_advertising(bleio_adapter_obj_t *self);
bool common_hal_bleio_adapter_get_enabled(bleio_adapter_obj_t *self);
void common_hal_bleio_adapter_set_enabled(bleio_adapter_obj_t *self, bool enabled);
bool common_hal_bleio_adapter_get_connected(bleio_adapter_obj_t *self);
bleio_address_obj_t *common_hal_bleio_adapter_get_address(bleio_adapter_obj_t *self);
extern mp_obj_str_t* common_hal_bleio_adapter_get_name(bleio_adapter_obj_t *self);
extern void common_hal_bleio_adapter_set_name(bleio_adapter_obj_t *self, const char* name);
mp_obj_str_t* common_hal_bleio_adapter_get_name(bleio_adapter_obj_t *self);
void common_hal_bleio_adapter_set_name(bleio_adapter_obj_t *self, const char* name);
extern uint32_t _common_hal_bleio_adapter_start_advertising(bleio_adapter_obj_t *self, bool connectable, bool anonymous, uint32_t timeout, float interval, uint8_t *advertising_data, uint16_t advertising_data_len, uint8_t *scan_response_data, uint16_t scan_response_data_len);
uint32_t _common_hal_bleio_adapter_start_advertising(bleio_adapter_obj_t *self, bool connectable, bool anonymous, uint32_t timeout, float interval, uint8_t *advertising_data, uint16_t advertising_data_len, uint8_t *scan_response_data, uint16_t scan_response_data_len);
extern void common_hal_bleio_adapter_start_advertising(bleio_adapter_obj_t *self, bool connectable, bool anonymous, uint32_t timeout, mp_float_t interval, mp_buffer_info_t *advertising_data_bufinfo, mp_buffer_info_t *scan_response_data_bufinfo);
extern void common_hal_bleio_adapter_stop_advertising(bleio_adapter_obj_t *self);
void common_hal_bleio_adapter_start_advertising(bleio_adapter_obj_t *self, bool connectable, bool anonymous, uint32_t timeout, mp_float_t interval, mp_buffer_info_t *advertising_data_bufinfo, mp_buffer_info_t *scan_response_data_bufinfo);
void common_hal_bleio_adapter_stop_advertising(bleio_adapter_obj_t *self);
extern mp_obj_t common_hal_bleio_adapter_start_scan(bleio_adapter_obj_t *self, uint8_t* prefixes, size_t prefix_length, bool extended, mp_int_t buffer_size, mp_float_t timeout, mp_float_t interval, mp_float_t window, mp_int_t minimum_rssi, bool active);
extern void common_hal_bleio_adapter_stop_scan(bleio_adapter_obj_t *self);
mp_obj_t common_hal_bleio_adapter_start_scan(bleio_adapter_obj_t *self, uint8_t* prefixes, size_t prefix_length, bool extended, mp_int_t buffer_size, mp_float_t timeout, mp_float_t interval, mp_float_t window, mp_int_t minimum_rssi, bool active);
void common_hal_bleio_adapter_stop_scan(bleio_adapter_obj_t *self);
extern bool common_hal_bleio_adapter_get_connected(bleio_adapter_obj_t *self);
extern mp_obj_t common_hal_bleio_adapter_get_connections(bleio_adapter_obj_t *self);
extern mp_obj_t common_hal_bleio_adapter_connect(bleio_adapter_obj_t *self, bleio_address_obj_t *address, mp_float_t timeout);
bool common_hal_bleio_adapter_get_connected(bleio_adapter_obj_t *self);
mp_obj_t common_hal_bleio_adapter_get_connections(bleio_adapter_obj_t *self);
mp_obj_t common_hal_bleio_adapter_connect(bleio_adapter_obj_t *self, bleio_address_obj_t *address, mp_float_t timeout);
extern void common_hal_bleio_adapter_erase_bonding(bleio_adapter_obj_t *self);
void common_hal_bleio_adapter_erase_bonding(bleio_adapter_obj_t *self);
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADAPTER_H